From dab3ca1324288a1abeb32590e1caec8848efe3e0 Mon Sep 17 00:00:00 2001 From: nbd Date: Tue, 10 Jan 2006 19:43:00 +0000 Subject: large target/linux cleanup git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@2877 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/brcm-2.4/patches/001-bcm47xx.patch | 23751 ++++++++++++++++++++++ 1 file changed, 23751 insertions(+) create mode 100644 target/linux/brcm-2.4/patches/001-bcm47xx.patch (limited to 'target/linux/brcm-2.4/patches/001-bcm47xx.patch') diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch new file mode 100644 index 0000000000..9d919156b6 --- /dev/null +++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -0,0 +1,23751 @@ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/cfe_env.c linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c +--- linux-2.4.32/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c 2005-12-19 01:56:35.104829500 +0100 +@@ -0,0 +1,234 @@ ++/* ++ * NVRAM variable manipulation (Linux kernel half) ++ * ++ * Copyright 2001-2003, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define NVRAM_SIZE (0x1ff0) ++static char _nvdata[NVRAM_SIZE] __initdata; ++static char _valuestr[256] __initdata; ++ ++/* ++ * TLV types. These codes are used in the "type-length-value" ++ * encoding of the items stored in the NVRAM device (flash or EEPROM) ++ * ++ * The layout of the flash/nvram is as follows: ++ * ++ * ++ * ++ * The type code of "ENV_TLV_TYPE_END" marks the end of the list. ++ * The "length" field marks the length of the data section, not ++ * including the type and length fields. ++ * ++ * Environment variables are stored as follows: ++ * ++ * = ++ * ++ * If bit 0 (low bit) is set, the length is an 8-bit value. ++ * If bit 0 (low bit) is clear, the length is a 16-bit value ++ * ++ * Bit 7 set indicates "user" TLVs. In this case, bit 0 still ++ * indicates the size of the length field. ++ * ++ * Flags are from the constants below: ++ * ++ */ ++#define ENV_LENGTH_16BITS 0x00 /* for low bit */ ++#define ENV_LENGTH_8BITS 0x01 ++ ++#define ENV_TYPE_USER 0x80 ++ ++#define ENV_CODE_SYS(n,l) (((n)<<1)|(l)) ++#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER) ++ ++/* ++ * The actual TLV types we support ++ */ ++ ++#define ENV_TLV_TYPE_END 0x00 ++#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS) ++ ++/* ++ * Environment variable flags ++ */ ++ ++#define ENV_FLG_NORMAL 0x00 /* normal read/write */ ++#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */ ++#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */ ++ ++#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */ ++#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */ ++ ++ ++/* ********************************************************************* ++ * _nvram_read(buffer,offset,length) ++ * ++ * Read data from the NVRAM device ++ * ++ * Input parameters: ++ * buffer - destination buffer ++ * offset - offset of data to read ++ * length - number of bytes to read ++ * ++ * Return value: ++ * number of bytes read, or <0 if error occured ++ ********************************************************************* */ ++static int ++_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length) ++{ ++ int i; ++ if (offset > NVRAM_SIZE) ++ return -1; ++ ++ for ( i = 0; i < length; i++) { ++ buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i]; ++ } ++ return length; ++} ++ ++ ++static char* ++_strnchr(const char *dest,int c,size_t cnt) ++{ ++ while (*dest && (cnt > 0)) { ++ if (*dest == c) return (char *) dest; ++ dest++; ++ cnt--; ++ } ++ return NULL; ++} ++ ++ ++ ++/* ++ * Core support API: Externally visible. ++ */ ++ ++/* ++ * Get the value of an NVRAM variable ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined ++ */ ++ ++char* ++cfe_env_get(unsigned char *nv_buf, char* name) ++{ ++ int size; ++ unsigned char *buffer; ++ unsigned char *ptr; ++ unsigned char *envval; ++ unsigned int reclen; ++ unsigned int rectype; ++ int offset; ++ int flg; ++ ++ size = NVRAM_SIZE; ++ buffer = &_nvdata[0]; ++ ++ ptr = buffer; ++ offset = 0; ++ ++ /* Read the record type and length */ ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { ++ goto error; ++ } ++ ++ while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) { ++ ++ /* Adjust pointer for TLV type */ ++ rectype = *(ptr); ++ offset++; ++ size--; ++ ++ /* ++ * Read the length. It can be either 1 or 2 bytes ++ * depending on the code ++ */ ++ if (rectype & ENV_LENGTH_8BITS) { ++ /* Read the record type and length - 8 bits */ ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { ++ goto error; ++ } ++ reclen = *(ptr); ++ size--; ++ offset++; ++ } ++ else { ++ /* Read the record type and length - 16 bits, MSB first */ ++ if (_nvram_read(nv_buf, ptr,offset,2) != 2) { ++ goto error; ++ } ++ reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1); ++ size -= 2; ++ offset += 2; ++ } ++ ++ if (reclen > size) ++ break; /* should not happen, bad NVRAM */ ++ ++ switch (rectype) { ++ case ENV_TLV_TYPE_ENV: ++ /* Read the TLV data */ ++ if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen) ++ goto error; ++ flg = *ptr++; ++ envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1)); ++ if (envval) { ++ *envval++ = '\0'; ++ memcpy(_valuestr,envval,(reclen-1)-(envval-ptr)); ++ _valuestr[(reclen-1)-(envval-ptr)] = '\0'; ++#if 0 ++ printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr); ++#endif ++ if(!strcmp(ptr, name)){ ++ return _valuestr; ++ } ++ if((strlen(ptr) > 1) && !strcmp(&ptr[1], name)) ++ return _valuestr; ++ } ++ break; ++ ++ default: ++ /* Unknown TLV type, skip it. */ ++ break; ++ } ++ ++ /* ++ * Advance to next TLV ++ */ ++ ++ size -= (int)reclen; ++ offset += reclen; ++ ++ /* Read the next record type */ ++ ptr = buffer; ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) ++ goto error; ++ } ++ ++error: ++ return NULL; ++ ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile +--- linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,33 @@ ++# ++# Makefile for Broadcom BCM947XX boards ++# ++# Copyright 2001-2003, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: Makefile,v 1.2 2005/04/02 12:12:57 wbx Exp $ ++# ++ ++OBJCOPY_ARGS = -O binary -R .reginfo -R .note -R .comment -R .mdebug -S ++SYSTEM ?= $(TOPDIR)/vmlinux ++ ++all: vmlinuz ++ ++# Don't build dependencies, this may die if $(CC) isn't gcc ++dep: ++ ++# Create a gzipped version named vmlinuz for compatibility ++vmlinuz: piggy ++ gzip -c9 $< > $@ ++ ++piggy: $(SYSTEM) ++ $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ ++ ++mrproper: clean ++ ++clean: ++ rm -f vmlinuz piggy +diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S +--- linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,51 @@ ++/* ++ * Generic interrupt handler for Broadcom MIPS boards ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: int-handler.S,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* ++ * MIPS IRQ Source ++ * -------- ------ ++ * 0 Software (ignored) ++ * 1 Software (ignored) ++ * 2 Combined hardware interrupt (hw0) ++ * 3 Hardware ++ * 4 Hardware ++ * 5 Hardware ++ * 6 Hardware ++ * 7 R4k timer ++ */ ++ ++ .text ++ .set noreorder ++ .set noat ++ .align 5 ++ NESTED(brcmIRQ, PT_SIZE, sp) ++ SAVE_ALL ++ CLI ++ .set at ++ .set noreorder ++ ++ jal brcm_irq_dispatch ++ move a0, sp ++ ++ j ret_from_irq ++ nop ++ ++ END(brcmIRQ) +diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/irq.c linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c +--- linux-2.4.32/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,130 @@ ++/* ++ * Generic interrupt control functions for Broadcom MIPS boards ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: irq.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) ++ ++extern asmlinkage void brcmIRQ(void); ++extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); ++ ++void ++brcm_irq_dispatch(struct pt_regs *regs) ++{ ++ u32 cause; ++ ++ cause = read_c0_cause() & ++ read_c0_status() & ++ CAUSEF_IP; ++ ++#ifdef CONFIG_KERNPROF ++ change_c0_status(cause | 1, 1); ++#else ++ clear_c0_status(cause); ++#endif ++ ++ if (cause & CAUSEF_IP7) ++ do_IRQ(7, regs); ++ if (cause & CAUSEF_IP2) ++ do_IRQ(2, regs); ++ if (cause & CAUSEF_IP3) ++ do_IRQ(3, regs); ++ if (cause & CAUSEF_IP4) ++ do_IRQ(4, regs); ++ if (cause & CAUSEF_IP5) ++ do_IRQ(5, regs); ++ if (cause & CAUSEF_IP6) ++ do_IRQ(6, regs); ++} ++ ++static void ++enable_brcm_irq(unsigned int irq) ++{ ++ if (irq < 8) ++ set_c0_status(1 << (irq + 8)); ++ else ++ set_c0_status(IE_IRQ0); ++} ++ ++static void ++disable_brcm_irq(unsigned int irq) ++{ ++ if (irq < 8) ++ clear_c0_status(1 << (irq + 8)); ++ else ++ clear_c0_status(IE_IRQ0); ++} ++ ++static void ++ack_brcm_irq(unsigned int irq) ++{ ++ /* Already done in brcm_irq_dispatch */ ++} ++ ++static unsigned int ++startup_brcm_irq(unsigned int irq) ++{ ++ enable_brcm_irq(irq); ++ ++ return 0; /* never anything pending */ ++} ++ ++static void ++end_brcm_irq(unsigned int irq) ++{ ++ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) ++ enable_brcm_irq(irq); ++} ++ ++static struct hw_interrupt_type brcm_irq_type = { ++ typename: "MIPS", ++ startup: startup_brcm_irq, ++ shutdown: disable_brcm_irq, ++ enable: enable_brcm_irq, ++ disable: disable_brcm_irq, ++ ack: ack_brcm_irq, ++ end: end_brcm_irq, ++ NULL ++}; ++ ++void __init ++init_IRQ(void) ++{ ++ int i; ++ ++ for (i = 0; i < NR_IRQS; i++) { ++ irq_desc[i].status = IRQ_DISABLED; ++ irq_desc[i].action = 0; ++ irq_desc[i].depth = 1; ++ irq_desc[i].handler = &brcm_irq_type; ++ } ++ ++ set_except_vector(0, brcmIRQ); ++ change_c0_status(ST0_IM, ALLINTS); ++ ++#ifdef CONFIG_REMOTE_DEBUG ++ printk("Breaking into debugger...\n"); ++ set_debug_traps(); ++ breakpoint(); ++#endif ++} +diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile +--- linux-2.4.32/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,15 @@ ++# ++# Makefile for the BCM947xx specific kernel interface routines ++# under Linux. ++# ++ ++.S.s: ++ $(CPP) $(AFLAGS) $< -o $*.s ++.S.o: ++ $(CC) $(AFLAGS) -c $< -o $*.o ++ ++O_TARGET := brcm.o ++ ++obj-y := int-handler.o irq.o ++ ++include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32/arch/mips/bcm947xx/gpio.c linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c +--- linux-2.4.32/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c 2005-12-16 23:39:10.668819500 +0100 +@@ -0,0 +1,158 @@ ++/* ++ * GPIO char driver ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++static sb_t *gpio_sbh; ++static int gpio_major; ++static devfs_handle_t gpio_dir; ++static struct { ++ char *name; ++ devfs_handle_t handle; ++} gpio_file[] = { ++ { "in", NULL }, ++ { "out", NULL }, ++ { "outen", NULL }, ++ { "control", NULL } ++}; ++ ++static int ++gpio_open(struct inode *inode, struct file * file) ++{ ++ if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file)) ++ return -ENODEV; ++ ++ MOD_INC_USE_COUNT; ++ return 0; ++} ++ ++static int ++gpio_release(struct inode *inode, struct file * file) ++{ ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static ssize_t ++gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ u32 val; ++ ++ switch (MINOR(file->f_dentry->d_inode->i_rdev)) { ++ case 0: ++ val = sb_gpioin(gpio_sbh); ++ break; ++ case 1: ++ val = sb_gpioout(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); ++ break; ++ case 2: ++ val = sb_gpioouten(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); ++ break; ++ case 3: ++ val = sb_gpiocontrol(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); ++ break; ++ default: ++ return -ENODEV; ++ } ++ ++ if (put_user(val, (u32 *) buf)) ++ return -EFAULT; ++ ++ return sizeof(val); ++} ++ ++static ssize_t ++gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ++{ ++ u32 val; ++ ++ if (get_user(val, (u32 *) buf)) ++ return -EFAULT; ++ ++ switch (MINOR(file->f_dentry->d_inode->i_rdev)) { ++ case 0: ++ return -EACCES; ++ case 1: ++ sb_gpioout(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); ++ break; ++ case 2: ++ sb_gpioouten(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); ++ break; ++ case 3: ++ sb_gpiocontrol(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); ++ break; ++ default: ++ return -ENODEV; ++ } ++ ++ return sizeof(val); ++} ++ ++static struct file_operations gpio_fops = { ++ owner: THIS_MODULE, ++ open: gpio_open, ++ release: gpio_release, ++ read: gpio_read, ++ write: gpio_write, ++}; ++ ++static int __init ++gpio_init(void) ++{ ++ int i; ++ ++ if (!(gpio_sbh = sb_kattach())) ++ return -ENODEV; ++ ++ sb_gpiosetcore(gpio_sbh); ++ ++ if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0) ++ return gpio_major; ++ ++ gpio_dir = devfs_mk_dir(NULL, "gpio", NULL); ++ ++ for (i = 0; i < ARRAYSIZE(gpio_file); i++) { ++ gpio_file[i].handle = devfs_register(gpio_dir, ++ gpio_file[i].name, ++ DEVFS_FL_DEFAULT, gpio_major, i, ++ S_IFCHR | S_IRUGO | S_IWUGO, ++ &gpio_fops, NULL); ++ } ++ ++ return 0; ++} ++ ++static void __exit ++gpio_exit(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAYSIZE(gpio_file); i++) ++ devfs_unregister(gpio_file[i].handle); ++ devfs_unregister(gpio_dir); ++ devfs_unregister_chrdev(gpio_major, "gpio"); ++ sb_detach(gpio_sbh); ++} ++ ++module_init(gpio_init); ++module_exit(gpio_exit); +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h 2005-12-16 23:39:10.672819750 +0100 +@@ -0,0 +1,391 @@ ++/* ++ * Broadcom device-specific manifest constants. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _BCMDEVS_H ++#define _BCMDEVS_H ++ ++ ++/* Known PCI vendor Id's */ ++#define VENDOR_EPIGRAM 0xfeda ++#define VENDOR_BROADCOM 0x14e4 ++#define VENDOR_3COM 0x10b7 ++#define VENDOR_NETGEAR 0x1385 ++#define VENDOR_DIAMOND 0x1092 ++#define VENDOR_DELL 0x1028 ++#define VENDOR_HP 0x0e11 ++#define VENDOR_APPLE 0x106b ++ ++/* PCI Device Id's */ ++#define BCM4210_DEVICE_ID 0x1072 /* never used */ ++#define BCM4211_DEVICE_ID 0x4211 ++#define BCM4230_DEVICE_ID 0x1086 /* never used */ ++#define BCM4231_DEVICE_ID 0x4231 ++ ++#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */ ++#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */ ++#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */ ++#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */ ++ ++#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */ ++#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */ ++ ++#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ ++#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */ ++ ++#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */ ++#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */ ++#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */ ++#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */ ++#define BCM47XX_USB_ID 0x4715 /* 47xx usb */ ++#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */ ++#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */ ++#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */ ++#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ ++#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ ++#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ ++ ++#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ ++ ++#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */ ++#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */ ++#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */ ++#define BCM4610_ENET_ID 0x4613 /* 4610 enet */ ++#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */ ++#define BCM4610_USB_ID 0x4615 /* 4610 usb */ ++ ++#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */ ++#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ ++#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ ++#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ ++ ++#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */ ++#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */ ++ ++#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */ ++#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */ ++#define BCM4307_ENET_ID 0x4306 /* 4307 enet */ ++#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */ ++ ++#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */ ++#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ ++#define BCM4306_D11G_ID2 0x4325 ++#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ ++#define BCM4306_UART_ID 0x4322 /* 4306 uart */ ++#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */ ++#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */ ++ ++#define BCM4309_PKG_ID 1 /* 4309 package id */ ++ ++#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ ++#define BCM4303_PKG_ID 2 /* 4303 package id */ ++ ++#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */ ++#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */ ++#define BCM4310_UART_ID 0x4312 /* 4310 uart */ ++#define BCM4310_ENET_ID 0x4313 /* 4310 enet */ ++#define BCM4310_USB_ID 0x4315 /* 4310 usb */ ++ ++#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ ++#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ ++ ++ ++#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */ ++#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ ++ ++#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */ ++ ++#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */ ++#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */ ++#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */ ++#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */ ++ ++#define FPGA_JTAGM_ID 0x4330 /* ??? */ ++ ++/* Address map */ ++#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */ ++#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */ ++#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */ ++#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */ ++#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */ ++ ++/* Core register space */ ++#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */ ++#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */ ++#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */ ++#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */ ++#define BCM4710_REG_USB 0x18004000 /* USB core registers */ ++#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */ ++#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */ ++#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */ ++#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */ ++ ++#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */ ++#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */ ++#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */ ++#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */ ++#define BCM4710_PROG 0x1f800000 /* Programable interface */ ++#define BCM4710_FLASH 0x1fc00000 /* Flash */ ++ ++#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++ ++#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300) ++ ++#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000) ++#define BCM4710_LED (BCM4710_EXTIF + 0x00900000) ++ ++#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */ ++#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ ++#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ ++#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ ++#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ ++ ++#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */ ++ ++#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */ ++#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */ ++#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */ ++ ++#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */ ++ ++/* PCMCIA vendor Id's */ ++ ++#define VENDOR_BROADCOM_PCMCIA 0x02d0 ++ ++/* SDIO vendor Id's */ ++#define VENDOR_BROADCOM_SDIO 0x00BF ++ ++ ++/* boardflags */ ++#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */ ++#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */ ++#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */ ++#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */ ++#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */ ++#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */ ++#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */ ++#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */ ++#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */ ++#define BFL_FEM 0x0800 /* This board supports the Front End Module */ ++#define BFL_EXTLNA 0x1000 /* This board has an external LNA */ ++#define BFL_HGPA 0x2000 /* This board has a high gain PA */ ++#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */ ++#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */ ++ ++/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ ++#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */ ++#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */ ++#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */ ++#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */ ++#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */ ++#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ ++#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ ++#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ ++#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ ++#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ ++ ++/* Bus types */ ++#define SB_BUS 0 /* Silicon Backplane */ ++#define PCI_BUS 1 /* PCI target */ ++#define PCMCIA_BUS 2 /* PCMCIA target */ ++#define SDIO_BUS 3 /* SDIO target */ ++#define JTAG_BUS 4 /* JTAG */ ++ ++/* Allows optimization for single-bus support */ ++#ifdef BCMBUSTYPE ++#define BUSTYPE(bus) (BCMBUSTYPE) ++#else ++#define BUSTYPE(bus) (bus) ++#endif ++ ++/* power control defines */ ++#define PLL_DELAY 150 /* us pll on delay */ ++#define FREF_DELAY 200 /* us fref change delay */ ++#define MIN_SLOW_CLK 32 /* us Slow clock period */ ++#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ ++ ++/* Reference Board Types */ ++ ++#define BU4710_BOARD 0x0400 ++#define VSIM4710_BOARD 0x0401 ++#define QT4710_BOARD 0x0402 ++ ++#define BU4610_BOARD 0x0403 ++#define VSIM4610_BOARD 0x0404 ++ ++#define BU4307_BOARD 0x0405 ++#define BCM94301CB_BOARD 0x0406 ++#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */ ++#define BCM94301MP_BOARD 0x0407 ++#define BCM94307MP_BOARD 0x0408 ++#define BCMAP4307_BOARD 0x0409 ++ ++#define BU4309_BOARD 0x040a ++#define BCM94309CB_BOARD 0x040b ++#define BCM94309MP_BOARD 0x040c ++#define BCM4309AP_BOARD 0x040d ++ ++#define BCM94302MP_BOARD 0x040e ++ ++#define VSIM4310_BOARD 0x040f ++#define BU4711_BOARD 0x0410 ++#define BCM94310U_BOARD 0x0411 ++#define BCM94310AP_BOARD 0x0412 ++#define BCM94310MP_BOARD 0x0414 ++ ++#define BU4306_BOARD 0x0416 ++#define BCM94306CB_BOARD 0x0417 ++#define BCM94306MP_BOARD 0x0418 ++ ++#define BCM94710D_BOARD 0x041a ++#define BCM94710R1_BOARD 0x041b ++#define BCM94710R4_BOARD 0x041c ++#define BCM94710AP_BOARD 0x041d ++ ++ ++#define BU2050_BOARD 0x041f ++ ++ ++#define BCM94309G_BOARD 0x0421 ++ ++#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */ ++ ++#define BU4704_BOARD 0x0423 ++#define BU4702_BOARD 0x0424 ++ ++#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ ++ ++#define BU4317_BOARD 0x0426 ++ ++ ++#define BCM94702MN_BOARD 0x0428 ++ ++/* BCM4702 1U CompactPCI Board */ ++#define BCM94702CPCI_BOARD 0x0429 ++ ++/* BCM4702 with BCM95380 VLAN Router */ ++#define BCM95380RR_BOARD 0x042a ++ ++/* cb4306 with SiGe PA */ ++#define BCM94306CBSG_BOARD 0x042b ++ ++/* mp4301 with 2050 radio */ ++#define BCM94301MPL_BOARD 0x042c ++ ++/* cb4306 with SiGe PA */ ++#define PCSG94306_BOARD 0x042d ++ ++/* bu4704 with sdram */ ++#define BU4704SD_BOARD 0x042e ++ ++/* Dual 11a/11g Router */ ++#define BCM94704AGR_BOARD 0x042f ++ ++/* 11a-only minipci */ ++#define BCM94308MP_BOARD 0x0430 ++ ++ ++ ++/* BCM94317 boards */ ++#define BCM94317CB_BOARD 0x0440 ++#define BCM94317MP_BOARD 0x0441 ++#define BCM94317PCMCIA_BOARD 0x0442 ++#define BCM94317SDIO_BOARD 0x0443 ++ ++#define BU4712_BOARD 0x0444 ++#define BU4712SD_BOARD 0x045d ++#define BU4712L_BOARD 0x045f ++ ++/* BCM4712 boards */ ++#define BCM94712AP_BOARD 0x0445 ++#define BCM94712P_BOARD 0x0446 ++ ++/* BCM4318 boards */ ++#define BU4318_BOARD 0x0447 ++#define CB4318_BOARD 0x0448 ++#define MPG4318_BOARD 0x0449 ++#define MP4318_BOARD 0x044a ++#define SD4318_BOARD 0x044b ++ ++/* BCM63XX boards */ ++#define BCM96338_BOARD 0x6338 ++#define BCM96345_BOARD 0x6345 ++#define BCM96348_BOARD 0x6348 ++ ++/* Another mp4306 with SiGe */ ++#define BCM94306P_BOARD 0x044c ++ ++/* CF-like 4317 modules */ ++#define BCM94317CF_BOARD 0x044d ++ ++/* mp4303 */ ++#define BCM94303MP_BOARD 0x044e ++ ++/* mpsgh4306 */ ++#define BCM94306MPSGH_BOARD 0x044f ++ ++/* BRCM 4306 w/ Front End Modules */ ++#define BCM94306MPM 0x0450 ++#define BCM94306MPL 0x0453 ++ ++/* 4712agr */ ++#define BCM94712AGR_BOARD 0x0451 ++ ++/* The real CF 4317 board */ ++#define CFI4317_BOARD 0x0452 ++ ++/* pcmcia 4303 */ ++#define PC4303_BOARD 0x0454 ++ ++/* 5350K */ ++#define BCM95350K_BOARD 0x0455 ++ ++/* 5350R */ ++#define BCM95350R_BOARD 0x0456 ++ ++/* 4306mplna */ ++#define BCM94306MPLNA_BOARD 0x0457 ++ ++/* 4320 boards */ ++#define BU4320_BOARD 0x0458 ++#define BU4320S_BOARD 0x0459 ++#define BCM94320PH_BOARD 0x045a ++ ++/* 4306mph */ ++#define BCM94306MPH_BOARD 0x045b ++ ++/* 4306pciv */ ++#define BCM94306PCIV_BOARD 0x045c ++ ++#define BU4712SD_BOARD 0x045d ++ ++#define BCM94320PFLSH_BOARD 0x045e ++ ++#define BU4712L_BOARD 0x045f ++#define BCM94712LGR_BOARD 0x0460 ++#define BCM94320R_BOARD 0x0461 ++ ++#define BU5352_BOARD 0x0462 ++ ++#define BCM94318MPGH_BOARD 0x0463 ++ ++ ++#define BCM95352GR_BOARD 0x0467 ++ ++/* bcm95351agr */ ++#define BCM95351AGR_BOARD 0x0470 ++ ++/* # of GPIO pins */ ++#define GPIO_NUMPINS 16 ++ ++#endif /* _BCMDEVS_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h 2005-12-16 23:39:10.672819750 +0100 +@@ -0,0 +1,152 @@ ++/* ++ * local version of endian.h - byte order defines ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++*/ ++ ++#ifndef _BCMENDIAN_H_ ++#define _BCMENDIAN_H_ ++ ++#include ++ ++/* Byte swap a 16 bit value */ ++#define BCMSWAP16(val) \ ++ ((uint16)( \ ++ (((uint16)(val) & (uint16)0x00ffU) << 8) | \ ++ (((uint16)(val) & (uint16)0xff00U) >> 8) )) ++ ++/* Byte swap a 32 bit value */ ++#define BCMSWAP32(val) \ ++ ((uint32)( \ ++ (((uint32)(val) & (uint32)0x000000ffUL) << 24) | \ ++ (((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \ ++ (((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \ ++ (((uint32)(val) & (uint32)0xff000000UL) >> 24) )) ++ ++/* 2 Byte swap a 32 bit value */ ++#define BCMSWAP32BY16(val) \ ++ ((uint32)( \ ++ (((uint32)(val) & (uint32)0x0000ffffUL) << 16) | \ ++ (((uint32)(val) & (uint32)0xffff0000UL) >> 16) )) ++ ++ ++static INLINE uint16 ++bcmswap16(uint16 val) ++{ ++ return BCMSWAP16(val); ++} ++ ++static INLINE uint32 ++bcmswap32(uint32 val) ++{ ++ return BCMSWAP32(val); ++} ++ ++static INLINE uint32 ++bcmswap32by16(uint32 val) ++{ ++ return BCMSWAP32BY16(val); ++} ++ ++/* buf - start of buffer of shorts to swap */ ++/* len - byte length of buffer */ ++static INLINE void ++bcmswap16_buf(uint16 *buf, uint len) ++{ ++ len = len/2; ++ ++ while(len--){ ++ *buf = bcmswap16(*buf); ++ buf++; ++ } ++} ++ ++#ifndef hton16 ++#ifndef IL_BIGENDIAN ++#define HTON16(i) BCMSWAP16(i) ++#define hton16(i) bcmswap16(i) ++#define hton32(i) bcmswap32(i) ++#define ntoh16(i) bcmswap16(i) ++#define ntoh32(i) bcmswap32(i) ++#define ltoh16(i) (i) ++#define ltoh32(i) (i) ++#define htol16(i) (i) ++#define htol32(i) (i) ++#else ++#define HTON16(i) (i) ++#define hton16(i) (i) ++#define hton32(i) (i) ++#define ntoh16(i) (i) ++#define ntoh32(i) (i) ++#define ltoh16(i) bcmswap16(i) ++#define ltoh32(i) bcmswap32(i) ++#define htol16(i) bcmswap16(i) ++#define htol32(i) bcmswap32(i) ++#endif ++#endif ++ ++#ifndef IL_BIGENDIAN ++#define ltoh16_buf(buf, i) ++#define htol16_buf(buf, i) ++#else ++#define ltoh16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) ++#define htol16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) ++#endif ++ ++/* ++* load 16-bit value from unaligned little endian byte array. ++*/ ++static INLINE uint16 ++ltoh16_ua(uint8 *bytes) ++{ ++ return (bytes[1]<<8)+bytes[0]; ++} ++ ++/* ++* load 32-bit value from unaligned little endian byte array. ++*/ ++static INLINE uint32 ++ltoh32_ua(uint8 *bytes) ++{ ++ return (bytes[3]<<24)+(bytes[2]<<16)+(bytes[1]<<8)+bytes[0]; ++} ++ ++/* ++* load 16-bit value from unaligned big(network) endian byte array. ++*/ ++static INLINE uint16 ++ntoh16_ua(uint8 *bytes) ++{ ++ return (bytes[0]<<8)+bytes[1]; ++} ++ ++/* ++* load 32-bit value from unaligned big(network) endian byte array. ++*/ ++static INLINE uint32 ++ntoh32_ua(uint8 *bytes) ++{ ++ return (bytes[0]<<24)+(bytes[1]<<16)+(bytes[2]<<8)+bytes[3]; ++} ++ ++#define ltoh_ua(ptr) ( \ ++ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] : \ ++ (((uint8 *)ptr)[3]<<24)+(((uint8 *)ptr)[2]<<16)+(((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] \ ++) ++ ++#define ntoh_ua(ptr) ( \ ++ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[0]<<8)+((uint8 *)ptr)[1] : \ ++ (((uint8 *)ptr)[0]<<24)+(((uint8 *)ptr)[1]<<16)+(((uint8 *)ptr)[2]<<8)+((uint8 *)ptr)[3] \ ++) ++ ++#endif /* _BCMENDIAN_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenet47xx.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmenet47xx.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,229 @@ ++/* ++ * Hardware-specific definitions for ++ * Broadcom BCM47XX 10/100 Mbps Ethernet cores. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _bcmenet_47xx_h_ ++#define _bcmenet_47xx_h_ ++ ++#include ++#include ++#include ++ ++#define BCMENET_NFILTERS 64 /* # ethernet address filter entries */ ++#define BCMENET_MCHASHBASE 0x200 /* multicast hash filter base address */ ++#define BCMENET_MCHASHSIZE 256 /* multicast hash filter size in bytes */ ++#define BCMENET_MAX_DMA 4096 /* chip has 12 bits of DMA addressing */ ++ ++/* power management event wakeup pattern constants */ ++#define BCMENET_NPMP 4 /* chip supports 4 wakeup patterns */ ++#define BCMENET_PMPBASE 0x400 /* wakeup pattern base address */ ++#define BCMENET_PMPSIZE 0x80 /* 128bytes each pattern */ ++#define BCMENET_PMMBASE 0x600 /* wakeup mask base address */ ++#define BCMENET_PMMSIZE 0x10 /* 128bits each mask */ ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* ++ * Host Interface Registers ++ */ ++typedef volatile struct _bcmenettregs { ++ /* Device and Power Control */ ++ uint32 devcontrol; ++ uint32 PAD[2]; ++ uint32 biststatus; ++ uint32 wakeuplength; ++ uint32 PAD[3]; ++ ++ /* Interrupt Control */ ++ uint32 intstatus; ++ uint32 intmask; ++ uint32 gptimer; ++ uint32 PAD[23]; ++ ++ /* Ethernet MAC Address Filtering Control */ ++ uint32 PAD[2]; ++ uint32 enetftaddr; ++ uint32 enetftdata; ++ uint32 PAD[2]; ++ ++ /* Ethernet MAC Control */ ++ uint32 emactxmaxburstlen; ++ uint32 emacrxmaxburstlen; ++ uint32 emaccontrol; ++ uint32 emacflowcontrol; ++ ++ uint32 PAD[20]; ++ ++ /* DMA Lazy Interrupt Control */ ++ uint32 intrecvlazy; ++ uint32 PAD[63]; ++ ++ /* DMA engine */ ++ dma32regp_t dmaregs; ++ dma32diag_t dmafifo; ++ uint32 PAD[116]; ++ ++ /* EMAC Registers */ ++ uint32 rxconfig; ++ uint32 rxmaxlength; ++ uint32 txmaxlength; ++ uint32 PAD; ++ uint32 mdiocontrol; ++ uint32 mdiodata; ++ uint32 emacintmask; ++ uint32 emacintstatus; ++ uint32 camdatalo; ++ uint32 camdatahi; ++ uint32 camcontrol; ++ uint32 enetcontrol; ++ uint32 txcontrol; ++ uint32 txwatermark; ++ uint32 mibcontrol; ++ uint32 PAD[49]; ++ ++ /* EMAC MIB counters */ ++ bcmenetmib_t mib; ++ ++ uint32 PAD[585]; ++ ++ /* Sonics SiliconBackplane config registers */ ++ sbconfig_t sbconfig; ++} bcmenetregs_t; ++ ++/* device control */ ++#define DC_PM ((uint32)1 << 7) /* pattern filtering enable */ ++#define DC_IP ((uint32)1 << 10) /* internal ephy present (rev >= 1) */ ++#define DC_ER ((uint32)1 << 15) /* ephy reset */ ++#define DC_MP ((uint32)1 << 16) /* mii phy mode enable */ ++#define DC_CO ((uint32)1 << 17) /* mii phy mode: enable clocks */ ++#define DC_PA_MASK 0x7c0000 /* mii phy mode: mdc/mdio phy address */ ++#define DC_PA_SHIFT 18 ++#define DC_FS_MASK 0x03800000 /* fifo size (rev >= 8) */ ++#define DC_FS_SHIFT 23 ++#define DC_FS_4K 0 /* 4Kbytes */ ++#define DC_FS_512 1 /* 512bytes */ ++ ++/* wakeup length */ ++#define WL_P0_MASK 0x7f /* pattern 0 */ ++#define WL_D0 ((uint32)1 << 7) ++#define WL_P1_MASK 0x7f00 /* pattern 1 */ ++#define WL_P1_SHIFT 8 ++#define WL_D1 ((uint32)1 << 15) ++#define WL_P2_MASK 0x7f0000 /* pattern 2 */ ++#define WL_P2_SHIFT 16 ++#define WL_D2 ((uint32)1 << 23) ++#define WL_P3_MASK 0x7f000000 /* pattern 3 */ ++#define WL_P3_SHIFT 24 ++#define WL_D3 ((uint32)1 << 31) ++ ++/* intstatus and intmask */ ++#define I_PME ((uint32)1 << 6) /* power management event */ ++#define I_TO ((uint32)1 << 7) /* general purpose timeout */ ++#define I_PC ((uint32)1 << 10) /* descriptor error */ ++#define I_PD ((uint32)1 << 11) /* data error */ ++#define I_DE ((uint32)1 << 12) /* descriptor protocol error */ ++#define I_RU ((uint32)1 << 13) /* receive descriptor underflow */ ++#define I_RO ((uint32)1 << 14) /* receive fifo overflow */ ++#define I_XU ((uint32)1 << 15) /* transmit fifo underflow */ ++#define I_RI ((uint32)1 << 16) /* receive interrupt */ ++#define I_XI ((uint32)1 << 24) /* transmit interrupt */ ++#define I_EM ((uint32)1 << 26) /* emac interrupt */ ++#define I_MW ((uint32)1 << 27) /* mii write */ ++#define I_MR ((uint32)1 << 28) /* mii read */ ++ ++/* emaccontrol */ ++#define EMC_CG ((uint32)1 << 0) /* crc32 generation enable */ ++#define EMC_EP ((uint32)1 << 2) /* onchip ephy: powerdown (rev >= 1) */ ++#define EMC_ED ((uint32)1 << 3) /* onchip ephy: energy detected (rev >= 1) */ ++#define EMC_LC_MASK 0xe0 /* onchip ephy: led control (rev >= 1) */ ++#define EMC_LC_SHIFT 5 ++ ++/* emacflowcontrol */ ++#define EMF_RFH_MASK 0xff /* rx fifo hi water mark */ ++#define EMF_PG ((uint32)1 << 15) /* enable pause frame generation */ ++ ++/* interrupt receive lazy */ ++#define IRL_TO_MASK 0x00ffffff /* timeout */ ++#define IRL_FC_MASK 0xff000000 /* frame count */ ++#define IRL_FC_SHIFT 24 /* frame count */ ++ ++/* emac receive config */ ++#define ERC_DB ((uint32)1 << 0) /* disable broadcast */ ++#define ERC_AM ((uint32)1 << 1) /* accept all multicast */ ++#define ERC_RDT ((uint32)1 << 2) /* receive disable while transmitting */ ++#define ERC_PE ((uint32)1 << 3) /* promiscuous enable */ ++#define ERC_LE ((uint32)1 << 4) /* loopback enable */ ++#define ERC_FE ((uint32)1 << 5) /* enable flow control */ ++#define ERC_UF ((uint32)1 << 6) /* accept unicast flow control frame */ ++#define ERC_RF ((uint32)1 << 7) /* reject filter */ ++#define ERC_CA ((uint32)1 << 8) /* cam absent */ ++ ++/* emac mdio control */ ++#define MC_MF_MASK 0x7f /* mdc frequency */ ++#define MC_PE ((uint32)1 << 7) /* mii preamble enable */ ++ ++/* emac mdio data */ ++#define MD_DATA_MASK 0xffff /* r/w data */ ++#define MD_TA_MASK 0x30000 /* turnaround value */ ++#define MD_TA_SHIFT 16 ++#define MD_TA_VALID (2 << MD_TA_SHIFT) /* valid ta */ ++#define MD_RA_MASK 0x7c0000 /* register address */ ++#define MD_RA_SHIFT 18 ++#define MD_PMD_MASK 0xf800000 /* physical media device */ ++#define MD_PMD_SHIFT 23 ++#define MD_OP_MASK 0x30000000 /* opcode */ ++#define MD_OP_SHIFT 28 ++#define MD_OP_WRITE (1 << MD_OP_SHIFT) /* write op */ ++#define MD_OP_READ (2 << MD_OP_SHIFT) /* read op */ ++#define MD_SB_MASK 0xc0000000 /* start bits */ ++#define MD_SB_SHIFT 30 ++#define MD_SB_START (0x1 << MD_SB_SHIFT) /* start of frame */ ++ ++/* emac intstatus and intmask */ ++#define EI_MII ((uint32)1 << 0) /* mii mdio interrupt */ ++#define EI_MIB ((uint32)1 << 1) /* mib interrupt */ ++#define EI_FLOW ((uint32)1 << 2) /* flow control interrupt */ ++ ++/* emac cam data high */ ++#define CD_V ((uint32)1 << 16) /* valid bit */ ++ ++/* emac cam control */ ++#define CC_CE ((uint32)1 << 0) /* cam enable */ ++#define CC_MS ((uint32)1 << 1) /* mask select */ ++#define CC_RD ((uint32)1 << 2) /* read */ ++#define CC_WR ((uint32)1 << 3) /* write */ ++#define CC_INDEX_MASK 0x3f0000 /* index */ ++#define CC_INDEX_SHIFT 16 ++#define CC_CB ((uint32)1 << 31) /* cam busy */ ++ ++/* emac ethernet control */ ++#define EC_EE ((uint32)1 << 0) /* emac enable */ ++#define EC_ED ((uint32)1 << 1) /* emac disable */ ++#define EC_ES ((uint32)1 << 2) /* emac soft reset */ ++#define EC_EP ((uint32)1 << 3) /* external phy select */ ++ ++/* emac transmit control */ ++#define EXC_FD ((uint32)1 << 0) /* full duplex */ ++#define EXC_FM ((uint32)1 << 1) /* flowmode */ ++#define EXC_SB ((uint32)1 << 2) /* single backoff enable */ ++#define EXC_SS ((uint32)1 << 3) /* small slottime */ ++ ++/* emac mib control */ ++#define EMC_RZ ((uint32)1 << 0) /* autoclear on read */ ++ ++#endif /* _bcmenet_47xx_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenetmib.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetmib.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmenetmib.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetmib.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,81 @@ ++/* ++ * Hardware-specific MIB definition for ++ * Broadcom Home Networking Division ++ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _bcmenetmib_h_ ++#define _bcmenetmib_h_ ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* ++ * EMAC MIB Registers ++ */ ++typedef volatile struct { ++ uint32 tx_good_octets; ++ uint32 tx_good_pkts; ++ uint32 tx_octets; ++ uint32 tx_pkts; ++ uint32 tx_broadcast_pkts; ++ uint32 tx_multicast_pkts; ++ uint32 tx_len_64; ++ uint32 tx_len_65_to_127; ++ uint32 tx_len_128_to_255; ++ uint32 tx_len_256_to_511; ++ uint32 tx_len_512_to_1023; ++ uint32 tx_len_1024_to_max; ++ uint32 tx_jabber_pkts; ++ uint32 tx_oversize_pkts; ++ uint32 tx_fragment_pkts; ++ uint32 tx_underruns; ++ uint32 tx_total_cols; ++ uint32 tx_single_cols; ++ uint32 tx_multiple_cols; ++ uint32 tx_excessive_cols; ++ uint32 tx_late_cols; ++ uint32 tx_defered; ++ uint32 tx_carrier_lost; ++ uint32 tx_pause_pkts; ++ uint32 PAD[8]; ++ ++ uint32 rx_good_octets; ++ uint32 rx_good_pkts; ++ uint32 rx_octets; ++ uint32 rx_pkts; ++ uint32 rx_broadcast_pkts; ++ uint32 rx_multicast_pkts; ++ uint32 rx_len_64; ++ uint32 rx_len_65_to_127; ++ uint32 rx_len_128_to_255; ++ uint32 rx_len_256_to_511; ++ uint32 rx_len_512_to_1023; ++ uint32 rx_len_1024_to_max; ++ uint32 rx_jabber_pkts; ++ uint32 rx_oversize_pkts; ++ uint32 rx_fragment_pkts; ++ uint32 rx_missed_pkts; ++ uint32 rx_crc_align_errs; ++ uint32 rx_undersize; ++ uint32 rx_crc_errs; ++ uint32 rx_align_errs; ++ uint32 rx_symbol_errs; ++ uint32 rx_pause_pkts; ++ uint32 rx_nonpause_pkts; ++} bcmenetmib_t; ++ ++#endif /* _bcmenetmib_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenetphy.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetphy.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmenetphy.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetphy.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,58 @@ ++/* ++ * Misc Broadcom BCM47XX MDC/MDIO enet phy definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _bcmenetphy_h_ ++#define _bcmenetphy_h_ ++ ++/* phy address */ ++#define MAXEPHY 32 /* mdio phy addresses are 5bit quantities */ ++#define EPHY_MASK 0x1f ++#define EPHY_NONE 31 /* nvram: no phy present at all */ ++#define EPHY_NOREG 30 /* nvram: no local phy regs */ ++ ++/* just a few phy registers */ ++#define CTL_RESET (1 << 15) /* reset */ ++#define CTL_LOOP (1 << 14) /* loopback */ ++#define CTL_SPEED (1 << 13) /* speed selection 0=10, 1=100 */ ++#define CTL_ANENAB (1 << 12) /* autonegotiation enable */ ++#define CTL_RESTART (1 << 9) /* restart autonegotiation */ ++#define CTL_DUPLEX (1 << 8) /* duplex mode 0=half, 1=full */ ++ ++#define ADV_10FULL (1 << 6) /* autonegotiate advertise 10full */ ++#define ADV_10HALF (1 << 5) /* autonegotiate advertise 10half */ ++#define ADV_100FULL (1 << 8) /* autonegotiate advertise 100full */ ++#define ADV_100HALF (1 << 7) /* autonegotiate advertise 100half */ ++ ++/* link partner ability register */ ++#define LPA_SLCT 0x001f /* same as advertise selector */ ++#define LPA_10HALF 0x0020 /* can do 10mbps half-duplex */ ++#define LPA_10FULL 0x0040 /* can do 10mbps full-duplex */ ++#define LPA_100HALF 0x0080 /* can do 100mbps half-duplex */ ++#define LPA_100FULL 0x0100 /* can do 100mbps full-duplex */ ++#define LPA_100BASE4 0x0200 /* can do 100mbps 4k packets */ ++#define LPA_RESV 0x1c00 /* unused */ ++#define LPA_RFAULT 0x2000 /* link partner faulted */ ++#define LPA_LPACK 0x4000 /* link partner acked us */ ++#define LPA_NPAGE 0x8000 /* next page bit */ ++ ++#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) ++#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) ++ ++#define STAT_REMFAULT (1 << 4) /* remote fault */ ++#define STAT_LINK (1 << 2) /* link status */ ++#define STAT_JAB (1 << 1) /* jabber detected */ ++#define AUX_FORCED (1 << 2) /* forced 10/100 */ ++#define AUX_SPEED (1 << 1) /* speed 0=10mbps 1=100mbps */ ++#define AUX_DUPLEX (1 << 0) /* duplex 0=half 1=full */ ++ ++#endif /* _bcmenetphy_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenetrxh.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmenetrxh.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,43 @@ ++/* ++ * Hardware-specific Receive Data Header for the ++ * Broadcom Home Networking Division ++ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _bcmenetrxh_h_ ++#define _bcmenetrxh_h_ ++ ++/* ++ * The Ethernet MAC core returns an 8-byte Receive Frame Data Header ++ * with every frame consisting of ++ * 16bits of frame length, followed by ++ * 16bits of EMAC rx descriptor info, followed by 32bits of undefined. ++ */ ++typedef volatile struct { ++ uint16 len; ++ uint16 flags; ++ uint16 pad[12]; ++} bcmenetrxh_t; ++ ++#define RXHDR_LEN 28 ++ ++#define RXF_L ((uint16)1 << 11) /* last buffer in a frame */ ++#define RXF_MISS ((uint16)1 << 7) /* received due to promisc mode */ ++#define RXF_BRDCAST ((uint16)1 << 6) /* dest is broadcast address */ ++#define RXF_MULT ((uint16)1 << 5) /* dest is multicast address */ ++#define RXF_LG ((uint16)1 << 4) /* frame length > rxmaxlength */ ++#define RXF_NO ((uint16)1 << 3) /* odd number of nibbles */ ++#define RXF_RXER ((uint16)1 << 2) /* receive symbol error */ ++#define RXF_CRC ((uint16)1 << 1) /* crc error */ ++#define RXF_OV ((uint16)1 << 0) /* fifo overflow */ ++ ++#endif /* _bcmenetrxh_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,141 @@ ++/* ++ * NVRAM variable manipulation ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _bcmnvram_h_ ++#define _bcmnvram_h_ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++#include ++ ++struct nvram_header { ++ uint32 magic; ++ uint32 len; ++ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ ++ uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ ++ uint32 config_ncdl; /* ncdl values for memc */ ++}; ++ ++struct nvram_tuple { ++ char *name; ++ char *value; ++ struct nvram_tuple *next; ++}; ++ ++/* ++ * Initialize NVRAM access. May be unnecessary or undefined on certain ++ * platforms. ++ */ ++extern int BCMINIT(nvram_init)(void *sbh); ++ ++/* ++ * Disable NVRAM access. May be unnecessary or undefined on certain ++ * platforms. ++ */ ++extern void BCMINIT(nvram_exit)(void *sbh); ++ ++/* ++ * Get the value of an NVRAM variable. The pointer returned may be ++ * invalid after a set. ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined ++ */ ++extern char * BCMINIT(nvram_get)(const char *name); ++ ++/* ++ * Read the reset GPIO value from the nvram and set the GPIO ++ * as input ++ */ ++extern int BCMINITFN(nvram_resetgpio_init)(void *sbh); ++ ++/* ++ * Get the value of an NVRAM variable. ++ * @param name name of variable to get ++ * @return value of variable or NUL if undefined ++ */ ++#define nvram_safe_get(name) (BCMINIT(nvram_get)(name) ? : "") ++ ++/* ++ * Match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is string equal ++ * to match or FALSE otherwise ++ */ ++static INLINE int ++nvram_match(char *name, char *match) { ++ const char *value = BCMINIT(nvram_get)(name); ++ return (value && !strcmp(value, match)); ++} ++ ++/* ++ * Inversely match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is not string ++ * equal to invmatch or FALSE otherwise ++ */ ++static INLINE int ++nvram_invmatch(char *name, char *invmatch) { ++ const char *value = BCMINIT(nvram_get)(name); ++ return (value && strcmp(value, invmatch)); ++} ++ ++/* ++ * Set the value of an NVRAM variable. The name and value strings are ++ * copied into private storage. Pointers to previously set values ++ * may become invalid. The new value may be immediately ++ * retrieved but will not be permanently stored until a commit. ++ * @param name name of variable to set ++ * @param value value of variable ++ * @return 0 on success and errno on failure ++ */ ++extern int BCMINIT(nvram_set)(const char *name, const char *value); ++ ++/* ++ * Unset an NVRAM variable. Pointers to previously set values ++ * remain valid until a set. ++ * @param name name of variable to unset ++ * @return 0 on success and errno on failure ++ * NOTE: use nvram_commit to commit this change to flash. ++ */ ++extern int BCMINIT(nvram_unset)(const char *name); ++ ++/* ++ * Commit NVRAM variables to permanent storage. All pointers to values ++ * may be invalid after a commit. ++ * NVRAM values are undefined after a commit. ++ * @return 0 on success and errno on failure ++ */ ++extern int BCMINIT(nvram_commit)(void); ++ ++/* ++ * Get all NVRAM variables (format name=value\0 ... \0\0). ++ * @param buf buffer to store variables ++ * @param count size of buffer in bytes ++ * @return 0 on success and errno on failure ++ */ ++extern int BCMINIT(nvram_getall)(char *buf, int count); ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ ++#define NVRAM_VERSION 1 ++#define NVRAM_HEADER_SIZE 20 ++#define NVRAM_SPACE 0x8000 ++ ++#define NVRAM_MAX_VALUE_LEN 255 ++#define NVRAM_MAX_PARAM_LEN 64 ++ ++#endif /* _bcmnvram_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmparams.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmparams.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmparams.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmparams.h 2005-12-16 23:39:10.700821500 +0100 +@@ -0,0 +1,25 @@ ++/* ++ * Misc system wide parameters. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _bcmparams_h_ ++#define _bcmparams_h_ ++ ++#define VLAN_MAXVID 15 /* Max. VLAN ID supported/allowed */ ++ ++#define VLAN_NUMPRIS 8 /* # of prio, start from 0 */ ++ ++#define DEV_NUMIFS 16 /* Max. # of devices/interfaces supported */ ++ ++#define WL_MAXBSSCFG 16 /* maximum number of BSS Configs we can configure */ ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,23 @@ ++/* ++ * Misc useful routines to access NIC local SROM/OTP . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _bcmsrom_h_ ++#define _bcmsrom_h_ ++ ++extern int srom_var_init(void *sbh, uint bus, void *curmap, osl_t *osh, char **vars, int *count); ++ ++extern int srom_read(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); ++extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); ++ ++#endif /* _bcmsrom_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,313 @@ ++/* ++ * Misc useful os-independent macros and functions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _bcmutils_h_ ++#define _bcmutils_h_ ++ ++/*** driver-only section ***/ ++#ifdef BCMDRIVER ++#include ++ ++#define _BCM_U 0x01 /* upper */ ++#define _BCM_L 0x02 /* lower */ ++#define _BCM_D 0x04 /* digit */ ++#define _BCM_C 0x08 /* cntrl */ ++#define _BCM_P 0x10 /* punct */ ++#define _BCM_S 0x20 /* white space (space/lf/tab) */ ++#define _BCM_X 0x40 /* hex digit */ ++#define _BCM_SP 0x80 /* hard space (0x20) */ ++ ++#define GPIO_PIN_NOTDEFINED 0x20 ++ ++extern unsigned char bcm_ctype[]; ++#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) ++ ++#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) ++#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) ++#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) ++#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) ++#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) ++#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) ++#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) ++#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) ++#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) ++ ++/* ++ * Spin at most 'us' microseconds while 'exp' is true. ++ * Caller should explicitly test 'exp' when this completes ++ * and take appropriate error action if 'exp' is still true. ++ */ ++#define SPINWAIT(exp, us) { \ ++ uint countdown = (us) + 9; \ ++ while ((exp) && (countdown >= 10)) {\ ++ OSL_DELAY(10); \ ++ countdown -= 10; \ ++ } \ ++} ++ ++/* generic osl packet queue */ ++struct pktq { ++ void *head; /* first packet to dequeue */ ++ void *tail; /* last packet to dequeue */ ++ uint len; /* number of queued packets */ ++ uint maxlen; /* maximum number of queued packets */ ++ bool priority; /* enqueue by packet priority */ ++ uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */ ++}; ++#define DEFAULT_QLEN 128 ++ ++#define pktq_len(q) ((q)->len) ++#define pktq_avail(q) ((q)->maxlen - (q)->len) ++#define pktq_head(q) ((q)->head) ++#define pktq_full(q) ((q)->len >= (q)->maxlen) ++#define _pktq_pri(q, pri) ((q)->prio_map[pri]) ++#define pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0)) ++ ++/* externs */ ++/* packet */ ++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); ++extern uint pkttotlen(osl_t *osh, void *); ++extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]); ++extern void pktenq(struct pktq *q, void *p, bool lifo); ++extern void *pktdeq(struct pktq *q); ++extern void *pktdeqtail(struct pktq *q); ++/* string */ ++extern uint bcm_atoi(char *s); ++extern uchar bcm_toupper(uchar c); ++extern ulong bcm_strtoul(char *cp, char **endp, uint base); ++extern char *bcmstrstr(char *haystack, char *needle); ++extern char *bcmstrcat(char *dest, const char *src); ++extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); ++/* ethernet address */ ++extern char *bcm_ether_ntoa(char *ea, char *buf); ++extern int bcm_ether_atoe(char *p, char *ea); ++/* delay */ ++extern void bcm_mdelay(uint ms); ++/* variable access */ ++extern char *getvar(char *vars, char *name); ++extern int getintvar(char *vars, char *name); ++extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); ++#define bcmlog(fmt, a1, a2) ++#define bcmdumplog(buf, size) *buf = '\0' ++#define bcmdumplogent(buf, idx) -1 ++ ++#endif /* #ifdef BCMDRIVER */ ++ ++/*** driver/apps-shared section ***/ ++ ++#define BCME_STRLEN 64 ++#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) ++ ++ ++/* ++ * error codes could be added but the defined ones shouldn't be changed/deleted ++ * these error codes are exposed to the user code ++ * when ever a new error code is added to this list ++ * please update errorstring table with the related error string and ++ * update osl files with os specific errorcode map ++*/ ++ ++#define BCME_ERROR -1 /* Error generic */ ++#define BCME_BADARG -2 /* Bad Argument */ ++#define BCME_BADOPTION -3 /* Bad option */ ++#define BCME_NOTUP -4 /* Not up */ ++#define BCME_NOTDOWN -5 /* Not down */ ++#define BCME_NOTAP -6 /* Not AP */ ++#define BCME_NOTSTA -7 /* Not STA */ ++#define BCME_BADKEYIDX -8 /* BAD Key Index */ ++#define BCME_RADIOOFF -9 /* Radio Off */ ++#define BCME_NOTBANDLOCKED -10 /* Not bandlocked */ ++#define BCME_NOCLK -11 /* No Clock*/ ++#define BCME_BADRATESET -12 /* BAD RateSet*/ ++#define BCME_BADBAND -13 /* BAD Band */ ++#define BCME_BUFTOOSHORT -14 /* Buffer too short */ ++#define BCME_BUFTOOLONG -15 /* Buffer too Long */ ++#define BCME_BUSY -16 /* Busy*/ ++#define BCME_NOTASSOCIATED -17 /* Not associated*/ ++#define BCME_BADSSIDLEN -18 /* BAD SSID Len */ ++#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel*/ ++#define BCME_BADCHAN -20 /* BAD Channel */ ++#define BCME_BADADDR -21 /* BAD Address*/ ++#define BCME_NORESOURCE -22 /* No resources*/ ++#define BCME_UNSUPPORTED -23 /* Unsupported*/ ++#define BCME_BADLEN -24 /* Bad Length*/ ++#define BCME_NOTREADY -25 /* Not ready Yet*/ ++#define BCME_EPERM -26 /* Not Permitted */ ++#define BCME_NOMEM -27 /* No Memory */ ++#define BCME_ASSOCIATED -28 /* Associated */ ++#define BCME_RANGE -29 /* Range Error*/ ++#define BCME_NOTFOUND -30 /* Not found */ ++#define BCME_LAST BCME_NOTFOUND ++ ++#ifndef ABS ++#define ABS(a) (((a)<0)?-(a):(a)) ++#endif ++ ++#ifndef MIN ++#define MIN(a, b) (((a)<(b))?(a):(b)) ++#endif ++ ++#ifndef MAX ++#define MAX(a, b) (((a)>(b))?(a):(b)) ++#endif ++ ++#define CEIL(x, y) (((x) + ((y)-1)) / (y)) ++#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) ++#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) ++#define ISPOWEROF2(x) ((((x)-1)&(x))==0) ++#define VALID_MASK(mask) !((mask) & ((mask) + 1)) ++#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) ++#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) ++ ++/* bit map related macros */ ++#ifndef setbit ++#define NBBY 8 /* 8 bits per byte */ ++#define setbit(a,i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) ++#define clrbit(a,i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) ++#define isset(a,i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) ++#define isclr(a,i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) ++#endif ++ ++#define NBITS(type) (sizeof(type) * 8) ++#define NBITVAL(bits) (1 << (bits)) ++#define MAXBITVAL(bits) ((1 << (bits)) - 1) ++ ++/* crc defines */ ++#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ ++#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ ++#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ ++#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ ++#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ ++#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ ++ ++/* bcm_format_flags() bit description structure */ ++typedef struct bcm_bit_desc { ++ uint32 bit; ++ char* name; ++} bcm_bit_desc_t; ++ ++/* tag_ID/length/value_buffer tuple */ ++typedef struct bcm_tlv { ++ uint8 id; ++ uint8 len; ++ uint8 data[1]; ++} bcm_tlv_t; ++ ++/* Check that bcm_tlv_t fits into the given buflen */ ++#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) ++ ++/* buffer length for ethernet address from bcm_ether_ntoa() */ ++#define ETHER_ADDR_STR_LEN 18 ++ ++/* unaligned load and store macros */ ++#ifdef IL_BIGENDIAN ++static INLINE uint32 ++load32_ua(uint8 *a) ++{ ++ return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); ++} ++ ++static INLINE void ++store32_ua(uint8 *a, uint32 v) ++{ ++ a[0] = (v >> 24) & 0xff; ++ a[1] = (v >> 16) & 0xff; ++ a[2] = (v >> 8) & 0xff; ++ a[3] = v & 0xff; ++} ++ ++static INLINE uint16 ++load16_ua(uint8 *a) ++{ ++ return ((a[0] << 8) | a[1]); ++} ++ ++static INLINE void ++store16_ua(uint8 *a, uint16 v) ++{ ++ a[0] = (v >> 8) & 0xff; ++ a[1] = v & 0xff; ++} ++ ++#else ++ ++static INLINE uint32 ++load32_ua(uint8 *a) ++{ ++ return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]); ++} ++ ++static INLINE void ++store32_ua(uint8 *a, uint32 v) ++{ ++ a[3] = (v >> 24) & 0xff; ++ a[2] = (v >> 16) & 0xff; ++ a[1] = (v >> 8) & 0xff; ++ a[0] = v & 0xff; ++} ++ ++static INLINE uint16 ++load16_ua(uint8 *a) ++{ ++ return ((a[1] << 8) | a[0]); ++} ++ ++static INLINE void ++store16_ua(uint8 *a, uint16 v) ++{ ++ a[1] = (v >> 8) & 0xff; ++ a[0] = v & 0xff; ++} ++ ++#endif ++ ++/* externs */ ++/* crc */ ++extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); ++extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); ++extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); ++/* format/print */ ++/* IE parsing */ ++extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); ++extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); ++extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); ++ ++/* bcmerror*/ ++extern const char *bcmerrorstr(int bcmerror); ++ ++/* multi-bool data type: set of bools, mbool is true if any is set */ ++typedef uint32 mbool; ++#define mboolset(mb, bit) (mb |= bit) /* set one bool */ ++#define mboolclr(mb, bit) (mb &= ~bit) /* clear one bool */ ++#define mboolisset(mb, bit) ((mb & bit) != 0) /* TRUE if one bool is set */ ++#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) ++ ++/* power conversion */ ++extern uint16 bcm_qdbm_to_mw(uint8 qdbm); ++extern uint8 bcm_mw_to_qdbm(uint16 mw); ++ ++/* generic datastruct to help dump routines */ ++struct fielddesc { ++ char *nameandfmt; ++ uint32 offset; ++ uint32 len; ++}; ++ ++typedef uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset); ++extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str, char *buf, uint32 bufsize); ++ ++extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); ++ ++#endif /* _bcmutils_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bitfuncs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bitfuncs.h +--- linux-2.4.32/arch/mips/bcm947xx/include/bitfuncs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bitfuncs.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,85 @@ ++/* ++ * bit manipulation utility functions ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _BITFUNCS_H ++#define _BITFUNCS_H ++ ++#include ++ ++/* local prototypes */ ++static INLINE uint32 find_msbit(uint32 x); ++ ++ ++/* ++ * find_msbit: returns index of most significant set bit in x, with index ++ * range defined as 0-31. NOTE: returns zero if input is zero. ++ */ ++ ++#if defined(USE_PENTIUM_BSR) && defined(__GNUC__) ++ ++/* ++ * Implementation for Pentium processors and gcc. Note that this ++ * instruction is actually very slow on some processors (e.g., family 5, ++ * model 2, stepping 12, "Pentium 75 - 200"), so we use the generic ++ * implementation instead. ++ */ ++static INLINE uint32 find_msbit(uint32 x) ++{ ++ uint msbit; ++ __asm__("bsrl %1,%0" ++ :"=r" (msbit) ++ :"r" (x)); ++ return msbit; ++} ++ ++#else ++ ++/* ++ * Generic Implementation ++ */ ++ ++#define DB_POW_MASK16 0xffff0000 ++#define DB_POW_MASK8 0x0000ff00 ++#define DB_POW_MASK4 0x000000f0 ++#define DB_POW_MASK2 0x0000000c ++#define DB_POW_MASK1 0x00000002 ++ ++static INLINE uint32 find_msbit(uint32 x) ++{ ++ uint32 temp_x = x; ++ uint msbit = 0; ++ if (temp_x & DB_POW_MASK16) { ++ temp_x >>= 16; ++ msbit = 16; ++ } ++ if (temp_x & DB_POW_MASK8) { ++ temp_x >>= 8; ++ msbit += 8; ++ } ++ if (temp_x & DB_POW_MASK4) { ++ temp_x >>= 4; ++ msbit += 4; ++ } ++ if (temp_x & DB_POW_MASK2) { ++ temp_x >>= 2; ++ msbit += 2; ++ } ++ if (temp_x & DB_POW_MASK1) { ++ msbit += 1; ++ } ++ return(msbit); ++} ++ ++#endif ++ ++#endif /* _BITFUNCS_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/cfe_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/cfe_osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/cfe_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/cfe_osl.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,191 @@ ++/* ++ * CFE boot loader OS Abstraction Layer. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _cfe_osl_h_ ++#define _cfe_osl_h_ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++/* dump string */ ++extern int (*xprinthook)(const char *str); ++#define puts(str) do { if (xprinthook) xprinthook(str); } while (0) ++ ++/* assert and panic */ ++#define ASSERT(exp) do {} while (0) ++ ++/* PCMCIA attribute space access macros */ ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ ++ bzero(buf, size) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ ++ do {} while (0) ++ ++/* PCI configuration space access macros */ ++#define OSL_PCI_READ_CONFIG(loc, offset, size) \ ++ (offset == 8 ? 0 : 0xffffffff) ++#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) \ ++ do {} while (0) ++ ++/* PCI device bus # and slot # */ ++#define OSL_PCI_BUS(osh) (0) ++#define OSL_PCI_SLOT(osh) (0) ++ ++/* register access macros */ ++#define wreg32(r, v) (*(volatile uint32*)(r) = (uint32)(v)) ++#define rreg32(r) (*(volatile uint32*)(r)) ++#ifdef IL_BIGENDIAN ++#define wreg16(r, v) (*(volatile uint16*)((ulong)(r)^2) = (uint16)(v)) ++#define rreg16(r) (*(volatile uint16*)((ulong)(r)^2)) ++#define wreg8(r, v) (*(volatile uint8*)((ulong)(r)^3) = (uint8)(v)) ++#define rreg8(r) (*(volatile uint8*)((ulong)(r)^3)) ++#else ++#define wreg16(r, v) (*(volatile uint16*)(r) = (uint16)(v)) ++#define rreg16(r) (*(volatile uint16*)(r)) ++#define wreg8(r, v) (*(volatile uint8*)(r) = (uint8)(v)) ++#define rreg8(r) (*(volatile uint8*)(r)) ++#endif ++#define R_REG(r) ({ \ ++ __typeof(*(r)) __osl_v; \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = rreg8((r)); break; \ ++ case sizeof(uint16): __osl_v = rreg16((r)); break; \ ++ case sizeof(uint32): __osl_v = rreg32((r)); break; \ ++ } \ ++ __osl_v; \ ++}) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): wreg8((r), (v)); break; \ ++ case sizeof(uint16): wreg16((r), (v)); break; \ ++ case sizeof(uint32): wreg32((r), (v)); break; \ ++ } \ ++} while (0) ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++ ++/* bcopy, bcmp, and bzero */ ++#define bcmp(b1, b2, len) lib_memcmp((b1), (b2), (len)) ++ ++#define osl_attach(pdev) ((osl_t*)pdev) ++#define osl_detach(osh) ++ ++/* general purpose memory allocation */ ++#define MALLOC(osh, size) KMALLOC((size),0) ++#define MFREE(osh, addr, size) KFREE((addr)) ++#define MALLOCED(osh) (0) ++#define MALLOC_DUMP(osh, buf, sz) ++#define MALLOC_FAILED(osh) (0) ++ ++/* uncached virtual address */ ++#define OSL_UNCACHED(va) ((void*)UNCADDR((ulong)(va))) ++ ++/* host/bus architecture-specific address byte swap */ ++#define BUS_SWAP32(v) (v) ++ ++/* get processor cycle count */ ++#define OSL_GETCYCLES(x) ((x) = 0) ++ ++/* microsecond delay */ ++#define OSL_DELAY(usec) cfe_usleep((cfe_cpu_speed/CPUCFG_CYCLESPERCPUTICK/1000000*(usec))) ++ ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++ ++/* map/unmap physical to virtual I/O */ ++#define REG_MAP(pa, size) ((void*)UNCADDR((ulong)(pa))) ++#define REG_UNMAP(va) do {} while (0) ++ ++/* dereference an address that may cause a bus exception */ ++#define BUSPROBE(val, addr) osl_busprobe(&(val), (uint32)(addr)) ++extern int osl_busprobe(uint32 *val, uint32 addr); ++ ++/* allocate/free shared (dma-able) consistent (uncached) memory */ ++#define DMA_CONSISTENT_ALIGN 4096 ++#define DMA_ALLOC_CONSISTENT(osh, size, pap) \ ++ osl_dma_alloc_consistent((size), (pap)) ++#define DMA_FREE_CONSISTENT(osh, va, size, pa) \ ++ osl_dma_free_consistent((void*)(va)) ++extern void *osl_dma_alloc_consistent(uint size, ulong *pap); ++extern void osl_dma_free_consistent(void *va); ++ ++/* map/unmap direction */ ++#define DMA_TX 1 ++#define DMA_RX 2 ++ ++/* map/unmap shared (dma-able) memory */ ++#define DMA_MAP(osh, va, size, direction, lb) ({ \ ++ cfe_flushcache(CFE_CACHE_FLUSH_D); \ ++ PHYSADDR((ulong)(va)); \ ++}) ++#define DMA_UNMAP(osh, pa, size, direction, p) \ ++ do {} while (0) ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) lib_memset((r), '\0', (len)) ++ ++/* generic packet structure */ ++#define LBUFSZ 4096 ++#define LBDATASZ (LBUFSZ - sizeof(struct lbuf)) ++struct lbuf { ++ struct lbuf *next; /* pointer to next lbuf if in a chain */ ++ struct lbuf *link; /* pointer to next lbuf if in a list */ ++ uchar *head; /* start of buffer */ ++ uchar *end; /* end of buffer */ ++ uchar *data; /* start of data */ ++ uchar *tail; /* end of data */ ++ uint len; /* nbytes of data */ ++ void *cookie; /* generic cookie */ ++}; ++ ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) ((void*)osl_pktget((len))) ++#define PKTFREE(osh, lb, send) osl_pktfree((struct lbuf*)(lb)) ++#define PKTDATA(osh, lb) (((struct lbuf*)(lb))->data) ++#define PKTLEN(osh, lb) (((struct lbuf*)(lb))->len) ++#define PKTHEADROOM(osh, lb) (PKTDATA(osh,lb)-(((struct lbuf*)(lb))->head)) ++#define PKTTAILROOM(osh, lb) ((((struct lbuf*)(lb))->end)-(((struct lbuf*)(lb))->tail)) ++#define PKTNEXT(osh, lb) (((struct lbuf*)(lb))->next) ++#define PKTSETNEXT(lb, x) (((struct lbuf*)(lb))->next = (struct lbuf*)(x)) ++#define PKTSETLEN(osh, lb, len) osl_pktsetlen((struct lbuf*)(lb), (len)) ++#define PKTPUSH(osh, lb, bytes) osl_pktpush((struct lbuf*)(lb), (bytes)) ++#define PKTPULL(osh, lb, bytes) osl_pktpull((struct lbuf*)(lb), (bytes)) ++#define PKTDUP(osh, lb) osl_pktdup((struct lbuf*)(lb)) ++#define PKTCOOKIE(lb) (((struct lbuf*)(lb))->cookie) ++#define PKTSETCOOKIE(lb, x) (((struct lbuf*)(lb))->cookie = (void*)(x)) ++#define PKTLINK(lb) (((struct lbuf*)(lb))->link) ++#define PKTSETLINK(lb, x) (((struct lbuf*)(lb))->link = (struct lbuf*)(x)) ++#define PKTPRIO(lb) (0) ++#define PKTSETPRIO(lb, x) do {} while (0) ++extern struct lbuf *osl_pktget(uint len); ++extern void osl_pktfree(struct lbuf *lb); ++extern void osl_pktsetlen(struct lbuf *lb, uint len); ++extern uchar *osl_pktpush(struct lbuf *lb, uint bytes); ++extern uchar *osl_pktpull(struct lbuf *lb, uint bytes); ++extern struct lbuf *osl_pktdup(struct lbuf *lb); ++extern int osl_error(int bcmerror); ++ ++#endif /* _cfe_osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/epivers.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h +--- linux-2.4.32/arch/mips/bcm947xx/include/epivers.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,69 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ * ++*/ ++ ++#ifndef _epivers_h_ ++#define _epivers_h_ ++ ++#ifdef linux ++#include ++#endif ++ ++/* Vendor Name, ASCII, 32 chars max */ ++#ifdef COMPANYNAME ++#define HPNA_VENDOR COMPANYNAME ++#else ++#define HPNA_VENDOR "Broadcom Corporation" ++#endif ++ ++/* Driver Date, ASCII, 32 chars max */ ++#define HPNA_DRV_BUILD_DATE __DATE__ ++ ++/* Hardware Manufacture Date, ASCII, 32 chars max */ ++#define HPNA_HW_MFG_DATE "Not Specified" ++ ++/* See documentation for Device Type values, 32 values max */ ++#ifndef HPNA_DEV_TYPE ++ ++#if defined(CONFIG_BRCM_VJ) ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_DISPLAY } ++ ++#elif defined(CONFIG_BCRM_93725) ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY } ++ ++#else ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_PCINIC } ++ ++#endif ++ ++#endif /* !HPNA_DEV_TYPE */ ++ ++ ++#define EPI_MAJOR_VERSION 3 ++ ++#define EPI_MINOR_VERSION 130 ++ ++#define EPI_RC_NUMBER 20 ++ ++#define EPI_INCREMENTAL_NUMBER 0 ++ ++#define EPI_BUILD_NUMBER 0 ++ ++#define EPI_VERSION 3,130,20,0 ++ ++#define EPI_VERSION_NUM 0x03821400 ++ ++/* Driver Version String, ASCII, 32 chars max */ ++#define EPI_VERSION_STR "3.130.20.0" ++#define EPI_ROUTER_VERSION_STR "3.131.20.0" ++ ++#endif /* _epivers_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/epivers.h.in linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h.in +--- linux-2.4.32/arch/mips/bcm947xx/include/epivers.h.in 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h.in 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,69 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ * ++*/ ++ ++#ifndef _epivers_h_ ++#define _epivers_h_ ++ ++#ifdef linux ++#include ++#endif ++ ++/* Vendor Name, ASCII, 32 chars max */ ++#ifdef COMPANYNAME ++#define HPNA_VENDOR COMPANYNAME ++#else ++#define HPNA_VENDOR "Broadcom Corporation" ++#endif ++ ++/* Driver Date, ASCII, 32 chars max */ ++#define HPNA_DRV_BUILD_DATE __DATE__ ++ ++/* Hardware Manufacture Date, ASCII, 32 chars max */ ++#define HPNA_HW_MFG_DATE "Not Specified" ++ ++/* See documentation for Device Type values, 32 values max */ ++#ifndef HPNA_DEV_TYPE ++ ++#if defined(CONFIG_BRCM_VJ) ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_DISPLAY } ++ ++#elif defined(CONFIG_BCRM_93725) ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY } ++ ++#else ++#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_PCINIC } ++ ++#endif ++ ++#endif /* !HPNA_DEV_TYPE */ ++ ++ ++#define EPI_MAJOR_VERSION @EPI_MAJOR_VERSION@ ++ ++#define EPI_MINOR_VERSION @EPI_MINOR_VERSION@ ++ ++#define EPI_RC_NUMBER @EPI_RC_NUMBER@ ++ ++#define EPI_INCREMENTAL_NUMBER @EPI_INCREMENTAL_NUMBER@ ++ ++#define EPI_BUILD_NUMBER @EPI_BUILD_NUMBER@ ++ ++#define EPI_VERSION @EPI_VERSION@ ++ ++#define EPI_VERSION_NUM @EPI_VERSION_NUM@ ++ ++/* Driver Version String, ASCII, 32 chars max */ ++#define EPI_VERSION_STR "@EPI_VERSION_STR@" ++#define EPI_ROUTER_VERSION_STR "@EPI_ROUTER_VERSION_STR@" ++ ++#endif /* _epivers_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/etsockio.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/etsockio.h +--- linux-2.4.32/arch/mips/bcm947xx/include/etsockio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/etsockio.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,59 @@ ++/* ++ * Driver-specific socket ioctls ++ * used by BSD, Linux, and PSOS ++ * Broadcom BCM44XX 10/100Mbps Ethernet Device Driver ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _etsockio_h_ ++#define _etsockio_h_ ++ ++/* THESE MUST BE CONTIGUOUS AND CONSISTENT WITH VALUES IN ETC.H */ ++ ++ ++#if defined(linux) ++#define SIOCSETCUP (SIOCDEVPRIVATE + 0) ++#define SIOCSETCDOWN (SIOCDEVPRIVATE + 1) ++#define SIOCSETCLOOP (SIOCDEVPRIVATE + 2) ++#define SIOCGETCDUMP (SIOCDEVPRIVATE + 3) ++#define SIOCSETCSETMSGLEVEL (SIOCDEVPRIVATE + 4) ++#define SIOCSETCPROMISC (SIOCDEVPRIVATE + 5) ++#define SIOCSETCTXDOWN (SIOCDEVPRIVATE + 6) /* obsolete */ ++#define SIOCSETCSPEED (SIOCDEVPRIVATE + 7) ++#define SIOCTXGEN (SIOCDEVPRIVATE + 8) ++#define SIOCGETCPHYRD (SIOCDEVPRIVATE + 9) ++#define SIOCSETCPHYWR (SIOCDEVPRIVATE + 10) ++#define SIOCSETCQOS (SIOCDEVPRIVATE + 11) ++ ++#else /* !linux */ ++ ++#define SIOCSETCUP _IOWR('e', 130 + 0, struct ifreq) ++#define SIOCSETCDOWN _IOWR('e', 130 + 1, struct ifreq) ++#define SIOCSETCLOOP _IOWR('e', 130 + 2, struct ifreq) ++#define SIOCGETCDUMP _IOWR('e', 130 + 3, struct ifreq) ++#define SIOCSETCSETMSGLEVEL _IOWR('e', 130 + 4, struct ifreq) ++#define SIOCSETCPROMISC _IOWR('e', 130 + 5, struct ifreq) ++#define SIOCSETCTXDOWN _IOWR('e', 130 + 6, struct ifreq) /* obsolete */ ++#define SIOCSETCSPEED _IOWR('e', 130 + 7, struct ifreq) ++#define SIOCTXGEN _IOWR('e', 130 + 8, struct ifreq) ++ ++#endif ++ ++/* arg to SIOCTXGEN */ ++struct txg { ++ uint32 num; /* number of frames to send */ ++ uint32 delay; /* delay in microseconds between sending each */ ++ uint32 size; /* size of ether frame to send */ ++ uchar buf[1514]; /* starting ether frame data */ ++}; ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/flash.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/flash.h +--- linux-2.4.32/arch/mips/bcm947xx/include/flash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/flash.h 2005-12-16 23:39:10.704821750 +0100 +@@ -0,0 +1,188 @@ ++/* ++ * flash.h: Common definitions for flash access. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++/* Types of flashes we know about */ ++typedef enum _flash_type {OLD, BSC, SCS, AMD, SST, SFLASH} flash_type_t; ++ ++/* Commands to write/erase the flases */ ++typedef struct _flash_cmds{ ++ flash_type_t type; ++ bool need_unlock; ++ uint16 pre_erase; ++ uint16 erase_block; ++ uint16 erase_chip; ++ uint16 write_word; ++ uint16 write_buf; ++ uint16 clear_csr; ++ uint16 read_csr; ++ uint16 read_id; ++ uint16 confirm; ++ uint16 read_array; ++} flash_cmds_t; ++ ++#define UNLOCK_CMD_WORDS 2 ++ ++typedef struct _unlock_cmd { ++ uint addr[UNLOCK_CMD_WORDS]; ++ uint16 cmd[UNLOCK_CMD_WORDS]; ++} unlock_cmd_t; ++ ++/* Flash descriptors */ ++typedef struct _flash_desc { ++ uint16 mfgid; /* Manufacturer Id */ ++ uint16 devid; /* Device Id */ ++ uint size; /* Total size in bytes */ ++ uint width; /* Device width in bytes */ ++ flash_type_t type; /* Device type old, S, J */ ++ uint bsize; /* Block size */ ++ uint nb; /* Number of blocks */ ++ uint ff; /* First full block */ ++ uint lf; /* Last full block */ ++ uint nsub; /* Number of subblocks */ ++ uint *subblocks; /* Offsets for subblocks */ ++ char *desc; /* Description */ ++} flash_desc_t; ++ ++ ++#ifdef DECLARE_FLASHES ++flash_cmds_t sflash_cmd_t = ++ { SFLASH, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; ++ ++flash_cmds_t flash_cmds[] = { ++/* type needu preera eraseb erasech write wbuf clcsr rdcsr rdid confrm read */ ++ { BSC, 0, 0x00, 0x20, 0x00, 0x40, 0x00, 0x50, 0x70, 0x90, 0xd0, 0xff }, ++ { SCS, 0, 0x00, 0x20, 0x00, 0x40, 0xe8, 0x50, 0x70, 0x90, 0xd0, 0xff }, ++ { AMD, 1, 0x80, 0x30, 0x10, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf0 }, ++ { SST, 1, 0x80, 0x50, 0x10, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf0 }, ++ { 0 } ++}; ++ ++unlock_cmd_t unlock_cmd_amd = { ++#ifdef MIPSEB ++/* addr: */ { 0x0aa8, 0x0556}, ++#else ++/* addr: */ { 0x0aaa, 0x0554}, ++#endif ++/* data: */ { 0xaa, 0x55} ++}; ++ ++unlock_cmd_t unlock_cmd_sst = { ++#ifdef MIPSEB ++/* addr: */ { 0xaaa8, 0x5556}, ++#else ++/* addr: */ { 0xaaaa, 0x5554}, ++#endif ++/* data: */ { 0xaa, 0x55} ++}; ++ ++#define AMD_CMD 0xaaa ++#define SST_CMD 0xaaaa ++ ++/* intel unlock block cmds */ ++#define INTEL_UNLOCK1 0x60 ++#define INTEL_UNLOCK2 0xD0 ++ ++/* Just eight blocks of 8KB byte each */ ++ ++uint blk8x8k[] = { 0x00000000, ++ 0x00002000, ++ 0x00004000, ++ 0x00006000, ++ 0x00008000, ++ 0x0000a000, ++ 0x0000c000, ++ 0x0000e000, ++ 0x00010000 ++}; ++ ++/* Funky AMD arrangement for 29xx800's */ ++uint amd800[] = { 0x00000000, /* 16KB */ ++ 0x00004000, /* 32KB */ ++ 0x0000c000, /* 8KB */ ++ 0x0000e000, /* 8KB */ ++ 0x00010000, /* 8KB */ ++ 0x00012000, /* 8KB */ ++ 0x00014000, /* 32KB */ ++ 0x0001c000, /* 16KB */ ++ 0x00020000 ++}; ++ ++/* AMD arrangement for 29xx160's */ ++uint amd4112[] = { 0x00000000, /* 32KB */ ++ 0x00008000, /* 8KB */ ++ 0x0000a000, /* 8KB */ ++ 0x0000c000, /* 16KB */ ++ 0x00010000 ++}; ++uint amd2114[] = { 0x00000000, /* 16KB */ ++ 0x00004000, /* 8KB */ ++ 0x00006000, /* 8KB */ ++ 0x00008000, /* 32KB */ ++ 0x00010000 ++}; ++ ++ ++flash_desc_t sflash_desc = ++ { 0, 0, 0, 0, SFLASH, 0, 0, 0, 0, 0, NULL, "SFLASH" }; ++ ++flash_desc_t flashes[] = { ++ { 0x00b0, 0x00d0, 0x0200000, 2, SCS, 0x10000, 32, 0, 31, 0, NULL, "Intel 28F160S3/5 1Mx16" }, ++ { 0x00b0, 0x00d4, 0x0400000, 2, SCS, 0x10000, 64, 0, 63, 0, NULL, "Intel 28F320S3/5 2Mx16" }, ++ { 0x0089, 0x8890, 0x0200000, 2, BSC, 0x10000, 32, 0, 30, 8, blk8x8k, "Intel 28F160B3 1Mx16 TopB" }, ++ { 0x0089, 0x8891, 0x0200000, 2, BSC, 0x10000, 32, 1, 31, 8, blk8x8k, "Intel 28F160B3 1Mx16 BotB" }, ++ { 0x0089, 0x8896, 0x0400000, 2, BSC, 0x10000, 64, 0, 62, 8, blk8x8k, "Intel 28F320B3 2Mx16 TopB" }, ++ { 0x0089, 0x8897, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Intel 28F320B3 2Mx16 BotB" }, ++ { 0x0089, 0x8898, 0x0800000, 2, BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640B3 4Mx16 TopB" }, ++ { 0x0089, 0x8899, 0x0800000, 2, BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640B3 4Mx16 BotB" }, ++ { 0x0089, 0x88C2, 0x0200000, 2, BSC, 0x10000, 32, 0, 30, 8, blk8x8k, "Intel 28F160C3 1Mx16 TopB" }, ++ { 0x0089, 0x88C3, 0x0200000, 2, BSC, 0x10000, 32, 1, 31, 8, blk8x8k, "Intel 28F160C3 1Mx16 BotB" }, ++ { 0x0089, 0x88C4, 0x0400000, 2, BSC, 0x10000, 64, 0, 62, 8, blk8x8k, "Intel 28F320C3 2Mx16 TopB" }, ++ { 0x0089, 0x88C5, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Intel 28F320C3 2Mx16 BotB" }, ++ { 0x0089, 0x88CC, 0x0800000, 2, BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640C3 4Mx16 TopB" }, ++ { 0x0089, 0x88CD, 0x0800000, 2, BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640C3 4Mx16 BotB" }, ++ { 0x0089, 0x0014, 0x0400000, 2, SCS, 0x20000, 32, 0, 31, 0, NULL, "Intel 28F320J5 2Mx16" }, ++ { 0x0089, 0x0015, 0x0800000, 2, SCS, 0x20000, 64, 0, 63, 0, NULL, "Intel 28F640J5 4Mx16" }, ++ { 0x0089, 0x0016, 0x0400000, 2, SCS, 0x20000, 32, 0, 31, 0, NULL, "Intel 28F320J3 2Mx16" }, ++ { 0x0089, 0x0017, 0x0800000, 2, SCS, 0x20000, 64, 0, 63, 0, NULL, "Intel 28F640J3 4Mx16" }, ++ { 0x0089, 0x0018, 0x1000000, 2, SCS, 0x20000, 128, 0, 127, 0, NULL, "Intel 28F128J3 8Mx16" }, ++ { 0x00b0, 0x00e3, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Sharp 28F320BJE 2Mx16 BotB" }, ++ { 0x0001, 0x224a, 0x0100000, 2, AMD, 0x10000, 16, 0, 13, 8, amd800, "AMD 29DL800BT 512Kx16 TopB" }, ++ { 0x0001, 0x22cb, 0x0100000, 2, AMD, 0x10000, 16, 2, 15, 8, amd800, "AMD 29DL800BB 512Kx16 BotB" }, ++ { 0x0001, 0x22c4, 0x0200000, 2, AMD, 0x10000, 32, 0, 30, 4, amd2114, "AMD 29lv160DT 1Mx16 TopB" }, ++ { 0x0001, 0x2249, 0x0200000, 2, AMD, 0x10000, 32, 1, 31, 4, amd4112, "AMD 29lv160DB 1Mx16 BotB" }, ++ { 0x0001, 0x22f6, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 8, blk8x8k, "AMD 29lv320DT 2Mx16 TopB" }, ++ { 0x0001, 0x22f9, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 8, blk8x8k, "AMD 29lv320DB 2Mx16 BotB" }, ++ { 0x0001, 0x227e, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 8, blk8x8k, "AMD 29lv320MT 2Mx16 TopB" }, ++ { 0x0001, 0x2200, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 8, blk8x8k, "AMD 29lv320MB 2Mx16 BotB" }, ++ { 0x0020, 0x22CA, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "ST 29w320DT 2Mx16 TopB" }, ++ { 0x0020, 0x22CB, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "ST 29w320DB 2Mx16 BotB" }, ++ { 0x00C2, 0x00A7, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MX29LV320T 2Mx16 TopB" }, ++ { 0x00C2, 0x00A8, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MX29LV320B 2Mx16 BotB" }, ++ { 0x0004, 0x22F6, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MBM29LV320TE 2Mx16 TopB" }, ++ { 0x0004, 0x22F9, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MBM29LV320BE 2Mx16 BotB" }, ++ { 0x0098, 0x009A, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "TC58FVT321 2Mx16 TopB" }, ++ { 0x0098, 0x009C, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "TC58FVB321 2Mx16 BotB" }, ++ { 0x00C2, 0x22A7, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MX29LV320T 2Mx16 TopB" }, ++ { 0x00C2, 0x22A8, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MX29LV320B 2Mx16 BotB" }, ++ { 0x00BF, 0x2783, 0x0400000, 2, SST, 0x10000, 64, 0, 63, 0, NULL, "SST39VF320 2Mx16" }, ++ { 0, 0, 0, 0, OLD, 0, 0, 0, 0, 0, NULL, NULL }, ++}; ++ ++#else ++ ++extern flash_cmds_t flash_cmds[]; ++extern unlock_cmd_t unlock_cmd; ++extern flash_desc_t flashes[]; ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/flashutl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/flashutl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/flashutl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/flashutl.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,27 @@ ++/* ++ * BCM47XX FLASH driver interface ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _flashutl_h_ ++#define _flashutl_h_ ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++int sysFlashInit(char *flash_str); ++int sysFlashRead(uint off, uchar *dst, uint bytes); ++int sysFlashWrite(uint off, uchar *src, uint bytes); ++void nvWrite(unsigned short *data, unsigned int len); ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#endif /* _flashutl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h +--- linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,71 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _hnddma_h_ ++#define _hnddma_h_ ++ ++/* export structure */ ++typedef volatile struct { ++ /* rx error counters */ ++ uint rxgiants; /* rx giant frames */ ++ uint rxnobuf; /* rx out of dma descriptors */ ++ /* tx error counters */ ++ uint txnobuf; /* tx out of dma descriptors */ ++} hnddma_t; ++ ++#ifndef di_t ++#define di_t void ++#endif ++ ++#ifndef osl_t ++#define osl_t void ++#endif ++ ++/* externs */ ++extern void * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level); ++extern void dma_detach(di_t *di); ++extern void dma_txreset(di_t *di); ++extern void dma_rxreset(di_t *di); ++extern void dma_txinit(di_t *di); ++extern bool dma_txenabled(di_t *di); ++extern void dma_rxinit(di_t *di); ++extern void dma_rxenable(di_t *di); ++extern bool dma_rxenabled(di_t *di); ++extern void dma_txsuspend(di_t *di); ++extern void dma_txresume(di_t *di); ++extern bool dma_txsuspended(di_t *di); ++extern bool dma_txsuspendedidle(di_t *di); ++extern bool dma_txstopped(di_t *di); ++extern bool dma_rxstopped(di_t *di); ++extern int dma_txfast(di_t *di, void *p, uint32 coreflags); ++extern void dma_fifoloopbackenable(di_t *di); ++extern void *dma_rx(di_t *di); ++extern void dma_rxfill(di_t *di); ++extern void dma_txreclaim(di_t *di, bool forceall); ++extern void dma_rxreclaim(di_t *di); ++extern uintptr dma_getvar(di_t *di, char *name); ++extern void *dma_getnexttxp(di_t *di, bool forceall); ++extern void *dma_peeknexttxp(di_t *di); ++extern void *dma_getnextrxp(di_t *di, bool forceall); ++extern void dma_txblock(di_t *di); ++extern void dma_txunblock(di_t *di); ++extern uint dma_txactive(di_t *di); ++extern void dma_txrotate(di_t *di); ++ ++extern void dma_rxpiomode(dma32regs_t *); ++extern void dma_txpioloopback(dma32regs_t *); ++ ++ ++#endif /* _hnddma_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h +--- linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,16 @@ ++/* ++ * Alternate include file for HND sbmips.h since CFE also ships with ++ * a sbmips.h. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include "sbmips.h" +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,371 @@ ++/* ++ * Linux OS Independent Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _linux_osl_h_ ++#define _linux_osl_h_ ++ ++#include ++ ++/* use current 2.4.x calling conventions */ ++#include ++ ++/* assert and panic */ ++#ifdef __GNUC__ ++#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) ++#if GCC_VERSION > 30100 ++#define ASSERT(exp) do {} while (0) ++#else ++/* ASSERT could causes segmentation fault on GCC3.1, use empty instead*/ ++#define ASSERT(exp) ++#endif ++#endif ++ ++/* microsecond delay */ ++#define OSL_DELAY(usec) osl_delay(usec) ++extern void osl_delay(uint usec); ++ ++/* PCMCIA attribute space access macros */ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++struct pcmcia_dev { ++ dev_link_t link; /* PCMCIA device pointer */ ++ dev_node_t node; /* PCMCIA node structure */ ++ void *base; /* Mapped attribute memory window */ ++ size_t size; /* Size of window */ ++ void *drv; /* Driver data */ ++}; ++#endif ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ ++ osl_pcmcia_read_attr((osh), (offset), (buf), (size)) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ ++ osl_pcmcia_write_attr((osh), (offset), (buf), (size)) ++extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); ++extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); ++ ++/* PCI configuration space access macros */ ++#define OSL_PCI_READ_CONFIG(osh, offset, size) \ ++ osl_pci_read_config((osh), (offset), (size)) ++#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ ++ osl_pci_write_config((osh), (offset), (size), (val)) ++extern uint32 osl_pci_read_config(osl_t *osh, uint size, uint offset); ++extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); ++ ++/* PCI device bus # and slot # */ ++#define OSL_PCI_BUS(osh) osl_pci_bus(osh) ++#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) ++extern uint osl_pci_bus(osl_t *osh); ++extern uint osl_pci_slot(osl_t *osh); ++ ++/* OSL initialization */ ++extern osl_t *osl_attach(void *pdev); ++extern void osl_detach(osl_t *osh); ++ ++/* host/bus architecture-specific byte swap */ ++#define BUS_SWAP32(v) (v) ++ ++/* general purpose memory allocation */ ++ ++#if defined(BCMDBG_MEM) ++ ++#define MALLOC(osh, size) osl_debug_malloc((osh), (size), __LINE__, __FILE__) ++#define MFREE(osh, addr, size) osl_debug_mfree((osh), (addr), (size), __LINE__, __FILE__) ++#define MALLOCED(osh) osl_malloced((osh)) ++#define MALLOC_DUMP(osh, buf, sz) osl_debug_memdump((osh), (buf), (sz)) ++extern void *osl_debug_malloc(osl_t *osh, uint size, int line, char* file); ++extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file); ++extern char *osl_debug_memdump(osl_t *osh, char *buf, uint sz); ++ ++#else ++ ++#define MALLOC(osh, size) osl_malloc((osh), (size)) ++#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) ++#define MALLOCED(osh) osl_malloced((osh)) ++ ++#endif /* BCMDBG_MEM */ ++ ++#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) ++ ++extern void *osl_malloc(osl_t *osh, uint size); ++extern void osl_mfree(osl_t *osh, void *addr, uint size); ++extern uint osl_malloced(osl_t *osh); ++extern uint osl_malloc_failed(osl_t *osh); ++ ++/* allocate/free shared (dma-able) consistent memory */ ++#define DMA_CONSISTENT_ALIGN PAGE_SIZE ++#define DMA_ALLOC_CONSISTENT(osh, size, pap) \ ++ osl_dma_alloc_consistent((osh), (size), (pap)) ++#define DMA_FREE_CONSISTENT(osh, va, size, pa) \ ++ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) ++extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap); ++extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); ++ ++/* map/unmap direction */ ++#define DMA_TX 1 ++#define DMA_RX 2 ++ ++/* map/unmap shared (dma-able) memory */ ++#define DMA_MAP(osh, va, size, direction, p) \ ++ osl_dma_map((osh), (va), (size), (direction)) ++#define DMA_UNMAP(osh, pa, size, direction, p) \ ++ osl_dma_unmap((osh), (pa), (size), (direction)) ++extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); ++extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); ++ ++/* register access macros */ ++#if defined(BCMJTAG) ++#include ++#define R_REG(r) bcmjtag_read(NULL, (uint32)(r), sizeof (*(r))) ++#define W_REG(r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof (*(r))) ++#endif ++ ++/* ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ * Macros expand to calls to functions defined in linux_osl.c . ++ */ ++#ifndef BINOSL ++ ++/* string library, kernel mode */ ++#define printf(fmt, args...) printk(fmt, ## args) ++#include ++#include ++ ++/* register access macros */ ++#if !defined(BCMJTAG) ++#ifndef IL_BIGENDIAN ++#define R_REG(r) ( \ ++ sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ ++ readl((volatile uint32*)(r)) \ ++) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#else /* IL_BIGENDIAN */ ++#define R_REG(r) ({ \ ++ __typeof(*(r)) __osl_v; \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): __osl_v = readl((volatile uint32*)(r)); break; \ ++ } \ ++ __osl_v; \ ++}) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#endif ++#endif ++ ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++ ++/* bcopy, bcmp, and bzero */ ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) ++ ++/* uncached virtual address */ ++#ifdef mips ++#define OSL_UNCACHED(va) KSEG1ADDR((va)) ++#include ++#else ++#define OSL_UNCACHED(va) (va) ++#endif ++ ++/* get processor cycle count */ ++#if defined(mips) ++#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2) ++#elif defined(__i386__) ++#define OSL_GETCYCLES(x) rdtscl((x)) ++#else ++#define OSL_GETCYCLES(x) ((x) = 0) ++#endif ++ ++/* dereference an address that may cause a bus exception */ ++#ifdef mips ++#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17)) ++#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into a module") ++#else ++#define BUSPROBE(val, addr) get_dbe((val), (addr)) ++#include ++#endif ++#else ++#define BUSPROBE(val, addr) ({ (val) = R_REG((addr)); 0; }) ++#endif ++ ++/* map/unmap physical to virtual I/O */ ++#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) ++#define REG_UNMAP(va) iounmap((void *)(va)) ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) memset((r), '\0', (len)) ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) ++#define PKTFREE(osh, skb, send) osl_pktfree((skb)) ++#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) ++#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) ++#define PKTHEADROOM(osh, skb) (PKTDATA(osh,skb)-(((struct sk_buff*)(skb))->head)) ++#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) ++#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) ++#define PKTSETNEXT(skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) ++#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) ++#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) ++#define PKTDUP(osh, skb) skb_clone((struct sk_buff*)(skb), GFP_ATOMIC) ++#define PKTCOOKIE(skb) ((void*)((struct sk_buff*)(skb))->csum) ++#define PKTSETCOOKIE(skb, x) (((struct sk_buff*)(skb))->csum = (uint)(x)) ++#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) ++#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) ++#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) ++#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) ++extern void *osl_pktget(osl_t *osh, uint len, bool send); ++extern void osl_pktfree(void *skb); ++ ++#else /* BINOSL */ ++ ++/* string library */ ++#ifndef LINUX_OSL ++#undef printf ++#define printf(fmt, args...) osl_printf((fmt), ## args) ++#undef sprintf ++#define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args) ++#undef strcmp ++#define strcmp(s1, s2) osl_strcmp((s1), (s2)) ++#undef strncmp ++#define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n)) ++#undef strlen ++#define strlen(s) osl_strlen((s)) ++#undef strcpy ++#define strcpy(d, s) osl_strcpy((d), (s)) ++#undef strncpy ++#define strncpy(d, s, n) osl_strncpy((d), (s), (n)) ++#endif ++extern int osl_printf(const char *format, ...); ++extern int osl_sprintf(char *buf, const char *format, ...); ++extern int osl_strcmp(const char *s1, const char *s2); ++extern int osl_strncmp(const char *s1, const char *s2, uint n); ++extern int osl_strlen(const char *s); ++extern char* osl_strcpy(char *d, const char *s); ++extern char* osl_strncpy(char *d, const char *s, uint n); ++ ++/* register access macros */ ++#if !defined(BCMJTAG) ++#define R_REG(r) ( \ ++ sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \ ++ osl_readl((volatile uint32*)(r)) \ ++) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#endif ++ ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++extern uint8 osl_readb(volatile uint8 *r); ++extern uint16 osl_readw(volatile uint16 *r); ++extern uint32 osl_readl(volatile uint32 *r); ++extern void osl_writeb(uint8 v, volatile uint8 *r); ++extern void osl_writew(uint16 v, volatile uint16 *r); ++extern void osl_writel(uint32 v, volatile uint32 *r); ++ ++/* bcopy, bcmp, and bzero */ ++extern void bcopy(const void *src, void *dst, int len); ++extern int bcmp(const void *b1, const void *b2, int len); ++extern void bzero(void *b, int len); ++ ++/* uncached virtual address */ ++#define OSL_UNCACHED(va) osl_uncached((va)) ++extern void *osl_uncached(void *va); ++ ++/* get processor cycle count */ ++#define OSL_GETCYCLES(x) ((x) = osl_getcycles()) ++extern uint osl_getcycles(void); ++ ++/* dereference an address that may target abort */ ++#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr)) ++extern int osl_busprobe(uint32 *val, uint32 addr); ++ ++/* map/unmap physical to virtual */ ++#define REG_MAP(pa, size) osl_reg_map((pa), (size)) ++#define REG_UNMAP(va) osl_reg_unmap((va)) ++extern void *osl_reg_map(uint32 pa, uint size); ++extern void osl_reg_unmap(void *va); ++ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) bzero((r), (len)) ++ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) ++#define PKTFREE(osh, skb, send) osl_pktfree((skb)) ++#define PKTDATA(osh, skb) osl_pktdata((osh), (skb)) ++#define PKTLEN(osh, skb) osl_pktlen((osh), (skb)) ++#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb)) ++#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb)) ++#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb)) ++#define PKTSETNEXT(skb, x) osl_pktsetnext((skb), (x)) ++#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len)) ++#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes)) ++#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) ++#define PKTCOOKIE(skb) osl_pktcookie((skb)) ++#define PKTSETCOOKIE(skb, x) osl_pktsetcookie((skb), (x)) ++#define PKTLINK(skb) osl_pktlink((skb)) ++#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x)) ++#define PKTPRIO(skb) osl_pktprio((skb)) ++#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x)) ++extern void *osl_pktget(osl_t *osh, uint len, bool send); ++extern void osl_pktfree(void *skb); ++extern uchar *osl_pktdata(osl_t *osh, void *skb); ++extern uint osl_pktlen(osl_t *osh, void *skb); ++extern uint osl_pktheadroom(osl_t *osh, void *skb); ++extern uint osl_pkttailroom(osl_t *osh, void *skb); ++extern void *osl_pktnext(osl_t *osh, void *skb); ++extern void osl_pktsetnext(void *skb, void *x); ++extern void osl_pktsetlen(osl_t *osh, void *skb, uint len); ++extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes); ++extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes); ++extern void *osl_pktdup(osl_t *osh, void *skb); ++extern void *osl_pktcookie(void *skb); ++extern void osl_pktsetcookie(void *skb, void *x); ++extern void *osl_pktlink(void *skb); ++extern void osl_pktsetlink(void *skb, void *x); ++extern uint osl_pktprio(void *skb); ++extern void osl_pktsetprio(void *skb, uint x); ++ ++#endif /* BINOSL */ ++ ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++extern int osl_error(int bcmerror); ++ ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 ++ ++#endif /* _linux_osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h +--- linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,411 @@ ++/* ++ * Linux-specific abstractions to gain some independence from linux kernel versions. ++ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _linuxver_h_ ++#define _linuxver_h_ ++ ++#include ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) ++/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ ++#ifdef __UNDEF_NO_VERSION__ ++#undef __NO_VERSION__ ++#else ++#define __NO_VERSION__ ++#endif ++#endif ++ ++#if defined(MODULE) && defined(MODVERSIONS) ++#include ++#endif ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ++#include ++#endif ++ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ++#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") ++#define module_param_string(_name_, _string_, _size_, _perm_) MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) ++#endif ++ ++/* linux/malloc.h is deprecated, use linux/slab.h instead. */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)) ++#include ++#else ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) ++#include ++#else ++#include ++#ifndef work_struct ++#define work_struct tq_struct ++#endif ++#ifndef INIT_WORK ++#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) ++#endif ++#ifndef schedule_work ++#define schedule_work(_work) schedule_task((_work)) ++#endif ++#ifndef flush_scheduled_work ++#define flush_scheduled_work() flush_scheduled_tasks() ++#endif ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++/* Some distributions have their own 2.6.x compatibility layers */ ++#ifndef IRQ_NONE ++typedef void irqreturn_t; ++#define IRQ_NONE ++#define IRQ_HANDLED ++#define IRQ_RETVAL(x) ++#endif ++#else ++typedef irqreturn_t (*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); ++#endif ++ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)) ++/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which ++ * does this, but it's not in 2.4 so we do our own for now. */ ++static inline void ++cs_error(client_handle_t handle, int func, int ret) ++{ ++ error_info_t err = { func, ret }; ++ CardServices(ReportError, handle, &err); ++} ++#endif ++ ++#endif /* CONFIG_PCMCIA */ ++ ++#ifndef __exit ++#define __exit ++#endif ++#ifndef __devexit ++#define __devexit ++#endif ++#ifndef __devinit ++#define __devinit __init ++#endif ++#ifndef __devinitdata ++#define __devinitdata ++#endif ++#ifndef __devexit_p ++#define __devexit_p(x) x ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) ++ ++#define pci_get_drvdata(dev) (dev)->sysdata ++#define pci_set_drvdata(dev, value) (dev)->sysdata=(value) ++ ++/* ++ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration ++ */ ++ ++struct pci_device_id { ++ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ ++ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ ++ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ ++ unsigned long driver_data; /* Data private to the driver */ ++}; ++ ++struct pci_driver { ++ struct list_head node; ++ char *name; ++ const struct pci_device_id *id_table; /* NULL if wants all devices */ ++ int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ ++ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ ++ void (*suspend)(struct pci_dev *dev); /* Device suspended */ ++ void (*resume)(struct pci_dev *dev); /* Device woken up */ ++}; ++ ++#define MODULE_DEVICE_TABLE(type, name) ++#define PCI_ANY_ID (~0) ++ ++/* compatpci.c */ ++#define pci_module_init pci_register_driver ++extern int pci_register_driver(struct pci_driver *drv); ++extern void pci_unregister_driver(struct pci_driver *drv); ++ ++#endif /* PCI registration */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) ++#ifdef MODULE ++#define module_init(x) int init_module(void) { return x(); } ++#define module_exit(x) void cleanup_module(void) { x(); } ++#else ++#define module_init(x) __initcall(x); ++#define module_exit(x) __exitcall(x); ++#endif ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)) ++#define list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)) ++#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) ++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,44)) ++#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,23)) ++#define pci_enable_device(dev) do { } while (0) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14)) ++#define net_device device ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)) ++ ++/* ++ * DMA mapping ++ * ++ * See linux/Documentation/DMA-mapping.txt ++ */ ++ ++#ifndef PCI_DMA_TODEVICE ++#define PCI_DMA_TODEVICE 1 ++#define PCI_DMA_FROMDEVICE 2 ++#endif ++ ++typedef u32 dma_addr_t; ++ ++/* Pure 2^n version of get_order */ ++static inline int get_order(unsigned long size) ++{ ++ int order; ++ ++ size = (size-1) >> (PAGE_SHIFT-1); ++ order = -1; ++ do { ++ size >>= 1; ++ order++; ++ } while (size); ++ return order; ++} ++ ++static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, ++ dma_addr_t *dma_handle) ++{ ++ void *ret; ++ int gfp = GFP_ATOMIC | GFP_DMA; ++ ++ ret = (void *)__get_free_pages(gfp, get_order(size)); ++ ++ if (ret != NULL) { ++ memset(ret, 0, size); ++ *dma_handle = virt_to_bus(ret); ++ } ++ return ret; ++} ++static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, ++ void *vaddr, dma_addr_t dma_handle) ++{ ++ free_pages((unsigned long)vaddr, get_order(size)); ++} ++#ifdef ILSIM ++extern uint pci_map_single(void *dev, void *va, uint size, int direction); ++extern void pci_unmap_single(void *dev, uint pa, uint size, int direction); ++#else ++#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) ++#define pci_unmap_single(cookie, address, size, dir) ++#endif ++ ++#endif /* DMA mapping */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) ++ ++#define dev_kfree_skb_any(a) dev_kfree_skb(a) ++#define netif_down(dev) do { (dev)->start = 0; } while(0) ++ ++/* pcmcia-cs provides its own netdevice compatibility layer */ ++#ifndef _COMPAT_NETDEVICE_H ++ ++/* ++ * SoftNet ++ * ++ * For pre-softnet kernels we need to tell the upper layer not to ++ * re-enter start_xmit() while we are in there. However softnet ++ * guarantees not to enter while we are in there so there is no need ++ * to do the netif_stop_queue() dance unless the transmit queue really ++ * gets stuck. This should also improve performance according to tests ++ * done by Aman Singla. ++ */ ++ ++#define dev_kfree_skb_irq(a) dev_kfree_skb(a) ++#define netif_wake_queue(dev) do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while(0) ++#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) ++ ++static inline void netif_start_queue(struct net_device *dev) ++{ ++ dev->tbusy = 0; ++ dev->interrupt = 0; ++ dev->start = 1; ++} ++ ++#define netif_queue_stopped(dev) (dev)->tbusy ++#define netif_running(dev) (dev)->start ++ ++#endif /* _COMPAT_NETDEVICE_H */ ++ ++#define netif_device_attach(dev) netif_start_queue(dev) ++#define netif_device_detach(dev) netif_stop_queue(dev) ++ ++/* 2.4.x renamed bottom halves to tasklets */ ++#define tasklet_struct tq_struct ++static inline void tasklet_schedule(struct tasklet_struct *tasklet) ++{ ++ queue_task(tasklet, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++} ++ ++static inline void tasklet_init(struct tasklet_struct *tasklet, ++ void (*func)(unsigned long), ++ unsigned long data) ++{ ++ tasklet->next = NULL; ++ tasklet->sync = 0; ++ tasklet->routine = (void (*)(void *))func; ++ tasklet->data = (void *)data; ++} ++#define tasklet_kill(tasklet) {do{} while(0);} ++ ++/* 2.4.x introduced del_timer_sync() */ ++#define del_timer_sync(timer) del_timer(timer) ++ ++#else ++ ++#define netif_down(dev) ++ ++#endif /* SoftNet */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)) ++ ++/* ++ * Emit code to initialise a tq_struct's routine and data pointers ++ */ ++#define PREPARE_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ (_tq)->routine = _routine; \ ++ (_tq)->data = _data; \ ++ } while (0) ++ ++/* ++ * Emit code to initialise all of a tq_struct ++ */ ++#define INIT_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ INIT_LIST_HEAD(&(_tq)->list); \ ++ (_tq)->sync = 0; \ ++ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ ++ } while (0) ++ ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6)) ++ ++/* Power management related routines */ ++ ++static inline int ++pci_save_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_read_config_dword(dev, i * 4,&buffer[i]); ++ } ++ return 0; ++} ++ ++static inline int ++pci_restore_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_write_config_dword(dev,i * 4, buffer[i]); ++ } ++ /* ++ * otherwise, write the context information we know from bootup. ++ * This works around a problem where warm-booting from Windows ++ * combined with a D3(hot)->D0 transition causes PCI config ++ * header data to be forgotten. ++ */ ++ else { ++ for (i = 0; i < 6; i ++) ++ pci_write_config_dword(dev, ++ PCI_BASE_ADDRESS_0 + (i * 4), ++ pci_resource_start(dev, i)); ++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); ++ } ++ return 0; ++} ++ ++#endif /* PCI power management */ ++ ++/* Old cp0 access macros deprecated in 2.4.19 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)) ++#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) ++#endif ++ ++/* Module refcount handled internally in 2.6.x */ ++#ifndef SET_MODULE_OWNER ++#define SET_MODULE_OWNER(dev) do {} while (0) ++#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT ++#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT ++#else ++#define OLD_MOD_INC_USE_COUNT do {} while (0) ++#define OLD_MOD_DEC_USE_COUNT do {} while (0) ++#endif ++ ++#ifndef SET_NETDEV_DEV ++#define SET_NETDEV_DEV(net, pdev) do {} while (0) ++#endif ++ ++#ifndef HAVE_FREE_NETDEV ++#define free_netdev(dev) kfree(dev) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++/* struct packet_type redefined in 2.6.x */ ++#define af_packet_priv data ++#endif ++ ++#endif /* _linuxver_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/min_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/min_osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/min_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/min_osl.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,126 @@ ++/* ++ * HND Minimal OS Abstraction Layer. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _min_osl_h_ ++#define _min_osl_h_ ++ ++#include ++#include ++#include ++ ++/* Cache support */ ++extern void caches_on(void); ++extern void blast_dcache(void); ++extern void blast_icache(void); ++ ++/* uart output */ ++extern void putc(int c); ++ ++/* lib functions */ ++extern int printf(const char *fmt, ...); ++extern int sprintf(char *buf, const char *fmt, ...); ++extern int strcmp(const char *s1, const char *s2); ++extern int strncmp(const char *s1, const char *s2, uint n); ++extern char *strcpy(char *dest, const char *src); ++extern char *strncpy(char *dest, const char *src, uint n); ++extern uint strlen(const char *s); ++extern char *strchr(const char *str,int c); ++extern char *strrchr(const char *str, int c); ++extern char *strcat(char *d, const char *s); ++extern void *memset(void *dest, int c, uint n); ++extern void *memcpy(void *dest, const void *src, uint n); ++extern int memcmp(const void *s1, const void *s2, uint n); ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) ++ ++/* assert & debugging */ ++#define ASSERT(exp) do {} while (0) ++ ++/* PCMCIA attribute space access macros */ ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ ++ ASSERT(0) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ ++ ASSERT(0) ++ ++/* PCI configuration space access macros */ ++#define OSL_PCI_READ_CONFIG(loc, offset, size) \ ++ (offset == 8 ? 0 : 0xffffffff) ++#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) \ ++ do {} while (0) ++ ++/* PCI device bus # and slot # */ ++#define OSL_PCI_BUS(osh) (0) ++#define OSL_PCI_SLOT(osh) (0) ++ ++/* register access macros */ ++#define wreg32(r, v) (*(volatile uint32*)(r) = (uint32)(v)) ++#define rreg32(r) (*(volatile uint32*)(r)) ++#define wreg16(r, v) (*(volatile uint16*)(r) = (uint16)(v)) ++#define rreg16(r) (*(volatile uint16*)(r)) ++#define wreg8(r, v) (*(volatile uint8*)(r) = (uint8)(v)) ++#define rreg8(r) (*(volatile uint8*)(r)) ++#define R_REG(r) ({ \ ++ __typeof(*(r)) __osl_v; \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = rreg8((r)); break; \ ++ case sizeof(uint16): __osl_v = rreg16((r)); break; \ ++ case sizeof(uint32): __osl_v = rreg32((r)); break; \ ++ } \ ++ __osl_v; \ ++}) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): wreg8((r), (v)); break; \ ++ case sizeof(uint16): wreg16((r), (v)); break; \ ++ case sizeof(uint32): wreg32((r), (v)); break; \ ++ } \ ++} while (0) ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++ ++/* general purpose memory allocation */ ++#define MALLOC(osh, size) malloc(size) ++#define MFREE(osh, addr, size) free(addr) ++#define MALLOCED(osh) 0 ++#define MALLOC_FAILED(osh) 0 ++#define MALLOC_DUMP(osh, buf, sz) ++extern int free(void *ptr); ++extern void *malloc(uint size); ++ ++/* uncached virtual address */ ++#define OSL_UNCACHED(va) ((void*)KSEG1ADDR((ulong)(va))) ++ ++/* host/bus architecture-specific address byte swap */ ++#define BUS_SWAP32(v) (v) ++ ++/* microsecond delay */ ++#define OSL_DELAY(usec) udelay(usec) ++extern void udelay(uint32 usec); ++ ++/* map/unmap physical to virtual I/O */ ++#define REG_MAP(pa, size) ((void*)KSEG1ADDR((ulong)(pa))) ++#define REG_UNMAP(va) do {} while (0) ++ ++/* dereference an address that may cause a bus exception */ ++#define BUSPROBE(val, addr) (uint32 *)(addr) = (val) ++ ++/* Misc stubs */ ++#define osl_attach(pdev) ((osl_t*)pdev) ++#define osl_detach(osh) ++extern void *osl_init(void); ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++extern int osl_error(int); ++ ++#endif /* _min_osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h +--- linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,552 @@ ++/* ++ * HND Run Time Environment for standalone MIPS programs. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _MISPINC_H ++#define _MISPINC_H ++ ++ ++/* MIPS defines */ ++ ++#ifdef _LANGUAGE_ASSEMBLY ++ ++/* ++ * Symbolic register names for 32 bit ABI ++ */ ++#define zero $0 /* wired zero */ ++#define AT $1 /* assembler temp - uppercase because of ".set at" */ ++#define v0 $2 /* return value */ ++#define v1 $3 ++#define a0 $4 /* argument registers */ ++#define a1 $5 ++#define a2 $6 ++#define a3 $7 ++#define t0 $8 /* caller saved */ ++#define t1 $9 ++#define t2 $10 ++#define t3 $11 ++#define t4 $12 ++#define t5 $13 ++#define t6 $14 ++#define t7 $15 ++#define s0 $16 /* callee saved */ ++#define s1 $17 ++#define s2 $18 ++#define s3 $19 ++#define s4 $20 ++#define s5 $21 ++#define s6 $22 ++#define s7 $23 ++#define t8 $24 /* caller saved */ ++#define t9 $25 ++#define jp $25 /* PIC jump register */ ++#define k0 $26 /* kernel scratch */ ++#define k1 $27 ++#define gp $28 /* global pointer */ ++#define sp $29 /* stack pointer */ ++#define fp $30 /* frame pointer */ ++#define s8 $30 /* same like fp! */ ++#define ra $31 /* return address */ ++ ++ ++/* ++ * CP0 Registers ++ */ ++ ++#define C0_INX $0 ++#define C0_RAND $1 ++#define C0_TLBLO0 $2 ++#define C0_TLBLO C0_TLBLO0 ++#define C0_TLBLO1 $3 ++#define C0_CTEXT $4 ++#define C0_PGMASK $5 ++#define C0_WIRED $6 ++#define C0_BADVADDR $8 ++#define C0_COUNT $9 ++#define C0_TLBHI $10 ++#define C0_COMPARE $11 ++#define C0_SR $12 ++#define C0_STATUS C0_SR ++#define C0_CAUSE $13 ++#define C0_EPC $14 ++#define C0_PRID $15 ++#define C0_CONFIG $16 ++#define C0_LLADDR $17 ++#define C0_WATCHLO $18 ++#define C0_WATCHHI $19 ++#define C0_XCTEXT $20 ++#define C0_DIAGNOSTIC $22 ++#define C0_BROADCOM C0_DIAGNOSTIC ++#define C0_PERFORMANCE $25 ++#define C0_ECC $26 ++#define C0_CACHEERR $27 ++#define C0_TAGLO $28 ++#define C0_TAGHI $29 ++#define C0_ERREPC $30 ++#define C0_DESAVE $31 ++ ++/* ++ * LEAF - declare leaf routine ++ */ ++#define LEAF(symbol) \ ++ .globl symbol; \ ++ .align 2; \ ++ .type symbol,@function; \ ++ .ent symbol,0; \ ++symbol: .frame sp,0,ra ++ ++/* ++ * END - mark end of function ++ */ ++#define END(function) \ ++ .end function; \ ++ .size function,.-function ++ ++#define _ULCAST_ ++ ++#else ++ ++/* ++ * The following macros are especially useful for __asm__ ++ * inline assembler. ++ */ ++#ifndef __STR ++#define __STR(x) #x ++#endif ++#ifndef STR ++#define STR(x) __STR(x) ++#endif ++ ++#define _ULCAST_ (unsigned long) ++ ++ ++/* ++ * CP0 Registers ++ */ ++ ++#define C0_INX 0 /* CP0: TLB Index */ ++#define C0_RAND 1 /* CP0: TLB Random */ ++#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ ++#define C0_CTEXT 4 /* CP0: Context */ ++#define C0_PGMASK 5 /* CP0: TLB PageMask */ ++#define C0_WIRED 6 /* CP0: TLB Wired */ ++#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ ++#define C0_COUNT 9 /* CP0: Count */ ++#define C0_TLBHI 10 /* CP0: TLB EntryHi */ ++#define C0_COMPARE 11 /* CP0: Compare */ ++#define C0_SR 12 /* CP0: Processor Status */ ++#define C0_STATUS C0_SR /* CP0: Processor Status */ ++#define C0_CAUSE 13 /* CP0: Exception Cause */ ++#define C0_EPC 14 /* CP0: Exception PC */ ++#define C0_PRID 15 /* CP0: Processor Revision Indentifier */ ++#define C0_CONFIG 16 /* CP0: Config */ ++#define C0_LLADDR 17 /* CP0: LLAddr */ ++#define C0_WATCHLO 18 /* CP0: WatchpointLo */ ++#define C0_WATCHHI 19 /* CP0: WatchpointHi */ ++#define C0_XCTEXT 20 /* CP0: XContext */ ++#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ ++#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ ++#define C0_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */ ++#define C0_ECC 26 /* CP0: ECC */ ++#define C0_CACHEERR 27 /* CP0: CacheErr */ ++#define C0_TAGLO 28 /* CP0: TagLo */ ++#define C0_TAGHI 29 /* CP0: TagHi */ ++#define C0_ERREPC 30 /* CP0: ErrorEPC */ ++#define C0_DESAVE 31 /* CP0: DebugSave */ ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* ++ * Memory segments (32bit kernel mode addresses) ++ */ ++#undef KUSEG ++#undef KSEG0 ++#undef KSEG1 ++#undef KSEG2 ++#undef KSEG3 ++#define KUSEG 0x00000000 ++#define KSEG0 0x80000000 ++#define KSEG1 0xa0000000 ++#define KSEG2 0xc0000000 ++#define KSEG3 0xe0000000 ++#define PHYSADDR_MASK 0x1fffffff ++ ++/* ++ * Map an address to a certain kernel segment ++ */ ++#undef PHYSADDR ++#undef KSEG0ADDR ++#undef KSEG1ADDR ++#undef KSEG2ADDR ++#undef KSEG3ADDR ++ ++#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) ++#define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0) ++#define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1) ++#define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2) ++#define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3) ++ ++ ++#ifndef Index_Invalidate_I ++/* ++ * Cache Operations ++ */ ++#define Index_Invalidate_I 0x00 ++#define Index_Writeback_Inv_D 0x01 ++#define Index_Invalidate_SI 0x02 ++#define Index_Writeback_Inv_SD 0x03 ++#define Index_Load_Tag_I 0x04 ++#define Index_Load_Tag_D 0x05 ++#define Index_Load_Tag_SI 0x06 ++#define Index_Load_Tag_SD 0x07 ++#define Index_Store_Tag_I 0x08 ++#define Index_Store_Tag_D 0x09 ++#define Index_Store_Tag_SI 0x0A ++#define Index_Store_Tag_SD 0x0B ++#define Create_Dirty_Excl_D 0x0d ++#define Create_Dirty_Excl_SD 0x0f ++#define Hit_Invalidate_I 0x10 ++#define Hit_Invalidate_D 0x11 ++#define Hit_Invalidate_SI 0x12 ++#define Hit_Invalidate_SD 0x13 ++#define Fill_I 0x14 ++#define Hit_Writeback_Inv_D 0x15 ++ /* 0x16 is unused */ ++#define Hit_Writeback_Inv_SD 0x17 ++#define R5K_Page_Invalidate_S 0x17 ++#define Hit_Writeback_I 0x18 ++#define Hit_Writeback_D 0x19 ++ /* 0x1a is unused */ ++#define Hit_Writeback_SD 0x1b ++ /* 0x1c is unused */ ++ /* 0x1e is unused */ ++#define Hit_Set_Virtual_SI 0x1e ++#define Hit_Set_Virtual_SD 0x1f ++#endif ++ ++ ++/* ++ * R4x00 interrupt enable / cause bits ++ */ ++#define IE_SW0 (_ULCAST_(1) << 8) ++#define IE_SW1 (_ULCAST_(1) << 9) ++#define IE_IRQ0 (_ULCAST_(1) << 10) ++#define IE_IRQ1 (_ULCAST_(1) << 11) ++#define IE_IRQ2 (_ULCAST_(1) << 12) ++#define IE_IRQ3 (_ULCAST_(1) << 13) ++#define IE_IRQ4 (_ULCAST_(1) << 14) ++#define IE_IRQ5 (_ULCAST_(1) << 15) ++ ++#ifndef ST0_UM ++/* ++ * Bitfields in the mips32 cp0 status register ++ */ ++#define ST0_IE 0x00000001 ++#define ST0_EXL 0x00000002 ++#define ST0_ERL 0x00000004 ++#define ST0_UM 0x00000010 ++#define ST0_SWINT0 0x00000100 ++#define ST0_SWINT1 0x00000200 ++#define ST0_HWINT0 0x00000400 ++#define ST0_HWINT1 0x00000800 ++#define ST0_HWINT2 0x00001000 ++#define ST0_HWINT3 0x00002000 ++#define ST0_HWINT4 0x00004000 ++#define ST0_HWINT5 0x00008000 ++#define ST0_IM 0x0000ff00 ++#define ST0_NMI 0x00080000 ++#define ST0_SR 0x00100000 ++#define ST0_TS 0x00200000 ++#define ST0_BEV 0x00400000 ++#define ST0_RE 0x02000000 ++#define ST0_RP 0x08000000 ++#define ST0_CU 0xf0000000 ++#define ST0_CU0 0x10000000 ++#define ST0_CU1 0x20000000 ++#define ST0_CU2 0x40000000 ++#define ST0_CU3 0x80000000 ++#endif ++ ++ ++/* ++ * Bitfields in the mips32 cp0 cause register ++ */ ++#define C_EXC 0x0000007c ++#define C_EXC_SHIFT 2 ++#define C_INT 0x0000ff00 ++#define C_INT_SHIFT 8 ++#define C_SW0 (_ULCAST_(1) << 8) ++#define C_SW1 (_ULCAST_(1) << 9) ++#define C_IRQ0 (_ULCAST_(1) << 10) ++#define C_IRQ1 (_ULCAST_(1) << 11) ++#define C_IRQ2 (_ULCAST_(1) << 12) ++#define C_IRQ3 (_ULCAST_(1) << 13) ++#define C_IRQ4 (_ULCAST_(1) << 14) ++#define C_IRQ5 (_ULCAST_(1) << 15) ++#define C_WP 0x00400000 ++#define C_IV 0x00800000 ++#define C_CE 0x30000000 ++#define C_CE_SHIFT 28 ++#define C_BD 0x80000000 ++ ++/* Values in C_EXC */ ++#define EXC_INT 0 ++#define EXC_TLBM 1 ++#define EXC_TLBL 2 ++#define EXC_TLBS 3 ++#define EXC_AEL 4 ++#define EXC_AES 5 ++#define EXC_IBE 6 ++#define EXC_DBE 7 ++#define EXC_SYS 8 ++#define EXC_BPT 9 ++#define EXC_RI 10 ++#define EXC_CU 11 ++#define EXC_OV 12 ++#define EXC_TR 13 ++#define EXC_WATCH 23 ++#define EXC_MCHK 24 ++ ++ ++/* ++ * Bits in the cp0 config register. ++ */ ++#define CONF_CM_CACHABLE_NO_WA 0 ++#define CONF_CM_CACHABLE_WA 1 ++#define CONF_CM_UNCACHED 2 ++#define CONF_CM_CACHABLE_NONCOHERENT 3 ++#define CONF_CM_CACHABLE_CE 4 ++#define CONF_CM_CACHABLE_COW 5 ++#define CONF_CM_CACHABLE_CUW 6 ++#define CONF_CM_CACHABLE_ACCELERATED 7 ++#define CONF_CM_CMASK 7 ++#define CONF_CU (_ULCAST_(1) << 3) ++#define CONF_DB (_ULCAST_(1) << 4) ++#define CONF_IB (_ULCAST_(1) << 5) ++#define CONF_SE (_ULCAST_(1) << 12) ++#define CONF_SC (_ULCAST_(1) << 17) ++#define CONF_AC (_ULCAST_(1) << 23) ++#define CONF_HALT (_ULCAST_(1) << 25) ++ ++ ++/* ++ * Bits in the cp0 config register select 1. ++ */ ++#define CONF1_FP 0x00000001 /* FPU present */ ++#define CONF1_EP 0x00000002 /* EJTAG present */ ++#define CONF1_CA 0x00000004 /* mips16 implemented */ ++#define CONF1_WR 0x00000008 /* Watch registers present */ ++#define CONF1_PC 0x00000010 /* Performance counters present */ ++#define CONF1_DA_SHIFT 7 /* D$ associativity */ ++#define CONF1_DA_MASK 0x00000380 ++#define CONF1_DA_BASE 1 ++#define CONF1_DL_SHIFT 10 /* D$ line size */ ++#define CONF1_DL_MASK 0x00001c00 ++#define CONF1_DL_BASE 2 ++#define CONF1_DS_SHIFT 13 /* D$ sets/way */ ++#define CONF1_DS_MASK 0x0000e000 ++#define CONF1_DS_BASE 64 ++#define CONF1_IA_SHIFT 16 /* I$ associativity */ ++#define CONF1_IA_MASK 0x00070000 ++#define CONF1_IA_BASE 1 ++#define CONF1_IL_SHIFT 19 /* I$ line size */ ++#define CONF1_IL_MASK 0x00380000 ++#define CONF1_IL_BASE 2 ++#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ ++#define CONF1_IS_MASK 0x01c00000 ++#define CONF1_IS_BASE 64 ++#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */ ++#define CONF1_MS_SHIFT 25 ++ ++/* PRID register */ ++#define PRID_COPT_MASK 0xff000000 ++#define PRID_COMP_MASK 0x00ff0000 ++#define PRID_IMP_MASK 0x0000ff00 ++#define PRID_REV_MASK 0x000000ff ++ ++#define PRID_COMP_LEGACY 0x000000 ++#define PRID_COMP_MIPS 0x010000 ++#define PRID_COMP_BROADCOM 0x020000 ++#define PRID_COMP_ALCHEMY 0x030000 ++#define PRID_COMP_SIBYTE 0x040000 ++#define PRID_IMP_BCM4710 0x4000 ++#define PRID_IMP_BCM3302 0x9000 ++#define PRID_IMP_BCM3303 0x9100 ++ ++#define PRID_IMP_UNKNOWN 0xff00 ++ ++#define BCM330X(id) \ ++ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \ ++ || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) ++ ++/* Bits in C0_BROADCOM */ ++#define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */ ++#define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */ ++#define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */ ++#define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */ ++ ++/* PreFetch Cache aka Read Ahead Cache */ ++ ++#define PFC_CR0 0xff400000 /* control reg 0 */ ++#define PFC_CR1 0xff400004 /* control reg 1 */ ++ ++/* PFC operations */ ++#define PFC_I 0x00000001 /* Enable PFC use for instructions */ ++#define PFC_D 0x00000002 /* Enable PFC use for data */ ++#define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */ ++#define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */ ++#define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */ ++#define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */ ++#define PFC_DPF 0x00000040 /* Enable directional prefetching */ ++#define PFC_FLUSH 0x00000100 /* Flush the PFC */ ++#define PFC_BRR 0x40000000 /* Bus error indication */ ++#define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */ ++ ++/* Handy defaults */ ++#define PFC_DISABLED 0 ++#define PFC_AUTO 0xffffffff /* auto select the default mode */ ++#define PFC_INST (PFC_I | PFC_PFI | PFC_CINV) ++#define PFC_INST_NOPF (PFC_I | PFC_CINV) ++#define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV) ++#define PFC_DATA_NOPF (PFC_D | PFC_CINV) ++#define PFC_I_AND_D (PFC_INST | PFC_DATA) ++#define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF) ++ ++ ++/* ++ * These are the UART port assignments, expressed as offsets from the base ++ * register. These assignments should hold for any serial port based on ++ * a 8250, 16450, or 16550(A). ++ */ ++ ++#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ ++#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ ++#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ ++#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ ++#define UART_LCR 3 /* Out: Line Control Register */ ++#define UART_MCR 4 /* Out: Modem Control Register */ ++#define UART_LSR 5 /* In: Line Status Register */ ++#define UART_MSR 6 /* In: Modem Status Register */ ++#define UART_SCR 7 /* I/O: Scratch Register */ ++#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ ++#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ ++#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ ++#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ ++#define UART_LSR_RXRDY 0x01 /* Receiver ready */ ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* ++ * Macros to access the system control coprocessor ++ */ ++ ++#define MFC0(source, sel) \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \ ++ "move\t%0,$1\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ :"=r" (__res) \ ++ : \ ++ :"$1"); \ ++ __res; \ ++}) ++ ++#define MTC0(source, sel, value) \ ++do { \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ "move\t$1,%z0\n\t" \ ++ ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ : \ ++ :"jr" (value) \ ++ :"$1"); \ ++} while (0) ++ ++#define get_c0_count() \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ "mfc0\t%0,$9\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ :"=r" (__res)); \ ++ __res; \ ++}) ++ ++static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; ++ ++ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT))) ++ lsz = CONF1_IL_BASE << lsz; ++ sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT); ++ ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} ++ ++static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; ++ ++ /* Data Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT))) ++ lsz = CONF1_DL_BASE << lsz; ++ sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT); ++ ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} ++ ++#define cache_op(base, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1, (%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); ++ ++#define cache_unroll4(base, delta, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1,0(%0); \ ++ cache %1,delta(%0); \ ++ cache %1,(2 * delta)(%0); \ ++ cache %1,(3 * delta)(%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); ++ ++#endif /* !_LANGUAGE_ASSEMBLY */ ++ ++#endif /* _MISPINC_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/nvports.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/nvports.h +--- linux-2.4.32/arch/mips/bcm947xx/include/nvports.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/nvports.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,55 @@ ++/* ++ * BCM53xx RoboSwitch utility functions ++ * ++ * Copyright (C) 2002 Broadcom Corporation ++ * $Id$ ++ */ ++ ++#ifndef _nvports_h_ ++#define _nvports_h_ ++ ++#define uint32 unsigned long ++#define uint16 unsigned short ++#define uint unsigned int ++#define uint8 unsigned char ++#define uint64 unsigned long long ++ ++enum FORCE_PORT { ++ FORCE_OFF, ++ FORCE_10H, ++ FORCE_10F, ++ FORCE_100H, ++ FORCE_100F, ++ FORCE_DOWN, ++ POWER_OFF ++}; ++ ++typedef struct _PORT_ATTRIBS ++{ ++ uint autoneg; ++ uint force; ++ uint native; ++} PORT_ATTRIBS; ++ ++extern uint ++nvExistsPortAttrib(char *attrib, uint portno); ++ ++extern int ++nvExistsAnyForcePortAttrib(uint portno); ++ ++extern void ++nvSetPortAttrib(char *attrib, uint portno); ++ ++extern void ++nvUnsetPortAttrib(char *attrib, uint portno); ++ ++extern void ++nvUnsetAllForcePortAttrib(uint portno); ++ ++extern PORT_ATTRIBS ++nvGetSwitchPortAttribs(uint portno); ++ ++#endif /* _nvports_h_ */ ++ ++ ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,42 @@ ++/* ++ * OS Abstraction Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _osl_h_ ++#define _osl_h_ ++ ++/* osl handle type forward declaration */ ++typedef struct os_handle osl_t; ++ ++#if defined(linux) ++#include ++#elif defined(NDIS) ++#include ++#elif defined(_CFE_) ++#include ++#elif defined(_HNDRTE_) ++#include ++#elif defined(_MINOSL_) ++#include ++#elif PMON ++#include ++#elif defined(MACOSX) ++#include ++#else ++#error "Unsupported OSL requested" ++#endif ++ ++/* handy */ ++#define SET_REG(r, mask, val) W_REG((r), ((R_REG(r) & ~(mask)) | (val))) ++#define MAXPRIO 7 /* 0-7 */ ++ ++#endif /* _osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h +--- linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h 2005-12-16 23:39:10.752824750 +0100 +@@ -0,0 +1,451 @@ ++/* ++ * pcicfg.h: PCI configuration constants and structures. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _h_pci_ ++#define _h_pci_ ++ ++/* The following inside ifndef's so we don't collide with NTDDK.H */ ++#ifndef PCI_MAX_BUS ++#define PCI_MAX_BUS 0x100 ++#endif ++#ifndef PCI_MAX_DEVICES ++#define PCI_MAX_DEVICES 0x20 ++#endif ++#ifndef PCI_MAX_FUNCTION ++#define PCI_MAX_FUNCTION 0x8 ++#endif ++ ++#ifndef PCI_INVALID_VENDORID ++#define PCI_INVALID_VENDORID 0xffff ++#endif ++#ifndef PCI_INVALID_DEVICEID ++#define PCI_INVALID_DEVICEID 0xffff ++#endif ++ ++ ++/* Convert between bus-slot-function-register and config addresses */ ++ ++#define PCICFG_BUS_SHIFT 16 /* Bus shift */ ++#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ ++#define PCICFG_FUN_SHIFT 8 /* Function shift */ ++#define PCICFG_OFF_SHIFT 0 /* Register shift */ ++ ++#define PCICFG_BUS_MASK 0xff /* Bus mask */ ++#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ ++#define PCICFG_FUN_MASK 7 /* Function mask */ ++#define PCICFG_OFF_MASK 0xff /* Bus mask */ ++ ++#define PCI_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ ++ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ ++ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ ++ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) ++ ++#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) ++#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) ++#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) ++#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) ++ ++/* PCIE Config space accessing MACROS*/ ++ ++#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ ++#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ ++#define PCIECFG_FUN_SHIFT 16 /* Function shift */ ++#define PCIECFG_OFF_SHIFT 0 /* Register shift */ ++ ++#define PCIECFG_BUS_MASK 0xff /* Bus mask */ ++#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ ++#define PCIECFG_FUN_MASK 7 /* Function mask */ ++#define PCIECFG_OFF_MASK 0x3ff /* Register mask */ ++ ++#define PCIE_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ ++ | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ ++ | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ ++ | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) ++ ++#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) ++#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) ++#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) ++#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) ++ ++ ++/* The actual config space */ ++ ++#define PCI_BAR_MAX 6 ++ ++#define PCI_ROM_BAR 8 ++ ++#define PCR_RSVDA_MAX 2 ++ ++/* pci config status reg has a bit to indicate that capability ptr is present*/ ++ ++#define PCI_CAPPTR_PRESENT 0x0010 ++ ++typedef struct _pci_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long base[PCI_BAR_MAX]; ++ unsigned long cardbus_cis; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long baserom; ++ unsigned long rsvd_a[PCR_RSVDA_MAX]; ++ unsigned char int_line; ++ unsigned char int_pin; ++ unsigned char min_gnt; ++ unsigned char max_lat; ++ unsigned char dev_dep[192]; ++} pci_config_regs; ++ ++#define SZPCR (sizeof (pci_config_regs)) ++#define MINSZPCR 64 /* offsetof (dev_dep[0] */ ++ ++/* A structure for the config registers is nice, but in most ++ * systems the config space is not memory mapped, so we need ++ * filed offsetts. :-( ++ */ ++#define PCI_CFG_VID 0 ++#define PCI_CFG_DID 2 ++#define PCI_CFG_CMD 4 ++#define PCI_CFG_STAT 6 ++#define PCI_CFG_REV 8 ++#define PCI_CFG_PROGIF 9 ++#define PCI_CFG_SUBCL 0xa ++#define PCI_CFG_BASECL 0xb ++#define PCI_CFG_CLSZ 0xc ++#define PCI_CFG_LATTIM 0xd ++#define PCI_CFG_HDR 0xe ++#define PCI_CFG_BIST 0xf ++#define PCI_CFG_BAR0 0x10 ++#define PCI_CFG_BAR1 0x14 ++#define PCI_CFG_BAR2 0x18 ++#define PCI_CFG_BAR3 0x1c ++#define PCI_CFG_BAR4 0x20 ++#define PCI_CFG_BAR5 0x24 ++#define PCI_CFG_CIS 0x28 ++#define PCI_CFG_SVID 0x2c ++#define PCI_CFG_SSID 0x2e ++#define PCI_CFG_ROMBAR 0x30 ++#define PCI_CFG_CAPPTR 0x34 ++#define PCI_CFG_INT 0x3c ++#define PCI_CFG_PIN 0x3d ++#define PCI_CFG_MINGNT 0x3e ++#define PCI_CFG_MAXLAT 0x3f ++ ++/* Classes and subclasses */ ++ ++typedef enum { ++ PCI_CLASS_OLD = 0, ++ PCI_CLASS_DASDI, ++ PCI_CLASS_NET, ++ PCI_CLASS_DISPLAY, ++ PCI_CLASS_MMEDIA, ++ PCI_CLASS_MEMORY, ++ PCI_CLASS_BRIDGE, ++ PCI_CLASS_COMM, ++ PCI_CLASS_BASE, ++ PCI_CLASS_INPUT, ++ PCI_CLASS_DOCK, ++ PCI_CLASS_CPU, ++ PCI_CLASS_SERIAL, ++ PCI_CLASS_INTELLIGENT = 0xe, ++ PCI_CLASS_SATELLITE, ++ PCI_CLASS_CRYPT, ++ PCI_CLASS_DSP, ++ PCI_CLASS_MAX ++} pci_classes; ++ ++typedef enum { ++ PCI_DASDI_SCSI, ++ PCI_DASDI_IDE, ++ PCI_DASDI_FLOPPY, ++ PCI_DASDI_IPI, ++ PCI_DASDI_RAID, ++ PCI_DASDI_OTHER = 0x80 ++} pci_dasdi_subclasses; ++ ++typedef enum { ++ PCI_NET_ETHER, ++ PCI_NET_TOKEN, ++ PCI_NET_FDDI, ++ PCI_NET_ATM, ++ PCI_NET_OTHER = 0x80 ++} pci_net_subclasses; ++ ++typedef enum { ++ PCI_DISPLAY_VGA, ++ PCI_DISPLAY_XGA, ++ PCI_DISPLAY_3D, ++ PCI_DISPLAY_OTHER = 0x80 ++} pci_display_subclasses; ++ ++typedef enum { ++ PCI_MMEDIA_VIDEO, ++ PCI_MMEDIA_AUDIO, ++ PCI_MMEDIA_PHONE, ++ PCI_MEDIA_OTHER = 0x80 ++} pci_mmedia_subclasses; ++ ++typedef enum { ++ PCI_MEMORY_RAM, ++ PCI_MEMORY_FLASH, ++ PCI_MEMORY_OTHER = 0x80 ++} pci_memory_subclasses; ++ ++typedef enum { ++ PCI_BRIDGE_HOST, ++ PCI_BRIDGE_ISA, ++ PCI_BRIDGE_EISA, ++ PCI_BRIDGE_MC, ++ PCI_BRIDGE_PCI, ++ PCI_BRIDGE_PCMCIA, ++ PCI_BRIDGE_NUBUS, ++ PCI_BRIDGE_CARDBUS, ++ PCI_BRIDGE_RACEWAY, ++ PCI_BRIDGE_OTHER = 0x80 ++} pci_bridge_subclasses; ++ ++typedef enum { ++ PCI_COMM_UART, ++ PCI_COMM_PARALLEL, ++ PCI_COMM_MULTIUART, ++ PCI_COMM_MODEM, ++ PCI_COMM_OTHER = 0x80 ++} pci_comm_subclasses; ++ ++typedef enum { ++ PCI_BASE_PIC, ++ PCI_BASE_DMA, ++ PCI_BASE_TIMER, ++ PCI_BASE_RTC, ++ PCI_BASE_PCI_HOTPLUG, ++ PCI_BASE_OTHER = 0x80 ++} pci_base_subclasses; ++ ++typedef enum { ++ PCI_INPUT_KBD, ++ PCI_INPUT_PEN, ++ PCI_INPUT_MOUSE, ++ PCI_INPUT_SCANNER, ++ PCI_INPUT_GAMEPORT, ++ PCI_INPUT_OTHER = 0x80 ++} pci_input_subclasses; ++ ++typedef enum { ++ PCI_DOCK_GENERIC, ++ PCI_DOCK_OTHER = 0x80 ++} pci_dock_subclasses; ++ ++typedef enum { ++ PCI_CPU_386, ++ PCI_CPU_486, ++ PCI_CPU_PENTIUM, ++ PCI_CPU_ALPHA = 0x10, ++ PCI_CPU_POWERPC = 0x20, ++ PCI_CPU_MIPS = 0x30, ++ PCI_CPU_COPROC = 0x40, ++ PCI_CPU_OTHER = 0x80 ++} pci_cpu_subclasses; ++ ++typedef enum { ++ PCI_SERIAL_IEEE1394, ++ PCI_SERIAL_ACCESS, ++ PCI_SERIAL_SSA, ++ PCI_SERIAL_USB, ++ PCI_SERIAL_FIBER, ++ PCI_SERIAL_SMBUS, ++ PCI_SERIAL_OTHER = 0x80 ++} pci_serial_subclasses; ++ ++typedef enum { ++ PCI_INTELLIGENT_I2O, ++} pci_intelligent_subclasses; ++ ++typedef enum { ++ PCI_SATELLITE_TV, ++ PCI_SATELLITE_AUDIO, ++ PCI_SATELLITE_VOICE, ++ PCI_SATELLITE_DATA, ++ PCI_SATELLITE_OTHER = 0x80 ++} pci_satellite_subclasses; ++ ++typedef enum { ++ PCI_CRYPT_NETWORK, ++ PCI_CRYPT_ENTERTAINMENT, ++ PCI_CRYPT_OTHER = 0x80 ++} pci_crypt_subclasses; ++ ++typedef enum { ++ PCI_DSP_DPIO, ++ PCI_DSP_OTHER = 0x80 ++} pci_dsp_subclasses; ++ ++/* Header types */ ++typedef enum { ++ PCI_HEADER_NORMAL, ++ PCI_HEADER_BRIDGE, ++ PCI_HEADER_CARDBUS ++} pci_header_types; ++ ++ ++/* Overlay for a PCI-to-PCI bridge */ ++ ++#define PPB_RSVDA_MAX 2 ++#define PPB_RSVDD_MAX 8 ++ ++typedef struct _ppb_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long rsvd_a[PPB_RSVDA_MAX]; ++ unsigned char prim_bus; ++ unsigned char sec_bus; ++ unsigned char sub_bus; ++ unsigned char sec_lat; ++ unsigned char io_base; ++ unsigned char io_lim; ++ unsigned short sec_status; ++ unsigned short mem_base; ++ unsigned short mem_lim; ++ unsigned short pf_mem_base; ++ unsigned short pf_mem_lim; ++ unsigned long pf_mem_base_hi; ++ unsigned long pf_mem_lim_hi; ++ unsigned short io_base_hi; ++ unsigned short io_lim_hi; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long rsvd_b; ++ unsigned char rsvd_c; ++ unsigned char int_pin; ++ unsigned short bridge_ctrl; ++ unsigned char chip_ctrl; ++ unsigned char diag_ctrl; ++ unsigned short arb_ctrl; ++ unsigned long rsvd_d[PPB_RSVDD_MAX]; ++ unsigned char dev_dep[192]; ++} ppb_config_regs; ++ ++ ++/* PCI CAPABILITY DEFINES */ ++#define PCI_CAP_POWERMGMTCAP_ID 0x01 ++#define PCI_CAP_MSICAP_ID 0x05 ++#define PCI_CAP_PCIECAP_ID 0x10 ++ ++/* Data structure to define the Message Signalled Interrupt facility ++ * Valid for PCI and PCIE configurations */ ++typedef struct _pciconfig_cap_msi { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short msgctrl; ++ unsigned int msgaddr; ++} pciconfig_cap_msi; ++ ++/* Data structure to define the Power managment facility ++ * Valid for PCI and PCIE configurations */ ++typedef struct _pciconfig_cap_pwrmgmt { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short pme_cap; ++ unsigned short pme_sts_ctrl; ++ unsigned char pme_bridge_ext; ++ unsigned char data; ++} pciconfig_cap_pwrmgmt; ++ ++/* Data structure to define the PCIE capability */ ++typedef struct _pciconfig_cap_pcie { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short pcie_cap; ++ unsigned int dev_cap; ++ unsigned short dev_ctrl; ++ unsigned short dev_status; ++ unsigned int link_cap; ++ unsigned short link_ctrl; ++ unsigned short link_status; ++} pciconfig_cap_pcie; ++ ++/* PCIE Enhanced CAPABILITY DEFINES */ ++#define PCIE_EXTCFG_OFFSET 0x100 ++#define PCIE_ADVERRREP_CAPID 0x0001 ++#define PCIE_VC_CAPID 0x0002 ++#define PCIE_DEVSNUM_CAPID 0x0003 ++#define PCIE_PWRBUDGET_CAPID 0x0004 ++ ++/* Header to define the PCIE specific capabilities in the extended config space */ ++typedef struct _pcie_enhanced_caphdr { ++ unsigned short capID; ++ unsigned short cap_ver : 4; ++ unsigned short next_ptr : 12; ++} pcie_enhanced_caphdr; ++ ++ ++/* Everything below is BRCM HND proprietary */ ++ ++#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ ++#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ ++#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ ++#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ ++#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ ++#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ ++#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ ++#define PCI_BACKPLANE_ADDR 0xA0 /* address an arbitrary location on the system backplane */ ++#define PCI_BACKPLANE_DATA 0xA4 /* data at the location specified by above address register */ ++#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ ++#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ ++#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ ++ ++#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ ++#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ ++ ++/* PCI_INT_STATUS */ ++#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ ++ ++/* PCI_INT_MASK */ ++#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ ++#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ ++#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ ++ ++/* PCI_SPROM_CONTROL */ ++#define SPROM_BLANK 0x04 /* indicating a blank sprom */ ++#define SPROM_WRITEEN 0x10 /* sprom write enable */ ++#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ ++ ++#define SPROM_SIZE 256 /* sprom size in 16-bit */ ++#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */ ++ ++/* PCI_CFG_CMD_STAT */ ++#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */ ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pmon_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pmon_osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/pmon_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pmon_osl.h 2005-12-16 23:39:10.752824750 +0100 +@@ -0,0 +1,126 @@ ++/* ++ * MIPS PMON boot loader OS Abstraction Layer. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * $Id$ ++ */ ++ ++#ifndef _pmon_osl_h_ ++#define _pmon_osl_h_ ++ ++#include ++#include ++#include ++#include ++ ++extern int printf(char *fmt,...); ++extern int sprintf(char *dst,char *fmt,...); ++ ++#define OSL_UNCACHED(va) phy2k1(log2phy((va))) ++#define REG_MAP(pa, size) phy2k1((pa)) ++#define REG_UNMAP(va) /* nop */ ++ ++/* Common macros */ ++ ++#define BUSPROBE(val, addr) ((val) = *(addr)) ++ ++#define ASSERT(exp) ++ ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) bzero(buf, size) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) ++ ++/* kludge */ ++#define OSL_PCI_READ_CONFIG(loc, offset, size) ((offset == 8)? 0: 0xffffffff) ++#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) ASSERT(0) ++ ++#define wreg32(r,v) (*(volatile uint32 *)(r) = (v)) ++#define rreg32(r) (*(volatile uint32 *)(r)) ++#ifdef IL_BIGENDIAN ++#define wreg16(r,v) (*(volatile uint16 *)((uint32)r^2) = (v)) ++#define rreg16(r) (*(volatile uint16 *)((uint32)r^2)) ++#else ++#define wreg16(r,v) (*(volatile uint16 *)(r) = (v)) ++#define rreg16(r) (*(volatile uint16 *)(r)) ++#endif ++ ++#include ++#define bcopy(src, dst, len) memcpy(dst, src, len) ++#define bcmp(b1, b2, len) memcmp(b1, b2, len) ++#define bzero(b, len) memset(b, '\0', len) ++ ++/* register access macros */ ++#define R_REG(r) ((sizeof *(r) == sizeof (uint32))? rreg32(r): rreg16(r)) ++#define W_REG(r,v) ((sizeof *(r) == sizeof (uint32))? wreg32(r,(uint32)v): wreg16(r,(uint16)v)) ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) memset(r, '\0', len) ++ ++/* Host/Bus architecture specific swap. Noop for little endian systems, possible swap on big endian */ ++#define BUS_SWAP32(v) (v) ++ ++#define OSL_DELAY(usec) delay_us(usec) ++extern void delay_us(uint usec); ++ ++#define OSL_GETCYCLES(x) ((x) = 0) ++ ++#define osl_attach(pdev) (pdev) ++#define osl_detach(osh) ++ ++#define MALLOC(osh, size) malloc(size) ++#define MFREE(osh, addr, size) free(addr) ++#define MALLOCED(osh) (0) ++#define MALLOC_DUMP(osh, buf, sz) ++#define MALLOC_FAILED(osh) ++extern void *malloc(); ++extern void free(void *addr); ++ ++#define DMA_CONSISTENT_ALIGN sizeof (int) ++#define DMA_ALLOC_CONSISTENT(osh, size, pap) et_dma_alloc_consistent(osh, size, pap) ++#define DMA_FREE_CONSISTENT(osh, va, size, pa) ++extern void* et_dma_alloc_consistent(void *osh, uint size, ulong *pap); ++#define DMA_TX 0 ++#define DMA_RX 1 ++ ++#define DMA_MAP(osh, va, size, direction, p) osl_dma_map(osh, (void*)va, size, direction) ++#define DMA_UNMAP(osh, pa, size, direction, p) /* nop */ ++extern void* osl_dma_map(void *osh, void *va, uint size, uint direction); ++ ++struct lbuf { ++ struct lbuf *next; /* pointer to next lbuf on freelist */ ++ uchar *buf; /* pointer to buffer */ ++ uint len; /* nbytes of data */ ++}; ++ ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 ++ ++/* packet primitives */ ++#define PKTGET(drv, len, send) et_pktget(drv, len, send) ++#define PKTFREE(drv, lb, send) et_pktfree(drv, (struct lbuf*)lb, send) ++#define PKTDATA(drv, lb) ((uchar*)OSL_UNCACHED(((struct lbuf*)lb)->buf)) ++#define PKTLEN(drv, lb) ((struct lbuf*)lb)->len ++#define PKTHEADROOM(drv, lb) (0) ++#define PKTTAILROOM(drv, lb) (0) ++#define PKTNEXT(drv, lb) NULL ++#define PKTSETNEXT(lb, x) ASSERT(0) ++#define PKTSETLEN(drv, lb, bytes) ((struct lbuf*)lb)->len = bytes ++#define PKTPUSH(drv, lb, bytes) ASSERT(0) ++#define PKTPULL(drv, lb, bytes) ASSERT(0) ++#define PKTDUP(drv, lb) ASSERT(0) ++#define PKTLINK(lb) ((struct lbuf*)lb)->next ++#define PKTSETLINK(lb, x) ((struct lbuf*)lb)->next = (struct lbuf*)x ++#define PKTPRIO(lb) (0) ++#define PKTSETPRIO(lb, x) do {} while (0) ++extern void *et_pktget(void *drv, uint len, bool send); ++extern void et_pktfree(void *drv, struct lbuf *lb, bool send); ++ ++#endif /* _pmon_osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/802.11.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/802.11.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/802.11.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/802.11.h 2005-12-16 23:39:10.752824750 +0100 +@@ -0,0 +1,930 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * Fundamental types and constants relating to 802.11 ++ * ++ * $Id$ ++ */ ++ ++#ifndef _802_11_H_ ++#define _802_11_H_ ++ ++#ifndef _TYPEDEFS_H_ ++#include ++#endif ++ ++#ifndef _NET_ETHERNET_H_ ++#include ++#endif ++ ++#include ++ ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */ ++ ++/* Generic 802.11 frame constants */ ++#define DOT11_A3_HDR_LEN 24 ++#define DOT11_A4_HDR_LEN 30 ++#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN ++#define DOT11_FCS_LEN 4 ++#define DOT11_ICV_LEN 4 ++#define DOT11_ICV_AES_LEN 8 ++#define DOT11_QOS_LEN 2 ++ ++#define DOT11_KEY_INDEX_SHIFT 6 ++#define DOT11_IV_LEN 4 ++#define DOT11_IV_TKIP_LEN 8 ++#define DOT11_IV_AES_OCB_LEN 4 ++#define DOT11_IV_AES_CCM_LEN 8 ++ ++/* Includes MIC */ ++#define DOT11_MAX_MPDU_BODY_LEN 2304 ++/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */ ++#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ ++ DOT11_QOS_LEN + \ ++ DOT11_IV_AES_CCM_LEN + \ ++ DOT11_MAX_MPDU_BODY_LEN + \ ++ DOT11_ICV_LEN + \ ++ DOT11_FCS_LEN) ++ ++#define DOT11_MAX_SSID_LEN 32 ++ ++/* dot11RTSThreshold */ ++#define DOT11_DEFAULT_RTS_LEN 2347 ++#define DOT11_MAX_RTS_LEN 2347 ++ ++/* dot11FragmentationThreshold */ ++#define DOT11_MIN_FRAG_LEN 256 ++#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength of the attached PHY */ ++#define DOT11_DEFAULT_FRAG_LEN 2346 ++ ++/* dot11BeaconPeriod */ ++#define DOT11_MIN_BEACON_PERIOD 1 ++#define DOT11_MAX_BEACON_PERIOD 0xFFFF ++ ++/* dot11DTIMPeriod */ ++#define DOT11_MIN_DTIM_PERIOD 1 ++#define DOT11_MAX_DTIM_PERIOD 0xFF ++ ++/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */ ++#define DOT11_LLC_SNAP_HDR_LEN 8 ++#define DOT11_OUI_LEN 3 ++struct dot11_llc_snap_header { ++ uint8 dsap; /* always 0xAA */ ++ uint8 ssap; /* always 0xAA */ ++ uint8 ctl; /* always 0x03 */ ++ uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00 ++ Bridge-Tunnel: 0x00 0x00 0xF8 */ ++ uint16 type; /* ethertype */ ++} PACKED; ++ ++/* RFC1042 header used by 802.11 per 802.1H */ ++#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) ++ ++/* Generic 802.11 MAC header */ ++/* ++ * N.B.: This struct reflects the full 4 address 802.11 MAC header. ++ * The fields are defined such that the shorter 1, 2, and 3 ++ * address headers just use the first k fields. ++ */ ++struct dot11_header { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr a1; /* address 1 */ ++ struct ether_addr a2; /* address 2 */ ++ struct ether_addr a3; /* address 3 */ ++ uint16 seq; /* sequence control */ ++ struct ether_addr a4; /* address 4 */ ++} PACKED; ++ ++/* Control frames */ ++ ++struct dot11_rts_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++ struct ether_addr ta; /* transmitter address */ ++} PACKED; ++#define DOT11_RTS_LEN 16 ++ ++struct dot11_cts_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++} PACKED; ++#define DOT11_CTS_LEN 10 ++ ++struct dot11_ack_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++} PACKED; ++#define DOT11_ACK_LEN 10 ++ ++struct dot11_ps_poll_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* AID */ ++ struct ether_addr bssid; /* receiver address, STA in AP */ ++ struct ether_addr ta; /* transmitter address */ ++} PACKED; ++#define DOT11_PS_POLL_LEN 16 ++ ++struct dot11_cf_end_frame { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr ra; /* receiver address */ ++ struct ether_addr bssid; /* transmitter address, STA in AP */ ++} PACKED; ++#define DOT11_CS_END_LEN 16 ++ ++/* Management frame header */ ++struct dot11_management_header { ++ uint16 fc; /* frame control */ ++ uint16 durid; /* duration/ID */ ++ struct ether_addr da; /* receiver address */ ++ struct ether_addr sa; /* transmitter address */ ++ struct ether_addr bssid; /* BSS ID */ ++ uint16 seq; /* sequence control */ ++} PACKED; ++#define DOT11_MGMT_HDR_LEN 24 ++ ++/* Management frame payloads */ ++ ++struct dot11_bcn_prb { ++ uint32 timestamp[2]; ++ uint16 beacon_interval; ++ uint16 capability; ++} PACKED; ++#define DOT11_BCN_PRB_LEN 12 ++ ++struct dot11_auth { ++ uint16 alg; /* algorithm */ ++ uint16 seq; /* sequence control */ ++ uint16 status; /* status code */ ++} PACKED; ++#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge info elt */ ++ ++struct dot11_assoc_req { ++ uint16 capability; /* capability information */ ++ uint16 listen; /* listen interval */ ++} PACKED; ++#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */ ++ ++struct dot11_reassoc_req { ++ uint16 capability; /* capability information */ ++ uint16 listen; /* listen interval */ ++ struct ether_addr ap; /* Current AP address */ ++} PACKED; ++#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */ ++ ++struct dot11_assoc_resp { ++ uint16 capability; /* capability information */ ++ uint16 status; /* status code */ ++ uint16 aid; /* association ID */ ++} PACKED; ++ ++struct dot11_action_measure { ++ uint8 category; ++ uint8 action; ++ uint8 token; ++ uint8 data[1]; ++} PACKED; ++#define DOT11_ACTION_MEASURE_LEN 3 ++ ++struct dot11_action_switch_channel { ++ uint8 category; ++ uint8 action; ++ uint8 data[5]; /* for switch IE */ ++} PACKED; ++ ++/************** ++ 802.11h related definitions. ++**************/ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 power; ++} dot11_power_cnst_t; ++ ++typedef struct { ++ uint8 min; ++ uint8 max; ++} dot11_power_cap_t; ++ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 tx_pwr; ++ uint8 margin; ++} dot11_tpc_rep_t; ++#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */ ++ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 first_channel; ++ uint8 num_channels; ++} dot11_supp_channels_t; ++ ++/* csa mode type */ ++#define DOT11_CSA_MODE_ADVISORY 0 ++#define DOT11_CSA_MODE_NO_TX 1 ++struct dot11_channel_switch { ++ uint8 id; ++ uint8 len; ++ uint8 mode; ++ uint8 channel; ++ uint8 count; ++} PACKED; ++typedef struct dot11_channel_switch dot11_channel_switch_t; ++ ++/* length of IE data, not including 2 byte header */ ++#define DOT11_SWITCH_IE_LEN 3 ++ ++/* 802.11h Measurement Request/Report IEs */ ++/* Measurement Type field */ ++#define DOT11_MEASURE_TYPE_BASIC 0 ++#define DOT11_MEASURE_TYPE_CCA 1 ++#define DOT11_MEASURE_TYPE_RPI 2 ++ ++/* Measurement Mode field */ ++ ++/* Measurement Request Modes */ ++#define DOT11_MEASURE_MODE_ENABLE (1<<1) ++#define DOT11_MEASURE_MODE_REQUEST (1<<2) ++#define DOT11_MEASURE_MODE_REPORT (1<<3) ++/* Measurement Report Modes */ ++#define DOT11_MEASURE_MODE_LATE (1<<0) ++#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) ++#define DOT11_MEASURE_MODE_REFUSED (1<<2) ++/* Basic Measurement Map bits */ ++#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) ++#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) ++#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) ++#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) ++#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) ++ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 token; ++ uint8 mode; ++ uint8 type; ++ uint8 channel; ++ uint8 start_time[8]; ++ uint16 duration; ++} dot11_meas_req_t; ++#define DOT11_MNG_IE_MREQ_LEN 14 ++/* length of Measure Request IE data not including variable len */ ++#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 ++ ++struct dot11_meas_rep { ++ uint8 id; ++ uint8 len; ++ uint8 token; ++ uint8 mode; ++ uint8 type; ++ union ++ { ++ struct { ++ uint8 channel; ++ uint8 start_time[8]; ++ uint16 duration; ++ uint8 map; ++ } PACKED basic; ++ uint8 data[1]; ++ } PACKED rep; ++} PACKED; ++typedef struct dot11_meas_rep dot11_meas_rep_t; ++ ++/* length of Measure Report IE data not including variable len */ ++#define DOT11_MNG_IE_MREP_FIXED_LEN 3 ++ ++struct dot11_meas_rep_basic { ++ uint8 channel; ++ uint8 start_time[8]; ++ uint16 duration; ++ uint8 map; ++} PACKED; ++typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; ++#define DOT11_MEASURE_BASIC_REP_LEN 12 ++ ++struct dot11_quiet { ++ uint8 id; ++ uint8 len; ++ uint8 count; /* TBTTs until beacon interval in quiet starts */ ++ uint8 period; /* Beacon intervals between periodic quiet periods ? */ ++ uint16 duration;/* Length of quiet period, in TU's */ ++ uint16 offset; /* TU's offset from TBTT in Count field */ ++} PACKED; ++typedef struct dot11_quiet dot11_quiet_t; ++ ++typedef struct { ++ uint8 channel; ++ uint8 map; ++} chan_map_tuple_t; ++ ++typedef struct { ++ uint8 id; ++ uint8 len; ++ uint8 eaddr[ETHER_ADDR_LEN]; ++ uint8 interval; ++ chan_map_tuple_t map[1]; ++} dot11_ibss_dfs_t; ++ ++/* WME Elements */ ++#define WME_OUI "\x00\x50\xf2" ++#define WME_VER 1 ++#define WME_TYPE 2 ++#define WME_SUBTYPE_IE 0 /* Information Element */ ++#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */ ++#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */ ++ ++/* WME Access Category Indices (ACIs) */ ++#define AC_BE 0 /* Best Effort */ ++#define AC_BK 1 /* Background */ ++#define AC_VI 2 /* Video */ ++#define AC_VO 3 /* Voice */ ++#define AC_MAX 4 ++ ++/* WME Information Element (IE) */ ++struct wme_ie { ++ uint8 oui[3]; ++ uint8 type; ++ uint8 subtype; ++ uint8 version; ++ uint8 acinfo; ++} PACKED; ++typedef struct wme_ie wme_ie_t; ++#define WME_IE_LEN 7 ++ ++struct wme_acparam { ++ uint8 ACI; ++ uint8 ECW; ++ uint16 TXOP; /* stored in network order (ls octet first) */ ++} PACKED; ++typedef struct wme_acparam wme_acparam_t; ++ ++/* WME Parameter Element (PE) */ ++struct wme_params { ++ uint8 oui[3]; ++ uint8 type; ++ uint8 subtype; ++ uint8 version; ++ uint8 acinfo; ++ uint8 rsvd; ++ wme_acparam_t acparam[4]; ++} PACKED; ++typedef struct wme_params wme_params_t; ++#define WME_PARAMS_IE_LEN 24 ++ ++/* acinfo */ ++#define WME_COUNT_MASK 0x0f ++/* ACI */ ++#define WME_AIFS_MASK 0x0f ++#define WME_ACM_MASK 0x10 ++#define WME_ACI_MASK 0x60 ++#define WME_ACI_SHIFT 5 ++/* ECW */ ++#define WME_CWMIN_MASK 0x0f ++#define WME_CWMAX_MASK 0xf0 ++#define WME_CWMAX_SHIFT 4 ++ ++#define WME_TXOP_UNITS 32 ++ ++/* AP: default params to be announced in the Beacon Frames/Probe Responses Table 12 WME Draft*/ ++/* AP: default params to be Used in the AP Side Table 14 WME Draft January 2004 802.11-03-504r5 */ ++#define WME_AC_BK_ACI_STA 0x27 ++#define WME_AC_BK_ECW_STA 0xA4 ++#define WME_AC_BK_TXOP_STA 0x0000 ++#define WME_AC_BE_ACI_STA 0x03 ++#define WME_AC_BE_ECW_STA 0xA4 ++#define WME_AC_BE_TXOP_STA 0x0000 ++#define WME_AC_VI_ACI_STA 0x42 ++#define WME_AC_VI_ECW_STA 0x43 ++#define WME_AC_VI_TXOP_STA 0x005e ++#define WME_AC_VO_ACI_STA 0x62 ++#define WME_AC_VO_ECW_STA 0x32 ++#define WME_AC_VO_TXOP_STA 0x002f ++ ++#define WME_AC_BK_ACI_AP 0x27 ++#define WME_AC_BK_ECW_AP 0xA4 ++#define WME_AC_BK_TXOP_AP 0x0000 ++#define WME_AC_BE_ACI_AP 0x03 ++#define WME_AC_BE_ECW_AP 0x64 ++#define WME_AC_BE_TXOP_AP 0x0000 ++#define WME_AC_VI_ACI_AP 0x41 ++#define WME_AC_VI_ECW_AP 0x43 ++#define WME_AC_VI_TXOP_AP 0x005e ++#define WME_AC_VO_ACI_AP 0x61 ++#define WME_AC_VO_ECW_AP 0x32 ++#define WME_AC_VO_TXOP_AP 0x002f ++ ++/* WME Traffic Specification (TSPEC) element */ ++#define WME_SUBTYPE_TSPEC 2 ++#define WME_TSPEC_HDR_LEN 2 ++#define WME_TSPEC_BODY_OFF 2 ++struct wme_tspec { ++ uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */ ++ uint8 type; /* WME_TYPE */ ++ uint8 subtype; /* WME_SUBTYPE_TSPEC */ ++ uint8 version; /* WME_VERSION */ ++ uint16 ts_info; /* TS Info */ ++ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ ++ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ ++ uint32 min_service_interval; /* Minimum Service Interval (us) */ ++ uint32 max_service_interval; /* Maximum Service Interval (us) */ ++ uint32 inactivity_interval; /* Inactivity Interval (us) */ ++ uint32 service_start; /* Service Start Time (us) */ ++ uint32 min_rate; /* Minimum Data Rate (bps) */ ++ uint32 mean_rate; /* Mean Data Rate (bps) */ ++ uint32 max_burst_size; /* Maximum Burst Size (bytes) */ ++ uint32 min_phy_rate; /* Minimum PHY Rate (bps) */ ++ uint32 peak_rate; /* Peak Data Rate (bps) */ ++ uint32 delay_bound; /* Delay Bound (us) */ ++ uint16 surplus_bandwidth; /* Surplus Bandwidth Allowance Factor */ ++ uint16 medium_time; /* Medium Time (32 us/s periods) */ ++} PACKED; ++typedef struct wme_tspec wme_tspec_t; ++#define WME_TSPEC_LEN 56 /* not including 2-byte header */ ++ ++/* ts_info */ ++/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */ ++#define TS_INFO_PRIO_SHIFT_HI 11 ++#define TS_INFO_PRIO_MASK_HI (0x7 << TS_INFO_PRIO_SHIFT_HI) ++#define TS_INFO_PRIO_SHIFT_LO 1 ++#define TS_INFO_PRIO_MASK_LO (0x7 << TS_INFO_PRIO_SHIFT_LO) ++#define TS_INFO_CONTENTION_SHIFT 7 ++#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) ++#define TS_INFO_DIRECTION_SHIFT 5 ++#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) ++#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) ++#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) ++#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) ++ ++/* nom_msdu_size */ ++#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */ ++#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */ ++ ++/* surplus_bandwidth */ ++/* Represented as 3 bits of integer, binary point, 13 bits fraction */ ++#define INTEGER_SHIFT 13 ++#define FRACTION_MASK 0x1FFF ++ ++/* Management Notification Frame */ ++struct dot11_management_notification { ++ uint8 category; /* DOT11_ACTION_NOTIFICATION */ ++ uint8 action; ++ uint8 token; ++ uint8 status; ++ uint8 data[1]; /* Elements */ ++} PACKED; ++#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */ ++ ++/* WME Action Codes */ ++#define WME_SETUP_REQUEST 0 ++#define WME_SETUP_RESPONSE 1 ++#define WME_TEARDOWN 2 ++ ++/* WME Setup Response Status Codes */ ++#define WME_ADMISSION_ACCEPTED 0 ++#define WME_INVALID_PARAMETERS 1 ++#define WME_ADMISSION_REFUSED 3 ++ ++/* Macro to take a pointer to a beacon or probe response ++ * header and return the char* pointer to the SSID info element ++ */ ++#define BCN_PRB_SSID(hdr) ((char*)(hdr) + DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_LEN) ++ ++/* Authentication frame payload constants */ ++#define DOT11_OPEN_SYSTEM 0 ++#define DOT11_SHARED_KEY 1 ++#define DOT11_CHALLENGE_LEN 128 ++ ++/* Frame control macros */ ++#define FC_PVER_MASK 0x3 ++#define FC_PVER_SHIFT 0 ++#define FC_TYPE_MASK 0xC ++#define FC_TYPE_SHIFT 2 ++#define FC_SUBTYPE_MASK 0xF0 ++#define FC_SUBTYPE_SHIFT 4 ++#define FC_TODS 0x100 ++#define FC_TODS_SHIFT 8 ++#define FC_FROMDS 0x200 ++#define FC_FROMDS_SHIFT 9 ++#define FC_MOREFRAG 0x400 ++#define FC_MOREFRAG_SHIFT 10 ++#define FC_RETRY 0x800 ++#define FC_RETRY_SHIFT 11 ++#define FC_PM 0x1000 ++#define FC_PM_SHIFT 12 ++#define FC_MOREDATA 0x2000 ++#define FC_MOREDATA_SHIFT 13 ++#define FC_WEP 0x4000 ++#define FC_WEP_SHIFT 14 ++#define FC_ORDER 0x8000 ++#define FC_ORDER_SHIFT 15 ++ ++/* sequence control macros */ ++#define SEQNUM_SHIFT 4 ++#define FRAGNUM_MASK 0xF ++ ++/* Frame Control type/subtype defs */ ++ ++/* FC Types */ ++#define FC_TYPE_MNG 0 ++#define FC_TYPE_CTL 1 ++#define FC_TYPE_DATA 2 ++ ++/* Management Subtypes */ ++#define FC_SUBTYPE_ASSOC_REQ 0 ++#define FC_SUBTYPE_ASSOC_RESP 1 ++#define FC_SUBTYPE_REASSOC_REQ 2 ++#define FC_SUBTYPE_REASSOC_RESP 3 ++#define FC_SUBTYPE_PROBE_REQ 4 ++#define FC_SUBTYPE_PROBE_RESP 5 ++#define FC_SUBTYPE_BEACON 8 ++#define FC_SUBTYPE_ATIM 9 ++#define FC_SUBTYPE_DISASSOC 10 ++#define FC_SUBTYPE_AUTH 11 ++#define FC_SUBTYPE_DEAUTH 12 ++#define FC_SUBTYPE_ACTION 13 ++ ++/* Control Subtypes */ ++#define FC_SUBTYPE_PS_POLL 10 ++#define FC_SUBTYPE_RTS 11 ++#define FC_SUBTYPE_CTS 12 ++#define FC_SUBTYPE_ACK 13 ++#define FC_SUBTYPE_CF_END 14 ++#define FC_SUBTYPE_CF_END_ACK 15 ++ ++/* Data Subtypes */ ++#define FC_SUBTYPE_DATA 0 ++#define FC_SUBTYPE_DATA_CF_ACK 1 ++#define FC_SUBTYPE_DATA_CF_POLL 2 ++#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 ++#define FC_SUBTYPE_NULL 4 ++#define FC_SUBTYPE_CF_ACK 5 ++#define FC_SUBTYPE_CF_POLL 6 ++#define FC_SUBTYPE_CF_ACK_POLL 7 ++#define FC_SUBTYPE_QOS_DATA 8 ++#define FC_SUBTYPE_QOS_NULL 12 ++ ++/* type-subtype combos */ ++#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) ++ ++#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) ++ ++#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) ++#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) ++#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) ++#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) ++#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) ++#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) ++#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) ++#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) ++#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) ++#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) ++#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) ++ ++#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) ++#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) ++#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) ++#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) ++#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) ++#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) ++ ++#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) ++#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) ++#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) ++#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) ++#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) ++ ++/* QoS Control Field */ ++ ++/* 802.1D Tag */ ++#define QOS_PRIO_SHIFT 0 ++#define QOS_PRIO_MASK 0x0007 ++#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) ++ ++#define QOS_TID_SHIFT 0 ++#define QOS_TID_MASK 0x000f ++#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) ++ ++/* Ack Policy (0 means Acknowledge) */ ++#define QOS_ACK_SHIFT 5 ++#define QOS_ACK_MASK 0x0060 ++#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) ++ ++/* Management Frames */ ++ ++/* Management Frame Constants */ ++ ++/* Fixed fields */ ++#define DOT11_MNG_AUTH_ALGO_LEN 2 ++#define DOT11_MNG_AUTH_SEQ_LEN 2 ++#define DOT11_MNG_BEACON_INT_LEN 2 ++#define DOT11_MNG_CAP_LEN 2 ++#define DOT11_MNG_AP_ADDR_LEN 6 ++#define DOT11_MNG_LISTEN_INT_LEN 2 ++#define DOT11_MNG_REASON_LEN 2 ++#define DOT11_MNG_AID_LEN 2 ++#define DOT11_MNG_STATUS_LEN 2 ++#define DOT11_MNG_TIMESTAMP_LEN 8 ++ ++/* DUR/ID field in assoc resp is 0xc000 | AID */ ++#define DOT11_AID_MASK 0x3fff ++ ++/* Reason Codes */ ++#define DOT11_RC_RESERVED 0 ++#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */ ++#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */ ++#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station is ++ leaving (or has left) IBSS or ESS */ ++#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */ ++#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle ++ all currently associated stations */ ++#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from ++ nonauthenticated station */ ++#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from ++ nonassociated station */ ++#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is ++ leaving (or has left) BSS */ ++#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is ++ not authenticated with responding station */ ++#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */ ++ ++/* Status Codes */ ++#define DOT11_STATUS_SUCCESS 0 /* Successful */ ++#define DOT11_STATUS_FAILURE 1 /* Unspecified failure */ ++#define DOT11_STATUS_CAP_MISMATCH 10 /* Cannot support all requested capabilities ++ in the Capability Information field */ ++#define DOT11_STATUS_REASSOC_FAIL 11 /* Reassociation denied due to inability to ++ confirm that association exists */ ++#define DOT11_STATUS_ASSOC_FAIL 12 /* Association denied due to reason outside ++ the scope of this standard */ ++#define DOT11_STATUS_AUTH_MISMATCH 13 /* Responding station does not support the ++ specified authentication algorithm */ ++#define DOT11_STATUS_AUTH_SEQ 14 /* Received an Authentication frame with ++ authentication transaction sequence number ++ out of expected sequence */ ++#define DOT11_STATUS_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of challenge failure */ ++#define DOT11_STATUS_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout waiting ++ for next frame in sequence */ ++#define DOT11_STATUS_ASSOC_BUSY_FAIL 17 /* Association denied because AP is unable to ++ handle additional associated stations */ ++#define DOT11_STATUS_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting station ++ not supporting all of the data rates in the ++ BSSBasicRateSet parameter */ ++#define DOT11_STATUS_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting station ++ not supporting the Short Preamble option */ ++#define DOT11_STATUS_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting station ++ not supporting the PBCC Modulation option */ ++#define DOT11_STATUS_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting station ++ not supporting the Channel Agility option */ ++#define DOT11_STATUS_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum Management ++ capability is required. */ ++#define DOT11_STATUS_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info in the ++ Power Cap element is unacceptable. */ ++#define DOT11_STATUS_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info in the ++ Supported Channel element is unacceptable */ ++#define DOT11_STATUS_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting station ++ not supporting the Short Slot Time option */ ++#define DOT11_STATUS_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting station ++ not supporting the ER-PBCC Modulation option */ ++#define DOT11_STATUS_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting station ++ not supporting the DSS-OFDM option */ ++ ++/* Info Elts, length of INFORMATION portion of Info Elts */ ++#define DOT11_MNG_DS_PARAM_LEN 1 ++#define DOT11_MNG_IBSS_PARAM_LEN 2 ++ ++/* TIM Info element has 3 bytes fixed info in INFORMATION field, ++ * followed by 1 to 251 bytes of Partial Virtual Bitmap */ ++#define DOT11_MNG_TIM_FIXED_LEN 3 ++#define DOT11_MNG_TIM_DTIM_COUNT 0 ++#define DOT11_MNG_TIM_DTIM_PERIOD 1 ++#define DOT11_MNG_TIM_BITMAP_CTL 2 ++#define DOT11_MNG_TIM_PVB 3 ++ ++/* TLV defines */ ++#define TLV_TAG_OFF 0 ++#define TLV_LEN_OFF 1 ++#define TLV_HDR_LEN 2 ++#define TLV_BODY_OFF 2 ++ ++/* Management Frame Information Element IDs */ ++#define DOT11_MNG_SSID_ID 0 ++#define DOT11_MNG_RATES_ID 1 ++#define DOT11_MNG_FH_PARMS_ID 2 ++#define DOT11_MNG_DS_PARMS_ID 3 ++#define DOT11_MNG_CF_PARMS_ID 4 ++#define DOT11_MNG_TIM_ID 5 ++#define DOT11_MNG_IBSS_PARMS_ID 6 ++#define DOT11_MNG_COUNTRY_ID 7 ++#define DOT11_MNG_HOPPING_PARMS_ID 8 ++#define DOT11_MNG_HOPPING_TABLE_ID 9 ++#define DOT11_MNG_REQUEST_ID 10 ++#define DOT11_MNG_CHALLENGE_ID 16 ++#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */ ++#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */ ++#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */ ++#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */ ++#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */ ++#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement*/ ++#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */ ++#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */ ++#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */ ++#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ ++#define DOT11_MNG_ERP_ID 42 ++#define DOT11_MNG_NONERP_ID 47 ++#ifdef BCMWPA2 ++#define DOT11_MNG_RSN_ID 48 ++#endif /* BCMWPA2 */ ++#define DOT11_MNG_EXT_RATES_ID 50 ++#define DOT11_MNG_WPA_ID 221 ++#define DOT11_MNG_PROPR_ID 221 ++ ++/* ERP info element bit values */ ++#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */ ++#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present in the BSS */ ++#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for ERP-OFDM frames */ ++#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, 1 == not allowed */ ++ ++/* Capability Information Field */ ++#define DOT11_CAP_ESS 0x0001 ++#define DOT11_CAP_IBSS 0x0002 ++#define DOT11_CAP_POLLABLE 0x0004 ++#define DOT11_CAP_POLL_RQ 0x0008 ++#define DOT11_CAP_PRIVACY 0x0010 ++#define DOT11_CAP_SHORT 0x0020 ++#define DOT11_CAP_PBCC 0x0040 ++#define DOT11_CAP_AGILITY 0x0080 ++#define DOT11_CAP_SPECTRUM 0x0100 ++#define DOT11_CAP_SHORTSLOT 0x0400 ++#define DOT11_CAP_CCK_OFDM 0x2000 ++ ++/* Action Frame Constants */ ++#define DOT11_ACTION_CAT_ERR_MASK 0x80 ++#define DOT11_ACTION_CAT_SPECT_MNG 0x00 ++#define DOT11_ACTION_NOTIFICATION 0x11 /* 17 */ ++ ++#define DOT11_ACTION_ID_M_REQ 0 ++#define DOT11_ACTION_ID_M_REP 1 ++#define DOT11_ACTION_ID_TPC_REQ 2 ++#define DOT11_ACTION_ID_TPC_REP 3 ++#define DOT11_ACTION_ID_CHANNEL_SWITCH 4 ++ ++/* MLME Enumerations */ ++#define DOT11_BSSTYPE_INFRASTRUCTURE 0 ++#define DOT11_BSSTYPE_INDEPENDENT 1 ++#define DOT11_BSSTYPE_ANY 2 ++#define DOT11_SCANTYPE_ACTIVE 0 ++#define DOT11_SCANTYPE_PASSIVE 1 ++ ++/* 802.11 A PHY constants */ ++#define APHY_SLOT_TIME 9 ++#define APHY_SIFS_TIME 16 ++#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) ++#define APHY_PREAMBLE_TIME 16 ++#define APHY_SIGNAL_TIME 4 ++#define APHY_SYMBOL_TIME 4 ++#define APHY_SERVICE_NBITS 16 ++#define APHY_TAIL_NBITS 6 ++#define APHY_CWMIN 15 ++ ++/* 802.11 B PHY constants */ ++#define BPHY_SLOT_TIME 20 ++#define BPHY_SIFS_TIME 10 ++#define BPHY_DIFS_TIME 50 ++#define BPHY_PLCP_TIME 192 ++#define BPHY_PLCP_SHORT_TIME 96 ++#define BPHY_CWMIN 31 ++ ++/* 802.11 G constants */ ++#define DOT11_OFDM_SIGNAL_EXTENSION 6 ++ ++#define PHY_CWMAX 1023 ++ ++#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */ ++ ++/* dot11Counters Table - 802.11 spec., Annex D */ ++typedef struct d11cnt { ++ uint32 txfrag; /* dot11TransmittedFragmentCount */ ++ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ ++ uint32 txfail; /* dot11FailedCount */ ++ uint32 txretry; /* dot11RetryCount */ ++ uint32 txretrie; /* dot11MultipleRetryCount */ ++ uint32 rxdup; /* dot11FrameduplicateCount */ ++ uint32 txrts; /* dot11RTSSuccessCount */ ++ uint32 txnocts; /* dot11RTSFailureCount */ ++ uint32 txnoack; /* dot11ACKFailureCount */ ++ uint32 rxfrag; /* dot11ReceivedFragmentCount */ ++ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ ++ uint32 rxcrc; /* dot11FCSErrorCount */ ++ uint32 txfrmsnt; /* dot11TransmittedFrameCount */ ++ uint32 rxundec; /* dot11WEPUndecryptableCount */ ++} d11cnt_t; ++ ++/* BRCM OUI */ ++#define BRCM_OUI "\x00\x10\x18" ++ ++/* BRCM info element */ ++struct brcm_ie { ++ uchar id; /* 221, DOT11_MNG_PROPR_ID */ ++ uchar len; ++ uchar oui[3]; ++ uchar ver; ++ uchar assoc; /* # of assoc STAs */ ++ uchar flags; /* misc flags */ ++} PACKED; ++#define BRCM_IE_LEN 8 ++typedef struct brcm_ie brcm_ie_t; ++#define BRCM_IE_VER 2 ++#define BRCM_IE_LEGACY_AES_VER 1 ++ ++/* brcm_ie flags */ ++#define BRF_ABCAP 0x1 /* afterburner capable */ ++#define BRF_ABRQRD 0x2 /* afterburner requested */ ++#define BRF_LZWDS 0x4 /* lazy wds enabled */ ++#define BRF_ABCOUNTER_MASK 0xf0 /* afterburner wds "state" counter */ ++#define BRF_ABCOUNTER_SHIFT 4 ++ ++#define AB_WDS_TIMEOUT_MAX 15 /* afterburner wds Max count indicating not locally capable */ ++#define AB_WDS_TIMEOUT_MIN 1 /* afterburner wds, use zero count as indicating "downrev" */ ++ ++ ++/* OUI for BRCM proprietary IE */ ++#define BRCM_PROP_OUI "\x00\x90\x4C" ++ ++/* Vendor IE structure */ ++struct vndr_ie { ++ uchar id; ++ uchar len; ++ uchar oui [3]; ++ uchar data [1]; /* Variable size data */ ++}PACKED; ++typedef struct vndr_ie vndr_ie_t; ++ ++#define VNDR_IE_HDR_LEN 2 /* id + len field */ ++#define VNDR_IE_MIN_LEN 3 /* size of the oui field */ ++#define VNDR_IE_MAX_LEN 256 ++ ++/* WPA definitions */ ++#define WPA_VERSION 1 ++#define WPA_OUI "\x00\x50\xF2" ++ ++#ifdef BCMWPA2 ++#define WPA2_VERSION 1 ++#define WPA2_VERSION_LEN 2 ++#define WPA2_OUI "\x00\x0F\xAC" ++#endif /* BCMWPA2 */ ++ ++#define WPA_OUI_LEN 3 ++ ++/* RSN authenticated key managment suite */ ++#define RSN_AKM_NONE 0 /* None (IBSS) */ ++#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ ++#define RSN_AKM_PSK 2 /* Pre-shared Key */ ++ ++ ++/* Key related defines */ ++#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */ ++#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */ ++#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */ ++#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */ ++ ++#define WEP1_KEY_SIZE 5 /* max size of any WEP key */ ++#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */ ++#define WEP128_KEY_SIZE 13 /* max size of any WEP key */ ++#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */ ++#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */ ++#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */ ++#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */ ++#define TKIP_KEY_SIZE 32 /* size of any TKIP key */ ++#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */ ++#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */ ++#define TKIP_MIC_SUP_RX 16 /* offset to Supplicant MIC RX key */ ++#define TKIP_MIC_SUP_TX 24 /* offset to Supplicant MIC TX key */ ++#define AES_KEY_SIZE 16 /* size of AES key */ ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif /* _802_11_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmeth.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmeth.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmeth.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmeth.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,103 @@ ++/* ++ * Broadcom Ethernettype protocol definitions ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++/* ++ * Broadcom Ethernet protocol defines ++ * ++ */ ++ ++#ifndef _BCMETH_H_ ++#define _BCMETH_H_ ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++/* ETHER_TYPE_BRCM is defined in ethernet.h */ ++ ++/* ++ * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field ++ * in one of two formats: (only subtypes 32768-65535 are in use now) ++ * ++ * subtypes 0-32767: ++ * 8 bit subtype (0-127) ++ * 8 bit length in bytes (0-255) ++ * ++ * subtypes 32768-65535: ++ * 16 bit big-endian subtype ++ * 16 bit big-endian length in bytes (0-65535) ++ * ++ * length is the number of additional bytes beyond the 4 or 6 byte header ++ * ++ * Reserved values: ++ * 0 reserved ++ * 5-15 reserved for iLine protocol assignments ++ * 17-126 reserved, assignable ++ * 127 reserved ++ * 32768 reserved ++ * 32769-65534 reserved, assignable ++ * 65535 reserved ++ */ ++ ++/* ++ * While adding the subtypes and their specific processing code make sure ++ * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition ++ */ ++ ++#define BCMILCP_SUBTYPE_RATE 1 ++#define BCMILCP_SUBTYPE_LINK 2 ++#define BCMILCP_SUBTYPE_CSA 3 ++#define BCMILCP_SUBTYPE_LARQ 4 ++#define BCMILCP_SUBTYPE_VENDOR 5 ++#define BCMILCP_SUBTYPE_FLH 17 ++ ++#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 ++#define BCMILCP_SUBTYPE_CERT 32770 ++#define BCMILCP_SUBTYPE_SES 32771 ++ ++ ++#define BCMILCP_BCM_SUBTYPE_RESERVED 0 ++#define BCMILCP_BCM_SUBTYPE_EVENT 1 ++#define BCMILCP_BCM_SUBTYPE_SES 2 ++/* ++The EAPOL type is not used anymore. Instead EAPOL messages are now embedded ++within BCMILCP_BCM_SUBTYPE_EVENT type messages ++*/ ++/*#define BCMILCP_BCM_SUBTYPE_EAPOL 3*/ ++ ++#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 ++#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 ++ ++/* These fields are stored in network order */ ++typedef struct bcmeth_hdr ++{ ++ uint16 subtype; /* Vendor specific..32769*/ ++ uint16 length; ++ uint8 version; /* Version is 0*/ ++ uint8 oui[3]; /* Broadcom OUI*/ ++ /* user specific Data */ ++ uint16 usr_subtype; ++} PACKED bcmeth_hdr_t; ++ ++ ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmip.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmip.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmip.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmip.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,42 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; ++ * the contents of this file may not be disclosed to third parties, copied ++ * or duplicated in any form, in whole or in part, without the prior ++ * written permission of Broadcom Corporation. ++ * ++ * Fundamental constants relating to IP Protocol ++ * ++ * $Id$ ++ */ ++ ++#ifndef _bcmip_h_ ++#define _bcmip_h_ ++ ++/* IP header */ ++#define IPV4_VERIHL_OFFSET 0 /* version and ihl byte offset */ ++#define IPV4_TOS_OFFSET 1 /* TOS offset */ ++#define IPV4_PROT_OFFSET 9 /* protocol type offset */ ++#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ ++#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ ++#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ ++ ++#define IPV4_VER_MASK 0xf0 ++#define IPV4_IHL_MASK 0x0f ++ ++#define IPV4_PROT_UDP 17 /* UDP protocol type */ ++ ++#define IPV4_ADDR_LEN 4 /* IP v4 address length */ ++ ++#define IPV4_VER_NUM 0x40 /* IP v4 version number */ ++ ++/* NULL IP address check */ ++#define IPV4_ISNULLADDR(a) ((((uint8 *)(a))[0] + ((uint8 *)(a))[1] + \ ++ ((uint8 *)(a))[2] + ((uint8 *)(a))[3]) == 0) ++ ++#define IPV4_ADDR_STR_LEN 16 ++ ++#endif /* #ifndef _bcmip_h_ */ ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/ethernet.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/ethernet.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/ethernet.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,169 @@ ++/******************************************************************************* ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. ++ ******************************************************************************/ ++ ++#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ ++#define _NET_ETHERNET_H_ ++ ++#ifndef _TYPEDEFS_H_ ++#include "typedefs.h" ++#endif ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++/* ++ * The number of bytes in an ethernet (MAC) address. ++ */ ++#define ETHER_ADDR_LEN 6 ++ ++/* ++ * The number of bytes in the type field. ++ */ ++#define ETHER_TYPE_LEN 2 ++ ++/* ++ * The number of bytes in the trailing CRC field. ++ */ ++#define ETHER_CRC_LEN 4 ++ ++/* ++ * The length of the combined header. ++ */ ++#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) ++ ++/* ++ * The minimum packet length. ++ */ ++#define ETHER_MIN_LEN 64 ++ ++/* ++ * The minimum packet user data length. ++ */ ++#define ETHER_MIN_DATA 46 ++ ++/* ++ * The maximum packet length. ++ */ ++#define ETHER_MAX_LEN 1518 ++ ++/* ++ * The maximum packet user data length. ++ */ ++#define ETHER_MAX_DATA 1500 ++ ++/* ether types */ ++#define ETHER_TYPE_IP 0x0800 /* IP */ ++#define ETHER_TYPE_ARP 0x0806 /* ARP */ ++#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ ++#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */ ++#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ ++#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication*/ ++ ++/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */ ++#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */ ++#define ETHER_BRCM_CRAM 0x1 /* Broadcom subtype cram protocol */ ++ ++/* ether header */ ++#define ETHER_DEST_OFFSET 0 /* dest address offset */ ++#define ETHER_SRC_OFFSET 6 /* src address offset */ ++#define ETHER_TYPE_OFFSET 12 /* ether type offset */ ++ ++/* ++ * A macro to validate a length with ++ */ ++#define ETHER_IS_VALID_LEN(foo) \ ++ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) ++ ++ ++#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ ++/* ++ * Structure of a 10Mb/s Ethernet header. ++ */ ++struct ether_header { ++ uint8 ether_dhost[ETHER_ADDR_LEN]; ++ uint8 ether_shost[ETHER_ADDR_LEN]; ++ uint16 ether_type; ++} PACKED; ++ ++/* ++ * Structure of a 48-bit Ethernet address. ++ */ ++struct ether_addr { ++ uint8 octet[ETHER_ADDR_LEN]; ++} PACKED; ++#endif ++ ++/* ++ * Takes a pointer, sets locally admininistered ++ * address bit in the 48-bit Ethernet address. ++ */ ++#define ETHER_SET_LOCALADDR(ea) ( ((uint8 *)(ea))[0] = \ ++ (((uint8 *)(ea))[0] | 2) ) ++ ++/* ++ * Takes a pointer, returns true if a 48-bit multicast address ++ * (including broadcast, since it is all ones) ++ */ ++#define ETHER_ISMULTI(ea) (((uint8 *)(ea))[0] & 1) ++ ++ ++/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */ ++#define ether_cmp(a, b) ( \ ++ !(((short*)a)[0] == ((short*)b)[0]) | \ ++ !(((short*)a)[1] == ((short*)b)[1]) | \ ++ !(((short*)a)[2] == ((short*)b)[2])) ++ ++/* copy an ethernet address - assumes the pointers can be referenced as shorts */ ++#define ether_copy(s, d) { \ ++ ((short*)d)[0] = ((short*)s)[0]; \ ++ ((short*)d)[1] = ((short*)s)[1]; \ ++ ((short*)d)[2] = ((short*)s)[2]; } ++ ++/* ++ * Takes a pointer, returns true if a 48-bit broadcast (all ones) ++ */ ++#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ ++ ((uint8 *)(ea))[1] & \ ++ ((uint8 *)(ea))[2] & \ ++ ((uint8 *)(ea))[3] & \ ++ ((uint8 *)(ea))[4] & \ ++ ((uint8 *)(ea))[5]) == 0xff) ++ ++static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; ++ ++/* ++ * Takes a pointer, returns true if a 48-bit null address (all zeros) ++ */ ++#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ ++ ((uint8 *)(ea))[1] | \ ++ ((uint8 *)(ea))[2] | \ ++ ((uint8 *)(ea))[3] | \ ++ ((uint8 *)(ea))[4] | \ ++ ((uint8 *)(ea))[5]) == 0) ++ ++/* Differentiated Services Codepoint - upper 6 bits of tos in iphdr */ ++#define DSCP_MASK 0xFC /* upper 6 bits */ ++#define DSCP_SHIFT 2 ++#define DSCP_WME_PRI_MASK 0xE0 /* upper 3 bits */ ++#define DSCP_WME_PRI_SHIFT 5 ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif /* _NET_ETHERNET_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/vlan.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/vlan.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/vlan.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/vlan.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,50 @@ ++/* ++ * 802.1Q VLAN protocol definitions ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _vlan_h_ ++#define _vlan_h_ ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++#define VLAN_VID_MASK 0xfff /* low 12 bits are vlan id */ ++#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */ ++#define VLAN_PRI_SHIFT 13 /* user priority */ ++ ++#define VLAN_PRI_MASK 7 /* 3 bits of priority */ ++ ++#define VLAN_TAG_LEN 4 ++#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) ++ ++struct ethervlan_header { ++ uint8 ether_dhost[ETHER_ADDR_LEN]; ++ uint8 ether_shost[ETHER_ADDR_LEN]; ++ uint16 vlan_type; /* 0x8100 */ ++ uint16 vlan_tag; /* priority, cfi and vid */ ++ uint16 ether_type; ++}; ++ ++#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif /* _vlan_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/wpa.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/wpa.h +--- linux-2.4.32/arch/mips/bcm947xx/include/proto/wpa.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/wpa.h 2005-12-16 23:39:10.756825000 +0100 +@@ -0,0 +1,140 @@ ++/* ++ * Fundamental types and constants relating to WPA ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _proto_wpa_h_ ++#define _proto_wpa_h_ ++ ++#include ++#include ++ ++/* enable structure packing */ ++#if defined(__GNUC__) ++#define PACKED __attribute__((packed)) ++#else ++#pragma pack(1) ++#define PACKED ++#endif ++ ++/* Reason Codes */ ++ ++/* 10 and 11 are from TGh. */ ++#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */ ++#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */ ++/* 12 is unused */ ++/* 13 through 23 taken from P802.11i/D3.0, November 2002 */ ++#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */ ++#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */ ++#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */ ++#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */ ++#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from (re-)assoc. request/probe response */ ++#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */ ++#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */ ++#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */ ++#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */ ++#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */ ++#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */ ++ ++#define WPA2_PMKID_LEN 16 ++ ++/* WPA IE fixed portion */ ++typedef struct ++{ ++ uint8 tag; /* TAG */ ++ uint8 length; /* TAG length */ ++ uint8 oui[3]; /* IE OUI */ ++ uint8 oui_type; /* OUI type */ ++ struct { ++ uint8 low; ++ uint8 high; ++ } PACKED version; /* IE version */ ++} PACKED wpa_ie_fixed_t; ++#define WPA_IE_OUITYPE_LEN 4 ++#define WPA_IE_FIXED_LEN 8 ++#define WPA_IE_TAG_FIXED_LEN 6 ++ ++typedef struct { ++ uint8 tag; /* TAG */ ++ uint8 length; /* TAG length */ ++ struct { ++ uint8 low; ++ uint8 high; ++ } PACKED version; /* IE version */ ++} PACKED wpa_rsn_ie_fixed_t; ++#define WPA_RSN_IE_FIXED_LEN 4 ++#define WPA_RSN_IE_TAG_FIXED_LEN 2 ++typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; ++ ++/* WPA suite/multicast suite */ ++typedef struct ++{ ++ uint8 oui[3]; ++ uint8 type; ++} PACKED wpa_suite_t, wpa_suite_mcast_t; ++#define WPA_SUITE_LEN 4 ++ ++/* WPA unicast suite list/key management suite list */ ++typedef struct ++{ ++ struct { ++ uint8 low; ++ uint8 high; ++ } PACKED count; ++ wpa_suite_t list[1]; ++} PACKED wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; ++#define WPA_IE_SUITE_COUNT_LEN 2 ++typedef struct ++{ ++ struct { ++ uint8 low; ++ uint8 high; ++ } PACKED count; ++ wpa_pmkid_t list[1]; ++} PACKED wpa_pmkid_list_t; ++ ++/* WPA cipher suites */ ++#define WPA_CIPHER_NONE 0 /* None */ ++#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */ ++#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */ ++#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */ ++#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */ ++#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ ++ ++#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ ++ (cipher) == WPA_CIPHER_WEP_40 || \ ++ (cipher) == WPA_CIPHER_WEP_104 || \ ++ (cipher) == WPA_CIPHER_TKIP || \ ++ (cipher) == WPA_CIPHER_AES_OCB || \ ++ (cipher) == WPA_CIPHER_AES_CCM) ++ ++/* WPA TKIP countermeasures parameters */ ++#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ ++#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ ++ ++/* WPA capabilities defined in 802.11i */ ++#define WPA_CAP_4_REPLAY_CNTRS 2 ++#define WPA_CAP_16_REPLAY_CNTRS 3 ++#define WPA_CAP_REPLAY_CNTR_SHIFT 2 ++#define WPA_CAP_REPLAY_CNTR_MASK 0x000c ++ ++/* WPA Specific defines */ ++#define WPA_CAP_LEN 2 ++ ++#define WPA_CAP_WPA2_PREAUTH 1 ++ ++#undef PACKED ++#if !defined(__GNUC__) ++#pragma pack() ++#endif ++ ++#endif /* _proto_wpa_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/rts/crc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/rts/crc.h +--- linux-2.4.32/arch/mips/bcm947xx/include/rts/crc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/rts/crc.h 2005-12-16 23:39:10.928835750 +0100 +@@ -0,0 +1,69 @@ ++/******************************************************************************* ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * crc.h - a function to compute crc for iLine10 headers ++ ******************************************************************************/ ++ ++#ifndef _RTS_CRC_H_ ++#define _RTS_CRC_H_ 1 ++ ++#include "typedefs.h" ++ ++#ifdef __cplusplus ++extern "C" { ++#endif ++ ++ ++#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ ++#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ ++#define HCS_GOOD_VALUE 0x39 /* Good final header checksum value */ ++ ++#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ ++#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ ++ ++#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ ++#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ ++ ++void hcs(uint8 *, uint); ++uint8 crc8(uint8 *, uint, uint8); ++uint16 crc16(uint8 *, uint, uint16); ++uint32 crc32(uint8 *, uint, uint32); ++ ++/* macros for common usage */ ++ ++#define APPEND_CRC8(pbytes, nbytes) \ ++do { \ ++ uint8 tmp = crc8(pbytes, nbytes, CRC8_INIT_VALUE) ^ 0xff; \ ++ (pbytes)[(nbytes)] = tmp; \ ++ (nbytes) += 1; \ ++} while (0) ++ ++#define APPEND_CRC16(pbytes, nbytes) \ ++do { \ ++ uint16 tmp = crc16(pbytes, nbytes, CRC16_INIT_VALUE) ^ 0xffff; \ ++ (pbytes)[(nbytes) + 0] = (tmp >> 0) & 0xff; \ ++ (pbytes)[(nbytes) + 1] = (tmp >> 8) & 0xff; \ ++ (nbytes) += 2; \ ++} while (0) ++ ++#define APPEND_CRC32(pbytes, nbytes) \ ++do { \ ++ uint32 tmp = crc32(pbytes, nbytes, CRC32_INIT_VALUE) ^ 0xffffffff; \ ++ (pbytes)[(nbytes) + 0] = (tmp >> 0) & 0xff; \ ++ (pbytes)[(nbytes) + 1] = (tmp >> 8) & 0xff; \ ++ (pbytes)[(nbytes) + 2] = (tmp >> 16) & 0xff; \ ++ (pbytes)[(nbytes) + 3] = (tmp >> 24) & 0xff; \ ++ (nbytes) += 4; \ ++} while (0) ++ ++#ifdef __cplusplus ++} ++#endif ++ ++#endif /* _RTS_CRC_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,440 @@ ++/* ++ * SiliconBackplane Chipcommon core hardware definitions. ++ * ++ * The chipcommon core provides chip identification, SB control, ++ * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer, ++ * gpio interface, extbus, and support for serial and parallel flashes. ++ * ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++#ifndef _SBCHIPC_H ++#define _SBCHIPC_H ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++typedef volatile struct { ++ uint32 chipid; /* 0x0 */ ++ uint32 capabilities; ++ uint32 corecontrol; /* corerev >= 1 */ ++ uint32 bist; ++ ++ /* OTP */ ++ uint32 otpstatus; /* 0x10, corerev >= 10 */ ++ uint32 otpcontrol; ++ uint32 otpprog; ++ uint32 PAD; ++ ++ /* Interrupt control */ ++ uint32 intstatus; /* 0x20 */ ++ uint32 intmask; ++ uint32 chipcontrol; /* 0x28, rev >= 11 */ ++ uint32 chipstatus; /* 0x2c, rev >= 11 */ ++ ++ /* Jtag Master */ ++ uint32 jtagcmd; /* 0x30, rev >= 10 */ ++ uint32 jtagir; ++ uint32 jtagdr; ++ uint32 jtagctrl; ++ ++ /* serial flash interface registers */ ++ uint32 flashcontrol; /* 0x40 */ ++ uint32 flashaddress; ++ uint32 flashdata; ++ uint32 PAD[1]; ++ ++ /* Silicon backplane configuration broadcast control */ ++ uint32 broadcastaddress; /* 0x50 */ ++ uint32 broadcastdata; ++ uint32 PAD[2]; ++ ++ /* gpio - cleared only by power-on-reset */ ++ uint32 gpioin; /* 0x60 */ ++ uint32 gpioout; ++ uint32 gpioouten; ++ uint32 gpiocontrol; ++ uint32 gpiointpolarity; ++ uint32 gpiointmask; ++ uint32 PAD[2]; ++ ++ /* Watchdog timer */ ++ uint32 watchdog; /* 0x80 */ ++ uint32 PAD[1]; ++ ++ /*GPIO based LED powersave registers corerev >= 16*/ ++ uint32 gpiotimerval; /*0x88 */ ++ uint32 gpiotimeroutmask; ++ ++ /* clock control */ ++ uint32 clockcontrol_n; /* 0x90 */ ++ uint32 clockcontrol_sb; /* aka m0 */ ++ uint32 clockcontrol_pci; /* aka m1 */ ++ uint32 clockcontrol_m2; /* mii/uart/mipsref */ ++ uint32 clockcontrol_mips; /* aka m3 */ ++ uint32 clkdiv; /* corerev >= 3 */ ++ uint32 PAD[2]; ++ ++ /* pll delay registers (corerev >= 4) */ ++ uint32 pll_on_delay; /* 0xb0 */ ++ uint32 fref_sel_delay; ++ uint32 slow_clk_ctl; /* 5 < corerev < 10 */ ++ uint32 PAD[1]; ++ ++ /* Instaclock registers (corerev >= 10) */ ++ uint32 system_clk_ctl; /* 0xc0 */ ++ uint32 clkstatestretch; ++ uint32 PAD[14]; ++ ++ /* ExtBus control registers (corerev >= 3) */ ++ uint32 pcmcia_config; /* 0x100 */ ++ uint32 pcmcia_memwait; ++ uint32 pcmcia_attrwait; ++ uint32 pcmcia_iowait; ++ uint32 ide_config; ++ uint32 ide_memwait; ++ uint32 ide_attrwait; ++ uint32 ide_iowait; ++ uint32 prog_config; ++ uint32 prog_waitcount; ++ uint32 flash_config; ++ uint32 flash_waitcount; ++ uint32 PAD[116]; ++ ++ /* uarts */ ++ uint8 uart0data; /* 0x300 */ ++ uint8 uart0imr; ++ uint8 uart0fcr; ++ uint8 uart0lcr; ++ uint8 uart0mcr; ++ uint8 uart0lsr; ++ uint8 uart0msr; ++ uint8 uart0scratch; ++ uint8 PAD[248]; /* corerev >= 1 */ ++ ++ uint8 uart1data; /* 0x400 */ ++ uint8 uart1imr; ++ uint8 uart1fcr; ++ uint8 uart1lcr; ++ uint8 uart1mcr; ++ uint8 uart1lsr; ++ uint8 uart1msr; ++ uint8 uart1scratch; ++} chipcregs_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#define CC_CHIPID 0 ++#define CC_CAPABILITIES 4 ++#define CC_JTAGCMD 0x30 ++#define CC_JTAGIR 0x34 ++#define CC_JTAGDR 0x38 ++#define CC_JTAGCTRL 0x3c ++#define CC_WATCHDOG 0x80 ++#define CC_CLKC_N 0x90 ++#define CC_CLKC_M0 0x94 ++#define CC_CLKC_M1 0x98 ++#define CC_CLKC_M2 0x9c ++#define CC_CLKC_M3 0xa0 ++#define CC_CLKDIV 0xa4 ++#define CC_SYS_CLK_CTL 0xc0 ++#define CC_OTP 0x800 ++ ++/* chipid */ ++#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ ++#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ ++#define CID_REV_SHIFT 16 /* Chip Revision shift */ ++#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ ++#define CID_PKG_SHIFT 20 /* Package Option shift */ ++#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ ++#define CID_CC_SHIFT 24 ++ ++/* capabilities */ ++#define CAP_UARTS_MASK 0x00000003 /* Number of uarts */ ++#define CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ ++#define CAP_UCLKSEL 0x00000018 /* UARTs clock select */ ++#define CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ ++#define CAP_UARTGPIO 0x00000020 /* UARTs own Gpio's 15:12 */ ++#define CAP_EXTBUS 0x00000040 /* External bus present */ ++#define CAP_FLASH_MASK 0x00000700 /* Type of flash */ ++#define CAP_PLL_MASK 0x00038000 /* Type of PLL */ ++#define CAP_PWR_CTL 0x00040000 /* Power control */ ++#define CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ ++#define CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ ++#define CAP_OTPSIZE_BASE 5 /* OTP Size base */ ++#define CAP_JTAGP 0x00400000 /* JTAG Master Present */ ++#define CAP_ROM 0x00800000 /* Internal boot rom active */ ++ ++/* PLL type */ ++#define PLL_NONE 0x00000000 ++#define PLL_TYPE1 0x00010000 /* 48Mhz base, 3 dividers */ ++#define PLL_TYPE2 0x00020000 /* 48Mhz, 4 dividers */ ++#define PLL_TYPE3 0x00030000 /* 25Mhz, 2 dividers */ ++#define PLL_TYPE4 0x00008000 /* 48Mhz, 4 dividers */ ++#define PLL_TYPE5 0x00018000 /* 25Mhz, 4 dividers */ ++#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */ ++#define PLL_TYPE7 0x00038000 /* 25Mhz, 4 dividers */ ++ ++/* corecontrol */ ++#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */ ++#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ ++ ++/* Fields in the otpstatus register */ ++#define OTPS_PROGFAIL 0x80000000 ++#define OTPS_PROTECT 0x00000007 ++#define OTPS_HW_PROTECT 0x00000001 ++#define OTPS_SW_PROTECT 0x00000002 ++#define OTPS_CID_PROTECT 0x00000004 ++ ++/* Fields in the otpcontrol register */ ++#define OTPC_RECWAIT 0xff000000 ++#define OTPC_PROGWAIT 0x00ffff00 ++#define OTPC_PRW_SHIFT 8 ++#define OTPC_MAXFAIL 0x00000038 ++#define OTPC_VSEL 0x00000006 ++#define OTPC_SELVL 0x00000001 ++ ++/* Fields in otpprog */ ++#define OTPP_COL_MASK 0x000000ff ++#define OTPP_ROW_MASK 0x0000ff00 ++#define OTPP_ROW_SHIFT 8 ++#define OTPP_READERR 0x10000000 ++#define OTPP_VALUE 0x20000000 ++#define OTPP_VALUE_SHIFT 29 ++#define OTPP_READ 0x40000000 ++#define OTPP_START 0x80000000 ++#define OTPP_BUSY 0x80000000 ++ ++/* jtagcmd */ ++#define JCMD_START 0x80000000 ++#define JCMD_BUSY 0x80000000 ++#define JCMD_PAUSE 0x40000000 ++#define JCMD0_ACC_MASK 0x0000f000 ++#define JCMD0_ACC_IRDR 0x00000000 ++#define JCMD0_ACC_DR 0x00001000 ++#define JCMD0_ACC_IR 0x00002000 ++#define JCMD0_ACC_RESET 0x00003000 ++#define JCMD0_ACC_IRPDR 0x00004000 ++#define JCMD0_ACC_PDR 0x00005000 ++#define JCMD0_IRW_MASK 0x00000f00 ++#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */ ++#define JCMD_ACC_IRDR 0x00000000 ++#define JCMD_ACC_DR 0x00010000 ++#define JCMD_ACC_IR 0x00020000 ++#define JCMD_ACC_RESET 0x00030000 ++#define JCMD_ACC_IRPDR 0x00040000 ++#define JCMD_ACC_PDR 0x00050000 ++#define JCMD_IRW_MASK 0x00001f00 ++#define JCMD_IRW_SHIFT 8 ++#define JCMD_DRW_MASK 0x0000003f ++ ++/* jtagctrl */ ++#define JCTRL_FORCE_CLK 4 /* Force clock */ ++#define JCTRL_EXT_EN 2 /* Enable external targets */ ++#define JCTRL_EN 1 /* Enable Jtag master */ ++ ++/* Fields in clkdiv */ ++#define CLKD_SFLASH 0x0f000000 ++#define CLKD_SFLASH_SHIFT 24 ++#define CLKD_OTP 0x000f0000 ++#define CLKD_OTP_SHIFT 16 ++#define CLKD_JTAG 0x00000f00 ++#define CLKD_JTAG_SHIFT 8 ++#define CLKD_UART 0x000000ff ++ ++/* intstatus/intmask */ ++#define CI_GPIO 0x00000001 /* gpio intr */ ++#define CI_EI 0x00000002 /* ro: ext intr pin (corerev >= 3) */ ++#define CI_WDRESET 0x80000000 /* watchdog reset occurred */ ++ ++/* slow_clk_ctl */ ++#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ ++#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ ++#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ ++#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ ++#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ ++#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */ ++#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */ ++#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */ ++#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */ ++#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ ++#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ ++#define SCC_CD_SHIFT 16 ++ ++/* system_clk_ctl */ ++#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ ++#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ ++#define SYCC_FP 0x00000004 /* ForcePLLOn */ ++#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ ++#define SYCC_HR 0x00000010 /* Force HT */ ++#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4+divisor)) */ ++#define SYCC_CD_SHIFT 16 ++ ++/* gpiotimerval*/ ++#define GPIO_ONTIME_SHIFT 16 ++ ++/* clockcontrol_n */ ++#define CN_N1_MASK 0x3f /* n1 control */ ++#define CN_N2_MASK 0x3f00 /* n2 control */ ++#define CN_N2_SHIFT 8 ++#define CN_PLLC_MASK 0xf0000 /* pll control */ ++#define CN_PLLC_SHIFT 16 ++ ++/* clockcontrol_sb/pci/uart */ ++#define CC_M1_MASK 0x3f /* m1 control */ ++#define CC_M2_MASK 0x3f00 /* m2 control */ ++#define CC_M2_SHIFT 8 ++#define CC_M3_MASK 0x3f0000 /* m3 control */ ++#define CC_M3_SHIFT 16 ++#define CC_MC_MASK 0x1f000000 /* mux control */ ++#define CC_MC_SHIFT 24 ++ ++/* N3M Clock control magic field values */ ++#define CC_F6_2 0x02 /* A factor of 2 in */ ++#define CC_F6_3 0x03 /* 6-bit fields like */ ++#define CC_F6_4 0x05 /* N1, M1 or M3 */ ++#define CC_F6_5 0x09 ++#define CC_F6_6 0x11 ++#define CC_F6_7 0x21 ++ ++#define CC_F5_BIAS 5 /* 5-bit fields get this added */ ++ ++#define CC_MC_BYPASS 0x08 ++#define CC_MC_M1 0x04 ++#define CC_MC_M1M2 0x02 ++#define CC_MC_M1M2M3 0x01 ++#define CC_MC_M1M3 0x11 ++ ++/* Type 2 Clock control magic field values */ ++#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ ++#define CC_T2M2_BIAS 3 /* m2 bias */ ++ ++#define CC_T2MC_M1BYP 1 ++#define CC_T2MC_M2BYP 2 ++#define CC_T2MC_M3BYP 4 ++ ++/* Type 6 Clock control magic field values */ ++#define CC_T6_MMASK 1 /* bits of interest in m */ ++#define CC_T6_M0 120000000 /* sb clock for m = 0 */ ++#define CC_T6_M1 100000000 /* sb clock for m = 1 */ ++#define SB2MIPS_T6(sb) (2 * (sb)) ++ ++/* Common clock base */ ++#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */ ++#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLL's */ ++ ++/* Clock control values for 200Mhz in 5350 */ ++#define CLKC_5350_N 0x0311 ++#define CLKC_5350_M 0x04020009 ++ ++/* Flash types in the chipcommon capabilities register */ ++#define FLASH_NONE 0x000 /* No flash */ ++#define SFLASH_ST 0x100 /* ST serial flash */ ++#define SFLASH_AT 0x200 /* Atmel serial flash */ ++#define PFLASH 0x700 /* Parallel flash */ ++ ++/* Bits in the config registers */ ++#define CC_CFG_EN 0x0001 /* Enable */ ++#define CC_CFG_EM_MASK 0x000e /* Extif Mode */ ++#define CC_CFG_EM_ASYNC 0x0002 /* Async/Parallel flash */ ++#define CC_CFG_EM_SYNC 0x0004 /* Synchronous */ ++#define CC_CFG_EM_PCMCIA 0x0008 /* PCMCIA */ ++#define CC_CFG_EM_IDE 0x000a /* IDE */ ++#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ ++#define CC_CFG_CD_MASK 0x0060 /* Sync: Clock divisor */ ++#define CC_CFG_CE 0x0080 /* Sync: Clock enable */ ++#define CC_CFG_SB 0x0100 /* Sync: Size/Bytestrobe */ ++ ++/* Start/busy bit in flashcontrol */ ++#define SFLASH_START 0x80000000 ++#define SFLASH_BUSY SFLASH_START ++ ++/* flashcontrol opcodes for ST flashes */ ++#define SFLASH_ST_WREN 0x0006 /* Write Enable */ ++#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */ ++#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */ ++#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */ ++#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */ ++#define SFLASH_ST_PP 0x0302 /* Page Program */ ++#define SFLASH_ST_SE 0x02d8 /* Sector Erase */ ++#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */ ++#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */ ++#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */ ++ ++/* Status register bits for ST flashes */ ++#define SFLASH_ST_WIP 0x01 /* Write In Progress */ ++#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */ ++#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */ ++#define SFLASH_ST_BP_SHIFT 2 ++#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */ ++ ++/* flashcontrol opcodes for Atmel flashes */ ++#define SFLASH_AT_READ 0x07e8 ++#define SFLASH_AT_PAGE_READ 0x07d2 ++#define SFLASH_AT_BUF1_READ ++#define SFLASH_AT_BUF2_READ ++#define SFLASH_AT_STATUS 0x01d7 ++#define SFLASH_AT_BUF1_WRITE 0x0384 ++#define SFLASH_AT_BUF2_WRITE 0x0387 ++#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 ++#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 ++#define SFLASH_AT_BUF1_PROGRAM 0x0288 ++#define SFLASH_AT_BUF2_PROGRAM 0x0289 ++#define SFLASH_AT_PAGE_ERASE 0x0281 ++#define SFLASH_AT_BLOCK_ERASE 0x0250 ++#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 ++#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 ++#define SFLASH_AT_BUF1_LOAD 0x0253 ++#define SFLASH_AT_BUF2_LOAD 0x0255 ++#define SFLASH_AT_BUF1_COMPARE 0x0260 ++#define SFLASH_AT_BUF2_COMPARE 0x0261 ++#define SFLASH_AT_BUF1_REPROGRAM 0x0258 ++#define SFLASH_AT_BUF2_REPROGRAM 0x0259 ++ ++/* Status register bits for Atmel flashes */ ++#define SFLASH_AT_READY 0x80 ++#define SFLASH_AT_MISMATCH 0x40 ++#define SFLASH_AT_ID_MASK 0x38 ++#define SFLASH_AT_ID_SHIFT 3 ++ ++/* OTP regions */ ++#define OTP_HW_REGION OTPS_HW_PROTECT ++#define OTP_SW_REGION OTPS_SW_PROTECT ++#define OTP_CID_REGION OTPS_CID_PROTECT ++ ++/* OTP regions (Byte offsets from otp size) */ ++#define OTP_SWLIM_OFF (-8) ++#define OTP_CIDBASE_OFF 0 ++#define OTP_CIDLIM_OFF 8 ++ ++/* Predefined OTP words (Word offset from otp size) */ ++#define OTP_BOUNDARY_OFF (-4) ++#define OTP_HWSIGN_OFF (-3) ++#define OTP_SWSIGN_OFF (-2) ++#define OTP_CIDSIGN_OFF (-1) ++ ++#define OTP_CID_OFF 0 ++#define OTP_PKG_OFF 1 ++#define OTP_FID_OFF 2 ++#define OTP_RSV_OFF 3 ++#define OTP_LIM_OFF 4 ++ ++#define OTP_SIGNATURE 0x578a ++#define OTP_MAGIC 0x4e56 ++ ++#endif /* _SBCHIPC_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,342 @@ ++/* ++ * Broadcom SiliconBackplane hardware register definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _SBCONFIG_H ++#define _SBCONFIG_H ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* ++ * SiliconBackplane Address Map. ++ * All regions may not exist on all chips. ++ */ ++#define SB_SDRAM_BASE 0x00000000 /* Physical SDRAM */ ++#define SB_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ ++#define SB_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ ++#define SB_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define SB_ENUM_BASE 0x18000000 /* Enumeration space base */ ++#define SB_ENUM_LIM 0x18010000 /* Enumeration space limit */ ++ ++#define SB_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ ++#define SB_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ ++ ++#define SB_EXTIF_BASE 0x1f000000 /* External Interface region base address */ ++#define SB_FLASH1 0x1fc00000 /* Flash Region 1 */ ++#define SB_FLASH1_SZ 0x00400000 /* Size of Flash Region 1 */ ++ ++#define SB_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ ++#define SB_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ ++#define SB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */ ++#define SB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ ++#define SB_EUART (SB_EXTIF_BASE + 0x00800000) ++#define SB_LED (SB_EXTIF_BASE + 0x00900000) ++ ++ ++/* enumeration space related defs */ ++#define SB_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ ++#define SB_MAXCORES ((SB_ENUM_LIM - SB_ENUM_BASE)/SB_CORE_SIZE) ++#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ ++#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */ ++ ++/* mips address */ ++#define SB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++ ++/* ++ * Sonics Configuration Space Registers. ++ */ ++#define SBIPSFLAG 0x08 ++#define SBTPSFLAG 0x18 ++#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */ ++#define SBTMERRLOG 0x50 /* sonics >= 2.3 */ ++#define SBADMATCH3 0x60 ++#define SBADMATCH2 0x68 ++#define SBADMATCH1 0x70 ++#define SBIMSTATE 0x90 ++#define SBINTVEC 0x94 ++#define SBTMSTATELOW 0x98 ++#define SBTMSTATEHIGH 0x9c ++#define SBBWA0 0xa0 ++#define SBIMCONFIGLOW 0xa8 ++#define SBIMCONFIGHIGH 0xac ++#define SBADMATCH0 0xb0 ++#define SBTMCONFIGLOW 0xb8 ++#define SBTMCONFIGHIGH 0xbc ++#define SBBCONFIG 0xc0 ++#define SBBSTATE 0xc8 ++#define SBACTCNFG 0xd8 ++#define SBFLAGST 0xe8 ++#define SBIDLOW 0xf8 ++#define SBIDHIGH 0xfc ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++typedef volatile struct _sbconfig { ++ uint32 PAD[2]; ++ uint32 sbipsflag; /* initiator port ocp slave flag */ ++ uint32 PAD[3]; ++ uint32 sbtpsflag; /* target port ocp slave flag */ ++ uint32 PAD[11]; ++ uint32 sbtmerrloga; /* (sonics >= 2.3) */ ++ uint32 PAD; ++ uint32 sbtmerrlog; /* (sonics >= 2.3) */ ++ uint32 PAD[3]; ++ uint32 sbadmatch3; /* address match3 */ ++ uint32 PAD; ++ uint32 sbadmatch2; /* address match2 */ ++ uint32 PAD; ++ uint32 sbadmatch1; /* address match1 */ ++ uint32 PAD[7]; ++ uint32 sbimstate; /* initiator agent state */ ++ uint32 sbintvec; /* interrupt mask */ ++ uint32 sbtmstatelow; /* target state */ ++ uint32 sbtmstatehigh; /* target state */ ++ uint32 sbbwa0; /* bandwidth allocation table0 */ ++ uint32 PAD; ++ uint32 sbimconfiglow; /* initiator configuration */ ++ uint32 sbimconfighigh; /* initiator configuration */ ++ uint32 sbadmatch0; /* address match0 */ ++ uint32 PAD; ++ uint32 sbtmconfiglow; /* target configuration */ ++ uint32 sbtmconfighigh; /* target configuration */ ++ uint32 sbbconfig; /* broadcast configuration */ ++ uint32 PAD; ++ uint32 sbbstate; /* broadcast state */ ++ uint32 PAD[3]; ++ uint32 sbactcnfg; /* activate configuration */ ++ uint32 PAD[3]; ++ uint32 sbflagst; /* current sbflags */ ++ uint32 PAD[3]; ++ uint32 sbidlow; /* identification */ ++ uint32 sbidhigh; /* identification */ ++} sbconfig_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* sbipsflag */ ++#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */ ++#define SBIPS_INT1_SHIFT 0 ++#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */ ++#define SBIPS_INT2_SHIFT 8 ++#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */ ++#define SBIPS_INT3_SHIFT 16 ++#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */ ++#define SBIPS_INT4_SHIFT 24 ++ ++/* sbtpsflag */ ++#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */ ++#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */ ++ ++/* sbtmerrlog */ ++#define SBTMEL_CM 0x00000007 /* command */ ++#define SBTMEL_CI 0x0000ff00 /* connection id */ ++#define SBTMEL_EC 0x0f000000 /* error code */ ++#define SBTMEL_ME 0x80000000 /* multiple error */ ++ ++/* sbimstate */ ++#define SBIM_PC 0xf /* pipecount */ ++#define SBIM_AP_MASK 0x30 /* arbitration policy */ ++#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */ ++#define SBIM_AP_TS 0x10 /* use timesliaces only */ ++#define SBIM_AP_TK 0x20 /* use token only */ ++#define SBIM_AP_RSV 0x30 /* reserved */ ++#define SBIM_IBE 0x20000 /* inbanderror */ ++#define SBIM_TO 0x40000 /* timeout */ ++#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ ++#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ ++ ++/* sbtmstatelow */ ++#define SBTML_RESET 0x1 /* reset */ ++#define SBTML_REJ_MASK 0x6 /* reject */ ++#define SBTML_REJ_SHIFT 1 ++#define SBTML_CLK 0x10000 /* clock enable */ ++#define SBTML_FGC 0x20000 /* force gated clocks on */ ++#define SBTML_FL_MASK 0x3ffc0000 /* core-specific flags */ ++#define SBTML_PE 0x40000000 /* pme enable */ ++#define SBTML_BE 0x80000000 /* bist enable */ ++ ++/* sbtmstatehigh */ ++#define SBTMH_SERR 0x1 /* serror */ ++#define SBTMH_INT 0x2 /* interrupt */ ++#define SBTMH_BUSY 0x4 /* busy */ ++#define SBTMH_TO 0x00000020 /* timeout (sonics >= 2.3) */ ++#define SBTMH_FL_MASK 0x1fff0000 /* core-specific flags */ ++#define SBTMH_DMA64 0x10000000 /* supports DMA with 64-bit addresses */ ++#define SBTMH_GCR 0x20000000 /* gated clock request */ ++#define SBTMH_BISTF 0x40000000 /* bist failed */ ++#define SBTMH_BISTD 0x80000000 /* bist done */ ++ ++ ++/* sbbwa0 */ ++#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */ ++#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */ ++#define SBBWA_TAB1_SHIFT 16 ++ ++/* sbimconfiglow */ ++#define SBIMCL_STO_MASK 0x7 /* service timeout */ ++#define SBIMCL_RTO_MASK 0x70 /* request timeout */ ++#define SBIMCL_RTO_SHIFT 4 ++#define SBIMCL_CID_MASK 0xff0000 /* connection id */ ++#define SBIMCL_CID_SHIFT 16 ++ ++/* sbimconfighigh */ ++#define SBIMCH_IEM_MASK 0xc /* inband error mode */ ++#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */ ++#define SBIMCH_TEM_SHIFT 4 ++#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */ ++#define SBIMCH_BEM_SHIFT 6 ++ ++/* sbadmatch0 */ ++#define SBAM_TYPE_MASK 0x3 /* address type */ ++#define SBAM_AD64 0x4 /* reserved */ ++#define SBAM_ADINT0_MASK 0xf8 /* type0 size */ ++#define SBAM_ADINT0_SHIFT 3 ++#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */ ++#define SBAM_ADINT1_SHIFT 3 ++#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */ ++#define SBAM_ADINT2_SHIFT 3 ++#define SBAM_ADEN 0x400 /* enable */ ++#define SBAM_ADNEG 0x800 /* negative decode */ ++#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */ ++#define SBAM_BASE0_SHIFT 8 ++#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */ ++#define SBAM_BASE1_SHIFT 12 ++#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */ ++#define SBAM_BASE2_SHIFT 16 ++ ++/* sbtmconfiglow */ ++#define SBTMCL_CD_MASK 0xff /* clock divide */ ++#define SBTMCL_CO_MASK 0xf800 /* clock offset */ ++#define SBTMCL_CO_SHIFT 11 ++#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */ ++#define SBTMCL_IF_SHIFT 18 ++#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */ ++#define SBTMCL_IM_SHIFT 24 ++ ++/* sbtmconfighigh */ ++#define SBTMCH_BM_MASK 0x3 /* busy mode */ ++#define SBTMCH_RM_MASK 0x3 /* retry mode */ ++#define SBTMCH_RM_SHIFT 2 ++#define SBTMCH_SM_MASK 0x30 /* stop mode */ ++#define SBTMCH_SM_SHIFT 4 ++#define SBTMCH_EM_MASK 0x300 /* sb error mode */ ++#define SBTMCH_EM_SHIFT 8 ++#define SBTMCH_IM_MASK 0xc00 /* int mode */ ++#define SBTMCH_IM_SHIFT 10 ++ ++/* sbbconfig */ ++#define SBBC_LAT_MASK 0x3 /* sb latency */ ++#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */ ++#define SBBC_MAX0_SHIFT 16 ++#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */ ++#define SBBC_MAX1_SHIFT 20 ++ ++/* sbbstate */ ++#define SBBS_SRD 0x1 /* st reg disable */ ++#define SBBS_HRD 0x2 /* hold reg disable */ ++ ++/* sbidlow */ ++#define SBIDL_CS_MASK 0x3 /* config space */ ++#define SBIDL_AR_MASK 0x38 /* # address ranges supported */ ++#define SBIDL_AR_SHIFT 3 ++#define SBIDL_SYNCH 0x40 /* sync */ ++#define SBIDL_INIT 0x80 /* initiator */ ++#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */ ++#define SBIDL_MINLAT_SHIFT 8 ++#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */ ++#define SBIDL_MAXLAT_SHIFT 12 ++#define SBIDL_FIRST 0x10000 /* this initiator is first */ ++#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */ ++#define SBIDL_CW_SHIFT 18 ++#define SBIDL_TP_MASK 0xf00000 /* target ports */ ++#define SBIDL_TP_SHIFT 20 ++#define SBIDL_IP_MASK 0xf000000 /* initiator ports */ ++#define SBIDL_IP_SHIFT 24 ++#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */ ++#define SBIDL_RV_SHIFT 28 ++#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */ ++#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */ ++ ++/* sbidhigh */ ++#define SBIDH_RC_MASK 0x000f /* revision code */ ++#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ ++#define SBIDH_RCE_SHIFT 8 ++#define SBCOREREV(sbidh) \ ++ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) ++#define SBIDH_CC_MASK 0x8ff0 /* core code */ ++#define SBIDH_CC_SHIFT 4 ++#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ ++#define SBIDH_VC_SHIFT 16 ++ ++#define SB_COMMIT 0xfd8 /* update buffered registers value */ ++ ++/* vendor codes */ ++#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */ ++ ++/* core codes */ ++#define SB_CC 0x800 /* chipcommon core */ ++#define SB_ILINE20 0x801 /* iline20 core */ ++#define SB_SDRAM 0x803 /* sdram core */ ++#define SB_PCI 0x804 /* pci core */ ++#define SB_MIPS 0x805 /* mips core */ ++#define SB_ENET 0x806 /* enet mac core */ ++#define SB_CODEC 0x807 /* v90 codec core */ ++#define SB_USB 0x808 /* usb 1.1 host/device core */ ++#define SB_ADSL 0x809 /* ADSL core */ ++#define SB_ILINE100 0x80a /* iline100 core */ ++#define SB_IPSEC 0x80b /* ipsec core */ ++#define SB_PCMCIA 0x80d /* pcmcia core */ ++#define SB_SOCRAM 0x80e /* internal memory core */ ++#define SB_MEMC 0x80f /* memc sdram core */ ++#define SB_EXTIF 0x811 /* external interface core */ ++#define SB_D11 0x812 /* 802.11 MAC core */ ++#define SB_MIPS33 0x816 /* mips3302 core */ ++#define SB_USB11H 0x817 /* usb 1.1 host core */ ++#define SB_USB11D 0x818 /* usb 1.1 device core */ ++#define SB_USB20H 0x819 /* usb 2.0 host core */ ++#define SB_USB20D 0x81a /* usb 2.0 device core */ ++#define SB_SDIOH 0x81b /* sdio host core */ ++#define SB_ROBO 0x81c /* roboswitch core */ ++#define SB_ATA100 0x81d /* parallel ATA core */ ++#define SB_SATAXOR 0x81e /* serial ATA & XOR DMA core */ ++#define SB_GIGETH 0x81f /* gigabit ethernet core */ ++#define SB_PCIE 0x820 /* pci express core */ ++#define SB_SRAMC 0x822 /* SRAM controller core */ ++#define SB_MINIMAC 0x823 /* MINI MAC/phy core */ ++ ++#define SB_CC_IDX 0 /* chipc, when present, is always core 0 */ ++ ++/* Not really related to Silicon Backplane, but a couple of software ++ * conventions for the use the flash space: ++ */ ++ ++/* Minumum amount of flash we support */ ++#define FLASH_MIN 0x00020000 /* Minimum flash size */ ++ ++/* A boot/binary may have an embedded block that describes its size */ ++#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ ++#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ ++#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ ++#define BISZ_TXTST_IDX 1 /* 1: text start */ ++#define BISZ_TXTEND_IDX 2 /* 2: text start */ ++#define BISZ_DATAST_IDX 3 /* 3: text start */ ++#define BISZ_DATAEND_IDX 4 /* 4: text start */ ++#define BISZ_BSSST_IDX 5 /* 5: text start */ ++#define BISZ_BSSEND_IDX 6 /* 6: text start */ ++#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */ ++ ++#endif /* _SBCONFIG_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,242 @@ ++/* ++ * Hardware-specific External Interface I/O core definitions ++ * for the BCM47xx family of SiliconBackplane-based chips. ++ * ++ * The External Interface core supports a total of three external chip selects ++ * supporting external interfaces. One of the external chip selects is ++ * used for Flash, one is used for PCMCIA, and the other may be ++ * programmed to support either a synchronous interface or an ++ * asynchronous interface. The asynchronous interface can be used to ++ * support external devices such as UARTs and the BCM2019 Bluetooth ++ * baseband processor. ++ * The external interface core also contains 2 on-chip 16550 UARTs, clock ++ * frequency control, a watchdog interrupt timer, and a GPIO interface. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _SBEXTIF_H ++#define _SBEXTIF_H ++ ++/* external interface address space */ ++#define EXTIF_PCMCIA_MEMBASE(x) (x) ++#define EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000) ++#define EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000) ++#define EXTIF_CFGIF_BASE(x) ((x) + 0x800000) ++#define EXTIF_FLASH_BASE(x) ((x) + 0xc00000) ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++/* ++ * The multiple instances of output and output enable registers ++ * are present to allow driver software for multiple cores to control ++ * gpio outputs without needing to share a single register pair. ++ */ ++struct gpiouser { ++ uint32 out; ++ uint32 outen; ++}; ++#define NGPIOUSER 5 ++ ++typedef volatile struct { ++ uint32 corecontrol; ++ uint32 extstatus; ++ uint32 PAD[2]; ++ ++ /* pcmcia control registers */ ++ uint32 pcmcia_config; ++ uint32 pcmcia_memwait; ++ uint32 pcmcia_attrwait; ++ uint32 pcmcia_iowait; ++ ++ /* programmable interface control registers */ ++ uint32 prog_config; ++ uint32 prog_waitcount; ++ ++ /* flash control registers */ ++ uint32 flash_config; ++ uint32 flash_waitcount; ++ uint32 PAD[4]; ++ ++ uint32 watchdog; ++ ++ /* clock control */ ++ uint32 clockcontrol_n; ++ uint32 clockcontrol_sb; ++ uint32 clockcontrol_pci; ++ uint32 clockcontrol_mii; ++ uint32 PAD[3]; ++ ++ /* gpio */ ++ uint32 gpioin; ++ struct gpiouser gpio[NGPIOUSER]; ++ uint32 PAD; ++ uint32 ejtagouten; ++ uint32 gpiointpolarity; ++ uint32 gpiointmask; ++ uint32 PAD[153]; ++ ++ uint8 uartdata; ++ uint8 PAD[3]; ++ uint8 uartimer; ++ uint8 PAD[3]; ++ uint8 uartfcr; ++ uint8 PAD[3]; ++ uint8 uartlcr; ++ uint8 PAD[3]; ++ uint8 uartmcr; ++ uint8 PAD[3]; ++ uint8 uartlsr; ++ uint8 PAD[3]; ++ uint8 uartmsr; ++ uint8 PAD[3]; ++ uint8 uartscratch; ++ uint8 PAD[3]; ++} extifregs_t; ++ ++/* corecontrol */ ++#define CC_UE (1 << 0) /* uart enable */ ++ ++/* extstatus */ ++#define ES_EM (1 << 0) /* endian mode (ro) */ ++#define ES_EI (1 << 1) /* external interrupt pin (ro) */ ++#define ES_GI (1 << 2) /* gpio interrupt pin (ro) */ ++ ++/* gpio bit mask */ ++#define GPIO_BIT0 (1 << 0) ++#define GPIO_BIT1 (1 << 1) ++#define GPIO_BIT2 (1 << 2) ++#define GPIO_BIT3 (1 << 3) ++#define GPIO_BIT4 (1 << 4) ++#define GPIO_BIT5 (1 << 5) ++#define GPIO_BIT6 (1 << 6) ++#define GPIO_BIT7 (1 << 7) ++ ++ ++/* pcmcia/prog/flash_config */ ++#define CF_EN (1 << 0) /* enable */ ++#define CF_EM_MASK 0xe /* mode */ ++#define CF_EM_SHIFT 1 ++#define CF_EM_FLASH 0x0 /* flash/asynchronous mode */ ++#define CF_EM_SYNC 0x2 /* synchronous mode */ ++#define CF_EM_PCMCIA 0x4 /* pcmcia mode */ ++#define CF_DS (1 << 4) /* destsize: 0=8bit, 1=16bit */ ++#define CF_BS (1 << 5) /* byteswap */ ++#define CF_CD_MASK 0xc0 /* clock divider */ ++#define CF_CD_SHIFT 6 ++#define CF_CD_DIV2 0x0 /* backplane/2 */ ++#define CF_CD_DIV3 0x40 /* backplane/3 */ ++#define CF_CD_DIV4 0x80 /* backplane/4 */ ++#define CF_CE (1 << 8) /* clock enable */ ++#define CF_SB (1 << 9) /* size/bytestrobe (synch only) */ ++ ++/* pcmcia_memwait */ ++#define PM_W0_MASK 0x3f /* waitcount0 */ ++#define PM_W1_MASK 0x1f00 /* waitcount1 */ ++#define PM_W1_SHIFT 8 ++#define PM_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PM_W2_SHIFT 16 ++#define PM_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PM_W3_SHIFT 24 ++ ++/* pcmcia_attrwait */ ++#define PA_W0_MASK 0x3f /* waitcount0 */ ++#define PA_W1_MASK 0x1f00 /* waitcount1 */ ++#define PA_W1_SHIFT 8 ++#define PA_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PA_W2_SHIFT 16 ++#define PA_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PA_W3_SHIFT 24 ++ ++/* pcmcia_iowait */ ++#define PI_W0_MASK 0x3f /* waitcount0 */ ++#define PI_W1_MASK 0x1f00 /* waitcount1 */ ++#define PI_W1_SHIFT 8 ++#define PI_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PI_W2_SHIFT 16 ++#define PI_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PI_W3_SHIFT 24 ++ ++/* prog_waitcount */ ++#define PW_W0_MASK 0x0000001f /* waitcount0 */ ++#define PW_W1_MASK 0x00001f00 /* waitcount1 */ ++#define PW_W1_SHIFT 8 ++#define PW_W2_MASK 0x001f0000 /* waitcount2 */ ++#define PW_W2_SHIFT 16 ++#define PW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PW_W3_SHIFT 24 ++ ++#define PW_W0 0x0000000c ++#define PW_W1 0x00000a00 ++#define PW_W2 0x00020000 ++#define PW_W3 0x01000000 ++ ++/* flash_waitcount */ ++#define FW_W0_MASK 0x1f /* waitcount0 */ ++#define FW_W1_MASK 0x1f00 /* waitcount1 */ ++#define FW_W1_SHIFT 8 ++#define FW_W2_MASK 0x1f0000 /* waitcount2 */ ++#define FW_W2_SHIFT 16 ++#define FW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define FW_W3_SHIFT 24 ++ ++/* watchdog */ ++#define WATCHDOG_CLOCK 48000000 /* Hz */ ++ ++/* clockcontrol_n */ ++#define CN_N1_MASK 0x3f /* n1 control */ ++#define CN_N2_MASK 0x3f00 /* n2 control */ ++#define CN_N2_SHIFT 8 ++ ++/* clockcontrol_sb/pci/mii */ ++#define CC_M1_MASK 0x3f /* m1 control */ ++#define CC_M2_MASK 0x3f00 /* m2 control */ ++#define CC_M2_SHIFT 8 ++#define CC_M3_MASK 0x3f0000 /* m3 control */ ++#define CC_M3_SHIFT 16 ++#define CC_MC_MASK 0x1f000000 /* mux control */ ++#define CC_MC_SHIFT 24 ++ ++/* Clock control default values */ ++#define CC_DEF_N 0x0009 /* Default values for bcm4710 */ ++#define CC_DEF_100 0x04020011 ++#define CC_DEF_33 0x11030011 ++#define CC_DEF_25 0x11050011 ++ ++/* Clock control values for 125Mhz */ ++#define CC_125_N 0x0802 ++#define CC_125_M 0x04020009 ++#define CC_125_M25 0x11090009 ++#define CC_125_M33 0x11090005 ++ ++/* Clock control magic field values */ ++#define CC_F6_2 0x02 /* A factor of 2 in */ ++#define CC_F6_3 0x03 /* 6-bit fields like */ ++#define CC_F6_4 0x05 /* N1, M1 or M3 */ ++#define CC_F6_5 0x09 ++#define CC_F6_6 0x11 ++#define CC_F6_7 0x21 ++ ++#define CC_F5_BIAS 5 /* 5-bit fields get this added */ ++ ++#define CC_MC_BYPASS 0x08 ++#define CC_MC_M1 0x04 ++#define CC_MC_M1M2 0x02 ++#define CC_MC_M1M2M3 0x01 ++#define CC_MC_M1M3 0x11 ++ ++#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */ ++ ++#endif /* _SBEXTIF_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,312 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _sbhnddma_h_ ++#define _sbhnddma_h_ ++ ++ ++/* 2byte-wide pio register set per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint16 fifocontrol; ++ uint16 fifodata; ++ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */ ++ uint16 PAD; ++} pio2regs_t; ++ ++/* a pair of pio channels(tx and rx) */ ++typedef volatile struct { ++ pio2regs_t tx; ++ pio2regs_t rx; ++} pio2regp_t; ++ ++/* 4byte-wide pio register set per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 fifocontrol; ++ uint32 fifodata; ++} pio4regs_t; ++ ++/* a pair of pio channels(tx and rx) */ ++typedef volatile struct { ++ pio4regs_t tx; ++ pio4regs_t rx; ++} pio4regp_t; ++ ++ ++ ++/* DMA structure: ++ * support two DMA engines: 32 bits address or 64 bit addressing ++ * basic DMA register set is per channel(transmit or receive) ++ * a pair of channels is defined for convenience ++ */ ++ ++ ++/*** 32 bits addressing ***/ ++ ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 addr; /* descriptor ring base address (4K aligned) */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 status; /* current active descriptor, et al */ ++} dma32regs_t; ++ ++typedef volatile struct { ++ dma32regs_t xmt; /* dma tx channel */ ++ dma32regs_t rcv; /* dma rx channel */ ++} dma32regp_t; ++ ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma32diag_t; ++ ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl; /* misc control bits & bufcount */ ++ uint32 addr; /* data buffer address */ ++} dma32dd_t; ++ ++/* ++ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. ++ */ ++#define D32MAXRINGSZ 4096 ++#define D32RINGALIGN 4096 ++#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) ++ ++/* transmit channel control */ ++#define XC_XE ((uint32)1 << 0) /* transmit enable */ ++#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ ++#define XC_LE ((uint32)1 << 2) /* loopback enable */ ++#define XC_FL ((uint32)1 << 4) /* flush request */ ++#define XC_AE ((uint32)3 << 16) /* address extension bits */ ++#define XC_AE_SHIFT 16 ++ ++/* transmit descriptor table pointer */ ++#define XP_LD_MASK 0xfff /* last valid descriptor */ ++ ++/* transmit channel status */ ++#define XS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define XS_XS_MASK 0xf000 /* transmit state */ ++#define XS_XS_SHIFT 12 ++#define XS_XS_DISABLED 0x0000 /* disabled */ ++#define XS_XS_ACTIVE 0x1000 /* active */ ++#define XS_XS_IDLE 0x2000 /* idle wait */ ++#define XS_XS_STOPPED 0x3000 /* stopped */ ++#define XS_XS_SUSP 0x4000 /* suspend pending */ ++#define XS_XE_MASK 0xf0000 /* transmit errors */ ++#define XS_XE_SHIFT 16 ++#define XS_XE_NOERR 0x00000 /* no error */ ++#define XS_XE_DPE 0x10000 /* descriptor protocol error */ ++#define XS_XE_DFU 0x20000 /* data fifo underrun */ ++#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ ++#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ ++#define XS_AD_MASK 0xfff00000 /* active descriptor */ ++#define XS_AD_SHIFT 20 ++ ++/* receive channel control */ ++#define RC_RE ((uint32)1 << 0) /* receive enable */ ++#define RC_RO_MASK 0xfe /* receive frame offset */ ++#define RC_RO_SHIFT 1 ++#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ ++#define RC_AE ((uint32)3 << 16) /* address extension bits */ ++#define RC_AE_SHIFT 16 ++ ++/* receive descriptor table pointer */ ++#define RP_LD_MASK 0xfff /* last valid descriptor */ ++ ++/* receive channel status */ ++#define RS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define RS_RS_MASK 0xf000 /* receive state */ ++#define RS_RS_SHIFT 12 ++#define RS_RS_DISABLED 0x0000 /* disabled */ ++#define RS_RS_ACTIVE 0x1000 /* active */ ++#define RS_RS_IDLE 0x2000 /* idle wait */ ++#define RS_RS_STOPPED 0x3000 /* reserved */ ++#define RS_RE_MASK 0xf0000 /* receive errors */ ++#define RS_RE_SHIFT 16 ++#define RS_RE_NOERR 0x00000 /* no error */ ++#define RS_RE_DPE 0x10000 /* descriptor protocol error */ ++#define RS_RE_DFO 0x20000 /* data fifo overflow */ ++#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ ++#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ ++#define RS_AD_MASK 0xfff00000 /* active descriptor */ ++#define RS_AD_SHIFT 20 ++ ++/* fifoaddr */ ++#define FA_OFF_MASK 0xffff /* offset */ ++#define FA_SEL_MASK 0xf0000 /* select */ ++#define FA_SEL_SHIFT 16 ++#define FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define FA_SEL_RDD 0x40000 /* receive dma data */ ++#define FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ ++/* descriptor control flags */ ++#define CTRL_BC_MASK 0x1fff /* buffer byte count */ ++#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ ++#define CTRL_AE_SHIFT 16 ++#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ ++#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ ++ ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define CTRL_CORE_MASK 0x0ff00000 ++ ++/*** 64 bits addressing ***/ ++ ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ ++ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ ++ uint32 status0; /* current descriptor, xmt state */ ++ uint32 status1; /* active descriptor, xmt error */ ++} dma64regs_t; ++ ++typedef volatile struct { ++ dma64regs_t tx; /* dma64 tx channel */ ++ dma64regs_t rx; /* dma64 rx channel */ ++} dma64regp_t; ++ ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma64diag_t; ++ ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl1; /* misc control bits & bufcount */ ++ uint32 ctrl2; /* buffer count and address extension */ ++ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */ ++ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */ ++} dma64dd_t; ++ ++/* ++ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. ++ */ ++#define D64MAXRINGSZ 8192 ++#define D64RINGALIGN 8192 ++#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) ++ ++/* transmit channel control */ ++#define D64_XC_XE 0x00000001 /* transmit enable */ ++#define D64_XC_SE 0x00000002 /* transmit suspend request */ ++#define D64_XC_LE 0x00000004 /* loopback enable */ ++#define D64_XC_FL 0x00000010 /* flush request */ ++#define D64_XC_AE 0x00110000 /* address extension bits */ ++#define D64_XC_AE_SHIFT 16 ++ ++/* transmit descriptor table pointer */ ++#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ ++ ++/* transmit channel status */ ++#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ ++#define D64_XS0_XS_SHIFT 28 ++#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ ++#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ ++#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ ++#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ ++#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ ++ ++#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ ++#define D64_XS1_XE_SHIFT 28 ++#define D64_XS1_XE_NOERR 0x00000000 /* no error */ ++#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ ++#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ ++#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ ++#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_XS1_XE_COREE 0x50000000 /* core error */ ++ ++/* receive channel control */ ++#define D64_RC_RE 0x00000001 /* receive enable */ ++#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ ++#define D64_RC_RO_SHIFT 1 ++#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ ++#define D64_RC_AE 0x00110000 /* address extension bits */ ++#define D64_RC_AE_SHIFT 16 ++ ++/* receive descriptor table pointer */ ++#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ ++ ++/* receive channel status */ ++#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ ++#define D64_RS0_RS_SHIFT 28 ++#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ ++#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ ++#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ ++#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ ++#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ ++ ++#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ ++#define D64_RS1_RE_SHIFT 28 ++#define D64_RS1_RE_NOERR 0x00000000 /* no error */ ++#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ ++#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ ++#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ ++#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_RS1_RE_COREE 0x50000000 /* core error */ ++ ++/* fifoaddr */ ++#define D64_FA_OFF_MASK 0xffff /* offset */ ++#define D64_FA_SEL_MASK 0xf0000 /* select */ ++#define D64_FA_SEL_SHIFT 16 ++#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ ++#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ ++/* descriptor control flags 1 */ ++#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ ++#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ ++ ++/* descriptor control flags 2 */ ++#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ ++#define D64_CTRL2_AE 0x00110000 /* address extension bits */ ++#define D64_CTRL2_AE_SHIFT 16 ++ ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define D64_CTRL_CORE_MASK 0x0ff00000 ++ ++ ++#endif /* _sbhnddma_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h 2005-12-16 23:39:10.932836000 +0100 +@@ -0,0 +1,148 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _SBMEMC_H ++#define _SBMEMC_H ++ ++#ifdef _LANGUAGE_ASSEMBLY ++ ++#define MEMC_CONTROL 0x00 ++#define MEMC_CONFIG 0x04 ++#define MEMC_REFRESH 0x08 ++#define MEMC_BISTSTAT 0x0c ++#define MEMC_MODEBUF 0x10 ++#define MEMC_BKCLS 0x14 ++#define MEMC_PRIORINV 0x18 ++#define MEMC_DRAMTIM 0x1c ++#define MEMC_INTSTAT 0x20 ++#define MEMC_INTMASK 0x24 ++#define MEMC_INTINFO 0x28 ++#define MEMC_NCDLCTL 0x30 ++#define MEMC_RDNCDLCOR 0x34 ++#define MEMC_WRNCDLCOR 0x38 ++#define MEMC_MISCDLYCTL 0x3c ++#define MEMC_DQSGATENCDL 0x40 ++#define MEMC_SPARE 0x44 ++#define MEMC_TPADDR 0x48 ++#define MEMC_TPDATA 0x4c ++#define MEMC_BARRIER 0x50 ++#define MEMC_CORE 0x54 ++ ++ ++#else ++ ++/* Sonics side: MEMC core registers */ ++typedef volatile struct sbmemcregs { ++ uint32 control; ++ uint32 config; ++ uint32 refresh; ++ uint32 biststat; ++ uint32 modebuf; ++ uint32 bkcls; ++ uint32 priorinv; ++ uint32 dramtim; ++ uint32 intstat; ++ uint32 intmask; ++ uint32 intinfo; ++ uint32 reserved1; ++ uint32 ncdlctl; ++ uint32 rdncdlcor; ++ uint32 wrncdlcor; ++ uint32 miscdlyctl; ++ uint32 dqsgatencdl; ++ uint32 spare; ++ uint32 tpaddr; ++ uint32 tpdata; ++ uint32 barrier; ++ uint32 core; ++} sbmemcregs_t; ++ ++#endif ++ ++/* MEMC Core Init values (OCP ID 0x80f) */ ++ ++/* For sdr: */ ++#define MEMC_SD_CONFIG_INIT 0x00048000 ++#define MEMC_SD_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_SD_DRAMTIM3_INIT 0x000754da ++#define MEMC_SD_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_SD_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 /* For corerev 1 (4712) */ ++#define MEMC_SD_MISCDLYCTL_INIT 0x00061c1b ++#define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 /* For corerev 1 (4712) */ ++#define MEMC_SD_CONTROL_INIT0 0x00000002 ++#define MEMC_SD_CONTROL_INIT1 0x00000008 ++#define MEMC_SD_CONTROL_INIT2 0x00000004 ++#define MEMC_SD_CONTROL_INIT3 0x00000010 ++#define MEMC_SD_CONTROL_INIT4 0x00000001 ++#define MEMC_SD_MODEBUF_INIT 0x00000000 ++#define MEMC_SD_REFRESH_INIT 0x0000840f ++ ++ ++/* This is for SDRM8X8X4 */ ++#define MEMC_SDR_INIT 0x0008 ++#define MEMC_SDR_MODE 0x32 ++#define MEMC_SDR_NCDL 0x00020032 ++#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */ ++ ++/* For ddr: */ ++#define MEMC_CONFIG_INIT 0x00048000 ++#define MEMC_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_DRAMTIM25_INIT 0x000754d9 ++#define MEMC_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */ ++#define MEMC_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_1_WRNCDLCOR_INIT 0x14500200 ++#define MEMC_DQSGATENCDL_INIT 0x00030000 ++#define MEMC_MISCDLYCTL_INIT 0x21061c1b ++#define MEMC_1_MISCDLYCTL_INIT 0x21021400 ++#define MEMC_NCDLCTL_INIT 0x00002001 ++#define MEMC_CONTROL_INIT0 0x00000002 ++#define MEMC_CONTROL_INIT1 0x00000008 ++#define MEMC_MODEBUF_INIT0 0x00004000 ++#define MEMC_CONTROL_INIT2 0x00000010 ++#define MEMC_MODEBUF_INIT1 0x00000100 ++#define MEMC_CONTROL_INIT3 0x00000010 ++#define MEMC_CONTROL_INIT4 0x00000008 ++#define MEMC_REFRESH_INIT 0x0000840f ++#define MEMC_CONTROL_INIT5 0x00000004 ++#define MEMC_MODEBUF_INIT2 0x00000000 ++#define MEMC_CONTROL_INIT6 0x00000010 ++#define MEMC_CONTROL_INIT7 0x00000001 ++ ++ ++/* This is for DDRM16X16X2 */ ++#define MEMC_DDR_INIT 0x0009 ++#define MEMC_DDR_MODE 0x62 ++#define MEMC_DDR_NCDL 0x0005050a ++#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */ ++ ++/* mask for sdr/ddr calibration registers */ ++#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff ++#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff ++#define MEMC_DQSGATENCDL_G_MASK 0x000000ff ++ ++/* masks for miscdlyctl registers */ ++#define MEMC_MISC_SM_MASK 0x30000000 ++#define MEMC_MISC_SM_SHIFT 28 ++#define MEMC_MISC_SD_MASK 0x0f000000 ++#define MEMC_MISC_SD_SHIFT 24 ++ ++/* hw threshhold for calculating wr/rd for sdr memc */ ++#define MEMC_CD_THRESHOLD 128 ++ ++/* Low bit of init register says if memc is ddr or sdr */ ++#define MEMC_CONFIG_DDR 0x00000001 ++ ++#endif /* _SBMEMC_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,62 @@ ++/* ++ * Broadcom SiliconBackplane MIPS definitions ++ * ++ * SB MIPS cores are custom MIPS32 processors with SiliconBackplane ++ * OCP interfaces. The CP0 processor ID is 0x00024000, where bits ++ * 23:16 mean Broadcom and bits 15:8 mean a MIPS core with an OCP ++ * interface. The core revision is stored in the SB ID register in SB ++ * configuration space. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _SBMIPS_H ++#define _SBMIPS_H ++ ++#include ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ ++ ++typedef volatile struct { ++ uint32 corecontrol; ++ uint32 PAD[2]; ++ uint32 biststatus; ++ uint32 PAD[4]; ++ uint32 intstatus; ++ uint32 intmask; ++ uint32 timer; ++} mipsregs_t; ++ ++extern uint32 sb_flag(sb_t *sbh); ++extern uint sb_irq(sb_t *sbh); ++ ++extern void BCMINIT(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)); ++ ++extern void *sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap); ++extern void sb_jtagm_disable(void *h); ++extern uint32 jtag_rwreg(void *h, uint32 ir, uint32 dr); ++extern void BCMINIT(sb_mips_init)(sb_t *sbh); ++extern uint32 BCMINIT(sb_mips_clock)(sb_t *sbh); ++extern bool BCMINIT(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock); ++extern void BCMINIT(enable_pfc)(uint32 mode); ++extern uint32 BCMINIT(sb_memc_get_ncdl)(sb_t *sbh); ++ ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#endif /* _SBMIPS_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,199 @@ ++/* ++ * BCM43XX SiliconBackplane PCIE core hardware definitions. ++ * ++ * $Id: ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ */ ++ ++#ifndef _SBPCIE_H ++#define _SBPCIE_H ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* PCIE Enumeration space offsets*/ ++#define PCIE_CORE_CONFIG_OFFSET 0x0 ++#define PCIE_FUNC0_CONFIG_OFFSET 0x400 ++#define PCIE_FUNC1_CONFIG_OFFSET 0x500 ++#define PCIE_FUNC2_CONFIG_OFFSET 0x600 ++#define PCIE_FUNC3_CONFIG_OFFSET 0x700 ++#define PCIE_SPROM_SHADOW_OFFSET 0x800 ++#define PCIE_SBCONFIG_OFFSET 0xE00 ++ ++/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */ ++#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0 ++#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000 ++#define PCIE_BAR0_PCIECORE_OFFSET 0x2000 ++#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000 ++ ++/* SB side: PCIE core and host control registers */ ++typedef struct sbpcieregs { ++ ++ uint32 PAD[3]; ++ uint32 biststatus; /* bist Status: 0x00C*/ ++ uint32 PAD[6]; ++ uint32 sbtopcimailbox; /* sb to pcie mailbox: 0x028*/ ++ uint32 PAD[54]; ++ uint32 sbtopcie0; /* sb to pcie translation 0: 0x100 */ ++ uint32 sbtopcie1; /* sb to pcie translation 1: 0x104 */ ++ uint32 sbtopcie2; /* sb to pcie translation 2: 0x108 */ ++ uint32 PAD[4]; ++ ++ /* pcie core supports in direct access to config space */ ++ uint32 configaddr; /* pcie config space access: Address field: 0x120*/ ++ uint32 configdata; /* pcie config space access: Data field: 0x124*/ ++ ++ /* mdio access to serdes */ ++ uint32 mdiocontrol; /* controls the mdio access: 0x128 */ ++ uint32 mdiodata; /* Data to the mdio access: 0x12c */ ++ ++ /* pcie protocol phy/dllp/tlp register access mechanism*/ ++ uint32 pcieaddr; /* address of the internal registeru: 0x130 */ ++ uint32 pciedata; /* Data to/from the internal regsiter: 0x134 */ ++ ++ uint32 PAD[434]; ++ uint16 sprom[36]; /* SPROM shadow Area */ ++} sbpcieregs_t; ++ ++/* SB to PCIE translation masks */ ++#define SBTOPCIE0_MASK 0xfc000000 ++#define SBTOPCIE1_MASK 0xfc000000 ++#define SBTOPCIE2_MASK 0xc0000000 ++ ++/* Access type bits (0:1)*/ ++#define SBTOPCIE_MEM 0 ++#define SBTOPCIE_IO 1 ++#define SBTOPCIE_CFG0 2 ++#define SBTOPCIE_CFG1 3 ++ ++/*Prefetch enable bit 2*/ ++#define SBTOPCIE_PF 4 ++ ++/*Write Burst enable for memory write bit 3*/ ++#define SBTOPCIE_WR_BURST 8 ++ ++/* config access */ ++#define CONFIGADDR_FUNC_MASK 0x7000 ++#define CONFIGADDR_FUNC_SHF 12 ++#define CONFIGADDR_REG_MASK 0x0FFF ++#define CONFIGADDR_REG_SHF 0 ++ ++/* PCIE protocol regs Indirect Address */ ++#define PCIEADDR_PROT_MASK 0x300 ++#define PCIEADDR_PROT_SHF 8 ++#define PCIEADDR_PL_TLP 0 ++#define PCIEADDR_PL_DLLP 1 ++#define PCIEADDR_PL_PLP 2 ++ ++/* PCIE protocol PHY diagnostic registers */ ++#define PCIE_PLP_MODEREG 0x200 /* Mode*/ ++#define PCIE_PLP_STATUSREG 0x204 /* Status*/ ++#define PCIE_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */ ++#define PCIE_PLP_LTLINKNUMREG 0x20c /* Link Training Link number*/ ++#define PCIE_PLP_LTLANENUMREG 0x210 /* Link Training Lane number*/ ++#define PCIE_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */ ++#define PCIE_PLP_ATTNREG 0x218 /* Attention */ ++#define PCIE_PLP_ATTNMASKREG 0x21C /* Attention Mask */ ++#define PCIE_PLP_RXERRCTR 0x220 /* Rx Error */ ++#define PCIE_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error*/ ++#define PCIE_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */ ++#define PCIE_PLP_TESTCTRLREG 0x22C /* Test Control reg*/ ++#define PCIE_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */ ++#define PCIE_PLP_TIMINGOVRDREG 0x234 /* Timing param override */ ++#define PCIE_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag*/ ++#define PCIE_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag*/ ++ ++/* PCIE protocol DLLP diagnostic registers */ ++#define PCIE_DLLP_LCREG 0x100 /* Link Control*/ ++#define PCIE_DLLP_LSREG 0x104 /* Link Status */ ++#define PCIE_DLLP_LAREG 0x108 /* Link Attention*/ ++#define PCIE_DLLP_LAMASKREG 0x10C /* Link Attention Mask */ ++#define PCIE_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num*/ ++#define PCIE_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num*/ ++#define PCIE_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num*/ ++#define PCIE_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */ ++#define PCIE_DLLP_LRREG 0x120 /* Link Replay*/ ++#define PCIE_DLLP_LACKTOREG 0x124 /* Link Ack Timeout*/ ++#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold*/ ++#define PCIE_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr*/ ++#define PCIE_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr*/ ++#define PCIE_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr*/ ++#define PCIE_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write*/ ++#define PCIE_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */ ++#define PCIE_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */ ++#define PCIE_DLLP_ERRCTRREG 0x144 /* Error Counter*/ ++#define PCIE_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter*/ ++#define PCIE_DLLP_TESTREG 0x14C /* Test */ ++#define PCIE_DLLP_PKTBIST 0x150 /* Packet BIST*/ ++ ++/* PCIE protocol TLP diagnostic registers */ ++#define PCIE_TLP_CONFIGREG 0x000 /* Configuration */ ++#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */ ++#define PCIE_TLP_WRDMAUPPER 0x010 /* Write DMA Upper Address*/ ++#define PCIE_TLP_WRDMALOWER 0x014 /* Write DMA Lower Address*/ ++#define PCIE_TLP_WRDMAREQ_LBEREG 0x018 /* Write DMA Len/ByteEn Req*/ ++#define PCIE_TLP_RDDMAUPPER 0x01C /* Read DMA Upper Address*/ ++#define PCIE_TLP_RDDMALOWER 0x020 /* Read DMA Lower Address*/ ++#define PCIE_TLP_RDDMALENREG 0x024 /* Read DMA Len Req*/ ++#define PCIE_TLP_MSIDMAUPPER 0x028 /* MSI DMA Upper Address*/ ++#define PCIE_TLP_MSIDMALOWER 0x02C /* MSI DMA Lower Address*/ ++#define PCIE_TLP_MSIDMALENREG 0x030 /* MSI DMA Len Req*/ ++#define PCIE_TLP_SLVREQLENREG 0x034 /* Slave Request Len*/ ++#define PCIE_TLP_FCINPUTSREQ 0x038 /* Flow Control Inputs*/ ++#define PCIE_TLP_TXSMGRSREQ 0x03C /* Tx StateMachine and Gated Req*/ ++#define PCIE_TLP_ADRACKCNTARBLEN 0x040 /* Address Ack XferCnt and ARB Len*/ ++#define PCIE_TLP_DMACPLHDR0 0x044 /* DMA Completion Hdr 0*/ ++#define PCIE_TLP_DMACPLHDR1 0x048 /* DMA Completion Hdr 1*/ ++#define PCIE_TLP_DMACPLHDR2 0x04C /* DMA Completion Hdr 2*/ ++#define PCIE_TLP_DMACPLMISC0 0x050 /* DMA Completion Misc0 */ ++#define PCIE_TLP_DMACPLMISC1 0x054 /* DMA Completion Misc1 */ ++#define PCIE_TLP_DMACPLMISC2 0x058 /* DMA Completion Misc2 */ ++#define PCIE_TLP_SPTCTRLLEN 0x05C /* Split Controller Req len*/ ++#define PCIE_TLP_SPTCTRLMSIC0 0x060 /* Split Controller Misc 0*/ ++#define PCIE_TLP_SPTCTRLMSIC1 0x064 /* Split Controller Misc 1*/ ++#define PCIE_TLP_BUSDEVFUNC 0x068 /* Bus/Device/Func*/ ++#define PCIE_TLP_RESETCTR 0x06C /* Reset Counter*/ ++#define PCIE_TLP_RTRYBUF 0x070 /* Retry Buffer value*/ ++#define PCIE_TLP_TGTDEBUG1 0x074 /* Target Debug Reg1*/ ++#define PCIE_TLP_TGTDEBUG2 0x078 /* Target Debug Reg2*/ ++#define PCIE_TLP_TGTDEBUG3 0x07C /* Target Debug Reg3*/ ++#define PCIE_TLP_TGTDEBUG4 0x080 /* Target Debug Reg4*/ ++ ++/* MDIO control */ ++#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ ++#define MDIOCTL_DIVISOR_VAL 0x2 ++#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */ ++#define MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */ ++ ++/* MDIO Data */ ++#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */ ++#define MDIODATA_TA 0x00020000 /* Turnaround */ ++#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */ ++#define MDIODATA_REGADDR_MASK 0x003c0000 /* Regaddr Mask */ ++#define MDIODATA_DEVADDR_SHF 22 /* Physmedia devaddr shift */ ++#define MDIODATA_DEVADDR_MASK 0x0fc00000 /* Physmedia devaddr Mask */ ++#define MDIODATA_WRITE 0x10000000 /* write Transaction */ ++#define MDIODATA_READ 0x20000000 /* Read Transaction */ ++#define MDIODATA_START 0x40000000 /* start of Transaction */ ++ ++/* MDIO devices (SERDES modules) */ ++#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */ ++#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */ ++#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */ ++ ++/* SERDES registers */ ++#define SERDES_RX_TIMER1 2 /* Rx Timer1 */ ++#define SERDES_RX_CDR 6 /* CDR */ ++#define SERDES_RX_CDRBW 7 /* CDR BW */ ++ ++#endif /* _SBPCIE_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,122 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane PCI core hardware definitions. ++ * ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ */ ++ ++#ifndef _SBPCI_H ++#define _SBPCI_H ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* Sonics side: PCI core and host control registers */ ++typedef struct sbpciregs { ++ uint32 control; /* PCI control */ ++ uint32 PAD[3]; ++ uint32 arbcontrol; /* PCI arbiter control */ ++ uint32 PAD[3]; ++ uint32 intstatus; /* Interrupt status */ ++ uint32 intmask; /* Interrupt mask */ ++ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */ ++ uint32 PAD[9]; ++ uint32 bcastaddr; /* Sonics broadcast address */ ++ uint32 bcastdata; /* Sonics broadcast data */ ++ uint32 PAD[2]; ++ uint32 gpioin; /* ro: gpio input (>=rev2) */ ++ uint32 gpioout; /* rw: gpio output (>=rev2) */ ++ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */ ++ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */ ++ uint32 PAD[36]; ++ uint32 sbtopci0; /* Sonics to PCI translation 0 */ ++ uint32 sbtopci1; /* Sonics to PCI translation 1 */ ++ uint32 sbtopci2; /* Sonics to PCI translation 2 */ ++ uint32 PAD[445]; ++ uint16 sprom[36]; /* SPROM shadow Area */ ++ uint32 PAD[46]; ++} sbpciregs_t; ++ ++/* PCI control */ ++#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ ++#define PCI_RST 0x02 /* Value driven out to pin */ ++#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ ++#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ ++ ++/* PCI arbiter control */ ++#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ ++#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ ++#define PCI_PARKID_MASK 0x06 /* Selects which agent is parked on an idle bus */ ++#define PCI_PARKID_SHIFT 1 ++#define PCI_PARKID_LAST 0 /* Last requestor */ ++#define PCI_PARKID_4710 1 /* 4710 */ ++#define PCI_PARKID_EXTREQ0 2 /* External requestor 0 */ ++#define PCI_PARKID_EXTREQ1 3 /* External requestor 1 */ ++ ++/* Interrupt status/mask */ ++#define PCI_INTA 0x01 /* PCI INTA# is asserted */ ++#define PCI_INTB 0x02 /* PCI INTB# is asserted */ ++#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ ++#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ ++#define PCI_PME 0x10 /* PCI PME# is asserted */ ++ ++/* (General) PCI/SB mailbox interrupts, two bits per pci function */ ++#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ ++#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ ++#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ ++#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ ++#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ ++#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ ++#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ ++#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ ++ ++/* Sonics broadcast address */ ++#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ ++ ++/* Sonics to PCI translation types */ ++#define SBTOPCI0_MASK 0xfc000000 ++#define SBTOPCI1_MASK 0xfc000000 ++#define SBTOPCI2_MASK 0xc0000000 ++#define SBTOPCI_MEM 0 ++#define SBTOPCI_IO 1 ++#define SBTOPCI_CFG0 2 ++#define SBTOPCI_CFG1 3 ++#define SBTOPCI_PREF 0x4 /* prefetch enable */ ++#define SBTOPCI_BURST 0x8 /* burst enable */ ++#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ ++#define SBTOPCI_RC_READ 0x00 /* memory read */ ++#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ ++#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ ++ ++/* PCI core index in SROM shadow area */ ++#define SRSH_PI_OFFSET 0 /* first word */ ++#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ ++#define SRSH_PI_SHIFT 12 /* bit 15:12 */ ++ ++/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */ ++#define cap_list rsvd_a[0] ++#define bar0_window dev_dep[0x80 - 0x40] ++#define bar1_window dev_dep[0x84 - 0x40] ++#define sprom_control dev_dep[0x88 - 0x40] ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); ++extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); ++extern void sbpci_ban(uint16 core); ++extern int sbpci_init(sb_t *sbh); ++extern void sbpci_check(sb_t *sbh); ++ ++#endif /* !_LANGUAGE_ASSEMBLY */ ++ ++#endif /* _SBPCI_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,146 @@ ++/* ++ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. ++ * ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ */ ++ ++#ifndef _SBPCMCIA_H ++#define _SBPCMCIA_H ++ ++ ++/* All the addresses that are offsets in attribute space are divided ++ * by two to account for the fact that odd bytes are invalid in ++ * attribute space and our read/write routines make the space appear ++ * as if they didn't exist. Still we want to show the original numbers ++ * as documented in the hnd_pcmcia core manual. ++ */ ++ ++/* PCMCIA Function Configuration Registers */ ++#define PCMCIA_FCR (0x700 / 2) ++ ++#define FCR0_OFF 0 ++#define FCR1_OFF (0x40 / 2) ++#define FCR2_OFF (0x80 / 2) ++#define FCR3_OFF (0xc0 / 2) ++ ++#define PCMCIA_FCR0 (0x700 / 2) ++#define PCMCIA_FCR1 (0x740 / 2) ++#define PCMCIA_FCR2 (0x780 / 2) ++#define PCMCIA_FCR3 (0x7c0 / 2) ++ ++/* Standard PCMCIA FCR registers */ ++ ++#define PCMCIA_COR 0 ++ ++#define COR_RST 0x80 ++#define COR_LEV 0x40 ++#define COR_IRQEN 0x04 ++#define COR_BLREN 0x01 ++#define COR_FUNEN 0x01 ++ ++ ++#define PCICIA_FCSR (2 / 2) ++#define PCICIA_PRR (4 / 2) ++#define PCICIA_SCR (6 / 2) ++#define PCICIA_ESR (8 / 2) ++ ++ ++#define PCM_MEMOFF 0x0000 ++#define F0_MEMOFF 0x1000 ++#define F1_MEMOFF 0x2000 ++#define F2_MEMOFF 0x3000 ++#define F3_MEMOFF 0x4000 ++ ++/* Memory base in the function fcr's */ ++#define MEM_ADDR0 (0x728 / 2) ++#define MEM_ADDR1 (0x72a / 2) ++#define MEM_ADDR2 (0x72c / 2) ++ ++/* PCMCIA base plus Srom access in fcr0: */ ++#define PCMCIA_ADDR0 (0x072e / 2) ++#define PCMCIA_ADDR1 (0x0730 / 2) ++#define PCMCIA_ADDR2 (0x0732 / 2) ++ ++#define MEM_SEG (0x0734 / 2) ++#define SROM_CS (0x0736 / 2) ++#define SROM_DATAL (0x0738 / 2) ++#define SROM_DATAH (0x073a / 2) ++#define SROM_ADDRL (0x073c / 2) ++#define SROM_ADDRH (0x073e / 2) ++ ++/* Values for srom_cs: */ ++#define SROM_IDLE 0 ++#define SROM_WRITE 1 ++#define SROM_READ 2 ++#define SROM_WEN 4 ++#define SROM_WDS 7 ++#define SROM_DONE 8 ++ ++/* CIS stuff */ ++ ++/* The CIS stops where the FCRs start */ ++#define CIS_SIZE PCMCIA_FCR ++ ++/* Standard tuples we know about */ ++ ++#define CISTPL_MANFID 0x20 /* Manufacturer and device id */ ++#define CISTPL_FUNCE 0x22 /* Function extensions */ ++#define CISTPL_CFTABLE 0x1b /* Config table entry */ ++ ++/* Function extensions for LANs */ ++ ++#define LAN_TECH 1 /* Technology type */ ++#define LAN_SPEED 2 /* Raw bit rate */ ++#define LAN_MEDIA 3 /* Transmission media */ ++#define LAN_NID 4 /* Node identification (aka MAC addr) */ ++#define LAN_CONN 5 /* Connector standard */ ++ ++ ++/* CFTable */ ++#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */ ++#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */ ++#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */ ++ ++/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll ++ * take one for HNBU, and use "extensions" (a la FUNCE) within it. ++ */ ++ ++#define CISTPL_BRCM_HNBU 0x80 ++ ++/* Subtypes of BRCM_HNBU: */ ++ ++#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */ ++#define HNBU_CHIPID 0x01 /* Six bytes with PCI vendor & ++ * device id and chiprev ++ */ ++#define HNBU_BOARDREV 0x02 /* Two bytes board revision */ ++#define HNBU_PAPARMS 0x03 /* PA parameters: 1 (old), 8 (sreomrev == 1) ++ * or 9 (sromrev > 1) bytes */ ++#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */ ++#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */ ++#define HNBU_AA 0x06 /* Antennas available */ ++#define HNBU_AG 0x07 /* Antenna gain */ ++#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */ ++#define HNBU_LEDS 0x09 /* LED set */ ++#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl) ++ * in rev 2 ++ */ ++#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */ ++#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */ ++ ++ ++/* sbtmstatelow */ ++#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */ ++#define SBTML_INT_EN 0x20000 /* enable sb interrupt */ ++ ++/* sbtmstatehigh */ ++#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */ ++ ++#endif /* _SBPCMCIA_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,75 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _SBSDRAM_H ++#define _SBSDRAM_H ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* Sonics side: SDRAM core registers */ ++typedef volatile struct sbsdramregs { ++ uint32 initcontrol; /* Generates external SDRAM initialization sequence */ ++ uint32 config; /* Initializes external SDRAM mode register */ ++ uint32 refresh; /* Controls external SDRAM refresh rate */ ++ uint32 pad1; ++ uint32 pad2; ++} sbsdramregs_t; ++ ++#endif ++ ++/* SDRAM initialization control (initcontrol) register bits */ ++#define SDRAM_CBR 0x0001 /* Writing 1 generates refresh cycle and toggles bit */ ++#define SDRAM_PRE 0x0002 /* Writing 1 generates precharge cycle and toggles bit */ ++#define SDRAM_MRS 0x0004 /* Writing 1 generates mode register select cycle and toggles bit */ ++#define SDRAM_EN 0x0008 /* When set, enables access to SDRAM */ ++#define SDRAM_16Mb 0x0000 /* Use 16 Megabit SDRAM */ ++#define SDRAM_64Mb 0x0010 /* Use 64 Megabit SDRAM */ ++#define SDRAM_128Mb 0x0020 /* Use 128 Megabit SDRAM */ ++#define SDRAM_RSVMb 0x0030 /* Use special SDRAM */ ++#define SDRAM_RST 0x0080 /* Writing 1 causes soft reset of controller */ ++#define SDRAM_SELFREF 0x0100 /* Writing 1 enables self refresh mode */ ++#define SDRAM_PWRDOWN 0x0200 /* Writing 1 causes controller to power down */ ++#define SDRAM_32BIT 0x0400 /* When set, indicates 32 bit SDRAM interface */ ++#define SDRAM_9BITCOL 0x0800 /* When set, indicates 9 bit column */ ++ ++/* SDRAM configuration (config) register bits */ ++#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */ ++#define SDRAM_BURST8 0x0001 /* Use burst of 8 */ ++#define SDRAM_BURST4 0x0002 /* Use burst of 4 */ ++#define SDRAM_BURST2 0x0003 /* Use burst of 2 */ ++#define SDRAM_CAS3 0x0000 /* Use CAS latency of 3 */ ++#define SDRAM_CAS2 0x0004 /* Use CAS latency of 2 */ ++ ++/* SDRAM refresh control (refresh) register bits */ ++#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */ ++#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */ ++ ++/* SDRAM Core default Init values (OCP ID 0x803) */ ++#define SDRAM_INIT MEM4MX16X2 ++#define SDRAM_CONFIG SDRAM_BURSTFULL ++#define SDRAM_REFRESH SDRAM_REF(0x40) ++ ++#define MEM1MX16 0x009 /* 2 MB */ ++#define MEM1MX16X2 0x409 /* 4 MB */ ++#define MEM2MX8X2 0x809 /* 4 MB */ ++#define MEM2MX8X4 0xc09 /* 8 MB */ ++#define MEM2MX32 0x439 /* 8 MB */ ++#define MEM4MX16 0x019 /* 8 MB */ ++#define MEM4MX16X2 0x419 /* 16 MB */ ++#define MEM8MX8X2 0x819 /* 16 MB */ ++#define MEM8MX16 0x829 /* 16 MB */ ++#define MEM4MX32 0x429 /* 16 MB */ ++#define MEM8MX8X4 0xc19 /* 32 MB */ ++#define MEM8MX16X2 0xc29 /* 32 MB */ ++ ++#endif /* _SBSDRAM_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,37 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane embedded ram core ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _SBSOCRAM_H ++#define _SBSOCRAM_H ++ ++#define SOCRAM_MEMSIZE 0x00 ++#define SOCRAM_BISTSTAT 0x0c ++ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* Memcsocram core registers */ ++typedef volatile struct sbsocramregs { ++ uint32 memsize; ++ uint32 biststat; ++} sbsocramregs_t; ++ ++#endif ++ ++/* Them memory size is 2 to the power of the following ++ * base added to the contents of the memsize register. ++ */ ++#define SOCRAM_MEMSIZE_BASESHIFT 16 ++ ++#endif /* _SBSOCRAM_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,140 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of Broadcom HNBU SiliconBackplane-based chips. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _sbutils_h_ ++#define _sbutils_h_ ++ ++/* ++ * Datastructure to export all chip specific common variables ++ * public (read-only) portion of sbutils handle returned by ++ * sb_attach()/sb_kattach() ++*/ ++ ++struct sb_pub { ++ ++ uint bustype; /* SB_BUS, PCI_BUS */ ++ uint buscoretype; /* SB_PCI, SB_PCMCIA, SB_PCIE*/ ++ uint buscorerev; /* buscore rev */ ++ uint buscoreidx; /* buscore index */ ++ int ccrev; /* chip common core rev */ ++ uint boardtype; /* board type */ ++ uint boardvendor; /* board vendor */ ++ uint chip; /* chip number */ ++ uint chiprev; /* chip revision */ ++ uint chippkg; /* chip package option */ ++ uint sonicsrev; /* sonics backplane rev */ ++}; ++ ++typedef const struct sb_pub sb_t; ++ ++/* ++ * Many of the routines below take an 'sbh' handle as their first arg. ++ * Allocate this by calling sb_attach(). Free it by calling sb_detach(). ++ * At any one time, the sbh is logically focused on one particular sb core ++ * (the "current core"). ++ * Use sb_setcore() or sb_setcoreidx() to change the association to another core. ++ */ ++ ++/* exported externs */ ++extern sb_t * BCMINIT(sb_attach)(uint pcidev, osl_t *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz); ++extern sb_t * BCMINIT(sb_kattach)(void); ++extern void sb_detach(sb_t *sbh); ++extern uint BCMINIT(sb_chip)(sb_t *sbh); ++extern uint BCMINIT(sb_chiprev)(sb_t *sbh); ++extern uint BCMINIT(sb_chipcrev)(sb_t *sbh); ++extern uint BCMINIT(sb_chippkg)(sb_t *sbh); ++extern uint BCMINIT(sb_pcirev)(sb_t *sbh); ++extern bool BCMINIT(sb_war16165)(sb_t *sbh); ++extern uint BCMINIT(sb_pcmciarev)(sb_t *sbh); ++extern uint BCMINIT(sb_boardvendor)(sb_t *sbh); ++extern uint BCMINIT(sb_boardtype)(sb_t *sbh); ++extern uint sb_bus(sb_t *sbh); ++extern uint sb_buscoretype(sb_t *sbh); ++extern uint sb_buscorerev(sb_t *sbh); ++extern uint sb_corelist(sb_t *sbh, uint coreid[]); ++extern uint sb_coreid(sb_t *sbh); ++extern uint sb_coreidx(sb_t *sbh); ++extern uint sb_coreunit(sb_t *sbh); ++extern uint sb_corevendor(sb_t *sbh); ++extern uint sb_corerev(sb_t *sbh); ++extern void *sb_osh(sb_t *sbh); ++extern void *sb_coreregs(sb_t *sbh); ++extern uint32 sb_coreflags(sb_t *sbh, uint32 mask, uint32 val); ++extern uint32 sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val); ++extern bool sb_iscoreup(sb_t *sbh); ++extern void *sb_setcoreidx(sb_t *sbh, uint coreidx); ++extern void *sb_setcore(sb_t *sbh, uint coreid, uint coreunit); ++extern int sb_corebist(sb_t *sbh, uint coreid, uint coreunit); ++extern void sb_commit(sb_t *sbh); ++extern uint32 sb_base(uint32 admatch); ++extern uint32 sb_size(uint32 admatch); ++extern void sb_core_reset(sb_t *sbh, uint32 bits); ++extern void sb_core_tofixup(sb_t *sbh); ++extern void sb_core_disable(sb_t *sbh, uint32 bits); ++extern uint32 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m); ++extern uint32 sb_clock(sb_t *sbh); ++extern void sb_pci_setup(sb_t *sbh, uint coremask); ++extern void sb_pcmcia_init(sb_t *sbh); ++extern void sb_watchdog(sb_t *sbh, uint ticks); ++extern void *sb_gpiosetcore(sb_t *sbh); ++extern uint32 sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioin(sb_t *sbh); ++extern uint32 sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioled(sb_t *sbh, uint32 mask, uint32 val); ++extern uint32 sb_gpioreserve(sb_t *sbh, uint32 gpio_num, uint8 priority); ++extern uint32 sb_gpiorelease(sb_t *sbh, uint32 gpio_num, uint8 priority); ++ ++extern void sb_clkctl_init(sb_t *sbh); ++extern uint16 sb_clkctl_fast_pwrup_delay(sb_t *sbh); ++extern bool sb_clkctl_clk(sb_t *sbh, uint mode); ++extern int sb_clkctl_xtal(sb_t *sbh, uint what, bool on); ++extern void sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, ++ void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg); ++extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to); ++extern void sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, ++ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif); ++extern uint sb_pcie_readreg(void *sbh, void* arg1, uint offset); ++extern uint sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val); ++extern uint32 sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 val); ++ ++ ++ ++/* ++* Build device path. Path size must be >= SB_DEVPATH_BUFSZ. ++* The returned path is NULL terminated and has trailing '/'. ++* Return 0 on success, nonzero otherwise. ++*/ ++extern int sb_devpath(sb_t *sbh, char *path, int size); ++ ++/* clkctl xtal what flags */ ++#define XTAL 0x1 /* primary crystal oscillator (2050) */ ++#define PLL 0x2 /* main chip pll */ ++ ++/* clkctl clk mode */ ++#define CLK_FAST 0 /* force fast (pll) clock */ ++#define CLK_DYNAMIC 2 /* enable dynamic clock control */ ++ ++ ++/* GPIO usage priorities */ ++#define GPIO_DRV_PRIORITY 0 ++#define GPIO_APP_PRIORITY 1 ++ ++/* device path */ ++#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ ++ ++#endif /* _sbutils_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sflash.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h +--- linux-2.4.32/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h 2005-12-16 23:39:10.936836250 +0100 +@@ -0,0 +1,36 @@ ++/* ++ * Broadcom SiliconBackplane chipcommon serial flash interface ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _sflash_h_ ++#define _sflash_h_ ++ ++#include ++#include ++ ++struct sflash { ++ uint blocksize; /* Block size */ ++ uint numblocks; /* Number of blocks */ ++ uint32 type; /* Type */ ++ uint size; /* Total size in bytes */ ++}; ++ ++/* Utility functions */ ++extern int sflash_poll(chipcregs_t *cc, uint offset); ++extern int sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf); ++extern int sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf); ++extern int sflash_erase(chipcregs_t *cc, uint offset); ++extern int sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf); ++extern struct sflash * sflash_init(chipcregs_t *cc); ++ ++#endif /* _sflash_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h +--- linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h 2005-12-16 23:39:10.940836500 +0100 +@@ -0,0 +1,33 @@ ++/* ++ * TRX image file header format. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++ ++#define TRX_MAGIC 0x30524448 /* "HDR0" */ ++#define TRX_VERSION 1 ++#define TRX_MAX_LEN 0x3A0000 ++#define TRX_NO_HEADER 1 /* Do not write TRX header */ ++#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ ++#define TRX_MAX_OFFSET 3 ++ ++struct trx_header { ++ uint32 magic; /* "HDR0" */ ++ uint32 len; /* Length of file including header */ ++ uint32 crc32; /* 32-bit CRC from flag_version to end of file */ ++ uint32 flag_version; /* 0:15 flags, 16:31 version */ ++ uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ ++}; ++ ++/* Compatibility */ ++typedef struct trx_header TRXHDR, *PTRXHDR; +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h +--- linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h 2005-12-16 23:39:10.940836500 +0100 +@@ -0,0 +1,326 @@ ++/* ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#ifndef _TYPEDEFS_H_ ++#define _TYPEDEFS_H_ ++ ++ ++/* Define 'SITE_TYPEDEFS' in the compile to include a site specific ++ * typedef file "site_typedefs.h". ++ * ++ * If 'SITE_TYPEDEFS' is not defined, then the "Inferred Typedefs" ++ * section of this file makes inferences about the compile environment ++ * based on defined symbols and possibly compiler pragmas. ++ * ++ * Following these two sections is the "Default Typedefs" ++ * section. This section is only prcessed if 'USE_TYPEDEF_DEFAULTS' is ++ * defined. This section has a default set of typedefs and a few ++ * proprocessor symbols (TRUE, FALSE, NULL, ...). ++ */ ++ ++#ifdef SITE_TYPEDEFS ++ ++/******************************************************************************* ++ * Site Specific Typedefs ++ *******************************************************************************/ ++ ++#include "site_typedefs.h" ++ ++#else ++ ++/******************************************************************************* ++ * Inferred Typedefs ++ *******************************************************************************/ ++ ++/* Infer the compile environment based on preprocessor symbols and pramas. ++ * Override type definitions as needed, and include configuration dependent ++ * header files to define types. ++ */ ++ ++#ifdef __cplusplus ++ ++#define TYPEDEF_BOOL ++#ifndef FALSE ++#define FALSE false ++#endif ++#ifndef TRUE ++#define TRUE true ++#endif ++ ++#else /* ! __cplusplus */ ++ ++#if defined(_WIN32) ++ ++#define TYPEDEF_BOOL ++typedef unsigned char bool; /* consistent w/BOOL */ ++ ++#endif /* _WIN32 */ ++ ++#endif /* ! __cplusplus */ ++ ++/* use the Windows ULONG_PTR type when compiling for 64 bit */ ++#if defined(_WIN64) ++#include ++#define TYPEDEF_UINTPTR ++typedef ULONG_PTR uintptr; ++#endif ++ ++#ifdef _HNDRTE_ ++typedef long unsigned int size_t; ++#endif ++ ++#ifdef _MSC_VER /* Microsoft C */ ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++typedef signed __int64 int64; ++typedef unsigned __int64 uint64; ++#endif ++ ++#if defined(MACOSX) && defined(KERNEL) ++#define TYPEDEF_BOOL ++#endif ++ ++ ++#if defined(linux) ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#define TYPEDEF_ULONG ++#endif ++ ++#if !defined(linux) && !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_) ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#endif ++ ++ ++/* Do not support the (u)int64 types with strict ansi for GNU C */ ++#if defined(__GNUC__) && defined(__STRICT_ANSI__) ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++#endif ++ ++/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode ++ * for singned or unsigned */ ++#if defined(__ICL) ++ ++#define TYPEDEF_INT64 ++ ++#if defined(__STDC__) ++#define TYPEDEF_UINT64 ++#endif ++ ++#endif /* __ICL */ ++ ++ ++#if !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_) ++ ++/* pick up ushort & uint from standard types.h */ ++#if defined(linux) && defined(__KERNEL__) ++ ++#include /* sys/types.h and linux/types.h are oil and water */ ++ ++#else ++ ++#include ++ ++#endif ++ ++#endif /* !_WIN32 && !PMON && !_CFE_ && !_HNDRTE_ && !_MINOSL_ */ ++ ++#if defined(MACOSX) && defined(KERNEL) ++#include ++#endif ++ ++ ++/* use the default typedefs in the next section of this file */ ++#define USE_TYPEDEF_DEFAULTS ++ ++#endif /* SITE_TYPEDEFS */ ++ ++ ++/******************************************************************************* ++ * Default Typedefs ++ *******************************************************************************/ ++ ++#ifdef USE_TYPEDEF_DEFAULTS ++#undef USE_TYPEDEF_DEFAULTS ++ ++#ifndef TYPEDEF_BOOL ++typedef /*@abstract@*/ unsigned char bool; ++#endif ++ ++/*----------------------- define uchar, ushort, uint, ulong ------------------*/ ++ ++#ifndef TYPEDEF_UCHAR ++typedef unsigned char uchar; ++#endif ++ ++#ifndef TYPEDEF_USHORT ++typedef unsigned short ushort; ++#endif ++ ++#ifndef TYPEDEF_UINT ++typedef unsigned int uint; ++#endif ++ ++#ifndef TYPEDEF_ULONG ++typedef unsigned long ulong; ++#endif ++ ++/*----------------------- define [u]int8/16/32/64, uintptr --------------------*/ ++ ++#ifndef TYPEDEF_UINT8 ++typedef unsigned char uint8; ++#endif ++ ++#ifndef TYPEDEF_UINT16 ++typedef unsigned short uint16; ++#endif ++ ++#ifndef TYPEDEF_UINT32 ++typedef unsigned int uint32; ++#endif ++ ++#ifndef TYPEDEF_UINT64 ++typedef unsigned long long uint64; ++#endif ++ ++#ifndef TYPEDEF_UINTPTR ++typedef unsigned int uintptr; ++#endif ++ ++#ifndef TYPEDEF_INT8 ++typedef signed char int8; ++#endif ++ ++#ifndef TYPEDEF_INT16 ++typedef signed short int16; ++#endif ++ ++#ifndef TYPEDEF_INT32 ++typedef signed int int32; ++#endif ++ ++#ifndef TYPEDEF_INT64 ++typedef signed long long int64; ++#endif ++ ++/*----------------------- define float32/64, float_t -----------------------*/ ++ ++#ifndef TYPEDEF_FLOAT32 ++typedef float float32; ++#endif ++ ++#ifndef TYPEDEF_FLOAT64 ++typedef double float64; ++#endif ++ ++/* ++ * abstracted floating point type allows for compile time selection of ++ * single or double precision arithmetic. Compiling with -DFLOAT32 ++ * selects single precision; the default is double precision. ++ */ ++ ++#ifndef TYPEDEF_FLOAT_T ++ ++#if defined(FLOAT32) ++typedef float32 float_t; ++#else /* default to double precision floating point */ ++typedef float64 float_t; ++#endif ++ ++#endif /* TYPEDEF_FLOAT_T */ ++ ++/*----------------------- define macro values -----------------------------*/ ++ ++#ifndef FALSE ++#define FALSE 0 ++#endif ++ ++#ifndef TRUE ++#define TRUE 1 ++#endif ++ ++#ifndef NULL ++#define NULL 0 ++#endif ++ ++#ifndef OFF ++#define OFF 0 ++#endif ++ ++#ifndef ON ++#define ON 1 ++#endif ++ ++#define AUTO (-1) ++ ++/* Reclaiming text and data : ++ The following macros specify special linker sections that can be reclaimed ++ after a system is considered 'up'. ++ */ ++#if defined(__GNUC__) && defined(BCMRECLAIM) ++extern bool bcmreclaimed; ++#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data##_ini ++#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn##_ini ++#define BCMINIT(_id) _id##_ini ++#else ++#define BCMINITDATA(_data) _data ++#define BCMINITFN(_fn) _fn ++#define BCMINIT(_id) _id ++#define bcmreclaimed 0 ++#endif ++ ++/*----------------------- define PTRSZ, INLINE ----------------------------*/ ++ ++#ifndef PTRSZ ++#define PTRSZ sizeof (char*) ++#endif ++ ++#ifndef INLINE ++ ++#ifdef _MSC_VER ++ ++#define INLINE __inline ++ ++#elif __GNUC__ ++ ++#define INLINE __inline__ ++ ++#else ++ ++#define INLINE ++ ++#endif /* _MSC_VER */ ++ ++#endif /* INLINE */ ++ ++#undef TYPEDEF_BOOL ++#undef TYPEDEF_UCHAR ++#undef TYPEDEF_USHORT ++#undef TYPEDEF_UINT ++#undef TYPEDEF_ULONG ++#undef TYPEDEF_UINT8 ++#undef TYPEDEF_UINT16 ++#undef TYPEDEF_UINT32 ++#undef TYPEDEF_UINT64 ++#undef TYPEDEF_UINTPTR ++#undef TYPEDEF_INT8 ++#undef TYPEDEF_INT16 ++#undef TYPEDEF_INT32 ++#undef TYPEDEF_INT64 ++#undef TYPEDEF_FLOAT32 ++#undef TYPEDEF_FLOAT64 ++#undef TYPEDEF_FLOAT_T ++ ++#endif /* USE_TYPEDEF_DEFAULTS */ ++ ++#endif /* _TYPEDEFS_H_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/wlioctl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/wlioctl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/wlioctl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/wlioctl.h 2005-12-16 23:39:10.940836500 +0100 +@@ -0,0 +1,1030 @@ ++/* ++ * Custom OID/ioctl definitions for ++ * Broadcom 802.11abg Networking Device Driver ++ * ++ * Definitions subject to change without notice. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#ifndef _wlioctl_h_ ++#define _wlioctl_h_ ++ ++#include ++#include ++#include ++#include ++#include ++ ++/* require default structure packing */ ++#if !defined(__GNUC__) ++#pragma pack(push,8) ++#endif ++ ++#define WL_NUMRATES 255 /* max # of rates in a rateset */ ++ ++typedef struct wl_rateset { ++ uint32 count; /* # rates in this set */ ++ uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ ++} wl_rateset_t; ++ ++#define WL_CHANSPEC_CHAN_MASK 0x0fff ++#define WL_CHANSPEC_BAND_MASK 0xf000 ++#define WL_CHANSPEC_BAND_SHIFT 12 ++#define WL_CHANSPEC_BAND_A 0x1000 ++#define WL_CHANSPEC_BAND_B 0x2000 ++ ++/* ++ * Per-bss information structure. ++ */ ++ ++#define WL_BSS_INFO_VERSION 107 /* current version of wl_bss_info struct */ ++ ++typedef struct wl_bss_info { ++ uint32 version; /* version field */ ++ uint32 length; /* byte length of data in this record, starting at version and including IEs */ ++ struct ether_addr BSSID; ++ uint16 beacon_period; /* units are Kusec */ ++ uint16 capability; /* Capability information */ ++ uint8 SSID_len; ++ uint8 SSID[32]; ++ struct { ++ uint count; /* # rates in this set */ ++ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ ++ } rateset; /* supported rates */ ++ uint8 channel; /* Channel no. */ ++ uint16 atim_window; /* units are Kusec */ ++ uint8 dtim_period; /* DTIM period */ ++ int16 RSSI; /* receive signal strength (in dBm) */ ++ int8 phy_noise; /* noise (in dBm) */ ++ uint32 ie_length; /* byte length of Information Elements */ ++ /* variable length Information Elements */ ++} wl_bss_info_t; ++ ++typedef struct wlc_ssid { ++ uint32 SSID_len; ++ uchar SSID[32]; ++} wlc_ssid_t; ++ ++typedef struct wl_scan_params { ++ wlc_ssid_t ssid; /* default is {0, ""} */ ++ struct ether_addr bssid;/* default is bcast */ ++ int8 bss_type; /* default is any, DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT */ ++ int8 scan_type; /* -1 use default, DOT11_SCANTYPE_ACTIVE/PASSIVE */ ++ int32 nprobes; /* -1 use default, number of probes per channel */ ++ int32 active_time; /* -1 use default, dwell time per channel for active scanning */ ++ int32 passive_time; /* -1 use default, dwell time per channel for passive scanning */ ++ int32 home_time; /* -1 use default, dwell time for the home channel between channel scans */ ++ int32 channel_num; /* 0 use default (all available channels), count of channels in channel_list */ ++ uint16 channel_list[1]; /* list of chanspecs */ ++} wl_scan_params_t; ++/* size of wl_scan_params not including variable length array */ ++#define WL_SCAN_PARAMS_FIXED_SIZE 64 ++ ++typedef struct wl_scan_results { ++ uint32 buflen; ++ uint32 version; ++ uint32 count; ++ wl_bss_info_t bss_info[1]; ++} wl_scan_results_t; ++/* size of wl_scan_results not including variable length array */ ++#define WL_SCAN_RESULTS_FIXED_SIZE 12 ++ ++/* uint32 list */ ++typedef struct wl_uint32_list { ++ /* in - # of elements, out - # of entries */ ++ uint32 count; ++ /* variable length uint32 list */ ++ uint32 element[1]; ++} wl_uint32_list_t; ++ ++#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NULL */ ++ ++typedef struct wl_channels_in_country { ++ uint32 buflen; ++ uint32 band; ++ char country_abbrev[WLC_CNTRY_BUF_SZ]; ++ uint32 count; ++ uint32 channel[1]; ++} wl_channels_in_country_t; ++ ++typedef struct wl_country_list { ++ uint32 buflen; ++ uint32 band_set; ++ uint32 band; ++ uint32 count; ++ char country_abbrev[1]; ++} wl_country_list_t; ++ ++#define WL_RM_TYPE_BASIC 1 ++#define WL_RM_TYPE_CCA 2 ++#define WL_RM_TYPE_RPI 3 ++ ++#define WL_RM_FLAG_PARALLEL (1<<0) ++ ++#define WL_RM_FLAG_LATE (1<<1) ++#define WL_RM_FLAG_INCAPABLE (1<<2) ++#define WL_RM_FLAG_REFUSED (1<<3) ++ ++typedef struct wl_rm_req_elt { ++ int8 type; ++ int8 flags; ++ uint16 chanspec; ++ uint32 token; /* token for this measurement */ ++ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ ++ uint32 tsf_l; /* TSF low 32-bits */ ++ uint32 dur; /* TUs */ ++} wl_rm_req_elt_t; ++ ++typedef struct wl_rm_req { ++ uint32 token; /* overall measurement set token */ ++ uint32 count; /* number of measurement reqests */ ++ wl_rm_req_elt_t req[1]; /* variable length block of requests */ ++} wl_rm_req_t; ++#define WL_RM_REQ_FIXED_LEN 8 ++ ++typedef struct wl_rm_rep_elt { ++ int8 type; ++ int8 flags; ++ uint16 chanspec; ++ uint32 token; /* token for this measurement */ ++ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ ++ uint32 tsf_l; /* TSF low 32-bits */ ++ uint32 dur; /* TUs */ ++ uint32 len; /* byte length of data block */ ++ uint8 data[1]; /* variable length data block */ ++} wl_rm_rep_elt_t; ++#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ ++ ++#define WL_RPI_REP_BIN_NUM 8 ++typedef struct wl_rm_rpi_rep { ++ uint8 rpi[WL_RPI_REP_BIN_NUM]; ++ int8 rpi_max[WL_RPI_REP_BIN_NUM]; ++} wl_rm_rpi_rep_t; ++ ++typedef struct wl_rm_rep { ++ uint32 token; /* overall measurement set token */ ++ uint32 len; /* length of measurement report block */ ++ wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ ++} wl_rm_rep_t; ++#define WL_RM_REP_FIXED_LEN 8 ++ ++ ++#if defined(BCMSUP_PSK) ++typedef enum sup_auth_status { ++ WLC_SUP_DISCONNECTED = 0, ++ WLC_SUP_CONNECTING, ++ WLC_SUP_IDREQUIRED, ++ WLC_SUP_AUTHENTICATING, ++ WLC_SUP_AUTHENTICATED, ++ WLC_SUP_KEYXCHANGE, ++ WLC_SUP_KEYED, ++ WLC_SUP_TIMEOUT ++} sup_auth_status_t; ++#endif /* BCMCCX | BCMSUP_PSK */ ++ ++/* Enumerate crypto algorithms */ ++#define CRYPTO_ALGO_OFF 0 ++#define CRYPTO_ALGO_WEP1 1 ++#define CRYPTO_ALGO_TKIP 2 ++#define CRYPTO_ALGO_WEP128 3 ++#define CRYPTO_ALGO_AES_CCM 4 ++#define CRYPTO_ALGO_AES_OCB_MSDU 5 ++#define CRYPTO_ALGO_AES_OCB_MPDU 6 ++#define CRYPTO_ALGO_NALG 7 ++ ++#define WSEC_GEN_MIC_ERROR 0x0001 ++#define WSEC_GEN_REPLAY 0x0002 ++ ++#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ ++#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ ++#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ ++#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ ++ ++typedef struct wl_wsec_key { ++ uint32 index; /* key index */ ++ uint32 len; /* key length */ ++ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */ ++ uint32 pad_1[18]; ++ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ ++ uint32 flags; /* misc flags */ ++ uint32 pad_2[2]; ++ int pad_3; ++ int iv_initialized; /* has IV been initialized already? */ ++ int pad_4; ++ /* Rx IV */ ++ struct { ++ uint32 hi; /* upper 32 bits of IV */ ++ uint16 lo; /* lower 16 bits of IV */ ++ } rxiv; ++ uint32 pad_5[2]; ++ struct ether_addr ea; /* per station */ ++} wl_wsec_key_t; ++ ++ ++#define WSEC_MIN_PSK_LEN 8 ++#define WSEC_MAX_PSK_LEN 64 ++ ++/* Flag for key material needing passhash'ing */ ++#define WSEC_PASSPHRASE (1<<0) ++ ++/* recepticle for WLC_SET_WSEC_PMK parameter */ ++typedef struct { ++ ushort key_len; /* octets in key material */ ++ ushort flags; /* key handling qualification */ ++ uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ ++} wsec_pmk_t; ++ ++/* wireless security bitvec */ ++#define WEP_ENABLED 0x0001 ++#define TKIP_ENABLED 0x0002 ++#define AES_ENABLED 0x0004 ++#define WSEC_SWFLAG 0x0008 ++#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ ++ ++/* WPA authentication mode bitvec */ ++#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ ++#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ ++#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ ++#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ ++/*#define WPA_AUTH_8021X 0x0020*/ /* 802.1x, reserved */ ++ ++#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ ++#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ ++ ++ ++ ++/* pmkid */ ++#define MAXPMKID 16 ++ ++typedef struct _pmkid ++{ ++ struct ether_addr BSSID; ++ uint8 PMKID[WPA2_PMKID_LEN]; ++} pmkid_t; ++ ++typedef struct _pmkid_list ++{ ++ uint32 npmkid; ++ pmkid_t pmkid[1]; ++} pmkid_list_t; ++ ++typedef struct _pmkid_cand { ++ struct ether_addr BSSID; ++ uint8 preauth; ++} pmkid_cand_t; ++ ++typedef struct _pmkid_cand_list { ++ uint32 npmkid_cand; ++ pmkid_cand_t pmkid_cand[1]; ++} pmkid_cand_list_t; ++ ++ ++typedef struct wl_led_info { ++ uint32 index; /* led index */ ++ uint32 behavior; ++ bool activehi; ++} wl_led_info_t; ++ ++typedef struct wlc_assoc_info { ++ uint32 req_len; ++ uint32 resp_len; ++ uint32 flags; ++ struct dot11_assoc_req req; ++ struct ether_addr reassoc_bssid; /* used in reassoc's */ ++ struct dot11_assoc_resp resp; ++} wl_assoc_info_t; ++/* flags */ ++#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ ++/* srom read/write struct passed through ioctl */ ++typedef struct { ++ uint byteoff; /* byte offset */ ++ uint nbytes; /* number of bytes */ ++ uint16 buf[1]; ++} srom_rw_t; ++ ++/* R_REG and W_REG struct passed through ioctl */ ++typedef struct { ++ uint32 byteoff; /* byte offset of the field in d11regs_t */ ++ uint32 val; /* read/write value of the field */ ++ uint32 size; /* sizeof the field */ ++ uint band; /* band (optional) */ ++} rw_reg_t; ++ ++/* Structure used by GET/SET_ATTEN ioctls */ ++typedef struct { ++ uint16 auto_ctrl; /* 1: Automatic control, 0: overriden */ ++ uint16 bb; /* Baseband attenuation */ ++ uint16 radio; /* Radio attenuation */ ++ uint16 txctl1; /* Radio TX_CTL1 value */ ++} atten_t; ++ ++/* Used to get specific STA parameters */ ++typedef struct { ++ uint32 val; ++ struct ether_addr ea; ++} scb_val_t; ++ ++ ++/* Event data type */ ++typedef struct wlc_event { ++ wl_event_msg_t event; /* encapsulated event */ ++ struct ether_addr *addr; /* used to keep a trace of the potential present of ++ an address in wlc_event_msg_t */ ++ void *data; /* used to hang additional data on an event */ ++ struct wlc_event *next; /* enables ordered list of pending events */ ++} wlc_event_t; ++ ++#define BCM_MAC_STATUS_INDICATION (0x40010200L) ++ ++typedef struct { ++ uint16 ver; /* version of this struct */ ++ uint16 len; /* length in bytes of this structure */ ++ uint16 cap; /* sta's advertized capabilities */ ++ uint32 flags; /* flags defined below */ ++ uint32 idle; /* time since data pkt rx'd from sta */ ++ struct ether_addr ea; /* Station address */ ++ wl_rateset_t rateset; /* rateset in use */ ++ uint32 in; /* seconds elapsed since associated */ ++ uint32 listen_interval_inms; /* Min Listen interval in ms for this STA*/ ++} sta_info_t; ++ ++#define WL_STA_VER 2 ++ ++/* flags fields */ ++#define WL_STA_BRCM 0x01 ++#define WL_STA_WME 0x02 ++#define WL_STA_ABCAP 0x04 ++#define WL_STA_AUTHE 0x08 ++#define WL_STA_ASSOC 0x10 ++#define WL_STA_AUTHO 0x20 ++#define WL_STA_WDS 0x40 ++#define WL_WDS_LINKUP 0x80 ++ ++ ++/* ++ * Country locale determines which channels are available to us. ++ */ ++typedef enum _wlc_locale { ++ WLC_WW = 0, /* Worldwide */ ++ WLC_THA, /* Thailand */ ++ WLC_ISR, /* Israel */ ++ WLC_JDN, /* Jordan */ ++ WLC_PRC, /* China */ ++ WLC_JPN, /* Japan */ ++ WLC_FCC, /* USA */ ++ WLC_EUR, /* Europe */ ++ WLC_USL, /* US Low Band only */ ++ WLC_JPH, /* Japan High Band only */ ++ WLC_ALL, /* All the channels in this band */ ++ WLC_11D, /* Represents locale recieved by 11d beacons */ ++ WLC_LAST_LOCALE, ++ WLC_UNDEFINED_LOCALE = 0xf ++} wlc_locale_t; ++ ++/* channel encoding */ ++typedef struct channel_info { ++ int hw_channel; ++ int target_channel; ++ int scan_channel; ++} channel_info_t; ++ ++/* For ioctls that take a list of MAC addresses */ ++struct maclist { ++ uint count; /* number of MAC addresses */ ++ struct ether_addr ea[1]; /* variable length array of MAC addresses */ ++}; ++ ++/* get pkt count struct passed through ioctl */ ++typedef struct get_pktcnt { ++ uint rx_good_pkt; ++ uint rx_bad_pkt; ++ uint tx_good_pkt; ++ uint tx_bad_pkt; ++} get_pktcnt_t; ++ ++/* Linux network driver ioctl encoding */ ++typedef struct wl_ioctl { ++ uint cmd; /* common ioctl definition */ ++ void *buf; /* pointer to user buffer */ ++ uint len; /* length of user buffer */ ++ bool set; /* get or set request (optional) */ ++ uint used; /* bytes read or written (optional) */ ++ uint needed; /* bytes needed (optional) */ ++} wl_ioctl_t; ++ ++/* ++ * Structure for passing hardware and software ++ * revision info up from the driver. ++ */ ++typedef struct wlc_rev_info { ++ uint vendorid; /* PCI vendor id */ ++ uint deviceid; /* device id of chip */ ++ uint radiorev; /* radio revision */ ++ uint chiprev; /* chip revision */ ++ uint corerev; /* core revision */ ++ uint boardid; /* board identifier (usu. PCI sub-device id) */ ++ uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ ++ uint boardrev; /* board revision */ ++ uint driverrev; /* driver version */ ++ uint ucoderev; /* microcode version */ ++ uint bus; /* bus type */ ++ uint chipnum; /* chip number */ ++} wlc_rev_info_t; ++ ++#define WL_BRAND_MAX 10 ++typedef struct wl_instance_info { ++ uint instance; ++ char brand[WL_BRAND_MAX]; ++} wl_instance_info_t; ++ ++/* check this magic number */ ++#define WLC_IOCTL_MAGIC 0x14e46c77 ++ ++/* bump this number if you change the ioctl interface */ ++#define WLC_IOCTL_VERSION 1 ++ ++#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ ++#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ ++ ++/* common ioctl definitions */ ++#define WLC_GET_MAGIC 0 ++#define WLC_GET_VERSION 1 ++#define WLC_UP 2 ++#define WLC_DOWN 3 ++#define WLC_DUMP 6 ++#define WLC_GET_MSGLEVEL 7 ++#define WLC_SET_MSGLEVEL 8 ++#define WLC_GET_PROMISC 9 ++#define WLC_SET_PROMISC 10 ++#define WLC_GET_RATE 12 ++/* #define WLC_SET_RATE 13 */ /* no longer supported */ ++#define WLC_GET_INSTANCE 14 ++/* #define WLC_GET_FRAG 15 */ /* no longer supported */ ++/* #define WLC_SET_FRAG 16 */ /* no longer supported */ ++/* #define WLC_GET_RTS 17 */ /* no longer supported */ ++/* #define WLC_SET_RTS 18 */ /* no longer supported */ ++#define WLC_GET_INFRA 19 ++#define WLC_SET_INFRA 20 ++#define WLC_GET_AUTH 21 ++#define WLC_SET_AUTH 22 ++#define WLC_GET_BSSID 23 ++#define WLC_SET_BSSID 24 ++#define WLC_GET_SSID 25 ++#define WLC_SET_SSID 26 ++#define WLC_RESTART 27 ++#define WLC_GET_CHANNEL 29 ++#define WLC_SET_CHANNEL 30 ++#define WLC_GET_SRL 31 ++#define WLC_SET_SRL 32 ++#define WLC_GET_LRL 33 ++#define WLC_SET_LRL 34 ++#define WLC_GET_PLCPHDR 35 ++#define WLC_SET_PLCPHDR 36 ++#define WLC_GET_RADIO 37 ++#define WLC_SET_RADIO 38 ++#define WLC_GET_PHYTYPE 39 ++/* #define WLC_GET_WEP 42 */ /* no longer supported */ ++/* #define WLC_SET_WEP 43 */ /* no longer supported */ ++#define WLC_GET_KEY 44 ++#define WLC_SET_KEY 45 ++#define WLC_GET_REGULATORY 46 ++#define WLC_SET_REGULATORY 47 ++#define WLC_SCAN 50 ++#define WLC_SCAN_RESULTS 51 ++#define WLC_DISASSOC 52 ++#define WLC_REASSOC 53 ++#define WLC_GET_ROAM_TRIGGER 54 ++#define WLC_SET_ROAM_TRIGGER 55 ++#define WLC_GET_TXANT 61 ++#define WLC_SET_TXANT 62 ++#define WLC_GET_ANTDIV 63 ++#define WLC_SET_ANTDIV 64 ++/* #define WLC_GET_TXPWR 65 */ /* no longer supported */ ++/* #define WLC_SET_TXPWR 66 */ /* no longer supported */ ++#define WLC_GET_CLOSED 67 ++#define WLC_SET_CLOSED 68 ++#define WLC_GET_MACLIST 69 ++#define WLC_SET_MACLIST 70 ++#define WLC_GET_RATESET 71 ++#define WLC_SET_RATESET 72 ++#define WLC_GET_LOCALE 73 ++#define WLC_LONGTRAIN 74 ++#define WLC_GET_BCNPRD 75 ++#define WLC_SET_BCNPRD 76 ++#define WLC_GET_DTIMPRD 77 ++#define WLC_SET_DTIMPRD 78 ++#define WLC_GET_SROM 79 ++#define WLC_SET_SROM 80 ++#define WLC_GET_WEP_RESTRICT 81 ++#define WLC_SET_WEP_RESTRICT 82 ++#define WLC_GET_COUNTRY 83 ++#define WLC_SET_COUNTRY 84 ++#define WLC_GET_REVINFO 98 ++#define WLC_GET_MACMODE 105 ++#define WLC_SET_MACMODE 106 ++#define WLC_GET_GMODE 109 ++#define WLC_SET_GMODE 110 ++#define WLC_GET_CURR_RATESET 114 /* current rateset */ ++#define WLC_GET_SCANSUPPRESS 115 ++#define WLC_SET_SCANSUPPRESS 116 ++#define WLC_GET_AP 117 ++#define WLC_SET_AP 118 ++#define WLC_GET_EAP_RESTRICT 119 ++#define WLC_SET_EAP_RESTRICT 120 ++#define WLC_GET_WDSLIST 123 ++#define WLC_SET_WDSLIST 124 ++#define WLC_GET_RSSI 127 ++#define WLC_GET_WSEC 133 ++#define WLC_SET_WSEC 134 ++#define WLC_GET_BSS_INFO 136 ++#define WLC_GET_LAZYWDS 138 ++#define WLC_SET_LAZYWDS 139 ++#define WLC_GET_BANDLIST 140 ++#define WLC_GET_BAND 141 ++#define WLC_SET_BAND 142 ++#define WLC_GET_SHORTSLOT 144 ++#define WLC_GET_SHORTSLOT_OVERRIDE 145 ++#define WLC_SET_SHORTSLOT_OVERRIDE 146 ++#define WLC_GET_SHORTSLOT_RESTRICT 147 ++#define WLC_SET_SHORTSLOT_RESTRICT 148 ++#define WLC_GET_GMODE_PROTECTION 149 ++#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 ++#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 ++#define WLC_UPGRADE 152 ++/* #define WLC_GET_MRATE 153 */ /* no longer supported */ ++/* #define WLC_SET_MRATE 154 */ /* no longer supported */ ++#define WLC_GET_ASSOCLIST 159 ++#define WLC_GET_CLK 160 ++#define WLC_SET_CLK 161 ++#define WLC_GET_UP 162 ++#define WLC_OUT 163 ++#define WLC_GET_WPA_AUTH 164 ++#define WLC_SET_WPA_AUTH 165 ++#define WLC_GET_GMODE_PROTECTION_CONTROL 178 ++#define WLC_SET_GMODE_PROTECTION_CONTROL 179 ++#define WLC_GET_PHYLIST 180 ++#define WLC_GET_KEY_SEQ 183 ++#define WLC_GET_GMODE_PROTECTION_CTS 198 ++#define WLC_SET_GMODE_PROTECTION_CTS 199 ++#define WLC_GET_PIOMODE 203 ++#define WLC_SET_PIOMODE 204 ++#define WLC_SET_LED 209 ++#define WLC_GET_LED 210 ++#define WLC_GET_CHANNEL_SEL 215 ++#define WLC_START_CHANNEL_SEL 216 ++#define WLC_GET_VALID_CHANNELS 217 ++#define WLC_GET_FAKEFRAG 218 ++#define WLC_SET_FAKEFRAG 219 ++#define WLC_GET_WET 230 ++#define WLC_SET_WET 231 ++#define WLC_GET_KEY_PRIMARY 235 ++#define WLC_SET_KEY_PRIMARY 236 ++#define WLC_GET_RADAR 242 ++#define WLC_SET_RADAR 243 ++#define WLC_SET_SPECT_MANAGMENT 244 ++#define WLC_GET_SPECT_MANAGMENT 245 ++#define WLC_WDS_GET_REMOTE_HWADDR 246 /* currently handled in wl_linux.c/wl_vx.c */ ++#define WLC_SET_CS_SCAN_TIMER 248 ++#define WLC_GET_CS_SCAN_TIMER 249 ++#define WLC_SEND_PWR_CONSTRAINT 254 ++#define WLC_CURRENT_PWR 256 ++#define WLC_GET_CHANNELS_IN_COUNTRY 260 ++#define WLC_GET_COUNTRY_LIST 261 ++#define WLC_GET_VAR 262 /* get value of named variable */ ++#define WLC_SET_VAR 263 /* set named variable to value */ ++#define WLC_NVRAM_GET 264 ++#define WLC_NVRAM_SET 265 ++#define WLC_SET_WSEC_PMK 268 ++#define WLC_GET_AUTH_MODE 269 ++#define WLC_SET_AUTH_MODE 270 ++#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ ++#define WLC_NVOTPW 274 ++/* #define WLC_OTPW 275 */ /* no longer supported */ ++#define WLC_SET_LOCALE 278 ++#define WLC_LAST 279 /* do not change - use get_var/set_var */ ++ ++/* ++ * Minor kludge alert: ++ * Duplicate a few definitions that irelay requires from epiioctl.h here ++ * so caller doesn't have to include this file and epiioctl.h . ++ * If this grows any more, it would be time to move these irelay-specific ++ * definitions out of the epiioctl.h and into a separate driver common file. ++ */ ++#ifndef EPICTRL_COOKIE ++#define EPICTRL_COOKIE 0xABADCEDE ++#endif ++ ++/* vx wlc ioctl's offset */ ++#define CMN_IOCTL_OFF 0x180 ++ ++/* ++ * custom OID support ++ * ++ * 0xFF - implementation specific OID ++ * 0xE4 - first byte of Broadcom PCI vendor ID ++ * 0x14 - second byte of Broadcom PCI vendor ID ++ * 0xXX - the custom OID number ++ */ ++ ++/* begin 0x1f values beyond the start of the ET driver range. */ ++#define WL_OID_BASE 0xFFE41420 ++ ++/* NDIS overrides */ ++#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) ++#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) ++ ++#define WL_DECRYPT_STATUS_SUCCESS 1 ++#define WL_DECRYPT_STATUS_FAILURE 2 ++#define WL_DECRYPT_STATUS_UNKNOWN 3 ++ ++/* allows user-mode app to poll the status of USB image upgrade */ ++#define WLC_UPGRADE_SUCCESS 0 ++#define WLC_UPGRADE_PENDING 1 ++ ++#ifdef CONFIG_USBRNDIS_RETAIL ++/* struct passed in for WLC_NDCONFIG_ITEM */ ++typedef struct { ++ char *name; ++ void *param; ++} ndconfig_item_t; ++#endif ++ ++/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ ++#define WL_RADIO_SW_DISABLE (1<<0) ++#define WL_RADIO_HW_DISABLE (1<<1) ++#define WL_RADIO_MPC_DISABLE (1<<2) ++#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any 802.11 channel */ ++ ++/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ ++#define WL_TXPWR_OVERRIDE (1<<31) ++ ++/* "diag" iovar argument and error code */ ++#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ ++#define WL_DIAG_MEMORY 3 /* d11 memory test */ ++#define WL_DIAG_LED 4 /* LED test */ ++#define WL_DIAG_REG 5 /* d11/phy register test */ ++#define WL_DIAG_SROM 6 /* srom read/crc test */ ++#define WL_DIAG_DMA 7 /* DMA test */ ++ ++#define WL_DIAGERR_SUCCESS 0 ++#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ ++#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ ++#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ ++#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ ++#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ ++#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ ++#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ ++#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ ++#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ ++#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ ++ ++/* Bus types */ ++#define WL_SB_BUS 0 /* Silicon Backplane */ ++#define WL_PCI_BUS 1 /* PCI target */ ++#define WL_PCMCIA_BUS 2 /* PCMCIA target */ ++ ++/* band types */ ++#define WLC_BAND_AUTO 0 /* auto-select */ ++#define WLC_BAND_A 1 /* "a" band (5 Ghz) */ ++#define WLC_BAND_B 2 /* "b" band (2.4 Ghz) */ ++#define WLC_BAND_ALL 3 /* all bands */ ++ ++/* phy types (returned by WLC_GET_PHYTPE) */ ++#define WLC_PHY_TYPE_A 0 ++#define WLC_PHY_TYPE_B 1 ++#define WLC_PHY_TYPE_G 2 ++#define WLC_PHY_TYPE_NULL 0xf ++ ++/* MAC list modes */ ++#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ ++#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ ++#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ ++ ++/* ++ * ++ */ ++#define GMODE_LEGACY_B 0 ++#define GMODE_AUTO 1 ++#define GMODE_ONLY 2 ++#define GMODE_B_DEFERRED 3 ++#define GMODE_PERFORMANCE 4 ++#define GMODE_LRS 5 ++#define GMODE_MAX 6 ++ ++/* values for PLCPHdr_override */ ++#define WLC_PLCP_AUTO -1 ++#define WLC_PLCP_SHORT 0 ++#define WLC_PLCP_LONG 1 ++ ++/* values for g_protection_override */ ++#define WLC_G_PROTECTION_AUTO -1 ++#define WLC_G_PROTECTION_OFF 0 ++#define WLC_G_PROTECTION_ON 1 ++ ++/* values for g_protection_control */ ++#define WLC_G_PROTECTION_CTL_OFF 0 ++#define WLC_G_PROTECTION_CTL_LOCAL 1 ++#define WLC_G_PROTECTION_CTL_OVERLAP 2 ++ ++/* Values for PM */ ++#define PM_OFF 0 ++#define PM_MAX 1 ++#define PM_FAST 2 ++ ++ ++ ++typedef struct { ++ int npulses; /* required number of pulses at n * t_int */ ++ int ncontig; /* required number of pulses at t_int */ ++ int min_pw; /* minimum pulse width (20 MHz clocks) */ ++ int max_pw; /* maximum pulse width (20 MHz clocks) */ ++ uint16 thresh0; /* Radar detection, thresh 0 */ ++ uint16 thresh1; /* Radar detection, thresh 1 */ ++} wl_radar_args_t; ++ ++/* radar iovar SET defines */ ++#define WL_RADRA_DETECTOR_OFF 0 /* radar dector off */ ++#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */ ++#define WL_RADAR_SIMULATED 2 /* force radar detector to declare detection once */ ++ ++/* dfs_status iovar-related defines */ ++ ++/* cac - channel availability check, ++ * ism - in-service monitoring ++ * csa - channel switching anouncement ++ */ ++ ++/* cac state values */ ++#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */ ++#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */ ++#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */ ++#define WL_DFS_CACSTATE_CSA 3 /* csa */ ++#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */ ++#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */ ++#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */ ++#define WL_DFS_CACSTATES 7 /* this many states exist */ ++ ++/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */ ++typedef struct { ++ uint state; /* noted by WL_DFS_CACSTATE_XX. */ ++ uint duration; /* time spent in ms in state. */ ++ /* as dfs enters ISM state, it removes the operational channel from quiet channel list ++ * and notes the channel in channel_cleared. set to 0 if no channel is cleared ++ */ ++ uint channel_cleared; ++} wl_dfs_status_t; ++ ++#define NUM_PWRCTRL_RATES 12 ++ ++ ++/* 802.11h enforcement levels */ ++#define SPECT_MNGMT_OFF 0 /* 11h disabled */ ++#define SPECT_MNGMT_LOOSE 1 /* allow scan lists to contain non-11h AP */ ++#define SPECT_MNGMT_STRICT 2 /* prune out non-11h APs from scan list */ ++#define SPECT_MNGMT_11D 3 /* switch to 802.11D mode */ ++ ++#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ ++#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */ ++#define WL_CHAN_BAND_A (1 << 2) /* A-band channel */ ++#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ ++#define WL_CHAN_INACTIVE (1 << 4) /* temporarily out of service due to radar */ ++#define WL_CHAN_RADAR_PASSIVE (1 << 5) /* radar channel is in passive mode */ ++ ++#define WL_MPC_VAL 0x00400000 ++#define WL_APSTA_VAL 0x00800000 ++#define WL_DFS_VAL 0x01000000 ++ ++/* max # of leds supported by GPIO (gpio pin# == led index#) */ ++#define WL_LED_NUMGPIO 16 /* gpio 0-15 */ ++ ++/* led per-pin behaviors */ ++#define WL_LED_OFF 0 /* always off */ ++#define WL_LED_ON 1 /* always on */ ++#define WL_LED_ACTIVITY 2 /* activity */ ++#define WL_LED_RADIO 3 /* radio enabled */ ++#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */ ++#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */ ++#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */ ++#define WL_LED_WI1 7 ++#define WL_LED_WI2 8 ++#define WL_LED_WI3 9 ++#define WL_LED_ASSOC 10 /* associated state indicator */ ++#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */ ++#define WL_LED_NUMBEHAVIOR 12 ++ ++/* led behavior numeric value format */ ++#define WL_LED_BEH_MASK 0x7f /* behavior mask */ ++#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */ ++ ++ ++/* WDS link local endpoint WPA role */ ++#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */ ++#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */ ++#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */ ++ ++/* number of bytes needed to define a 128-bit mask for MAC event reporting */ ++#define WL_EVENTING_MASK_LEN 16 ++ ++/* Structures and constants used for "vndr_ie" IOVar interface */ ++#define VNDR_IE_CMD_LEN 4 /* length of the set command string: "add", "del" (+ NULL) */ ++ ++/* 802.11 Mgmt Packet flags */ ++#define VNDR_IE_BEACON_FLAG 0x1 ++#define VNDR_IE_PRBRSP_FLAG 0x2 ++#define VNDR_IE_ASSOCRSP_FLAG 0x4 ++#define VNDR_IE_AUTHRSP_FLAG 0x8 ++ ++typedef struct { ++ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ ++ vndr_ie_t vndr_ie_data; /* vendor IE data */ ++} vndr_ie_info_t; ++ ++typedef struct { ++ int iecount; /* number of entries in the vndr_ie_list[] array */ ++ vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */ ++} vndr_ie_buf_t; ++ ++typedef struct { ++ char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NULL */ ++ vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */ ++} vndr_ie_setbuf_t; ++ ++/* join target preference types */ ++#define WL_JOIN_PREF_RSSI 1 /* by RSSI, mandatory */ ++#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers, optional, RSN and WPA as values */ ++#define WL_JOIN_PREF_BAND 3 /* by 802.11 band, optional, WLC_BAND_XXXX as values */ ++ ++/* band preference */ ++#define WLJP_BAND_ASSOC_PREF 255 /* use assoc preference settings */ ++ /* others use WLC_BAND_XXXX as values */ ++ ++/* any multicast cipher suite */ ++#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" ++ ++#if !defined(__GNUC__) ++#pragma pack(pop) ++#endif ++ ++#define NFIFO 6 /* # tx/rx fifopairs */ ++ ++#define WL_CNT_T_VERSION 1 /* current version of wl_cnt_t struct */ ++ ++typedef struct { ++ uint16 version; /* see definition of WL_CNT_T_VERSION */ ++ uint16 length; /* length of entire structure */ ++ ++ /* transmit stat counters */ ++ uint32 txframe; /* tx data frames */ ++ uint32 txbyte; /* tx data bytes */ ++ uint32 txretrans; /* tx mac retransmits */ ++ uint32 txerror; /* tx data errors */ ++ uint32 txctl; /* tx management frames */ ++ uint32 txprshort; /* tx short preamble frames */ ++ uint32 txserr; /* tx status errors */ ++ uint32 txnobuf; /* tx out of buffers errors */ ++ uint32 txnoassoc; /* tx discard because we're not associated */ ++ uint32 txrunt; /* tx runt frames */ ++ uint32 txchit; /* tx header cache hit (fastpath) */ ++ uint32 txcmiss; /* tx header cache miss (slowpath) */ ++ ++ /* transmit chip error counters */ ++ uint32 txuflo; /* tx fifo underflows */ ++ uint32 txphyerr; /* tx phy errors (indicated in tx status) */ ++ uint32 txphycrs; ++ ++ /* receive stat counters */ ++ uint32 rxframe; /* rx data frames */ ++ uint32 rxbyte; /* rx data bytes */ ++ uint32 rxerror; /* rx data errors */ ++ uint32 rxctl; /* rx management frames */ ++ uint32 rxnobuf; /* rx out of buffers errors */ ++ uint32 rxnondata; /* rx non data frames in the data channel errors */ ++ uint32 rxbadds; /* rx bad DS errors */ ++ uint32 rxbadcm; /* rx bad control or management frames */ ++ uint32 rxfragerr; /* rx fragmentation errors */ ++ uint32 rxrunt; /* rx runt frames */ ++ uint32 rxgiant; /* rx giant frames */ ++ uint32 rxnoscb; /* rx no scb error */ ++ uint32 rxbadproto; /* rx invalid frames */ ++ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac*/ ++ uint32 rxbadda; /* rx frames tossed for invalid da */ ++ uint32 rxfilter; /* rx frames filtered out */ ++ ++ /* receive chip error counters */ ++ uint32 rxoflo; /* rx fifo overflow errors */ ++ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ ++ ++ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ ++ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ ++ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ ++ ++ /* misc counters */ ++ uint32 dmade; /* tx/rx dma descriptor errors */ ++ uint32 dmada; /* tx/rx dma data errors */ ++ uint32 dmape; /* tx/rx dma descriptor protocol errors */ ++ uint32 reset; /* reset count */ ++ uint32 tbtt; /* cnts the TBTT int's */ ++ uint32 txdmawar; ++ ++ /* MAC counters: 32-bit version of d11.h's macstat_t */ ++ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, ++ Control Management (includes retransmissions) */ ++ uint32 txrtsfrm; /* number of RTS sent out by the MAC */ ++ uint32 txctsfrm; /* number of CTS sent out by the MAC */ ++ uint32 txackfrm; /* number of ACK frames sent out */ ++ uint32 txdnlfrm; /* Not used */ ++ uint32 txbcnfrm; /* beacons transmitted */ ++ uint32 txfunfl[8]; /* per-fifo tx underflows */ ++ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS or BCN) */ ++ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for ++ driver enqueued frames*/ ++ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ ++ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ ++ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not ++ data/control/management*/ ++ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ ++ uint32 rxbadplcp; /* parity check of the PLCP header failed */ ++ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ ++ uint32 rxstrt; /* Number of received frames with a good PLCP (i.e. passing parity check) */ ++ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ ++ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ ++ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ ++ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ ++ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS)*/ ++ uint32 rxackucast; /* number of ucast ACKS received (good FCS)*/ ++ uint32 rxdfrmocast; /* number of received DATA frames with good FCS and not matching RA */ ++ uint32 rxmfrmocast; /* number of received MGMT frames with good FCS and not matching RA */ ++ uint32 rxcfrmocast; /* number of received CNTRL frame with good FCS and not matching RA */ ++ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ ++ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ ++ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ ++ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ ++ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC (unlikely ++ to see these) */ ++ uint32 rxbeaconmbss; /* beacons received from member of BSS */ ++ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from other BSS (WDS FRAME) */ ++ uint32 rxbeaconobss; /* beacons received from other BSS */ ++ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames expecting a ++ response */ ++ uint32 bcntxcancl; /* transmit beacons cancelled due to receipt of beacon (IBSS) */ ++ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ ++ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ ++ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ ++ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ ++ uint32 pmqovfl; /* Number of PMQ overflows */ ++ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into the PRQ fifo */ ++ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ ++ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did not get ACK */ ++ uint32 txcgprssuc; /* Tx Probe Rresponse Success (ACK was received) */ ++ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ fifo because ++ a probe response could not be sent out within the time limit defined ++ in M_PRS_MAXTIME */ ++ uint32 rxnack; /* Number of NACKS received (Afterburner) */ ++ uint32 frmscons; /* Number of frames completed without transmission because of an ++ Afterburner re-queue */ ++ uint32 txnack; /* Number of NACKs transmtitted (Afterburner) */ ++ uint32 txglitch_nack; /* obsolete */ ++ uint32 txburst; /* obsolete */ ++ uint32 rxburst; /* obsolete */ ++ ++ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ ++ uint32 txfrag; /* dot11TransmittedFragmentCount */ ++ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ ++ uint32 txfail; /* dot11FailedCount */ ++ uint32 txretry; /* dot11RetryCount */ ++ uint32 txretrie; /* dot11MultipleRetryCount */ ++ uint32 rxdup; /* dot11FrameduplicateCount */ ++ uint32 txrts; /* dot11RTSSuccessCount */ ++ uint32 txnocts; /* dot11RTSFailureCount */ ++ uint32 txnoack; /* dot11ACKFailureCount */ ++ uint32 rxfrag; /* dot11ReceivedFragmentCount */ ++ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ ++ uint32 rxcrc; /* dot11FCSErrorCount */ ++ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ ++ uint32 rxundec; /* dot11WEPUndecryptableCount */ ++ ++ /* WPA2 counters (see rxundec for DecryptFailureCount) */ ++ uint32 tkipmicfaill; /* TKIPLocalMICFailures */ ++ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ ++ uint32 tkipreplay; /* TKIPReplays */ ++ uint32 ccmpfmterr; /* CCMPFormatErrors */ ++ uint32 ccmpreplay; /* CCMPReplays */ ++ uint32 ccmpundec; /* CCMPDecryptErrors */ ++ uint32 fourwayfail; /* FourWayHandshakeFailures */ ++ uint32 wepundec; /* dot11WEPUndecryptableCount */ ++ uint32 wepicverr; /* dot11WEPICVErrorCount */ ++ uint32 decsuccess; /* DecryptSuccessCount */ ++ uint32 tkipicverr; /* TKIPICVErrorCount */ ++ uint32 wepexcluded; /* dot11WEPExcludedCount */ ++} wl_cnt_t; ++ ++#endif /* _wlioctl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile +--- linux-2.4.32/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile 2005-12-19 01:56:51.733868750 +0100 +@@ -0,0 +1,15 @@ ++# ++# Makefile for the BCM947xx specific kernel interface routines ++# under Linux. ++# ++ ++EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER ++ ++O_TARGET := bcm947xx.o ++ ++export-objs := nvram_linux.o setup.o ++obj-y := prom.o setup.o time.o sbmips.o gpio.o ++obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o ++obj-$(CONFIG_PCI) += sbpci.o pcibios.o ++ ++include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c +--- linux-2.4.32/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c 2005-12-19 01:05:00.079582750 +0100 +@@ -0,0 +1,320 @@ ++/* ++ * NVRAM variable manipulation (common) ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern struct nvram_tuple * BCMINIT(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value); ++extern void BCMINIT(_nvram_free)(struct nvram_tuple *t); ++extern int BCMINIT(_nvram_read)(void *buf); ++ ++char * BCMINIT(_nvram_get)(const char *name); ++int BCMINIT(_nvram_set)(const char *name, const char *value); ++int BCMINIT(_nvram_unset)(const char *name); ++int BCMINIT(_nvram_getall)(char *buf, int count); ++int BCMINIT(_nvram_commit)(struct nvram_header *header); ++int BCMINIT(_nvram_init)(void); ++void BCMINIT(_nvram_exit)(void); ++ ++static struct nvram_tuple * BCMINITDATA(nvram_hash)[257]; ++static struct nvram_tuple * nvram_dead; ++ ++/* Free all tuples. Should be locked. */ ++static void ++BCMINITFN(nvram_free)(void) ++{ ++ uint i; ++ struct nvram_tuple *t, *next; ++ ++ /* Free hash table */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { ++ for (t = BCMINIT(nvram_hash)[i]; t; t = next) { ++ next = t->next; ++ BCMINIT(_nvram_free)(t); ++ } ++ BCMINIT(nvram_hash)[i] = NULL; ++ } ++ ++ /* Free dead table */ ++ for (t = nvram_dead; t; t = next) { ++ next = t->next; ++ BCMINIT(_nvram_free)(t); ++ } ++ nvram_dead = NULL; ++ ++ /* Indicate to per-port code that all tuples have been freed */ ++ BCMINIT(_nvram_free)(NULL); ++} ++ ++/* String hash */ ++static INLINE uint ++hash(const char *s) ++{ ++ uint hash = 0; ++ ++ while (*s) ++ hash = 31 * hash + *s++; ++ ++ return hash; ++} ++ ++/* (Re)initialize the hash table. Should be locked. */ ++static int ++BCMINITFN(nvram_rehash)(struct nvram_header *header) ++{ ++ char buf[] = "0xXXXXXXXX", *name, *value, *end, *eq; ++ ++ /* (Re)initialize hash table */ ++ BCMINIT(nvram_free)(); ++ ++ /* Parse and set "name=value\0 ... \0\0" */ ++ name = (char *) &header[1]; ++ end = (char *) header + NVRAM_SPACE - 2; ++ end[0] = end[1] = '\0'; ++ for (; *name; name = value + strlen(value) + 1) { ++ if (!(eq = strchr(name, '='))) ++ break; ++ *eq = '\0'; ++ value = eq + 1; ++ BCMINIT(_nvram_set)(name, value); ++ *eq = '='; ++ } ++ ++ /* Set special SDRAM parameters */ ++ if (!BCMINIT(_nvram_get)("sdram_init")) { ++ sprintf(buf, "0x%04X", (uint16)(header->crc_ver_init >> 16)); ++ BCMINIT(_nvram_set)("sdram_init", buf); ++ } ++ if (!BCMINIT(_nvram_get)("sdram_config")) { ++ sprintf(buf, "0x%04X", (uint16)(header->config_refresh & 0xffff)); ++ BCMINIT(_nvram_set)("sdram_config", buf); ++ } ++ if (!BCMINIT(_nvram_get)("sdram_refresh")) { ++ sprintf(buf, "0x%04X", (uint16)((header->config_refresh >> 16) & 0xffff)); ++ BCMINIT(_nvram_set)("sdram_refresh", buf); ++ } ++ if (!BCMINIT(_nvram_get)("sdram_ncdl")) { ++ sprintf(buf, "0x%08X", header->config_ncdl); ++ BCMINIT(_nvram_set)("sdram_ncdl", buf); ++ } ++ ++ return 0; ++} ++ ++/* Get the value of an NVRAM variable. Should be locked. */ ++char * ++BCMINITFN(_nvram_get)(const char *name) ++{ ++ uint i; ++ struct nvram_tuple *t; ++ char *value; ++ ++ if (!name) ++ return NULL; ++ ++ /* Hash the name */ ++ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++ ++ /* Find the associated tuple in the hash table */ ++ for (t = BCMINIT(nvram_hash)[i]; t && strcmp(t->name, name); t = t->next); ++ ++ value = t ? t->value : NULL; ++ ++ return value; ++} ++ ++/* Get the value of an NVRAM variable. Should be locked. */ ++int ++BCMINITFN(_nvram_set)(const char *name, const char *value) ++{ ++ uint i; ++ struct nvram_tuple *t, *u, **prev; ++ ++ /* Hash the name */ ++ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++ ++ /* Find the associated tuple in the hash table */ ++ for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev); ++ ++ /* (Re)allocate tuple */ ++ if (!(u = BCMINIT(_nvram_realloc)(t, name, value))) ++ return -12; /* -ENOMEM */ ++ ++ /* Value reallocated */ ++ if (t && t == u) ++ return 0; ++ ++ /* Move old tuple to the dead table */ ++ if (t) { ++ *prev = t->next; ++ t->next = nvram_dead; ++ nvram_dead = t; ++ } ++ ++ /* Add new tuple to the hash table */ ++ u->next = BCMINIT(nvram_hash)[i]; ++ BCMINIT(nvram_hash)[i] = u; ++ ++ return 0; ++} ++ ++/* Unset the value of an NVRAM variable. Should be locked. */ ++int ++BCMINITFN(_nvram_unset)(const char *name) ++{ ++ uint i; ++ struct nvram_tuple *t, **prev; ++ ++ if (!name) ++ return 0; ++ ++ /* Hash the name */ ++ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++ ++ /* Find the associated tuple in the hash table */ ++ for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev); ++ ++ /* Move it to the dead table */ ++ if (t) { ++ *prev = t->next; ++ t->next = nvram_dead; ++ nvram_dead = t; ++ } ++ ++ return 0; ++} ++ ++/* Get all NVRAM variables. Should be locked. */ ++int ++BCMINITFN(_nvram_getall)(char *buf, int count) ++{ ++ uint i; ++ struct nvram_tuple *t; ++ int len = 0; ++ ++ bzero(buf, count); ++ ++ /* Write name=value\0 ... \0\0 */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { ++ for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) { ++ if ((count - len) > (strlen(t->name) + 1 + strlen(t->value) + 1)) ++ len += sprintf(buf + len, "%s=%s", t->name, t->value) + 1; ++ else ++ break; ++ } ++ } ++ ++ return 0; ++} ++ ++/* Regenerate NVRAM. Should be locked. */ ++int ++BCMINITFN(_nvram_commit)(struct nvram_header *header) ++{ ++ char *init, *config, *refresh, *ncdl; ++ char *ptr, *end; ++ int i; ++ struct nvram_tuple *t; ++ struct nvram_header tmp; ++ uint8 crc; ++ ++ /* Regenerate header */ ++ header->magic = NVRAM_MAGIC; ++ header->crc_ver_init = (NVRAM_VERSION << 8); ++ if (!(init = BCMINIT(_nvram_get)("sdram_init")) || ++ !(config = BCMINIT(_nvram_get)("sdram_config")) || ++ !(refresh = BCMINIT(_nvram_get)("sdram_refresh")) || ++ !(ncdl = BCMINIT(_nvram_get)("sdram_ncdl"))) { ++ header->crc_ver_init |= SDRAM_INIT << 16; ++ header->config_refresh = SDRAM_CONFIG; ++ header->config_refresh |= SDRAM_REFRESH << 16; ++ header->config_ncdl = 0; ++ } else { ++ header->crc_ver_init |= (bcm_strtoul(init, NULL, 0) & 0xffff) << 16; ++ header->config_refresh = bcm_strtoul(config, NULL, 0) & 0xffff; ++ header->config_refresh |= (bcm_strtoul(refresh, NULL, 0) & 0xffff) << 16; ++ header->config_ncdl = bcm_strtoul(ncdl, NULL, 0); ++ } ++ ++ /* Clear data area */ ++ ptr = (char *) header + sizeof(struct nvram_header); ++ bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header)); ++ ++ /* Leave space for a double NUL at the end */ ++ end = (char *) header + NVRAM_SPACE - 2; ++ ++ /* Write out all tuples */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { ++ for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) { ++ if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end) ++ break; ++ ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1; ++ } ++ } ++ ++ /* End with a double NUL */ ++ ptr += 2; ++ ++ /* Set new length */ ++ header->len = ROUNDUP(ptr - (char *) header, 4); ++ ++ /* Little-endian CRC8 over the last 11 bytes of the header */ ++ tmp.crc_ver_init = htol32(header->crc_ver_init); ++ tmp.config_refresh = htol32(header->config_refresh); ++ tmp.config_ncdl = htol32(header->config_ncdl); ++ crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE); ++ ++ /* Continue CRC8 over data bytes */ ++ crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc); ++ ++ /* Set new CRC8 */ ++ header->crc_ver_init |= crc; ++ ++ /* Reinitialize hash table */ ++ return BCMINIT(nvram_rehash)(header); ++} ++ ++/* Initialize hash table. Should be locked. */ ++int ++BCMINITFN(_nvram_init)(void) ++{ ++ struct nvram_header *header; ++ int ret; ++ void *osh; ++ ++ /* get kernel osl handler */ ++ osh = osl_attach(NULL); ++ ++ if (!(header = (struct nvram_header *) MALLOC(osh, NVRAM_SPACE))) { ++ printf("nvram_init: out of memory, malloced %d bytes\n", MALLOCED(osh)); ++ return -12; /* -ENOMEM */ ++ } ++ ++ if ((ret = BCMINIT(_nvram_read)(header)) == 0 && ++ header->magic == NVRAM_MAGIC) ++ BCMINIT(nvram_rehash)(header); ++ ++ MFREE(osh, header, NVRAM_SPACE); ++ return ret; ++} ++ ++/* Free hash table. Should be locked. */ ++void ++BCMINITFN(_nvram_exit)(void) ++{ ++ BCMINIT(nvram_free)(); ++} +diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c +--- linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c 2005-12-19 01:09:59.782313000 +0100 +@@ -0,0 +1,653 @@ ++/* ++ * NVRAM variable manipulation (Linux kernel half) ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* In BSS to minimize text size and page aligned so it can be mmap()-ed */ ++static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE))); ++ ++#ifdef MODULE ++ ++#define early_nvram_get(name) nvram_get(name) ++ ++#else /* !MODULE */ ++ ++/* Global SB handle */ ++extern void *bcm947xx_sbh; ++extern spinlock_t bcm947xx_sbh_lock; ++ ++static int cfe_env; ++extern char *cfe_env_get(char *nv_buf, const char *name); ++ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock ++#define KB * 1024 ++#define MB * 1024 * 1024 ++ ++/* Probe for NVRAM header */ ++static void __init ++early_nvram_init(void) ++{ ++ struct nvram_header *header; ++ chipcregs_t *cc; ++ struct sflash *info = NULL; ++ int i; ++ uint32 base, off, lim; ++ u32 *src, *dst; ++ ++ if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) { ++ base = KSEG1ADDR(SB_FLASH2); ++ switch (readl(&cc->capabilities) & CAP_FLASH_MASK) { ++ case PFLASH: ++ lim = SB_FLASH2_SZ; ++ break; ++ ++ case SFLASH_ST: ++ case SFLASH_AT: ++ if ((info = sflash_init(cc)) == NULL) ++ return; ++ lim = info->size; ++ break; ++ ++ case FLASH_NONE: ++ default: ++ return; ++ } ++ } else { ++ /* extif assumed, Stop at 4 MB */ ++ base = KSEG1ADDR(SB_FLASH1); ++ lim = SB_FLASH1_SZ; ++ } ++ ++ /* XXX: hack for supporting the CFE environment stuff on WGT634U */ ++ src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000); ++ dst = (u32 *) nvram_buf; ++ if ((lim == 0x02000000) && ((*src & 0xff00ff) == 0x000001)) { ++ printk("early_nvram_init: WGT634U NVRAM found.\n"); ++ ++ for (i = 0; i < 0x1ff0; i++) { ++ if (*src == 0xFFFFFFFF) ++ break; ++ *dst++ = *src++; ++ } ++ cfe_env = 1; ++ return; ++ } ++ ++ off = FLASH_MIN; ++ while (off <= lim) { ++ /* Windowed flash access */ ++ header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ off <<= 1; ++ } ++ ++ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ ++ header = (struct nvram_header *) KSEG1ADDR(base + 4 KB); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ ++ header = (struct nvram_header *) KSEG1ADDR(base + 1 KB); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ ++ printk("early_nvram_init: NVRAM not found\n"); ++ return; ++ ++found: ++ src = (u32 *) header; ++ dst = (u32 *) nvram_buf; ++ for (i = 0; i < sizeof(struct nvram_header); i += 4) ++ *dst++ = *src++; ++ for (; i < header->len && i < NVRAM_SPACE; i += 4) ++ *dst++ = ltoh32(*src++); ++} ++ ++/* Early (before mm or mtd) read-only access to NVRAM */ ++static char * __init ++early_nvram_get(const char *name) ++{ ++ char *var, *value, *end, *eq; ++ ++ if (!name) ++ return NULL; ++ ++ /* Too early? */ ++ if (sbh == NULL) ++ return NULL; ++ ++ if (!nvram_buf[0]) ++ early_nvram_init(); ++ ++ if (cfe_env) ++ return cfe_env_get(nvram_buf, name); ++ ++ /* Look for name=value and return value */ ++ var = &nvram_buf[sizeof(struct nvram_header)]; ++ end = nvram_buf + sizeof(nvram_buf) - 2; ++ end[0] = end[1] = '\0'; ++ for (; *var; var = value + strlen(value) + 1) { ++ if (!(eq = strchr(var, '='))) ++ break; ++ value = eq + 1; ++ if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0) ++ return value; ++ } ++ ++ return NULL; ++} ++ ++#endif /* !MODULE */ ++ ++extern char * _nvram_get(const char *name); ++extern int _nvram_set(const char *name, const char *value); ++extern int _nvram_unset(const char *name); ++extern int _nvram_getall(char *buf, int count); ++extern int _nvram_commit(struct nvram_header *header); ++extern int _nvram_init(void); ++extern void _nvram_exit(void); ++ ++/* Globals */ ++static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED; ++static struct semaphore nvram_sem; ++static unsigned long nvram_offset = 0; ++static int nvram_major = -1; ++static devfs_handle_t nvram_handle = NULL; ++static struct mtd_info *nvram_mtd = NULL; ++ ++int ++_nvram_read(char *buf) ++{ ++ struct nvram_header *header = (struct nvram_header *) buf; ++ size_t len; ++ ++ if (!nvram_mtd || ++ MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) || ++ len != NVRAM_SPACE || ++ header->magic != NVRAM_MAGIC) { ++ /* Maybe we can recover some data from early initialization */ ++ memcpy(buf, nvram_buf, NVRAM_SPACE); ++ } ++ ++ return 0; ++} ++ ++struct nvram_tuple * ++_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value) ++{ ++ if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE) ++ return NULL; ++ ++ if (!t) { ++ if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC))) ++ return NULL; ++ ++ /* Copy name */ ++ t->name = (char *) &t[1]; ++ strcpy(t->name, name); ++ ++ t->value = NULL; ++ } ++ ++ /* Copy value */ ++ if (!t->value || strcmp(t->value, value)) { ++ t->value = &nvram_buf[nvram_offset]; ++ strcpy(t->value, value); ++ nvram_offset += strlen(value) + 1; ++ } ++ ++ return t; ++} ++ ++void ++_nvram_free(struct nvram_tuple *t) ++{ ++ if (!t) ++ nvram_offset = 0; ++ else ++ kfree(t); ++} ++ ++int ++nvram_set(const char *name, const char *value) ++{ ++ unsigned long flags; ++ int ret; ++ struct nvram_header *header; ++ ++ spin_lock_irqsave(&nvram_lock, flags); ++ if ((ret = _nvram_set(name, value))) { ++ /* Consolidate space and try again */ ++ if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) { ++ if (_nvram_commit(header) == 0) ++ ret = _nvram_set(name, value); ++ kfree(header); ++ } ++ } ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ ++ return ret; ++} ++ ++char * ++real_nvram_get(const char *name) ++{ ++ unsigned long flags; ++ char *value; ++ ++ spin_lock_irqsave(&nvram_lock, flags); ++ value = _nvram_get(name); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ ++ return value; ++} ++ ++char * ++nvram_get(const char *name) ++{ ++ if (nvram_major >= 0) ++ return real_nvram_get(name); ++ else ++ return early_nvram_get(name); ++} ++ ++int ++nvram_unset(const char *name) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&nvram_lock, flags); ++ ret = _nvram_unset(name); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ ++ return ret; ++} ++ ++static void ++erase_callback(struct erase_info *done) ++{ ++ wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv; ++ wake_up(wait_q); ++} ++ ++int ++nvram_commit(void) ++{ ++ char *buf; ++ size_t erasesize, len; ++ unsigned int i; ++ int ret; ++ struct nvram_header *header; ++ unsigned long flags; ++ u_int32_t offset; ++ DECLARE_WAITQUEUE(wait, current); ++ wait_queue_head_t wait_q; ++ struct erase_info erase; ++ ++ if (!nvram_mtd) { ++ printk("nvram_commit: NVRAM not found\n"); ++ return -ENODEV; ++ } ++ ++ if (in_interrupt()) { ++ printk("nvram_commit: not committing in interrupt\n"); ++ return -EINVAL; ++ } ++ ++ /* Backup sector blocks to be erased */ ++ erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize); ++ if (!(buf = kmalloc(erasesize, GFP_KERNEL))) { ++ printk("nvram_commit: out of memory\n"); ++ return -ENOMEM; ++ } ++ ++ down(&nvram_sem); ++ ++ if ((i = erasesize - NVRAM_SPACE) > 0) { ++ offset = nvram_mtd->size - erasesize; ++ len = 0; ++ ret = MTD_READ(nvram_mtd, offset, i, &len, buf); ++ if (ret || len != i) { ++ printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i); ++ ret = -EIO; ++ goto done; ++ } ++ header = (struct nvram_header *)(buf + i); ++ } else { ++ offset = nvram_mtd->size - NVRAM_SPACE; ++ header = (struct nvram_header *)buf; ++ } ++ ++ /* Regenerate NVRAM */ ++ spin_lock_irqsave(&nvram_lock, flags); ++ ret = _nvram_commit(header); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ if (ret) ++ goto done; ++ ++ /* Erase sector blocks */ ++ init_waitqueue_head(&wait_q); ++ for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) { ++ erase.mtd = nvram_mtd; ++ erase.addr = offset; ++ erase.len = nvram_mtd->erasesize; ++ erase.callback = erase_callback; ++ erase.priv = (u_long) &wait_q; ++ ++ set_current_state(TASK_INTERRUPTIBLE); ++ add_wait_queue(&wait_q, &wait); ++ ++ /* Unlock sector blocks */ ++ if (nvram_mtd->unlock) ++ nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize); ++ ++ if ((ret = MTD_ERASE(nvram_mtd, &erase))) { ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&wait_q, &wait); ++ printk("nvram_commit: erase error\n"); ++ goto done; ++ } ++ ++ /* Wait for erase to finish */ ++ schedule(); ++ remove_wait_queue(&wait_q, &wait); ++ } ++ ++ /* Write partition up to end of data area */ ++ offset = nvram_mtd->size - erasesize; ++ i = erasesize - NVRAM_SPACE + header->len; ++ ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf); ++ if (ret || len != i) { ++ printk("nvram_commit: write error\n"); ++ ret = -EIO; ++ goto done; ++ } ++ ++ offset = nvram_mtd->size - erasesize; ++ ret = MTD_READ(nvram_mtd, offset, 4, &len, buf); ++ ++ done: ++ up(&nvram_sem); ++ kfree(buf); ++ return ret; ++} ++ ++int ++nvram_getall(char *buf, int count) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&nvram_lock, flags); ++ ret = _nvram_getall(buf, count); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ ++ return ret; ++} ++ ++EXPORT_SYMBOL(nvram_get); ++EXPORT_SYMBOL(nvram_getall); ++EXPORT_SYMBOL(nvram_set); ++EXPORT_SYMBOL(nvram_unset); ++EXPORT_SYMBOL(nvram_commit); ++ ++/* User mode interface below */ ++ ++static ssize_t ++dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ char tmp[100], *name = tmp, *value; ++ ssize_t ret; ++ unsigned long off; ++ ++ if (count > sizeof(tmp)) { ++ if (!(name = kmalloc(count, GFP_KERNEL))) ++ return -ENOMEM; ++ } ++ ++ if (copy_from_user(name, buf, count)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ++ if (*name == '\0') { ++ /* Get all variables */ ++ ret = nvram_getall(name, count); ++ if (ret == 0) { ++ if (copy_to_user(buf, name, count)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ret = count; ++ } ++ } else { ++ if (!(value = nvram_get(name))) { ++ ret = 0; ++ goto done; ++ } ++ ++ /* Provide the offset into mmap() space */ ++ off = (unsigned long) value - (unsigned long) nvram_buf; ++ ++ if (put_user(off, (unsigned long *) buf)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ++ ret = sizeof(unsigned long); ++ } ++ ++ flush_cache_all(); ++ ++done: ++ if (name != tmp) ++ kfree(name); ++ ++ return ret; ++} ++ ++static ssize_t ++dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ++{ ++ char tmp[100], *name = tmp, *value; ++ ssize_t ret; ++ ++ if (count > sizeof(tmp)) { ++ if (!(name = kmalloc(count, GFP_KERNEL))) ++ return -ENOMEM; ++ } ++ ++ if (copy_from_user(name, buf, count)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ++ value = name; ++ name = strsep(&value, "="); ++ if (value) ++ ret = nvram_set(name, value) ? : count; ++ else ++ ret = nvram_unset(name) ? : count; ++ ++ done: ++ if (name != tmp) ++ kfree(name); ++ ++ return ret; ++} ++ ++static int ++dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) ++{ ++ if (cmd != NVRAM_MAGIC) ++ return -EINVAL; ++ return nvram_commit(); ++} ++ ++static int ++dev_nvram_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ unsigned long offset = virt_to_phys(nvram_buf); ++ ++ if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start, ++ vma->vm_page_prot)) ++ return -EAGAIN; ++ ++ return 0; ++} ++ ++static int ++dev_nvram_open(struct inode *inode, struct file * file) ++{ ++ MOD_INC_USE_COUNT; ++ return 0; ++} ++ ++static int ++dev_nvram_release(struct inode *inode, struct file * file) ++{ ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static struct file_operations dev_nvram_fops = { ++ owner: THIS_MODULE, ++ open: dev_nvram_open, ++ release: dev_nvram_release, ++ read: dev_nvram_read, ++ write: dev_nvram_write, ++ ioctl: dev_nvram_ioctl, ++ mmap: dev_nvram_mmap, ++}; ++ ++static void ++dev_nvram_exit(void) ++{ ++ int order = 0; ++ struct page *page, *end; ++ ++ if (nvram_handle) ++ devfs_unregister(nvram_handle); ++ ++ if (nvram_major >= 0) ++ devfs_unregister_chrdev(nvram_major, "nvram"); ++ ++ if (nvram_mtd) ++ put_mtd_device(nvram_mtd); ++ ++ while ((PAGE_SIZE << order) < NVRAM_SPACE) ++ order++; ++ end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1); ++ for (page = virt_to_page(nvram_buf); page <= end; page++) ++ mem_map_unreserve(page); ++ ++ _nvram_exit(); ++} ++ ++static int __init ++dev_nvram_init(void) ++{ ++ int order = 0, ret = 0; ++ struct page *page, *end; ++ unsigned int i; ++ ++ /* Allocate and reserve memory to mmap() */ ++ while ((PAGE_SIZE << order) < NVRAM_SPACE) ++ order++; ++ end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1); ++ for (page = virt_to_page(nvram_buf); page <= end; page++) ++ mem_map_reserve(page); ++ ++#ifdef CONFIG_MTD ++ /* Find associated MTD device */ ++ for (i = 0; i < MAX_MTD_DEVICES; i++) { ++ nvram_mtd = get_mtd_device(NULL, i); ++ if (nvram_mtd) { ++ if (!strcmp(nvram_mtd->name, "nvram") && ++ nvram_mtd->size >= NVRAM_SPACE) ++ break; ++ put_mtd_device(nvram_mtd); ++ } ++ } ++ if (i >= MAX_MTD_DEVICES) ++ nvram_mtd = NULL; ++#endif ++ ++ /* Initialize hash table lock */ ++ spin_lock_init(&nvram_lock); ++ ++ /* Initialize commit semaphore */ ++ init_MUTEX(&nvram_sem); ++ ++ /* Register char device */ ++ if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) { ++ ret = nvram_major; ++ goto err; ++ } ++ ++ /* Initialize hash table */ ++ _nvram_init(); ++ ++ /* Create /dev/nvram handle */ ++ nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0, ++ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL); ++ ++ /* Set the SDRAM NCDL value into NVRAM if not already done */ ++ if (getintvar(NULL, "sdram_ncdl") == 0) { ++ unsigned int ncdl; ++ char buf[] = "0x00000000"; ++ ++ if ((ncdl = sb_memc_get_ncdl(sbh))) { ++ sprintf(buf, "0x%08x", ncdl); ++ nvram_set("sdram_ncdl", buf); ++ nvram_commit(); ++ } ++ } ++ ++ return 0; ++ ++ err: ++ dev_nvram_exit(); ++ return ret; ++} ++ ++module_init(dev_nvram_init); ++module_exit(dev_nvram_exit); +diff -Nur linux-2.4.32/arch/mips/bcm947xx/pcibios.c linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c +--- linux-2.4.32/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c 2005-12-16 23:39:10.944836750 +0100 +@@ -0,0 +1,355 @@ ++/* ++ * Low-Level PCI and SB support for BCM47xx (Linux support code) ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Global SB handle */ ++extern sb_t *bcm947xx_sbh; ++extern spinlock_t bcm947xx_sbh_lock; ++ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock ++ ++static int ++sbpci_read_config_byte(struct pci_dev *dev, int where, u8 *value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_read_config_word(struct pci_dev *dev, int where, u16 *value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_read_config_dword(struct pci_dev *dev, int where, u32 *value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_write_config_byte(struct pci_dev *dev, int where, u8 value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_write_config_word(struct pci_dev *dev, int where, u16 value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static int ++sbpci_write_config_dword(struct pci_dev *dev, int where, u32 value) ++{ ++ unsigned long flags; ++ int ret; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} ++ ++static struct pci_ops pcibios_ops = { ++ sbpci_read_config_byte, ++ sbpci_read_config_word, ++ sbpci_read_config_dword, ++ sbpci_write_config_byte, ++ sbpci_write_config_word, ++ sbpci_write_config_dword ++}; ++ ++ ++void __init ++pcibios_init(void) ++{ ++ ulong flags; ++ ++ if (!(sbh = sb_kattach())) ++ panic("sb_kattach failed"); ++ spin_lock_init(&sbh_lock); ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ sbpci_init(sbh); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ ++ set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000)); ++ ++ mdelay(300); //By Joey for Atheros Card ++ ++ /* Scan the SB bus */ ++ pci_scan_bus(0, &pcibios_ops, NULL); ++ ++} ++ ++char * __init ++pcibios_setup(char *str) ++{ ++ if (!strncmp(str, "ban=", 4)) { ++ sbpci_ban(simple_strtoul(str + 4, NULL, 0)); ++ return NULL; ++ } ++ ++ return (str); ++} ++ ++static u32 pci_iobase = 0x100; ++static u32 pci_membase = SB_PCI_DMA; ++ ++void __init ++pcibios_fixup_bus(struct pci_bus *b) ++{ ++ struct list_head *ln; ++ struct pci_dev *d; ++ struct resource *res; ++ int pos, size; ++ u32 *base; ++ u8 irq; ++ ++ printk("PCI: Fixing up bus %d\n", b->number); ++ ++ /* Fix up SB */ ++ if (b->number == 0) { ++ for (ln=b->devices.next; ln != &b->devices; ln=ln->next) { ++ d = pci_dev_b(ln); ++ /* Fix up interrupt lines */ ++ pci_read_config_byte(d, PCI_INTERRUPT_LINE, &irq); ++ d->irq = irq + 2; ++ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); ++ } ++ } ++ ++ /* Fix up external PCI */ ++ else { ++ for (ln=b->devices.next; ln != &b->devices; ln=ln->next) { ++ d = pci_dev_b(ln); ++ /* Fix up resource bases */ ++ for (pos = 0; pos < 6; pos++) { ++ res = &d->resource[pos]; ++ base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase; ++ if (res->end) { ++ size = res->end - res->start + 1; ++ if (*base & (size - 1)) ++ *base = (*base + size) & ~(size - 1); ++ res->start = *base; ++ res->end = res->start + size - 1; ++ *base += size; ++ pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start); ++ } ++ /* Fix up PCI bridge BAR0 only */ ++ if (b->number == 1 && PCI_SLOT(d->devfn) == 0) ++ break; ++ } ++ /* Fix up interrupt lines */ ++ if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL)) ++ d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq; ++ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); ++ } ++ } ++} ++ ++unsigned int ++pcibios_assign_all_busses(void) ++{ ++ return 1; ++} ++ ++void ++pcibios_align_resource(void *data, struct resource *res, ++ unsigned long size, unsigned long align) ++{ ++} ++ ++int ++pcibios_enable_resources(struct pci_dev *dev) ++{ ++ u16 cmd, old_cmd; ++ int idx; ++ struct resource *r; ++ ++ /* External PCI only */ ++ if (dev->bus->number == 0) ++ return 0; ++ ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ old_cmd = cmd; ++ for(idx=0; idx<6; idx++) { ++ r = &dev->resource[idx]; ++ if (r->flags & IORESOURCE_IO) ++ cmd |= PCI_COMMAND_IO; ++ if (r->flags & IORESOURCE_MEM) ++ cmd |= PCI_COMMAND_MEMORY; ++ } ++ if (dev->resource[PCI_ROM_RESOURCE].start) ++ cmd |= PCI_COMMAND_MEMORY; ++ if (cmd != old_cmd) { ++ printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ } ++ return 0; ++} ++ ++int ++pcibios_enable_device(struct pci_dev *dev, int mask) ++{ ++ ulong flags; ++ uint coreidx; ++ ++ /* External PCI device enable */ ++ if (dev->bus->number != 0) ++ return pcibios_enable_resources(dev); ++ ++ /* These cores come out of reset enabled */ ++ if (dev->device == SB_MIPS || ++ dev->device == SB_MIPS33 || ++ dev->device == SB_EXTIF || ++ dev->device == SB_CC) ++ return 0; ++ ++ spin_lock_irqsave(&sbh_lock, flags); ++ coreidx = sb_coreidx(sbh); ++ if (!sb_setcoreidx(sbh, PCI_SLOT(dev->devfn))) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ /* ++ * The USB core requires a special bit to be set during core ++ * reset to enable host (OHCI) mode. Resetting the SB core in ++ * pcibios_enable_device() is a hack for compatibility with ++ * vanilla usb-ohci so that it does not have to know about ++ * SB. A driver that wants to use the USB core in device mode ++ * should know about SB and should reset the bit back to 0 ++ * after calling pcibios_enable_device(). ++ */ ++ if (sb_coreid(sbh) == SB_USB) { ++ sb_core_disable(sbh, sb_coreflags(sbh, 0, 0)); ++ sb_core_reset(sbh, 1 << 29); ++ } else ++ sb_core_reset(sbh, 0); ++ ++ sb_setcoreidx(sbh, coreidx); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ ++ return 0; ++} ++ ++void ++pcibios_update_resource(struct pci_dev *dev, struct resource *root, ++ struct resource *res, int resource) ++{ ++ unsigned long where, size; ++ u32 reg; ++ ++ /* External PCI only */ ++ if (dev->bus->number == 0) ++ return; ++ ++ where = PCI_BASE_ADDRESS_0 + (resource * 4); ++ size = res->end - res->start; ++ pci_read_config_dword(dev, where, ®); ++ reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); ++ pci_write_config_dword(dev, where, reg); ++} ++ ++static void __init ++quirk_sbpci_bridge(struct pci_dev *dev) ++{ ++ if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0) ++ return; ++ ++ printk("PCI: Fixing up bridge\n"); ++ ++ /* Enable PCI bridge bus mastering and memory space */ ++ pci_set_master(dev); ++ pcibios_enable_resources(dev); ++ ++ /* Enable PCI bridge BAR1 prefetch and burst */ ++ pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3); ++} ++ ++struct pci_fixup pcibios_fixups[] = { ++ { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_sbpci_bridge }, ++ { 0 } ++}; ++ ++/* ++ * If we set up a device for bus mastering, we need to check the latency ++ * timer as certain crappy BIOSes forget to set it properly. ++ */ ++unsigned int pcibios_max_latency = 255; ++ ++void pcibios_set_master(struct pci_dev *dev) ++{ ++ u8 lat; ++ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); ++ if (lat < 16) ++ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; ++ else if (lat > pcibios_max_latency) ++ lat = pcibios_max_latency; ++ else ++ return; ++ printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat); ++ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/prom.c linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c +--- linux-2.4.32/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c 2005-12-16 23:39:10.944836750 +0100 +@@ -0,0 +1,41 @@ ++/* ++ * Early initialization code for BCM94710 boards ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: prom.c,v 1.1 2005/03/16 13:49:59 wbx Exp $ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++void __init ++prom_init(int argc, const char **argv) ++{ ++ unsigned long mem; ++ ++ mips_machgroup = MACH_GROUP_BRCM; ++ mips_machtype = MACH_BCM947XX; ++ ++ /* Figure out memory size by finding aliases */ ++ for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { ++ if (*(unsigned long *)((unsigned long)(prom_init) + mem) == ++ *(unsigned long *)(prom_init)) ++ break; ++ } ++ add_memory_region(0, mem, BOOT_MEM_RAM); ++} ++ ++void __init ++prom_free_prom_memory(void) ++{ ++} +diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbmips.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c +--- linux-2.4.32/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c 2005-12-16 23:39:10.944836750 +0100 +@@ -0,0 +1,1038 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane MIPS core routines ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* ++ * Returns TRUE if an external UART exists at the given base ++ * register. ++ */ ++static bool ++BCMINITFN(serial_exists)(uint8 *regs) ++{ ++ uint8 save_mcr, status1; ++ ++ save_mcr = R_REG(®s[UART_MCR]); ++ W_REG(®s[UART_MCR], UART_MCR_LOOP | 0x0a); ++ status1 = R_REG(®s[UART_MSR]) & 0xf0; ++ W_REG(®s[UART_MCR], save_mcr); ++ ++ return (status1 == 0x90); ++} ++ ++/* ++ * Initializes UART access. The callback function will be called once ++ * per found UART. ++ */ ++void ++BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)) ++{ ++ void *regs; ++ ulong base; ++ uint irq; ++ int i, n; ++ ++ if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) { ++ extifregs_t *eir = (extifregs_t *) regs; ++ sbconfig_t *sb; ++ ++ /* Determine external UART register base */ ++ sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF); ++ base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1))); ++ ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); ++ ++ /* Disable GPIO interrupt initially */ ++ W_REG(&eir->gpiointpolarity, 0); ++ W_REG(&eir->gpiointmask, 0); ++ ++ /* Search for external UARTs */ ++ n = 2; ++ for (i = 0; i < 2; i++) { ++ regs = (void *) REG_MAP(base + (i * 8), 8); ++ if (BCMINIT(serial_exists)(regs)) { ++ /* Set GPIO 1 to be the external UART IRQ */ ++ W_REG(&eir->gpiointmask, 2); ++ if (add) ++ add(regs, irq, 13500000, 0); ++ } ++ } ++ ++ /* Add internal UART if enabled */ ++ if (R_REG(&eir->corecontrol) & CC_UE) ++ if (add) ++ add((void *) &eir->uartdata, irq, sb_clock(sbh), 2); ++ } else if ((regs = sb_setcore(sbh, SB_CC, 0))) { ++ chipcregs_t *cc = (chipcregs_t *) regs; ++ uint32 rev, cap, pll, baud_base, div; ++ ++ /* Determine core revision and capabilities */ ++ rev = sb_corerev(sbh); ++ cap = R_REG(&cc->capabilities); ++ pll = cap & CAP_PLL_MASK; ++ ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); ++ ++ if (pll == PLL_TYPE1) { ++ /* PLL clock */ ++ baud_base = sb_clock_rate(pll, ++ R_REG(&cc->clockcontrol_n), ++ R_REG(&cc->clockcontrol_m2)); ++ div = 1; ++ } else { ++ if (rev >= 11) { ++ /* Fixed ALP clock */ ++ baud_base = 20000000; ++ div = 1; ++ /* Set the override bit so we don't divide it */ ++ W_REG(&cc->corecontrol, CC_UARTCLKO); ++ } else if (rev >= 3) { ++ /* Internal backplane clock */ ++ baud_base = sb_clock(sbh); ++ div = 2; /* Minimum divisor */ ++ W_REG(&cc->clkdiv, ++ ((R_REG(&cc->clkdiv) & ~CLKD_UART) | div)); ++ } else { ++ /* Fixed internal backplane clock */ ++ baud_base = 88000000; ++ div = 48; ++ } ++ ++ /* Clock source depends on strapping if UartClkOverride is unset */ ++ if ((rev > 0) && ++ ((R_REG(&cc->corecontrol) & CC_UARTCLKO) == 0)) { ++ if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) { ++ /* Internal divided backplane clock */ ++ baud_base /= div; ++ } else { ++ /* Assume external clock of 1.8432 MHz */ ++ baud_base = 1843200; ++ } ++ } ++ } ++ ++ /* Add internal UARTs */ ++ n = cap & CAP_UARTS_MASK; ++ for (i = 0; i < n; i++) { ++ /* Register offset changed after revision 0 */ ++ if (rev) ++ regs = (void *)((ulong) &cc->uart0data + (i * 256)); ++ else ++ regs = (void *)((ulong) &cc->uart0data + (i * 8)); ++ ++ if (add) ++ add(regs, irq, baud_base, 0); ++ } ++ } ++} ++ ++/* ++ * Initialize jtag master and return handle for ++ * jtag_rwreg. Returns NULL on failure. ++ */ ++void * ++sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap) ++{ ++ void *regs; ++ ++ if ((regs = sb_setcore(sbh, SB_CC, 0)) != NULL) { ++ chipcregs_t *cc = (chipcregs_t *) regs; ++ uint32 tmp; ++ ++ /* ++ * Determine jtagm availability from ++ * core revision and capabilities. ++ */ ++ tmp = sb_corerev(sbh); ++ /* ++ * Corerev 10 has jtagm, but the only chip ++ * with it does not have a mips, and ++ * the layout of the jtagcmd register is ++ * different. We'll only accept >= 11. ++ */ ++ if (tmp < 11) ++ return (NULL); ++ ++ tmp = R_REG(&cc->capabilities); ++ if ((tmp & CAP_JTAGP) == 0) ++ return (NULL); ++ ++ /* Set clock divider if requested */ ++ if (clkd != 0) { ++ tmp = R_REG(&cc->clkdiv); ++ tmp = (tmp & ~CLKD_JTAG) | ++ ((clkd << CLKD_JTAG_SHIFT) & CLKD_JTAG); ++ W_REG(&cc->clkdiv, tmp); ++ } ++ ++ /* Enable jtagm */ ++ tmp = JCTRL_EN | (exttap ? JCTRL_EXT_EN : 0); ++ W_REG(&cc->jtagctrl, tmp); ++ } ++ ++ return (regs); ++} ++ ++void ++sb_jtagm_disable(void *h) ++{ ++ chipcregs_t *cc = (chipcregs_t *)h; ++ ++ W_REG(&cc->jtagctrl, R_REG(&cc->jtagctrl) & ~JCTRL_EN); ++} ++ ++/* ++ * Read/write a jtag register. Assumes a target with ++ * 8 bit IR and 32 bit DR. ++ */ ++#define IRWIDTH 8 ++#define DRWIDTH 32 ++uint32 ++jtag_rwreg(void *h, uint32 ir, uint32 dr) ++{ ++ chipcregs_t *cc = (chipcregs_t *) h; ++ uint32 tmp; ++ ++ W_REG(&cc->jtagir, ir); ++ W_REG(&cc->jtagdr, dr); ++ tmp = JCMD_START | JCMD_ACC_IRDR | ++ ((IRWIDTH - 1) << JCMD_IRW_SHIFT) | ++ (DRWIDTH - 1); ++ W_REG(&cc->jtagcmd, tmp); ++ while (((tmp = R_REG(&cc->jtagcmd)) & JCMD_BUSY) == JCMD_BUSY) { ++ /* OSL_DELAY(1); */ ++ } ++ ++ tmp = R_REG(&cc->jtagdr); ++ return (tmp); ++} ++ ++/* Returns the SB interrupt flag of the current core. */ ++uint32 ++sb_flag(sb_t *sbh) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ ++ regs = sb_coreregs(sbh); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ return (R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK); ++} ++ ++static const uint32 sbips_int_mask[] = { ++ 0, ++ SBIPS_INT1_MASK, ++ SBIPS_INT2_MASK, ++ SBIPS_INT3_MASK, ++ SBIPS_INT4_MASK ++}; ++ ++static const uint32 sbips_int_shift[] = { ++ 0, ++ 0, ++ SBIPS_INT2_SHIFT, ++ SBIPS_INT3_SHIFT, ++ SBIPS_INT4_SHIFT ++}; ++ ++/* ++ * Returns the MIPS IRQ assignment of the current core. If unassigned, ++ * 0 is returned. ++ */ ++uint ++sb_irq(sb_t *sbh) ++{ ++ uint idx; ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag, sbipsflag; ++ uint irq = 0; ++ ++ flag = sb_flag(sbh); ++ ++ idx = sb_coreidx(sbh); ++ ++ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || ++ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ /* sbipsflag specifies which core is routed to interrupts 1 to 4 */ ++ sbipsflag = R_REG(&sb->sbipsflag); ++ for (irq = 1; irq <= 4; irq++) { ++ if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag) ++ break; ++ } ++ if (irq == 5) ++ irq = 0; ++ } ++ ++ sb_setcoreidx(sbh, idx); ++ ++ return irq; ++} ++ ++/* Clears the specified MIPS IRQ. */ ++static void ++BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ if (irq == 0) ++ W_REG(&sb->sbintvec, 0); ++ else ++ OR_REG(&sb->sbipsflag, sbips_int_mask[irq]); ++} ++ ++/* ++ * Assigns the specified MIPS IRQ to the specified core. Shared MIPS ++ * IRQ 0 may be assigned more than once. ++ */ ++static void ++BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit) ++{ ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag; ++ ++ regs = sb_setcore(sbh, coreid, coreunit); ++ ASSERT(regs); ++ flag = sb_flag(sbh); ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ if (irq == 0) ++ OR_REG(&sb->sbintvec, 1 << flag); ++ else { ++ flag <<= sbips_int_shift[irq]; ++ ASSERT(!(flag & ~sbips_int_mask[irq])); ++ flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq]; ++ W_REG(&sb->sbipsflag, flag); ++ } ++} ++ ++/* ++ * Initializes clocks and interrupts. SB and NVRAM access must be ++ * initialized prior to calling. ++ */ ++void ++BCMINITFN(sb_mips_init)(sb_t *sbh) ++{ ++ ulong hz, ns, tmp; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ char *value; ++ uint irq; ++ ++ /* Figure out current SB clock speed */ ++ if ((hz = sb_clock(sbh)) == 0) ++ hz = 100000000; ++ ns = 1000000000 / hz; ++ ++ /* Setup external interface timing */ ++ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { ++ /* Initialize extif so we can get to the LEDs and external UART */ ++ W_REG(&eir->prog_config, CF_EN); ++ ++ /* Set timing for the flash */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */ ++ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ ++ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ ++ ++ /* Set programmable interface timing for external uart */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */ ++ tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */ ++ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ ++ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ ++ } else if ((cc = sb_setcore(sbh, SB_CC, 0))) { ++ /* Set timing for the flash */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp |= CEIL(10, ns) << FW_W1_SHIFT; /* W1 = 10nS */ ++ tmp |= CEIL(120, ns); /* W0 = 120nS */ ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ { ++ W_REG(&cc->flash_waitcount, tmp); ++ W_REG(&cc->pcmcia_memwait, tmp); ++ } ++ else ++ { ++ if (sb_corerev(sbh) < 9) ++ W_REG(&cc->flash_waitcount, tmp); ++ ++ if ((sb_corerev(sbh) < 9) || ++ ((BCMINIT(sb_chip)(sbh) == BCM5350_DEVICE_ID) && BCMINIT(sb_chiprev)(sbh) == 0)) { ++ W_REG(&cc->pcmcia_memwait, tmp); ++ } ++ } ++ } ++ ++ /* Chip specific initialization */ ++ switch (BCMINIT(sb_chip)(sbh)) { ++ case BCM4710_DEVICE_ID: ++ /* Clear interrupt map */ ++ for (irq = 0; irq <= 4; irq++) ++ BCMINIT(sb_clearirq)(sbh, irq); ++ BCMINIT(sb_setirq)(sbh, 0, SB_CODEC, 0); ++ BCMINIT(sb_setirq)(sbh, 0, SB_EXTIF, 0); ++ BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 1); ++ BCMINIT(sb_setirq)(sbh, 3, SB_ILINE20, 0); ++ BCMINIT(sb_setirq)(sbh, 4, SB_PCI, 0); ++ ASSERT(eir); ++ value = BCMINIT(nvram_get)("et0phyaddr"); ++ if (value && !strcmp(value, "31")) { ++ /* Enable internal UART */ ++ W_REG(&eir->corecontrol, CC_UE); ++ /* Give USB its own interrupt */ ++ BCMINIT(sb_setirq)(sbh, 1, SB_USB, 0); ++ } else { ++ /* Disable internal UART */ ++ W_REG(&eir->corecontrol, 0); ++ /* Give Ethernet its own interrupt */ ++ BCMINIT(sb_setirq)(sbh, 1, SB_ENET, 0); ++ BCMINIT(sb_setirq)(sbh, 0, SB_USB, 0); ++ } ++ break; ++ case BCM5350_DEVICE_ID: ++ /* Clear interrupt map */ ++ for (irq = 0; irq <= 4; irq++) ++ BCMINIT(sb_clearirq)(sbh, irq); ++ BCMINIT(sb_setirq)(sbh, 0, SB_CC, 0); ++ BCMINIT(sb_setirq)(sbh, 1, SB_D11, 0); ++ BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 0); ++ BCMINIT(sb_setirq)(sbh, 3, SB_PCI, 0); ++ BCMINIT(sb_setirq)(sbh, 4, SB_USB, 0); ++ break; ++ } ++} ++ ++uint32 ++BCMINITFN(sb_mips_clock)(sb_t *sbh) ++{ ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate = 0; ++ ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ pll_type = PLL_TYPE1; ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(&eir->clockcontrol_n); ++ m = R_REG(&eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(&cc->clockcontrol_n); ++ if ((pll_type == PLL_TYPE2) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE6) || ++ (pll_type == PLL_TYPE7)) ++ m = R_REG(&cc->clockcontrol_mips); ++ else if (pll_type == PLL_TYPE5) { ++ rate = 200000000; ++ goto out; ++ } ++ else if (pll_type == PLL_TYPE3) { ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) { /* 5365 is also type3 */ ++ rate = 200000000; ++ goto out; ++ } else ++ m = R_REG(&cc->clockcontrol_m2); /* 5350 uses m2 to control mips */ ++ } else ++ m = R_REG(&cc->clockcontrol_sb); ++ } else ++ goto out; ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ rate = 100000000; ++ else ++ /* calculate rate */ ++ rate = sb_clock_rate(pll_type, n, m); ++ ++ if (pll_type == PLL_TYPE6) ++ rate = SB2MIPS_T6(rate); ++ ++out: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return rate; ++} ++ ++#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) ++ ++static void ++BCMINITFN(handler)(void) ++{ ++ /* Step 11 */ ++ __asm__ ( ++ ".set\tmips32\n\t" ++ "ssnop\n\t" ++ "ssnop\n\t" ++ /* Disable interrupts */ ++ /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */ ++ "mfc0 $15, $12\n\t" ++ /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */ ++ "li $14, -31746\n\t" ++ "and $15, $15, $14\n\t" ++ "mtc0 $15, $12\n\t" ++ "eret\n\t" ++ "nop\n\t" ++ "nop\n\t" ++ ".set\tmips0" ++ ); ++} ++ ++/* The following MUST come right after handler() */ ++static void ++BCMINITFN(afterhandler)(void) ++{ ++} ++ ++/* ++ * Set the MIPS, backplane and PCI clocks as closely as possible. ++ */ ++bool ++BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock) ++{ ++ extifregs_t *eir = NULL; ++ chipcregs_t *cc = NULL; ++ mipsregs_t *mipsr = NULL; ++ volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci, *clockcontrol_m2; ++ uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, orig_ratio_cfg; ++ uint32 pll_type, sync_mode; ++ uint ic_size, ic_lsize; ++ uint idx, i; ++ typedef struct { ++ uint32 mipsclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 pci25; ++ } n3m_table_t; ++ static n3m_table_t BCMINITDATA(type1_table)[] = { ++ { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */ ++ { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */ ++ { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */ ++ { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */ ++ { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */ ++ { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */ ++ { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */ ++ { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */ ++ { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */ ++ { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */ ++ { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */ ++ { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */ ++ { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */ ++ { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */ ++ { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */ ++ { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */ ++ { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */ ++ { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */ ++ { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */ ++ { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */ ++ }; ++ typedef struct { ++ uint32 mipsclock; ++ uint16 n; ++ uint32 m2; /* that is the clockcontrol_m2 */ ++ } type3_table_t; ++ static type3_table_t type3_table[] = { /* for 5350, mips clock is always double sb clock */ ++ { 150000000, 0x311, 0x4020005 }, ++ { 200000000, 0x311, 0x4020003 }, ++ }; ++ typedef struct { ++ uint32 mipsclock; ++ uint32 sbclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 m2; ++ uint32 m3; ++ uint32 ratio_cfg; ++ uint32 ratio_parm; ++ } n4m_table_t; ++ ++ static n4m_table_t BCMINITDATA(type2_table)[] = { ++ { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 11, 0x0aaa0555 }, ++ { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 11, 0x0aaa0555 }, ++ { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, ++ { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 }, ++ { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 }, ++ { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 8, 0x012a00a9 }, ++ { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 11, 0x0aaa0555 } ++ }; ++ ++ static n4m_table_t BCMINITDATA(type4_table)[] = { ++ { 192000000, 96000000, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, ++ { 198000000, 99000000, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 }, ++ { 204000000, 102000000, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 208000000, 104000000, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, ++ { 210000000, 105000000, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 224000000, 112000000, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, ++ { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005, 8, 0x012a00a9 }, ++ { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 240000000, 102857143, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003, 13, 0x254a14a9 }, ++ { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, ++ { 252000000, 100800000, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002, 9, 0x02520129 }, ++ { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 }, ++ { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 }, ++ { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 13, 0x254a14a9 }, ++ { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 }, ++ { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 }, ++ { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 9, 0x02520129 }, ++ { 300000000, 150000000, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002, 11, 0x0aaa0555 } ++ }; ++ ++ static n4m_table_t BCMINITDATA(type7_table)[] = { ++ { 183333333, 91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, ++ { 187500000, 93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, ++ { 196875000, 98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 11, 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 }, ++ { 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, ++ { 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, ++ { 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, ++ { 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, ++ { 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 11, 0x0aaa0555 }, ++ { 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 11, 0x0aaa0555 } ++ }; ++ ++ ulong start, end, dst; ++ bool ret = FALSE; ++ ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ clockcontrol_m2 = NULL; ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ pll_type = PLL_TYPE1; ++ clockcontrol_n = &eir->clockcontrol_n; ++ clockcontrol_sb = &eir->clockcontrol_sb; ++ clockcontrol_pci = &eir->clockcontrol_pci; ++ clockcontrol_m2 = &cc->clockcontrol_m2; ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ if (pll_type == PLL_TYPE6) { ++ clockcontrol_n = NULL; ++ clockcontrol_sb = NULL; ++ clockcontrol_pci = NULL; ++ } else { ++ clockcontrol_n = &cc->clockcontrol_n; ++ clockcontrol_sb = &cc->clockcontrol_sb; ++ clockcontrol_pci = &cc->clockcontrol_pci; ++ clockcontrol_m2 = &cc->clockcontrol_m2; ++ } ++ } else ++ goto done; ++ ++ if (pll_type == PLL_TYPE6) { ++ /* Silence compilers */ ++ orig_n = orig_sb = orig_pci = 0; ++ } else { ++ /* Store the current clock register values */ ++ orig_n = R_REG(clockcontrol_n); ++ orig_sb = R_REG(clockcontrol_sb); ++ orig_pci = R_REG(clockcontrol_pci); ++ } ++ ++ if (pll_type == PLL_TYPE1) { ++ /* Keep the current PCI clock if not specified */ ++ if (pciclock == 0) { ++ pciclock = sb_clock_rate(pll_type, R_REG(clockcontrol_n), R_REG(clockcontrol_pci)); ++ pciclock = (pciclock <= 25000000) ? 25000000 : 33000000; ++ } ++ ++ /* Search for the closest MIPS clock less than or equal to a preferred value */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(type1_table)); i++) { ++ ASSERT(BCMINIT(type1_table)[i].mipsclock == ++ sb_clock_rate(pll_type, BCMINIT(type1_table)[i].n, BCMINIT(type1_table)[i].sb)); ++ if (BCMINIT(type1_table)[i].mipsclock > mipsclock) ++ break; ++ } ++ if (i == 0) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ i--; ++ } ++ ASSERT(BCMINIT(type1_table)[i].mipsclock <= mipsclock); ++ ++ /* No PLL change */ ++ if ((orig_n == BCMINIT(type1_table)[i].n) && ++ (orig_sb == BCMINIT(type1_table)[i].sb) && ++ (orig_pci == BCMINIT(type1_table)[i].pci33)) ++ goto done; ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, BCMINIT(type1_table)[i].n); ++ W_REG(clockcontrol_sb, BCMINIT(type1_table)[i].sb); ++ if (pciclock == 25000000) ++ W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci25); ++ else ++ W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci33); ++ ++ /* Reset */ ++ sb_watchdog(sbh, 1); ++ ++ while (1); ++ } else if ((pll_type == PLL_TYPE3) && ++ (BCMINIT(sb_chip)(sbh) != BCM5365_DEVICE_ID)) { ++ /* 5350 */ ++ /* Search for the closest MIPS clock less than or equal to a preferred value */ ++ ++ for (i = 0; i < ARRAYSIZE(type3_table); i++) { ++ if (type3_table[i].mipsclock > mipsclock) ++ break; ++ } ++ if (i == 0) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ i--; ++ } ++ ASSERT(type3_table[i].mipsclock <= mipsclock); ++ ++ /* No PLL change */ ++ orig_m2 = R_REG(&cc->clockcontrol_m2); ++ if ((orig_n == type3_table[i].n) && ++ (orig_m2 == type3_table[i].m2)) { ++ goto done; ++ } ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, type3_table[i].n); ++ W_REG(clockcontrol_m2, type3_table[i].m2); ++ ++ /* Reset */ ++ sb_watchdog(sbh, 1); ++ while (1); ++ } else if ((pll_type == PLL_TYPE2) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE6) || ++ (pll_type == PLL_TYPE7)) { ++ n4m_table_t *table = NULL, *te; ++ uint tabsz = 0; ++ ++ ASSERT(cc); ++ ++ orig_mips = R_REG(&cc->clockcontrol_mips); ++ ++ if (pll_type == PLL_TYPE6) { ++ uint32 new_mips = 0; ++ ++ ret = TRUE; ++ if (mipsclock <= SB2MIPS_T6(CC_T6_M1)) ++ new_mips = CC_T6_MMASK; ++ ++ if (orig_mips == new_mips) ++ goto done; ++ ++ W_REG(&cc->clockcontrol_mips, new_mips); ++ goto end_fill; ++ } ++ ++ if (pll_type == PLL_TYPE2) { ++ table = BCMINIT(type2_table); ++ tabsz = ARRAYSIZE(BCMINIT(type2_table)); ++ } else if (pll_type == PLL_TYPE4) { ++ table = BCMINIT(type4_table); ++ tabsz = ARRAYSIZE(BCMINIT(type4_table)); ++ } else if (pll_type == PLL_TYPE7) { ++ table = BCMINIT(type7_table); ++ tabsz = ARRAYSIZE(BCMINIT(type7_table)); ++ } else ++ ASSERT("No table for plltype" == NULL); ++ ++ /* Store the current clock register values */ ++ orig_m2 = R_REG(&cc->clockcontrol_m2); ++ orig_ratio_parm = 0; ++ orig_ratio_cfg = 0; ++ ++ /* Look up current ratio */ ++ for (i = 0; i < tabsz; i++) { ++ if ((orig_n == table[i].n) && ++ (orig_sb == table[i].sb) && ++ (orig_pci == table[i].pci33) && ++ (orig_m2 == table[i].m2) && ++ (orig_mips == table[i].m3)) { ++ orig_ratio_parm = table[i].ratio_parm; ++ orig_ratio_cfg = table[i].ratio_cfg; ++ break; ++ } ++ } ++ ++ /* Search for the closest MIPS clock greater or equal to a preferred value */ ++ for (i = 0; i < tabsz; i++) { ++ ASSERT(table[i].mipsclock == ++ sb_clock_rate(pll_type, table[i].n, table[i].m3)); ++ if ((mipsclock <= table[i].mipsclock) && ++ ((sbclock == 0) || (sbclock <= table[i].sbclock))) ++ break; ++ } ++ if (i == tabsz) { ++ ret = FALSE; ++ goto done; ++ } else { ++ te = &table[i]; ++ ret = TRUE; ++ } ++ ++ /* No PLL change */ ++ if ((orig_n == te->n) && ++ (orig_sb == te->sb) && ++ (orig_pci == te->pci33) && ++ (orig_m2 == te->m2) && ++ (orig_mips == te->m3)) ++ goto done; ++ ++ /* Set the PLL controls */ ++ W_REG(clockcontrol_n, te->n); ++ W_REG(clockcontrol_sb, te->sb); ++ W_REG(clockcontrol_pci, te->pci33); ++ W_REG(&cc->clockcontrol_m2, te->m2); ++ W_REG(&cc->clockcontrol_mips, te->m3); ++ ++ /* Set the chipcontrol bit to change mipsref to the backplane divider if needed */ ++ if ((pll_type == PLL_TYPE7) && ++ (te->sb != te->m2) && ++ (sb_clock_rate(pll_type, te->n, te->m2) == 120000000)) ++ W_REG(&cc->chipcontrol, R_REG(&cc->chipcontrol) | 0x100); ++ ++ /* No ratio change */ ++ if (orig_ratio_parm == te->ratio_parm) ++ goto end_fill; ++ ++ icache_probe(MFC0(C0_CONFIG, 1), &ic_size, &ic_lsize); ++ ++ /* Preload the code into the cache */ ++ start = ((ulong) &&start_fill) & ~(ic_lsize - 1); ++ end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1); ++ while (start < end) { ++ cache_op(start, Fill_I); ++ start += ic_lsize; ++ } ++ ++ /* Copy the handler */ ++ start = (ulong) &BCMINIT(handler); ++ end = (ulong) &BCMINIT(afterhandler); ++ dst = KSEG1ADDR(0x180); ++ for (i = 0; i < (end - start); i += 4) ++ *((ulong *)(dst + i)) = *((ulong *)(start + i)); ++ ++ /* Preload handler into the cache one line at a time */ ++ for (i = 0; i < (end - start); i += 4) ++ cache_op(dst + i, Fill_I); ++ ++ /* Clear BEV bit */ ++ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV); ++ ++ /* Enable interrupts */ ++ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) | (ALLINTS | ST0_IE)); ++ ++ /* Enable MIPS timer interrupt */ ++ if (!(mipsr = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(mipsr = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(mipsr); ++ W_REG(&mipsr->intmask, 1); ++ ++ start_fill: ++ /* step 1, set clock ratios */ ++ MTC0(C0_BROADCOM, 3, te->ratio_parm); ++ MTC0(C0_BROADCOM, 1, te->ratio_cfg); ++ ++ /* step 2: program timer intr */ ++ W_REG(&mipsr->timer, 100); ++ (void) R_REG(&mipsr->timer); ++ ++ /* step 3, switch to async */ ++ sync_mode = MFC0(C0_BROADCOM, 4); ++ MTC0(C0_BROADCOM, 4, 1 << 22); ++ ++ /* step 4, set cfg active */ ++ MTC0(C0_BROADCOM, 2, 0x9); ++ ++ ++ /* steps 5 & 6 */ ++ __asm__ __volatile__ ( ++ ".set\tmips3\n\t" ++ "wait\n\t" ++ ".set\tmips0" ++ ); ++ ++ /* step 7, clear cfg_active */ ++ MTC0(C0_BROADCOM, 2, 0); ++ ++ /* Additional Step: set back to orig sync mode */ ++ MTC0(C0_BROADCOM, 4, sync_mode); ++ ++ /* step 8, fake soft reset */ ++ MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | 4); ++ ++ end_fill: ++ /* step 9 set watchdog timer */ ++ sb_watchdog(sbh, 20); ++ (void) R_REG(&cc->chipid); ++ ++ /* step 11 */ ++ __asm__ __volatile__ ( ++ ".set\tmips3\n\t" ++ "sync\n\t" ++ "wait\n\t" ++ ".set\tmips0" ++ ); ++ while (1); ++ } ++ ++done: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return ret; ++} ++ ++/* ++ * This also must be run from the cache on 47xx ++ * so there are no mips core BIU ops in progress ++ * when the PFC is enabled. ++ */ ++ ++static void ++BCMINITFN(_enable_pfc)(uint32 mode) ++{ ++ /* write range */ ++ *(volatile uint32 *)PFC_CR1 = 0xffff0000; ++ ++ /* enable */ ++ *(volatile uint32 *)PFC_CR0 = mode; ++} ++ ++void ++BCMINITFN(enable_pfc)(uint32 mode) ++{ ++ ulong start, end; ++ int i; ++ ++ /* If auto then choose the correct mode for this ++ platform, currently we only ever select one mode */ ++ if (mode == PFC_AUTO) ++ mode = PFC_INST; ++ ++ /* enable prefetch cache if available */ ++ if (MFC0(C0_BROADCOM, 0) & BRCM_PFC_AVAIL) { ++ start = (ulong) &BCMINIT(_enable_pfc); ++ end = (ulong) &BCMINIT(enable_pfc); ++ ++ /* Preload handler into the cache one line at a time */ ++ for (i = 0; i < (end - start); i += 4) ++ cache_op(start + i, Fill_I); ++ ++ BCMINIT(_enable_pfc)(mode); ++ } ++} ++ ++/* returns the ncdl value to be programmed into sdram_ncdl for calibration */ ++uint32 ++BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh) ++{ ++ sbmemcregs_t *memc; ++ uint32 ret = 0; ++ uint32 config, rd, wr, misc, dqsg, cd, sm, sd; ++ uint idx, rev; ++ ++ idx = sb_coreidx(sbh); ++ ++ memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0); ++ if (memc == 0) ++ goto out; ++ ++ rev = sb_corerev(sbh); ++ ++ config = R_REG(&memc->config); ++ wr = R_REG(&memc->wrncdlcor); ++ rd = R_REG(&memc->rdncdlcor); ++ misc = R_REG(&memc->miscdlyctl); ++ dqsg = R_REG(&memc->dqsgatencdl); ++ ++ rd &= MEMC_RDNCDLCOR_RD_MASK; ++ wr &= MEMC_WRNCDLCOR_WR_MASK; ++ dqsg &= MEMC_DQSGATENCDL_G_MASK; ++ ++ if (config & MEMC_CONFIG_DDR) { ++ ret = (wr << 16) | (rd << 8) | dqsg; ++ } else { ++ if (rev > 0) ++ cd = rd; ++ else ++ cd = (rd == MEMC_CD_THRESHOLD) ? rd : (wr + MEMC_CD_THRESHOLD); ++ sm = (misc & MEMC_MISC_SM_MASK) >> MEMC_MISC_SM_SHIFT; ++ sd = (misc & MEMC_MISC_SD_MASK) >> MEMC_MISC_SD_SHIFT; ++ ret = (sm << 16) | (sd << 8) | cd; ++ } ++ ++out: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ return ret; ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbpci.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c +--- linux-2.4.32/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c 2005-12-16 23:39:10.948837000 +0100 +@@ -0,0 +1,588 @@ ++/* ++ * Low-Level PCI and SB support for BCM47xx ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Can free sbpci_init() memory after boot */ ++#ifndef linux ++#define __init ++#endif ++ ++/* Emulated configuration space */ ++static pci_config_regs sb_config_regs[SB_MAXCORES]; ++ ++/* Banned cores */ ++static uint16 pci_ban[32] = { 0 }; ++static uint pci_banned = 0; ++ ++/* CardBus mode */ ++static bool cardbus = FALSE; ++ ++/* Disable PCI host core */ ++static bool pci_disabled = FALSE; ++ ++/* ++ * Functions for accessing external PCI configuration space ++ */ ++ ++/* Assume one-hot slot wiring */ ++#define PCI_SLOT_MAX 16 ++ ++static uint32 ++config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off) ++{ ++ uint coreidx; ++ sbpciregs_t *regs; ++ uint32 addr = 0; ++ ++ /* CardBusMode supports only one device */ ++ if (cardbus && dev > 1) ++ return 0; ++ ++ coreidx = sb_coreidx(sbh); ++ regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); ++ ++ /* Type 0 transaction */ ++ if (bus == 1) { ++ /* Skip unwired slots */ ++ if (dev < PCI_SLOT_MAX) { ++ /* Slide the PCI window to the appropriate slot */ ++ W_REG(®s->sbtopci1, SBTOPCI_CFG0 | ((1 << (dev + 16)) & SBTOPCI1_MASK)); ++ addr = SB_PCI_CFG | ((1 << (dev + 16)) & ~SBTOPCI1_MASK) | ++ (func << 8) | (off & ~3); ++ } ++ } ++ ++ /* Type 1 transaction */ ++ else { ++ W_REG(®s->sbtopci1, SBTOPCI_CFG1); ++ addr = SB_PCI_CFG | (bus << 16) | (dev << 11) | (func << 8) | (off & ~3); ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++ ++ return addr; ++} ++ ++static int ++extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint32 addr, *reg = NULL, val; ++ int ret = 0; ++ ++ if (pci_disabled || ++ !(addr = config_cmd(sbh, bus, dev, func, off)) || ++ !(reg = (uint32 *) REG_MAP(addr, len)) || ++ BUSPROBE(val, reg)) ++ val = 0xffffffff; ++ ++ val >>= 8 * (off & 3); ++ if (len == 4) ++ *((uint32 *) buf) = val; ++ else if (len == 2) ++ *((uint16 *) buf) = (uint16) val; ++ else if (len == 1) ++ *((uint8 *) buf) = (uint8) val; ++ else ++ ret = -1; ++ ++ if (reg) ++ REG_UNMAP(reg); ++ ++ return ret; ++} ++ ++static int ++extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint32 addr, *reg = NULL, val; ++ int ret = 0; ++ ++ if (pci_disabled || ++ !(addr = config_cmd(sbh, bus, dev, func, off)) || ++ !(reg = (uint32 *) REG_MAP(addr, len)) || ++ BUSPROBE(val, reg)) ++ goto done; ++ ++ if (len == 4) ++ val = *((uint32 *) buf); ++ else if (len == 2) { ++ val &= ~(0xffff << (8 * (off & 3))); ++ val |= *((uint16 *) buf) << (8 * (off & 3)); ++ } else if (len == 1) { ++ val &= ~(0xff << (8 * (off & 3))); ++ val |= *((uint8 *) buf) << (8 * (off & 3)); ++ } else ++ ret = -1; ++ ++ W_REG(reg, val); ++ ++ done: ++ if (reg) ++ REG_UNMAP(reg); ++ ++ return ret; ++} ++ ++/* ++ * Functions for accessing translated SB configuration space ++ */ ++ ++static int ++sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ pci_config_regs *cfg; ++ ++ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = &sb_config_regs[dev]; ++ ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED((uintptr)buf, len)); ++ ++ if (len == 4) ++ *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off))); ++ else if (len == 2) ++ *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off))); ++ else if (len == 1) ++ *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off)); ++ else ++ return -1; ++ ++ return 0; ++} ++ ++static int ++sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ uint coreidx, n; ++ void *regs; ++ sbconfig_t *sb; ++ pci_config_regs *cfg; ++ ++ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = &sb_config_regs[dev]; ++ ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED((uintptr)buf, len)); ++ ++ /* Emulate BAR sizing */ ++ if (off >= OFFSETOF(pci_config_regs, base[0]) && off <= OFFSETOF(pci_config_regs, base[3]) && ++ len == 4 && *((uint32 *) buf) == ~0) { ++ coreidx = sb_coreidx(sbh); ++ if ((regs = sb_setcoreidx(sbh, dev))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ /* Highest numbered address match register */ ++ n = (R_REG(&sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT; ++ if (off == OFFSETOF(pci_config_regs, base[0])) ++ cfg->base[0] = ~(sb_size(R_REG(&sb->sbadmatch0)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1) ++ cfg->base[1] = ~(sb_size(R_REG(&sb->sbadmatch1)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[2]) && n >= 2) ++ cfg->base[2] = ~(sb_size(R_REG(&sb->sbadmatch2)) - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[3]) && n >= 3) ++ cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1); ++ } ++ sb_setcoreidx(sbh, coreidx); ++ return 0; ++ } ++ ++ if (len == 4) ++ *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf)); ++ else if (len == 2) ++ *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf)); ++ else if (len == 1) ++ *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf); ++ else ++ return -1; ++ ++ return 0; ++} ++ ++int ++sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ if (bus == 0) ++ return sb_read_config(sbh, bus, dev, func, off, buf, len); ++ else ++ return extpci_read_config(sbh, bus, dev, func, off, buf, len); ++} ++ ++int ++sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ if (bus == 0) ++ return sb_write_config(sbh, bus, dev, func, off, buf, len); ++ else ++ return extpci_write_config(sbh, bus, dev, func, off, buf, len); ++} ++ ++void ++sbpci_ban(uint16 core) ++{ ++ if (pci_banned < ARRAYSIZE(pci_ban)) ++ pci_ban[pci_banned++] = core; ++} ++ ++static int ++sbpci_init_pci(sb_t *sbh) ++{ ++ uint chip, chiprev, chippkg, host; ++ uint32 boardflags; ++ sbpciregs_t *pci; ++ sbconfig_t *sb; ++ uint32 val; ++ ++ chip = sb_chip(sbh); ++ chiprev = sb_chiprev(sbh); ++ chippkg = sb_chippkg(sbh); ++ ++ if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) { ++ printf("PCI: no core\n"); ++ pci_disabled = TRUE; ++ return -1; ++ } ++ sb_core_reset(sbh, 0); ++ ++ boardflags = (uint32) getintvar(NULL, "boardflags"); ++ ++ if ((chip == BCM4310_DEVICE_ID) && (chiprev == 0)) ++ pci_disabled = TRUE; ++ ++ /* ++ * The 200-pin BCM4712 package does not bond out PCI. Even when ++ * PCI is bonded out, some boards may leave the pins ++ * floating. ++ */ ++ if (((chip == BCM4712_DEVICE_ID) && ++ ((chippkg == BCM4712SMALL_PKG_ID) || ++ (chippkg == BCM4712MID_PKG_ID))) || ++ (boardflags & BFL_NOPCI)) ++ pci_disabled = TRUE; ++ ++ /* ++ * If the PCI core should not be touched (disabled, not bonded ++ * out, or pins floating), do not even attempt to access core ++ * registers. Otherwise, try to determine if it is in host ++ * mode. ++ */ ++ if (pci_disabled) ++ host = 0; ++ else ++ host = !BUSPROBE(val, &pci->control); ++ ++ if (!host) { ++ /* Disable PCI interrupts in client mode */ ++ sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF); ++ W_REG(&sb->sbintvec, 0); ++ ++ /* Disable the PCI bridge in client mode */ ++ sbpci_ban(SB_PCI); ++ printf("PCI: Disabled\n"); ++ } else { ++ /* Reset the external PCI bus and enable the clock */ ++ W_REG(&pci->control, 0x5); /* enable the tristate drivers */ ++ W_REG(&pci->control, 0xd); /* enable the PCI clock */ ++ OSL_DELAY(150); /* delay > 100 us */ ++ W_REG(&pci->control, 0xf); /* deassert PCI reset */ ++ W_REG(&pci->arbcontrol, PCI_INT_ARB); /* use internal arbiter */ ++ OSL_DELAY(1); /* delay 1 us */ ++ ++ /* Enable CardBusMode */ ++ cardbus = nvram_match("cardbus", "1"); ++ if (cardbus) { ++ printf("PCI: Enabling CardBus\n"); ++ /* GPIO 1 resets the CardBus device on bcm94710ap */ ++ sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY); ++ sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY); ++ W_REG(&pci->sprom[0], R_REG(&pci->sprom[0]) | 0x400); ++ } ++ ++ /* 64 MB I/O access window */ ++ W_REG(&pci->sbtopci0, SBTOPCI_IO); ++ /* 64 MB configuration access window */ ++ W_REG(&pci->sbtopci1, SBTOPCI_CFG0); ++ /* 1 GB memory access window */ ++ W_REG(&pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA); ++ ++ /* Enable PCI bridge BAR0 prefetch and burst */ ++ val = 6; ++ sbpci_write_config(sbh, 1, 0, 0, PCI_CFG_CMD, &val, sizeof(val)); ++ ++ /* Enable PCI interrupts */ ++ W_REG(&pci->intmask, PCI_INTA); ++ } ++ ++ return 0; ++} ++ ++static int ++sbpci_init_cores(sb_t *sbh) ++{ ++ uint chip, chiprev, chippkg, coreidx, i; ++ sbconfig_t *sb; ++ pci_config_regs *cfg; ++ void *regs; ++ char varname[8]; ++ uint wlidx = 0; ++ uint16 vendor, core; ++ uint8 class, subclass, progif; ++ uint32 val; ++ uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK }; ++ uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT }; ++ ++ chip = sb_chip(sbh); ++ chiprev = sb_chiprev(sbh); ++ chippkg = sb_chippkg(sbh); ++ coreidx = sb_coreidx(sbh); ++ ++ /* Scan the SB bus */ ++ bzero(sb_config_regs, sizeof(sb_config_regs)); ++ for (cfg = sb_config_regs; cfg < &sb_config_regs[SB_MAXCORES]; cfg++) { ++ cfg->vendor = 0xffff; ++ if (!(regs = sb_setcoreidx(sbh, cfg - sb_config_regs))) ++ continue; ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ /* Read ID register and parse vendor and core */ ++ val = R_REG(&sb->sbidhigh); ++ vendor = (val & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT; ++ core = (val & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; ++ progif = 0; ++ ++ /* Check if this core is banned */ ++ for (i = 0; i < pci_banned; i++) ++ if (core == pci_ban[i]) ++ break; ++ if (i < pci_banned) ++ continue; ++ ++ /* Known vendor translations */ ++ switch (vendor) { ++ case SB_VEND_BCM: ++ vendor = VENDOR_BROADCOM; ++ break; ++ } ++ ++ /* Determine class based on known core codes */ ++ switch (core) { ++ case SB_ILINE20: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ILINE_ID; ++ break; ++ case SB_ILINE100: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM4610_ILINE_ID; ++ break; ++ case SB_ENET: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ENET_ID; ++ break; ++ case SB_SDRAM: ++ case SB_MEMC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_RAM; ++ break; ++ case SB_PCI: ++ class = PCI_CLASS_BRIDGE; ++ subclass = PCI_BRIDGE_PCI; ++ break; ++ case SB_MIPS: ++ case SB_MIPS33: ++ class = PCI_CLASS_CPU; ++ subclass = PCI_CPU_MIPS; ++ break; ++ case SB_CODEC: ++ class = PCI_CLASS_COMM; ++ subclass = PCI_COMM_MODEM; ++ core = BCM47XX_V90_ID; ++ break; ++ case SB_USB: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USB_ID; ++ break; ++ case SB_USB11H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USBH_ID; ++ break; ++ case SB_USB11D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ core = BCM47XX_USBD_ID; ++ break; ++ case SB_IPSEC: ++ class = PCI_CLASS_CRYPT; ++ subclass = PCI_CRYPT_NETWORK; ++ core = BCM47XX_IPSEC_ID; ++ break; ++ case SB_ROBO: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ core = BCM47XX_ROBO_ID; ++ break; ++ case SB_EXTIF: ++ case SB_CC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_FLASH; ++ break; ++ case SB_D11: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ /* Let an nvram variable override this */ ++ sprintf(varname, "wl%did", wlidx); ++ wlidx++; ++ if ((core = getintvar(NULL, varname)) == 0) { ++ if (chip == BCM4712_DEVICE_ID) { ++ if (chippkg == BCM4712SMALL_PKG_ID) ++ core = BCM4306_D11G_ID; ++ else ++ core = BCM4306_D11DUAL_ID; ++ } else { ++ /* 4310 */ ++ core = BCM4310_D11B_ID; ++ } ++ } ++ break; ++ ++ default: ++ class = subclass = progif = 0xff; ++ break; ++ } ++ ++ /* Supported translations */ ++ cfg->vendor = htol16(vendor); ++ cfg->device = htol16(core); ++ cfg->rev_id = chiprev; ++ cfg->prog_if = progif; ++ cfg->sub_class = subclass; ++ cfg->base_class = class; ++ cfg->base[0] = htol32(sb_base(R_REG(&sb->sbadmatch0))); ++ cfg->base[1] = htol32(sb_base(R_REG(&sb->sbadmatch1))); ++ cfg->base[2] = htol32(sb_base(R_REG(&sb->sbadmatch2))); ++ cfg->base[3] = htol32(sb_base(R_REG(&sb->sbadmatch3))); ++ cfg->base[4] = 0; ++ cfg->base[5] = 0; ++ if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) ++ cfg->header_type = PCI_HEADER_BRIDGE; ++ else ++ cfg->header_type = PCI_HEADER_NORMAL; ++ /* Save core interrupt flag */ ++ cfg->int_pin = R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ /* Default to MIPS shared interrupt 0 */ ++ cfg->int_line = 0; ++ /* MIPS sbipsflag maps core interrupt flags to interrupts 1 through 4 */ ++ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || ++ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ val = R_REG(&sb->sbipsflag); ++ for (cfg->int_line = 1; cfg->int_line <= 4; cfg->int_line++) { ++ if (((val & sbips_int_mask[cfg->int_line]) >> sbips_int_shift[cfg->int_line]) == cfg->int_pin) ++ break; ++ } ++ if (cfg->int_line > 4) ++ cfg->int_line = 0; ++ } ++ /* Emulated core */ ++ *((uint32 *) &cfg->sprom_control) = 0xffffffff; ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++ return 0; ++} ++ ++int __init ++sbpci_init(sb_t *sbh) ++{ ++ sbpci_init_pci(sbh); ++ sbpci_init_cores(sbh); ++ return 0; ++} ++ ++void ++sbpci_check(sb_t *sbh) ++{ ++ uint coreidx; ++ sbpciregs_t *pci; ++ uint32 sbtopci1; ++ uint32 buf[64], *ptr, i; ++ ulong pa; ++ volatile uint j; ++ ++ coreidx = sb_coreidx(sbh); ++ pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); ++ ++ /* Clear the test array */ ++ pa = (ulong) DMA_MAP(NULL, buf, sizeof(buf), DMA_RX, NULL); ++ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); ++ memset(ptr, 0, sizeof(buf)); ++ ++ /* Point PCI window 1 to memory */ ++ sbtopci1 = R_REG(&pci->sbtopci1); ++ W_REG(&pci->sbtopci1, SBTOPCI_MEM | (pa & SBTOPCI1_MASK)); ++ ++ /* Fill the test array via PCI window 1 */ ++ ptr = (uint32 *) REG_MAP(SB_PCI_CFG + (pa & ~SBTOPCI1_MASK), sizeof(buf)); ++ for (i = 0; i < ARRAYSIZE(buf); i++) { ++ for (j = 0; j < 2; j++); ++ W_REG(&ptr[i], i); ++ } ++ REG_UNMAP(ptr); ++ ++ /* Restore PCI window 1 */ ++ W_REG(&pci->sbtopci1, sbtopci1); ++ ++ /* Check the test array */ ++ DMA_UNMAP(NULL, pa, sizeof(buf), DMA_RX, NULL); ++ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); ++ for (i = 0; i < ARRAYSIZE(buf); i++) { ++ if (ptr[i] != i) ++ break; ++ } ++ ++ /* Change the clock if the test fails */ ++ if (i < ARRAYSIZE(buf)) { ++ uint32 req, cur; ++ ++ cur = sb_clock(sbh); ++ printf("PCI: Test failed at %d MHz\n", (cur + 500000) / 1000000); ++ for (req = 104000000; req < 176000000; req += 4000000) { ++ printf("PCI: Resetting to %d MHz\n", (req + 500000) / 1000000); ++ /* This will only reset if the clocks are valid and have changed */ ++ sb_mips_setclock(sbh, req, 0, 0); ++ } ++ /* Should not reach here */ ++ ASSERT(0); ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/setup.c linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c +--- linux-2.4.32/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c 2005-12-20 00:29:40.187416500 +0100 +@@ -0,0 +1,234 @@ ++/* ++ * Generic setup routines for Broadcom MIPS boards ++ * ++ * Copyright (C) 2005 Felix Fietkau ++ * ++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Global SB handle */ ++sb_t *bcm947xx_sbh = NULL; ++spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED; ++ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock ++ ++extern void bcm947xx_time_init(void); ++extern void bcm947xx_timer_setup(struct irqaction *irq); ++ ++#ifdef CONFIG_REMOTE_DEBUG ++extern void set_debug_traps(void); ++extern void rs_kgdb_hook(struct serial_state *); ++extern void breakpoint(void); ++#endif ++ ++#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ++extern struct ide_ops std_ide_ops; ++#endif ++ ++/* Kernel command line */ ++char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE; ++ ++void ++bcm947xx_machine_restart(char *command) ++{ ++ printk("Please stand by while rebooting the system...\n"); ++ ++ /* Set the watchdog timer to reset immediately */ ++ __cli(); ++ sb_watchdog(sbh, 1); ++ while (1); ++} ++ ++void ++bcm947xx_machine_halt(void) ++{ ++ printk("System halted\n"); ++ ++ /* Disable interrupts and watchdog and spin forever */ ++ __cli(); ++ sb_watchdog(sbh, 0); ++ while (1); ++} ++ ++#ifdef CONFIG_SERIAL ++ ++static int ser_line = 0; ++ ++typedef struct { ++ void *regs; ++ uint irq; ++ uint baud_base; ++ uint reg_shift; ++} serial_port; ++ ++static serial_port ports[4]; ++static int num_ports = 0; ++ ++static void ++serial_add(void *regs, uint irq, uint baud_base, uint reg_shift) ++{ ++ ports[num_ports].regs = regs; ++ ports[num_ports].irq = irq; ++ ports[num_ports].baud_base = baud_base; ++ ports[num_ports].reg_shift = reg_shift; ++ num_ports++; ++} ++ ++static void ++do_serial_add(serial_port *port) ++{ ++ void *regs; ++ uint irq; ++ uint baud_base; ++ uint reg_shift; ++ struct serial_struct s; ++ ++ regs = port->regs; ++ irq = port->irq; ++ baud_base = port->baud_base; ++ reg_shift = port->reg_shift; ++ ++ memset(&s, 0, sizeof(s)); ++ ++ s.line = ser_line++; ++ s.iomem_base = regs; ++ s.irq = irq + 2; ++ s.baud_base = baud_base / 16; ++ s.flags = ASYNC_BOOT_AUTOCONF; ++ s.io_type = SERIAL_IO_MEM; ++ s.iomem_reg_shift = reg_shift; ++ ++ if (early_serial_setup(&s) != 0) { ++ printk(KERN_ERR "Serial setup failed!\n"); ++ } ++} ++ ++#endif /* CONFIG_SERIAL */ ++ ++void __init ++brcm_setup(void) ++{ ++ char *s; ++ int i; ++ char *value; ++ ++ /* Get global SB handle */ ++ sbh = sb_kattach(); ++ ++ /* Initialize clocks and interrupts */ ++ sb_mips_init(sbh); ++ ++ if (BCM330X(current_cpu_data.processor_id) && ++ (read_c0_diag() & BRCM_PFC_AVAIL)) { ++ /* ++ * Now that the sbh is inited set the proper PFC value ++ */ ++ printk("Setting the PFC to its default value\n"); ++ enable_pfc(PFC_AUTO); ++ } ++ ++ ++#ifdef CONFIG_SERIAL ++ sb_serial_init(sbh, serial_add); ++ ++ /* reverse serial ports if nvram variable starts with console=ttyS1 */ ++ /* Initialize UARTs */ ++ s = nvram_get("kernel_args"); ++ if (!s) s = ""; ++ if (!strncmp(s, "console=ttyS1", 13)) { ++ for (i = num_ports; i; i--) ++ do_serial_add(&ports[i - 1]); ++ } else { ++ for (i = 0; i < num_ports; i++) ++ do_serial_add(&ports[i]); ++ } ++#endif ++ ++#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ++ ide_ops = &std_ide_ops; ++#endif ++ ++ /* Override default command line arguments */ ++ value = nvram_get("kernel_cmdline"); ++ if (value && strlen(value) && strncmp(value, "empty", 5)) ++ strncpy(arcs_cmdline, value, sizeof(arcs_cmdline)); ++ ++ ++ /* Generic setup */ ++ _machine_restart = bcm947xx_machine_restart; ++ _machine_halt = bcm947xx_machine_halt; ++ _machine_power_off = bcm947xx_machine_halt; ++ ++ board_time_init = bcm947xx_time_init; ++ board_timer_setup = bcm947xx_timer_setup; ++} ++ ++const char * ++get_system_type(void) ++{ ++ static char s[32]; ++ ++ if (bcm947xx_sbh) { ++ sprintf(s, "Broadcom BCM%X chip rev %d", sb_chip(bcm947xx_sbh), ++ sb_chiprev(bcm947xx_sbh)); ++ return s; ++ } ++ else ++ return "Broadcom BCM947XX"; ++} ++ ++void __init ++bus_error_init(void) ++{ ++} ++ ++EXPORT_SYMBOL(bcm947xx_sbh); +diff -Nur linux-2.4.32/arch/mips/bcm947xx/sflash.c linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c +--- linux-2.4.32/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c 2005-12-16 23:39:10.948837000 +0100 +@@ -0,0 +1,418 @@ ++/* ++ * Broadcom SiliconBackplane chipcommon serial flash interface ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Private global state */ ++static struct sflash sflash; ++ ++/* Issue a serial flash command */ ++static INLINE void ++sflash_cmd(chipcregs_t *cc, uint opcode) ++{ ++ W_REG(&cc->flashcontrol, SFLASH_START | opcode); ++ while (R_REG(&cc->flashcontrol) & SFLASH_BUSY); ++} ++ ++/* Initialize serial flash access */ ++struct sflash * ++sflash_init(chipcregs_t *cc) ++{ ++ uint32 id, id2; ++ ++ bzero(&sflash, sizeof(sflash)); ++ ++ sflash.type = R_REG(&cc->capabilities) & CAP_FLASH_MASK; ++ ++ switch (sflash.type) { ++ case SFLASH_ST: ++ /* Probe for ST chips */ ++ sflash_cmd(cc, SFLASH_ST_DP); ++ sflash_cmd(cc, SFLASH_ST_RES); ++ id = R_REG(&cc->flashdata); ++ switch (id) { ++ case 0x11: ++ /* ST M25P20 2 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 4; ++ break; ++ case 0x12: ++ /* ST M25P40 4 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 8; ++ break; ++ case 0x13: ++ /* ST M25P80 8 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 16; ++ break; ++ case 0x14: ++ /* ST M25P16 16 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 32; ++ break; ++ case 0x15: ++ /* ST M25P32 32 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 64; ++ break; ++ case 0xbf: ++ W_REG(&cc->flashaddress, 1); ++ sflash_cmd(cc, SFLASH_ST_RES); ++ id2 = R_REG(&cc->flashdata); ++ if (id2 == 0x44) { ++ /* SST M25VF80 4 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 8; ++ } ++ break; ++ } ++ break; ++ ++ case SFLASH_AT: ++ /* Probe for Atmel chips */ ++ sflash_cmd(cc, SFLASH_AT_STATUS); ++ id = R_REG(&cc->flashdata) & 0x3c; ++ switch (id) { ++ case 0xc: ++ /* Atmel AT45DB011 1Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 512; ++ break; ++ case 0x14: ++ /* Atmel AT45DB021 2Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 1024; ++ break; ++ case 0x1c: ++ /* Atmel AT45DB041 4Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 2048; ++ break; ++ case 0x24: ++ /* Atmel AT45DB081 8Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 4096; ++ break; ++ case 0x2c: ++ /* Atmel AT45DB161 16Mbit Serial Flash */ ++ sflash.blocksize = 512; ++ sflash.numblocks = 4096; ++ break; ++ case 0x34: ++ /* Atmel AT45DB321 32Mbit Serial Flash */ ++ sflash.blocksize = 512; ++ sflash.numblocks = 8192; ++ break; ++ case 0x3c: ++ /* Atmel AT45DB642 64Mbit Serial Flash */ ++ sflash.blocksize = 1024; ++ sflash.numblocks = 8192; ++ break; ++ } ++ break; ++ } ++ ++ sflash.size = sflash.blocksize * sflash.numblocks; ++ return sflash.size ? &sflash : NULL; ++} ++ ++/* Read len bytes starting at offset into buf. Returns number of bytes read. */ ++int ++sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf) ++{ ++ int cnt; ++ uint32 *from, *to; ++ ++ if (!len) ++ return 0; ++ ++ if ((offset + len) > sflash.size) ++ return -22; ++ ++ if ((len >= 4) && (offset & 3)) ++ cnt = 4 - (offset & 3); ++ else if ((len >= 4) && ((uint32)buf & 3)) ++ cnt = 4 - ((uint32)buf & 3); ++ else ++ cnt = len; ++ ++ from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset); ++ to = (uint32 *)buf; ++ ++ if (cnt < 4) { ++ bcopy(from, to, cnt); ++ return cnt; ++ } ++ ++ while (cnt >= 4) { ++ *to++ = *from++; ++ cnt -= 4; ++ } ++ ++ return (len - cnt); ++} ++ ++/* Poll for command completion. Returns zero when complete. */ ++int ++sflash_poll(chipcregs_t *cc, uint offset) ++{ ++ if (offset >= sflash.size) ++ return -22; ++ ++ switch (sflash.type) { ++ case SFLASH_ST: ++ /* Check for ST Write In Progress bit */ ++ sflash_cmd(cc, SFLASH_ST_RDSR); ++ return R_REG(&cc->flashdata) & SFLASH_ST_WIP; ++ case SFLASH_AT: ++ /* Check for Atmel Ready bit */ ++ sflash_cmd(cc, SFLASH_AT_STATUS); ++ return !(R_REG(&cc->flashdata) & SFLASH_AT_READY); ++ } ++ ++ return 0; ++} ++ ++/* Write len bytes starting at offset into buf. Returns number of bytes ++ * written. Caller should poll for completion. ++ */ ++int ++sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf) ++{ ++ struct sflash *sfl; ++ int ret = 0; ++ bool is4712b0; ++ uint32 page, byte, mask; ++ ++ if (!len) ++ return 0; ++ ++ if ((offset + len) > sflash.size) ++ return -22; ++ ++ sfl = &sflash; ++ switch (sfl->type) { ++ case SFLASH_ST: ++ mask = R_REG(&cc->chipid); ++ is4712b0 = (((mask & CID_ID_MASK) == BCM4712_DEVICE_ID) && ++ ((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT))); ++ /* Enable writes */ ++ sflash_cmd(cc, SFLASH_ST_WREN); ++ if (is4712b0) { ++ mask = 1 << 14; ++ W_REG(&cc->flashaddress, offset); ++ W_REG(&cc->flashdata, *buf++); ++ /* Set chip select */ ++ OR_REG(&cc->gpioout, mask); ++ /* Issue a page program with the first byte */ ++ sflash_cmd(cc, SFLASH_ST_PP); ++ ret = 1; ++ offset++; ++ len--; ++ while (len > 0) { ++ if ((offset & 255) == 0) { ++ /* Page boundary, drop cs and return */ ++ AND_REG(&cc->gpioout, ~mask); ++ if (!sflash_poll(cc, offset)) { ++ /* Flash rejected command */ ++ return -11; ++ } ++ return ret; ++ } else { ++ /* Write single byte */ ++ sflash_cmd(cc, *buf++); ++ } ++ ret++; ++ offset++; ++ len--; ++ } ++ /* All done, drop cs if needed */ ++ if ((offset & 255) != 1) { ++ /* Drop cs */ ++ AND_REG(&cc->gpioout, ~mask); ++ if (!sflash_poll(cc, offset)) { ++ /* Flash rejected command */ ++ return -12; ++ } ++ } ++ } else { ++ ret = 1; ++ W_REG(&cc->flashaddress, offset); ++ W_REG(&cc->flashdata, *buf); ++ /* Page program */ ++ sflash_cmd(cc, SFLASH_ST_PP); ++ } ++ break; ++ case SFLASH_AT: ++ mask = sfl->blocksize - 1; ++ page = (offset & ~mask) << 1; ++ byte = offset & mask; ++ /* Read main memory page into buffer 1 */ ++ if (byte || len < sfl->blocksize) { ++ W_REG(&cc->flashaddress, page); ++ sflash_cmd(cc, SFLASH_AT_BUF1_LOAD); ++ /* 250 us for AT45DB321B */ ++ SPINWAIT(sflash_poll(cc, offset), 1000); ++ ASSERT(!sflash_poll(cc, offset)); ++ } ++ /* Write into buffer 1 */ ++ for (ret = 0; ret < len && byte < sfl->blocksize; ret++) { ++ W_REG(&cc->flashaddress, byte++); ++ W_REG(&cc->flashdata, *buf++); ++ sflash_cmd(cc, SFLASH_AT_BUF1_WRITE); ++ } ++ /* Write buffer 1 into main memory page */ ++ W_REG(&cc->flashaddress, page); ++ sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM); ++ break; ++ } ++ ++ return ret; ++} ++ ++/* Erase a region. Returns number of bytes scheduled for erasure. ++ * Caller should poll for completion. ++ */ ++int ++sflash_erase(chipcregs_t *cc, uint offset) ++{ ++ struct sflash *sfl; ++ ++ if (offset >= sflash.size) ++ return -22; ++ ++ sfl = &sflash; ++ switch (sfl->type) { ++ case SFLASH_ST: ++ sflash_cmd(cc, SFLASH_ST_WREN); ++ W_REG(&cc->flashaddress, offset); ++ sflash_cmd(cc, SFLASH_ST_SE); ++ return sfl->blocksize; ++ case SFLASH_AT: ++ W_REG(&cc->flashaddress, offset << 1); ++ sflash_cmd(cc, SFLASH_AT_PAGE_ERASE); ++ return sfl->blocksize; ++ } ++ ++ return 0; ++} ++ ++/* ++ * writes the appropriate range of flash, a NULL buf simply erases ++ * the region of flash ++ */ ++int ++sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf) ++{ ++ struct sflash *sfl; ++ uchar *block = NULL, *cur_ptr, *blk_ptr; ++ uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder; ++ uint blk_offset, blk_len, copied; ++ int bytes, ret = 0; ++ ++ /* Check address range */ ++ if (len <= 0) ++ return 0; ++ ++ sfl = &sflash; ++ if ((offset + len) > sfl->size) ++ return -1; ++ ++ blocksize = sfl->blocksize; ++ mask = blocksize - 1; ++ ++ /* Allocate a block of mem */ ++ if (!(block = MALLOC(NULL, blocksize))) ++ return -1; ++ ++ while (len) { ++ /* Align offset */ ++ cur_offset = offset & ~mask; ++ cur_length = blocksize; ++ cur_ptr = block; ++ ++ remainder = blocksize - (offset & mask); ++ if (len < remainder) ++ cur_retlen = len; ++ else ++ cur_retlen = remainder; ++ ++ /* buf == NULL means erase only */ ++ if (buf) { ++ /* Copy existing data into holding block if necessary */ ++ if ((offset & mask) || (len < blocksize)) { ++ blk_offset = cur_offset; ++ blk_len = cur_length; ++ blk_ptr = cur_ptr; ++ ++ /* Copy entire block */ ++ while(blk_len) { ++ copied = sflash_read(cc, blk_offset, blk_len, blk_ptr); ++ blk_offset += copied; ++ blk_len -= copied; ++ blk_ptr += copied; ++ } ++ } ++ ++ /* Copy input data into holding block */ ++ memcpy(cur_ptr + (offset & mask), buf, cur_retlen); ++ } ++ ++ /* Erase block */ ++ if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0) ++ goto done; ++ while (sflash_poll(cc, (uint) cur_offset)); ++ ++ /* buf == NULL means erase only */ ++ if (!buf) { ++ offset += cur_retlen; ++ len -= cur_retlen; ++ continue; ++ } ++ ++ /* Write holding block */ ++ while (cur_length > 0) { ++ if ((bytes = sflash_write(cc, ++ (uint) cur_offset, ++ (uint) cur_length, ++ (uchar *) cur_ptr)) < 0) { ++ ret = bytes; ++ goto done; ++ } ++ while (sflash_poll(cc, (uint) cur_offset)); ++ cur_offset += bytes; ++ cur_length -= bytes; ++ cur_ptr += bytes; ++ } ++ ++ offset += cur_retlen; ++ len -= cur_retlen; ++ buf += cur_retlen; ++ } ++ ++ ret = len; ++done: ++ if (block) ++ MFREE(NULL, block, blocksize); ++ return ret; ++} ++ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/time.c linux-2.4.32-brcm/arch/mips/bcm947xx/time.c +--- linux-2.4.32/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/time.c 2005-12-16 23:39:10.948837000 +0100 +@@ -0,0 +1,118 @@ ++/* ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: time.c,v 1.1 2005/03/16 13:49:59 wbx Exp $ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Global SB handle */ ++extern void *bcm947xx_sbh; ++extern spinlock_t bcm947xx_sbh_lock; ++ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock ++ ++extern int panic_timeout; ++static int watchdog = 0; ++static u8 *mcr = NULL; ++ ++void __init ++bcm947xx_time_init(void) ++{ ++ unsigned int hz; ++ extifregs_t *eir; ++ ++ /* ++ * Use deterministic values for initial counter interrupt ++ * so that calibrate delay avoids encountering a counter wrap. ++ */ ++ write_c0_count(0); ++ write_c0_compare(0xffff); ++ ++ if (!(hz = sb_mips_clock(sbh))) ++ hz = 100000000; ++ ++ printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh), ++ (hz + 500000) / 1000000); ++ ++ /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ ++ mips_hpt_frequency = hz / 2; ++ ++ /* Set watchdog interval in ms */ ++ watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0); ++ ++ /* Please set the watchdog to 3 sec if it is less than 3 but not equal to 0 */ ++ if (watchdog > 0) { ++ if (watchdog < 3000) ++ watchdog = 3000; ++ } ++ ++ ++ /* Set panic timeout in seconds */ ++ panic_timeout = watchdog / 1000; ++ ++ /* Setup blink */ ++ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { ++ sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF); ++ unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1))); ++ mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1); ++ } ++} ++ ++static void ++bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ /* Generic MIPS timer code */ ++ timer_interrupt(irq, dev_id, regs); ++ ++ /* Set the watchdog timer to reset after the specified number of ms */ ++ if (watchdog > 0) ++ sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog); ++ ++#ifdef CONFIG_HWSIM ++ (*((int *)0xa0000f1c))++; ++#else ++ /* Blink one of the LEDs in the external UART */ ++ if (mcr && !(jiffies % (HZ/2))) ++ writeb(readb(mcr) ^ UART_MCR_OUT2, mcr); ++#endif ++} ++ ++static struct irqaction bcm947xx_timer_irqaction = { ++ bcm947xx_timer_interrupt, ++ SA_INTERRUPT, ++ 0, ++ "timer", ++ NULL, ++ NULL ++}; ++ ++void __init ++bcm947xx_timer_setup(struct irqaction *irq) ++{ ++ /* Enable the timer interrupt */ ++ setup_irq(7, &bcm947xx_timer_irqaction); ++} +diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/config-shared.in +--- linux-2.4.32/arch/mips/config-shared.in 2005-01-19 15:09:27.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/config-shared.in 2005-12-16 23:39:11.080845250 +0100 +@@ -205,6 +205,14 @@ + fi + define_bool CONFIG_MIPS_RTC y + fi ++dep_bool 'Support for Broadcom MIPS-based boards' CONFIG_MIPS_BRCM $CONFIG_EXPERIMENTAL ++dep_bool 'Support for Broadcom BCM947XX' CONFIG_BCM947XX $CONFIG_MIPS_BRCM ++if [ "$CONFIG_BCM947XX" = "y" ] ; then ++ bool ' Support for Broadcom BCM4710' CONFIG_BCM4710 ++ bool ' Support for Broadcom BCM4310' CONFIG_BCM4310 ++ bool ' Support for Broadcom BCM4704' CONFIG_BCM4704 ++ bool ' Support for Broadcom BCM5365' CONFIG_BCM5365 ++fi + bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI + bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226 + bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229 +@@ -226,6 +234,11 @@ + define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n + + # ++# Provide an option for a default kernel command line ++# ++string 'Default kernel command string' CONFIG_CMDLINE "" ++ ++# + # Select some configuration options automatically based on user selections. + # + if [ "$CONFIG_ACER_PICA_61" = "y" ]; then +@@ -533,6 +546,13 @@ + define_bool CONFIG_SWAP_IO_SPACE_L y + define_bool CONFIG_BOOT_ELF32 y + fi ++if [ "$CONFIG_BCM947XX" = "y" ] ; then ++ define_bool CONFIG_PCI y ++ define_bool CONFIG_NONCOHERENT_IO y ++ define_bool CONFIG_NEW_TIME_C y ++ define_bool CONFIG_NEW_IRQ y ++ define_bool CONFIG_HND y ++fi + if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then + define_bool CONFIG_ARC32 y + define_bool CONFIG_ARC_MEMORY y +@@ -1011,7 +1031,11 @@ + + bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE + bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG +-bool 'Remote GDB kernel debugging' CONFIG_KGDB ++if [ "$CONFIG_BCM947XX" = "y" ] ; then ++ bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG ++else ++ bool 'Remote GDB kernel debugging' CONFIG_KGDB ++fi + dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB + if [ "$CONFIG_KGDB" = "y" ]; then + define_bool CONFIG_DEBUG_INFO y +diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c +--- linux-2.4.32/arch/mips/kernel/cpu-probe.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c 2005-12-16 23:39:11.084845500 +0100 +@@ -174,7 +174,7 @@ + + static inline void cpu_probe_legacy(struct cpuinfo_mips *c) + { +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_R2000: + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; +@@ -184,7 +184,7 @@ + c->tlbsize = 64; + break; + case PRID_IMP_R3000: +- if ((c->processor_id & 0xff) == PRID_REV_R3000A) ++ if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) + if (cpu_has_confreg()) + c->cputype = CPU_R3081E; + else +@@ -199,12 +199,12 @@ + break; + case PRID_IMP_R4000: + if (read_c0_config() & CONF_SC) { +- if ((c->processor_id & 0xff) >= PRID_REV_R4400) ++ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) + c->cputype = CPU_R4400PC; + else + c->cputype = CPU_R4000PC; + } else { +- if ((c->processor_id & 0xff) >= PRID_REV_R4400) ++ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; + else + c->cputype = CPU_R4000SC; +@@ -450,7 +450,7 @@ + static inline void cpu_probe_mips(struct cpuinfo_mips *c) + { + decode_config1(c); +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_4KC: + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; +@@ -491,10 +491,10 @@ + { + decode_config1(c); + c->options |= MIPS_CPU_PREFETCH; +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_AU1_REV1: + case PRID_IMP_AU1_REV2: +- switch ((c->processor_id >> 24) & 0xff) { ++ switch ((c->processor_id >> 24) & PRID_REV_MASK) { + case 0: + c->cputype = CPU_AU1000; + break; +@@ -522,10 +522,34 @@ + } + } + ++static inline void cpu_probe_broadcom(struct cpuinfo_mips *c) ++{ ++ decode_config1(c); ++ c->options |= MIPS_CPU_PREFETCH; ++ switch (c->processor_id & PRID_IMP_MASK) { ++ case PRID_IMP_BCM4710: ++ c->cputype = CPU_BCM4710; ++ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | ++ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; ++ c->scache.flags = MIPS_CACHE_NOT_PRESENT; ++ break; ++ case PRID_IMP_4KC: ++ case PRID_IMP_BCM3302: ++ c->cputype = CPU_BCM3302; ++ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | ++ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; ++ c->scache.flags = MIPS_CACHE_NOT_PRESENT; ++ break; ++ default: ++ c->cputype = CPU_UNKNOWN; ++ break; ++ } ++} ++ + static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) + { + decode_config1(c); +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_SB1: + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; +@@ -547,7 +571,7 @@ + static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) + { + decode_config1(c); +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; +@@ -572,7 +596,7 @@ + c->cputype = CPU_UNKNOWN; + + c->processor_id = read_c0_prid(); +- switch (c->processor_id & 0xff0000) { ++ switch (c->processor_id & PRID_COMP_MASK) { + + case PRID_COMP_LEGACY: + cpu_probe_legacy(c); +@@ -583,6 +607,9 @@ + case PRID_COMP_ALCHEMY: + cpu_probe_alchemy(c); + break; ++ case PRID_COMP_BROADCOM: ++ cpu_probe_broadcom(c); ++ break; + case PRID_COMP_SIBYTE: + cpu_probe_sibyte(c); + break; +diff -Nur linux-2.4.32/arch/mips/kernel/head.S linux-2.4.32-brcm/arch/mips/kernel/head.S +--- linux-2.4.32/arch/mips/kernel/head.S 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/head.S 2005-12-16 23:39:11.084845500 +0100 +@@ -28,12 +28,20 @@ + #include + #include + ++#ifdef CONFIG_BCM4710 ++#undef eret ++#define eret nop; nop; eret ++#endif ++ + .text ++ j kernel_entry ++ nop ++ + /* + * Reserved space for exception handlers. + * Necessary for machines which link their kernels at KSEG0. + */ +- .fill 0x400 ++ .fill 0x3f4 + + /* The following two symbols are used for kernel profiling. */ + EXPORT(stext) +diff -Nur linux-2.4.32/arch/mips/kernel/proc.c linux-2.4.32-brcm/arch/mips/kernel/proc.c +--- linux-2.4.32/arch/mips/kernel/proc.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/proc.c 2005-12-16 23:39:11.084845500 +0100 +@@ -78,9 +78,10 @@ + [CPU_AU1550] "Au1550", + [CPU_24K] "MIPS 24K", + [CPU_AU1200] "Au1200", ++ [CPU_BCM4710] "BCM4710", ++ [CPU_BCM3302] "BCM3302", + }; + +- + static int show_cpuinfo(struct seq_file *m, void *v) + { + unsigned int version = current_cpu_data.processor_id; +diff -Nur linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32-brcm/arch/mips/kernel/setup.c +--- linux-2.4.32/arch/mips/kernel/setup.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/setup.c 2005-12-16 23:39:11.140849000 +0100 +@@ -495,6 +495,7 @@ + void swarm_setup(void); + void hp_setup(void); + void au1x00_setup(void); ++ void brcm_setup(void); + void frame_info_init(void); + + frame_info_init(); +@@ -693,6 +694,11 @@ + pmc_yosemite_setup(); + break; + #endif ++#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4310) ++ case MACH_GROUP_BRCM: ++ brcm_setup(); ++ break; ++#endif + default: + panic("Unsupported architecture"); + } +diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kernel/traps.c +--- linux-2.4.32/arch/mips/kernel/traps.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/kernel/traps.c 2005-12-16 23:39:11.140849000 +0100 +@@ -913,6 +913,7 @@ + void __init trap_init(void) + { + extern char except_vec1_generic; ++ extern char except_vec2_generic; + extern char except_vec3_generic, except_vec3_r4000; + extern char except_vec_ejtag_debug; + extern char except_vec4; +@@ -922,6 +923,7 @@ + + /* Copy the generic exception handler code to it's final destination. */ + memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); ++ memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + + /* + * Setup default vectors +@@ -980,6 +982,12 @@ + set_except_vector(13, handle_tr); + set_except_vector(22, handle_mdmx); + ++ if (current_cpu_data.cputype == CPU_SB1) { ++ /* Enable timer interrupt and scd mapped interrupt */ ++ clear_c0_status(0xf000); ++ set_c0_status(0xc00); ++ } ++ + if (cpu_has_fpu && !cpu_has_nofpuex) + set_except_vector(15, handle_fpe); + +diff -Nur linux-2.4.32/arch/mips/Makefile linux-2.4.32-brcm/arch/mips/Makefile +--- linux-2.4.32/arch/mips/Makefile 2005-01-19 15:09:26.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/Makefile 2005-12-16 23:39:10.668819500 +0100 +@@ -715,6 +715,19 @@ + endif + + # ++# Broadcom BCM947XX variants ++# ++ifdef CONFIG_BCM947XX ++LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o ++SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx ++LOADADDR := 0x80001000 ++ ++zImage: vmlinux ++ $(MAKE) -C arch/$(ARCH)/bcm947xx/compressed ++export LOADADDR ++endif ++ ++# + # Choosing incompatible machines durings configuration will result in + # error messages during linking. Select a default linkscript if + # none has been choosen above. +@@ -767,6 +780,7 @@ + $(MAKE) -C arch/$(ARCH)/tools clean + $(MAKE) -C arch/mips/baget clean + $(MAKE) -C arch/mips/lasat clean ++ $(MAKE) -C arch/mips/bcm947xx/compressed clean + + archmrproper: + @$(MAKEBOOT) mrproper +diff -Nur linux-2.4.32/arch/mips/mm/c-r4k.c linux-2.4.32-brcm/arch/mips/mm/c-r4k.c +--- linux-2.4.32/arch/mips/mm/c-r4k.c 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/mm/c-r4k.c 2005-12-16 23:39:11.144849250 +0100 +@@ -1114,3 +1114,47 @@ + build_clear_page(); + build_copy_page(); + } ++ ++#ifdef CONFIG_BCM4704 ++static void __init mips32_icache_fill(unsigned long addr, uint nbytes) ++{ ++ unsigned long ic_lsize = current_cpu_data.icache.linesz; ++ int i; ++ for (i = 0; i < nbytes; i += ic_lsize) ++ fill_icache_line((addr + i)); ++} ++ ++/* ++ * This must be run from the cache on 4704A0 ++ * so there are no mips core BIU ops in progress ++ * when the PFC is enabled. ++ */ ++#define PFC_CR0 0xff400000 /* control reg 0 */ ++#define PFC_CR1 0xff400004 /* control reg 1 */ ++static void __init enable_pfc(u32 mode) ++{ ++ /* write range */ ++ *(volatile u32 *)PFC_CR1 = 0xffff0000; ++ ++ /* enable */ ++ *(volatile u32 *)PFC_CR0 = mode; ++} ++#endif ++ ++ ++void check_enable_mips_pfc(int val) ++{ ++ ++#ifdef CONFIG_BCM4704 ++ struct cpuinfo_mips *c = ¤t_cpu_data; ++ ++ /* enable prefetch cache */ ++ if (((c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) == PRID_IMP_BCM3302) ++ && (read_c0_diag() & (1 << 29))) { ++ mips32_icache_fill((unsigned long) &enable_pfc, 64); ++ enable_pfc(val); ++ } ++#endif ++} ++ ++ +diff -Nur linux-2.4.32/arch/mips/pci/Makefile linux-2.4.32-brcm/arch/mips/pci/Makefile +--- linux-2.4.32/arch/mips/pci/Makefile 2005-01-19 15:09:29.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/pci/Makefile 2005-12-16 23:39:11.144849250 +0100 +@@ -13,7 +13,9 @@ + obj-$(CONFIG_MIPS_MSC) += ops-msc.o + obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o + obj-$(CONFIG_SNI_RM200_PCI) += ops-sni.o ++ifndef CONFIG_BCM947XX + obj-y += pci.o ++endif + obj-$(CONFIG_PCI_AUTO) += pci_auto.o + + include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/serial.c +--- linux-2.4.32/drivers/char/serial.c 2005-11-16 20:12:54.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/char/serial.c 2005-12-16 23:39:11.200852750 +0100 +@@ -422,6 +422,10 @@ + return inb(info->port+1); + #endif + case SERIAL_IO_MEM: ++#ifdef CONFIG_BCM4310 ++ readb((unsigned long) info->iomem_base + ++ (UART_SCR<iomem_reg_shift)); ++#endif + return readb((unsigned long) info->iomem_base + + (offset<iomem_reg_shift)); + default: +@@ -442,6 +446,9 @@ + case SERIAL_IO_MEM: + writeb(value, (unsigned long) info->iomem_base + + (offset<iomem_reg_shift)); ++#ifdef CONFIG_BCM4704 ++ *((volatile unsigned int *) KSEG1ADDR(0x18000000)); ++#endif + break; + default: + outb(value, info->port+offset); +@@ -1704,7 +1711,7 @@ + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) +- quot = baud_base / baud; ++ quot = (baud_base + (baud / 2)) / baud; + } + /* If the quotient is zero refuse the change */ + if (!quot && old_termios) { +@@ -1721,12 +1728,12 @@ + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) +- quot = baud_base / baud; ++ quot = (baud_base + (baud / 2)) / baud; + } + } + /* As a last resort, if the quotient is zero, default to 9600 bps */ + if (!quot) +- quot = baud_base / 9600; ++ quot = (baud_base + 4800) / 9600; + /* + * Work around a bug in the Oxford Semiconductor 952 rev B + * chip which causes it to seriously miscalculate baud rates +@@ -5982,6 +5989,13 @@ + * Divisor, bytesize and parity + */ + state = rs_table + co->index; ++ /* ++ * Safe guard: state structure must have been initialized ++ */ ++ if (state->iomem_base == NULL) { ++ printk("!unable to setup serial console!\n"); ++ return -1; ++ } + if (doflow) + state->flags |= ASYNC_CONS_FLOW; + info = &async_sercons; +@@ -5995,7 +6009,7 @@ + info->io_type = state->io_type; + info->iomem_base = state->iomem_base; + info->iomem_reg_shift = state->iomem_reg_shift; +- quot = state->baud_base / baud; ++ quot = (state->baud_base + (baud / 2)) / baud; + cval = cflag & (CSIZE | CSTOPB); + #if defined(__powerpc__) || defined(__alpha__) + cval >>= 8; +diff -Nur linux-2.4.32/drivers/net/Config.in linux-2.4.32-brcm/drivers/net/Config.in +--- linux-2.4.32/drivers/net/Config.in 2005-01-19 15:09:56.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/Config.in 2005-12-16 23:39:11.232854750 +0100 +@@ -2,6 +2,8 @@ + # Network device configuration + # + ++tristate 'Broadcom Home Network Division' CONFIG_HND $CONFIG_PCI ++ + source drivers/net/arcnet/Config.in + + tristate 'Dummy net driver support' CONFIG_DUMMY +diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c +--- linux-2.4.32/drivers/net/hnd/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c 2005-12-16 23:39:11.284858000 +0100 +@@ -0,0 +1,936 @@ ++/* ++ * Misc useful routines to access NIC SROM/OTP . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include /* for sprom content groking */ ++ ++#define VARS_MAX 4096 /* should be reduced */ ++ ++#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */ ++#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */ ++ ++static int initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count); ++static int initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, int *count); ++static int initvars_flash_sb(void *sbh, char **vars, int *count); ++static int srom_parsecis(osl_t *osh, uint8 *cis, char **vars, int *count); ++static int sprom_cmd_pcmcia(osl_t *osh, uint8 cmd); ++static int sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data); ++static int sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data); ++static int sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc); ++ ++static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count); ++static int initvars_flash(osl_t *osh, char **vp, int len, char *devpath); ++ ++/* ++ * Initialize local vars from the right source for this platform. ++ * Return 0 on success, nonzero on error. ++ */ ++int ++srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, int *count) ++{ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ if (vars == NULL || count == NULL) ++ return (0); ++ ++ switch (BUSTYPE(bustype)) { ++ case SB_BUS: ++ case JTAG_BUS: ++ return initvars_flash_sb(sbh, vars, count); ++ ++ case PCI_BUS: ++ ASSERT(curmap); /* can not be NULL */ ++ return initvars_srom_pci(sbh, curmap, vars, count); ++ ++ case PCMCIA_BUS: ++ return initvars_cis_pcmcia(sbh, osh, vars, count); ++ ++ ++ default: ++ ASSERT(0); ++ } ++ return (-1); ++} ++ ++/* support only 16-bit word read from srom */ ++int ++srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) ++{ ++ void *srom; ++ uint i, off, nw; ++ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ ++ /* check input - 16-bit access only */ ++ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) ++ return 1; ++ ++ off = byteoff / 2; ++ nw = nbytes / 2; ++ ++ if (BUSTYPE(bustype) == PCI_BUS) { ++ if (!curmap) ++ return 1; ++ srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET; ++ if (sprom_read_pci(srom, off, buf, nw, FALSE)) ++ return 1; ++ } else if (BUSTYPE(bustype) == PCMCIA_BUS) { ++ for (i = 0; i < nw; i++) { ++ if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i))) ++ return 1; ++ } ++ } else { ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* support only 16-bit word write into srom */ ++int ++srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) ++{ ++ uint16 *srom; ++ uint i, off, nw, crc_range; ++ uint16 image[SPROM_SIZE], *p; ++ uint8 crc; ++ volatile uint32 val32; ++ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ ++ /* check input - 16-bit access only */ ++ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) ++ return 1; ++ ++ crc_range = (((BUSTYPE(bustype) == PCMCIA_BUS) || (BUSTYPE(bustype) == SDIO_BUS)) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2; ++ ++ /* if changes made inside crc cover range */ ++ if (byteoff < crc_range) { ++ nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2; ++ /* read data including entire first 64 words from srom */ ++ if (srom_read(bustype, curmap, osh, 0, nw * 2, image)) ++ return 1; ++ /* make changes */ ++ bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes); ++ /* calculate crc */ ++ htol16_buf(image, crc_range); ++ crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE); ++ ltoh16_buf(image, crc_range); ++ image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff); ++ p = image; ++ off = 0; ++ } else { ++ p = buf; ++ off = byteoff / 2; ++ nw = nbytes / 2; ++ } ++ ++ if (BUSTYPE(bustype) == PCI_BUS) { ++ srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET); ++ /* enable writes to the SPROM */ ++ val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); ++ val32 |= SPROM_WRITEEN; ++ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32); ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ /* write srom */ ++ for (i = 0; i < nw; i++) { ++ W_REG(&srom[off + i], p[i]); ++ bcm_mdelay(WRITE_WORD_DELAY); ++ } ++ /* disable writes to the SPROM */ ++ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN); ++ } else if (BUSTYPE(bustype) == PCMCIA_BUS) { ++ /* enable writes to the SPROM */ ++ if (sprom_cmd_pcmcia(osh, SROM_WEN)) ++ return 1; ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ /* write srom */ ++ for (i = 0; i < nw; i++) { ++ sprom_write_pcmcia(osh, (uint16)(off + i), p[i]); ++ bcm_mdelay(WRITE_WORD_DELAY); ++ } ++ /* disable writes to the SPROM */ ++ if (sprom_cmd_pcmcia(osh, SROM_WDS)) ++ return 1; ++ } else { ++ return 1; ++ } ++ ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ return 0; ++} ++ ++ ++static int ++srom_parsecis(osl_t *osh, uint8 *cis, char **vars, int *count) ++{ ++ char eabuf[32]; ++ char *vp, *base; ++ uint8 tup, tlen, sromrev = 1; ++ int i, j; ++ uint varsize; ++ bool ag_init = FALSE; ++ uint32 w32; ++ ++ ASSERT(vars); ++ ASSERT(count); ++ ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return -2; ++ ++ i = 0; ++ do { ++ tup = cis[i++]; ++ tlen = cis[i++]; ++ if ((i + tlen) >= CIS_SIZE) ++ break; ++ ++ switch (tup) { ++ case CISTPL_MANFID: ++ vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]); ++ vp++; ++ vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]); ++ vp++; ++ break; ++ ++ case CISTPL_FUNCE: ++ if (cis[i] == LAN_NID) { ++ ASSERT(cis[i + 1] == ETHER_ADDR_LEN); ++ bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf); ++ vp += sprintf(vp, "il0macaddr=%s", eabuf); ++ vp++; ++ } ++ break; ++ ++ case CISTPL_CFTABLE: ++ vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]); ++ vp++; ++ break; ++ ++ case CISTPL_BRCM_HNBU: ++ switch (cis[i]) { ++ case HNBU_SROMREV: ++ sromrev = cis[i + 1]; ++ break; ++ ++ case HNBU_CHIPID: ++ vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + cis[i + 1]); ++ vp++; ++ vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + cis[i + 3]); ++ vp++; ++ if (tlen == 7) { ++ vp += sprintf(vp, "chiprev=%d", (cis[i + 6] << 8) + cis[i + 5]); ++ vp++; ++ } ++ break; ++ ++ case HNBU_BOARDREV: ++ vp += sprintf(vp, "boardrev=%d", cis[i + 1]); ++ vp++; ++ break; ++ ++ case HNBU_AA: ++ vp += sprintf(vp, "aa0=%d", cis[i + 1]); ++ vp++; ++ break; ++ ++ case HNBU_AG: ++ vp += sprintf(vp, "ag0=%d", cis[i + 1]); ++ vp++; ++ ag_init = TRUE; ++ break; ++ ++ case HNBU_CC: ++ ASSERT(sromrev > 1); ++ vp += sprintf(vp, "cc=%d", cis[i + 1]); ++ vp++; ++ break; ++ ++ case HNBU_PAPARMS: ++ if (tlen == 2) { ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 1]); ++ vp++; ++ } else if (tlen >= 9) { ++ if (tlen == 10) { ++ ASSERT(sromrev == 2); ++ vp += sprintf(vp, "opo=%d", cis[i + 9]); ++ vp++; ++ } else ++ ASSERT(tlen == 9); ++ ++ for (j = 0; j < 3; j++) { ++ vp += sprintf(vp, "pa0b%d=%d", j, ++ (cis[i + (j * 2) + 2] << 8) + cis[i + (j * 2) + 1]); ++ vp++; ++ } ++ vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]); ++ vp++; ++ vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 8]); ++ vp++; ++ } else ++ ASSERT(tlen >= 9); ++ break; ++ ++ case HNBU_OEM: ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", ++ cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4], ++ cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8]); ++ vp++; ++ break; ++ ++ case HNBU_BOARDFLAGS: ++ w32 = (cis[i + 2] << 8) + cis[i + 1]; ++ if (tlen == 5) ++ w32 |= (cis[i + 4] << 24) + (cis[i + 3] << 16); ++ vp += sprintf(vp, "boardflags=0x%x", w32); ++ vp++; ++ break; ++ ++ case HNBU_LEDS: ++ if (cis[i + 1] != 0xff) { ++ vp += sprintf(vp, "wl0gpio0=%d", cis[i + 1]); ++ vp++; ++ } ++ if (cis[i + 2] != 0xff) { ++ vp += sprintf(vp, "wl0gpio1=%d", cis[i + 2]); ++ vp++; ++ } ++ if (cis[i + 3] != 0xff) { ++ vp += sprintf(vp, "wl0gpio2=%d", cis[i + 3]); ++ vp++; ++ } ++ if (cis[i + 4] != 0xff) { ++ vp += sprintf(vp, "wl0gpio3=%d", cis[i + 4]); ++ vp++; ++ } ++ break; ++ ++ case HNBU_CCODE: ++ ASSERT(sromrev > 1); ++ vp += sprintf(vp, "ccode=%c%c", cis[i + 1], cis[i + 2]); ++ vp++; ++ vp += sprintf(vp, "cctl=0x%x", cis[i + 3]); ++ vp++; ++ break; ++ ++ case HNBU_CCKPO: ++ ASSERT(sromrev > 2); ++ vp += sprintf(vp, "cckpo=0x%x", (cis[i + 2] << 8) | cis[i + 1]); ++ vp++; ++ break; ++ ++ case HNBU_OFDMPO: ++ ASSERT(sromrev > 2); ++ vp += sprintf(vp, "ofdmpo=0x%x", (cis[i + 4] << 24) | ++ (cis[i + 3] << 16) | (cis[i + 2] << 8) | cis[i + 1]); ++ vp++; ++ break; ++ } ++ break; ++ ++ } ++ i += tlen; ++ } while (tup != 0xff); ++ ++ /* Set the srom version */ ++ vp += sprintf(vp, "sromrev=%d", sromrev); ++ vp++; ++ ++ /* if there is no antenna gain field, set default */ ++ if (ag_init == FALSE) { ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "ag0=%d", 0xff); ++ vp++; ++ } ++ ++ /* final nullbyte terminator */ ++ *vp++ = '\0'; ++ varsize = (uint)(vp - base); ++ ++ ASSERT((vp - base) < VARS_MAX); ++ ++ if (varsize == VARS_MAX) { ++ *vars = base; ++ } else { ++ vp = MALLOC(osh, varsize); ++ ASSERT(vp); ++ if (vp) ++ bcopy(base, vp, varsize); ++ MFREE(osh, base, VARS_MAX); ++ *vars = vp; ++ if (!vp) { ++ *count = 0; ++ return -2; ++ } ++ } ++ *count = varsize; ++ ++ return (0); ++} ++ ++ ++/* set PCMCIA sprom command register */ ++static int ++sprom_cmd_pcmcia(osl_t *osh, uint8 cmd) ++{ ++ uint8 status = 0; ++ uint wait_cnt = 1000; ++ ++ /* write sprom command register */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1); ++ ++ /* wait status */ ++ while (wait_cnt--) { ++ OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1); ++ if (status & SROM_DONE) ++ return 0; ++ } ++ ++ return 1; ++} ++ ++/* read a word from the PCMCIA srom */ ++static int ++sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data) ++{ ++ uint8 addr_l, addr_h, data_l, data_h; ++ ++ addr_l = (uint8)((addr * 2) & 0xff); ++ addr_h = (uint8)(((addr * 2) >> 8) & 0xff); ++ ++ /* set address */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); ++ ++ /* do read */ ++ if (sprom_cmd_pcmcia(osh, SROM_READ)) ++ return 1; ++ ++ /* read data */ ++ data_h = data_l = 0; ++ OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1); ++ OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1); ++ ++ *data = (data_h << 8) | data_l; ++ return 0; ++} ++ ++/* write a word to the PCMCIA srom */ ++static int ++sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data) ++{ ++ uint8 addr_l, addr_h, data_l, data_h; ++ ++ addr_l = (uint8)((addr * 2) & 0xff); ++ addr_h = (uint8)(((addr * 2) >> 8) & 0xff); ++ data_l = (uint8)(data & 0xff); ++ data_h = (uint8)((data >> 8) & 0xff); ++ ++ /* set address */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); ++ ++ /* write data */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1); ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1); ++ ++ /* do write */ ++ return sprom_cmd_pcmcia(osh, SROM_WRITE); ++} ++ ++/* ++ * Read in and validate sprom. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc) ++{ ++ int err = 0; ++ uint i; ++ ++ /* read the sprom */ ++ for (i = 0; i < nwords; i++) ++ buf[i] = R_REG(&sprom[wordoff + i]); ++ ++ if (check_crc) { ++ /* fixup the endianness so crc8 will pass */ ++ htol16_buf(buf, nwords * 2); ++ if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) ++ err = 1; ++ /* now correct the endianness of the byte array */ ++ ltoh16_buf(buf, nwords * 2); ++ } ++ ++ return err; ++} ++ ++/* ++* Create variable table from memory. ++* Return 0 on success, nonzero on error. ++*/ ++static int ++initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count) ++{ ++ int c = (int)(end - start); ++ ++ /* do it only when there is more than just the null string */ ++ if (c > 1) { ++ char *vp = MALLOC(osh, c); ++ ASSERT(vp); ++ if (!vp) ++ return BCME_NOMEM; ++ bcopy(start, vp, c); ++ *vars = vp; ++ *count = c; ++ } ++ else { ++ *vars = NULL; ++ *count = 0; ++ } ++ ++ return 0; ++} ++ ++/* ++* Find variables with from flash. 'base' points to the beginning ++* of the table upon enter and to the end of the table upon exit when success. ++* Return 0 on success, nonzero on error. ++*/ ++static int ++initvars_flash(osl_t *osh, char **base, int size, char *devpath) ++{ ++ char *vp = *base; ++ char *flash; ++ int err; ++ char *s; ++ uint l, dl, copy_len; ++ ++ /* allocate memory and read in flash */ ++ if (!(flash = MALLOC(osh, NVRAM_SPACE))) ++ return BCME_NOMEM; ++ if ((err = BCMINIT(nvram_getall)(flash, NVRAM_SPACE))) ++ goto exit; ++ ++ /* grab vars with the prefix in name */ ++ dl = strlen(devpath); ++ for (s = flash; s && *s; s += l + 1) { ++ l = strlen(s); ++ ++ /* skip non-matching variable */ ++ if (strncmp(s, devpath, dl)) ++ continue; ++ ++ /* is there enough room to copy? */ ++ copy_len = l - dl + 1; ++ if (size < (int)copy_len) { ++ err = BCME_BUFTOOSHORT; ++ goto exit; ++ } ++ ++ /* no prefix, just the name=value */ ++ strcpy(vp, &s[dl]); ++ vp += copy_len; ++ size -= copy_len; ++ } ++ ++ /* add null string as terminator */ ++ if (size < 1) { ++ err = BCME_BUFTOOSHORT; ++ goto exit; ++ } ++ *vp++ = '\0'; ++ ++ *base = vp; ++ ++exit: MFREE(osh, flash, NVRAM_SPACE); ++ return err; ++} ++ ++/* ++ * Initialize nonvolatile variable table from flash. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_flash_sb(void *sbh, char **vars, int *count) ++{ ++ osl_t *osh = sb_osh(sbh); ++ char devpath[SB_DEVPATH_BUFSZ]; ++ char *vp, *base; ++ int err; ++ ++ ASSERT(vars); ++ ASSERT(count); ++ ++ if ((err = sb_devpath(sbh, devpath, sizeof(devpath)))) ++ return err; ++ ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return BCME_NOMEM; ++ ++ if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath))) ++ goto err; ++ ++ err = initvars_table(osh, base, vp, vars, count); ++ ++err: MFREE(osh, base, VARS_MAX); ++ return err; ++} ++ ++/* ++ * Initialize nonvolatile variable table from sprom. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count) ++{ ++ uint16 w, b[64]; ++ uint8 sromrev; ++ struct ether_addr ea; ++ char eabuf[32]; ++ uint32 w32; ++ int woff, i; ++ char *vp, *base; ++ osl_t *osh = sb_osh(sbh); ++ bool flash = FALSE; ++ char name[SB_DEVPATH_BUFSZ+16], *value; ++ char devpath[SB_DEVPATH_BUFSZ]; ++ int err; ++ ++ /* ++ * Apply CRC over SROM content regardless SROM is present or not, ++ * and use variable sromrev's existance in flash to decide ++ * if we should return an error when CRC fails or read SROM variables ++ * from flash. ++ */ ++ if (sprom_read_pci((void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof(b)/sizeof(b[0]), TRUE)) { ++ if ((err = sb_devpath(sbh, devpath, sizeof(devpath)))) ++ return err; ++ sprintf(name, "%ssromrev", devpath); ++ if (!(value = getvar(NULL, name))) ++ return (-1); ++ sromrev = (uint8)bcm_strtoul(value, NULL, 0); ++ flash = TRUE; ++ } ++ /* srom is good */ ++ else { ++ /* top word of sprom contains version and crc8 */ ++ sromrev = b[63] & 0xff; ++ /* bcm4401 sroms misprogrammed */ ++ if (sromrev == 0x10) ++ sromrev = 1; ++ } ++ ++ /* srom version check */ ++ if (sromrev > 3) ++ return (-2); ++ ++ ASSERT(vars); ++ ASSERT(count); ++ ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return -2; ++ ++ /* read variables from flash */ ++ if (flash) { ++ if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath))) ++ goto err; ++ goto done; ++ } ++ ++ vp += sprintf(vp, "sromrev=%d", sromrev); ++ vp++; ++ ++ if (sromrev >= 3) { ++ /* New section takes over the 3th hardware function space */ ++ ++ /* Words 22+23 are 11a (mid) ofdm power offsets */ ++ w32 = ((uint32)b[23] << 16) | b[22]; ++ vp += sprintf(vp, "ofdmapo=%d", w32); ++ vp++; ++ ++ /* Words 24+25 are 11a (low) ofdm power offsets */ ++ w32 = ((uint32)b[25] << 16) | b[24]; ++ vp += sprintf(vp, "ofdmalpo=%d", w32); ++ vp++; ++ ++ /* Words 26+27 are 11a (high) ofdm power offsets */ ++ w32 = ((uint32)b[27] << 16) | b[26]; ++ vp += sprintf(vp, "ofdmahpo=%d", w32); ++ vp++; ++ ++ /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/ ++ w32 = ((uint32)b[43] << 24) | ((uint32)b[42] << 8); ++ vp += sprintf(vp, "gpiotimerval=%d", w32); ++ ++ /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/ ++ w32 = ((uint32)((unsigned char)(b[21] >> 8) & 0xFF) << 24) | /* oncount*/ ++ ((uint32)((unsigned char)(b[21] & 0xFF)) << 8); /* offcount */ ++ vp += sprintf(vp, "gpiotimerval=%d", w32); ++ ++ vp++; ++ } ++ ++ if (sromrev >= 2) { ++ /* New section takes over the 4th hardware function space */ ++ ++ /* Word 29 is max power 11a high/low */ ++ w = b[29]; ++ vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ /* Words 30-32 set the 11alow pa settings, ++ * 33-35 are the 11ahigh ones. ++ */ ++ for (i = 0; i < 3; i++) { ++ vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]); ++ vp++; ++ vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]); ++ vp++; ++ } ++ w = b[59]; ++ if (w == 0) ++ vp += sprintf(vp, "ccode="); ++ else ++ vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff)); ++ vp++; ++ ++ } ++ ++ /* parameter section of sprom starts at byte offset 72 */ ++ woff = 72/2; ++ ++ /* first 6 bytes are il0macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += ETHER_ADDR_LEN/2 ; ++ bcm_ether_ntoa((uchar*)&ea, eabuf); ++ vp += sprintf(vp, "il0macaddr=%s", eabuf); ++ vp++; ++ ++ /* next 6 bytes are et0macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += ETHER_ADDR_LEN/2 ; ++ bcm_ether_ntoa((uchar*)&ea, eabuf); ++ vp += sprintf(vp, "et0macaddr=%s", eabuf); ++ vp++; ++ ++ /* next 6 bytes are et1macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += ETHER_ADDR_LEN/2 ; ++ bcm_ether_ntoa((uchar*)&ea, eabuf); ++ vp += sprintf(vp, "et1macaddr=%s", eabuf); ++ vp++; ++ ++ /* ++ * Enet phy settings one or two singles or a dual ++ * Bits 4-0 : MII address for enet0 (0x1f for not there) ++ * Bits 9-5 : MII address for enet1 (0x1f for not there) ++ * Bit 14 : Mdio for enet0 ++ * Bit 15 : Mdio for enet1 ++ */ ++ w = b[woff]; ++ vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f)); ++ vp++; ++ vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f)); ++ vp++; ++ vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1)); ++ vp++; ++ vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1)); ++ vp++; ++ ++ /* Word 46 has board rev, antennas 0/1 & Country code/control */ ++ w = b[46]; ++ vp += sprintf(vp, "boardrev=%d", w & 0xff); ++ vp++; ++ ++ if (sromrev > 1) ++ vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf); ++ else ++ vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf); ++ vp++; ++ ++ vp += sprintf(vp, "aa0=%d", (w >> 12) & 0x3); ++ vp++; ++ ++ vp += sprintf(vp, "aa1=%d", (w >> 14) & 0x3); ++ vp++; ++ ++ /* Words 47-49 set the (wl) pa settings */ ++ woff = 47; ++ ++ for (i = 0; i < 3; i++) { ++ vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]); ++ vp++; ++ vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]); ++ vp++; ++ } ++ ++ /* ++ * Words 50-51 set the customer-configured wl led behavior. ++ * 8 bits/gpio pin. High bit: activehi=0, activelo=1; ++ * LED behavior values defined in wlioctl.h . ++ */ ++ w = b[50]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* gpio0 */ ++ vp += sprintf(vp, "wl0gpio0=%d", (w & 0xff)); ++ vp++; ++ ++ /* gpio1 */ ++ vp += sprintf(vp, "wl0gpio1=%d", (w >> 8) & 0xff); ++ vp++; ++ } ++ w = b[51]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* gpio2 */ ++ vp += sprintf(vp, "wl0gpio2=%d", w & 0xff); ++ vp++; ++ ++ /* gpio3 */ ++ vp += sprintf(vp, "wl0gpio3=%d", (w >> 8) & 0xff); ++ vp++; ++ } ++ ++ /* Word 52 is max power 0/1 */ ++ w = b[52]; ++ vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ /* Word 56 is idle tssi target 0/1 */ ++ w = b[56]; ++ vp += sprintf(vp, "pa0itssit=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ /* Word 57 is boardflags, if not programmed make it zero */ ++ w32 = (uint32)b[57]; ++ if (w32 == 0xffff) w32 = 0; ++ if (sromrev > 1) { ++ /* Word 28 is the high bits of boardflags */ ++ w32 |= (uint32)b[28] << 16; ++ } ++ vp += sprintf(vp, "boardflags=%d", w32); ++ vp++; ++ ++ /* Word 58 is antenna gain 0/1 */ ++ w = b[58]; ++ vp += sprintf(vp, "ag0=%d", w & 0xff); ++ vp++; ++ ++ vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff); ++ vp++; ++ ++ if (sromrev == 1) { ++ /* set the oem string */ ++ vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", ++ ((b[59] >> 8) & 0xff), (b[59] & 0xff), ++ ((b[60] >> 8) & 0xff), (b[60] & 0xff), ++ ((b[61] >> 8) & 0xff), (b[61] & 0xff), ++ ((b[62] >> 8) & 0xff), (b[62] & 0xff)); ++ vp++; ++ } else if (sromrev == 2) { ++ /* Word 60 OFDM tx power offset from CCK level */ ++ /* OFDM Power Offset - opo */ ++ vp += sprintf(vp, "opo=%d", b[60] & 0xff); ++ vp++; ++ } else { ++ /* Word 60: cck power offsets */ ++ vp += sprintf(vp, "cckpo=%d", b[60]); ++ vp++; ++ ++ /* Words 61+62: 11g ofdm power offsets */ ++ w32 = ((uint32)b[62] << 16) | b[61]; ++ vp += sprintf(vp, "ofdmgpo=%d", w32); ++ vp++; ++ } ++ ++ /* final nullbyte terminator */ ++ *vp++ = '\0'; ++ ++ ASSERT((vp - base) <= VARS_MAX); ++ ++done: err = initvars_table(osh, base, vp, vars, count); ++ ++err: MFREE(osh, base, VARS_MAX); ++ return err; ++} ++ ++/* ++ * Read the cis and call parsecis to initialize the vars. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, int *count) ++{ ++ uint8 *cis = NULL; ++ int rc; ++ uint data_sz; ++ ++ data_sz = (sb_pcmciarev(sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE; ++ ++ if ((cis = MALLOC(osh, data_sz)) == NULL) ++ return (-2); ++ ++ if (sb_pcmciarev(sbh) == 1) { ++ if (srom_read(PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis)) { ++ MFREE(osh, cis, data_sz); ++ return (-1); ++ } ++ /* fix up endianess for 16-bit data vs 8-bit parsing */ ++ ltoh16_buf((uint16 *)cis, data_sz); ++ } else ++ OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz); ++ ++ rc = srom_parsecis(osh, cis, vars, count); ++ ++ MFREE(osh, cis, data_sz); ++ ++ return (rc); ++} ++ +diff -Nur linux-2.4.32/drivers/net/hnd/bcmutils.c linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c +--- linux-2.4.32/drivers/net/hnd/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c 2005-12-16 23:39:11.288858250 +0100 +@@ -0,0 +1,1081 @@ ++/* ++ * Misc useful OS-independent routines. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#ifdef BCMDRIVER ++#include ++#include ++#include ++#else ++#include ++#include ++#endif ++#include ++#include ++#include ++ ++#ifdef BCMDRIVER ++/* copy a pkt buffer chain into a buffer */ ++uint ++pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) ++{ ++ uint n, ret = 0; ++ ++ if (len < 0) ++ len = 4096; /* "infinite" */ ++ ++ /* skip 'offset' bytes */ ++ for (; p && offset; p = PKTNEXT(osh, p)) { ++ if (offset < (uint)PKTLEN(osh, p)) ++ break; ++ offset -= PKTLEN(osh, p); ++ } ++ ++ if (!p) ++ return 0; ++ ++ /* copy the data */ ++ for (; p && len; p = PKTNEXT(osh, p)) { ++ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); ++ bcopy(PKTDATA(osh, p) + offset, buf, n); ++ buf += n; ++ len -= n; ++ ret += n; ++ offset = 0; ++ } ++ ++ return ret; ++} ++ ++/* return total length of buffer chain */ ++uint ++pkttotlen(osl_t *osh, void *p) ++{ ++ uint total; ++ ++ total = 0; ++ for (; p; p = PKTNEXT(osh, p)) ++ total += PKTLEN(osh, p); ++ return (total); ++} ++ ++void ++pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]) ++{ ++ q->head = q->tail = NULL; ++ q->maxlen = maxlen; ++ q->len = 0; ++ if (prio_map) { ++ q->priority = TRUE; ++ bcopy(prio_map, q->prio_map, sizeof(q->prio_map)); ++ } ++ else ++ q->priority = FALSE; ++} ++ ++/* should always check pktq_full before calling pktenq */ ++void ++pktenq(struct pktq *q, void *p, bool lifo) ++{ ++ void *next, *prev; ++ ++ /* allow 10 pkts slack */ ++ ASSERT(q->len < (q->maxlen + 10)); ++ ++ /* Queueing chains not allowed */ ++ ASSERT(PKTLINK(p) == NULL); ++ ++ /* Queue is empty */ ++ if (q->tail == NULL) { ++ ASSERT(q->head == NULL); ++ q->head = q->tail = p; ++ } ++ ++ /* Insert at head or tail */ ++ else if (q->priority == FALSE) { ++ /* Insert at head (LIFO) */ ++ if (lifo) { ++ PKTSETLINK(p, q->head); ++ q->head = p; ++ } ++ /* Insert at tail (FIFO) */ ++ else { ++ ASSERT(PKTLINK(q->tail) == NULL); ++ PKTSETLINK(q->tail, p); ++ PKTSETLINK(p, NULL); ++ q->tail = p; ++ } ++ } ++ ++ /* Insert by priority */ ++ else { ++ /* legal priorities 0-7 */ ++ ASSERT(PKTPRIO(p) <= MAXPRIO); ++ ++ ASSERT(q->head); ++ ASSERT(q->tail); ++ /* Shortcut to insertion at tail */ ++ if (_pktq_pri(q, PKTPRIO(p)) < _pktq_pri(q, PKTPRIO(q->tail)) || ++ (!lifo && _pktq_pri(q, PKTPRIO(p)) <= _pktq_pri(q, PKTPRIO(q->tail)))) { ++ prev = q->tail; ++ next = NULL; ++ } ++ /* Insert at head or in the middle */ ++ else { ++ prev = NULL; ++ next = q->head; ++ } ++ /* Walk the queue */ ++ for (; next; prev = next, next = PKTLINK(next)) { ++ /* Priority queue invariant */ ++ ASSERT(!prev || _pktq_pri(q, PKTPRIO(prev)) >= _pktq_pri(q, PKTPRIO(next))); ++ /* Insert at head of string of packets of same priority (LIFO) */ ++ if (lifo) { ++ if (_pktq_pri(q, PKTPRIO(p)) >= _pktq_pri(q, PKTPRIO(next))) ++ break; ++ } ++ /* Insert at tail of string of packets of same priority (FIFO) */ ++ else { ++ if (_pktq_pri(q, PKTPRIO(p)) > _pktq_pri(q, PKTPRIO(next))) ++ break; ++ } ++ } ++ /* Insert at tail */ ++ if (next == NULL) { ++ ASSERT(PKTLINK(q->tail) == NULL); ++ PKTSETLINK(q->tail, p); ++ PKTSETLINK(p, NULL); ++ q->tail = p; ++ } ++ /* Insert in the middle */ ++ else if (prev) { ++ PKTSETLINK(prev, p); ++ PKTSETLINK(p, next); ++ } ++ /* Insert at head */ ++ else { ++ PKTSETLINK(p, q->head); ++ q->head = p; ++ } ++ } ++ ++ /* List invariants after insertion */ ++ ASSERT(q->head); ++ ASSERT(PKTLINK(q->tail) == NULL); ++ ++ q->len++; ++} ++ ++/* dequeue packet at head */ ++void* ++pktdeq(struct pktq *q) ++{ ++ void *p; ++ ++ if ((p = q->head)) { ++ ASSERT(q->tail); ++ q->head = PKTLINK(p); ++ PKTSETLINK(p, NULL); ++ q->len--; ++ if (q->head == NULL) ++ q->tail = NULL; ++ } ++ else { ++ ASSERT(q->tail == NULL); ++ } ++ ++ return (p); ++} ++ ++/* dequeue packet at tail */ ++void* ++pktdeqtail(struct pktq *q) ++{ ++ void *p; ++ void *next, *prev; ++ ++ if (q->head == q->tail) { /* last packet on queue or queue empty */ ++ p = q->head; ++ q->head = q->tail = NULL; ++ q->len = 0; ++ return(p); ++ } ++ ++ /* start walk at head */ ++ prev = NULL; ++ next = q->head; ++ ++ /* Walk the queue to find prev of q->tail */ ++ for (; next; prev = next, next = PKTLINK(next)) { ++ if (next == q->tail) ++ break; ++ } ++ ++ ASSERT(prev); ++ ++ PKTSETLINK(prev, NULL); ++ q->tail = prev; ++ q->len--; ++ p = next; ++ ++ return (p); ++} ++ ++unsigned char bcm_ctype[] = { ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ ++ _BCM_C,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C,_BCM_C, /* 8-15 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ ++ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ ++ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ ++ _BCM_P,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U, /* 64-71 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ ++ _BCM_P,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L, /* 96-103 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 160-175 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 176-191 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 192-207 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_L, /* 208-223 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 224-239 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L /* 240-255 */ ++}; ++ ++uchar ++bcm_toupper(uchar c) ++{ ++ if (bcm_islower(c)) ++ c -= 'a'-'A'; ++ return (c); ++} ++ ++ulong ++bcm_strtoul(char *cp, char **endp, uint base) ++{ ++ ulong result, value; ++ bool minus; ++ ++ minus = FALSE; ++ ++ while (bcm_isspace(*cp)) ++ cp++; ++ ++ if (cp[0] == '+') ++ cp++; ++ else if (cp[0] == '-') { ++ minus = TRUE; ++ cp++; ++ } ++ ++ if (base == 0) { ++ if (cp[0] == '0') { ++ if ((cp[1] == 'x') || (cp[1] == 'X')) { ++ base = 16; ++ cp = &cp[2]; ++ } else { ++ base = 8; ++ cp = &cp[1]; ++ } ++ } else ++ base = 10; ++ } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { ++ cp = &cp[2]; ++ } ++ ++ result = 0; ++ ++ while (bcm_isxdigit(*cp) && ++ (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { ++ result = result*base + value; ++ cp++; ++ } ++ ++ if (minus) ++ result = (ulong)(result * -1); ++ ++ if (endp) ++ *endp = (char *)cp; ++ ++ return (result); ++} ++ ++uint ++bcm_atoi(char *s) ++{ ++ uint n; ++ ++ n = 0; ++ ++ while (bcm_isdigit(*s)) ++ n = (n * 10) + *s++ - '0'; ++ return (n); ++} ++ ++/* return pointer to location of substring 'needle' in 'haystack' */ ++char* ++bcmstrstr(char *haystack, char *needle) ++{ ++ int len, nlen; ++ int i; ++ ++ if ((haystack == NULL) || (needle == NULL)) ++ return (haystack); ++ ++ nlen = strlen(needle); ++ len = strlen(haystack) - nlen + 1; ++ ++ for (i = 0; i < len; i++) ++ if (bcmp(needle, &haystack[i], nlen) == 0) ++ return (&haystack[i]); ++ return (NULL); ++} ++ ++char* ++bcmstrcat(char *dest, const char *src) ++{ ++ strcpy(&dest[strlen(dest)], src); ++ return (dest); ++} ++ ++#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) ++/* registry routine buffer preparation utility functions: ++ * parameter order is like strncpy, but returns count ++ * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) ++ */ ++ulong ++wchar2ascii( ++ char *abuf, ++ ushort *wbuf, ++ ushort wbuflen, ++ ulong abuflen ++) ++{ ++ ulong copyct = 1; ++ ushort i; ++ ++ if (abuflen == 0) ++ return 0; ++ ++ /* wbuflen is in bytes */ ++ wbuflen /= sizeof(ushort); ++ ++ for (i = 0; i < wbuflen; ++i) { ++ if (--abuflen == 0) ++ break; ++ *abuf++ = (char) *wbuf++; ++ ++copyct; ++ } ++ *abuf = '\0'; ++ ++ return copyct; ++} ++#endif ++ ++char* ++bcm_ether_ntoa(char *ea, char *buf) ++{ ++ sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x", ++ (uchar)ea[0]&0xff, (uchar)ea[1]&0xff, (uchar)ea[2]&0xff, ++ (uchar)ea[3]&0xff, (uchar)ea[4]&0xff, (uchar)ea[5]&0xff); ++ return (buf); ++} ++ ++/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ ++int ++bcm_ether_atoe(char *p, char *ea) ++{ ++ int i = 0; ++ ++ for (;;) { ++ ea[i++] = (char) bcm_strtoul(p, &p, 16); ++ if (!*p++ || i == 6) ++ break; ++ } ++ ++ return (i == 6); ++} ++ ++void ++bcm_mdelay(uint ms) ++{ ++ uint i; ++ ++ for (i = 0; i < ms; i++) { ++ OSL_DELAY(1000); ++ } ++} ++ ++/* ++ * Search the name=value vars for a specific one and return its value. ++ * Returns NULL if not found. ++ */ ++char* ++getvar(char *vars, char *name) ++{ ++ char *s; ++ int len; ++ ++ len = strlen(name); ++ ++ /* first look in vars[] */ ++ for (s = vars; s && *s; ) { ++ if ((bcmp(s, name, len) == 0) && (s[len] == '=')) ++ return (&s[len+1]); ++ ++ while (*s++) ++ ; ++ } ++ ++ /* then query nvram */ ++ return (BCMINIT(nvram_get)(name)); ++} ++ ++/* ++ * Search the vars for a specific one and return its value as ++ * an integer. Returns 0 if not found. ++ */ ++int ++getintvar(char *vars, char *name) ++{ ++ char *val; ++ ++ if ((val = getvar(vars, name)) == NULL) ++ return (0); ++ ++ return (bcm_strtoul(val, NULL, 0)); ++} ++ ++ ++/* Search for token in comma separated token-string */ ++static int ++findmatch(char *string, char *name) ++{ ++ uint len; ++ char *c; ++ ++ len = strlen(name); ++ while ((c = strchr(string, ',')) != NULL) { ++ if (len == (uint)(c - string) && !strncmp(string, name, len)) ++ return 1; ++ string = c + 1; ++ } ++ ++ return (!strcmp(string, name)); ++} ++ ++/* Return gpio pin number assigned to the named pin */ ++/* ++* Variable should be in format: ++* ++* gpio=pin_name,pin_name ++* ++* This format allows multiple features to share the gpio with mutual ++* understanding. ++* ++* 'def_pin' is returned if a specific gpio is not defined for the requested functionality ++* and if def_pin is not used by others. ++*/ ++uint ++getgpiopin(char *vars, char *pin_name, uint def_pin) ++{ ++ char name[] = "gpioXXXX"; ++ char *val; ++ uint pin; ++ ++ /* Go thru all possibilities till a match in pin name */ ++ for (pin = 0; pin < GPIO_NUMPINS; pin ++) { ++ sprintf(name, "gpio%d", pin); ++ val = getvar(vars, name); ++ if (val && findmatch(val, pin_name)) ++ return pin; ++ } ++ ++ if (def_pin != GPIO_PIN_NOTDEFINED) { ++ /* make sure the default pin is not used by someone else */ ++ sprintf(name, "gpio%d", def_pin); ++ if (getvar(vars, name)) { ++ def_pin = GPIO_PIN_NOTDEFINED; ++ } ++ } ++ ++ return def_pin; ++} ++ ++ ++static char bcm_undeferrstr[BCME_STRLEN]; ++ ++static const char *bcmerrorstrtable[] = \ ++{ "OK", /* 0 */ ++ "Undefined error", /* BCME_ERROR */ ++ "Bad Argument", /* BCME_BADARG*/ ++ "Bad Option", /* BCME_BADOPTION*/ ++ "Not up", /* BCME_NOTUP */ ++ "Not down", /* BCME_NOTDOWN */ ++ "Not AP", /* BCME_NOTAP */ ++ "Not STA", /* BCME_NOTSTA */ ++ "Bad Key Index", /* BCME_BADKEYIDX */ ++ "Radio Off", /* BCME_RADIOOFF */ ++ "Not band locked", /* BCME_NOTBANDLOCKED */ ++ "No clock", /* BCME_NOCLK */ ++ "Bad Rate valueset", /* BCME_BADRATESET */ ++ "Bad Band", /* BCME_BADBAND */ ++ "Buffer too short", /* BCME_BUFTOOSHORT */ ++ "Buffer too length", /* BCME_BUFTOOLONG */ ++ "Busy", /* BCME_BUSY */ ++ "Not Associated", /* BCME_NOTASSOCIATED */ ++ "Bad SSID len", /* BCME_BADSSIDLEN */ ++ "Out of Range Channel", /* BCME_OUTOFRANGECHAN */ ++ "Bad Channel", /* BCME_BADCHAN */ ++ "Bad Address", /* BCME_BADADDR */ ++ "Not Enough Resources", /* BCME_NORESOURCE */ ++ "Unsupported", /* BCME_UNSUPPORTED */ ++ "Bad length", /* BCME_BADLENGTH */ ++ "Not Ready", /* BCME_NOTREADY */ ++ "Not Permitted", /* BCME_EPERM */ ++ "No Memory", /* BCME_NOMEM */ ++ "Associated", /* BCME_ASSOCIATED */ ++ "Not In Range", /* BCME_RANGE */ ++ "Not Found" /* BCME_NOTFOUND */ ++ }; ++ ++/* Convert the Error codes into related Error strings */ ++const char * ++bcmerrorstr(int bcmerror) ++{ ++ int abs_bcmerror; ++ ++ abs_bcmerror = ABS(bcmerror); ++ ++ /* check if someone added a bcmerror code but forgot to add errorstring */ ++ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); ++ if ( (bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) { ++ sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror); ++ return bcm_undeferrstr; ++ } ++ ++ ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN); ++ ++ return bcmerrorstrtable[abs_bcmerror]; ++} ++#endif /* #ifdef BCMDRIVER */ ++ ++ ++/******************************************************************************* ++ * crc8 ++ * ++ * Computes a crc8 over the input data using the polynomial: ++ * ++ * x^8 + x^7 +x^6 + x^4 + x^2 + 1 ++ * ++ * The caller provides the initial value (either CRC8_INIT_VALUE ++ * or the previous returned value) to allow for processing of ++ * discontiguous blocks of data. When generating the CRC the ++ * caller is responsible for complementing the final return value ++ * and inserting it into the byte stream. When checking, a final ++ * return value of CRC8_GOOD_VALUE indicates a valid CRC. ++ * ++ * Reference: Dallas Semiconductor Application Note 27 ++ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", ++ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., ++ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt ++ * ++ ******************************************************************************/ ++ ++static uint8 crc8_table[256] = { ++ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, ++ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, ++ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, ++ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, ++ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, ++ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, ++ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, ++ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, ++ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, ++ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, ++ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, ++ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, ++ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, ++ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, ++ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, ++ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, ++ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, ++ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, ++ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, ++ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, ++ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, ++ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, ++ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, ++ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, ++ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, ++ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, ++ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, ++ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, ++ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, ++ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, ++ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, ++ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F ++}; ++ ++#define CRC_INNER_LOOP(n, c, x) \ ++ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] ++ ++uint8 ++hndcrc8( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint8 crc /* either CRC8_INIT_VALUE or previous return value */ ++) ++{ ++ /* hard code the crc loop instead of using CRC_INNER_LOOP macro ++ * to avoid the undefined and unnecessary (uint8 >> 8) operation. */ ++ while (nbytes-- > 0) ++ crc = crc8_table[(crc ^ *pdata++) & 0xff]; ++ ++ return crc; ++} ++ ++/******************************************************************************* ++ * crc16 ++ * ++ * Computes a crc16 over the input data using the polynomial: ++ * ++ * x^16 + x^12 +x^5 + 1 ++ * ++ * The caller provides the initial value (either CRC16_INIT_VALUE ++ * or the previous returned value) to allow for processing of ++ * discontiguous blocks of data. When generating the CRC the ++ * caller is responsible for complementing the final return value ++ * and inserting it into the byte stream. When checking, a final ++ * return value of CRC16_GOOD_VALUE indicates a valid CRC. ++ * ++ * Reference: Dallas Semiconductor Application Note 27 ++ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", ++ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., ++ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt ++ * ++ ******************************************************************************/ ++ ++static uint16 crc16_table[256] = { ++ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, ++ 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, ++ 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, ++ 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, ++ 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, ++ 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, ++ 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, ++ 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, ++ 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, ++ 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, ++ 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, ++ 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, ++ 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, ++ 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, ++ 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, ++ 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, ++ 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, ++ 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, ++ 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, ++ 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, ++ 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, ++ 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, ++ 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, ++ 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, ++ 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, ++ 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, ++ 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, ++ 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, ++ 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, ++ 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, ++ 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, ++ 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 ++}; ++ ++uint16 ++hndcrc16( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint16 crc /* either CRC16_INIT_VALUE or previous return value */ ++) ++{ ++ while (nbytes-- > 0) ++ CRC_INNER_LOOP(16, crc, *pdata++); ++ return crc; ++} ++ ++static uint32 crc32_table[256] = { ++ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, ++ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, ++ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, ++ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, ++ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, ++ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, ++ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, ++ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, ++ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, ++ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, ++ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, ++ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, ++ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, ++ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, ++ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, ++ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, ++ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, ++ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, ++ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, ++ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, ++ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, ++ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, ++ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, ++ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, ++ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, ++ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, ++ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, ++ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, ++ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, ++ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, ++ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, ++ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, ++ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, ++ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, ++ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, ++ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, ++ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, ++ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, ++ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, ++ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, ++ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, ++ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, ++ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, ++ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, ++ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, ++ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, ++ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, ++ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, ++ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, ++ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, ++ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, ++ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, ++ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, ++ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, ++ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, ++ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, ++ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, ++ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, ++ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, ++ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, ++ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, ++ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, ++ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, ++ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D ++}; ++ ++uint32 ++hndcrc32( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint32 crc /* either CRC32_INIT_VALUE or previous return value */ ++) ++{ ++ uint8 *pend; ++#ifdef __mips__ ++ uint8 tmp[4]; ++ ulong *tptr = (ulong *)tmp; ++ ++ /* in case the beginning of the buffer isn't aligned */ ++ pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); ++ nbytes -= (pend - pdata); ++ while (pdata < pend) ++ CRC_INNER_LOOP(32, crc, *pdata++); ++ ++ /* handle bulk of data as 32-bit words */ ++ pend = pdata + (nbytes & 0xfffffffc); ++ while (pdata < pend) { ++ tptr = *((ulong *) pdata); ++ *((ulong *) pdata) += 1; ++ CRC_INNER_LOOP(32, crc, tmp[0]); ++ CRC_INNER_LOOP(32, crc, tmp[1]); ++ CRC_INNER_LOOP(32, crc, tmp[2]); ++ CRC_INNER_LOOP(32, crc, tmp[3]); ++ } ++ ++ /* 1-3 bytes at end of buffer */ ++ pend = pdata + (nbytes & 0x03); ++ while (pdata < pend) ++ CRC_INNER_LOOP(32, crc, *pdata++); ++#else ++ pend = pdata + nbytes; ++ while (pdata < pend) ++ CRC_INNER_LOOP(32, crc, *pdata++); ++#endif ++ ++ return crc; ++} ++ ++#ifdef notdef ++#define CLEN 1499 ++#define CBUFSIZ (CLEN+4) ++#define CNBUFS 5 ++ ++void testcrc32(void) ++{ ++ uint j,k,l; ++ uint8 *buf; ++ uint len[CNBUFS]; ++ uint32 crcr; ++ uint32 crc32tv[CNBUFS] = ++ {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; ++ ++ ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); ++ ++ /* step through all possible alignments */ ++ for (l=0;l<=4;l++) { ++ for (j=0; jlen; ++ elt = (bcm_tlv_t*)(elt->data + len); ++ *buflen -= (2 + len); ++ ++ /* validate next elt */ ++ if (!bcm_valid_tlv(elt, *buflen)) ++ return NULL; ++ ++ return elt; ++} ++ ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag ++ */ ++bcm_tlv_t * ++bcm_parse_tlvs(void *buf, int buflen, uint key) ++{ ++ bcm_tlv_t *elt; ++ int totlen; ++ ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; ++ ++ /* find tagged parameter */ ++ while (totlen >= 2) { ++ int len = elt->len; ++ ++ /* validate remaining totlen */ ++ if ((elt->id == key) && (totlen >= (len + 2))) ++ return (elt); ++ ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); ++ totlen -= (len + 2); ++ } ++ ++ return NULL; ++} ++ ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag. Stop parsing when we see an element whose ID is greater ++ * than the target key. ++ */ ++bcm_tlv_t * ++bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) ++{ ++ bcm_tlv_t *elt; ++ int totlen; ++ ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; ++ ++ /* find tagged parameter */ ++ while (totlen >= 2) { ++ uint id = elt->id; ++ int len = elt->len; ++ ++ /* Punt if we start seeing IDs > than target key */ ++ if (id > key) ++ return(NULL); ++ ++ /* validate remaining totlen */ ++ if ((id == key) && (totlen >= (len + 2))) ++ return (elt); ++ ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); ++ totlen -= (len + 2); ++ } ++ return NULL; ++} ++/* routine to dump fields in a fileddesc structure */ ++ ++uint ++bcmdumpfields(readreg_rtn read_rtn, void *arg0, void *arg1, struct fielddesc *fielddesc_array, char *buf, uint32 bufsize) ++{ ++ uint filled_len; ++ uint len; ++ struct fielddesc *cur_ptr; ++ ++ filled_len = 0; ++ cur_ptr = fielddesc_array; ++ ++ while (bufsize > (filled_len + 64)) { ++ if (cur_ptr->nameandfmt == NULL) ++ break; ++ len = sprintf(buf, cur_ptr->nameandfmt, read_rtn(arg0, arg1, cur_ptr->offset)); ++ buf += len; ++ filled_len += len; ++ cur_ptr++; ++ } ++ return filled_len; ++} ++ ++uint ++bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) ++{ ++ uint len; ++ ++ len = strlen(name) + 1; ++ ++ if ((len + datalen) > buflen) ++ return 0; ++ ++ strcpy(buf, name); ++ ++ /* append data onto the end of the name string */ ++ memcpy(&buf[len], data, datalen); ++ len += datalen; ++ ++ return len; ++} ++ ++/* Quarter dBm units to mW ++ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 ++ * Table is offset so the last entry is largest mW value that fits in ++ * a uint16. ++ */ ++ ++#define QDBM_OFFSET 153 ++#define QDBM_TABLE_LEN 40 ++ ++/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. ++ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 ++ */ ++#define QDBM_TABLE_LOW_BOUND 6493 ++ ++/* Largest mW value that will round down to the last table entry, ++ * QDBM_OFFSET + QDBM_TABLE_LEN-1. ++ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. ++ */ ++#define QDBM_TABLE_HIGH_BOUND 64938 ++ ++static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { ++/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ ++/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, ++/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, ++/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, ++/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, ++/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 ++}; ++ ++uint16 ++bcm_qdbm_to_mw(uint8 qdbm) ++{ ++ uint factor = 1; ++ int idx = qdbm - QDBM_OFFSET; ++ ++ if (idx > QDBM_TABLE_LEN) { ++ /* clamp to max uint16 mW value */ ++ return 0xFFFF; ++ } ++ ++ /* scale the qdBm index up to the range of the table 0-40 ++ * where an offset of 40 qdBm equals a factor of 10 mW. ++ */ ++ while (idx < 0) { ++ idx += 40; ++ factor *= 10; ++ } ++ ++ /* return the mW value scaled down to the correct factor of 10, ++ * adding in factor/2 to get proper rounding. */ ++ return ((nqdBm_to_mW_map[idx] + factor/2) / factor); ++} ++ ++uint8 ++bcm_mw_to_qdbm(uint16 mw) ++{ ++ uint8 qdbm; ++ int offset; ++ uint mw_uint = mw; ++ uint boundary; ++ ++ /* handle boundary case */ ++ if (mw_uint <= 1) ++ return 0; ++ ++ offset = QDBM_OFFSET; ++ ++ /* move mw into the range of the table */ ++ while (mw_uint < QDBM_TABLE_LOW_BOUND) { ++ mw_uint *= 10; ++ offset -= 40; ++ } ++ ++ for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { ++ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - nqdBm_to_mW_map[qdbm])/2; ++ if (mw_uint < boundary) break; ++ } ++ ++ qdbm += (uint8)offset; ++ ++ return(qdbm); ++} +diff -Nur linux-2.4.32/drivers/net/hnd/hnddma.c linux-2.4.32-brcm/drivers/net/hnd/hnddma.c +--- linux-2.4.32/drivers/net/hnd/hnddma.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/hnddma.c 2005-12-16 23:39:11.288858250 +0100 +@@ -0,0 +1,1527 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA module. ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct dma_info; /* forward declaration */ ++#define di_t struct dma_info ++ ++#include ++#include ++ ++/* debug/trace */ ++#define DMA_ERROR(args) ++#define DMA_TRACE(args) ++ ++/* default dma message level (if input msg_level pointer is null in dma_attach()) */ ++static uint dma_msg_level = ++ 0; ++ ++#define MAXNAMEL 8 ++ ++/* dma engine software state */ ++typedef struct dma_info { ++ hnddma_t hnddma; /* exported structure */ ++ uint *msg_level; /* message level pointer */ ++ char name[MAXNAMEL]; /* callers name for diag msgs */ ++ ++ void *osh; /* os handle */ ++ sb_t *sbh; /* sb handle */ ++ ++ bool dma64; /* dma64 enabled */ ++ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ ++ ++ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ ++ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ ++ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ ++ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ ++ ++ uint32 dma64align; /* either 8k or 4k depends on number of dd */ ++ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ ++ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ ++ uint ntxd; /* # tx descriptors tunable */ ++ uint txin; /* index of next descriptor to reclaim */ ++ uint txout; /* index of next descriptor to post */ ++ uint txavail; /* # free tx descriptors */ ++ void **txp; /* pointer to parallel array of pointers to packets */ ++ ulong txdpa; /* physical address of descriptor ring */ ++ uint txdalign; /* #bytes added to alloc'd mem to align txd */ ++ uint txdalloc; /* #bytes allocated for the ring */ ++ ++ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ ++ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ ++ uint nrxd; /* # rx descriptors tunable */ ++ uint rxin; /* index of next descriptor to reclaim */ ++ uint rxout; /* index of next descriptor to post */ ++ void **rxp; /* pointer to parallel array of pointers to packets */ ++ ulong rxdpa; /* physical address of descriptor ring */ ++ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ ++ uint rxdalloc; /* #bytes allocated for the ring */ ++ ++ /* tunables */ ++ uint rxbufsize; /* rx buffer size in bytes */ ++ uint nrxpost; /* # rx buffers to keep posted */ ++ uint rxoffset; /* rxcontrol offset */ ++ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ ++ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */ ++ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ ++ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */ ++} dma_info_t; ++ ++#ifdef BCMDMA64 ++#define DMA64_ENAB(di) ((di)->dma64) ++#else ++#define DMA64_ENAB(di) (0) ++#endif ++ ++/* descriptor bumping macros */ ++#define XXD(x, n) ((x) & ((n) - 1)) ++#define TXD(x) XXD((x), di->ntxd) ++#define RXD(x) XXD((x), di->nrxd) ++#define NEXTTXD(i) TXD(i + 1) ++#define PREVTXD(i) TXD(i - 1) ++#define NEXTRXD(i) RXD(i + 1) ++#define NTXDACTIVE(h, t) TXD(t - h) ++#define NRXDACTIVE(h, t) RXD(t - h) ++ ++/* macros to convert between byte offsets and indexes */ ++#define B2I(bytes, type) ((bytes) / sizeof(type)) ++#define I2B(index, type) ((index) * sizeof(type)) ++ ++#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ ++#define PCI32ADDR_HIGH_SHIFT 30 ++ ++ ++/* prototypes */ ++static bool dma_isaddrext(dma_info_t *di); ++static bool dma_alloc(dma_info_t *di, uint direction); ++ ++static bool dma32_alloc(dma_info_t *di, uint direction); ++static void dma32_txreset(dma_info_t *di); ++static void dma32_rxreset(dma_info_t *di); ++static bool dma32_txsuspendedidle(dma_info_t *di); ++static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags); ++static void* dma32_getnexttxp(dma_info_t *di, bool forceall); ++static void* dma32_getnextrxp(dma_info_t *di, bool forceall); ++static void dma32_txrotate(di_t *di); ++ ++/* prototype or stubs */ ++#ifdef BCMDMA64 ++static bool dma64_alloc(dma_info_t *di, uint direction); ++static void dma64_txreset(dma_info_t *di); ++static void dma64_rxreset(dma_info_t *di); ++static bool dma64_txsuspendedidle(dma_info_t *di); ++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags); ++static void* dma64_getnexttxp(dma_info_t *di, bool forceall); ++static void* dma64_getnextrxp(dma_info_t *di, bool forceall); ++static void dma64_txrotate(di_t *di); ++#else ++static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; } ++static void dma64_txreset(dma_info_t *di) {} ++static void dma64_rxreset(dma_info_t *di) {} ++static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;} ++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; } ++static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; } ++static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; } ++static void dma64_txrotate(di_t *di) { return; } ++#endif ++ ++/* old dmaregs struct for compatibility */ ++typedef volatile struct { ++ /* transmit channel */ ++ uint32 xmtcontrol; /* enable, et al */ ++ uint32 xmtaddr; /* descriptor ring base address (4K aligned) */ ++ uint32 xmtptr; /* last descriptor posted to chip */ ++ uint32 xmtstatus; /* current active descriptor, et al */ ++ ++ /* receive channel */ ++ uint32 rcvcontrol; /* enable, et al */ ++ uint32 rcvaddr; /* descriptor ring base address (4K aligned) */ ++ uint32 rcvptr; /* last descriptor posted to chip */ ++ uint32 rcvstatus; /* current active descriptor, et al */ ++} dmaregs_t; ++ ++typedef struct { ++ uint ddoffset; ++ uint dataoffset; ++} compat_data; ++ ++static compat_data *ugly_hack = NULL; ++ ++void* ++dma_attold(void *drv, void *osh, char *name, dmaregs_t *regs, uint ntxd, uint nrxd, ++ uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level) ++{ ++ dma32regs_t *dtx = regs; ++ dma32regs_t *drx = dtx + 1; ++ ++ ugly_hack = kmalloc(sizeof(ugly_hack), GFP_KERNEL); ++ ugly_hack->ddoffset = ddoffset; ++ ugly_hack->dataoffset = dataoffset; ++ dma_attach((osl_t *) osh, name, NULL, dtx, drx, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, msg_level); ++ ugly_hack = NULL; ++} ++ ++ ++void* ++dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) ++{ ++ dma_info_t *di; ++ uint size; ++ ++ /* allocate private info structure */ ++ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { ++ return (NULL); ++ } ++ bzero((char*)di, sizeof (dma_info_t)); ++ ++ di->msg_level = msg_level ? msg_level : &dma_msg_level; ++ ++ if (sbh != NULL) ++ di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64); ++ ++#ifndef BCMDMA64 ++ if (di->dma64) { ++ DMA_ERROR(("dma_attach: driver doesn't have the capability to support 64 bits DMA\n")); ++ goto fail; ++ } ++#endif ++ ++ /* check arguments */ ++ ASSERT(ISPOWEROF2(ntxd)); ++ ASSERT(ISPOWEROF2(nrxd)); ++ if (nrxd == 0) ++ ASSERT(dmaregsrx == NULL); ++ if (ntxd == 0) ++ ASSERT(dmaregstx == NULL); ++ ++ ++ /* init dma reg pointer */ ++ if (di->dma64) { ++ ASSERT(ntxd <= D64MAXDD); ++ ASSERT(nrxd <= D64MAXDD); ++ di->d64txregs = (dma64regs_t *)dmaregstx; ++ di->d64rxregs = (dma64regs_t *)dmaregsrx; ++ ++ di->dma64align = D64RINGALIGN; ++ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { ++ /* for smaller dd table, HW relax the alignment requirement */ ++ di->dma64align = D64RINGALIGN / 2; ++ } ++ } else { ++ ASSERT(ntxd <= D32MAXDD); ++ ASSERT(nrxd <= D32MAXDD); ++ di->d32txregs = (dma32regs_t *)dmaregstx; ++ di->d32rxregs = (dma32regs_t *)dmaregsrx; ++ } ++ ++ ++ /* make a private copy of our callers name */ ++ strncpy(di->name, name, MAXNAMEL); ++ di->name[MAXNAMEL-1] = '\0'; ++ ++ di->osh = osh; ++ di->sbh = sbh; ++ ++ /* save tunables */ ++ di->ntxd = ntxd; ++ di->nrxd = nrxd; ++ di->rxbufsize = rxbufsize; ++ di->nrxpost = nrxpost; ++ di->rxoffset = rxoffset; ++ ++ /* ++ * figure out the DMA physical address offset for dd and data ++ * for old chips w/o sb, use zero ++ * for new chips w sb, ++ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset ++ * Other bus: use zero ++ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor ++ */ ++ di->ddoffsetlow = 0; ++ di->dataoffsetlow = 0; ++ if (ugly_hack != NULL) { ++ di->ddoffsetlow = ugly_hack->ddoffset; ++ di->dataoffsetlow = ugly_hack->dataoffset; ++ di->ddoffsethigh = 0; ++ di->dataoffsethigh = 0; ++ } else if (sbh != NULL) { ++ if (sbh->bustype == PCI_BUS) { /* for pci bus, add offset */ ++ if ((sbh->buscoretype == SB_PCIE) && di->dma64){ ++ di->ddoffsetlow = 0; ++ di->ddoffsethigh = SB_PCIE_DMA_H32; ++ } else { ++ di->ddoffsetlow = SB_PCI_DMA; ++ di->ddoffsethigh = 0; ++ } ++ di->dataoffsetlow = di->ddoffsetlow; ++ di->dataoffsethigh = di->ddoffsethigh; ++ } ++#if defined(__mips__) && defined(IL_BIGENDIAN) ++ /* use sdram swapped region for data buffers but not dma descriptors */ ++ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; ++#endif ++ } ++ ++ di->addrext = ((ugly_hack == NULL) ? dma_isaddrext(di) : 0); ++ ++ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", ++ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow)); ++ ++ /* allocate tx packet pointer vector */ ++ if (ntxd) { ++ size = ntxd * sizeof (void*); ++ if ((di->txp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero((char*)di->txp, size); ++ } ++ ++ /* allocate rx packet pointer vector */ ++ if (nrxd) { ++ size = nrxd * sizeof (void*); ++ if ((di->rxp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero((char*)di->rxp, size); ++ } ++ ++ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ ++ if (ntxd) { ++ if (!dma_alloc(di, DMA_TX)) ++ goto fail; ++ } ++ ++ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ ++ if (nrxd) { ++ if (!dma_alloc(di, DMA_RX)) ++ goto fail; ++ } ++ ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa)); ++ goto fail; ++ } ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa)); ++ goto fail; ++ } ++ ++ return ((void*)di); ++ ++fail: ++ dma_detach((void*)di); ++ return (NULL); ++} ++ ++static bool ++dma_alloc(dma_info_t *di, uint direction) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_alloc(di, direction); ++ } else { ++ return dma32_alloc(di, direction); ++ } ++} ++ ++/* may be called with core in reset */ ++void ++dma_detach(dma_info_t *di) ++{ ++ if (di == NULL) ++ return; ++ ++ DMA_TRACE(("%s: dma_detach\n", di->name)); ++ ++ /* shouldn't be here if descriptors are unreclaimed */ ++ ASSERT(di->txin == di->txout); ++ ASSERT(di->rxin == di->rxout); ++ ++ /* free dma descriptor rings */ ++ if (di->txd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign)); ++ if (di->rxd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign)); ++ ++ /* free packet pointer vectors */ ++ if (di->txp) ++ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*))); ++ if (di->rxp) ++ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*))); ++ ++ /* free our private info structure */ ++ MFREE(di->osh, (void*)di, sizeof (dma_info_t)); ++} ++ ++/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ ++static bool ++dma_isaddrext(dma_info_t *di) ++{ ++ uint32 w; ++ ++ if (DMA64_ENAB(di)) { ++ OR_REG(&di->d64txregs->control, D64_XC_AE); ++ w = R_REG(&di->d32txregs->control); ++ AND_REG(&di->d32txregs->control, ~D64_XC_AE); ++ return ((w & XC_AE) == D64_XC_AE); ++ } else { ++ OR_REG(&di->d32txregs->control, XC_AE); ++ w = R_REG(&di->d32txregs->control); ++ AND_REG(&di->d32txregs->control, ~XC_AE); ++ return ((w & XC_AE) == XC_AE); ++ } ++} ++ ++void ++dma_txreset(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txreset\n", di->name)); ++ ++ if (DMA64_ENAB(di)) ++ dma64_txreset(di); ++ else ++ dma32_txreset(di); ++} ++ ++void ++dma_rxreset(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxreset\n", di->name)); ++ ++ if (DMA64_ENAB(di)) ++ dma64_rxreset(di); ++ else ++ dma32_rxreset(di); ++} ++ ++/* initialize descriptor table base address */ ++static void ++dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) ++{ ++ if (DMA64_ENAB(di)) { ++ if (direction == DMA_TX) { ++ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow); ++ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); ++ } else { ++ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow); ++ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); ++ } ++ } else { ++ uint32 offset = di->ddoffsetlow; ++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ if (direction == DMA_TX) ++ W_REG(&di->d32txregs->addr, (pa + offset)); ++ else ++ W_REG(&di->d32rxregs->addr, (pa + offset)); ++ } else { ++ /* dma32 address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ ++ if (direction == DMA_TX) { ++ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); ++ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT)); ++ } else { ++ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); ++ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT)); ++ } ++ } ++ } ++} ++ ++/* init the tx or rx descriptor */ ++static INLINE void ++dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl) ++{ ++ uint offset = di->dataoffsetlow; ++ ++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); ++ } else { ++ /* address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ ++ *ctrl |= (ae << CTRL_AE_SHIFT); ++ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); ++ } ++} ++ ++/* init the tx or rx descriptor */ ++static INLINE void ++dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount) ++{ ++ uint32 bufaddr_low = pa + di->dataoffsetlow; ++ uint32 bufaddr_high = 0 + di->dataoffsethigh; ++ ++ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; ++ ++ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low)); ++ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high)); ++ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); ++ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); ++} ++ ++void ++dma_txinit(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txinit\n", di->name)); ++ ++ di->txin = di->txout = 0; ++ di->txavail = di->ntxd - 1; ++ ++ /* clear tx descriptor ring */ ++ if (DMA64_ENAB(di)) { ++ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t))); ++ W_REG(&di->d64txregs->control, XC_XE); ++ dma_ddtable_init(di, DMA_TX, di->txdpa); ++ } else { ++ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t))); ++ W_REG(&di->d32txregs->control, XC_XE); ++ dma_ddtable_init(di, DMA_TX, di->txdpa); ++ } ++} ++ ++bool ++dma_txenabled(dma_info_t *di) ++{ ++ uint32 xc; ++ ++ /* If the chip is dead, it is not enabled :-) */ ++ if (DMA64_ENAB(di)) { ++ xc = R_REG(&di->d64txregs->control); ++ return ((xc != 0xffffffff) && (xc & D64_XC_XE)); ++ } else { ++ xc = R_REG(&di->d32txregs->control); ++ return ((xc != 0xffffffff) && (xc & XC_XE)); ++ } ++} ++ ++void ++dma_txsuspend(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); ++ if (DMA64_ENAB(di)) ++ OR_REG(&di->d64txregs->control, D64_XC_SE); ++ else ++ OR_REG(&di->d32txregs->control, XC_SE); ++} ++ ++void ++dma_txresume(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txresume\n", di->name)); ++ if (DMA64_ENAB(di)) ++ AND_REG(&di->d64txregs->control, ~D64_XC_SE); ++ else ++ AND_REG(&di->d32txregs->control, ~XC_SE); ++} ++ ++bool ++dma_txsuspendedidle(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return dma64_txsuspendedidle(di); ++ else ++ return dma32_txsuspendedidle(di); ++} ++ ++bool ++dma_txsuspended(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); ++ else ++ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE); ++} ++ ++bool ++dma_txstopped(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); ++ else ++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); ++} ++ ++bool ++dma_rxstopped(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); ++ else ++ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); ++} ++ ++void ++dma_fifoloopbackenable(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); ++ if (DMA64_ENAB(di)) ++ OR_REG(&di->d64txregs->control, D64_XC_LE); ++ else ++ OR_REG(&di->d32txregs->control, XC_LE); ++} ++ ++void ++dma_rxinit(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxinit\n", di->name)); ++ ++ di->rxin = di->rxout = 0; ++ ++ /* clear rx descriptor ring */ ++ if (DMA64_ENAB(di)) { ++ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t))); ++ dma_rxenable(di); ++ dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ } else { ++ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t))); ++ dma_rxenable(di); ++ dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ } ++} ++ ++void ++dma_rxenable(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxenable\n", di->name)); ++ if (DMA64_ENAB(di)) ++ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE)); ++ else ++ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); ++} ++ ++bool ++dma_rxenabled(dma_info_t *di) ++{ ++ uint32 rc; ++ ++ if (DMA64_ENAB(di)) { ++ rc = R_REG(&di->d64rxregs->control); ++ return ((rc != 0xffffffff) && (rc & D64_RC_RE)); ++ } else { ++ rc = R_REG(&di->d32rxregs->control); ++ return ((rc != 0xffffffff) && (rc & RC_RE)); ++ } ++} ++ ++ ++/* !! tx entry routine */ ++int ++dma_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_txfast(di, p0, coreflags); ++ } else { ++ return dma32_txfast(di, p0, coreflags); ++ } ++} ++ ++/* !! rx entry routine, returns a pointer to the next frame received, or NULL if there are no more */ ++void* ++dma_rx(dma_info_t *di) ++{ ++ void *p; ++ uint len; ++ int skiplen = 0; ++ ++ while ((p = dma_getnextrxp(di, FALSE))) { ++ /* skip giant packets which span multiple rx descriptors */ ++ if (skiplen > 0) { ++ skiplen -= di->rxbufsize; ++ if (skiplen < 0) ++ skiplen = 0; ++ PKTFREE(di->osh, p, FALSE); ++ continue; ++ } ++ ++ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); ++ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); ++ ++ /* bad frame length check */ ++ if (len > (di->rxbufsize - di->rxoffset)) { ++ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); ++ if (len > 0) ++ skiplen = len - (di->rxbufsize - di->rxoffset); ++ PKTFREE(di->osh, p, FALSE); ++ di->hnddma.rxgiants++; ++ continue; ++ } ++ ++ /* set actual length */ ++ PKTSETLEN(di->osh, p, (di->rxoffset + len)); ++ ++ break; ++ } ++ ++ return (p); ++} ++ ++/* post receive buffers */ ++void ++dma_rxfill(dma_info_t *di) ++{ ++ void *p; ++ uint rxin, rxout; ++ uint32 ctrl; ++ uint n; ++ uint i; ++ uint32 pa; ++ uint rxbufsize; ++ ++ /* ++ * Determine how many receive buffers we're lacking ++ * from the full complement, allocate, initialize, ++ * and post them, then update the chip rx lastdscr. ++ */ ++ ++ rxin = di->rxin; ++ rxout = di->rxout; ++ rxbufsize = di->rxbufsize; ++ ++ n = di->nrxpost - NRXDACTIVE(rxin, rxout); ++ ++ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); ++ ++ for (i = 0; i < n; i++) { ++ if ((p = PKTGET(di->osh, rxbufsize, FALSE)) == NULL) { ++ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); ++ di->hnddma.rxnobuf++; ++ break; ++ } ++ ++ /* Do a cached write instead of uncached write since DMA_MAP ++ * will flush the cache. */ ++ *(uint32*)(PKTDATA(di->osh, p)) = 0; ++ ++ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p); ++ ASSERT(ISALIGNED(pa, 4)); ++ ++ /* save the free packet pointer */ ++ ASSERT(di->rxp[rxout] == NULL); ++ di->rxp[rxout] = p; ++ ++ if (DMA64_ENAB(di)) { ++ /* prep the descriptor control value */ ++ if (rxout == (di->nrxd - 1)) ++ ctrl = CTRL_EOT; ++ ++ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize); ++ } else { ++ /* prep the descriptor control value */ ++ ctrl = rxbufsize; ++ if (rxout == (di->nrxd - 1)) ++ ctrl |= CTRL_EOT; ++ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl); ++ } ++ ++ rxout = NEXTRXD(rxout); ++ } ++ ++ di->rxout = rxout; ++ ++ /* update the chip lastdscr pointer */ ++ if (DMA64_ENAB(di)) { ++ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t)); ++ } else { ++ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); ++ } ++} ++ ++void ++dma_txreclaim(dma_info_t *di, bool forceall) ++{ ++ void *p; ++ ++ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); ++ ++ while ((p = dma_getnexttxp(di, forceall))) ++ PKTFREE(di->osh, p, TRUE); ++} ++ ++/* ++ * Reclaim next completed txd (txds if using chained buffers) and ++ * return associated packet. ++ * If 'force' is true, reclaim txd(s) and return associated packet ++ * regardless of the value of the hardware "curr" pointer. ++ */ ++void* ++dma_getnexttxp(dma_info_t *di, bool forceall) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_getnexttxp(di, forceall); ++ } else { ++ return dma32_getnexttxp(di, forceall); ++ } ++} ++ ++/* like getnexttxp but no reclaim */ ++void* ++dma_peeknexttxp(dma_info_t *di) ++{ ++ uint end, i; ++ ++ if (DMA64_ENAB(di)) { ++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ } else { ++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ } ++ ++ for (i = di->txin; i != end; i = NEXTTXD(i)) ++ if (di->txp[i]) ++ return (di->txp[i]); ++ ++ return (NULL); ++} ++ ++/* ++ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). ++ */ ++void ++dma_txrotate(di_t *di) ++{ ++ if (DMA64_ENAB(di)) { ++ dma64_txrotate(di); ++ } else { ++ dma32_txrotate(di); ++ } ++} ++ ++void ++dma_rxreclaim(dma_info_t *di) ++{ ++ void *p; ++ ++ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); ++ ++ while ((p = dma_getnextrxp(di, TRUE))) ++ PKTFREE(di->osh, p, FALSE); ++} ++ ++void * ++dma_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_getnextrxp(di, forceall); ++ } else { ++ return dma32_getnextrxp(di, forceall); ++ } ++} ++ ++uintptr ++dma_getvar(dma_info_t *di, char *name) ++{ ++ if (!strcmp(name, "&txavail")) ++ return ((uintptr) &di->txavail); ++ else { ++ ASSERT(0); ++ } ++ return (0); ++} ++ ++void ++dma_txblock(dma_info_t *di) ++{ ++ di->txavail = 0; ++} ++ ++void ++dma_txunblock(dma_info_t *di) ++{ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++} ++ ++uint ++dma_txactive(dma_info_t *di) ++{ ++ return (NTXDACTIVE(di->txin, di->txout)); ++} ++ ++void ++dma_rxpiomode(dma32regs_t *regs) ++{ ++ W_REG(®s->control, RC_FM); ++} ++ ++void ++dma_txpioloopback(dma32regs_t *regs) ++{ ++ OR_REG(®s->control, XC_LE); ++} ++ ++ ++ ++ ++/*** 32 bits DMA non-inline functions ***/ ++static bool ++dma32_alloc(dma_info_t *di, uint direction) ++{ ++ uint size; ++ uint ddlen; ++ void *va; ++ ++ ddlen = sizeof (dma32dd_t); ++ ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) ++ size += D32RINGALIGN; ++ ++ ++ if (direction == DMA_TX) { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); ++ return FALSE; ++ } ++ ++ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); ++ di->txdpa += di->txdalign; ++ di->txdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); ++ } else { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); ++ return FALSE; ++ } ++ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); ++ di->rxdpa += di->rxdalign; ++ di->rxdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); ++ } ++ ++ return TRUE; ++} ++ ++static void ++dma32_txreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ /* suspend tx DMA first */ ++ W_REG(&di->d32txregs->control, XC_SE); ++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED && ++ status != XS_XS_IDLE && ++ status != XS_XS_STOPPED, ++ 10000); ++ ++ W_REG(&di->d32txregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED, ++ 10000); ++ ++ if (status != XS_XS_DISABLED) { ++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); ++ } ++ ++ /* wait for the last transaction to complete */ ++ OSL_DELAY(300); ++} ++ ++static void ++dma32_rxreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ W_REG(&di->d32rxregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED, ++ 10000); ++ ++ if (status != RS_RS_DISABLED) { ++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); ++ } ++} ++ ++static bool ++dma32_txsuspendedidle(dma_info_t *di) ++{ ++ if (!(R_REG(&di->d32txregs->control) & XC_SE)) ++ return 0; ++ ++ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) ++ return 0; ++ ++ OSL_DELAY(2); ++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); ++} ++ ++/* ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ */ ++static int ++dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++{ ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint txout; ++ uint32 ctrl; ++ uint32 pa; ++ ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ ++ txout = di->txout; ++ ctrl = 0; ++ ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++ next = PKTNEXT(di->osh, p); ++ ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) ++ goto outoftxd; ++ ++ if (len == 0) ++ continue; ++ ++ /* get physical address of buffer start */ ++ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ ++ /* build the descriptor control value */ ++ ctrl = len & CTRL_BC_MASK; ++ ++ ctrl |= coreflags; ++ ++ if (p == p0) ++ ctrl |= CTRL_SOF; ++ if (next == NULL) ++ ctrl |= (CTRL_IOC | CTRL_EOF); ++ if (txout == (di->ntxd - 1)) ++ ctrl |= CTRL_EOT; ++ ++ if (DMA64_ENAB(di)) { ++ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len); ++ } else { ++ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl); ++ } ++ ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); ++ } ++ ++ /* if last txd eof not set, fix it */ ++ if (!(ctrl & CTRL_EOF)) ++ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF)); ++ ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; ++ ++ /* bump the tx descriptor index */ ++ di->txout = txout; ++ ++ /* kick the chip */ ++ if (DMA64_ENAB(di)) { ++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); ++ } else { ++ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t)); ++ } ++ ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (0); ++ ++ outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); ++} ++ ++static void* ++dma32_getnexttxp(dma_info_t *di, bool forceall) ++{ ++ uint start, end, i; ++ void *txp; ++ ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); ++ ++ txp = NULL; ++ ++ start = di->txin; ++ if (forceall) ++ end = di->txout; ++ else ++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ ++ if ((start == 0) && (end > di->txout)) ++ goto bogus; ++ ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), ++ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]); ++ ++ W_SM(&di->txd32[i].addr, 0xdeadbeef); ++ txp = di->txp[i]; ++ di->txp[i] = NULL; ++ } ++ ++ di->txin = i; ++ ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (txp); ++ ++bogus: ++/* ++ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++*/ ++ return (NULL); ++} ++ ++static void * ++dma32_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ uint i; ++ void *rxp; ++ ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma_rxenabled(di)); ++ ++ i = di->rxin; ++ ++ /* return if no packets posted */ ++ if (i == di->rxout) ++ return (NULL); ++ ++ /* ignore curr if forceall */ ++ if (!forceall && (i == B2I(R_REG(&di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) ++ return (NULL); ++ ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; ++ ++ /* clear this packet from the descriptor ring */ ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), ++ di->rxbufsize, DMA_RX, rxp); ++ W_SM(&di->rxd32[i].addr, 0xdeadbeef); ++ ++ di->rxin = NEXTRXD(i); ++ ++ return (rxp); ++} ++ ++static void ++dma32_txrotate(di_t *di) ++{ ++ uint ad; ++ uint nactive; ++ uint rot; ++ uint old, new; ++ uint32 w; ++ uint first, last; ++ ++ ASSERT(dma_txsuspendedidle(di)); ++ ++ nactive = dma_txactive(di); ++ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); ++ rot = TXD(ad - di->txin); ++ ++ ASSERT(rot < di->ntxd); ++ ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } ++ ++ first = di->txin; ++ last = PREVTXD(di->txout); ++ ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); ++ ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = R_SM(&di->txd32[old].ctrl) & ~CTRL_EOT; ++ if (new == (di->ntxd - 1)) ++ w |= CTRL_EOT; ++ W_SM(&di->txd32[new].ctrl, w); ++ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); ++ ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd32[old].addr, 0xdeadbeef); ++ ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ di->txp[old] = NULL; ++ } ++ ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ /* kick the chip */ ++ W_REG(&di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); ++} ++ ++/*** 64 bits DMA non-inline functions ***/ ++ ++#ifdef BCMDMA64 ++ ++static bool ++dma64_alloc(dma_info_t *di, uint direction) ++{ ++ uint size; ++ uint ddlen; ++ uint32 alignbytes; ++ void *va; ++ ++ ddlen = sizeof (dma64dd_t); ++ ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ ++ alignbytes = di->dma64align; ++ ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes)) ++ size += alignbytes; ++ ++ ++ if (direction == DMA_TX) { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); ++ return FALSE; ++ } ++ ++ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); ++ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va); ++ di->txdpa += di->txdalign; ++ di->txdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes)); ++ } else { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); ++ return FALSE; ++ } ++ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); ++ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va); ++ di->rxdpa += di->rxdalign; ++ di->rxdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes)); ++ } ++ ++ return TRUE; ++} ++ ++static void ++dma64_txreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ /* suspend tx DMA first */ ++ W_REG(&di->d64txregs->control, D64_XC_SE); ++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED && ++ status != D64_XS0_XS_IDLE && ++ status != D64_XS0_XS_STOPPED, ++ 10000); ++ ++ W_REG(&di->d64txregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED, ++ 10000); ++ ++ if (status != D64_XS0_XS_DISABLED) { ++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); ++ } ++ ++ /* wait for the last transaction to complete */ ++ OSL_DELAY(300); ++} ++ ++static void ++dma64_rxreset(dma_info_t *di) ++{ ++ uint32 status; ++ ++ W_REG(&di->d64rxregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED, ++ 10000); ++ ++ if (status != D64_RS0_RS_DISABLED) { ++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); ++ } ++} ++ ++static bool ++dma64_txsuspendedidle(dma_info_t *di) ++{ ++ ++ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE)) ++ return 0; ++ ++ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) ++ return 1; ++ ++ return 0; ++} ++ ++/* ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ */ ++static int ++dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++{ ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint txout; ++ uint32 flags; ++ uint32 pa; ++ ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ ++ txout = di->txout; ++ flags = 0; ++ ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++ next = PKTNEXT(di->osh, p); ++ ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) ++ goto outoftxd; ++ ++ if (len == 0) ++ continue; ++ ++ /* get physical address of buffer start */ ++ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ ++ flags = coreflags; ++ ++ if (p == p0) ++ flags |= D64_CTRL1_SOF; ++ if (next == NULL) ++ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); ++ if (txout == (di->ntxd - 1)) ++ flags |= D64_CTRL1_EOT; ++ ++ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); ++ ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); ++ } ++ ++ /* if last txd eof not set, fix it */ ++ if (!(flags & D64_CTRL1_EOF)) ++ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); ++ ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; ++ ++ /* bump the tx descriptor index */ ++ di->txout = txout; ++ ++ /* kick the chip */ ++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); ++ ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (0); ++ ++outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); ++} ++ ++static void* ++dma64_getnexttxp(dma_info_t *di, bool forceall) ++{ ++ uint start, end, i; ++ void *txp; ++ ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); ++ ++ txp = NULL; ++ ++ start = di->txin; ++ if (forceall) ++ end = di->txout; ++ else ++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ ++ if ((start == 0) && (end > di->txout)) ++ goto bogus; ++ ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow), ++ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]); ++ ++ W_SM(&di->txd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); ++ ++ txp = di->txp[i]; ++ di->txp[i] = NULL; ++ } ++ ++ di->txin = i; ++ ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (txp); ++ ++bogus: ++/* ++ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++*/ ++ return (NULL); ++} ++ ++static void * ++dma64_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ uint i; ++ void *rxp; ++ ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma_rxenabled(di)); ++ ++ i = di->rxin; ++ ++ /* return if no packets posted */ ++ if (i == di->rxout) ++ return (NULL); ++ ++ /* ignore curr if forceall */ ++ if (!forceall && (i == B2I(R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t))) ++ return (NULL); ++ ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; ++ ++ /* clear this packet from the descriptor ring */ ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow), ++ di->rxbufsize, DMA_RX, rxp); ++ ++ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); ++ ++ di->rxin = NEXTRXD(i); ++ ++ return (rxp); ++} ++ ++static void ++dma64_txrotate(di_t *di) ++{ ++ uint ad; ++ uint nactive; ++ uint rot; ++ uint old, new; ++ uint32 w; ++ uint first, last; ++ ++ ASSERT(dma_txsuspendedidle(di)); ++ ++ nactive = dma_txactive(di); ++ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t); ++ rot = TXD(ad - di->txin); ++ ++ ASSERT(rot < di->ntxd); ++ ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } ++ ++ first = di->txin; ++ last = PREVTXD(di->txout); ++ ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); ++ ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = R_SM(&di->txd64[old].ctrl1) & ~D64_CTRL1_EOT; ++ if (new == (di->ntxd - 1)) ++ w |= D64_CTRL1_EOT; ++ W_SM(&di->txd64[new].ctrl1, w); ++ ++ w = R_SM(&di->txd64[old].ctrl2); ++ W_SM(&di->txd64[new].ctrl2, w); ++ ++ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); ++ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); ++ ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd64[old].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[old].addrhigh, 0xdeadbeef); ++ ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ di->txp[old] = NULL; ++ } ++ ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ /* kick the chip */ ++ W_REG(&di->d64txregs->ptr, I2B(di->txout, dma64dd_t)); ++} ++ ++#endif ++ +diff -Nur linux-2.4.32/drivers/net/hnd/linux_osl.c linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c +--- linux-2.4.32/drivers/net/hnd/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c 2005-12-16 23:39:11.292858500 +0100 +@@ -0,0 +1,708 @@ ++/* ++ * Linux OS Independent Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#define LINUX_OSL ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef mips ++#include ++#endif ++#include ++ ++#define PCI_CFG_RETRY 10 ++ ++#define OS_HANDLE_MAGIC 0x1234abcd ++#define BCM_MEM_FILENAME_LEN 24 ++ ++typedef struct bcm_mem_link { ++ struct bcm_mem_link *prev; ++ struct bcm_mem_link *next; ++ uint size; ++ int line; ++ char file[BCM_MEM_FILENAME_LEN]; ++} bcm_mem_link_t; ++ ++struct os_handle { ++ uint magic; ++ void *pdev; ++ uint malloced; ++ uint failed; ++ bcm_mem_link_t *dbgmem_list; ++}; ++ ++static int16 linuxbcmerrormap[] = \ ++{ 0, /* 0 */ ++ -EINVAL, /* BCME_ERROR */ ++ -EINVAL, /* BCME_BADARG*/ ++ -EINVAL, /* BCME_BADOPTION*/ ++ -EINVAL, /* BCME_NOTUP */ ++ -EINVAL, /* BCME_NOTDOWN */ ++ -EINVAL, /* BCME_NOTAP */ ++ -EINVAL, /* BCME_NOTSTA */ ++ -EINVAL, /* BCME_BADKEYIDX */ ++ -EINVAL, /* BCME_RADIOOFF */ ++ -EINVAL, /* BCME_NOTBANDLOCKED */ ++ -EINVAL, /* BCME_NOCLK */ ++ -EINVAL, /* BCME_BADRATESET */ ++ -EINVAL, /* BCME_BADBAND */ ++ -E2BIG, /* BCME_BUFTOOSHORT */ ++ -E2BIG, /* BCME_BUFTOOLONG */ ++ -EBUSY, /* BCME_BUSY */ ++ -EINVAL, /* BCME_NOTASSOCIATED */ ++ -EINVAL, /* BCME_BADSSIDLEN */ ++ -EINVAL, /* BCME_OUTOFRANGECHAN */ ++ -EINVAL, /* BCME_BADCHAN */ ++ -EFAULT, /* BCME_BADADDR */ ++ -ENOMEM, /* BCME_NORESOURCE */ ++ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ ++ -EMSGSIZE, /* BCME_BADLENGTH */ ++ -EINVAL, /* BCME_NOTREADY */ ++ -EPERM, /* BCME_NOTPERMITTED */ ++ -ENOMEM, /* BCME_NOMEM */ ++ -EINVAL, /* BCME_ASSOCIATED */ ++ -ERANGE, /* BCME_RANGE */ ++ -EINVAL /* BCME_NOTFOUND */ ++}; ++ ++/* translate bcmerrors into linux errors*/ ++int ++osl_error(int bcmerror) ++{ ++ int abs_bcmerror; ++ int array_size = ARRAYSIZE(linuxbcmerrormap); ++ ++ abs_bcmerror = ABS(bcmerror); ++ ++ if (bcmerror > 0) ++ abs_bcmerror = 0; ++ ++ else if (abs_bcmerror >= array_size) ++ abs_bcmerror = BCME_ERROR; ++ ++ return linuxbcmerrormap[abs_bcmerror]; ++} ++ ++osl_t * ++osl_attach(void *pdev) ++{ ++ osl_t *osh; ++ ++ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); ++ ASSERT(osh); ++ ++ /* ++ * check the cases where ++ * 1.Error code Added to bcmerror table, but forgot to add it to the OS ++ * dependent error code ++ * 2. Error code is added to the bcmerror table, but forgot to add the ++ * corresponding errorstring(dummy call to bcmerrorstr) ++ */ ++ bcmerrorstr(0); ++ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); ++ ++ osh->magic = OS_HANDLE_MAGIC; ++ osh->malloced = 0; ++ osh->failed = 0; ++ osh->dbgmem_list = NULL; ++ osh->pdev = pdev; ++ ++ return osh; ++} ++ ++void ++osl_detach(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC)); ++ kfree(osh); ++} ++ ++void* ++osl_pktget(osl_t *osh, uint len, bool send) ++{ ++ struct sk_buff *skb; ++ ++ if ((skb = dev_alloc_skb(len)) == NULL) ++ return (NULL); ++ ++ skb_put(skb, len); ++ ++ /* ensure the cookie field is cleared */ ++ PKTSETCOOKIE(skb, NULL); ++ ++ return ((void*) skb); ++} ++ ++void ++osl_pktfree(void *p) ++{ ++ struct sk_buff *skb, *nskb; ++ ++ skb = (struct sk_buff*) p; ++ ++ /* perversion: we use skb->next to chain multi-skb packets */ ++ while (skb) { ++ nskb = skb->next; ++ skb->next = NULL; ++ if (skb->destructor) { ++ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ ++ dev_kfree_skb_any(skb); ++ } else { ++ /* can free immediately (even in_irq()) if destructor does not exist */ ++ dev_kfree_skb(skb); ++ } ++ skb = nskb; ++ } ++} ++ ++uint32 ++osl_pci_read_config(osl_t *osh, uint offset, uint size) ++{ ++ uint val; ++ uint retry=PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_read_config_dword(osh->pdev, offset, &val); ++ if (val != 0xffffffff) ++ break; ++ } while (retry--); ++ ++ ++ return (val); ++} ++ ++void ++osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) ++{ ++ uint retry=PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_write_config_dword(osh->pdev, offset, val); ++ if (offset!=PCI_BAR0_WIN) ++ break; ++ if (osl_pci_read_config(osh,offset,size) == val) ++ break; ++ } while (retry--); ++ ++} ++ ++/* return bus # for the pci device pointed by osh->pdev */ ++uint ++osl_pci_bus(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ ++ return ((struct pci_dev *)osh->pdev)->bus->number; ++} ++ ++/* return slot # for the pci device pointed by osh->pdev */ ++uint ++osl_pci_slot(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ ++ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); ++} ++ ++static void ++osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) ++{ ++} ++ ++void ++osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) ++{ ++ osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); ++} ++ ++void ++osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) ++{ ++ osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); ++} ++ ++ ++#ifdef BCMDBG_MEM ++ ++void* ++osl_debug_malloc(osl_t *osh, uint size, int line, char* file) ++{ ++ bcm_mem_link_t *p; ++ char* basename; ++ ++ ASSERT(size); ++ ++ if ((p = (bcm_mem_link_t*)osl_malloc(osh, sizeof(bcm_mem_link_t) + size)) == NULL) ++ return (NULL); ++ ++ p->size = size; ++ p->line = line; ++ ++ basename = strrchr(file, '/'); ++ /* skip the '/' */ ++ if (basename) ++ basename++; ++ ++ if (!basename) ++ basename = file; ++ ++ strncpy(p->file, basename, BCM_MEM_FILENAME_LEN); ++ p->file[BCM_MEM_FILENAME_LEN - 1] = '\0'; ++ ++ /* link this block */ ++ p->prev = NULL; ++ p->next = osh->dbgmem_list; ++ if (p->next) ++ p->next->prev = p; ++ osh->dbgmem_list = p; ++ ++ return p + 1; ++} ++ ++void ++osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file) ++{ ++ bcm_mem_link_t *p = (bcm_mem_link_t *)((int8*)addr - sizeof(bcm_mem_link_t)); ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ if (p->size == 0) { ++ printk("osl_debug_mfree: double free on addr 0x%x size %d at line %d file %s\n", ++ (uint)addr, size, line, file); ++ ASSERT(p->size); ++ return; ++ } ++ ++ if (p->size != size) { ++ printk("osl_debug_mfree: dealloc size %d does not match alloc size %d on addr 0x%x at line %d file %s\n", ++ size, p->size, (uint)addr, line, file); ++ ASSERT(p->size == size); ++ return; ++ } ++ ++ /* unlink this block */ ++ if (p->prev) ++ p->prev->next = p->next; ++ if (p->next) ++ p->next->prev = p->prev; ++ if (osh->dbgmem_list == p) ++ osh->dbgmem_list = p->next; ++ p->next = p->prev = NULL; ++ ++ osl_mfree(osh, p, size + sizeof(bcm_mem_link_t)); ++} ++ ++char* ++osl_debug_memdump(osl_t *osh, char *buf, uint sz) ++{ ++ bcm_mem_link_t *p; ++ char *obuf; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ obuf = buf; ++ ++ buf += sprintf(buf, " Address\tSize\tFile:line\n"); ++ for (p = osh->dbgmem_list; p && ((buf - obuf) < (sz - 128)); p = p->next) ++ buf += sprintf(buf, "0x%08x\t%5d\t%s:%d\n", ++ (int)p + sizeof(bcm_mem_link_t), p->size, p->file, p->line); ++ ++ return (obuf); ++} ++ ++#endif /* BCMDBG_MEM */ ++ ++void* ++osl_malloc(osl_t *osh, uint size) ++{ ++ void *addr; ++ ++ /* only ASSERT if osh is defined */ ++ if (osh) ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ ++ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { ++ if(osh) ++ osh->failed++; ++ return (NULL); ++ } ++ if (osh) ++ osh->malloced += size; ++ ++ return (addr); ++} ++ ++void ++osl_mfree(osl_t *osh, void *addr, uint size) ++{ ++ if (osh) { ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ osh->malloced -= size; ++ } ++ kfree(addr); ++} ++ ++uint ++osl_malloced(osl_t *osh) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->malloced); ++} ++ ++uint osl_malloc_failed(osl_t *osh) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->failed); ++} ++ ++void* ++osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); ++} ++ ++void ++osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); ++} ++ ++uint ++osl_dma_map(osl_t *osh, void *va, uint size, int direction) ++{ ++ int dir; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ return (pci_map_single(osh->pdev, va, size, dir)); ++} ++ ++void ++osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) ++{ ++ int dir; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ pci_unmap_single(osh->pdev, (uint32)pa, size, dir); ++} ++ ++#if defined(BINOSL) ++void ++osl_assert(char *exp, char *file, int line) ++{ ++ char tempbuf[255]; ++ ++ sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line); ++ panic(tempbuf); ++} ++#endif /* BCMDBG || BINOSL */ ++ ++void ++osl_delay(uint usec) ++{ ++ uint d; ++ ++ while (usec > 0) { ++ d = MIN(usec, 1000); ++ udelay(d); ++ usec -= d; ++ } ++} ++ ++/* ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ */ ++#ifdef BINOSL ++ ++int ++osl_printf(const char *format, ...) ++{ ++ va_list args; ++ char buf[1024]; ++ int len; ++ ++ /* sprintf into a local buffer because there *is* no "vprintk()".. */ ++ va_start(args, format); ++ len = vsprintf(buf, format, args); ++ va_end(args); ++ ++ if (len > sizeof (buf)) { ++ printk("osl_printf: buffer overrun\n"); ++ return (0); ++ } ++ ++ return (printk(buf)); ++} ++ ++int ++osl_sprintf(char *buf, const char *format, ...) ++{ ++ va_list args; ++ int rc; ++ ++ va_start(args, format); ++ rc = vsprintf(buf, format, args); ++ va_end(args); ++ return (rc); ++} ++ ++int ++osl_strcmp(const char *s1, const char *s2) ++{ ++ return (strcmp(s1, s2)); ++} ++ ++int ++osl_strncmp(const char *s1, const char *s2, uint n) ++{ ++ return (strncmp(s1, s2, n)); ++} ++ ++int ++osl_strlen(const char *s) ++{ ++ return (strlen(s)); ++} ++ ++char* ++osl_strcpy(char *d, const char *s) ++{ ++ return (strcpy(d, s)); ++} ++ ++char* ++osl_strncpy(char *d, const char *s, uint n) ++{ ++ return (strncpy(d, s, n)); ++} ++ ++void ++bcopy(const void *src, void *dst, int len) ++{ ++ memcpy(dst, src, len); ++} ++ ++int ++bcmp(const void *b1, const void *b2, int len) ++{ ++ return (memcmp(b1, b2, len)); ++} ++ ++void ++bzero(void *b, int len) ++{ ++ memset(b, '\0', len); ++} ++ ++uint32 ++osl_readl(volatile uint32 *r) ++{ ++ return (readl(r)); ++} ++ ++uint16 ++osl_readw(volatile uint16 *r) ++{ ++ return (readw(r)); ++} ++ ++uint8 ++osl_readb(volatile uint8 *r) ++{ ++ return (readb(r)); ++} ++ ++void ++osl_writel(uint32 v, volatile uint32 *r) ++{ ++ writel(v, r); ++} ++ ++void ++osl_writew(uint16 v, volatile uint16 *r) ++{ ++ writew(v, r); ++} ++ ++void ++osl_writeb(uint8 v, volatile uint8 *r) ++{ ++ writeb(v, r); ++} ++ ++void * ++osl_uncached(void *va) ++{ ++#ifdef mips ++ return ((void*)KSEG1ADDR(va)); ++#else ++ return ((void*)va); ++#endif ++} ++ ++uint ++osl_getcycles(void) ++{ ++ uint cycles; ++ ++#if defined(mips) ++ cycles = read_c0_count() * 2; ++#elif defined(__i386__) ++ rdtscl(cycles); ++#else ++ cycles = 0; ++#endif ++ return cycles; ++} ++ ++void * ++osl_reg_map(uint32 pa, uint size) ++{ ++ return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); ++} ++ ++void ++osl_reg_unmap(void *va) ++{ ++ iounmap(va); ++} ++ ++int ++osl_busprobe(uint32 *val, uint32 addr) ++{ ++#ifdef mips ++ return get_dbe(*val, (uint32*)addr); ++#else ++ *val = readl(addr); ++ return 0; ++#endif ++} ++ ++uchar* ++osl_pktdata(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->data); ++} ++ ++uint ++osl_pktlen(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->len); ++} ++ ++uint ++osl_pktheadroom(osl_t *osh, void *skb) ++{ ++ return (uint) skb_headroom((struct sk_buff *) skb); ++} ++ ++uint ++osl_pkttailroom(osl_t *osh, void *skb) ++{ ++ return (uint) skb_tailroom((struct sk_buff *) skb); ++} ++ ++void* ++osl_pktnext(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->next); ++} ++ ++void ++osl_pktsetnext(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->next = (struct sk_buff*)x; ++} ++ ++void ++osl_pktsetlen(osl_t *osh, void *skb, uint len) ++{ ++ __skb_trim((struct sk_buff*)skb, len); ++} ++ ++uchar* ++osl_pktpush(osl_t *osh, void *skb, int bytes) ++{ ++ return (skb_push((struct sk_buff*)skb, bytes)); ++} ++ ++uchar* ++osl_pktpull(osl_t *osh, void *skb, int bytes) ++{ ++ return (skb_pull((struct sk_buff*)skb, bytes)); ++} ++ ++void* ++osl_pktdup(osl_t *osh, void *skb) ++{ ++ return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC)); ++} ++ ++void* ++osl_pktcookie(void *skb) ++{ ++ return ((void*)((struct sk_buff*)skb)->csum); ++} ++ ++void ++osl_pktsetcookie(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->csum = (uint)x; ++} ++ ++void* ++osl_pktlink(void *skb) ++{ ++ return (((struct sk_buff*)skb)->prev); ++} ++ ++void ++osl_pktsetlink(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; ++} ++ ++uint ++osl_pktprio(void *skb) ++{ ++ return (((struct sk_buff*)skb)->priority); ++} ++ ++void ++osl_pktsetprio(void *skb, uint x) ++{ ++ ((struct sk_buff*)skb)->priority = x; ++} ++ ++ ++#endif /* BINOSL */ +diff -Nur linux-2.4.32/drivers/net/hnd/Makefile linux-2.4.32-brcm/drivers/net/hnd/Makefile +--- linux-2.4.32/drivers/net/hnd/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/Makefile 2005-12-16 23:39:11.284858000 +0100 +@@ -0,0 +1,19 @@ ++# ++# Makefile for the BCM47xx specific kernel interface routines ++# under Linux. ++# ++ ++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER ++ ++O_TARGET := hnd.o ++ ++HND_OBJS := bcmutils.o hnddma.o linux_osl.o sbutils.o bcmsrom.o ++ ++export-objs := shared_ksyms.o ++obj-y := shared_ksyms.o $(HND_OBJS) ++obj-m := $(O_TARGET) ++ ++include $(TOPDIR)/Rules.make ++ ++shared_ksyms.c: shared_ksyms.sh $(HND_OBJS) ++ sh -e $< $(HND_OBJS) > $@ +diff -Nur linux-2.4.32/drivers/net/hnd/sbutils.c linux-2.4.32-brcm/drivers/net/hnd/sbutils.c +--- linux-2.4.32/drivers/net/hnd/sbutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/sbutils.c 2005-12-16 23:39:11.316860000 +0100 +@@ -0,0 +1,2837 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of the SiliconBackplane-based Broadcom chips. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* debug/trace */ ++#define SB_ERROR(args) ++ ++ ++typedef uint32 (*sb_intrsoff_t)(void *intr_arg); ++typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg); ++typedef bool (*sb_intrsenabled_t)(void *intr_arg); ++ ++/* misc sb info needed by some of the routines */ ++typedef struct sb_info { ++ ++ struct sb_pub sb; /* back plane public state(must be first field of sb_info */ ++ ++ void *osh; /* osl os handle */ ++ void *sdh; /* bcmsdh handle */ ++ ++ void *curmap; /* current regs va */ ++ void *regs[SB_MAXCORES]; /* other regs va */ ++ ++ uint curidx; /* current core index */ ++ uint dev_coreid; /* the core provides driver functions */ ++ ++ bool memseg; /* flag to toggle MEM_SEG register */ ++ ++ uint gpioidx; /* gpio control core index */ ++ uint gpioid; /* gpio control coretype */ ++ ++ uint numcores; /* # discovered cores */ ++ uint coreid[SB_MAXCORES]; /* id of each core */ ++ ++ void *intr_arg; /* interrupt callback function arg */ ++ sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */ ++ sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */ ++ sb_intrsenabled_t intrsenabled_fn; /* function to check if chip interrupts are enabled */ ++ ++} sb_info_t; ++ ++/* local prototypes */ ++static sb_info_t * BCMINIT(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz); ++static void BCMINIT(sb_scan)(sb_info_t *si); ++static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val); ++static uint _sb_coreidx(sb_info_t *si); ++static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit); ++static uint BCMINIT(sb_pcidev2chip)(uint pcidev); ++static uint BCMINIT(sb_chip2numcores)(uint chip); ++static bool sb_ispcie(sb_info_t *si); ++static bool sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen); ++static int sb_pci_fixcfg(sb_info_t *si); ++ ++/* routines to access mdio slave device registers */ ++static int sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint readdr, uint val); ++static void BCMINIT(sb_war30841)(sb_info_t *si); ++ ++/* delay needed between the mdio control/ mdiodata register data access */ ++#define PR28829_DELAY() OSL_DELAY(10) ++ ++ ++/* global variable to indicate reservation/release of gpio's*/ ++static uint32 sb_gpioreservation = 0; ++ ++#define SB_INFO(sbh) (sb_info_t*)sbh ++#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val))) ++#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE)) ++#define GOODREGS(regs) ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE)) ++#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) ++#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) ++#define BADIDX (SB_MAXCORES+1) ++#define NOREV -1 ++ ++#define PCI(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI)) ++#define PCIE(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCIE)) ++ ++/* sonicsrev */ ++#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) ++#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) ++ ++#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr)) ++#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v)) ++#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v))) ++#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v))) ++ ++/* ++ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ ++ * after core switching to avoid invalid register accesss inside ISR. ++ */ ++#define INTR_OFF(si, intr_val) \ ++ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } ++#define INTR_RESTORE(si, intr_val) \ ++ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } ++ ++/* dynamic clock control defines */ ++#define LPOMINFREQ 25000 /* low power oscillator min */ ++#define LPOMAXFREQ 43000 /* low power oscillator max */ ++#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ ++#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ ++#define PCIMINFREQ 25000000 /* 25 MHz */ ++#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ ++ ++#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ ++#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ ++ ++#define MIN_DUMPBUFLEN 32 /* debug */ ++ ++/* different register spaces to access thr'u pcie indirect access*/ ++#define PCIE_CONFIGREGS 1 ++#define PCIE_PCIEREGS 2 ++ ++/* GPIO Based LED powersave defines */ ++#define DEFAULT_GPIO_ONTIME 10 ++#define DEFAULT_GPIO_OFFTIME 90 ++ ++#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) ++ ++static uint32 ++sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr) ++{ ++ uint8 tmp; ++ uint32 val, intr_val = 0; ++ ++ ++ /* ++ * compact flash only has 11 bits address, while we needs 12 bits address. ++ * MEM_SEG will be OR'd with other 11 bits address in hardware, ++ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). ++ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special ++ */ ++ if(si->memseg) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ ++ } ++ ++ val = R_REG(sbr); ++ ++ if(si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ INTR_RESTORE(si, intr_val); ++ } ++ ++ return (val); ++} ++ ++static void ++sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v) ++{ ++ uint8 tmp; ++ volatile uint32 dummy; ++ uint32 intr_val = 0; ++ ++ ++ /* ++ * compact flash only has 11 bits address, while we needs 12 bits address. ++ * MEM_SEG will be OR'd with other 11 bits address in hardware, ++ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). ++ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special ++ */ ++ if(si->memseg) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ ++ } ++ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++#ifdef IL_BIGENDIAN ++ dummy = R_REG(sbr); ++ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++#else ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++ dummy = R_REG(sbr); ++ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); ++#endif ++ } else ++ W_REG(sbr, v); ++ ++ if(si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ INTR_RESTORE(si, intr_val); ++ } ++} ++ ++/* ++ * Allocate a sb handle. ++ * devid - pci device id (used to determine chip#) ++ * osh - opaque OS handle ++ * regs - virtual address of initial core registers ++ * bustype - pci/pcmcia/sb/sdio/etc ++ * vars - pointer to a pointer area for "environment" variables ++ * varsz - pointer to int to return the size of the vars ++ */ ++sb_t * ++BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz) ++{ ++ sb_info_t *si; ++ ++ /* alloc sb_info_t */ ++ if ((si = MALLOC(osh, sizeof (sb_info_t))) == NULL) { ++ SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); ++ return (NULL); ++ } ++ ++ if (BCMINIT(sb_doattach)(si, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { ++ MFREE(osh, si, sizeof (sb_info_t)); ++ return (NULL); ++ } ++ return (sb_t *)si; ++} ++ ++/* Using sb_kattach depends on SB_BUS support, either implicit */ ++/* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */ ++#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS) ++ ++/* global kernel resource */ ++static sb_info_t ksi; ++ ++/* generic kernel variant of sb_attach() */ ++sb_t * ++BCMINITFN(sb_kattach)() ++{ ++ uint32 *regs; ++ ++ if (ksi.curmap == NULL) { ++ uint32 cid; ++ ++ regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); ++ cid = R_REG((uint32 *)regs); ++ if (((cid & CID_ID_MASK) == BCM4712_DEVICE_ID) && ++ ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) && ++ ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) { ++ uint32 *scc, val; ++ ++ scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); ++ val = R_REG(scc); ++ SB_ERROR((" initial scc = 0x%x\n", val)); ++ val |= SCC_SS_XTAL; ++ W_REG(scc, val); ++ } ++ ++ if (BCMINIT(sb_doattach)(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, ++ SB_BUS, NULL, NULL, NULL) == NULL) { ++ return NULL; ++ } ++ } ++ ++ return (sb_t *)&ksi; ++} ++#endif ++ ++static sb_info_t * ++BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz) ++{ ++ uint origidx; ++ chipcregs_t *cc; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ ASSERT(GOODREGS(regs)); ++ ++ bzero((uchar*)si, sizeof (sb_info_t)); ++ ++ si->sb.buscoreidx = si->gpioidx = BADIDX; ++ ++ si->osh = osh; ++ si->curmap = regs; ++ si->sdh = sdh; ++ ++ /* check to see if we are a sb core mimic'ing a pci core */ ++ if (bustype == PCI_BUS) { ++ if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff) ++ bustype = SB_BUS; ++ else ++ bustype = PCI_BUS; ++ } ++ ++ si->sb.bustype = bustype; ++ if (si->sb.bustype != BUSTYPE(si->sb.bustype)) { ++ SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n", ++ si->sb.bustype, BUSTYPE(si->sb.bustype))); ++ return NULL; ++ } ++ ++ /* need to set memseg flag for CF card first before any sb registers access */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) ++ si->memseg = TRUE; ++ ++ /* kludge to enable the clock on the 4306 which lacks a slowclock */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) ++ sb_clkctl_xtal(&si->sb, XTAL|PLL, ON); ++ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(osh, PCI_BAR0_WIN, sizeof (uint32)); ++ if (!GOODCOREADDR(w)) ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32), SB_ENUM_BASE); ++ } ++ ++ /* initialize current core index value */ ++ si->curidx = _sb_coreidx(si); ++ ++ if (si->curidx == BADIDX) { ++ SB_ERROR(("sb_doattach: bad core index\n")); ++ return NULL; ++ } ++ ++ /* get sonics backplane revision */ ++ sb = REGS2SB(si->curmap); ++ si->sb.sonicsrev = (R_SBREG(si, &(sb)->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; ++ ++ /* keep and reuse the initial register mapping */ ++ origidx = si->curidx; ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ si->regs[origidx] = regs; ++ ++ /* is core-0 a chipcommon core? */ ++ si->numcores = 1; ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0); ++ if (sb_coreid(&si->sb) != SB_CC) ++ cc = NULL; ++ ++ /* determine chip id and rev */ ++ if (cc) { ++ /* chip common core found! */ ++ si->sb.chip = R_REG(&cc->chipid) & CID_ID_MASK; ++ si->sb.chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; ++ si->sb.chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; ++ } else { ++ /* The only pcmcia chip without a chipcommon core is a 4301 */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) ++ devid = BCM4301_DEVICE_ID; ++ ++ /* no chip common core -- must convert device id to chip id */ ++ if ((si->sb.chip = BCMINIT(sb_pcidev2chip)(devid)) == 0) { ++ SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid)); ++ sb_setcoreidx(&si->sb, origidx); ++ return NULL; ++ } ++ } ++ ++ /* get chipcommon rev */ ++ si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV; ++ ++ /* determine numcores */ ++ if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6))) ++ si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; ++ else ++ si->numcores = BCMINIT(sb_chip2numcores)(si->sb.chip); ++ ++ /* return to original core */ ++ sb_setcoreidx(&si->sb, origidx); ++ ++ /* sanity checks */ ++ ASSERT(si->sb.chip); ++ ++ /* scan for cores */ ++ BCMINIT(sb_scan)(si); ++ ++ /* fixup necessary chip/core configurations */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ if (sb_pci_fixcfg(si)) { ++ SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n")); ++ return NULL; ++ } ++ } ++ ++ /* srom_var_init() depends on sb_scan() info */ ++ if (srom_var_init(si, si->sb.bustype, si->curmap, osh, vars, varsz)) { ++ SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n")); ++ return (NULL); ++ } ++ ++ if (cc == NULL) { ++ /* ++ * The chip revision number is hardwired into all ++ * of the pci function config rev fields and is ++ * independent from the individual core revision numbers. ++ * For example, the "A0" silicon of each chip is chip rev 0. ++ * For PCMCIA we get it from the CIS instead. ++ */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++ ASSERT(vars); ++ si->sb.chiprev = getintvar(*vars, "chiprev"); ++ } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32)); ++ si->sb.chiprev = w & 0xff; ++ } else ++ si->sb.chiprev = 0; ++ } ++ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++ w = getintvar(*vars, "regwindowsz"); ++ si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; ++ } ++ ++ /* gpio control core is required */ ++ if (!GOODIDX(si->gpioidx)) { ++ SB_ERROR(("sb_doattach: gpio control core not found\n")); ++ return NULL; ++ } ++ ++ /* get boardtype and boardrev */ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ /* do a pci config read to get subsystem id and subvendor id */ ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32)); ++ si->sb.boardvendor = w & 0xffff; ++ si->sb.boardtype = (w >> 16) & 0xffff; ++ break; ++ ++ case PCMCIA_BUS: ++ case SDIO_BUS: ++ si->sb.boardvendor = getintvar(*vars, "manfid"); ++ si->sb.boardtype = getintvar(*vars, "prodid"); ++ break; ++ ++ case SB_BUS: ++ case JTAG_BUS: ++ si->sb.boardvendor = VENDOR_BROADCOM; ++ if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0) ++ si->sb.boardtype = 0xffff; ++ break; ++ } ++ ++ if (si->sb.boardtype == 0) { ++ SB_ERROR(("sb_doattach: unknown board type\n")); ++ ASSERT(si->sb.boardtype); ++ } ++ ++ /* setup the GPIO based LED powersave register */ ++ if (si->sb.ccrev >= 16) { ++ w = getintvar(*vars, "gpiotimerval"); ++ if (!w) ++ w = DEFAULT_GPIOTIMERVAL; ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); ++ } ++ ++ ++ return (si); ++} ++ ++uint ++sb_coreid(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); ++} ++ ++uint ++sb_coreidx(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->curidx); ++} ++ ++/* return current index of core */ ++static uint ++_sb_coreidx(sb_info_t *si) ++{ ++ sbconfig_t *sb; ++ uint32 sbaddr = 0; ++ ++ ASSERT(si); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ sb = REGS2SB(si->curmap); ++ sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0)); ++ break; ++ ++ case PCI_BUS: ++ sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32)); ++ break; ++ ++ case PCMCIA_BUS: { ++ uint8 tmp = 0; ++ ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); ++ sbaddr = (uint)tmp << 12; ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); ++ sbaddr |= (uint)tmp << 16; ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); ++ sbaddr |= (uint)tmp << 24; ++ break; ++ } ++ ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ sbaddr = (uint32)si->curmap; ++ break; ++#endif /* BCMJTAG */ ++ ++ default: ++ ASSERT(0); ++ } ++ ++ if (!GOODCOREADDR(sbaddr)) ++ return BADIDX; ++ ++ return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE); ++} ++ ++uint ++sb_corevendor(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); ++} ++ ++uint ++sb_corerev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint sbidh; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ sbidh = R_SBREG(si, &(sb)->sbidhigh); ++ ++ return (SBCOREREV(sbidh)); ++} ++ ++void * ++sb_osh(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return si->osh; ++} ++ ++#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK) ++ ++/* set/clear sbtmstatelow core-specific flags */ ++uint32 ++sb_coreflags(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SBTML_ALLOW) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatelow, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatelow) & SBTML_ALLOW); ++} ++ ++/* set/clear sbtmstatehigh core-specific flags */ ++uint32 ++sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SBTMH_FL_MASK) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatehigh, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK); ++} ++ ++/* caller needs to take care of core-specific bist hazards */ ++int ++sb_corebist(sb_t *sbh, uint coreid, uint coreunit) ++{ ++ uint32 sblo; ++ uint coreidx; ++ sb_info_t *si; ++ int result = 0; ++ ++ si = SB_INFO(sbh); ++ ++ coreidx = sb_findcoreidx(si, coreid, coreunit); ++ if (!GOODIDX(coreidx)) ++ result = BCME_ERROR; ++ else { ++ sblo = sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), 0, 0); ++ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, (sblo | SBTML_FGC | SBTML_BE)); ++ ++ SPINWAIT(((sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTD) == 0), 100000); ++ ++ if (sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTF) ++ result = BCME_ERROR; ++ ++ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, sblo); ++ } ++ ++ return result; ++} ++ ++bool ++sb_iscoreup(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK); ++} ++ ++/* ++ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, ++ * switch back to the original core, and return the new value. ++ */ ++static uint ++sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val) ++{ ++ uint origidx; ++ uint32 *r; ++ uint w; ++ uint intr_val = 0; ++ ++ ASSERT(GOODIDX(coreidx)); ++ ASSERT(regoff < SB_CORE_SIZE); ++ ASSERT((val & ~mask) == 0); ++ ++ INTR_OFF(si, intr_val); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ /* switch core */ ++ r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff); ++ ++ /* mask and set */ ++ if (mask || val) { ++ if (regoff >= SBCONFIGOFF) { ++ w = (R_SBREG(si, r) & ~mask) | val; ++ W_SBREG(si, r, w); ++ } else { ++ w = (R_REG(r) & ~mask) | val; ++ W_REG(r, w); ++ } ++ } ++ ++ /* readback */ ++ if (regoff >= SBCONFIGOFF) ++ w = R_SBREG(si, r); ++ else ++ w = R_REG(r); ++ ++ /* restore core index */ ++ if (origidx != coreidx) ++ sb_setcoreidx(&si->sb, origidx); ++ ++ INTR_RESTORE(si, intr_val); ++ return (w); ++} ++ ++#define DWORD_ALIGN(x) (x & ~(0x03)) ++#define BYTE_POS(x) (x & 0x3) ++#define WORD_POS(x) (x & 0x1) ++ ++#define BYTE_SHIFT(x) (8 * BYTE_POS(x)) ++#define WORD_SHIFT(x) (16 * WORD_POS(x)) ++ ++#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF) ++#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF) ++ ++#define read_pci_cfg_byte(a) \ ++ (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff) ++ ++#define read_pci_cfg_write(a) \ ++ (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff) ++ ++ ++/* return TRUE if requested capability exists in the PCI config space */ ++static bool ++sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen) ++{ ++ uint8 cap_id; ++ uint8 cap_ptr; ++ uint32 bufsize; ++ uint8 byte_val; ++ ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) ++ return FALSE; ++ ++ /* check for Header type 0*/ ++ byte_val = read_pci_cfg_byte(PCI_CFG_HDR); ++ if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) ++ return FALSE; ++ ++ /* check if the capability pointer field exists */ ++ byte_val = read_pci_cfg_byte(PCI_CFG_STAT); ++ if (!(byte_val & PCI_CAPPTR_PRESENT)) ++ return FALSE; ++ ++ cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR); ++ /* check if the capability pointer is 0x00 */ ++ if (cap_ptr == 0x00) ++ return FALSE; ++ ++ ++ /* loop thr'u the capability list and see if the pcie capabilty exists */ ++ ++ cap_id = read_pci_cfg_byte(cap_ptr); ++ ++ while (cap_id != req_cap_id) { ++ cap_ptr = read_pci_cfg_byte((cap_ptr+1)); ++ if (cap_ptr == 0x00) break; ++ cap_id = read_pci_cfg_byte(cap_ptr); ++ } ++ if (cap_id != req_cap_id) { ++ return FALSE; ++ } ++ /* found the caller requested capability */ ++ if ((buf != NULL) && (buflen != NULL)) { ++ bufsize = *buflen; ++ if (!bufsize) goto end; ++ *buflen = 0; ++ /* copy the cpability data excluding cap ID and next ptr */ ++ cap_ptr += 2; ++ if ((bufsize + cap_ptr) > SZPCR) ++ bufsize = SZPCR - cap_ptr; ++ *buflen = bufsize; ++ while (bufsize--) { ++ *buf = read_pci_cfg_byte(cap_ptr); ++ cap_ptr++; ++ buf++; ++ } ++ } ++end: ++ return TRUE; ++} ++ ++/* return TRUE if PCIE capability exists the pci config space */ ++static bool ++sb_ispcie(sb_info_t *si) ++{ ++ return(sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL)); ++} ++ ++/* scan the sb enumerated space to identify all cores */ ++static void ++BCMINITFN(sb_scan)(sb_info_t *si) ++{ ++ uint origidx; ++ uint i; ++ bool pci; ++ bool pcie; ++ uint pciidx; ++ uint pcieidx; ++ uint pcirev; ++ uint pcierev; ++ ++ ++ ++ /* numcores should already be set */ ++ ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ si->sb.buscorerev = NOREV; ++ si->sb.buscoreidx = BADIDX; ++ ++ si->gpioidx = BADIDX; ++ ++ pci = pcie = FALSE; ++ pcirev = pcierev = NOREV; ++ pciidx = pcieidx = BADIDX; ++ ++ for (i = 0; i < si->numcores; i++) { ++ sb_setcoreidx(&si->sb, i); ++ si->coreid[i] = sb_coreid(&si->sb); ++ ++ if (si->coreid[i] == SB_PCI) { ++ pciidx = i; ++ pcirev = sb_corerev(&si->sb); ++ pci = TRUE; ++ } else if (si->coreid[i] == SB_PCIE) { ++ pcieidx = i; ++ pcierev = sb_corerev(&si->sb); ++ pcie = TRUE; ++ } else if (si->coreid[i] == SB_PCMCIA) { ++ si->sb.buscorerev = sb_corerev(&si->sb); ++ si->sb.buscoretype = si->coreid[i]; ++ si->sb.buscoreidx = i; ++ } ++ } ++ if (pci && pcie) { ++ if (sb_ispcie(si)) ++ pci = FALSE; ++ else ++ pcie = FALSE; ++ } ++ if (pci) { ++ si->sb.buscoretype = SB_PCI; ++ si->sb.buscorerev = pcirev; ++ si->sb.buscoreidx = pciidx; ++ } ++ else if (pcie) { ++ si->sb.buscoretype = SB_PCIE; ++ si->sb.buscorerev = pcierev; ++ si->sb.buscoreidx = pcieidx; ++ } ++ ++ /* ++ * Find the gpio "controlling core" type and index. ++ * Precedence: ++ * - if there's a chip common core - use that ++ * - else if there's a pci core (rev >= 2) - use that ++ * - else there had better be an extif core (4710 only) ++ */ ++ if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) { ++ si->gpioidx = sb_findcoreidx(si, SB_CC, 0); ++ si->gpioid = SB_CC; ++ } else if (PCI(si) && (si->sb.buscorerev >= 2)) { ++ si->gpioidx = si->sb.buscoreidx; ++ si->gpioid = SB_PCI; ++ } else if (sb_findcoreidx(si, SB_EXTIF, 0)) { ++ si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0); ++ si->gpioid = SB_EXTIF; ++ } else ++ ASSERT(si->gpioidx != BADIDX); ++ ++ /* return to original core index */ ++ sb_setcoreidx(&si->sb, origidx); ++} ++ ++/* may be called with core in reset */ ++void ++sb_detach(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ ++ if (si == NULL) ++ return; ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ for (idx = 0; idx < SB_MAXCORES; idx++) ++ if (si->regs[idx]) { ++ REG_UNMAP(si->regs[idx]); ++ si->regs[idx] = NULL; ++ } ++ ++ if (si != &ksi) ++ MFREE(si->osh, si, sizeof (sb_info_t)); ++} ++ ++/* use pci dev id to determine chip id for chips not having a chipcommon core */ ++static uint ++BCMINITFN(sb_pcidev2chip)(uint pcidev) ++{ ++ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) ++ return (BCM4710_DEVICE_ID); ++ if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID)) ++ return (BCM4402_DEVICE_ID); ++ if (pcidev == BCM4401_ENET_ID) ++ return (BCM4402_DEVICE_ID); ++ if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID)) ++ return (BCM4307_DEVICE_ID); ++ if (pcidev == BCM4301_DEVICE_ID) ++ return (BCM4301_DEVICE_ID); ++ ++ return (0); ++} ++ ++/* convert chip number to number of i/o cores */ ++static uint ++BCMINITFN(sb_chip2numcores)(uint chip) ++{ ++ if (chip == BCM4710_DEVICE_ID) ++ return (9); ++ if (chip == BCM4402_DEVICE_ID) ++ return (3); ++ if ((chip == BCM4301_DEVICE_ID) || (chip == BCM4307_DEVICE_ID)) ++ return (5); ++ if (chip == BCM4306_DEVICE_ID) /* < 4306c0 */ ++ return (6); ++ if (chip == BCM4704_DEVICE_ID) ++ return (9); ++ if (chip == BCM5365_DEVICE_ID) ++ return (7); ++ ++ SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); ++ ASSERT(0); ++ return (1); ++} ++ ++/* return index of coreid or BADIDX if not found */ ++static uint ++sb_findcoreidx( sb_info_t *si, uint coreid, uint coreunit) ++{ ++ uint found; ++ uint i; ++ ++ found = 0; ++ ++ for (i = 0; i < si->numcores; i++) ++ if (si->coreid[i] == coreid) { ++ if (found == coreunit) ++ return (i); ++ found++; ++ } ++ ++ return (BADIDX); ++} ++ ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcoreidx(sb_t *sbh, uint coreidx) ++{ ++ sb_info_t *si; ++ uint32 sbaddr; ++ uint8 tmp; ++ ++ si = SB_INFO(sbh); ++ ++ if (coreidx >= si->numcores) ++ return (NULL); ++ ++ /* ++ * If the user has provided an interrupt mask enabled function, ++ * then assert interrupts are disabled before switching the core. ++ */ ++ ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg)); ++ ++ sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; ++ ++ case PCI_BUS: ++ /* point bar0 window */ ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); ++ break; ++ ++ case PCMCIA_BUS: ++ tmp = (sbaddr >> 12) & 0x0f; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); ++ tmp = (sbaddr >> 16) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); ++ tmp = (sbaddr >> 24) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); ++ break; ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void *)sbaddr; ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; ++#endif /* BCMJTAG */ ++ } ++ ++ si->curidx = coreidx; ++ ++ return (si->curmap); ++} ++ ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcore(sb_t *sbh, uint coreid, uint coreunit) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ idx = sb_findcoreidx(si, coreid, coreunit); ++ if (!GOODIDX(idx)) ++ return (NULL); ++ ++ return (sb_setcoreidx(sbh, idx)); ++} ++ ++/* return chip number */ ++uint ++BCMINITFN(sb_chip)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chip); ++} ++ ++/* return chip revision number */ ++uint ++BCMINITFN(sb_chiprev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chiprev); ++} ++ ++/* return chip common revision number */ ++uint ++BCMINITFN(sb_chipcrev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.ccrev); ++} ++ ++/* return chip package option */ ++uint ++BCMINITFN(sb_chippkg)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chippkg); ++} ++ ++/* return PCI core rev. */ ++uint ++BCMINITFN(sb_pcirev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.buscorerev); ++} ++ ++bool ++BCMINITFN(sb_war16165)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (PCI(si) && (si->sb.buscorerev <= 10)); ++} ++ ++static void ++BCMINITFN(sb_war30841)(sb_info_t *si) ++{ ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); ++} ++ ++/* return PCMCIA core rev. */ ++uint ++BCMINITFN(sb_pcmciarev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.buscorerev); ++} ++ ++/* return board vendor id */ ++uint ++BCMINITFN(sb_boardvendor)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.boardvendor); ++} ++ ++/* return boardtype */ ++uint ++BCMINITFN(sb_boardtype)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ char *var; ++ ++ si = SB_INFO(sbh); ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) { ++ /* boardtype format is a hex string */ ++ si->sb.boardtype = getintvar(NULL, "boardtype"); ++ ++ /* backward compatibility for older boardtype string format */ ++ if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) { ++ if (!strcmp(var, "bcm94710dev")) ++ si->sb.boardtype = BCM94710D_BOARD; ++ else if (!strcmp(var, "bcm94710ap")) ++ si->sb.boardtype = BCM94710AP_BOARD; ++ else if (!strcmp(var, "bu4710")) ++ si->sb.boardtype = BU4710_BOARD; ++ else if (!strcmp(var, "bcm94702mn")) ++ si->sb.boardtype = BCM94702MN_BOARD; ++ else if (!strcmp(var, "bcm94710r1")) ++ si->sb.boardtype = BCM94710R1_BOARD; ++ else if (!strcmp(var, "bcm94710r4")) ++ si->sb.boardtype = BCM94710R4_BOARD; ++ else if (!strcmp(var, "bcm94702cpci")) ++ si->sb.boardtype = BCM94702CPCI_BOARD; ++ else if (!strcmp(var, "bcm95380_rr")) ++ si->sb.boardtype = BCM95380RR_BOARD; ++ } ++ } ++ ++ return (si->sb.boardtype); ++} ++ ++/* return bus type of sbh device */ ++uint ++sb_bus(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.bustype); ++} ++ ++/* return bus core type */ ++uint ++sb_buscoretype(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (si->sb.buscoretype); ++} ++ ++/* return bus core revision */ ++uint ++sb_buscorerev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ si = SB_INFO(sbh); ++ ++ return (si->sb.buscorerev); ++} ++ ++/* return list of found cores */ ++uint ++sb_corelist(sb_t *sbh, uint coreid[]) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint))); ++ return (si->numcores); ++} ++ ++/* return current register mapping */ ++void * ++sb_coreregs(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ ++ return (si->curmap); ++} ++ ++ ++/* do buffered registers update */ ++void ++sb_commit(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ origidx = si->curidx; ++ ASSERT(GOODIDX(origidx)); ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch over to chipcommon core if there is one, else use pci */ ++ if (si->sb.ccrev != NOREV) { ++ chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(&ccregs->broadcastaddress, SB_COMMIT); ++ W_REG(&ccregs->broadcastdata, 0x0); ++ } else if (PCI(si)) { ++ sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(&pciregs->bcastaddr, SB_COMMIT); ++ W_REG(&pciregs->bcastdata, 0x0); ++ } else ++ ASSERT(0); ++ ++ /* restore core index */ ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++} ++ ++/* reset and re-enable a core */ ++void ++sb_core_reset(sb_t *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ volatile uint32 dummy; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* ++ * Must do the disable sequence first to work for arbitrary current core state. ++ */ ++ sb_core_disable(sbh, bits); ++ ++ /* ++ * Now do the initialization sequence. ++ */ ++ ++ /* set reset while enabling the clock and forcing them on throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ ++ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) { ++ W_SBREG(si, &sb->sbtmstatehigh, 0); ++ } ++ if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { ++ AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); ++ } ++ ++ /* clear reset and allow it to propagate throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ ++ /* leave clock enabled */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++} ++ ++void ++sb_core_tofixup(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ if ( (BUSTYPE(si->sb.bustype) != PCI_BUS) || PCIE(si) || (PCI(si) && (si->sb.buscorerev >= 5)) ) ++ return; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x5 << SBIMCL_RTO_SHIFT) | 0x3); ++ } else { ++ if (sb_coreid(sbh) == SB_PCI) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ } else { ++ SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); ++ } ++ } ++ ++ sb_commit(sbh); ++} ++ ++/* ++ * Set the initiator timeout for the "master core". ++ * The master core is defined to be the core in control ++ * of the chip and so it issues accesses to non-memory ++ * locations (Because of dma *any* core can access memeory). ++ * ++ * The routine uses the bus to decide who is the master: ++ * SB_BUS => mips ++ * JTAG_BUS => chipc ++ * PCI_BUS => pci or pcie ++ * PCMCIA_BUS => pcmcia ++ * SDIO_BUS => pcmcia ++ * ++ * This routine exists so callers can disable initiator ++ * timeouts so accesses to very slow devices like otp ++ * won't cause an abort. The routine allows arbitrary ++ * settings of the service and request timeouts, though. ++ * ++ * Returns the timeout state before changing it or -1 ++ * on error. ++ */ ++ ++#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) ++ ++uint32 ++sb_set_initiator_to(sb_t *sbh, uint32 to) ++{ ++ sb_info_t *si; ++ uint origidx, idx; ++ uint intr_val = 0; ++ uint32 tmp, ret = 0xffffffff; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ if ((to & ~TO_MASK) != 0) ++ return ret; ++ ++ /* Figure out the master core */ ++ idx = BADIDX; ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ idx = si->sb.buscoreidx; ++ break; ++ case JTAG_BUS: ++ idx = SB_CC_IDX; ++ break; ++ case PCMCIA_BUS: ++ case SDIO_BUS: ++ idx = sb_findcoreidx(si, SB_PCMCIA, 0); ++ break; ++ case SB_BUS: ++ if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX) ++ idx = sb_findcoreidx(si, SB_MIPS, 0); ++ break; ++ default: ++ ASSERT(0); ++ } ++ if (idx == BADIDX) ++ return ret; ++ ++ INTR_OFF(si, intr_val); ++ origidx = sb_coreidx(sbh); ++ ++ sb = REGS2SB(sb_setcoreidx(sbh, idx)); ++ ++ tmp = R_SBREG(si, &sb->sbimconfiglow); ++ ret = tmp & TO_MASK; ++ W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); ++ ++ sb_commit(sbh); ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return ret; ++} ++ ++void ++sb_core_disable(sb_t *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ volatile uint32 dummy; ++ uint32 rej; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* if core is already in reset, just return */ ++ if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET) ++ return; ++ ++ /* reject value changed between sonics 2.2 and 2.3 */ ++ if (si->sb.sonicsrev == SONICS_2_2) ++ rej = (1 << SBTML_REJ_SHIFT); ++ else ++ rej = (2 << SBTML_REJ_SHIFT); ++ ++ /* if clocks are not enabled, put into reset and return */ ++ if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0) ++ goto disable; ++ ++ /* set target reject and spin until busy is clear (preserve core-specific bits) */ ++ OR_SBREG(si, &sb->sbtmstatelow, rej); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); ++ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) { ++ OR_SBREG(si, &sb->sbimstate, SBIM_RJ); ++ dummy = R_SBREG(si, &sb->sbimstate); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000); ++ } ++ ++ /* set reset and reject while enabling the clocks */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(10); ++ ++ /* don't forget to clear the initiator reject bit */ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) ++ AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ); ++ ++disable: ++ /* leave reset and reject asserted */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET)); ++ OSL_DELAY(1); ++} ++ ++/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */ ++void ++sb_watchdog(sb_t *sbh, uint ticks) ++{ ++ sb_info_t *si = SB_INFO(sbh); ++ ++ /* instant NMI */ ++ switch (si->gpioid) { ++ case SB_CC: ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); ++ break; ++ case SB_EXTIF: ++ sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); ++ break; ++ } ++} ++ ++/* initialize the pcmcia core */ ++void ++sb_pcmcia_init(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint8 cor; ++ ++ si = SB_INFO(sbh); ++ ++ /* enable d11 mac interrupts */ ++ if (si->sb.chip == BCM4301_DEVICE_ID) { ++ /* Have to use FCR2 in 4301 */ ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); ++ cor |= COR_IRQEN | COR_FUNEN; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); ++ } else { ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ cor |= COR_IRQEN | COR_FUNEN; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ } ++ ++} ++ ++ ++/* ++ * Configure the pci core for pci client (NIC) action ++ * coremask is the bitvec of cores by index to be enabled. ++ */ ++void ++sb_pci_setup(sb_t *sbh, uint coremask) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ sbpciregs_t *pciregs; ++ uint32 sbflag; ++ uint32 w; ++ uint idx; ++ int reg_val; ++ ++ si = SB_INFO(sbh); ++ ++ /* if not pci bus, we're done */ ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) ++ return; ++ ++ ASSERT(PCI(si) || PCIE(si)); ++ ASSERT(si->sb.buscoreidx != BADIDX); ++ ++ /* get current core index */ ++ idx = si->curidx; ++ ++ /* we interrupt on this backplane flag number */ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ ++ /* switch over to pci core */ ++ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx); ++ sb = REGS2SB(pciregs); ++ ++ /* ++ * Enable sb->pci interrupts. Assume ++ * PCI rev 2.3 support was added in pci core rev 6 and things changed.. ++ */ ++ if (PCIE(si) || (PCI(si) && ((si->sb.buscorerev) >= 6))) { ++ /* pci config write to set this core bit in PCIIntMask */ ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32)); ++ w |= (coremask << PCI_SBIM_SHIFT); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w); ++ } else { ++ /* set sbintvec bit for our flag number */ ++ OR_SBREG(si, &sb->sbintvec, (1 << sbflag)); ++ } ++ ++ if (PCI(si)) { ++ OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); ++ if (si->sb.buscorerev >= 11) ++ OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI); ++ if (si->sb.buscorerev < 5) { ++ SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ sb_commit(sbh); ++ } ++ } ++ ++ if (PCIE(si) && (si->sb.buscorerev == 0)) { ++ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); ++ reg_val |= 0x8; ++ sb_pcie_writereg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, reg_val); ++ ++ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG); ++ reg_val &= ~(0x40); ++ sb_pcie_writereg(sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG, reg_val); ++ ++ BCMINIT(sb_war30841)(si); ++ } ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++} ++ ++uint32 ++sb_base(uint32 admatch) ++{ ++ uint32 base; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ base = 0; ++ ++ if (type == 0) { ++ base = admatch & SBAM_BASE0_MASK; ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE1_MASK; ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE2_MASK; ++ } ++ ++ return (base); ++} ++ ++uint32 ++sb_size(uint32 admatch) ++{ ++ uint32 size; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ size = 0; ++ ++ if (type == 0) { ++ size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); ++ } ++ ++ return (size); ++} ++ ++/* return the core-type instantiation # of the current core */ ++uint ++sb_coreunit(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ uint coreid; ++ uint coreunit; ++ uint i; ++ ++ si = SB_INFO(sbh); ++ coreunit = 0; ++ ++ idx = si->curidx; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ coreid = sb_coreid(sbh); ++ ++ /* count the cores of our type */ ++ for (i = 0; i < idx; i++) ++ if (si->coreid[i] == coreid) ++ coreunit++; ++ ++ return (coreunit); ++} ++ ++static INLINE uint32 ++factor6(uint32 x) ++{ ++ switch (x) { ++ case CC_F6_2: return 2; ++ case CC_F6_3: return 3; ++ case CC_F6_4: return 4; ++ case CC_F6_5: return 5; ++ case CC_F6_6: return 6; ++ case CC_F6_7: return 7; ++ default: return 0; ++ } ++} ++ ++/* calculate the speed the SB would run at given a set of clockcontrol values */ ++uint32 ++sb_clock_rate(uint32 pll_type, uint32 n, uint32 m) ++{ ++ uint32 n1, n2, clock, m1, m2, m3, mc; ++ ++ n1 = n & CN_N1_MASK; ++ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; ++ ++ if (pll_type == PLL_TYPE6) { ++ if (m & CC_T6_MMASK) ++ return CC_T6_M1; ++ else ++ return CC_T6_M0; ++ } else if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ n1 = factor6(n1); ++ n2 += CC_F5_BIAS; ++ } else if (pll_type == PLL_TYPE2) { ++ n1 += CC_T2_BIAS; ++ n2 += CC_T2_BIAS; ++ ASSERT((n1 >= 2) && (n1 <= 7)); ++ ASSERT((n2 >= 5) && (n2 <= 23)); ++ } else if (pll_type == PLL_TYPE5) { ++ return (100000000); ++ } else ++ ASSERT(0); ++ /* PLL types 3 and 7 use BASE2 (25Mhz) */ ++ if ((pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE7)) { ++ clock = CC_CLOCK_BASE2 * n1 * n2; ++ } ++ else ++ clock = CC_CLOCK_BASE1 * n1 * n2; ++ ++ if (clock == 0) ++ return 0; ++ ++ m1 = m & CC_M1_MASK; ++ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; ++ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; ++ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; ++ ++ if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ m1 = factor6(m1); ++ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) ++ m2 += CC_F5_BIAS; ++ else ++ m2 = factor6(m2); ++ m3 = factor6(m3); ++ ++ switch (mc) { ++ case CC_MC_BYPASS: return (clock); ++ case CC_MC_M1: return (clock / m1); ++ case CC_MC_M1M2: return (clock / (m1 * m2)); ++ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); ++ case CC_MC_M1M3: return (clock / (m1 * m3)); ++ default: return (0); ++ } ++ } else { ++ ASSERT(pll_type == PLL_TYPE2); ++ ++ m1 += CC_T2_BIAS; ++ m2 += CC_T2M2_BIAS; ++ m3 += CC_T2_BIAS; ++ ASSERT((m1 >= 2) && (m1 <= 7)); ++ ASSERT((m2 >= 3) && (m2 <= 10)); ++ ASSERT((m3 >= 2) && (m3 <= 7)); ++ ++ if ((mc & CC_T2MC_M1BYP) == 0) ++ clock /= m1; ++ if ((mc & CC_T2MC_M2BYP) == 0) ++ clock /= m2; ++ if ((mc & CC_T2MC_M3BYP) == 0) ++ clock /= m3; ++ ++ return(clock); ++ } ++} ++ ++/* returns the current speed the SB is running at */ ++uint32 ++sb_clock(sb_t *sbh) ++{ ++ sb_info_t *si; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ idx = si->curidx; ++ pll_type = PLL_TYPE1; ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(&eir->clockcontrol_n); ++ m = R_REG(&eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(&cc->clockcontrol_n); ++ if (pll_type == PLL_TYPE6) ++ m = R_REG(&cc->clockcontrol_mips); ++ else if (pll_type == PLL_TYPE3) ++ { ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ m = R_REG(&cc->clockcontrol_sb); ++ else ++ m = R_REG(&cc->clockcontrol_m2); ++ } ++ else ++ m = R_REG(&cc->clockcontrol_sb); ++ } else { ++ INTR_RESTORE(si, intr_val); ++ return 0; ++ } ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ { ++ rate = 100000000; ++ } ++ else ++ { ++ /* calculate rate */ ++ rate = sb_clock_rate(pll_type, n, m); ++ if (pll_type == PLL_TYPE3) ++ rate = rate / 2; ++ } ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ INTR_RESTORE(si, intr_val); ++ ++ return rate; ++} ++ ++/* change logical "focus" to the gpio core for optimized access */ ++void* ++sb_gpiosetcore(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (sb_setcoreidx(sbh, si->gpioidx)); ++} ++ ++/* mask&set gpiocontrol bits */ ++uint32 ++sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiocontrol); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpiocontrol); ++ break; ++ ++ case SB_EXTIF: ++ return (0); ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output enable bits */ ++uint32 ++sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioouten); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioouten); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].outen); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output bits */ ++uint32 ++sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioout); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioout); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].out); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* reserve one gpio */ ++uint32 ++sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ ++ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; ++ } ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; ++ } ++ ++ /* already reserved */ ++ if (sb_gpioreservation & gpio_bitmask) ++ return -1; ++ /* set reservation */ ++ sb_gpioreservation |= gpio_bitmask; ++ ++ return sb_gpioreservation; ++} ++ ++/* release one gpio */ ++/* ++ * releasing the gpio doesn't change the current value on the GPIO last write value ++ * persists till some one overwrites it ++*/ ++ ++uint32 ++sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ ++ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; ++ } ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; ++ } ++ ++ /* already released */ ++ if (!(sb_gpioreservation & gpio_bitmask)) ++ return -1; ++ ++ /* clear reservation */ ++ sb_gpioreservation &= ~gpio_bitmask; ++ ++ return sb_gpioreservation; ++} ++ ++/* return the current gpioin register value */ ++uint32 ++sb_gpioin(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioin); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioin); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpioin); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, 0, 0)); ++} ++ ++/* mask&set gpio interrupt polarity bits */ ++uint32 ++sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt polarity */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointpolarity); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio interrupt mask bits */ ++uint32 ++sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointmask); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt mask */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointmask); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* assign the gpio to an led */ ++uint32 ++sb_gpioled(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ if (si->sb.ccrev < 16) ++ return -1; ++ ++ /* gpio led powersave reg */ ++ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); ++} ++ ++/* mask&set gpio timer val */ ++uint32 ++sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval) ++{ ++ sb_info_t *si; ++ si = SB_INFO(sbh); ++ ++ if (si->sb.ccrev < 16) ++ return -1; ++ ++ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); ++} ++ ++ ++/* return the slow clock source - LPO, XTAL, or PCI */ ++static uint ++sb_slowclk_src(sb_info_t *si) ++{ ++ chipcregs_t *cc; ++ ++ ++ ASSERT(sb_coreid(&si->sb) == SB_CC); ++ ++ if (si->sb.ccrev < 6) { ++ if ((BUSTYPE(si->sb.bustype) == PCI_BUS) ++ && (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)) & PCI_CFG_GPIO_SCS)) ++ return (SCC_SS_PCI); ++ else ++ return (SCC_SS_XTAL); ++ } else if (si->sb.ccrev < 10) { ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ return (R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK); ++ } else /* Insta-clock */ ++ return (SCC_SS_XTAL); ++} ++ ++/* return the ILP (slowclock) min or max frequency */ ++static uint ++sb_slowclk_freq(sb_info_t *si, bool max) ++{ ++ chipcregs_t *cc; ++ uint32 slowclk; ++ uint div; ++ ++ ++ ASSERT(sb_coreid(&si->sb) == SB_CC); ++ ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ ++ /* shouldn't be here unless we've established the chip has dynamic clk control */ ++ ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL); ++ ++ slowclk = sb_slowclk_src(si); ++ if (si->sb.ccrev < 6) { ++ if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64)); ++ else ++ return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32)); ++ } else if (si->sb.ccrev < 10) { ++ div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ if (slowclk == SCC_SS_LPO) ++ return (max? LPOMAXFREQ : LPOMINFREQ); ++ else if (slowclk == SCC_SS_XTAL) ++ return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); ++ else if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); ++ else ++ ASSERT(0); ++ } else { ++ /* Chipc rev 10 is InstaClock */ ++ div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; ++ div = 4 * (div + 1); ++ return (max ? XTALMAXFREQ : (XTALMINFREQ/div)); ++ } ++ return (0); ++} ++ ++static void ++sb_clkctl_setdelay(sb_info_t *si, void *chipcregs) ++{ ++ chipcregs_t * cc; ++ uint slowmaxfreq, pll_delay, slowclk; ++ uint pll_on_delay, fref_sel_delay; ++ ++ pll_delay = PLL_DELAY; ++ ++ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay ++ * since the xtal will also be powered down by dynamic clk control logic. ++ */ ++ slowclk = sb_slowclk_src(si); ++ if (slowclk != SCC_SS_XTAL) ++ pll_delay += XTAL_ON_DELAY; ++ ++ /* Starting with 4318 it is ILP that is used for the delays */ ++ slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE); ++ ++ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; ++ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; ++ ++ cc = (chipcregs_t *)chipcregs; ++ W_REG(&cc->pll_on_delay, pll_on_delay); ++ W_REG(&cc->fref_sel_delay, fref_sel_delay); ++} ++ ++int ++sb_pwrctl_slowclk(void *sbh, bool set, uint *div) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint intr_val = 0; ++ uint err = 0; ++ ++ si = SB_INFO(sbh); ++ ++ /* chipcommon cores prior to rev6 don't support slowclkcontrol */ ++ if (si->sb.ccrev < 6) ++ return 1; ++ ++ /* chipcommon cores rev10 are a whole new ball game */ ++ if (si->sb.ccrev >= 10) ++ return 1; ++ ++ if (set && ((*div % 4) || (*div < 4))) ++ return 2; ++ ++ INTR_OFF(si, intr_val); ++ origidx = si->curidx; ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) { ++ err = 3; ++ goto done; ++ } ++ ++ if (set) { ++ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHIFT)); ++ sb_clkctl_setdelay(sbh, (void *)cc); ++ } else ++ *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return err; ++} ++ ++/* initialize power control delay registers */ ++void sb_clkctl_init(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ ++ si = SB_INFO(sbh); ++ ++ origidx = si->curidx; ++ ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ return; ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ /* 4317pc does not work with SlowClock less than 5 MHz */ ++ if ((BUSTYPE(si->sb.bustype) == PCMCIA_BUS) && (si->sb.ccrev >= 6) && (si->sb.ccrev < 10)) ++ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (ILP_DIV_5MHZ << SCC_CD_SHIFT)); ++ ++ /* set all Instaclk chip ILP to 1 MHz */ ++ else if (si->sb.ccrev >= 10) ++ SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); ++ ++ sb_clkctl_setdelay(si, (void *)cc); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++} ++void sb_pwrctl_init(sb_t *sbh) ++{ ++sb_clkctl_init(sbh); ++} ++/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ ++uint16 ++sb_clkctl_fast_pwrup_delay(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint slowminfreq; ++ uint16 fpdelay; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ fpdelay = 0; ++ origidx = si->curidx; ++ ++ INTR_OFF(si, intr_val); ++ ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ goto done; ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ slowminfreq = sb_slowclk_freq(si, FALSE); ++ fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (fpdelay); ++} ++uint16 sb_pwrctl_fast_pwrup_delay(sb_t *sbh) ++{ ++return sb_clkctl_fast_pwrup_delay(sbh); ++} ++/* turn primary xtal and/or pll off/on */ ++int ++sb_clkctl_xtal(sb_t *sbh, uint what, bool on) ++{ ++ sb_info_t *si; ++ uint32 in, out, outen; ++ ++ si = SB_INFO(sbh); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ ++ ++ case PCMCIA_BUS: ++ return (0); ++ ++ ++ case PCI_BUS: ++ ++ /* pcie core doesn't have any mapping to control the xtal pu */ ++ if (PCIE(si)) ++ return -1; ++ ++ in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32)); ++ out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)); ++ outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32)); ++ ++ /* ++ * Avoid glitching the clock if GPRS is already using it. ++ * We can't actually read the state of the PLLPD so we infer it ++ * by the value of XTAL_PU which *is* readable via gpioin. ++ */ ++ if (on && (in & PCI_CFG_GPIO_XTAL)) ++ return (0); ++ ++ if (what & XTAL) ++ outen |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ outen |= PCI_CFG_GPIO_PLL; ++ ++ if (on) { ++ /* turn primary xtal on */ ++ if (what & XTAL) { ++ out |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); ++ OSL_DELAY(XTAL_ON_DELAY); ++ } ++ ++ /* turn pll on */ ++ if (what & PLL) { ++ out &= ~PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_DELAY(2000); ++ } ++ } else { ++ if (what & XTAL) ++ out &= ~PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); ++ } ++ ++ default: ++ return (-1); ++ } ++ ++ return (0); ++} ++ ++int sb_pwrctl_xtal(sb_t *sbh, uint what, bool on) ++{ ++return sb_clkctl_xtal(sbh,what,on); ++} ++ ++/* set dynamic clk control mode (forceslow, forcefast, dynamic) */ ++/* returns true if ignore pll off is set and false if it is not */ ++bool ++sb_clkctl_clk(sb_t *sbh, uint mode) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint32 scc; ++ bool forcefastclk=FALSE; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ /* chipcommon cores prior to rev6 don't support dynamic clock control */ ++ if (si->sb.ccrev < 6) ++ return (FALSE); ++ ++ /* chipcommon cores rev10 are a whole new ball game */ ++ if (si->sb.ccrev >= 10) ++ return (FALSE); ++ ++ INTR_OFF(si, intr_val); ++ ++ origidx = si->curidx; ++ ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; ++ ++ switch (mode) { ++ case CLK_FAST: /* force fast (pll) clock */ ++ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ ++ sb_clkctl_xtal(&si->sb, XTAL, ON); ++ ++ SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); ++ break; ++ ++ case CLK_DYNAMIC: /* enable dynamic clock control */ ++ scc = R_REG(&cc->slow_clk_ctl); ++ scc &= ~(SCC_FS | SCC_IP | SCC_XC); ++ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) ++ scc |= SCC_XC; ++ W_REG(&cc->slow_clk_ctl, scc); ++ ++ /* for dynamic control, we have to release our xtal_pu "force on" */ ++ if (scc & SCC_XC) ++ sb_clkctl_xtal(&si->sb, XTAL, OFF); ++ break; ++ ++ default: ++ ASSERT(0); ++ } ++ ++ /* Is the h/w forcing the use of the fast clk */ ++ forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (forcefastclk); ++} ++ ++bool sb_pwrctl_clk(sb_t *sbh, uint mode) ++{ ++return sb_clkctl_clk(sbh, mode); ++} ++/* register driver interrupt disabling and restoring callback functions */ ++void ++sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ si->intr_arg = intr_arg; ++ si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn; ++ si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn; ++ si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn; ++ /* save current core id. when this function called, the current core ++ * must be the core which provides driver functions(il, et, wl, etc.) ++ */ ++ si->dev_coreid = si->coreid[si->curidx]; ++} ++ ++ ++void ++sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, ++ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif) ++{ ++ uint vendor, core, unit; ++ uint chip, chippkg; ++ char varname[8]; ++ uint8 class, subclass, progif; ++ ++ vendor = sb_corevendor(sbh); ++ core = sb_coreid(sbh); ++ unit = sb_coreunit(sbh); ++ ++ chip = BCMINIT(sb_chip)(sbh); ++ chippkg = BCMINIT(sb_chippkg)(sbh); ++ ++ progif = 0; ++ ++ /* Known vendor translations */ ++ switch (vendor) { ++ case SB_VEND_BCM: ++ vendor = VENDOR_BROADCOM; ++ break; ++ } ++ ++ /* Determine class based on known core codes */ ++ switch (core) { ++ case SB_ILINE20: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ILINE_ID; ++ break; ++ case SB_ENET: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ENET_ID; ++ break; ++ case SB_SDRAM: ++ case SB_MEMC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_RAM; ++ break; ++ case SB_PCI: ++ case SB_PCIE: ++ class = PCI_CLASS_BRIDGE; ++ subclass = PCI_BRIDGE_PCI; ++ break; ++ case SB_MIPS: ++ case SB_MIPS33: ++ class = PCI_CLASS_CPU; ++ subclass = PCI_CPU_MIPS; ++ break; ++ case SB_CODEC: ++ class = PCI_CLASS_COMM; ++ subclass = PCI_COMM_MODEM; ++ core = BCM47XX_V90_ID; ++ break; ++ case SB_USB: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USB_ID; ++ break; ++ case SB_USB11H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USBH_ID; ++ break; ++ case SB_USB11D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ core = BCM47XX_USBD_ID; ++ break; ++ case SB_IPSEC: ++ class = PCI_CLASS_CRYPT; ++ subclass = PCI_CRYPT_NETWORK; ++ core = BCM47XX_IPSEC_ID; ++ break; ++ case SB_ROBO: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ core = BCM47XX_ROBO_ID; ++ break; ++ case SB_EXTIF: ++ case SB_CC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_FLASH; ++ break; ++ case SB_D11: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ /* Let an nvram variable override this */ ++ sprintf(varname, "wl%did", unit); ++ if ((core = getintvar(NULL, varname)) == 0) { ++ if (chip == BCM4712_DEVICE_ID) { ++ if (chippkg == BCM4712SMALL_PKG_ID) ++ core = BCM4306_D11G_ID; ++ else ++ core = BCM4306_D11DUAL_ID; ++ } ++ } ++ break; ++ ++ default: ++ class = subclass = progif = 0xff; ++ break; ++ } ++ ++ *pcivendor = (uint16)vendor; ++ *pcidevice = (uint16)core; ++ *pciclass = class; ++ *pcisubclass = subclass; ++ *pciprogif = progif; ++} ++ ++ ++ ++ ++/* use the mdio interface to write to mdio slaves */ ++static int ++sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val) ++{ ++ uint mdiodata; ++ uint i = 0; ++ sbpcieregs_t *pcieregs; ++ ++ pcieregs = (sbpcieregs_t*) sb_setcoreidx(&si->sb, si->sb.buscoreidx); ++ ASSERT (pcieregs); ++ ++ /* enable mdio access to SERDES */ ++ W_REG((&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); ++ ++ mdiodata = MDIODATA_START | MDIODATA_WRITE | ++ (physmedia << MDIODATA_DEVADDR_SHF) | ++ (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val; ++ ++ W_REG((&pcieregs->mdiodata), mdiodata); ++ ++ PR28829_DELAY(); ++ ++ /* retry till the transaction is complete */ ++ while ( i < 10 ) { ++ if (R_REG(&(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { ++ /* Disable mdio access to SERDES */ ++ W_REG((&pcieregs->mdiocontrol), 0); ++ return 0; ++ } ++ OSL_DELAY(1000); ++ i++; ++ } ++ ++ SB_ERROR(("sb_pcie_mdiowrite: timed out\n")); ++ /* Disable mdio access to SERDES */ ++ W_REG((&pcieregs->mdiocontrol), 0); ++ ASSERT(0); ++ return 1; ++ ++} ++ ++/* indirect way to read pcie config regs*/ ++uint ++sb_pcie_readreg(void *sb, void* arg1, uint offset) ++{ ++ sb_info_t *si; ++ sb_t *sbh; ++ uint retval = 0xFFFFFFFF; ++ sbpcieregs_t *pcieregs; ++ uint addrtype; ++ ++ sbh = (sb_t *)sb; ++ si = SB_INFO(sbh); ++ ASSERT (PCIE(si)); ++ ++ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); ++ ASSERT (pcieregs); ++ ++ addrtype = (uint)((uintptr)arg1); ++ switch(addrtype) { ++ case PCIE_CONFIGREGS: ++ W_REG((&pcieregs->configaddr),offset); ++ retval = R_REG(&(pcieregs->configdata)); ++ break; ++ case PCIE_PCIEREGS: ++ W_REG(&(pcieregs->pcieaddr),offset); ++ retval = R_REG(&(pcieregs->pciedata)); ++ break; ++ default: ++ ASSERT(0); ++ break; ++ } ++ return retval; ++} ++ ++/* indirect way to write pcie config/mdio/pciecore regs*/ ++uint ++sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val) ++{ ++ sb_info_t *si; ++ sbpcieregs_t *pcieregs; ++ uint addrtype; ++ ++ si = SB_INFO(sbh); ++ ASSERT (PCIE(si)); ++ ++ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); ++ ASSERT (pcieregs); ++ ++ addrtype = (uint)((uintptr)arg1); ++ ++ switch(addrtype) { ++ case PCIE_CONFIGREGS: ++ W_REG((&pcieregs->configaddr),offset); ++ W_REG((&pcieregs->configdata),val); ++ break; ++ case PCIE_PCIEREGS: ++ W_REG((&pcieregs->pcieaddr),offset); ++ W_REG((&pcieregs->pciedata),val); ++ break; ++ default: ++ ASSERT(0); ++ break; ++ } ++ return 0; ++} ++ ++ ++/* Build device path. Support SB, PCI, and JTAG for now. */ ++int ++sb_devpath(sb_t *sbh, char *path, int size) ++{ ++ ASSERT(path); ++ ASSERT(size >= SB_DEVPATH_BUFSZ); ++ ++ switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) { ++ case SB_BUS: ++ case JTAG_BUS: ++ sprintf(path, "sb/%u/", sb_coreidx(sbh)); ++ break; ++ case PCI_BUS: ++ ASSERT((SB_INFO(sbh))->osh); ++ sprintf(path, "pci/%u/%u/", OSL_PCI_BUS((SB_INFO(sbh))->osh), ++ OSL_PCI_SLOT((SB_INFO(sbh))->osh)); ++ break; ++ case PCMCIA_BUS: ++ SB_ERROR(("sb_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n")); ++ SB_ERROR(("sb_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n")); ++ sprintf(path, "pc/%u/%u/", 1, 1); ++ break; ++ case SDIO_BUS: ++ SB_ERROR(("sb_devpath: device 0 assumed\n")); ++ sprintf(path, "sd/%u/", sb_coreidx(sbh)); ++ break; ++ default: ++ ASSERT(0); ++ break; ++ } ++ ++ return 0; ++} ++ ++/* Fix chip's configuration. The current core may be changed upon return */ ++static int ++sb_pci_fixcfg(sb_info_t *si) ++{ ++ uint origidx, pciidx; ++ sbpciregs_t *pciregs; ++ sbpcieregs_t *pcieregs; ++ uint16 val16, *reg16; ++ char name[SB_DEVPATH_BUFSZ+16], *value; ++ char devpath[SB_DEVPATH_BUFSZ]; ++ ++ ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS); ++ ++ /* Fix PCI(e) SROM shadow area */ ++ /* save the current index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ /* check 'pi' is correct and fix it if not */ ++ if (si->sb.buscoretype == SB_PCIE) { ++ pcieregs = (sbpcieregs_t *)sb_setcore(&si->sb, SB_PCIE, 0); ++ ASSERT(pcieregs); ++ reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; ++ } ++ else if (si->sb.buscoretype == SB_PCI) { ++ pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0); ++ ASSERT(pciregs); ++ reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; ++ } ++ else { ++ ASSERT(0); ++ return -1; ++ } ++ pciidx = sb_coreidx(&si->sb); ++ val16 = R_REG(reg16); ++ if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) { ++ val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK); ++ W_REG(reg16, val16); ++ } ++ ++ /* restore the original index */ ++ sb_setcoreidx(&si->sb, origidx); ++ ++ /* Fix bar0window */ ++ /* !do it last, it changes the current core! */ ++ if (sb_devpath(&si->sb, devpath, sizeof(devpath))) ++ return -1; ++ sprintf(name, "%sb0w", devpath); ++ if ((value = getvar(NULL, name))) { ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32), ++ bcm_strtoul(value, NULL, 16)); ++ /* update curidx since the current core is changed */ ++ si->curidx = _sb_coreidx(si); ++ if (si->curidx == BADIDX) { ++ SB_ERROR(("sb_pci_fixcfg: bad core index\n")); ++ return -1; ++ } ++ } ++ ++ return 0; ++} ++ +diff -Nur linux-2.4.32/drivers/net/hnd/shared_ksyms.sh linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh +--- linux-2.4.32/drivers/net/hnd/shared_ksyms.sh 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh 2005-12-16 23:39:11.316860000 +0100 +@@ -0,0 +1,21 @@ ++#!/bin/sh ++# ++# Copyright 2004, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: shared_ksyms.sh,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++# ++ ++cat < ++#include ++EOF ++ ++for file in $* ; do ++ ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p' ++done +diff -Nur linux-2.4.32/drivers/net/Makefile linux-2.4.32-brcm/drivers/net/Makefile +--- linux-2.4.32/drivers/net/Makefile 2005-01-19 15:09:56.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/Makefile 2005-12-16 23:39:11.284858000 +0100 +@@ -3,6 +3,8 @@ + # Makefile for the Linux network (ethercard) device drivers. + # + ++EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include ++ + obj-y := + obj-m := + obj-n := +@@ -39,6 +41,8 @@ + obj-$(CONFIG_ISDN) += slhc.o + endif + ++subdir-$(CONFIG_HND) += hnd ++subdir-$(CONFIG_WL) += wl + subdir-$(CONFIG_NET_PCMCIA) += pcmcia + subdir-$(CONFIG_NET_WIRELESS) += wireless + subdir-$(CONFIG_TULIP) += tulip +@@ -69,6 +74,13 @@ + obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o + obj-$(CONFIG_SUNGEM) += sungem.o + ++ifeq ($(CONFIG_HND),y) ++ obj-y += hnd/hnd.o ++endif ++ifeq ($(CONFIG_WL),y) ++ obj-y += wl/wl.o ++endif ++ + obj-$(CONFIG_MACE) += mace.o + obj-$(CONFIG_BMAC) += bmac.o + obj-$(CONFIG_GMAC) += gmac.o +diff -Nur linux-2.4.32/drivers/net/wireless/Config.in linux-2.4.32-brcm/drivers/net/wireless/Config.in +--- linux-2.4.32/drivers/net/wireless/Config.in 2004-11-17 12:54:21.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/wireless/Config.in 2005-12-16 23:39:11.364863000 +0100 +@@ -13,6 +13,7 @@ + fi + + if [ "$CONFIG_PCI" = "y" ]; then ++ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL + dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL + dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL + dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL +diff -Nur linux-2.4.32/drivers/net/wl/Makefile linux-2.4.32-brcm/drivers/net/wl/Makefile +--- linux-2.4.32/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/net/wl/Makefile 2005-12-16 23:39:11.364863000 +0100 +@@ -0,0 +1,26 @@ ++# ++# Makefile for the Broadcom wl driver ++# ++# Copyright 2004, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ ++ ++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include ++ ++O_TARGET := wl.o ++ ++obj-y := apsta_aeskeywrap.o apsta_aes.o apsta_bcmwpa.o apsta_d11ucode.o ++obj-y += apsta_hmac.o apsta_md5.o apsta_passhash.o apsta_prf.o apsta_rc4.o ++obj-y += apsta_rijndael-alg-fst.o apsta_sha1.o apsta_tkhash.o apsta_wlc_led.o ++obj-y += apsta_wlc_phy.o apsta_wlc_rate.o apsta_wlc_security.o ++obj-y += apsta_wlc_sup.o apsta_wlc_wet.o apsta_wl_linux.o apsta_wlc.o ++ ++obj-m := $(O_TARGET) ++ ++include $(TOPDIR)/Rules.make +diff -Nur linux-2.4.32/drivers/parport/Config.in linux-2.4.32-brcm/drivers/parport/Config.in +--- linux-2.4.32/drivers/parport/Config.in 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/parport/Config.in 2005-12-16 23:39:11.364863000 +0100 +@@ -11,6 +11,7 @@ + tristate 'Parallel port support' CONFIG_PARPORT + if [ "$CONFIG_PARPORT" != "n" ]; then + dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT ++ dep_tristate ' Asus WL500g parallel port' CONFIG_PARPORT_SPLINK $CONFIG_PARPORT + if [ "$CONFIG_PARPORT_PC" != "n" -a "$CONFIG_SERIAL" != "n" ]; then + if [ "$CONFIG_SERIAL" = "m" ]; then + define_tristate CONFIG_PARPORT_PC_CML1 m +diff -Nur linux-2.4.32/drivers/parport/Makefile linux-2.4.32-brcm/drivers/parport/Makefile +--- linux-2.4.32/drivers/parport/Makefile 2004-08-08 01:26:05.000000000 +0200 ++++ linux-2.4.32-brcm/drivers/parport/Makefile 2005-12-16 23:39:11.364863000 +0100 +@@ -22,6 +22,7 @@ + + obj-$(CONFIG_PARPORT) += parport.o + obj-$(CONFIG_PARPORT_PC) += parport_pc.o ++obj-$(CONFIG_PARPORT_SPLINK) += parport_splink.o + obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o + obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o + obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o +diff -Nur linux-2.4.32/drivers/parport/parport_splink.c linux-2.4.32-brcm/drivers/parport/parport_splink.c +--- linux-2.4.32/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/parport/parport_splink.c 2005-12-16 23:39:11.364863000 +0100 +@@ -0,0 +1,345 @@ ++/* Low-level parallel port routines for the ASUS WL-500g built-in port ++ * ++ * Author: Nuno Grilo ++ * Based on parport_pc source ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define SPLINK_ADDRESS 0xBF800010 ++ ++#undef DEBUG ++ ++#ifdef DEBUG ++#define DPRINTK printk ++#else ++#define DPRINTK(stuff...) ++#endif ++ ++ ++/* __parport_splink_frob_control differs from parport_splink_frob_control in that ++ * it doesn't do any extra masking. */ ++static __inline__ unsigned char __parport_splink_frob_control (struct parport *p, ++ unsigned char mask, ++ unsigned char val) ++{ ++ struct parport_pc_private *priv = p->physport->private_data; ++ unsigned char *io = (unsigned char *) p->base; ++ unsigned char ctr = priv->ctr; ++#ifdef DEBUG_PARPORT ++ printk (KERN_DEBUG ++ "__parport_splink_frob_control(%02x,%02x): %02x -> %02x\n", ++ mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable); ++#endif ++ ctr = (ctr & ~mask) ^ val; ++ ctr &= priv->ctr_writable; /* only write writable bits. */ ++ *(io+2) = ctr; ++ priv->ctr = ctr; /* Update soft copy */ ++ return ctr; ++} ++ ++ ++ ++static void parport_splink_data_forward (struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n"); ++ __parport_splink_frob_control (p, 0x20, 0); ++} ++ ++static void parport_splink_data_reverse (struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n"); ++ __parport_splink_frob_control (p, 0x20, 0x20); ++} ++ ++/* ++static void parport_splink_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: IRQ handler called\n"); ++ parport_generic_irq(irq, (struct parport *) dev_id, regs); ++} ++*/ ++ ++static void parport_splink_enable_irq(struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_enable_irq called\n"); ++ __parport_splink_frob_control (p, 0x10, 0x10); ++} ++ ++static void parport_splink_disable_irq(struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_disable_irq called\n"); ++ __parport_splink_frob_control (p, 0x10, 0); ++} ++ ++static void parport_splink_init_state(struct pardevice *dev, struct parport_state *s) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_init_state called\n"); ++ s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0); ++ if (dev->irq_func && ++ dev->port->irq != PARPORT_IRQ_NONE) ++ /* Set ackIntEn */ ++ s->u.pc.ctr |= 0x10; ++} ++ ++static void parport_splink_save_state(struct parport *p, struct parport_state *s) ++{ ++ const struct parport_pc_private *priv = p->physport->private_data; ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_save_state called\n"); ++ s->u.pc.ctr = priv->ctr; ++} ++ ++static void parport_splink_restore_state(struct parport *p, struct parport_state *s) ++{ ++ struct parport_pc_private *priv = p->physport->private_data; ++ unsigned char *io = (unsigned char *) p->base; ++ unsigned char ctr = s->u.pc.ctr; ++ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_restore_state called\n"); ++ *(io+2) = ctr; ++ priv->ctr = ctr; ++} ++ ++static void parport_splink_setup_interrupt(void) { ++ return; ++} ++ ++static void parport_splink_write_data(struct parport *p, unsigned char d) { ++ DPRINTK(KERN_DEBUG "parport_splink: write data called\n"); ++ unsigned char *io = (unsigned char *) p->base; ++ *io = d; ++} ++ ++static unsigned char parport_splink_read_data(struct parport *p) { ++ DPRINTK(KERN_DEBUG "parport_splink: read data called\n"); ++ unsigned char *io = (unsigned char *) p->base; ++ return *io; ++} ++ ++static void parport_splink_write_control(struct parport *p, unsigned char d) ++{ ++ const unsigned char wm = (PARPORT_CONTROL_STROBE | ++ PARPORT_CONTROL_AUTOFD | ++ PARPORT_CONTROL_INIT | ++ PARPORT_CONTROL_SELECT); ++ ++ DPRINTK(KERN_DEBUG "parport_splink: write control called\n"); ++ /* Take this out when drivers have adapted to the newer interface. */ ++ if (d & 0x20) { ++ printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n", ++ p->name, p->cad->name); ++ parport_splink_data_reverse (p); ++ } ++ ++ __parport_splink_frob_control (p, wm, d & wm); ++} ++ ++static unsigned char parport_splink_read_control(struct parport *p) ++{ ++ const unsigned char wm = (PARPORT_CONTROL_STROBE | ++ PARPORT_CONTROL_AUTOFD | ++ PARPORT_CONTROL_INIT | ++ PARPORT_CONTROL_SELECT); ++ DPRINTK(KERN_DEBUG "parport_splink: read control called\n"); ++ const struct parport_pc_private *priv = p->physport->private_data; ++ return priv->ctr & wm; /* Use soft copy */ ++} ++ ++static unsigned char parport_splink_frob_control (struct parport *p, unsigned char mask, ++ unsigned char val) ++{ ++ const unsigned char wm = (PARPORT_CONTROL_STROBE | ++ PARPORT_CONTROL_AUTOFD | ++ PARPORT_CONTROL_INIT | ++ PARPORT_CONTROL_SELECT); ++ ++ DPRINTK(KERN_DEBUG "parport_splink: frob control called\n"); ++ /* Take this out when drivers have adapted to the newer interface. */ ++ if (mask & 0x20) { ++ printk (KERN_DEBUG "%s (%s): use data_%s for this!\n", ++ p->name, p->cad->name, ++ (val & 0x20) ? "reverse" : "forward"); ++ if (val & 0x20) ++ parport_splink_data_reverse (p); ++ else ++ parport_splink_data_forward (p); ++ } ++ ++ /* Restrict mask and val to control lines. */ ++ mask &= wm; ++ val &= wm; ++ ++ return __parport_splink_frob_control (p, mask, val); ++} ++ ++static unsigned char parport_splink_read_status(struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: read status called\n"); ++ unsigned char *io = (unsigned char *) p->base; ++ return *(io+1); ++} ++ ++static void parport_splink_inc_use_count(void) ++{ ++#ifdef MODULE ++ MOD_INC_USE_COUNT; ++#endif ++} ++ ++static void parport_splink_dec_use_count(void) ++{ ++#ifdef MODULE ++ MOD_DEC_USE_COUNT; ++#endif ++} ++ ++static struct parport_operations parport_splink_ops = ++{ ++ parport_splink_write_data, ++ parport_splink_read_data, ++ ++ parport_splink_write_control, ++ parport_splink_read_control, ++ parport_splink_frob_control, ++ ++ parport_splink_read_status, ++ ++ parport_splink_enable_irq, ++ parport_splink_disable_irq, ++ ++ parport_splink_data_forward, ++ parport_splink_data_reverse, ++ ++ parport_splink_init_state, ++ parport_splink_save_state, ++ parport_splink_restore_state, ++ ++ parport_splink_inc_use_count, ++ parport_splink_dec_use_count, ++ ++ parport_ieee1284_epp_write_data, ++ parport_ieee1284_epp_read_data, ++ parport_ieee1284_epp_write_addr, ++ parport_ieee1284_epp_read_addr, ++ ++ parport_ieee1284_ecp_write_data, ++ parport_ieee1284_ecp_read_data, ++ parport_ieee1284_ecp_write_addr, ++ ++ parport_ieee1284_write_compat, ++ parport_ieee1284_read_nibble, ++ parport_ieee1284_read_byte, ++}; ++ ++/* --- Initialisation code -------------------------------- */ ++ ++static struct parport *parport_splink_probe_port (unsigned long int base) ++{ ++ struct parport_pc_private *priv; ++ struct parport_operations *ops; ++ struct parport *p; ++ ++ if (check_mem_region(base, 3)) { ++ printk (KERN_DEBUG "parport (0x%lx): iomem region not available\n", base); ++ return NULL; ++ } ++ priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL); ++ if (!priv) { ++ printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); ++ return NULL; ++ } ++ ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); ++ if (!ops) { ++ printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n", ++ base); ++ kfree (priv); ++ return NULL; ++ } ++ memcpy (ops, &parport_splink_ops, sizeof (struct parport_operations)); ++ priv->ctr = 0xc; ++ priv->ctr_writable = 0xff; ++ ++ if (!(p = parport_register_port(base, PARPORT_IRQ_NONE, ++ PARPORT_DMA_NONE, ops))) { ++ printk (KERN_DEBUG "parport (0x%lx): registration failed!\n", ++ base); ++ kfree (priv); ++ kfree (ops); ++ return NULL; ++ } ++ ++ p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; ++ p->size = (p->modes & PARPORT_MODE_EPP)?8:3; ++ p->private_data = priv; ++ ++ parport_proc_register(p); ++ request_mem_region (p->base, 3, p->name); ++ ++ /* Done probing. Now put the port into a sensible start-up state. */ ++ parport_splink_write_data(p, 0); ++ parport_splink_data_forward (p); ++ ++ /* Now that we've told the sharing engine about the port, and ++ found out its characteristics, let the high-level drivers ++ know about it. */ ++ parport_announce_port (p); ++ ++ DPRINTK(KERN_DEBUG "parport (0x%lx): init ok!\n", ++ base); ++ return p; ++} ++ ++static void parport_splink_unregister_port(struct parport *p) { ++ struct parport_pc_private *priv = p->private_data; ++ struct parport_operations *ops = p->ops; ++ ++ if (p->irq != PARPORT_IRQ_NONE) ++ free_irq(p->irq, p); ++ release_mem_region(p->base, 3); ++ parport_proc_unregister(p); ++ kfree (priv); ++ parport_unregister_port(p); ++ kfree (ops); ++} ++ ++ ++int parport_splink_init(void) ++{ ++ int ret; ++ ++ DPRINTK(KERN_DEBUG "parport_splink init called\n"); ++ parport_splink_setup_interrupt(); ++ ret = !parport_splink_probe_port(SPLINK_ADDRESS); ++ ++ return ret; ++} ++ ++void parport_splink_cleanup(void) { ++ struct parport *p = parport_enumerate(), *tmp; ++ DPRINTK(KERN_DEBUG "parport_splink cleanup called\n"); ++ if (p->size) { ++ if (p->modes & PARPORT_MODE_PCSPP) { ++ while(p) { ++ tmp = p->next; ++ parport_splink_unregister_port(p); ++ p = tmp; ++ } ++ } ++ } ++} ++ ++MODULE_AUTHOR("Nuno Grilo "); ++MODULE_DESCRIPTION("Parport Driver for ASUS WL-500g router builtin Port"); ++MODULE_SUPPORTED_DEVICE("ASUS WL-500g builtin Parallel Port"); ++MODULE_LICENSE("GPL"); ++ ++module_init(parport_splink_init) ++module_exit(parport_splink_cleanup) ++ +diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_generic.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c +--- linux-2.4.32/drivers/pcmcia/bcm4710_generic.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c 2005-12-16 23:39:11.368863250 +0100 +@@ -0,0 +1,912 @@ ++/* ++ * ++ * bcm47xx pcmcia driver ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * Based on sa1100_generic.c from www.handhelds.org, ++ * and au1000_generic.c from oss.sgi.com. ++ * ++ * $Id: bcm4710_generic.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "cs_internal.h" ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include "bcm4710pcmcia.h" ++ ++#ifdef PCMCIA_DEBUG ++static int pc_debug = PCMCIA_DEBUG; ++#endif ++ ++MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm47xx Socket Controller"); ++ ++/* This structure maintains housekeeping state for each socket, such ++ * as the last known values of the card detect pins, or the Card Services ++ * callback value associated with the socket: ++ */ ++static struct bcm47xx_pcmcia_socket *pcmcia_socket; ++static int socket_count; ++ ++ ++/* Returned by the low-level PCMCIA interface: */ ++static struct pcmcia_low_level *pcmcia_low_level; ++ ++/* Event poll timer structure */ ++static struct timer_list poll_timer; ++ ++ ++/* Prototypes for routines which are used internally: */ ++ ++static int bcm47xx_pcmcia_driver_init(void); ++static void bcm47xx_pcmcia_driver_shutdown(void); ++static void bcm47xx_pcmcia_task_handler(void *data); ++static void bcm47xx_pcmcia_poll_event(unsigned long data); ++static void bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs); ++static struct tq_struct bcm47xx_pcmcia_task; ++ ++#ifdef CONFIG_PROC_FS ++static int bcm47xx_pcmcia_proc_status(char *buf, char **start, ++ off_t pos, int count, int *eof, void *data); ++#endif ++ ++ ++/* Prototypes for operations which are exported to the ++ * in-kernel PCMCIA core: ++ */ ++ ++static int bcm47xx_pcmcia_init(unsigned int sock); ++static int bcm47xx_pcmcia_suspend(unsigned int sock); ++static int bcm47xx_pcmcia_register_callback(unsigned int sock, ++ void (*handler)(void *, unsigned int), void *info); ++static int bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap); ++static int bcm47xx_pcmcia_get_status(unsigned int sock, u_int *value); ++static int bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state); ++static int bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state); ++static int bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *io); ++static int bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *io); ++static int bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *mem); ++static int bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *mem); ++#ifdef CONFIG_PROC_FS ++static void bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base); ++#endif ++ ++static struct pccard_operations bcm47xx_pcmcia_operations = { ++ bcm47xx_pcmcia_init, ++ bcm47xx_pcmcia_suspend, ++ bcm47xx_pcmcia_register_callback, ++ bcm47xx_pcmcia_inquire_socket, ++ bcm47xx_pcmcia_get_status, ++ bcm47xx_pcmcia_get_socket, ++ bcm47xx_pcmcia_set_socket, ++ bcm47xx_pcmcia_get_io_map, ++ bcm47xx_pcmcia_set_io_map, ++ bcm47xx_pcmcia_get_mem_map, ++ bcm47xx_pcmcia_set_mem_map, ++#ifdef CONFIG_PROC_FS ++ bcm47xx_pcmcia_proc_setup ++#endif ++}; ++ ++ ++/* ++ * bcm47xx_pcmcia_driver_init() ++ * ++ * This routine performs a basic sanity check to ensure that this ++ * kernel has been built with the appropriate board-specific low-level ++ * PCMCIA support, performs low-level PCMCIA initialization, registers ++ * this socket driver with Card Services, and then spawns the daemon ++ * thread which is the real workhorse of the socket driver. ++ * ++ * Please see linux/Documentation/arm/SA1100/PCMCIA for more information ++ * on the low-level kernel interface. ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++static int __init bcm47xx_pcmcia_driver_init(void) ++{ ++ servinfo_t info; ++ struct pcmcia_init pcmcia_init; ++ struct pcmcia_state state; ++ unsigned int i; ++ unsigned long tmp; ++ ++ ++ printk("\nBCM47XX PCMCIA (CS release %s)\n", CS_RELEASE); ++ ++ CardServices(GetCardServicesInfo, &info); ++ ++ if (info.Revision != CS_RELEASE_CODE) { ++ printk(KERN_ERR "Card Services release codes do not match\n"); ++ return -1; ++ } ++ ++#ifdef CONFIG_BCM4710 ++ pcmcia_low_level=&bcm4710_pcmcia_ops; ++#else ++#error Unsupported Broadcom BCM47XX board. ++#endif ++ ++ pcmcia_init.handler=bcm47xx_pcmcia_interrupt; ++ ++ if ((socket_count = pcmcia_low_level->init(&pcmcia_init)) < 0) { ++ printk(KERN_ERR "Unable to initialize PCMCIA service.\n"); ++ return -EIO; ++ } else { ++ printk("\t%d PCMCIA sockets initialized.\n", socket_count); ++ } ++ ++ pcmcia_socket = ++ kmalloc(sizeof(struct bcm47xx_pcmcia_socket) * socket_count, ++ GFP_KERNEL); ++ memset(pcmcia_socket, 0, ++ sizeof(struct bcm47xx_pcmcia_socket) * socket_count); ++ if (!pcmcia_socket) { ++ printk(KERN_ERR "Card Services can't get memory \n"); ++ return -1; ++ } ++ ++ for (i = 0; i < socket_count; i++) { ++ if (pcmcia_low_level->socket_state(i, &state) < 0) { ++ printk(KERN_ERR "Unable to get PCMCIA status\n"); ++ return -EIO; ++ } ++ pcmcia_socket[i].k_state = state; ++ pcmcia_socket[i].cs_state.csc_mask = SS_DETECT; ++ ++ if (i == 0) { ++ pcmcia_socket[i].virt_io = ++ (unsigned long)ioremap_nocache(EXTIF_PCMCIA_IOBASE(BCM4710_EXTIF), 0x1000); ++ /* Substract ioport base which gets added by in/out */ ++ pcmcia_socket[i].virt_io -= mips_io_port_base; ++ pcmcia_socket[i].phys_attr = ++ (unsigned long)EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF); ++ pcmcia_socket[i].phys_mem = ++ (unsigned long)EXTIF_PCMCIA_MEMBASE(BCM4710_EXTIF); ++ } else { ++ printk(KERN_ERR "bcm4710: socket 1 not supported\n"); ++ return 1; ++ } ++ } ++ ++ /* Only advertise as many sockets as we can detect: */ ++ if (register_ss_entry(socket_count, &bcm47xx_pcmcia_operations) < 0) { ++ printk(KERN_ERR "Unable to register socket service routine\n"); ++ return -ENXIO; ++ } ++ ++ /* Start the event poll timer. ++ * It will reschedule by itself afterwards. ++ */ ++ bcm47xx_pcmcia_poll_event(0); ++ ++ DEBUG(1, "bcm4710: initialization complete\n"); ++ return 0; ++ ++} ++ ++module_init(bcm47xx_pcmcia_driver_init); ++ ++ ++/* ++ * bcm47xx_pcmcia_driver_shutdown() ++ * ++ * Invokes the low-level kernel service to free IRQs associated with this ++ * socket controller and reset GPIO edge detection. ++ */ ++static void __exit bcm47xx_pcmcia_driver_shutdown(void) ++{ ++ int i; ++ ++ del_timer_sync(&poll_timer); ++ unregister_ss_entry(&bcm47xx_pcmcia_operations); ++ pcmcia_low_level->shutdown(); ++ flush_scheduled_tasks(); ++ for (i = 0; i < socket_count; i++) { ++ if (pcmcia_socket[i].virt_io) ++ iounmap((void *)pcmcia_socket[i].virt_io); ++ if (pcmcia_socket[i].phys_attr) ++ iounmap((void *)pcmcia_socket[i].phys_attr); ++ if (pcmcia_socket[i].phys_mem) ++ iounmap((void *)pcmcia_socket[i].phys_mem); ++ } ++ DEBUG(1, "bcm4710: shutdown complete\n"); ++} ++ ++module_exit(bcm47xx_pcmcia_driver_shutdown); ++ ++/* ++ * bcm47xx_pcmcia_init() ++ * We perform all of the interesting initialization tasks in ++ * bcm47xx_pcmcia_driver_init(). ++ * ++ * Returns: 0 ++ */ ++static int bcm47xx_pcmcia_init(unsigned int sock) ++{ ++ DEBUG(1, "%s(): initializing socket %u\n", __FUNCTION__, sock); ++ ++ return 0; ++} ++ ++/* ++ * bcm47xx_pcmcia_suspend() ++ * ++ * We don't currently perform any actions on a suspend. ++ * ++ * Returns: 0 ++ */ ++static int bcm47xx_pcmcia_suspend(unsigned int sock) ++{ ++ DEBUG(1, "%s(): suspending socket %u\n", __FUNCTION__, sock); ++ ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_events() ++ * ++ * Helper routine to generate a Card Services event mask based on ++ * state information obtained from the kernel low-level PCMCIA layer ++ * in a recent (and previous) sampling. Updates `prev_state'. ++ * ++ * Returns: an event mask for the given socket state. ++ */ ++static inline unsigned ++bcm47xx_pcmcia_events(struct pcmcia_state *state, ++ struct pcmcia_state *prev_state, ++ unsigned int mask, unsigned int flags) ++{ ++ unsigned int events=0; ++ ++ if (state->bvd1 != prev_state->bvd1) { ++ ++ DEBUG(3, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1); ++ ++ events |= mask & (flags & SS_IOCARD) ? SS_STSCHG : SS_BATDEAD; ++ } ++ ++ if (state->bvd2 != prev_state->bvd2) { ++ ++ DEBUG(3, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2); ++ ++ events |= mask & (flags & SS_IOCARD) ? 0 : SS_BATWARN; ++ } ++ ++ if (state->detect != prev_state->detect) { ++ ++ DEBUG(3, "%s(): card detect value %u\n", __FUNCTION__, state->detect); ++ ++ events |= mask & SS_DETECT; ++ } ++ ++ ++ if (state->ready != prev_state->ready) { ++ ++ DEBUG(3, "%s(): card ready value %u\n", __FUNCTION__, state->ready); ++ ++ events |= mask & ((flags & SS_IOCARD) ? 0 : SS_READY); ++ } ++ ++ if (events != 0) { ++ DEBUG(2, "events: %s%s%s%s%s\n", ++ (events & SS_DETECT) ? "DETECT " : "", ++ (events & SS_READY) ? "READY " : "", ++ (events & SS_BATDEAD) ? "BATDEAD " : "", ++ (events & SS_BATWARN) ? "BATWARN " : "", ++ (events & SS_STSCHG) ? "STSCHG " : ""); ++ } ++ ++ *prev_state=*state; ++ return events; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_task_handler() ++ * ++ * Processes serviceable socket events using the "eventd" thread context. ++ * ++ * Event processing (specifically, the invocation of the Card Services event ++ * callback) occurs in this thread rather than in the actual interrupt ++ * handler due to the use of scheduling operations in the PCMCIA core. ++ */ ++static void bcm47xx_pcmcia_task_handler(void *data) ++{ ++ struct pcmcia_state state; ++ int i, events, irq_status; ++ ++ DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__); ++ ++ for (i = 0; i < socket_count; i++) { ++ if ((irq_status = pcmcia_low_level->socket_state(i, &state)) < 0) ++ printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n"); ++ ++ events = bcm47xx_pcmcia_events(&state, ++ &pcmcia_socket[i].k_state, ++ pcmcia_socket[i].cs_state.csc_mask, ++ pcmcia_socket[i].cs_state.flags); ++ ++ if (pcmcia_socket[i].handler != NULL) { ++ pcmcia_socket[i].handler(pcmcia_socket[i].handler_info, ++ events); ++ } ++ } ++} ++ ++static struct tq_struct bcm47xx_pcmcia_task = { ++ routine: bcm47xx_pcmcia_task_handler ++}; ++ ++ ++/* ++ * bcm47xx_pcmcia_poll_event() ++ * ++ * Let's poll for events in addition to IRQs since IRQ only is unreliable... ++ */ ++static void bcm47xx_pcmcia_poll_event(unsigned long dummy) ++{ ++ DEBUG(4, "%s(): polling for events\n", __FUNCTION__); ++ ++ poll_timer.function = bcm47xx_pcmcia_poll_event; ++ poll_timer.expires = jiffies + BCM47XX_PCMCIA_POLL_PERIOD; ++ add_timer(&poll_timer); ++ schedule_task(&bcm47xx_pcmcia_task); ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_interrupt() ++ * ++ * Service routine for socket driver interrupts (requested by the ++ * low-level PCMCIA init() operation via bcm47xx_pcmcia_thread()). ++ * ++ * The actual interrupt-servicing work is performed by ++ * bcm47xx_pcmcia_task(), largely because the Card Services event- ++ * handling code performs scheduling operations which cannot be ++ * executed from within an interrupt context. ++ */ ++static void ++bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs) ++{ ++ DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq); ++ schedule_task(&bcm47xx_pcmcia_task); ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_register_callback() ++ * ++ * Implements the register_callback() operation for the in-kernel ++ * PCMCIA service (formerly SS_RegisterCallback in Card Services). If ++ * the function pointer `handler' is not NULL, remember the callback ++ * location in the state for `sock', and increment the usage counter ++ * for the driver module. (The callback is invoked from the interrupt ++ * service routine, bcm47xx_pcmcia_interrupt(), to notify Card Services ++ * of interesting events.) Otherwise, clear the callback pointer in the ++ * socket state and decrement the module usage count. ++ * ++ * Returns: 0 ++ */ ++static int ++bcm47xx_pcmcia_register_callback(unsigned int sock, ++ void (*handler)(void *, unsigned int), void *info) ++{ ++ if (handler == NULL) { ++ pcmcia_socket[sock].handler = NULL; ++ MOD_DEC_USE_COUNT; ++ } else { ++ MOD_INC_USE_COUNT; ++ pcmcia_socket[sock].handler = handler; ++ pcmcia_socket[sock].handler_info = info; ++ } ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_inquire_socket() ++ * ++ * Implements the inquire_socket() operation for the in-kernel PCMCIA ++ * service (formerly SS_InquireSocket in Card Services). Of note is ++ * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of ++ * `cap' to "trick" Card Services into tolerating large "I/O memory" ++ * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory ++ * resource database check. (Mapped memory is set up within the socket ++ * driver itself.) ++ * ++ * In conjunction with the STATIC_MAP capability is a new field, ++ * `io_offset', recommended by David Hinds. Rather than go through ++ * the SetIOMap interface (which is not quite suited for communicating ++ * window locations up from the socket driver), we just pass up ++ * an offset which is applied to client-requested base I/O addresses ++ * in alloc_io_space(). ++ * ++ * Returns: 0 on success, -1 if no pin has been configured for `sock' ++ */ ++static int ++bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap) ++{ ++ struct pcmcia_irq_info irq_info; ++ ++ if (sock >= socket_count) { ++ printk(KERN_ERR "bcm47xx: socket %u not configured\n", sock); ++ return -1; ++ } ++ ++ /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the ++ * force_low argument to validate_mem() in rsrc_mgr.c -- since in ++ * general, the mapped * addresses of the PCMCIA memory regions ++ * will not be within 0xffff, setting force_low would be ++ * undesirable. ++ * ++ * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory ++ * resource database; we instead pass up physical address ranges ++ * and allow other parts of Card Services to deal with remapping. ++ * ++ * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but ++ * not 32-bit CardBus devices. ++ */ ++ cap->features = (SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD); ++ ++ irq_info.sock = sock; ++ irq_info.irq = -1; ++ ++ if (pcmcia_low_level->get_irq_info(&irq_info) < 0) { ++ printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock); ++ return -1; ++ } ++ ++ cap->irq_mask = 0; ++ cap->map_size = PAGE_SIZE; ++ cap->pci_irq = irq_info.irq; ++ cap->io_offset = pcmcia_socket[sock].virt_io; ++ ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_get_status() ++ * ++ * Implements the get_status() operation for the in-kernel PCMCIA ++ * service (formerly SS_GetStatus in Card Services). Essentially just ++ * fills in bits in `status' according to internal driver state or ++ * the value of the voltage detect chipselect register. ++ * ++ * As a debugging note, during card startup, the PCMCIA core issues ++ * three set_socket() commands in a row the first with RESET deasserted, ++ * the second with RESET asserted, and the last with RESET deasserted ++ * again. Following the third set_socket(), a get_status() command will ++ * be issued. The kernel is looking for the SS_READY flag (see ++ * setup_socket(), reset_socket(), and unreset_socket() in cs.c). ++ * ++ * Returns: 0 ++ */ ++static int ++bcm47xx_pcmcia_get_status(unsigned int sock, unsigned int *status) ++{ ++ struct pcmcia_state state; ++ ++ ++ if ((pcmcia_low_level->socket_state(sock, &state)) < 0) { ++ printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n"); ++ return -1; ++ } ++ ++ pcmcia_socket[sock].k_state = state; ++ ++ *status = state.detect ? SS_DETECT : 0; ++ ++ *status |= state.ready ? SS_READY : 0; ++ ++ /* The power status of individual sockets is not available ++ * explicitly from the hardware, so we just remember the state ++ * and regurgitate it upon request: ++ */ ++ *status |= pcmcia_socket[sock].cs_state.Vcc ? SS_POWERON : 0; ++ ++ if (pcmcia_socket[sock].cs_state.flags & SS_IOCARD) ++ *status |= state.bvd1 ? SS_STSCHG : 0; ++ else { ++ if (state.bvd1 == 0) ++ *status |= SS_BATDEAD; ++ else if (state.bvd2 == 0) ++ *status |= SS_BATWARN; ++ } ++ ++ *status |= state.vs_3v ? SS_3VCARD : 0; ++ ++ *status |= state.vs_Xv ? SS_XVCARD : 0; ++ ++ DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n", ++ (*status&SS_DETECT)?"DETECT ":"", ++ (*status&SS_READY)?"READY ":"", ++ (*status&SS_BATDEAD)?"BATDEAD ":"", ++ (*status&SS_BATWARN)?"BATWARN ":"", ++ (*status&SS_POWERON)?"POWERON ":"", ++ (*status&SS_STSCHG)?"STSCHG ":"", ++ (*status&SS_3VCARD)?"3VCARD ":"", ++ (*status&SS_XVCARD)?"XVCARD ":""); ++ ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_get_socket() ++ * ++ * Implements the get_socket() operation for the in-kernel PCMCIA ++ * service (formerly SS_GetSocket in Card Services). Not a very ++ * exciting routine. ++ * ++ * Returns: 0 ++ */ ++static int ++bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state) ++{ ++ DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock); ++ ++ /* This information was given to us in an earlier call to set_socket(), ++ * so we're just regurgitating it here: ++ */ ++ *state = pcmcia_socket[sock].cs_state; ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_set_socket() ++ * ++ * Implements the set_socket() operation for the in-kernel PCMCIA ++ * service (formerly SS_SetSocket in Card Services). We more or ++ * less punt all of this work and let the kernel handle the details ++ * of power configuration, reset, &c. We also record the value of ++ * `state' in order to regurgitate it to the PCMCIA core later. ++ * ++ * Returns: 0 ++ */ ++static int ++bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state) ++{ ++ struct pcmcia_configure configure; ++ ++ DEBUG(2, "\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n" ++ "\tVcc %d Vpp %d irq %d\n", ++ (state->csc_mask == 0) ? "" : "", ++ (state->csc_mask & SS_DETECT) ? "DETECT " : "", ++ (state->csc_mask & SS_READY) ? "READY " : "", ++ (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "", ++ (state->csc_mask & SS_BATWARN) ? "BATWARN " : "", ++ (state->csc_mask & SS_STSCHG) ? "STSCHG " : "", ++ (state->flags == 0) ? "" : "", ++ (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "", ++ (state->flags & SS_IOCARD) ? "IOCARD " : "", ++ (state->flags & SS_RESET) ? "RESET " : "", ++ (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "", ++ (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "", ++ state->Vcc, state->Vpp, state->io_irq); ++ ++ configure.sock = sock; ++ configure.vcc = state->Vcc; ++ configure.vpp = state->Vpp; ++ configure.output = (state->flags & SS_OUTPUT_ENA) ? 1 : 0; ++ configure.speaker = (state->flags & SS_SPKR_ENA) ? 1 : 0; ++ configure.reset = (state->flags & SS_RESET) ? 1 : 0; ++ ++ if (pcmcia_low_level->configure_socket(&configure) < 0) { ++ printk(KERN_ERR "Unable to configure socket %u\n", sock); ++ return -1; ++ } ++ ++ pcmcia_socket[sock].cs_state = *state; ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_get_io_map() ++ * ++ * Implements the get_io_map() operation for the in-kernel PCMCIA ++ * service (formerly SS_GetIOMap in Card Services). Just returns an ++ * I/O map descriptor which was assigned earlier by a set_io_map(). ++ * ++ * Returns: 0 on success, -1 if the map index was out of range ++ */ ++static int ++bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map) ++{ ++ DEBUG(2, "bcm47xx_pcmcia_get_io_map: sock %d\n", sock); ++ ++ if (map->map >= MAX_IO_WIN) { ++ printk(KERN_ERR "%s(): map (%d) out of range\n", ++ __FUNCTION__, map->map); ++ return -1; ++ } ++ ++ *map = pcmcia_socket[sock].io_map[map->map]; ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_set_io_map() ++ * ++ * Implements the set_io_map() operation for the in-kernel PCMCIA ++ * service (formerly SS_SetIOMap in Card Services). We configure ++ * the map speed as requested, but override the address ranges ++ * supplied by Card Services. ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++int ++bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map) ++{ ++ unsigned int speed; ++ unsigned long start; ++ ++ DEBUG(2, "\tmap %u speed %u\n\tstart 0x%08lx stop 0x%08lx\n" ++ "\tflags: %s%s%s%s%s%s%s%s\n", ++ map->map, map->speed, map->start, map->stop, ++ (map->flags == 0) ? "" : "", ++ (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", ++ (map->flags & MAP_16BIT) ? "16BIT " : "", ++ (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", ++ (map->flags & MAP_0WS) ? "0WS " : "", ++ (map->flags & MAP_WRPROT) ? "WRPROT " : "", ++ (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "", ++ (map->flags & MAP_PREFETCH) ? "PREFETCH " : ""); ++ ++ if (map->map >= MAX_IO_WIN) { ++ printk(KERN_ERR "%s(): map (%d) out of range\n", ++ __FUNCTION__, map->map); ++ return -1; ++ } ++ ++ if (map->flags & MAP_ACTIVE) { ++ speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_IO_SPEED; ++ pcmcia_socket[sock].speed_io = speed; ++ } ++ ++ start = map->start; ++ ++ if (map->stop == 1) { ++ map->stop = PAGE_SIZE - 1; ++ } ++ ++ map->start = pcmcia_socket[sock].virt_io; ++ map->stop = map->start + (map->stop - start); ++ pcmcia_socket[sock].io_map[map->map] = *map; ++ DEBUG(2, "set_io_map %d start %x stop %x\n", ++ map->map, map->start, map->stop); ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_get_mem_map() ++ * ++ * Implements the get_mem_map() operation for the in-kernel PCMCIA ++ * service (formerly SS_GetMemMap in Card Services). Just returns a ++ * memory map descriptor which was assigned earlier by a ++ * set_mem_map() request. ++ * ++ * Returns: 0 on success, -1 if the map index was out of range ++ */ ++static int ++bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map) ++{ ++ DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock); ++ ++ if (map->map >= MAX_WIN) { ++ printk(KERN_ERR "%s(): map (%d) out of range\n", ++ __FUNCTION__, map->map); ++ return -1; ++ } ++ ++ *map = pcmcia_socket[sock].mem_map[map->map]; ++ return 0; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_set_mem_map() ++ * ++ * Implements the set_mem_map() operation for the in-kernel PCMCIA ++ * service (formerly SS_SetMemMap in Card Services). We configure ++ * the map speed as requested, but override the address ranges ++ * supplied by Card Services. ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++static int ++bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map) ++{ ++ unsigned int speed; ++ unsigned long start; ++ u_long flags; ++ ++ if (map->map >= MAX_WIN) { ++ printk(KERN_ERR "%s(): map (%d) out of range\n", ++ __FUNCTION__, map->map); ++ return -1; ++ } ++ ++ DEBUG(2, "\tmap %u speed %u\n\tsys_start %#lx\n" ++ "\tsys_stop %#lx\n\tcard_start %#x\n" ++ "\tflags: %s%s%s%s%s%s%s%s\n", ++ map->map, map->speed, map->sys_start, map->sys_stop, ++ map->card_start, (map->flags == 0) ? "" : "", ++ (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", ++ (map->flags & MAP_16BIT) ? "16BIT " : "", ++ (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", ++ (map->flags & MAP_0WS) ? "0WS " : "", ++ (map->flags & MAP_WRPROT) ? "WRPROT " : "", ++ (map->flags & MAP_ATTRIB) ? "ATTRIB " : "", ++ (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : ""); ++ ++ if (map->flags & MAP_ACTIVE) { ++ /* When clients issue RequestMap, the access speed is not always ++ * properly configured: ++ */ ++ speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_MEM_SPEED; ++ ++ /* TBD */ ++ if (map->flags & MAP_ATTRIB) { ++ pcmcia_socket[sock].speed_attr = speed; ++ } else { ++ pcmcia_socket[sock].speed_mem = speed; ++ } ++ } ++ ++ save_flags(flags); ++ cli(); ++ start = map->sys_start; ++ ++ if (map->sys_stop == 0) ++ map->sys_stop = PAGE_SIZE - 1; ++ ++ if (map->flags & MAP_ATTRIB) { ++ map->sys_start = pcmcia_socket[sock].phys_attr + ++ map->card_start; ++ } else { ++ map->sys_start = pcmcia_socket[sock].phys_mem + ++ map->card_start; ++ } ++ ++ map->sys_stop = map->sys_start + (map->sys_stop - start); ++ pcmcia_socket[sock].mem_map[map->map] = *map; ++ restore_flags(flags); ++ DEBUG(2, "set_mem_map %d start %x stop %x card_start %x\n", ++ map->map, map->sys_start, map->sys_stop, ++ map->card_start); ++ return 0; ++} ++ ++ ++#if defined(CONFIG_PROC_FS) ++ ++/* ++ * bcm47xx_pcmcia_proc_setup() ++ * ++ * Implements the proc_setup() operation for the in-kernel PCMCIA ++ * service (formerly SS_ProcSetup in Card Services). ++ * ++ * Returns: 0 on success, -1 on error ++ */ ++static void ++bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base) ++{ ++ struct proc_dir_entry *entry; ++ ++ if ((entry = create_proc_entry("status", 0, base)) == NULL) { ++ printk(KERN_ERR "Unable to install \"status\" procfs entry\n"); ++ return; ++ } ++ ++ entry->read_proc = bcm47xx_pcmcia_proc_status; ++ entry->data = (void *)sock; ++} ++ ++ ++/* ++ * bcm47xx_pcmcia_proc_status() ++ * ++ * Implements the /proc/bus/pccard/??/status file. ++ * ++ * Returns: the number of characters added to the buffer ++ */ ++static int ++bcm47xx_pcmcia_proc_status(char *buf, char **start, off_t pos, ++ int count, int *eof, void *data) ++{ ++ char *p = buf; ++ unsigned int sock = (unsigned int)data; ++ ++ p += sprintf(p, "k_flags : %s%s%s%s%s%s%s\n", ++ pcmcia_socket[sock].k_state.detect ? "detect " : "", ++ pcmcia_socket[sock].k_state.ready ? "ready " : "", ++ pcmcia_socket[sock].k_state.bvd1 ? "bvd1 " : "", ++ pcmcia_socket[sock].k_state.bvd2 ? "bvd2 " : "", ++ pcmcia_socket[sock].k_state.wrprot ? "wrprot " : "", ++ pcmcia_socket[sock].k_state.vs_3v ? "vs_3v " : "", ++ pcmcia_socket[sock].k_state.vs_Xv ? "vs_Xv " : ""); ++ ++ p += sprintf(p, "status : %s%s%s%s%s%s%s%s%s\n", ++ pcmcia_socket[sock].k_state.detect ? "SS_DETECT " : "", ++ pcmcia_socket[sock].k_state.ready ? "SS_READY " : "", ++ pcmcia_socket[sock].cs_state.Vcc ? "SS_POWERON " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? "SS_IOCARD " : "", ++ (pcmcia_socket[sock].cs_state.flags & SS_IOCARD && ++ pcmcia_socket[sock].k_state.bvd1) ? "SS_STSCHG " : "", ++ ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 && ++ (pcmcia_socket[sock].k_state.bvd1 == 0)) ? "SS_BATDEAD " : "", ++ ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 && ++ (pcmcia_socket[sock].k_state.bvd2 == 0)) ? "SS_BATWARN " : "", ++ pcmcia_socket[sock].k_state.vs_3v ? "SS_3VCARD " : "", ++ pcmcia_socket[sock].k_state.vs_Xv ? "SS_XVCARD " : ""); ++ ++ p += sprintf(p, "mask : %s%s%s%s%s\n", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_DETECT ? "SS_DETECT " : "", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_READY ? "SS_READY " : "", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_BATDEAD ? "SS_BATDEAD " : "", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_BATWARN ? "SS_BATWARN " : "", ++ pcmcia_socket[sock].cs_state.csc_mask & SS_STSCHG ? "SS_STSCHG " : ""); ++ ++ p += sprintf(p, "cs_flags : %s%s%s%s%s\n", ++ pcmcia_socket[sock].cs_state.flags & SS_PWR_AUTO ? ++ "SS_PWR_AUTO " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? ++ "SS_IOCARD " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_RESET ? ++ "SS_RESET " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_SPKR_ENA ? ++ "SS_SPKR_ENA " : "", ++ pcmcia_socket[sock].cs_state.flags & SS_OUTPUT_ENA ? ++ "SS_OUTPUT_ENA " : ""); ++ ++ p += sprintf(p, "Vcc : %d\n", pcmcia_socket[sock].cs_state.Vcc); ++ p += sprintf(p, "Vpp : %d\n", pcmcia_socket[sock].cs_state.Vpp); ++ p += sprintf(p, "irq : %d\n", pcmcia_socket[sock].cs_state.io_irq); ++ p += sprintf(p, "I/O : %u\n", pcmcia_socket[sock].speed_io); ++ p += sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr); ++ p += sprintf(p, "common : %u\n", pcmcia_socket[sock].speed_mem); ++ return p-buf; ++} ++ ++ ++#endif /* defined(CONFIG_PROC_FS) */ +diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c +--- linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c 2005-12-16 23:39:11.368863250 +0100 +@@ -0,0 +1,266 @@ ++/* ++ * BCM4710 specific pcmcia routines. ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: bcm4710_pcmcia.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "cs_internal.h" ++ ++#include ++#include ++#include ++ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "bcm4710pcmcia.h" ++ ++/* Use a static var for irq dev_id */ ++static int bcm47xx_pcmcia_dev_id; ++ ++/* Do we think we have a card or not? */ ++static int bcm47xx_pcmcia_present = 0; ++ ++ ++static void bcm4710_pcmcia_reset(void) ++{ ++ extifregs_t *eir; ++ unsigned long s; ++ uint32 out0, out1, outen; ++ ++ ++ eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t)); ++ ++ save_and_cli(s); ++ ++ /* Use gpio7 to reset the pcmcia slot */ ++ outen = readl(&eir->gpio[0].outen); ++ outen |= BCM47XX_PCMCIA_RESET; ++ out0 = readl(&eir->gpio[0].out); ++ out0 &= ~(BCM47XX_PCMCIA_RESET); ++ out1 = out0 | BCM47XX_PCMCIA_RESET; ++ ++ writel(out0, &eir->gpio[0].out); ++ writel(outen, &eir->gpio[0].outen); ++ mdelay(1); ++ writel(out1, &eir->gpio[0].out); ++ mdelay(1); ++ writel(out0, &eir->gpio[0].out); ++ ++ restore_flags(s); ++} ++ ++ ++static int bcm4710_pcmcia_init(struct pcmcia_init *init) ++{ ++ struct pci_dev *pdev; ++ extifregs_t *eir; ++ uint32 outen, intp, intm, tmp; ++ uint16 *attrsp; ++ int rc = 0, i; ++ extern unsigned long bcm4710_cpu_cycle; ++ ++ ++ if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_EXTIF, NULL))) { ++ printk(KERN_ERR "bcm4710_pcmcia: extif not found\n"); ++ return -ENODEV; ++ } ++ eir = (extifregs_t *) ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); ++ ++ /* Initialize the pcmcia i/f: 16bit no swap */ ++ writel(CF_EM_PCMCIA | CF_DS | CF_EN, &eir->pcmcia_config); ++ ++#ifdef notYet ++ ++ /* Set the timing for memory accesses */ ++ tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */ ++ tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */ ++ tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */ ++ tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */ ++ writel(tmp, &eir->pcmcia_memwait); /* 0x01020a0c for a 100Mhz clock */ ++ ++ /* Set the timing for I/O accesses */ ++ tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */ ++ tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */ ++ tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */ ++ tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */ ++ writel(tmp, &eir->pcmcia_iowait); /* 0x01020a0c for a 100Mhz clock */ ++ ++ /* Set the timing for attribute accesses */ ++ tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */ ++ tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */ ++ tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */ ++ tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */ ++ writel(tmp, &eir->pcmcia_attrwait); /* 0x01020a0c for a 100Mhz clock */ ++ ++#endif ++ /* Make sure gpio0 and gpio5 are inputs */ ++ outen = readl(&eir->gpio[0].outen); ++ outen &= ~(BCM47XX_PCMCIA_WP | BCM47XX_PCMCIA_STSCHG | BCM47XX_PCMCIA_RESET); ++ writel(outen, &eir->gpio[0].outen); ++ ++ /* Issue a reset to the pcmcia socket */ ++ bcm4710_pcmcia_reset(); ++ ++#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS ++ /* Setup gpio5 to be the STSCHG interrupt */ ++ intp = readl(&eir->gpiointpolarity); ++ writel(intp | BCM47XX_PCMCIA_STSCHG, &eir->gpiointpolarity); /* Active low */ ++ intm = readl(&eir->gpiointmask); ++ writel(intm | BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Enable it */ ++#endif ++ ++ DEBUG(2, "bcm4710_pcmcia after reset:\n"); ++ DEBUG(2, "\textstatus\t= 0x%08x:\n", readl(&eir->extstatus)); ++ DEBUG(2, "\tpcmcia_config\t= 0x%08x:\n", readl(&eir->pcmcia_config)); ++ DEBUG(2, "\tpcmcia_memwait\t= 0x%08x:\n", readl(&eir->pcmcia_memwait)); ++ DEBUG(2, "\tpcmcia_attrwait\t= 0x%08x:\n", readl(&eir->pcmcia_attrwait)); ++ DEBUG(2, "\tpcmcia_iowait\t= 0x%08x:\n", readl(&eir->pcmcia_iowait)); ++ DEBUG(2, "\tgpioin\t\t= 0x%08x:\n", readl(&eir->gpioin)); ++ DEBUG(2, "\tgpio_outen0\t= 0x%08x:\n", readl(&eir->gpio[0].outen)); ++ DEBUG(2, "\tgpio_out0\t= 0x%08x:\n", readl(&eir->gpio[0].out)); ++ DEBUG(2, "\tgpiointpolarity\t= 0x%08x:\n", readl(&eir->gpiointpolarity)); ++ DEBUG(2, "\tgpiointmask\t= 0x%08x:\n", readl(&eir->gpiointmask)); ++ ++#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS ++ /* Request pcmcia interrupt */ ++ rc = request_irq(BCM47XX_PCMCIA_IRQ, init->handler, SA_INTERRUPT, ++ "PCMCIA Interrupt", &bcm47xx_pcmcia_dev_id); ++#endif ++ ++ attrsp = (uint16 *)ioremap_nocache(EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF), 0x1000); ++ tmp = readw(&attrsp[0]); ++ DEBUG(2, "\tattr[0] = 0x%04x\n", tmp); ++ if ((tmp == 0x7fff) || (tmp == 0x7f00)) { ++ bcm47xx_pcmcia_present = 0; ++ } else { ++ bcm47xx_pcmcia_present = 1; ++ } ++ ++ /* There's only one socket */ ++ return 1; ++} ++ ++static int bcm4710_pcmcia_shutdown(void) ++{ ++ extifregs_t *eir; ++ uint32 intm; ++ ++ eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t)); ++ ++ /* Disable the pcmcia i/f */ ++ writel(0, &eir->pcmcia_config); ++ ++ /* Reset gpio's */ ++ intm = readl(&eir->gpiointmask); ++ writel(intm & ~BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Disable it */ ++ ++ free_irq(BCM47XX_PCMCIA_IRQ, &bcm47xx_pcmcia_dev_id); ++ ++ return 0; ++} ++ ++static int ++bcm4710_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) ++{ ++ extifregs_t *eir; ++ ++ eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t)); ++ ++ ++ if (sock != 0) { ++ printk(KERN_ERR "bcm4710 socket_state bad sock %d\n", sock); ++ return -1; ++ } ++ ++ if (bcm47xx_pcmcia_present) { ++ state->detect = 1; ++ state->ready = 1; ++ state->bvd1 = 1; ++ state->bvd2 = 1; ++ state->wrprot = (readl(&eir->gpioin) & BCM47XX_PCMCIA_WP) == BCM47XX_PCMCIA_WP; ++ state->vs_3v = 0; ++ state->vs_Xv = 0; ++ } else { ++ state->detect = 0; ++ state->ready = 0; ++ } ++ ++ return 1; ++} ++ ++ ++static int bcm4710_pcmcia_get_irq_info(struct pcmcia_irq_info *info) ++{ ++ if (info->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1; ++ ++ info->irq = BCM47XX_PCMCIA_IRQ; ++ ++ return 0; ++} ++ ++ ++static int ++bcm4710_pcmcia_configure_socket(const struct pcmcia_configure *configure) ++{ ++ if (configure->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1; ++ ++ ++ DEBUG(2, "Vcc %dV Vpp %dV output %d speaker %d reset %d\n", configure->vcc, ++ configure->vpp, configure->output, configure->speaker, configure->reset); ++ ++ if ((configure->vcc != 50) || (configure->vpp != 50)) { ++ printk("%s: bad Vcc/Vpp (%d:%d)\n", __FUNCTION__, configure->vcc, ++ configure->vpp); ++ } ++ ++ if (configure->reset) { ++ /* Issue a reset to the pcmcia socket */ ++ DEBUG(1, "%s: Reseting socket\n", __FUNCTION__); ++ bcm4710_pcmcia_reset(); ++ } ++ ++ ++ return 0; ++} ++ ++struct pcmcia_low_level bcm4710_pcmcia_ops = { ++ bcm4710_pcmcia_init, ++ bcm4710_pcmcia_shutdown, ++ bcm4710_pcmcia_socket_state, ++ bcm4710_pcmcia_get_irq_info, ++ bcm4710_pcmcia_configure_socket ++}; ++ +diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h +--- linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h 2005-12-16 23:39:11.368863250 +0100 +@@ -0,0 +1,118 @@ ++/* ++ * ++ * bcm47xx pcmcia driver ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * Based on sa1100.h and include/asm-arm/arch-sa1100/pcmica.h ++ * from www.handhelds.org, ++ * and au1000_generic.c from oss.sgi.com. ++ * ++ * $Id: bcm4710pcmcia.h,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ ++ ++#if !defined(_BCM4710PCMCIA_H) ++#define _BCM4710PCMCIA_H ++ ++#include ++#include ++#include ++#include ++#include "cs_internal.h" ++ ++ ++/* The 47xx can only support one socket */ ++#define BCM47XX_PCMCIA_MAX_SOCK 1 ++ ++/* In the bcm947xx gpio's are used for some pcmcia functions */ ++#define BCM47XX_PCMCIA_WP 0x01 /* Bit 0 is WP input */ ++#define BCM47XX_PCMCIA_STSCHG 0x20 /* Bit 5 is STSCHG input/interrupt */ ++#define BCM47XX_PCMCIA_RESET 0x80 /* Bit 7 is RESET */ ++ ++#define BCM47XX_PCMCIA_IRQ 2 ++ ++/* The socket driver actually works nicely in interrupt-driven form, ++ * so the (relatively infrequent) polling is "just to be sure." ++ */ ++#define BCM47XX_PCMCIA_POLL_PERIOD (2 * HZ) ++ ++#define BCM47XX_PCMCIA_IO_SPEED (255) ++#define BCM47XX_PCMCIA_MEM_SPEED (300) ++ ++ ++struct pcmcia_state { ++ unsigned detect: 1, ++ ready: 1, ++ bvd1: 1, ++ bvd2: 1, ++ wrprot: 1, ++ vs_3v: 1, ++ vs_Xv: 1; ++}; ++ ++ ++struct pcmcia_configure { ++ unsigned sock: 8, ++ vcc: 8, ++ vpp: 8, ++ output: 1, ++ speaker: 1, ++ reset: 1; ++}; ++ ++struct pcmcia_irq_info { ++ unsigned int sock; ++ unsigned int irq; ++}; ++ ++/* This structure encapsulates per-socket state which we might need to ++ * use when responding to a Card Services query of some kind. ++ */ ++struct bcm47xx_pcmcia_socket { ++ socket_state_t cs_state; ++ struct pcmcia_state k_state; ++ unsigned int irq; ++ void (*handler)(void *, unsigned int); ++ void *handler_info; ++ pccard_io_map io_map[MAX_IO_WIN]; ++ pccard_mem_map mem_map[MAX_WIN]; ++ ioaddr_t virt_io, phys_attr, phys_mem; ++ unsigned short speed_io, speed_attr, speed_mem; ++}; ++ ++struct pcmcia_init { ++ void (*handler)(int irq, void *dev, struct pt_regs *regs); ++}; ++ ++struct pcmcia_low_level { ++ int (*init)(struct pcmcia_init *); ++ int (*shutdown)(void); ++ int (*socket_state)(unsigned sock, struct pcmcia_state *); ++ int (*get_irq_info)(struct pcmcia_irq_info *); ++ int (*configure_socket)(const struct pcmcia_configure *); ++}; ++ ++extern struct pcmcia_low_level bcm47xx_pcmcia_ops; ++ ++/* I/O pins replacing memory pins ++ * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75) ++ * ++ * These signals change meaning when going from memory-only to ++ * memory-or-I/O interface: ++ */ ++#define iostschg bvd1 ++#define iospkr bvd2 ++ ++ ++/* ++ * Declaration for implementation specific low_level operations. ++ */ ++extern struct pcmcia_low_level bcm4710_pcmcia_ops; ++ ++#endif /* !defined(_BCM4710PCMCIA_H) */ +diff -Nur linux-2.4.32/drivers/pcmcia/Makefile linux-2.4.32-brcm/drivers/pcmcia/Makefile +--- linux-2.4.32/drivers/pcmcia/Makefile 2004-02-18 14:36:31.000000000 +0100 ++++ linux-2.4.32-brcm/drivers/pcmcia/Makefile 2005-12-16 23:39:11.364863000 +0100 +@@ -65,6 +65,10 @@ + au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00) += au1000_db1x00.o + au1000_ss-objs-$(CONFIG_PCMCIA_XXS1500) += au1000_xxs1500.o + ++obj-$(CONFIG_PCMCIA_BCM4710) += bcm4710_ss.o ++bcm4710_ss-objs := bcm4710_generic.o ++bcm4710_ss-objs += bcm4710_pcmcia.o ++ + obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o + obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o + obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o +@@ -102,5 +106,8 @@ + au1x00_ss.o: $(au1000_ss-objs-y) + $(LD) -r -o $@ $(au1000_ss-objs-y) + ++bcm4710_ss.o: $(bcm4710_ss-objs) ++ $(LD) -r -o $@ $(bcm4710_ss-objs) ++ + yenta_socket.o: $(yenta_socket-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs) +diff -Nur linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32-brcm/include/asm-mips/bootinfo.h +--- linux-2.4.32/include/asm-mips/bootinfo.h 2004-02-18 14:36:32.000000000 +0100 ++++ linux-2.4.32-brcm/include/asm-mips/bootinfo.h 2005-12-16 23:39:11.400865250 +0100 +@@ -37,6 +37,7 @@ + #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ + #define MACH_GROUP_LASAT 21 + #define MACH_GROUP_TITAN 22 /* PMC-Sierra Titan */ ++#define MACH_GROUP_BRCM 23 /* Broadcom */ + + /* + * Valid machtype values for group unknown (low order halfword of mips_machtype) +@@ -194,6 +195,15 @@ + #define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */ + + /* ++ * Valid machtypes for group Broadcom ++ */ ++#define MACH_BCM93725 0 ++#define MACH_BCM93725_VJ 1 ++#define MACH_BCM93730 2 ++#define MACH_BCM947XX 3 ++#define MACH_BCM933XX 4 ++ ++/* + * Valid machtype for group TITAN + */ + #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ +diff -Nur linux-2.4.32/include/asm-mips/cpu.h linux-2.4.32-brcm/include/asm-mips/cpu.h +--- linux-2.4.32/include/asm-mips/cpu.h 2005-01-19 15:10:11.000000000 +0100 ++++ linux-2.4.32-brcm/include/asm-mips/cpu.h 2005-12-16 23:39:11.412866000 +0100 +@@ -22,6 +22,11 @@ + spec. + */ + ++#define PRID_COPT_MASK 0xff000000 ++#define PRID_COMP_MASK 0x00ff0000 ++#define PRID_IMP_MASK 0x0000ff00 ++#define PRID_REV_MASK 0x000000ff ++ + #define PRID_COMP_LEGACY 0x000000 + #define PRID_COMP_MIPS 0x010000 + #define PRID_COMP_BROADCOM 0x020000 +@@ -58,6 +63,7 @@ + #define PRID_IMP_RM7000 0x2700 + #define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ + #define PRID_IMP_RM9000 0x3400 ++#define PRID_IMP_BCM4710 0x4000 + #define PRID_IMP_R5432 0x5400 + #define PRID_IMP_R5500 0x5500 + #define PRID_IMP_4KC 0x8000 +@@ -66,10 +72,16 @@ + #define PRID_IMP_4KEC 0x8400 + #define PRID_IMP_4KSC 0x8600 + #define PRID_IMP_25KF 0x8800 ++#define PRID_IMP_BCM3302 0x9000 ++#define PRID_IMP_BCM3303 0x9100 + #define PRID_IMP_24K 0x9300 + + #define PRID_IMP_UNKNOWN 0xff00 + ++#define BCM330X(id) \ ++ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \ ++ || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) ++ + /* + * These are the PRID's for when 23:16 == PRID_COMP_SIBYTE + */ +@@ -174,7 +186,9 @@ + #define CPU_AU1550 57 + #define CPU_24K 58 + #define CPU_AU1200 59 +-#define CPU_LAST 59 ++#define CPU_BCM4710 60 ++#define CPU_BCM3302 61 ++#define CPU_LAST 61 + + /* + * ISA Level encodings +diff -Nur linux-2.4.32/include/asm-mips/r4kcache.h linux-2.4.32-brcm/include/asm-mips/r4kcache.h +--- linux-2.4.32/include/asm-mips/r4kcache.h 2004-02-18 14:36:32.000000000 +0100 ++++ linux-2.4.32-brcm/include/asm-mips/r4kcache.h 2005-12-16 23:39:11.416866250 +0100 +@@ -567,4 +567,17 @@ + cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); + } + ++extern inline void fill_icache_line(unsigned long addr) ++{ ++ __asm__ __volatile__( ++ ".set noreorder\n\t" ++ ".set mips3\n\t" ++ "cache %1, (%0)\n\t" ++ ".set mips0\n\t" ++ ".set reorder" ++ : ++ : "r" (addr), ++ "i" (Fill)); ++} ++ + #endif /* __ASM_R4KCACHE_H */ +diff -Nur linux-2.4.32/include/asm-mips/serial.h linux-2.4.32-brcm/include/asm-mips/serial.h +--- linux-2.4.32/include/asm-mips/serial.h 2005-01-19 15:10:12.000000000 +0100 ++++ linux-2.4.32-brcm/include/asm-mips/serial.h 2005-12-16 23:39:11.428867000 +0100 +@@ -223,6 +223,13 @@ + #define TXX927_SERIAL_PORT_DEFNS + #endif + ++#ifdef CONFIG_BCM947XX ++/* reserve 4 ports to be configured at runtime */ ++#define BCM947XX_SERIAL_PORT_DEFNS { 0, }, { 0, }, { 0, }, { 0, }, ++#else ++#define BCM947XX_SERIAL_PORT_DEFNS ++#endif ++ + #ifdef CONFIG_HAVE_STD_PC_SERIAL_PORT + #define STD_SERIAL_PORT_DEFNS \ + /* UART CLK PORT IRQ FLAGS */ \ +@@ -470,6 +477,7 @@ + #define SERIAL_PORT_DFNS \ + ATLAS_SERIAL_PORT_DEFNS \ + AU1000_SERIAL_PORT_DEFNS \ ++ BCM947XX_SERIAL_PORT_DEFNS \ + COBALT_SERIAL_PORT_DEFNS \ + DDB5477_SERIAL_PORT_DEFNS \ + EV96100_SERIAL_PORT_DEFNS \ +diff -Nur linux-2.4.32/init/do_mounts.c linux-2.4.32-brcm/init/do_mounts.c +--- linux-2.4.32/init/do_mounts.c 2003-11-28 19:26:21.000000000 +0100 ++++ linux-2.4.32-brcm/init/do_mounts.c 2005-12-16 23:39:11.504871750 +0100 +@@ -253,7 +253,13 @@ + { "ftlb", 0x2c08 }, + { "ftlc", 0x2c10 }, + { "ftld", 0x2c18 }, ++#if defined(CONFIG_MTD_BLOCK) || defined(CONFIG_MTD_BLOCK_RO) + { "mtdblock", 0x1f00 }, ++ { "mtdblock0",0x1f00 }, ++ { "mtdblock1",0x1f01 }, ++ { "mtdblock2",0x1f02 }, ++ { "mtdblock3",0x1f03 }, ++#endif + { "nb", 0x2b00 }, + { NULL, 0 } + }; -- cgit v1.2.3 From 584258d442d423627b075574d102427de35ce6b9 Mon Sep 17 00:00:00 2001 From: nbd Date: Sun, 19 Mar 2006 05:20:55 +0000 Subject: clean up brcm-2.4 system code git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@3410 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/brcm-2.4/patches/001-bcm47xx.patch | 7268 +++++------------------ 1 file changed, 1607 insertions(+), 5661 deletions(-) (limited to 'target/linux/brcm-2.4/patches/001-bcm47xx.patch') diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch index 9d919156b6..2e64b0fc3e 100644 --- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch +++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -1194,433 +1194,6 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h linux-2.4.32-brcm/ +) + +#endif /* _BCMENDIAN_H_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenet47xx.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmenet47xx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenet47xx.h 2005-12-16 23:39:10.700821500 +0100 -@@ -0,0 +1,229 @@ -+/* -+ * Hardware-specific definitions for -+ * Broadcom BCM47XX 10/100 Mbps Ethernet cores. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; -+ * the contents of this file may not be disclosed to third parties, copied -+ * or duplicated in any form, in whole or in part, without the prior -+ * written permission of Broadcom Corporation. -+ * $Id$ -+ */ -+ -+#ifndef _bcmenet_47xx_h_ -+#define _bcmenet_47xx_h_ -+ -+#include -+#include -+#include -+ -+#define BCMENET_NFILTERS 64 /* # ethernet address filter entries */ -+#define BCMENET_MCHASHBASE 0x200 /* multicast hash filter base address */ -+#define BCMENET_MCHASHSIZE 256 /* multicast hash filter size in bytes */ -+#define BCMENET_MAX_DMA 4096 /* chip has 12 bits of DMA addressing */ -+ -+/* power management event wakeup pattern constants */ -+#define BCMENET_NPMP 4 /* chip supports 4 wakeup patterns */ -+#define BCMENET_PMPBASE 0x400 /* wakeup pattern base address */ -+#define BCMENET_PMPSIZE 0x80 /* 128bytes each pattern */ -+#define BCMENET_PMMBASE 0x600 /* wakeup mask base address */ -+#define BCMENET_PMMSIZE 0x10 /* 128bits each mask */ -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+/* -+ * Host Interface Registers -+ */ -+typedef volatile struct _bcmenettregs { -+ /* Device and Power Control */ -+ uint32 devcontrol; -+ uint32 PAD[2]; -+ uint32 biststatus; -+ uint32 wakeuplength; -+ uint32 PAD[3]; -+ -+ /* Interrupt Control */ -+ uint32 intstatus; -+ uint32 intmask; -+ uint32 gptimer; -+ uint32 PAD[23]; -+ -+ /* Ethernet MAC Address Filtering Control */ -+ uint32 PAD[2]; -+ uint32 enetftaddr; -+ uint32 enetftdata; -+ uint32 PAD[2]; -+ -+ /* Ethernet MAC Control */ -+ uint32 emactxmaxburstlen; -+ uint32 emacrxmaxburstlen; -+ uint32 emaccontrol; -+ uint32 emacflowcontrol; -+ -+ uint32 PAD[20]; -+ -+ /* DMA Lazy Interrupt Control */ -+ uint32 intrecvlazy; -+ uint32 PAD[63]; -+ -+ /* DMA engine */ -+ dma32regp_t dmaregs; -+ dma32diag_t dmafifo; -+ uint32 PAD[116]; -+ -+ /* EMAC Registers */ -+ uint32 rxconfig; -+ uint32 rxmaxlength; -+ uint32 txmaxlength; -+ uint32 PAD; -+ uint32 mdiocontrol; -+ uint32 mdiodata; -+ uint32 emacintmask; -+ uint32 emacintstatus; -+ uint32 camdatalo; -+ uint32 camdatahi; -+ uint32 camcontrol; -+ uint32 enetcontrol; -+ uint32 txcontrol; -+ uint32 txwatermark; -+ uint32 mibcontrol; -+ uint32 PAD[49]; -+ -+ /* EMAC MIB counters */ -+ bcmenetmib_t mib; -+ -+ uint32 PAD[585]; -+ -+ /* Sonics SiliconBackplane config registers */ -+ sbconfig_t sbconfig; -+} bcmenetregs_t; -+ -+/* device control */ -+#define DC_PM ((uint32)1 << 7) /* pattern filtering enable */ -+#define DC_IP ((uint32)1 << 10) /* internal ephy present (rev >= 1) */ -+#define DC_ER ((uint32)1 << 15) /* ephy reset */ -+#define DC_MP ((uint32)1 << 16) /* mii phy mode enable */ -+#define DC_CO ((uint32)1 << 17) /* mii phy mode: enable clocks */ -+#define DC_PA_MASK 0x7c0000 /* mii phy mode: mdc/mdio phy address */ -+#define DC_PA_SHIFT 18 -+#define DC_FS_MASK 0x03800000 /* fifo size (rev >= 8) */ -+#define DC_FS_SHIFT 23 -+#define DC_FS_4K 0 /* 4Kbytes */ -+#define DC_FS_512 1 /* 512bytes */ -+ -+/* wakeup length */ -+#define WL_P0_MASK 0x7f /* pattern 0 */ -+#define WL_D0 ((uint32)1 << 7) -+#define WL_P1_MASK 0x7f00 /* pattern 1 */ -+#define WL_P1_SHIFT 8 -+#define WL_D1 ((uint32)1 << 15) -+#define WL_P2_MASK 0x7f0000 /* pattern 2 */ -+#define WL_P2_SHIFT 16 -+#define WL_D2 ((uint32)1 << 23) -+#define WL_P3_MASK 0x7f000000 /* pattern 3 */ -+#define WL_P3_SHIFT 24 -+#define WL_D3 ((uint32)1 << 31) -+ -+/* intstatus and intmask */ -+#define I_PME ((uint32)1 << 6) /* power management event */ -+#define I_TO ((uint32)1 << 7) /* general purpose timeout */ -+#define I_PC ((uint32)1 << 10) /* descriptor error */ -+#define I_PD ((uint32)1 << 11) /* data error */ -+#define I_DE ((uint32)1 << 12) /* descriptor protocol error */ -+#define I_RU ((uint32)1 << 13) /* receive descriptor underflow */ -+#define I_RO ((uint32)1 << 14) /* receive fifo overflow */ -+#define I_XU ((uint32)1 << 15) /* transmit fifo underflow */ -+#define I_RI ((uint32)1 << 16) /* receive interrupt */ -+#define I_XI ((uint32)1 << 24) /* transmit interrupt */ -+#define I_EM ((uint32)1 << 26) /* emac interrupt */ -+#define I_MW ((uint32)1 << 27) /* mii write */ -+#define I_MR ((uint32)1 << 28) /* mii read */ -+ -+/* emaccontrol */ -+#define EMC_CG ((uint32)1 << 0) /* crc32 generation enable */ -+#define EMC_EP ((uint32)1 << 2) /* onchip ephy: powerdown (rev >= 1) */ -+#define EMC_ED ((uint32)1 << 3) /* onchip ephy: energy detected (rev >= 1) */ -+#define EMC_LC_MASK 0xe0 /* onchip ephy: led control (rev >= 1) */ -+#define EMC_LC_SHIFT 5 -+ -+/* emacflowcontrol */ -+#define EMF_RFH_MASK 0xff /* rx fifo hi water mark */ -+#define EMF_PG ((uint32)1 << 15) /* enable pause frame generation */ -+ -+/* interrupt receive lazy */ -+#define IRL_TO_MASK 0x00ffffff /* timeout */ -+#define IRL_FC_MASK 0xff000000 /* frame count */ -+#define IRL_FC_SHIFT 24 /* frame count */ -+ -+/* emac receive config */ -+#define ERC_DB ((uint32)1 << 0) /* disable broadcast */ -+#define ERC_AM ((uint32)1 << 1) /* accept all multicast */ -+#define ERC_RDT ((uint32)1 << 2) /* receive disable while transmitting */ -+#define ERC_PE ((uint32)1 << 3) /* promiscuous enable */ -+#define ERC_LE ((uint32)1 << 4) /* loopback enable */ -+#define ERC_FE ((uint32)1 << 5) /* enable flow control */ -+#define ERC_UF ((uint32)1 << 6) /* accept unicast flow control frame */ -+#define ERC_RF ((uint32)1 << 7) /* reject filter */ -+#define ERC_CA ((uint32)1 << 8) /* cam absent */ -+ -+/* emac mdio control */ -+#define MC_MF_MASK 0x7f /* mdc frequency */ -+#define MC_PE ((uint32)1 << 7) /* mii preamble enable */ -+ -+/* emac mdio data */ -+#define MD_DATA_MASK 0xffff /* r/w data */ -+#define MD_TA_MASK 0x30000 /* turnaround value */ -+#define MD_TA_SHIFT 16 -+#define MD_TA_VALID (2 << MD_TA_SHIFT) /* valid ta */ -+#define MD_RA_MASK 0x7c0000 /* register address */ -+#define MD_RA_SHIFT 18 -+#define MD_PMD_MASK 0xf800000 /* physical media device */ -+#define MD_PMD_SHIFT 23 -+#define MD_OP_MASK 0x30000000 /* opcode */ -+#define MD_OP_SHIFT 28 -+#define MD_OP_WRITE (1 << MD_OP_SHIFT) /* write op */ -+#define MD_OP_READ (2 << MD_OP_SHIFT) /* read op */ -+#define MD_SB_MASK 0xc0000000 /* start bits */ -+#define MD_SB_SHIFT 30 -+#define MD_SB_START (0x1 << MD_SB_SHIFT) /* start of frame */ -+ -+/* emac intstatus and intmask */ -+#define EI_MII ((uint32)1 << 0) /* mii mdio interrupt */ -+#define EI_MIB ((uint32)1 << 1) /* mib interrupt */ -+#define EI_FLOW ((uint32)1 << 2) /* flow control interrupt */ -+ -+/* emac cam data high */ -+#define CD_V ((uint32)1 << 16) /* valid bit */ -+ -+/* emac cam control */ -+#define CC_CE ((uint32)1 << 0) /* cam enable */ -+#define CC_MS ((uint32)1 << 1) /* mask select */ -+#define CC_RD ((uint32)1 << 2) /* read */ -+#define CC_WR ((uint32)1 << 3) /* write */ -+#define CC_INDEX_MASK 0x3f0000 /* index */ -+#define CC_INDEX_SHIFT 16 -+#define CC_CB ((uint32)1 << 31) /* cam busy */ -+ -+/* emac ethernet control */ -+#define EC_EE ((uint32)1 << 0) /* emac enable */ -+#define EC_ED ((uint32)1 << 1) /* emac disable */ -+#define EC_ES ((uint32)1 << 2) /* emac soft reset */ -+#define EC_EP ((uint32)1 << 3) /* external phy select */ -+ -+/* emac transmit control */ -+#define EXC_FD ((uint32)1 << 0) /* full duplex */ -+#define EXC_FM ((uint32)1 << 1) /* flowmode */ -+#define EXC_SB ((uint32)1 << 2) /* single backoff enable */ -+#define EXC_SS ((uint32)1 << 3) /* small slottime */ -+ -+/* emac mib control */ -+#define EMC_RZ ((uint32)1 << 0) /* autoclear on read */ -+ -+#endif /* _bcmenet_47xx_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenetmib.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetmib.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmenetmib.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetmib.h 2005-12-16 23:39:10.700821500 +0100 -@@ -0,0 +1,81 @@ -+/* -+ * Hardware-specific MIB definition for -+ * Broadcom Home Networking Division -+ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; -+ * the contents of this file may not be disclosed to third parties, copied -+ * or duplicated in any form, in whole or in part, without the prior -+ * written permission of Broadcom Corporation. -+ * $Id$ -+ */ -+ -+#ifndef _bcmenetmib_h_ -+#define _bcmenetmib_h_ -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+/* -+ * EMAC MIB Registers -+ */ -+typedef volatile struct { -+ uint32 tx_good_octets; -+ uint32 tx_good_pkts; -+ uint32 tx_octets; -+ uint32 tx_pkts; -+ uint32 tx_broadcast_pkts; -+ uint32 tx_multicast_pkts; -+ uint32 tx_len_64; -+ uint32 tx_len_65_to_127; -+ uint32 tx_len_128_to_255; -+ uint32 tx_len_256_to_511; -+ uint32 tx_len_512_to_1023; -+ uint32 tx_len_1024_to_max; -+ uint32 tx_jabber_pkts; -+ uint32 tx_oversize_pkts; -+ uint32 tx_fragment_pkts; -+ uint32 tx_underruns; -+ uint32 tx_total_cols; -+ uint32 tx_single_cols; -+ uint32 tx_multiple_cols; -+ uint32 tx_excessive_cols; -+ uint32 tx_late_cols; -+ uint32 tx_defered; -+ uint32 tx_carrier_lost; -+ uint32 tx_pause_pkts; -+ uint32 PAD[8]; -+ -+ uint32 rx_good_octets; -+ uint32 rx_good_pkts; -+ uint32 rx_octets; -+ uint32 rx_pkts; -+ uint32 rx_broadcast_pkts; -+ uint32 rx_multicast_pkts; -+ uint32 rx_len_64; -+ uint32 rx_len_65_to_127; -+ uint32 rx_len_128_to_255; -+ uint32 rx_len_256_to_511; -+ uint32 rx_len_512_to_1023; -+ uint32 rx_len_1024_to_max; -+ uint32 rx_jabber_pkts; -+ uint32 rx_oversize_pkts; -+ uint32 rx_fragment_pkts; -+ uint32 rx_missed_pkts; -+ uint32 rx_crc_align_errs; -+ uint32 rx_undersize; -+ uint32 rx_crc_errs; -+ uint32 rx_align_errs; -+ uint32 rx_symbol_errs; -+ uint32 rx_pause_pkts; -+ uint32 rx_nonpause_pkts; -+} bcmenetmib_t; -+ -+#endif /* _bcmenetmib_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenetphy.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetphy.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmenetphy.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetphy.h 2005-12-16 23:39:10.700821500 +0100 -@@ -0,0 +1,58 @@ -+/* -+ * Misc Broadcom BCM47XX MDC/MDIO enet phy definitions. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; -+ * the contents of this file may not be disclosed to third parties, copied -+ * or duplicated in any form, in whole or in part, without the prior -+ * written permission of Broadcom Corporation. -+ * $Id$ -+ */ -+ -+#ifndef _bcmenetphy_h_ -+#define _bcmenetphy_h_ -+ -+/* phy address */ -+#define MAXEPHY 32 /* mdio phy addresses are 5bit quantities */ -+#define EPHY_MASK 0x1f -+#define EPHY_NONE 31 /* nvram: no phy present at all */ -+#define EPHY_NOREG 30 /* nvram: no local phy regs */ -+ -+/* just a few phy registers */ -+#define CTL_RESET (1 << 15) /* reset */ -+#define CTL_LOOP (1 << 14) /* loopback */ -+#define CTL_SPEED (1 << 13) /* speed selection 0=10, 1=100 */ -+#define CTL_ANENAB (1 << 12) /* autonegotiation enable */ -+#define CTL_RESTART (1 << 9) /* restart autonegotiation */ -+#define CTL_DUPLEX (1 << 8) /* duplex mode 0=half, 1=full */ -+ -+#define ADV_10FULL (1 << 6) /* autonegotiate advertise 10full */ -+#define ADV_10HALF (1 << 5) /* autonegotiate advertise 10half */ -+#define ADV_100FULL (1 << 8) /* autonegotiate advertise 100full */ -+#define ADV_100HALF (1 << 7) /* autonegotiate advertise 100half */ -+ -+/* link partner ability register */ -+#define LPA_SLCT 0x001f /* same as advertise selector */ -+#define LPA_10HALF 0x0020 /* can do 10mbps half-duplex */ -+#define LPA_10FULL 0x0040 /* can do 10mbps full-duplex */ -+#define LPA_100HALF 0x0080 /* can do 100mbps half-duplex */ -+#define LPA_100FULL 0x0100 /* can do 100mbps full-duplex */ -+#define LPA_100BASE4 0x0200 /* can do 100mbps 4k packets */ -+#define LPA_RESV 0x1c00 /* unused */ -+#define LPA_RFAULT 0x2000 /* link partner faulted */ -+#define LPA_LPACK 0x4000 /* link partner acked us */ -+#define LPA_NPAGE 0x8000 /* next page bit */ -+ -+#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) -+#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) -+ -+#define STAT_REMFAULT (1 << 4) /* remote fault */ -+#define STAT_LINK (1 << 2) /* link status */ -+#define STAT_JAB (1 << 1) /* jabber detected */ -+#define AUX_FORCED (1 << 2) /* forced 10/100 */ -+#define AUX_SPEED (1 << 1) /* speed 0=10mbps 1=100mbps */ -+#define AUX_DUPLEX (1 << 0) /* duplex 0=half 1=full */ -+ -+#endif /* _bcmenetphy_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmenetrxh.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmenetrxh.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmenetrxh.h 2005-12-16 23:39:10.700821500 +0100 -@@ -0,0 +1,43 @@ -+/* -+ * Hardware-specific Receive Data Header for the -+ * Broadcom Home Networking Division -+ * BCM44XX and BCM47XX 10/100 Mbps Ethernet cores. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; -+ * the contents of this file may not be disclosed to third parties, copied -+ * or duplicated in any form, in whole or in part, without the prior -+ * written permission of Broadcom Corporation. -+ * $Id$ -+ */ -+ -+#ifndef _bcmenetrxh_h_ -+#define _bcmenetrxh_h_ -+ -+/* -+ * The Ethernet MAC core returns an 8-byte Receive Frame Data Header -+ * with every frame consisting of -+ * 16bits of frame length, followed by -+ * 16bits of EMAC rx descriptor info, followed by 32bits of undefined. -+ */ -+typedef volatile struct { -+ uint16 len; -+ uint16 flags; -+ uint16 pad[12]; -+} bcmenetrxh_t; -+ -+#define RXHDR_LEN 28 -+ -+#define RXF_L ((uint16)1 << 11) /* last buffer in a frame */ -+#define RXF_MISS ((uint16)1 << 7) /* received due to promisc mode */ -+#define RXF_BRDCAST ((uint16)1 << 6) /* dest is broadcast address */ -+#define RXF_MULT ((uint16)1 << 5) /* dest is multicast address */ -+#define RXF_LG ((uint16)1 << 4) /* frame length > rxmaxlength */ -+#define RXF_NO ((uint16)1 << 3) /* odd number of nibbles */ -+#define RXF_RXER ((uint16)1 << 2) /* receive symbol error */ -+#define RXF_CRC ((uint16)1 << 1) /* crc error */ -+#define RXF_OV ((uint16)1 << 0) /* fifo overflow */ -+ -+#endif /* _bcmenetrxh_h_ */ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h --- linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h 2005-12-16 23:39:10.700821500 +0100 @@ -1766,35 +1339,6 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h linux-2.4.32-brcm/a +#define NVRAM_MAX_PARAM_LEN 64 + +#endif /* _bcmnvram_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmparams.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmparams.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmparams.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmparams.h 2005-12-16 23:39:10.700821500 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * Misc system wide parameters. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ -+ -+#ifndef _bcmparams_h_ -+#define _bcmparams_h_ -+ -+#define VLAN_MAXVID 15 /* Max. VLAN ID supported/allowed */ -+ -+#define VLAN_NUMPRIS 8 /* # of prio, start from 0 */ -+ -+#define DEV_NUMIFS 16 /* Max. # of devices/interfaces supported */ -+ -+#define WL_MAXBSSCFG 16 /* maximum number of BSS Configs we can configure */ -+ -+#endif diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h --- linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h 2005-12-16 23:39:10.704821750 +0100 @@ -2139,505 +1683,483 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/a +extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); + +#endif /* _bcmutils_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bitfuncs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bitfuncs.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bitfuncs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bitfuncs.h 2005-12-16 23:39:10.704821750 +0100 -@@ -0,0 +1,85 @@ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h +--- linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,71 @@ +/* -+ * bit manipulation utility functions ++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . + * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * $Id$ + */ + -+#ifndef _BITFUNCS_H -+#define _BITFUNCS_H -+ -+#include ++#ifndef _hnddma_h_ ++#define _hnddma_h_ + -+/* local prototypes */ -+static INLINE uint32 find_msbit(uint32 x); ++/* export structure */ ++typedef volatile struct { ++ /* rx error counters */ ++ uint rxgiants; /* rx giant frames */ ++ uint rxnobuf; /* rx out of dma descriptors */ ++ /* tx error counters */ ++ uint txnobuf; /* tx out of dma descriptors */ ++} hnddma_t; + ++#ifndef di_t ++#define di_t void ++#endif + -+/* -+ * find_msbit: returns index of most significant set bit in x, with index -+ * range defined as 0-31. NOTE: returns zero if input is zero. -+ */ ++#ifndef osl_t ++#define osl_t void ++#endif + -+#if defined(USE_PENTIUM_BSR) && defined(__GNUC__) ++/* externs */ ++extern void * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level); ++extern void dma_detach(di_t *di); ++extern void dma_txreset(di_t *di); ++extern void dma_rxreset(di_t *di); ++extern void dma_txinit(di_t *di); ++extern bool dma_txenabled(di_t *di); ++extern void dma_rxinit(di_t *di); ++extern void dma_rxenable(di_t *di); ++extern bool dma_rxenabled(di_t *di); ++extern void dma_txsuspend(di_t *di); ++extern void dma_txresume(di_t *di); ++extern bool dma_txsuspended(di_t *di); ++extern bool dma_txsuspendedidle(di_t *di); ++extern bool dma_txstopped(di_t *di); ++extern bool dma_rxstopped(di_t *di); ++extern int dma_txfast(di_t *di, void *p, uint32 coreflags); ++extern void dma_fifoloopbackenable(di_t *di); ++extern void *dma_rx(di_t *di); ++extern void dma_rxfill(di_t *di); ++extern void dma_txreclaim(di_t *di, bool forceall); ++extern void dma_rxreclaim(di_t *di); ++extern uintptr dma_getvar(di_t *di, char *name); ++extern void *dma_getnexttxp(di_t *di, bool forceall); ++extern void *dma_peeknexttxp(di_t *di); ++extern void *dma_getnextrxp(di_t *di, bool forceall); ++extern void dma_txblock(di_t *di); ++extern void dma_txunblock(di_t *di); ++extern uint dma_txactive(di_t *di); ++extern void dma_txrotate(di_t *di); + -+/* -+ * Implementation for Pentium processors and gcc. Note that this -+ * instruction is actually very slow on some processors (e.g., family 5, -+ * model 2, stepping 12, "Pentium 75 - 200"), so we use the generic -+ * implementation instead. -+ */ -+static INLINE uint32 find_msbit(uint32 x) -+{ -+ uint msbit; -+ __asm__("bsrl %1,%0" -+ :"=r" (msbit) -+ :"r" (x)); -+ return msbit; -+} ++extern void dma_rxpiomode(dma32regs_t *); ++extern void dma_txpioloopback(dma32regs_t *); + -+#else + ++#endif /* _hnddma_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h +--- linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,16 @@ +/* -+ * Generic Implementation ++ * Alternate include file for HND sbmips.h since CFE also ships with ++ * a sbmips.h. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ + */ + -+#define DB_POW_MASK16 0xffff0000 -+#define DB_POW_MASK8 0x0000ff00 -+#define DB_POW_MASK4 0x000000f0 -+#define DB_POW_MASK2 0x0000000c -+#define DB_POW_MASK1 0x00000002 -+ -+static INLINE uint32 find_msbit(uint32 x) -+{ -+ uint32 temp_x = x; -+ uint msbit = 0; -+ if (temp_x & DB_POW_MASK16) { -+ temp_x >>= 16; -+ msbit = 16; -+ } -+ if (temp_x & DB_POW_MASK8) { -+ temp_x >>= 8; -+ msbit += 8; -+ } -+ if (temp_x & DB_POW_MASK4) { -+ temp_x >>= 4; -+ msbit += 4; -+ } -+ if (temp_x & DB_POW_MASK2) { -+ temp_x >>= 2; -+ msbit += 2; -+ } -+ if (temp_x & DB_POW_MASK1) { -+ msbit += 1; -+ } -+ return(msbit); -+} -+ -+#endif -+ -+#endif /* _BITFUNCS_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/cfe_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/cfe_osl.h ---- linux-2.4.32/arch/mips/bcm947xx/include/cfe_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/cfe_osl.h 2005-12-16 23:39:10.704821750 +0100 -@@ -0,0 +1,191 @@ ++#include "sbmips.h" +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h 2005-12-16 23:39:10.708822000 +0100 +@@ -0,0 +1,371 @@ +/* -+ * CFE boot loader OS Abstraction Layer. ++ * Linux OS Independent Layer + * + * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; -+ * the contents of this file may not be disclosed to third parties, copied -+ * or duplicated in any form, in whole or in part, without the prior -+ * written permission of Broadcom Corporation. ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id$ + */ + -+#ifndef _cfe_osl_h_ -+#define _cfe_osl_h_ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#ifndef _linux_osl_h_ ++#define _linux_osl_h_ + +#include + -+/* dump string */ -+extern int (*xprinthook)(const char *str); -+#define puts(str) do { if (xprinthook) xprinthook(str); } while (0) ++/* use current 2.4.x calling conventions */ ++#include + +/* assert and panic */ ++#ifdef __GNUC__ ++#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) ++#if GCC_VERSION > 30100 +#define ASSERT(exp) do {} while (0) ++#else ++/* ASSERT could causes segmentation fault on GCC3.1, use empty instead*/ ++#define ASSERT(exp) ++#endif ++#endif ++ ++/* microsecond delay */ ++#define OSL_DELAY(usec) osl_delay(usec) ++extern void osl_delay(uint usec); + +/* PCMCIA attribute space access macros */ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++struct pcmcia_dev { ++ dev_link_t link; /* PCMCIA device pointer */ ++ dev_node_t node; /* PCMCIA node structure */ ++ void *base; /* Mapped attribute memory window */ ++ size_t size; /* Size of window */ ++ void *drv; /* Driver data */ ++}; ++#endif +#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ -+ bzero(buf, size) ++ osl_pcmcia_read_attr((osh), (offset), (buf), (size)) +#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ -+ do {} while (0) ++ osl_pcmcia_write_attr((osh), (offset), (buf), (size)) ++extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); ++extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); + +/* PCI configuration space access macros */ -+#define OSL_PCI_READ_CONFIG(loc, offset, size) \ -+ (offset == 8 ? 0 : 0xffffffff) -+#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) \ -+ do {} while (0) ++#define OSL_PCI_READ_CONFIG(osh, offset, size) \ ++ osl_pci_read_config((osh), (offset), (size)) ++#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ ++ osl_pci_write_config((osh), (offset), (size), (val)) ++extern uint32 osl_pci_read_config(osl_t *osh, uint size, uint offset); ++extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); + +/* PCI device bus # and slot # */ -+#define OSL_PCI_BUS(osh) (0) -+#define OSL_PCI_SLOT(osh) (0) ++#define OSL_PCI_BUS(osh) osl_pci_bus(osh) ++#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) ++extern uint osl_pci_bus(osl_t *osh); ++extern uint osl_pci_slot(osl_t *osh); + -+/* register access macros */ -+#define wreg32(r, v) (*(volatile uint32*)(r) = (uint32)(v)) -+#define rreg32(r) (*(volatile uint32*)(r)) -+#ifdef IL_BIGENDIAN -+#define wreg16(r, v) (*(volatile uint16*)((ulong)(r)^2) = (uint16)(v)) -+#define rreg16(r) (*(volatile uint16*)((ulong)(r)^2)) -+#define wreg8(r, v) (*(volatile uint8*)((ulong)(r)^3) = (uint8)(v)) -+#define rreg8(r) (*(volatile uint8*)((ulong)(r)^3)) -+#else -+#define wreg16(r, v) (*(volatile uint16*)(r) = (uint16)(v)) -+#define rreg16(r) (*(volatile uint16*)(r)) -+#define wreg8(r, v) (*(volatile uint8*)(r) = (uint8)(v)) -+#define rreg8(r) (*(volatile uint8*)(r)) -+#endif -+#define R_REG(r) ({ \ -+ __typeof(*(r)) __osl_v; \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): __osl_v = rreg8((r)); break; \ -+ case sizeof(uint16): __osl_v = rreg16((r)); break; \ -+ case sizeof(uint32): __osl_v = rreg32((r)); break; \ -+ } \ -+ __osl_v; \ -+}) -+#define W_REG(r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): wreg8((r), (v)); break; \ -+ case sizeof(uint16): wreg16((r), (v)); break; \ -+ case sizeof(uint32): wreg32((r), (v)); break; \ -+ } \ -+} while (0) -+#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) -+#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) -+ -+/* bcopy, bcmp, and bzero */ -+#define bcmp(b1, b2, len) lib_memcmp((b1), (b2), (len)) ++/* OSL initialization */ ++extern osl_t *osl_attach(void *pdev); ++extern void osl_detach(osl_t *osh); + -+#define osl_attach(pdev) ((osl_t*)pdev) -+#define osl_detach(osh) ++/* host/bus architecture-specific byte swap */ ++#define BUS_SWAP32(v) (v) + +/* general purpose memory allocation */ -+#define MALLOC(osh, size) KMALLOC((size),0) -+#define MFREE(osh, addr, size) KFREE((addr)) -+#define MALLOCED(osh) (0) -+#define MALLOC_DUMP(osh, buf, sz) -+#define MALLOC_FAILED(osh) (0) + -+/* uncached virtual address */ -+#define OSL_UNCACHED(va) ((void*)UNCADDR((ulong)(va))) ++#if defined(BCMDBG_MEM) + -+/* host/bus architecture-specific address byte swap */ -+#define BUS_SWAP32(v) (v) ++#define MALLOC(osh, size) osl_debug_malloc((osh), (size), __LINE__, __FILE__) ++#define MFREE(osh, addr, size) osl_debug_mfree((osh), (addr), (size), __LINE__, __FILE__) ++#define MALLOCED(osh) osl_malloced((osh)) ++#define MALLOC_DUMP(osh, buf, sz) osl_debug_memdump((osh), (buf), (sz)) ++extern void *osl_debug_malloc(osl_t *osh, uint size, int line, char* file); ++extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file); ++extern char *osl_debug_memdump(osl_t *osh, char *buf, uint sz); + -+/* get processor cycle count */ -+#define OSL_GETCYCLES(x) ((x) = 0) ++#else + -+/* microsecond delay */ -+#define OSL_DELAY(usec) cfe_usleep((cfe_cpu_speed/CPUCFG_CYCLESPERCPUTICK/1000000*(usec))) ++#define MALLOC(osh, size) osl_malloc((osh), (size)) ++#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) ++#define MALLOCED(osh) osl_malloced((osh)) + -+#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++#endif /* BCMDBG_MEM */ + -+/* map/unmap physical to virtual I/O */ -+#define REG_MAP(pa, size) ((void*)UNCADDR((ulong)(pa))) -+#define REG_UNMAP(va) do {} while (0) ++#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) + -+/* dereference an address that may cause a bus exception */ -+#define BUSPROBE(val, addr) osl_busprobe(&(val), (uint32)(addr)) -+extern int osl_busprobe(uint32 *val, uint32 addr); ++extern void *osl_malloc(osl_t *osh, uint size); ++extern void osl_mfree(osl_t *osh, void *addr, uint size); ++extern uint osl_malloced(osl_t *osh); ++extern uint osl_malloc_failed(osl_t *osh); + -+/* allocate/free shared (dma-able) consistent (uncached) memory */ -+#define DMA_CONSISTENT_ALIGN 4096 ++/* allocate/free shared (dma-able) consistent memory */ ++#define DMA_CONSISTENT_ALIGN PAGE_SIZE +#define DMA_ALLOC_CONSISTENT(osh, size, pap) \ -+ osl_dma_alloc_consistent((size), (pap)) ++ osl_dma_alloc_consistent((osh), (size), (pap)) +#define DMA_FREE_CONSISTENT(osh, va, size, pa) \ -+ osl_dma_free_consistent((void*)(va)) -+extern void *osl_dma_alloc_consistent(uint size, ulong *pap); -+extern void osl_dma_free_consistent(void *va); ++ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) ++extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap); ++extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); + +/* map/unmap direction */ -+#define DMA_TX 1 -+#define DMA_RX 2 ++#define DMA_TX 1 ++#define DMA_RX 2 + +/* map/unmap shared (dma-able) memory */ -+#define DMA_MAP(osh, va, size, direction, lb) ({ \ -+ cfe_flushcache(CFE_CACHE_FLUSH_D); \ -+ PHYSADDR((ulong)(va)); \ -+}) ++#define DMA_MAP(osh, va, size, direction, p) \ ++ osl_dma_map((osh), (va), (size), (direction)) +#define DMA_UNMAP(osh, pa, size, direction, p) \ -+ do {} while (0) -+ -+/* shared (dma-able) memory access macros */ -+#define R_SM(r) *(r) -+#define W_SM(r, v) (*(r) = (v)) -+#define BZERO_SM(r, len) lib_memset((r), '\0', (len)) -+ -+/* generic packet structure */ -+#define LBUFSZ 4096 -+#define LBDATASZ (LBUFSZ - sizeof(struct lbuf)) -+struct lbuf { -+ struct lbuf *next; /* pointer to next lbuf if in a chain */ -+ struct lbuf *link; /* pointer to next lbuf if in a list */ -+ uchar *head; /* start of buffer */ -+ uchar *end; /* end of buffer */ -+ uchar *data; /* start of data */ -+ uchar *tail; /* end of data */ -+ uint len; /* nbytes of data */ -+ void *cookie; /* generic cookie */ -+}; -+ -+/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -+#define PKTBUFSZ 2048 ++ osl_dma_unmap((osh), (pa), (size), (direction)) ++extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); ++extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); + -+/* packet primitives */ -+#define PKTGET(osh, len, send) ((void*)osl_pktget((len))) -+#define PKTFREE(osh, lb, send) osl_pktfree((struct lbuf*)(lb)) -+#define PKTDATA(osh, lb) (((struct lbuf*)(lb))->data) -+#define PKTLEN(osh, lb) (((struct lbuf*)(lb))->len) -+#define PKTHEADROOM(osh, lb) (PKTDATA(osh,lb)-(((struct lbuf*)(lb))->head)) -+#define PKTTAILROOM(osh, lb) ((((struct lbuf*)(lb))->end)-(((struct lbuf*)(lb))->tail)) -+#define PKTNEXT(osh, lb) (((struct lbuf*)(lb))->next) -+#define PKTSETNEXT(lb, x) (((struct lbuf*)(lb))->next = (struct lbuf*)(x)) -+#define PKTSETLEN(osh, lb, len) osl_pktsetlen((struct lbuf*)(lb), (len)) -+#define PKTPUSH(osh, lb, bytes) osl_pktpush((struct lbuf*)(lb), (bytes)) -+#define PKTPULL(osh, lb, bytes) osl_pktpull((struct lbuf*)(lb), (bytes)) -+#define PKTDUP(osh, lb) osl_pktdup((struct lbuf*)(lb)) -+#define PKTCOOKIE(lb) (((struct lbuf*)(lb))->cookie) -+#define PKTSETCOOKIE(lb, x) (((struct lbuf*)(lb))->cookie = (void*)(x)) -+#define PKTLINK(lb) (((struct lbuf*)(lb))->link) -+#define PKTSETLINK(lb, x) (((struct lbuf*)(lb))->link = (struct lbuf*)(x)) -+#define PKTPRIO(lb) (0) -+#define PKTSETPRIO(lb, x) do {} while (0) -+extern struct lbuf *osl_pktget(uint len); -+extern void osl_pktfree(struct lbuf *lb); -+extern void osl_pktsetlen(struct lbuf *lb, uint len); -+extern uchar *osl_pktpush(struct lbuf *lb, uint bytes); -+extern uchar *osl_pktpull(struct lbuf *lb, uint bytes); -+extern struct lbuf *osl_pktdup(struct lbuf *lb); -+extern int osl_error(int bcmerror); ++/* register access macros */ ++#if defined(BCMJTAG) ++#include ++#define R_REG(r) bcmjtag_read(NULL, (uint32)(r), sizeof (*(r))) ++#define W_REG(r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof (*(r))) ++#endif + -+#endif /* _cfe_osl_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/epivers.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h ---- linux-2.4.32/arch/mips/bcm947xx/include/epivers.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h 2005-12-16 23:39:10.704821750 +0100 -@@ -0,0 +1,69 @@ +/* -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ * -+*/ ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ * Macros expand to calls to functions defined in linux_osl.c . ++ */ ++#ifndef BINOSL + -+#ifndef _epivers_h_ -+#define _epivers_h_ ++/* string library, kernel mode */ ++#define printf(fmt, args...) printk(fmt, ## args) ++#include ++#include + -+#ifdef linux -+#include ++/* register access macros */ ++#if !defined(BCMJTAG) ++#ifndef IL_BIGENDIAN ++#define R_REG(r) ( \ ++ sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ ++ readl((volatile uint32*)(r)) \ ++) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#else /* IL_BIGENDIAN */ ++#define R_REG(r) ({ \ ++ __typeof(*(r)) __osl_v; \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): __osl_v = readl((volatile uint32*)(r)); break; \ ++ } \ ++ __osl_v; \ ++}) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) +#endif -+ -+/* Vendor Name, ASCII, 32 chars max */ -+#ifdef COMPANYNAME -+#define HPNA_VENDOR COMPANYNAME -+#else -+#define HPNA_VENDOR "Broadcom Corporation" +#endif + -+/* Driver Date, ASCII, 32 chars max */ -+#define HPNA_DRV_BUILD_DATE __DATE__ -+ -+/* Hardware Manufacture Date, ASCII, 32 chars max */ -+#define HPNA_HW_MFG_DATE "Not Specified" -+ -+/* See documentation for Device Type values, 32 values max */ -+#ifndef HPNA_DEV_TYPE -+ -+#if defined(CONFIG_BRCM_VJ) -+#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_DISPLAY } ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) + -+#elif defined(CONFIG_BCRM_93725) -+#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY } ++/* bcopy, bcmp, and bzero */ ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) + ++/* uncached virtual address */ ++#ifdef mips ++#define OSL_UNCACHED(va) KSEG1ADDR((va)) ++#include +#else -+#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_PCINIC } -+ ++#define OSL_UNCACHED(va) (va) +#endif + -+#endif /* !HPNA_DEV_TYPE */ -+ -+ -+#define EPI_MAJOR_VERSION 3 -+ -+#define EPI_MINOR_VERSION 130 -+ -+#define EPI_RC_NUMBER 20 -+ -+#define EPI_INCREMENTAL_NUMBER 0 -+ -+#define EPI_BUILD_NUMBER 0 -+ -+#define EPI_VERSION 3,130,20,0 -+ -+#define EPI_VERSION_NUM 0x03821400 -+ -+/* Driver Version String, ASCII, 32 chars max */ -+#define EPI_VERSION_STR "3.130.20.0" -+#define EPI_ROUTER_VERSION_STR "3.131.20.0" -+ -+#endif /* _epivers_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/epivers.h.in linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h.in ---- linux-2.4.32/arch/mips/bcm947xx/include/epivers.h.in 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/epivers.h.in 2005-12-16 23:39:10.704821750 +0100 -@@ -0,0 +1,69 @@ -+/* -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ * -+*/ -+ -+#ifndef _epivers_h_ -+#define _epivers_h_ -+ -+#ifdef linux -+#include ++/* get processor cycle count */ ++#if defined(mips) ++#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2) ++#elif defined(__i386__) ++#define OSL_GETCYCLES(x) rdtscl((x)) ++#else ++#define OSL_GETCYCLES(x) ((x) = 0) +#endif + -+/* Vendor Name, ASCII, 32 chars max */ -+#ifdef COMPANYNAME -+#define HPNA_VENDOR COMPANYNAME ++/* dereference an address that may cause a bus exception */ ++#ifdef mips ++#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17)) ++#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into a module") +#else -+#define HPNA_VENDOR "Broadcom Corporation" ++#define BUSPROBE(val, addr) get_dbe((val), (addr)) ++#include +#endif -+ -+/* Driver Date, ASCII, 32 chars max */ -+#define HPNA_DRV_BUILD_DATE __DATE__ -+ -+/* Hardware Manufacture Date, ASCII, 32 chars max */ -+#define HPNA_HW_MFG_DATE "Not Specified" -+ -+/* See documentation for Device Type values, 32 values max */ -+#ifndef HPNA_DEV_TYPE -+ -+#if defined(CONFIG_BRCM_VJ) -+#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_DISPLAY } -+ -+#elif defined(CONFIG_BCRM_93725) -+#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_CM_BRIDGE, CDCF_V0_DEVICE_DISPLAY } -+ +#else -+#define HPNA_DEV_TYPE { CDCF_V0_DEVICE_PCINIC } -+ ++#define BUSPROBE(val, addr) ({ (val) = R_REG((addr)); 0; }) +#endif + -+#endif /* !HPNA_DEV_TYPE */ -+ -+ -+#define EPI_MAJOR_VERSION @EPI_MAJOR_VERSION@ -+ -+#define EPI_MINOR_VERSION @EPI_MINOR_VERSION@ -+ -+#define EPI_RC_NUMBER @EPI_RC_NUMBER@ ++/* map/unmap physical to virtual I/O */ ++#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) ++#define REG_UNMAP(va) iounmap((void *)(va)) + -+#define EPI_INCREMENTAL_NUMBER @EPI_INCREMENTAL_NUMBER@ ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) memset((r), '\0', (len)) + -+#define EPI_BUILD_NUMBER @EPI_BUILD_NUMBER@ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) ++#define PKTFREE(osh, skb, send) osl_pktfree((skb)) ++#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) ++#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) ++#define PKTHEADROOM(osh, skb) (PKTDATA(osh,skb)-(((struct sk_buff*)(skb))->head)) ++#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) ++#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) ++#define PKTSETNEXT(skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) ++#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) ++#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) ++#define PKTDUP(osh, skb) skb_clone((struct sk_buff*)(skb), GFP_ATOMIC) ++#define PKTCOOKIE(skb) ((void*)((struct sk_buff*)(skb))->csum) ++#define PKTSETCOOKIE(skb, x) (((struct sk_buff*)(skb))->csum = (uint)(x)) ++#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) ++#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) ++#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) ++#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) ++extern void *osl_pktget(osl_t *osh, uint len, bool send); ++extern void osl_pktfree(void *skb); + -+#define EPI_VERSION @EPI_VERSION@ ++#else /* BINOSL */ + -+#define EPI_VERSION_NUM @EPI_VERSION_NUM@ ++/* string library */ ++#ifndef LINUX_OSL ++#undef printf ++#define printf(fmt, args...) osl_printf((fmt), ## args) ++#undef sprintf ++#define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args) ++#undef strcmp ++#define strcmp(s1, s2) osl_strcmp((s1), (s2)) ++#undef strncmp ++#define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n)) ++#undef strlen ++#define strlen(s) osl_strlen((s)) ++#undef strcpy ++#define strcpy(d, s) osl_strcpy((d), (s)) ++#undef strncpy ++#define strncpy(d, s, n) osl_strncpy((d), (s), (n)) ++#endif ++extern int osl_printf(const char *format, ...); ++extern int osl_sprintf(char *buf, const char *format, ...); ++extern int osl_strcmp(const char *s1, const char *s2); ++extern int osl_strncmp(const char *s1, const char *s2, uint n); ++extern int osl_strlen(const char *s); ++extern char* osl_strcpy(char *d, const char *s); ++extern char* osl_strncpy(char *d, const char *s, uint n); + -+/* Driver Version String, ASCII, 32 chars max */ -+#define EPI_VERSION_STR "@EPI_VERSION_STR@" -+#define EPI_ROUTER_VERSION_STR "@EPI_ROUTER_VERSION_STR@" ++/* register access macros */ ++#if !defined(BCMJTAG) ++#define R_REG(r) ( \ ++ sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \ ++ osl_readl((volatile uint32*)(r)) \ ++) ++#define W_REG(r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#endif + -+#endif /* _epivers_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/etsockio.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/etsockio.h ---- linux-2.4.32/arch/mips/bcm947xx/include/etsockio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/etsockio.h 2005-12-16 23:39:10.704821750 +0100 -@@ -0,0 +1,59 @@ -+/* -+ * Driver-specific socket ioctls -+ * used by BSD, Linux, and PSOS -+ * Broadcom BCM44XX 10/100Mbps Ethernet Device Driver -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) ++#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++extern uint8 osl_readb(volatile uint8 *r); ++extern uint16 osl_readw(volatile uint16 *r); ++extern uint32 osl_readl(volatile uint32 *r); ++extern void osl_writeb(uint8 v, volatile uint8 *r); ++extern void osl_writew(uint16 v, volatile uint16 *r); ++extern void osl_writel(uint32 v, volatile uint32 *r); + -+#ifndef _etsockio_h_ -+#define _etsockio_h_ ++/* bcopy, bcmp, and bzero */ ++extern void bcopy(const void *src, void *dst, int len); ++extern int bcmp(const void *b1, const void *b2, int len); ++extern void bzero(void *b, int len); + -+/* THESE MUST BE CONTIGUOUS AND CONSISTENT WITH VALUES IN ETC.H */ ++/* uncached virtual address */ ++#define OSL_UNCACHED(va) osl_uncached((va)) ++extern void *osl_uncached(void *va); + ++/* get processor cycle count */ ++#define OSL_GETCYCLES(x) ((x) = osl_getcycles()) ++extern uint osl_getcycles(void); + -+#if defined(linux) -+#define SIOCSETCUP (SIOCDEVPRIVATE + 0) -+#define SIOCSETCDOWN (SIOCDEVPRIVATE + 1) -+#define SIOCSETCLOOP (SIOCDEVPRIVATE + 2) -+#define SIOCGETCDUMP (SIOCDEVPRIVATE + 3) -+#define SIOCSETCSETMSGLEVEL (SIOCDEVPRIVATE + 4) -+#define SIOCSETCPROMISC (SIOCDEVPRIVATE + 5) -+#define SIOCSETCTXDOWN (SIOCDEVPRIVATE + 6) /* obsolete */ -+#define SIOCSETCSPEED (SIOCDEVPRIVATE + 7) -+#define SIOCTXGEN (SIOCDEVPRIVATE + 8) -+#define SIOCGETCPHYRD (SIOCDEVPRIVATE + 9) -+#define SIOCSETCPHYWR (SIOCDEVPRIVATE + 10) -+#define SIOCSETCQOS (SIOCDEVPRIVATE + 11) -+ -+#else /* !linux */ -+ -+#define SIOCSETCUP _IOWR('e', 130 + 0, struct ifreq) -+#define SIOCSETCDOWN _IOWR('e', 130 + 1, struct ifreq) -+#define SIOCSETCLOOP _IOWR('e', 130 + 2, struct ifreq) -+#define SIOCGETCDUMP _IOWR('e', 130 + 3, struct ifreq) -+#define SIOCSETCSETMSGLEVEL _IOWR('e', 130 + 4, struct ifreq) -+#define SIOCSETCPROMISC _IOWR('e', 130 + 5, struct ifreq) -+#define SIOCSETCTXDOWN _IOWR('e', 130 + 6, struct ifreq) /* obsolete */ -+#define SIOCSETCSPEED _IOWR('e', 130 + 7, struct ifreq) -+#define SIOCTXGEN _IOWR('e', 130 + 8, struct ifreq) ++/* dereference an address that may target abort */ ++#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr)) ++extern int osl_busprobe(uint32 *val, uint32 addr); + -+#endif ++/* map/unmap physical to virtual */ ++#define REG_MAP(pa, size) osl_reg_map((pa), (size)) ++#define REG_UNMAP(va) osl_reg_unmap((va)) ++extern void *osl_reg_map(uint32 pa, uint size); ++extern void osl_reg_unmap(void *va); + -+/* arg to SIOCTXGEN */ -+struct txg { -+ uint32 num; /* number of frames to send */ -+ uint32 delay; /* delay in microseconds between sending each */ -+ uint32 size; /* size of ether frame to send */ -+ uchar buf[1514]; /* starting ether frame data */ -+}; ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) bzero((r), (len)) + -+#endif -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/flash.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/flash.h ---- linux-2.4.32/arch/mips/bcm947xx/include/flash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/flash.h 2005-12-16 23:39:10.704821750 +0100 -@@ -0,0 +1,188 @@ ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) ++#define PKTFREE(osh, skb, send) osl_pktfree((skb)) ++#define PKTDATA(osh, skb) osl_pktdata((osh), (skb)) ++#define PKTLEN(osh, skb) osl_pktlen((osh), (skb)) ++#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb)) ++#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb)) ++#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb)) ++#define PKTSETNEXT(skb, x) osl_pktsetnext((skb), (x)) ++#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len)) ++#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes)) ++#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) ++#define PKTCOOKIE(skb) osl_pktcookie((skb)) ++#define PKTSETCOOKIE(skb, x) osl_pktsetcookie((skb), (x)) ++#define PKTLINK(skb) osl_pktlink((skb)) ++#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x)) ++#define PKTPRIO(skb) osl_pktprio((skb)) ++#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x)) ++extern void *osl_pktget(osl_t *osh, uint len, bool send); ++extern void osl_pktfree(void *skb); ++extern uchar *osl_pktdata(osl_t *osh, void *skb); ++extern uint osl_pktlen(osl_t *osh, void *skb); ++extern uint osl_pktheadroom(osl_t *osh, void *skb); ++extern uint osl_pkttailroom(osl_t *osh, void *skb); ++extern void *osl_pktnext(osl_t *osh, void *skb); ++extern void osl_pktsetnext(void *skb, void *x); ++extern void osl_pktsetlen(osl_t *osh, void *skb, uint len); ++extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes); ++extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes); ++extern void *osl_pktdup(osl_t *osh, void *skb); ++extern void *osl_pktcookie(void *skb); ++extern void osl_pktsetcookie(void *skb, void *x); ++extern void *osl_pktlink(void *skb); ++extern void osl_pktsetlink(void *skb, void *x); ++extern uint osl_pktprio(void *skb); ++extern void osl_pktsetprio(void *skb, uint x); ++ ++#endif /* BINOSL */ ++ ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++extern int osl_error(int bcmerror); ++ ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 ++ ++#endif /* _linux_osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h +--- linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,411 @@ +/* -+ * flash.h: Common definitions for flash access. ++ * Linux-specific abstractions to gain some independence from linux kernel versions. ++ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. + * + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. @@ -2646,2481 +2168,969 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/flash.h linux-2.4.32-brcm/arch + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * ++ * + * $Id$ + */ + -+/* Types of flashes we know about */ -+typedef enum _flash_type {OLD, BSC, SCS, AMD, SST, SFLASH} flash_type_t; -+ -+/* Commands to write/erase the flases */ -+typedef struct _flash_cmds{ -+ flash_type_t type; -+ bool need_unlock; -+ uint16 pre_erase; -+ uint16 erase_block; -+ uint16 erase_chip; -+ uint16 write_word; -+ uint16 write_buf; -+ uint16 clear_csr; -+ uint16 read_csr; -+ uint16 read_id; -+ uint16 confirm; -+ uint16 read_array; -+} flash_cmds_t; -+ -+#define UNLOCK_CMD_WORDS 2 -+ -+typedef struct _unlock_cmd { -+ uint addr[UNLOCK_CMD_WORDS]; -+ uint16 cmd[UNLOCK_CMD_WORDS]; -+} unlock_cmd_t; -+ -+/* Flash descriptors */ -+typedef struct _flash_desc { -+ uint16 mfgid; /* Manufacturer Id */ -+ uint16 devid; /* Device Id */ -+ uint size; /* Total size in bytes */ -+ uint width; /* Device width in bytes */ -+ flash_type_t type; /* Device type old, S, J */ -+ uint bsize; /* Block size */ -+ uint nb; /* Number of blocks */ -+ uint ff; /* First full block */ -+ uint lf; /* Last full block */ -+ uint nsub; /* Number of subblocks */ -+ uint *subblocks; /* Offsets for subblocks */ -+ char *desc; /* Description */ -+} flash_desc_t; -+ -+ -+#ifdef DECLARE_FLASHES -+flash_cmds_t sflash_cmd_t = -+ { SFLASH, 0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -+ -+flash_cmds_t flash_cmds[] = { -+/* type needu preera eraseb erasech write wbuf clcsr rdcsr rdid confrm read */ -+ { BSC, 0, 0x00, 0x20, 0x00, 0x40, 0x00, 0x50, 0x70, 0x90, 0xd0, 0xff }, -+ { SCS, 0, 0x00, 0x20, 0x00, 0x40, 0xe8, 0x50, 0x70, 0x90, 0xd0, 0xff }, -+ { AMD, 1, 0x80, 0x30, 0x10, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf0 }, -+ { SST, 1, 0x80, 0x50, 0x10, 0xa0, 0x00, 0x00, 0x00, 0x90, 0x00, 0xf0 }, -+ { 0 } -+}; ++#ifndef _linuxver_h_ ++#define _linuxver_h_ + -+unlock_cmd_t unlock_cmd_amd = { -+#ifdef MIPSEB -+/* addr: */ { 0x0aa8, 0x0556}, -+#else -+/* addr: */ { 0x0aaa, 0x0554}, -+#endif -+/* data: */ { 0xaa, 0x55} -+}; ++#include ++#include + -+unlock_cmd_t unlock_cmd_sst = { -+#ifdef MIPSEB -+/* addr: */ { 0xaaa8, 0x5556}, ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) ++/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ ++#ifdef __UNDEF_NO_VERSION__ ++#undef __NO_VERSION__ +#else -+/* addr: */ { 0xaaaa, 0x5554}, ++#define __NO_VERSION__ ++#endif +#endif -+/* data: */ { 0xaa, 0x55} -+}; -+ -+#define AMD_CMD 0xaaa -+#define SST_CMD 0xaaaa + -+/* intel unlock block cmds */ -+#define INTEL_UNLOCK1 0x60 -+#define INTEL_UNLOCK2 0xD0 ++#if defined(MODULE) && defined(MODVERSIONS) ++#include ++#endif + -+/* Just eight blocks of 8KB byte each */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ++#include ++#endif + -+uint blk8x8k[] = { 0x00000000, -+ 0x00002000, -+ 0x00004000, -+ 0x00006000, -+ 0x00008000, -+ 0x0000a000, -+ 0x0000c000, -+ 0x0000e000, -+ 0x00010000 -+}; + -+/* Funky AMD arrangement for 29xx800's */ -+uint amd800[] = { 0x00000000, /* 16KB */ -+ 0x00004000, /* 32KB */ -+ 0x0000c000, /* 8KB */ -+ 0x0000e000, /* 8KB */ -+ 0x00010000, /* 8KB */ -+ 0x00012000, /* 8KB */ -+ 0x00014000, /* 32KB */ -+ 0x0001c000, /* 16KB */ -+ 0x00020000 -+}; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) ++#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") ++#define module_param_string(_name_, _string_, _size_, _perm_) MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) ++#endif + -+/* AMD arrangement for 29xx160's */ -+uint amd4112[] = { 0x00000000, /* 32KB */ -+ 0x00008000, /* 8KB */ -+ 0x0000a000, /* 8KB */ -+ 0x0000c000, /* 16KB */ -+ 0x00010000 -+}; -+uint amd2114[] = { 0x00000000, /* 16KB */ -+ 0x00004000, /* 8KB */ -+ 0x00006000, /* 8KB */ -+ 0x00008000, /* 32KB */ -+ 0x00010000 -+}; ++/* linux/malloc.h is deprecated, use linux/slab.h instead. */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)) ++#include ++#else ++#include ++#endif + ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+flash_desc_t sflash_desc = -+ { 0, 0, 0, 0, SFLASH, 0, 0, 0, 0, 0, NULL, "SFLASH" }; -+ -+flash_desc_t flashes[] = { -+ { 0x00b0, 0x00d0, 0x0200000, 2, SCS, 0x10000, 32, 0, 31, 0, NULL, "Intel 28F160S3/5 1Mx16" }, -+ { 0x00b0, 0x00d4, 0x0400000, 2, SCS, 0x10000, 64, 0, 63, 0, NULL, "Intel 28F320S3/5 2Mx16" }, -+ { 0x0089, 0x8890, 0x0200000, 2, BSC, 0x10000, 32, 0, 30, 8, blk8x8k, "Intel 28F160B3 1Mx16 TopB" }, -+ { 0x0089, 0x8891, 0x0200000, 2, BSC, 0x10000, 32, 1, 31, 8, blk8x8k, "Intel 28F160B3 1Mx16 BotB" }, -+ { 0x0089, 0x8896, 0x0400000, 2, BSC, 0x10000, 64, 0, 62, 8, blk8x8k, "Intel 28F320B3 2Mx16 TopB" }, -+ { 0x0089, 0x8897, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Intel 28F320B3 2Mx16 BotB" }, -+ { 0x0089, 0x8898, 0x0800000, 2, BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640B3 4Mx16 TopB" }, -+ { 0x0089, 0x8899, 0x0800000, 2, BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640B3 4Mx16 BotB" }, -+ { 0x0089, 0x88C2, 0x0200000, 2, BSC, 0x10000, 32, 0, 30, 8, blk8x8k, "Intel 28F160C3 1Mx16 TopB" }, -+ { 0x0089, 0x88C3, 0x0200000, 2, BSC, 0x10000, 32, 1, 31, 8, blk8x8k, "Intel 28F160C3 1Mx16 BotB" }, -+ { 0x0089, 0x88C4, 0x0400000, 2, BSC, 0x10000, 64, 0, 62, 8, blk8x8k, "Intel 28F320C3 2Mx16 TopB" }, -+ { 0x0089, 0x88C5, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Intel 28F320C3 2Mx16 BotB" }, -+ { 0x0089, 0x88CC, 0x0800000, 2, BSC, 0x10000, 128, 0, 126, 8, blk8x8k, "Intel 28F640C3 4Mx16 TopB" }, -+ { 0x0089, 0x88CD, 0x0800000, 2, BSC, 0x10000, 128, 1, 127, 8, blk8x8k, "Intel 28F640C3 4Mx16 BotB" }, -+ { 0x0089, 0x0014, 0x0400000, 2, SCS, 0x20000, 32, 0, 31, 0, NULL, "Intel 28F320J5 2Mx16" }, -+ { 0x0089, 0x0015, 0x0800000, 2, SCS, 0x20000, 64, 0, 63, 0, NULL, "Intel 28F640J5 4Mx16" }, -+ { 0x0089, 0x0016, 0x0400000, 2, SCS, 0x20000, 32, 0, 31, 0, NULL, "Intel 28F320J3 2Mx16" }, -+ { 0x0089, 0x0017, 0x0800000, 2, SCS, 0x20000, 64, 0, 63, 0, NULL, "Intel 28F640J3 4Mx16" }, -+ { 0x0089, 0x0018, 0x1000000, 2, SCS, 0x20000, 128, 0, 127, 0, NULL, "Intel 28F128J3 8Mx16" }, -+ { 0x00b0, 0x00e3, 0x0400000, 2, BSC, 0x10000, 64, 1, 63, 8, blk8x8k, "Sharp 28F320BJE 2Mx16 BotB" }, -+ { 0x0001, 0x224a, 0x0100000, 2, AMD, 0x10000, 16, 0, 13, 8, amd800, "AMD 29DL800BT 512Kx16 TopB" }, -+ { 0x0001, 0x22cb, 0x0100000, 2, AMD, 0x10000, 16, 2, 15, 8, amd800, "AMD 29DL800BB 512Kx16 BotB" }, -+ { 0x0001, 0x22c4, 0x0200000, 2, AMD, 0x10000, 32, 0, 30, 4, amd2114, "AMD 29lv160DT 1Mx16 TopB" }, -+ { 0x0001, 0x2249, 0x0200000, 2, AMD, 0x10000, 32, 1, 31, 4, amd4112, "AMD 29lv160DB 1Mx16 BotB" }, -+ { 0x0001, 0x22f6, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 8, blk8x8k, "AMD 29lv320DT 2Mx16 TopB" }, -+ { 0x0001, 0x22f9, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 8, blk8x8k, "AMD 29lv320DB 2Mx16 BotB" }, -+ { 0x0001, 0x227e, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 8, blk8x8k, "AMD 29lv320MT 2Mx16 TopB" }, -+ { 0x0001, 0x2200, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 8, blk8x8k, "AMD 29lv320MB 2Mx16 BotB" }, -+ { 0x0020, 0x22CA, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "ST 29w320DT 2Mx16 TopB" }, -+ { 0x0020, 0x22CB, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "ST 29w320DB 2Mx16 BotB" }, -+ { 0x00C2, 0x00A7, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MX29LV320T 2Mx16 TopB" }, -+ { 0x00C2, 0x00A8, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MX29LV320B 2Mx16 BotB" }, -+ { 0x0004, 0x22F6, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MBM29LV320TE 2Mx16 TopB" }, -+ { 0x0004, 0x22F9, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MBM29LV320BE 2Mx16 BotB" }, -+ { 0x0098, 0x009A, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "TC58FVT321 2Mx16 TopB" }, -+ { 0x0098, 0x009C, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "TC58FVB321 2Mx16 BotB" }, -+ { 0x00C2, 0x22A7, 0x0400000, 2, AMD, 0x10000, 64, 0, 62, 4, amd4112, "MX29LV320T 2Mx16 TopB" }, -+ { 0x00C2, 0x22A8, 0x0400000, 2, AMD, 0x10000, 64, 1, 63, 4, amd2114, "MX29LV320B 2Mx16 BotB" }, -+ { 0x00BF, 0x2783, 0x0400000, 2, SST, 0x10000, 64, 0, 63, 0, NULL, "SST39VF320 2Mx16" }, -+ { 0, 0, 0, 0, OLD, 0, 0, 0, 0, 0, NULL, NULL }, -+}; ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) ++#include ++#else ++#include ++#ifndef work_struct ++#define work_struct tq_struct ++#endif ++#ifndef INIT_WORK ++#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) ++#endif ++#ifndef schedule_work ++#define schedule_work(_work) schedule_task((_work)) ++#endif ++#ifndef flush_scheduled_work ++#define flush_scheduled_work() flush_scheduled_tasks() ++#endif ++#endif + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++/* Some distributions have their own 2.6.x compatibility layers */ ++#ifndef IRQ_NONE ++typedef void irqreturn_t; ++#define IRQ_NONE ++#define IRQ_HANDLED ++#define IRQ_RETVAL(x) ++#endif +#else ++typedef irqreturn_t (*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); ++#endif + -+extern flash_cmds_t flash_cmds[]; -+extern unlock_cmd_t unlock_cmd; -+extern flash_desc_t flashes[]; ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) + -+#endif -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/flashutl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/flashutl.h ---- linux-2.4.32/arch/mips/bcm947xx/include/flashutl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/flashutl.h 2005-12-16 23:39:10.708822000 +0100 -@@ -0,0 +1,27 @@ -+/* -+ * BCM47XX FLASH driver interface -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ ++#include ++#include ++#include ++#include ++#include ++#include + -+#ifndef _flashutl_h_ -+#define _flashutl_h_ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)) ++/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which ++ * does this, but it's not in 2.4 so we do our own for now. */ ++static inline void ++cs_error(client_handle_t handle, int func, int ret) ++{ ++ error_info_t err = { func, ret }; ++ CardServices(ReportError, handle, &err); ++} ++#endif + ++#endif /* CONFIG_PCMCIA */ + -+#ifndef _LANGUAGE_ASSEMBLY ++#ifndef __exit ++#define __exit ++#endif ++#ifndef __devexit ++#define __devexit ++#endif ++#ifndef __devinit ++#define __devinit __init ++#endif ++#ifndef __devinitdata ++#define __devinitdata ++#endif ++#ifndef __devexit_p ++#define __devexit_p(x) x ++#endif + -+int sysFlashInit(char *flash_str); -+int sysFlashRead(uint off, uchar *dst, uint bytes); -+int sysFlashWrite(uint off, uchar *src, uint bytes); -+void nvWrite(unsigned short *data, unsigned int len); ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) + -+#endif /* _LANGUAGE_ASSEMBLY */ ++#define pci_get_drvdata(dev) (dev)->sysdata ++#define pci_set_drvdata(dev, value) (dev)->sysdata=(value) + -+#endif /* _flashutl_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h ---- linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h 2005-12-16 23:39:10.708822000 +0100 -@@ -0,0 +1,71 @@ +/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ ++ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration + */ + -+#ifndef _hnddma_h_ -+#define _hnddma_h_ -+ -+/* export structure */ -+typedef volatile struct { -+ /* rx error counters */ -+ uint rxgiants; /* rx giant frames */ -+ uint rxnobuf; /* rx out of dma descriptors */ -+ /* tx error counters */ -+ uint txnobuf; /* tx out of dma descriptors */ -+} hnddma_t; ++struct pci_device_id { ++ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ ++ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ ++ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ ++ unsigned long driver_data; /* Data private to the driver */ ++}; + -+#ifndef di_t -+#define di_t void ++struct pci_driver { ++ struct list_head node; ++ char *name; ++ const struct pci_device_id *id_table; /* NULL if wants all devices */ ++ int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ ++ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ ++ void (*suspend)(struct pci_dev *dev); /* Device suspended */ ++ void (*resume)(struct pci_dev *dev); /* Device woken up */ ++}; ++ ++#define MODULE_DEVICE_TABLE(type, name) ++#define PCI_ANY_ID (~0) ++ ++/* compatpci.c */ ++#define pci_module_init pci_register_driver ++extern int pci_register_driver(struct pci_driver *drv); ++extern void pci_unregister_driver(struct pci_driver *drv); ++ ++#endif /* PCI registration */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) ++#ifdef MODULE ++#define module_init(x) int init_module(void) { return x(); } ++#define module_exit(x) void cleanup_module(void) { x(); } ++#else ++#define module_init(x) __initcall(x); ++#define module_exit(x) __exitcall(x); ++#endif +#endif + -+#ifndef osl_t -+#define osl_t void ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)) ++#define list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) +#endif + -+/* externs */ -+extern void * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, -+ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level); -+extern void dma_detach(di_t *di); -+extern void dma_txreset(di_t *di); -+extern void dma_rxreset(di_t *di); -+extern void dma_txinit(di_t *di); -+extern bool dma_txenabled(di_t *di); -+extern void dma_rxinit(di_t *di); -+extern void dma_rxenable(di_t *di); -+extern bool dma_rxenabled(di_t *di); -+extern void dma_txsuspend(di_t *di); -+extern void dma_txresume(di_t *di); -+extern bool dma_txsuspended(di_t *di); -+extern bool dma_txsuspendedidle(di_t *di); -+extern bool dma_txstopped(di_t *di); -+extern bool dma_rxstopped(di_t *di); -+extern int dma_txfast(di_t *di, void *p, uint32 coreflags); -+extern void dma_fifoloopbackenable(di_t *di); -+extern void *dma_rx(di_t *di); -+extern void dma_rxfill(di_t *di); -+extern void dma_txreclaim(di_t *di, bool forceall); -+extern void dma_rxreclaim(di_t *di); -+extern uintptr dma_getvar(di_t *di, char *name); -+extern void *dma_getnexttxp(di_t *di, bool forceall); -+extern void *dma_peeknexttxp(di_t *di); -+extern void *dma_getnextrxp(di_t *di, bool forceall); -+extern void dma_txblock(di_t *di); -+extern void dma_txunblock(di_t *di); -+extern uint dma_txactive(di_t *di); -+extern void dma_txrotate(di_t *di); ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)) ++#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) ++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,44)) ++#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) ++#endif + -+extern void dma_rxpiomode(dma32regs_t *); -+extern void dma_txpioloopback(dma32regs_t *); ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,23)) ++#define pci_enable_device(dev) do { } while (0) ++#endif + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14)) ++#define net_device device ++#endif + -+#endif /* _hnddma_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h ---- linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h 2005-12-16 23:39:10.708822000 +0100 -@@ -0,0 +1,16 @@ -+/* -+ * Alternate include file for HND sbmips.h since CFE also ships with -+ * a sbmips.h. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)) + -+#include "sbmips.h" -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h ---- linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h 2005-12-16 23:39:10.708822000 +0100 -@@ -0,0 +1,371 @@ +/* -+ * Linux OS Independent Layer -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * DMA mapping + * -+ * $Id$ ++ * See linux/Documentation/DMA-mapping.txt + */ + -+#ifndef _linux_osl_h_ -+#define _linux_osl_h_ ++#ifndef PCI_DMA_TODEVICE ++#define PCI_DMA_TODEVICE 1 ++#define PCI_DMA_FROMDEVICE 2 ++#endif + -+#include ++typedef u32 dma_addr_t; + -+/* use current 2.4.x calling conventions */ -+#include ++/* Pure 2^n version of get_order */ ++static inline int get_order(unsigned long size) ++{ ++ int order; + -+/* assert and panic */ -+#ifdef __GNUC__ -+#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -+#if GCC_VERSION > 30100 -+#define ASSERT(exp) do {} while (0) -+#else -+/* ASSERT could causes segmentation fault on GCC3.1, use empty instead*/ -+#define ASSERT(exp) -+#endif -+#endif ++ size = (size-1) >> (PAGE_SHIFT-1); ++ order = -1; ++ do { ++ size >>= 1; ++ order++; ++ } while (size); ++ return order; ++} + -+/* microsecond delay */ -+#define OSL_DELAY(usec) osl_delay(usec) -+extern void osl_delay(uint usec); ++static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, ++ dma_addr_t *dma_handle) ++{ ++ void *ret; ++ int gfp = GFP_ATOMIC | GFP_DMA; + -+/* PCMCIA attribute space access macros */ -+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) -+struct pcmcia_dev { -+ dev_link_t link; /* PCMCIA device pointer */ -+ dev_node_t node; /* PCMCIA node structure */ -+ void *base; /* Mapped attribute memory window */ -+ size_t size; /* Size of window */ -+ void *drv; /* Driver data */ -+}; -+#endif -+#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ -+ osl_pcmcia_read_attr((osh), (offset), (buf), (size)) -+#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ -+ osl_pcmcia_write_attr((osh), (offset), (buf), (size)) -+extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); -+extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); ++ ret = (void *)__get_free_pages(gfp, get_order(size)); + -+/* PCI configuration space access macros */ -+#define OSL_PCI_READ_CONFIG(osh, offset, size) \ -+ osl_pci_read_config((osh), (offset), (size)) -+#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ -+ osl_pci_write_config((osh), (offset), (size), (val)) -+extern uint32 osl_pci_read_config(osl_t *osh, uint size, uint offset); -+extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); ++ if (ret != NULL) { ++ memset(ret, 0, size); ++ *dma_handle = virt_to_bus(ret); ++ } ++ return ret; ++} ++static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, ++ void *vaddr, dma_addr_t dma_handle) ++{ ++ free_pages((unsigned long)vaddr, get_order(size)); ++} ++#ifdef ILSIM ++extern uint pci_map_single(void *dev, void *va, uint size, int direction); ++extern void pci_unmap_single(void *dev, uint pa, uint size, int direction); ++#else ++#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) ++#define pci_unmap_single(cookie, address, size, dir) ++#endif + -+/* PCI device bus # and slot # */ -+#define OSL_PCI_BUS(osh) osl_pci_bus(osh) -+#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -+extern uint osl_pci_bus(osl_t *osh); -+extern uint osl_pci_slot(osl_t *osh); ++#endif /* DMA mapping */ + -+/* OSL initialization */ -+extern osl_t *osl_attach(void *pdev); -+extern void osl_detach(osl_t *osh); ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) + -+/* host/bus architecture-specific byte swap */ -+#define BUS_SWAP32(v) (v) ++#define dev_kfree_skb_any(a) dev_kfree_skb(a) ++#define netif_down(dev) do { (dev)->start = 0; } while(0) + -+/* general purpose memory allocation */ ++/* pcmcia-cs provides its own netdevice compatibility layer */ ++#ifndef _COMPAT_NETDEVICE_H + -+#if defined(BCMDBG_MEM) ++/* ++ * SoftNet ++ * ++ * For pre-softnet kernels we need to tell the upper layer not to ++ * re-enter start_xmit() while we are in there. However softnet ++ * guarantees not to enter while we are in there so there is no need ++ * to do the netif_stop_queue() dance unless the transmit queue really ++ * gets stuck. This should also improve performance according to tests ++ * done by Aman Singla. ++ */ + -+#define MALLOC(osh, size) osl_debug_malloc((osh), (size), __LINE__, __FILE__) -+#define MFREE(osh, addr, size) osl_debug_mfree((osh), (addr), (size), __LINE__, __FILE__) -+#define MALLOCED(osh) osl_malloced((osh)) -+#define MALLOC_DUMP(osh, buf, sz) osl_debug_memdump((osh), (buf), (sz)) -+extern void *osl_debug_malloc(osl_t *osh, uint size, int line, char* file); -+extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file); -+extern char *osl_debug_memdump(osl_t *osh, char *buf, uint sz); ++#define dev_kfree_skb_irq(a) dev_kfree_skb(a) ++#define netif_wake_queue(dev) do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while(0) ++#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) + -+#else ++static inline void netif_start_queue(struct net_device *dev) ++{ ++ dev->tbusy = 0; ++ dev->interrupt = 0; ++ dev->start = 1; ++} + -+#define MALLOC(osh, size) osl_malloc((osh), (size)) -+#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) -+#define MALLOCED(osh) osl_malloced((osh)) ++#define netif_queue_stopped(dev) (dev)->tbusy ++#define netif_running(dev) (dev)->start + -+#endif /* BCMDBG_MEM */ ++#endif /* _COMPAT_NETDEVICE_H */ + -+#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) ++#define netif_device_attach(dev) netif_start_queue(dev) ++#define netif_device_detach(dev) netif_stop_queue(dev) + -+extern void *osl_malloc(osl_t *osh, uint size); -+extern void osl_mfree(osl_t *osh, void *addr, uint size); -+extern uint osl_malloced(osl_t *osh); -+extern uint osl_malloc_failed(osl_t *osh); ++/* 2.4.x renamed bottom halves to tasklets */ ++#define tasklet_struct tq_struct ++static inline void tasklet_schedule(struct tasklet_struct *tasklet) ++{ ++ queue_task(tasklet, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++} + -+/* allocate/free shared (dma-able) consistent memory */ -+#define DMA_CONSISTENT_ALIGN PAGE_SIZE -+#define DMA_ALLOC_CONSISTENT(osh, size, pap) \ -+ osl_dma_alloc_consistent((osh), (size), (pap)) -+#define DMA_FREE_CONSISTENT(osh, va, size, pa) \ -+ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) -+extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap); -+extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); ++static inline void tasklet_init(struct tasklet_struct *tasklet, ++ void (*func)(unsigned long), ++ unsigned long data) ++{ ++ tasklet->next = NULL; ++ tasklet->sync = 0; ++ tasklet->routine = (void (*)(void *))func; ++ tasklet->data = (void *)data; ++} ++#define tasklet_kill(tasklet) {do{} while(0);} + -+/* map/unmap direction */ -+#define DMA_TX 1 -+#define DMA_RX 2 ++/* 2.4.x introduced del_timer_sync() */ ++#define del_timer_sync(timer) del_timer(timer) + -+/* map/unmap shared (dma-able) memory */ -+#define DMA_MAP(osh, va, size, direction, p) \ -+ osl_dma_map((osh), (va), (size), (direction)) -+#define DMA_UNMAP(osh, pa, size, direction, p) \ -+ osl_dma_unmap((osh), (pa), (size), (direction)) -+extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); -+extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); ++#else + -+/* register access macros */ -+#if defined(BCMJTAG) -+#include -+#define R_REG(r) bcmjtag_read(NULL, (uint32)(r), sizeof (*(r))) -+#define W_REG(r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof (*(r))) -+#endif ++#define netif_down(dev) ++ ++#endif /* SoftNet */ ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)) + +/* -+ * BINOSL selects the slightly slower function-call-based binary compatible osl. -+ * Macros expand to calls to functions defined in linux_osl.c . ++ * Emit code to initialise a tq_struct's routine and data pointers + */ -+#ifndef BINOSL ++#define PREPARE_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ (_tq)->routine = _routine; \ ++ (_tq)->data = _data; \ ++ } while (0) + -+/* string library, kernel mode */ -+#define printf(fmt, args...) printk(fmt, ## args) -+#include -+#include ++/* ++ * Emit code to initialise all of a tq_struct ++ */ ++#define INIT_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ INIT_LIST_HEAD(&(_tq)->list); \ ++ (_tq)->sync = 0; \ ++ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ ++ } while (0) + -+/* register access macros */ -+#if !defined(BCMJTAG) -+#ifndef IL_BIGENDIAN -+#define R_REG(r) ( \ -+ sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ -+ sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ -+ readl((volatile uint32*)(r)) \ -+) -+#define W_REG(r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ -+ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ -+ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ -+ } \ -+} while (0) -+#else /* IL_BIGENDIAN */ -+#define R_REG(r) ({ \ -+ __typeof(*(r)) __osl_v; \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \ -+ case sizeof(uint16): __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \ -+ case sizeof(uint32): __osl_v = readl((volatile uint32*)(r)); break; \ -+ } \ -+ __osl_v; \ -+}) -+#define W_REG(r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \ -+ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \ -+ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ -+ } \ -+} while (0) -+#endif +#endif + -+#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) -+#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6)) + -+/* bcopy, bcmp, and bzero */ -+#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -+#define bzero(b, len) memset((b), '\0', (len)) ++/* Power management related routines */ + -+/* uncached virtual address */ -+#ifdef mips -+#define OSL_UNCACHED(va) KSEG1ADDR((va)) -+#include -+#else -+#define OSL_UNCACHED(va) (va) ++static inline int ++pci_save_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_read_config_dword(dev, i * 4,&buffer[i]); ++ } ++ return 0; ++} ++ ++static inline int ++pci_restore_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_write_config_dword(dev,i * 4, buffer[i]); ++ } ++ /* ++ * otherwise, write the context information we know from bootup. ++ * This works around a problem where warm-booting from Windows ++ * combined with a D3(hot)->D0 transition causes PCI config ++ * header data to be forgotten. ++ */ ++ else { ++ for (i = 0; i < 6; i ++) ++ pci_write_config_dword(dev, ++ PCI_BASE_ADDRESS_0 + (i * 4), ++ pci_resource_start(dev, i)); ++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); ++ } ++ return 0; ++} ++ ++#endif /* PCI power management */ ++ ++/* Old cp0 access macros deprecated in 2.4.19 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)) ++#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) +#endif + -+/* get processor cycle count */ -+#if defined(mips) -+#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2) -+#elif defined(__i386__) -+#define OSL_GETCYCLES(x) rdtscl((x)) ++/* Module refcount handled internally in 2.6.x */ ++#ifndef SET_MODULE_OWNER ++#define SET_MODULE_OWNER(dev) do {} while (0) ++#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT ++#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT +#else -+#define OSL_GETCYCLES(x) ((x) = 0) ++#define OLD_MOD_INC_USE_COUNT do {} while (0) ++#define OLD_MOD_DEC_USE_COUNT do {} while (0) +#endif + -+/* dereference an address that may cause a bus exception */ -+#ifdef mips -+#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17)) -+#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into a module") -+#else -+#define BUSPROBE(val, addr) get_dbe((val), (addr)) -+#include ++#ifndef SET_NETDEV_DEV ++#define SET_NETDEV_DEV(net, pdev) do {} while (0) +#endif -+#else -+#define BUSPROBE(val, addr) ({ (val) = R_REG((addr)); 0; }) ++ ++#ifndef HAVE_FREE_NETDEV ++#define free_netdev(dev) kfree(dev) +#endif + -+/* map/unmap physical to virtual I/O */ -+#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) -+#define REG_UNMAP(va) iounmap((void *)(va)) ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) ++/* struct packet_type redefined in 2.6.x */ ++#define af_packet_priv data ++#endif + -+/* shared (dma-able) memory access macros */ -+#define R_SM(r) *(r) -+#define W_SM(r, v) (*(r) = (v)) -+#define BZERO_SM(r, len) memset((r), '\0', (len)) ++#endif /* _linuxver_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h +--- linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,552 @@ ++/* ++ * HND Run Time Environment for standalone MIPS programs. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ + -+/* packet primitives */ -+#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) -+#define PKTFREE(osh, skb, send) osl_pktfree((skb)) -+#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) -+#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) -+#define PKTHEADROOM(osh, skb) (PKTDATA(osh,skb)-(((struct sk_buff*)(skb))->head)) -+#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) -+#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) -+#define PKTSETNEXT(skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) -+#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) -+#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) -+#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) -+#define PKTDUP(osh, skb) skb_clone((struct sk_buff*)(skb), GFP_ATOMIC) -+#define PKTCOOKIE(skb) ((void*)((struct sk_buff*)(skb))->csum) -+#define PKTSETCOOKIE(skb, x) (((struct sk_buff*)(skb))->csum = (uint)(x)) -+#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) -+#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) -+#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) -+#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) -+extern void *osl_pktget(osl_t *osh, uint len, bool send); -+extern void osl_pktfree(void *skb); ++#ifndef _MISPINC_H ++#define _MISPINC_H + -+#else /* BINOSL */ + -+/* string library */ -+#ifndef LINUX_OSL -+#undef printf -+#define printf(fmt, args...) osl_printf((fmt), ## args) -+#undef sprintf -+#define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args) -+#undef strcmp -+#define strcmp(s1, s2) osl_strcmp((s1), (s2)) -+#undef strncmp -+#define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n)) -+#undef strlen -+#define strlen(s) osl_strlen((s)) -+#undef strcpy -+#define strcpy(d, s) osl_strcpy((d), (s)) -+#undef strncpy -+#define strncpy(d, s, n) osl_strncpy((d), (s), (n)) -+#endif -+extern int osl_printf(const char *format, ...); -+extern int osl_sprintf(char *buf, const char *format, ...); -+extern int osl_strcmp(const char *s1, const char *s2); -+extern int osl_strncmp(const char *s1, const char *s2, uint n); -+extern int osl_strlen(const char *s); -+extern char* osl_strcpy(char *d, const char *s); -+extern char* osl_strncpy(char *d, const char *s, uint n); -+ -+/* register access macros */ -+#if !defined(BCMJTAG) -+#define R_REG(r) ( \ -+ sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \ -+ sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \ -+ osl_readl((volatile uint32*)(r)) \ -+) -+#define W_REG(r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \ -+ case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \ -+ case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \ -+ } \ -+} while (0) -+#endif -+ -+#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) -+#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) -+extern uint8 osl_readb(volatile uint8 *r); -+extern uint16 osl_readw(volatile uint16 *r); -+extern uint32 osl_readl(volatile uint32 *r); -+extern void osl_writeb(uint8 v, volatile uint8 *r); -+extern void osl_writew(uint16 v, volatile uint16 *r); -+extern void osl_writel(uint32 v, volatile uint32 *r); -+ -+/* bcopy, bcmp, and bzero */ -+extern void bcopy(const void *src, void *dst, int len); -+extern int bcmp(const void *b1, const void *b2, int len); -+extern void bzero(void *b, int len); -+ -+/* uncached virtual address */ -+#define OSL_UNCACHED(va) osl_uncached((va)) -+extern void *osl_uncached(void *va); -+ -+/* get processor cycle count */ -+#define OSL_GETCYCLES(x) ((x) = osl_getcycles()) -+extern uint osl_getcycles(void); -+ -+/* dereference an address that may target abort */ -+#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr)) -+extern int osl_busprobe(uint32 *val, uint32 addr); -+ -+/* map/unmap physical to virtual */ -+#define REG_MAP(pa, size) osl_reg_map((pa), (size)) -+#define REG_UNMAP(va) osl_reg_unmap((va)) -+extern void *osl_reg_map(uint32 pa, uint size); -+extern void osl_reg_unmap(void *va); ++/* MIPS defines */ + -+/* shared (dma-able) memory access macros */ -+#define R_SM(r) *(r) -+#define W_SM(r, v) (*(r) = (v)) -+#define BZERO_SM(r, len) bzero((r), (len)) ++#ifdef _LANGUAGE_ASSEMBLY + -+/* packet primitives */ -+#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) -+#define PKTFREE(osh, skb, send) osl_pktfree((skb)) -+#define PKTDATA(osh, skb) osl_pktdata((osh), (skb)) -+#define PKTLEN(osh, skb) osl_pktlen((osh), (skb)) -+#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb)) -+#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb)) -+#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb)) -+#define PKTSETNEXT(skb, x) osl_pktsetnext((skb), (x)) -+#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len)) -+#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes)) -+#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes)) -+#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -+#define PKTCOOKIE(skb) osl_pktcookie((skb)) -+#define PKTSETCOOKIE(skb, x) osl_pktsetcookie((skb), (x)) -+#define PKTLINK(skb) osl_pktlink((skb)) -+#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x)) -+#define PKTPRIO(skb) osl_pktprio((skb)) -+#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x)) -+extern void *osl_pktget(osl_t *osh, uint len, bool send); -+extern void osl_pktfree(void *skb); -+extern uchar *osl_pktdata(osl_t *osh, void *skb); -+extern uint osl_pktlen(osl_t *osh, void *skb); -+extern uint osl_pktheadroom(osl_t *osh, void *skb); -+extern uint osl_pkttailroom(osl_t *osh, void *skb); -+extern void *osl_pktnext(osl_t *osh, void *skb); -+extern void osl_pktsetnext(void *skb, void *x); -+extern void osl_pktsetlen(osl_t *osh, void *skb, uint len); -+extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes); -+extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes); -+extern void *osl_pktdup(osl_t *osh, void *skb); -+extern void *osl_pktcookie(void *skb); -+extern void osl_pktsetcookie(void *skb, void *x); -+extern void *osl_pktlink(void *skb); -+extern void osl_pktsetlink(void *skb, void *x); -+extern uint osl_pktprio(void *skb); -+extern void osl_pktsetprio(void *skb, uint x); ++/* ++ * Symbolic register names for 32 bit ABI ++ */ ++#define zero $0 /* wired zero */ ++#define AT $1 /* assembler temp - uppercase because of ".set at" */ ++#define v0 $2 /* return value */ ++#define v1 $3 ++#define a0 $4 /* argument registers */ ++#define a1 $5 ++#define a2 $6 ++#define a3 $7 ++#define t0 $8 /* caller saved */ ++#define t1 $9 ++#define t2 $10 ++#define t3 $11 ++#define t4 $12 ++#define t5 $13 ++#define t6 $14 ++#define t7 $15 ++#define s0 $16 /* callee saved */ ++#define s1 $17 ++#define s2 $18 ++#define s3 $19 ++#define s4 $20 ++#define s5 $21 ++#define s6 $22 ++#define s7 $23 ++#define t8 $24 /* caller saved */ ++#define t9 $25 ++#define jp $25 /* PIC jump register */ ++#define k0 $26 /* kernel scratch */ ++#define k1 $27 ++#define gp $28 /* global pointer */ ++#define sp $29 /* stack pointer */ ++#define fp $30 /* frame pointer */ ++#define s8 $30 /* same like fp! */ ++#define ra $31 /* return address */ + -+#endif /* BINOSL */ + -+#define OSL_ERROR(bcmerror) osl_error(bcmerror) -+extern int osl_error(int bcmerror); ++/* ++ * CP0 Registers ++ */ + -+/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -+#define PKTBUFSZ 2048 ++#define C0_INX $0 ++#define C0_RAND $1 ++#define C0_TLBLO0 $2 ++#define C0_TLBLO C0_TLBLO0 ++#define C0_TLBLO1 $3 ++#define C0_CTEXT $4 ++#define C0_PGMASK $5 ++#define C0_WIRED $6 ++#define C0_BADVADDR $8 ++#define C0_COUNT $9 ++#define C0_TLBHI $10 ++#define C0_COMPARE $11 ++#define C0_SR $12 ++#define C0_STATUS C0_SR ++#define C0_CAUSE $13 ++#define C0_EPC $14 ++#define C0_PRID $15 ++#define C0_CONFIG $16 ++#define C0_LLADDR $17 ++#define C0_WATCHLO $18 ++#define C0_WATCHHI $19 ++#define C0_XCTEXT $20 ++#define C0_DIAGNOSTIC $22 ++#define C0_BROADCOM C0_DIAGNOSTIC ++#define C0_PERFORMANCE $25 ++#define C0_ECC $26 ++#define C0_CACHEERR $27 ++#define C0_TAGLO $28 ++#define C0_TAGHI $29 ++#define C0_ERREPC $30 ++#define C0_DESAVE $31 + -+#endif /* _linux_osl_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h ---- linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h 2005-12-16 23:39:10.748824500 +0100 -@@ -0,0 +1,411 @@ +/* -+ * Linux-specific abstractions to gain some independence from linux kernel versions. -+ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ ++ * LEAF - declare leaf routine + */ ++#define LEAF(symbol) \ ++ .globl symbol; \ ++ .align 2; \ ++ .type symbol,@function; \ ++ .ent symbol,0; \ ++symbol: .frame sp,0,ra + -+#ifndef _linuxver_h_ -+#define _linuxver_h_ ++/* ++ * END - mark end of function ++ */ ++#define END(function) \ ++ .end function; \ ++ .size function,.-function + -+#include -+#include ++#define _ULCAST_ + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) -+/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ -+#ifdef __UNDEF_NO_VERSION__ -+#undef __NO_VERSION__ +#else -+#define __NO_VERSION__ -+#endif -+#endif + -+#if defined(MODULE) && defined(MODVERSIONS) -+#include ++/* ++ * The following macros are especially useful for __asm__ ++ * inline assembler. ++ */ ++#ifndef __STR ++#define __STR(x) #x +#endif -+ -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -+#include ++#ifndef STR ++#define STR(x) __STR(x) +#endif + ++#define _ULCAST_ (unsigned long) + -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -+#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") -+#define module_param_string(_name_, _string_, _size_, _perm_) MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) -+#endif -+ -+/* linux/malloc.h is deprecated, use linux/slab.h instead. */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)) -+#include -+#else -+#include -+#endif + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++/* ++ * CP0 Registers ++ */ + -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) -+#include -+#else -+#include -+#ifndef work_struct -+#define work_struct tq_struct -+#endif -+#ifndef INIT_WORK -+#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) -+#endif -+#ifndef schedule_work -+#define schedule_work(_work) schedule_task((_work)) -+#endif -+#ifndef flush_scheduled_work -+#define flush_scheduled_work() flush_scheduled_tasks() -+#endif -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) -+/* Some distributions have their own 2.6.x compatibility layers */ -+#ifndef IRQ_NONE -+typedef void irqreturn_t; -+#define IRQ_NONE -+#define IRQ_HANDLED -+#define IRQ_RETVAL(x) -+#endif -+#else -+typedef irqreturn_t (*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); -+#endif -+ -+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)) -+/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which -+ * does this, but it's not in 2.4 so we do our own for now. */ -+static inline void -+cs_error(client_handle_t handle, int func, int ret) -+{ -+ error_info_t err = { func, ret }; -+ CardServices(ReportError, handle, &err); -+} -+#endif -+ -+#endif /* CONFIG_PCMCIA */ -+ -+#ifndef __exit -+#define __exit -+#endif -+#ifndef __devexit -+#define __devexit -+#endif -+#ifndef __devinit -+#define __devinit __init -+#endif -+#ifndef __devinitdata -+#define __devinitdata -+#endif -+#ifndef __devexit_p -+#define __devexit_p(x) x -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) ++#define C0_INX 0 /* CP0: TLB Index */ ++#define C0_RAND 1 /* CP0: TLB Random */ ++#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ ++#define C0_CTEXT 4 /* CP0: Context */ ++#define C0_PGMASK 5 /* CP0: TLB PageMask */ ++#define C0_WIRED 6 /* CP0: TLB Wired */ ++#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ ++#define C0_COUNT 9 /* CP0: Count */ ++#define C0_TLBHI 10 /* CP0: TLB EntryHi */ ++#define C0_COMPARE 11 /* CP0: Compare */ ++#define C0_SR 12 /* CP0: Processor Status */ ++#define C0_STATUS C0_SR /* CP0: Processor Status */ ++#define C0_CAUSE 13 /* CP0: Exception Cause */ ++#define C0_EPC 14 /* CP0: Exception PC */ ++#define C0_PRID 15 /* CP0: Processor Revision Indentifier */ ++#define C0_CONFIG 16 /* CP0: Config */ ++#define C0_LLADDR 17 /* CP0: LLAddr */ ++#define C0_WATCHLO 18 /* CP0: WatchpointLo */ ++#define C0_WATCHHI 19 /* CP0: WatchpointHi */ ++#define C0_XCTEXT 20 /* CP0: XContext */ ++#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ ++#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ ++#define C0_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */ ++#define C0_ECC 26 /* CP0: ECC */ ++#define C0_CACHEERR 27 /* CP0: CacheErr */ ++#define C0_TAGLO 28 /* CP0: TagLo */ ++#define C0_TAGHI 29 /* CP0: TagHi */ ++#define C0_ERREPC 30 /* CP0: ErrorEPC */ ++#define C0_DESAVE 31 /* CP0: DebugSave */ + -+#define pci_get_drvdata(dev) (dev)->sysdata -+#define pci_set_drvdata(dev, value) (dev)->sysdata=(value) ++#endif /* _LANGUAGE_ASSEMBLY */ + +/* -+ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration ++ * Memory segments (32bit kernel mode addresses) + */ ++#undef KUSEG ++#undef KSEG0 ++#undef KSEG1 ++#undef KSEG2 ++#undef KSEG3 ++#define KUSEG 0x00000000 ++#define KSEG0 0x80000000 ++#define KSEG1 0xa0000000 ++#define KSEG2 0xc0000000 ++#define KSEG3 0xe0000000 ++#define PHYSADDR_MASK 0x1fffffff + -+struct pci_device_id { -+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ -+ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ -+ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ -+ unsigned long driver_data; /* Data private to the driver */ -+}; -+ -+struct pci_driver { -+ struct list_head node; -+ char *name; -+ const struct pci_device_id *id_table; /* NULL if wants all devices */ -+ int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ -+ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ -+ void (*suspend)(struct pci_dev *dev); /* Device suspended */ -+ void (*resume)(struct pci_dev *dev); /* Device woken up */ -+}; -+ -+#define MODULE_DEVICE_TABLE(type, name) -+#define PCI_ANY_ID (~0) -+ -+/* compatpci.c */ -+#define pci_module_init pci_register_driver -+extern int pci_register_driver(struct pci_driver *drv); -+extern void pci_unregister_driver(struct pci_driver *drv); ++/* ++ * Map an address to a certain kernel segment ++ */ ++#undef PHYSADDR ++#undef KSEG0ADDR ++#undef KSEG1ADDR ++#undef KSEG2ADDR ++#undef KSEG3ADDR + -+#endif /* PCI registration */ ++#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) ++#define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0) ++#define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1) ++#define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2) ++#define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3) + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) -+#ifdef MODULE -+#define module_init(x) int init_module(void) { return x(); } -+#define module_exit(x) void cleanup_module(void) { x(); } -+#else -+#define module_init(x) __initcall(x); -+#define module_exit(x) __exitcall(x); -+#endif -+#endif + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)) -+#define list_for_each(pos, head) \ -+ for (pos = (head)->next; pos != (head); pos = pos->next) ++#ifndef Index_Invalidate_I ++/* ++ * Cache Operations ++ */ ++#define Index_Invalidate_I 0x00 ++#define Index_Writeback_Inv_D 0x01 ++#define Index_Invalidate_SI 0x02 ++#define Index_Writeback_Inv_SD 0x03 ++#define Index_Load_Tag_I 0x04 ++#define Index_Load_Tag_D 0x05 ++#define Index_Load_Tag_SI 0x06 ++#define Index_Load_Tag_SD 0x07 ++#define Index_Store_Tag_I 0x08 ++#define Index_Store_Tag_D 0x09 ++#define Index_Store_Tag_SI 0x0A ++#define Index_Store_Tag_SD 0x0B ++#define Create_Dirty_Excl_D 0x0d ++#define Create_Dirty_Excl_SD 0x0f ++#define Hit_Invalidate_I 0x10 ++#define Hit_Invalidate_D 0x11 ++#define Hit_Invalidate_SI 0x12 ++#define Hit_Invalidate_SD 0x13 ++#define Fill_I 0x14 ++#define Hit_Writeback_Inv_D 0x15 ++ /* 0x16 is unused */ ++#define Hit_Writeback_Inv_SD 0x17 ++#define R5K_Page_Invalidate_S 0x17 ++#define Hit_Writeback_I 0x18 ++#define Hit_Writeback_D 0x19 ++ /* 0x1a is unused */ ++#define Hit_Writeback_SD 0x1b ++ /* 0x1c is unused */ ++ /* 0x1e is unused */ ++#define Hit_Set_Virtual_SI 0x1e ++#define Hit_Set_Virtual_SD 0x1f +#endif + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)) -+#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) -+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,44)) -+#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) -+#endif + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,23)) -+#define pci_enable_device(dev) do { } while (0) -+#endif ++/* ++ * R4x00 interrupt enable / cause bits ++ */ ++#define IE_SW0 (_ULCAST_(1) << 8) ++#define IE_SW1 (_ULCAST_(1) << 9) ++#define IE_IRQ0 (_ULCAST_(1) << 10) ++#define IE_IRQ1 (_ULCAST_(1) << 11) ++#define IE_IRQ2 (_ULCAST_(1) << 12) ++#define IE_IRQ3 (_ULCAST_(1) << 13) ++#define IE_IRQ4 (_ULCAST_(1) << 14) ++#define IE_IRQ5 (_ULCAST_(1) << 15) + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14)) -+#define net_device device ++#ifndef ST0_UM ++/* ++ * Bitfields in the mips32 cp0 status register ++ */ ++#define ST0_IE 0x00000001 ++#define ST0_EXL 0x00000002 ++#define ST0_ERL 0x00000004 ++#define ST0_UM 0x00000010 ++#define ST0_SWINT0 0x00000100 ++#define ST0_SWINT1 0x00000200 ++#define ST0_HWINT0 0x00000400 ++#define ST0_HWINT1 0x00000800 ++#define ST0_HWINT2 0x00001000 ++#define ST0_HWINT3 0x00002000 ++#define ST0_HWINT4 0x00004000 ++#define ST0_HWINT5 0x00008000 ++#define ST0_IM 0x0000ff00 ++#define ST0_NMI 0x00080000 ++#define ST0_SR 0x00100000 ++#define ST0_TS 0x00200000 ++#define ST0_BEV 0x00400000 ++#define ST0_RE 0x02000000 ++#define ST0_RP 0x08000000 ++#define ST0_CU 0xf0000000 ++#define ST0_CU0 0x10000000 ++#define ST0_CU1 0x20000000 ++#define ST0_CU2 0x40000000 ++#define ST0_CU3 0x80000000 +#endif + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)) + +/* -+ * DMA mapping -+ * -+ * See linux/Documentation/DMA-mapping.txt ++ * Bitfields in the mips32 cp0 cause register + */ ++#define C_EXC 0x0000007c ++#define C_EXC_SHIFT 2 ++#define C_INT 0x0000ff00 ++#define C_INT_SHIFT 8 ++#define C_SW0 (_ULCAST_(1) << 8) ++#define C_SW1 (_ULCAST_(1) << 9) ++#define C_IRQ0 (_ULCAST_(1) << 10) ++#define C_IRQ1 (_ULCAST_(1) << 11) ++#define C_IRQ2 (_ULCAST_(1) << 12) ++#define C_IRQ3 (_ULCAST_(1) << 13) ++#define C_IRQ4 (_ULCAST_(1) << 14) ++#define C_IRQ5 (_ULCAST_(1) << 15) ++#define C_WP 0x00400000 ++#define C_IV 0x00800000 ++#define C_CE 0x30000000 ++#define C_CE_SHIFT 28 ++#define C_BD 0x80000000 + -+#ifndef PCI_DMA_TODEVICE -+#define PCI_DMA_TODEVICE 1 -+#define PCI_DMA_FROMDEVICE 2 -+#endif -+ -+typedef u32 dma_addr_t; -+ -+/* Pure 2^n version of get_order */ -+static inline int get_order(unsigned long size) -+{ -+ int order; -+ -+ size = (size-1) >> (PAGE_SHIFT-1); -+ order = -1; -+ do { -+ size >>= 1; -+ order++; -+ } while (size); -+ return order; -+} -+ -+static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, -+ dma_addr_t *dma_handle) -+{ -+ void *ret; -+ int gfp = GFP_ATOMIC | GFP_DMA; -+ -+ ret = (void *)__get_free_pages(gfp, get_order(size)); -+ -+ if (ret != NULL) { -+ memset(ret, 0, size); -+ *dma_handle = virt_to_bus(ret); -+ } -+ return ret; -+} -+static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, -+ void *vaddr, dma_addr_t dma_handle) -+{ -+ free_pages((unsigned long)vaddr, get_order(size)); -+} -+#ifdef ILSIM -+extern uint pci_map_single(void *dev, void *va, uint size, int direction); -+extern void pci_unmap_single(void *dev, uint pa, uint size, int direction); -+#else -+#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) -+#define pci_unmap_single(cookie, address, size, dir) -+#endif -+ -+#endif /* DMA mapping */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) -+ -+#define dev_kfree_skb_any(a) dev_kfree_skb(a) -+#define netif_down(dev) do { (dev)->start = 0; } while(0) -+ -+/* pcmcia-cs provides its own netdevice compatibility layer */ -+#ifndef _COMPAT_NETDEVICE_H -+ -+/* -+ * SoftNet -+ * -+ * For pre-softnet kernels we need to tell the upper layer not to -+ * re-enter start_xmit() while we are in there. However softnet -+ * guarantees not to enter while we are in there so there is no need -+ * to do the netif_stop_queue() dance unless the transmit queue really -+ * gets stuck. This should also improve performance according to tests -+ * done by Aman Singla. -+ */ -+ -+#define dev_kfree_skb_irq(a) dev_kfree_skb(a) -+#define netif_wake_queue(dev) do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while(0) -+#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) -+ -+static inline void netif_start_queue(struct net_device *dev) -+{ -+ dev->tbusy = 0; -+ dev->interrupt = 0; -+ dev->start = 1; -+} -+ -+#define netif_queue_stopped(dev) (dev)->tbusy -+#define netif_running(dev) (dev)->start -+ -+#endif /* _COMPAT_NETDEVICE_H */ -+ -+#define netif_device_attach(dev) netif_start_queue(dev) -+#define netif_device_detach(dev) netif_stop_queue(dev) -+ -+/* 2.4.x renamed bottom halves to tasklets */ -+#define tasklet_struct tq_struct -+static inline void tasklet_schedule(struct tasklet_struct *tasklet) -+{ -+ queue_task(tasklet, &tq_immediate); -+ mark_bh(IMMEDIATE_BH); -+} -+ -+static inline void tasklet_init(struct tasklet_struct *tasklet, -+ void (*func)(unsigned long), -+ unsigned long data) -+{ -+ tasklet->next = NULL; -+ tasklet->sync = 0; -+ tasklet->routine = (void (*)(void *))func; -+ tasklet->data = (void *)data; -+} -+#define tasklet_kill(tasklet) {do{} while(0);} -+ -+/* 2.4.x introduced del_timer_sync() */ -+#define del_timer_sync(timer) del_timer(timer) -+ -+#else -+ -+#define netif_down(dev) -+ -+#endif /* SoftNet */ -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)) -+ -+/* -+ * Emit code to initialise a tq_struct's routine and data pointers -+ */ -+#define PREPARE_TQUEUE(_tq, _routine, _data) \ -+ do { \ -+ (_tq)->routine = _routine; \ -+ (_tq)->data = _data; \ -+ } while (0) -+ -+/* -+ * Emit code to initialise all of a tq_struct -+ */ -+#define INIT_TQUEUE(_tq, _routine, _data) \ -+ do { \ -+ INIT_LIST_HEAD(&(_tq)->list); \ -+ (_tq)->sync = 0; \ -+ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ -+ } while (0) -+ -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6)) -+ -+/* Power management related routines */ -+ -+static inline int -+pci_save_state(struct pci_dev *dev, u32 *buffer) -+{ -+ int i; -+ if (buffer) { -+ for (i = 0; i < 16; i++) -+ pci_read_config_dword(dev, i * 4,&buffer[i]); -+ } -+ return 0; -+} -+ -+static inline int -+pci_restore_state(struct pci_dev *dev, u32 *buffer) -+{ -+ int i; -+ -+ if (buffer) { -+ for (i = 0; i < 16; i++) -+ pci_write_config_dword(dev,i * 4, buffer[i]); -+ } -+ /* -+ * otherwise, write the context information we know from bootup. -+ * This works around a problem where warm-booting from Windows -+ * combined with a D3(hot)->D0 transition causes PCI config -+ * header data to be forgotten. -+ */ -+ else { -+ for (i = 0; i < 6; i ++) -+ pci_write_config_dword(dev, -+ PCI_BASE_ADDRESS_0 + (i * 4), -+ pci_resource_start(dev, i)); -+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); -+ } -+ return 0; -+} -+ -+#endif /* PCI power management */ -+ -+/* Old cp0 access macros deprecated in 2.4.19 */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)) -+#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) -+#endif -+ -+/* Module refcount handled internally in 2.6.x */ -+#ifndef SET_MODULE_OWNER -+#define SET_MODULE_OWNER(dev) do {} while (0) -+#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -+#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -+#else -+#define OLD_MOD_INC_USE_COUNT do {} while (0) -+#define OLD_MOD_DEC_USE_COUNT do {} while (0) -+#endif -+ -+#ifndef SET_NETDEV_DEV -+#define SET_NETDEV_DEV(net, pdev) do {} while (0) -+#endif -+ -+#ifndef HAVE_FREE_NETDEV -+#define free_netdev(dev) kfree(dev) -+#endif -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) -+/* struct packet_type redefined in 2.6.x */ -+#define af_packet_priv data -+#endif -+ -+#endif /* _linuxver_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/min_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/min_osl.h ---- linux-2.4.32/arch/mips/bcm947xx/include/min_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/min_osl.h 2005-12-16 23:39:10.748824500 +0100 -@@ -0,0 +1,126 @@ -+/* -+ * HND Minimal OS Abstraction Layer. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ -+ -+#ifndef _min_osl_h_ -+#define _min_osl_h_ -+ -+#include -+#include -+#include -+ -+/* Cache support */ -+extern void caches_on(void); -+extern void blast_dcache(void); -+extern void blast_icache(void); -+ -+/* uart output */ -+extern void putc(int c); -+ -+/* lib functions */ -+extern int printf(const char *fmt, ...); -+extern int sprintf(char *buf, const char *fmt, ...); -+extern int strcmp(const char *s1, const char *s2); -+extern int strncmp(const char *s1, const char *s2, uint n); -+extern char *strcpy(char *dest, const char *src); -+extern char *strncpy(char *dest, const char *src, uint n); -+extern uint strlen(const char *s); -+extern char *strchr(const char *str,int c); -+extern char *strrchr(const char *str, int c); -+extern char *strcat(char *d, const char *s); -+extern void *memset(void *dest, int c, uint n); -+extern void *memcpy(void *dest, const void *src, uint n); -+extern int memcmp(const void *s1, const void *s2, uint n); -+#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -+#define bzero(b, len) memset((b), '\0', (len)) -+ -+/* assert & debugging */ -+#define ASSERT(exp) do {} while (0) -+ -+/* PCMCIA attribute space access macros */ -+#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ -+ ASSERT(0) -+#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ -+ ASSERT(0) -+ -+/* PCI configuration space access macros */ -+#define OSL_PCI_READ_CONFIG(loc, offset, size) \ -+ (offset == 8 ? 0 : 0xffffffff) -+#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) \ -+ do {} while (0) -+ -+/* PCI device bus # and slot # */ -+#define OSL_PCI_BUS(osh) (0) -+#define OSL_PCI_SLOT(osh) (0) -+ -+/* register access macros */ -+#define wreg32(r, v) (*(volatile uint32*)(r) = (uint32)(v)) -+#define rreg32(r) (*(volatile uint32*)(r)) -+#define wreg16(r, v) (*(volatile uint16*)(r) = (uint16)(v)) -+#define rreg16(r) (*(volatile uint16*)(r)) -+#define wreg8(r, v) (*(volatile uint8*)(r) = (uint8)(v)) -+#define rreg8(r) (*(volatile uint8*)(r)) -+#define R_REG(r) ({ \ -+ __typeof(*(r)) __osl_v; \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): __osl_v = rreg8((r)); break; \ -+ case sizeof(uint16): __osl_v = rreg16((r)); break; \ -+ case sizeof(uint32): __osl_v = rreg32((r)); break; \ -+ } \ -+ __osl_v; \ -+}) -+#define W_REG(r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): wreg8((r), (v)); break; \ -+ case sizeof(uint16): wreg16((r), (v)); break; \ -+ case sizeof(uint32): wreg32((r), (v)); break; \ -+ } \ -+} while (0) -+#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) -+#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) -+ -+/* general purpose memory allocation */ -+#define MALLOC(osh, size) malloc(size) -+#define MFREE(osh, addr, size) free(addr) -+#define MALLOCED(osh) 0 -+#define MALLOC_FAILED(osh) 0 -+#define MALLOC_DUMP(osh, buf, sz) -+extern int free(void *ptr); -+extern void *malloc(uint size); -+ -+/* uncached virtual address */ -+#define OSL_UNCACHED(va) ((void*)KSEG1ADDR((ulong)(va))) -+ -+/* host/bus architecture-specific address byte swap */ -+#define BUS_SWAP32(v) (v) -+ -+/* microsecond delay */ -+#define OSL_DELAY(usec) udelay(usec) -+extern void udelay(uint32 usec); -+ -+/* map/unmap physical to virtual I/O */ -+#define REG_MAP(pa, size) ((void*)KSEG1ADDR((ulong)(pa))) -+#define REG_UNMAP(va) do {} while (0) -+ -+/* dereference an address that may cause a bus exception */ -+#define BUSPROBE(val, addr) (uint32 *)(addr) = (val) -+ -+/* Misc stubs */ -+#define osl_attach(pdev) ((osl_t*)pdev) -+#define osl_detach(osh) -+extern void *osl_init(void); -+#define OSL_ERROR(bcmerror) osl_error(bcmerror) -+extern int osl_error(int); -+ -+#endif /* _min_osl_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h ---- linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h 2005-12-16 23:39:10.748824500 +0100 -@@ -0,0 +1,552 @@ -+/* -+ * HND Run Time Environment for standalone MIPS programs. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ -+ -+#ifndef _MISPINC_H -+#define _MISPINC_H -+ -+ -+/* MIPS defines */ -+ -+#ifdef _LANGUAGE_ASSEMBLY -+ -+/* -+ * Symbolic register names for 32 bit ABI -+ */ -+#define zero $0 /* wired zero */ -+#define AT $1 /* assembler temp - uppercase because of ".set at" */ -+#define v0 $2 /* return value */ -+#define v1 $3 -+#define a0 $4 /* argument registers */ -+#define a1 $5 -+#define a2 $6 -+#define a3 $7 -+#define t0 $8 /* caller saved */ -+#define t1 $9 -+#define t2 $10 -+#define t3 $11 -+#define t4 $12 -+#define t5 $13 -+#define t6 $14 -+#define t7 $15 -+#define s0 $16 /* callee saved */ -+#define s1 $17 -+#define s2 $18 -+#define s3 $19 -+#define s4 $20 -+#define s5 $21 -+#define s6 $22 -+#define s7 $23 -+#define t8 $24 /* caller saved */ -+#define t9 $25 -+#define jp $25 /* PIC jump register */ -+#define k0 $26 /* kernel scratch */ -+#define k1 $27 -+#define gp $28 /* global pointer */ -+#define sp $29 /* stack pointer */ -+#define fp $30 /* frame pointer */ -+#define s8 $30 /* same like fp! */ -+#define ra $31 /* return address */ -+ -+ -+/* -+ * CP0 Registers -+ */ -+ -+#define C0_INX $0 -+#define C0_RAND $1 -+#define C0_TLBLO0 $2 -+#define C0_TLBLO C0_TLBLO0 -+#define C0_TLBLO1 $3 -+#define C0_CTEXT $4 -+#define C0_PGMASK $5 -+#define C0_WIRED $6 -+#define C0_BADVADDR $8 -+#define C0_COUNT $9 -+#define C0_TLBHI $10 -+#define C0_COMPARE $11 -+#define C0_SR $12 -+#define C0_STATUS C0_SR -+#define C0_CAUSE $13 -+#define C0_EPC $14 -+#define C0_PRID $15 -+#define C0_CONFIG $16 -+#define C0_LLADDR $17 -+#define C0_WATCHLO $18 -+#define C0_WATCHHI $19 -+#define C0_XCTEXT $20 -+#define C0_DIAGNOSTIC $22 -+#define C0_BROADCOM C0_DIAGNOSTIC -+#define C0_PERFORMANCE $25 -+#define C0_ECC $26 -+#define C0_CACHEERR $27 -+#define C0_TAGLO $28 -+#define C0_TAGHI $29 -+#define C0_ERREPC $30 -+#define C0_DESAVE $31 -+ -+/* -+ * LEAF - declare leaf routine -+ */ -+#define LEAF(symbol) \ -+ .globl symbol; \ -+ .align 2; \ -+ .type symbol,@function; \ -+ .ent symbol,0; \ -+symbol: .frame sp,0,ra -+ -+/* -+ * END - mark end of function -+ */ -+#define END(function) \ -+ .end function; \ -+ .size function,.-function -+ -+#define _ULCAST_ -+ -+#else -+ -+/* -+ * The following macros are especially useful for __asm__ -+ * inline assembler. -+ */ -+#ifndef __STR -+#define __STR(x) #x -+#endif -+#ifndef STR -+#define STR(x) __STR(x) -+#endif -+ -+#define _ULCAST_ (unsigned long) -+ -+ -+/* -+ * CP0 Registers -+ */ -+ -+#define C0_INX 0 /* CP0: TLB Index */ -+#define C0_RAND 1 /* CP0: TLB Random */ -+#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ -+#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ -+#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ -+#define C0_CTEXT 4 /* CP0: Context */ -+#define C0_PGMASK 5 /* CP0: TLB PageMask */ -+#define C0_WIRED 6 /* CP0: TLB Wired */ -+#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ -+#define C0_COUNT 9 /* CP0: Count */ -+#define C0_TLBHI 10 /* CP0: TLB EntryHi */ -+#define C0_COMPARE 11 /* CP0: Compare */ -+#define C0_SR 12 /* CP0: Processor Status */ -+#define C0_STATUS C0_SR /* CP0: Processor Status */ -+#define C0_CAUSE 13 /* CP0: Exception Cause */ -+#define C0_EPC 14 /* CP0: Exception PC */ -+#define C0_PRID 15 /* CP0: Processor Revision Indentifier */ -+#define C0_CONFIG 16 /* CP0: Config */ -+#define C0_LLADDR 17 /* CP0: LLAddr */ -+#define C0_WATCHLO 18 /* CP0: WatchpointLo */ -+#define C0_WATCHHI 19 /* CP0: WatchpointHi */ -+#define C0_XCTEXT 20 /* CP0: XContext */ -+#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ -+#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ -+#define C0_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */ -+#define C0_ECC 26 /* CP0: ECC */ -+#define C0_CACHEERR 27 /* CP0: CacheErr */ -+#define C0_TAGLO 28 /* CP0: TagLo */ -+#define C0_TAGHI 29 /* CP0: TagHi */ -+#define C0_ERREPC 30 /* CP0: ErrorEPC */ -+#define C0_DESAVE 31 /* CP0: DebugSave */ -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+/* -+ * Memory segments (32bit kernel mode addresses) -+ */ -+#undef KUSEG -+#undef KSEG0 -+#undef KSEG1 -+#undef KSEG2 -+#undef KSEG3 -+#define KUSEG 0x00000000 -+#define KSEG0 0x80000000 -+#define KSEG1 0xa0000000 -+#define KSEG2 0xc0000000 -+#define KSEG3 0xe0000000 -+#define PHYSADDR_MASK 0x1fffffff -+ -+/* -+ * Map an address to a certain kernel segment -+ */ -+#undef PHYSADDR -+#undef KSEG0ADDR -+#undef KSEG1ADDR -+#undef KSEG2ADDR -+#undef KSEG3ADDR -+ -+#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) -+#define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0) -+#define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1) -+#define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2) -+#define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3) -+ -+ -+#ifndef Index_Invalidate_I -+/* -+ * Cache Operations -+ */ -+#define Index_Invalidate_I 0x00 -+#define Index_Writeback_Inv_D 0x01 -+#define Index_Invalidate_SI 0x02 -+#define Index_Writeback_Inv_SD 0x03 -+#define Index_Load_Tag_I 0x04 -+#define Index_Load_Tag_D 0x05 -+#define Index_Load_Tag_SI 0x06 -+#define Index_Load_Tag_SD 0x07 -+#define Index_Store_Tag_I 0x08 -+#define Index_Store_Tag_D 0x09 -+#define Index_Store_Tag_SI 0x0A -+#define Index_Store_Tag_SD 0x0B -+#define Create_Dirty_Excl_D 0x0d -+#define Create_Dirty_Excl_SD 0x0f -+#define Hit_Invalidate_I 0x10 -+#define Hit_Invalidate_D 0x11 -+#define Hit_Invalidate_SI 0x12 -+#define Hit_Invalidate_SD 0x13 -+#define Fill_I 0x14 -+#define Hit_Writeback_Inv_D 0x15 -+ /* 0x16 is unused */ -+#define Hit_Writeback_Inv_SD 0x17 -+#define R5K_Page_Invalidate_S 0x17 -+#define Hit_Writeback_I 0x18 -+#define Hit_Writeback_D 0x19 -+ /* 0x1a is unused */ -+#define Hit_Writeback_SD 0x1b -+ /* 0x1c is unused */ -+ /* 0x1e is unused */ -+#define Hit_Set_Virtual_SI 0x1e -+#define Hit_Set_Virtual_SD 0x1f -+#endif -+ -+ -+/* -+ * R4x00 interrupt enable / cause bits -+ */ -+#define IE_SW0 (_ULCAST_(1) << 8) -+#define IE_SW1 (_ULCAST_(1) << 9) -+#define IE_IRQ0 (_ULCAST_(1) << 10) -+#define IE_IRQ1 (_ULCAST_(1) << 11) -+#define IE_IRQ2 (_ULCAST_(1) << 12) -+#define IE_IRQ3 (_ULCAST_(1) << 13) -+#define IE_IRQ4 (_ULCAST_(1) << 14) -+#define IE_IRQ5 (_ULCAST_(1) << 15) -+ -+#ifndef ST0_UM -+/* -+ * Bitfields in the mips32 cp0 status register -+ */ -+#define ST0_IE 0x00000001 -+#define ST0_EXL 0x00000002 -+#define ST0_ERL 0x00000004 -+#define ST0_UM 0x00000010 -+#define ST0_SWINT0 0x00000100 -+#define ST0_SWINT1 0x00000200 -+#define ST0_HWINT0 0x00000400 -+#define ST0_HWINT1 0x00000800 -+#define ST0_HWINT2 0x00001000 -+#define ST0_HWINT3 0x00002000 -+#define ST0_HWINT4 0x00004000 -+#define ST0_HWINT5 0x00008000 -+#define ST0_IM 0x0000ff00 -+#define ST0_NMI 0x00080000 -+#define ST0_SR 0x00100000 -+#define ST0_TS 0x00200000 -+#define ST0_BEV 0x00400000 -+#define ST0_RE 0x02000000 -+#define ST0_RP 0x08000000 -+#define ST0_CU 0xf0000000 -+#define ST0_CU0 0x10000000 -+#define ST0_CU1 0x20000000 -+#define ST0_CU2 0x40000000 -+#define ST0_CU3 0x80000000 -+#endif -+ -+ -+/* -+ * Bitfields in the mips32 cp0 cause register -+ */ -+#define C_EXC 0x0000007c -+#define C_EXC_SHIFT 2 -+#define C_INT 0x0000ff00 -+#define C_INT_SHIFT 8 -+#define C_SW0 (_ULCAST_(1) << 8) -+#define C_SW1 (_ULCAST_(1) << 9) -+#define C_IRQ0 (_ULCAST_(1) << 10) -+#define C_IRQ1 (_ULCAST_(1) << 11) -+#define C_IRQ2 (_ULCAST_(1) << 12) -+#define C_IRQ3 (_ULCAST_(1) << 13) -+#define C_IRQ4 (_ULCAST_(1) << 14) -+#define C_IRQ5 (_ULCAST_(1) << 15) -+#define C_WP 0x00400000 -+#define C_IV 0x00800000 -+#define C_CE 0x30000000 -+#define C_CE_SHIFT 28 -+#define C_BD 0x80000000 -+ -+/* Values in C_EXC */ -+#define EXC_INT 0 -+#define EXC_TLBM 1 -+#define EXC_TLBL 2 -+#define EXC_TLBS 3 -+#define EXC_AEL 4 -+#define EXC_AES 5 -+#define EXC_IBE 6 -+#define EXC_DBE 7 -+#define EXC_SYS 8 -+#define EXC_BPT 9 -+#define EXC_RI 10 -+#define EXC_CU 11 -+#define EXC_OV 12 -+#define EXC_TR 13 -+#define EXC_WATCH 23 -+#define EXC_MCHK 24 -+ -+ -+/* -+ * Bits in the cp0 config register. -+ */ -+#define CONF_CM_CACHABLE_NO_WA 0 -+#define CONF_CM_CACHABLE_WA 1 -+#define CONF_CM_UNCACHED 2 -+#define CONF_CM_CACHABLE_NONCOHERENT 3 -+#define CONF_CM_CACHABLE_CE 4 -+#define CONF_CM_CACHABLE_COW 5 -+#define CONF_CM_CACHABLE_CUW 6 -+#define CONF_CM_CACHABLE_ACCELERATED 7 -+#define CONF_CM_CMASK 7 -+#define CONF_CU (_ULCAST_(1) << 3) -+#define CONF_DB (_ULCAST_(1) << 4) -+#define CONF_IB (_ULCAST_(1) << 5) -+#define CONF_SE (_ULCAST_(1) << 12) -+#define CONF_SC (_ULCAST_(1) << 17) -+#define CONF_AC (_ULCAST_(1) << 23) -+#define CONF_HALT (_ULCAST_(1) << 25) -+ -+ -+/* -+ * Bits in the cp0 config register select 1. -+ */ -+#define CONF1_FP 0x00000001 /* FPU present */ -+#define CONF1_EP 0x00000002 /* EJTAG present */ -+#define CONF1_CA 0x00000004 /* mips16 implemented */ -+#define CONF1_WR 0x00000008 /* Watch registers present */ -+#define CONF1_PC 0x00000010 /* Performance counters present */ -+#define CONF1_DA_SHIFT 7 /* D$ associativity */ -+#define CONF1_DA_MASK 0x00000380 -+#define CONF1_DA_BASE 1 -+#define CONF1_DL_SHIFT 10 /* D$ line size */ -+#define CONF1_DL_MASK 0x00001c00 -+#define CONF1_DL_BASE 2 -+#define CONF1_DS_SHIFT 13 /* D$ sets/way */ -+#define CONF1_DS_MASK 0x0000e000 -+#define CONF1_DS_BASE 64 -+#define CONF1_IA_SHIFT 16 /* I$ associativity */ -+#define CONF1_IA_MASK 0x00070000 -+#define CONF1_IA_BASE 1 -+#define CONF1_IL_SHIFT 19 /* I$ line size */ -+#define CONF1_IL_MASK 0x00380000 -+#define CONF1_IL_BASE 2 -+#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ -+#define CONF1_IS_MASK 0x01c00000 -+#define CONF1_IS_BASE 64 -+#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */ -+#define CONF1_MS_SHIFT 25 -+ -+/* PRID register */ -+#define PRID_COPT_MASK 0xff000000 -+#define PRID_COMP_MASK 0x00ff0000 -+#define PRID_IMP_MASK 0x0000ff00 -+#define PRID_REV_MASK 0x000000ff -+ -+#define PRID_COMP_LEGACY 0x000000 -+#define PRID_COMP_MIPS 0x010000 -+#define PRID_COMP_BROADCOM 0x020000 -+#define PRID_COMP_ALCHEMY 0x030000 -+#define PRID_COMP_SIBYTE 0x040000 -+#define PRID_IMP_BCM4710 0x4000 -+#define PRID_IMP_BCM3302 0x9000 -+#define PRID_IMP_BCM3303 0x9100 -+ -+#define PRID_IMP_UNKNOWN 0xff00 -+ -+#define BCM330X(id) \ -+ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \ -+ || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) -+ -+/* Bits in C0_BROADCOM */ -+#define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */ -+#define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */ -+#define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */ -+#define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */ -+ -+/* PreFetch Cache aka Read Ahead Cache */ -+ -+#define PFC_CR0 0xff400000 /* control reg 0 */ -+#define PFC_CR1 0xff400004 /* control reg 1 */ -+ -+/* PFC operations */ -+#define PFC_I 0x00000001 /* Enable PFC use for instructions */ -+#define PFC_D 0x00000002 /* Enable PFC use for data */ -+#define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */ -+#define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */ -+#define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */ -+#define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */ -+#define PFC_DPF 0x00000040 /* Enable directional prefetching */ -+#define PFC_FLUSH 0x00000100 /* Flush the PFC */ -+#define PFC_BRR 0x40000000 /* Bus error indication */ -+#define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */ -+ -+/* Handy defaults */ -+#define PFC_DISABLED 0 -+#define PFC_AUTO 0xffffffff /* auto select the default mode */ -+#define PFC_INST (PFC_I | PFC_PFI | PFC_CINV) -+#define PFC_INST_NOPF (PFC_I | PFC_CINV) -+#define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV) -+#define PFC_DATA_NOPF (PFC_D | PFC_CINV) -+#define PFC_I_AND_D (PFC_INST | PFC_DATA) -+#define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF) -+ -+ -+/* -+ * These are the UART port assignments, expressed as offsets from the base -+ * register. These assignments should hold for any serial port based on -+ * a 8250, 16450, or 16550(A). -+ */ -+ -+#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ -+#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ -+#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ -+#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ -+#define UART_LCR 3 /* Out: Line Control Register */ -+#define UART_MCR 4 /* Out: Modem Control Register */ -+#define UART_LSR 5 /* In: Line Status Register */ -+#define UART_MSR 6 /* In: Modem Status Register */ -+#define UART_SCR 7 /* I/O: Scratch Register */ -+#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ -+#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ -+#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ -+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ -+#define UART_LSR_RXRDY 0x01 /* Receiver ready */ -+ -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+/* -+ * Macros to access the system control coprocessor -+ */ -+ -+#define MFC0(source, sel) \ -+({ \ -+ int __res; \ -+ __asm__ __volatile__( \ -+ ".set\tnoreorder\n\t" \ -+ ".set\tnoat\n\t" \ -+ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \ -+ "move\t%0,$1\n\t" \ -+ ".set\tat\n\t" \ -+ ".set\treorder" \ -+ :"=r" (__res) \ -+ : \ -+ :"$1"); \ -+ __res; \ -+}) -+ -+#define MTC0(source, sel, value) \ -+do { \ -+ __asm__ __volatile__( \ -+ ".set\tnoreorder\n\t" \ -+ ".set\tnoat\n\t" \ -+ "move\t$1,%z0\n\t" \ -+ ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \ -+ ".set\tat\n\t" \ -+ ".set\treorder" \ -+ : \ -+ :"jr" (value) \ -+ :"$1"); \ -+} while (0) -+ -+#define get_c0_count() \ -+({ \ -+ int __res; \ -+ __asm__ __volatile__( \ -+ ".set\tnoreorder\n\t" \ -+ ".set\tnoat\n\t" \ -+ "mfc0\t%0,$9\n\t" \ -+ ".set\tat\n\t" \ -+ ".set\treorder" \ -+ :"=r" (__res)); \ -+ __res; \ -+}) -+ -+static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize) -+{ -+ uint lsz, sets, ways; -+ -+ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ -+ if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT))) -+ lsz = CONF1_IL_BASE << lsz; -+ sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT); -+ ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT); -+ *size = lsz * sets * ways; -+ *lsize = lsz; -+} -+ -+static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize) -+{ -+ uint lsz, sets, ways; -+ -+ /* Data Cache Size = Associativity * Line Size * Sets Per Way */ -+ if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT))) -+ lsz = CONF1_DL_BASE << lsz; -+ sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT); -+ ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT); -+ *size = lsz * sets * ways; -+ *lsize = lsz; -+} -+ -+#define cache_op(base, op) \ -+ __asm__ __volatile__(" \ -+ .set noreorder; \ -+ .set mips3; \ -+ cache %1, (%0); \ -+ .set mips0; \ -+ .set reorder" \ -+ : \ -+ : "r" (base), \ -+ "i" (op)); -+ -+#define cache_unroll4(base, delta, op) \ -+ __asm__ __volatile__(" \ -+ .set noreorder; \ -+ .set mips3; \ -+ cache %1,0(%0); \ -+ cache %1,delta(%0); \ -+ cache %1,(2 * delta)(%0); \ -+ cache %1,(3 * delta)(%0); \ -+ .set mips0; \ -+ .set reorder" \ -+ : \ -+ : "r" (base), \ -+ "i" (op)); -+ -+#endif /* !_LANGUAGE_ASSEMBLY */ -+ -+#endif /* _MISPINC_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/nvports.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/nvports.h ---- linux-2.4.32/arch/mips/bcm947xx/include/nvports.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/nvports.h 2005-12-16 23:39:10.748824500 +0100 -@@ -0,0 +1,55 @@ -+/* -+ * BCM53xx RoboSwitch utility functions -+ * -+ * Copyright (C) 2002 Broadcom Corporation -+ * $Id$ -+ */ -+ -+#ifndef _nvports_h_ -+#define _nvports_h_ -+ -+#define uint32 unsigned long -+#define uint16 unsigned short -+#define uint unsigned int -+#define uint8 unsigned char -+#define uint64 unsigned long long -+ -+enum FORCE_PORT { -+ FORCE_OFF, -+ FORCE_10H, -+ FORCE_10F, -+ FORCE_100H, -+ FORCE_100F, -+ FORCE_DOWN, -+ POWER_OFF -+}; -+ -+typedef struct _PORT_ATTRIBS -+{ -+ uint autoneg; -+ uint force; -+ uint native; -+} PORT_ATTRIBS; -+ -+extern uint -+nvExistsPortAttrib(char *attrib, uint portno); -+ -+extern int -+nvExistsAnyForcePortAttrib(uint portno); -+ -+extern void -+nvSetPortAttrib(char *attrib, uint portno); -+ -+extern void -+nvUnsetPortAttrib(char *attrib, uint portno); -+ -+extern void -+nvUnsetAllForcePortAttrib(uint portno); -+ -+extern PORT_ATTRIBS -+nvGetSwitchPortAttribs(uint portno); -+ -+#endif /* _nvports_h_ */ -+ -+ -+ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h ---- linux-2.4.32/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h 2005-12-16 23:39:10.748824500 +0100 -@@ -0,0 +1,42 @@ -+/* -+ * OS Abstraction Layer -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ -+ -+#ifndef _osl_h_ -+#define _osl_h_ -+ -+/* osl handle type forward declaration */ -+typedef struct os_handle osl_t; -+ -+#if defined(linux) -+#include -+#elif defined(NDIS) -+#include -+#elif defined(_CFE_) -+#include -+#elif defined(_HNDRTE_) -+#include -+#elif defined(_MINOSL_) -+#include -+#elif PMON -+#include -+#elif defined(MACOSX) -+#include -+#else -+#error "Unsupported OSL requested" -+#endif -+ -+/* handy */ -+#define SET_REG(r, mask, val) W_REG((r), ((R_REG(r) & ~(mask)) | (val))) -+#define MAXPRIO 7 /* 0-7 */ -+ -+#endif /* _osl_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h ---- linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h 2005-12-16 23:39:10.752824750 +0100 -@@ -0,0 +1,451 @@ -+/* -+ * pcicfg.h: PCI configuration constants and structures. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ -+ -+#ifndef _h_pci_ -+#define _h_pci_ -+ -+/* The following inside ifndef's so we don't collide with NTDDK.H */ -+#ifndef PCI_MAX_BUS -+#define PCI_MAX_BUS 0x100 -+#endif -+#ifndef PCI_MAX_DEVICES -+#define PCI_MAX_DEVICES 0x20 -+#endif -+#ifndef PCI_MAX_FUNCTION -+#define PCI_MAX_FUNCTION 0x8 -+#endif -+ -+#ifndef PCI_INVALID_VENDORID -+#define PCI_INVALID_VENDORID 0xffff -+#endif -+#ifndef PCI_INVALID_DEVICEID -+#define PCI_INVALID_DEVICEID 0xffff -+#endif -+ -+ -+/* Convert between bus-slot-function-register and config addresses */ -+ -+#define PCICFG_BUS_SHIFT 16 /* Bus shift */ -+#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ -+#define PCICFG_FUN_SHIFT 8 /* Function shift */ -+#define PCICFG_OFF_SHIFT 0 /* Register shift */ -+ -+#define PCICFG_BUS_MASK 0xff /* Bus mask */ -+#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ -+#define PCICFG_FUN_MASK 7 /* Function mask */ -+#define PCICFG_OFF_MASK 0xff /* Bus mask */ -+ -+#define PCI_CONFIG_ADDR(b, s, f, o) \ -+ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ -+ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ -+ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ -+ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) -+ -+#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) -+#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) -+#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) -+#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) -+ -+/* PCIE Config space accessing MACROS*/ -+ -+#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ -+#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ -+#define PCIECFG_FUN_SHIFT 16 /* Function shift */ -+#define PCIECFG_OFF_SHIFT 0 /* Register shift */ -+ -+#define PCIECFG_BUS_MASK 0xff /* Bus mask */ -+#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ -+#define PCIECFG_FUN_MASK 7 /* Function mask */ -+#define PCIECFG_OFF_MASK 0x3ff /* Register mask */ -+ -+#define PCIE_CONFIG_ADDR(b, s, f, o) \ -+ ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ -+ | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ -+ | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ -+ | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) -+ -+#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) -+#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) -+#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) -+#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) -+ -+ -+/* The actual config space */ -+ -+#define PCI_BAR_MAX 6 -+ -+#define PCI_ROM_BAR 8 -+ -+#define PCR_RSVDA_MAX 2 -+ -+/* pci config status reg has a bit to indicate that capability ptr is present*/ -+ -+#define PCI_CAPPTR_PRESENT 0x0010 -+ -+typedef struct _pci_config_regs { -+ unsigned short vendor; -+ unsigned short device; -+ unsigned short command; -+ unsigned short status; -+ unsigned char rev_id; -+ unsigned char prog_if; -+ unsigned char sub_class; -+ unsigned char base_class; -+ unsigned char cache_line_size; -+ unsigned char latency_timer; -+ unsigned char header_type; -+ unsigned char bist; -+ unsigned long base[PCI_BAR_MAX]; -+ unsigned long cardbus_cis; -+ unsigned short subsys_vendor; -+ unsigned short subsys_id; -+ unsigned long baserom; -+ unsigned long rsvd_a[PCR_RSVDA_MAX]; -+ unsigned char int_line; -+ unsigned char int_pin; -+ unsigned char min_gnt; -+ unsigned char max_lat; -+ unsigned char dev_dep[192]; -+} pci_config_regs; -+ -+#define SZPCR (sizeof (pci_config_regs)) -+#define MINSZPCR 64 /* offsetof (dev_dep[0] */ -+ -+/* A structure for the config registers is nice, but in most -+ * systems the config space is not memory mapped, so we need -+ * filed offsetts. :-( -+ */ -+#define PCI_CFG_VID 0 -+#define PCI_CFG_DID 2 -+#define PCI_CFG_CMD 4 -+#define PCI_CFG_STAT 6 -+#define PCI_CFG_REV 8 -+#define PCI_CFG_PROGIF 9 -+#define PCI_CFG_SUBCL 0xa -+#define PCI_CFG_BASECL 0xb -+#define PCI_CFG_CLSZ 0xc -+#define PCI_CFG_LATTIM 0xd -+#define PCI_CFG_HDR 0xe -+#define PCI_CFG_BIST 0xf -+#define PCI_CFG_BAR0 0x10 -+#define PCI_CFG_BAR1 0x14 -+#define PCI_CFG_BAR2 0x18 -+#define PCI_CFG_BAR3 0x1c -+#define PCI_CFG_BAR4 0x20 -+#define PCI_CFG_BAR5 0x24 -+#define PCI_CFG_CIS 0x28 -+#define PCI_CFG_SVID 0x2c -+#define PCI_CFG_SSID 0x2e -+#define PCI_CFG_ROMBAR 0x30 -+#define PCI_CFG_CAPPTR 0x34 -+#define PCI_CFG_INT 0x3c -+#define PCI_CFG_PIN 0x3d -+#define PCI_CFG_MINGNT 0x3e -+#define PCI_CFG_MAXLAT 0x3f -+ -+/* Classes and subclasses */ -+ -+typedef enum { -+ PCI_CLASS_OLD = 0, -+ PCI_CLASS_DASDI, -+ PCI_CLASS_NET, -+ PCI_CLASS_DISPLAY, -+ PCI_CLASS_MMEDIA, -+ PCI_CLASS_MEMORY, -+ PCI_CLASS_BRIDGE, -+ PCI_CLASS_COMM, -+ PCI_CLASS_BASE, -+ PCI_CLASS_INPUT, -+ PCI_CLASS_DOCK, -+ PCI_CLASS_CPU, -+ PCI_CLASS_SERIAL, -+ PCI_CLASS_INTELLIGENT = 0xe, -+ PCI_CLASS_SATELLITE, -+ PCI_CLASS_CRYPT, -+ PCI_CLASS_DSP, -+ PCI_CLASS_MAX -+} pci_classes; -+ -+typedef enum { -+ PCI_DASDI_SCSI, -+ PCI_DASDI_IDE, -+ PCI_DASDI_FLOPPY, -+ PCI_DASDI_IPI, -+ PCI_DASDI_RAID, -+ PCI_DASDI_OTHER = 0x80 -+} pci_dasdi_subclasses; -+ -+typedef enum { -+ PCI_NET_ETHER, -+ PCI_NET_TOKEN, -+ PCI_NET_FDDI, -+ PCI_NET_ATM, -+ PCI_NET_OTHER = 0x80 -+} pci_net_subclasses; -+ -+typedef enum { -+ PCI_DISPLAY_VGA, -+ PCI_DISPLAY_XGA, -+ PCI_DISPLAY_3D, -+ PCI_DISPLAY_OTHER = 0x80 -+} pci_display_subclasses; -+ -+typedef enum { -+ PCI_MMEDIA_VIDEO, -+ PCI_MMEDIA_AUDIO, -+ PCI_MMEDIA_PHONE, -+ PCI_MEDIA_OTHER = 0x80 -+} pci_mmedia_subclasses; -+ -+typedef enum { -+ PCI_MEMORY_RAM, -+ PCI_MEMORY_FLASH, -+ PCI_MEMORY_OTHER = 0x80 -+} pci_memory_subclasses; -+ -+typedef enum { -+ PCI_BRIDGE_HOST, -+ PCI_BRIDGE_ISA, -+ PCI_BRIDGE_EISA, -+ PCI_BRIDGE_MC, -+ PCI_BRIDGE_PCI, -+ PCI_BRIDGE_PCMCIA, -+ PCI_BRIDGE_NUBUS, -+ PCI_BRIDGE_CARDBUS, -+ PCI_BRIDGE_RACEWAY, -+ PCI_BRIDGE_OTHER = 0x80 -+} pci_bridge_subclasses; -+ -+typedef enum { -+ PCI_COMM_UART, -+ PCI_COMM_PARALLEL, -+ PCI_COMM_MULTIUART, -+ PCI_COMM_MODEM, -+ PCI_COMM_OTHER = 0x80 -+} pci_comm_subclasses; -+ -+typedef enum { -+ PCI_BASE_PIC, -+ PCI_BASE_DMA, -+ PCI_BASE_TIMER, -+ PCI_BASE_RTC, -+ PCI_BASE_PCI_HOTPLUG, -+ PCI_BASE_OTHER = 0x80 -+} pci_base_subclasses; -+ -+typedef enum { -+ PCI_INPUT_KBD, -+ PCI_INPUT_PEN, -+ PCI_INPUT_MOUSE, -+ PCI_INPUT_SCANNER, -+ PCI_INPUT_GAMEPORT, -+ PCI_INPUT_OTHER = 0x80 -+} pci_input_subclasses; -+ -+typedef enum { -+ PCI_DOCK_GENERIC, -+ PCI_DOCK_OTHER = 0x80 -+} pci_dock_subclasses; -+ -+typedef enum { -+ PCI_CPU_386, -+ PCI_CPU_486, -+ PCI_CPU_PENTIUM, -+ PCI_CPU_ALPHA = 0x10, -+ PCI_CPU_POWERPC = 0x20, -+ PCI_CPU_MIPS = 0x30, -+ PCI_CPU_COPROC = 0x40, -+ PCI_CPU_OTHER = 0x80 -+} pci_cpu_subclasses; -+ -+typedef enum { -+ PCI_SERIAL_IEEE1394, -+ PCI_SERIAL_ACCESS, -+ PCI_SERIAL_SSA, -+ PCI_SERIAL_USB, -+ PCI_SERIAL_FIBER, -+ PCI_SERIAL_SMBUS, -+ PCI_SERIAL_OTHER = 0x80 -+} pci_serial_subclasses; -+ -+typedef enum { -+ PCI_INTELLIGENT_I2O, -+} pci_intelligent_subclasses; -+ -+typedef enum { -+ PCI_SATELLITE_TV, -+ PCI_SATELLITE_AUDIO, -+ PCI_SATELLITE_VOICE, -+ PCI_SATELLITE_DATA, -+ PCI_SATELLITE_OTHER = 0x80 -+} pci_satellite_subclasses; -+ -+typedef enum { -+ PCI_CRYPT_NETWORK, -+ PCI_CRYPT_ENTERTAINMENT, -+ PCI_CRYPT_OTHER = 0x80 -+} pci_crypt_subclasses; -+ -+typedef enum { -+ PCI_DSP_DPIO, -+ PCI_DSP_OTHER = 0x80 -+} pci_dsp_subclasses; -+ -+/* Header types */ -+typedef enum { -+ PCI_HEADER_NORMAL, -+ PCI_HEADER_BRIDGE, -+ PCI_HEADER_CARDBUS -+} pci_header_types; -+ -+ -+/* Overlay for a PCI-to-PCI bridge */ -+ -+#define PPB_RSVDA_MAX 2 -+#define PPB_RSVDD_MAX 8 -+ -+typedef struct _ppb_config_regs { -+ unsigned short vendor; -+ unsigned short device; -+ unsigned short command; -+ unsigned short status; -+ unsigned char rev_id; -+ unsigned char prog_if; -+ unsigned char sub_class; -+ unsigned char base_class; -+ unsigned char cache_line_size; -+ unsigned char latency_timer; -+ unsigned char header_type; -+ unsigned char bist; -+ unsigned long rsvd_a[PPB_RSVDA_MAX]; -+ unsigned char prim_bus; -+ unsigned char sec_bus; -+ unsigned char sub_bus; -+ unsigned char sec_lat; -+ unsigned char io_base; -+ unsigned char io_lim; -+ unsigned short sec_status; -+ unsigned short mem_base; -+ unsigned short mem_lim; -+ unsigned short pf_mem_base; -+ unsigned short pf_mem_lim; -+ unsigned long pf_mem_base_hi; -+ unsigned long pf_mem_lim_hi; -+ unsigned short io_base_hi; -+ unsigned short io_lim_hi; -+ unsigned short subsys_vendor; -+ unsigned short subsys_id; -+ unsigned long rsvd_b; -+ unsigned char rsvd_c; -+ unsigned char int_pin; -+ unsigned short bridge_ctrl; -+ unsigned char chip_ctrl; -+ unsigned char diag_ctrl; -+ unsigned short arb_ctrl; -+ unsigned long rsvd_d[PPB_RSVDD_MAX]; -+ unsigned char dev_dep[192]; -+} ppb_config_regs; -+ -+ -+/* PCI CAPABILITY DEFINES */ -+#define PCI_CAP_POWERMGMTCAP_ID 0x01 -+#define PCI_CAP_MSICAP_ID 0x05 -+#define PCI_CAP_PCIECAP_ID 0x10 ++/* Values in C_EXC */ ++#define EXC_INT 0 ++#define EXC_TLBM 1 ++#define EXC_TLBL 2 ++#define EXC_TLBS 3 ++#define EXC_AEL 4 ++#define EXC_AES 5 ++#define EXC_IBE 6 ++#define EXC_DBE 7 ++#define EXC_SYS 8 ++#define EXC_BPT 9 ++#define EXC_RI 10 ++#define EXC_CU 11 ++#define EXC_OV 12 ++#define EXC_TR 13 ++#define EXC_WATCH 23 ++#define EXC_MCHK 24 + -+/* Data structure to define the Message Signalled Interrupt facility -+ * Valid for PCI and PCIE configurations */ -+typedef struct _pciconfig_cap_msi { -+ unsigned char capID; -+ unsigned char nextptr; -+ unsigned short msgctrl; -+ unsigned int msgaddr; -+} pciconfig_cap_msi; + -+/* Data structure to define the Power managment facility -+ * Valid for PCI and PCIE configurations */ -+typedef struct _pciconfig_cap_pwrmgmt { -+ unsigned char capID; -+ unsigned char nextptr; -+ unsigned short pme_cap; -+ unsigned short pme_sts_ctrl; -+ unsigned char pme_bridge_ext; -+ unsigned char data; -+} pciconfig_cap_pwrmgmt; ++/* ++ * Bits in the cp0 config register. ++ */ ++#define CONF_CM_CACHABLE_NO_WA 0 ++#define CONF_CM_CACHABLE_WA 1 ++#define CONF_CM_UNCACHED 2 ++#define CONF_CM_CACHABLE_NONCOHERENT 3 ++#define CONF_CM_CACHABLE_CE 4 ++#define CONF_CM_CACHABLE_COW 5 ++#define CONF_CM_CACHABLE_CUW 6 ++#define CONF_CM_CACHABLE_ACCELERATED 7 ++#define CONF_CM_CMASK 7 ++#define CONF_CU (_ULCAST_(1) << 3) ++#define CONF_DB (_ULCAST_(1) << 4) ++#define CONF_IB (_ULCAST_(1) << 5) ++#define CONF_SE (_ULCAST_(1) << 12) ++#define CONF_SC (_ULCAST_(1) << 17) ++#define CONF_AC (_ULCAST_(1) << 23) ++#define CONF_HALT (_ULCAST_(1) << 25) + -+/* Data structure to define the PCIE capability */ -+typedef struct _pciconfig_cap_pcie { -+ unsigned char capID; -+ unsigned char nextptr; -+ unsigned short pcie_cap; -+ unsigned int dev_cap; -+ unsigned short dev_ctrl; -+ unsigned short dev_status; -+ unsigned int link_cap; -+ unsigned short link_ctrl; -+ unsigned short link_status; -+} pciconfig_cap_pcie; + -+/* PCIE Enhanced CAPABILITY DEFINES */ -+#define PCIE_EXTCFG_OFFSET 0x100 -+#define PCIE_ADVERRREP_CAPID 0x0001 -+#define PCIE_VC_CAPID 0x0002 -+#define PCIE_DEVSNUM_CAPID 0x0003 -+#define PCIE_PWRBUDGET_CAPID 0x0004 ++/* ++ * Bits in the cp0 config register select 1. ++ */ ++#define CONF1_FP 0x00000001 /* FPU present */ ++#define CONF1_EP 0x00000002 /* EJTAG present */ ++#define CONF1_CA 0x00000004 /* mips16 implemented */ ++#define CONF1_WR 0x00000008 /* Watch registers present */ ++#define CONF1_PC 0x00000010 /* Performance counters present */ ++#define CONF1_DA_SHIFT 7 /* D$ associativity */ ++#define CONF1_DA_MASK 0x00000380 ++#define CONF1_DA_BASE 1 ++#define CONF1_DL_SHIFT 10 /* D$ line size */ ++#define CONF1_DL_MASK 0x00001c00 ++#define CONF1_DL_BASE 2 ++#define CONF1_DS_SHIFT 13 /* D$ sets/way */ ++#define CONF1_DS_MASK 0x0000e000 ++#define CONF1_DS_BASE 64 ++#define CONF1_IA_SHIFT 16 /* I$ associativity */ ++#define CONF1_IA_MASK 0x00070000 ++#define CONF1_IA_BASE 1 ++#define CONF1_IL_SHIFT 19 /* I$ line size */ ++#define CONF1_IL_MASK 0x00380000 ++#define CONF1_IL_BASE 2 ++#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ ++#define CONF1_IS_MASK 0x01c00000 ++#define CONF1_IS_BASE 64 ++#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */ ++#define CONF1_MS_SHIFT 25 + -+/* Header to define the PCIE specific capabilities in the extended config space */ -+typedef struct _pcie_enhanced_caphdr { -+ unsigned short capID; -+ unsigned short cap_ver : 4; -+ unsigned short next_ptr : 12; -+} pcie_enhanced_caphdr; ++/* PRID register */ ++#define PRID_COPT_MASK 0xff000000 ++#define PRID_COMP_MASK 0x00ff0000 ++#define PRID_IMP_MASK 0x0000ff00 ++#define PRID_REV_MASK 0x000000ff + ++#define PRID_COMP_LEGACY 0x000000 ++#define PRID_COMP_MIPS 0x010000 ++#define PRID_COMP_BROADCOM 0x020000 ++#define PRID_COMP_ALCHEMY 0x030000 ++#define PRID_COMP_SIBYTE 0x040000 ++#define PRID_IMP_BCM4710 0x4000 ++#define PRID_IMP_BCM3302 0x9000 ++#define PRID_IMP_BCM3303 0x9100 + -+/* Everything below is BRCM HND proprietary */ ++#define PRID_IMP_UNKNOWN 0xff00 + -+#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ -+#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ -+#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ -+#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ -+#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ -+#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ -+#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ -+#define PCI_BACKPLANE_ADDR 0xA0 /* address an arbitrary location on the system backplane */ -+#define PCI_BACKPLANE_DATA 0xA4 /* data at the location specified by above address register */ -+#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ -+#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ -+#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ ++#define BCM330X(id) \ ++ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \ ++ || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) + -+#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ -+#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ ++/* Bits in C0_BROADCOM */ ++#define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */ ++#define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */ ++#define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */ ++#define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */ + -+/* PCI_INT_STATUS */ -+#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ ++/* PreFetch Cache aka Read Ahead Cache */ + -+/* PCI_INT_MASK */ -+#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ -+#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ -+#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ ++#define PFC_CR0 0xff400000 /* control reg 0 */ ++#define PFC_CR1 0xff400004 /* control reg 1 */ + -+/* PCI_SPROM_CONTROL */ -+#define SPROM_BLANK 0x04 /* indicating a blank sprom */ -+#define SPROM_WRITEEN 0x10 /* sprom write enable */ -+#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ ++/* PFC operations */ ++#define PFC_I 0x00000001 /* Enable PFC use for instructions */ ++#define PFC_D 0x00000002 /* Enable PFC use for data */ ++#define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */ ++#define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */ ++#define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */ ++#define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */ ++#define PFC_DPF 0x00000040 /* Enable directional prefetching */ ++#define PFC_FLUSH 0x00000100 /* Flush the PFC */ ++#define PFC_BRR 0x40000000 /* Bus error indication */ ++#define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */ + -+#define SPROM_SIZE 256 /* sprom size in 16-bit */ -+#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */ ++/* Handy defaults */ ++#define PFC_DISABLED 0 ++#define PFC_AUTO 0xffffffff /* auto select the default mode */ ++#define PFC_INST (PFC_I | PFC_PFI | PFC_CINV) ++#define PFC_INST_NOPF (PFC_I | PFC_CINV) ++#define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV) ++#define PFC_DATA_NOPF (PFC_D | PFC_CINV) ++#define PFC_I_AND_D (PFC_INST | PFC_DATA) ++#define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF) + -+/* PCI_CFG_CMD_STAT */ -+#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */ + -+#endif -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pmon_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pmon_osl.h ---- linux-2.4.32/arch/mips/bcm947xx/include/pmon_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pmon_osl.h 2005-12-16 23:39:10.752824750 +0100 -@@ -0,0 +1,126 @@ -+/* -+ * MIPS PMON boot loader OS Abstraction Layer. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; -+ * the contents of this file may not be disclosed to third parties, copied -+ * or duplicated in any form, in whole or in part, without the prior -+ * written permission of Broadcom Corporation. -+ * $Id$ ++/* ++ * These are the UART port assignments, expressed as offsets from the base ++ * register. These assignments should hold for any serial port based on ++ * a 8250, 16450, or 16550(A). + */ + -+#ifndef _pmon_osl_h_ -+#define _pmon_osl_h_ ++#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ ++#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ ++#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ ++#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ ++#define UART_LCR 3 /* Out: Line Control Register */ ++#define UART_MCR 4 /* Out: Modem Control Register */ ++#define UART_LSR 5 /* In: Line Status Register */ ++#define UART_MSR 6 /* In: Modem Status Register */ ++#define UART_SCR 7 /* I/O: Scratch Register */ ++#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ ++#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ ++#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ ++#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ ++#define UART_LSR_RXRDY 0x01 /* Receiver ready */ + -+#include -+#include -+#include -+#include + -+extern int printf(char *fmt,...); -+extern int sprintf(char *dst,char *fmt,...); ++#ifndef _LANGUAGE_ASSEMBLY + -+#define OSL_UNCACHED(va) phy2k1(log2phy((va))) -+#define REG_MAP(pa, size) phy2k1((pa)) -+#define REG_UNMAP(va) /* nop */ ++/* ++ * Macros to access the system control coprocessor ++ */ + -+/* Common macros */ ++#define MFC0(source, sel) \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \ ++ "move\t%0,$1\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ :"=r" (__res) \ ++ : \ ++ :"$1"); \ ++ __res; \ ++}) + -+#define BUSPROBE(val, addr) ((val) = *(addr)) ++#define MTC0(source, sel, value) \ ++do { \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ "move\t$1,%z0\n\t" \ ++ ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ : \ ++ :"jr" (value) \ ++ :"$1"); \ ++} while (0) + -+#define ASSERT(exp) ++#define get_c0_count() \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__( \ ++ ".set\tnoreorder\n\t" \ ++ ".set\tnoat\n\t" \ ++ "mfc0\t%0,$9\n\t" \ ++ ".set\tat\n\t" \ ++ ".set\treorder" \ ++ :"=r" (__res)); \ ++ __res; \ ++}) + -+#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) bzero(buf, size) -+#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) ++static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; + -+/* kludge */ -+#define OSL_PCI_READ_CONFIG(loc, offset, size) ((offset == 8)? 0: 0xffffffff) -+#define OSL_PCI_WRITE_CONFIG(loc, offset, size, val) ASSERT(0) ++ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT))) ++ lsz = CONF1_IL_BASE << lsz; ++ sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT); ++ ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} + -+#define wreg32(r,v) (*(volatile uint32 *)(r) = (v)) -+#define rreg32(r) (*(volatile uint32 *)(r)) -+#ifdef IL_BIGENDIAN -+#define wreg16(r,v) (*(volatile uint16 *)((uint32)r^2) = (v)) -+#define rreg16(r) (*(volatile uint16 *)((uint32)r^2)) -+#else -+#define wreg16(r,v) (*(volatile uint16 *)(r) = (v)) -+#define rreg16(r) (*(volatile uint16 *)(r)) -+#endif ++static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; + -+#include -+#define bcopy(src, dst, len) memcpy(dst, src, len) -+#define bcmp(b1, b2, len) memcmp(b1, b2, len) -+#define bzero(b, len) memset(b, '\0', len) ++ /* Data Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT))) ++ lsz = CONF1_DL_BASE << lsz; ++ sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT); ++ ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} + -+/* register access macros */ -+#define R_REG(r) ((sizeof *(r) == sizeof (uint32))? rreg32(r): rreg16(r)) -+#define W_REG(r,v) ((sizeof *(r) == sizeof (uint32))? wreg32(r,(uint32)v): wreg16(r,(uint16)v)) -+#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) -+#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) ++#define cache_op(base, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1, (%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); + -+#define R_SM(r) *(r) -+#define W_SM(r, v) (*(r) = (v)) -+#define BZERO_SM(r, len) memset(r, '\0', len) -+ -+/* Host/Bus architecture specific swap. Noop for little endian systems, possible swap on big endian */ -+#define BUS_SWAP32(v) (v) -+ -+#define OSL_DELAY(usec) delay_us(usec) -+extern void delay_us(uint usec); -+ -+#define OSL_GETCYCLES(x) ((x) = 0) -+ -+#define osl_attach(pdev) (pdev) -+#define osl_detach(osh) -+ -+#define MALLOC(osh, size) malloc(size) -+#define MFREE(osh, addr, size) free(addr) -+#define MALLOCED(osh) (0) -+#define MALLOC_DUMP(osh, buf, sz) -+#define MALLOC_FAILED(osh) -+extern void *malloc(); -+extern void free(void *addr); -+ -+#define DMA_CONSISTENT_ALIGN sizeof (int) -+#define DMA_ALLOC_CONSISTENT(osh, size, pap) et_dma_alloc_consistent(osh, size, pap) -+#define DMA_FREE_CONSISTENT(osh, va, size, pa) -+extern void* et_dma_alloc_consistent(void *osh, uint size, ulong *pap); -+#define DMA_TX 0 -+#define DMA_RX 1 -+ -+#define DMA_MAP(osh, va, size, direction, p) osl_dma_map(osh, (void*)va, size, direction) -+#define DMA_UNMAP(osh, pa, size, direction, p) /* nop */ -+extern void* osl_dma_map(void *osh, void *va, uint size, uint direction); -+ -+struct lbuf { -+ struct lbuf *next; /* pointer to next lbuf on freelist */ -+ uchar *buf; /* pointer to buffer */ -+ uint len; /* nbytes of data */ -+}; ++#define cache_unroll4(base, delta, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1,0(%0); \ ++ cache %1,delta(%0); \ ++ cache %1,(2 * delta)(%0); \ ++ cache %1,(3 * delta)(%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); + -+/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -+#define PKTBUFSZ 2048 ++#endif /* !_LANGUAGE_ASSEMBLY */ + -+/* packet primitives */ -+#define PKTGET(drv, len, send) et_pktget(drv, len, send) -+#define PKTFREE(drv, lb, send) et_pktfree(drv, (struct lbuf*)lb, send) -+#define PKTDATA(drv, lb) ((uchar*)OSL_UNCACHED(((struct lbuf*)lb)->buf)) -+#define PKTLEN(drv, lb) ((struct lbuf*)lb)->len -+#define PKTHEADROOM(drv, lb) (0) -+#define PKTTAILROOM(drv, lb) (0) -+#define PKTNEXT(drv, lb) NULL -+#define PKTSETNEXT(lb, x) ASSERT(0) -+#define PKTSETLEN(drv, lb, bytes) ((struct lbuf*)lb)->len = bytes -+#define PKTPUSH(drv, lb, bytes) ASSERT(0) -+#define PKTPULL(drv, lb, bytes) ASSERT(0) -+#define PKTDUP(drv, lb) ASSERT(0) -+#define PKTLINK(lb) ((struct lbuf*)lb)->next -+#define PKTSETLINK(lb, x) ((struct lbuf*)lb)->next = (struct lbuf*)x -+#define PKTPRIO(lb) (0) -+#define PKTSETPRIO(lb, x) do {} while (0) -+extern void *et_pktget(void *drv, uint len, bool send); -+extern void et_pktfree(void *drv, struct lbuf *lb, bool send); -+ -+#endif /* _pmon_osl_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/802.11.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/802.11.h ---- linux-2.4.32/arch/mips/bcm947xx/include/proto/802.11.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/802.11.h 2005-12-16 23:39:10.752824750 +0100 -@@ -0,0 +1,930 @@ ++#endif /* _MISPINC_H */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h +--- linux-2.4.32/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h 2005-12-16 23:39:10.748824500 +0100 +@@ -0,0 +1,42 @@ +/* ++ * OS Abstraction Layer ++ * + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * @@ -5128,934 +3138,44 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/802.11.h linux-2.4.32-br + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * Fundamental types and constants relating to 802.11 -+ * + * $Id$ + */ + -+#ifndef _802_11_H_ -+#define _802_11_H_ -+ -+#ifndef _TYPEDEFS_H_ -+#include -+#endif -+ -+#ifndef _NET_ETHERNET_H_ -+#include -+#endif -+ -+#include ++#ifndef _osl_h_ ++#define _osl_h_ + ++/* osl handle type forward declaration */ ++typedef struct os_handle osl_t; + -+/* enable structure packing */ -+#if defined(__GNUC__) -+#define PACKED __attribute__((packed)) ++#if defined(linux) ++#include ++#elif defined(NDIS) ++#include ++#elif defined(_CFE_) ++#include ++#elif defined(_HNDRTE_) ++#include ++#elif defined(_MINOSL_) ++#include ++#elif PMON ++#include ++#elif defined(MACOSX) ++#include +#else -+#pragma pack(1) -+#define PACKED ++#error "Unsupported OSL requested" +#endif + -+#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */ -+ -+/* Generic 802.11 frame constants */ -+#define DOT11_A3_HDR_LEN 24 -+#define DOT11_A4_HDR_LEN 30 -+#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN -+#define DOT11_FCS_LEN 4 -+#define DOT11_ICV_LEN 4 -+#define DOT11_ICV_AES_LEN 8 -+#define DOT11_QOS_LEN 2 -+ -+#define DOT11_KEY_INDEX_SHIFT 6 -+#define DOT11_IV_LEN 4 -+#define DOT11_IV_TKIP_LEN 8 -+#define DOT11_IV_AES_OCB_LEN 4 -+#define DOT11_IV_AES_CCM_LEN 8 -+ -+/* Includes MIC */ -+#define DOT11_MAX_MPDU_BODY_LEN 2304 -+/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */ -+#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ -+ DOT11_QOS_LEN + \ -+ DOT11_IV_AES_CCM_LEN + \ -+ DOT11_MAX_MPDU_BODY_LEN + \ -+ DOT11_ICV_LEN + \ -+ DOT11_FCS_LEN) -+ -+#define DOT11_MAX_SSID_LEN 32 -+ -+/* dot11RTSThreshold */ -+#define DOT11_DEFAULT_RTS_LEN 2347 -+#define DOT11_MAX_RTS_LEN 2347 -+ -+/* dot11FragmentationThreshold */ -+#define DOT11_MIN_FRAG_LEN 256 -+#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength of the attached PHY */ -+#define DOT11_DEFAULT_FRAG_LEN 2346 -+ -+/* dot11BeaconPeriod */ -+#define DOT11_MIN_BEACON_PERIOD 1 -+#define DOT11_MAX_BEACON_PERIOD 0xFFFF -+ -+/* dot11DTIMPeriod */ -+#define DOT11_MIN_DTIM_PERIOD 1 -+#define DOT11_MAX_DTIM_PERIOD 0xFF -+ -+/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */ -+#define DOT11_LLC_SNAP_HDR_LEN 8 -+#define DOT11_OUI_LEN 3 -+struct dot11_llc_snap_header { -+ uint8 dsap; /* always 0xAA */ -+ uint8 ssap; /* always 0xAA */ -+ uint8 ctl; /* always 0x03 */ -+ uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00 -+ Bridge-Tunnel: 0x00 0x00 0xF8 */ -+ uint16 type; /* ethertype */ -+} PACKED; -+ -+/* RFC1042 header used by 802.11 per 802.1H */ -+#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) -+ -+/* Generic 802.11 MAC header */ -+/* -+ * N.B.: This struct reflects the full 4 address 802.11 MAC header. -+ * The fields are defined such that the shorter 1, 2, and 3 -+ * address headers just use the first k fields. -+ */ -+struct dot11_header { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr a1; /* address 1 */ -+ struct ether_addr a2; /* address 2 */ -+ struct ether_addr a3; /* address 3 */ -+ uint16 seq; /* sequence control */ -+ struct ether_addr a4; /* address 4 */ -+} PACKED; -+ -+/* Control frames */ -+ -+struct dot11_rts_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+ struct ether_addr ta; /* transmitter address */ -+} PACKED; -+#define DOT11_RTS_LEN 16 -+ -+struct dot11_cts_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+} PACKED; -+#define DOT11_CTS_LEN 10 -+ -+struct dot11_ack_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+} PACKED; -+#define DOT11_ACK_LEN 10 -+ -+struct dot11_ps_poll_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* AID */ -+ struct ether_addr bssid; /* receiver address, STA in AP */ -+ struct ether_addr ta; /* transmitter address */ -+} PACKED; -+#define DOT11_PS_POLL_LEN 16 -+ -+struct dot11_cf_end_frame { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr ra; /* receiver address */ -+ struct ether_addr bssid; /* transmitter address, STA in AP */ -+} PACKED; -+#define DOT11_CS_END_LEN 16 -+ -+/* Management frame header */ -+struct dot11_management_header { -+ uint16 fc; /* frame control */ -+ uint16 durid; /* duration/ID */ -+ struct ether_addr da; /* receiver address */ -+ struct ether_addr sa; /* transmitter address */ -+ struct ether_addr bssid; /* BSS ID */ -+ uint16 seq; /* sequence control */ -+} PACKED; -+#define DOT11_MGMT_HDR_LEN 24 -+ -+/* Management frame payloads */ -+ -+struct dot11_bcn_prb { -+ uint32 timestamp[2]; -+ uint16 beacon_interval; -+ uint16 capability; -+} PACKED; -+#define DOT11_BCN_PRB_LEN 12 -+ -+struct dot11_auth { -+ uint16 alg; /* algorithm */ -+ uint16 seq; /* sequence control */ -+ uint16 status; /* status code */ -+} PACKED; -+#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge info elt */ -+ -+struct dot11_assoc_req { -+ uint16 capability; /* capability information */ -+ uint16 listen; /* listen interval */ -+} PACKED; -+#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */ -+ -+struct dot11_reassoc_req { -+ uint16 capability; /* capability information */ -+ uint16 listen; /* listen interval */ -+ struct ether_addr ap; /* Current AP address */ -+} PACKED; -+#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */ -+ -+struct dot11_assoc_resp { -+ uint16 capability; /* capability information */ -+ uint16 status; /* status code */ -+ uint16 aid; /* association ID */ -+} PACKED; -+ -+struct dot11_action_measure { -+ uint8 category; -+ uint8 action; -+ uint8 token; -+ uint8 data[1]; -+} PACKED; -+#define DOT11_ACTION_MEASURE_LEN 3 -+ -+struct dot11_action_switch_channel { -+ uint8 category; -+ uint8 action; -+ uint8 data[5]; /* for switch IE */ -+} PACKED; -+ -+/************** -+ 802.11h related definitions. -+**************/ -+typedef struct { -+ uint8 id; -+ uint8 len; -+ uint8 power; -+} dot11_power_cnst_t; -+ -+typedef struct { -+ uint8 min; -+ uint8 max; -+} dot11_power_cap_t; -+ -+typedef struct { -+ uint8 id; -+ uint8 len; -+ uint8 tx_pwr; -+ uint8 margin; -+} dot11_tpc_rep_t; -+#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */ -+ -+typedef struct { -+ uint8 id; -+ uint8 len; -+ uint8 first_channel; -+ uint8 num_channels; -+} dot11_supp_channels_t; -+ -+/* csa mode type */ -+#define DOT11_CSA_MODE_ADVISORY 0 -+#define DOT11_CSA_MODE_NO_TX 1 -+struct dot11_channel_switch { -+ uint8 id; -+ uint8 len; -+ uint8 mode; -+ uint8 channel; -+ uint8 count; -+} PACKED; -+typedef struct dot11_channel_switch dot11_channel_switch_t; -+ -+/* length of IE data, not including 2 byte header */ -+#define DOT11_SWITCH_IE_LEN 3 -+ -+/* 802.11h Measurement Request/Report IEs */ -+/* Measurement Type field */ -+#define DOT11_MEASURE_TYPE_BASIC 0 -+#define DOT11_MEASURE_TYPE_CCA 1 -+#define DOT11_MEASURE_TYPE_RPI 2 -+ -+/* Measurement Mode field */ -+ -+/* Measurement Request Modes */ -+#define DOT11_MEASURE_MODE_ENABLE (1<<1) -+#define DOT11_MEASURE_MODE_REQUEST (1<<2) -+#define DOT11_MEASURE_MODE_REPORT (1<<3) -+/* Measurement Report Modes */ -+#define DOT11_MEASURE_MODE_LATE (1<<0) -+#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) -+#define DOT11_MEASURE_MODE_REFUSED (1<<2) -+/* Basic Measurement Map bits */ -+#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) -+#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) -+#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) -+#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) -+#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) -+ -+typedef struct { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+ uint8 channel; -+ uint8 start_time[8]; -+ uint16 duration; -+} dot11_meas_req_t; -+#define DOT11_MNG_IE_MREQ_LEN 14 -+/* length of Measure Request IE data not including variable len */ -+#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 -+ -+struct dot11_meas_rep { -+ uint8 id; -+ uint8 len; -+ uint8 token; -+ uint8 mode; -+ uint8 type; -+ union -+ { -+ struct { -+ uint8 channel; -+ uint8 start_time[8]; -+ uint16 duration; -+ uint8 map; -+ } PACKED basic; -+ uint8 data[1]; -+ } PACKED rep; -+} PACKED; -+typedef struct dot11_meas_rep dot11_meas_rep_t; -+ -+/* length of Measure Report IE data not including variable len */ -+#define DOT11_MNG_IE_MREP_FIXED_LEN 3 -+ -+struct dot11_meas_rep_basic { -+ uint8 channel; -+ uint8 start_time[8]; -+ uint16 duration; -+ uint8 map; -+} PACKED; -+typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; -+#define DOT11_MEASURE_BASIC_REP_LEN 12 -+ -+struct dot11_quiet { -+ uint8 id; -+ uint8 len; -+ uint8 count; /* TBTTs until beacon interval in quiet starts */ -+ uint8 period; /* Beacon intervals between periodic quiet periods ? */ -+ uint16 duration;/* Length of quiet period, in TU's */ -+ uint16 offset; /* TU's offset from TBTT in Count field */ -+} PACKED; -+typedef struct dot11_quiet dot11_quiet_t; -+ -+typedef struct { -+ uint8 channel; -+ uint8 map; -+} chan_map_tuple_t; -+ -+typedef struct { -+ uint8 id; -+ uint8 len; -+ uint8 eaddr[ETHER_ADDR_LEN]; -+ uint8 interval; -+ chan_map_tuple_t map[1]; -+} dot11_ibss_dfs_t; -+ -+/* WME Elements */ -+#define WME_OUI "\x00\x50\xf2" -+#define WME_VER 1 -+#define WME_TYPE 2 -+#define WME_SUBTYPE_IE 0 /* Information Element */ -+#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */ -+#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */ -+ -+/* WME Access Category Indices (ACIs) */ -+#define AC_BE 0 /* Best Effort */ -+#define AC_BK 1 /* Background */ -+#define AC_VI 2 /* Video */ -+#define AC_VO 3 /* Voice */ -+#define AC_MAX 4 -+ -+/* WME Information Element (IE) */ -+struct wme_ie { -+ uint8 oui[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 version; -+ uint8 acinfo; -+} PACKED; -+typedef struct wme_ie wme_ie_t; -+#define WME_IE_LEN 7 -+ -+struct wme_acparam { -+ uint8 ACI; -+ uint8 ECW; -+ uint16 TXOP; /* stored in network order (ls octet first) */ -+} PACKED; -+typedef struct wme_acparam wme_acparam_t; -+ -+/* WME Parameter Element (PE) */ -+struct wme_params { -+ uint8 oui[3]; -+ uint8 type; -+ uint8 subtype; -+ uint8 version; -+ uint8 acinfo; -+ uint8 rsvd; -+ wme_acparam_t acparam[4]; -+} PACKED; -+typedef struct wme_params wme_params_t; -+#define WME_PARAMS_IE_LEN 24 -+ -+/* acinfo */ -+#define WME_COUNT_MASK 0x0f -+/* ACI */ -+#define WME_AIFS_MASK 0x0f -+#define WME_ACM_MASK 0x10 -+#define WME_ACI_MASK 0x60 -+#define WME_ACI_SHIFT 5 -+/* ECW */ -+#define WME_CWMIN_MASK 0x0f -+#define WME_CWMAX_MASK 0xf0 -+#define WME_CWMAX_SHIFT 4 -+ -+#define WME_TXOP_UNITS 32 -+ -+/* AP: default params to be announced in the Beacon Frames/Probe Responses Table 12 WME Draft*/ -+/* AP: default params to be Used in the AP Side Table 14 WME Draft January 2004 802.11-03-504r5 */ -+#define WME_AC_BK_ACI_STA 0x27 -+#define WME_AC_BK_ECW_STA 0xA4 -+#define WME_AC_BK_TXOP_STA 0x0000 -+#define WME_AC_BE_ACI_STA 0x03 -+#define WME_AC_BE_ECW_STA 0xA4 -+#define WME_AC_BE_TXOP_STA 0x0000 -+#define WME_AC_VI_ACI_STA 0x42 -+#define WME_AC_VI_ECW_STA 0x43 -+#define WME_AC_VI_TXOP_STA 0x005e -+#define WME_AC_VO_ACI_STA 0x62 -+#define WME_AC_VO_ECW_STA 0x32 -+#define WME_AC_VO_TXOP_STA 0x002f -+ -+#define WME_AC_BK_ACI_AP 0x27 -+#define WME_AC_BK_ECW_AP 0xA4 -+#define WME_AC_BK_TXOP_AP 0x0000 -+#define WME_AC_BE_ACI_AP 0x03 -+#define WME_AC_BE_ECW_AP 0x64 -+#define WME_AC_BE_TXOP_AP 0x0000 -+#define WME_AC_VI_ACI_AP 0x41 -+#define WME_AC_VI_ECW_AP 0x43 -+#define WME_AC_VI_TXOP_AP 0x005e -+#define WME_AC_VO_ACI_AP 0x61 -+#define WME_AC_VO_ECW_AP 0x32 -+#define WME_AC_VO_TXOP_AP 0x002f -+ -+/* WME Traffic Specification (TSPEC) element */ -+#define WME_SUBTYPE_TSPEC 2 -+#define WME_TSPEC_HDR_LEN 2 -+#define WME_TSPEC_BODY_OFF 2 -+struct wme_tspec { -+ uint8 oui[DOT11_OUI_LEN]; /* WME_OUI */ -+ uint8 type; /* WME_TYPE */ -+ uint8 subtype; /* WME_SUBTYPE_TSPEC */ -+ uint8 version; /* WME_VERSION */ -+ uint16 ts_info; /* TS Info */ -+ uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ -+ uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ -+ uint32 min_service_interval; /* Minimum Service Interval (us) */ -+ uint32 max_service_interval; /* Maximum Service Interval (us) */ -+ uint32 inactivity_interval; /* Inactivity Interval (us) */ -+ uint32 service_start; /* Service Start Time (us) */ -+ uint32 min_rate; /* Minimum Data Rate (bps) */ -+ uint32 mean_rate; /* Mean Data Rate (bps) */ -+ uint32 max_burst_size; /* Maximum Burst Size (bytes) */ -+ uint32 min_phy_rate; /* Minimum PHY Rate (bps) */ -+ uint32 peak_rate; /* Peak Data Rate (bps) */ -+ uint32 delay_bound; /* Delay Bound (us) */ -+ uint16 surplus_bandwidth; /* Surplus Bandwidth Allowance Factor */ -+ uint16 medium_time; /* Medium Time (32 us/s periods) */ -+} PACKED; -+typedef struct wme_tspec wme_tspec_t; -+#define WME_TSPEC_LEN 56 /* not including 2-byte header */ -+ -+/* ts_info */ -+/* 802.1D priority is duplicated - bits 13-11 AND bits 3-1 */ -+#define TS_INFO_PRIO_SHIFT_HI 11 -+#define TS_INFO_PRIO_MASK_HI (0x7 << TS_INFO_PRIO_SHIFT_HI) -+#define TS_INFO_PRIO_SHIFT_LO 1 -+#define TS_INFO_PRIO_MASK_LO (0x7 << TS_INFO_PRIO_SHIFT_LO) -+#define TS_INFO_CONTENTION_SHIFT 7 -+#define TS_INFO_CONTENTION_MASK (0x1 << TS_INFO_CONTENTION_SHIFT) -+#define TS_INFO_DIRECTION_SHIFT 5 -+#define TS_INFO_DIRECTION_MASK (0x3 << TS_INFO_DIRECTION_SHIFT) -+#define TS_INFO_UPLINK (0 << TS_INFO_DIRECTION_SHIFT) -+#define TS_INFO_DOWNLINK (1 << TS_INFO_DIRECTION_SHIFT) -+#define TS_INFO_BIDIRECTIONAL (3 << TS_INFO_DIRECTION_SHIFT) -+ -+/* nom_msdu_size */ -+#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */ -+#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */ -+ -+/* surplus_bandwidth */ -+/* Represented as 3 bits of integer, binary point, 13 bits fraction */ -+#define INTEGER_SHIFT 13 -+#define FRACTION_MASK 0x1FFF -+ -+/* Management Notification Frame */ -+struct dot11_management_notification { -+ uint8 category; /* DOT11_ACTION_NOTIFICATION */ -+ uint8 action; -+ uint8 token; -+ uint8 status; -+ uint8 data[1]; /* Elements */ -+} PACKED; -+#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */ -+ -+/* WME Action Codes */ -+#define WME_SETUP_REQUEST 0 -+#define WME_SETUP_RESPONSE 1 -+#define WME_TEARDOWN 2 -+ -+/* WME Setup Response Status Codes */ -+#define WME_ADMISSION_ACCEPTED 0 -+#define WME_INVALID_PARAMETERS 1 -+#define WME_ADMISSION_REFUSED 3 -+ -+/* Macro to take a pointer to a beacon or probe response -+ * header and return the char* pointer to the SSID info element -+ */ -+#define BCN_PRB_SSID(hdr) ((char*)(hdr) + DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_LEN) -+ -+/* Authentication frame payload constants */ -+#define DOT11_OPEN_SYSTEM 0 -+#define DOT11_SHARED_KEY 1 -+#define DOT11_CHALLENGE_LEN 128 -+ -+/* Frame control macros */ -+#define FC_PVER_MASK 0x3 -+#define FC_PVER_SHIFT 0 -+#define FC_TYPE_MASK 0xC -+#define FC_TYPE_SHIFT 2 -+#define FC_SUBTYPE_MASK 0xF0 -+#define FC_SUBTYPE_SHIFT 4 -+#define FC_TODS 0x100 -+#define FC_TODS_SHIFT 8 -+#define FC_FROMDS 0x200 -+#define FC_FROMDS_SHIFT 9 -+#define FC_MOREFRAG 0x400 -+#define FC_MOREFRAG_SHIFT 10 -+#define FC_RETRY 0x800 -+#define FC_RETRY_SHIFT 11 -+#define FC_PM 0x1000 -+#define FC_PM_SHIFT 12 -+#define FC_MOREDATA 0x2000 -+#define FC_MOREDATA_SHIFT 13 -+#define FC_WEP 0x4000 -+#define FC_WEP_SHIFT 14 -+#define FC_ORDER 0x8000 -+#define FC_ORDER_SHIFT 15 -+ -+/* sequence control macros */ -+#define SEQNUM_SHIFT 4 -+#define FRAGNUM_MASK 0xF -+ -+/* Frame Control type/subtype defs */ -+ -+/* FC Types */ -+#define FC_TYPE_MNG 0 -+#define FC_TYPE_CTL 1 -+#define FC_TYPE_DATA 2 -+ -+/* Management Subtypes */ -+#define FC_SUBTYPE_ASSOC_REQ 0 -+#define FC_SUBTYPE_ASSOC_RESP 1 -+#define FC_SUBTYPE_REASSOC_REQ 2 -+#define FC_SUBTYPE_REASSOC_RESP 3 -+#define FC_SUBTYPE_PROBE_REQ 4 -+#define FC_SUBTYPE_PROBE_RESP 5 -+#define FC_SUBTYPE_BEACON 8 -+#define FC_SUBTYPE_ATIM 9 -+#define FC_SUBTYPE_DISASSOC 10 -+#define FC_SUBTYPE_AUTH 11 -+#define FC_SUBTYPE_DEAUTH 12 -+#define FC_SUBTYPE_ACTION 13 -+ -+/* Control Subtypes */ -+#define FC_SUBTYPE_PS_POLL 10 -+#define FC_SUBTYPE_RTS 11 -+#define FC_SUBTYPE_CTS 12 -+#define FC_SUBTYPE_ACK 13 -+#define FC_SUBTYPE_CF_END 14 -+#define FC_SUBTYPE_CF_END_ACK 15 -+ -+/* Data Subtypes */ -+#define FC_SUBTYPE_DATA 0 -+#define FC_SUBTYPE_DATA_CF_ACK 1 -+#define FC_SUBTYPE_DATA_CF_POLL 2 -+#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 -+#define FC_SUBTYPE_NULL 4 -+#define FC_SUBTYPE_CF_ACK 5 -+#define FC_SUBTYPE_CF_POLL 6 -+#define FC_SUBTYPE_CF_ACK_POLL 7 -+#define FC_SUBTYPE_QOS_DATA 8 -+#define FC_SUBTYPE_QOS_NULL 12 -+ -+/* type-subtype combos */ -+#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) -+ -+#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) -+ -+#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) -+#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) -+#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) -+#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) -+#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) -+#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) -+#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) -+#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) -+#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) -+#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) -+#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) -+ -+#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) -+#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) -+#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) -+#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) -+#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) -+#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) -+ -+#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) -+#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) -+#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) -+#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) -+#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) -+ -+/* QoS Control Field */ -+ -+/* 802.1D Tag */ -+#define QOS_PRIO_SHIFT 0 -+#define QOS_PRIO_MASK 0x0007 -+#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) -+ -+#define QOS_TID_SHIFT 0 -+#define QOS_TID_MASK 0x000f -+#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) -+ -+/* Ack Policy (0 means Acknowledge) */ -+#define QOS_ACK_SHIFT 5 -+#define QOS_ACK_MASK 0x0060 -+#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) -+ -+/* Management Frames */ -+ -+/* Management Frame Constants */ -+ -+/* Fixed fields */ -+#define DOT11_MNG_AUTH_ALGO_LEN 2 -+#define DOT11_MNG_AUTH_SEQ_LEN 2 -+#define DOT11_MNG_BEACON_INT_LEN 2 -+#define DOT11_MNG_CAP_LEN 2 -+#define DOT11_MNG_AP_ADDR_LEN 6 -+#define DOT11_MNG_LISTEN_INT_LEN 2 -+#define DOT11_MNG_REASON_LEN 2 -+#define DOT11_MNG_AID_LEN 2 -+#define DOT11_MNG_STATUS_LEN 2 -+#define DOT11_MNG_TIMESTAMP_LEN 8 -+ -+/* DUR/ID field in assoc resp is 0xc000 | AID */ -+#define DOT11_AID_MASK 0x3fff -+ -+/* Reason Codes */ -+#define DOT11_RC_RESERVED 0 -+#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */ -+#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer valid */ -+#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station is -+ leaving (or has left) IBSS or ESS */ -+#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */ -+#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable to handle -+ all currently associated stations */ -+#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from -+ nonauthenticated station */ -+#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from -+ nonassociated station */ -+#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is -+ leaving (or has left) BSS */ -+#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is -+ not authenticated with responding station */ -+#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */ -+ -+/* Status Codes */ -+#define DOT11_STATUS_SUCCESS 0 /* Successful */ -+#define DOT11_STATUS_FAILURE 1 /* Unspecified failure */ -+#define DOT11_STATUS_CAP_MISMATCH 10 /* Cannot support all requested capabilities -+ in the Capability Information field */ -+#define DOT11_STATUS_REASSOC_FAIL 11 /* Reassociation denied due to inability to -+ confirm that association exists */ -+#define DOT11_STATUS_ASSOC_FAIL 12 /* Association denied due to reason outside -+ the scope of this standard */ -+#define DOT11_STATUS_AUTH_MISMATCH 13 /* Responding station does not support the -+ specified authentication algorithm */ -+#define DOT11_STATUS_AUTH_SEQ 14 /* Received an Authentication frame with -+ authentication transaction sequence number -+ out of expected sequence */ -+#define DOT11_STATUS_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of challenge failure */ -+#define DOT11_STATUS_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout waiting -+ for next frame in sequence */ -+#define DOT11_STATUS_ASSOC_BUSY_FAIL 17 /* Association denied because AP is unable to -+ handle additional associated stations */ -+#define DOT11_STATUS_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting station -+ not supporting all of the data rates in the -+ BSSBasicRateSet parameter */ -+#define DOT11_STATUS_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting station -+ not supporting the Short Preamble option */ -+#define DOT11_STATUS_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting station -+ not supporting the PBCC Modulation option */ -+#define DOT11_STATUS_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting station -+ not supporting the Channel Agility option */ -+#define DOT11_STATUS_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum Management -+ capability is required. */ -+#define DOT11_STATUS_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info in the -+ Power Cap element is unacceptable. */ -+#define DOT11_STATUS_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info in the -+ Supported Channel element is unacceptable */ -+#define DOT11_STATUS_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting station -+ not supporting the Short Slot Time option */ -+#define DOT11_STATUS_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting station -+ not supporting the ER-PBCC Modulation option */ -+#define DOT11_STATUS_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting station -+ not supporting the DSS-OFDM option */ -+ -+/* Info Elts, length of INFORMATION portion of Info Elts */ -+#define DOT11_MNG_DS_PARAM_LEN 1 -+#define DOT11_MNG_IBSS_PARAM_LEN 2 -+ -+/* TIM Info element has 3 bytes fixed info in INFORMATION field, -+ * followed by 1 to 251 bytes of Partial Virtual Bitmap */ -+#define DOT11_MNG_TIM_FIXED_LEN 3 -+#define DOT11_MNG_TIM_DTIM_COUNT 0 -+#define DOT11_MNG_TIM_DTIM_PERIOD 1 -+#define DOT11_MNG_TIM_BITMAP_CTL 2 -+#define DOT11_MNG_TIM_PVB 3 -+ -+/* TLV defines */ -+#define TLV_TAG_OFF 0 -+#define TLV_LEN_OFF 1 -+#define TLV_HDR_LEN 2 -+#define TLV_BODY_OFF 2 -+ -+/* Management Frame Information Element IDs */ -+#define DOT11_MNG_SSID_ID 0 -+#define DOT11_MNG_RATES_ID 1 -+#define DOT11_MNG_FH_PARMS_ID 2 -+#define DOT11_MNG_DS_PARMS_ID 3 -+#define DOT11_MNG_CF_PARMS_ID 4 -+#define DOT11_MNG_TIM_ID 5 -+#define DOT11_MNG_IBSS_PARMS_ID 6 -+#define DOT11_MNG_COUNTRY_ID 7 -+#define DOT11_MNG_HOPPING_PARMS_ID 8 -+#define DOT11_MNG_HOPPING_TABLE_ID 9 -+#define DOT11_MNG_REQUEST_ID 10 -+#define DOT11_MNG_CHALLENGE_ID 16 -+#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */ -+#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */ -+#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */ -+#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */ -+#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */ -+#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement*/ -+#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */ -+#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */ -+#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */ -+#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ -+#define DOT11_MNG_ERP_ID 42 -+#define DOT11_MNG_NONERP_ID 47 -+#ifdef BCMWPA2 -+#define DOT11_MNG_RSN_ID 48 -+#endif /* BCMWPA2 */ -+#define DOT11_MNG_EXT_RATES_ID 50 -+#define DOT11_MNG_WPA_ID 221 -+#define DOT11_MNG_PROPR_ID 221 -+ -+/* ERP info element bit values */ -+#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */ -+#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present in the BSS */ -+#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for ERP-OFDM frames */ -+#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, 1 == not allowed */ -+ -+/* Capability Information Field */ -+#define DOT11_CAP_ESS 0x0001 -+#define DOT11_CAP_IBSS 0x0002 -+#define DOT11_CAP_POLLABLE 0x0004 -+#define DOT11_CAP_POLL_RQ 0x0008 -+#define DOT11_CAP_PRIVACY 0x0010 -+#define DOT11_CAP_SHORT 0x0020 -+#define DOT11_CAP_PBCC 0x0040 -+#define DOT11_CAP_AGILITY 0x0080 -+#define DOT11_CAP_SPECTRUM 0x0100 -+#define DOT11_CAP_SHORTSLOT 0x0400 -+#define DOT11_CAP_CCK_OFDM 0x2000 -+ -+/* Action Frame Constants */ -+#define DOT11_ACTION_CAT_ERR_MASK 0x80 -+#define DOT11_ACTION_CAT_SPECT_MNG 0x00 -+#define DOT11_ACTION_NOTIFICATION 0x11 /* 17 */ -+ -+#define DOT11_ACTION_ID_M_REQ 0 -+#define DOT11_ACTION_ID_M_REP 1 -+#define DOT11_ACTION_ID_TPC_REQ 2 -+#define DOT11_ACTION_ID_TPC_REP 3 -+#define DOT11_ACTION_ID_CHANNEL_SWITCH 4 -+ -+/* MLME Enumerations */ -+#define DOT11_BSSTYPE_INFRASTRUCTURE 0 -+#define DOT11_BSSTYPE_INDEPENDENT 1 -+#define DOT11_BSSTYPE_ANY 2 -+#define DOT11_SCANTYPE_ACTIVE 0 -+#define DOT11_SCANTYPE_PASSIVE 1 -+ -+/* 802.11 A PHY constants */ -+#define APHY_SLOT_TIME 9 -+#define APHY_SIFS_TIME 16 -+#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) -+#define APHY_PREAMBLE_TIME 16 -+#define APHY_SIGNAL_TIME 4 -+#define APHY_SYMBOL_TIME 4 -+#define APHY_SERVICE_NBITS 16 -+#define APHY_TAIL_NBITS 6 -+#define APHY_CWMIN 15 -+ -+/* 802.11 B PHY constants */ -+#define BPHY_SLOT_TIME 20 -+#define BPHY_SIFS_TIME 10 -+#define BPHY_DIFS_TIME 50 -+#define BPHY_PLCP_TIME 192 -+#define BPHY_PLCP_SHORT_TIME 96 -+#define BPHY_CWMIN 31 -+ -+/* 802.11 G constants */ -+#define DOT11_OFDM_SIGNAL_EXTENSION 6 -+ -+#define PHY_CWMAX 1023 -+ -+#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */ -+ -+/* dot11Counters Table - 802.11 spec., Annex D */ -+typedef struct d11cnt { -+ uint32 txfrag; /* dot11TransmittedFragmentCount */ -+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ -+ uint32 txfail; /* dot11FailedCount */ -+ uint32 txretry; /* dot11RetryCount */ -+ uint32 txretrie; /* dot11MultipleRetryCount */ -+ uint32 rxdup; /* dot11FrameduplicateCount */ -+ uint32 txrts; /* dot11RTSSuccessCount */ -+ uint32 txnocts; /* dot11RTSFailureCount */ -+ uint32 txnoack; /* dot11ACKFailureCount */ -+ uint32 rxfrag; /* dot11ReceivedFragmentCount */ -+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ -+ uint32 rxcrc; /* dot11FCSErrorCount */ -+ uint32 txfrmsnt; /* dot11TransmittedFrameCount */ -+ uint32 rxundec; /* dot11WEPUndecryptableCount */ -+} d11cnt_t; -+ -+/* BRCM OUI */ -+#define BRCM_OUI "\x00\x10\x18" -+ -+/* BRCM info element */ -+struct brcm_ie { -+ uchar id; /* 221, DOT11_MNG_PROPR_ID */ -+ uchar len; -+ uchar oui[3]; -+ uchar ver; -+ uchar assoc; /* # of assoc STAs */ -+ uchar flags; /* misc flags */ -+} PACKED; -+#define BRCM_IE_LEN 8 -+typedef struct brcm_ie brcm_ie_t; -+#define BRCM_IE_VER 2 -+#define BRCM_IE_LEGACY_AES_VER 1 -+ -+/* brcm_ie flags */ -+#define BRF_ABCAP 0x1 /* afterburner capable */ -+#define BRF_ABRQRD 0x2 /* afterburner requested */ -+#define BRF_LZWDS 0x4 /* lazy wds enabled */ -+#define BRF_ABCOUNTER_MASK 0xf0 /* afterburner wds "state" counter */ -+#define BRF_ABCOUNTER_SHIFT 4 -+ -+#define AB_WDS_TIMEOUT_MAX 15 /* afterburner wds Max count indicating not locally capable */ -+#define AB_WDS_TIMEOUT_MIN 1 /* afterburner wds, use zero count as indicating "downrev" */ -+ -+ -+/* OUI for BRCM proprietary IE */ -+#define BRCM_PROP_OUI "\x00\x90\x4C" -+ -+/* Vendor IE structure */ -+struct vndr_ie { -+ uchar id; -+ uchar len; -+ uchar oui [3]; -+ uchar data [1]; /* Variable size data */ -+}PACKED; -+typedef struct vndr_ie vndr_ie_t; -+ -+#define VNDR_IE_HDR_LEN 2 /* id + len field */ -+#define VNDR_IE_MIN_LEN 3 /* size of the oui field */ -+#define VNDR_IE_MAX_LEN 256 -+ -+/* WPA definitions */ -+#define WPA_VERSION 1 -+#define WPA_OUI "\x00\x50\xF2" -+ -+#ifdef BCMWPA2 -+#define WPA2_VERSION 1 -+#define WPA2_VERSION_LEN 2 -+#define WPA2_OUI "\x00\x0F\xAC" -+#endif /* BCMWPA2 */ -+ -+#define WPA_OUI_LEN 3 -+ -+/* RSN authenticated key managment suite */ -+#define RSN_AKM_NONE 0 /* None (IBSS) */ -+#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ -+#define RSN_AKM_PSK 2 /* Pre-shared Key */ -+ -+ -+/* Key related defines */ -+#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */ -+#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */ -+#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */ -+#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */ -+ -+#define WEP1_KEY_SIZE 5 /* max size of any WEP key */ -+#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */ -+#define WEP128_KEY_SIZE 13 /* max size of any WEP key */ -+#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */ -+#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */ -+#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */ -+#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */ -+#define TKIP_KEY_SIZE 32 /* size of any TKIP key */ -+#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */ -+#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */ -+#define TKIP_MIC_SUP_RX 16 /* offset to Supplicant MIC RX key */ -+#define TKIP_MIC_SUP_TX 24 /* offset to Supplicant MIC TX key */ -+#define AES_KEY_SIZE 16 /* size of AES key */ -+ -+#undef PACKED -+#if !defined(__GNUC__) -+#pragma pack() -+#endif ++/* handy */ ++#define SET_REG(r, mask, val) W_REG((r), ((R_REG(r) & ~(mask)) | (val))) ++#define MAXPRIO 7 /* 0-7 */ + -+#endif /* _802_11_H_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmeth.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmeth.h ---- linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmeth.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmeth.h 2005-12-16 23:39:10.756825000 +0100 -@@ -0,0 +1,103 @@ ++#endif /* _osl_h_ */ +diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h +--- linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h 2005-12-16 23:39:10.752824750 +0100 +@@ -0,0 +1,451 @@ +/* -+ * Broadcom Ethernettype protocol definitions ++ * pcicfg.h: PCI configuration constants and structures. + * + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. @@ -6065,588 +3185,446 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmeth.h linux-2.4.32-br + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * ++ * $Id$ + */ + -+/* -+ * Broadcom Ethernet protocol defines -+ * -+ */ -+ -+#ifndef _BCMETH_H_ -+#define _BCMETH_H_ ++#ifndef _h_pci_ ++#define _h_pci_ + -+/* enable structure packing */ -+#if defined(__GNUC__) -+#define PACKED __attribute__((packed)) -+#else -+#pragma pack(1) -+#define PACKED ++/* The following inside ifndef's so we don't collide with NTDDK.H */ ++#ifndef PCI_MAX_BUS ++#define PCI_MAX_BUS 0x100 +#endif -+ -+/* ETHER_TYPE_BRCM is defined in ethernet.h */ -+ -+/* -+ * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field -+ * in one of two formats: (only subtypes 32768-65535 are in use now) -+ * -+ * subtypes 0-32767: -+ * 8 bit subtype (0-127) -+ * 8 bit length in bytes (0-255) -+ * -+ * subtypes 32768-65535: -+ * 16 bit big-endian subtype -+ * 16 bit big-endian length in bytes (0-65535) -+ * -+ * length is the number of additional bytes beyond the 4 or 6 byte header -+ * -+ * Reserved values: -+ * 0 reserved -+ * 5-15 reserved for iLine protocol assignments -+ * 17-126 reserved, assignable -+ * 127 reserved -+ * 32768 reserved -+ * 32769-65534 reserved, assignable -+ * 65535 reserved -+ */ -+ -+/* -+ * While adding the subtypes and their specific processing code make sure -+ * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition -+ */ -+ -+#define BCMILCP_SUBTYPE_RATE 1 -+#define BCMILCP_SUBTYPE_LINK 2 -+#define BCMILCP_SUBTYPE_CSA 3 -+#define BCMILCP_SUBTYPE_LARQ 4 -+#define BCMILCP_SUBTYPE_VENDOR 5 -+#define BCMILCP_SUBTYPE_FLH 17 -+ -+#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 -+#define BCMILCP_SUBTYPE_CERT 32770 -+#define BCMILCP_SUBTYPE_SES 32771 -+ -+ -+#define BCMILCP_BCM_SUBTYPE_RESERVED 0 -+#define BCMILCP_BCM_SUBTYPE_EVENT 1 -+#define BCMILCP_BCM_SUBTYPE_SES 2 -+/* -+The EAPOL type is not used anymore. Instead EAPOL messages are now embedded -+within BCMILCP_BCM_SUBTYPE_EVENT type messages -+*/ -+/*#define BCMILCP_BCM_SUBTYPE_EAPOL 3*/ -+ -+#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 -+#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 -+ -+/* These fields are stored in network order */ -+typedef struct bcmeth_hdr -+{ -+ uint16 subtype; /* Vendor specific..32769*/ -+ uint16 length; -+ uint8 version; /* Version is 0*/ -+ uint8 oui[3]; /* Broadcom OUI*/ -+ /* user specific Data */ -+ uint16 usr_subtype; -+} PACKED bcmeth_hdr_t; -+ -+ -+ -+#undef PACKED -+#if !defined(__GNUC__) -+#pragma pack() ++#ifndef PCI_MAX_DEVICES ++#define PCI_MAX_DEVICES 0x20 +#endif -+ ++#ifndef PCI_MAX_FUNCTION ++#define PCI_MAX_FUNCTION 0x8 +#endif -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmip.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmip.h ---- linux-2.4.32/arch/mips/bcm947xx/include/proto/bcmip.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/bcmip.h 2005-12-16 23:39:10.756825000 +0100 -@@ -0,0 +1,42 @@ -+/* -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation; -+ * the contents of this file may not be disclosed to third parties, copied -+ * or duplicated in any form, in whole or in part, without the prior -+ * written permission of Broadcom Corporation. -+ * -+ * Fundamental constants relating to IP Protocol -+ * -+ * $Id$ -+ */ -+ -+#ifndef _bcmip_h_ -+#define _bcmip_h_ -+ -+/* IP header */ -+#define IPV4_VERIHL_OFFSET 0 /* version and ihl byte offset */ -+#define IPV4_TOS_OFFSET 1 /* TOS offset */ -+#define IPV4_PROT_OFFSET 9 /* protocol type offset */ -+#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ -+#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ -+#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ -+ -+#define IPV4_VER_MASK 0xf0 -+#define IPV4_IHL_MASK 0x0f + -+#define IPV4_PROT_UDP 17 /* UDP protocol type */ -+ -+#define IPV4_ADDR_LEN 4 /* IP v4 address length */ ++#ifndef PCI_INVALID_VENDORID ++#define PCI_INVALID_VENDORID 0xffff ++#endif ++#ifndef PCI_INVALID_DEVICEID ++#define PCI_INVALID_DEVICEID 0xffff ++#endif + -+#define IPV4_VER_NUM 0x40 /* IP v4 version number */ + -+/* NULL IP address check */ -+#define IPV4_ISNULLADDR(a) ((((uint8 *)(a))[0] + ((uint8 *)(a))[1] + \ -+ ((uint8 *)(a))[2] + ((uint8 *)(a))[3]) == 0) ++/* Convert between bus-slot-function-register and config addresses */ + -+#define IPV4_ADDR_STR_LEN 16 ++#define PCICFG_BUS_SHIFT 16 /* Bus shift */ ++#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ ++#define PCICFG_FUN_SHIFT 8 /* Function shift */ ++#define PCICFG_OFF_SHIFT 0 /* Register shift */ + -+#endif /* #ifndef _bcmip_h_ */ ++#define PCICFG_BUS_MASK 0xff /* Bus mask */ ++#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ ++#define PCICFG_FUN_MASK 7 /* Function mask */ ++#define PCICFG_OFF_MASK 0xff /* Bus mask */ + -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/ethernet.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/ethernet.h ---- linux-2.4.32/arch/mips/bcm947xx/include/proto/ethernet.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/ethernet.h 2005-12-16 23:39:10.756825000 +0100 -@@ -0,0 +1,169 @@ -+/******************************************************************************* -+ * $Id$ -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. -+ ******************************************************************************/ ++#define PCI_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ ++ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ ++ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ ++ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) + -+#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ -+#define _NET_ETHERNET_H_ ++#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) ++#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) ++#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) ++#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) + -+#ifndef _TYPEDEFS_H_ -+#include "typedefs.h" -+#endif ++/* PCIE Config space accessing MACROS*/ + -+/* enable structure packing */ -+#if defined(__GNUC__) -+#define PACKED __attribute__((packed)) -+#else -+#pragma pack(1) -+#define PACKED -+#endif ++#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ ++#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ ++#define PCIECFG_FUN_SHIFT 16 /* Function shift */ ++#define PCIECFG_OFF_SHIFT 0 /* Register shift */ + -+/* -+ * The number of bytes in an ethernet (MAC) address. -+ */ -+#define ETHER_ADDR_LEN 6 ++#define PCIECFG_BUS_MASK 0xff /* Bus mask */ ++#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ ++#define PCIECFG_FUN_MASK 7 /* Function mask */ ++#define PCIECFG_OFF_MASK 0x3ff /* Register mask */ + -+/* -+ * The number of bytes in the type field. -+ */ -+#define ETHER_TYPE_LEN 2 ++#define PCIE_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ ++ | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ ++ | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ ++ | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) + -+/* -+ * The number of bytes in the trailing CRC field. -+ */ -+#define ETHER_CRC_LEN 4 ++#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) ++#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) ++#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) ++#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) + -+/* -+ * The length of the combined header. -+ */ -+#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) ++ ++/* The actual config space */ + -+/* -+ * The minimum packet length. -+ */ -+#define ETHER_MIN_LEN 64 ++#define PCI_BAR_MAX 6 + -+/* -+ * The minimum packet user data length. -+ */ -+#define ETHER_MIN_DATA 46 ++#define PCI_ROM_BAR 8 + -+/* -+ * The maximum packet length. -+ */ -+#define ETHER_MAX_LEN 1518 ++#define PCR_RSVDA_MAX 2 + -+/* -+ * The maximum packet user data length. -+ */ -+#define ETHER_MAX_DATA 1500 ++/* pci config status reg has a bit to indicate that capability ptr is present*/ + -+/* ether types */ -+#define ETHER_TYPE_IP 0x0800 /* IP */ -+#define ETHER_TYPE_ARP 0x0806 /* ARP */ -+#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ -+#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */ -+#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ -+#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication*/ ++#define PCI_CAPPTR_PRESENT 0x0010 + -+/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */ -+#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */ -+#define ETHER_BRCM_CRAM 0x1 /* Broadcom subtype cram protocol */ ++typedef struct _pci_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long base[PCI_BAR_MAX]; ++ unsigned long cardbus_cis; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long baserom; ++ unsigned long rsvd_a[PCR_RSVDA_MAX]; ++ unsigned char int_line; ++ unsigned char int_pin; ++ unsigned char min_gnt; ++ unsigned char max_lat; ++ unsigned char dev_dep[192]; ++} pci_config_regs; + -+/* ether header */ -+#define ETHER_DEST_OFFSET 0 /* dest address offset */ -+#define ETHER_SRC_OFFSET 6 /* src address offset */ -+#define ETHER_TYPE_OFFSET 12 /* ether type offset */ ++#define SZPCR (sizeof (pci_config_regs)) ++#define MINSZPCR 64 /* offsetof (dev_dep[0] */ + -+/* -+ * A macro to validate a length with ++/* A structure for the config registers is nice, but in most ++ * systems the config space is not memory mapped, so we need ++ * filed offsetts. :-( + */ -+#define ETHER_IS_VALID_LEN(foo) \ -+ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) ++#define PCI_CFG_VID 0 ++#define PCI_CFG_DID 2 ++#define PCI_CFG_CMD 4 ++#define PCI_CFG_STAT 6 ++#define PCI_CFG_REV 8 ++#define PCI_CFG_PROGIF 9 ++#define PCI_CFG_SUBCL 0xa ++#define PCI_CFG_BASECL 0xb ++#define PCI_CFG_CLSZ 0xc ++#define PCI_CFG_LATTIM 0xd ++#define PCI_CFG_HDR 0xe ++#define PCI_CFG_BIST 0xf ++#define PCI_CFG_BAR0 0x10 ++#define PCI_CFG_BAR1 0x14 ++#define PCI_CFG_BAR2 0x18 ++#define PCI_CFG_BAR3 0x1c ++#define PCI_CFG_BAR4 0x20 ++#define PCI_CFG_BAR5 0x24 ++#define PCI_CFG_CIS 0x28 ++#define PCI_CFG_SVID 0x2c ++#define PCI_CFG_SSID 0x2e ++#define PCI_CFG_ROMBAR 0x30 ++#define PCI_CFG_CAPPTR 0x34 ++#define PCI_CFG_INT 0x3c ++#define PCI_CFG_PIN 0x3d ++#define PCI_CFG_MINGNT 0x3e ++#define PCI_CFG_MAXLAT 0x3f + ++/* Classes and subclasses */ + -+#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ -+/* -+ * Structure of a 10Mb/s Ethernet header. -+ */ -+struct ether_header { -+ uint8 ether_dhost[ETHER_ADDR_LEN]; -+ uint8 ether_shost[ETHER_ADDR_LEN]; -+ uint16 ether_type; -+} PACKED; ++typedef enum { ++ PCI_CLASS_OLD = 0, ++ PCI_CLASS_DASDI, ++ PCI_CLASS_NET, ++ PCI_CLASS_DISPLAY, ++ PCI_CLASS_MMEDIA, ++ PCI_CLASS_MEMORY, ++ PCI_CLASS_BRIDGE, ++ PCI_CLASS_COMM, ++ PCI_CLASS_BASE, ++ PCI_CLASS_INPUT, ++ PCI_CLASS_DOCK, ++ PCI_CLASS_CPU, ++ PCI_CLASS_SERIAL, ++ PCI_CLASS_INTELLIGENT = 0xe, ++ PCI_CLASS_SATELLITE, ++ PCI_CLASS_CRYPT, ++ PCI_CLASS_DSP, ++ PCI_CLASS_MAX ++} pci_classes; + -+/* -+ * Structure of a 48-bit Ethernet address. -+ */ -+struct ether_addr { -+ uint8 octet[ETHER_ADDR_LEN]; -+} PACKED; -+#endif ++typedef enum { ++ PCI_DASDI_SCSI, ++ PCI_DASDI_IDE, ++ PCI_DASDI_FLOPPY, ++ PCI_DASDI_IPI, ++ PCI_DASDI_RAID, ++ PCI_DASDI_OTHER = 0x80 ++} pci_dasdi_subclasses; + -+/* -+ * Takes a pointer, sets locally admininistered -+ * address bit in the 48-bit Ethernet address. -+ */ -+#define ETHER_SET_LOCALADDR(ea) ( ((uint8 *)(ea))[0] = \ -+ (((uint8 *)(ea))[0] | 2) ) ++typedef enum { ++ PCI_NET_ETHER, ++ PCI_NET_TOKEN, ++ PCI_NET_FDDI, ++ PCI_NET_ATM, ++ PCI_NET_OTHER = 0x80 ++} pci_net_subclasses; + -+/* -+ * Takes a pointer, returns true if a 48-bit multicast address -+ * (including broadcast, since it is all ones) -+ */ -+#define ETHER_ISMULTI(ea) (((uint8 *)(ea))[0] & 1) ++typedef enum { ++ PCI_DISPLAY_VGA, ++ PCI_DISPLAY_XGA, ++ PCI_DISPLAY_3D, ++ PCI_DISPLAY_OTHER = 0x80 ++} pci_display_subclasses; + ++typedef enum { ++ PCI_MMEDIA_VIDEO, ++ PCI_MMEDIA_AUDIO, ++ PCI_MMEDIA_PHONE, ++ PCI_MEDIA_OTHER = 0x80 ++} pci_mmedia_subclasses; + -+/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */ -+#define ether_cmp(a, b) ( \ -+ !(((short*)a)[0] == ((short*)b)[0]) | \ -+ !(((short*)a)[1] == ((short*)b)[1]) | \ -+ !(((short*)a)[2] == ((short*)b)[2])) ++typedef enum { ++ PCI_MEMORY_RAM, ++ PCI_MEMORY_FLASH, ++ PCI_MEMORY_OTHER = 0x80 ++} pci_memory_subclasses; + -+/* copy an ethernet address - assumes the pointers can be referenced as shorts */ -+#define ether_copy(s, d) { \ -+ ((short*)d)[0] = ((short*)s)[0]; \ -+ ((short*)d)[1] = ((short*)s)[1]; \ -+ ((short*)d)[2] = ((short*)s)[2]; } ++typedef enum { ++ PCI_BRIDGE_HOST, ++ PCI_BRIDGE_ISA, ++ PCI_BRIDGE_EISA, ++ PCI_BRIDGE_MC, ++ PCI_BRIDGE_PCI, ++ PCI_BRIDGE_PCMCIA, ++ PCI_BRIDGE_NUBUS, ++ PCI_BRIDGE_CARDBUS, ++ PCI_BRIDGE_RACEWAY, ++ PCI_BRIDGE_OTHER = 0x80 ++} pci_bridge_subclasses; + -+/* -+ * Takes a pointer, returns true if a 48-bit broadcast (all ones) -+ */ -+#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ -+ ((uint8 *)(ea))[1] & \ -+ ((uint8 *)(ea))[2] & \ -+ ((uint8 *)(ea))[3] & \ -+ ((uint8 *)(ea))[4] & \ -+ ((uint8 *)(ea))[5]) == 0xff) ++typedef enum { ++ PCI_COMM_UART, ++ PCI_COMM_PARALLEL, ++ PCI_COMM_MULTIUART, ++ PCI_COMM_MODEM, ++ PCI_COMM_OTHER = 0x80 ++} pci_comm_subclasses; + -+static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; ++typedef enum { ++ PCI_BASE_PIC, ++ PCI_BASE_DMA, ++ PCI_BASE_TIMER, ++ PCI_BASE_RTC, ++ PCI_BASE_PCI_HOTPLUG, ++ PCI_BASE_OTHER = 0x80 ++} pci_base_subclasses; + -+/* -+ * Takes a pointer, returns true if a 48-bit null address (all zeros) -+ */ -+#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ -+ ((uint8 *)(ea))[1] | \ -+ ((uint8 *)(ea))[2] | \ -+ ((uint8 *)(ea))[3] | \ -+ ((uint8 *)(ea))[4] | \ -+ ((uint8 *)(ea))[5]) == 0) -+ -+/* Differentiated Services Codepoint - upper 6 bits of tos in iphdr */ -+#define DSCP_MASK 0xFC /* upper 6 bits */ -+#define DSCP_SHIFT 2 -+#define DSCP_WME_PRI_MASK 0xE0 /* upper 3 bits */ -+#define DSCP_WME_PRI_SHIFT 5 -+ -+#undef PACKED -+#if !defined(__GNUC__) -+#pragma pack() -+#endif ++typedef enum { ++ PCI_INPUT_KBD, ++ PCI_INPUT_PEN, ++ PCI_INPUT_MOUSE, ++ PCI_INPUT_SCANNER, ++ PCI_INPUT_GAMEPORT, ++ PCI_INPUT_OTHER = 0x80 ++} pci_input_subclasses; + -+#endif /* _NET_ETHERNET_H_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/vlan.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/vlan.h ---- linux-2.4.32/arch/mips/bcm947xx/include/proto/vlan.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/vlan.h 2005-12-16 23:39:10.756825000 +0100 -@@ -0,0 +1,50 @@ -+/* -+ * 802.1Q VLAN protocol definitions -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++typedef enum { ++ PCI_DOCK_GENERIC, ++ PCI_DOCK_OTHER = 0x80 ++} pci_dock_subclasses; + -+#ifndef _vlan_h_ -+#define _vlan_h_ ++typedef enum { ++ PCI_CPU_386, ++ PCI_CPU_486, ++ PCI_CPU_PENTIUM, ++ PCI_CPU_ALPHA = 0x10, ++ PCI_CPU_POWERPC = 0x20, ++ PCI_CPU_MIPS = 0x30, ++ PCI_CPU_COPROC = 0x40, ++ PCI_CPU_OTHER = 0x80 ++} pci_cpu_subclasses; + -+/* enable structure packing */ -+#if defined(__GNUC__) -+#define PACKED __attribute__((packed)) -+#else -+#pragma pack(1) -+#define PACKED -+#endif ++typedef enum { ++ PCI_SERIAL_IEEE1394, ++ PCI_SERIAL_ACCESS, ++ PCI_SERIAL_SSA, ++ PCI_SERIAL_USB, ++ PCI_SERIAL_FIBER, ++ PCI_SERIAL_SMBUS, ++ PCI_SERIAL_OTHER = 0x80 ++} pci_serial_subclasses; + -+#define VLAN_VID_MASK 0xfff /* low 12 bits are vlan id */ -+#define VLAN_CFI_SHIFT 12 /* canonical format indicator bit */ -+#define VLAN_PRI_SHIFT 13 /* user priority */ ++typedef enum { ++ PCI_INTELLIGENT_I2O, ++} pci_intelligent_subclasses; + -+#define VLAN_PRI_MASK 7 /* 3 bits of priority */ ++typedef enum { ++ PCI_SATELLITE_TV, ++ PCI_SATELLITE_AUDIO, ++ PCI_SATELLITE_VOICE, ++ PCI_SATELLITE_DATA, ++ PCI_SATELLITE_OTHER = 0x80 ++} pci_satellite_subclasses; + -+#define VLAN_TAG_LEN 4 -+#define VLAN_TAG_OFFSET (2 * ETHER_ADDR_LEN) ++typedef enum { ++ PCI_CRYPT_NETWORK, ++ PCI_CRYPT_ENTERTAINMENT, ++ PCI_CRYPT_OTHER = 0x80 ++} pci_crypt_subclasses; + -+struct ethervlan_header { -+ uint8 ether_dhost[ETHER_ADDR_LEN]; -+ uint8 ether_shost[ETHER_ADDR_LEN]; -+ uint16 vlan_type; /* 0x8100 */ -+ uint16 vlan_tag; /* priority, cfi and vid */ -+ uint16 ether_type; -+}; ++typedef enum { ++ PCI_DSP_DPIO, ++ PCI_DSP_OTHER = 0x80 ++} pci_dsp_subclasses; + -+#define ETHERVLAN_HDR_LEN (ETHER_HDR_LEN + VLAN_TAG_LEN) ++/* Header types */ ++typedef enum { ++ PCI_HEADER_NORMAL, ++ PCI_HEADER_BRIDGE, ++ PCI_HEADER_CARDBUS ++} pci_header_types; + -+#undef PACKED -+#if !defined(__GNUC__) -+#pragma pack() -+#endif + -+#endif /* _vlan_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/proto/wpa.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/wpa.h ---- linux-2.4.32/arch/mips/bcm947xx/include/proto/wpa.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/proto/wpa.h 2005-12-16 23:39:10.756825000 +0100 -@@ -0,0 +1,140 @@ -+/* -+ * Fundamental types and constants relating to WPA -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++/* Overlay for a PCI-to-PCI bridge */ + -+#ifndef _proto_wpa_h_ -+#define _proto_wpa_h_ ++#define PPB_RSVDA_MAX 2 ++#define PPB_RSVDD_MAX 8 + -+#include -+#include ++typedef struct _ppb_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long rsvd_a[PPB_RSVDA_MAX]; ++ unsigned char prim_bus; ++ unsigned char sec_bus; ++ unsigned char sub_bus; ++ unsigned char sec_lat; ++ unsigned char io_base; ++ unsigned char io_lim; ++ unsigned short sec_status; ++ unsigned short mem_base; ++ unsigned short mem_lim; ++ unsigned short pf_mem_base; ++ unsigned short pf_mem_lim; ++ unsigned long pf_mem_base_hi; ++ unsigned long pf_mem_lim_hi; ++ unsigned short io_base_hi; ++ unsigned short io_lim_hi; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long rsvd_b; ++ unsigned char rsvd_c; ++ unsigned char int_pin; ++ unsigned short bridge_ctrl; ++ unsigned char chip_ctrl; ++ unsigned char diag_ctrl; ++ unsigned short arb_ctrl; ++ unsigned long rsvd_d[PPB_RSVDD_MAX]; ++ unsigned char dev_dep[192]; ++} ppb_config_regs; + -+/* enable structure packing */ -+#if defined(__GNUC__) -+#define PACKED __attribute__((packed)) -+#else -+#pragma pack(1) -+#define PACKED -+#endif + -+/* Reason Codes */ -+ -+/* 10 and 11 are from TGh. */ -+#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */ -+#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */ -+/* 12 is unused */ -+/* 13 through 23 taken from P802.11i/D3.0, November 2002 */ -+#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */ -+#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */ -+#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */ -+#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */ -+#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from (re-)assoc. request/probe response */ -+#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */ -+#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */ -+#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */ -+#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */ -+#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */ -+#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */ -+ -+#define WPA2_PMKID_LEN 16 -+ -+/* WPA IE fixed portion */ -+typedef struct -+{ -+ uint8 tag; /* TAG */ -+ uint8 length; /* TAG length */ -+ uint8 oui[3]; /* IE OUI */ -+ uint8 oui_type; /* OUI type */ -+ struct { -+ uint8 low; -+ uint8 high; -+ } PACKED version; /* IE version */ -+} PACKED wpa_ie_fixed_t; -+#define WPA_IE_OUITYPE_LEN 4 -+#define WPA_IE_FIXED_LEN 8 -+#define WPA_IE_TAG_FIXED_LEN 6 ++/* PCI CAPABILITY DEFINES */ ++#define PCI_CAP_POWERMGMTCAP_ID 0x01 ++#define PCI_CAP_MSICAP_ID 0x05 ++#define PCI_CAP_PCIECAP_ID 0x10 + -+typedef struct { -+ uint8 tag; /* TAG */ -+ uint8 length; /* TAG length */ -+ struct { -+ uint8 low; -+ uint8 high; -+ } PACKED version; /* IE version */ -+} PACKED wpa_rsn_ie_fixed_t; -+#define WPA_RSN_IE_FIXED_LEN 4 -+#define WPA_RSN_IE_TAG_FIXED_LEN 2 -+typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; -+ -+/* WPA suite/multicast suite */ -+typedef struct -+{ -+ uint8 oui[3]; -+ uint8 type; -+} PACKED wpa_suite_t, wpa_suite_mcast_t; -+#define WPA_SUITE_LEN 4 -+ -+/* WPA unicast suite list/key management suite list */ -+typedef struct -+{ -+ struct { -+ uint8 low; -+ uint8 high; -+ } PACKED count; -+ wpa_suite_t list[1]; -+} PACKED wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; -+#define WPA_IE_SUITE_COUNT_LEN 2 -+typedef struct -+{ -+ struct { -+ uint8 low; -+ uint8 high; -+ } PACKED count; -+ wpa_pmkid_t list[1]; -+} PACKED wpa_pmkid_list_t; -+ -+/* WPA cipher suites */ -+#define WPA_CIPHER_NONE 0 /* None */ -+#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */ -+#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */ -+#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */ -+#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */ -+#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ -+ -+#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ -+ (cipher) == WPA_CIPHER_WEP_40 || \ -+ (cipher) == WPA_CIPHER_WEP_104 || \ -+ (cipher) == WPA_CIPHER_TKIP || \ -+ (cipher) == WPA_CIPHER_AES_OCB || \ -+ (cipher) == WPA_CIPHER_AES_CCM) -+ -+/* WPA TKIP countermeasures parameters */ -+#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ -+#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ -+ -+/* WPA capabilities defined in 802.11i */ -+#define WPA_CAP_4_REPLAY_CNTRS 2 -+#define WPA_CAP_16_REPLAY_CNTRS 3 -+#define WPA_CAP_REPLAY_CNTR_SHIFT 2 -+#define WPA_CAP_REPLAY_CNTR_MASK 0x000c -+ -+/* WPA Specific defines */ -+#define WPA_CAP_LEN 2 -+ -+#define WPA_CAP_WPA2_PREAUTH 1 -+ -+#undef PACKED -+#if !defined(__GNUC__) -+#pragma pack() -+#endif ++/* Data structure to define the Message Signalled Interrupt facility ++ * Valid for PCI and PCIE configurations */ ++typedef struct _pciconfig_cap_msi { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short msgctrl; ++ unsigned int msgaddr; ++} pciconfig_cap_msi; + -+#endif /* _proto_wpa_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/rts/crc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/rts/crc.h ---- linux-2.4.32/arch/mips/bcm947xx/include/rts/crc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/rts/crc.h 2005-12-16 23:39:10.928835750 +0100 -@@ -0,0 +1,69 @@ -+/******************************************************************************* -+ * $Id$ -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * crc.h - a function to compute crc for iLine10 headers -+ ******************************************************************************/ ++/* Data structure to define the Power managment facility ++ * Valid for PCI and PCIE configurations */ ++typedef struct _pciconfig_cap_pwrmgmt { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short pme_cap; ++ unsigned short pme_sts_ctrl; ++ unsigned char pme_bridge_ext; ++ unsigned char data; ++} pciconfig_cap_pwrmgmt; + -+#ifndef _RTS_CRC_H_ -+#define _RTS_CRC_H_ 1 ++/* Data structure to define the PCIE capability */ ++typedef struct _pciconfig_cap_pcie { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short pcie_cap; ++ unsigned int dev_cap; ++ unsigned short dev_ctrl; ++ unsigned short dev_status; ++ unsigned int link_cap; ++ unsigned short link_ctrl; ++ unsigned short link_status; ++} pciconfig_cap_pcie; + -+#include "typedefs.h" ++/* PCIE Enhanced CAPABILITY DEFINES */ ++#define PCIE_EXTCFG_OFFSET 0x100 ++#define PCIE_ADVERRREP_CAPID 0x0001 ++#define PCIE_VC_CAPID 0x0002 ++#define PCIE_DEVSNUM_CAPID 0x0003 ++#define PCIE_PWRBUDGET_CAPID 0x0004 + -+#ifdef __cplusplus -+extern "C" { -+#endif ++/* Header to define the PCIE specific capabilities in the extended config space */ ++typedef struct _pcie_enhanced_caphdr { ++ unsigned short capID; ++ unsigned short cap_ver : 4; ++ unsigned short next_ptr : 12; ++} pcie_enhanced_caphdr; + + -+#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ -+#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ -+#define HCS_GOOD_VALUE 0x39 /* Good final header checksum value */ ++/* Everything below is BRCM HND proprietary */ + -+#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ -+#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ ++#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ ++#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ ++#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ ++#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ ++#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ ++#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ ++#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ ++#define PCI_BACKPLANE_ADDR 0xA0 /* address an arbitrary location on the system backplane */ ++#define PCI_BACKPLANE_DATA 0xA4 /* data at the location specified by above address register */ ++#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ ++#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ ++#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ + -+#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ -+#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ ++#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ ++#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ + -+void hcs(uint8 *, uint); -+uint8 crc8(uint8 *, uint, uint8); -+uint16 crc16(uint8 *, uint, uint16); -+uint32 crc32(uint8 *, uint, uint32); ++/* PCI_INT_STATUS */ ++#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ + -+/* macros for common usage */ ++/* PCI_INT_MASK */ ++#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ ++#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ ++#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ + -+#define APPEND_CRC8(pbytes, nbytes) \ -+do { \ -+ uint8 tmp = crc8(pbytes, nbytes, CRC8_INIT_VALUE) ^ 0xff; \ -+ (pbytes)[(nbytes)] = tmp; \ -+ (nbytes) += 1; \ -+} while (0) ++/* PCI_SPROM_CONTROL */ ++#define SPROM_BLANK 0x04 /* indicating a blank sprom */ ++#define SPROM_WRITEEN 0x10 /* sprom write enable */ ++#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ + -+#define APPEND_CRC16(pbytes, nbytes) \ -+do { \ -+ uint16 tmp = crc16(pbytes, nbytes, CRC16_INIT_VALUE) ^ 0xffff; \ -+ (pbytes)[(nbytes) + 0] = (tmp >> 0) & 0xff; \ -+ (pbytes)[(nbytes) + 1] = (tmp >> 8) & 0xff; \ -+ (nbytes) += 2; \ -+} while (0) ++#define SPROM_SIZE 256 /* sprom size in 16-bit */ ++#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */ + -+#define APPEND_CRC32(pbytes, nbytes) \ -+do { \ -+ uint32 tmp = crc32(pbytes, nbytes, CRC32_INIT_VALUE) ^ 0xffffffff; \ -+ (pbytes)[(nbytes) + 0] = (tmp >> 0) & 0xff; \ -+ (pbytes)[(nbytes) + 1] = (tmp >> 8) & 0xff; \ -+ (pbytes)[(nbytes) + 2] = (tmp >> 16) & 0xff; \ -+ (pbytes)[(nbytes) + 3] = (tmp >> 24) & 0xff; \ -+ (nbytes) += 4; \ -+} while (0) ++/* PCI_CFG_CMD_STAT */ ++#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */ + -+#ifdef __cplusplus -+} +#endif -+ -+#endif /* _RTS_CRC_H_ */ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h --- linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h 2005-12-16 23:39:10.932836000 +0100 @@ -9367,1040 +6345,6 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h linux-2.4.32-brcm/a +#endif /* USE_TYPEDEF_DEFAULTS */ + +#endif /* _TYPEDEFS_H_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/wlioctl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/wlioctl.h ---- linux-2.4.32/arch/mips/bcm947xx/include/wlioctl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/wlioctl.h 2005-12-16 23:39:10.940836500 +0100 -@@ -0,0 +1,1030 @@ -+/* -+ * Custom OID/ioctl definitions for -+ * Broadcom 802.11abg Networking Device Driver -+ * -+ * Definitions subject to change without notice. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ -+ -+#ifndef _wlioctl_h_ -+#define _wlioctl_h_ -+ -+#include -+#include -+#include -+#include -+#include -+ -+/* require default structure packing */ -+#if !defined(__GNUC__) -+#pragma pack(push,8) -+#endif -+ -+#define WL_NUMRATES 255 /* max # of rates in a rateset */ -+ -+typedef struct wl_rateset { -+ uint32 count; /* # rates in this set */ -+ uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ -+} wl_rateset_t; -+ -+#define WL_CHANSPEC_CHAN_MASK 0x0fff -+#define WL_CHANSPEC_BAND_MASK 0xf000 -+#define WL_CHANSPEC_BAND_SHIFT 12 -+#define WL_CHANSPEC_BAND_A 0x1000 -+#define WL_CHANSPEC_BAND_B 0x2000 -+ -+/* -+ * Per-bss information structure. -+ */ -+ -+#define WL_BSS_INFO_VERSION 107 /* current version of wl_bss_info struct */ -+ -+typedef struct wl_bss_info { -+ uint32 version; /* version field */ -+ uint32 length; /* byte length of data in this record, starting at version and including IEs */ -+ struct ether_addr BSSID; -+ uint16 beacon_period; /* units are Kusec */ -+ uint16 capability; /* Capability information */ -+ uint8 SSID_len; -+ uint8 SSID[32]; -+ struct { -+ uint count; /* # rates in this set */ -+ uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ -+ } rateset; /* supported rates */ -+ uint8 channel; /* Channel no. */ -+ uint16 atim_window; /* units are Kusec */ -+ uint8 dtim_period; /* DTIM period */ -+ int16 RSSI; /* receive signal strength (in dBm) */ -+ int8 phy_noise; /* noise (in dBm) */ -+ uint32 ie_length; /* byte length of Information Elements */ -+ /* variable length Information Elements */ -+} wl_bss_info_t; -+ -+typedef struct wlc_ssid { -+ uint32 SSID_len; -+ uchar SSID[32]; -+} wlc_ssid_t; -+ -+typedef struct wl_scan_params { -+ wlc_ssid_t ssid; /* default is {0, ""} */ -+ struct ether_addr bssid;/* default is bcast */ -+ int8 bss_type; /* default is any, DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT */ -+ int8 scan_type; /* -1 use default, DOT11_SCANTYPE_ACTIVE/PASSIVE */ -+ int32 nprobes; /* -1 use default, number of probes per channel */ -+ int32 active_time; /* -1 use default, dwell time per channel for active scanning */ -+ int32 passive_time; /* -1 use default, dwell time per channel for passive scanning */ -+ int32 home_time; /* -1 use default, dwell time for the home channel between channel scans */ -+ int32 channel_num; /* 0 use default (all available channels), count of channels in channel_list */ -+ uint16 channel_list[1]; /* list of chanspecs */ -+} wl_scan_params_t; -+/* size of wl_scan_params not including variable length array */ -+#define WL_SCAN_PARAMS_FIXED_SIZE 64 -+ -+typedef struct wl_scan_results { -+ uint32 buflen; -+ uint32 version; -+ uint32 count; -+ wl_bss_info_t bss_info[1]; -+} wl_scan_results_t; -+/* size of wl_scan_results not including variable length array */ -+#define WL_SCAN_RESULTS_FIXED_SIZE 12 -+ -+/* uint32 list */ -+typedef struct wl_uint32_list { -+ /* in - # of elements, out - # of entries */ -+ uint32 count; -+ /* variable length uint32 list */ -+ uint32 element[1]; -+} wl_uint32_list_t; -+ -+#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NULL */ -+ -+typedef struct wl_channels_in_country { -+ uint32 buflen; -+ uint32 band; -+ char country_abbrev[WLC_CNTRY_BUF_SZ]; -+ uint32 count; -+ uint32 channel[1]; -+} wl_channels_in_country_t; -+ -+typedef struct wl_country_list { -+ uint32 buflen; -+ uint32 band_set; -+ uint32 band; -+ uint32 count; -+ char country_abbrev[1]; -+} wl_country_list_t; -+ -+#define WL_RM_TYPE_BASIC 1 -+#define WL_RM_TYPE_CCA 2 -+#define WL_RM_TYPE_RPI 3 -+ -+#define WL_RM_FLAG_PARALLEL (1<<0) -+ -+#define WL_RM_FLAG_LATE (1<<1) -+#define WL_RM_FLAG_INCAPABLE (1<<2) -+#define WL_RM_FLAG_REFUSED (1<<3) -+ -+typedef struct wl_rm_req_elt { -+ int8 type; -+ int8 flags; -+ uint16 chanspec; -+ uint32 token; /* token for this measurement */ -+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ -+ uint32 tsf_l; /* TSF low 32-bits */ -+ uint32 dur; /* TUs */ -+} wl_rm_req_elt_t; -+ -+typedef struct wl_rm_req { -+ uint32 token; /* overall measurement set token */ -+ uint32 count; /* number of measurement reqests */ -+ wl_rm_req_elt_t req[1]; /* variable length block of requests */ -+} wl_rm_req_t; -+#define WL_RM_REQ_FIXED_LEN 8 -+ -+typedef struct wl_rm_rep_elt { -+ int8 type; -+ int8 flags; -+ uint16 chanspec; -+ uint32 token; /* token for this measurement */ -+ uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ -+ uint32 tsf_l; /* TSF low 32-bits */ -+ uint32 dur; /* TUs */ -+ uint32 len; /* byte length of data block */ -+ uint8 data[1]; /* variable length data block */ -+} wl_rm_rep_elt_t; -+#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ -+ -+#define WL_RPI_REP_BIN_NUM 8 -+typedef struct wl_rm_rpi_rep { -+ uint8 rpi[WL_RPI_REP_BIN_NUM]; -+ int8 rpi_max[WL_RPI_REP_BIN_NUM]; -+} wl_rm_rpi_rep_t; -+ -+typedef struct wl_rm_rep { -+ uint32 token; /* overall measurement set token */ -+ uint32 len; /* length of measurement report block */ -+ wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ -+} wl_rm_rep_t; -+#define WL_RM_REP_FIXED_LEN 8 -+ -+ -+#if defined(BCMSUP_PSK) -+typedef enum sup_auth_status { -+ WLC_SUP_DISCONNECTED = 0, -+ WLC_SUP_CONNECTING, -+ WLC_SUP_IDREQUIRED, -+ WLC_SUP_AUTHENTICATING, -+ WLC_SUP_AUTHENTICATED, -+ WLC_SUP_KEYXCHANGE, -+ WLC_SUP_KEYED, -+ WLC_SUP_TIMEOUT -+} sup_auth_status_t; -+#endif /* BCMCCX | BCMSUP_PSK */ -+ -+/* Enumerate crypto algorithms */ -+#define CRYPTO_ALGO_OFF 0 -+#define CRYPTO_ALGO_WEP1 1 -+#define CRYPTO_ALGO_TKIP 2 -+#define CRYPTO_ALGO_WEP128 3 -+#define CRYPTO_ALGO_AES_CCM 4 -+#define CRYPTO_ALGO_AES_OCB_MSDU 5 -+#define CRYPTO_ALGO_AES_OCB_MPDU 6 -+#define CRYPTO_ALGO_NALG 7 -+ -+#define WSEC_GEN_MIC_ERROR 0x0001 -+#define WSEC_GEN_REPLAY 0x0002 -+ -+#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ -+#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -+#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ -+#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ -+ -+typedef struct wl_wsec_key { -+ uint32 index; /* key index */ -+ uint32 len; /* key length */ -+ uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */ -+ uint32 pad_1[18]; -+ uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ -+ uint32 flags; /* misc flags */ -+ uint32 pad_2[2]; -+ int pad_3; -+ int iv_initialized; /* has IV been initialized already? */ -+ int pad_4; -+ /* Rx IV */ -+ struct { -+ uint32 hi; /* upper 32 bits of IV */ -+ uint16 lo; /* lower 16 bits of IV */ -+ } rxiv; -+ uint32 pad_5[2]; -+ struct ether_addr ea; /* per station */ -+} wl_wsec_key_t; -+ -+ -+#define WSEC_MIN_PSK_LEN 8 -+#define WSEC_MAX_PSK_LEN 64 -+ -+/* Flag for key material needing passhash'ing */ -+#define WSEC_PASSPHRASE (1<<0) -+ -+/* recepticle for WLC_SET_WSEC_PMK parameter */ -+typedef struct { -+ ushort key_len; /* octets in key material */ -+ ushort flags; /* key handling qualification */ -+ uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ -+} wsec_pmk_t; -+ -+/* wireless security bitvec */ -+#define WEP_ENABLED 0x0001 -+#define TKIP_ENABLED 0x0002 -+#define AES_ENABLED 0x0004 -+#define WSEC_SWFLAG 0x0008 -+#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ -+ -+/* WPA authentication mode bitvec */ -+#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ -+#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ -+#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ -+#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ -+/*#define WPA_AUTH_8021X 0x0020*/ /* 802.1x, reserved */ -+ -+#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ -+#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ -+ -+ -+ -+/* pmkid */ -+#define MAXPMKID 16 -+ -+typedef struct _pmkid -+{ -+ struct ether_addr BSSID; -+ uint8 PMKID[WPA2_PMKID_LEN]; -+} pmkid_t; -+ -+typedef struct _pmkid_list -+{ -+ uint32 npmkid; -+ pmkid_t pmkid[1]; -+} pmkid_list_t; -+ -+typedef struct _pmkid_cand { -+ struct ether_addr BSSID; -+ uint8 preauth; -+} pmkid_cand_t; -+ -+typedef struct _pmkid_cand_list { -+ uint32 npmkid_cand; -+ pmkid_cand_t pmkid_cand[1]; -+} pmkid_cand_list_t; -+ -+ -+typedef struct wl_led_info { -+ uint32 index; /* led index */ -+ uint32 behavior; -+ bool activehi; -+} wl_led_info_t; -+ -+typedef struct wlc_assoc_info { -+ uint32 req_len; -+ uint32 resp_len; -+ uint32 flags; -+ struct dot11_assoc_req req; -+ struct ether_addr reassoc_bssid; /* used in reassoc's */ -+ struct dot11_assoc_resp resp; -+} wl_assoc_info_t; -+/* flags */ -+#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ -+/* srom read/write struct passed through ioctl */ -+typedef struct { -+ uint byteoff; /* byte offset */ -+ uint nbytes; /* number of bytes */ -+ uint16 buf[1]; -+} srom_rw_t; -+ -+/* R_REG and W_REG struct passed through ioctl */ -+typedef struct { -+ uint32 byteoff; /* byte offset of the field in d11regs_t */ -+ uint32 val; /* read/write value of the field */ -+ uint32 size; /* sizeof the field */ -+ uint band; /* band (optional) */ -+} rw_reg_t; -+ -+/* Structure used by GET/SET_ATTEN ioctls */ -+typedef struct { -+ uint16 auto_ctrl; /* 1: Automatic control, 0: overriden */ -+ uint16 bb; /* Baseband attenuation */ -+ uint16 radio; /* Radio attenuation */ -+ uint16 txctl1; /* Radio TX_CTL1 value */ -+} atten_t; -+ -+/* Used to get specific STA parameters */ -+typedef struct { -+ uint32 val; -+ struct ether_addr ea; -+} scb_val_t; -+ -+ -+/* Event data type */ -+typedef struct wlc_event { -+ wl_event_msg_t event; /* encapsulated event */ -+ struct ether_addr *addr; /* used to keep a trace of the potential present of -+ an address in wlc_event_msg_t */ -+ void *data; /* used to hang additional data on an event */ -+ struct wlc_event *next; /* enables ordered list of pending events */ -+} wlc_event_t; -+ -+#define BCM_MAC_STATUS_INDICATION (0x40010200L) -+ -+typedef struct { -+ uint16 ver; /* version of this struct */ -+ uint16 len; /* length in bytes of this structure */ -+ uint16 cap; /* sta's advertized capabilities */ -+ uint32 flags; /* flags defined below */ -+ uint32 idle; /* time since data pkt rx'd from sta */ -+ struct ether_addr ea; /* Station address */ -+ wl_rateset_t rateset; /* rateset in use */ -+ uint32 in; /* seconds elapsed since associated */ -+ uint32 listen_interval_inms; /* Min Listen interval in ms for this STA*/ -+} sta_info_t; -+ -+#define WL_STA_VER 2 -+ -+/* flags fields */ -+#define WL_STA_BRCM 0x01 -+#define WL_STA_WME 0x02 -+#define WL_STA_ABCAP 0x04 -+#define WL_STA_AUTHE 0x08 -+#define WL_STA_ASSOC 0x10 -+#define WL_STA_AUTHO 0x20 -+#define WL_STA_WDS 0x40 -+#define WL_WDS_LINKUP 0x80 -+ -+ -+/* -+ * Country locale determines which channels are available to us. -+ */ -+typedef enum _wlc_locale { -+ WLC_WW = 0, /* Worldwide */ -+ WLC_THA, /* Thailand */ -+ WLC_ISR, /* Israel */ -+ WLC_JDN, /* Jordan */ -+ WLC_PRC, /* China */ -+ WLC_JPN, /* Japan */ -+ WLC_FCC, /* USA */ -+ WLC_EUR, /* Europe */ -+ WLC_USL, /* US Low Band only */ -+ WLC_JPH, /* Japan High Band only */ -+ WLC_ALL, /* All the channels in this band */ -+ WLC_11D, /* Represents locale recieved by 11d beacons */ -+ WLC_LAST_LOCALE, -+ WLC_UNDEFINED_LOCALE = 0xf -+} wlc_locale_t; -+ -+/* channel encoding */ -+typedef struct channel_info { -+ int hw_channel; -+ int target_channel; -+ int scan_channel; -+} channel_info_t; -+ -+/* For ioctls that take a list of MAC addresses */ -+struct maclist { -+ uint count; /* number of MAC addresses */ -+ struct ether_addr ea[1]; /* variable length array of MAC addresses */ -+}; -+ -+/* get pkt count struct passed through ioctl */ -+typedef struct get_pktcnt { -+ uint rx_good_pkt; -+ uint rx_bad_pkt; -+ uint tx_good_pkt; -+ uint tx_bad_pkt; -+} get_pktcnt_t; -+ -+/* Linux network driver ioctl encoding */ -+typedef struct wl_ioctl { -+ uint cmd; /* common ioctl definition */ -+ void *buf; /* pointer to user buffer */ -+ uint len; /* length of user buffer */ -+ bool set; /* get or set request (optional) */ -+ uint used; /* bytes read or written (optional) */ -+ uint needed; /* bytes needed (optional) */ -+} wl_ioctl_t; -+ -+/* -+ * Structure for passing hardware and software -+ * revision info up from the driver. -+ */ -+typedef struct wlc_rev_info { -+ uint vendorid; /* PCI vendor id */ -+ uint deviceid; /* device id of chip */ -+ uint radiorev; /* radio revision */ -+ uint chiprev; /* chip revision */ -+ uint corerev; /* core revision */ -+ uint boardid; /* board identifier (usu. PCI sub-device id) */ -+ uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ -+ uint boardrev; /* board revision */ -+ uint driverrev; /* driver version */ -+ uint ucoderev; /* microcode version */ -+ uint bus; /* bus type */ -+ uint chipnum; /* chip number */ -+} wlc_rev_info_t; -+ -+#define WL_BRAND_MAX 10 -+typedef struct wl_instance_info { -+ uint instance; -+ char brand[WL_BRAND_MAX]; -+} wl_instance_info_t; -+ -+/* check this magic number */ -+#define WLC_IOCTL_MAGIC 0x14e46c77 -+ -+/* bump this number if you change the ioctl interface */ -+#define WLC_IOCTL_VERSION 1 -+ -+#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -+#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ -+ -+/* common ioctl definitions */ -+#define WLC_GET_MAGIC 0 -+#define WLC_GET_VERSION 1 -+#define WLC_UP 2 -+#define WLC_DOWN 3 -+#define WLC_DUMP 6 -+#define WLC_GET_MSGLEVEL 7 -+#define WLC_SET_MSGLEVEL 8 -+#define WLC_GET_PROMISC 9 -+#define WLC_SET_PROMISC 10 -+#define WLC_GET_RATE 12 -+/* #define WLC_SET_RATE 13 */ /* no longer supported */ -+#define WLC_GET_INSTANCE 14 -+/* #define WLC_GET_FRAG 15 */ /* no longer supported */ -+/* #define WLC_SET_FRAG 16 */ /* no longer supported */ -+/* #define WLC_GET_RTS 17 */ /* no longer supported */ -+/* #define WLC_SET_RTS 18 */ /* no longer supported */ -+#define WLC_GET_INFRA 19 -+#define WLC_SET_INFRA 20 -+#define WLC_GET_AUTH 21 -+#define WLC_SET_AUTH 22 -+#define WLC_GET_BSSID 23 -+#define WLC_SET_BSSID 24 -+#define WLC_GET_SSID 25 -+#define WLC_SET_SSID 26 -+#define WLC_RESTART 27 -+#define WLC_GET_CHANNEL 29 -+#define WLC_SET_CHANNEL 30 -+#define WLC_GET_SRL 31 -+#define WLC_SET_SRL 32 -+#define WLC_GET_LRL 33 -+#define WLC_SET_LRL 34 -+#define WLC_GET_PLCPHDR 35 -+#define WLC_SET_PLCPHDR 36 -+#define WLC_GET_RADIO 37 -+#define WLC_SET_RADIO 38 -+#define WLC_GET_PHYTYPE 39 -+/* #define WLC_GET_WEP 42 */ /* no longer supported */ -+/* #define WLC_SET_WEP 43 */ /* no longer supported */ -+#define WLC_GET_KEY 44 -+#define WLC_SET_KEY 45 -+#define WLC_GET_REGULATORY 46 -+#define WLC_SET_REGULATORY 47 -+#define WLC_SCAN 50 -+#define WLC_SCAN_RESULTS 51 -+#define WLC_DISASSOC 52 -+#define WLC_REASSOC 53 -+#define WLC_GET_ROAM_TRIGGER 54 -+#define WLC_SET_ROAM_TRIGGER 55 -+#define WLC_GET_TXANT 61 -+#define WLC_SET_TXANT 62 -+#define WLC_GET_ANTDIV 63 -+#define WLC_SET_ANTDIV 64 -+/* #define WLC_GET_TXPWR 65 */ /* no longer supported */ -+/* #define WLC_SET_TXPWR 66 */ /* no longer supported */ -+#define WLC_GET_CLOSED 67 -+#define WLC_SET_CLOSED 68 -+#define WLC_GET_MACLIST 69 -+#define WLC_SET_MACLIST 70 -+#define WLC_GET_RATESET 71 -+#define WLC_SET_RATESET 72 -+#define WLC_GET_LOCALE 73 -+#define WLC_LONGTRAIN 74 -+#define WLC_GET_BCNPRD 75 -+#define WLC_SET_BCNPRD 76 -+#define WLC_GET_DTIMPRD 77 -+#define WLC_SET_DTIMPRD 78 -+#define WLC_GET_SROM 79 -+#define WLC_SET_SROM 80 -+#define WLC_GET_WEP_RESTRICT 81 -+#define WLC_SET_WEP_RESTRICT 82 -+#define WLC_GET_COUNTRY 83 -+#define WLC_SET_COUNTRY 84 -+#define WLC_GET_REVINFO 98 -+#define WLC_GET_MACMODE 105 -+#define WLC_SET_MACMODE 106 -+#define WLC_GET_GMODE 109 -+#define WLC_SET_GMODE 110 -+#define WLC_GET_CURR_RATESET 114 /* current rateset */ -+#define WLC_GET_SCANSUPPRESS 115 -+#define WLC_SET_SCANSUPPRESS 116 -+#define WLC_GET_AP 117 -+#define WLC_SET_AP 118 -+#define WLC_GET_EAP_RESTRICT 119 -+#define WLC_SET_EAP_RESTRICT 120 -+#define WLC_GET_WDSLIST 123 -+#define WLC_SET_WDSLIST 124 -+#define WLC_GET_RSSI 127 -+#define WLC_GET_WSEC 133 -+#define WLC_SET_WSEC 134 -+#define WLC_GET_BSS_INFO 136 -+#define WLC_GET_LAZYWDS 138 -+#define WLC_SET_LAZYWDS 139 -+#define WLC_GET_BANDLIST 140 -+#define WLC_GET_BAND 141 -+#define WLC_SET_BAND 142 -+#define WLC_GET_SHORTSLOT 144 -+#define WLC_GET_SHORTSLOT_OVERRIDE 145 -+#define WLC_SET_SHORTSLOT_OVERRIDE 146 -+#define WLC_GET_SHORTSLOT_RESTRICT 147 -+#define WLC_SET_SHORTSLOT_RESTRICT 148 -+#define WLC_GET_GMODE_PROTECTION 149 -+#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 -+#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 -+#define WLC_UPGRADE 152 -+/* #define WLC_GET_MRATE 153 */ /* no longer supported */ -+/* #define WLC_SET_MRATE 154 */ /* no longer supported */ -+#define WLC_GET_ASSOCLIST 159 -+#define WLC_GET_CLK 160 -+#define WLC_SET_CLK 161 -+#define WLC_GET_UP 162 -+#define WLC_OUT 163 -+#define WLC_GET_WPA_AUTH 164 -+#define WLC_SET_WPA_AUTH 165 -+#define WLC_GET_GMODE_PROTECTION_CONTROL 178 -+#define WLC_SET_GMODE_PROTECTION_CONTROL 179 -+#define WLC_GET_PHYLIST 180 -+#define WLC_GET_KEY_SEQ 183 -+#define WLC_GET_GMODE_PROTECTION_CTS 198 -+#define WLC_SET_GMODE_PROTECTION_CTS 199 -+#define WLC_GET_PIOMODE 203 -+#define WLC_SET_PIOMODE 204 -+#define WLC_SET_LED 209 -+#define WLC_GET_LED 210 -+#define WLC_GET_CHANNEL_SEL 215 -+#define WLC_START_CHANNEL_SEL 216 -+#define WLC_GET_VALID_CHANNELS 217 -+#define WLC_GET_FAKEFRAG 218 -+#define WLC_SET_FAKEFRAG 219 -+#define WLC_GET_WET 230 -+#define WLC_SET_WET 231 -+#define WLC_GET_KEY_PRIMARY 235 -+#define WLC_SET_KEY_PRIMARY 236 -+#define WLC_GET_RADAR 242 -+#define WLC_SET_RADAR 243 -+#define WLC_SET_SPECT_MANAGMENT 244 -+#define WLC_GET_SPECT_MANAGMENT 245 -+#define WLC_WDS_GET_REMOTE_HWADDR 246 /* currently handled in wl_linux.c/wl_vx.c */ -+#define WLC_SET_CS_SCAN_TIMER 248 -+#define WLC_GET_CS_SCAN_TIMER 249 -+#define WLC_SEND_PWR_CONSTRAINT 254 -+#define WLC_CURRENT_PWR 256 -+#define WLC_GET_CHANNELS_IN_COUNTRY 260 -+#define WLC_GET_COUNTRY_LIST 261 -+#define WLC_GET_VAR 262 /* get value of named variable */ -+#define WLC_SET_VAR 263 /* set named variable to value */ -+#define WLC_NVRAM_GET 264 -+#define WLC_NVRAM_SET 265 -+#define WLC_SET_WSEC_PMK 268 -+#define WLC_GET_AUTH_MODE 269 -+#define WLC_SET_AUTH_MODE 270 -+#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ -+#define WLC_NVOTPW 274 -+/* #define WLC_OTPW 275 */ /* no longer supported */ -+#define WLC_SET_LOCALE 278 -+#define WLC_LAST 279 /* do not change - use get_var/set_var */ -+ -+/* -+ * Minor kludge alert: -+ * Duplicate a few definitions that irelay requires from epiioctl.h here -+ * so caller doesn't have to include this file and epiioctl.h . -+ * If this grows any more, it would be time to move these irelay-specific -+ * definitions out of the epiioctl.h and into a separate driver common file. -+ */ -+#ifndef EPICTRL_COOKIE -+#define EPICTRL_COOKIE 0xABADCEDE -+#endif -+ -+/* vx wlc ioctl's offset */ -+#define CMN_IOCTL_OFF 0x180 -+ -+/* -+ * custom OID support -+ * -+ * 0xFF - implementation specific OID -+ * 0xE4 - first byte of Broadcom PCI vendor ID -+ * 0x14 - second byte of Broadcom PCI vendor ID -+ * 0xXX - the custom OID number -+ */ -+ -+/* begin 0x1f values beyond the start of the ET driver range. */ -+#define WL_OID_BASE 0xFFE41420 -+ -+/* NDIS overrides */ -+#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) -+#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) -+ -+#define WL_DECRYPT_STATUS_SUCCESS 1 -+#define WL_DECRYPT_STATUS_FAILURE 2 -+#define WL_DECRYPT_STATUS_UNKNOWN 3 -+ -+/* allows user-mode app to poll the status of USB image upgrade */ -+#define WLC_UPGRADE_SUCCESS 0 -+#define WLC_UPGRADE_PENDING 1 -+ -+#ifdef CONFIG_USBRNDIS_RETAIL -+/* struct passed in for WLC_NDCONFIG_ITEM */ -+typedef struct { -+ char *name; -+ void *param; -+} ndconfig_item_t; -+#endif -+ -+/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ -+#define WL_RADIO_SW_DISABLE (1<<0) -+#define WL_RADIO_HW_DISABLE (1<<1) -+#define WL_RADIO_MPC_DISABLE (1<<2) -+#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any 802.11 channel */ -+ -+/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ -+#define WL_TXPWR_OVERRIDE (1<<31) -+ -+/* "diag" iovar argument and error code */ -+#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ -+#define WL_DIAG_MEMORY 3 /* d11 memory test */ -+#define WL_DIAG_LED 4 /* LED test */ -+#define WL_DIAG_REG 5 /* d11/phy register test */ -+#define WL_DIAG_SROM 6 /* srom read/crc test */ -+#define WL_DIAG_DMA 7 /* DMA test */ -+ -+#define WL_DIAGERR_SUCCESS 0 -+#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ -+#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ -+#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ -+#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ -+#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ -+#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ -+#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ -+#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ -+#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ -+#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ -+ -+/* Bus types */ -+#define WL_SB_BUS 0 /* Silicon Backplane */ -+#define WL_PCI_BUS 1 /* PCI target */ -+#define WL_PCMCIA_BUS 2 /* PCMCIA target */ -+ -+/* band types */ -+#define WLC_BAND_AUTO 0 /* auto-select */ -+#define WLC_BAND_A 1 /* "a" band (5 Ghz) */ -+#define WLC_BAND_B 2 /* "b" band (2.4 Ghz) */ -+#define WLC_BAND_ALL 3 /* all bands */ -+ -+/* phy types (returned by WLC_GET_PHYTPE) */ -+#define WLC_PHY_TYPE_A 0 -+#define WLC_PHY_TYPE_B 1 -+#define WLC_PHY_TYPE_G 2 -+#define WLC_PHY_TYPE_NULL 0xf -+ -+/* MAC list modes */ -+#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ -+#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ -+#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ -+ -+/* -+ * -+ */ -+#define GMODE_LEGACY_B 0 -+#define GMODE_AUTO 1 -+#define GMODE_ONLY 2 -+#define GMODE_B_DEFERRED 3 -+#define GMODE_PERFORMANCE 4 -+#define GMODE_LRS 5 -+#define GMODE_MAX 6 -+ -+/* values for PLCPHdr_override */ -+#define WLC_PLCP_AUTO -1 -+#define WLC_PLCP_SHORT 0 -+#define WLC_PLCP_LONG 1 -+ -+/* values for g_protection_override */ -+#define WLC_G_PROTECTION_AUTO -1 -+#define WLC_G_PROTECTION_OFF 0 -+#define WLC_G_PROTECTION_ON 1 -+ -+/* values for g_protection_control */ -+#define WLC_G_PROTECTION_CTL_OFF 0 -+#define WLC_G_PROTECTION_CTL_LOCAL 1 -+#define WLC_G_PROTECTION_CTL_OVERLAP 2 -+ -+/* Values for PM */ -+#define PM_OFF 0 -+#define PM_MAX 1 -+#define PM_FAST 2 -+ -+ -+ -+typedef struct { -+ int npulses; /* required number of pulses at n * t_int */ -+ int ncontig; /* required number of pulses at t_int */ -+ int min_pw; /* minimum pulse width (20 MHz clocks) */ -+ int max_pw; /* maximum pulse width (20 MHz clocks) */ -+ uint16 thresh0; /* Radar detection, thresh 0 */ -+ uint16 thresh1; /* Radar detection, thresh 1 */ -+} wl_radar_args_t; -+ -+/* radar iovar SET defines */ -+#define WL_RADRA_DETECTOR_OFF 0 /* radar dector off */ -+#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */ -+#define WL_RADAR_SIMULATED 2 /* force radar detector to declare detection once */ -+ -+/* dfs_status iovar-related defines */ -+ -+/* cac - channel availability check, -+ * ism - in-service monitoring -+ * csa - channel switching anouncement -+ */ -+ -+/* cac state values */ -+#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */ -+#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */ -+#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */ -+#define WL_DFS_CACSTATE_CSA 3 /* csa */ -+#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */ -+#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */ -+#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */ -+#define WL_DFS_CACSTATES 7 /* this many states exist */ -+ -+/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */ -+typedef struct { -+ uint state; /* noted by WL_DFS_CACSTATE_XX. */ -+ uint duration; /* time spent in ms in state. */ -+ /* as dfs enters ISM state, it removes the operational channel from quiet channel list -+ * and notes the channel in channel_cleared. set to 0 if no channel is cleared -+ */ -+ uint channel_cleared; -+} wl_dfs_status_t; -+ -+#define NUM_PWRCTRL_RATES 12 -+ -+ -+/* 802.11h enforcement levels */ -+#define SPECT_MNGMT_OFF 0 /* 11h disabled */ -+#define SPECT_MNGMT_LOOSE 1 /* allow scan lists to contain non-11h AP */ -+#define SPECT_MNGMT_STRICT 2 /* prune out non-11h APs from scan list */ -+#define SPECT_MNGMT_11D 3 /* switch to 802.11D mode */ -+ -+#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ -+#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */ -+#define WL_CHAN_BAND_A (1 << 2) /* A-band channel */ -+#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ -+#define WL_CHAN_INACTIVE (1 << 4) /* temporarily out of service due to radar */ -+#define WL_CHAN_RADAR_PASSIVE (1 << 5) /* radar channel is in passive mode */ -+ -+#define WL_MPC_VAL 0x00400000 -+#define WL_APSTA_VAL 0x00800000 -+#define WL_DFS_VAL 0x01000000 -+ -+/* max # of leds supported by GPIO (gpio pin# == led index#) */ -+#define WL_LED_NUMGPIO 16 /* gpio 0-15 */ -+ -+/* led per-pin behaviors */ -+#define WL_LED_OFF 0 /* always off */ -+#define WL_LED_ON 1 /* always on */ -+#define WL_LED_ACTIVITY 2 /* activity */ -+#define WL_LED_RADIO 3 /* radio enabled */ -+#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */ -+#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */ -+#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */ -+#define WL_LED_WI1 7 -+#define WL_LED_WI2 8 -+#define WL_LED_WI3 9 -+#define WL_LED_ASSOC 10 /* associated state indicator */ -+#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */ -+#define WL_LED_NUMBEHAVIOR 12 -+ -+/* led behavior numeric value format */ -+#define WL_LED_BEH_MASK 0x7f /* behavior mask */ -+#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */ -+ -+ -+/* WDS link local endpoint WPA role */ -+#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */ -+#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */ -+#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */ -+ -+/* number of bytes needed to define a 128-bit mask for MAC event reporting */ -+#define WL_EVENTING_MASK_LEN 16 -+ -+/* Structures and constants used for "vndr_ie" IOVar interface */ -+#define VNDR_IE_CMD_LEN 4 /* length of the set command string: "add", "del" (+ NULL) */ -+ -+/* 802.11 Mgmt Packet flags */ -+#define VNDR_IE_BEACON_FLAG 0x1 -+#define VNDR_IE_PRBRSP_FLAG 0x2 -+#define VNDR_IE_ASSOCRSP_FLAG 0x4 -+#define VNDR_IE_AUTHRSP_FLAG 0x8 -+ -+typedef struct { -+ uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ -+ vndr_ie_t vndr_ie_data; /* vendor IE data */ -+} vndr_ie_info_t; -+ -+typedef struct { -+ int iecount; /* number of entries in the vndr_ie_list[] array */ -+ vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */ -+} vndr_ie_buf_t; -+ -+typedef struct { -+ char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NULL */ -+ vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */ -+} vndr_ie_setbuf_t; -+ -+/* join target preference types */ -+#define WL_JOIN_PREF_RSSI 1 /* by RSSI, mandatory */ -+#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers, optional, RSN and WPA as values */ -+#define WL_JOIN_PREF_BAND 3 /* by 802.11 band, optional, WLC_BAND_XXXX as values */ -+ -+/* band preference */ -+#define WLJP_BAND_ASSOC_PREF 255 /* use assoc preference settings */ -+ /* others use WLC_BAND_XXXX as values */ -+ -+/* any multicast cipher suite */ -+#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" -+ -+#if !defined(__GNUC__) -+#pragma pack(pop) -+#endif -+ -+#define NFIFO 6 /* # tx/rx fifopairs */ -+ -+#define WL_CNT_T_VERSION 1 /* current version of wl_cnt_t struct */ -+ -+typedef struct { -+ uint16 version; /* see definition of WL_CNT_T_VERSION */ -+ uint16 length; /* length of entire structure */ -+ -+ /* transmit stat counters */ -+ uint32 txframe; /* tx data frames */ -+ uint32 txbyte; /* tx data bytes */ -+ uint32 txretrans; /* tx mac retransmits */ -+ uint32 txerror; /* tx data errors */ -+ uint32 txctl; /* tx management frames */ -+ uint32 txprshort; /* tx short preamble frames */ -+ uint32 txserr; /* tx status errors */ -+ uint32 txnobuf; /* tx out of buffers errors */ -+ uint32 txnoassoc; /* tx discard because we're not associated */ -+ uint32 txrunt; /* tx runt frames */ -+ uint32 txchit; /* tx header cache hit (fastpath) */ -+ uint32 txcmiss; /* tx header cache miss (slowpath) */ -+ -+ /* transmit chip error counters */ -+ uint32 txuflo; /* tx fifo underflows */ -+ uint32 txphyerr; /* tx phy errors (indicated in tx status) */ -+ uint32 txphycrs; -+ -+ /* receive stat counters */ -+ uint32 rxframe; /* rx data frames */ -+ uint32 rxbyte; /* rx data bytes */ -+ uint32 rxerror; /* rx data errors */ -+ uint32 rxctl; /* rx management frames */ -+ uint32 rxnobuf; /* rx out of buffers errors */ -+ uint32 rxnondata; /* rx non data frames in the data channel errors */ -+ uint32 rxbadds; /* rx bad DS errors */ -+ uint32 rxbadcm; /* rx bad control or management frames */ -+ uint32 rxfragerr; /* rx fragmentation errors */ -+ uint32 rxrunt; /* rx runt frames */ -+ uint32 rxgiant; /* rx giant frames */ -+ uint32 rxnoscb; /* rx no scb error */ -+ uint32 rxbadproto; /* rx invalid frames */ -+ uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac*/ -+ uint32 rxbadda; /* rx frames tossed for invalid da */ -+ uint32 rxfilter; /* rx frames filtered out */ -+ -+ /* receive chip error counters */ -+ uint32 rxoflo; /* rx fifo overflow errors */ -+ uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ -+ -+ uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ -+ uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ -+ uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ -+ -+ /* misc counters */ -+ uint32 dmade; /* tx/rx dma descriptor errors */ -+ uint32 dmada; /* tx/rx dma data errors */ -+ uint32 dmape; /* tx/rx dma descriptor protocol errors */ -+ uint32 reset; /* reset count */ -+ uint32 tbtt; /* cnts the TBTT int's */ -+ uint32 txdmawar; -+ -+ /* MAC counters: 32-bit version of d11.h's macstat_t */ -+ uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, -+ Control Management (includes retransmissions) */ -+ uint32 txrtsfrm; /* number of RTS sent out by the MAC */ -+ uint32 txctsfrm; /* number of CTS sent out by the MAC */ -+ uint32 txackfrm; /* number of ACK frames sent out */ -+ uint32 txdnlfrm; /* Not used */ -+ uint32 txbcnfrm; /* beacons transmitted */ -+ uint32 txfunfl[8]; /* per-fifo tx underflows */ -+ uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS or BCN) */ -+ uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for -+ driver enqueued frames*/ -+ uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ -+ uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ -+ uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not -+ data/control/management*/ -+ uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ -+ uint32 rxbadplcp; /* parity check of the PLCP header failed */ -+ uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ -+ uint32 rxstrt; /* Number of received frames with a good PLCP (i.e. passing parity check) */ -+ uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ -+ uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ -+ uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ -+ uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ -+ uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS)*/ -+ uint32 rxackucast; /* number of ucast ACKS received (good FCS)*/ -+ uint32 rxdfrmocast; /* number of received DATA frames with good FCS and not matching RA */ -+ uint32 rxmfrmocast; /* number of received MGMT frames with good FCS and not matching RA */ -+ uint32 rxcfrmocast; /* number of received CNTRL frame with good FCS and not matching RA */ -+ uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ -+ uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ -+ uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ -+ uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ -+ uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC (unlikely -+ to see these) */ -+ uint32 rxbeaconmbss; /* beacons received from member of BSS */ -+ uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from other BSS (WDS FRAME) */ -+ uint32 rxbeaconobss; /* beacons received from other BSS */ -+ uint32 rxrsptmout; /* Number of response timeouts for transmitted frames expecting a -+ response */ -+ uint32 bcntxcancl; /* transmit beacons cancelled due to receipt of beacon (IBSS) */ -+ uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ -+ uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ -+ uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ -+ uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ -+ uint32 pmqovfl; /* Number of PMQ overflows */ -+ uint32 rxcgprqfrm; /* Number of received Probe requests that made it into the PRQ fifo */ -+ uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ -+ uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did not get ACK */ -+ uint32 txcgprssuc; /* Tx Probe Rresponse Success (ACK was received) */ -+ uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ fifo because -+ a probe response could not be sent out within the time limit defined -+ in M_PRS_MAXTIME */ -+ uint32 rxnack; /* Number of NACKS received (Afterburner) */ -+ uint32 frmscons; /* Number of frames completed without transmission because of an -+ Afterburner re-queue */ -+ uint32 txnack; /* Number of NACKs transmtitted (Afterburner) */ -+ uint32 txglitch_nack; /* obsolete */ -+ uint32 txburst; /* obsolete */ -+ uint32 rxburst; /* obsolete */ -+ -+ /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ -+ uint32 txfrag; /* dot11TransmittedFragmentCount */ -+ uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ -+ uint32 txfail; /* dot11FailedCount */ -+ uint32 txretry; /* dot11RetryCount */ -+ uint32 txretrie; /* dot11MultipleRetryCount */ -+ uint32 rxdup; /* dot11FrameduplicateCount */ -+ uint32 txrts; /* dot11RTSSuccessCount */ -+ uint32 txnocts; /* dot11RTSFailureCount */ -+ uint32 txnoack; /* dot11ACKFailureCount */ -+ uint32 rxfrag; /* dot11ReceivedFragmentCount */ -+ uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ -+ uint32 rxcrc; /* dot11FCSErrorCount */ -+ uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ -+ uint32 rxundec; /* dot11WEPUndecryptableCount */ -+ -+ /* WPA2 counters (see rxundec for DecryptFailureCount) */ -+ uint32 tkipmicfaill; /* TKIPLocalMICFailures */ -+ uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ -+ uint32 tkipreplay; /* TKIPReplays */ -+ uint32 ccmpfmterr; /* CCMPFormatErrors */ -+ uint32 ccmpreplay; /* CCMPReplays */ -+ uint32 ccmpundec; /* CCMPDecryptErrors */ -+ uint32 fourwayfail; /* FourWayHandshakeFailures */ -+ uint32 wepundec; /* dot11WEPUndecryptableCount */ -+ uint32 wepicverr; /* dot11WEPICVErrorCount */ -+ uint32 decsuccess; /* DecryptSuccessCount */ -+ uint32 tkipicverr; /* TKIPICVErrorCount */ -+ uint32 wepexcluded; /* dot11WEPExcludedCount */ -+} wl_cnt_t; -+ -+#endif /* _wlioctl_h_ */ diff -Nur linux-2.4.32/arch/mips/bcm947xx/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile --- linux-2.4.32/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile 2005-12-19 01:56:51.733868750 +0100 @@ -14676,7 +10620,7 @@ diff -Nur linux-2.4.32/drivers/net/Config.in linux-2.4.32-brcm/drivers/net/Confi diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c --- linux-2.4.32/drivers/net/hnd/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c 2005-12-16 23:39:11.284858000 +0100 -@@ -0,0 +1,936 @@ +@@ -0,0 +1,938 @@ +/* + * Misc useful routines to access NIC SROM/OTP . + * @@ -14701,7 +10645,9 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/h +#include +#include + -+#include /* for sprom content groking */ ++struct ether_addr { ++ uint8 octet[6]; ++} PACKED; + +#define VARS_MAX 4096 /* should be reduced */ + @@ -14895,7 +10841,7 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/h + + case CISTPL_FUNCE: + if (cis[i] == LAN_NID) { -+ ASSERT(cis[i + 1] == ETHER_ADDR_LEN); ++ ASSERT(cis[i + 1] == 6); + bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf); + vp += sprintf(vp, "il0macaddr=%s", eabuf); + vp++; @@ -15414,7 +11360,7 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/h + ea.octet[3] = b[woff+1] & 0xff; + ea.octet[4] = (b[woff+2] >> 8) & 0xff; + ea.octet[5] = b[woff+2] & 0xff; -+ woff += ETHER_ADDR_LEN/2 ; ++ woff += 3; + bcm_ether_ntoa((uchar*)&ea, eabuf); + vp += sprintf(vp, "il0macaddr=%s", eabuf); + vp++; @@ -15426,7 +11372,7 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/h + ea.octet[3] = b[woff+1] & 0xff; + ea.octet[4] = (b[woff+2] >> 8) & 0xff; + ea.octet[5] = b[woff+2] & 0xff; -+ woff += ETHER_ADDR_LEN/2 ; ++ woff += 3; + bcm_ether_ntoa((uchar*)&ea, eabuf); + vp += sprintf(vp, "et0macaddr=%s", eabuf); + vp++; @@ -15438,7 +11384,7 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/h + ea.octet[3] = b[woff+1] & 0xff; + ea.octet[4] = (b[woff+2] >> 8) & 0xff; + ea.octet[5] = b[woff+2] & 0xff; -+ woff += ETHER_ADDR_LEN/2 ; ++ woff += 3; + bcm_ether_ntoa((uchar*)&ea, eabuf); + vp += sprintf(vp, "et1macaddr=%s", eabuf); + vp++; -- cgit v1.2.3 From 6ecb6bdbed9e35706c2f584fab7675aaa32b8d34 Mon Sep 17 00:00:00 2001 From: nbd Date: Thu, 6 Apr 2006 15:52:01 +0000 Subject: integrate the newer broadcom wl driver from us robotics git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@3596 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/brcm-2.4/Makefile | 11 +- target/linux/brcm-2.4/config | 1 + target/linux/brcm-2.4/patches/001-bcm47xx.patch | 13649 +++++++++++++--------- 3 files changed, 8013 insertions(+), 5648 deletions(-) (limited to 'target/linux/brcm-2.4/patches/001-bcm47xx.patch') diff --git a/target/linux/brcm-2.4/Makefile b/target/linux/brcm-2.4/Makefile index ab68b7ae88..17473be323 100644 --- a/target/linux/brcm-2.4/Makefile +++ b/target/linux/brcm-2.4/Makefile @@ -13,7 +13,7 @@ $(eval $(call KMOD_template,BRCM_WL,brcm-wl,\ ,CONFIG_WL,,20,wl)) $(eval $(call KMOD_template,BRCM_WL2,brcm-wl2,\ - $(BUILD_DIR)/wl/wl2/wl.o \ + $(MODULES_DIR)/kernel/drivers/net/wl2/wl.o \ ,CONFIG_WL,,20,wl)) $(eval $(call KMOD_template,LP,lp,\ @@ -40,8 +40,8 @@ $(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked LINUX_BINARY_DRIVER_SITE=http://openwrt.org/downloads/sources # proprietary driver, extracted from Linksys GPL sourcetree WRT54GS 4.70.6 -LINUX_BINARY_WL_DRIVER=kernel-binary-wl-0.5.tar.gz -LINUX_BINARY_WL_MD5SUM=78e839842bdc04022bb44469f92b1131 +LINUX_BINARY_WL_DRIVER=kernel-binary-wl-0.6.tar.gz +LINUX_BINARY_WL_MD5SUM=4fc1d5b46bcb7a17d6d5dd31da9c8d7f $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER): $(SCRIPT_DIR)/download.pl $(DL_DIR) $(LINUX_BINARY_WL_DRIVER) $(LINUX_BINARY_WL_MD5SUM) $(LINUX_BINARY_DRIVER_SITE) $(MAKE_TRACE) @@ -56,12 +56,15 @@ $(LINUX_DIR)/.drivers-unpacked: $(LINUX_DIR)/.unpacked zcat $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) - # copy binary wlan driver mkdir -p $(LINUX_DIR)/drivers/net/wl - $(CP) $(BUILD_DIR)/wl/*.o $(LINUX_DIR)/drivers/net/wl + $(CP) $(BUILD_DIR)/kernel-binary-wl/old/*.o $(LINUX_DIR)/drivers/net/wl + $(CP) $(BUILD_DIR)/kernel-binary-wl/new/*.o $(LINUX_DIR)/drivers/net/wl2 touch $@ $(LINUX_DIR)/.drivers-installed: $(LINUX_DIR)/.modules_done mkdir -p $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl + mkdir -p $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl2 @-[ -f $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/wl.o ] || $(CP) $(LINUX_DIR)/drivers/net/wl/wl.o $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/ + @-[ -f $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl2/wl.o ] || $(CP) $(LINUX_DIR)/drivers/net/wl2/wl.o $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl2/ touch $@ linux-dirclean: drivers-clean diff --git a/target/linux/brcm-2.4/config b/target/linux/brcm-2.4/config index c4cf5340ea..9759b90f5f 100644 --- a/target/linux/brcm-2.4/config +++ b/target/linux/brcm-2.4/config @@ -833,6 +833,7 @@ CONFIG_NET_RADIO=y # CONFIG_AIRO is not set # CONFIG_HERMES is not set CONFIG_WL=m +CONFIG_WL2=m # CONFIG_PLX_HERMES is not set # CONFIG_TMD_HERMES is not set # CONFIG_PCI_HERMES is not set diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch index 2e64b0fc3e..d662b4c015 100644 --- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch +++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -1,6 +1,56 @@ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/cfe_env.c linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c ---- linux-2.4.32/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/cfe_env.c 2005-12-19 01:56:35.104829500 +0100 +diff -Naur linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile +--- linux.old/arch/mips/Makefile 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/arch/mips/Makefile 2006-04-06 15:34:15.000000000 +0200 +@@ -726,6 +726,19 @@ + endif + + # ++# Broadcom BCM947XX variants ++# ++ifdef CONFIG_BCM947XX ++LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o ++SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx ++LOADADDR := 0x80001000 ++ ++zImage: vmlinux ++ $(MAKE) -C arch/$(ARCH)/bcm947xx/compressed ++export LOADADDR ++endif ++ ++# + # Choosing incompatible machines durings configuration will result in + # error messages during linking. Select a default linkscript if + # none has been choosen above. +@@ -778,6 +791,7 @@ + $(MAKE) -C arch/$(ARCH)/tools clean + $(MAKE) -C arch/mips/baget clean + $(MAKE) -C arch/mips/lasat clean ++ $(MAKE) -C arch/mips/bcm947xx/compressed clean + + archmrproper: + @$(MAKEBOOT) mrproper +diff -Naur linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Makefile +--- linux.old/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/Makefile 2006-04-06 15:34:14.000000000 +0200 +@@ -0,0 +1,15 @@ ++# ++# Makefile for the BCM947xx specific kernel interface routines ++# under Linux. ++# ++ ++EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER ++ ++O_TARGET := bcm947xx.o ++ ++export-objs := nvram_linux.o setup.o ++obj-y := prom.o setup.o time.o sbmips.o gpio.o ++obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o ++obj-$(CONFIG_PCI) += sbpci.o pcibios.o ++ ++include $(TOPDIR)/Rules.make +diff -Naur linux.old/arch/mips/bcm947xx/cfe_env.c linux.dev/arch/mips/bcm947xx/cfe_env.c +--- linux.old/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/cfe_env.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,234 @@ +/* + * NVRAM variable manipulation (Linux kernel half) @@ -236,9 +286,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/cfe_env.c linux-2.4.32-brcm/arch/mips/ + +} + -diff -Nur linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile ---- linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/compressed/Makefile 2005-12-16 23:39:10.668819500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/compressed/Makefile linux.dev/arch/mips/bcm947xx/compressed/Makefile +--- linux.old/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/compressed/Makefile 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,33 @@ +# +# Makefile for Broadcom BCM947XX boards @@ -273,9 +323,28 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/compressed/Makefile linux-2.4.32-brcm/ + +clean: + rm -f vmlinuz piggy -diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S ---- linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/int-handler.S 2005-12-16 23:39:10.668819500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/generic/Makefile linux.dev/arch/mips/bcm947xx/generic/Makefile +--- linux.old/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/generic/Makefile 2006-04-06 15:34:14.000000000 +0200 +@@ -0,0 +1,15 @@ ++# ++# Makefile for the BCM947xx specific kernel interface routines ++# under Linux. ++# ++ ++.S.s: ++ $(CPP) $(AFLAGS) $< -o $*.s ++.S.o: ++ $(CC) $(AFLAGS) -c $< -o $*.o ++ ++O_TARGET := brcm.o ++ ++obj-y := int-handler.o irq.o ++ ++include $(TOPDIR)/Rules.make +diff -Naur linux.old/arch/mips/bcm947xx/generic/int-handler.S linux.dev/arch/mips/bcm947xx/generic/int-handler.S +--- linux.old/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/generic/int-handler.S 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,51 @@ +/* + * Generic interrupt handler for Broadcom MIPS boards @@ -328,9 +397,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/int-handler.S linux-2.4.32-brc + nop + + END(brcmIRQ) -diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/irq.c linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c ---- linux-2.4.32/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/irq.c 2005-12-16 23:39:10.668819500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/generic/irq.c linux.dev/arch/mips/bcm947xx/generic/irq.c +--- linux.old/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/generic/irq.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,130 @@ +/* + * Generic interrupt control functions for Broadcom MIPS boards @@ -462,28 +531,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/irq.c linux-2.4.32-brcm/arch/m + breakpoint(); +#endif +} -diff -Nur linux-2.4.32/arch/mips/bcm947xx/generic/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile ---- linux-2.4.32/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/generic/Makefile 2005-12-16 23:39:10.668819500 +0100 -@@ -0,0 +1,15 @@ -+# -+# Makefile for the BCM947xx specific kernel interface routines -+# under Linux. -+# -+ -+.S.s: -+ $(CPP) $(AFLAGS) $< -o $*.s -+.S.o: -+ $(CC) $(AFLAGS) -c $< -o $*.o -+ -+O_TARGET := brcm.o -+ -+obj-y := int-handler.o irq.o -+ -+include $(TOPDIR)/Rules.make -diff -Nur linux-2.4.32/arch/mips/bcm947xx/gpio.c linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c ---- linux-2.4.32/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/gpio.c 2005-12-16 23:39:10.668819500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio.c +--- linux.old/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/gpio.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,158 @@ +/* + * GPIO char driver @@ -643,9 +693,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/gpio.c linux-2.4.32-brcm/arch/mips/bcm + +module_init(gpio_init); +module_exit(gpio_exit); -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmdevs.h 2005-12-16 23:39:10.672819750 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm947xx/include/bcmdevs.h +--- linux.old/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,391 @@ +/* + * Broadcom device-specific manifest constants. @@ -1038,9 +1088,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmdevs.h linux-2.4.32-brcm/ar +#define GPIO_NUMPINS 16 + +#endif /* _BCMDEVS_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmendian.h 2005-12-16 23:39:10.672819750 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/bcm947xx/include/bcmendian.h +--- linux.old/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,152 @@ +/* + * local version of endian.h - byte order defines @@ -1194,9 +1244,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmendian.h linux-2.4.32-brcm/ +) + +#endif /* _BCMENDIAN_H_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmnvram.h 2005-12-16 23:39:10.700821500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bcm947xx/include/bcmnvram.h +--- linux.old/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,141 @@ +/* + * NVRAM variable manipulation @@ -1339,9 +1389,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmnvram.h linux-2.4.32-brcm/a +#define NVRAM_MAX_PARAM_LEN 64 + +#endif /* _bcmnvram_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmsrom.h 2005-12-16 23:39:10.704821750 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/bcmsrom.h linux.dev/arch/mips/bcm947xx/include/bcmsrom.h +--- linux.old/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmsrom.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,23 @@ +/* + * Misc useful routines to access NIC local SROM/OTP . @@ -1366,10 +1416,10 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmsrom.h linux-2.4.32-brcm/ar +extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); + +#endif /* _bcmsrom_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h ---- linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/bcmutils.h 2005-12-16 23:39:10.704821750 +0100 -@@ -0,0 +1,313 @@ +diff -Naur linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bcm947xx/include/bcmutils.h +--- linux.old/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmutils.h 2006-04-06 17:07:30.000000000 +0200 +@@ -0,0 +1,287 @@ +/* + * Misc useful os-independent macros and functions. + * @@ -1429,32 +1479,6 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/a + } \ +} + -+/* generic osl packet queue */ -+struct pktq { -+ void *head; /* first packet to dequeue */ -+ void *tail; /* last packet to dequeue */ -+ uint len; /* number of queued packets */ -+ uint maxlen; /* maximum number of queued packets */ -+ bool priority; /* enqueue by packet priority */ -+ uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */ -+}; -+#define DEFAULT_QLEN 128 -+ -+#define pktq_len(q) ((q)->len) -+#define pktq_avail(q) ((q)->maxlen - (q)->len) -+#define pktq_head(q) ((q)->head) -+#define pktq_full(q) ((q)->len >= (q)->maxlen) -+#define _pktq_pri(q, pri) ((q)->prio_map[pri]) -+#define pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0)) -+ -+/* externs */ -+/* packet */ -+extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); -+extern uint pkttotlen(osl_t *osh, void *); -+extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]); -+extern void pktenq(struct pktq *q, void *p, bool lifo); -+extern void *pktdeq(struct pktq *q); -+extern void *pktdeqtail(struct pktq *q); +/* string */ +extern uint bcm_atoi(char *s); +extern uchar bcm_toupper(uchar c); @@ -1683,84 +1707,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/bcmutils.h linux-2.4.32-brcm/a +extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); + +#endif /* _bcmutils_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h ---- linux-2.4.32/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hnddma.h 2005-12-16 23:39:10.708822000 +0100 -@@ -0,0 +1,71 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ -+ -+#ifndef _hnddma_h_ -+#define _hnddma_h_ -+ -+/* export structure */ -+typedef volatile struct { -+ /* rx error counters */ -+ uint rxgiants; /* rx giant frames */ -+ uint rxnobuf; /* rx out of dma descriptors */ -+ /* tx error counters */ -+ uint txnobuf; /* tx out of dma descriptors */ -+} hnddma_t; -+ -+#ifndef di_t -+#define di_t void -+#endif -+ -+#ifndef osl_t -+#define osl_t void -+#endif -+ -+/* externs */ -+extern void * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, -+ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level); -+extern void dma_detach(di_t *di); -+extern void dma_txreset(di_t *di); -+extern void dma_rxreset(di_t *di); -+extern void dma_txinit(di_t *di); -+extern bool dma_txenabled(di_t *di); -+extern void dma_rxinit(di_t *di); -+extern void dma_rxenable(di_t *di); -+extern bool dma_rxenabled(di_t *di); -+extern void dma_txsuspend(di_t *di); -+extern void dma_txresume(di_t *di); -+extern bool dma_txsuspended(di_t *di); -+extern bool dma_txsuspendedidle(di_t *di); -+extern bool dma_txstopped(di_t *di); -+extern bool dma_rxstopped(di_t *di); -+extern int dma_txfast(di_t *di, void *p, uint32 coreflags); -+extern void dma_fifoloopbackenable(di_t *di); -+extern void *dma_rx(di_t *di); -+extern void dma_rxfill(di_t *di); -+extern void dma_txreclaim(di_t *di, bool forceall); -+extern void dma_rxreclaim(di_t *di); -+extern uintptr dma_getvar(di_t *di, char *name); -+extern void *dma_getnexttxp(di_t *di, bool forceall); -+extern void *dma_peeknexttxp(di_t *di); -+extern void *dma_getnextrxp(di_t *di, bool forceall); -+extern void dma_txblock(di_t *di); -+extern void dma_txunblock(di_t *di); -+extern uint dma_txactive(di_t *di); -+extern void dma_txrotate(di_t *di); -+ -+extern void dma_rxpiomode(dma32regs_t *); -+extern void dma_txpioloopback(dma32regs_t *); -+ -+ -+#endif /* _hnddma_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h ---- linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/hndmips.h 2005-12-16 23:39:10.708822000 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/hndmips.h linux.dev/arch/mips/bcm947xx/include/hndmips.h +--- linux.old/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/hndmips.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,16 @@ +/* + * Alternate include file for HND sbmips.h since CFE also ships with @@ -1778,9 +1727,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/hndmips.h linux-2.4.32-brcm/ar + */ + +#include "sbmips.h" -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h ---- linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linux_osl.h 2005-12-16 23:39:10.708822000 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/bcm947xx/include/linux_osl.h +--- linux.old/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/linux_osl.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,371 @@ +/* + * Linux OS Independent Layer @@ -2153,9 +2102,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linux_osl.h linux-2.4.32-brcm/ +#define PKTBUFSZ 2048 + +#endif /* _linux_osl_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h ---- linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/linuxver.h 2005-12-16 23:39:10.748824500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bcm947xx/include/linuxver.h +--- linux.old/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/linuxver.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,411 @@ +/* + * Linux-specific abstractions to gain some independence from linux kernel versions. @@ -2568,9 +2517,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/linuxver.h linux-2.4.32-brcm/a +#endif + +#endif /* _linuxver_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h ---- linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/mipsinc.h 2005-12-16 23:39:10.748824500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm947xx/include/mipsinc.h +--- linux.old/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/mipsinc.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,552 @@ +/* + * HND Run Time Environment for standalone MIPS programs. @@ -3124,9 +3073,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/mipsinc.h linux-2.4.32-brcm/ar +#endif /* !_LANGUAGE_ASSEMBLY */ + +#endif /* _MISPINC_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/osl.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h ---- linux-2.4.32/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/osl.h 2005-12-16 23:39:10.748824500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947xx/include/osl.h +--- linux.old/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/osl.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,42 @@ +/* + * OS Abstraction Layer @@ -3170,9 +3119,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/osl.h linux-2.4.32-brcm/arch/m +#define MAXPRIO 7 /* 0-7 */ + +#endif /* _osl_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h ---- linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/pcicfg.h 2005-12-16 23:39:10.752824750 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm947xx/include/pcicfg.h +--- linux.old/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/pcicfg.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,451 @@ +/* + * pcicfg.h: PCI configuration constants and structures. @@ -3625,9 +3574,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/pcicfg.h linux-2.4.32-brcm/arc +#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */ + +#endif -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbchipc.h 2005-12-16 23:39:10.932836000 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm947xx/include/sbchipc.h +--- linux.old/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbchipc.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,440 @@ +/* + * SiliconBackplane Chipcommon core hardware definitions. @@ -4069,9 +4018,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbchipc.h linux-2.4.32-brcm/ar +#define OTP_MAGIC 0x4e56 + +#endif /* _SBCHIPC_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbconfig.h 2005-12-16 23:39:10.932836000 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bcm947xx/include/sbconfig.h +--- linux.old/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbconfig.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,342 @@ +/* + * Broadcom SiliconBackplane hardware register definitions. @@ -4415,9 +4364,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbconfig.h linux-2.4.32-brcm/a +#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */ + +#endif /* _SBCONFIG_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbextif.h 2005-12-16 23:39:10.932836000 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/sbextif.h linux.dev/arch/mips/bcm947xx/include/sbextif.h +--- linux.old/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbextif.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,242 @@ +/* + * Hardware-specific External Interface I/O core definitions @@ -4661,13 +4610,12 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbextif.h linux-2.4.32-brcm/ar +#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */ + +#endif /* _SBEXTIF_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbhnddma.h 2005-12-16 23:39:10.932836000 +0100 -@@ -0,0 +1,312 @@ +diff -Naur linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm947xx/include/sbmemc.h +--- linux.old/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbmemc.h 2006-04-06 15:34:14.000000000 +0200 +@@ -0,0 +1,148 @@ +/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. + * + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. @@ -4676,314 +4624,344 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbhnddma.h linux-2.4.32-brcm/a + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * + * $Id$ + */ + -+#ifndef _sbhnddma_h_ -+#define _sbhnddma_h_ ++#ifndef _SBMEMC_H ++#define _SBMEMC_H + -+ -+/* 2byte-wide pio register set per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint16 fifocontrol; -+ uint16 fifodata; -+ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */ -+ uint16 PAD; -+} pio2regs_t; ++#ifdef _LANGUAGE_ASSEMBLY + -+/* a pair of pio channels(tx and rx) */ -+typedef volatile struct { -+ pio2regs_t tx; -+ pio2regs_t rx; -+} pio2regp_t; ++#define MEMC_CONTROL 0x00 ++#define MEMC_CONFIG 0x04 ++#define MEMC_REFRESH 0x08 ++#define MEMC_BISTSTAT 0x0c ++#define MEMC_MODEBUF 0x10 ++#define MEMC_BKCLS 0x14 ++#define MEMC_PRIORINV 0x18 ++#define MEMC_DRAMTIM 0x1c ++#define MEMC_INTSTAT 0x20 ++#define MEMC_INTMASK 0x24 ++#define MEMC_INTINFO 0x28 ++#define MEMC_NCDLCTL 0x30 ++#define MEMC_RDNCDLCOR 0x34 ++#define MEMC_WRNCDLCOR 0x38 ++#define MEMC_MISCDLYCTL 0x3c ++#define MEMC_DQSGATENCDL 0x40 ++#define MEMC_SPARE 0x44 ++#define MEMC_TPADDR 0x48 ++#define MEMC_TPDATA 0x4c ++#define MEMC_BARRIER 0x50 ++#define MEMC_CORE 0x54 + -+/* 4byte-wide pio register set per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 fifocontrol; -+ uint32 fifodata; -+} pio4regs_t; + -+/* a pair of pio channels(tx and rx) */ -+typedef volatile struct { -+ pio4regs_t tx; -+ pio4regs_t rx; -+} pio4regp_t; ++#else + ++/* Sonics side: MEMC core registers */ ++typedef volatile struct sbmemcregs { ++ uint32 control; ++ uint32 config; ++ uint32 refresh; ++ uint32 biststat; ++ uint32 modebuf; ++ uint32 bkcls; ++ uint32 priorinv; ++ uint32 dramtim; ++ uint32 intstat; ++ uint32 intmask; ++ uint32 intinfo; ++ uint32 reserved1; ++ uint32 ncdlctl; ++ uint32 rdncdlcor; ++ uint32 wrncdlcor; ++ uint32 miscdlyctl; ++ uint32 dqsgatencdl; ++ uint32 spare; ++ uint32 tpaddr; ++ uint32 tpdata; ++ uint32 barrier; ++ uint32 core; ++} sbmemcregs_t; + ++#endif + -+/* DMA structure: -+ * support two DMA engines: 32 bits address or 64 bit addressing -+ * basic DMA register set is per channel(transmit or receive) -+ * a pair of channels is defined for convenience -+ */ ++/* MEMC Core Init values (OCP ID 0x80f) */ + ++/* For sdr: */ ++#define MEMC_SD_CONFIG_INIT 0x00048000 ++#define MEMC_SD_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_SD_DRAMTIM3_INIT 0x000754da ++#define MEMC_SD_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_SD_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 /* For corerev 1 (4712) */ ++#define MEMC_SD_MISCDLYCTL_INIT 0x00061c1b ++#define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 /* For corerev 1 (4712) */ ++#define MEMC_SD_CONTROL_INIT0 0x00000002 ++#define MEMC_SD_CONTROL_INIT1 0x00000008 ++#define MEMC_SD_CONTROL_INIT2 0x00000004 ++#define MEMC_SD_CONTROL_INIT3 0x00000010 ++#define MEMC_SD_CONTROL_INIT4 0x00000001 ++#define MEMC_SD_MODEBUF_INIT 0x00000000 ++#define MEMC_SD_REFRESH_INIT 0x0000840f + -+/*** 32 bits addressing ***/ + -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 addr; /* descriptor ring base address (4K aligned) */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 status; /* current active descriptor, et al */ -+} dma32regs_t; ++/* This is for SDRM8X8X4 */ ++#define MEMC_SDR_INIT 0x0008 ++#define MEMC_SDR_MODE 0x32 ++#define MEMC_SDR_NCDL 0x00020032 ++#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */ + -+typedef volatile struct { -+ dma32regs_t xmt; /* dma tx channel */ -+ dma32regs_t rcv; /* dma rx channel */ -+} dma32regp_t; ++/* For ddr: */ ++#define MEMC_CONFIG_INIT 0x00048000 ++#define MEMC_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_DRAMTIM25_INIT 0x000754d9 ++#define MEMC_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */ ++#define MEMC_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_1_WRNCDLCOR_INIT 0x14500200 ++#define MEMC_DQSGATENCDL_INIT 0x00030000 ++#define MEMC_MISCDLYCTL_INIT 0x21061c1b ++#define MEMC_1_MISCDLYCTL_INIT 0x21021400 ++#define MEMC_NCDLCTL_INIT 0x00002001 ++#define MEMC_CONTROL_INIT0 0x00000002 ++#define MEMC_CONTROL_INIT1 0x00000008 ++#define MEMC_MODEBUF_INIT0 0x00004000 ++#define MEMC_CONTROL_INIT2 0x00000010 ++#define MEMC_MODEBUF_INIT1 0x00000100 ++#define MEMC_CONTROL_INIT3 0x00000010 ++#define MEMC_CONTROL_INIT4 0x00000008 ++#define MEMC_REFRESH_INIT 0x0000840f ++#define MEMC_CONTROL_INIT5 0x00000004 ++#define MEMC_MODEBUF_INIT2 0x00000000 ++#define MEMC_CONTROL_INIT6 0x00000010 ++#define MEMC_CONTROL_INIT7 0x00000001 + -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma32diag_t; + -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl; /* misc control bits & bufcount */ -+ uint32 addr; /* data buffer address */ -+} dma32dd_t; ++/* This is for DDRM16X16X2 */ ++#define MEMC_DDR_INIT 0x0009 ++#define MEMC_DDR_MODE 0x62 ++#define MEMC_DDR_NCDL 0x0005050a ++#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */ + -+/* -+ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. -+ */ -+#define D32MAXRINGSZ 4096 -+#define D32RINGALIGN 4096 -+#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) ++/* mask for sdr/ddr calibration registers */ ++#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff ++#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff ++#define MEMC_DQSGATENCDL_G_MASK 0x000000ff + -+/* transmit channel control */ -+#define XC_XE ((uint32)1 << 0) /* transmit enable */ -+#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ -+#define XC_LE ((uint32)1 << 2) /* loopback enable */ -+#define XC_FL ((uint32)1 << 4) /* flush request */ -+#define XC_AE ((uint32)3 << 16) /* address extension bits */ -+#define XC_AE_SHIFT 16 ++/* masks for miscdlyctl registers */ ++#define MEMC_MISC_SM_MASK 0x30000000 ++#define MEMC_MISC_SM_SHIFT 28 ++#define MEMC_MISC_SD_MASK 0x0f000000 ++#define MEMC_MISC_SD_SHIFT 24 + -+/* transmit descriptor table pointer */ -+#define XP_LD_MASK 0xfff /* last valid descriptor */ ++/* hw threshhold for calculating wr/rd for sdr memc */ ++#define MEMC_CD_THRESHOLD 128 + -+/* transmit channel status */ -+#define XS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define XS_XS_MASK 0xf000 /* transmit state */ -+#define XS_XS_SHIFT 12 -+#define XS_XS_DISABLED 0x0000 /* disabled */ -+#define XS_XS_ACTIVE 0x1000 /* active */ -+#define XS_XS_IDLE 0x2000 /* idle wait */ -+#define XS_XS_STOPPED 0x3000 /* stopped */ -+#define XS_XS_SUSP 0x4000 /* suspend pending */ -+#define XS_XE_MASK 0xf0000 /* transmit errors */ -+#define XS_XE_SHIFT 16 -+#define XS_XE_NOERR 0x00000 /* no error */ -+#define XS_XE_DPE 0x10000 /* descriptor protocol error */ -+#define XS_XE_DFU 0x20000 /* data fifo underrun */ -+#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ -+#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ -+#define XS_AD_MASK 0xfff00000 /* active descriptor */ -+#define XS_AD_SHIFT 20 ++/* Low bit of init register says if memc is ddr or sdr */ ++#define MEMC_CONFIG_DDR 0x00000001 + -+/* receive channel control */ -+#define RC_RE ((uint32)1 << 0) /* receive enable */ -+#define RC_RO_MASK 0xfe /* receive frame offset */ -+#define RC_RO_SHIFT 1 -+#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ -+#define RC_AE ((uint32)3 << 16) /* address extension bits */ -+#define RC_AE_SHIFT 16 ++#endif /* _SBMEMC_H */ +diff -Naur linux.old/arch/mips/bcm947xx/include/sbmips.h linux.dev/arch/mips/bcm947xx/include/sbmips.h +--- linux.old/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbmips.h 2006-04-06 15:34:14.000000000 +0200 +@@ -0,0 +1,62 @@ ++/* ++ * Broadcom SiliconBackplane MIPS definitions ++ * ++ * SB MIPS cores are custom MIPS32 processors with SiliconBackplane ++ * OCP interfaces. The CP0 processor ID is 0x00024000, where bits ++ * 23:16 mean Broadcom and bits 15:8 mean a MIPS core with an OCP ++ * interface. The core revision is stored in the SB ID register in SB ++ * configuration space. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ + -+/* receive descriptor table pointer */ -+#define RP_LD_MASK 0xfff /* last valid descriptor */ ++#ifndef _SBMIPS_H ++#define _SBMIPS_H + -+/* receive channel status */ -+#define RS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define RS_RS_MASK 0xf000 /* receive state */ -+#define RS_RS_SHIFT 12 -+#define RS_RS_DISABLED 0x0000 /* disabled */ -+#define RS_RS_ACTIVE 0x1000 /* active */ -+#define RS_RS_IDLE 0x2000 /* idle wait */ -+#define RS_RS_STOPPED 0x3000 /* reserved */ -+#define RS_RE_MASK 0xf0000 /* receive errors */ -+#define RS_RE_SHIFT 16 -+#define RS_RE_NOERR 0x00000 /* no error */ -+#define RS_RE_DPE 0x10000 /* descriptor protocol error */ -+#define RS_RE_DFO 0x20000 /* data fifo overflow */ -+#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ -+#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ -+#define RS_AD_MASK 0xfff00000 /* active descriptor */ -+#define RS_AD_SHIFT 20 ++#include + -+/* fifoaddr */ -+#define FA_OFF_MASK 0xffff /* offset */ -+#define FA_SEL_MASK 0xf0000 /* select */ -+#define FA_SEL_SHIFT 16 -+#define FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define FA_SEL_RDD 0x40000 /* receive dma data */ -+#define FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++#ifndef _LANGUAGE_ASSEMBLY + -+/* descriptor control flags */ -+#define CTRL_BC_MASK 0x1fff /* buffer byte count */ -+#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ -+#define CTRL_AE_SHIFT 16 -+#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ -+#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ + -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define CTRL_CORE_MASK 0x0ff00000 ++typedef volatile struct { ++ uint32 corecontrol; ++ uint32 PAD[2]; ++ uint32 biststatus; ++ uint32 PAD[4]; ++ uint32 intstatus; ++ uint32 intmask; ++ uint32 timer; ++} mipsregs_t; + -+/*** 64 bits addressing ***/ ++extern uint32 sb_flag(sb_t *sbh); ++extern uint sb_irq(sb_t *sbh); + -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ -+ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ -+ uint32 status0; /* current descriptor, xmt state */ -+ uint32 status1; /* active descriptor, xmt error */ -+} dma64regs_t; ++extern void BCMINIT(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)); + -+typedef volatile struct { -+ dma64regs_t tx; /* dma64 tx channel */ -+ dma64regs_t rx; /* dma64 rx channel */ -+} dma64regp_t; ++extern void *sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap); ++extern void sb_jtagm_disable(void *h); ++extern uint32 jtag_rwreg(void *h, uint32 ir, uint32 dr); ++extern void BCMINIT(sb_mips_init)(sb_t *sbh); ++extern uint32 BCMINIT(sb_mips_clock)(sb_t *sbh); ++extern bool BCMINIT(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock); ++extern void BCMINIT(enable_pfc)(uint32 mode); ++extern uint32 BCMINIT(sb_memc_get_ncdl)(sb_t *sbh); + -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma64diag_t; + ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++#endif /* _SBMIPS_H */ +diff -Naur linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm947xx/include/sbpci.h +--- linux.old/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbpci.h 2006-04-06 15:34:14.000000000 +0200 +@@ -0,0 +1,122 @@ +/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl1; /* misc control bits & bufcount */ -+ uint32 ctrl2; /* buffer count and address extension */ -+ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */ -+ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */ -+} dma64dd_t; -+ -+/* -+ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. ++ * BCM47XX Sonics SiliconBackplane PCI core hardware definitions. ++ * ++ * $Id$ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + */ -+#define D64MAXRINGSZ 8192 -+#define D64RINGALIGN 8192 -+#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) + -+/* transmit channel control */ -+#define D64_XC_XE 0x00000001 /* transmit enable */ -+#define D64_XC_SE 0x00000002 /* transmit suspend request */ -+#define D64_XC_LE 0x00000004 /* loopback enable */ -+#define D64_XC_FL 0x00000010 /* flush request */ -+#define D64_XC_AE 0x00110000 /* address extension bits */ -+#define D64_XC_AE_SHIFT 16 ++#ifndef _SBPCI_H ++#define _SBPCI_H + -+/* transmit descriptor table pointer */ -+#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif + -+/* transmit channel status */ -+#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ -+#define D64_XS0_XS_SHIFT 28 -+#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ -+#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ -+#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ -+#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ -+#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ ++/* Sonics side: PCI core and host control registers */ ++typedef struct sbpciregs { ++ uint32 control; /* PCI control */ ++ uint32 PAD[3]; ++ uint32 arbcontrol; /* PCI arbiter control */ ++ uint32 PAD[3]; ++ uint32 intstatus; /* Interrupt status */ ++ uint32 intmask; /* Interrupt mask */ ++ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */ ++ uint32 PAD[9]; ++ uint32 bcastaddr; /* Sonics broadcast address */ ++ uint32 bcastdata; /* Sonics broadcast data */ ++ uint32 PAD[2]; ++ uint32 gpioin; /* ro: gpio input (>=rev2) */ ++ uint32 gpioout; /* rw: gpio output (>=rev2) */ ++ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */ ++ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */ ++ uint32 PAD[36]; ++ uint32 sbtopci0; /* Sonics to PCI translation 0 */ ++ uint32 sbtopci1; /* Sonics to PCI translation 1 */ ++ uint32 sbtopci2; /* Sonics to PCI translation 2 */ ++ uint32 PAD[445]; ++ uint16 sprom[36]; /* SPROM shadow Area */ ++ uint32 PAD[46]; ++} sbpciregs_t; + -+#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ -+#define D64_XS1_XE_SHIFT 28 -+#define D64_XS1_XE_NOERR 0x00000000 /* no error */ -+#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ -+#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ -+#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ -+#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_XS1_XE_COREE 0x50000000 /* core error */ ++/* PCI control */ ++#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ ++#define PCI_RST 0x02 /* Value driven out to pin */ ++#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ ++#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ + -+/* receive channel control */ -+#define D64_RC_RE 0x00000001 /* receive enable */ -+#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ -+#define D64_RC_RO_SHIFT 1 -+#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ -+#define D64_RC_AE 0x00110000 /* address extension bits */ -+#define D64_RC_AE_SHIFT 16 ++/* PCI arbiter control */ ++#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ ++#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ ++#define PCI_PARKID_MASK 0x06 /* Selects which agent is parked on an idle bus */ ++#define PCI_PARKID_SHIFT 1 ++#define PCI_PARKID_LAST 0 /* Last requestor */ ++#define PCI_PARKID_4710 1 /* 4710 */ ++#define PCI_PARKID_EXTREQ0 2 /* External requestor 0 */ ++#define PCI_PARKID_EXTREQ1 3 /* External requestor 1 */ + -+/* receive descriptor table pointer */ -+#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ ++/* Interrupt status/mask */ ++#define PCI_INTA 0x01 /* PCI INTA# is asserted */ ++#define PCI_INTB 0x02 /* PCI INTB# is asserted */ ++#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ ++#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ ++#define PCI_PME 0x10 /* PCI PME# is asserted */ + -+/* receive channel status */ -+#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ -+#define D64_RS0_RS_SHIFT 28 -+#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ -+#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ -+#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ -+#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ -+#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ ++/* (General) PCI/SB mailbox interrupts, two bits per pci function */ ++#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ ++#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ ++#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ ++#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ ++#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ ++#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ ++#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ ++#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ + -+#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ -+#define D64_RS1_RE_SHIFT 28 -+#define D64_RS1_RE_NOERR 0x00000000 /* no error */ -+#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ -+#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ -+#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ -+#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_RS1_RE_COREE 0x50000000 /* core error */ ++/* Sonics broadcast address */ ++#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ + -+/* fifoaddr */ -+#define D64_FA_OFF_MASK 0xffff /* offset */ -+#define D64_FA_SEL_MASK 0xf0000 /* select */ -+#define D64_FA_SEL_SHIFT 16 -+#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ -+#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++/* Sonics to PCI translation types */ ++#define SBTOPCI0_MASK 0xfc000000 ++#define SBTOPCI1_MASK 0xfc000000 ++#define SBTOPCI2_MASK 0xc0000000 ++#define SBTOPCI_MEM 0 ++#define SBTOPCI_IO 1 ++#define SBTOPCI_CFG0 2 ++#define SBTOPCI_CFG1 3 ++#define SBTOPCI_PREF 0x4 /* prefetch enable */ ++#define SBTOPCI_BURST 0x8 /* burst enable */ ++#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ ++#define SBTOPCI_RC_READ 0x00 /* memory read */ ++#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ ++#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ + -+/* descriptor control flags 1 */ -+#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ -+#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ ++/* PCI core index in SROM shadow area */ ++#define SRSH_PI_OFFSET 0 /* first word */ ++#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ ++#define SRSH_PI_SHIFT 12 /* bit 15:12 */ + -+/* descriptor control flags 2 */ -+#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ -+#define D64_CTRL2_AE 0x00110000 /* address extension bits */ -+#define D64_CTRL2_AE_SHIFT 16 ++/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */ ++#define cap_list rsvd_a[0] ++#define bar0_window dev_dep[0x80 - 0x40] ++#define bar1_window dev_dep[0x84 - 0x40] ++#define sprom_control dev_dep[0x88 - 0x40] + -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define D64_CTRL_CORE_MASK 0x0ff00000 ++#ifndef _LANGUAGE_ASSEMBLY ++ ++extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); ++extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); ++extern void sbpci_ban(uint16 core); ++extern int sbpci_init(sb_t *sbh); ++extern void sbpci_check(sb_t *sbh); + ++#endif /* !_LANGUAGE_ASSEMBLY */ + -+#endif /* _sbhnddma_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmemc.h 2005-12-16 23:39:10.932836000 +0100 -@@ -0,0 +1,148 @@ ++#endif /* _SBPCI_H */ +diff -Naur linux.old/arch/mips/bcm947xx/include/sbpcie.h linux.dev/arch/mips/bcm947xx/include/sbpcie.h +--- linux.old/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbpcie.h 2006-04-06 15:34:14.000000000 +0200 +@@ -0,0 +1,199 @@ +/* -+ * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. ++ * BCM43XX SiliconBackplane PCIE core hardware definitions. + * ++ * $Id: + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * @@ -4991,254 +4969,35 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmemc.h linux-2.4.32-brcm/arc + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ + */ + -+#ifndef _SBMEMC_H -+#define _SBMEMC_H ++#ifndef _SBPCIE_H ++#define _SBPCIE_H + -+#ifdef _LANGUAGE_ASSEMBLY ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif + -+#define MEMC_CONTROL 0x00 -+#define MEMC_CONFIG 0x04 -+#define MEMC_REFRESH 0x08 -+#define MEMC_BISTSTAT 0x0c -+#define MEMC_MODEBUF 0x10 -+#define MEMC_BKCLS 0x14 -+#define MEMC_PRIORINV 0x18 -+#define MEMC_DRAMTIM 0x1c -+#define MEMC_INTSTAT 0x20 -+#define MEMC_INTMASK 0x24 -+#define MEMC_INTINFO 0x28 -+#define MEMC_NCDLCTL 0x30 -+#define MEMC_RDNCDLCOR 0x34 -+#define MEMC_WRNCDLCOR 0x38 -+#define MEMC_MISCDLYCTL 0x3c -+#define MEMC_DQSGATENCDL 0x40 -+#define MEMC_SPARE 0x44 -+#define MEMC_TPADDR 0x48 -+#define MEMC_TPDATA 0x4c -+#define MEMC_BARRIER 0x50 -+#define MEMC_CORE 0x54 ++/* PCIE Enumeration space offsets*/ ++#define PCIE_CORE_CONFIG_OFFSET 0x0 ++#define PCIE_FUNC0_CONFIG_OFFSET 0x400 ++#define PCIE_FUNC1_CONFIG_OFFSET 0x500 ++#define PCIE_FUNC2_CONFIG_OFFSET 0x600 ++#define PCIE_FUNC3_CONFIG_OFFSET 0x700 ++#define PCIE_SPROM_SHADOW_OFFSET 0x800 ++#define PCIE_SBCONFIG_OFFSET 0xE00 + ++/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */ ++#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0 ++#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000 ++#define PCIE_BAR0_PCIECORE_OFFSET 0x2000 ++#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000 + -+#else -+ -+/* Sonics side: MEMC core registers */ -+typedef volatile struct sbmemcregs { -+ uint32 control; -+ uint32 config; -+ uint32 refresh; -+ uint32 biststat; -+ uint32 modebuf; -+ uint32 bkcls; -+ uint32 priorinv; -+ uint32 dramtim; -+ uint32 intstat; -+ uint32 intmask; -+ uint32 intinfo; -+ uint32 reserved1; -+ uint32 ncdlctl; -+ uint32 rdncdlcor; -+ uint32 wrncdlcor; -+ uint32 miscdlyctl; -+ uint32 dqsgatencdl; -+ uint32 spare; -+ uint32 tpaddr; -+ uint32 tpdata; -+ uint32 barrier; -+ uint32 core; -+} sbmemcregs_t; -+ -+#endif -+ -+/* MEMC Core Init values (OCP ID 0x80f) */ -+ -+/* For sdr: */ -+#define MEMC_SD_CONFIG_INIT 0x00048000 -+#define MEMC_SD_DRAMTIM2_INIT 0x000754d8 -+#define MEMC_SD_DRAMTIM3_INIT 0x000754da -+#define MEMC_SD_RDNCDLCOR_INIT 0x00000000 -+#define MEMC_SD_WRNCDLCOR_INIT 0x49351200 -+#define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 /* For corerev 1 (4712) */ -+#define MEMC_SD_MISCDLYCTL_INIT 0x00061c1b -+#define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 /* For corerev 1 (4712) */ -+#define MEMC_SD_CONTROL_INIT0 0x00000002 -+#define MEMC_SD_CONTROL_INIT1 0x00000008 -+#define MEMC_SD_CONTROL_INIT2 0x00000004 -+#define MEMC_SD_CONTROL_INIT3 0x00000010 -+#define MEMC_SD_CONTROL_INIT4 0x00000001 -+#define MEMC_SD_MODEBUF_INIT 0x00000000 -+#define MEMC_SD_REFRESH_INIT 0x0000840f -+ -+ -+/* This is for SDRM8X8X4 */ -+#define MEMC_SDR_INIT 0x0008 -+#define MEMC_SDR_MODE 0x32 -+#define MEMC_SDR_NCDL 0x00020032 -+#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */ -+ -+/* For ddr: */ -+#define MEMC_CONFIG_INIT 0x00048000 -+#define MEMC_DRAMTIM2_INIT 0x000754d8 -+#define MEMC_DRAMTIM25_INIT 0x000754d9 -+#define MEMC_RDNCDLCOR_INIT 0x00000000 -+#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */ -+#define MEMC_WRNCDLCOR_INIT 0x49351200 -+#define MEMC_1_WRNCDLCOR_INIT 0x14500200 -+#define MEMC_DQSGATENCDL_INIT 0x00030000 -+#define MEMC_MISCDLYCTL_INIT 0x21061c1b -+#define MEMC_1_MISCDLYCTL_INIT 0x21021400 -+#define MEMC_NCDLCTL_INIT 0x00002001 -+#define MEMC_CONTROL_INIT0 0x00000002 -+#define MEMC_CONTROL_INIT1 0x00000008 -+#define MEMC_MODEBUF_INIT0 0x00004000 -+#define MEMC_CONTROL_INIT2 0x00000010 -+#define MEMC_MODEBUF_INIT1 0x00000100 -+#define MEMC_CONTROL_INIT3 0x00000010 -+#define MEMC_CONTROL_INIT4 0x00000008 -+#define MEMC_REFRESH_INIT 0x0000840f -+#define MEMC_CONTROL_INIT5 0x00000004 -+#define MEMC_MODEBUF_INIT2 0x00000000 -+#define MEMC_CONTROL_INIT6 0x00000010 -+#define MEMC_CONTROL_INIT7 0x00000001 -+ -+ -+/* This is for DDRM16X16X2 */ -+#define MEMC_DDR_INIT 0x0009 -+#define MEMC_DDR_MODE 0x62 -+#define MEMC_DDR_NCDL 0x0005050a -+#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */ -+ -+/* mask for sdr/ddr calibration registers */ -+#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff -+#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff -+#define MEMC_DQSGATENCDL_G_MASK 0x000000ff -+ -+/* masks for miscdlyctl registers */ -+#define MEMC_MISC_SM_MASK 0x30000000 -+#define MEMC_MISC_SM_SHIFT 28 -+#define MEMC_MISC_SD_MASK 0x0f000000 -+#define MEMC_MISC_SD_SHIFT 24 -+ -+/* hw threshhold for calculating wr/rd for sdr memc */ -+#define MEMC_CD_THRESHOLD 128 -+ -+/* Low bit of init register says if memc is ddr or sdr */ -+#define MEMC_CONFIG_DDR 0x00000001 -+ -+#endif /* _SBMEMC_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbmips.h 2005-12-16 23:39:10.936836250 +0100 -@@ -0,0 +1,62 @@ -+/* -+ * Broadcom SiliconBackplane MIPS definitions -+ * -+ * SB MIPS cores are custom MIPS32 processors with SiliconBackplane -+ * OCP interfaces. The CP0 processor ID is 0x00024000, where bits -+ * 23:16 mean Broadcom and bits 15:8 mean a MIPS core with an OCP -+ * interface. The core revision is stored in the SB ID register in SB -+ * configuration space. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ -+ -+#ifndef _SBMIPS_H -+#define _SBMIPS_H -+ -+#include -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ -+ -+typedef volatile struct { -+ uint32 corecontrol; -+ uint32 PAD[2]; -+ uint32 biststatus; -+ uint32 PAD[4]; -+ uint32 intstatus; -+ uint32 intmask; -+ uint32 timer; -+} mipsregs_t; -+ -+extern uint32 sb_flag(sb_t *sbh); -+extern uint sb_irq(sb_t *sbh); -+ -+extern void BCMINIT(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)); -+ -+extern void *sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap); -+extern void sb_jtagm_disable(void *h); -+extern uint32 jtag_rwreg(void *h, uint32 ir, uint32 dr); -+extern void BCMINIT(sb_mips_init)(sb_t *sbh); -+extern uint32 BCMINIT(sb_mips_clock)(sb_t *sbh); -+extern bool BCMINIT(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock); -+extern void BCMINIT(enable_pfc)(uint32 mode); -+extern uint32 BCMINIT(sb_memc_get_ncdl)(sb_t *sbh); -+ -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+#endif /* _SBMIPS_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcie.h 2005-12-16 23:39:10.936836250 +0100 -@@ -0,0 +1,199 @@ -+/* -+ * BCM43XX SiliconBackplane PCIE core hardware definitions. -+ * -+ * $Id: -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ */ -+ -+#ifndef _SBPCIE_H -+#define _SBPCIE_H -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif -+ -+/* PCIE Enumeration space offsets*/ -+#define PCIE_CORE_CONFIG_OFFSET 0x0 -+#define PCIE_FUNC0_CONFIG_OFFSET 0x400 -+#define PCIE_FUNC1_CONFIG_OFFSET 0x500 -+#define PCIE_FUNC2_CONFIG_OFFSET 0x600 -+#define PCIE_FUNC3_CONFIG_OFFSET 0x700 -+#define PCIE_SPROM_SHADOW_OFFSET 0x800 -+#define PCIE_SBCONFIG_OFFSET 0xE00 -+ -+/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */ -+#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0 -+#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000 -+#define PCIE_BAR0_PCIECORE_OFFSET 0x2000 -+#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000 -+ -+/* SB side: PCIE core and host control registers */ -+typedef struct sbpcieregs { ++/* SB side: PCIE core and host control registers */ ++typedef struct sbpcieregs { + + uint32 PAD[3]; + uint32 biststatus; /* bist Status: 0x00C*/ @@ -5398,12 +5157,12 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcie.h linux-2.4.32-brcm/arc +#define SERDES_RX_CDRBW 7 /* CDR BW */ + +#endif /* _SBPCIE_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpci.h 2005-12-16 23:39:10.936836250 +0100 -@@ -0,0 +1,122 @@ +diff -Naur linux.old/arch/mips/bcm947xx/include/sbpcmcia.h linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h +--- linux.old/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h 2006-04-06 15:34:14.000000000 +0200 +@@ -0,0 +1,146 @@ +/* -+ * BCM47XX Sonics SiliconBackplane PCI core hardware definitions. ++ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. + * + * $Id$ + * Copyright 2005, Broadcom Corporation @@ -5415,145 +5174,19 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpci.h linux-2.4.32-brcm/arch + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + */ + -+#ifndef _SBPCI_H -+#define _SBPCI_H ++#ifndef _SBPCMCIA_H ++#define _SBPCMCIA_H + -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif + -+/* Sonics side: PCI core and host control registers */ -+typedef struct sbpciregs { -+ uint32 control; /* PCI control */ -+ uint32 PAD[3]; -+ uint32 arbcontrol; /* PCI arbiter control */ -+ uint32 PAD[3]; -+ uint32 intstatus; /* Interrupt status */ -+ uint32 intmask; /* Interrupt mask */ -+ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */ -+ uint32 PAD[9]; -+ uint32 bcastaddr; /* Sonics broadcast address */ -+ uint32 bcastdata; /* Sonics broadcast data */ -+ uint32 PAD[2]; -+ uint32 gpioin; /* ro: gpio input (>=rev2) */ -+ uint32 gpioout; /* rw: gpio output (>=rev2) */ -+ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */ -+ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */ -+ uint32 PAD[36]; -+ uint32 sbtopci0; /* Sonics to PCI translation 0 */ -+ uint32 sbtopci1; /* Sonics to PCI translation 1 */ -+ uint32 sbtopci2; /* Sonics to PCI translation 2 */ -+ uint32 PAD[445]; -+ uint16 sprom[36]; /* SPROM shadow Area */ -+ uint32 PAD[46]; -+} sbpciregs_t; ++/* All the addresses that are offsets in attribute space are divided ++ * by two to account for the fact that odd bytes are invalid in ++ * attribute space and our read/write routines make the space appear ++ * as if they didn't exist. Still we want to show the original numbers ++ * as documented in the hnd_pcmcia core manual. ++ */ + -+/* PCI control */ -+#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ -+#define PCI_RST 0x02 /* Value driven out to pin */ -+#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ -+#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ -+ -+/* PCI arbiter control */ -+#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ -+#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ -+#define PCI_PARKID_MASK 0x06 /* Selects which agent is parked on an idle bus */ -+#define PCI_PARKID_SHIFT 1 -+#define PCI_PARKID_LAST 0 /* Last requestor */ -+#define PCI_PARKID_4710 1 /* 4710 */ -+#define PCI_PARKID_EXTREQ0 2 /* External requestor 0 */ -+#define PCI_PARKID_EXTREQ1 3 /* External requestor 1 */ -+ -+/* Interrupt status/mask */ -+#define PCI_INTA 0x01 /* PCI INTA# is asserted */ -+#define PCI_INTB 0x02 /* PCI INTB# is asserted */ -+#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ -+#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ -+#define PCI_PME 0x10 /* PCI PME# is asserted */ -+ -+/* (General) PCI/SB mailbox interrupts, two bits per pci function */ -+#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ -+#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ -+#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ -+#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ -+#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ -+#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ -+#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ -+#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ -+ -+/* Sonics broadcast address */ -+#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ -+ -+/* Sonics to PCI translation types */ -+#define SBTOPCI0_MASK 0xfc000000 -+#define SBTOPCI1_MASK 0xfc000000 -+#define SBTOPCI2_MASK 0xc0000000 -+#define SBTOPCI_MEM 0 -+#define SBTOPCI_IO 1 -+#define SBTOPCI_CFG0 2 -+#define SBTOPCI_CFG1 3 -+#define SBTOPCI_PREF 0x4 /* prefetch enable */ -+#define SBTOPCI_BURST 0x8 /* burst enable */ -+#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ -+#define SBTOPCI_RC_READ 0x00 /* memory read */ -+#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ -+#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ -+ -+/* PCI core index in SROM shadow area */ -+#define SRSH_PI_OFFSET 0 /* first word */ -+#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ -+#define SRSH_PI_SHIFT 12 /* bit 15:12 */ -+ -+/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */ -+#define cap_list rsvd_a[0] -+#define bar0_window dev_dep[0x80 - 0x40] -+#define bar1_window dev_dep[0x84 - 0x40] -+#define sprom_control dev_dep[0x88 - 0x40] -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); -+extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); -+extern void sbpci_ban(uint16 core); -+extern int sbpci_init(sb_t *sbh); -+extern void sbpci_check(sb_t *sbh); -+ -+#endif /* !_LANGUAGE_ASSEMBLY */ -+ -+#endif /* _SBPCI_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbpcmcia.h 2005-12-16 23:39:10.936836250 +0100 -@@ -0,0 +1,146 @@ -+/* -+ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. -+ * -+ * $Id$ -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ */ -+ -+#ifndef _SBPCMCIA_H -+#define _SBPCMCIA_H -+ -+ -+/* All the addresses that are offsets in attribute space are divided -+ * by two to account for the fact that odd bytes are invalid in -+ * attribute space and our read/write routines make the space appear -+ * as if they didn't exist. Still we want to show the original numbers -+ * as documented in the hnd_pcmcia core manual. -+ */ -+ -+/* PCMCIA Function Configuration Registers */ -+#define PCMCIA_FCR (0x700 / 2) ++/* PCMCIA Function Configuration Registers */ ++#define PCMCIA_FCR (0x700 / 2) + +#define FCR0_OFF 0 +#define FCR1_OFF (0x40 / 2) @@ -5674,9 +5307,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbpcmcia.h linux-2.4.32-brcm/a +#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */ + +#endif /* _SBPCMCIA_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsdram.h 2005-12-16 23:39:10.936836250 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/sbsdram.h linux.dev/arch/mips/bcm947xx/include/sbsdram.h +--- linux.old/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbsdram.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,75 @@ +/* + * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions. @@ -5753,9 +5386,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsdram.h linux-2.4.32-brcm/ar +#define MEM8MX16X2 0xc29 /* 32 MB */ + +#endif /* _SBSDRAM_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbsocram.h 2005-12-16 23:39:10.936836250 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/sbsocram.h linux.dev/arch/mips/bcm947xx/include/sbsocram.h +--- linux.old/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbsocram.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,37 @@ +/* + * BCM47XX Sonics SiliconBackplane embedded ram core @@ -5794,9 +5427,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbsocram.h linux-2.4.32-brcm/a +#define SOCRAM_MEMSIZE_BASESHIFT 16 + +#endif /* _SBSOCRAM_H */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sbutils.h 2005-12-16 23:39:10.936836250 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm947xx/include/sbutils.h +--- linux.old/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbutils.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,140 @@ +/* + * Misc utility routines for accessing chip-specific features @@ -5938,9 +5571,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sbutils.h linux-2.4.32-brcm/ar +#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ + +#endif /* _sbutils_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sflash.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h ---- linux-2.4.32/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/sflash.h 2005-12-16 23:39:10.936836250 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/sflash.h linux.dev/arch/mips/bcm947xx/include/sflash.h +--- linux.old/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sflash.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,36 @@ +/* + * Broadcom SiliconBackplane chipcommon serial flash interface @@ -5978,9 +5611,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/sflash.h linux-2.4.32-brcm/arc +extern struct sflash * sflash_init(chipcregs_t *cc); + +#endif /* _sflash_h_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h ---- linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/trxhdr.h 2005-12-16 23:39:10.940836500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/trxhdr.h linux.dev/arch/mips/bcm947xx/include/trxhdr.h +--- linux.old/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/trxhdr.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,33 @@ +/* + * TRX image file header format. @@ -6015,9 +5648,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/trxhdr.h linux-2.4.32-brcm/arc + +/* Compatibility */ +typedef struct trx_header TRXHDR, *PTRXHDR; -diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h ---- linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/include/typedefs.h 2005-12-16 23:39:10.940836500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bcm947xx/include/typedefs.h +--- linux.old/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/typedefs.h 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,326 @@ +/* + * Copyright 2005, Broadcom Corporation @@ -6345,28 +5978,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/include/typedefs.h linux-2.4.32-brcm/a +#endif /* USE_TYPEDEF_DEFAULTS */ + +#endif /* _TYPEDEFS_H_ */ -diff -Nur linux-2.4.32/arch/mips/bcm947xx/Makefile linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile ---- linux-2.4.32/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/Makefile 2005-12-19 01:56:51.733868750 +0100 -@@ -0,0 +1,15 @@ -+# -+# Makefile for the BCM947xx specific kernel interface routines -+# under Linux. -+# -+ -+EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER -+ -+O_TARGET := bcm947xx.o -+ -+export-objs := nvram_linux.o setup.o -+obj-y := prom.o setup.o time.o sbmips.o gpio.o -+obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o -+obj-$(CONFIG_PCI) += sbpci.o pcibios.o -+ -+include $(TOPDIR)/Rules.make -diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c ---- linux-2.4.32/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram.c 2005-12-19 01:05:00.079582750 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/nvram.c linux.dev/arch/mips/bcm947xx/nvram.c +--- linux.old/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/nvram.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,320 @@ +/* + * NVRAM variable manipulation (common) @@ -6688,9 +6302,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram.c linux-2.4.32-brcm/arch/mips/bc +{ + BCMINIT(nvram_free)(); +} -diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c ---- linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/nvram_linux.c 2005-12-19 01:09:59.782313000 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947xx/nvram_linux.c +--- linux.old/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/nvram_linux.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,653 @@ +/* + * NVRAM variable manipulation (Linux kernel half) @@ -7345,9 +6959,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/nvram_linux.c linux-2.4.32-brcm/arch/m + +module_init(dev_nvram_init); +module_exit(dev_nvram_exit); -diff -Nur linux-2.4.32/arch/mips/bcm947xx/pcibios.c linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c ---- linux-2.4.32/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/pcibios.c 2005-12-16 23:39:10.944836750 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/pcibios.c +--- linux.old/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/pcibios.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,355 @@ +/* + * Low-Level PCI and SB support for BCM47xx (Linux support code) @@ -7704,9 +7318,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/pcibios.c linux-2.4.32-brcm/arch/mips/ + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); +} + -diff -Nur linux-2.4.32/arch/mips/bcm947xx/prom.c linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c ---- linux-2.4.32/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/prom.c 2005-12-16 23:39:10.944836750 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom.c +--- linux.old/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/prom.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,41 @@ +/* + * Early initialization code for BCM94710 boards @@ -7749,9 +7363,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/prom.c linux-2.4.32-brcm/arch/mips/bcm +prom_free_prom_memory(void) +{ +} -diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbmips.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c ---- linux-2.4.32/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbmips.c 2005-12-16 23:39:10.944836750 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbmips.c +--- linux.old/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/sbmips.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,1038 @@ +/* + * BCM47XX Sonics SiliconBackplane MIPS core routines @@ -8791,9 +8405,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbmips.c linux-2.4.32-brcm/arch/mips/b + return ret; +} + -diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbpci.c linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c ---- linux-2.4.32/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/sbpci.c 2005-12-16 23:39:10.948837000 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpci.c +--- linux.old/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/sbpci.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,588 @@ +/* + * Low-Level PCI and SB support for BCM47xx @@ -9383,9 +8997,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/sbpci.c linux-2.4.32-brcm/arch/mips/bc + sb_setcoreidx(sbh, coreidx); +} + -diff -Nur linux-2.4.32/arch/mips/bcm947xx/setup.c linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c ---- linux-2.4.32/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/setup.c 2005-12-20 00:29:40.187416500 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setup.c +--- linux.old/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/setup.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,234 @@ +/* + * Generic setup routines for Broadcom MIPS boards @@ -9621,9 +9235,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/setup.c linux-2.4.32-brcm/arch/mips/bc +} + +EXPORT_SYMBOL(bcm947xx_sbh); -diff -Nur linux-2.4.32/arch/mips/bcm947xx/sflash.c linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c ---- linux-2.4.32/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/sflash.c 2005-12-16 23:39:10.948837000 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/sflash.c linux.dev/arch/mips/bcm947xx/sflash.c +--- linux.old/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/sflash.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,418 @@ +/* + * Broadcom SiliconBackplane chipcommon serial flash interface @@ -10043,9 +9657,9 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/sflash.c linux-2.4.32-brcm/arch/mips/b + return ret; +} + -diff -Nur linux-2.4.32/arch/mips/bcm947xx/time.c linux-2.4.32-brcm/arch/mips/bcm947xx/time.c ---- linux-2.4.32/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/bcm947xx/time.c 2005-12-16 23:39:10.948837000 +0100 +diff -Naur linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time.c +--- linux.old/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/time.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,118 @@ +/* + * Copyright 2004, Broadcom Corporation @@ -10165,10 +9779,10 @@ diff -Nur linux-2.4.32/arch/mips/bcm947xx/time.c linux-2.4.32-brcm/arch/mips/bcm + /* Enable the timer interrupt */ + setup_irq(7, &bcm947xx_timer_irqaction); +} -diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/config-shared.in ---- linux-2.4.32/arch/mips/config-shared.in 2005-01-19 15:09:27.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/config-shared.in 2005-12-16 23:39:11.080845250 +0100 -@@ -205,6 +205,14 @@ +diff -Naur linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared.in +--- linux.old/arch/mips/config-shared.in 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/arch/mips/config-shared.in 2006-04-06 15:34:14.000000000 +0200 +@@ -208,6 +208,14 @@ fi define_bool CONFIG_MIPS_RTC y fi @@ -10183,7 +9797,7 @@ diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/co bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226 bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229 -@@ -226,6 +234,11 @@ +@@ -229,6 +237,11 @@ define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n # @@ -10195,7 +9809,7 @@ diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/co # Select some configuration options automatically based on user selections. # if [ "$CONFIG_ACER_PICA_61" = "y" ]; then -@@ -533,6 +546,13 @@ +@@ -554,6 +567,13 @@ define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_BOOT_ELF32 y fi @@ -10209,7 +9823,7 @@ diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/co if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then define_bool CONFIG_ARC32 y define_bool CONFIG_ARC_MEMORY y -@@ -1011,7 +1031,11 @@ +@@ -1042,7 +1062,11 @@ bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG @@ -10222,10 +9836,10 @@ diff -Nur linux-2.4.32/arch/mips/config-shared.in linux-2.4.32-brcm/arch/mips/co dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB if [ "$CONFIG_KGDB" = "y" ]; then define_bool CONFIG_DEBUG_INFO y -diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c ---- linux-2.4.32/arch/mips/kernel/cpu-probe.c 2005-01-19 15:09:29.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/kernel/cpu-probe.c 2005-12-16 23:39:11.084845500 +0100 -@@ -174,7 +174,7 @@ +diff -Naur linux.old/arch/mips/kernel/cpu-probe.c linux.dev/arch/mips/kernel/cpu-probe.c +--- linux.old/arch/mips/kernel/cpu-probe.c 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/arch/mips/kernel/cpu-probe.c 2006-04-06 15:34:14.000000000 +0200 +@@ -162,7 +162,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) { @@ -10234,7 +9848,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/ case PRID_IMP_R2000: c->cputype = CPU_R2000; c->isa_level = MIPS_CPU_ISA_I; -@@ -184,7 +184,7 @@ +@@ -172,7 +172,7 @@ c->tlbsize = 64; break; case PRID_IMP_R3000: @@ -10243,7 +9857,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/ if (cpu_has_confreg()) c->cputype = CPU_R3081E; else -@@ -199,12 +199,12 @@ +@@ -187,12 +187,12 @@ break; case PRID_IMP_R4000: if (read_c0_config() & CONF_SC) { @@ -10258,7 +9872,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/ c->cputype = CPU_R4400SC; else c->cputype = CPU_R4000SC; -@@ -450,7 +450,7 @@ +@@ -438,7 +438,7 @@ static inline void cpu_probe_mips(struct cpuinfo_mips *c) { decode_config1(c); @@ -10267,7 +9881,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/ case PRID_IMP_4KC: c->cputype = CPU_4KC; c->isa_level = MIPS_CPU_ISA_M32; -@@ -491,10 +491,10 @@ +@@ -479,10 +479,10 @@ { decode_config1(c); c->options |= MIPS_CPU_PREFETCH; @@ -10280,7 +9894,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/ case 0: c->cputype = CPU_AU1000; break; -@@ -522,10 +522,34 @@ +@@ -510,10 +510,34 @@ } } @@ -10316,7 +9930,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/ case PRID_IMP_SB1: c->cputype = CPU_SB1; c->isa_level = MIPS_CPU_ISA_M64; -@@ -547,7 +571,7 @@ +@@ -535,7 +559,7 @@ static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) { decode_config1(c); @@ -10325,7 +9939,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/ case PRID_IMP_SR71000: c->cputype = CPU_SR71000; c->isa_level = MIPS_CPU_ISA_M64; -@@ -572,7 +596,7 @@ +@@ -560,7 +584,7 @@ c->cputype = CPU_UNKNOWN; c->processor_id = read_c0_prid(); @@ -10334,7 +9948,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/ case PRID_COMP_LEGACY: cpu_probe_legacy(c); -@@ -583,6 +607,9 @@ +@@ -571,6 +595,9 @@ case PRID_COMP_ALCHEMY: cpu_probe_alchemy(c); break; @@ -10344,9 +9958,9 @@ diff -Nur linux-2.4.32/arch/mips/kernel/cpu-probe.c linux-2.4.32-brcm/arch/mips/ case PRID_COMP_SIBYTE: cpu_probe_sibyte(c); break; -diff -Nur linux-2.4.32/arch/mips/kernel/head.S linux-2.4.32-brcm/arch/mips/kernel/head.S ---- linux-2.4.32/arch/mips/kernel/head.S 2005-01-19 15:09:29.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/kernel/head.S 2005-12-16 23:39:11.084845500 +0100 +diff -Naur linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S +--- linux.old/arch/mips/kernel/head.S 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/arch/mips/kernel/head.S 2006-04-06 15:34:14.000000000 +0200 @@ -28,12 +28,20 @@ #include #include @@ -10369,9 +9983,9 @@ diff -Nur linux-2.4.32/arch/mips/kernel/head.S linux-2.4.32-brcm/arch/mips/kerne /* The following two symbols are used for kernel profiling. */ EXPORT(stext) -diff -Nur linux-2.4.32/arch/mips/kernel/proc.c linux-2.4.32-brcm/arch/mips/kernel/proc.c ---- linux-2.4.32/arch/mips/kernel/proc.c 2005-01-19 15:09:29.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/kernel/proc.c 2005-12-16 23:39:11.084845500 +0100 +diff -Naur linux.old/arch/mips/kernel/proc.c linux.dev/arch/mips/kernel/proc.c +--- linux.old/arch/mips/kernel/proc.c 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/arch/mips/kernel/proc.c 2006-04-06 15:34:14.000000000 +0200 @@ -78,9 +78,10 @@ [CPU_AU1550] "Au1550", [CPU_24K] "MIPS 24K", @@ -10384,10 +9998,10 @@ diff -Nur linux-2.4.32/arch/mips/kernel/proc.c linux-2.4.32-brcm/arch/mips/kerne static int show_cpuinfo(struct seq_file *m, void *v) { unsigned int version = current_cpu_data.processor_id; -diff -Nur linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32-brcm/arch/mips/kernel/setup.c ---- linux-2.4.32/arch/mips/kernel/setup.c 2005-01-19 15:09:29.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/kernel/setup.c 2005-12-16 23:39:11.140849000 +0100 -@@ -495,6 +495,7 @@ +diff -Naur linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c +--- linux.old/arch/mips/kernel/setup.c 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/arch/mips/kernel/setup.c 2006-04-06 15:34:14.000000000 +0200 +@@ -493,6 +493,7 @@ void swarm_setup(void); void hp_setup(void); void au1x00_setup(void); @@ -10395,7 +10009,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32-brcm/arch/mips/kern void frame_info_init(void); frame_info_init(); -@@ -693,6 +694,11 @@ +@@ -691,6 +692,11 @@ pmc_yosemite_setup(); break; #endif @@ -10407,10 +10021,10 @@ diff -Nur linux-2.4.32/arch/mips/kernel/setup.c linux-2.4.32-brcm/arch/mips/kern default: panic("Unsupported architecture"); } -diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kernel/traps.c ---- linux-2.4.32/arch/mips/kernel/traps.c 2005-01-19 15:09:29.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/kernel/traps.c 2005-12-16 23:39:11.140849000 +0100 -@@ -913,6 +913,7 @@ +diff -Naur linux.old/arch/mips/kernel/traps.c linux.dev/arch/mips/kernel/traps.c +--- linux.old/arch/mips/kernel/traps.c 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/arch/mips/kernel/traps.c 2006-04-06 15:34:14.000000000 +0200 +@@ -920,6 +920,7 @@ void __init trap_init(void) { extern char except_vec1_generic; @@ -10418,7 +10032,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kern extern char except_vec3_generic, except_vec3_r4000; extern char except_vec_ejtag_debug; extern char except_vec4; -@@ -922,6 +923,7 @@ +@@ -927,6 +928,7 @@ /* Copy the generic exception handler code to it's final destination. */ memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); @@ -10426,7 +10040,7 @@ diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kern /* * Setup default vectors -@@ -980,6 +982,12 @@ +@@ -985,6 +987,12 @@ set_except_vector(13, handle_tr); set_except_vector(22, handle_mdmx); @@ -10439,41 +10053,10 @@ diff -Nur linux-2.4.32/arch/mips/kernel/traps.c linux-2.4.32-brcm/arch/mips/kern if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); -diff -Nur linux-2.4.32/arch/mips/Makefile linux-2.4.32-brcm/arch/mips/Makefile ---- linux-2.4.32/arch/mips/Makefile 2005-01-19 15:09:26.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/Makefile 2005-12-16 23:39:10.668819500 +0100 -@@ -715,6 +715,19 @@ - endif - - # -+# Broadcom BCM947XX variants -+# -+ifdef CONFIG_BCM947XX -+LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o -+SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx -+LOADADDR := 0x80001000 -+ -+zImage: vmlinux -+ $(MAKE) -C arch/$(ARCH)/bcm947xx/compressed -+export LOADADDR -+endif -+ -+# - # Choosing incompatible machines durings configuration will result in - # error messages during linking. Select a default linkscript if - # none has been choosen above. -@@ -767,6 +780,7 @@ - $(MAKE) -C arch/$(ARCH)/tools clean - $(MAKE) -C arch/mips/baget clean - $(MAKE) -C arch/mips/lasat clean -+ $(MAKE) -C arch/mips/bcm947xx/compressed clean - - archmrproper: - @$(MAKEBOOT) mrproper -diff -Nur linux-2.4.32/arch/mips/mm/c-r4k.c linux-2.4.32-brcm/arch/mips/mm/c-r4k.c ---- linux-2.4.32/arch/mips/mm/c-r4k.c 2005-01-19 15:09:29.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/mm/c-r4k.c 2005-12-16 23:39:11.144849250 +0100 -@@ -1114,3 +1114,47 @@ +diff -Naur linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c +--- linux.old/arch/mips/mm/c-r4k.c 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/arch/mips/mm/c-r4k.c 2006-04-06 15:34:15.000000000 +0200 +@@ -1166,3 +1166,47 @@ build_clear_page(); build_copy_page(); } @@ -10521,9 +10104,9 @@ diff -Nur linux-2.4.32/arch/mips/mm/c-r4k.c linux-2.4.32-brcm/arch/mips/mm/c-r4k +} + + -diff -Nur linux-2.4.32/arch/mips/pci/Makefile linux-2.4.32-brcm/arch/mips/pci/Makefile ---- linux-2.4.32/arch/mips/pci/Makefile 2005-01-19 15:09:29.000000000 +0100 -+++ linux-2.4.32-brcm/arch/mips/pci/Makefile 2005-12-16 23:39:11.144849250 +0100 +diff -Naur linux.old/arch/mips/pci/Makefile linux.dev/arch/mips/pci/Makefile +--- linux.old/arch/mips/pci/Makefile 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/arch/mips/pci/Makefile 2006-04-06 15:34:14.000000000 +0200 @@ -13,7 +13,9 @@ obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o @@ -10534,10 +10117,10 @@ diff -Nur linux-2.4.32/arch/mips/pci/Makefile linux-2.4.32-brcm/arch/mips/pci/Ma obj-$(CONFIG_PCI_AUTO) += pci_auto.o include $(TOPDIR)/Rules.make -diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/serial.c ---- linux-2.4.32/drivers/char/serial.c 2005-11-16 20:12:54.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/char/serial.c 2005-12-16 23:39:11.200852750 +0100 -@@ -422,6 +422,10 @@ +diff -Naur linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c +--- linux.old/drivers/char/serial.c 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/drivers/char/serial.c 2006-04-06 15:34:14.000000000 +0200 +@@ -444,6 +444,10 @@ return inb(info->port+1); #endif case SERIAL_IO_MEM: @@ -10548,7 +10131,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri return readb((unsigned long) info->iomem_base + (offset<iomem_reg_shift)); default: -@@ -442,6 +446,9 @@ +@@ -464,6 +468,9 @@ case SERIAL_IO_MEM: writeb(value, (unsigned long) info->iomem_base + (offset<iomem_reg_shift)); @@ -10558,7 +10141,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri break; default: outb(value, info->port+offset); -@@ -1704,7 +1711,7 @@ +@@ -1728,7 +1735,7 @@ /* Special case since 134 is really 134.5 */ quot = (2*baud_base / 269); else if (baud) @@ -10567,7 +10150,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri } /* If the quotient is zero refuse the change */ if (!quot && old_termios) { -@@ -1721,12 +1728,12 @@ +@@ -1745,12 +1752,12 @@ /* Special case since 134 is really 134.5 */ quot = (2*baud_base / 269); else if (baud) @@ -10582,7 +10165,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri /* * Work around a bug in the Oxford Semiconductor 952 rev B * chip which causes it to seriously miscalculate baud rates -@@ -5982,6 +5989,13 @@ +@@ -5994,6 +6001,13 @@ * Divisor, bytesize and parity */ state = rs_table + co->index; @@ -10596,7 +10179,7 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri if (doflow) state->flags |= ASYNC_CONS_FLOW; info = &async_sercons; -@@ -5995,7 +6009,7 @@ +@@ -6007,7 +6021,7 @@ info->io_type = state->io_type; info->iomem_base = state->iomem_base; info->iomem_reg_shift = state->iomem_reg_shift; @@ -10605,9 +10188,9 @@ diff -Nur linux-2.4.32/drivers/char/serial.c linux-2.4.32-brcm/drivers/char/seri cval = cflag & (CSIZE | CSTOPB); #if defined(__powerpc__) || defined(__alpha__) cval >>= 8; -diff -Nur linux-2.4.32/drivers/net/Config.in linux-2.4.32-brcm/drivers/net/Config.in ---- linux-2.4.32/drivers/net/Config.in 2005-01-19 15:09:56.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/Config.in 2005-12-16 23:39:11.232854750 +0100 +diff -Naur linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in +--- linux.old/drivers/net/Config.in 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/drivers/net/Config.in 2006-04-06 15:34:14.000000000 +0200 @@ -2,6 +2,8 @@ # Network device configuration # @@ -10617,9 +10200,65 @@ diff -Nur linux-2.4.32/drivers/net/Config.in linux-2.4.32-brcm/drivers/net/Confi source drivers/net/arcnet/Config.in tristate 'Dummy net driver support' CONFIG_DUMMY -diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c ---- linux-2.4.32/drivers/net/hnd/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/hnd/bcmsrom.c 2005-12-16 23:39:11.284858000 +0100 +diff -Naur linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile +--- linux.old/drivers/net/Makefile 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/drivers/net/Makefile 2006-04-06 16:45:29.000000000 +0200 +@@ -3,6 +3,8 @@ + # Makefile for the Linux network (ethercard) device drivers. + # + ++EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include ++ + obj-y := + obj-m := + obj-n := +@@ -39,6 +41,9 @@ + obj-$(CONFIG_ISDN) += slhc.o + endif + ++subdir-$(CONFIG_HND) += hnd ++subdir-$(CONFIG_WL) += wl ++subdir-$(CONFIG_WL2) += wl2 + subdir-$(CONFIG_NET_PCMCIA) += pcmcia + subdir-$(CONFIG_NET_WIRELESS) += wireless + subdir-$(CONFIG_TULIP) += tulip +@@ -69,6 +74,10 @@ + obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o + obj-$(CONFIG_SUNGEM) += sungem.o + ++ifeq ($(CONFIG_HND),y) ++ obj-y += hnd/hnd.o ++endif ++ + obj-$(CONFIG_MACE) += mace.o + obj-$(CONFIG_BMAC) += bmac.o + obj-$(CONFIG_GMAC) += gmac.o +diff -Naur linux.old/drivers/net/hnd/Makefile linux.dev/drivers/net/hnd/Makefile +--- linux.old/drivers/net/hnd/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/hnd/Makefile 2006-04-06 16:20:00.000000000 +0200 +@@ -0,0 +1,19 @@ ++# ++# Makefile for the BCM47xx specific kernel interface routines ++# under Linux. ++# ++ ++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER ++ ++O_TARGET := hnd.o ++ ++HND_OBJS := bcmutils.o linux_osl.o sbutils.o bcmsrom.o ++ ++export-objs := shared_ksyms.o ++obj-y := shared_ksyms.o $(HND_OBJS) ++obj-m := $(O_TARGET) ++ ++include $(TOPDIR)/Rules.make ++ ++shared_ksyms.c: shared_ksyms.sh $(HND_OBJS) ++ sh -e $< $(HND_OBJS) > $@ +diff -Naur linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom.c +--- linux.old/drivers/net/hnd/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/hnd/bcmsrom.c 2006-04-06 15:34:14.000000000 +0200 @@ -0,0 +1,938 @@ +/* + * Misc useful routines to access NIC SROM/OTP . @@ -11559,10 +11198,10 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmsrom.c linux-2.4.32-brcm/drivers/net/h + return (rc); +} + -diff -Nur linux-2.4.32/drivers/net/hnd/bcmutils.c linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c ---- linux-2.4.32/drivers/net/hnd/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/hnd/bcmutils.c 2005-12-16 23:39:11.288858250 +0100 -@@ -0,0 +1,1081 @@ +diff -Naur linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutils.c +--- linux.old/drivers/net/hnd/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/hnd/bcmutils.c 2006-04-06 16:05:56.000000000 +0200 +@@ -0,0 +1,875 @@ +/* + * Misc useful OS-independent routines. + * @@ -11590,254 +11229,48 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmutils.c linux-2.4.32-brcm/drivers/net/ +#include + +#ifdef BCMDRIVER -+/* copy a pkt buffer chain into a buffer */ -+uint -+pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) -+{ -+ uint n, ret = 0; -+ -+ if (len < 0) -+ len = 4096; /* "infinite" */ -+ -+ /* skip 'offset' bytes */ -+ for (; p && offset; p = PKTNEXT(osh, p)) { -+ if (offset < (uint)PKTLEN(osh, p)) -+ break; -+ offset -= PKTLEN(osh, p); -+ } -+ -+ if (!p) -+ return 0; -+ -+ /* copy the data */ -+ for (; p && len; p = PKTNEXT(osh, p)) { -+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); -+ bcopy(PKTDATA(osh, p) + offset, buf, n); -+ buf += n; -+ len -= n; -+ ret += n; -+ offset = 0; -+ } ++unsigned char bcm_ctype[] = { ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ ++ _BCM_C,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C,_BCM_C, /* 8-15 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ ++ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ ++ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ ++ _BCM_P,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U, /* 64-71 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ ++ _BCM_P,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L, /* 96-103 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ ++ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 160-175 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 176-191 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 192-207 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_L, /* 208-223 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 224-239 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L /* 240-255 */ ++}; + -+ return ret; ++uchar ++bcm_toupper(uchar c) ++{ ++ if (bcm_islower(c)) ++ c -= 'a'-'A'; ++ return (c); +} + -+/* return total length of buffer chain */ -+uint -+pkttotlen(osl_t *osh, void *p) ++ulong ++bcm_strtoul(char *cp, char **endp, uint base) +{ -+ uint total; -+ -+ total = 0; -+ for (; p; p = PKTNEXT(osh, p)) -+ total += PKTLEN(osh, p); -+ return (total); -+} -+ -+void -+pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]) -+{ -+ q->head = q->tail = NULL; -+ q->maxlen = maxlen; -+ q->len = 0; -+ if (prio_map) { -+ q->priority = TRUE; -+ bcopy(prio_map, q->prio_map, sizeof(q->prio_map)); -+ } -+ else -+ q->priority = FALSE; -+} -+ -+/* should always check pktq_full before calling pktenq */ -+void -+pktenq(struct pktq *q, void *p, bool lifo) -+{ -+ void *next, *prev; -+ -+ /* allow 10 pkts slack */ -+ ASSERT(q->len < (q->maxlen + 10)); -+ -+ /* Queueing chains not allowed */ -+ ASSERT(PKTLINK(p) == NULL); -+ -+ /* Queue is empty */ -+ if (q->tail == NULL) { -+ ASSERT(q->head == NULL); -+ q->head = q->tail = p; -+ } -+ -+ /* Insert at head or tail */ -+ else if (q->priority == FALSE) { -+ /* Insert at head (LIFO) */ -+ if (lifo) { -+ PKTSETLINK(p, q->head); -+ q->head = p; -+ } -+ /* Insert at tail (FIFO) */ -+ else { -+ ASSERT(PKTLINK(q->tail) == NULL); -+ PKTSETLINK(q->tail, p); -+ PKTSETLINK(p, NULL); -+ q->tail = p; -+ } -+ } -+ -+ /* Insert by priority */ -+ else { -+ /* legal priorities 0-7 */ -+ ASSERT(PKTPRIO(p) <= MAXPRIO); -+ -+ ASSERT(q->head); -+ ASSERT(q->tail); -+ /* Shortcut to insertion at tail */ -+ if (_pktq_pri(q, PKTPRIO(p)) < _pktq_pri(q, PKTPRIO(q->tail)) || -+ (!lifo && _pktq_pri(q, PKTPRIO(p)) <= _pktq_pri(q, PKTPRIO(q->tail)))) { -+ prev = q->tail; -+ next = NULL; -+ } -+ /* Insert at head or in the middle */ -+ else { -+ prev = NULL; -+ next = q->head; -+ } -+ /* Walk the queue */ -+ for (; next; prev = next, next = PKTLINK(next)) { -+ /* Priority queue invariant */ -+ ASSERT(!prev || _pktq_pri(q, PKTPRIO(prev)) >= _pktq_pri(q, PKTPRIO(next))); -+ /* Insert at head of string of packets of same priority (LIFO) */ -+ if (lifo) { -+ if (_pktq_pri(q, PKTPRIO(p)) >= _pktq_pri(q, PKTPRIO(next))) -+ break; -+ } -+ /* Insert at tail of string of packets of same priority (FIFO) */ -+ else { -+ if (_pktq_pri(q, PKTPRIO(p)) > _pktq_pri(q, PKTPRIO(next))) -+ break; -+ } -+ } -+ /* Insert at tail */ -+ if (next == NULL) { -+ ASSERT(PKTLINK(q->tail) == NULL); -+ PKTSETLINK(q->tail, p); -+ PKTSETLINK(p, NULL); -+ q->tail = p; -+ } -+ /* Insert in the middle */ -+ else if (prev) { -+ PKTSETLINK(prev, p); -+ PKTSETLINK(p, next); -+ } -+ /* Insert at head */ -+ else { -+ PKTSETLINK(p, q->head); -+ q->head = p; -+ } -+ } -+ -+ /* List invariants after insertion */ -+ ASSERT(q->head); -+ ASSERT(PKTLINK(q->tail) == NULL); -+ -+ q->len++; -+} -+ -+/* dequeue packet at head */ -+void* -+pktdeq(struct pktq *q) -+{ -+ void *p; -+ -+ if ((p = q->head)) { -+ ASSERT(q->tail); -+ q->head = PKTLINK(p); -+ PKTSETLINK(p, NULL); -+ q->len--; -+ if (q->head == NULL) -+ q->tail = NULL; -+ } -+ else { -+ ASSERT(q->tail == NULL); -+ } -+ -+ return (p); -+} -+ -+/* dequeue packet at tail */ -+void* -+pktdeqtail(struct pktq *q) -+{ -+ void *p; -+ void *next, *prev; -+ -+ if (q->head == q->tail) { /* last packet on queue or queue empty */ -+ p = q->head; -+ q->head = q->tail = NULL; -+ q->len = 0; -+ return(p); -+ } -+ -+ /* start walk at head */ -+ prev = NULL; -+ next = q->head; -+ -+ /* Walk the queue to find prev of q->tail */ -+ for (; next; prev = next, next = PKTLINK(next)) { -+ if (next == q->tail) -+ break; -+ } -+ -+ ASSERT(prev); -+ -+ PKTSETLINK(prev, NULL); -+ q->tail = prev; -+ q->len--; -+ p = next; -+ -+ return (p); -+} -+ -+unsigned char bcm_ctype[] = { -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ -+ _BCM_C,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C,_BCM_C, /* 8-15 */ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ -+ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ -+ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ -+ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ -+ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ -+ _BCM_P,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U, /* 64-71 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ -+ _BCM_P,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L, /* 96-103 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ -+ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 160-175 */ -+ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 176-191 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 192-207 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_L, /* 208-223 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 224-239 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L /* 240-255 */ -+}; -+ -+uchar -+bcm_toupper(uchar c) -+{ -+ if (bcm_islower(c)) -+ c -= 'a'-'A'; -+ return (c); -+} -+ -+ulong -+bcm_strtoul(char *cp, char **endp, uint base) -+{ -+ ulong result, value; -+ bool minus; -+ -+ minus = FALSE; ++ ulong result, value; ++ bool minus; ++ ++ minus = FALSE; + + while (bcm_isspace(*cp)) + cp++; @@ -12393,2530 +11826,5655 @@ diff -Nur linux-2.4.32/drivers/net/hnd/bcmutils.c linux-2.4.32-brcm/drivers/net/ + return crc; +} + -+#ifdef notdef -+#define CLEN 1499 -+#define CBUFSIZ (CLEN+4) -+#define CNBUFS 5 ++#ifdef notdef ++#define CLEN 1499 ++#define CBUFSIZ (CLEN+4) ++#define CNBUFS 5 ++ ++void testcrc32(void) ++{ ++ uint j,k,l; ++ uint8 *buf; ++ uint len[CNBUFS]; ++ uint32 crcr; ++ uint32 crc32tv[CNBUFS] = ++ {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; ++ ++ ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); ++ ++ /* step through all possible alignments */ ++ for (l=0;l<=4;l++) { ++ for (j=0; jlen; ++ elt = (bcm_tlv_t*)(elt->data + len); ++ *buflen -= (2 + len); ++ ++ /* validate next elt */ ++ if (!bcm_valid_tlv(elt, *buflen)) ++ return NULL; ++ ++ return elt; ++} ++ ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag ++ */ ++bcm_tlv_t * ++bcm_parse_tlvs(void *buf, int buflen, uint key) ++{ ++ bcm_tlv_t *elt; ++ int totlen; ++ ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; ++ ++ /* find tagged parameter */ ++ while (totlen >= 2) { ++ int len = elt->len; ++ ++ /* validate remaining totlen */ ++ if ((elt->id == key) && (totlen >= (len + 2))) ++ return (elt); ++ ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); ++ totlen -= (len + 2); ++ } ++ ++ return NULL; ++} ++ ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag. Stop parsing when we see an element whose ID is greater ++ * than the target key. ++ */ ++bcm_tlv_t * ++bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) ++{ ++ bcm_tlv_t *elt; ++ int totlen; ++ ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; ++ ++ /* find tagged parameter */ ++ while (totlen >= 2) { ++ uint id = elt->id; ++ int len = elt->len; ++ ++ /* Punt if we start seeing IDs > than target key */ ++ if (id > key) ++ return(NULL); ++ ++ /* validate remaining totlen */ ++ if ((id == key) && (totlen >= (len + 2))) ++ return (elt); ++ ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); ++ totlen -= (len + 2); ++ } ++ return NULL; ++} ++/* routine to dump fields in a fileddesc structure */ ++ ++uint ++bcmdumpfields(readreg_rtn read_rtn, void *arg0, void *arg1, struct fielddesc *fielddesc_array, char *buf, uint32 bufsize) ++{ ++ uint filled_len; ++ uint len; ++ struct fielddesc *cur_ptr; ++ ++ filled_len = 0; ++ cur_ptr = fielddesc_array; ++ ++ while (bufsize > (filled_len + 64)) { ++ if (cur_ptr->nameandfmt == NULL) ++ break; ++ len = sprintf(buf, cur_ptr->nameandfmt, read_rtn(arg0, arg1, cur_ptr->offset)); ++ buf += len; ++ filled_len += len; ++ cur_ptr++; ++ } ++ return filled_len; ++} ++ ++uint ++bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) ++{ ++ uint len; ++ ++ len = strlen(name) + 1; ++ ++ if ((len + datalen) > buflen) ++ return 0; ++ ++ strcpy(buf, name); ++ ++ /* append data onto the end of the name string */ ++ memcpy(&buf[len], data, datalen); ++ len += datalen; ++ ++ return len; ++} ++ ++/* Quarter dBm units to mW ++ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 ++ * Table is offset so the last entry is largest mW value that fits in ++ * a uint16. ++ */ ++ ++#define QDBM_OFFSET 153 ++#define QDBM_TABLE_LEN 40 ++ ++/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. ++ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 ++ */ ++#define QDBM_TABLE_LOW_BOUND 6493 ++ ++/* Largest mW value that will round down to the last table entry, ++ * QDBM_OFFSET + QDBM_TABLE_LEN-1. ++ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. ++ */ ++#define QDBM_TABLE_HIGH_BOUND 64938 ++ ++static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { ++/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ ++/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, ++/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, ++/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, ++/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, ++/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 ++}; ++ ++uint16 ++bcm_qdbm_to_mw(uint8 qdbm) ++{ ++ uint factor = 1; ++ int idx = qdbm - QDBM_OFFSET; ++ ++ if (idx > QDBM_TABLE_LEN) { ++ /* clamp to max uint16 mW value */ ++ return 0xFFFF; ++ } ++ ++ /* scale the qdBm index up to the range of the table 0-40 ++ * where an offset of 40 qdBm equals a factor of 10 mW. ++ */ ++ while (idx < 0) { ++ idx += 40; ++ factor *= 10; ++ } ++ ++ /* return the mW value scaled down to the correct factor of 10, ++ * adding in factor/2 to get proper rounding. */ ++ return ((nqdBm_to_mW_map[idx] + factor/2) / factor); ++} ++ ++uint8 ++bcm_mw_to_qdbm(uint16 mw) ++{ ++ uint8 qdbm; ++ int offset; ++ uint mw_uint = mw; ++ uint boundary; ++ ++ /* handle boundary case */ ++ if (mw_uint <= 1) ++ return 0; ++ ++ offset = QDBM_OFFSET; ++ ++ /* move mw into the range of the table */ ++ while (mw_uint < QDBM_TABLE_LOW_BOUND) { ++ mw_uint *= 10; ++ offset -= 40; ++ } ++ ++ for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { ++ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - nqdBm_to_mW_map[qdbm])/2; ++ if (mw_uint < boundary) break; ++ } ++ ++ qdbm += (uint8)offset; ++ ++ return(qdbm); ++} +diff -Naur linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_osl.c +--- linux.old/drivers/net/hnd/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/hnd/linux_osl.c 2006-04-06 15:34:15.000000000 +0200 +@@ -0,0 +1,708 @@ ++/* ++ * Linux OS Independent Layer ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ ++ ++#define LINUX_OSL ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef mips ++#include ++#endif ++#include ++ ++#define PCI_CFG_RETRY 10 ++ ++#define OS_HANDLE_MAGIC 0x1234abcd ++#define BCM_MEM_FILENAME_LEN 24 ++ ++typedef struct bcm_mem_link { ++ struct bcm_mem_link *prev; ++ struct bcm_mem_link *next; ++ uint size; ++ int line; ++ char file[BCM_MEM_FILENAME_LEN]; ++} bcm_mem_link_t; ++ ++struct os_handle { ++ uint magic; ++ void *pdev; ++ uint malloced; ++ uint failed; ++ bcm_mem_link_t *dbgmem_list; ++}; ++ ++static int16 linuxbcmerrormap[] = \ ++{ 0, /* 0 */ ++ -EINVAL, /* BCME_ERROR */ ++ -EINVAL, /* BCME_BADARG*/ ++ -EINVAL, /* BCME_BADOPTION*/ ++ -EINVAL, /* BCME_NOTUP */ ++ -EINVAL, /* BCME_NOTDOWN */ ++ -EINVAL, /* BCME_NOTAP */ ++ -EINVAL, /* BCME_NOTSTA */ ++ -EINVAL, /* BCME_BADKEYIDX */ ++ -EINVAL, /* BCME_RADIOOFF */ ++ -EINVAL, /* BCME_NOTBANDLOCKED */ ++ -EINVAL, /* BCME_NOCLK */ ++ -EINVAL, /* BCME_BADRATESET */ ++ -EINVAL, /* BCME_BADBAND */ ++ -E2BIG, /* BCME_BUFTOOSHORT */ ++ -E2BIG, /* BCME_BUFTOOLONG */ ++ -EBUSY, /* BCME_BUSY */ ++ -EINVAL, /* BCME_NOTASSOCIATED */ ++ -EINVAL, /* BCME_BADSSIDLEN */ ++ -EINVAL, /* BCME_OUTOFRANGECHAN */ ++ -EINVAL, /* BCME_BADCHAN */ ++ -EFAULT, /* BCME_BADADDR */ ++ -ENOMEM, /* BCME_NORESOURCE */ ++ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ ++ -EMSGSIZE, /* BCME_BADLENGTH */ ++ -EINVAL, /* BCME_NOTREADY */ ++ -EPERM, /* BCME_NOTPERMITTED */ ++ -ENOMEM, /* BCME_NOMEM */ ++ -EINVAL, /* BCME_ASSOCIATED */ ++ -ERANGE, /* BCME_RANGE */ ++ -EINVAL /* BCME_NOTFOUND */ ++}; ++ ++/* translate bcmerrors into linux errors*/ ++int ++osl_error(int bcmerror) ++{ ++ int abs_bcmerror; ++ int array_size = ARRAYSIZE(linuxbcmerrormap); ++ ++ abs_bcmerror = ABS(bcmerror); ++ ++ if (bcmerror > 0) ++ abs_bcmerror = 0; ++ ++ else if (abs_bcmerror >= array_size) ++ abs_bcmerror = BCME_ERROR; ++ ++ return linuxbcmerrormap[abs_bcmerror]; ++} ++ ++osl_t * ++osl_attach(void *pdev) ++{ ++ osl_t *osh; ++ ++ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); ++ ASSERT(osh); ++ ++ /* ++ * check the cases where ++ * 1.Error code Added to bcmerror table, but forgot to add it to the OS ++ * dependent error code ++ * 2. Error code is added to the bcmerror table, but forgot to add the ++ * corresponding errorstring(dummy call to bcmerrorstr) ++ */ ++ bcmerrorstr(0); ++ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); ++ ++ osh->magic = OS_HANDLE_MAGIC; ++ osh->malloced = 0; ++ osh->failed = 0; ++ osh->dbgmem_list = NULL; ++ osh->pdev = pdev; ++ ++ return osh; ++} ++ ++void ++osl_detach(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC)); ++ kfree(osh); ++} ++ ++void* ++osl_pktget(osl_t *osh, uint len, bool send) ++{ ++ struct sk_buff *skb; ++ ++ if ((skb = dev_alloc_skb(len)) == NULL) ++ return (NULL); ++ ++ skb_put(skb, len); ++ ++ /* ensure the cookie field is cleared */ ++ PKTSETCOOKIE(skb, NULL); ++ ++ return ((void*) skb); ++} ++ ++void ++osl_pktfree(void *p) ++{ ++ struct sk_buff *skb, *nskb; ++ ++ skb = (struct sk_buff*) p; ++ ++ /* perversion: we use skb->next to chain multi-skb packets */ ++ while (skb) { ++ nskb = skb->next; ++ skb->next = NULL; ++ if (skb->destructor) { ++ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ ++ dev_kfree_skb_any(skb); ++ } else { ++ /* can free immediately (even in_irq()) if destructor does not exist */ ++ dev_kfree_skb(skb); ++ } ++ skb = nskb; ++ } ++} ++ ++uint32 ++osl_pci_read_config(osl_t *osh, uint offset, uint size) ++{ ++ uint val; ++ uint retry=PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_read_config_dword(osh->pdev, offset, &val); ++ if (val != 0xffffffff) ++ break; ++ } while (retry--); ++ ++ ++ return (val); ++} ++ ++void ++osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) ++{ ++ uint retry=PCI_CFG_RETRY; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ /* only 4byte access supported */ ++ ASSERT(size == 4); ++ ++ do { ++ pci_write_config_dword(osh->pdev, offset, val); ++ if (offset!=PCI_BAR0_WIN) ++ break; ++ if (osl_pci_read_config(osh,offset,size) == val) ++ break; ++ } while (retry--); ++ ++} ++ ++/* return bus # for the pci device pointed by osh->pdev */ ++uint ++osl_pci_bus(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ ++ return ((struct pci_dev *)osh->pdev)->bus->number; ++} ++ ++/* return slot # for the pci device pointed by osh->pdev */ ++uint ++osl_pci_slot(osl_t *osh) ++{ ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ ++ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); ++} ++ ++static void ++osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) ++{ ++} ++ ++void ++osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) ++{ ++ osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); ++} ++ ++void ++osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) ++{ ++ osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); ++} ++ ++ ++#ifdef BCMDBG_MEM ++ ++void* ++osl_debug_malloc(osl_t *osh, uint size, int line, char* file) ++{ ++ bcm_mem_link_t *p; ++ char* basename; ++ ++ ASSERT(size); ++ ++ if ((p = (bcm_mem_link_t*)osl_malloc(osh, sizeof(bcm_mem_link_t) + size)) == NULL) ++ return (NULL); ++ ++ p->size = size; ++ p->line = line; ++ ++ basename = strrchr(file, '/'); ++ /* skip the '/' */ ++ if (basename) ++ basename++; ++ ++ if (!basename) ++ basename = file; ++ ++ strncpy(p->file, basename, BCM_MEM_FILENAME_LEN); ++ p->file[BCM_MEM_FILENAME_LEN - 1] = '\0'; ++ ++ /* link this block */ ++ p->prev = NULL; ++ p->next = osh->dbgmem_list; ++ if (p->next) ++ p->next->prev = p; ++ osh->dbgmem_list = p; ++ ++ return p + 1; ++} ++ ++void ++osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file) ++{ ++ bcm_mem_link_t *p = (bcm_mem_link_t *)((int8*)addr - sizeof(bcm_mem_link_t)); ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ if (p->size == 0) { ++ printk("osl_debug_mfree: double free on addr 0x%x size %d at line %d file %s\n", ++ (uint)addr, size, line, file); ++ ASSERT(p->size); ++ return; ++ } ++ ++ if (p->size != size) { ++ printk("osl_debug_mfree: dealloc size %d does not match alloc size %d on addr 0x%x at line %d file %s\n", ++ size, p->size, (uint)addr, line, file); ++ ASSERT(p->size == size); ++ return; ++ } ++ ++ /* unlink this block */ ++ if (p->prev) ++ p->prev->next = p->next; ++ if (p->next) ++ p->next->prev = p->prev; ++ if (osh->dbgmem_list == p) ++ osh->dbgmem_list = p->next; ++ p->next = p->prev = NULL; ++ ++ osl_mfree(osh, p, size + sizeof(bcm_mem_link_t)); ++} ++ ++char* ++osl_debug_memdump(osl_t *osh, char *buf, uint sz) ++{ ++ bcm_mem_link_t *p; ++ char *obuf; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ obuf = buf; ++ ++ buf += sprintf(buf, " Address\tSize\tFile:line\n"); ++ for (p = osh->dbgmem_list; p && ((buf - obuf) < (sz - 128)); p = p->next) ++ buf += sprintf(buf, "0x%08x\t%5d\t%s:%d\n", ++ (int)p + sizeof(bcm_mem_link_t), p->size, p->file, p->line); ++ ++ return (obuf); ++} ++ ++#endif /* BCMDBG_MEM */ ++ ++void* ++osl_malloc(osl_t *osh, uint size) ++{ ++ void *addr; ++ ++ /* only ASSERT if osh is defined */ ++ if (osh) ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ ++ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { ++ if(osh) ++ osh->failed++; ++ return (NULL); ++ } ++ if (osh) ++ osh->malloced += size; ++ ++ return (addr); ++} ++ ++void ++osl_mfree(osl_t *osh, void *addr, uint size) ++{ ++ if (osh) { ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ osh->malloced -= size; ++ } ++ kfree(addr); ++} ++ ++uint ++osl_malloced(osl_t *osh) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->malloced); ++} ++ ++uint osl_malloc_failed(osl_t *osh) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->failed); ++} ++ ++void* ++osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); ++} ++ ++void ++osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ ++ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); ++} ++ ++uint ++osl_dma_map(osl_t *osh, void *va, uint size, int direction) ++{ ++ int dir; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ return (pci_map_single(osh->pdev, va, size, dir)); ++} ++ ++void ++osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) ++{ ++ int dir; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ pci_unmap_single(osh->pdev, (uint32)pa, size, dir); ++} ++ ++#if defined(BINOSL) ++void ++osl_assert(char *exp, char *file, int line) ++{ ++ char tempbuf[255]; ++ ++ sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line); ++ panic(tempbuf); ++} ++#endif /* BCMDBG || BINOSL */ ++ ++void ++osl_delay(uint usec) ++{ ++ uint d; ++ ++ while (usec > 0) { ++ d = MIN(usec, 1000); ++ udelay(d); ++ usec -= d; ++ } ++} ++ ++/* ++ * BINOSL selects the slightly slower function-call-based binary compatible osl. ++ */ ++#ifdef BINOSL ++ ++int ++osl_printf(const char *format, ...) ++{ ++ va_list args; ++ char buf[1024]; ++ int len; ++ ++ /* sprintf into a local buffer because there *is* no "vprintk()".. */ ++ va_start(args, format); ++ len = vsprintf(buf, format, args); ++ va_end(args); ++ ++ if (len > sizeof (buf)) { ++ printk("osl_printf: buffer overrun\n"); ++ return (0); ++ } ++ ++ return (printk(buf)); ++} ++ ++int ++osl_sprintf(char *buf, const char *format, ...) ++{ ++ va_list args; ++ int rc; ++ ++ va_start(args, format); ++ rc = vsprintf(buf, format, args); ++ va_end(args); ++ return (rc); ++} ++ ++int ++osl_strcmp(const char *s1, const char *s2) ++{ ++ return (strcmp(s1, s2)); ++} ++ ++int ++osl_strncmp(const char *s1, const char *s2, uint n) ++{ ++ return (strncmp(s1, s2, n)); ++} ++ ++int ++osl_strlen(const char *s) ++{ ++ return (strlen(s)); ++} ++ ++char* ++osl_strcpy(char *d, const char *s) ++{ ++ return (strcpy(d, s)); ++} ++ ++char* ++osl_strncpy(char *d, const char *s, uint n) ++{ ++ return (strncpy(d, s, n)); ++} ++ ++void ++bcopy(const void *src, void *dst, int len) ++{ ++ memcpy(dst, src, len); ++} ++ ++int ++bcmp(const void *b1, const void *b2, int len) ++{ ++ return (memcmp(b1, b2, len)); ++} ++ ++void ++bzero(void *b, int len) ++{ ++ memset(b, '\0', len); ++} ++ ++uint32 ++osl_readl(volatile uint32 *r) ++{ ++ return (readl(r)); ++} ++ ++uint16 ++osl_readw(volatile uint16 *r) ++{ ++ return (readw(r)); ++} ++ ++uint8 ++osl_readb(volatile uint8 *r) ++{ ++ return (readb(r)); ++} ++ ++void ++osl_writel(uint32 v, volatile uint32 *r) ++{ ++ writel(v, r); ++} ++ ++void ++osl_writew(uint16 v, volatile uint16 *r) ++{ ++ writew(v, r); ++} ++ ++void ++osl_writeb(uint8 v, volatile uint8 *r) ++{ ++ writeb(v, r); ++} ++ ++void * ++osl_uncached(void *va) ++{ ++#ifdef mips ++ return ((void*)KSEG1ADDR(va)); ++#else ++ return ((void*)va); ++#endif ++} ++ ++uint ++osl_getcycles(void) ++{ ++ uint cycles; ++ ++#if defined(mips) ++ cycles = read_c0_count() * 2; ++#elif defined(__i386__) ++ rdtscl(cycles); ++#else ++ cycles = 0; ++#endif ++ return cycles; ++} ++ ++void * ++osl_reg_map(uint32 pa, uint size) ++{ ++ return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); ++} ++ ++void ++osl_reg_unmap(void *va) ++{ ++ iounmap(va); ++} ++ ++int ++osl_busprobe(uint32 *val, uint32 addr) ++{ ++#ifdef mips ++ return get_dbe(*val, (uint32*)addr); ++#else ++ *val = readl(addr); ++ return 0; ++#endif ++} ++ ++uchar* ++osl_pktdata(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->data); ++} ++ ++uint ++osl_pktlen(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->len); ++} ++ ++uint ++osl_pktheadroom(osl_t *osh, void *skb) ++{ ++ return (uint) skb_headroom((struct sk_buff *) skb); ++} ++ ++uint ++osl_pkttailroom(osl_t *osh, void *skb) ++{ ++ return (uint) skb_tailroom((struct sk_buff *) skb); ++} ++ ++void* ++osl_pktnext(osl_t *osh, void *skb) ++{ ++ return (((struct sk_buff*)skb)->next); ++} ++ ++void ++osl_pktsetnext(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->next = (struct sk_buff*)x; ++} ++ ++void ++osl_pktsetlen(osl_t *osh, void *skb, uint len) ++{ ++ __skb_trim((struct sk_buff*)skb, len); ++} ++ ++uchar* ++osl_pktpush(osl_t *osh, void *skb, int bytes) ++{ ++ return (skb_push((struct sk_buff*)skb, bytes)); ++} ++ ++uchar* ++osl_pktpull(osl_t *osh, void *skb, int bytes) ++{ ++ return (skb_pull((struct sk_buff*)skb, bytes)); ++} ++ ++void* ++osl_pktdup(osl_t *osh, void *skb) ++{ ++ return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC)); ++} ++ ++void* ++osl_pktcookie(void *skb) ++{ ++ return ((void*)((struct sk_buff*)skb)->csum); ++} ++ ++void ++osl_pktsetcookie(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->csum = (uint)x; ++} ++ ++void* ++osl_pktlink(void *skb) ++{ ++ return (((struct sk_buff*)skb)->prev); ++} ++ ++void ++osl_pktsetlink(void *skb, void *x) ++{ ++ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; ++} ++ ++uint ++osl_pktprio(void *skb) ++{ ++ return (((struct sk_buff*)skb)->priority); ++} ++ ++void ++osl_pktsetprio(void *skb, uint x) ++{ ++ ((struct sk_buff*)skb)->priority = x; ++} ++ ++ ++#endif /* BINOSL */ +diff -Naur linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils.c +--- linux.old/drivers/net/hnd/sbutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/hnd/sbutils.c 2006-04-06 15:34:15.000000000 +0200 +@@ -0,0 +1,2837 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of the SiliconBackplane-based Broadcom chips. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* debug/trace */ ++#define SB_ERROR(args) ++ ++ ++typedef uint32 (*sb_intrsoff_t)(void *intr_arg); ++typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg); ++typedef bool (*sb_intrsenabled_t)(void *intr_arg); ++ ++/* misc sb info needed by some of the routines */ ++typedef struct sb_info { ++ ++ struct sb_pub sb; /* back plane public state(must be first field of sb_info */ ++ ++ void *osh; /* osl os handle */ ++ void *sdh; /* bcmsdh handle */ ++ ++ void *curmap; /* current regs va */ ++ void *regs[SB_MAXCORES]; /* other regs va */ ++ ++ uint curidx; /* current core index */ ++ uint dev_coreid; /* the core provides driver functions */ ++ ++ bool memseg; /* flag to toggle MEM_SEG register */ ++ ++ uint gpioidx; /* gpio control core index */ ++ uint gpioid; /* gpio control coretype */ ++ ++ uint numcores; /* # discovered cores */ ++ uint coreid[SB_MAXCORES]; /* id of each core */ ++ ++ void *intr_arg; /* interrupt callback function arg */ ++ sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */ ++ sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */ ++ sb_intrsenabled_t intrsenabled_fn; /* function to check if chip interrupts are enabled */ ++ ++} sb_info_t; ++ ++/* local prototypes */ ++static sb_info_t * BCMINIT(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz); ++static void BCMINIT(sb_scan)(sb_info_t *si); ++static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val); ++static uint _sb_coreidx(sb_info_t *si); ++static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit); ++static uint BCMINIT(sb_pcidev2chip)(uint pcidev); ++static uint BCMINIT(sb_chip2numcores)(uint chip); ++static bool sb_ispcie(sb_info_t *si); ++static bool sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen); ++static int sb_pci_fixcfg(sb_info_t *si); ++ ++/* routines to access mdio slave device registers */ ++static int sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint readdr, uint val); ++static void BCMINIT(sb_war30841)(sb_info_t *si); ++ ++/* delay needed between the mdio control/ mdiodata register data access */ ++#define PR28829_DELAY() OSL_DELAY(10) ++ ++ ++/* global variable to indicate reservation/release of gpio's*/ ++static uint32 sb_gpioreservation = 0; ++ ++#define SB_INFO(sbh) (sb_info_t*)sbh ++#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val))) ++#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE)) ++#define GOODREGS(regs) ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE)) ++#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) ++#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) ++#define BADIDX (SB_MAXCORES+1) ++#define NOREV -1 ++ ++#define PCI(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI)) ++#define PCIE(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCIE)) ++ ++/* sonicsrev */ ++#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) ++#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) ++ ++#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr)) ++#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v)) ++#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v))) ++#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v))) ++ ++/* ++ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ ++ * after core switching to avoid invalid register accesss inside ISR. ++ */ ++#define INTR_OFF(si, intr_val) \ ++ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } ++#define INTR_RESTORE(si, intr_val) \ ++ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } ++ ++/* dynamic clock control defines */ ++#define LPOMINFREQ 25000 /* low power oscillator min */ ++#define LPOMAXFREQ 43000 /* low power oscillator max */ ++#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ ++#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ ++#define PCIMINFREQ 25000000 /* 25 MHz */ ++#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ ++ ++#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ ++#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ ++ ++#define MIN_DUMPBUFLEN 32 /* debug */ ++ ++/* different register spaces to access thr'u pcie indirect access*/ ++#define PCIE_CONFIGREGS 1 ++#define PCIE_PCIEREGS 2 ++ ++/* GPIO Based LED powersave defines */ ++#define DEFAULT_GPIO_ONTIME 10 ++#define DEFAULT_GPIO_OFFTIME 90 ++ ++#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) ++ ++static uint32 ++sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr) ++{ ++ uint8 tmp; ++ uint32 val, intr_val = 0; ++ ++ ++ /* ++ * compact flash only has 11 bits address, while we needs 12 bits address. ++ * MEM_SEG will be OR'd with other 11 bits address in hardware, ++ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). ++ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special ++ */ ++ if(si->memseg) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ ++ } ++ ++ val = R_REG(sbr); ++ ++ if(si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ INTR_RESTORE(si, intr_val); ++ } ++ ++ return (val); ++} ++ ++static void ++sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v) ++{ ++ uint8 tmp; ++ volatile uint32 dummy; ++ uint32 intr_val = 0; ++ ++ ++ /* ++ * compact flash only has 11 bits address, while we needs 12 bits address. ++ * MEM_SEG will be OR'd with other 11 bits address in hardware, ++ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). ++ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special ++ */ ++ if(si->memseg) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ ++ } ++ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++#ifdef IL_BIGENDIAN ++ dummy = R_REG(sbr); ++ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++#else ++ dummy = R_REG(sbr); ++ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++ dummy = R_REG(sbr); ++ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); ++#endif ++ } else ++ W_REG(sbr, v); ++ ++ if(si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ INTR_RESTORE(si, intr_val); ++ } ++} ++ ++/* ++ * Allocate a sb handle. ++ * devid - pci device id (used to determine chip#) ++ * osh - opaque OS handle ++ * regs - virtual address of initial core registers ++ * bustype - pci/pcmcia/sb/sdio/etc ++ * vars - pointer to a pointer area for "environment" variables ++ * varsz - pointer to int to return the size of the vars ++ */ ++sb_t * ++BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz) ++{ ++ sb_info_t *si; ++ ++ /* alloc sb_info_t */ ++ if ((si = MALLOC(osh, sizeof (sb_info_t))) == NULL) { ++ SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); ++ return (NULL); ++ } ++ ++ if (BCMINIT(sb_doattach)(si, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { ++ MFREE(osh, si, sizeof (sb_info_t)); ++ return (NULL); ++ } ++ return (sb_t *)si; ++} ++ ++/* Using sb_kattach depends on SB_BUS support, either implicit */ ++/* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */ ++#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS) ++ ++/* global kernel resource */ ++static sb_info_t ksi; ++ ++/* generic kernel variant of sb_attach() */ ++sb_t * ++BCMINITFN(sb_kattach)() ++{ ++ uint32 *regs; ++ ++ if (ksi.curmap == NULL) { ++ uint32 cid; ++ ++ regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); ++ cid = R_REG((uint32 *)regs); ++ if (((cid & CID_ID_MASK) == BCM4712_DEVICE_ID) && ++ ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) && ++ ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) { ++ uint32 *scc, val; ++ ++ scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); ++ val = R_REG(scc); ++ SB_ERROR((" initial scc = 0x%x\n", val)); ++ val |= SCC_SS_XTAL; ++ W_REG(scc, val); ++ } ++ ++ if (BCMINIT(sb_doattach)(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, ++ SB_BUS, NULL, NULL, NULL) == NULL) { ++ return NULL; ++ } ++ } ++ ++ return (sb_t *)&ksi; ++} ++#endif ++ ++static sb_info_t * ++BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz) ++{ ++ uint origidx; ++ chipcregs_t *cc; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ ASSERT(GOODREGS(regs)); ++ ++ bzero((uchar*)si, sizeof (sb_info_t)); ++ ++ si->sb.buscoreidx = si->gpioidx = BADIDX; ++ ++ si->osh = osh; ++ si->curmap = regs; ++ si->sdh = sdh; ++ ++ /* check to see if we are a sb core mimic'ing a pci core */ ++ if (bustype == PCI_BUS) { ++ if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff) ++ bustype = SB_BUS; ++ else ++ bustype = PCI_BUS; ++ } ++ ++ si->sb.bustype = bustype; ++ if (si->sb.bustype != BUSTYPE(si->sb.bustype)) { ++ SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n", ++ si->sb.bustype, BUSTYPE(si->sb.bustype))); ++ return NULL; ++ } ++ ++ /* need to set memseg flag for CF card first before any sb registers access */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) ++ si->memseg = TRUE; ++ ++ /* kludge to enable the clock on the 4306 which lacks a slowclock */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) ++ sb_clkctl_xtal(&si->sb, XTAL|PLL, ON); ++ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(osh, PCI_BAR0_WIN, sizeof (uint32)); ++ if (!GOODCOREADDR(w)) ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32), SB_ENUM_BASE); ++ } ++ ++ /* initialize current core index value */ ++ si->curidx = _sb_coreidx(si); ++ ++ if (si->curidx == BADIDX) { ++ SB_ERROR(("sb_doattach: bad core index\n")); ++ return NULL; ++ } ++ ++ /* get sonics backplane revision */ ++ sb = REGS2SB(si->curmap); ++ si->sb.sonicsrev = (R_SBREG(si, &(sb)->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; ++ ++ /* keep and reuse the initial register mapping */ ++ origidx = si->curidx; ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ si->regs[origidx] = regs; ++ ++ /* is core-0 a chipcommon core? */ ++ si->numcores = 1; ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0); ++ if (sb_coreid(&si->sb) != SB_CC) ++ cc = NULL; ++ ++ /* determine chip id and rev */ ++ if (cc) { ++ /* chip common core found! */ ++ si->sb.chip = R_REG(&cc->chipid) & CID_ID_MASK; ++ si->sb.chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; ++ si->sb.chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; ++ } else { ++ /* The only pcmcia chip without a chipcommon core is a 4301 */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) ++ devid = BCM4301_DEVICE_ID; ++ ++ /* no chip common core -- must convert device id to chip id */ ++ if ((si->sb.chip = BCMINIT(sb_pcidev2chip)(devid)) == 0) { ++ SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid)); ++ sb_setcoreidx(&si->sb, origidx); ++ return NULL; ++ } ++ } ++ ++ /* get chipcommon rev */ ++ si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV; ++ ++ /* determine numcores */ ++ if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6))) ++ si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; ++ else ++ si->numcores = BCMINIT(sb_chip2numcores)(si->sb.chip); ++ ++ /* return to original core */ ++ sb_setcoreidx(&si->sb, origidx); ++ ++ /* sanity checks */ ++ ASSERT(si->sb.chip); ++ ++ /* scan for cores */ ++ BCMINIT(sb_scan)(si); ++ ++ /* fixup necessary chip/core configurations */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ if (sb_pci_fixcfg(si)) { ++ SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n")); ++ return NULL; ++ } ++ } ++ ++ /* srom_var_init() depends on sb_scan() info */ ++ if (srom_var_init(si, si->sb.bustype, si->curmap, osh, vars, varsz)) { ++ SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n")); ++ return (NULL); ++ } ++ ++ if (cc == NULL) { ++ /* ++ * The chip revision number is hardwired into all ++ * of the pci function config rev fields and is ++ * independent from the individual core revision numbers. ++ * For example, the "A0" silicon of each chip is chip rev 0. ++ * For PCMCIA we get it from the CIS instead. ++ */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++ ASSERT(vars); ++ si->sb.chiprev = getintvar(*vars, "chiprev"); ++ } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32)); ++ si->sb.chiprev = w & 0xff; ++ } else ++ si->sb.chiprev = 0; ++ } ++ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++ w = getintvar(*vars, "regwindowsz"); ++ si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; ++ } ++ ++ /* gpio control core is required */ ++ if (!GOODIDX(si->gpioidx)) { ++ SB_ERROR(("sb_doattach: gpio control core not found\n")); ++ return NULL; ++ } ++ ++ /* get boardtype and boardrev */ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ /* do a pci config read to get subsystem id and subvendor id */ ++ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32)); ++ si->sb.boardvendor = w & 0xffff; ++ si->sb.boardtype = (w >> 16) & 0xffff; ++ break; ++ ++ case PCMCIA_BUS: ++ case SDIO_BUS: ++ si->sb.boardvendor = getintvar(*vars, "manfid"); ++ si->sb.boardtype = getintvar(*vars, "prodid"); ++ break; ++ ++ case SB_BUS: ++ case JTAG_BUS: ++ si->sb.boardvendor = VENDOR_BROADCOM; ++ if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0) ++ si->sb.boardtype = 0xffff; ++ break; ++ } ++ ++ if (si->sb.boardtype == 0) { ++ SB_ERROR(("sb_doattach: unknown board type\n")); ++ ASSERT(si->sb.boardtype); ++ } ++ ++ /* setup the GPIO based LED powersave register */ ++ if (si->sb.ccrev >= 16) { ++ w = getintvar(*vars, "gpiotimerval"); ++ if (!w) ++ w = DEFAULT_GPIOTIMERVAL; ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); ++ } ++ ++ ++ return (si); ++} ++ ++uint ++sb_coreid(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); ++} ++ ++uint ++sb_coreidx(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->curidx); ++} ++ ++/* return current index of core */ ++static uint ++_sb_coreidx(sb_info_t *si) ++{ ++ sbconfig_t *sb; ++ uint32 sbaddr = 0; ++ ++ ASSERT(si); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ sb = REGS2SB(si->curmap); ++ sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0)); ++ break; ++ ++ case PCI_BUS: ++ sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32)); ++ break; ++ ++ case PCMCIA_BUS: { ++ uint8 tmp = 0; ++ ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); ++ sbaddr = (uint)tmp << 12; ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); ++ sbaddr |= (uint)tmp << 16; ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); ++ sbaddr |= (uint)tmp << 24; ++ break; ++ } ++ ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ sbaddr = (uint32)si->curmap; ++ break; ++#endif /* BCMJTAG */ ++ ++ default: ++ ASSERT(0); ++ } ++ ++ if (!GOODCOREADDR(sbaddr)) ++ return BADIDX; ++ ++ return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE); ++} ++ ++uint ++sb_corevendor(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); ++} ++ ++uint ++sb_corerev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint sbidh; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ sbidh = R_SBREG(si, &(sb)->sbidhigh); ++ ++ return (SBCOREREV(sbidh)); ++} ++ ++void * ++sb_osh(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return si->osh; ++} ++ ++#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK) ++ ++/* set/clear sbtmstatelow core-specific flags */ ++uint32 ++sb_coreflags(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SBTML_ALLOW) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatelow, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatelow) & SBTML_ALLOW); ++} ++ ++/* set/clear sbtmstatehigh core-specific flags */ ++uint32 ++sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SBTMH_FL_MASK) == 0); ++ ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatehigh, w); ++ } ++ ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK); ++} ++ ++/* caller needs to take care of core-specific bist hazards */ ++int ++sb_corebist(sb_t *sbh, uint coreid, uint coreunit) ++{ ++ uint32 sblo; ++ uint coreidx; ++ sb_info_t *si; ++ int result = 0; ++ ++ si = SB_INFO(sbh); ++ ++ coreidx = sb_findcoreidx(si, coreid, coreunit); ++ if (!GOODIDX(coreidx)) ++ result = BCME_ERROR; ++ else { ++ sblo = sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), 0, 0); ++ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, (sblo | SBTML_FGC | SBTML_BE)); ++ ++ SPINWAIT(((sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTD) == 0), 100000); ++ ++ if (sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTF) ++ result = BCME_ERROR; ++ ++ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, sblo); ++ } ++ ++ return result; ++} ++ ++bool ++sb_iscoreup(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ ++ return ((R_SBREG(si, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK); ++} ++ ++/* ++ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, ++ * switch back to the original core, and return the new value. ++ */ ++static uint ++sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val) ++{ ++ uint origidx; ++ uint32 *r; ++ uint w; ++ uint intr_val = 0; ++ ++ ASSERT(GOODIDX(coreidx)); ++ ASSERT(regoff < SB_CORE_SIZE); ++ ASSERT((val & ~mask) == 0); ++ ++ INTR_OFF(si, intr_val); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ /* switch core */ ++ r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff); ++ ++ /* mask and set */ ++ if (mask || val) { ++ if (regoff >= SBCONFIGOFF) { ++ w = (R_SBREG(si, r) & ~mask) | val; ++ W_SBREG(si, r, w); ++ } else { ++ w = (R_REG(r) & ~mask) | val; ++ W_REG(r, w); ++ } ++ } ++ ++ /* readback */ ++ if (regoff >= SBCONFIGOFF) ++ w = R_SBREG(si, r); ++ else ++ w = R_REG(r); ++ ++ /* restore core index */ ++ if (origidx != coreidx) ++ sb_setcoreidx(&si->sb, origidx); ++ ++ INTR_RESTORE(si, intr_val); ++ return (w); ++} ++ ++#define DWORD_ALIGN(x) (x & ~(0x03)) ++#define BYTE_POS(x) (x & 0x3) ++#define WORD_POS(x) (x & 0x1) ++ ++#define BYTE_SHIFT(x) (8 * BYTE_POS(x)) ++#define WORD_SHIFT(x) (16 * WORD_POS(x)) ++ ++#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF) ++#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF) ++ ++#define read_pci_cfg_byte(a) \ ++ (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff) ++ ++#define read_pci_cfg_write(a) \ ++ (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff) ++ ++ ++/* return TRUE if requested capability exists in the PCI config space */ ++static bool ++sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen) ++{ ++ uint8 cap_id; ++ uint8 cap_ptr; ++ uint32 bufsize; ++ uint8 byte_val; ++ ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) ++ return FALSE; ++ ++ /* check for Header type 0*/ ++ byte_val = read_pci_cfg_byte(PCI_CFG_HDR); ++ if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) ++ return FALSE; ++ ++ /* check if the capability pointer field exists */ ++ byte_val = read_pci_cfg_byte(PCI_CFG_STAT); ++ if (!(byte_val & PCI_CAPPTR_PRESENT)) ++ return FALSE; ++ ++ cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR); ++ /* check if the capability pointer is 0x00 */ ++ if (cap_ptr == 0x00) ++ return FALSE; ++ ++ ++ /* loop thr'u the capability list and see if the pcie capabilty exists */ ++ ++ cap_id = read_pci_cfg_byte(cap_ptr); ++ ++ while (cap_id != req_cap_id) { ++ cap_ptr = read_pci_cfg_byte((cap_ptr+1)); ++ if (cap_ptr == 0x00) break; ++ cap_id = read_pci_cfg_byte(cap_ptr); ++ } ++ if (cap_id != req_cap_id) { ++ return FALSE; ++ } ++ /* found the caller requested capability */ ++ if ((buf != NULL) && (buflen != NULL)) { ++ bufsize = *buflen; ++ if (!bufsize) goto end; ++ *buflen = 0; ++ /* copy the cpability data excluding cap ID and next ptr */ ++ cap_ptr += 2; ++ if ((bufsize + cap_ptr) > SZPCR) ++ bufsize = SZPCR - cap_ptr; ++ *buflen = bufsize; ++ while (bufsize--) { ++ *buf = read_pci_cfg_byte(cap_ptr); ++ cap_ptr++; ++ buf++; ++ } ++ } ++end: ++ return TRUE; ++} ++ ++/* return TRUE if PCIE capability exists the pci config space */ ++static bool ++sb_ispcie(sb_info_t *si) ++{ ++ return(sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL)); ++} ++ ++/* scan the sb enumerated space to identify all cores */ ++static void ++BCMINITFN(sb_scan)(sb_info_t *si) ++{ ++ uint origidx; ++ uint i; ++ bool pci; ++ bool pcie; ++ uint pciidx; ++ uint pcieidx; ++ uint pcirev; ++ uint pcierev; ++ ++ ++ ++ /* numcores should already be set */ ++ ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); ++ ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); ++ ++ si->sb.buscorerev = NOREV; ++ si->sb.buscoreidx = BADIDX; ++ ++ si->gpioidx = BADIDX; ++ ++ pci = pcie = FALSE; ++ pcirev = pcierev = NOREV; ++ pciidx = pcieidx = BADIDX; ++ ++ for (i = 0; i < si->numcores; i++) { ++ sb_setcoreidx(&si->sb, i); ++ si->coreid[i] = sb_coreid(&si->sb); ++ ++ if (si->coreid[i] == SB_PCI) { ++ pciidx = i; ++ pcirev = sb_corerev(&si->sb); ++ pci = TRUE; ++ } else if (si->coreid[i] == SB_PCIE) { ++ pcieidx = i; ++ pcierev = sb_corerev(&si->sb); ++ pcie = TRUE; ++ } else if (si->coreid[i] == SB_PCMCIA) { ++ si->sb.buscorerev = sb_corerev(&si->sb); ++ si->sb.buscoretype = si->coreid[i]; ++ si->sb.buscoreidx = i; ++ } ++ } ++ if (pci && pcie) { ++ if (sb_ispcie(si)) ++ pci = FALSE; ++ else ++ pcie = FALSE; ++ } ++ if (pci) { ++ si->sb.buscoretype = SB_PCI; ++ si->sb.buscorerev = pcirev; ++ si->sb.buscoreidx = pciidx; ++ } ++ else if (pcie) { ++ si->sb.buscoretype = SB_PCIE; ++ si->sb.buscorerev = pcierev; ++ si->sb.buscoreidx = pcieidx; ++ } ++ ++ /* ++ * Find the gpio "controlling core" type and index. ++ * Precedence: ++ * - if there's a chip common core - use that ++ * - else if there's a pci core (rev >= 2) - use that ++ * - else there had better be an extif core (4710 only) ++ */ ++ if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) { ++ si->gpioidx = sb_findcoreidx(si, SB_CC, 0); ++ si->gpioid = SB_CC; ++ } else if (PCI(si) && (si->sb.buscorerev >= 2)) { ++ si->gpioidx = si->sb.buscoreidx; ++ si->gpioid = SB_PCI; ++ } else if (sb_findcoreidx(si, SB_EXTIF, 0)) { ++ si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0); ++ si->gpioid = SB_EXTIF; ++ } else ++ ASSERT(si->gpioidx != BADIDX); ++ ++ /* return to original core index */ ++ sb_setcoreidx(&si->sb, origidx); ++} ++ ++/* may be called with core in reset */ ++void ++sb_detach(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ ++ if (si == NULL) ++ return; ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ for (idx = 0; idx < SB_MAXCORES; idx++) ++ if (si->regs[idx]) { ++ REG_UNMAP(si->regs[idx]); ++ si->regs[idx] = NULL; ++ } ++ ++ if (si != &ksi) ++ MFREE(si->osh, si, sizeof (sb_info_t)); ++} ++ ++/* use pci dev id to determine chip id for chips not having a chipcommon core */ ++static uint ++BCMINITFN(sb_pcidev2chip)(uint pcidev) ++{ ++ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) ++ return (BCM4710_DEVICE_ID); ++ if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID)) ++ return (BCM4402_DEVICE_ID); ++ if (pcidev == BCM4401_ENET_ID) ++ return (BCM4402_DEVICE_ID); ++ if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID)) ++ return (BCM4307_DEVICE_ID); ++ if (pcidev == BCM4301_DEVICE_ID) ++ return (BCM4301_DEVICE_ID); ++ ++ return (0); ++} ++ ++/* convert chip number to number of i/o cores */ ++static uint ++BCMINITFN(sb_chip2numcores)(uint chip) ++{ ++ if (chip == BCM4710_DEVICE_ID) ++ return (9); ++ if (chip == BCM4402_DEVICE_ID) ++ return (3); ++ if ((chip == BCM4301_DEVICE_ID) || (chip == BCM4307_DEVICE_ID)) ++ return (5); ++ if (chip == BCM4306_DEVICE_ID) /* < 4306c0 */ ++ return (6); ++ if (chip == BCM4704_DEVICE_ID) ++ return (9); ++ if (chip == BCM5365_DEVICE_ID) ++ return (7); ++ ++ SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); ++ ASSERT(0); ++ return (1); ++} ++ ++/* return index of coreid or BADIDX if not found */ ++static uint ++sb_findcoreidx( sb_info_t *si, uint coreid, uint coreunit) ++{ ++ uint found; ++ uint i; ++ ++ found = 0; ++ ++ for (i = 0; i < si->numcores; i++) ++ if (si->coreid[i] == coreid) { ++ if (found == coreunit) ++ return (i); ++ found++; ++ } ++ ++ return (BADIDX); ++} ++ ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcoreidx(sb_t *sbh, uint coreidx) ++{ ++ sb_info_t *si; ++ uint32 sbaddr; ++ uint8 tmp; ++ ++ si = SB_INFO(sbh); ++ ++ if (coreidx >= si->numcores) ++ return (NULL); ++ ++ /* ++ * If the user has provided an interrupt mask enabled function, ++ * then assert interrupts are disabled before switching the core. ++ */ ++ ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg)); ++ ++ sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); ++ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; ++ ++ case PCI_BUS: ++ /* point bar0 window */ ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); ++ break; ++ ++ case PCMCIA_BUS: ++ tmp = (sbaddr >> 12) & 0x0f; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); ++ tmp = (sbaddr >> 16) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); ++ tmp = (sbaddr >> 24) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); ++ break; ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void *)sbaddr; ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; ++#endif /* BCMJTAG */ ++ } ++ ++ si->curidx = coreidx; ++ ++ return (si->curmap); ++} ++ ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcore(sb_t *sbh, uint coreid, uint coreunit) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ idx = sb_findcoreidx(si, coreid, coreunit); ++ if (!GOODIDX(idx)) ++ return (NULL); ++ ++ return (sb_setcoreidx(sbh, idx)); ++} ++ ++/* return chip number */ ++uint ++BCMINITFN(sb_chip)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chip); ++} ++ ++/* return chip revision number */ ++uint ++BCMINITFN(sb_chiprev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chiprev); ++} ++ ++/* return chip common revision number */ ++uint ++BCMINITFN(sb_chipcrev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.ccrev); ++} ++ ++/* return chip package option */ ++uint ++BCMINITFN(sb_chippkg)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.chippkg); ++} ++ ++/* return PCI core rev. */ ++uint ++BCMINITFN(sb_pcirev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.buscorerev); ++} ++ ++bool ++BCMINITFN(sb_war16165)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (PCI(si) && (si->sb.buscorerev <= 10)); ++} ++ ++static void ++BCMINITFN(sb_war30841)(sb_info_t *si) ++{ ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); ++} ++ ++/* return PCMCIA core rev. */ ++uint ++BCMINITFN(sb_pcmciarev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.buscorerev); ++} ++ ++/* return board vendor id */ ++uint ++BCMINITFN(sb_boardvendor)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.boardvendor); ++} ++ ++/* return boardtype */ ++uint ++BCMINITFN(sb_boardtype)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ char *var; ++ ++ si = SB_INFO(sbh); ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) { ++ /* boardtype format is a hex string */ ++ si->sb.boardtype = getintvar(NULL, "boardtype"); ++ ++ /* backward compatibility for older boardtype string format */ ++ if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) { ++ if (!strcmp(var, "bcm94710dev")) ++ si->sb.boardtype = BCM94710D_BOARD; ++ else if (!strcmp(var, "bcm94710ap")) ++ si->sb.boardtype = BCM94710AP_BOARD; ++ else if (!strcmp(var, "bu4710")) ++ si->sb.boardtype = BU4710_BOARD; ++ else if (!strcmp(var, "bcm94702mn")) ++ si->sb.boardtype = BCM94702MN_BOARD; ++ else if (!strcmp(var, "bcm94710r1")) ++ si->sb.boardtype = BCM94710R1_BOARD; ++ else if (!strcmp(var, "bcm94710r4")) ++ si->sb.boardtype = BCM94710R4_BOARD; ++ else if (!strcmp(var, "bcm94702cpci")) ++ si->sb.boardtype = BCM94702CPCI_BOARD; ++ else if (!strcmp(var, "bcm95380_rr")) ++ si->sb.boardtype = BCM95380RR_BOARD; ++ } ++ } ++ ++ return (si->sb.boardtype); ++} ++ ++/* return bus type of sbh device */ ++uint ++sb_bus(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.bustype); ++} ++ ++/* return bus core type */ ++uint ++sb_buscoretype(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (si->sb.buscoretype); ++} ++ ++/* return bus core revision */ ++uint ++sb_buscorerev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ si = SB_INFO(sbh); ++ ++ return (si->sb.buscorerev); ++} ++ ++/* return list of found cores */ ++uint ++sb_corelist(sb_t *sbh, uint coreid[]) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint))); ++ return (si->numcores); ++} ++ ++/* return current register mapping */ ++void * ++sb_coreregs(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ ++ return (si->curmap); ++} ++ ++ ++/* do buffered registers update */ ++void ++sb_commit(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ ++ origidx = si->curidx; ++ ASSERT(GOODIDX(origidx)); ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch over to chipcommon core if there is one, else use pci */ ++ if (si->sb.ccrev != NOREV) { ++ chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(&ccregs->broadcastaddress, SB_COMMIT); ++ W_REG(&ccregs->broadcastdata, 0x0); ++ } else if (PCI(si)) { ++ sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(&pciregs->bcastaddr, SB_COMMIT); ++ W_REG(&pciregs->bcastdata, 0x0); ++ } else ++ ASSERT(0); ++ ++ /* restore core index */ ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++} ++ ++/* reset and re-enable a core */ ++void ++sb_core_reset(sb_t *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ volatile uint32 dummy; ++ ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* ++ * Must do the disable sequence first to work for arbitrary current core state. ++ */ ++ sb_core_disable(sbh, bits); ++ ++ /* ++ * Now do the initialization sequence. ++ */ ++ ++ /* set reset while enabling the clock and forcing them on throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ ++ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) { ++ W_SBREG(si, &sb->sbtmstatehigh, 0); ++ } ++ if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { ++ AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); ++ } ++ ++ /* clear reset and allow it to propagate throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ ++ /* leave clock enabled */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++} ++ ++void ++sb_core_tofixup(sb_t *sbh) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ if ( (BUSTYPE(si->sb.bustype) != PCI_BUS) || PCIE(si) || (PCI(si) && (si->sb.buscorerev >= 5)) ) ++ return; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x5 << SBIMCL_RTO_SHIFT) | 0x3); ++ } else { ++ if (sb_coreid(sbh) == SB_PCI) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ } else { ++ SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); ++ } ++ } ++ ++ sb_commit(sbh); ++} ++ ++/* ++ * Set the initiator timeout for the "master core". ++ * The master core is defined to be the core in control ++ * of the chip and so it issues accesses to non-memory ++ * locations (Because of dma *any* core can access memeory). ++ * ++ * The routine uses the bus to decide who is the master: ++ * SB_BUS => mips ++ * JTAG_BUS => chipc ++ * PCI_BUS => pci or pcie ++ * PCMCIA_BUS => pcmcia ++ * SDIO_BUS => pcmcia ++ * ++ * This routine exists so callers can disable initiator ++ * timeouts so accesses to very slow devices like otp ++ * won't cause an abort. The routine allows arbitrary ++ * settings of the service and request timeouts, though. ++ * ++ * Returns the timeout state before changing it or -1 ++ * on error. ++ */ ++ ++#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) ++ ++uint32 ++sb_set_initiator_to(sb_t *sbh, uint32 to) ++{ ++ sb_info_t *si; ++ uint origidx, idx; ++ uint intr_val = 0; ++ uint32 tmp, ret = 0xffffffff; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ if ((to & ~TO_MASK) != 0) ++ return ret; ++ ++ /* Figure out the master core */ ++ idx = BADIDX; ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ idx = si->sb.buscoreidx; ++ break; ++ case JTAG_BUS: ++ idx = SB_CC_IDX; ++ break; ++ case PCMCIA_BUS: ++ case SDIO_BUS: ++ idx = sb_findcoreidx(si, SB_PCMCIA, 0); ++ break; ++ case SB_BUS: ++ if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX) ++ idx = sb_findcoreidx(si, SB_MIPS, 0); ++ break; ++ default: ++ ASSERT(0); ++ } ++ if (idx == BADIDX) ++ return ret; ++ ++ INTR_OFF(si, intr_val); ++ origidx = sb_coreidx(sbh); ++ ++ sb = REGS2SB(sb_setcoreidx(sbh, idx)); ++ ++ tmp = R_SBREG(si, &sb->sbimconfiglow); ++ ret = tmp & TO_MASK; ++ W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); ++ ++ sb_commit(sbh); ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return ret; ++} ++ ++void ++sb_core_disable(sb_t *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ volatile uint32 dummy; ++ uint32 rej; ++ sbconfig_t *sb; ++ ++ si = SB_INFO(sbh); ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ /* if core is already in reset, just return */ ++ if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET) ++ return; ++ ++ /* reject value changed between sonics 2.2 and 2.3 */ ++ if (si->sb.sonicsrev == SONICS_2_2) ++ rej = (1 << SBTML_REJ_SHIFT); ++ else ++ rej = (2 << SBTML_REJ_SHIFT); ++ ++ /* if clocks are not enabled, put into reset and return */ ++ if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0) ++ goto disable; ++ ++ /* set target reject and spin until busy is clear (preserve core-specific bits) */ ++ OR_SBREG(si, &sb->sbtmstatelow, rej); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); ++ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) { ++ OR_SBREG(si, &sb->sbimstate, SBIM_RJ); ++ dummy = R_SBREG(si, &sb->sbimstate); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000); ++ } ++ ++ /* set reset and reject while enabling the clocks */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(10); ++ ++ /* don't forget to clear the initiator reject bit */ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) ++ AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ); ++ ++disable: ++ /* leave reset and reject asserted */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET)); ++ OSL_DELAY(1); ++} ++ ++/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */ ++void ++sb_watchdog(sb_t *sbh, uint ticks) ++{ ++ sb_info_t *si = SB_INFO(sbh); ++ ++ /* instant NMI */ ++ switch (si->gpioid) { ++ case SB_CC: ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); ++ break; ++ case SB_EXTIF: ++ sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); ++ break; ++ } ++} ++ ++/* initialize the pcmcia core */ ++void ++sb_pcmcia_init(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint8 cor; ++ ++ si = SB_INFO(sbh); ++ ++ /* enable d11 mac interrupts */ ++ if (si->sb.chip == BCM4301_DEVICE_ID) { ++ /* Have to use FCR2 in 4301 */ ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); ++ cor |= COR_IRQEN | COR_FUNEN; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); ++ } else { ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ cor |= COR_IRQEN | COR_FUNEN; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ } ++ ++} ++ ++ ++/* ++ * Configure the pci core for pci client (NIC) action ++ * coremask is the bitvec of cores by index to be enabled. ++ */ ++void ++sb_pci_setup(sb_t *sbh, uint coremask) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ sbpciregs_t *pciregs; ++ uint32 sbflag; ++ uint32 w; ++ uint idx; ++ int reg_val; ++ ++ si = SB_INFO(sbh); ++ ++ /* if not pci bus, we're done */ ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) ++ return; ++ ++ ASSERT(PCI(si) || PCIE(si)); ++ ASSERT(si->sb.buscoreidx != BADIDX); ++ ++ /* get current core index */ ++ idx = si->curidx; ++ ++ /* we interrupt on this backplane flag number */ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ ++ /* switch over to pci core */ ++ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx); ++ sb = REGS2SB(pciregs); ++ ++ /* ++ * Enable sb->pci interrupts. Assume ++ * PCI rev 2.3 support was added in pci core rev 6 and things changed.. ++ */ ++ if (PCIE(si) || (PCI(si) && ((si->sb.buscorerev) >= 6))) { ++ /* pci config write to set this core bit in PCIIntMask */ ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32)); ++ w |= (coremask << PCI_SBIM_SHIFT); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w); ++ } else { ++ /* set sbintvec bit for our flag number */ ++ OR_SBREG(si, &sb->sbintvec, (1 << sbflag)); ++ } ++ ++ if (PCI(si)) { ++ OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); ++ if (si->sb.buscorerev >= 11) ++ OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI); ++ if (si->sb.buscorerev < 5) { ++ SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ sb_commit(sbh); ++ } ++ } ++ ++ if (PCIE(si) && (si->sb.buscorerev == 0)) { ++ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); ++ reg_val |= 0x8; ++ sb_pcie_writereg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, reg_val); ++ ++ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG); ++ reg_val &= ~(0x40); ++ sb_pcie_writereg(sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG, reg_val); ++ ++ BCMINIT(sb_war30841)(si); ++ } ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++} ++ ++uint32 ++sb_base(uint32 admatch) ++{ ++ uint32 base; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ base = 0; ++ ++ if (type == 0) { ++ base = admatch & SBAM_BASE0_MASK; ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE1_MASK; ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE2_MASK; ++ } ++ ++ return (base); ++} ++ ++uint32 ++sb_size(uint32 admatch) ++{ ++ uint32 size; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ size = 0; ++ ++ if (type == 0) { ++ size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); ++ } ++ ++ return (size); ++} ++ ++/* return the core-type instantiation # of the current core */ ++uint ++sb_coreunit(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint idx; ++ uint coreid; ++ uint coreunit; ++ uint i; ++ ++ si = SB_INFO(sbh); ++ coreunit = 0; ++ ++ idx = si->curidx; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ coreid = sb_coreid(sbh); ++ ++ /* count the cores of our type */ ++ for (i = 0; i < idx; i++) ++ if (si->coreid[i] == coreid) ++ coreunit++; ++ ++ return (coreunit); ++} ++ ++static INLINE uint32 ++factor6(uint32 x) ++{ ++ switch (x) { ++ case CC_F6_2: return 2; ++ case CC_F6_3: return 3; ++ case CC_F6_4: return 4; ++ case CC_F6_5: return 5; ++ case CC_F6_6: return 6; ++ case CC_F6_7: return 7; ++ default: return 0; ++ } ++} ++ ++/* calculate the speed the SB would run at given a set of clockcontrol values */ ++uint32 ++sb_clock_rate(uint32 pll_type, uint32 n, uint32 m) ++{ ++ uint32 n1, n2, clock, m1, m2, m3, mc; ++ ++ n1 = n & CN_N1_MASK; ++ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; ++ ++ if (pll_type == PLL_TYPE6) { ++ if (m & CC_T6_MMASK) ++ return CC_T6_M1; ++ else ++ return CC_T6_M0; ++ } else if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ n1 = factor6(n1); ++ n2 += CC_F5_BIAS; ++ } else if (pll_type == PLL_TYPE2) { ++ n1 += CC_T2_BIAS; ++ n2 += CC_T2_BIAS; ++ ASSERT((n1 >= 2) && (n1 <= 7)); ++ ASSERT((n2 >= 5) && (n2 <= 23)); ++ } else if (pll_type == PLL_TYPE5) { ++ return (100000000); ++ } else ++ ASSERT(0); ++ /* PLL types 3 and 7 use BASE2 (25Mhz) */ ++ if ((pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE7)) { ++ clock = CC_CLOCK_BASE2 * n1 * n2; ++ } ++ else ++ clock = CC_CLOCK_BASE1 * n1 * n2; ++ ++ if (clock == 0) ++ return 0; ++ ++ m1 = m & CC_M1_MASK; ++ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; ++ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; ++ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; ++ ++ if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ m1 = factor6(m1); ++ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) ++ m2 += CC_F5_BIAS; ++ else ++ m2 = factor6(m2); ++ m3 = factor6(m3); ++ ++ switch (mc) { ++ case CC_MC_BYPASS: return (clock); ++ case CC_MC_M1: return (clock / m1); ++ case CC_MC_M1M2: return (clock / (m1 * m2)); ++ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); ++ case CC_MC_M1M3: return (clock / (m1 * m3)); ++ default: return (0); ++ } ++ } else { ++ ASSERT(pll_type == PLL_TYPE2); ++ ++ m1 += CC_T2_BIAS; ++ m2 += CC_T2M2_BIAS; ++ m3 += CC_T2_BIAS; ++ ASSERT((m1 >= 2) && (m1 <= 7)); ++ ASSERT((m2 >= 3) && (m2 <= 10)); ++ ASSERT((m3 >= 2) && (m3 <= 7)); ++ ++ if ((mc & CC_T2MC_M1BYP) == 0) ++ clock /= m1; ++ if ((mc & CC_T2MC_M2BYP) == 0) ++ clock /= m2; ++ if ((mc & CC_T2MC_M3BYP) == 0) ++ clock /= m3; ++ ++ return(clock); ++ } ++} ++ ++/* returns the current speed the SB is running at */ ++uint32 ++sb_clock(sb_t *sbh) ++{ ++ sb_info_t *si; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate; ++ uint intr_val = 0; ++ ++ si = SB_INFO(sbh); ++ idx = si->curidx; ++ pll_type = PLL_TYPE1; ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(&eir->clockcontrol_n); ++ m = R_REG(&eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(&cc->clockcontrol_n); ++ if (pll_type == PLL_TYPE6) ++ m = R_REG(&cc->clockcontrol_mips); ++ else if (pll_type == PLL_TYPE3) ++ { ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ m = R_REG(&cc->clockcontrol_sb); ++ else ++ m = R_REG(&cc->clockcontrol_m2); ++ } ++ else ++ m = R_REG(&cc->clockcontrol_sb); ++ } else { ++ INTR_RESTORE(si, intr_val); ++ return 0; ++ } ++ ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ { ++ rate = 100000000; ++ } ++ else ++ { ++ /* calculate rate */ ++ rate = sb_clock_rate(pll_type, n, m); ++ if (pll_type == PLL_TYPE3) ++ rate = rate / 2; ++ } ++ ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++ ++ INTR_RESTORE(si, intr_val); ++ ++ return rate; ++} ++ ++/* change logical "focus" to the gpio core for optimized access */ ++void* ++sb_gpiosetcore(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ ++ return (sb_setcoreidx(sbh, si->gpioidx)); ++} ++ ++/* mask&set gpiocontrol bits */ ++uint32 ++sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiocontrol); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpiocontrol); ++ break; ++ ++ case SB_EXTIF: ++ return (0); ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output enable bits */ ++uint32 ++sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioouten); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioouten); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].outen); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* mask&set gpio output bits */ ++uint32 ++sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++{ ++ sb_info_t *si; ++ uint regoff; ++ ++ si = SB_INFO(sbh); ++ regoff = 0; ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioout); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioout); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].out); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} + -+void testcrc32(void) ++/* reserve one gpio */ ++uint32 ++sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) +{ -+ uint j,k,l; -+ uint8 *buf; -+ uint len[CNBUFS]; -+ uint32 crcr; -+ uint32 crc32tv[CNBUFS] = -+ {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; ++ sb_info_t *si; + -+ ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); ++ si = SB_INFO(sbh); + -+ /* step through all possible alignments */ -+ for (l=0;l<=4;l++) { -+ for (j=0; jsb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; ++ } ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; + } + -+ MFREE(buf, CBUFSIZ*CNBUFS); -+ return; -+} -+#endif ++ /* already reserved */ ++ if (sb_gpioreservation & gpio_bitmask) ++ return -1; ++ /* set reservation */ ++ sb_gpioreservation |= gpio_bitmask; + ++ return sb_gpioreservation; ++} + ++/* release one gpio */ +/* -+ * Advance from the current 1-byte tag/1-byte length/variable-length value -+ * triple, to the next, returning a pointer to the next. -+ * If the current or next TLV is invalid (does not fit in given buffer length), -+ * NULL is returned. -+ * *buflen is not modified if the TLV elt parameter is invalid, or is decremented -+ * by the TLV paramter's length if it is valid. -+ */ -+bcm_tlv_t * -+bcm_next_tlv(bcm_tlv_t *elt, int *buflen) ++ * releasing the gpio doesn't change the current value on the GPIO last write value ++ * persists till some one overwrites it ++*/ ++ ++uint32 ++sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) +{ -+ int len; ++ sb_info_t *si; + -+ /* validate current elt */ -+ if (!bcm_valid_tlv(elt, *buflen)) -+ return NULL; -+ -+ /* advance to next elt */ -+ len = elt->len; -+ elt = (bcm_tlv_t*)(elt->data + len); -+ *buflen -= (2 + len); -+ -+ /* validate next elt */ -+ if (!bcm_valid_tlv(elt, *buflen)) -+ return NULL; ++ si = SB_INFO(sbh); ++ ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ ++ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; ++ } ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; ++ } + -+ return elt; ++ /* already released */ ++ if (!(sb_gpioreservation & gpio_bitmask)) ++ return -1; ++ ++ /* clear reservation */ ++ sb_gpioreservation &= ~gpio_bitmask; ++ ++ return sb_gpioreservation; +} + -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag -+ */ -+bcm_tlv_t * -+bcm_parse_tlvs(void *buf, int buflen, uint key) ++/* return the current gpioin register value */ ++uint32 ++sb_gpioin(sb_t *sbh) +{ -+ bcm_tlv_t *elt; -+ int totlen; ++ sb_info_t *si; ++ uint regoff; + -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; ++ si = SB_INFO(sbh); ++ regoff = 0; + -+ /* find tagged parameter */ -+ while (totlen >= 2) { -+ int len = elt->len; ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioin); ++ break; + -+ /* validate remaining totlen */ -+ if ((elt->id == key) && (totlen >= (len + 2))) -+ return (elt); ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioin); ++ break; + -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); -+ totlen -= (len + 2); ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpioin); ++ break; + } -+ -+ return NULL; ++ ++ return (sb_corereg(si, si->gpioidx, regoff, 0, 0)); +} + -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag. Stop parsing when we see an element whose ID is greater -+ * than the target key. -+ */ -+bcm_tlv_t * -+bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) ++/* mask&set gpio interrupt polarity bits */ ++uint32 ++sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ -+ bcm_tlv_t *elt; -+ int totlen; ++ sb_info_t *si; ++ uint regoff; + -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; ++ si = SB_INFO(sbh); ++ regoff = 0; + -+ /* find tagged parameter */ -+ while (totlen >= 2) { -+ uint id = elt->id; -+ int len = elt->len; -+ -+ /* Punt if we start seeing IDs > than target key */ -+ if (id > key) -+ return(NULL); ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ + -+ /* validate remaining totlen */ -+ if ((id == key) && (totlen >= (len + 2))) -+ return (elt); ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } + -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); -+ totlen -= (len + 2); ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt polarity */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointpolarity); ++ break; + } -+ return NULL; ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); +} -+/* routine to dump fields in a fileddesc structure */ + -+uint -+bcmdumpfields(readreg_rtn read_rtn, void *arg0, void *arg1, struct fielddesc *fielddesc_array, char *buf, uint32 bufsize) ++/* mask&set gpio interrupt mask bits */ ++uint32 ++sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ -+ uint filled_len; -+ uint len; -+ struct fielddesc *cur_ptr; ++ sb_info_t *si; ++ uint regoff; + -+ filled_len = 0; -+ cur_ptr = fielddesc_array; ++ si = SB_INFO(sbh); ++ regoff = 0; + -+ while (bufsize > (filled_len + 64)) { -+ if (cur_ptr->nameandfmt == NULL) -+ break; -+ len = sprintf(buf, cur_ptr->nameandfmt, read_rtn(arg0, arg1, cur_ptr->offset)); -+ buf += len; -+ filled_len += len; -+ cur_ptr++; ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; + } -+ return filled_len; ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointmask); ++ break; ++ ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt mask */ ++ ASSERT(0); ++ break; ++ ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointmask); ++ break; ++ } ++ ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} ++ ++/* assign the gpio to an led */ ++uint32 ++sb_gpioled(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ if (si->sb.ccrev < 16) ++ return -1; ++ ++ /* gpio led powersave reg */ ++ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); +} + -+uint -+bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) ++/* mask&set gpio timer val */ ++uint32 ++sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval) +{ -+ uint len; -+ -+ len = strlen(name) + 1; -+ -+ if ((len + datalen) > buflen) -+ return 0; -+ -+ strcpy(buf, name); ++ sb_info_t *si; ++ si = SB_INFO(sbh); + -+ /* append data onto the end of the name string */ -+ memcpy(&buf[len], data, datalen); -+ len += datalen; ++ if (si->sb.ccrev < 16) ++ return -1; + -+ return len; ++ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); +} + -+/* Quarter dBm units to mW -+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 -+ * Table is offset so the last entry is largest mW value that fits in -+ * a uint16. -+ */ -+ -+#define QDBM_OFFSET 153 -+#define QDBM_TABLE_LEN 40 + -+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. -+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 -+ */ -+#define QDBM_TABLE_LOW_BOUND 6493 ++/* return the slow clock source - LPO, XTAL, or PCI */ ++static uint ++sb_slowclk_src(sb_info_t *si) ++{ ++ chipcregs_t *cc; + -+/* Largest mW value that will round down to the last table entry, -+ * QDBM_OFFSET + QDBM_TABLE_LEN-1. -+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. -+ */ -+#define QDBM_TABLE_HIGH_BOUND 64938 + -+static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { -+/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ -+/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, -+/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, -+/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, -+/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, -+/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 -+}; ++ ASSERT(sb_coreid(&si->sb) == SB_CC); + -+uint16 -+bcm_qdbm_to_mw(uint8 qdbm) -+{ -+ uint factor = 1; -+ int idx = qdbm - QDBM_OFFSET; -+ -+ if (idx > QDBM_TABLE_LEN) { -+ /* clamp to max uint16 mW value */ -+ return 0xFFFF; -+ } -+ -+ /* scale the qdBm index up to the range of the table 0-40 -+ * where an offset of 40 qdBm equals a factor of 10 mW. -+ */ -+ while (idx < 0) { -+ idx += 40; -+ factor *= 10; -+ } -+ -+ /* return the mW value scaled down to the correct factor of 10, -+ * adding in factor/2 to get proper rounding. */ -+ return ((nqdBm_to_mW_map[idx] + factor/2) / factor); ++ if (si->sb.ccrev < 6) { ++ if ((BUSTYPE(si->sb.bustype) == PCI_BUS) ++ && (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)) & PCI_CFG_GPIO_SCS)) ++ return (SCC_SS_PCI); ++ else ++ return (SCC_SS_XTAL); ++ } else if (si->sb.ccrev < 10) { ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ return (R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK); ++ } else /* Insta-clock */ ++ return (SCC_SS_XTAL); +} + -+uint8 -+bcm_mw_to_qdbm(uint16 mw) ++/* return the ILP (slowclock) min or max frequency */ ++static uint ++sb_slowclk_freq(sb_info_t *si, bool max) +{ -+ uint8 qdbm; -+ int offset; -+ uint mw_uint = mw; -+ uint boundary; -+ -+ /* handle boundary case */ -+ if (mw_uint <= 1) -+ return 0; -+ -+ offset = QDBM_OFFSET; -+ -+ /* move mw into the range of the table */ -+ while (mw_uint < QDBM_TABLE_LOW_BOUND) { -+ mw_uint *= 10; -+ offset -= 40; -+ } ++ chipcregs_t *cc; ++ uint32 slowclk; ++ uint div; + -+ for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { -+ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - nqdBm_to_mW_map[qdbm])/2; -+ if (mw_uint < boundary) break; -+ } + -+ qdbm += (uint8)offset; ++ ASSERT(sb_coreid(&si->sb) == SB_CC); + -+ return(qdbm); -+} -diff -Nur linux-2.4.32/drivers/net/hnd/hnddma.c linux-2.4.32-brcm/drivers/net/hnd/hnddma.c ---- linux-2.4.32/drivers/net/hnd/hnddma.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/hnd/hnddma.c 2005-12-16 23:39:11.288858250 +0100 -@@ -0,0 +1,1527 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA module. -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); + -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ /* shouldn't be here unless we've established the chip has dynamic clk control */ ++ ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL); + -+struct dma_info; /* forward declaration */ -+#define di_t struct dma_info ++ slowclk = sb_slowclk_src(si); ++ if (si->sb.ccrev < 6) { ++ if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64)); ++ else ++ return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32)); ++ } else if (si->sb.ccrev < 10) { ++ div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ if (slowclk == SCC_SS_LPO) ++ return (max? LPOMAXFREQ : LPOMINFREQ); ++ else if (slowclk == SCC_SS_XTAL) ++ return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); ++ else if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); ++ else ++ ASSERT(0); ++ } else { ++ /* Chipc rev 10 is InstaClock */ ++ div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; ++ div = 4 * (div + 1); ++ return (max ? XTALMAXFREQ : (XTALMINFREQ/div)); ++ } ++ return (0); ++} + -+#include -+#include ++static void ++sb_clkctl_setdelay(sb_info_t *si, void *chipcregs) ++{ ++ chipcregs_t * cc; ++ uint slowmaxfreq, pll_delay, slowclk; ++ uint pll_on_delay, fref_sel_delay; + -+/* debug/trace */ -+#define DMA_ERROR(args) -+#define DMA_TRACE(args) ++ pll_delay = PLL_DELAY; + -+/* default dma message level (if input msg_level pointer is null in dma_attach()) */ -+static uint dma_msg_level = -+ 0; ++ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay ++ * since the xtal will also be powered down by dynamic clk control logic. ++ */ ++ slowclk = sb_slowclk_src(si); ++ if (slowclk != SCC_SS_XTAL) ++ pll_delay += XTAL_ON_DELAY; + -+#define MAXNAMEL 8 ++ /* Starting with 4318 it is ILP that is used for the delays */ ++ slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE); + -+/* dma engine software state */ -+typedef struct dma_info { -+ hnddma_t hnddma; /* exported structure */ -+ uint *msg_level; /* message level pointer */ -+ char name[MAXNAMEL]; /* callers name for diag msgs */ -+ -+ void *osh; /* os handle */ -+ sb_t *sbh; /* sb handle */ -+ -+ bool dma64; /* dma64 enabled */ -+ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ -+ -+ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ -+ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ -+ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ -+ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ ++ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; ++ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; + -+ uint32 dma64align; /* either 8k or 4k depends on number of dd */ -+ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ -+ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ -+ uint ntxd; /* # tx descriptors tunable */ -+ uint txin; /* index of next descriptor to reclaim */ -+ uint txout; /* index of next descriptor to post */ -+ uint txavail; /* # free tx descriptors */ -+ void **txp; /* pointer to parallel array of pointers to packets */ -+ ulong txdpa; /* physical address of descriptor ring */ -+ uint txdalign; /* #bytes added to alloc'd mem to align txd */ -+ uint txdalloc; /* #bytes allocated for the ring */ ++ cc = (chipcregs_t *)chipcregs; ++ W_REG(&cc->pll_on_delay, pll_on_delay); ++ W_REG(&cc->fref_sel_delay, fref_sel_delay); ++} + -+ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ -+ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ -+ uint nrxd; /* # rx descriptors tunable */ -+ uint rxin; /* index of next descriptor to reclaim */ -+ uint rxout; /* index of next descriptor to post */ -+ void **rxp; /* pointer to parallel array of pointers to packets */ -+ ulong rxdpa; /* physical address of descriptor ring */ -+ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ -+ uint rxdalloc; /* #bytes allocated for the ring */ ++int ++sb_pwrctl_slowclk(void *sbh, bool set, uint *div) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint intr_val = 0; ++ uint err = 0; ++ ++ si = SB_INFO(sbh); + -+ /* tunables */ -+ uint rxbufsize; /* rx buffer size in bytes */ -+ uint nrxpost; /* # rx buffers to keep posted */ -+ uint rxoffset; /* rxcontrol offset */ -+ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ -+ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */ -+ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ -+ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */ -+} dma_info_t; ++ /* chipcommon cores prior to rev6 don't support slowclkcontrol */ ++ if (si->sb.ccrev < 6) ++ return 1; + -+#ifdef BCMDMA64 -+#define DMA64_ENAB(di) ((di)->dma64) -+#else -+#define DMA64_ENAB(di) (0) -+#endif ++ /* chipcommon cores rev10 are a whole new ball game */ ++ if (si->sb.ccrev >= 10) ++ return 1; + -+/* descriptor bumping macros */ -+#define XXD(x, n) ((x) & ((n) - 1)) -+#define TXD(x) XXD((x), di->ntxd) -+#define RXD(x) XXD((x), di->nrxd) -+#define NEXTTXD(i) TXD(i + 1) -+#define PREVTXD(i) TXD(i - 1) -+#define NEXTRXD(i) RXD(i + 1) -+#define NTXDACTIVE(h, t) TXD(t - h) -+#define NRXDACTIVE(h, t) RXD(t - h) ++ if (set && ((*div % 4) || (*div < 4))) ++ return 2; ++ ++ INTR_OFF(si, intr_val); ++ origidx = si->curidx; ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); ++ ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) { ++ err = 3; ++ goto done; ++ } + -+/* macros to convert between byte offsets and indexes */ -+#define B2I(bytes, type) ((bytes) / sizeof(type)) -+#define I2B(index, type) ((index) * sizeof(type)) ++ if (set) { ++ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHIFT)); ++ sb_clkctl_setdelay(sbh, (void *)cc); ++ } else ++ *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); + -+#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ -+#define PCI32ADDR_HIGH_SHIFT 30 ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return err; ++} + ++/* initialize power control delay registers */ ++void sb_clkctl_init(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; + -+/* prototypes */ -+static bool dma_isaddrext(dma_info_t *di); -+static bool dma_alloc(dma_info_t *di, uint direction); ++ si = SB_INFO(sbh); + -+static bool dma32_alloc(dma_info_t *di, uint direction); -+static void dma32_txreset(dma_info_t *di); -+static void dma32_rxreset(dma_info_t *di); -+static bool dma32_txsuspendedidle(dma_info_t *di); -+static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags); -+static void* dma32_getnexttxp(dma_info_t *di, bool forceall); -+static void* dma32_getnextrxp(dma_info_t *di, bool forceall); -+static void dma32_txrotate(di_t *di); ++ origidx = si->curidx; + -+/* prototype or stubs */ -+#ifdef BCMDMA64 -+static bool dma64_alloc(dma_info_t *di, uint direction); -+static void dma64_txreset(dma_info_t *di); -+static void dma64_rxreset(dma_info_t *di); -+static bool dma64_txsuspendedidle(dma_info_t *di); -+static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags); -+static void* dma64_getnexttxp(dma_info_t *di, bool forceall); -+static void* dma64_getnextrxp(dma_info_t *di, bool forceall); -+static void dma64_txrotate(di_t *di); -+#else -+static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; } -+static void dma64_txreset(dma_info_t *di) {} -+static void dma64_rxreset(dma_info_t *di) {} -+static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;} -+static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; } -+static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; } -+static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; } -+static void dma64_txrotate(di_t *di) { return; } -+#endif ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ return; + -+/* old dmaregs struct for compatibility */ -+typedef volatile struct { -+ /* transmit channel */ -+ uint32 xmtcontrol; /* enable, et al */ -+ uint32 xmtaddr; /* descriptor ring base address (4K aligned) */ -+ uint32 xmtptr; /* last descriptor posted to chip */ -+ uint32 xmtstatus; /* current active descriptor, et al */ -+ -+ /* receive channel */ -+ uint32 rcvcontrol; /* enable, et al */ -+ uint32 rcvaddr; /* descriptor ring base address (4K aligned) */ -+ uint32 rcvptr; /* last descriptor posted to chip */ -+ uint32 rcvstatus; /* current active descriptor, et al */ -+} dmaregs_t; ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; + -+typedef struct { -+ uint ddoffset; -+ uint dataoffset; -+} compat_data; ++ /* 4317pc does not work with SlowClock less than 5 MHz */ ++ if ((BUSTYPE(si->sb.bustype) == PCMCIA_BUS) && (si->sb.ccrev >= 6) && (si->sb.ccrev < 10)) ++ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (ILP_DIV_5MHZ << SCC_CD_SHIFT)); + -+static compat_data *ugly_hack = NULL; ++ /* set all Instaclk chip ILP to 1 MHz */ ++ else if (si->sb.ccrev >= 10) ++ SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); ++ ++ sb_clkctl_setdelay(si, (void *)cc); + -+void* -+dma_attold(void *drv, void *osh, char *name, dmaregs_t *regs, uint ntxd, uint nrxd, -+ uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level) ++done: ++ sb_setcoreidx(sbh, origidx); ++} ++void sb_pwrctl_init(sb_t *sbh) +{ -+ dma32regs_t *dtx = regs; -+ dma32regs_t *drx = dtx + 1; -+ -+ ugly_hack = kmalloc(sizeof(ugly_hack), GFP_KERNEL); -+ ugly_hack->ddoffset = ddoffset; -+ ugly_hack->dataoffset = dataoffset; -+ dma_attach((osl_t *) osh, name, NULL, dtx, drx, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, msg_level); -+ ugly_hack = NULL; ++sb_clkctl_init(sbh); +} ++/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ ++uint16 ++sb_clkctl_fast_pwrup_delay(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint slowminfreq; ++ uint16 fpdelay; ++ uint intr_val = 0; + ++ si = SB_INFO(sbh); ++ fpdelay = 0; ++ origidx = si->curidx; + -+void* -+dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, -+ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) -+{ -+ dma_info_t *di; -+ uint size; ++ INTR_OFF(si, intr_val); + -+ /* allocate private info structure */ -+ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { -+ return (NULL); -+ } -+ bzero((char*)di, sizeof (dma_info_t)); ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ goto done; + -+ di->msg_level = msg_level ? msg_level : &dma_msg_level; ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; + -+ if (sbh != NULL) -+ di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64); ++ slowminfreq = sb_slowclk_freq(si, FALSE); ++ fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; + -+#ifndef BCMDMA64 -+ if (di->dma64) { -+ DMA_ERROR(("dma_attach: driver doesn't have the capability to support 64 bits DMA\n")); -+ goto fail; -+ } -+#endif -+ -+ /* check arguments */ -+ ASSERT(ISPOWEROF2(ntxd)); -+ ASSERT(ISPOWEROF2(nrxd)); -+ if (nrxd == 0) -+ ASSERT(dmaregsrx == NULL); -+ if (ntxd == 0) -+ ASSERT(dmaregstx == NULL); ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (fpdelay); ++} ++uint16 sb_pwrctl_fast_pwrup_delay(sb_t *sbh) ++{ ++return sb_clkctl_fast_pwrup_delay(sbh); ++} ++/* turn primary xtal and/or pll off/on */ ++int ++sb_clkctl_xtal(sb_t *sbh, uint what, bool on) ++{ ++ sb_info_t *si; ++ uint32 in, out, outen; + ++ si = SB_INFO(sbh); + -+ /* init dma reg pointer */ -+ if (di->dma64) { -+ ASSERT(ntxd <= D64MAXDD); -+ ASSERT(nrxd <= D64MAXDD); -+ di->d64txregs = (dma64regs_t *)dmaregstx; -+ di->d64rxregs = (dma64regs_t *)dmaregsrx; ++ switch (BUSTYPE(si->sb.bustype)) { + -+ di->dma64align = D64RINGALIGN; -+ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { -+ /* for smaller dd table, HW relax the alignment requirement */ -+ di->dma64align = D64RINGALIGN / 2; -+ } -+ } else { -+ ASSERT(ntxd <= D32MAXDD); -+ ASSERT(nrxd <= D32MAXDD); -+ di->d32txregs = (dma32regs_t *)dmaregstx; -+ di->d32rxregs = (dma32regs_t *)dmaregsrx; -+ } + ++ case PCMCIA_BUS: ++ return (0); + -+ /* make a private copy of our callers name */ -+ strncpy(di->name, name, MAXNAMEL); -+ di->name[MAXNAMEL-1] = '\0'; + -+ di->osh = osh; -+ di->sbh = sbh; ++ case PCI_BUS: + -+ /* save tunables */ -+ di->ntxd = ntxd; -+ di->nrxd = nrxd; -+ di->rxbufsize = rxbufsize; -+ di->nrxpost = nrxpost; -+ di->rxoffset = rxoffset; ++ /* pcie core doesn't have any mapping to control the xtal pu */ ++ if (PCIE(si)) ++ return -1; + -+ /* -+ * figure out the DMA physical address offset for dd and data -+ * for old chips w/o sb, use zero -+ * for new chips w sb, -+ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset -+ * Other bus: use zero -+ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor -+ */ -+ di->ddoffsetlow = 0; -+ di->dataoffsetlow = 0; -+ if (ugly_hack != NULL) { -+ di->ddoffsetlow = ugly_hack->ddoffset; -+ di->dataoffsetlow = ugly_hack->dataoffset; -+ di->ddoffsethigh = 0; -+ di->dataoffsethigh = 0; -+ } else if (sbh != NULL) { -+ if (sbh->bustype == PCI_BUS) { /* for pci bus, add offset */ -+ if ((sbh->buscoretype == SB_PCIE) && di->dma64){ -+ di->ddoffsetlow = 0; -+ di->ddoffsethigh = SB_PCIE_DMA_H32; ++ in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32)); ++ out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)); ++ outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32)); ++ ++ /* ++ * Avoid glitching the clock if GPRS is already using it. ++ * We can't actually read the state of the PLLPD so we infer it ++ * by the value of XTAL_PU which *is* readable via gpioin. ++ */ ++ if (on && (in & PCI_CFG_GPIO_XTAL)) ++ return (0); ++ ++ if (what & XTAL) ++ outen |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ outen |= PCI_CFG_GPIO_PLL; ++ ++ if (on) { ++ /* turn primary xtal on */ ++ if (what & XTAL) { ++ out |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); ++ OSL_DELAY(XTAL_ON_DELAY); ++ } ++ ++ /* turn pll on */ ++ if (what & PLL) { ++ out &= ~PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_DELAY(2000); ++ } + } else { -+ di->ddoffsetlow = SB_PCI_DMA; -+ di->ddoffsethigh = 0; ++ if (what & XTAL) ++ out &= ~PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); + } -+ di->dataoffsetlow = di->ddoffsetlow; -+ di->dataoffsethigh = di->ddoffsethigh; -+ } -+#if defined(__mips__) && defined(IL_BIGENDIAN) -+ /* use sdram swapped region for data buffers but not dma descriptors */ -+ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; -+#endif ++ ++ default: ++ return (-1); + } + -+ di->addrext = ((ugly_hack == NULL) ? dma_isaddrext(di) : 0); ++ return (0); ++} + -+ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", -+ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow)); ++int sb_pwrctl_xtal(sb_t *sbh, uint what, bool on) ++{ ++return sb_clkctl_xtal(sbh,what,on); ++} + -+ /* allocate tx packet pointer vector */ -+ if (ntxd) { -+ size = ntxd * sizeof (void*); -+ if ((di->txp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); -+ goto fail; -+ } -+ bzero((char*)di->txp, size); -+ } ++/* set dynamic clk control mode (forceslow, forcefast, dynamic) */ ++/* returns true if ignore pll off is set and false if it is not */ ++bool ++sb_clkctl_clk(sb_t *sbh, uint mode) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint32 scc; ++ bool forcefastclk=FALSE; ++ uint intr_val = 0; + -+ /* allocate rx packet pointer vector */ -+ if (nrxd) { -+ size = nrxd * sizeof (void*); -+ if ((di->rxp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); -+ goto fail; -+ } -+ bzero((char*)di->rxp, size); -+ } ++ si = SB_INFO(sbh); + -+ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ -+ if (ntxd) { -+ if (!dma_alloc(di, DMA_TX)) -+ goto fail; -+ } ++ /* chipcommon cores prior to rev6 don't support dynamic clock control */ ++ if (si->sb.ccrev < 6) ++ return (FALSE); + -+ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ -+ if (nrxd) { -+ if (!dma_alloc(di, DMA_RX)) -+ goto fail; -+ } ++ /* chipcommon cores rev10 are a whole new ball game */ ++ if (si->sb.ccrev >= 10) ++ return (FALSE); + -+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { -+ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa)); -+ goto fail; -+ } -+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { -+ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa)); -+ goto fail; -+ } ++ INTR_OFF(si, intr_val); + -+ return ((void*)di); ++ origidx = si->curidx; + -+fail: -+ dma_detach((void*)di); -+ return (NULL); -+} ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); + -+static bool -+dma_alloc(dma_info_t *di, uint direction) -+{ -+ if (DMA64_ENAB(di)) { -+ return dma64_alloc(di, direction); -+ } else { -+ return dma32_alloc(di, direction); -+ } -+} ++ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) ++ goto done; + -+/* may be called with core in reset */ -+void -+dma_detach(dma_info_t *di) -+{ -+ if (di == NULL) -+ return; ++ switch (mode) { ++ case CLK_FAST: /* force fast (pll) clock */ ++ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ ++ sb_clkctl_xtal(&si->sb, XTAL, ON); + -+ DMA_TRACE(("%s: dma_detach\n", di->name)); ++ SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); ++ break; + -+ /* shouldn't be here if descriptors are unreclaimed */ -+ ASSERT(di->txin == di->txout); -+ ASSERT(di->rxin == di->rxout); ++ case CLK_DYNAMIC: /* enable dynamic clock control */ ++ scc = R_REG(&cc->slow_clk_ctl); ++ scc &= ~(SCC_FS | SCC_IP | SCC_XC); ++ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) ++ scc |= SCC_XC; ++ W_REG(&cc->slow_clk_ctl, scc); + -+ /* free dma descriptor rings */ -+ if (di->txd32) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign)); -+ if (di->rxd32) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign)); ++ /* for dynamic control, we have to release our xtal_pu "force on" */ ++ if (scc & SCC_XC) ++ sb_clkctl_xtal(&si->sb, XTAL, OFF); ++ break; + -+ /* free packet pointer vectors */ -+ if (di->txp) -+ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*))); -+ if (di->rxp) -+ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*))); ++ default: ++ ASSERT(0); ++ } + -+ /* free our private info structure */ -+ MFREE(di->osh, (void*)di, sizeof (dma_info_t)); ++ /* Is the h/w forcing the use of the fast clk */ ++ forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP); ++ ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (forcefastclk); +} + -+/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ -+static bool -+dma_isaddrext(dma_info_t *di) ++bool sb_pwrctl_clk(sb_t *sbh, uint mode) +{ -+ uint32 w; -+ -+ if (DMA64_ENAB(di)) { -+ OR_REG(&di->d64txregs->control, D64_XC_AE); -+ w = R_REG(&di->d32txregs->control); -+ AND_REG(&di->d32txregs->control, ~D64_XC_AE); -+ return ((w & XC_AE) == D64_XC_AE); -+ } else { -+ OR_REG(&di->d32txregs->control, XC_AE); -+ w = R_REG(&di->d32txregs->control); -+ AND_REG(&di->d32txregs->control, ~XC_AE); -+ return ((w & XC_AE) == XC_AE); -+ } ++return sb_clkctl_clk(sbh, mode); +} -+ ++/* register driver interrupt disabling and restoring callback functions */ +void -+dma_txreset(dma_info_t *di) ++sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) +{ -+ DMA_TRACE(("%s: dma_txreset\n", di->name)); ++ sb_info_t *si; + -+ if (DMA64_ENAB(di)) -+ dma64_txreset(di); -+ else -+ dma32_txreset(di); ++ si = SB_INFO(sbh); ++ si->intr_arg = intr_arg; ++ si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn; ++ si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn; ++ si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn; ++ /* save current core id. when this function called, the current core ++ * must be the core which provides driver functions(il, et, wl, etc.) ++ */ ++ si->dev_coreid = si->coreid[si->curidx]; +} + ++ +void -+dma_rxreset(dma_info_t *di) ++sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, ++ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif) +{ -+ DMA_TRACE(("%s: dma_rxreset\n", di->name)); ++ uint vendor, core, unit; ++ uint chip, chippkg; ++ char varname[8]; ++ uint8 class, subclass, progif; ++ ++ vendor = sb_corevendor(sbh); ++ core = sb_coreid(sbh); ++ unit = sb_coreunit(sbh); + -+ if (DMA64_ENAB(di)) -+ dma64_rxreset(di); -+ else -+ dma32_rxreset(di); -+} ++ chip = BCMINIT(sb_chip)(sbh); ++ chippkg = BCMINIT(sb_chippkg)(sbh); + -+/* initialize descriptor table base address */ -+static void -+dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) -+{ -+ if (DMA64_ENAB(di)) { -+ if (direction == DMA_TX) { -+ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow); -+ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); -+ } else { -+ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow); -+ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); -+ } -+ } else { -+ uint32 offset = di->ddoffsetlow; -+ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { -+ if (direction == DMA_TX) -+ W_REG(&di->d32txregs->addr, (pa + offset)); -+ else -+ W_REG(&di->d32rxregs->addr, (pa + offset)); -+ } else { -+ /* dma32 address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ progif = 0; + -+ if (direction == DMA_TX) { -+ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); -+ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT)); -+ } else { -+ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); -+ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT)); ++ /* Known vendor translations */ ++ switch (vendor) { ++ case SB_VEND_BCM: ++ vendor = VENDOR_BROADCOM; ++ break; ++ } ++ ++ /* Determine class based on known core codes */ ++ switch (core) { ++ case SB_ILINE20: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ILINE_ID; ++ break; ++ case SB_ENET: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ core = BCM47XX_ENET_ID; ++ break; ++ case SB_SDRAM: ++ case SB_MEMC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_RAM; ++ break; ++ case SB_PCI: ++ case SB_PCIE: ++ class = PCI_CLASS_BRIDGE; ++ subclass = PCI_BRIDGE_PCI; ++ break; ++ case SB_MIPS: ++ case SB_MIPS33: ++ class = PCI_CLASS_CPU; ++ subclass = PCI_CPU_MIPS; ++ break; ++ case SB_CODEC: ++ class = PCI_CLASS_COMM; ++ subclass = PCI_COMM_MODEM; ++ core = BCM47XX_V90_ID; ++ break; ++ case SB_USB: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USB_ID; ++ break; ++ case SB_USB11H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ core = BCM47XX_USBH_ID; ++ break; ++ case SB_USB11D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ core = BCM47XX_USBD_ID; ++ break; ++ case SB_IPSEC: ++ class = PCI_CLASS_CRYPT; ++ subclass = PCI_CRYPT_NETWORK; ++ core = BCM47XX_IPSEC_ID; ++ break; ++ case SB_ROBO: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ core = BCM47XX_ROBO_ID; ++ break; ++ case SB_EXTIF: ++ case SB_CC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_FLASH; ++ break; ++ case SB_D11: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ /* Let an nvram variable override this */ ++ sprintf(varname, "wl%did", unit); ++ if ((core = getintvar(NULL, varname)) == 0) { ++ if (chip == BCM4712_DEVICE_ID) { ++ if (chippkg == BCM4712SMALL_PKG_ID) ++ core = BCM4306_D11G_ID; ++ else ++ core = BCM4306_D11DUAL_ID; + } + } ++ break; ++ ++ default: ++ class = subclass = progif = 0xff; ++ break; + } ++ ++ *pcivendor = (uint16)vendor; ++ *pcidevice = (uint16)core; ++ *pciclass = class; ++ *pcisubclass = subclass; ++ *pciprogif = progif; +} + -+/* init the tx or rx descriptor */ -+static INLINE void -+dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl) -+{ -+ uint offset = di->dataoffsetlow; + -+ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { -+ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); -+ } else { -+ /* address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; + -+ *ctrl |= (ae << CTRL_AE_SHIFT); -+ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); -+ } -+} + -+/* init the tx or rx descriptor */ -+static INLINE void -+dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount) ++/* use the mdio interface to write to mdio slaves */ ++static int ++sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val) +{ -+ uint32 bufaddr_low = pa + di->dataoffsetlow; -+ uint32 bufaddr_high = 0 + di->dataoffsethigh; ++ uint mdiodata; ++ uint i = 0; ++ sbpcieregs_t *pcieregs; + -+ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; ++ pcieregs = (sbpcieregs_t*) sb_setcoreidx(&si->sb, si->sb.buscoreidx); ++ ASSERT (pcieregs); + -+ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low)); -+ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high)); -+ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); -+ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); -+} ++ /* enable mdio access to SERDES */ ++ W_REG((&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); + -+void -+dma_txinit(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txinit\n", di->name)); ++ mdiodata = MDIODATA_START | MDIODATA_WRITE | ++ (physmedia << MDIODATA_DEVADDR_SHF) | ++ (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val; + -+ di->txin = di->txout = 0; -+ di->txavail = di->ntxd - 1; ++ W_REG((&pcieregs->mdiodata), mdiodata); + -+ /* clear tx descriptor ring */ -+ if (DMA64_ENAB(di)) { -+ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t))); -+ W_REG(&di->d64txregs->control, XC_XE); -+ dma_ddtable_init(di, DMA_TX, di->txdpa); -+ } else { -+ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t))); -+ W_REG(&di->d32txregs->control, XC_XE); -+ dma_ddtable_init(di, DMA_TX, di->txdpa); -+ } -+} ++ PR28829_DELAY(); + -+bool -+dma_txenabled(dma_info_t *di) -+{ -+ uint32 xc; -+ -+ /* If the chip is dead, it is not enabled :-) */ -+ if (DMA64_ENAB(di)) { -+ xc = R_REG(&di->d64txregs->control); -+ return ((xc != 0xffffffff) && (xc & D64_XC_XE)); -+ } else { -+ xc = R_REG(&di->d32txregs->control); -+ return ((xc != 0xffffffff) && (xc & XC_XE)); ++ /* retry till the transaction is complete */ ++ while ( i < 10 ) { ++ if (R_REG(&(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { ++ /* Disable mdio access to SERDES */ ++ W_REG((&pcieregs->mdiocontrol), 0); ++ return 0; ++ } ++ OSL_DELAY(1000); ++ i++; + } -+} -+ -+void -+dma_txsuspend(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); -+ if (DMA64_ENAB(di)) -+ OR_REG(&di->d64txregs->control, D64_XC_SE); -+ else -+ OR_REG(&di->d32txregs->control, XC_SE); -+} + -+void -+dma_txresume(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txresume\n", di->name)); -+ if (DMA64_ENAB(di)) -+ AND_REG(&di->d64txregs->control, ~D64_XC_SE); -+ else -+ AND_REG(&di->d32txregs->control, ~XC_SE); -+} ++ SB_ERROR(("sb_pcie_mdiowrite: timed out\n")); ++ /* Disable mdio access to SERDES */ ++ W_REG((&pcieregs->mdiocontrol), 0); ++ ASSERT(0); ++ return 1; + -+bool -+dma_txsuspendedidle(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di)) -+ return dma64_txsuspendedidle(di); -+ else -+ return dma32_txsuspendedidle(di); +} + -+bool -+dma_txsuspended(dma_info_t *di) ++/* indirect way to read pcie config regs*/ ++uint ++sb_pcie_readreg(void *sb, void* arg1, uint offset) +{ -+ if (DMA64_ENAB(di)) -+ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); -+ else -+ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE); -+} ++ sb_info_t *si; ++ sb_t *sbh; ++ uint retval = 0xFFFFFFFF; ++ sbpcieregs_t *pcieregs; ++ uint addrtype; + -+bool -+dma_txstopped(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di)) -+ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); -+ else -+ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); -+} ++ sbh = (sb_t *)sb; ++ si = SB_INFO(sbh); ++ ASSERT (PCIE(si)); + -+bool -+dma_rxstopped(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di)) -+ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); -+ else -+ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); -+} ++ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); ++ ASSERT (pcieregs); + -+void -+dma_fifoloopbackenable(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); -+ if (DMA64_ENAB(di)) -+ OR_REG(&di->d64txregs->control, D64_XC_LE); -+ else -+ OR_REG(&di->d32txregs->control, XC_LE); ++ addrtype = (uint)((uintptr)arg1); ++ switch(addrtype) { ++ case PCIE_CONFIGREGS: ++ W_REG((&pcieregs->configaddr),offset); ++ retval = R_REG(&(pcieregs->configdata)); ++ break; ++ case PCIE_PCIEREGS: ++ W_REG(&(pcieregs->pcieaddr),offset); ++ retval = R_REG(&(pcieregs->pciedata)); ++ break; ++ default: ++ ASSERT(0); ++ break; ++ } ++ return retval; +} + -+void -+dma_rxinit(dma_info_t *di) ++/* indirect way to write pcie config/mdio/pciecore regs*/ ++uint ++sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val) +{ -+ DMA_TRACE(("%s: dma_rxinit\n", di->name)); -+ -+ di->rxin = di->rxout = 0; ++ sb_info_t *si; ++ sbpcieregs_t *pcieregs; ++ uint addrtype; + -+ /* clear rx descriptor ring */ -+ if (DMA64_ENAB(di)) { -+ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t))); -+ dma_rxenable(di); -+ dma_ddtable_init(di, DMA_RX, di->rxdpa); -+ } else { -+ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t))); -+ dma_rxenable(di); -+ dma_ddtable_init(di, DMA_RX, di->rxdpa); -+ } -+} ++ si = SB_INFO(sbh); ++ ASSERT (PCIE(si)); + -+void -+dma_rxenable(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxenable\n", di->name)); -+ if (DMA64_ENAB(di)) -+ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE)); -+ else -+ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); -+} ++ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); ++ ASSERT (pcieregs); + -+bool -+dma_rxenabled(dma_info_t *di) -+{ -+ uint32 rc; ++ addrtype = (uint)((uintptr)arg1); + -+ if (DMA64_ENAB(di)) { -+ rc = R_REG(&di->d64rxregs->control); -+ return ((rc != 0xffffffff) && (rc & D64_RC_RE)); -+ } else { -+ rc = R_REG(&di->d32rxregs->control); -+ return ((rc != 0xffffffff) && (rc & RC_RE)); ++ switch(addrtype) { ++ case PCIE_CONFIGREGS: ++ W_REG((&pcieregs->configaddr),offset); ++ W_REG((&pcieregs->configdata),val); ++ break; ++ case PCIE_PCIEREGS: ++ W_REG((&pcieregs->pcieaddr),offset); ++ W_REG((&pcieregs->pciedata),val); ++ break; ++ default: ++ ASSERT(0); ++ break; + } ++ return 0; +} + + -+/* !! tx entry routine */ ++/* Build device path. Support SB, PCI, and JTAG for now. */ +int -+dma_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++sb_devpath(sb_t *sbh, char *path, int size) +{ -+ if (DMA64_ENAB(di)) { -+ return dma64_txfast(di, p0, coreflags); -+ } else { -+ return dma32_txfast(di, p0, coreflags); ++ ASSERT(path); ++ ASSERT(size >= SB_DEVPATH_BUFSZ); ++ ++ switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) { ++ case SB_BUS: ++ case JTAG_BUS: ++ sprintf(path, "sb/%u/", sb_coreidx(sbh)); ++ break; ++ case PCI_BUS: ++ ASSERT((SB_INFO(sbh))->osh); ++ sprintf(path, "pci/%u/%u/", OSL_PCI_BUS((SB_INFO(sbh))->osh), ++ OSL_PCI_SLOT((SB_INFO(sbh))->osh)); ++ break; ++ case PCMCIA_BUS: ++ SB_ERROR(("sb_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n")); ++ SB_ERROR(("sb_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n")); ++ sprintf(path, "pc/%u/%u/", 1, 1); ++ break; ++ case SDIO_BUS: ++ SB_ERROR(("sb_devpath: device 0 assumed\n")); ++ sprintf(path, "sd/%u/", sb_coreidx(sbh)); ++ break; ++ default: ++ ASSERT(0); ++ break; + } ++ ++ return 0; +} + -+/* !! rx entry routine, returns a pointer to the next frame received, or NULL if there are no more */ -+void* -+dma_rx(dma_info_t *di) ++/* Fix chip's configuration. The current core may be changed upon return */ ++static int ++sb_pci_fixcfg(sb_info_t *si) +{ -+ void *p; -+ uint len; -+ int skiplen = 0; -+ -+ while ((p = dma_getnextrxp(di, FALSE))) { -+ /* skip giant packets which span multiple rx descriptors */ -+ if (skiplen > 0) { -+ skiplen -= di->rxbufsize; -+ if (skiplen < 0) -+ skiplen = 0; -+ PKTFREE(di->osh, p, FALSE); -+ continue; -+ } ++ uint origidx, pciidx; ++ sbpciregs_t *pciregs; ++ sbpcieregs_t *pcieregs; ++ uint16 val16, *reg16; ++ char name[SB_DEVPATH_BUFSZ+16], *value; ++ char devpath[SB_DEVPATH_BUFSZ]; + -+ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); -+ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); ++ ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS); + -+ /* bad frame length check */ -+ if (len > (di->rxbufsize - di->rxoffset)) { -+ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); -+ if (len > 0) -+ skiplen = len - (di->rxbufsize - di->rxoffset); -+ PKTFREE(di->osh, p, FALSE); -+ di->hnddma.rxgiants++; -+ continue; -+ } ++ /* Fix PCI(e) SROM shadow area */ ++ /* save the current index */ ++ origidx = sb_coreidx(&si->sb); + -+ /* set actual length */ -+ PKTSETLEN(di->osh, p, (di->rxoffset + len)); ++ /* check 'pi' is correct and fix it if not */ ++ if (si->sb.buscoretype == SB_PCIE) { ++ pcieregs = (sbpcieregs_t *)sb_setcore(&si->sb, SB_PCIE, 0); ++ ASSERT(pcieregs); ++ reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; ++ } ++ else if (si->sb.buscoretype == SB_PCI) { ++ pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0); ++ ASSERT(pciregs); ++ reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; ++ } ++ else { ++ ASSERT(0); ++ return -1; ++ } ++ pciidx = sb_coreidx(&si->sb); ++ val16 = R_REG(reg16); ++ if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) { ++ val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK); ++ W_REG(reg16, val16); ++ } + -+ break; ++ /* restore the original index */ ++ sb_setcoreidx(&si->sb, origidx); ++ ++ /* Fix bar0window */ ++ /* !do it last, it changes the current core! */ ++ if (sb_devpath(&si->sb, devpath, sizeof(devpath))) ++ return -1; ++ sprintf(name, "%sb0w", devpath); ++ if ((value = getvar(NULL, name))) { ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32), ++ bcm_strtoul(value, NULL, 16)); ++ /* update curidx since the current core is changed */ ++ si->curidx = _sb_coreidx(si); ++ if (si->curidx == BADIDX) { ++ SB_ERROR(("sb_pci_fixcfg: bad core index\n")); ++ return -1; ++ } + } + -+ return (p); ++ return 0; +} + -+/* post receive buffers */ -+void -+dma_rxfill(dma_info_t *di) -+{ -+ void *p; -+ uint rxin, rxout; -+ uint32 ctrl; -+ uint n; -+ uint i; -+ uint32 pa; -+ uint rxbufsize; +diff -Naur linux.old/drivers/net/hnd/shared_ksyms.sh linux.dev/drivers/net/hnd/shared_ksyms.sh +--- linux.old/drivers/net/hnd/shared_ksyms.sh 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/hnd/shared_ksyms.sh 2006-04-06 15:34:15.000000000 +0200 +@@ -0,0 +1,21 @@ ++#!/bin/sh ++# ++# Copyright 2004, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: shared_ksyms.sh,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++# + -+ /* -+ * Determine how many receive buffers we're lacking -+ * from the full complement, allocate, initialize, -+ * and post them, then update the chip rx lastdscr. -+ */ ++cat < ++#include ++EOF + -+ rxin = di->rxin; -+ rxout = di->rxout; -+ rxbufsize = di->rxbufsize; ++for file in $* ; do ++ ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p' ++done +diff -Naur linux.old/drivers/net/wireless/Config.in linux.dev/drivers/net/wireless/Config.in +--- linux.old/drivers/net/wireless/Config.in 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/drivers/net/wireless/Config.in 2006-04-06 17:04:48.000000000 +0200 +@@ -13,6 +13,8 @@ + fi + + if [ "$CONFIG_PCI" = "y" ]; then ++ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support (old)' CONFIG_WL ++ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support (new)' CONFIG_WL2 + dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL + dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL + dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL +diff -Naur linux.old/drivers/net/wl/Makefile linux.dev/drivers/net/wl/Makefile +--- linux.old/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/Makefile 2006-04-06 16:56:38.000000000 +0200 +@@ -0,0 +1,27 @@ ++# ++# Makefile for the Broadcom wl driver ++# ++# Copyright 2004, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ + -+ n = di->nrxpost - NRXDACTIVE(rxin, rxout); ++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER + -+ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); ++O_TARGET := wl.o + -+ for (i = 0; i < n; i++) { -+ if ((p = PKTGET(di->osh, rxbufsize, FALSE)) == NULL) { -+ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); -+ di->hnddma.rxnobuf++; -+ break; -+ } ++obj-y := apsta_aeskeywrap.o apsta_aes.o apsta_bcmwpa.o apsta_d11ucode.o ++obj-y += apsta_hmac.o apsta_md5.o apsta_passhash.o apsta_prf.o apsta_rc4.o ++obj-y += apsta_rijndael-alg-fst.o apsta_sha1.o apsta_tkhash.o apsta_wlc_led.o ++obj-y += apsta_wlc_phy.o apsta_wlc_rate.o apsta_wlc_security.o ++obj-y += apsta_wlc_sup.o apsta_wlc_wet.o apsta_wl_linux.o apsta_wlc.o ++obj-y += compat.o hnddma.o + -+ /* Do a cached write instead of uncached write since DMA_MAP -+ * will flush the cache. */ -+ *(uint32*)(PKTDATA(di->osh, p)) = 0; ++obj-m := $(O_TARGET) + -+ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p); -+ ASSERT(ISALIGNED(pa, 4)); ++include $(TOPDIR)/Rules.make +diff -Naur linux.old/drivers/net/wl/compat.c linux.dev/drivers/net/wl/compat.c +--- linux.old/drivers/net/wl/compat.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/compat.c 2006-04-06 17:12:19.000000000 +0200 +@@ -0,0 +1,237 @@ ++/* ++ * Misc useful OS-independent routines. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ + -+ /* save the free packet pointer */ -+ ASSERT(di->rxp[rxout] == NULL); -+ di->rxp[rxout] = p; ++#include ++#ifdef BCMDRIVER ++#include ++#include ++#include ++#else ++#include ++#include ++#endif ++#include "pktq.h" ++#include ++#include ++#include + -+ if (DMA64_ENAB(di)) { -+ /* prep the descriptor control value */ -+ if (rxout == (di->nrxd - 1)) -+ ctrl = CTRL_EOT; ++#ifdef BCMDRIVER ++/* copy a pkt buffer chain into a buffer */ ++uint ++pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) ++{ ++ uint n, ret = 0; + -+ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize); -+ } else { -+ /* prep the descriptor control value */ -+ ctrl = rxbufsize; -+ if (rxout == (di->nrxd - 1)) -+ ctrl |= CTRL_EOT; -+ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl); -+ } ++ if (len < 0) ++ len = 4096; /* "infinite" */ + -+ rxout = NEXTRXD(rxout); ++ /* skip 'offset' bytes */ ++ for (; p && offset; p = PKTNEXT(osh, p)) { ++ if (offset < (uint)PKTLEN(osh, p)) ++ break; ++ offset -= PKTLEN(osh, p); + } + -+ di->rxout = rxout; ++ if (!p) ++ return 0; + -+ /* update the chip lastdscr pointer */ -+ if (DMA64_ENAB(di)) { -+ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t)); -+ } else { -+ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); ++ /* copy the data */ ++ for (; p && len; p = PKTNEXT(osh, p)) { ++ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); ++ bcopy(PKTDATA(osh, p) + offset, buf, n); ++ buf += n; ++ len -= n; ++ ret += n; ++ offset = 0; + } ++ ++ return ret; +} + -+void -+dma_txreclaim(dma_info_t *di, bool forceall) ++/* return total length of buffer chain */ ++uint ++pkttotlen(osl_t *osh, void *p) +{ -+ void *p; -+ -+ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); ++ uint total; + -+ while ((p = dma_getnexttxp(di, forceall))) -+ PKTFREE(di->osh, p, TRUE); ++ total = 0; ++ for (; p; p = PKTNEXT(osh, p)) ++ total += PKTLEN(osh, p); ++ return (total); +} + -+/* -+ * Reclaim next completed txd (txds if using chained buffers) and -+ * return associated packet. -+ * If 'force' is true, reclaim txd(s) and return associated packet -+ * regardless of the value of the hardware "curr" pointer. -+ */ -+void* -+dma_getnexttxp(dma_info_t *di, bool forceall) ++void ++pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]) +{ -+ if (DMA64_ENAB(di)) { -+ return dma64_getnexttxp(di, forceall); -+ } else { -+ return dma32_getnexttxp(di, forceall); ++ q->head = q->tail = NULL; ++ q->maxlen = maxlen; ++ q->len = 0; ++ if (prio_map) { ++ q->priority = TRUE; ++ bcopy(prio_map, q->prio_map, sizeof(q->prio_map)); + } ++ else ++ q->priority = FALSE; +} -+ -+/* like getnexttxp but no reclaim */ -+void* -+dma_peeknexttxp(dma_info_t *di) ++ ++ ++/* should always check pktq_full before calling pktenq */ ++void ++pktenq(struct pktq *q, void *p, bool lifo) +{ -+ uint end, i; ++ void *next, *prev; + -+ if (DMA64_ENAB(di)) { -+ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); -+ } else { -+ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ /* allow 10 pkts slack */ ++ ASSERT(q->len < (q->maxlen + 10)); ++ ++ /* Queueing chains not allowed */ ++ ASSERT(PKTLINK(p) == NULL); ++ ++ /* Queue is empty */ ++ if (q->tail == NULL) { ++ ASSERT(q->head == NULL); ++ q->head = q->tail = p; + } + -+ for (i = di->txin; i != end; i = NEXTTXD(i)) -+ if (di->txp[i]) -+ return (di->txp[i]); ++ /* Insert at head or tail */ ++ else if (q->priority == FALSE) { ++ /* Insert at head (LIFO) */ ++ if (lifo) { ++ PKTSETLINK(p, q->head); ++ q->head = p; ++ } ++ /* Insert at tail (FIFO) */ ++ else { ++ ASSERT(PKTLINK(q->tail) == NULL); ++ PKTSETLINK(q->tail, p); ++ PKTSETLINK(p, NULL); ++ q->tail = p; ++ } ++ } + -+ return (NULL); -+} ++ /* Insert by priority */ ++ else { ++ /* legal priorities 0-7 */ ++ ASSERT(PKTPRIO(p) <= MAXPRIO); + -+/* -+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). -+ */ -+void -+dma_txrotate(di_t *di) -+{ -+ if (DMA64_ENAB(di)) { -+ dma64_txrotate(di); -+ } else { -+ dma32_txrotate(di); ++ ASSERT(q->head); ++ ASSERT(q->tail); ++ /* Shortcut to insertion at tail */ ++ if (_pktq_pri(q, PKTPRIO(p)) < _pktq_pri(q, PKTPRIO(q->tail)) || ++ (!lifo && _pktq_pri(q, PKTPRIO(p)) <= _pktq_pri(q, PKTPRIO(q->tail)))) { ++ prev = q->tail; ++ next = NULL; ++ } ++ /* Insert at head or in the middle */ ++ else { ++ prev = NULL; ++ next = q->head; ++ } ++ /* Walk the queue */ ++ for (; next; prev = next, next = PKTLINK(next)) { ++ /* Priority queue invariant */ ++ ASSERT(!prev || _pktq_pri(q, PKTPRIO(prev)) >= _pktq_pri(q, PKTPRIO(next))); ++ /* Insert at head of string of packets of same priority (LIFO) */ ++ if (lifo) { ++ if (_pktq_pri(q, PKTPRIO(p)) >= _pktq_pri(q, PKTPRIO(next))) ++ break; ++ } ++ /* Insert at tail of string of packets of same priority (FIFO) */ ++ else { ++ if (_pktq_pri(q, PKTPRIO(p)) > _pktq_pri(q, PKTPRIO(next))) ++ break; ++ } ++ } ++ /* Insert at tail */ ++ if (next == NULL) { ++ ASSERT(PKTLINK(q->tail) == NULL); ++ PKTSETLINK(q->tail, p); ++ PKTSETLINK(p, NULL); ++ q->tail = p; ++ } ++ /* Insert in the middle */ ++ else if (prev) { ++ PKTSETLINK(prev, p); ++ PKTSETLINK(p, next); ++ } ++ /* Insert at head */ ++ else { ++ PKTSETLINK(p, q->head); ++ q->head = p; ++ } + } ++ ++ /* List invariants after insertion */ ++ ASSERT(q->head); ++ ASSERT(PKTLINK(q->tail) == NULL); ++ ++ q->len++; +} + -+void -+dma_rxreclaim(dma_info_t *di) ++/* dequeue packet at head */ ++void* ++pktdeq(struct pktq *q) +{ + void *p; + -+ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); ++ if ((p = q->head)) { ++ ASSERT(q->tail); ++ q->head = PKTLINK(p); ++ PKTSETLINK(p, NULL); ++ q->len--; ++ if (q->head == NULL) ++ q->tail = NULL; ++ } ++ else { ++ ASSERT(q->tail == NULL); ++ } + -+ while ((p = dma_getnextrxp(di, TRUE))) -+ PKTFREE(di->osh, p, FALSE); ++ return (p); +} + -+void * -+dma_getnextrxp(dma_info_t *di, bool forceall) ++/* dequeue packet at tail */ ++void* ++pktdeqtail(struct pktq *q) +{ -+ if (DMA64_ENAB(di)) { -+ return dma64_getnextrxp(di, forceall); -+ } else { -+ return dma32_getnextrxp(di, forceall); ++ void *p; ++ void *next, *prev; ++ ++ if (q->head == q->tail) { /* last packet on queue or queue empty */ ++ p = q->head; ++ q->head = q->tail = NULL; ++ q->len = 0; ++ return(p); + } -+} + -+uintptr -+dma_getvar(dma_info_t *di, char *name) -+{ -+ if (!strcmp(name, "&txavail")) -+ return ((uintptr) &di->txavail); -+ else { -+ ASSERT(0); ++ /* start walk at head */ ++ prev = NULL; ++ next = q->head; ++ ++ /* Walk the queue to find prev of q->tail */ ++ for (; next; prev = next, next = PKTLINK(next)) { ++ if (next == q->tail) ++ break; + } -+ return (0); -+} + -+void -+dma_txblock(dma_info_t *di) -+{ -+ di->txavail = 0; -+} ++ ASSERT(prev); + -+void -+dma_txunblock(dma_info_t *di) -+{ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+} ++ PKTSETLINK(prev, NULL); ++ q->tail = prev; ++ q->len--; ++ p = next; + -+uint -+dma_txactive(dma_info_t *di) -+{ -+ return (NTXDACTIVE(di->txin, di->txout)); -+} -+ -+void -+dma_rxpiomode(dma32regs_t *regs) -+{ -+ W_REG(®s->control, RC_FM); ++ return (p); +} ++#endif + -+void -+dma_txpioloopback(dma32regs_t *regs) -+{ -+ OR_REG(®s->control, XC_LE); -+} + +diff -Naur linux.old/drivers/net/wl/hnddma.c linux.dev/drivers/net/wl/hnddma.c +--- linux.old/drivers/net/wl/hnddma.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/hnddma.c 2006-04-06 16:58:24.000000000 +0200 +@@ -0,0 +1,1453 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA module. ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ + ++#include ++#include ++#include ++#include ++#include ++#include ++#include + ++struct dma_info; /* forward declaration */ ++#define di_t struct dma_info + -+/*** 32 bits DMA non-inline functions ***/ -+static bool -+dma32_alloc(dma_info_t *di, uint direction) -+{ -+ uint size; -+ uint ddlen; -+ void *va; ++#include "sbhnddma.h" ++#include "hnddma.h" + -+ ddlen = sizeof (dma32dd_t); ++/* debug/trace */ ++#define DMA_ERROR(args) ++#define DMA_TRACE(args) + -+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++/* default dma message level (if input msg_level pointer is null in dma_attach()) */ ++static uint dma_msg_level = ++ 0; + -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) -+ size += D32RINGALIGN; ++#define MAXNAMEL 8 + ++/* dma engine software state */ ++typedef struct dma_info { ++ hnddma_t hnddma; /* exported structure */ ++ uint *msg_level; /* message level pointer */ ++ char name[MAXNAMEL]; /* callers name for diag msgs */ ++ ++ void *osh; /* os handle */ ++ sb_t *sbh; /* sb handle */ ++ ++ bool dma64; /* dma64 enabled */ ++ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ ++ ++ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ ++ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ ++ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ ++ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ + -+ if (direction == DMA_TX) { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); -+ return FALSE; -+ } ++ uint32 dma64align; /* either 8k or 4k depends on number of dd */ ++ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ ++ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ ++ uint ntxd; /* # tx descriptors tunable */ ++ uint txin; /* index of next descriptor to reclaim */ ++ uint txout; /* index of next descriptor to post */ ++ uint txavail; /* # free tx descriptors */ ++ void **txp; /* pointer to parallel array of pointers to packets */ ++ ulong txdpa; /* physical address of descriptor ring */ ++ uint txdalign; /* #bytes added to alloc'd mem to align txd */ ++ uint txdalloc; /* #bytes allocated for the ring */ + -+ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); -+ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); -+ di->txdpa += di->txdalign; -+ di->txdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); -+ } else { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); -+ return FALSE; -+ } -+ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); -+ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); -+ di->rxdpa += di->rxdalign; -+ di->rxdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); -+ } ++ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ ++ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ ++ uint nrxd; /* # rx descriptors tunable */ ++ uint rxin; /* index of next descriptor to reclaim */ ++ uint rxout; /* index of next descriptor to post */ ++ void **rxp; /* pointer to parallel array of pointers to packets */ ++ ulong rxdpa; /* physical address of descriptor ring */ ++ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ ++ uint rxdalloc; /* #bytes allocated for the ring */ + -+ return TRUE; -+} ++ /* tunables */ ++ uint rxbufsize; /* rx buffer size in bytes */ ++ uint nrxpost; /* # rx buffers to keep posted */ ++ uint rxoffset; /* rxcontrol offset */ ++ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ ++ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */ ++ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ ++ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */ ++} dma_info_t; + -+static void -+dma32_txreset(dma_info_t *di) -+{ -+ uint32 status; ++#ifdef BCMDMA64 ++#define DMA64_ENAB(di) ((di)->dma64) ++#else ++#define DMA64_ENAB(di) (0) ++#endif + -+ /* suspend tx DMA first */ -+ W_REG(&di->d32txregs->control, XC_SE); -+ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED && -+ status != XS_XS_IDLE && -+ status != XS_XS_STOPPED, -+ 10000); ++/* descriptor bumping macros */ ++#define XXD(x, n) ((x) & ((n) - 1)) ++#define TXD(x) XXD((x), di->ntxd) ++#define RXD(x) XXD((x), di->nrxd) ++#define NEXTTXD(i) TXD(i + 1) ++#define PREVTXD(i) TXD(i - 1) ++#define NEXTRXD(i) RXD(i + 1) ++#define NTXDACTIVE(h, t) TXD(t - h) ++#define NRXDACTIVE(h, t) RXD(t - h) + -+ W_REG(&di->d32txregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED, -+ 10000); ++/* macros to convert between byte offsets and indexes */ ++#define B2I(bytes, type) ((bytes) / sizeof(type)) ++#define I2B(index, type) ((index) * sizeof(type)) + -+ if (status != XS_XS_DISABLED) { -+ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); -+ } ++#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ ++#define PCI32ADDR_HIGH_SHIFT 30 + -+ /* wait for the last transaction to complete */ -+ OSL_DELAY(300); -+} + -+static void -+dma32_rxreset(dma_info_t *di) -+{ -+ uint32 status; ++/* prototypes */ ++static bool dma_isaddrext(dma_info_t *di); ++static bool dma_alloc(dma_info_t *di, uint direction); + -+ W_REG(&di->d32rxregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED, -+ 10000); ++static bool dma32_alloc(dma_info_t *di, uint direction); ++static void dma32_txreset(dma_info_t *di); ++static void dma32_rxreset(dma_info_t *di); ++static bool dma32_txsuspendedidle(dma_info_t *di); ++static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags); ++static void* dma32_getnexttxp(dma_info_t *di, bool forceall); ++static void* dma32_getnextrxp(dma_info_t *di, bool forceall); ++static void dma32_txrotate(di_t *di); + -+ if (status != RS_RS_DISABLED) { -+ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); -+ } -+} ++/* prototype or stubs */ ++#ifdef BCMDMA64 ++static bool dma64_alloc(dma_info_t *di, uint direction); ++static void dma64_txreset(dma_info_t *di); ++static void dma64_rxreset(dma_info_t *di); ++static bool dma64_txsuspendedidle(dma_info_t *di); ++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags); ++static void* dma64_getnexttxp(dma_info_t *di, bool forceall); ++static void* dma64_getnextrxp(dma_info_t *di, bool forceall); ++static void dma64_txrotate(di_t *di); ++#else ++static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; } ++static void dma64_txreset(dma_info_t *di) {} ++static void dma64_rxreset(dma_info_t *di) {} ++static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;} ++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; } ++static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; } ++static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; } ++static void dma64_txrotate(di_t *di) { return; } ++#endif + -+static bool -+dma32_txsuspendedidle(dma_info_t *di) -+{ -+ if (!(R_REG(&di->d32txregs->control) & XC_SE)) -+ return 0; ++/* old dmaregs struct for compatibility */ ++typedef volatile struct { ++ /* transmit channel */ ++ uint32 xmtcontrol; /* enable, et al */ ++ uint32 xmtaddr; /* descriptor ring base address (4K aligned) */ ++ uint32 xmtptr; /* last descriptor posted to chip */ ++ uint32 xmtstatus; /* current active descriptor, et al */ + -+ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) -+ return 0; -+ -+ OSL_DELAY(2); -+ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); -+} ++ /* receive channel */ ++ uint32 rcvcontrol; /* enable, et al */ ++ uint32 rcvaddr; /* descriptor ring base address (4K aligned) */ ++ uint32 rcvptr; /* last descriptor posted to chip */ ++ uint32 rcvstatus; /* current active descriptor, et al */ ++} dmaregs_t; + -+/* -+ * supports full 32bit dma engine buffer addressing so -+ * dma buffers can cross 4 Kbyte page boundaries. -+ */ -+static int -+dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++void* ++dma_attach(void *drv, void *osh, char *name, dmaregs_t *regs, uint ntxd, uint nrxd, ++ uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level) +{ -+ void *p, *next; -+ uchar *data; -+ uint len; -+ uint txout; -+ uint32 ctrl; -+ uint32 pa; -+ -+ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ dma_info_t *di; ++ uint size; ++ dma32regs_t *dmaregstx = regs; ++ dma32regs_t *dmaregsrx = dmaregstx + 1; ++ ++ /* allocate private info structure */ ++ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { ++ return (NULL); ++ } ++ bzero((char*)di, sizeof (dma_info_t)); ++ di->msg_level = msg_level ? msg_level : &dma_msg_level; + -+ txout = di->txout; -+ ctrl = 0; ++ /* check arguments */ ++ ASSERT(ISPOWEROF2(ntxd)); ++ ASSERT(ISPOWEROF2(nrxd)); ++ if (nrxd == 0) ++ ASSERT(dmaregsrx == NULL); ++ if (ntxd == 0) ++ ASSERT(dmaregstx == NULL); + -+ /* -+ * Walk the chain of packet buffers -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ data = PKTDATA(di->osh, p); -+ len = PKTLEN(di->osh, p); -+ next = PKTNEXT(di->osh, p); ++ ASSERT(ntxd <= D32MAXDD); ++ ASSERT(nrxd <= D32MAXDD); ++ di->d32txregs = (dma32regs_t *)dmaregstx; ++ di->d32rxregs = (dma32regs_t *)dmaregsrx; + -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) -+ goto outoftxd; ++ /* make a private copy of our callers name */ ++ strncpy(di->name, name, MAXNAMEL); ++ di->name[MAXNAMEL-1] = '\0'; + -+ if (len == 0) -+ continue; ++ di->osh = osh; ++ di->sbh = NULL; + -+ /* get physical address of buffer start */ -+ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ /* save tunables */ ++ di->ntxd = ntxd; ++ di->nrxd = nrxd; ++ di->rxbufsize = rxbufsize; ++ di->nrxpost = nrxpost; ++ di->rxoffset = rxoffset; + -+ /* build the descriptor control value */ -+ ctrl = len & CTRL_BC_MASK; ++ di->ddoffsetlow = ddoffset; ++ di->dataoffsetlow = dataoffset; ++ di->ddoffsethigh = 0; ++ di->dataoffsethigh = 0; ++ ++ di->addrext = 0; ++ ++ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", ++ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow)); + -+ ctrl |= coreflags; -+ -+ if (p == p0) -+ ctrl |= CTRL_SOF; -+ if (next == NULL) -+ ctrl |= (CTRL_IOC | CTRL_EOF); -+ if (txout == (di->ntxd - 1)) -+ ctrl |= CTRL_EOT; ++ /* allocate tx packet pointer vector */ ++ if (ntxd) { ++ size = ntxd * sizeof (void*); ++ if ((di->txp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero((char*)di->txp, size); ++ } + -+ if (DMA64_ENAB(di)) { -+ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len); -+ } else { -+ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl); ++ /* allocate rx packet pointer vector */ ++ if (nrxd) { ++ size = nrxd * sizeof (void*); ++ if ((di->rxp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); ++ goto fail; + } ++ bzero((char*)di->rxp, size); ++ } + -+ ASSERT(di->txp[txout] == NULL); ++ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ ++ if (ntxd) { ++ if (!dma_alloc(di, DMA_TX)) ++ goto fail; ++ } + -+ txout = NEXTTXD(txout); ++ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ ++ if (nrxd) { ++ if (!dma_alloc(di, DMA_RX)) ++ goto fail; + } + -+ /* if last txd eof not set, fix it */ -+ if (!(ctrl & CTRL_EOF)) -+ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF)); ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa)); ++ goto fail; ++ } ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa)); ++ goto fail; ++ } + -+ /* save the packet */ -+ di->txp[PREVTXD(txout)] = p0; ++ return ((void*)di); + -+ /* bump the tx descriptor index */ -+ di->txout = txout; ++fail: ++ dma_detach((void*)di); ++ return (NULL); ++} + -+ /* kick the chip */ ++ ++static bool ++dma_alloc(dma_info_t *di, uint direction) ++{ + if (DMA64_ENAB(di)) { -+ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); ++ return dma64_alloc(di, direction); + } else { -+ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t)); ++ return dma32_alloc(di, direction); + } -+ -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (0); -+ -+ outoftxd: -+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); -+ PKTFREE(di->osh, p0, TRUE); -+ di->txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); +} + -+static void* -+dma32_getnexttxp(dma_info_t *di, bool forceall) ++/* may be called with core in reset */ ++void ++dma_detach(dma_info_t *di) +{ -+ uint start, end, i; -+ void *txp; -+ -+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); -+ -+ txp = NULL; -+ -+ start = di->txin; -+ if (forceall) -+ end = di->txout; -+ else -+ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); -+ -+ if ((start == 0) && (end > di->txout)) -+ goto bogus; -+ -+ for (i = start; i != end && !txp; i = NEXTTXD(i)) { -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), -+ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]); ++ if (di == NULL) ++ return; + -+ W_SM(&di->txd32[i].addr, 0xdeadbeef); -+ txp = di->txp[i]; -+ di->txp[i] = NULL; -+ } ++ DMA_TRACE(("%s: dma_detach\n", di->name)); + -+ di->txin = i; ++ /* shouldn't be here if descriptors are unreclaimed */ ++ ASSERT(di->txin == di->txout); ++ ASSERT(di->rxin == di->rxout); + -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ /* free dma descriptor rings */ ++ if (di->txd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign)); ++ if (di->rxd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign)); + -+ return (txp); ++ /* free packet pointer vectors */ ++ if (di->txp) ++ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*))); ++ if (di->rxp) ++ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*))); + -+bogus: -+/* -+ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", -+ start, end, di->txout, forceall)); -+*/ -+ return (NULL); ++ /* free our private info structure */ ++ MFREE(di->osh, (void*)di, sizeof (dma_info_t)); +} + -+static void * -+dma32_getnextrxp(dma_info_t *di, bool forceall) ++/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ ++static bool ++dma_isaddrext(dma_info_t *di) +{ -+ uint i; -+ void *rxp; -+ -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma_rxenabled(di)); -+ -+ i = di->rxin; -+ -+ /* return if no packets posted */ -+ if (i == di->rxout) -+ return (NULL); ++ uint32 w; + -+ /* ignore curr if forceall */ -+ if (!forceall && (i == B2I(R_REG(&di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) -+ return (NULL); ++ if (DMA64_ENAB(di)) { ++ OR_REG(&di->d64txregs->control, D64_XC_AE); ++ w = R_REG(&di->d32txregs->control); ++ AND_REG(&di->d32txregs->control, ~D64_XC_AE); ++ return ((w & XC_AE) == D64_XC_AE); ++ } else { ++ OR_REG(&di->d32txregs->control, XC_AE); ++ w = R_REG(&di->d32txregs->control); ++ AND_REG(&di->d32txregs->control, ~XC_AE); ++ return ((w & XC_AE) == XC_AE); ++ } ++} + -+ /* get the packet pointer that corresponds to the rx descriptor */ -+ rxp = di->rxp[i]; -+ ASSERT(rxp); -+ di->rxp[i] = NULL; ++void ++dma_txreset(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txreset\n", di->name)); + -+ /* clear this packet from the descriptor ring */ -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), -+ di->rxbufsize, DMA_RX, rxp); -+ W_SM(&di->rxd32[i].addr, 0xdeadbeef); ++ if (DMA64_ENAB(di)) ++ dma64_txreset(di); ++ else ++ dma32_txreset(di); ++} + -+ di->rxin = NEXTRXD(i); ++void ++dma_rxreset(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxreset\n", di->name)); + -+ return (rxp); ++ if (DMA64_ENAB(di)) ++ dma64_rxreset(di); ++ else ++ dma32_rxreset(di); +} + ++/* initialize descriptor table base address */ +static void -+dma32_txrotate(di_t *di) ++dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) +{ -+ uint ad; -+ uint nactive; -+ uint rot; -+ uint old, new; -+ uint32 w; -+ uint first, last; -+ -+ ASSERT(dma_txsuspendedidle(di)); -+ -+ nactive = dma_txactive(di); -+ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); -+ rot = TXD(ad - di->txin); -+ -+ ASSERT(rot < di->ntxd); -+ -+ /* full-ring case is a lot harder - don't worry about this */ -+ if (rot >= (di->ntxd - nactive)) { -+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); -+ return; ++ if (DMA64_ENAB(di)) { ++ if (direction == DMA_TX) { ++ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow); ++ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); ++ } else { ++ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow); ++ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); ++ } ++ } else { ++ uint32 offset = di->ddoffsetlow; ++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ if (direction == DMA_TX) ++ W_REG(&di->d32txregs->addr, (pa + offset)); ++ else ++ W_REG(&di->d32rxregs->addr, (pa + offset)); ++ } else { ++ /* dma32 address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ ++ if (direction == DMA_TX) { ++ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); ++ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT)); ++ } else { ++ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); ++ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT)); ++ } ++ } + } ++} + -+ first = di->txin; -+ last = PREVTXD(di->txout); -+ -+ /* move entries starting at last and moving backwards to first */ -+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { -+ new = TXD(old + rot); -+ -+ /* -+ * Move the tx dma descriptor. -+ * EOT is set only in the last entry in the ring. -+ */ -+ w = R_SM(&di->txd32[old].ctrl) & ~CTRL_EOT; -+ if (new == (di->ntxd - 1)) -+ w |= CTRL_EOT; -+ W_SM(&di->txd32[new].ctrl, w); -+ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); ++/* init the tx or rx descriptor */ ++static INLINE void ++dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl) ++{ ++ uint offset = di->dataoffsetlow; + -+ /* zap the old tx dma descriptor address field */ -+ W_SM(&di->txd32[old].addr, 0xdeadbeef); ++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); ++ } else { ++ /* address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; + -+ /* move the corresponding txp[] entry */ -+ ASSERT(di->txp[new] == NULL); -+ di->txp[new] = di->txp[old]; -+ di->txp[old] = NULL; ++ *ctrl |= (ae << CTRL_AE_SHIFT); ++ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); + } -+ -+ /* update txin and txout */ -+ di->txin = ad; -+ di->txout = TXD(di->txout + rot); -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ /* kick the chip */ -+ W_REG(&di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); +} + -+/*** 64 bits DMA non-inline functions ***/ -+ -+#ifdef BCMDMA64 -+ -+static bool -+dma64_alloc(dma_info_t *di, uint direction) ++/* init the tx or rx descriptor */ ++static INLINE void ++dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount) +{ -+ uint size; -+ uint ddlen; -+ uint32 alignbytes; -+ void *va; -+ -+ ddlen = sizeof (dma64dd_t); ++ uint32 bufaddr_low = pa + di->dataoffsetlow; ++ uint32 bufaddr_high = 0 + di->dataoffsethigh; + -+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; + -+ alignbytes = di->dma64align; ++ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low)); ++ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high)); ++ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); ++ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); ++} + -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes)) -+ size += alignbytes; ++void ++dma_txinit(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txinit\n", di->name)); + ++ di->txin = di->txout = 0; ++ di->txavail = di->ntxd - 1; + -+ if (direction == DMA_TX) { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); -+ return FALSE; -+ } ++ /* clear tx descriptor ring */ ++ if (DMA64_ENAB(di)) { ++ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t))); ++ W_REG(&di->d64txregs->control, XC_XE); ++ dma_ddtable_init(di, DMA_TX, di->txdpa); ++ } else { ++ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t))); ++ W_REG(&di->d32txregs->control, XC_XE); ++ dma_ddtable_init(di, DMA_TX, di->txdpa); ++ } ++} + -+ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); -+ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va); -+ di->txdpa += di->txdalign; -+ di->txdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes)); ++bool ++dma_txenabled(dma_info_t *di) ++{ ++ uint32 xc; ++ ++ /* If the chip is dead, it is not enabled :-) */ ++ if (DMA64_ENAB(di)) { ++ xc = R_REG(&di->d64txregs->control); ++ return ((xc != 0xffffffff) && (xc & D64_XC_XE)); + } else { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); -+ return FALSE; -+ } -+ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); -+ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va); -+ di->rxdpa += di->rxdalign; -+ di->rxdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes)); ++ xc = R_REG(&di->d32txregs->control); ++ return ((xc != 0xffffffff) && (xc & XC_XE)); + } ++} + -+ return TRUE; ++void ++dma_txsuspend(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); ++ if (DMA64_ENAB(di)) ++ OR_REG(&di->d64txregs->control, D64_XC_SE); ++ else ++ OR_REG(&di->d32txregs->control, XC_SE); +} + -+static void -+dma64_txreset(dma_info_t *di) ++void ++dma_txresume(dma_info_t *di) +{ -+ uint32 status; ++ DMA_TRACE(("%s: dma_txresume\n", di->name)); ++ if (DMA64_ENAB(di)) ++ AND_REG(&di->d64txregs->control, ~D64_XC_SE); ++ else ++ AND_REG(&di->d32txregs->control, ~XC_SE); ++} + -+ /* suspend tx DMA first */ -+ W_REG(&di->d64txregs->control, D64_XC_SE); -+ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED && -+ status != D64_XS0_XS_IDLE && -+ status != D64_XS0_XS_STOPPED, -+ 10000); ++bool ++dma_txsuspendedidle(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return dma64_txsuspendedidle(di); ++ else ++ return dma32_txsuspendedidle(di); ++} + -+ W_REG(&di->d64txregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED, -+ 10000); ++bool ++dma_txsuspended(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); ++ else ++ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE); ++} + -+ if (status != D64_XS0_XS_DISABLED) { -+ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); -+ } ++bool ++dma_txstopped(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); ++ else ++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); ++} + -+ /* wait for the last transaction to complete */ -+ OSL_DELAY(300); ++bool ++dma_rxstopped(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); ++ else ++ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); ++} ++ ++void ++dma_fifoloopbackenable(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); ++ if (DMA64_ENAB(di)) ++ OR_REG(&di->d64txregs->control, D64_XC_LE); ++ else ++ OR_REG(&di->d32txregs->control, XC_LE); +} + -+static void -+dma64_rxreset(dma_info_t *di) ++void ++dma_rxinit(dma_info_t *di) +{ -+ uint32 status; ++ DMA_TRACE(("%s: dma_rxinit\n", di->name)); + -+ W_REG(&di->d64rxregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED, -+ 10000); ++ di->rxin = di->rxout = 0; + -+ if (status != D64_RS0_RS_DISABLED) { -+ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); ++ /* clear rx descriptor ring */ ++ if (DMA64_ENAB(di)) { ++ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t))); ++ dma_rxenable(di); ++ dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ } else { ++ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t))); ++ dma_rxenable(di); ++ dma_ddtable_init(di, DMA_RX, di->rxdpa); + } +} + -+static bool -+dma64_txsuspendedidle(dma_info_t *di) ++void ++dma_rxenable(dma_info_t *di) +{ -+ -+ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE)) -+ return 0; -+ -+ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) -+ return 1; -+ -+ return 0; ++ DMA_TRACE(("%s: dma_rxenable\n", di->name)); ++ if (DMA64_ENAB(di)) ++ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE)); ++ else ++ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); +} + -+/* -+ * supports full 32bit dma engine buffer addressing so -+ * dma buffers can cross 4 Kbyte page boundaries. -+ */ -+static int -+dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++bool ++dma_rxenabled(dma_info_t *di) +{ -+ void *p, *next; -+ uchar *data; -+ uint len; -+ uint txout; -+ uint32 flags; -+ uint32 pa; -+ -+ DMA_TRACE(("%s: dma_txfast\n", di->name)); -+ -+ txout = di->txout; -+ flags = 0; -+ -+ /* -+ * Walk the chain of packet buffers -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ data = PKTDATA(di->osh, p); -+ len = PKTLEN(di->osh, p); -+ next = PKTNEXT(di->osh, p); -+ -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) -+ goto outoftxd; -+ -+ if (len == 0) -+ continue; -+ -+ /* get physical address of buffer start */ -+ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); -+ -+ flags = coreflags; -+ -+ if (p == p0) -+ flags |= D64_CTRL1_SOF; -+ if (next == NULL) -+ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); -+ if (txout == (di->ntxd - 1)) -+ flags |= D64_CTRL1_EOT; -+ -+ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); -+ -+ ASSERT(di->txp[txout] == NULL); ++ uint32 rc; + -+ txout = NEXTTXD(txout); ++ if (DMA64_ENAB(di)) { ++ rc = R_REG(&di->d64rxregs->control); ++ return ((rc != 0xffffffff) && (rc & D64_RC_RE)); ++ } else { ++ rc = R_REG(&di->d32rxregs->control); ++ return ((rc != 0xffffffff) && (rc & RC_RE)); + } ++} + -+ /* if last txd eof not set, fix it */ -+ if (!(flags & D64_CTRL1_EOF)) -+ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); -+ -+ /* save the packet */ -+ di->txp[PREVTXD(txout)] = p0; -+ -+ /* bump the tx descriptor index */ -+ di->txout = txout; -+ -+ /* kick the chip */ -+ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); -+ -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (0); + -+outoftxd: -+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); -+ PKTFREE(di->osh, p0, TRUE); -+ di->txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); ++/* !! tx entry routine */ ++int ++dma_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_txfast(di, p0, coreflags); ++ } else { ++ return dma32_txfast(di, p0, coreflags); ++ } +} + -+static void* -+dma64_getnexttxp(dma_info_t *di, bool forceall) ++/* !! rx entry routine, returns a pointer to the next frame received, or NULL if there are no more */ ++void* ++dma_rx(dma_info_t *di) +{ -+ uint start, end, i; -+ void *txp; -+ -+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); -+ -+ txp = NULL; ++ void *p; ++ uint len; ++ int skiplen = 0; + -+ start = di->txin; -+ if (forceall) -+ end = di->txout; -+ else -+ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ while ((p = dma_getnextrxp(di, FALSE))) { ++ /* skip giant packets which span multiple rx descriptors */ ++ if (skiplen > 0) { ++ skiplen -= di->rxbufsize; ++ if (skiplen < 0) ++ skiplen = 0; ++ PKTFREE(di->osh, p, FALSE); ++ continue; ++ } + -+ if ((start == 0) && (end > di->txout)) -+ goto bogus; ++ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); ++ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); + -+ for (i = start; i != end && !txp; i = NEXTTXD(i)) { -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow), -+ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]); ++ /* bad frame length check */ ++ if (len > (di->rxbufsize - di->rxoffset)) { ++ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); ++ if (len > 0) ++ skiplen = len - (di->rxbufsize - di->rxoffset); ++ PKTFREE(di->osh, p, FALSE); ++ di->hnddma.rxgiants++; ++ continue; ++ } + -+ W_SM(&di->txd64[i].addrlow, 0xdeadbeef); -+ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); ++ /* set actual length */ ++ PKTSETLEN(di->osh, p, (di->rxoffset + len)); + -+ txp = di->txp[i]; -+ di->txp[i] = NULL; ++ break; + } + -+ di->txin = i; -+ -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (txp); -+ -+bogus: -+/* -+ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", -+ start, end, di->txout, forceall)); -+*/ -+ return (NULL); ++ return (p); +} + -+static void * -+dma64_getnextrxp(dma_info_t *di, bool forceall) ++/* post receive buffers */ ++void ++dma_rxfill(dma_info_t *di) +{ ++ void *p; ++ uint rxin, rxout; ++ uint32 ctrl; ++ uint n; + uint i; -+ void *rxp; ++ uint32 pa; ++ uint rxbufsize; + -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma_rxenabled(di)); ++ /* ++ * Determine how many receive buffers we're lacking ++ * from the full complement, allocate, initialize, ++ * and post them, then update the chip rx lastdscr. ++ */ + -+ i = di->rxin; ++ rxin = di->rxin; ++ rxout = di->rxout; ++ rxbufsize = di->rxbufsize; + -+ /* return if no packets posted */ -+ if (i == di->rxout) -+ return (NULL); ++ n = di->nrxpost - NRXDACTIVE(rxin, rxout); + -+ /* ignore curr if forceall */ -+ if (!forceall && (i == B2I(R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t))) -+ return (NULL); ++ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); + -+ /* get the packet pointer that corresponds to the rx descriptor */ -+ rxp = di->rxp[i]; -+ ASSERT(rxp); -+ di->rxp[i] = NULL; ++ for (i = 0; i < n; i++) { ++ if ((p = PKTGET(di->osh, rxbufsize, FALSE)) == NULL) { ++ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); ++ di->hnddma.rxnobuf++; ++ break; ++ } + -+ /* clear this packet from the descriptor ring */ -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow), -+ di->rxbufsize, DMA_RX, rxp); ++ /* Do a cached write instead of uncached write since DMA_MAP ++ * will flush the cache. */ ++ *(uint32*)(PKTDATA(di->osh, p)) = 0; ++ ++ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p); ++ ASSERT(ISALIGNED(pa, 4)); ++ ++ /* save the free packet pointer */ ++ ASSERT(di->rxp[rxout] == NULL); ++ di->rxp[rxout] = p; ++ ++ if (DMA64_ENAB(di)) { ++ /* prep the descriptor control value */ ++ if (rxout == (di->nrxd - 1)) ++ ctrl = CTRL_EOT; + -+ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); -+ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); ++ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize); ++ } else { ++ /* prep the descriptor control value */ ++ ctrl = rxbufsize; ++ if (rxout == (di->nrxd - 1)) ++ ctrl |= CTRL_EOT; ++ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl); ++ } + -+ di->rxin = NEXTRXD(i); ++ rxout = NEXTRXD(rxout); ++ } + -+ return (rxp); ++ di->rxout = rxout; ++ ++ /* update the chip lastdscr pointer */ ++ if (DMA64_ENAB(di)) { ++ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t)); ++ } else { ++ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); ++ } +} + -+static void -+dma64_txrotate(di_t *di) ++void ++dma_txreclaim(dma_info_t *di, bool forceall) +{ -+ uint ad; -+ uint nactive; -+ uint rot; -+ uint old, new; -+ uint32 w; -+ uint first, last; ++ void *p; + -+ ASSERT(dma_txsuspendedidle(di)); ++ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); + -+ nactive = dma_txactive(di); -+ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t); -+ rot = TXD(ad - di->txin); ++ while ((p = dma_getnexttxp(di, forceall))) ++ PKTFREE(di->osh, p, TRUE); ++} + -+ ASSERT(rot < di->ntxd); ++/* ++ * Reclaim next completed txd (txds if using chained buffers) and ++ * return associated packet. ++ * If 'force' is true, reclaim txd(s) and return associated packet ++ * regardless of the value of the hardware "curr" pointer. ++ */ ++void* ++dma_getnexttxp(dma_info_t *di, bool forceall) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_getnexttxp(di, forceall); ++ } else { ++ return dma32_getnexttxp(di, forceall); ++ } ++} ++ ++/* like getnexttxp but no reclaim */ ++void* ++dma_peeknexttxp(dma_info_t *di) ++{ ++ uint end, i; + -+ /* full-ring case is a lot harder - don't worry about this */ -+ if (rot >= (di->ntxd - nactive)) { -+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); -+ return; ++ if (DMA64_ENAB(di)) { ++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ } else { ++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); + } + -+ first = di->txin; -+ last = PREVTXD(di->txout); ++ for (i = di->txin; i != end; i = NEXTTXD(i)) ++ if (di->txp[i]) ++ return (di->txp[i]); + -+ /* move entries starting at last and moving backwards to first */ -+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { -+ new = TXD(old + rot); ++ return (NULL); ++} + -+ /* -+ * Move the tx dma descriptor. -+ * EOT is set only in the last entry in the ring. -+ */ -+ w = R_SM(&di->txd64[old].ctrl1) & ~D64_CTRL1_EOT; -+ if (new == (di->ntxd - 1)) -+ w |= D64_CTRL1_EOT; -+ W_SM(&di->txd64[new].ctrl1, w); ++/* ++ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). ++ */ ++void ++dma_txrotate(di_t *di) ++{ ++ if (DMA64_ENAB(di)) { ++ dma64_txrotate(di); ++ } else { ++ dma32_txrotate(di); ++ } ++} + -+ w = R_SM(&di->txd64[old].ctrl2); -+ W_SM(&di->txd64[new].ctrl2, w); ++void ++dma_rxreclaim(dma_info_t *di) ++{ ++ void *p; + -+ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); -+ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); ++ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); + -+ /* zap the old tx dma descriptor address field */ -+ W_SM(&di->txd64[old].addrlow, 0xdeadbeef); -+ W_SM(&di->txd64[old].addrhigh, 0xdeadbeef); ++ while ((p = dma_getnextrxp(di, TRUE))) ++ PKTFREE(di->osh, p, FALSE); ++} + -+ /* move the corresponding txp[] entry */ -+ ASSERT(di->txp[new] == NULL); -+ di->txp[new] = di->txp[old]; -+ di->txp[old] = NULL; ++void * ++dma_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_getnextrxp(di, forceall); ++ } else { ++ return dma32_getnextrxp(di, forceall); + } -+ -+ /* update txin and txout */ -+ di->txin = ad; -+ di->txout = TXD(di->txout + rot); -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ /* kick the chip */ -+ W_REG(&di->d64txregs->ptr, I2B(di->txout, dma64dd_t)); +} + -+#endif -+ -diff -Nur linux-2.4.32/drivers/net/hnd/linux_osl.c linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c ---- linux-2.4.32/drivers/net/hnd/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/hnd/linux_osl.c 2005-12-16 23:39:11.292858500 +0100 -@@ -0,0 +1,708 @@ -+/* -+ * Linux OS Independent Layer -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++uintptr ++dma_getvar(dma_info_t *di, char *name) ++{ ++ if (!strcmp(name, "&txavail")) ++ return ((uintptr) &di->txavail); ++ else { ++ ASSERT(0); ++ } ++ return (0); ++} + -+#define LINUX_OSL ++void ++dma_txblock(dma_info_t *di) ++{ ++ di->txavail = 0; ++} + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef mips -+#include -+#endif -+#include ++void ++dma_txunblock(dma_info_t *di) ++{ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++} + -+#define PCI_CFG_RETRY 10 ++uint ++dma_txactive(dma_info_t *di) ++{ ++ return (NTXDACTIVE(di->txin, di->txout)); ++} ++ ++void ++dma_rxpiomode(dma32regs_t *regs) ++{ ++ W_REG(®s->control, RC_FM); ++} + -+#define OS_HANDLE_MAGIC 0x1234abcd -+#define BCM_MEM_FILENAME_LEN 24 ++void ++dma_txpioloopback(dma32regs_t *regs) ++{ ++ OR_REG(®s->control, XC_LE); ++} + -+typedef struct bcm_mem_link { -+ struct bcm_mem_link *prev; -+ struct bcm_mem_link *next; -+ uint size; -+ int line; -+ char file[BCM_MEM_FILENAME_LEN]; -+} bcm_mem_link_t; + -+struct os_handle { -+ uint magic; -+ void *pdev; -+ uint malloced; -+ uint failed; -+ bcm_mem_link_t *dbgmem_list; -+}; + -+static int16 linuxbcmerrormap[] = \ -+{ 0, /* 0 */ -+ -EINVAL, /* BCME_ERROR */ -+ -EINVAL, /* BCME_BADARG*/ -+ -EINVAL, /* BCME_BADOPTION*/ -+ -EINVAL, /* BCME_NOTUP */ -+ -EINVAL, /* BCME_NOTDOWN */ -+ -EINVAL, /* BCME_NOTAP */ -+ -EINVAL, /* BCME_NOTSTA */ -+ -EINVAL, /* BCME_BADKEYIDX */ -+ -EINVAL, /* BCME_RADIOOFF */ -+ -EINVAL, /* BCME_NOTBANDLOCKED */ -+ -EINVAL, /* BCME_NOCLK */ -+ -EINVAL, /* BCME_BADRATESET */ -+ -EINVAL, /* BCME_BADBAND */ -+ -E2BIG, /* BCME_BUFTOOSHORT */ -+ -E2BIG, /* BCME_BUFTOOLONG */ -+ -EBUSY, /* BCME_BUSY */ -+ -EINVAL, /* BCME_NOTASSOCIATED */ -+ -EINVAL, /* BCME_BADSSIDLEN */ -+ -EINVAL, /* BCME_OUTOFRANGECHAN */ -+ -EINVAL, /* BCME_BADCHAN */ -+ -EFAULT, /* BCME_BADADDR */ -+ -ENOMEM, /* BCME_NORESOURCE */ -+ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ -+ -EMSGSIZE, /* BCME_BADLENGTH */ -+ -EINVAL, /* BCME_NOTREADY */ -+ -EPERM, /* BCME_NOTPERMITTED */ -+ -ENOMEM, /* BCME_NOMEM */ -+ -EINVAL, /* BCME_ASSOCIATED */ -+ -ERANGE, /* BCME_RANGE */ -+ -EINVAL /* BCME_NOTFOUND */ -+}; + -+/* translate bcmerrors into linux errors*/ -+int -+osl_error(int bcmerror) ++/*** 32 bits DMA non-inline functions ***/ ++static bool ++dma32_alloc(dma_info_t *di, uint direction) +{ -+ int abs_bcmerror; -+ int array_size = ARRAYSIZE(linuxbcmerrormap); -+ -+ abs_bcmerror = ABS(bcmerror); ++ uint size; ++ uint ddlen; ++ void *va; + -+ if (bcmerror > 0) -+ abs_bcmerror = 0; ++ ddlen = sizeof (dma32dd_t); + -+ else if (abs_bcmerror >= array_size) -+ abs_bcmerror = BCME_ERROR; ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); + -+ return linuxbcmerrormap[abs_bcmerror]; ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) ++ size += D32RINGALIGN; ++ ++ ++ if (direction == DMA_TX) { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); ++ return FALSE; ++ } ++ ++ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); ++ di->txdpa += di->txdalign; ++ di->txdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); ++ } else { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); ++ return FALSE; ++ } ++ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); ++ di->rxdpa += di->rxdalign; ++ di->rxdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); ++ } ++ ++ return TRUE; +} + -+osl_t * -+osl_attach(void *pdev) ++static void ++dma32_txreset(dma_info_t *di) +{ -+ osl_t *osh; ++ uint32 status; + -+ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); -+ ASSERT(osh); ++ /* suspend tx DMA first */ ++ W_REG(&di->d32txregs->control, XC_SE); ++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED && ++ status != XS_XS_IDLE && ++ status != XS_XS_STOPPED, ++ 10000); + -+ /* -+ * check the cases where -+ * 1.Error code Added to bcmerror table, but forgot to add it to the OS -+ * dependent error code -+ * 2. Error code is added to the bcmerror table, but forgot to add the -+ * corresponding errorstring(dummy call to bcmerrorstr) -+ */ -+ bcmerrorstr(0); -+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); ++ W_REG(&di->d32txregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED, ++ 10000); + -+ osh->magic = OS_HANDLE_MAGIC; -+ osh->malloced = 0; -+ osh->failed = 0; -+ osh->dbgmem_list = NULL; -+ osh->pdev = pdev; ++ if (status != XS_XS_DISABLED) { ++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); ++ } + -+ return osh; ++ /* wait for the last transaction to complete */ ++ OSL_DELAY(300); +} + -+void -+osl_detach(osl_t *osh) ++static void ++dma32_rxreset(dma_info_t *di) +{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC)); -+ kfree(osh); ++ uint32 status; ++ ++ W_REG(&di->d32rxregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED, ++ 10000); ++ ++ if (status != RS_RS_DISABLED) { ++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); ++ } +} + -+void* -+osl_pktget(osl_t *osh, uint len, bool send) ++static bool ++dma32_txsuspendedidle(dma_info_t *di) +{ -+ struct sk_buff *skb; ++ if (!(R_REG(&di->d32txregs->control) & XC_SE)) ++ return 0; ++ ++ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) ++ return 0; + -+ if ((skb = dev_alloc_skb(len)) == NULL) -+ return (NULL); ++ OSL_DELAY(2); ++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); ++} + -+ skb_put(skb, len); ++/* ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ */ ++static int ++dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++{ ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint txout; ++ uint32 ctrl; ++ uint32 pa; + -+ /* ensure the cookie field is cleared */ -+ PKTSETCOOKIE(skb, NULL); ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); + -+ return ((void*) skb); -+} ++ txout = di->txout; ++ ctrl = 0; + -+void -+osl_pktfree(void *p) -+{ -+ struct sk_buff *skb, *nskb; ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++ next = PKTNEXT(di->osh, p); + -+ skb = (struct sk_buff*) p; ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) ++ goto outoftxd; + -+ /* perversion: we use skb->next to chain multi-skb packets */ -+ while (skb) { -+ nskb = skb->next; -+ skb->next = NULL; -+ if (skb->destructor) { -+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ -+ dev_kfree_skb_any(skb); ++ if (len == 0) ++ continue; ++ ++ /* get physical address of buffer start */ ++ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ ++ /* build the descriptor control value */ ++ ctrl = len & CTRL_BC_MASK; ++ ++ ctrl |= coreflags; ++ ++ if (p == p0) ++ ctrl |= CTRL_SOF; ++ if (next == NULL) ++ ctrl |= (CTRL_IOC | CTRL_EOF); ++ if (txout == (di->ntxd - 1)) ++ ctrl |= CTRL_EOT; ++ ++ if (DMA64_ENAB(di)) { ++ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len); + } else { -+ /* can free immediately (even in_irq()) if destructor does not exist */ -+ dev_kfree_skb(skb); ++ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl); + } -+ skb = nskb; ++ ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); + } -+} + -+uint32 -+osl_pci_read_config(osl_t *osh, uint offset, uint size) -+{ -+ uint val; -+ uint retry=PCI_CFG_RETRY; ++ /* if last txd eof not set, fix it */ ++ if (!(ctrl & CTRL_EOF)) ++ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF)); + -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; + -+ /* only 4byte access supported */ -+ ASSERT(size == 4); ++ /* bump the tx descriptor index */ ++ di->txout = txout; + -+ do { -+ pci_read_config_dword(osh->pdev, offset, &val); -+ if (val != 0xffffffff) -+ break; -+ } while (retry--); ++ /* kick the chip */ ++ if (DMA64_ENAB(di)) { ++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); ++ } else { ++ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t)); ++ } + ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+ return (val); ++ return (0); ++ ++ outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); +} + -+void -+osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) ++static void* ++dma32_getnexttxp(dma_info_t *di, bool forceall) +{ -+ uint retry=PCI_CFG_RETRY; ++ uint start, end, i; ++ void *txp; + -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); + -+ /* only 4byte access supported */ -+ ASSERT(size == 4); ++ txp = NULL; + -+ do { -+ pci_write_config_dword(osh->pdev, offset, val); -+ if (offset!=PCI_BAR0_WIN) -+ break; -+ if (osl_pci_read_config(osh,offset,size) == val) -+ break; -+ } while (retry--); ++ start = di->txin; ++ if (forceall) ++ end = di->txout; ++ else ++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); + -+} ++ if ((start == 0) && (end > di->txout)) ++ goto bogus; + -+/* return bus # for the pci device pointed by osh->pdev */ -+uint -+osl_pci_bus(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), ++ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]); + -+ return ((struct pci_dev *)osh->pdev)->bus->number; -+} ++ W_SM(&di->txd32[i].addr, 0xdeadbeef); ++ txp = di->txp[i]; ++ di->txp[i] = NULL; ++ } + -+/* return slot # for the pci device pointed by osh->pdev */ -+uint -+osl_pci_slot(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ di->txin = i; + -+ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); -+} ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+static void -+osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) -+{ -+} ++ return (txp); + -+void -+osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) -+{ -+ osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); ++bogus: ++/* ++ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++*/ ++ return (NULL); +} + -+void -+osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) ++static void * ++dma32_getnextrxp(dma_info_t *di, bool forceall) +{ -+ osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); -+} ++ uint i; ++ void *rxp; + ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma_rxenabled(di)); + -+#ifdef BCMDBG_MEM ++ i = di->rxin; + -+void* -+osl_debug_malloc(osl_t *osh, uint size, int line, char* file) -+{ -+ bcm_mem_link_t *p; -+ char* basename; ++ /* return if no packets posted */ ++ if (i == di->rxout) ++ return (NULL); + -+ ASSERT(size); -+ -+ if ((p = (bcm_mem_link_t*)osl_malloc(osh, sizeof(bcm_mem_link_t) + size)) == NULL) ++ /* ignore curr if forceall */ ++ if (!forceall && (i == B2I(R_REG(&di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) + return (NULL); -+ -+ p->size = size; -+ p->line = line; -+ -+ basename = strrchr(file, '/'); -+ /* skip the '/' */ -+ if (basename) -+ basename++; + -+ if (!basename) -+ basename = file; -+ -+ strncpy(p->file, basename, BCM_MEM_FILENAME_LEN); -+ p->file[BCM_MEM_FILENAME_LEN - 1] = '\0'; ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; + -+ /* link this block */ -+ p->prev = NULL; -+ p->next = osh->dbgmem_list; -+ if (p->next) -+ p->next->prev = p; -+ osh->dbgmem_list = p; ++ /* clear this packet from the descriptor ring */ ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), ++ di->rxbufsize, DMA_RX, rxp); ++ W_SM(&di->rxd32[i].addr, 0xdeadbeef); + -+ return p + 1; ++ di->rxin = NEXTRXD(i); ++ ++ return (rxp); +} + -+void -+osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file) ++static void ++dma32_txrotate(di_t *di) +{ -+ bcm_mem_link_t *p = (bcm_mem_link_t *)((int8*)addr - sizeof(bcm_mem_link_t)); -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ uint ad; ++ uint nactive; ++ uint rot; ++ uint old, new; ++ uint32 w; ++ uint first, last; + -+ if (p->size == 0) { -+ printk("osl_debug_mfree: double free on addr 0x%x size %d at line %d file %s\n", -+ (uint)addr, size, line, file); -+ ASSERT(p->size); ++ ASSERT(dma_txsuspendedidle(di)); ++ ++ nactive = dma_txactive(di); ++ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); ++ rot = TXD(ad - di->txin); ++ ++ ASSERT(rot < di->ntxd); ++ ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); + return; + } + -+ if (p->size != size) { -+ printk("osl_debug_mfree: dealloc size %d does not match alloc size %d on addr 0x%x at line %d file %s\n", -+ size, p->size, (uint)addr, line, file); -+ ASSERT(p->size == size); -+ return; ++ first = di->txin; ++ last = PREVTXD(di->txout); ++ ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); ++ ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = R_SM(&di->txd32[old].ctrl) & ~CTRL_EOT; ++ if (new == (di->ntxd - 1)) ++ w |= CTRL_EOT; ++ W_SM(&di->txd32[new].ctrl, w); ++ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); ++ ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd32[old].addr, 0xdeadbeef); ++ ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ di->txp[old] = NULL; + } + -+ /* unlink this block */ -+ if (p->prev) -+ p->prev->next = p->next; -+ if (p->next) -+ p->next->prev = p->prev; -+ if (osh->dbgmem_list == p) -+ osh->dbgmem_list = p->next; -+ p->next = p->prev = NULL; ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+ osl_mfree(osh, p, size + sizeof(bcm_mem_link_t)); ++ /* kick the chip */ ++ W_REG(&di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); +} + -+char* -+osl_debug_memdump(osl_t *osh, char *buf, uint sz) ++/*** 64 bits DMA non-inline functions ***/ ++ ++#ifdef BCMDMA64 ++ ++static bool ++dma64_alloc(dma_info_t *di, uint direction) +{ -+ bcm_mem_link_t *p; -+ char *obuf; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ obuf = buf; ++ uint size; ++ uint ddlen; ++ uint32 alignbytes; ++ void *va; + -+ buf += sprintf(buf, " Address\tSize\tFile:line\n"); -+ for (p = osh->dbgmem_list; p && ((buf - obuf) < (sz - 128)); p = p->next) -+ buf += sprintf(buf, "0x%08x\t%5d\t%s:%d\n", -+ (int)p + sizeof(bcm_mem_link_t), p->size, p->file, p->line); ++ ddlen = sizeof (dma64dd_t); + -+ return (obuf); -+} ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); + -+#endif /* BCMDBG_MEM */ ++ alignbytes = di->dma64align; + -+void* -+osl_malloc(osl_t *osh, uint size) -+{ -+ void *addr; -+ -+ /* only ASSERT if osh is defined */ -+ if (osh) -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes)) ++ size += alignbytes; + -+ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { -+ if(osh) -+ osh->failed++; -+ return (NULL); -+ } -+ if (osh) -+ osh->malloced += size; -+ -+ return (addr); -+} + -+void -+osl_mfree(osl_t *osh, void *addr, uint size) -+{ -+ if (osh) { -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ osh->malloced -= size; ++ if (direction == DMA_TX) { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); ++ return FALSE; ++ } ++ ++ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); ++ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va); ++ di->txdpa += di->txdalign; ++ di->txdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes)); ++ } else { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); ++ return FALSE; ++ } ++ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); ++ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va); ++ di->rxdpa += di->rxdalign; ++ di->rxdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes)); + } -+ kfree(addr); -+} + -+uint -+osl_malloced(osl_t *osh) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (osh->malloced); ++ return TRUE; +} + -+uint osl_malloc_failed(osl_t *osh) ++static void ++dma64_txreset(dma_info_t *di) +{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (osh->failed); -+} ++ uint32 status; ++ ++ /* suspend tx DMA first */ ++ W_REG(&di->d64txregs->control, D64_XC_SE); ++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED && ++ status != D64_XS0_XS_IDLE && ++ status != D64_XS0_XS_STOPPED, ++ 10000); ++ ++ W_REG(&di->d64txregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED, ++ 10000); + -+void* -+osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ if (status != D64_XS0_XS_DISABLED) { ++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); ++ } + -+ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); ++ /* wait for the last transaction to complete */ ++ OSL_DELAY(300); +} + -+void -+osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) ++static void ++dma64_rxreset(dma_info_t *di) +{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ uint32 status; + -+ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); -+} ++ W_REG(&di->d64rxregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED, ++ 10000); + -+uint -+osl_dma_map(osl_t *osh, void *va, uint size, int direction) -+{ -+ int dir; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ return (pci_map_single(osh->pdev, va, size, dir)); ++ if (status != D64_RS0_RS_DISABLED) { ++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); ++ } +} + -+void -+osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) ++static bool ++dma64_txsuspendedidle(dma_info_t *di) +{ -+ int dir; ++ ++ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE)) ++ return 0; + -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ pci_unmap_single(osh->pdev, (uint32)pa, size, dir); ++ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) ++ return 1; ++ ++ return 0; +} + -+#if defined(BINOSL) -+void -+osl_assert(char *exp, char *file, int line) ++/* ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ */ ++static int ++dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) +{ -+ char tempbuf[255]; ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint txout; ++ uint32 flags; ++ uint32 pa; + -+ sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line); -+ panic(tempbuf); -+} -+#endif /* BCMDBG || BINOSL */ ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); + -+void -+osl_delay(uint usec) -+{ -+ uint d; ++ txout = di->txout; ++ flags = 0; + -+ while (usec > 0) { -+ d = MIN(usec, 1000); -+ udelay(d); -+ usec -= d; -+ } -+} ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++ next = PKTNEXT(di->osh, p); + -+/* -+ * BINOSL selects the slightly slower function-call-based binary compatible osl. -+ */ -+#ifdef BINOSL ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) ++ goto outoftxd; + -+int -+osl_printf(const char *format, ...) -+{ -+ va_list args; -+ char buf[1024]; -+ int len; ++ if (len == 0) ++ continue; + -+ /* sprintf into a local buffer because there *is* no "vprintk()".. */ -+ va_start(args, format); -+ len = vsprintf(buf, format, args); -+ va_end(args); ++ /* get physical address of buffer start */ ++ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); + -+ if (len > sizeof (buf)) { -+ printk("osl_printf: buffer overrun\n"); -+ return (0); ++ flags = coreflags; ++ ++ if (p == p0) ++ flags |= D64_CTRL1_SOF; ++ if (next == NULL) ++ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); ++ if (txout == (di->ntxd - 1)) ++ flags |= D64_CTRL1_EOT; ++ ++ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); ++ ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); + } + -+ return (printk(buf)); -+} ++ /* if last txd eof not set, fix it */ ++ if (!(flags & D64_CTRL1_EOF)) ++ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); + -+int -+osl_sprintf(char *buf, const char *format, ...) -+{ -+ va_list args; -+ int rc; ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; + -+ va_start(args, format); -+ rc = vsprintf(buf, format, args); -+ va_end(args); -+ return (rc); -+} ++ /* bump the tx descriptor index */ ++ di->txout = txout; + -+int -+osl_strcmp(const char *s1, const char *s2) -+{ -+ return (strcmp(s1, s2)); -+} ++ /* kick the chip */ ++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); + -+int -+osl_strncmp(const char *s1, const char *s2, uint n) -+{ -+ return (strncmp(s1, s2, n)); -+} ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+int -+osl_strlen(const char *s) -+{ -+ return (strlen(s)); -+} ++ return (0); + -+char* -+osl_strcpy(char *d, const char *s) -+{ -+ return (strcpy(d, s)); ++outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); +} + -+char* -+osl_strncpy(char *d, const char *s, uint n) ++static void* ++dma64_getnexttxp(dma_info_t *di, bool forceall) +{ -+ return (strncpy(d, s, n)); -+} ++ uint start, end, i; ++ void *txp; + -+void -+bcopy(const void *src, void *dst, int len) -+{ -+ memcpy(dst, src, len); -+} ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); + -+int -+bcmp(const void *b1, const void *b2, int len) -+{ -+ return (memcmp(b1, b2, len)); -+} ++ txp = NULL; + -+void -+bzero(void *b, int len) -+{ -+ memset(b, '\0', len); -+} ++ start = di->txin; ++ if (forceall) ++ end = di->txout; ++ else ++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); + -+uint32 -+osl_readl(volatile uint32 *r) -+{ -+ return (readl(r)); -+} ++ if ((start == 0) && (end > di->txout)) ++ goto bogus; + -+uint16 -+osl_readw(volatile uint16 *r) -+{ -+ return (readw(r)); -+} ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow), ++ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]); + -+uint8 -+osl_readb(volatile uint8 *r) -+{ -+ return (readb(r)); -+} ++ W_SM(&di->txd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); + -+void -+osl_writel(uint32 v, volatile uint32 *r) -+{ -+ writel(v, r); -+} ++ txp = di->txp[i]; ++ di->txp[i] = NULL; ++ } + -+void -+osl_writew(uint16 v, volatile uint16 *r) -+{ -+ writew(v, r); -+} ++ di->txin = i; + -+void -+osl_writeb(uint8 v, volatile uint8 *r) -+{ -+ writeb(v, r); ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (txp); ++ ++bogus: ++/* ++ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++*/ ++ return (NULL); +} + -+void * -+osl_uncached(void *va) ++static void * ++dma64_getnextrxp(dma_info_t *di, bool forceall) +{ -+#ifdef mips -+ return ((void*)KSEG1ADDR(va)); -+#else -+ return ((void*)va); -+#endif -+} ++ uint i; ++ void *rxp; + -+uint -+osl_getcycles(void) -+{ -+ uint cycles; ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma_rxenabled(di)); + -+#if defined(mips) -+ cycles = read_c0_count() * 2; -+#elif defined(__i386__) -+ rdtscl(cycles); -+#else -+ cycles = 0; -+#endif -+ return cycles; -+} ++ i = di->rxin; + -+void * -+osl_reg_map(uint32 pa, uint size) -+{ -+ return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); -+} ++ /* return if no packets posted */ ++ if (i == di->rxout) ++ return (NULL); + -+void -+osl_reg_unmap(void *va) -+{ -+ iounmap(va); -+} ++ /* ignore curr if forceall */ ++ if (!forceall && (i == B2I(R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t))) ++ return (NULL); + -+int -+osl_busprobe(uint32 *val, uint32 addr) -+{ -+#ifdef mips -+ return get_dbe(*val, (uint32*)addr); -+#else -+ *val = readl(addr); -+ return 0; -+#endif -+} ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; + -+uchar* -+osl_pktdata(osl_t *osh, void *skb) -+{ -+ return (((struct sk_buff*)skb)->data); -+} ++ /* clear this packet from the descriptor ring */ ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow), ++ di->rxbufsize, DMA_RX, rxp); + -+uint -+osl_pktlen(osl_t *osh, void *skb) -+{ -+ return (((struct sk_buff*)skb)->len); -+} ++ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); + -+uint -+osl_pktheadroom(osl_t *osh, void *skb) -+{ -+ return (uint) skb_headroom((struct sk_buff *) skb); -+} ++ di->rxin = NEXTRXD(i); + -+uint -+osl_pkttailroom(osl_t *osh, void *skb) -+{ -+ return (uint) skb_tailroom((struct sk_buff *) skb); ++ return (rxp); +} + -+void* -+osl_pktnext(osl_t *osh, void *skb) ++static void ++dma64_txrotate(di_t *di) +{ -+ return (((struct sk_buff*)skb)->next); -+} ++ uint ad; ++ uint nactive; ++ uint rot; ++ uint old, new; ++ uint32 w; ++ uint first, last; + -+void -+osl_pktsetnext(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->next = (struct sk_buff*)x; -+} ++ ASSERT(dma_txsuspendedidle(di)); + -+void -+osl_pktsetlen(osl_t *osh, void *skb, uint len) -+{ -+ __skb_trim((struct sk_buff*)skb, len); -+} ++ nactive = dma_txactive(di); ++ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t); ++ rot = TXD(ad - di->txin); + -+uchar* -+osl_pktpush(osl_t *osh, void *skb, int bytes) -+{ -+ return (skb_push((struct sk_buff*)skb, bytes)); -+} ++ ASSERT(rot < di->ntxd); + -+uchar* -+osl_pktpull(osl_t *osh, void *skb, int bytes) -+{ -+ return (skb_pull((struct sk_buff*)skb, bytes)); -+} ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } + -+void* -+osl_pktdup(osl_t *osh, void *skb) -+{ -+ return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC)); -+} ++ first = di->txin; ++ last = PREVTXD(di->txout); + -+void* -+osl_pktcookie(void *skb) -+{ -+ return ((void*)((struct sk_buff*)skb)->csum); -+} ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); + -+void -+osl_pktsetcookie(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->csum = (uint)x; -+} ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = R_SM(&di->txd64[old].ctrl1) & ~D64_CTRL1_EOT; ++ if (new == (di->ntxd - 1)) ++ w |= D64_CTRL1_EOT; ++ W_SM(&di->txd64[new].ctrl1, w); + -+void* -+osl_pktlink(void *skb) -+{ -+ return (((struct sk_buff*)skb)->prev); -+} ++ w = R_SM(&di->txd64[old].ctrl2); ++ W_SM(&di->txd64[new].ctrl2, w); + -+void -+osl_pktsetlink(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; -+} ++ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); ++ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); + -+uint -+osl_pktprio(void *skb) -+{ -+ return (((struct sk_buff*)skb)->priority); -+} ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd64[old].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[old].addrhigh, 0xdeadbeef); + -+void -+osl_pktsetprio(void *skb, uint x) -+{ -+ ((struct sk_buff*)skb)->priority = x; ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ di->txp[old] = NULL; ++ } ++ ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ /* kick the chip */ ++ W_REG(&di->d64txregs->ptr, I2B(di->txout, dma64dd_t)); +} + ++#endif + -+#endif /* BINOSL */ -diff -Nur linux-2.4.32/drivers/net/hnd/Makefile linux-2.4.32-brcm/drivers/net/hnd/Makefile ---- linux-2.4.32/drivers/net/hnd/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/hnd/Makefile 2005-12-16 23:39:11.284858000 +0100 -@@ -0,0 +1,19 @@ -+# -+# Makefile for the BCM47xx specific kernel interface routines -+# under Linux. -+# +diff -Naur linux.old/drivers/net/wl/hnddma.h linux.dev/drivers/net/wl/hnddma.h +--- linux.old/drivers/net/wl/hnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/hnddma.h 2006-04-06 16:57:44.000000000 +0200 +@@ -0,0 +1,69 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ + -+EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER ++#ifndef _hnddma_h_ ++#define _hnddma_h_ + -+O_TARGET := hnd.o ++/* export structure */ ++typedef volatile struct { ++ /* rx error counters */ ++ uint rxgiants; /* rx giant frames */ ++ uint rxnobuf; /* rx out of dma descriptors */ ++ /* tx error counters */ ++ uint txnobuf; /* tx out of dma descriptors */ ++} hnddma_t; ++ ++#ifndef di_t ++#define di_t void ++#endif ++ ++#ifndef osl_t ++#define osl_t void ++#endif + -+HND_OBJS := bcmutils.o hnddma.o linux_osl.o sbutils.o bcmsrom.o ++/* externs */ ++extern void dma_detach(di_t *di); ++extern void dma_txreset(di_t *di); ++extern void dma_rxreset(di_t *di); ++extern void dma_txinit(di_t *di); ++extern bool dma_txenabled(di_t *di); ++extern void dma_rxinit(di_t *di); ++extern void dma_rxenable(di_t *di); ++extern bool dma_rxenabled(di_t *di); ++extern void dma_txsuspend(di_t *di); ++extern void dma_txresume(di_t *di); ++extern bool dma_txsuspended(di_t *di); ++extern bool dma_txsuspendedidle(di_t *di); ++extern bool dma_txstopped(di_t *di); ++extern bool dma_rxstopped(di_t *di); ++extern int dma_txfast(di_t *di, void *p, uint32 coreflags); ++extern void dma_fifoloopbackenable(di_t *di); ++extern void *dma_rx(di_t *di); ++extern void dma_rxfill(di_t *di); ++extern void dma_txreclaim(di_t *di, bool forceall); ++extern void dma_rxreclaim(di_t *di); ++extern uintptr dma_getvar(di_t *di, char *name); ++extern void *dma_getnexttxp(di_t *di, bool forceall); ++extern void *dma_peeknexttxp(di_t *di); ++extern void *dma_getnextrxp(di_t *di, bool forceall); ++extern void dma_txblock(di_t *di); ++extern void dma_txunblock(di_t *di); ++extern uint dma_txactive(di_t *di); ++extern void dma_txrotate(di_t *di); + -+export-objs := shared_ksyms.o -+obj-y := shared_ksyms.o $(HND_OBJS) -+obj-m := $(O_TARGET) ++extern void dma_rxpiomode(dma32regs_t *); ++extern void dma_txpioloopback(dma32regs_t *); + -+include $(TOPDIR)/Rules.make + -+shared_ksyms.c: shared_ksyms.sh $(HND_OBJS) -+ sh -e $< $(HND_OBJS) > $@ -diff -Nur linux-2.4.32/drivers/net/hnd/sbutils.c linux-2.4.32-brcm/drivers/net/hnd/sbutils.c ---- linux-2.4.32/drivers/net/hnd/sbutils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/hnd/sbutils.c 2005-12-16 23:39:11.316860000 +0100 -@@ -0,0 +1,2837 @@ ++#endif /* _hnddma_h_ */ +diff -Naur linux.old/drivers/net/wl/pktq.h linux.dev/drivers/net/wl/pktq.h +--- linux.old/drivers/net/wl/pktq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/pktq.h 2006-04-06 17:32:52.000000000 +0200 +@@ -0,0 +1,48 @@ +/* -+ * Misc utility routines for accessing chip-specific features -+ * of the SiliconBackplane-based Broadcom chips. ++ * Misc useful os-independent macros and functions. + * + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. @@ -14928,2933 +17486,2736 @@ diff -Nur linux-2.4.32/drivers/net/hnd/sbutils.c linux-2.4.32-brcm/drivers/net/h + * $Id$ + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* debug/trace */ -+#define SB_ERROR(args) -+ -+ -+typedef uint32 (*sb_intrsoff_t)(void *intr_arg); -+typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg); -+typedef bool (*sb_intrsenabled_t)(void *intr_arg); -+ -+/* misc sb info needed by some of the routines */ -+typedef struct sb_info { -+ -+ struct sb_pub sb; /* back plane public state(must be first field of sb_info */ -+ -+ void *osh; /* osl os handle */ -+ void *sdh; /* bcmsdh handle */ -+ -+ void *curmap; /* current regs va */ -+ void *regs[SB_MAXCORES]; /* other regs va */ -+ -+ uint curidx; /* current core index */ -+ uint dev_coreid; /* the core provides driver functions */ -+ -+ bool memseg; /* flag to toggle MEM_SEG register */ -+ -+ uint gpioidx; /* gpio control core index */ -+ uint gpioid; /* gpio control coretype */ -+ -+ uint numcores; /* # discovered cores */ -+ uint coreid[SB_MAXCORES]; /* id of each core */ -+ -+ void *intr_arg; /* interrupt callback function arg */ -+ sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */ -+ sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */ -+ sb_intrsenabled_t intrsenabled_fn; /* function to check if chip interrupts are enabled */ -+ -+} sb_info_t; -+ -+/* local prototypes */ -+static sb_info_t * BCMINIT(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, int *varsz); -+static void BCMINIT(sb_scan)(sb_info_t *si); -+static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val); -+static uint _sb_coreidx(sb_info_t *si); -+static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit); -+static uint BCMINIT(sb_pcidev2chip)(uint pcidev); -+static uint BCMINIT(sb_chip2numcores)(uint chip); -+static bool sb_ispcie(sb_info_t *si); -+static bool sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen); -+static int sb_pci_fixcfg(sb_info_t *si); -+ -+/* routines to access mdio slave device registers */ -+static int sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint readdr, uint val); -+static void BCMINIT(sb_war30841)(sb_info_t *si); -+ -+/* delay needed between the mdio control/ mdiodata register data access */ -+#define PR28829_DELAY() OSL_DELAY(10) -+ -+ -+/* global variable to indicate reservation/release of gpio's*/ -+static uint32 sb_gpioreservation = 0; ++#ifndef _pktq_h_ ++#define _pktq_h_ + -+#define SB_INFO(sbh) (sb_info_t*)sbh -+#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val))) -+#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE)) -+#define GOODREGS(regs) ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE)) -+#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) -+#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) -+#define BADIDX (SB_MAXCORES+1) -+#define NOREV -1 ++/*** driver-only section ***/ ++#ifdef BCMDRIVER + -+#define PCI(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI)) -+#define PCIE(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCIE)) ++/* generic osl packet queue */ ++struct pktq { ++ void *head; /* first packet to dequeue */ ++ void *tail; /* last packet to dequeue */ ++ uint len; /* number of queued packets */ ++ uint maxlen; /* maximum number of queued packets */ ++ bool priority; /* enqueue by packet priority */ ++ uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */ ++}; ++#define DEFAULT_QLEN 128 + -+/* sonicsrev */ -+#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) -+#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) ++#define pktq_len(q) ((q)->len) ++#define pktq_avail(q) ((q)->maxlen - (q)->len) ++#define pktq_head(q) ((q)->head) ++#define pktq_full(q) ((q)->len >= (q)->maxlen) ++#define _pktq_pri(q, pri) ((q)->prio_map[pri]) ++#define pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0)) + -+#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr)) -+#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v)) -+#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v))) -+#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v))) ++/* externs */ ++/* packet */ ++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); ++extern uint pkttotlen(osl_t *osh, void *); ++extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]); ++extern void pktenq(struct pktq *q, void *p, bool lifo); ++extern void *pktdeq(struct pktq *q); ++extern void *pktdeqtail(struct pktq *q); + ++#endif ++#endif /* _pktq_h_ */ +diff -Naur linux.old/drivers/net/wl/sbhnddma.h linux.dev/drivers/net/wl/sbhnddma.h +--- linux.old/drivers/net/wl/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/sbhnddma.h 2006-04-06 15:34:14.000000000 +0200 +@@ -0,0 +1,312 @@ +/* -+ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ -+ * after core switching to avoid invalid register accesss inside ISR. ++ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ + */ -+#define INTR_OFF(si, intr_val) \ -+ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -+#define INTR_RESTORE(si, intr_val) \ -+ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } -+ -+/* dynamic clock control defines */ -+#define LPOMINFREQ 25000 /* low power oscillator min */ -+#define LPOMAXFREQ 43000 /* low power oscillator max */ -+#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ -+#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ -+#define PCIMINFREQ 25000000 /* 25 MHz */ -+#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ -+ -+#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ -+#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ -+ -+#define MIN_DUMPBUFLEN 32 /* debug */ -+ -+/* different register spaces to access thr'u pcie indirect access*/ -+#define PCIE_CONFIGREGS 1 -+#define PCIE_PCIEREGS 2 + -+/* GPIO Based LED powersave defines */ -+#define DEFAULT_GPIO_ONTIME 10 -+#define DEFAULT_GPIO_OFFTIME 90 ++#ifndef _sbhnddma_h_ ++#define _sbhnddma_h_ + -+#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) ++ ++/* 2byte-wide pio register set per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint16 fifocontrol; ++ uint16 fifodata; ++ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */ ++ uint16 PAD; ++} pio2regs_t; + -+static uint32 -+sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr) -+{ -+ uint8 tmp; -+ uint32 val, intr_val = 0; ++/* a pair of pio channels(tx and rx) */ ++typedef volatile struct { ++ pio2regs_t tx; ++ pio2regs_t rx; ++} pio2regp_t; + ++/* 4byte-wide pio register set per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 fifocontrol; ++ uint32 fifodata; ++} pio4regs_t; + -+ /* -+ * compact flash only has 11 bits address, while we needs 12 bits address. -+ * MEM_SEG will be OR'd with other 11 bits address in hardware, -+ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). -+ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special -+ */ -+ if(si->memseg) { -+ INTR_OFF(si, intr_val); -+ tmp = 1; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ -+ } ++/* a pair of pio channels(tx and rx) */ ++typedef volatile struct { ++ pio4regs_t tx; ++ pio4regs_t rx; ++} pio4regp_t; + -+ val = R_REG(sbr); + -+ if(si->memseg) { -+ tmp = 0; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ INTR_RESTORE(si, intr_val); -+ } + -+ return (val); -+} ++/* DMA structure: ++ * support two DMA engines: 32 bits address or 64 bit addressing ++ * basic DMA register set is per channel(transmit or receive) ++ * a pair of channels is defined for convenience ++ */ + -+static void -+sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v) -+{ -+ uint8 tmp; -+ volatile uint32 dummy; -+ uint32 intr_val = 0; + ++/*** 32 bits addressing ***/ + -+ /* -+ * compact flash only has 11 bits address, while we needs 12 bits address. -+ * MEM_SEG will be OR'd with other 11 bits address in hardware, -+ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). -+ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special -+ */ -+ if(si->memseg) { -+ INTR_OFF(si, intr_val); -+ tmp = 1; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ -+ } ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 addr; /* descriptor ring base address (4K aligned) */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 status; /* current active descriptor, et al */ ++} dma32regs_t; + -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { -+#ifdef IL_BIGENDIAN -+ dummy = R_REG(sbr); -+ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); -+ dummy = R_REG(sbr); -+ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); -+#else -+ dummy = R_REG(sbr); -+ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); -+ dummy = R_REG(sbr); -+ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); -+#endif -+ } else -+ W_REG(sbr, v); ++typedef volatile struct { ++ dma32regs_t xmt; /* dma tx channel */ ++ dma32regs_t rcv; /* dma rx channel */ ++} dma32regp_t; + -+ if(si->memseg) { -+ tmp = 0; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ INTR_RESTORE(si, intr_val); -+ } -+} ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma32diag_t; + +/* -+ * Allocate a sb handle. -+ * devid - pci device id (used to determine chip#) -+ * osh - opaque OS handle -+ * regs - virtual address of initial core registers -+ * bustype - pci/pcmcia/sb/sdio/etc -+ * vars - pointer to a pointer area for "environment" variables -+ * varsz - pointer to int to return the size of the vars ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. + */ -+sb_t * -+BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, int *varsz) -+{ -+ sb_info_t *si; ++typedef volatile struct { ++ uint32 ctrl; /* misc control bits & bufcount */ ++ uint32 addr; /* data buffer address */ ++} dma32dd_t; + -+ /* alloc sb_info_t */ -+ if ((si = MALLOC(osh, sizeof (sb_info_t))) == NULL) { -+ SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); -+ return (NULL); -+ } ++/* ++ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. ++ */ ++#define D32MAXRINGSZ 4096 ++#define D32RINGALIGN 4096 ++#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) + -+ if (BCMINIT(sb_doattach)(si, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { -+ MFREE(osh, si, sizeof (sb_info_t)); -+ return (NULL); -+ } -+ return (sb_t *)si; -+} ++/* transmit channel control */ ++#define XC_XE ((uint32)1 << 0) /* transmit enable */ ++#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ ++#define XC_LE ((uint32)1 << 2) /* loopback enable */ ++#define XC_FL ((uint32)1 << 4) /* flush request */ ++#define XC_AE ((uint32)3 << 16) /* address extension bits */ ++#define XC_AE_SHIFT 16 + -+/* Using sb_kattach depends on SB_BUS support, either implicit */ -+/* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */ -+#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS) ++/* transmit descriptor table pointer */ ++#define XP_LD_MASK 0xfff /* last valid descriptor */ + -+/* global kernel resource */ -+static sb_info_t ksi; ++/* transmit channel status */ ++#define XS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define XS_XS_MASK 0xf000 /* transmit state */ ++#define XS_XS_SHIFT 12 ++#define XS_XS_DISABLED 0x0000 /* disabled */ ++#define XS_XS_ACTIVE 0x1000 /* active */ ++#define XS_XS_IDLE 0x2000 /* idle wait */ ++#define XS_XS_STOPPED 0x3000 /* stopped */ ++#define XS_XS_SUSP 0x4000 /* suspend pending */ ++#define XS_XE_MASK 0xf0000 /* transmit errors */ ++#define XS_XE_SHIFT 16 ++#define XS_XE_NOERR 0x00000 /* no error */ ++#define XS_XE_DPE 0x10000 /* descriptor protocol error */ ++#define XS_XE_DFU 0x20000 /* data fifo underrun */ ++#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ ++#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ ++#define XS_AD_MASK 0xfff00000 /* active descriptor */ ++#define XS_AD_SHIFT 20 + -+/* generic kernel variant of sb_attach() */ -+sb_t * -+BCMINITFN(sb_kattach)() -+{ -+ uint32 *regs; ++/* receive channel control */ ++#define RC_RE ((uint32)1 << 0) /* receive enable */ ++#define RC_RO_MASK 0xfe /* receive frame offset */ ++#define RC_RO_SHIFT 1 ++#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ ++#define RC_AE ((uint32)3 << 16) /* address extension bits */ ++#define RC_AE_SHIFT 16 + -+ if (ksi.curmap == NULL) { -+ uint32 cid; ++/* receive descriptor table pointer */ ++#define RP_LD_MASK 0xfff /* last valid descriptor */ + -+ regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); -+ cid = R_REG((uint32 *)regs); -+ if (((cid & CID_ID_MASK) == BCM4712_DEVICE_ID) && -+ ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) && -+ ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) { -+ uint32 *scc, val; ++/* receive channel status */ ++#define RS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define RS_RS_MASK 0xf000 /* receive state */ ++#define RS_RS_SHIFT 12 ++#define RS_RS_DISABLED 0x0000 /* disabled */ ++#define RS_RS_ACTIVE 0x1000 /* active */ ++#define RS_RS_IDLE 0x2000 /* idle wait */ ++#define RS_RS_STOPPED 0x3000 /* reserved */ ++#define RS_RE_MASK 0xf0000 /* receive errors */ ++#define RS_RE_SHIFT 16 ++#define RS_RE_NOERR 0x00000 /* no error */ ++#define RS_RE_DPE 0x10000 /* descriptor protocol error */ ++#define RS_RE_DFO 0x20000 /* data fifo overflow */ ++#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ ++#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ ++#define RS_AD_MASK 0xfff00000 /* active descriptor */ ++#define RS_AD_SHIFT 20 + -+ scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); -+ val = R_REG(scc); -+ SB_ERROR((" initial scc = 0x%x\n", val)); -+ val |= SCC_SS_XTAL; -+ W_REG(scc, val); -+ } ++/* fifoaddr */ ++#define FA_OFF_MASK 0xffff /* offset */ ++#define FA_SEL_MASK 0xf0000 /* select */ ++#define FA_SEL_SHIFT 16 ++#define FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define FA_SEL_RDD 0x40000 /* receive dma data */ ++#define FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ + -+ if (BCMINIT(sb_doattach)(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, -+ SB_BUS, NULL, NULL, NULL) == NULL) { -+ return NULL; -+ } -+ } ++/* descriptor control flags */ ++#define CTRL_BC_MASK 0x1fff /* buffer byte count */ ++#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ ++#define CTRL_AE_SHIFT 16 ++#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ ++#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ + -+ return (sb_t *)&ksi; -+} -+#endif ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define CTRL_CORE_MASK 0x0ff00000 + -+static sb_info_t * -+BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, int *varsz) -+{ -+ uint origidx; -+ chipcregs_t *cc; -+ sbconfig_t *sb; -+ uint32 w; ++/*** 64 bits addressing ***/ + -+ ASSERT(GOODREGS(regs)); ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ ++ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ ++ uint32 status0; /* current descriptor, xmt state */ ++ uint32 status1; /* active descriptor, xmt error */ ++} dma64regs_t; + -+ bzero((uchar*)si, sizeof (sb_info_t)); ++typedef volatile struct { ++ dma64regs_t tx; /* dma64 tx channel */ ++ dma64regs_t rx; /* dma64 rx channel */ ++} dma64regp_t; + -+ si->sb.buscoreidx = si->gpioidx = BADIDX; ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma64diag_t; + -+ si->osh = osh; -+ si->curmap = regs; -+ si->sdh = sdh; ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl1; /* misc control bits & bufcount */ ++ uint32 ctrl2; /* buffer count and address extension */ ++ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */ ++ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */ ++} dma64dd_t; + -+ /* check to see if we are a sb core mimic'ing a pci core */ -+ if (bustype == PCI_BUS) { -+ if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff) -+ bustype = SB_BUS; -+ else -+ bustype = PCI_BUS; -+ } ++/* ++ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. ++ */ ++#define D64MAXRINGSZ 8192 ++#define D64RINGALIGN 8192 ++#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) + -+ si->sb.bustype = bustype; -+ if (si->sb.bustype != BUSTYPE(si->sb.bustype)) { -+ SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n", -+ si->sb.bustype, BUSTYPE(si->sb.bustype))); -+ return NULL; -+ } ++/* transmit channel control */ ++#define D64_XC_XE 0x00000001 /* transmit enable */ ++#define D64_XC_SE 0x00000002 /* transmit suspend request */ ++#define D64_XC_LE 0x00000004 /* loopback enable */ ++#define D64_XC_FL 0x00000010 /* flush request */ ++#define D64_XC_AE 0x00110000 /* address extension bits */ ++#define D64_XC_AE_SHIFT 16 + -+ /* need to set memseg flag for CF card first before any sb registers access */ -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) -+ si->memseg = TRUE; ++/* transmit descriptor table pointer */ ++#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ ++ ++/* transmit channel status */ ++#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ ++#define D64_XS0_XS_SHIFT 28 ++#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ ++#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ ++#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ ++#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ ++#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ + -+ /* kludge to enable the clock on the 4306 which lacks a slowclock */ -+ if (BUSTYPE(si->sb.bustype) == PCI_BUS) -+ sb_clkctl_xtal(&si->sb, XTAL|PLL, ON); ++#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ ++#define D64_XS1_XE_SHIFT 28 ++#define D64_XS1_XE_NOERR 0x00000000 /* no error */ ++#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ ++#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ ++#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ ++#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_XS1_XE_COREE 0x50000000 /* core error */ + -+ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { -+ w = OSL_PCI_READ_CONFIG(osh, PCI_BAR0_WIN, sizeof (uint32)); -+ if (!GOODCOREADDR(w)) -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32), SB_ENUM_BASE); -+ } ++/* receive channel control */ ++#define D64_RC_RE 0x00000001 /* receive enable */ ++#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ ++#define D64_RC_RO_SHIFT 1 ++#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ ++#define D64_RC_AE 0x00110000 /* address extension bits */ ++#define D64_RC_AE_SHIFT 16 + -+ /* initialize current core index value */ -+ si->curidx = _sb_coreidx(si); ++/* receive descriptor table pointer */ ++#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ + -+ if (si->curidx == BADIDX) { -+ SB_ERROR(("sb_doattach: bad core index\n")); -+ return NULL; -+ } ++/* receive channel status */ ++#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ ++#define D64_RS0_RS_SHIFT 28 ++#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ ++#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ ++#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ ++#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ ++#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ + -+ /* get sonics backplane revision */ -+ sb = REGS2SB(si->curmap); -+ si->sb.sonicsrev = (R_SBREG(si, &(sb)->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; ++#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ ++#define D64_RS1_RE_SHIFT 28 ++#define D64_RS1_RE_NOERR 0x00000000 /* no error */ ++#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ ++#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ ++#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ ++#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_RS1_RE_COREE 0x50000000 /* core error */ + -+ /* keep and reuse the initial register mapping */ -+ origidx = si->curidx; -+ if (BUSTYPE(si->sb.bustype) == SB_BUS) -+ si->regs[origidx] = regs; ++/* fifoaddr */ ++#define D64_FA_OFF_MASK 0xffff /* offset */ ++#define D64_FA_SEL_MASK 0xf0000 /* select */ ++#define D64_FA_SEL_SHIFT 16 ++#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ ++#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ + -+ /* is core-0 a chipcommon core? */ -+ si->numcores = 1; -+ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0); -+ if (sb_coreid(&si->sb) != SB_CC) -+ cc = NULL; ++/* descriptor control flags 1 */ ++#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ ++#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ + -+ /* determine chip id and rev */ -+ if (cc) { -+ /* chip common core found! */ -+ si->sb.chip = R_REG(&cc->chipid) & CID_ID_MASK; -+ si->sb.chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; -+ si->sb.chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; -+ } else { -+ /* The only pcmcia chip without a chipcommon core is a 4301 */ -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) -+ devid = BCM4301_DEVICE_ID; ++/* descriptor control flags 2 */ ++#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ ++#define D64_CTRL2_AE 0x00110000 /* address extension bits */ ++#define D64_CTRL2_AE_SHIFT 16 + -+ /* no chip common core -- must convert device id to chip id */ -+ if ((si->sb.chip = BCMINIT(sb_pcidev2chip)(devid)) == 0) { -+ SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid)); -+ sb_setcoreidx(&si->sb, origidx); -+ return NULL; -+ } -+ } ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define D64_CTRL_CORE_MASK 0x0ff00000 + -+ /* get chipcommon rev */ -+ si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV; + -+ /* determine numcores */ -+ if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6))) -+ si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; -+ else -+ si->numcores = BCMINIT(sb_chip2numcores)(si->sb.chip); ++#endif /* _sbhnddma_h_ */ +diff -Naur linux.old/drivers/net/wl2/Makefile linux.dev/drivers/net/wl2/Makefile +--- linux.old/drivers/net/wl2/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl2/Makefile 2006-04-06 16:56:27.000000000 +0200 +@@ -0,0 +1,23 @@ ++# ++# Makefile for the Broadcom wl driver ++# ++# Copyright 2004, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ + -+ /* return to original core */ -+ sb_setcoreidx(&si->sb, origidx); ++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER + -+ /* sanity checks */ -+ ASSERT(si->sb.chip); ++O_TARGET := wl.o + -+ /* scan for cores */ -+ BCMINIT(sb_scan)(si); ++obj-y := wl_apsta.o ++obj-y += compat.o hnddma.o + -+ /* fixup necessary chip/core configurations */ -+ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { -+ if (sb_pci_fixcfg(si)) { -+ SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n")); -+ return NULL; -+ } -+ } -+ -+ /* srom_var_init() depends on sb_scan() info */ -+ if (srom_var_init(si, si->sb.bustype, si->curmap, osh, vars, varsz)) { -+ SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n")); -+ return (NULL); -+ } -+ -+ if (cc == NULL) { -+ /* -+ * The chip revision number is hardwired into all -+ * of the pci function config rev fields and is -+ * independent from the individual core revision numbers. -+ * For example, the "A0" silicon of each chip is chip rev 0. -+ * For PCMCIA we get it from the CIS instead. -+ */ -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { -+ ASSERT(vars); -+ si->sb.chiprev = getintvar(*vars, "chiprev"); -+ } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) { -+ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32)); -+ si->sb.chiprev = w & 0xff; -+ } else -+ si->sb.chiprev = 0; -+ } ++obj-m := $(O_TARGET) + -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { -+ w = getintvar(*vars, "regwindowsz"); -+ si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; -+ } ++include $(TOPDIR)/Rules.make +diff -Naur linux.old/drivers/net/wl2/compat.c linux.dev/drivers/net/wl2/compat.c +--- linux.old/drivers/net/wl2/compat.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl2/compat.c 2006-04-06 17:08:21.000000000 +0200 +@@ -0,0 +1,376 @@ ++/* ++ * Misc useful OS-independent routines. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ + -+ /* gpio control core is required */ -+ if (!GOODIDX(si->gpioidx)) { -+ SB_ERROR(("sb_doattach: gpio control core not found\n")); -+ return NULL; -+ } ++#include ++#ifdef BCMDRIVER ++#include ++#include ++#include ++#else ++#include ++#include ++#endif ++#include "pktq.h" ++#include ++#include ++#include + -+ /* get boardtype and boardrev */ -+ switch (BUSTYPE(si->sb.bustype)) { -+ case PCI_BUS: -+ /* do a pci config read to get subsystem id and subvendor id */ -+ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32)); -+ si->sb.boardvendor = w & 0xffff; -+ si->sb.boardtype = (w >> 16) & 0xffff; -+ break; ++#ifdef BCMDRIVER ++/* copy a pkt buffer chain into a buffer */ ++uint ++pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) ++{ ++ uint n, ret = 0; + -+ case PCMCIA_BUS: -+ case SDIO_BUS: -+ si->sb.boardvendor = getintvar(*vars, "manfid"); -+ si->sb.boardtype = getintvar(*vars, "prodid"); -+ break; ++ if (len < 0) ++ len = 4096; /* "infinite" */ + -+ case SB_BUS: -+ case JTAG_BUS: -+ si->sb.boardvendor = VENDOR_BROADCOM; -+ if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0) -+ si->sb.boardtype = 0xffff; -+ break; ++ /* skip 'offset' bytes */ ++ for (; p && offset; p = PKTNEXT(osh, p)) { ++ if (offset < (uint)PKTLEN(osh, p)) ++ break; ++ offset -= PKTLEN(osh, p); + } + -+ if (si->sb.boardtype == 0) { -+ SB_ERROR(("sb_doattach: unknown board type\n")); -+ ASSERT(si->sb.boardtype); -+ } ++ if (!p) ++ return 0; + -+ /* setup the GPIO based LED powersave register */ -+ if (si->sb.ccrev >= 16) { -+ w = getintvar(*vars, "gpiotimerval"); -+ if (!w) -+ w = DEFAULT_GPIOTIMERVAL; -+ sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); ++ /* copy the data */ ++ for (; p && len; p = PKTNEXT(osh, p)) { ++ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); ++ bcopy(PKTDATA(osh, p) + offset, buf, n); ++ buf += n; ++ len -= n; ++ ret += n; ++ offset = 0; + } + -+ -+ return (si); ++ return ret; +} + ++/* return total length of buffer chain */ +uint -+sb_coreid(sb_t *sbh) ++pkttotlen(osl_t *osh, void *p) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++ uint total; + -+ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); ++ total = 0; ++ for (; p; p = PKTNEXT(osh, p)) ++ total += PKTLEN(osh, p); ++ return (total); +} + -+uint -+sb_coreidx(sb_t *sbh) ++/* ++ * osl multiple-precedence packet queue ++ * hi_prec is always >= the number of the highest non-empty queue ++ */ ++ ++void * ++pktq_penq(struct pktq *pq, int prec, void *p) +{ -+ sb_info_t *si; ++ struct pktq_prec *q; + -+ si = SB_INFO(sbh); -+ return (si->curidx); ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ ++ ++ ASSERT(!pktq_full(pq)); ++ ASSERT(!pktq_pfull(pq, prec)); ++ ++ q = &pq->q[prec]; ++ ++ if (q->head) ++ PKTSETLINK(q->tail, p); ++ else ++ q->head = p; ++ ++ q->tail = p; ++ q->len++; ++ ++ if (pq->hi_prec < prec) ++ pq->hi_prec = (uint8)prec; ++ ++ pq->len++; ++ ++ return p; +} + -+/* return current index of core */ -+static uint -+_sb_coreidx(sb_info_t *si) ++void * ++pktq_penq_head(struct pktq *pq, int prec, void *p) +{ -+ sbconfig_t *sb; -+ uint32 sbaddr = 0; -+ -+ ASSERT(si); ++ struct pktq_prec *q; + -+ switch (BUSTYPE(si->sb.bustype)) { -+ case SB_BUS: -+ sb = REGS2SB(si->curmap); -+ sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0)); -+ break; ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ + -+ case PCI_BUS: -+ sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32)); -+ break; ++ ASSERT(!pktq_full(pq)); ++ ASSERT(!pktq_pfull(pq, prec)); + -+ case PCMCIA_BUS: { -+ uint8 tmp = 0; ++ q = &pq->q[prec]; + -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); -+ sbaddr = (uint)tmp << 12; -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); -+ sbaddr |= (uint)tmp << 16; -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); -+ sbaddr |= (uint)tmp << 24; -+ break; -+ } ++ if (q->head) ++ PKTSETLINK(p, q->head); ++ else ++ q->tail = p; + -+#ifdef BCMJTAG -+ case JTAG_BUS: -+ sbaddr = (uint32)si->curmap; -+ break; -+#endif /* BCMJTAG */ ++ q->head = p; ++ q->len++; + -+ default: -+ ASSERT(0); -+ } ++ if (pq->hi_prec < prec) ++ pq->hi_prec = (uint8)prec; + -+ if (!GOODCOREADDR(sbaddr)) -+ return BADIDX; ++ pq->len++; + -+ return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE); ++ return p; +} + -+uint -+sb_corevendor(sb_t *sbh) ++void * ++pktq_pdeq(struct pktq *pq, int prec) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; ++ struct pktq_prec *q; ++ void *p; + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++ ASSERT(prec >= 0 && prec < pq->num_prec); + -+ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); -+} ++ q = &pq->q[prec]; + -+uint -+sb_corerev(sb_t *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ uint sbidh; ++ if ((p = q->head) == NULL) ++ return NULL; + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); -+ sbidh = R_SBREG(si, &(sb)->sbidhigh); ++ if ((q->head = PKTLINK(p)) == NULL) ++ q->tail = NULL; + -+ return (SBCOREREV(sbidh)); ++ q->len--; ++ ++ pq->len--; ++ ++ PKTSETLINK(p, NULL); ++ ++ return p; +} + +void * -+sb_osh(sb_t *sbh) ++pktq_pdeq_tail(struct pktq *pq, int prec) +{ -+ sb_info_t *si; ++ struct pktq_prec *q; ++ void *p, *prev; + -+ si = SB_INFO(sbh); -+ return si->osh; -+} ++ ASSERT(prec >= 0 && prec < pq->num_prec); + -+#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK) ++ q = &pq->q[prec]; + -+/* set/clear sbtmstatelow core-specific flags */ -+uint32 -+sb_coreflags(sb_t *sbh, uint32 mask, uint32 val) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ uint32 w; ++ if ((p = q->head) == NULL) ++ return NULL; + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++ for (prev = NULL; p != q->tail; p = PKTLINK(p)) ++ prev = p; + -+ ASSERT((val & ~mask) == 0); -+ ASSERT((mask & ~SBTML_ALLOW) == 0); ++ if (prev) ++ PKTSETLINK(prev, NULL); ++ else ++ q->head = NULL; + -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val; -+ W_SBREG(si, &sb->sbtmstatelow, w); -+ } ++ q->tail = prev; ++ q->len--; + -+ /* return the new value */ -+ return (R_SBREG(si, &sb->sbtmstatelow) & SBTML_ALLOW); ++ pq->len--; ++ ++ return p; +} + -+/* set/clear sbtmstatehigh core-specific flags */ -+uint32 -+sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val) ++void ++pktq_init(struct pktq *pq, int num_prec, int max) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ uint32 w; ++ int prec; + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++ ASSERT(num_prec >= 0 && num_prec <= PKTQ_MAX_PREC); + -+ ASSERT((val & ~mask) == 0); -+ ASSERT((mask & ~SBTMH_FL_MASK) == 0); ++ bzero(pq, sizeof (*pq)); + -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val; -+ W_SBREG(si, &sb->sbtmstatehigh, w); -+ } ++ pq->num_prec = (uint16)num_prec; + -+ /* return the new value */ -+ return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK); ++ pq->max = (uint16)max; ++ ++ for (prec = 0; prec < num_prec; prec++) ++ pq->q[prec].max = pq->max; +} + -+/* caller needs to take care of core-specific bist hazards */ -+int -+sb_corebist(sb_t *sbh, uint coreid, uint coreunit) ++void * ++pktq_deq(struct pktq *pq, int *prec_out) +{ -+ uint32 sblo; -+ uint coreidx; -+ sb_info_t *si; -+ int result = 0; ++ struct pktq_prec *q; ++ void *p; ++ int prec; + -+ si = SB_INFO(sbh); ++ if (pq->len == 0) ++ return NULL; + -+ coreidx = sb_findcoreidx(si, coreid, coreunit); -+ if (!GOODIDX(coreidx)) -+ result = BCME_ERROR; -+ else { -+ sblo = sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), 0, 0); -+ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, (sblo | SBTML_FGC | SBTML_BE)); -+ -+ SPINWAIT(((sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTD) == 0), 100000); -+ -+ if (sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTF) -+ result = BCME_ERROR; ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) ++ pq->hi_prec--; + -+ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, sblo); -+ } ++ q = &pq->q[prec]; + -+ return result; -+} ++ if ((p = q->head) == NULL) ++ return NULL; + -+bool -+sb_iscoreup(sb_t *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; ++ if ((q->head = PKTLINK(p)) == NULL) ++ q->tail = NULL; + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++ q->len--; + -+ return ((R_SBREG(si, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK); ++ if (prec_out) ++ *prec_out = prec; ++ ++ pq->len--; ++ ++ PKTSETLINK(p, NULL); ++ ++ return p; +} + -+/* -+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, -+ * switch back to the original core, and return the new value. -+ */ -+static uint -+sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val) ++void * ++pktq_deq_tail(struct pktq *pq, int *prec_out) +{ -+ uint origidx; -+ uint32 *r; -+ uint w; -+ uint intr_val = 0; ++ struct pktq_prec *q; ++ void *p, *prev; ++ int prec; + -+ ASSERT(GOODIDX(coreidx)); -+ ASSERT(regoff < SB_CORE_SIZE); -+ ASSERT((val & ~mask) == 0); ++ if (pq->len == 0) ++ return NULL; + -+ INTR_OFF(si, intr_val); ++ for (prec = 0; prec < pq->hi_prec; prec++) ++ if (pq->q[prec].head) ++ break; + -+ /* save current core index */ -+ origidx = sb_coreidx(&si->sb); ++ q = &pq->q[prec]; + -+ /* switch core */ -+ r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff); ++ if ((p = q->head) == NULL) ++ return NULL; + -+ /* mask and set */ -+ if (mask || val) { -+ if (regoff >= SBCONFIGOFF) { -+ w = (R_SBREG(si, r) & ~mask) | val; -+ W_SBREG(si, r, w); -+ } else { -+ w = (R_REG(r) & ~mask) | val; -+ W_REG(r, w); -+ } -+ } ++ for (prev = NULL; p != q->tail; p = PKTLINK(p)) ++ prev = p; + -+ /* readback */ -+ if (regoff >= SBCONFIGOFF) -+ w = R_SBREG(si, r); ++ if (prev) ++ PKTSETLINK(prev, NULL); + else -+ w = R_REG(r); ++ q->head = NULL; + -+ /* restore core index */ -+ if (origidx != coreidx) -+ sb_setcoreidx(&si->sb, origidx); ++ q->tail = prev; ++ q->len--; + -+ INTR_RESTORE(si, intr_val); -+ return (w); -+} ++ if (prec_out) ++ *prec_out = prec; + -+#define DWORD_ALIGN(x) (x & ~(0x03)) -+#define BYTE_POS(x) (x & 0x3) -+#define WORD_POS(x) (x & 0x1) ++ pq->len--; + -+#define BYTE_SHIFT(x) (8 * BYTE_POS(x)) -+#define WORD_SHIFT(x) (16 * WORD_POS(x)) ++ PKTSETLINK(p, NULL); + -+#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF) -+#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF) ++ return p; ++} + -+#define read_pci_cfg_byte(a) \ -+ (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff) ++void * ++pktq_peek(struct pktq *pq, int *prec_out) ++{ ++ void *p; ++ int prec; + -+#define read_pci_cfg_write(a) \ -+ (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff) ++ if (pq->len == 0) ++ return NULL; ++ ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) ++ pq->hi_prec--; ++ ++ if ((p = pq->q[prec].head) == NULL) ++ return NULL; + ++ if (prec_out) ++ *prec_out = prec; + -+/* return TRUE if requested capability exists in the PCI config space */ -+static bool -+sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen) ++ return p; ++} ++ ++void * ++pktq_peek_tail(struct pktq *pq, int *prec_out) +{ -+ uint8 cap_id; -+ uint8 cap_ptr; -+ uint32 bufsize; -+ uint8 byte_val; ++ void *p; ++ int prec; + -+ if (BUSTYPE(si->sb.bustype) != PCI_BUS) -+ return FALSE; ++ if (pq->len == 0) ++ return NULL; + -+ /* check for Header type 0*/ -+ byte_val = read_pci_cfg_byte(PCI_CFG_HDR); -+ if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) -+ return FALSE; ++ for (prec = 0; prec < pq->hi_prec; prec++) ++ if (pq->q[prec].head) ++ break; + -+ /* check if the capability pointer field exists */ -+ byte_val = read_pci_cfg_byte(PCI_CFG_STAT); -+ if (!(byte_val & PCI_CAPPTR_PRESENT)) -+ return FALSE; ++ if ((p = pq->q[prec].tail) == NULL) ++ return NULL; + -+ cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR); -+ /* check if the capability pointer is 0x00 */ -+ if (cap_ptr == 0x00) -+ return FALSE; ++ if (prec_out) ++ *prec_out = prec; + ++ return p; ++} + -+ /* loop thr'u the capability list and see if the pcie capabilty exists */ ++int ++pktq_mlen(struct pktq *pq, uint prec_bmp) ++{ ++ int prec, len; + -+ cap_id = read_pci_cfg_byte(cap_ptr); ++ len = 0; + -+ while (cap_id != req_cap_id) { -+ cap_ptr = read_pci_cfg_byte((cap_ptr+1)); -+ if (cap_ptr == 0x00) break; -+ cap_id = read_pci_cfg_byte(cap_ptr); -+ } -+ if (cap_id != req_cap_id) { -+ return FALSE; -+ } -+ /* found the caller requested capability */ -+ if ((buf != NULL) && (buflen != NULL)) { -+ bufsize = *buflen; -+ if (!bufsize) goto end; -+ *buflen = 0; -+ /* copy the cpability data excluding cap ID and next ptr */ -+ cap_ptr += 2; -+ if ((bufsize + cap_ptr) > SZPCR) -+ bufsize = SZPCR - cap_ptr; -+ *buflen = bufsize; -+ while (bufsize--) { -+ *buf = read_pci_cfg_byte(cap_ptr); -+ cap_ptr++; -+ buf++; -+ } -+ } -+end: -+ return TRUE; -+} ++ for (prec = 0; prec <= pq->hi_prec; prec++) ++ if (prec_bmp & (1 << prec)) ++ len += pq->q[prec].len; + -+/* return TRUE if PCIE capability exists the pci config space */ -+static bool -+sb_ispcie(sb_info_t *si) -+{ -+ return(sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL)); ++ return len; +} + -+/* scan the sb enumerated space to identify all cores */ -+static void -+BCMINITFN(sb_scan)(sb_info_t *si) ++void * ++pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) +{ -+ uint origidx; -+ uint i; -+ bool pci; -+ bool pcie; -+ uint pciidx; -+ uint pcieidx; -+ uint pcirev; -+ uint pcierev; ++ struct pktq_prec *q; ++ void *p; ++ int prec; + ++ if (pq->len == 0) ++ return NULL; + ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) ++ pq->hi_prec--; + -+ /* numcores should already be set */ -+ ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); ++ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) ++ if (prec-- == 0) ++ return NULL; + -+ /* save current core index */ -+ origidx = sb_coreidx(&si->sb); ++ q = &pq->q[prec]; + -+ si->sb.buscorerev = NOREV; -+ si->sb.buscoreidx = BADIDX; ++ if ((p = q->head) == NULL) ++ return NULL; + -+ si->gpioidx = BADIDX; ++ if ((q->head = PKTLINK(p)) == NULL) ++ q->tail = NULL; + -+ pci = pcie = FALSE; -+ pcirev = pcierev = NOREV; -+ pciidx = pcieidx = BADIDX; ++ q->len--; + -+ for (i = 0; i < si->numcores; i++) { -+ sb_setcoreidx(&si->sb, i); -+ si->coreid[i] = sb_coreid(&si->sb); ++ if (prec_out) ++ *prec_out = prec; + -+ if (si->coreid[i] == SB_PCI) { -+ pciidx = i; -+ pcirev = sb_corerev(&si->sb); -+ pci = TRUE; -+ } else if (si->coreid[i] == SB_PCIE) { -+ pcieidx = i; -+ pcierev = sb_corerev(&si->sb); -+ pcie = TRUE; -+ } else if (si->coreid[i] == SB_PCMCIA) { -+ si->sb.buscorerev = sb_corerev(&si->sb); -+ si->sb.buscoretype = si->coreid[i]; -+ si->sb.buscoreidx = i; -+ } -+ } -+ if (pci && pcie) { -+ if (sb_ispcie(si)) -+ pci = FALSE; -+ else -+ pcie = FALSE; -+ } -+ if (pci) { -+ si->sb.buscoretype = SB_PCI; -+ si->sb.buscorerev = pcirev; -+ si->sb.buscoreidx = pciidx; -+ } -+ else if (pcie) { -+ si->sb.buscoretype = SB_PCIE; -+ si->sb.buscorerev = pcierev; -+ si->sb.buscoreidx = pcieidx; -+ } ++ pq->len--; + -+ /* -+ * Find the gpio "controlling core" type and index. -+ * Precedence: -+ * - if there's a chip common core - use that -+ * - else if there's a pci core (rev >= 2) - use that -+ * - else there had better be an extif core (4710 only) -+ */ -+ if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) { -+ si->gpioidx = sb_findcoreidx(si, SB_CC, 0); -+ si->gpioid = SB_CC; -+ } else if (PCI(si) && (si->sb.buscorerev >= 2)) { -+ si->gpioidx = si->sb.buscoreidx; -+ si->gpioid = SB_PCI; -+ } else if (sb_findcoreidx(si, SB_EXTIF, 0)) { -+ si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0); -+ si->gpioid = SB_EXTIF; -+ } else -+ ASSERT(si->gpioidx != BADIDX); ++ PKTSETLINK(p, NULL); + -+ /* return to original core index */ -+ sb_setcoreidx(&si->sb, origidx); ++ return p; +} + -+/* may be called with core in reset */ -+void -+sb_detach(sb_t *sbh) -+{ -+ sb_info_t *si; -+ uint idx; ++#endif + -+ si = SB_INFO(sbh); + -+ if (si == NULL) -+ return; +diff -Naur linux.old/drivers/net/wl2/hnddma.c linux.dev/drivers/net/wl2/hnddma.c +--- linux.old/drivers/net/wl2/hnddma.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl2/hnddma.c 2006-04-06 16:32:33.000000000 +0200 +@@ -0,0 +1,1487 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA module. ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ + -+ if (BUSTYPE(si->sb.bustype) == SB_BUS) -+ for (idx = 0; idx < SB_MAXCORES; idx++) -+ if (si->regs[idx]) { -+ REG_UNMAP(si->regs[idx]); -+ si->regs[idx] = NULL; -+ } ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+ if (si != &ksi) -+ MFREE(si->osh, si, sizeof (sb_info_t)); -+} ++struct dma_info; /* forward declaration */ ++#define di_t struct dma_info + -+/* use pci dev id to determine chip id for chips not having a chipcommon core */ -+static uint -+BCMINITFN(sb_pcidev2chip)(uint pcidev) -+{ -+ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) -+ return (BCM4710_DEVICE_ID); -+ if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID)) -+ return (BCM4402_DEVICE_ID); -+ if (pcidev == BCM4401_ENET_ID) -+ return (BCM4402_DEVICE_ID); -+ if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID)) -+ return (BCM4307_DEVICE_ID); -+ if (pcidev == BCM4301_DEVICE_ID) -+ return (BCM4301_DEVICE_ID); ++#include "sbhnddma.h" ++#include "hnddma.h" + -+ return (0); -+} ++/* debug/trace */ ++#define DMA_ERROR(args) ++#define DMA_TRACE(args) + -+/* convert chip number to number of i/o cores */ -+static uint -+BCMINITFN(sb_chip2numcores)(uint chip) -+{ -+ if (chip == BCM4710_DEVICE_ID) -+ return (9); -+ if (chip == BCM4402_DEVICE_ID) -+ return (3); -+ if ((chip == BCM4301_DEVICE_ID) || (chip == BCM4307_DEVICE_ID)) -+ return (5); -+ if (chip == BCM4306_DEVICE_ID) /* < 4306c0 */ -+ return (6); -+ if (chip == BCM4704_DEVICE_ID) -+ return (9); -+ if (chip == BCM5365_DEVICE_ID) -+ return (7); ++/* default dma message level (if input msg_level pointer is null in dma_attach()) */ ++static uint dma_msg_level = ++ 0; + -+ SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); -+ ASSERT(0); -+ return (1); -+} ++#define MAXNAMEL 8 + -+/* return index of coreid or BADIDX if not found */ -+static uint -+sb_findcoreidx( sb_info_t *si, uint coreid, uint coreunit) -+{ -+ uint found; -+ uint i; ++/* dma engine software state */ ++typedef struct dma_info { ++ hnddma_t hnddma; /* exported structure */ ++ uint *msg_level; /* message level pointer */ ++ char name[MAXNAMEL]; /* callers name for diag msgs */ ++ ++ void *osh; /* os handle */ ++ sb_t *sbh; /* sb handle */ ++ ++ bool dma64; /* dma64 enabled */ ++ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ ++ ++ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ ++ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ ++ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ ++ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ + -+ found = 0; ++ uint32 dma64align; /* either 8k or 4k depends on number of dd */ ++ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ ++ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ ++ uint ntxd; /* # tx descriptors tunable */ ++ uint txin; /* index of next descriptor to reclaim */ ++ uint txout; /* index of next descriptor to post */ ++ uint txavail; /* # free tx descriptors */ ++ void **txp; /* pointer to parallel array of pointers to packets */ ++ ulong txdpa; /* physical address of descriptor ring */ ++ uint txdalign; /* #bytes added to alloc'd mem to align txd */ ++ uint txdalloc; /* #bytes allocated for the ring */ + -+ for (i = 0; i < si->numcores; i++) -+ if (si->coreid[i] == coreid) { -+ if (found == coreunit) -+ return (i); -+ found++; -+ } ++ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ ++ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ ++ uint nrxd; /* # rx descriptors tunable */ ++ uint rxin; /* index of next descriptor to reclaim */ ++ uint rxout; /* index of next descriptor to post */ ++ void **rxp; /* pointer to parallel array of pointers to packets */ ++ ulong rxdpa; /* physical address of descriptor ring */ ++ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ ++ uint rxdalloc; /* #bytes allocated for the ring */ + -+ return (BADIDX); -+} ++ /* tunables */ ++ uint rxbufsize; /* rx buffer size in bytes */ ++ uint nrxpost; /* # rx buffers to keep posted */ ++ uint rxoffset; /* rxcontrol offset */ ++ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ ++ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */ ++ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ ++ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */ ++} dma_info_t; + -+/* -+ * this function changes logical "focus" to the indiciated core, -+ * must be called with interrupt off. -+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core -+ */ -+void* -+sb_setcoreidx(sb_t *sbh, uint coreidx) -+{ -+ sb_info_t *si; -+ uint32 sbaddr; -+ uint8 tmp; ++#ifdef BCMDMA64 ++#define DMA64_ENAB(di) ((di)->dma64) ++#else ++#define DMA64_ENAB(di) (0) ++#endif + -+ si = SB_INFO(sbh); ++/* descriptor bumping macros */ ++#define XXD(x, n) ((x) & ((n) - 1)) ++#define TXD(x) XXD((x), di->ntxd) ++#define RXD(x) XXD((x), di->nrxd) ++#define NEXTTXD(i) TXD(i + 1) ++#define PREVTXD(i) TXD(i - 1) ++#define NEXTRXD(i) RXD(i + 1) ++#define NTXDACTIVE(h, t) TXD(t - h) ++#define NRXDACTIVE(h, t) RXD(t - h) + -+ if (coreidx >= si->numcores) -+ return (NULL); -+ -+ /* -+ * If the user has provided an interrupt mask enabled function, -+ * then assert interrupts are disabled before switching the core. -+ */ -+ ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg)); ++/* macros to convert between byte offsets and indexes */ ++#define B2I(bytes, type) ((bytes) / sizeof(type)) ++#define I2B(index, type) ((index) * sizeof(type)) + -+ sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); ++#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ ++#define PCI32ADDR_HIGH_SHIFT 30 + -+ switch (BUSTYPE(si->sb.bustype)) { -+ case SB_BUS: -+ /* map new one */ -+ if (!si->regs[coreidx]) { -+ si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); -+ ASSERT(GOODREGS(si->regs[coreidx])); -+ } -+ si->curmap = si->regs[coreidx]; -+ break; + -+ case PCI_BUS: -+ /* point bar0 window */ -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); -+ break; ++/* prototypes */ ++static bool dma_isaddrext(dma_info_t *di); ++static bool dma_alloc(dma_info_t *di, uint direction); + -+ case PCMCIA_BUS: -+ tmp = (sbaddr >> 12) & 0x0f; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); -+ tmp = (sbaddr >> 16) & 0xff; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); -+ tmp = (sbaddr >> 24) & 0xff; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); -+ break; -+#ifdef BCMJTAG -+ case JTAG_BUS: -+ /* map new one */ -+ if (!si->regs[coreidx]) { -+ si->regs[coreidx] = (void *)sbaddr; -+ ASSERT(GOODREGS(si->regs[coreidx])); -+ } -+ si->curmap = si->regs[coreidx]; -+ break; -+#endif /* BCMJTAG */ -+ } ++static bool dma32_alloc(dma_info_t *di, uint direction); ++static void dma32_txreset(dma_info_t *di); ++static void dma32_rxreset(dma_info_t *di); ++static bool dma32_txsuspendedidle(dma_info_t *di); ++static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags); ++static void* dma32_getnexttxp(dma_info_t *di, bool forceall); ++static void* dma32_getnextrxp(dma_info_t *di, bool forceall); ++static void dma32_txrotate(di_t *di); + -+ si->curidx = coreidx; ++/* prototype or stubs */ ++#ifdef BCMDMA64 ++static bool dma64_alloc(dma_info_t *di, uint direction); ++static void dma64_txreset(dma_info_t *di); ++static void dma64_rxreset(dma_info_t *di); ++static bool dma64_txsuspendedidle(dma_info_t *di); ++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags); ++static void* dma64_getnexttxp(dma_info_t *di, bool forceall); ++static void* dma64_getnextrxp(dma_info_t *di, bool forceall); ++static void dma64_txrotate(di_t *di); ++#else ++static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; } ++static void dma64_txreset(dma_info_t *di) {} ++static void dma64_rxreset(dma_info_t *di) {} ++static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;} ++static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; } ++static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; } ++static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; } ++static void dma64_txrotate(di_t *di) { return; } ++#endif + -+ return (si->curmap); -+} + -+/* -+ * this function changes logical "focus" to the indiciated core, -+ * must be called with interrupt off. -+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core -+ */ -+void* -+sb_setcore(sb_t *sbh, uint coreid, uint coreunit) ++ ++void* ++dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) +{ -+ sb_info_t *si; -+ uint idx; ++ dma_info_t *di; ++ uint size; + -+ si = SB_INFO(sbh); -+ idx = sb_findcoreidx(si, coreid, coreunit); -+ if (!GOODIDX(idx)) ++ /* allocate private info structure */ ++ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { + return (NULL); ++ } ++ bzero((char*)di, sizeof (dma_info_t)); + -+ return (sb_setcoreidx(sbh, idx)); -+} ++ di->msg_level = msg_level ? msg_level : &dma_msg_level; + -+/* return chip number */ -+uint -+BCMINITFN(sb_chip)(sb_t *sbh) -+{ -+ sb_info_t *si; ++ if (sbh != NULL) ++ di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64); + -+ si = SB_INFO(sbh); -+ return (si->sb.chip); -+} ++#ifndef BCMDMA64 ++ if (di->dma64) { ++ DMA_ERROR(("dma_attach: driver doesn't have the capability to support 64 bits DMA\n")); ++ goto fail; ++ } ++#endif ++ ++ /* check arguments */ ++ ASSERT(ISPOWEROF2(ntxd)); ++ ASSERT(ISPOWEROF2(nrxd)); ++ if (nrxd == 0) ++ ASSERT(dmaregsrx == NULL); ++ if (ntxd == 0) ++ ASSERT(dmaregstx == NULL); + -+/* return chip revision number */ -+uint -+BCMINITFN(sb_chiprev)(sb_t *sbh) -+{ -+ sb_info_t *si; + -+ si = SB_INFO(sbh); -+ return (si->sb.chiprev); -+} ++ /* init dma reg pointer */ ++ if (di->dma64) { ++ ASSERT(ntxd <= D64MAXDD); ++ ASSERT(nrxd <= D64MAXDD); ++ di->d64txregs = (dma64regs_t *)dmaregstx; ++ di->d64rxregs = (dma64regs_t *)dmaregsrx; + -+/* return chip common revision number */ -+uint -+BCMINITFN(sb_chipcrev)(sb_t *sbh) -+{ -+ sb_info_t *si; ++ di->dma64align = D64RINGALIGN; ++ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { ++ /* for smaller dd table, HW relax the alignment requirement */ ++ di->dma64align = D64RINGALIGN / 2; ++ } ++ } else { ++ ASSERT(ntxd <= D32MAXDD); ++ ASSERT(nrxd <= D32MAXDD); ++ di->d32txregs = (dma32regs_t *)dmaregstx; ++ di->d32rxregs = (dma32regs_t *)dmaregsrx; ++ } + -+ si = SB_INFO(sbh); -+ return (si->sb.ccrev); -+} + -+/* return chip package option */ -+uint -+BCMINITFN(sb_chippkg)(sb_t *sbh) -+{ -+ sb_info_t *si; ++ /* make a private copy of our callers name */ ++ strncpy(di->name, name, MAXNAMEL); ++ di->name[MAXNAMEL-1] = '\0'; ++ ++ di->osh = osh; ++ di->sbh = sbh; ++ ++ /* save tunables */ ++ di->ntxd = ntxd; ++ di->nrxd = nrxd; ++ di->rxbufsize = rxbufsize; ++ di->nrxpost = nrxpost; ++ di->rxoffset = rxoffset; ++ ++ /* ++ * figure out the DMA physical address offset for dd and data ++ * for old chips w/o sb, use zero ++ * for new chips w sb, ++ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset ++ * Other bus: use zero ++ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor ++ */ ++ di->ddoffsetlow = 0; ++ di->dataoffsetlow = 0; ++ if (sbh != NULL) { ++ if (sbh->bustype == PCI_BUS) { /* for pci bus, add offset */ ++ if ((sbh->buscoretype == SB_PCIE) && di->dma64){ ++ di->ddoffsetlow = 0; ++ di->ddoffsethigh = SB_PCIE_DMA_H32; ++ } else { ++ di->ddoffsetlow = SB_PCI_DMA; ++ di->ddoffsethigh = 0; ++ } ++ di->dataoffsetlow = di->ddoffsetlow; ++ di->dataoffsethigh = di->ddoffsethigh; ++ } ++#if defined(__mips__) && defined(IL_BIGENDIAN) ++ /* use sdram swapped region for data buffers but not dma descriptors */ ++ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; ++#endif ++ } + -+ si = SB_INFO(sbh); -+ return (si->sb.chippkg); -+} ++ di->addrext = dma_isaddrext(di); + -+/* return PCI core rev. */ -+uint -+BCMINITFN(sb_pcirev)(sb_t *sbh) -+{ -+ sb_info_t *si; ++ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", ++ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow)); + -+ si = SB_INFO(sbh); -+ return (si->sb.buscorerev); -+} ++ /* allocate tx packet pointer vector */ ++ if (ntxd) { ++ size = ntxd * sizeof (void*); ++ if ((di->txp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero((char*)di->txp, size); ++ } + -+bool -+BCMINITFN(sb_war16165)(sb_t *sbh) -+{ -+ sb_info_t *si; ++ /* allocate rx packet pointer vector */ ++ if (nrxd) { ++ size = nrxd * sizeof (void*); ++ if ((di->rxp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero((char*)di->rxp, size); ++ } + -+ si = SB_INFO(sbh); ++ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ ++ if (ntxd) { ++ if (!dma_alloc(di, DMA_TX)) ++ goto fail; ++ } + -+ return (PCI(si) && (si->sb.buscorerev <= 10)); -+} ++ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ ++ if (nrxd) { ++ if (!dma_alloc(di, DMA_RX)) ++ goto fail; ++ } + -+static void -+BCMINITFN(sb_war30841)(sb_info_t *si) -+{ -+ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); -+ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); -+ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); -+} ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa)); ++ goto fail; ++ } ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa)); ++ goto fail; ++ } + -+/* return PCMCIA core rev. */ -+uint -+BCMINITFN(sb_pcmciarev)(sb_t *sbh) -+{ -+ sb_info_t *si; ++ return ((void*)di); + -+ si = SB_INFO(sbh); -+ return (si->sb.buscorerev); ++fail: ++ dma_detach((void*)di); ++ return (NULL); +} + -+/* return board vendor id */ -+uint -+BCMINITFN(sb_boardvendor)(sb_t *sbh) ++static bool ++dma_alloc(dma_info_t *di, uint direction) +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->sb.boardvendor); ++ if (DMA64_ENAB(di)) { ++ return dma64_alloc(di, direction); ++ } else { ++ return dma32_alloc(di, direction); ++ } +} + -+/* return boardtype */ -+uint -+BCMINITFN(sb_boardtype)(sb_t *sbh) ++/* may be called with core in reset */ ++void ++dma_detach(dma_info_t *di) +{ -+ sb_info_t *si; -+ char *var; -+ -+ si = SB_INFO(sbh); ++ if (di == NULL) ++ return; + -+ if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) { -+ /* boardtype format is a hex string */ -+ si->sb.boardtype = getintvar(NULL, "boardtype"); ++ DMA_TRACE(("%s: dma_detach\n", di->name)); + -+ /* backward compatibility for older boardtype string format */ -+ if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) { -+ if (!strcmp(var, "bcm94710dev")) -+ si->sb.boardtype = BCM94710D_BOARD; -+ else if (!strcmp(var, "bcm94710ap")) -+ si->sb.boardtype = BCM94710AP_BOARD; -+ else if (!strcmp(var, "bu4710")) -+ si->sb.boardtype = BU4710_BOARD; -+ else if (!strcmp(var, "bcm94702mn")) -+ si->sb.boardtype = BCM94702MN_BOARD; -+ else if (!strcmp(var, "bcm94710r1")) -+ si->sb.boardtype = BCM94710R1_BOARD; -+ else if (!strcmp(var, "bcm94710r4")) -+ si->sb.boardtype = BCM94710R4_BOARD; -+ else if (!strcmp(var, "bcm94702cpci")) -+ si->sb.boardtype = BCM94702CPCI_BOARD; -+ else if (!strcmp(var, "bcm95380_rr")) -+ si->sb.boardtype = BCM95380RR_BOARD; -+ } -+ } ++ /* shouldn't be here if descriptors are unreclaimed */ ++ ASSERT(di->txin == di->txout); ++ ASSERT(di->rxin == di->rxout); + -+ return (si->sb.boardtype); -+} ++ /* free dma descriptor rings */ ++ if (di->txd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign)); ++ if (di->rxd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign)); + -+/* return bus type of sbh device */ -+uint -+sb_bus(sb_t *sbh) -+{ -+ sb_info_t *si; ++ /* free packet pointer vectors */ ++ if (di->txp) ++ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*))); ++ if (di->rxp) ++ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*))); + -+ si = SB_INFO(sbh); -+ return (si->sb.bustype); ++ /* free our private info structure */ ++ MFREE(di->osh, (void*)di, sizeof (dma_info_t)); +} + -+/* return bus core type */ -+uint -+sb_buscoretype(sb_t *sbh) ++/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ ++static bool ++dma_isaddrext(dma_info_t *di) +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); ++ uint32 w; + -+ return (si->sb.buscoretype); ++ if (DMA64_ENAB(di)) { ++ OR_REG(&di->d64txregs->control, D64_XC_AE); ++ w = R_REG(&di->d32txregs->control); ++ AND_REG(&di->d32txregs->control, ~D64_XC_AE); ++ return ((w & XC_AE) == D64_XC_AE); ++ } else { ++ OR_REG(&di->d32txregs->control, XC_AE); ++ w = R_REG(&di->d32txregs->control); ++ AND_REG(&di->d32txregs->control, ~XC_AE); ++ return ((w & XC_AE) == XC_AE); ++ } +} + -+/* return bus core revision */ -+uint -+sb_buscorerev(sb_t *sbh) ++void ++dma_txreset(dma_info_t *di) +{ -+ sb_info_t *si; -+ si = SB_INFO(sbh); ++ DMA_TRACE(("%s: dma_txreset\n", di->name)); + -+ return (si->sb.buscorerev); ++ if (DMA64_ENAB(di)) ++ dma64_txreset(di); ++ else ++ dma32_txreset(di); +} + -+/* return list of found cores */ -+uint -+sb_corelist(sb_t *sbh, uint coreid[]) ++void ++dma_rxreset(dma_info_t *di) +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); ++ DMA_TRACE(("%s: dma_rxreset\n", di->name)); + -+ bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint))); -+ return (si->numcores); ++ if (DMA64_ENAB(di)) ++ dma64_rxreset(di); ++ else ++ dma32_rxreset(di); +} + -+/* return current register mapping */ -+void * -+sb_coreregs(sb_t *sbh) ++/* initialize descriptor table base address */ ++static void ++dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ ASSERT(GOODREGS(si->curmap)); -+ -+ return (si->curmap); ++ if (DMA64_ENAB(di)) { ++ if (direction == DMA_TX) { ++ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow); ++ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); ++ } else { ++ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow); ++ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); ++ } ++ } else { ++ uint32 offset = di->ddoffsetlow; ++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ if (direction == DMA_TX) ++ W_REG(&di->d32txregs->addr, (pa + offset)); ++ else ++ W_REG(&di->d32rxregs->addr, (pa + offset)); ++ } else { ++ /* dma32 address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ ++ if (direction == DMA_TX) { ++ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); ++ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT)); ++ } else { ++ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); ++ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT)); ++ } ++ } ++ } +} + -+ -+/* do buffered registers update */ -+void -+sb_commit(sb_t *sbh) ++/* init the tx or rx descriptor */ ++static INLINE void ++dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl) +{ -+ sb_info_t *si; -+ uint origidx; -+ uint intr_val = 0; -+ -+ si = SB_INFO(sbh); -+ -+ origidx = si->curidx; -+ ASSERT(GOODIDX(origidx)); ++ uint offset = di->dataoffsetlow; + -+ INTR_OFF(si, intr_val); ++ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); ++ } else { ++ /* address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; + -+ /* switch over to chipcommon core if there is one, else use pci */ -+ if (si->sb.ccrev != NOREV) { -+ chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0); ++ *ctrl |= (ae << CTRL_AE_SHIFT); ++ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); ++ } ++} + -+ /* do the buffer registers update */ -+ W_REG(&ccregs->broadcastaddress, SB_COMMIT); -+ W_REG(&ccregs->broadcastdata, 0x0); -+ } else if (PCI(si)) { -+ sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0); ++/* init the tx or rx descriptor */ ++static INLINE void ++dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount) ++{ ++ uint32 bufaddr_low = pa + di->dataoffsetlow; ++ uint32 bufaddr_high = 0 + di->dataoffsethigh; + -+ /* do the buffer registers update */ -+ W_REG(&pciregs->bcastaddr, SB_COMMIT); -+ W_REG(&pciregs->bcastdata, 0x0); -+ } else -+ ASSERT(0); ++ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; + -+ /* restore core index */ -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); ++ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low)); ++ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high)); ++ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); ++ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); +} + -+/* reset and re-enable a core */ +void -+sb_core_reset(sb_t *sbh, uint32 bits) ++dma_txinit(dma_info_t *di) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ volatile uint32 dummy; -+ -+ si = SB_INFO(sbh); -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); -+ -+ /* -+ * Must do the disable sequence first to work for arbitrary current core state. -+ */ -+ sb_core_disable(sbh, bits); -+ -+ /* -+ * Now do the initialization sequence. -+ */ ++ DMA_TRACE(("%s: dma_txinit\n", di->name)); + -+ /* set reset while enabling the clock and forcing them on throughout the core */ -+ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(1); ++ di->txin = di->txout = 0; ++ di->txavail = di->ntxd - 1; + -+ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) { -+ W_SBREG(si, &sb->sbtmstatehigh, 0); -+ } -+ if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { -+ AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); ++ /* clear tx descriptor ring */ ++ if (DMA64_ENAB(di)) { ++ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t))); ++ W_REG(&di->d64txregs->control, XC_XE); ++ dma_ddtable_init(di, DMA_TX, di->txdpa); ++ } else { ++ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t))); ++ W_REG(&di->d32txregs->control, XC_XE); ++ dma_ddtable_init(di, DMA_TX, di->txdpa); + } -+ -+ /* clear reset and allow it to propagate throughout the core */ -+ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(1); -+ -+ /* leave clock enabled */ -+ W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits)); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(1); +} + -+void -+sb_core_tofixup(sb_t *sbh) ++bool ++dma_txenabled(dma_info_t *di) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ -+ if ( (BUSTYPE(si->sb.bustype) != PCI_BUS) || PCIE(si) || (PCI(si) && (si->sb.buscorerev >= 5)) ) -+ return; -+ -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); -+ -+ if (BUSTYPE(si->sb.bustype) == SB_BUS) { -+ SET_SBREG(si, &sb->sbimconfiglow, -+ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x5 << SBIMCL_RTO_SHIFT) | 0x3); ++ uint32 xc; ++ ++ /* If the chip is dead, it is not enabled :-) */ ++ if (DMA64_ENAB(di)) { ++ xc = R_REG(&di->d64txregs->control); ++ return ((xc != 0xffffffff) && (xc & D64_XC_XE)); + } else { -+ if (sb_coreid(sbh) == SB_PCI) { -+ SET_SBREG(si, &sb->sbimconfiglow, -+ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); -+ } else { -+ SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); -+ } ++ xc = R_REG(&di->d32txregs->control); ++ return ((xc != 0xffffffff) && (xc & XC_XE)); + } -+ -+ sb_commit(sbh); +} + -+/* -+ * Set the initiator timeout for the "master core". -+ * The master core is defined to be the core in control -+ * of the chip and so it issues accesses to non-memory -+ * locations (Because of dma *any* core can access memeory). -+ * -+ * The routine uses the bus to decide who is the master: -+ * SB_BUS => mips -+ * JTAG_BUS => chipc -+ * PCI_BUS => pci or pcie -+ * PCMCIA_BUS => pcmcia -+ * SDIO_BUS => pcmcia -+ * -+ * This routine exists so callers can disable initiator -+ * timeouts so accesses to very slow devices like otp -+ * won't cause an abort. The routine allows arbitrary -+ * settings of the service and request timeouts, though. -+ * -+ * Returns the timeout state before changing it or -1 -+ * on error. -+ */ -+ -+#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) -+ -+uint32 -+sb_set_initiator_to(sb_t *sbh, uint32 to) ++void ++dma_txsuspend(dma_info_t *di) +{ -+ sb_info_t *si; -+ uint origidx, idx; -+ uint intr_val = 0; -+ uint32 tmp, ret = 0xffffffff; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ -+ if ((to & ~TO_MASK) != 0) -+ return ret; ++ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); ++ if (DMA64_ENAB(di)) ++ OR_REG(&di->d64txregs->control, D64_XC_SE); ++ else ++ OR_REG(&di->d32txregs->control, XC_SE); ++} + -+ /* Figure out the master core */ -+ idx = BADIDX; -+ switch (BUSTYPE(si->sb.bustype)) { -+ case PCI_BUS: -+ idx = si->sb.buscoreidx; -+ break; -+ case JTAG_BUS: -+ idx = SB_CC_IDX; -+ break; -+ case PCMCIA_BUS: -+ case SDIO_BUS: -+ idx = sb_findcoreidx(si, SB_PCMCIA, 0); -+ break; -+ case SB_BUS: -+ if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX) -+ idx = sb_findcoreidx(si, SB_MIPS, 0); -+ break; -+ default: -+ ASSERT(0); -+ } -+ if (idx == BADIDX) -+ return ret; ++void ++dma_txresume(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txresume\n", di->name)); ++ if (DMA64_ENAB(di)) ++ AND_REG(&di->d64txregs->control, ~D64_XC_SE); ++ else ++ AND_REG(&di->d32txregs->control, ~XC_SE); ++} + -+ INTR_OFF(si, intr_val); -+ origidx = sb_coreidx(sbh); ++bool ++dma_txsuspendedidle(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return dma64_txsuspendedidle(di); ++ else ++ return dma32_txsuspendedidle(di); ++} + -+ sb = REGS2SB(sb_setcoreidx(sbh, idx)); ++bool ++dma_txsuspended(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); ++ else ++ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE); ++} + -+ tmp = R_SBREG(si, &sb->sbimconfiglow); -+ ret = tmp & TO_MASK; -+ W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); ++bool ++dma_txstopped(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); ++ else ++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); ++} + -+ sb_commit(sbh); -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return ret; ++bool ++dma_rxstopped(dma_info_t *di) ++{ ++ if (DMA64_ENAB(di)) ++ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); ++ else ++ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); +} + +void -+sb_core_disable(sb_t *sbh, uint32 bits) ++dma_fifoloopbackenable(dma_info_t *di) +{ -+ sb_info_t *si; -+ volatile uint32 dummy; -+ uint32 rej; -+ sbconfig_t *sb; -+ -+ si = SB_INFO(sbh); -+ -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); -+ -+ /* if core is already in reset, just return */ -+ if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET) -+ return; -+ -+ /* reject value changed between sonics 2.2 and 2.3 */ -+ if (si->sb.sonicsrev == SONICS_2_2) -+ rej = (1 << SBTML_REJ_SHIFT); ++ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); ++ if (DMA64_ENAB(di)) ++ OR_REG(&di->d64txregs->control, D64_XC_LE); + else -+ rej = (2 << SBTML_REJ_SHIFT); ++ OR_REG(&di->d32txregs->control, XC_LE); ++} + -+ /* if clocks are not enabled, put into reset and return */ -+ if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0) -+ goto disable; ++void ++dma_rxinit(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxinit\n", di->name)); + -+ /* set target reject and spin until busy is clear (preserve core-specific bits) */ -+ OR_SBREG(si, &sb->sbtmstatelow, rej); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(1); -+ SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); ++ di->rxin = di->rxout = 0; + -+ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) { -+ OR_SBREG(si, &sb->sbimstate, SBIM_RJ); -+ dummy = R_SBREG(si, &sb->sbimstate); -+ OSL_DELAY(1); -+ SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000); ++ /* clear rx descriptor ring */ ++ if (DMA64_ENAB(di)) { ++ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t))); ++ dma_rxenable(di); ++ dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ } else { ++ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t))); ++ dma_rxenable(di); ++ dma_ddtable_init(di, DMA_RX, di->rxdpa); + } ++} + -+ /* set reset and reject while enabling the clocks */ -+ W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET)); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(10); ++void ++dma_rxenable(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxenable\n", di->name)); ++ if (DMA64_ENAB(di)) ++ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE)); ++ else ++ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); ++} + -+ /* don't forget to clear the initiator reject bit */ -+ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) -+ AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ); ++bool ++dma_rxenabled(dma_info_t *di) ++{ ++ uint32 rc; + -+disable: -+ /* leave reset and reject asserted */ -+ W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET)); -+ OSL_DELAY(1); ++ if (DMA64_ENAB(di)) { ++ rc = R_REG(&di->d64rxregs->control); ++ return ((rc != 0xffffffff) && (rc & D64_RC_RE)); ++ } else { ++ rc = R_REG(&di->d32rxregs->control); ++ return ((rc != 0xffffffff) && (rc & RC_RE)); ++ } +} + -+/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */ -+void -+sb_watchdog(sb_t *sbh, uint ticks) -+{ -+ sb_info_t *si = SB_INFO(sbh); + -+ /* instant NMI */ -+ switch (si->gpioid) { -+ case SB_CC: -+ sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); -+ break; -+ case SB_EXTIF: -+ sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); -+ break; ++/* !! tx entry routine */ ++int ++dma_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_txfast(di, p0, coreflags); ++ } else { ++ return dma32_txfast(di, p0, coreflags); + } +} + -+/* initialize the pcmcia core */ -+void -+sb_pcmcia_init(sb_t *sbh) ++/* !! rx entry routine, returns a pointer to the next frame received, or NULL if there are no more */ ++void* ++dma_rx(dma_info_t *di) +{ -+ sb_info_t *si; -+ uint8 cor; ++ void *p; ++ uint len; ++ int skiplen = 0; + -+ si = SB_INFO(sbh); ++ while ((p = dma_getnextrxp(di, FALSE))) { ++ /* skip giant packets which span multiple rx descriptors */ ++ if (skiplen > 0) { ++ skiplen -= di->rxbufsize; ++ if (skiplen < 0) ++ skiplen = 0; ++ PKTFREE(di->osh, p, FALSE); ++ continue; ++ } + -+ /* enable d11 mac interrupts */ -+ if (si->sb.chip == BCM4301_DEVICE_ID) { -+ /* Have to use FCR2 in 4301 */ -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); -+ cor |= COR_IRQEN | COR_FUNEN; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); -+ } else { -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); -+ cor |= COR_IRQEN | COR_FUNEN; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); ++ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); ++ ++ /* bad frame length check */ ++ if (len > (di->rxbufsize - di->rxoffset)) { ++ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); ++ if (len > 0) ++ skiplen = len - (di->rxbufsize - di->rxoffset); ++ PKTFREE(di->osh, p, FALSE); ++ di->hnddma.rxgiants++; ++ continue; ++ } ++ ++ /* set actual length */ ++ PKTSETLEN(di->osh, p, (di->rxoffset + len)); ++ ++ break; + } + ++ return (p); +} + -+ -+/* -+ * Configure the pci core for pci client (NIC) action -+ * coremask is the bitvec of cores by index to be enabled. -+ */ ++/* post receive buffers */ +void -+sb_pci_setup(sb_t *sbh, uint coremask) ++dma_rxfill(dma_info_t *di) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ sbpciregs_t *pciregs; -+ uint32 sbflag; -+ uint32 w; -+ uint idx; -+ int reg_val; ++ void *p; ++ uint rxin, rxout; ++ uint32 ctrl; ++ uint n; ++ uint i; ++ uint32 pa; ++ uint rxbufsize; + -+ si = SB_INFO(sbh); ++ /* ++ * Determine how many receive buffers we're lacking ++ * from the full complement, allocate, initialize, ++ * and post them, then update the chip rx lastdscr. ++ */ + -+ /* if not pci bus, we're done */ -+ if (BUSTYPE(si->sb.bustype) != PCI_BUS) -+ return; ++ rxin = di->rxin; ++ rxout = di->rxout; ++ rxbufsize = di->rxbufsize; + -+ ASSERT(PCI(si) || PCIE(si)); -+ ASSERT(si->sb.buscoreidx != BADIDX); ++ n = di->nrxpost - NRXDACTIVE(rxin, rxout); + -+ /* get current core index */ -+ idx = si->curidx; ++ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); + -+ /* we interrupt on this backplane flag number */ -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); -+ sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ for (i = 0; i < n; i++) { ++ if ((p = PKTGET(di->osh, rxbufsize, FALSE)) == NULL) { ++ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); ++ di->hnddma.rxnobuf++; ++ break; ++ } + -+ /* switch over to pci core */ -+ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx); -+ sb = REGS2SB(pciregs); ++ /* Do a cached write instead of uncached write since DMA_MAP ++ * will flush the cache. */ ++ *(uint32*)(PKTDATA(di->osh, p)) = 0; + -+ /* -+ * Enable sb->pci interrupts. Assume -+ * PCI rev 2.3 support was added in pci core rev 6 and things changed.. -+ */ -+ if (PCIE(si) || (PCI(si) && ((si->sb.buscorerev) >= 6))) { -+ /* pci config write to set this core bit in PCIIntMask */ -+ w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32)); -+ w |= (coremask << PCI_SBIM_SHIFT); -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w); -+ } else { -+ /* set sbintvec bit for our flag number */ -+ OR_SBREG(si, &sb->sbintvec, (1 << sbflag)); -+ } ++ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p); ++ ASSERT(ISALIGNED(pa, 4)); + -+ if (PCI(si)) { -+ OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); -+ if (si->sb.buscorerev >= 11) -+ OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI); -+ if (si->sb.buscorerev < 5) { -+ SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); -+ sb_commit(sbh); -+ } -+ } ++ /* save the free packet pointer */ ++ ASSERT(di->rxp[rxout] == NULL); ++ di->rxp[rxout] = p; + -+ if (PCIE(si) && (si->sb.buscorerev == 0)) { -+ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); -+ reg_val |= 0x8; -+ sb_pcie_writereg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, reg_val); ++ if (DMA64_ENAB(di)) { ++ /* prep the descriptor control value */ ++ if (rxout == (di->nrxd - 1)) ++ ctrl = CTRL_EOT; + -+ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG); -+ reg_val &= ~(0x40); -+ sb_pcie_writereg(sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG, reg_val); ++ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize); ++ } else { ++ /* prep the descriptor control value */ ++ ctrl = rxbufsize; ++ if (rxout == (di->nrxd - 1)) ++ ctrl |= CTRL_EOT; ++ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl); ++ } + -+ BCMINIT(sb_war30841)(si); ++ rxout = NEXTRXD(rxout); + } + -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); ++ di->rxout = rxout; ++ ++ /* update the chip lastdscr pointer */ ++ if (DMA64_ENAB(di)) { ++ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t)); ++ } else { ++ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); ++ } +} + -+uint32 -+sb_base(uint32 admatch) ++void ++dma_txreclaim(dma_info_t *di, bool forceall) +{ -+ uint32 base; -+ uint type; ++ void *p; + -+ type = admatch & SBAM_TYPE_MASK; -+ ASSERT(type < 3); ++ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); + -+ base = 0; ++ while ((p = dma_getnexttxp(di, forceall))) ++ PKTFREE(di->osh, p, TRUE); ++} + -+ if (type == 0) { -+ base = admatch & SBAM_BASE0_MASK; -+ } else if (type == 1) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ base = admatch & SBAM_BASE1_MASK; -+ } else if (type == 2) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ base = admatch & SBAM_BASE2_MASK; ++/* ++ * Reclaim next completed txd (txds if using chained buffers) and ++ * return associated packet. ++ * If 'force' is true, reclaim txd(s) and return associated packet ++ * regardless of the value of the hardware "curr" pointer. ++ */ ++void* ++dma_getnexttxp(dma_info_t *di, bool forceall) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_getnexttxp(di, forceall); ++ } else { ++ return dma32_getnexttxp(di, forceall); + } -+ -+ return (base); +} -+ -+uint32 -+sb_size(uint32 admatch) ++ ++/* like getnexttxp but no reclaim */ ++void* ++dma_peeknexttxp(dma_info_t *di) +{ -+ uint32 size; -+ uint type; ++ uint end, i; + -+ type = admatch & SBAM_TYPE_MASK; -+ ASSERT(type < 3); ++ if (DMA64_ENAB(di)) { ++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ } else { ++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ } + -+ size = 0; ++ for (i = di->txin; i != end; i = NEXTTXD(i)) ++ if (di->txp[i]) ++ return (di->txp[i]); + -+ if (type == 0) { -+ size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); -+ } else if (type == 1) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); -+ } else if (type == 2) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); -+ } ++ return (NULL); ++} + -+ return (size); ++/* ++ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). ++ */ ++void ++dma_txrotate(di_t *di) ++{ ++ if (DMA64_ENAB(di)) { ++ dma64_txrotate(di); ++ } else { ++ dma32_txrotate(di); ++ } +} + -+/* return the core-type instantiation # of the current core */ -+uint -+sb_coreunit(sb_t *sbh) ++void ++dma_rxreclaim(dma_info_t *di) +{ -+ sb_info_t *si; -+ uint idx; -+ uint coreid; -+ uint coreunit; -+ uint i; ++ void *p; + -+ si = SB_INFO(sbh); -+ coreunit = 0; ++ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); + -+ idx = si->curidx; ++ while ((p = dma_getnextrxp(di, TRUE))) ++ PKTFREE(di->osh, p, FALSE); ++} + -+ ASSERT(GOODREGS(si->curmap)); -+ coreid = sb_coreid(sbh); ++void * ++dma_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ if (DMA64_ENAB(di)) { ++ return dma64_getnextrxp(di, forceall); ++ } else { ++ return dma32_getnextrxp(di, forceall); ++ } ++} + -+ /* count the cores of our type */ -+ for (i = 0; i < idx; i++) -+ if (si->coreid[i] == coreid) -+ coreunit++; ++uintptr ++dma_getvar(dma_info_t *di, char *name) ++{ ++ if (!strcmp(name, "&txavail")) ++ return ((uintptr) &di->txavail); ++ else { ++ ASSERT(0); ++ } ++ return (0); ++} + -+ return (coreunit); ++void ++dma_txblock(dma_info_t *di) ++{ ++ di->txavail = 0; +} + -+static INLINE uint32 -+factor6(uint32 x) ++void ++dma_txunblock(dma_info_t *di) +{ -+ switch (x) { -+ case CC_F6_2: return 2; -+ case CC_F6_3: return 3; -+ case CC_F6_4: return 4; -+ case CC_F6_5: return 5; -+ case CC_F6_6: return 6; -+ case CC_F6_7: return 7; -+ default: return 0; -+ } ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; +} + -+/* calculate the speed the SB would run at given a set of clockcontrol values */ -+uint32 -+sb_clock_rate(uint32 pll_type, uint32 n, uint32 m) ++uint ++dma_txactive(dma_info_t *di) +{ -+ uint32 n1, n2, clock, m1, m2, m3, mc; ++ return (NTXDACTIVE(di->txin, di->txout)); ++} ++ ++void ++dma_rxpiomode(dma32regs_t *regs) ++{ ++ W_REG(®s->control, RC_FM); ++} + -+ n1 = n & CN_N1_MASK; -+ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; ++void ++dma_txpioloopback(dma32regs_t *regs) ++{ ++ OR_REG(®s->control, XC_LE); ++} + -+ if (pll_type == PLL_TYPE6) { -+ if (m & CC_T6_MMASK) -+ return CC_T6_M1; -+ else -+ return CC_T6_M0; -+ } else if ((pll_type == PLL_TYPE1) || -+ (pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE7)) { -+ n1 = factor6(n1); -+ n2 += CC_F5_BIAS; -+ } else if (pll_type == PLL_TYPE2) { -+ n1 += CC_T2_BIAS; -+ n2 += CC_T2_BIAS; -+ ASSERT((n1 >= 2) && (n1 <= 7)); -+ ASSERT((n2 >= 5) && (n2 <= 23)); -+ } else if (pll_type == PLL_TYPE5) { -+ return (100000000); -+ } else -+ ASSERT(0); -+ /* PLL types 3 and 7 use BASE2 (25Mhz) */ -+ if ((pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE7)) { -+ clock = CC_CLOCK_BASE2 * n1 * n2; -+ } -+ else -+ clock = CC_CLOCK_BASE1 * n1 * n2; + -+ if (clock == 0) -+ return 0; + -+ m1 = m & CC_M1_MASK; -+ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; -+ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; -+ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; + -+ if ((pll_type == PLL_TYPE1) || -+ (pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE7)) { -+ m1 = factor6(m1); -+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) -+ m2 += CC_F5_BIAS; -+ else -+ m2 = factor6(m2); -+ m3 = factor6(m3); ++/*** 32 bits DMA non-inline functions ***/ ++static bool ++dma32_alloc(dma_info_t *di, uint direction) ++{ ++ uint size; ++ uint ddlen; ++ void *va; + -+ switch (mc) { -+ case CC_MC_BYPASS: return (clock); -+ case CC_MC_M1: return (clock / m1); -+ case CC_MC_M1M2: return (clock / (m1 * m2)); -+ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); -+ case CC_MC_M1M3: return (clock / (m1 * m3)); -+ default: return (0); -+ } -+ } else { -+ ASSERT(pll_type == PLL_TYPE2); ++ ddlen = sizeof (dma32dd_t); + -+ m1 += CC_T2_BIAS; -+ m2 += CC_T2M2_BIAS; -+ m3 += CC_T2_BIAS; -+ ASSERT((m1 >= 2) && (m1 <= 7)); -+ ASSERT((m2 >= 3) && (m2 <= 10)); -+ ASSERT((m3 >= 2) && (m3 <= 7)); ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) ++ size += D32RINGALIGN; + -+ if ((mc & CC_T2MC_M1BYP) == 0) -+ clock /= m1; -+ if ((mc & CC_T2MC_M2BYP) == 0) -+ clock /= m2; -+ if ((mc & CC_T2MC_M3BYP) == 0) -+ clock /= m3; + -+ return(clock); ++ if (direction == DMA_TX) { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); ++ return FALSE; ++ } ++ ++ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); ++ di->txdpa += di->txdalign; ++ di->txdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); ++ } else { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); ++ return FALSE; ++ } ++ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); ++ di->rxdpa += di->rxdalign; ++ di->rxdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); + } ++ ++ return TRUE; +} + -+/* returns the current speed the SB is running at */ -+uint32 -+sb_clock(sb_t *sbh) ++static void ++dma32_txreset(dma_info_t *di) +{ -+ sb_info_t *si; -+ extifregs_t *eir; -+ chipcregs_t *cc; -+ uint32 n, m; -+ uint idx; -+ uint32 pll_type, rate; -+ uint intr_val = 0; ++ uint32 status; + -+ si = SB_INFO(sbh); -+ idx = si->curidx; -+ pll_type = PLL_TYPE1; ++ /* suspend tx DMA first */ ++ W_REG(&di->d32txregs->control, XC_SE); ++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED && ++ status != XS_XS_IDLE && ++ status != XS_XS_STOPPED, ++ 10000); + -+ INTR_OFF(si, intr_val); ++ W_REG(&di->d32txregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED, ++ 10000); + -+ /* switch to extif or chipc core */ -+ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { -+ n = R_REG(&eir->clockcontrol_n); -+ m = R_REG(&eir->clockcontrol_sb); -+ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { -+ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; -+ n = R_REG(&cc->clockcontrol_n); -+ if (pll_type == PLL_TYPE6) -+ m = R_REG(&cc->clockcontrol_mips); -+ else if (pll_type == PLL_TYPE3) -+ { -+ // Added by Chen-I for 5365 -+ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) -+ m = R_REG(&cc->clockcontrol_sb); -+ else -+ m = R_REG(&cc->clockcontrol_m2); -+ } -+ else -+ m = R_REG(&cc->clockcontrol_sb); -+ } else { -+ INTR_RESTORE(si, intr_val); -+ return 0; ++ if (status != XS_XS_DISABLED) { ++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); + } + -+ // Added by Chen-I for 5365 -+ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) -+ { -+ rate = 100000000; -+ } -+ else -+ { -+ /* calculate rate */ -+ rate = sb_clock_rate(pll_type, n, m); -+ if (pll_type == PLL_TYPE3) -+ rate = rate / 2; -+ } ++ /* wait for the last transaction to complete */ ++ OSL_DELAY(300); ++} + -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); ++static void ++dma32_rxreset(dma_info_t *di) ++{ ++ uint32 status; + -+ INTR_RESTORE(si, intr_val); ++ W_REG(&di->d32rxregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED, ++ 10000); + -+ return rate; ++ if (status != RS_RS_DISABLED) { ++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); ++ } +} + -+/* change logical "focus" to the gpio core for optimized access */ -+void* -+sb_gpiosetcore(sb_t *sbh) ++static bool ++dma32_txsuspendedidle(dma_info_t *di) +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); ++ if (!(R_REG(&di->d32txregs->control) & XC_SE)) ++ return 0; ++ ++ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) ++ return 0; + -+ return (sb_setcoreidx(sbh, si->gpioidx)); ++ OSL_DELAY(2); ++ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); +} + -+/* mask&set gpiocontrol bits */ -+uint32 -+sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++/* ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ */ ++static int ++dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags) +{ -+ sb_info_t *si; -+ uint regoff; ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint txout; ++ uint32 ctrl; ++ uint32 pa; + -+ si = SB_INFO(sbh); -+ regoff = 0; ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ txout = di->txout; ++ ctrl = 0; + -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; -+ } ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++ next = PKTNEXT(di->osh, p); + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpiocontrol); -+ break; ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) ++ goto outoftxd; + -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpiocontrol); -+ break; ++ if (len == 0) ++ continue; + -+ case SB_EXTIF: -+ return (0); -+ } ++ /* get physical address of buffer start */ ++ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); -+} ++ /* build the descriptor control value */ ++ ctrl = len & CTRL_BC_MASK; + -+/* mask&set gpio output enable bits */ -+uint32 -+sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) -+{ -+ sb_info_t *si; -+ uint regoff; ++ ctrl |= coreflags; ++ ++ if (p == p0) ++ ctrl |= CTRL_SOF; ++ if (next == NULL) ++ ctrl |= (CTRL_IOC | CTRL_EOF); ++ if (txout == (di->ntxd - 1)) ++ ctrl |= CTRL_EOT; + -+ si = SB_INFO(sbh); -+ regoff = 0; ++ if (DMA64_ENAB(di)) { ++ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len); ++ } else { ++ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl); ++ } + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ASSERT(di->txp[txout] == NULL); + -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; ++ txout = NEXTTXD(txout); + } + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpioouten); -+ break; ++ /* if last txd eof not set, fix it */ ++ if (!(ctrl & CTRL_EOF)) ++ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF)); + -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpioouten); -+ break; ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; + -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpio[0].outen); -+ break; ++ /* bump the tx descriptor index */ ++ di->txout = txout; ++ ++ /* kick the chip */ ++ if (DMA64_ENAB(di)) { ++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); ++ } else { ++ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t)); + } + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (0); ++ ++ outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); +} + -+/* mask&set gpio output bits */ -+uint32 -+sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++static void* ++dma32_getnexttxp(dma_info_t *di, bool forceall) +{ -+ sb_info_t *si; -+ uint regoff; ++ uint start, end, i; ++ void *txp; ++ ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); ++ ++ txp = NULL; ++ ++ start = di->txin; ++ if (forceall) ++ end = di->txout; ++ else ++ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); + -+ si = SB_INFO(sbh); -+ regoff = 0; ++ if ((start == 0) && (end > di->txout)) ++ goto bogus; + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), ++ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]); + -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; ++ W_SM(&di->txd32[i].addr, 0xdeadbeef); ++ txp = di->txp[i]; ++ di->txp[i] = NULL; + } + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpioout); -+ break; ++ di->txin = i; + -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpioout); -+ break; ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpio[0].out); -+ break; -+ } ++ return (txp); + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++bogus: ++/* ++ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++*/ ++ return (NULL); +} + -+/* reserve one gpio */ -+uint32 -+sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) ++static void * ++dma32_getnextrxp(dma_info_t *di, bool forceall) +{ -+ sb_info_t *si; ++ uint i; ++ void *rxp; + -+ si = SB_INFO(sbh); ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma_rxenabled(di)); + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ i = di->rxin; + -+ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ -+ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { -+ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); -+ return -1; -+ } -+ /* make sure only one bit is set */ -+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { -+ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); -+ return -1; -+ } ++ /* return if no packets posted */ ++ if (i == di->rxout) ++ return (NULL); + -+ /* already reserved */ -+ if (sb_gpioreservation & gpio_bitmask) -+ return -1; -+ /* set reservation */ -+ sb_gpioreservation |= gpio_bitmask; ++ /* ignore curr if forceall */ ++ if (!forceall && (i == B2I(R_REG(&di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) ++ return (NULL); + -+ return sb_gpioreservation; -+} ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; + -+/* release one gpio */ -+/* -+ * releasing the gpio doesn't change the current value on the GPIO last write value -+ * persists till some one overwrites it -+*/ ++ /* clear this packet from the descriptor ring */ ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), ++ di->rxbufsize, DMA_RX, rxp); ++ W_SM(&di->rxd32[i].addr, 0xdeadbeef); + -+uint32 -+sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) -+{ -+ sb_info_t *si; ++ di->rxin = NEXTRXD(i); + -+ si = SB_INFO(sbh); ++ return (rxp); ++} + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++static void ++dma32_txrotate(di_t *di) ++{ ++ uint ad; ++ uint nactive; ++ uint rot; ++ uint old, new; ++ uint32 w; ++ uint first, last; + -+ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ -+ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { -+ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); -+ return -1; -+ } -+ /* make sure only one bit is set */ -+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { -+ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); -+ return -1; -+ } -+ -+ /* already released */ -+ if (!(sb_gpioreservation & gpio_bitmask)) -+ return -1; ++ ASSERT(dma_txsuspendedidle(di)); + -+ /* clear reservation */ -+ sb_gpioreservation &= ~gpio_bitmask; ++ nactive = dma_txactive(di); ++ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); ++ rot = TXD(ad - di->txin); + -+ return sb_gpioreservation; -+} ++ ASSERT(rot < di->ntxd); + -+/* return the current gpioin register value */ -+uint32 -+sb_gpioin(sb_t *sbh) -+{ -+ sb_info_t *si; -+ uint regoff; ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } + -+ si = SB_INFO(sbh); -+ regoff = 0; ++ first = di->txin; ++ last = PREVTXD(di->txout); + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpioin); -+ break; ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); + -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpioin); -+ break; ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = R_SM(&di->txd32[old].ctrl) & ~CTRL_EOT; ++ if (new == (di->ntxd - 1)) ++ w |= CTRL_EOT; ++ W_SM(&di->txd32[new].ctrl, w); ++ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); + -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpioin); -+ break; ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd32[old].addr, 0xdeadbeef); ++ ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ di->txp[old] = NULL; + } + -+ return (sb_corereg(si, si->gpioidx, regoff, 0, 0)); ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ /* kick the chip */ ++ W_REG(&di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); +} + -+/* mask&set gpio interrupt polarity bits */ -+uint32 -+sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) -+{ -+ sb_info_t *si; -+ uint regoff; ++/*** 64 bits DMA non-inline functions ***/ + -+ si = SB_INFO(sbh); -+ regoff = 0; ++#ifdef BCMDMA64 + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++static bool ++dma64_alloc(dma_info_t *di, uint direction) ++{ ++ uint size; ++ uint ddlen; ++ uint32 alignbytes; ++ void *va; + -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; -+ } ++ ddlen = sizeof (dma64dd_t); + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); -+ break; ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); + -+ case SB_PCI: -+ /* pci gpio implementation does not support interrupt polarity */ -+ ASSERT(0); -+ break; ++ alignbytes = di->dma64align; + -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpiointpolarity); -+ break; -+ } ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes)) ++ size += alignbytes; + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); -+} + -+/* mask&set gpio interrupt mask bits */ -+uint32 -+sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) -+{ -+ sb_info_t *si; -+ uint regoff; ++ if (direction == DMA_TX) { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); ++ return FALSE; ++ } + -+ si = SB_INFO(sbh); -+ regoff = 0; ++ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); ++ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va); ++ di->txdpa += di->txdalign; ++ di->txdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes)); ++ } else { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); ++ return FALSE; ++ } ++ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); ++ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va); ++ di->rxdpa += di->rxdalign; ++ di->rxdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes)); ++ } + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ return TRUE; ++} + -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; -+ } ++static void ++dma64_txreset(dma_info_t *di) ++{ ++ uint32 status; + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpiointmask); -+ break; ++ /* suspend tx DMA first */ ++ W_REG(&di->d64txregs->control, D64_XC_SE); ++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED && ++ status != D64_XS0_XS_IDLE && ++ status != D64_XS0_XS_STOPPED, ++ 10000); + -+ case SB_PCI: -+ /* pci gpio implementation does not support interrupt mask */ -+ ASSERT(0); -+ break; ++ W_REG(&di->d64txregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED, ++ 10000); + -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpiointmask); -+ break; ++ if (status != D64_XS0_XS_DISABLED) { ++ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); + } + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++ /* wait for the last transaction to complete */ ++ OSL_DELAY(300); +} + -+/* assign the gpio to an led */ -+uint32 -+sb_gpioled(sb_t *sbh, uint32 mask, uint32 val) ++static void ++dma64_rxreset(dma_info_t *di) +{ -+ sb_info_t *si; ++ uint32 status; + -+ si = SB_INFO(sbh); -+ if (si->sb.ccrev < 16) -+ return -1; ++ W_REG(&di->d64rxregs->control, 0); ++ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED, ++ 10000); + -+ /* gpio led powersave reg */ -+ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); ++ if (status != D64_RS0_RS_DISABLED) { ++ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); ++ } +} + -+/* mask&set gpio timer val */ -+uint32 -+sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval) ++static bool ++dma64_txsuspendedidle(dma_info_t *di) +{ -+ sb_info_t *si; -+ si = SB_INFO(sbh); + -+ if (si->sb.ccrev < 16) -+ return -1; ++ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE)) ++ return 0; ++ ++ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) ++ return 1; + -+ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); ++ return 0; +} + -+ -+/* return the slow clock source - LPO, XTAL, or PCI */ -+static uint -+sb_slowclk_src(sb_info_t *si) ++/* ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ */ ++static int ++dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) +{ -+ chipcregs_t *cc; ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint txout; ++ uint32 flags; ++ uint32 pa; + ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); + -+ ASSERT(sb_coreid(&si->sb) == SB_CC); ++ txout = di->txout; ++ flags = 0; + -+ if (si->sb.ccrev < 6) { -+ if ((BUSTYPE(si->sb.bustype) == PCI_BUS) -+ && (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)) & PCI_CFG_GPIO_SCS)) -+ return (SCC_SS_PCI); -+ else -+ return (SCC_SS_XTAL); -+ } else if (si->sb.ccrev < 10) { -+ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); -+ return (R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK); -+ } else /* Insta-clock */ -+ return (SCC_SS_XTAL); -+} ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++ next = PKTNEXT(di->osh, p); + -+/* return the ILP (slowclock) min or max frequency */ -+static uint -+sb_slowclk_freq(sb_info_t *si, bool max) -+{ -+ chipcregs_t *cc; -+ uint32 slowclk; -+ uint div; ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) ++ goto outoftxd; + ++ if (len == 0) ++ continue; + -+ ASSERT(sb_coreid(&si->sb) == SB_CC); ++ /* get physical address of buffer start */ ++ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); + -+ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ flags = coreflags; ++ ++ if (p == p0) ++ flags |= D64_CTRL1_SOF; ++ if (next == NULL) ++ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); ++ if (txout == (di->ntxd - 1)) ++ flags |= D64_CTRL1_EOT; + -+ /* shouldn't be here unless we've established the chip has dynamic clk control */ -+ ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL); ++ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); + -+ slowclk = sb_slowclk_src(si); -+ if (si->sb.ccrev < 6) { -+ if (slowclk == SCC_SS_PCI) -+ return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64)); -+ else -+ return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32)); -+ } else if (si->sb.ccrev < 10) { -+ div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); -+ if (slowclk == SCC_SS_LPO) -+ return (max? LPOMAXFREQ : LPOMINFREQ); -+ else if (slowclk == SCC_SS_XTAL) -+ return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); -+ else if (slowclk == SCC_SS_PCI) -+ return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); -+ else -+ ASSERT(0); -+ } else { -+ /* Chipc rev 10 is InstaClock */ -+ div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; -+ div = 4 * (div + 1); -+ return (max ? XTALMAXFREQ : (XTALMINFREQ/div)); ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); + } -+ return (0); -+} + -+static void -+sb_clkctl_setdelay(sb_info_t *si, void *chipcregs) -+{ -+ chipcregs_t * cc; -+ uint slowmaxfreq, pll_delay, slowclk; -+ uint pll_on_delay, fref_sel_delay; ++ /* if last txd eof not set, fix it */ ++ if (!(flags & D64_CTRL1_EOF)) ++ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); + -+ pll_delay = PLL_DELAY; ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; + -+ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay -+ * since the xtal will also be powered down by dynamic clk control logic. -+ */ -+ slowclk = sb_slowclk_src(si); -+ if (slowclk != SCC_SS_XTAL) -+ pll_delay += XTAL_ON_DELAY; ++ /* bump the tx descriptor index */ ++ di->txout = txout; + -+ /* Starting with 4318 it is ILP that is used for the delays */ -+ slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE); ++ /* kick the chip */ ++ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); + -+ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; -+ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+ cc = (chipcregs_t *)chipcregs; -+ W_REG(&cc->pll_on_delay, pll_on_delay); -+ W_REG(&cc->fref_sel_delay, fref_sel_delay); ++ return (0); ++ ++outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); +} + -+int -+sb_pwrctl_slowclk(void *sbh, bool set, uint *div) ++static void* ++dma64_getnexttxp(dma_info_t *di, bool forceall) +{ -+ sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; -+ uint intr_val = 0; -+ uint err = 0; -+ -+ si = SB_INFO(sbh); ++ uint start, end, i; ++ void *txp; + -+ /* chipcommon cores prior to rev6 don't support slowclkcontrol */ -+ if (si->sb.ccrev < 6) -+ return 1; ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); + -+ /* chipcommon cores rev10 are a whole new ball game */ -+ if (si->sb.ccrev >= 10) -+ return 1; ++ txp = NULL; + -+ if (set && ((*div % 4) || (*div < 4))) -+ return 2; -+ -+ INTR_OFF(si, intr_val); -+ origidx = si->curidx; -+ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); -+ ASSERT(cc != NULL); -+ -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) { -+ err = 3; -+ goto done; ++ start = di->txin; ++ if (forceall) ++ end = di->txout; ++ else ++ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ ++ if ((start == 0) && (end > di->txout)) ++ goto bogus; ++ ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow), ++ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]); ++ ++ W_SM(&di->txd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); ++ ++ txp = di->txp[i]; ++ di->txp[i] = NULL; + } + -+ if (set) { -+ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHIFT)); -+ sb_clkctl_setdelay(sbh, (void *)cc); -+ } else -+ *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ di->txin = i; ++ ++ /* tx flow control */ ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+done: -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return err; ++ return (txp); ++ ++bogus: ++/* ++ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++*/ ++ return (NULL); +} + -+/* initialize power control delay registers */ -+void sb_clkctl_init(sb_t *sbh) ++static void * ++dma64_getnextrxp(dma_info_t *di, bool forceall) +{ -+ sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; ++ uint i; ++ void *rxp; + -+ si = SB_INFO(sbh); ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma_rxenabled(di)); + -+ origidx = si->curidx; ++ i = di->rxin; + -+ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) -+ return; ++ /* return if no packets posted */ ++ if (i == di->rxout) ++ return (NULL); + -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) -+ goto done; ++ /* ignore curr if forceall */ ++ if (!forceall && (i == B2I(R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t))) ++ return (NULL); + -+ /* 4317pc does not work with SlowClock less than 5 MHz */ -+ if ((BUSTYPE(si->sb.bustype) == PCMCIA_BUS) && (si->sb.ccrev >= 6) && (si->sb.ccrev < 10)) -+ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (ILP_DIV_5MHZ << SCC_CD_SHIFT)); ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; + -+ /* set all Instaclk chip ILP to 1 MHz */ -+ else if (si->sb.ccrev >= 10) -+ SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); -+ -+ sb_clkctl_setdelay(si, (void *)cc); ++ /* clear this packet from the descriptor ring */ ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow), ++ di->rxbufsize, DMA_RX, rxp); + -+done: -+ sb_setcoreidx(sbh, origidx); -+} -+void sb_pwrctl_init(sb_t *sbh) -+{ -+sb_clkctl_init(sbh); ++ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); ++ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); ++ ++ di->rxin = NEXTRXD(i); ++ ++ return (rxp); +} -+/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ -+uint16 -+sb_clkctl_fast_pwrup_delay(sb_t *sbh) ++ ++static void ++dma64_txrotate(di_t *di) +{ -+ sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; -+ uint slowminfreq; -+ uint16 fpdelay; -+ uint intr_val = 0; ++ uint ad; ++ uint nactive; ++ uint rot; ++ uint old, new; ++ uint32 w; ++ uint first, last; + -+ si = SB_INFO(sbh); -+ fpdelay = 0; -+ origidx = si->curidx; ++ ASSERT(dma_txsuspendedidle(di)); + -+ INTR_OFF(si, intr_val); ++ nactive = dma_txactive(di); ++ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t); ++ rot = TXD(ad - di->txin); + -+ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) -+ goto done; ++ ASSERT(rot < di->ntxd); + -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) -+ goto done; ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } + -+ slowminfreq = sb_slowclk_freq(si, FALSE); -+ fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; ++ first = di->txin; ++ last = PREVTXD(di->txout); + -+done: -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return (fpdelay); -+} -+uint16 sb_pwrctl_fast_pwrup_delay(sb_t *sbh) -+{ -+return sb_clkctl_fast_pwrup_delay(sbh); -+} -+/* turn primary xtal and/or pll off/on */ -+int -+sb_clkctl_xtal(sb_t *sbh, uint what, bool on) -+{ -+ sb_info_t *si; -+ uint32 in, out, outen; ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); + -+ si = SB_INFO(sbh); ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = R_SM(&di->txd64[old].ctrl1) & ~D64_CTRL1_EOT; ++ if (new == (di->ntxd - 1)) ++ w |= D64_CTRL1_EOT; ++ W_SM(&di->txd64[new].ctrl1, w); + -+ switch (BUSTYPE(si->sb.bustype)) { ++ w = R_SM(&di->txd64[old].ctrl2); ++ W_SM(&di->txd64[new].ctrl2, w); + ++ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); ++ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); + -+ case PCMCIA_BUS: -+ return (0); ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd64[old].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[old].addrhigh, 0xdeadbeef); + ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ di->txp[old] = NULL; ++ } + -+ case PCI_BUS: ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+ /* pcie core doesn't have any mapping to control the xtal pu */ -+ if (PCIE(si)) -+ return -1; ++ /* kick the chip */ ++ W_REG(&di->d64txregs->ptr, I2B(di->txout, dma64dd_t)); ++} + -+ in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32)); -+ out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)); -+ outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32)); ++#endif + -+ /* -+ * Avoid glitching the clock if GPRS is already using it. -+ * We can't actually read the state of the PLLPD so we infer it -+ * by the value of XTAL_PU which *is* readable via gpioin. -+ */ -+ if (on && (in & PCI_CFG_GPIO_XTAL)) -+ return (0); +diff -Naur linux.old/drivers/net/wl2/hnddma.h linux.dev/drivers/net/wl2/hnddma.h +--- linux.old/drivers/net/wl2/hnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl2/hnddma.h 2006-04-06 16:32:44.000000000 +0200 +@@ -0,0 +1,71 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ + -+ if (what & XTAL) -+ outen |= PCI_CFG_GPIO_XTAL; -+ if (what & PLL) -+ outen |= PCI_CFG_GPIO_PLL; ++#ifndef _hnddma_h_ ++#define _hnddma_h_ + -+ if (on) { -+ /* turn primary xtal on */ -+ if (what & XTAL) { -+ out |= PCI_CFG_GPIO_XTAL; -+ if (what & PLL) -+ out |= PCI_CFG_GPIO_PLL; -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); -+ OSL_DELAY(XTAL_ON_DELAY); -+ } ++/* export structure */ ++typedef volatile struct { ++ /* rx error counters */ ++ uint rxgiants; /* rx giant frames */ ++ uint rxnobuf; /* rx out of dma descriptors */ ++ /* tx error counters */ ++ uint txnobuf; /* tx out of dma descriptors */ ++} hnddma_t; + -+ /* turn pll on */ -+ if (what & PLL) { -+ out &= ~PCI_CFG_GPIO_PLL; -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); -+ OSL_DELAY(2000); -+ } -+ } else { -+ if (what & XTAL) -+ out &= ~PCI_CFG_GPIO_XTAL; -+ if (what & PLL) -+ out |= PCI_CFG_GPIO_PLL; -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); -+ } ++#ifndef di_t ++#define di_t void ++#endif + -+ default: -+ return (-1); -+ } ++#ifndef osl_t ++#define osl_t void ++#endif + -+ return (0); -+} ++/* externs */ ++extern void * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level); ++extern void dma_detach(di_t *di); ++extern void dma_txreset(di_t *di); ++extern void dma_rxreset(di_t *di); ++extern void dma_txinit(di_t *di); ++extern bool dma_txenabled(di_t *di); ++extern void dma_rxinit(di_t *di); ++extern void dma_rxenable(di_t *di); ++extern bool dma_rxenabled(di_t *di); ++extern void dma_txsuspend(di_t *di); ++extern void dma_txresume(di_t *di); ++extern bool dma_txsuspended(di_t *di); ++extern bool dma_txsuspendedidle(di_t *di); ++extern bool dma_txstopped(di_t *di); ++extern bool dma_rxstopped(di_t *di); ++extern int dma_txfast(di_t *di, void *p, uint32 coreflags); ++extern void dma_fifoloopbackenable(di_t *di); ++extern void *dma_rx(di_t *di); ++extern void dma_rxfill(di_t *di); ++extern void dma_txreclaim(di_t *di, bool forceall); ++extern void dma_rxreclaim(di_t *di); ++extern uintptr dma_getvar(di_t *di, char *name); ++extern void *dma_getnexttxp(di_t *di, bool forceall); ++extern void *dma_peeknexttxp(di_t *di); ++extern void *dma_getnextrxp(di_t *di, bool forceall); ++extern void dma_txblock(di_t *di); ++extern void dma_txunblock(di_t *di); ++extern uint dma_txactive(di_t *di); ++extern void dma_txrotate(di_t *di); + -+int sb_pwrctl_xtal(sb_t *sbh, uint what, bool on) -+{ -+return sb_clkctl_xtal(sbh,what,on); -+} ++extern void dma_rxpiomode(dma32regs_t *); ++extern void dma_txpioloopback(dma32regs_t *); + -+/* set dynamic clk control mode (forceslow, forcefast, dynamic) */ -+/* returns true if ignore pll off is set and false if it is not */ -+bool -+sb_clkctl_clk(sb_t *sbh, uint mode) -+{ -+ sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; -+ uint32 scc; -+ bool forcefastclk=FALSE; -+ uint intr_val = 0; + -+ si = SB_INFO(sbh); ++#endif /* _hnddma_h_ */ +diff -Naur linux.old/drivers/net/wl2/pktq.h linux.dev/drivers/net/wl2/pktq.h +--- linux.old/drivers/net/wl2/pktq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl2/pktq.h 2006-04-06 17:33:02.000000000 +0200 +@@ -0,0 +1,83 @@ ++/* ++ * Misc useful os-independent macros and functions. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ + -+ /* chipcommon cores prior to rev6 don't support dynamic clock control */ -+ if (si->sb.ccrev < 6) -+ return (FALSE); ++#ifndef _pktq_h_ ++#define _pktq_h_ + -+ /* chipcommon cores rev10 are a whole new ball game */ -+ if (si->sb.ccrev >= 10) -+ return (FALSE); ++/*** driver-only section ***/ ++#ifdef BCMDRIVER + -+ INTR_OFF(si, intr_val); ++/* osl packet chain functions */ ++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); ++extern uint pkttotlen(osl_t *osh, void *); + -+ origidx = si->curidx; ++#define pktenq(pq, p) pktq_penq((pq), 0, (p)) /* legacy */ ++#define pktdeq(pq) pktq_pdeq((pq), 0) /* legacy */ + -+ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); -+ ASSERT(cc != NULL); ++/* osl multi-precedence packet queue */ + -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) -+ goto done; ++#define PKTQ_LEN_DEFAULT 128 ++#define PKTQ_MAX_PREC 8 ++struct pktq_prec { ++ void *head; /* first packet to dequeue */ ++ void *tail; /* last packet to dequeue */ ++ uint16 len; /* number of queued packets */ ++ uint16 max; /* maximum number of queued packets */ ++}; + -+ switch (mode) { -+ case CLK_FAST: /* force fast (pll) clock */ -+ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ -+ sb_clkctl_xtal(&si->sb, XTAL, ON); ++struct pktq { ++ struct pktq_prec q[PKTQ_MAX_PREC]; ++ uint16 num_prec; /* number of precedences in use */ ++ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ ++ uint16 max; /* total max packets */ ++ uint16 len; /* total number of packets */ ++}; + -+ SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); -+ break; ++/* operations on a specific precedence in packet queue */ + -+ case CLK_DYNAMIC: /* enable dynamic clock control */ -+ scc = R_REG(&cc->slow_clk_ctl); -+ scc &= ~(SCC_FS | SCC_IP | SCC_XC); -+ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) -+ scc |= SCC_XC; -+ W_REG(&cc->slow_clk_ctl, scc); ++#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) ++#define pktq_plen(pq, prec) ((pq)->q[prec].len) ++#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) ++#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) ++#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) + -+ /* for dynamic control, we have to release our xtal_pu "force on" */ -+ if (scc & SCC_XC) -+ sb_clkctl_xtal(&si->sb, XTAL, OFF); -+ break; ++#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) ++#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) + -+ default: -+ ASSERT(0); -+ } ++extern void *pktq_penq(struct pktq *pq, int prec, void *p); ++extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); ++extern void *pktq_pdeq(struct pktq *pq, int prec); ++extern void *pktq_pdeq_tail(struct pktq *pq, int prec); + -+ /* Is the h/w forcing the use of the fast clk */ -+ forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP); ++/* operations on packet queue as a whole */ + -+done: -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return (forcefastclk); -+} ++extern void pktq_init(struct pktq *pq, int num_prec, int max); + -+bool sb_pwrctl_clk(sb_t *sbh, uint mode) -+{ -+return sb_clkctl_clk(sbh, mode); -+} -+/* register driver interrupt disabling and restoring callback functions */ -+void -+sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) -+{ -+ sb_info_t *si; ++#define pktq_len(pq) ((int)(pq)->len) ++#define pktq_max(pq) ((int)(pq)->max) ++#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) ++#define pktq_full(pq) ((pq)->len >= (pq)->max) ++#define pktq_empty(pq) ((pq)->len == 0) + -+ si = SB_INFO(sbh); -+ si->intr_arg = intr_arg; -+ si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn; -+ si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn; -+ si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn; -+ /* save current core id. when this function called, the current core -+ * must be the core which provides driver functions(il, et, wl, etc.) -+ */ -+ si->dev_coreid = si->coreid[si->curidx]; -+} ++extern void *pktq_deq(struct pktq *pq, int *prec_out); ++extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); ++extern void *pktq_peek(struct pktq *pq, int *prec_out); ++extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); + ++extern int pktq_mlen(struct pktq *pq, uint prec_bmp); ++extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); + -+void -+sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, -+ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif) -+{ -+ uint vendor, core, unit; -+ uint chip, chippkg; -+ char varname[8]; -+ uint8 class, subclass, progif; -+ -+ vendor = sb_corevendor(sbh); -+ core = sb_coreid(sbh); -+ unit = sb_coreunit(sbh); ++#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) + -+ chip = BCMINIT(sb_chip)(sbh); -+ chippkg = BCMINIT(sb_chippkg)(sbh); ++#endif ++#endif /* _pktq_h_ */ +diff -Naur linux.old/drivers/net/wl2/sbhnddma.h linux.dev/drivers/net/wl2/sbhnddma.h +--- linux.old/drivers/net/wl2/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl2/sbhnddma.h 2006-04-06 16:32:44.000000000 +0200 +@@ -0,0 +1,312 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ ++ */ + -+ progif = 0; -+ -+ /* Known vendor translations */ -+ switch (vendor) { -+ case SB_VEND_BCM: -+ vendor = VENDOR_BROADCOM; -+ break; -+ } ++#ifndef _sbhnddma_h_ ++#define _sbhnddma_h_ + -+ /* Determine class based on known core codes */ -+ switch (core) { -+ case SB_ILINE20: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM47XX_ILINE_ID; -+ break; -+ case SB_ENET: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM47XX_ENET_ID; -+ break; -+ case SB_SDRAM: -+ case SB_MEMC: -+ class = PCI_CLASS_MEMORY; -+ subclass = PCI_MEMORY_RAM; -+ break; -+ case SB_PCI: -+ case SB_PCIE: -+ class = PCI_CLASS_BRIDGE; -+ subclass = PCI_BRIDGE_PCI; -+ break; -+ case SB_MIPS: -+ case SB_MIPS33: -+ class = PCI_CLASS_CPU; -+ subclass = PCI_CPU_MIPS; -+ break; -+ case SB_CODEC: -+ class = PCI_CLASS_COMM; -+ subclass = PCI_COMM_MODEM; -+ core = BCM47XX_V90_ID; -+ break; -+ case SB_USB: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ progif = 0x10; /* OHCI */ -+ core = BCM47XX_USB_ID; -+ break; -+ case SB_USB11H: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ progif = 0x10; /* OHCI */ -+ core = BCM47XX_USBH_ID; -+ break; -+ case SB_USB11D: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ core = BCM47XX_USBD_ID; -+ break; -+ case SB_IPSEC: -+ class = PCI_CLASS_CRYPT; -+ subclass = PCI_CRYPT_NETWORK; -+ core = BCM47XX_IPSEC_ID; -+ break; -+ case SB_ROBO: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_OTHER; -+ core = BCM47XX_ROBO_ID; -+ break; -+ case SB_EXTIF: -+ case SB_CC: -+ class = PCI_CLASS_MEMORY; -+ subclass = PCI_MEMORY_FLASH; -+ break; -+ case SB_D11: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_OTHER; -+ /* Let an nvram variable override this */ -+ sprintf(varname, "wl%did", unit); -+ if ((core = getintvar(NULL, varname)) == 0) { -+ if (chip == BCM4712_DEVICE_ID) { -+ if (chippkg == BCM4712SMALL_PKG_ID) -+ core = BCM4306_D11G_ID; -+ else -+ core = BCM4306_D11DUAL_ID; -+ } -+ } -+ break; ++ ++/* 2byte-wide pio register set per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint16 fifocontrol; ++ uint16 fifodata; ++ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */ ++ uint16 PAD; ++} pio2regs_t; + -+ default: -+ class = subclass = progif = 0xff; -+ break; -+ } ++/* a pair of pio channels(tx and rx) */ ++typedef volatile struct { ++ pio2regs_t tx; ++ pio2regs_t rx; ++} pio2regp_t; + -+ *pcivendor = (uint16)vendor; -+ *pcidevice = (uint16)core; -+ *pciclass = class; -+ *pcisubclass = subclass; -+ *pciprogif = progif; -+} ++/* 4byte-wide pio register set per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 fifocontrol; ++ uint32 fifodata; ++} pio4regs_t; + ++/* a pair of pio channels(tx and rx) */ ++typedef volatile struct { ++ pio4regs_t tx; ++ pio4regs_t rx; ++} pio4regp_t; + + + -+/* use the mdio interface to write to mdio slaves */ -+static int -+sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val) -+{ -+ uint mdiodata; -+ uint i = 0; -+ sbpcieregs_t *pcieregs; ++/* DMA structure: ++ * support two DMA engines: 32 bits address or 64 bit addressing ++ * basic DMA register set is per channel(transmit or receive) ++ * a pair of channels is defined for convenience ++ */ + -+ pcieregs = (sbpcieregs_t*) sb_setcoreidx(&si->sb, si->sb.buscoreidx); -+ ASSERT (pcieregs); + -+ /* enable mdio access to SERDES */ -+ W_REG((&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); ++/*** 32 bits addressing ***/ + -+ mdiodata = MDIODATA_START | MDIODATA_WRITE | -+ (physmedia << MDIODATA_DEVADDR_SHF) | -+ (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val; ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 addr; /* descriptor ring base address (4K aligned) */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 status; /* current active descriptor, et al */ ++} dma32regs_t; + -+ W_REG((&pcieregs->mdiodata), mdiodata); ++typedef volatile struct { ++ dma32regs_t xmt; /* dma tx channel */ ++ dma32regs_t rcv; /* dma rx channel */ ++} dma32regp_t; + -+ PR28829_DELAY(); ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma32diag_t; + -+ /* retry till the transaction is complete */ -+ while ( i < 10 ) { -+ if (R_REG(&(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { -+ /* Disable mdio access to SERDES */ -+ W_REG((&pcieregs->mdiocontrol), 0); -+ return 0; -+ } -+ OSL_DELAY(1000); -+ i++; -+ } ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl; /* misc control bits & bufcount */ ++ uint32 addr; /* data buffer address */ ++} dma32dd_t; + -+ SB_ERROR(("sb_pcie_mdiowrite: timed out\n")); -+ /* Disable mdio access to SERDES */ -+ W_REG((&pcieregs->mdiocontrol), 0); -+ ASSERT(0); -+ return 1; ++/* ++ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. ++ */ ++#define D32MAXRINGSZ 4096 ++#define D32RINGALIGN 4096 ++#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) + -+} ++/* transmit channel control */ ++#define XC_XE ((uint32)1 << 0) /* transmit enable */ ++#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ ++#define XC_LE ((uint32)1 << 2) /* loopback enable */ ++#define XC_FL ((uint32)1 << 4) /* flush request */ ++#define XC_AE ((uint32)3 << 16) /* address extension bits */ ++#define XC_AE_SHIFT 16 + -+/* indirect way to read pcie config regs*/ -+uint -+sb_pcie_readreg(void *sb, void* arg1, uint offset) -+{ -+ sb_info_t *si; -+ sb_t *sbh; -+ uint retval = 0xFFFFFFFF; -+ sbpcieregs_t *pcieregs; -+ uint addrtype; ++/* transmit descriptor table pointer */ ++#define XP_LD_MASK 0xfff /* last valid descriptor */ + -+ sbh = (sb_t *)sb; -+ si = SB_INFO(sbh); -+ ASSERT (PCIE(si)); ++/* transmit channel status */ ++#define XS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define XS_XS_MASK 0xf000 /* transmit state */ ++#define XS_XS_SHIFT 12 ++#define XS_XS_DISABLED 0x0000 /* disabled */ ++#define XS_XS_ACTIVE 0x1000 /* active */ ++#define XS_XS_IDLE 0x2000 /* idle wait */ ++#define XS_XS_STOPPED 0x3000 /* stopped */ ++#define XS_XS_SUSP 0x4000 /* suspend pending */ ++#define XS_XE_MASK 0xf0000 /* transmit errors */ ++#define XS_XE_SHIFT 16 ++#define XS_XE_NOERR 0x00000 /* no error */ ++#define XS_XE_DPE 0x10000 /* descriptor protocol error */ ++#define XS_XE_DFU 0x20000 /* data fifo underrun */ ++#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ ++#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ ++#define XS_AD_MASK 0xfff00000 /* active descriptor */ ++#define XS_AD_SHIFT 20 + -+ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); -+ ASSERT (pcieregs); ++/* receive channel control */ ++#define RC_RE ((uint32)1 << 0) /* receive enable */ ++#define RC_RO_MASK 0xfe /* receive frame offset */ ++#define RC_RO_SHIFT 1 ++#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ ++#define RC_AE ((uint32)3 << 16) /* address extension bits */ ++#define RC_AE_SHIFT 16 + -+ addrtype = (uint)((uintptr)arg1); -+ switch(addrtype) { -+ case PCIE_CONFIGREGS: -+ W_REG((&pcieregs->configaddr),offset); -+ retval = R_REG(&(pcieregs->configdata)); -+ break; -+ case PCIE_PCIEREGS: -+ W_REG(&(pcieregs->pcieaddr),offset); -+ retval = R_REG(&(pcieregs->pciedata)); -+ break; -+ default: -+ ASSERT(0); -+ break; -+ } -+ return retval; -+} ++/* receive descriptor table pointer */ ++#define RP_LD_MASK 0xfff /* last valid descriptor */ + -+/* indirect way to write pcie config/mdio/pciecore regs*/ -+uint -+sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val) -+{ -+ sb_info_t *si; -+ sbpcieregs_t *pcieregs; -+ uint addrtype; ++/* receive channel status */ ++#define RS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define RS_RS_MASK 0xf000 /* receive state */ ++#define RS_RS_SHIFT 12 ++#define RS_RS_DISABLED 0x0000 /* disabled */ ++#define RS_RS_ACTIVE 0x1000 /* active */ ++#define RS_RS_IDLE 0x2000 /* idle wait */ ++#define RS_RS_STOPPED 0x3000 /* reserved */ ++#define RS_RE_MASK 0xf0000 /* receive errors */ ++#define RS_RE_SHIFT 16 ++#define RS_RE_NOERR 0x00000 /* no error */ ++#define RS_RE_DPE 0x10000 /* descriptor protocol error */ ++#define RS_RE_DFO 0x20000 /* data fifo overflow */ ++#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ ++#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ ++#define RS_AD_MASK 0xfff00000 /* active descriptor */ ++#define RS_AD_SHIFT 20 + -+ si = SB_INFO(sbh); -+ ASSERT (PCIE(si)); ++/* fifoaddr */ ++#define FA_OFF_MASK 0xffff /* offset */ ++#define FA_SEL_MASK 0xf0000 /* select */ ++#define FA_SEL_SHIFT 16 ++#define FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define FA_SEL_RDD 0x40000 /* receive dma data */ ++#define FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ + -+ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); -+ ASSERT (pcieregs); ++/* descriptor control flags */ ++#define CTRL_BC_MASK 0x1fff /* buffer byte count */ ++#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ ++#define CTRL_AE_SHIFT 16 ++#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ ++#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ + -+ addrtype = (uint)((uintptr)arg1); ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define CTRL_CORE_MASK 0x0ff00000 + -+ switch(addrtype) { -+ case PCIE_CONFIGREGS: -+ W_REG((&pcieregs->configaddr),offset); -+ W_REG((&pcieregs->configdata),val); -+ break; -+ case PCIE_PCIEREGS: -+ W_REG((&pcieregs->pcieaddr),offset); -+ W_REG((&pcieregs->pciedata),val); -+ break; -+ default: -+ ASSERT(0); -+ break; -+ } -+ return 0; -+} ++/*** 64 bits addressing ***/ + ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ ++ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ ++ uint32 status0; /* current descriptor, xmt state */ ++ uint32 status1; /* active descriptor, xmt error */ ++} dma64regs_t; + -+/* Build device path. Support SB, PCI, and JTAG for now. */ -+int -+sb_devpath(sb_t *sbh, char *path, int size) -+{ -+ ASSERT(path); -+ ASSERT(size >= SB_DEVPATH_BUFSZ); -+ -+ switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) { -+ case SB_BUS: -+ case JTAG_BUS: -+ sprintf(path, "sb/%u/", sb_coreidx(sbh)); -+ break; -+ case PCI_BUS: -+ ASSERT((SB_INFO(sbh))->osh); -+ sprintf(path, "pci/%u/%u/", OSL_PCI_BUS((SB_INFO(sbh))->osh), -+ OSL_PCI_SLOT((SB_INFO(sbh))->osh)); -+ break; -+ case PCMCIA_BUS: -+ SB_ERROR(("sb_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n")); -+ SB_ERROR(("sb_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n")); -+ sprintf(path, "pc/%u/%u/", 1, 1); -+ break; -+ case SDIO_BUS: -+ SB_ERROR(("sb_devpath: device 0 assumed\n")); -+ sprintf(path, "sd/%u/", sb_coreidx(sbh)); -+ break; -+ default: -+ ASSERT(0); -+ break; -+ } ++typedef volatile struct { ++ dma64regs_t tx; /* dma64 tx channel */ ++ dma64regs_t rx; /* dma64 rx channel */ ++} dma64regp_t; + -+ return 0; -+} ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma64diag_t; + -+/* Fix chip's configuration. The current core may be changed upon return */ -+static int -+sb_pci_fixcfg(sb_info_t *si) -+{ -+ uint origidx, pciidx; -+ sbpciregs_t *pciregs; -+ sbpcieregs_t *pcieregs; -+ uint16 val16, *reg16; -+ char name[SB_DEVPATH_BUFSZ+16], *value; -+ char devpath[SB_DEVPATH_BUFSZ]; ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl1; /* misc control bits & bufcount */ ++ uint32 ctrl2; /* buffer count and address extension */ ++ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */ ++ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */ ++} dma64dd_t; + -+ ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS); ++/* ++ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. ++ */ ++#define D64MAXRINGSZ 8192 ++#define D64RINGALIGN 8192 ++#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) + -+ /* Fix PCI(e) SROM shadow area */ -+ /* save the current index */ -+ origidx = sb_coreidx(&si->sb); ++/* transmit channel control */ ++#define D64_XC_XE 0x00000001 /* transmit enable */ ++#define D64_XC_SE 0x00000002 /* transmit suspend request */ ++#define D64_XC_LE 0x00000004 /* loopback enable */ ++#define D64_XC_FL 0x00000010 /* flush request */ ++#define D64_XC_AE 0x00110000 /* address extension bits */ ++#define D64_XC_AE_SHIFT 16 + -+ /* check 'pi' is correct and fix it if not */ -+ if (si->sb.buscoretype == SB_PCIE) { -+ pcieregs = (sbpcieregs_t *)sb_setcore(&si->sb, SB_PCIE, 0); -+ ASSERT(pcieregs); -+ reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; -+ } -+ else if (si->sb.buscoretype == SB_PCI) { -+ pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0); -+ ASSERT(pciregs); -+ reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; -+ } -+ else { -+ ASSERT(0); -+ return -1; -+ } -+ pciidx = sb_coreidx(&si->sb); -+ val16 = R_REG(reg16); -+ if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) { -+ val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK); -+ W_REG(reg16, val16); -+ } ++/* transmit descriptor table pointer */ ++#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ + -+ /* restore the original index */ -+ sb_setcoreidx(&si->sb, origidx); -+ -+ /* Fix bar0window */ -+ /* !do it last, it changes the current core! */ -+ if (sb_devpath(&si->sb, devpath, sizeof(devpath))) -+ return -1; -+ sprintf(name, "%sb0w", devpath); -+ if ((value = getvar(NULL, name))) { -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32), -+ bcm_strtoul(value, NULL, 16)); -+ /* update curidx since the current core is changed */ -+ si->curidx = _sb_coreidx(si); -+ if (si->curidx == BADIDX) { -+ SB_ERROR(("sb_pci_fixcfg: bad core index\n")); -+ return -1; -+ } -+ } ++/* transmit channel status */ ++#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ ++#define D64_XS0_XS_SHIFT 28 ++#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ ++#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ ++#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ ++#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ ++#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ + -+ return 0; -+} ++#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ ++#define D64_XS1_XE_SHIFT 28 ++#define D64_XS1_XE_NOERR 0x00000000 /* no error */ ++#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ ++#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ ++#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ ++#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_XS1_XE_COREE 0x50000000 /* core error */ + -diff -Nur linux-2.4.32/drivers/net/hnd/shared_ksyms.sh linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh ---- linux-2.4.32/drivers/net/hnd/shared_ksyms.sh 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/hnd/shared_ksyms.sh 2005-12-16 23:39:11.316860000 +0100 -@@ -0,0 +1,21 @@ -+#!/bin/sh -+# -+# Copyright 2004, Broadcom Corporation -+# All Rights Reserved. -+# -+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+# -+# $Id: shared_ksyms.sh,v 1.1 2005/03/16 13:50:00 wbx Exp $ -+# ++/* receive channel control */ ++#define D64_RC_RE 0x00000001 /* receive enable */ ++#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ ++#define D64_RC_RO_SHIFT 1 ++#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ ++#define D64_RC_AE 0x00110000 /* address extension bits */ ++#define D64_RC_AE_SHIFT 16 + -+cat < -+#include -+EOF ++/* receive descriptor table pointer */ ++#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ + -+for file in $* ; do -+ ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p' -+done -diff -Nur linux-2.4.32/drivers/net/Makefile linux-2.4.32-brcm/drivers/net/Makefile ---- linux-2.4.32/drivers/net/Makefile 2005-01-19 15:09:56.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/Makefile 2005-12-16 23:39:11.284858000 +0100 -@@ -3,6 +3,8 @@ - # Makefile for the Linux network (ethercard) device drivers. - # - -+EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include ++/* receive channel status */ ++#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ ++#define D64_RS0_RS_SHIFT 28 ++#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ ++#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ ++#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ ++#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ ++#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ + - obj-y := - obj-m := - obj-n := -@@ -39,6 +41,8 @@ - obj-$(CONFIG_ISDN) += slhc.o - endif - -+subdir-$(CONFIG_HND) += hnd -+subdir-$(CONFIG_WL) += wl - subdir-$(CONFIG_NET_PCMCIA) += pcmcia - subdir-$(CONFIG_NET_WIRELESS) += wireless - subdir-$(CONFIG_TULIP) += tulip -@@ -69,6 +74,13 @@ - obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o - obj-$(CONFIG_SUNGEM) += sungem.o - -+ifeq ($(CONFIG_HND),y) -+ obj-y += hnd/hnd.o -+endif -+ifeq ($(CONFIG_WL),y) -+ obj-y += wl/wl.o -+endif ++#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ ++#define D64_RS1_RE_SHIFT 28 ++#define D64_RS1_RE_NOERR 0x00000000 /* no error */ ++#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ ++#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ ++#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ ++#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_RS1_RE_COREE 0x50000000 /* core error */ + - obj-$(CONFIG_MACE) += mace.o - obj-$(CONFIG_BMAC) += bmac.o - obj-$(CONFIG_GMAC) += gmac.o -diff -Nur linux-2.4.32/drivers/net/wireless/Config.in linux-2.4.32-brcm/drivers/net/wireless/Config.in ---- linux-2.4.32/drivers/net/wireless/Config.in 2004-11-17 12:54:21.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/wireless/Config.in 2005-12-16 23:39:11.364863000 +0100 -@@ -13,6 +13,7 @@ - fi - - if [ "$CONFIG_PCI" = "y" ]; then -+ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL - dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL - dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL - dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL -diff -Nur linux-2.4.32/drivers/net/wl/Makefile linux-2.4.32-brcm/drivers/net/wl/Makefile ---- linux-2.4.32/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/net/wl/Makefile 2005-12-16 23:39:11.364863000 +0100 -@@ -0,0 +1,26 @@ -+# -+# Makefile for the Broadcom wl driver -+# -+# Copyright 2004, Broadcom Corporation -+# All Rights Reserved. -+# -+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+# -+# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ ++/* fifoaddr */ ++#define D64_FA_OFF_MASK 0xffff /* offset */ ++#define D64_FA_SEL_MASK 0xf0000 /* select */ ++#define D64_FA_SEL_SHIFT 16 ++#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ ++#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ + -+EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include ++/* descriptor control flags 1 */ ++#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ ++#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ + -+O_TARGET := wl.o ++/* descriptor control flags 2 */ ++#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ ++#define D64_CTRL2_AE 0x00110000 /* address extension bits */ ++#define D64_CTRL2_AE_SHIFT 16 + -+obj-y := apsta_aeskeywrap.o apsta_aes.o apsta_bcmwpa.o apsta_d11ucode.o -+obj-y += apsta_hmac.o apsta_md5.o apsta_passhash.o apsta_prf.o apsta_rc4.o -+obj-y += apsta_rijndael-alg-fst.o apsta_sha1.o apsta_tkhash.o apsta_wlc_led.o -+obj-y += apsta_wlc_phy.o apsta_wlc_rate.o apsta_wlc_security.o -+obj-y += apsta_wlc_sup.o apsta_wlc_wet.o apsta_wl_linux.o apsta_wlc.o ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define D64_CTRL_CORE_MASK 0x0ff00000 + -+obj-m := $(O_TARGET) + -+include $(TOPDIR)/Rules.make -diff -Nur linux-2.4.32/drivers/parport/Config.in linux-2.4.32-brcm/drivers/parport/Config.in ---- linux-2.4.32/drivers/parport/Config.in 2004-02-18 14:36:31.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/parport/Config.in 2005-12-16 23:39:11.364863000 +0100 ++#endif /* _sbhnddma_h_ */ +diff -Naur linux.old/drivers/parport/Config.in linux.dev/drivers/parport/Config.in +--- linux.old/drivers/parport/Config.in 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/drivers/parport/Config.in 2006-04-06 15:34:15.000000000 +0200 @@ -11,6 +11,7 @@ tristate 'Parallel port support' CONFIG_PARPORT if [ "$CONFIG_PARPORT" != "n" ]; then @@ -17863,9 +20224,9 @@ diff -Nur linux-2.4.32/drivers/parport/Config.in linux-2.4.32-brcm/drivers/parpo if [ "$CONFIG_PARPORT_PC" != "n" -a "$CONFIG_SERIAL" != "n" ]; then if [ "$CONFIG_SERIAL" = "m" ]; then define_tristate CONFIG_PARPORT_PC_CML1 m -diff -Nur linux-2.4.32/drivers/parport/Makefile linux-2.4.32-brcm/drivers/parport/Makefile ---- linux-2.4.32/drivers/parport/Makefile 2004-08-08 01:26:05.000000000 +0200 -+++ linux-2.4.32-brcm/drivers/parport/Makefile 2005-12-16 23:39:11.364863000 +0100 +diff -Naur linux.old/drivers/parport/Makefile linux.dev/drivers/parport/Makefile +--- linux.old/drivers/parport/Makefile 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/drivers/parport/Makefile 2006-04-06 15:34:15.000000000 +0200 @@ -22,6 +22,7 @@ obj-$(CONFIG_PARPORT) += parport.o @@ -17874,9 +20235,9 @@ diff -Nur linux-2.4.32/drivers/parport/Makefile linux-2.4.32-brcm/drivers/parpor obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o -diff -Nur linux-2.4.32/drivers/parport/parport_splink.c linux-2.4.32-brcm/drivers/parport/parport_splink.c ---- linux-2.4.32/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/parport/parport_splink.c 2005-12-16 23:39:11.364863000 +0100 +diff -Naur linux.old/drivers/parport/parport_splink.c linux.dev/drivers/parport/parport_splink.c +--- linux.old/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/parport/parport_splink.c 2006-04-06 15:34:15.000000000 +0200 @@ -0,0 +1,345 @@ +/* Low-level parallel port routines for the ASUS WL-500g built-in port + * @@ -18223,9 +20584,32 @@ diff -Nur linux-2.4.32/drivers/parport/parport_splink.c linux-2.4.32-brcm/driver +module_init(parport_splink_init) +module_exit(parport_splink_cleanup) + -diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_generic.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c ---- linux-2.4.32/drivers/pcmcia/bcm4710_generic.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_generic.c 2005-12-16 23:39:11.368863250 +0100 +diff -Naur linux.old/drivers/pcmcia/Makefile linux.dev/drivers/pcmcia/Makefile +--- linux.old/drivers/pcmcia/Makefile 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/drivers/pcmcia/Makefile 2006-04-06 15:34:15.000000000 +0200 +@@ -74,6 +74,10 @@ + au1000_ss-objs-$(CONFIG_MIPS_HYDROGEN3) += au1000_hydrogen3.o + au1000_ss-objs-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o + ++obj-$(CONFIG_PCMCIA_BCM4710) += bcm4710_ss.o ++bcm4710_ss-objs := bcm4710_generic.o ++bcm4710_ss-objs += bcm4710_pcmcia.o ++ + obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o + obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o + obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o +@@ -112,5 +116,8 @@ + au1x00_ss.o: $(au1000_ss-objs-y) + $(LD) -r -o $@ $(au1000_ss-objs-y) + ++bcm4710_ss.o: $(bcm4710_ss-objs) ++ $(LD) -r -o $@ $(bcm4710_ss-objs) ++ + yenta_socket.o: $(yenta_socket-objs) + $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs) +diff -Naur linux.old/drivers/pcmcia/bcm4710_generic.c linux.dev/drivers/pcmcia/bcm4710_generic.c +--- linux.old/drivers/pcmcia/bcm4710_generic.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/pcmcia/bcm4710_generic.c 2006-04-06 15:34:15.000000000 +0200 @@ -0,0 +1,912 @@ +/* + * @@ -19139,9 +21523,9 @@ diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_generic.c linux-2.4.32-brcm/driver + + +#endif /* defined(CONFIG_PROC_FS) */ -diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c ---- linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710_pcmcia.c 2005-12-16 23:39:11.368863250 +0100 +diff -Naur linux.old/drivers/pcmcia/bcm4710_pcmcia.c linux.dev/drivers/pcmcia/bcm4710_pcmcia.c +--- linux.old/drivers/pcmcia/bcm4710_pcmcia.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/pcmcia/bcm4710_pcmcia.c 2006-04-06 15:34:15.000000000 +0200 @@ -0,0 +1,266 @@ +/* + * BCM4710 specific pcmcia routines. @@ -19409,9 +21793,9 @@ diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710_pcmcia.c linux-2.4.32-brcm/drivers + bcm4710_pcmcia_configure_socket +}; + -diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h ---- linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/pcmcia/bcm4710pcmcia.h 2005-12-16 23:39:11.368863250 +0100 +diff -Naur linux.old/drivers/pcmcia/bcm4710pcmcia.h linux.dev/drivers/pcmcia/bcm4710pcmcia.h +--- linux.old/drivers/pcmcia/bcm4710pcmcia.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/pcmcia/bcm4710pcmcia.h 2006-04-06 15:34:15.000000000 +0200 @@ -0,0 +1,118 @@ +/* + * @@ -19531,32 +21915,9 @@ diff -Nur linux-2.4.32/drivers/pcmcia/bcm4710pcmcia.h linux-2.4.32-brcm/drivers/ +extern struct pcmcia_low_level bcm4710_pcmcia_ops; + +#endif /* !defined(_BCM4710PCMCIA_H) */ -diff -Nur linux-2.4.32/drivers/pcmcia/Makefile linux-2.4.32-brcm/drivers/pcmcia/Makefile ---- linux-2.4.32/drivers/pcmcia/Makefile 2004-02-18 14:36:31.000000000 +0100 -+++ linux-2.4.32-brcm/drivers/pcmcia/Makefile 2005-12-16 23:39:11.364863000 +0100 -@@ -65,6 +65,10 @@ - au1000_ss-objs-$(CONFIG_PCMCIA_DB1X00) += au1000_db1x00.o - au1000_ss-objs-$(CONFIG_PCMCIA_XXS1500) += au1000_xxs1500.o - -+obj-$(CONFIG_PCMCIA_BCM4710) += bcm4710_ss.o -+bcm4710_ss-objs := bcm4710_generic.o -+bcm4710_ss-objs += bcm4710_pcmcia.o -+ - obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o - obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o - obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o -@@ -102,5 +106,8 @@ - au1x00_ss.o: $(au1000_ss-objs-y) - $(LD) -r -o $@ $(au1000_ss-objs-y) - -+bcm4710_ss.o: $(bcm4710_ss-objs) -+ $(LD) -r -o $@ $(bcm4710_ss-objs) -+ - yenta_socket.o: $(yenta_socket-objs) - $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs) -diff -Nur linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32-brcm/include/asm-mips/bootinfo.h ---- linux-2.4.32/include/asm-mips/bootinfo.h 2004-02-18 14:36:32.000000000 +0100 -+++ linux-2.4.32-brcm/include/asm-mips/bootinfo.h 2005-12-16 23:39:11.400865250 +0100 +diff -Naur linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h +--- linux.old/include/asm-mips/bootinfo.h 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/include/asm-mips/bootinfo.h 2006-04-06 15:34:15.000000000 +0200 @@ -37,6 +37,7 @@ #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ #define MACH_GROUP_LASAT 21 @@ -19565,7 +21926,7 @@ diff -Nur linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32-brcm/include/asm /* * Valid machtype values for group unknown (low order halfword of mips_machtype) -@@ -194,6 +195,15 @@ +@@ -197,6 +198,15 @@ #define MACH_TANBAC_TB0229 7 /* TANBAC TB0229 (VR4131DIMM) */ /* @@ -19581,9 +21942,9 @@ diff -Nur linux-2.4.32/include/asm-mips/bootinfo.h linux-2.4.32-brcm/include/asm * Valid machtype for group TITAN */ #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ -diff -Nur linux-2.4.32/include/asm-mips/cpu.h linux-2.4.32-brcm/include/asm-mips/cpu.h ---- linux-2.4.32/include/asm-mips/cpu.h 2005-01-19 15:10:11.000000000 +0100 -+++ linux-2.4.32-brcm/include/asm-mips/cpu.h 2005-12-16 23:39:11.412866000 +0100 +diff -Naur linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h +--- linux.old/include/asm-mips/cpu.h 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/include/asm-mips/cpu.h 2006-04-06 15:34:15.000000000 +0200 @@ -22,6 +22,11 @@ spec. */ @@ -19632,10 +21993,10 @@ diff -Nur linux-2.4.32/include/asm-mips/cpu.h linux-2.4.32-brcm/include/asm-mips /* * ISA Level encodings -diff -Nur linux-2.4.32/include/asm-mips/r4kcache.h linux-2.4.32-brcm/include/asm-mips/r4kcache.h ---- linux-2.4.32/include/asm-mips/r4kcache.h 2004-02-18 14:36:32.000000000 +0100 -+++ linux-2.4.32-brcm/include/asm-mips/r4kcache.h 2005-12-16 23:39:11.416866250 +0100 -@@ -567,4 +567,17 @@ +diff -Naur linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h +--- linux.old/include/asm-mips/r4kcache.h 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/include/asm-mips/r4kcache.h 2006-04-06 15:34:15.000000000 +0200 +@@ -658,4 +658,17 @@ cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } @@ -19653,9 +22014,9 @@ diff -Nur linux-2.4.32/include/asm-mips/r4kcache.h linux-2.4.32-brcm/include/asm +} + #endif /* __ASM_R4KCACHE_H */ -diff -Nur linux-2.4.32/include/asm-mips/serial.h linux-2.4.32-brcm/include/asm-mips/serial.h ---- linux-2.4.32/include/asm-mips/serial.h 2005-01-19 15:10:12.000000000 +0100 -+++ linux-2.4.32-brcm/include/asm-mips/serial.h 2005-12-16 23:39:11.428867000 +0100 +diff -Naur linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial.h +--- linux.old/include/asm-mips/serial.h 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/include/asm-mips/serial.h 2006-04-06 15:34:15.000000000 +0200 @@ -223,6 +223,13 @@ #define TXX927_SERIAL_PORT_DEFNS #endif @@ -19678,10 +22039,10 @@ diff -Nur linux-2.4.32/include/asm-mips/serial.h linux-2.4.32-brcm/include/asm-m COBALT_SERIAL_PORT_DEFNS \ DDB5477_SERIAL_PORT_DEFNS \ EV96100_SERIAL_PORT_DEFNS \ -diff -Nur linux-2.4.32/init/do_mounts.c linux-2.4.32-brcm/init/do_mounts.c ---- linux-2.4.32/init/do_mounts.c 2003-11-28 19:26:21.000000000 +0100 -+++ linux-2.4.32-brcm/init/do_mounts.c 2005-12-16 23:39:11.504871750 +0100 -@@ -253,7 +253,13 @@ +diff -Naur linux.old/init/do_mounts.c linux.dev/init/do_mounts.c +--- linux.old/init/do_mounts.c 2006-04-06 15:38:09.000000000 +0200 ++++ linux.dev/init/do_mounts.c 2006-04-06 15:34:15.000000000 +0200 +@@ -254,7 +254,13 @@ { "ftlb", 0x2c08 }, { "ftlc", 0x2c10 }, { "ftld", 0x2c18 }, -- cgit v1.2.3 From be8ad0190d689eb7f797bdc0618d7e87892a831d Mon Sep 17 00:00:00 2001 From: nbd Date: Tue, 30 May 2006 19:38:38 +0000 Subject: resync with kamikaze git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@3844 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/base-files/default/etc/functions.sh | 4 + package/base-files/default/etc/init.d/S10boot | 3 +- package/iptables/files/firewall.awk | 1 + target/Config.in | 9 + target/linux/Config.in | 12 +- target/linux/Makefile | 2 + target/linux/aruba-2.6/Makefile | 4 +- target/linux/aruba-2.6/patches/000-aruba.patch | 42 +- target/linux/aruba-2.6/patches/004-wdt.patch | 126 + target/linux/au1000-2.6/Makefile | 11 +- target/linux/au1000-2.6/config | 811 +- .../au1000-2.6/patches/002-mtx1_flash_map.patch | 16 + target/linux/au1000-2.6/patches/003-zImage.patch | 1364 + .../au1000-2.6/patches/004-mtx1_watchdog.patch | 279 + .../patches/005-au1000_eth_link_beat.patch | 24 + .../patches/006-mtx1_system_button.patch | 241 + .../linux/au1000-2.6/patches/007-mtx1_sio2.patch | 13 + .../au1000-2.6/patches/008-isdel_cardbus.patch | 63 + target/linux/au1000-2.6/patches/009-boot.patch | 15 + target/linux/brcm-2.4/Config.in | 10 - target/linux/brcm-2.4/Makefile | 17 +- target/linux/brcm-2.4/config | 1 - target/linux/brcm-2.4/patches/001-bcm47xx.patch | 34791 +++++++++---------- .../brcm-2.4/patches/009-wrt54g3g_pcmcia.patch | 119 + target/linux/brcm-2.6/Makefile | 4 +- target/linux/control/kernel.control | 2 - target/linux/control/kmod-arptables.control | 2 - target/linux/control/kmod-atm.control | 2 - target/linux/control/kmod-ax25.control | 2 - target/linux/control/kmod-bluetooth.control | 2 - target/linux/control/kmod-brcm-et.control | 2 - target/linux/control/kmod-brcm-wl.control | 2 - target/linux/control/kmod-brcm-wl2.control | 2 - target/linux/control/kmod-cpmac.control | 2 - target/linux/control/kmod-crypto.control | 2 - target/linux/control/kmod-ebtables.control | 2 - target/linux/control/kmod-gre.control | 2 - target/linux/control/kmod-ide.control | 2 - target/linux/control/kmod-ip6tables.control | 2 - target/linux/control/kmod-ipip.control | 4 + target/linux/control/kmod-iptables-extra.control | 2 - target/linux/control/kmod-iptables.control | 2 - target/linux/control/kmod-ipv6.control | 2 - target/linux/control/kmod-loop.control | 2 - target/linux/control/kmod-lp.control | 2 - target/linux/control/kmod-mppe.control | 2 - target/linux/control/kmod-nbd.control | 2 - target/linux/control/kmod-nls-base.control | 2 - target/linux/control/kmod-nls-cp437.control | 2 - target/linux/control/kmod-nls-cp850.control | 2 - target/linux/control/kmod-nls-iso8859-1.control | 2 - target/linux/control/kmod-nls-iso8859-15.control | 2 - target/linux/control/kmod-nls-utf8.control | 2 - target/linux/control/kmod-ppp.control | 2 - target/linux/control/kmod-pppoatm.control | 2 - target/linux/control/kmod-pppoe.control | 2 - target/linux/control/kmod-pwc.control | 2 - .../linux/control/kmod-sangam-atm-annex-a.control | 2 - .../linux/control/kmod-sangam-atm-annex-b.control | 2 - target/linux/control/kmod-sched.control | 2 - target/linux/control/kmod-softdog.control | 2 - target/linux/control/kmod-soundcore.control | 2 - target/linux/control/kmod-tun.control | 2 - target/linux/control/kmod-usb-acm.control | 2 - .../linux/control/kmod-usb-atm-speedtouch.control | 2 - target/linux/control/kmod-usb-audio.control | 2 - target/linux/control/kmod-usb-core.control | 2 - target/linux/control/kmod-usb-ohci.control | 2 - target/linux/control/kmod-usb-printer.control | 2 - .../linux/control/kmod-usb-serial-belkin.control | 2 - target/linux/control/kmod-usb-serial-ftdi.control | 2 - .../linux/control/kmod-usb-serial-mct-u232.control | 2 - .../linux/control/kmod-usb-serial-pl2303.control | 2 - target/linux/control/kmod-usb-serial-visor.control | 5 +- target/linux/control/kmod-usb-serial.control | 2 - target/linux/control/kmod-usb-storage.control | 2 - target/linux/control/kmod-usb-uhci.control | 2 - target/linux/control/kmod-usb2.control | 2 - target/linux/control/kmod-videodev.control | 2 - target/linux/control/kmod-wd1100.control | 2 - target/linux/generic-2.4/modules.mk | 10 +- target/linux/generic-2.6/modules.mk | 6 +- .../linux/generic-2.6/patches/005-gcc4_fix.patch | 14 +- target/linux/image/au1000/Makefile | 58 +- target/linux/image/jffs2.mk | 2 +- target/linux/image/squashfs.mk | 6 +- target/linux/image/xscale/Makefile | 36 + target/linux/kernel.mk | 6 +- target/linux/package/Makefile | 3 - .../base-files/files/au1000-2.6/sbin/mount_root | 23 + .../files/brcm-2.4/etc/hotplug.d/net/09-net | 6 +- .../base-files/files/sibyte-2.6/etc/config/network | 12 + .../base-files/files/sibyte-2.6/etc/inittab | 3 + .../linux/package/base-files/files/sibyte-2.6/init | 6 + .../base-files/files/xscale-2.6/etc/config/network | 5 + .../files/xscale-2.6/etc/init.d/S00xscale | 4 + .../linux/package/base-files/files/xscale-2.6/init | 3 + target/linux/package/bcm43xx-standalone/Config.in | 12 - target/linux/package/bcm43xx-standalone/Makefile | 57 - .../package/bcm43xx-standalone/fwcutter/Makefile | 32 - .../package/bcm43xx-standalone/fwcutter/fwcutter.c | 562 - .../bcm43xx-standalone/fwcutter/fwcutter_list.h | 810 - .../package/bcm43xx-standalone/fwcutter/md5.c | 253 - .../package/bcm43xx-standalone/fwcutter/md5.h | 16 - .../ipkg/kmod-bcm43xx-standalone.control | 4 - target/linux/package/ieee80211-dscape/Config.in | 10 - target/linux/package/ieee80211-dscape/Makefile | 46 - .../ipkg/kmod-ieee80211-dscape.control | 4 - target/linux/package/ieee80211-dscape/src/Kconfig | 32 - target/linux/package/ieee80211-dscape/src/Makefile | 23 - target/linux/package/ieee80211-dscape/src/aes.c | 564 - .../linux/package/ieee80211-dscape/src/aes_ccm.c | 119 - .../linux/package/ieee80211-dscape/src/aes_ccm.h | 22 - .../package/ieee80211-dscape/src/fifo_qdisc.c | 103 - .../package/ieee80211-dscape/src/hostapd_ioctl.h | 438 - .../linux/package/ieee80211-dscape/src/ieee80211.c | 4895 --- .../package/ieee80211-dscape/src/ieee80211_i.h | 571 - .../package/ieee80211-dscape/src/ieee80211_ioctl.c | 2832 -- .../package/ieee80211-dscape/src/ieee80211_key.h | 80 - .../package/ieee80211-dscape/src/ieee80211_led.c | 32 - .../package/ieee80211-dscape/src/ieee80211_proc.c | 777 - .../package/ieee80211-dscape/src/ieee80211_proc.h | 41 - .../package/ieee80211-dscape/src/ieee80211_scan.c | 352 - .../package/ieee80211-dscape/src/ieee80211_sta.c | 2868 -- .../ieee80211-dscape/src/include/net/ieee80211.h | 872 - .../src/include/net/ieee80211_common.h | 96 - .../src/include/net/ieee80211_mgmt.h | 196 - .../src/include/net/ieee80211_shared.h | 50 - .../linux/package/ieee80211-dscape/src/michael.c | 104 - .../linux/package/ieee80211-dscape/src/michael.h | 18 - .../package/ieee80211-dscape/src/rate_control.c | 381 - .../package/ieee80211-dscape/src/rate_control.h | 128 - .../linux/package/ieee80211-dscape/src/sta_info.c | 417 - .../linux/package/ieee80211-dscape/src/sta_info.h | 142 - target/linux/package/ieee80211-dscape/src/tkip.c | 341 - target/linux/package/ieee80211-dscape/src/tkip.h | 26 - target/linux/package/ieee80211-dscape/src/wep.c | 423 - target/linux/package/ieee80211-dscape/src/wep.h | 34 - target/linux/package/ieee80211-dscape/src/wme.c | 700 - target/linux/package/ieee80211-dscape/src/wme.h | 53 - target/linux/package/ieee80211-dscape/src/wpa.c | 825 - target/linux/package/ieee80211-dscape/src/wpa.h | 30 - target/linux/package/madwifi/Config.in | 2 +- target/linux/package/madwifi/Makefile | 7 +- .../madwifi/patches/100-kernel_cflags.patch | 11 + target/linux/package/wlcompat/Config.in | 4 +- target/linux/package/wlcompat/wlcompat.c | 4 +- target/linux/rules.mk | 6 + target/linux/sibyte-2.6/Makefile | 19 + target/linux/sibyte-2.6/config | 1311 + target/linux/sibyte-2.6/patches/000-DUART.patch | 956 + .../linux/sibyte-2.6/patches/001-bcm112x_ax.patch | 17 + target/linux/x86-2.6/Makefile | 4 +- target/linux/xscale-2.6/Makefile | 18 + target/linux/xscale-2.6/config | 1363 + .../xscale-2.6/patches/001-gateway_7001.patch | 159 + 156 files changed, 23066 insertions(+), 39506 deletions(-) create mode 100644 target/linux/aruba-2.6/patches/004-wdt.patch create mode 100644 target/linux/au1000-2.6/patches/002-mtx1_flash_map.patch create mode 100644 target/linux/au1000-2.6/patches/003-zImage.patch create mode 100644 target/linux/au1000-2.6/patches/004-mtx1_watchdog.patch create mode 100644 target/linux/au1000-2.6/patches/005-au1000_eth_link_beat.patch create mode 100644 target/linux/au1000-2.6/patches/006-mtx1_system_button.patch create mode 100644 target/linux/au1000-2.6/patches/007-mtx1_sio2.patch create mode 100644 target/linux/au1000-2.6/patches/008-isdel_cardbus.patch create mode 100644 target/linux/au1000-2.6/patches/009-boot.patch create mode 100644 target/linux/brcm-2.4/patches/009-wrt54g3g_pcmcia.patch create mode 100644 target/linux/control/kmod-ipip.control create mode 100644 target/linux/image/xscale/Makefile create mode 100755 target/linux/package/base-files/files/au1000-2.6/sbin/mount_root create mode 100644 target/linux/package/base-files/files/sibyte-2.6/etc/config/network create mode 100644 target/linux/package/base-files/files/sibyte-2.6/etc/inittab create mode 100755 target/linux/package/base-files/files/sibyte-2.6/init create mode 100644 target/linux/package/base-files/files/xscale-2.6/etc/config/network create mode 100755 target/linux/package/base-files/files/xscale-2.6/etc/init.d/S00xscale create mode 100755 target/linux/package/base-files/files/xscale-2.6/init delete mode 100644 target/linux/package/bcm43xx-standalone/Config.in delete mode 100644 target/linux/package/bcm43xx-standalone/Makefile delete mode 100644 target/linux/package/bcm43xx-standalone/fwcutter/Makefile delete mode 100644 target/linux/package/bcm43xx-standalone/fwcutter/fwcutter.c delete mode 100644 target/linux/package/bcm43xx-standalone/fwcutter/fwcutter_list.h delete mode 100644 target/linux/package/bcm43xx-standalone/fwcutter/md5.c delete mode 100644 target/linux/package/bcm43xx-standalone/fwcutter/md5.h delete mode 100644 target/linux/package/bcm43xx-standalone/ipkg/kmod-bcm43xx-standalone.control delete mode 100644 target/linux/package/ieee80211-dscape/Config.in delete mode 100644 target/linux/package/ieee80211-dscape/Makefile delete mode 100644 target/linux/package/ieee80211-dscape/ipkg/kmod-ieee80211-dscape.control delete mode 100644 target/linux/package/ieee80211-dscape/src/Kconfig delete mode 100644 target/linux/package/ieee80211-dscape/src/Makefile delete mode 100644 target/linux/package/ieee80211-dscape/src/aes.c delete mode 100644 target/linux/package/ieee80211-dscape/src/aes_ccm.c delete mode 100644 target/linux/package/ieee80211-dscape/src/aes_ccm.h delete mode 100644 target/linux/package/ieee80211-dscape/src/fifo_qdisc.c delete mode 100644 target/linux/package/ieee80211-dscape/src/hostapd_ioctl.h delete mode 100644 target/linux/package/ieee80211-dscape/src/ieee80211.c delete mode 100644 target/linux/package/ieee80211-dscape/src/ieee80211_i.h delete mode 100644 target/linux/package/ieee80211-dscape/src/ieee80211_ioctl.c delete mode 100644 target/linux/package/ieee80211-dscape/src/ieee80211_key.h delete mode 100644 target/linux/package/ieee80211-dscape/src/ieee80211_led.c delete mode 100644 target/linux/package/ieee80211-dscape/src/ieee80211_proc.c delete mode 100644 target/linux/package/ieee80211-dscape/src/ieee80211_proc.h delete mode 100644 target/linux/package/ieee80211-dscape/src/ieee80211_scan.c delete mode 100644 target/linux/package/ieee80211-dscape/src/ieee80211_sta.c delete mode 100644 target/linux/package/ieee80211-dscape/src/include/net/ieee80211.h delete mode 100644 target/linux/package/ieee80211-dscape/src/include/net/ieee80211_common.h delete mode 100644 target/linux/package/ieee80211-dscape/src/include/net/ieee80211_mgmt.h delete mode 100644 target/linux/package/ieee80211-dscape/src/include/net/ieee80211_shared.h delete mode 100644 target/linux/package/ieee80211-dscape/src/michael.c delete mode 100644 target/linux/package/ieee80211-dscape/src/michael.h delete mode 100644 target/linux/package/ieee80211-dscape/src/rate_control.c delete mode 100644 target/linux/package/ieee80211-dscape/src/rate_control.h delete mode 100644 target/linux/package/ieee80211-dscape/src/sta_info.c delete mode 100644 target/linux/package/ieee80211-dscape/src/sta_info.h delete mode 100644 target/linux/package/ieee80211-dscape/src/tkip.c delete mode 100644 target/linux/package/ieee80211-dscape/src/tkip.h delete mode 100644 target/linux/package/ieee80211-dscape/src/wep.c delete mode 100644 target/linux/package/ieee80211-dscape/src/wep.h delete mode 100644 target/linux/package/ieee80211-dscape/src/wme.c delete mode 100644 target/linux/package/ieee80211-dscape/src/wme.h delete mode 100644 target/linux/package/ieee80211-dscape/src/wpa.c delete mode 100644 target/linux/package/ieee80211-dscape/src/wpa.h create mode 100644 target/linux/sibyte-2.6/Makefile create mode 100644 target/linux/sibyte-2.6/config create mode 100644 target/linux/sibyte-2.6/patches/000-DUART.patch create mode 100644 target/linux/sibyte-2.6/patches/001-bcm112x_ax.patch create mode 100644 target/linux/xscale-2.6/Makefile create mode 100644 target/linux/xscale-2.6/config create mode 100644 target/linux/xscale-2.6/patches/001-gateway_7001.patch (limited to 'target/linux/brcm-2.4/patches/001-bcm47xx.patch') diff --git a/package/base-files/default/etc/functions.sh b/package/base-files/default/etc/functions.sh index 858dc286ad..d54a346315 100755 --- a/package/base-files/default/etc/functions.sh +++ b/package/base-files/default/etc/functions.sh @@ -61,3 +61,7 @@ config_get() { config_set() { export CONFIG_${1}_${2}="${3}" } + +load_modules() { + sed 's/^[^#]/insmod &/' $* | ash 2>&- || : +} diff --git a/package/base-files/default/etc/init.d/S10boot b/package/base-files/default/etc/init.d/S10boot index 0cc519d8eb..42bb438861 100755 --- a/package/base-files/default/etc/init.d/S10boot +++ b/package/base-files/default/etc/init.d/S10boot @@ -1,4 +1,5 @@ #!/bin/sh +. /etc/functions.sh [ -f /proc/jffs2_bbc ] && echo "S" > /proc/jffs2_bbc vconfig set_name_type VLAN_PLUS_VID_NO_PAD @@ -16,7 +17,7 @@ for iface in $(/sbin/ifconfig -a | awk '{print $1}' | grep eth); do /usr/bin/env -i ACTION=add INTERFACE="$iface" /sbin/hotplug net done -sed 's/^[^#]/insmod &/' /etc/modules /etc/modules.d/* 2>&-|ash +load_modules /etc/modules /etc/modules.d/* ifconfig lo 127.0.0.1 up ifconfig eth0 promisc diff --git a/package/iptables/files/firewall.awk b/package/iptables/files/firewall.awk index 1b63f83862..1a201a0bce 100644 --- a/package/iptables/files/firewall.awk +++ b/package/iptables/files/firewall.awk @@ -1,4 +1,5 @@ BEGIN { + print ". /etc/config/network" print "proto=\"$wan_proto\"" print "[ -z \"$proto\" -o \"$proto\" = \"none\" ] && exit" print "ifname=\"$wan_ifname\"" diff --git a/target/Config.in b/target/Config.in index f20504031c..aad5f9940f 100644 --- a/target/Config.in +++ b/target/Config.in @@ -7,6 +7,7 @@ config LINUX_2_6_ARUBA select mips select LINUX_2_6 select PCI_SUPPORT + select BIG_ENDIAN help Build firmware images for Aruba boards @@ -14,6 +15,7 @@ config LINUX_2_4_AR531X bool "Atheros AR531x [2.4]" select mips select LINUX_2_4 + select BIG_ENDIAN help Build firmware images for Atheros AR531x based boards (e.g. Netgear WGT624, Linksys WRT55AG) @@ -84,6 +86,7 @@ config LINUX_2_6_ARM config LINUX_2_6_ARMEB bool "UNSUPPORTED big-endian arm platform" select LINUX_2_6 + select BIG_ENDIAN select armeb config LINUX_2_6_CRIS @@ -99,6 +102,7 @@ config LINUX_2_6_M68K config LINUX_2_6_PPC bool "UNSUPPORTED powerpc platform" select LINUX_2_6 + select BIG_ENDIAN select powerpc config LINUX_2_6_SH3 @@ -109,6 +113,7 @@ config LINUX_2_6_SH3 config LINUX_2_6_SH3EB bool "UNSUPPORTED big-endian sh3 platform" select LINUX_2_6 + select BIG_ENDIAN select sh3eb config LINUX_2_6_SH4 @@ -119,11 +124,13 @@ config LINUX_2_6_SH4 config LINUX_2_6_SH4EB bool "UNSUPPORTED big-endian sh4 platform" select LINUX_2_6 + select BIG_ENDIAN select sh4eb config LINUX_2_6_SPARC bool "UNSUPPORTED sparc platform" select LINUX_2_6 + select BIG_ENDIAN select sparc endif @@ -145,6 +152,8 @@ config PCI_SUPPORT config PCMCIA_SUPPORT bool +config BIG_ENDIAN + bool # Architecture selection diff --git a/target/linux/Config.in b/target/linux/Config.in index 5257c78ad0..540e2b7364 100644 --- a/target/linux/Config.in +++ b/target/linux/Config.in @@ -10,6 +10,7 @@ menu "Target Root Filesystem" bool "squashfs-lzma" default y depends !LINUX_2_6_ARUBA + depends !LINUX_2_6_XSCALE help Build a squashfs-lzma root filesystem @@ -53,6 +54,13 @@ config PACKAGE_KMOD_IMQ help Kernel support for the Intermediate Queueing device +config PACKAGE_KMOD_IPIP + prompt "kmod-ipip......................... IP in IP encapsulation support" + tristate + default m + help + Kernel module for IP in IP encapsulation + config PACKAGE_KMOD_IPV6 prompt "kmod-ipv6......................... IPv6 support" tristate @@ -294,7 +302,7 @@ config PACKAGE_KMOD_IDE - ide-core - ide-detect - ide-disk - - pdc202old + - pdc202xx_old config PACKAGE_KMOD_LOOP prompt "kmod-loop......................... Loop mount support" @@ -316,7 +324,7 @@ config PACKAGE_KMOD_CRYPTO prompt "CryptoAPI modules" tristate default m - select BUSYBOX_FEATURE_CHECK_TAINTED_MODULE + select BUSYBOX_CONFIG_FEATURE_CHECK_TAINTED_MODULE help Kernel modules for cryptographic algorithms diff --git a/target/linux/Makefile b/target/linux/Makefile index d7744f56e0..bea43514a7 100644 --- a/target/linux/Makefile +++ b/target/linux/Makefile @@ -84,3 +84,5 @@ $(eval $(call kernel_template,2.6,x86,2_6_X86)) $(eval $(call kernel_template,2.4,ar531x,2_4_AR531X)) $(eval $(call kernel_template,2.6,aruba,2_6_ARUBA)) $(eval $(call kernel_template,2.6,au1000,2_6_AU1000)) +$(eval $(call kernel_template,2.6,xscale,2_6_XSCALE)) +$(eval $(call kernel_template,2.6,sibyte,2_6_SIBYTE)) diff --git a/target/linux/aruba-2.6/Makefile b/target/linux/aruba-2.6/Makefile index b5b220d0f2..e21bf818de 100644 --- a/target/linux/aruba-2.6/Makefile +++ b/target/linux/aruba-2.6/Makefile @@ -1,8 +1,8 @@ include $(TOPDIR)/rules.mk -LINUX_VERSION:=2.6.16.4 +LINUX_VERSION:=2.6.16.7 LINUX_RELEASE:=1 -LINUX_KERNEL_MD5SUM:=cb675279c9711237a06ebb8379a4da27 +LINUX_KERNEL_MD5SUM:=9682b2bd6e02f3087982d7c3f5ba824e include ../rules.mk include ./config diff --git a/target/linux/aruba-2.6/patches/000-aruba.patch b/target/linux/aruba-2.6/patches/000-aruba.patch index 34fbaf2dec..7bb8a26d7f 100644 --- a/target/linux/aruba-2.6/patches/000-aruba.patch +++ b/target/linux/aruba-2.6/patches/000-aruba.patch @@ -45,7 +45,7 @@ diff -Nur linux-2.6.16/arch/mips/aruba/Makefile linux-2.6.16-owrt/arch/mips/arub +# .S.o: +# $(CC) $(CFLAGS) -c $< -o $*.o + -+obj-y := prom.o setup.o idtIRQ.o irq.o time.o flash_lock.o wdt_merlot.o ++obj-y := prom.o setup.o idtIRQ.o irq.o time.o flash_lock.o +obj-$(CONFIG_SERIAL_8250) += serial.o + +subdir-y += nvram @@ -823,6 +823,7 @@ diff -Nur linux-2.6.16/arch/mips/aruba/setup.c linux-2.6.16-owrt/arch/mips/aruba + */ + +#include ++#include +#include +#include +#include @@ -872,7 +873,6 @@ diff -Nur linux-2.6.16/arch/mips/aruba/setup.c linux-2.6.16-owrt/arch/mips/aruba + +extern char * getenv(char *e); +extern void unlock_ap60_70_flash(void); -+extern void wdt_merlot_disable(void); + +void __init plat_setup(void) +{ @@ -895,8 +895,6 @@ diff -Nur linux-2.6.16/arch/mips/aruba/setup.c linux-2.6.16-owrt/arch/mips/aruba + + printk("BOARD - %s\n",getenv("boardname")); + -+ wdt_merlot_disable(); -+ + return 0; +} + @@ -909,6 +907,8 @@ diff -Nur linux-2.6.16/arch/mips/aruba/setup.c linux-2.6.16-owrt/arch/mips/aruba +{ + return "MIPS IDT32434 - ARUBA"; +} ++ ++EXPORT_SYMBOL(get_system_type); diff -Nur linux-2.6.16/arch/mips/aruba/time.c linux-2.6.16-owrt/arch/mips/aruba/time.c --- linux-2.6.16/arch/mips/aruba/time.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-2.6.16-owrt/arch/mips/aruba/time.c 2006-03-20 14:25:10.000000000 +0100 @@ -1021,40 +1021,6 @@ diff -Nur linux-2.6.16/arch/mips/aruba/time.c linux-2.6.16-owrt/arch/mips/aruba/ + timer_interrupt(irq, NULL, regs); + irq_exit(); +} -diff -Nur linux-2.6.16/arch/mips/aruba/wdt_merlot.c linux-2.6.16-owrt/arch/mips/aruba/wdt_merlot.c ---- linux-2.6.16/arch/mips/aruba/wdt_merlot.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-2.6.16-owrt/arch/mips/aruba/wdt_merlot.c 2006-03-20 14:25:10.000000000 +0100 -@@ -0,0 +1,30 @@ -+#include -+#include -+#include -+ -+void wdt_merlot_disable() -+{ -+ volatile __u32 *wdt_errcs; -+ volatile __u32 *wdt_wtc; -+ volatile __u32 *wdt_ctl; -+ volatile __u32 val; -+ -+ switch (mips_machtype) { -+ case MACH_ARUBA_AP70: -+ wdt_errcs = (__u32 *) 0xb8030030; -+ wdt_wtc = (__u32 *) 0xb803003c; -+ val = *wdt_errcs; -+ val &= ~0x201; -+ *wdt_errcs = val; -+ val = *wdt_wtc; -+ val &= ~0x1; -+ *wdt_wtc = val; -+ break; -+ case MACH_ARUBA_AP65: -+ case MACH_ARUBA_AP60: -+ default: -+ wdt_ctl = (__u32 *) 0xbc003008; -+ *wdt_ctl = 0; -+ break; -+ } -+} diff -Nur linux-2.6.16/arch/mips/Kconfig linux-2.6.16-owrt/arch/mips/Kconfig --- linux-2.6.16/arch/mips/Kconfig 2006-03-20 06:53:29.000000000 +0100 +++ linux-2.6.16-owrt/arch/mips/Kconfig 2006-03-20 14:25:10.000000000 +0100 diff --git a/target/linux/aruba-2.6/patches/004-wdt.patch b/target/linux/aruba-2.6/patches/004-wdt.patch new file mode 100644 index 0000000000..15fbffa043 --- /dev/null +++ b/target/linux/aruba-2.6/patches/004-wdt.patch @@ -0,0 +1,126 @@ +diff -Nur linux-2.6.15.1/drivers/char/watchdog/wdt_merlot.c linux-2.6.15.1-openwrt/drivers/char/watchdog/wdt_merlot.c +--- linux-2.6.15.1/drivers/char/watchdog/wdt_merlot.c 2006-01-26 21:14:02.204626250 -0800 ++++ linux-2.6.15.1-openwrt/drivers/char/watchdog/wdt_merlot.c 2006-02-02 20:31:43.000000000 -0800 +@@ -0,0 +1,110 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++extern unsigned long mips_machtype; ++ ++static unsigned long wdt_is_open; ++static struct timer_list wdt_timer; ++ ++static void wdt_merlot_refresh(void) ++{ ++ volatile __u32 *wdt; ++ switch (mips_machtype) { ++ case MACH_ARUBA_AP70: ++ wdt = (__u32 *) 0xb8030034; ++ *wdt = 0x10000000; ++ break; ++ default: ++ wdt = (__u32 *) 0xbc00300c; ++ *wdt = 0x40000000; ++ break; ++ } ++} ++ ++static void wdt_merlot_timer_fn(unsigned long data) ++{ ++ wdt_merlot_refresh(); ++ if (!test_bit(1, &wdt_is_open)) ++ mod_timer(&wdt_timer, jiffies + HZ); ++} ++ ++static int wdt_merlot_setup_timer(void) ++{ ++ ++ init_timer(&wdt_timer); ++ wdt_timer.function = wdt_merlot_timer_fn; ++ wdt_timer.data = 0; ++ wdt_timer.expires = jiffies + HZ; ++ add_timer(&wdt_timer); ++ return 0; ++} ++ ++static int wdt_open(struct inode *inode, struct file *file) ++{ ++ if (test_and_set_bit(0, &wdt_is_open)) ++ return -EBUSY; ++ set_bit(1, &wdt_is_open); ++ return nonseekable_open(inode, file); ++} ++ ++static ssize_t wdt_write(struct file *file, const char __user * buf, size_t count, loff_t * ppos) ++{ ++ if (count) /* something was written */ ++ wdt_merlot_refresh(); ++ return count; ++} ++ ++static int wdt_release(struct inode *inode, struct file *file) ++{ ++ clear_bit(0, &wdt_is_open); ++ return 0; ++} ++ ++static struct file_operations wdt_fops = { ++ .owner = THIS_MODULE, ++ .llseek = no_llseek, ++ .write = wdt_write, ++ .open = wdt_open, ++ .release = wdt_release, ++}; ++ ++static struct miscdevice wdt_miscdev = { ++ .minor = WATCHDOG_MINOR, ++ .name = "watchdog", ++ .fops = &wdt_fops, ++}; ++ ++static void __exit wdt_exit(void) ++{ ++ misc_deregister(&wdt_miscdev); ++} ++ ++static int __init wdt_init(void) ++{ ++ int ret; ++ ret = misc_register(&wdt_miscdev); ++ if (ret) { ++ printk(KERN_ERR ++ "wdt: cannot register miscdev on minor=%d (err=%d)\n", ++ WATCHDOG_MINOR, ret); ++ misc_deregister(&wdt_miscdev); ++ goto out; ++ } ++ printk("wdt: registered with refresh\n"); ++ wdt_merlot_refresh(); ++ wdt_merlot_setup_timer(); ++ out: ++ return ret; ++} ++ ++module_init(wdt_init); ++module_exit(wdt_exit); +diff -Nur linux-2.6.15.3/drivers/char/watchdog/Makefile linux-2.6.15.3-openwrt/drivers/char/watchdog/Makefile +--- linux-2.6.15.3/drivers/char/watchdog/Makefile 2006-02-22 10:04:18.596278000 -0800 ++++ linux-2.6.15.3-openwrt/drivers/char/watchdog/Makefile 2006-02-22 10:06:21.400960000 -0800 +@@ -71,5 +71,8 @@ + + # SPARC64 Architecture + ++# Aruba Architecture ++obj-$(CONFIG_MACH_ARUBA) += wdt_merlot.o ++ + # Architecture Independant + obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o diff --git a/target/linux/au1000-2.6/Makefile b/target/linux/au1000-2.6/Makefile index 8c1c67d183..8ba22aa683 100644 --- a/target/linux/au1000-2.6/Makefile +++ b/target/linux/au1000-2.6/Makefile @@ -1,8 +1,8 @@ include $(TOPDIR)/rules.mk -LINUX_VERSION:=2.6.16.4 +LINUX_VERSION:=2.6.16.7 LINUX_RELEASE:=1 -LINUX_KERNEL_MD5SUM:=cb675279c9711237a06ebb8379a4da27 +LINUX_KERNEL_MD5SUM:=9682b2bd6e02f3087982d7c3f5ba824e include ../rules.mk include ./config @@ -17,9 +17,10 @@ $(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked @$(CP) config $(LINUX_DIR)/.config touch $@ -$(LINUX_BUILD_DIR)/bzImage: $(LINUX_DIR)/vmlinux - $(MAKE) -C $(LINUX_DIR) V=1 CROSS_COMPILE=$(TARGET_CROSS) ARCH=$(LINUX_KARCH) PATH=$(TARGET_PATH) bzImage - $(CP) $(LINUX_DIR)/vmlinux $@ +$(LINUX_BUILD_DIR)/zImage.flash.srec: $(LINUX_DIR)/arch/mips/boot/compressed/images/zImage.flash.srec $(LINUX_DIR)/arch/mips/boot/compressed/images/zImage.srec + $(MAKE) -C $(LINUX_DIR) V=1 CROSS_COMPILE=$(TARGET_CROSS) ARCH=$(LINUX_KARCH) PATH=$(TARGET_PATH) zImage.flash + $(CP) $(LINUX_DIR)/arch/mips/boot/compressed/images/zImage.flash.srec $(LINUX_DIR)/zImage.flash.srec + $(CP) $(LINUX_DIR)/arch/mips/boot/compressed/images/zImage.srec $(LINUX_DIR)/zImage.srec touch $@ compile: $(LINUX_DIR)/vmlinux diff --git a/target/linux/au1000-2.6/config b/target/linux/au1000-2.6/config index 37dac8ed26..b274fcfd55 100644 --- a/target/linux/au1000-2.6/config +++ b/target/linux/au1000-2.6/config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16.2 -# Tue Apr 11 13:27:02 2006 +# Linux kernel version: 2.6.16.7 +# Sat Apr 29 20:33:29 2006 # CONFIG_MIPS=y @@ -113,7 +113,7 @@ CONFIG_PAGE_SIZE_4KB=y # CONFIG_PAGE_SIZE_64KB is not set CONFIG_CPU_HAS_PREFETCH=y # CONFIG_MIPS_MT is not set -# CONFIG_64BIT_PHYS_ADDR is not set +CONFIG_64BIT_PHYS_ADDR=y # CONFIG_CPU_ADVANCED is not set CONFIG_CPU_HAS_LLSC=y CONFIG_CPU_HAS_SYNC=y @@ -148,19 +148,21 @@ CONFIG_LOCALVERSION_AUTO=y CONFIG_SWAP=y CONFIG_SYSVIPC=y # CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_INITRAMFS_SOURCE="" -CONFIG_CC_OPTIMIZE_FOR_SIZE=y +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EMBEDDED=y -# CONFIG_KALLSYMS is not set +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y -# CONFIG_ELF_CORE is not set +CONFIG_ELF_CORE=y CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y @@ -169,10 +171,10 @@ CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_SLAB is not set +CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 -CONFIG_SLOB=y +# CONFIG_SLOB is not set CONFIG_OBSOLETE_INTERMODULE=y # @@ -180,11 +182,11 @@ CONFIG_OBSOLETE_INTERMODULE=y # CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y -# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_MODULE_FORCE_UNLOAD=y CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -# CONFIG_KMOD is not set +CONFIG_KMOD=y # # Block layer @@ -196,8 +198,8 @@ CONFIG_OBSOLETE_MODPARM=y # CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y -# CONFIG_IOSCHED_DEADLINE is not set -# CONFIG_IOSCHED_CFQ is not set +CONFIG_IOSCHED_DEADLINE=m +CONFIG_IOSCHED_CFQ=m CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_DEADLINE is not set # CONFIG_DEFAULT_CFQ is not set @@ -226,7 +228,7 @@ CONFIG_MMU=y # Executable file formats # CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m +CONFIG_BINFMT_MISC=y CONFIG_TRAD_SIGNALS=y # CONFIG_PM is not set @@ -239,12 +241,12 @@ CONFIG_NET=y # Networking options # # CONFIG_NETDEBUG is not set -CONFIG_PACKET=y +CONFIG_PACKET=m CONFIG_PACKET_MMAP=y -CONFIG_UNIX=y +CONFIG_UNIX=m CONFIG_XFRM=y -# CONFIG_XFRM_USER is not set -# CONFIG_NET_KEY is not set +CONFIG_XFRM_USER=m +CONFIG_NET_KEY=m CONFIG_INET=y CONFIG_IP_MULTICAST=y CONFIG_IP_ADVANCED_ROUTER=y @@ -255,33 +257,35 @@ CONFIG_IP_MULTIPLE_TABLES=y CONFIG_IP_ROUTE_FWMARK=y CONFIG_IP_ROUTE_MULTIPATH=y # CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set -# CONFIG_IP_ROUTE_VERBOSE is not set -# CONFIG_IP_PNP is not set +CONFIG_IP_ROUTE_VERBOSE=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set CONFIG_NET_IPIP=m CONFIG_NET_IPGRE=m -# CONFIG_NET_IPGRE_BROADCAST is not set -CONFIG_IPSEC_NAT_TRAVERSAL=y +CONFIG_NET_IPGRE_BROADCAST=y +# CONFIG_IPSEC_NAT_TRAVERSAL is not set # CONFIG_IP_MROUTE is not set # CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set +CONFIG_SYN_COOKIES=y +CONFIG_INET_AH=m +CONFIG_INET_ESP=m +CONFIG_INET_IPCOMP=m CONFIG_INET_TUNNEL=m -CONFIG_INET_DIAG=m -CONFIG_INET_TCP_DIAG=m +# CONFIG_INET_DIAG is not set CONFIG_TCP_CONG_ADVANCED=y # # TCP congestion control # -CONFIG_TCP_CONG_BIC=m -CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_BIC=y +# CONFIG_TCP_CONG_CUBIC is not set CONFIG_TCP_CONG_WESTWOOD=m CONFIG_TCP_CONG_HTCP=m CONFIG_TCP_CONG_HSTCP=m CONFIG_TCP_CONG_HYBLA=m -CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_VEGAS=m CONFIG_TCP_CONG_SCALABLE=m # @@ -289,62 +293,67 @@ CONFIG_TCP_CONG_SCALABLE=m # # CONFIG_IP_VS is not set CONFIG_IPV6=m -# CONFIG_IPV6_PRIVACY is not set -# CONFIG_INET6_AH is not set -# CONFIG_INET6_ESP is not set -# CONFIG_INET6_IPCOMP is not set -# CONFIG_INET6_TUNNEL is not set -# CONFIG_IPV6_TUNNEL is not set +CONFIG_IPV6_PRIVACY=y +CONFIG_INET6_AH=m +CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m +CONFIG_INET6_TUNNEL=m +CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set -# CONFIG_BRIDGE_NETFILTER is not set +CONFIG_BRIDGE_NETFILTER=y # # Core Netfilter Configuration # -# CONFIG_NETFILTER_NETLINK is not set -CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_NETLINK=m +CONFIG_NETFILTER_NETLINK_QUEUE=m +CONFIG_NETFILTER_NETLINK_LOG=m +CONFIG_NETFILTER_XTABLES=m CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m -CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set CONFIG_NETFILTER_XT_TARGET_MARK=m -# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set -# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set -# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +CONFIG_NETFILTER_XT_MATCH_COMMENT=m +CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m -CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y -# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +CONFIG_NETFILTER_XT_MATCH_DCCP=m CONFIG_NETFILTER_XT_MATCH_HELPER=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m -# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set -# CONFIG_NETFILTER_XT_MATCH_REALM is not set -# CONFIG_NETFILTER_XT_MATCH_SCTP is not set -CONFIG_NETFILTER_XT_MATCH_STATE=y -# CONFIG_NETFILTER_XT_MATCH_STRING is not set -CONFIG_NETFILTER_XT_MATCH_TCPMSS=y +CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m +CONFIG_NETFILTER_XT_MATCH_REALM=m +CONFIG_NETFILTER_XT_MATCH_SCTP=m +CONFIG_NETFILTER_XT_MATCH_STATE=m +CONFIG_NETFILTER_XT_MATCH_STRING=m +CONFIG_NETFILTER_XT_MATCH_TCPMSS=m # # IP: Netfilter Configuration # -CONFIG_IP_NF_CONNTRACK=y +CONFIG_IP_NF_CONNTRACK=m CONFIG_IP_NF_CT_ACCT=y CONFIG_IP_NF_CONNTRACK_MARK=y -# CONFIG_IP_NF_CONNTRACK_EVENTS is not set -# CONFIG_IP_NF_CT_PROTO_SCTP is not set -CONFIG_IP_NF_FTP=y -CONFIG_IP_NF_IRC=y -# CONFIG_IP_NF_NETBIOS_NS is not set +CONFIG_IP_NF_CONNTRACK_EVENTS=y +CONFIG_IP_NF_CONNTRACK_NETLINK=m +CONFIG_IP_NF_CT_PROTO_SCTP=m +CONFIG_IP_NF_FTP=m +CONFIG_IP_NF_IRC=m +CONFIG_IP_NF_NETBIOS_NS=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m CONFIG_IP_NF_PPTP=m CONFIG_IP_NF_SIP=m CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_IPRANGE=m CONFIG_IP_NF_MATCH_LAYER7=m -# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set +CONFIG_IP_NF_MATCH_LAYER7_DEBUG=y CONFIG_IP_NF_MATCH_MULTIPORT=m CONFIG_IP_NF_MATCH_IPP2P=m CONFIG_IP_NF_MATCH_TOS=m @@ -355,36 +364,38 @@ CONFIG_IP_NF_MATCH_DSCP=m CONFIG_IP_NF_MATCH_AH_ESP=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_MATCH_OWNER=m -# CONFIG_IP_NF_MATCH_ADDRTYPE is not set -# CONFIG_IP_NF_MATCH_HASHLIMIT is not set -# CONFIG_IP_NF_MATCH_POLICY is not set -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_MATCH_ADDRTYPE=m +CONFIG_IP_NF_MATCH_HASHLIMIT=m +CONFIG_IP_NF_MATCH_POLICY=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_IMQ=m -# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_LOG=m CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=y -CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_NAT=m CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_REDIRECT=y -# CONFIG_IP_NF_TARGET_NETMAP is not set -# CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_NF_NAT_SNMP_BASIC is not set -CONFIG_IP_NF_NAT_IRC=y -CONFIG_IP_NF_NAT_FTP=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_TARGET_NETMAP=m +CONFIG_IP_NF_TARGET_SAME=m +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=m +CONFIG_IP_NF_NAT_FTP=m CONFIG_IP_NF_NAT_TFTP=m CONFIG_IP_NF_NAT_AMANDA=m CONFIG_IP_NF_NAT_PPTP=m CONFIG_IP_NF_NAT_SIP=m -CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_TOS=m CONFIG_IP_NF_TARGET_ECN=m CONFIG_IP_NF_TARGET_DSCP=m CONFIG_IP_NF_TARGET_TTL=m -# CONFIG_IP_NF_TARGET_CLUSTERIP is not set -# CONFIG_IP_NF_RAW is not set -# CONFIG_IP_NF_ARPTABLES is not set +CONFIG_IP_NF_TARGET_CLUSTERIP=m +CONFIG_IP_NF_RAW=m +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m CONFIG_IP_NF_SET=m CONFIG_IP_NF_SET_MAX=256 CONFIG_IP_NF_SET_HASHSIZE=1024 @@ -401,24 +412,7 @@ CONFIG_IP_NF_TARGET_SET=m # IPv6: Netfilter Configuration (EXPERIMENTAL) # CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_HL is not set -CONFIG_IP6_NF_MATCH_MULTIPORT=m -CONFIG_IP6_NF_MATCH_OWNER=m -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_AHESP is not set -CONFIG_IP6_NF_MATCH_EUI64=m -# CONFIG_IP6_NF_MATCH_POLICY is not set -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_IMQ=m -# CONFIG_IP6_NF_TARGET_LOG is not set -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_MANGLE=m -# CONFIG_IP6_NF_TARGET_HL is not set -# CONFIG_IP6_NF_RAW is not set +# CONFIG_IP6_NF_IPTABLES is not set # # Bridge: Netfilter Configuration @@ -458,17 +452,12 @@ CONFIG_BRIDGE_EBT_ULOG=m # TIPC Configuration (EXPERIMENTAL) # # CONFIG_TIPC is not set -CONFIG_ATM=m -CONFIG_ATM_CLIP=m -CONFIG_ATM_CLIP_NO_ICMP=y -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -CONFIG_ATM_BR2684_IPFILTER=y -CONFIG_BRIDGE=y -CONFIG_VLAN_8021Q=y +# CONFIG_ATM is not set +CONFIG_BRIDGE=m +CONFIG_VLAN_8021Q=m # CONFIG_DECNET is not set -# CONFIG_LLC2 is not set +CONFIG_LLC=m +CONFIG_LLC2=m # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_X25 is not set @@ -491,16 +480,15 @@ CONFIG_NET_SCH_CLK_JIFFIES=y CONFIG_NET_SCH_CBQ=m CONFIG_NET_SCH_HTB=m CONFIG_NET_SCH_HFSC=m -CONFIG_NET_SCH_ATM=m CONFIG_NET_SCH_PRIO=m CONFIG_NET_SCH_RED=m CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_ESFQ=m +# CONFIG_NET_SCH_ESFQ is not set CONFIG_NET_SCH_TEQL=m CONFIG_NET_SCH_TBF=m CONFIG_NET_SCH_GRED=m CONFIG_NET_SCH_DSMARK=m -# CONFIG_NET_SCH_NETEM is not set +CONFIG_NET_SCH_NETEM=m CONFIG_NET_SCH_INGRESS=m # @@ -513,67 +501,36 @@ CONFIG_NET_CLS_ROUTE4=m CONFIG_NET_CLS_ROUTE=y CONFIG_NET_CLS_FW=m CONFIG_NET_CLS_U32=m -# CONFIG_CLS_U32_PERF is not set -# CONFIG_CLS_U32_MARK is not set +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y CONFIG_NET_CLS_RSVP=m CONFIG_NET_CLS_RSVP6=m -# CONFIG_NET_EMATCH is not set -# CONFIG_NET_CLS_ACT is not set -CONFIG_NET_CLS_POLICE=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_STACK=32 +CONFIG_NET_EMATCH_CMP=m +CONFIG_NET_EMATCH_NBYTE=m +CONFIG_NET_EMATCH_U32=m +CONFIG_NET_EMATCH_META=m +CONFIG_NET_EMATCH_TEXT=m +CONFIG_NET_CLS_ACT=y +CONFIG_NET_ACT_POLICE=m +CONFIG_NET_ACT_GACT=m +CONFIG_GACT_PROB=y +CONFIG_NET_ACT_MIRRED=m +# CONFIG_NET_ACT_IPT is not set +CONFIG_NET_ACT_PEDIT=m +CONFIG_NET_ACT_SIMP=m # CONFIG_NET_CLS_IND is not set CONFIG_NET_ESTIMATOR=y # # Network testing # -# CONFIG_NET_PKTGEN is not set -CONFIG_HAMRADIO=y - -# -# Packet Radio protocols -# -CONFIG_AX25=m -# CONFIG_AX25_DAMA_SLAVE is not set -# CONFIG_NETROM is not set -# CONFIG_ROSE is not set - -# -# AX.25 network device drivers -# -CONFIG_MKISS=m -# CONFIG_6PACK is not set -# CONFIG_BPQETHER is not set -# CONFIG_BAYCOM_SER_FDX is not set -# CONFIG_BAYCOM_SER_HDX is not set -# CONFIG_YAM is not set +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set # CONFIG_IRDA is not set -CONFIG_BT=m -CONFIG_BT_L2CAP=m -CONFIG_BT_SCO=m -CONFIG_BT_RFCOMM=m -CONFIG_BT_RFCOMM_TTY=y -CONFIG_BT_BNEP=m -CONFIG_BT_BNEP_MC_FILTER=y -CONFIG_BT_BNEP_PROTO_FILTER=y -CONFIG_BT_HIDP=m - -# -# Bluetooth device drivers -# -CONFIG_BT_HCIUSB=m -CONFIG_BT_HCIUSB_SCO=y -CONFIG_BT_HCIUART=m -CONFIG_BT_HCIUART_H4=y -CONFIG_BT_HCIUART_BCSP=y -# CONFIG_BT_HCIBCM203X is not set -# CONFIG_BT_HCIBPA10X is not set -# CONFIG_BT_HCIBFUSB is not set -# CONFIG_BT_HCIVHCI is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_CRYPT_TKIP=m +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set # # Device Drivers @@ -582,21 +539,21 @@ CONFIG_IEEE80211_CRYPT_TKIP=m # # Generic Driver Options # -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_STANDALONE is not set +# CONFIG_PREVENT_FIRMWARE_BUILD is not set CONFIG_FW_LOADER=y # # Connector - unified userspace <-> kernelspace linker # -CONFIG_CONNECTOR=m +# CONFIG_CONNECTOR is not set # # Memory Technology Devices (MTD) # CONFIG_MTD=y # CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_CONCAT=y CONFIG_MTD_PARTITIONS=y # CONFIG_MTD_REDBOOT_PARTS is not set # CONFIG_MTD_CMDLINE_PARTS is not set @@ -628,7 +585,7 @@ CONFIG_MTD_CFI_I1=y CONFIG_MTD_CFI_I2=y # CONFIG_MTD_CFI_I4 is not set # CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_INTELEXT is not set CONFIG_MTD_CFI_AMDSTD=y CONFIG_MTD_CFI_AMDSTD_RETRY=0 # CONFIG_MTD_CFI_STAA is not set @@ -641,11 +598,10 @@ CONFIG_MTD_CFI_UTIL=y # # Mapping drivers for chip access # -CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_COMPLEX_MAPPINGS is not set # CONFIG_MTD_PHYSMAP is not set # CONFIG_MTD_ALCHEMY is not set CONFIG_MTD_MTX1=y -# CONFIG_MTD_PCI is not set # CONFIG_MTD_PLATRAM is not set # @@ -697,8 +653,9 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m CONFIG_BLK_DEV_NBD=m # CONFIG_BLK_DEV_SX8 is not set # CONFIG_BLK_DEV_UB is not set -# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM=m CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=4096 # CONFIG_CDROM_PKTCDVD is not set # CONFIG_ATA_OVER_ETH is not set @@ -712,7 +669,7 @@ CONFIG_BLK_DEV_RAM_COUNT=16 # # CONFIG_RAID_ATTRS is not set CONFIG_SCSI=m -CONFIG_SCSI_PROC_FS=y +# CONFIG_SCSI_PROC_FS is not set # # SCSI support type (disk, tape, CD-ROM) @@ -721,14 +678,14 @@ CONFIG_BLK_DEV_SD=m # CONFIG_CHR_DEV_ST is not set # CONFIG_CHR_DEV_OSST is not set # CONFIG_BLK_DEV_SR is not set -# CONFIG_CHR_DEV_SG is not set +CONFIG_CHR_DEV_SG=m # CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs # -# CONFIG_SCSI_MULTI_LUN is not set -# CONFIG_SCSI_CONSTANTS is not set +CONFIG_SCSI_MULTI_LUN=y +CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_LOGGING is not set # @@ -798,8 +755,9 @@ CONFIG_BLK_DEV_SD=m # Network device support # CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set +# CONFIG_IFB is not set +CONFIG_DUMMY=m +CONFIG_BONDING=m # CONFIG_EQUALIZER is not set CONFIG_IMQ=m # CONFIG_IMQ_BEHAVIOR_AA is not set @@ -837,26 +795,7 @@ CONFIG_MIPS_AU1X00_ENET=y # # CONFIG_NET_TULIP is not set # CONFIG_HP100 is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_B44 is not set -# CONFIG_FORCEDETH is not set -# CONFIG_DGRS is not set -# CONFIG_EEPRO100 is not set -# CONFIG_E100 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_LAN_SAA9730 is not set +# CONFIG_NET_PCI is not set # # Ethernet (1000 Mbit) @@ -872,7 +811,6 @@ CONFIG_NET_PCI=y # CONFIG_SKGE is not set # CONFIG_SKY2 is not set # CONFIG_SK98LIN is not set -# CONFIG_VIA_VELOCITY is not set # CONFIG_TIGON3 is not set # CONFIG_BNX2 is not set @@ -896,20 +834,15 @@ CONFIG_NET_RADIO=y # # Obsolete Wireless cards support (pre-802.11) # -# CONFIG_STRIP is not set +CONFIG_STRIP=m # # Wireless 802.11b ISA/PCI cards support # -CONFIG_IPW2100=m -CONFIG_IPW2100_MONITOR=y -# CONFIG_IPW2100_DEBUG is not set -CONFIG_IPW2200=m -# CONFIG_IPW2200_DEBUG is not set CONFIG_HERMES=m -CONFIG_PLX_HERMES=m -CONFIG_TMD_HERMES=m -CONFIG_NORTEL_HERMES=m +# CONFIG_PLX_HERMES is not set +# CONFIG_TMD_HERMES is not set +# CONFIG_NORTEL_HERMES is not set CONFIG_PCI_HERMES=m CONFIG_ATMEL=m CONFIG_PCI_ATMEL=m @@ -918,49 +851,27 @@ CONFIG_PCI_ATMEL=m # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support # CONFIG_PRISM54=m -CONFIG_HOSTAP=m -CONFIG_HOSTAP_FIRMWARE=y -CONFIG_HOSTAP_FIRMWARE_NVRAM=y -CONFIG_HOSTAP_PLX=m -CONFIG_HOSTAP_PCI=m +# CONFIG_HOSTAP is not set CONFIG_NET_WIRELESS=y # # Wan interfaces # # CONFIG_WAN is not set - -# -# ATM drivers -# -CONFIG_ATM_DUMMY=m -CONFIG_ATM_TCP=m -# CONFIG_ATM_LANAI is not set -# CONFIG_ATM_ENI is not set -# CONFIG_ATM_FIRESTREAM is not set -# CONFIG_ATM_ZATM is not set -# CONFIG_ATM_NICSTAR is not set -# CONFIG_ATM_IDT77252 is not set -# CONFIG_ATM_AMBASSADOR is not set -# CONFIG_ATM_HORIZON is not set -# CONFIG_ATM_IA is not set -# CONFIG_ATM_FORE200E_MAYBE is not set -# CONFIG_ATM_HE is not set # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=m -# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_MULTILINK=y CONFIG_PPP_FILTER=y CONFIG_PPP_ASYNC=m -# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_SYNC_TTY=m CONFIG_PPP_DEFLATE=m CONFIG_PPP_BSDCOMP=m -CONFIG_PPP_MPPE=m +# CONFIG_PPP_MPPE is not set CONFIG_PPPOE=m -CONFIG_PPPOATM=m # CONFIG_SLIP is not set # CONFIG_NET_FC is not set -# CONFIG_SHAPER is not set +CONFIG_SHAPER=m # CONFIG_NETCONSOLE is not set # CONFIG_NETPOLL is not set # CONFIG_NET_POLL_CONTROLLER is not set @@ -978,7 +889,7 @@ CONFIG_PPPOATM=m # # Input device support # -CONFIG_INPUT=m +CONFIG_INPUT=y # # Userland interfaces @@ -986,7 +897,7 @@ CONFIG_INPUT=m # CONFIG_INPUT_MOUSEDEV is not set # CONFIG_INPUT_JOYDEV is not set # CONFIG_INPUT_TSDEV is not set -CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVDEV is not set # CONFIG_INPUT_EVBUG is not set # @@ -1007,7 +918,9 @@ CONFIG_INPUT_EVDEV=m # # Character devices # -# CONFIG_VT is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -1015,10 +928,10 @@ CONFIG_INPUT_EVDEV=m # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=2 -CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set -# CONFIG_SERIAL_8250_AU1X00 is not set +CONFIG_SERIAL_8250_AU1X00=y # # Non-8250 serial port support @@ -1038,7 +951,25 @@ CONFIG_UNIX98_PTYS=y # # Watchdog Cards # -# CONFIG_WATCHDOG is not set +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +CONFIG_SOFT_WATCHDOG=m +CONFIG_MTX1_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set # CONFIG_RTC is not set # CONFIG_GEN_RTC is not set # CONFIG_DTLK is not set @@ -1090,29 +1021,7 @@ CONFIG_UNIX98_PTYS=y # # Multimedia devices # -CONFIG_VIDEO_DEV=m - -# -# Video For Linux -# - -# -# Video Adapters -# -# CONFIG_VIDEO_ADV_DEBUG is not set -# CONFIG_VIDEO_CPIA is not set -# CONFIG_VIDEO_STRADIS is not set -# CONFIG_VIDEO_MXB is not set -# CONFIG_VIDEO_DPC is not set -# CONFIG_VIDEO_HEXIUM_ORION is not set -# CONFIG_VIDEO_HEXIUM_GEMINI is not set - -# -# Radio Adapters -# -# CONFIG_RADIO_GEMTEK_PCI is not set -# CONFIG_RADIO_MAXIRADIO is not set -# CONFIG_RADIO_MAESTRO is not set +# CONFIG_VIDEO_DEV is not set # # Digital Video Broadcasting Devices @@ -1124,94 +1033,16 @@ CONFIG_VIDEO_DEV=m # # CONFIG_FB is not set +# +# Console display driver support +# +# CONFIG_VGA_CONSOLE is not set +CONFIG_DUMMY_CONSOLE=y + # # Sound # -CONFIG_SOUND=m - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=m -CONFIG_SND_TIMER=m -CONFIG_SND_PCM=m -CONFIG_SND_HWDEP=m -CONFIG_SND_RAWMIDI=m -# CONFIG_SND_SEQUENCER is not set -# CONFIG_SND_MIXER_OSS is not set -# CONFIG_SND_PCM_OSS is not set -# CONFIG_SND_DYNAMIC_MINORS is not set -# CONFIG_SND_SUPPORT_OLD_API is not set -# CONFIG_SND_VERBOSE_PRINTK is not set -# CONFIG_SND_DEBUG is not set - -# -# Generic devices -# -# CONFIG_SND_DUMMY is not set -# CONFIG_SND_MTPAV is not set -# CONFIG_SND_SERIAL_U16550 is not set -# CONFIG_SND_MPU401 is not set - -# -# PCI devices -# -# CONFIG_SND_AD1889 is not set -# CONFIG_SND_ALI5451 is not set -# CONFIG_SND_ATIIXP is not set -# CONFIG_SND_ATIIXP_MODEM is not set -# CONFIG_SND_AU8810 is not set -# CONFIG_SND_AU8820 is not set -# CONFIG_SND_AU8830 is not set -# CONFIG_SND_AZT3328 is not set -# CONFIG_SND_BT87X is not set -# CONFIG_SND_CA0106 is not set -# CONFIG_SND_CMIPCI is not set -# CONFIG_SND_CS4281 is not set -# CONFIG_SND_CS46XX is not set -# CONFIG_SND_EMU10K1 is not set -# CONFIG_SND_EMU10K1X is not set -# CONFIG_SND_ENS1370 is not set -# CONFIG_SND_ENS1371 is not set -# CONFIG_SND_ES1938 is not set -# CONFIG_SND_ES1968 is not set -# CONFIG_SND_FM801 is not set -# CONFIG_SND_HDA_INTEL is not set -# CONFIG_SND_HDSP is not set -# CONFIG_SND_HDSPM is not set -# CONFIG_SND_ICE1712 is not set -# CONFIG_SND_ICE1724 is not set -# CONFIG_SND_INTEL8X0 is not set -# CONFIG_SND_INTEL8X0M is not set -# CONFIG_SND_KORG1212 is not set -# CONFIG_SND_MAESTRO3 is not set -# CONFIG_SND_MIXART is not set -# CONFIG_SND_NM256 is not set -# CONFIG_SND_PCXHR is not set -# CONFIG_SND_RME32 is not set -# CONFIG_SND_RME96 is not set -# CONFIG_SND_RME9652 is not set -# CONFIG_SND_SONICVIBES is not set -# CONFIG_SND_TRIDENT is not set -# CONFIG_SND_VIA82XX is not set -# CONFIG_SND_VIA82XX_MODEM is not set -# CONFIG_SND_VX222 is not set -# CONFIG_SND_YMFPCI is not set - -# -# ALSA MIPS devices -# -# CONFIG_SND_AU1X00 is not set - -# -# USB devices -# -CONFIG_SND_USB_AUDIO=m - -# -# Open Sound System -# -# CONFIG_SOUND_PRIME is not set +# CONFIG_SOUND is not set # # USB support @@ -1232,20 +1063,15 @@ CONFIG_USB_DEVICEFS=y # # USB Host Controller Drivers # -CONFIG_USB_EHCI_HCD=m -# CONFIG_USB_EHCI_SPLIT_ISO is not set -# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_EHCI_HCD is not set # CONFIG_USB_ISP116X_HCD is not set -CONFIG_USB_OHCI_HCD=m -# CONFIG_USB_OHCI_BIG_ENDIAN is not set -CONFIG_USB_OHCI_LITTLE_ENDIAN=y -CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_OHCI_HCD is not set +# CONFIG_USB_UHCI_HCD is not set # CONFIG_USB_SL811_HCD is not set # # USB Device Class drivers # -# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m @@ -1258,15 +1084,14 @@ CONFIG_USB_PRINTER=m # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_USBAT is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set +CONFIG_USB_STORAGE_DATAFAB=y +CONFIG_USB_STORAGE_FREECOM=y +CONFIG_USB_STORAGE_DPCM=y +CONFIG_USB_STORAGE_USBAT=y +CONFIG_USB_STORAGE_SDDR09=y +CONFIG_USB_STORAGE_SDDR55=y +CONFIG_USB_STORAGE_JUMPSHOT=y # CONFIG_USB_STORAGE_ALAUDA is not set -# CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_LIBUSUAL is not set # @@ -1297,34 +1122,36 @@ CONFIG_USB_STORAGE=m # # USB Imaging devices # -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_MICROTEK is not set +CONFIG_USB_MDC800=m +CONFIG_USB_MICROTEK=m # # USB Multimedia devices # -# CONFIG_USB_DABUSB is not set -# CONFIG_USB_VICAM is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_ET61X251 is not set -# CONFIG_USB_IBMCAM is not set -# CONFIG_USB_KONICAWC is not set -# CONFIG_USB_OV511 is not set -# CONFIG_USB_SE401 is not set -# CONFIG_USB_SN9C102 is not set -# CONFIG_USB_STV680 is not set -# CONFIG_USB_PWC is not set +CONFIG_USB_DABUSB=m + +# +# Video4Linux support is needed for USB Multimedia device support +# # # USB Network Adapters # -# CONFIG_USB_CATC is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_USBNET is not set -# CONFIG_USB_ZD1201 is not set -# CONFIG_USB_MON is not set +CONFIG_USB_CATC=m +CONFIG_USB_KAWETH=m +CONFIG_USB_PEGASUS=m +CONFIG_USB_RTL8150=m +CONFIG_USB_USBNET=m +CONFIG_USB_NET_AX8817X=m +CONFIG_USB_NET_CDCETHER=m +# CONFIG_USB_NET_GL620A is not set +CONFIG_USB_NET_NET1080=m +# CONFIG_USB_NET_PLUSB is not set +# CONFIG_USB_NET_RNDIS_HOST is not set +# CONFIG_USB_NET_CDC_SUBSET is not set +CONFIG_USB_NET_ZAURUS=m +CONFIG_USB_ZD1201=m +CONFIG_USB_MON=y # # USB port drivers @@ -1334,62 +1161,58 @@ CONFIG_USB_STORAGE=m # USB Serial Converter support # CONFIG_USB_SERIAL=m -# CONFIG_USB_SERIAL_GENERIC is not set -# CONFIG_USB_SERIAL_AIRPRIME is not set +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_AIRPRIME=m # CONFIG_USB_SERIAL_ANYDATA is not set CONFIG_USB_SERIAL_BELKIN=m -# CONFIG_USB_SERIAL_WHITEHEAT is not set -# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set -# CONFIG_USB_SERIAL_CP2101 is not set -# CONFIG_USB_SERIAL_CYPRESS_M8 is not set -# CONFIG_USB_SERIAL_EMPEG is not set +CONFIG_USB_SERIAL_WHITEHEAT=m +CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m +CONFIG_USB_SERIAL_CP2101=m +CONFIG_USB_SERIAL_CYPRESS_M8=m +CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m CONFIG_USB_SERIAL_VISOR=m -# CONFIG_USB_SERIAL_IPAQ is not set -# CONFIG_USB_SERIAL_IR is not set -# CONFIG_USB_SERIAL_EDGEPORT is not set -# CONFIG_USB_SERIAL_EDGEPORT_TI is not set -# CONFIG_USB_SERIAL_GARMIN is not set -# CONFIG_USB_SERIAL_IPW is not set -# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +CONFIG_USB_SERIAL_IPAQ=m +CONFIG_USB_SERIAL_IR=m +CONFIG_USB_SERIAL_EDGEPORT=m +CONFIG_USB_SERIAL_EDGEPORT_TI=m +CONFIG_USB_SERIAL_GARMIN=m +CONFIG_USB_SERIAL_IPW=m +CONFIG_USB_SERIAL_KEYSPAN_PDA=m # CONFIG_USB_SERIAL_KEYSPAN is not set -# CONFIG_USB_SERIAL_KLSI is not set -# CONFIG_USB_SERIAL_KOBIL_SCT is not set -# CONFIG_USB_SERIAL_MCT_U232 is not set +CONFIG_USB_SERIAL_KLSI=m +CONFIG_USB_SERIAL_KOBIL_SCT=m +CONFIG_USB_SERIAL_MCT_U232=m CONFIG_USB_SERIAL_PL2303=m -# CONFIG_USB_SERIAL_HP4X is not set -# CONFIG_USB_SERIAL_SAFE is not set -# CONFIG_USB_SERIAL_TI is not set -# CONFIG_USB_SERIAL_CYBERJACK is not set -# CONFIG_USB_SERIAL_XIRCOM is not set -# CONFIG_USB_SERIAL_OMNINET is not set +CONFIG_USB_SERIAL_HP4X=m +CONFIG_USB_SERIAL_SAFE=m +CONFIG_USB_SERIAL_SAFE_PADDED=y +CONFIG_USB_SERIAL_TI=m +CONFIG_USB_SERIAL_CYBERJACK=m +CONFIG_USB_SERIAL_XIRCOM=m +CONFIG_USB_SERIAL_OMNINET=m +CONFIG_USB_EZUSB=y # # USB Miscellaneous drivers # -# CONFIG_USB_EMI62 is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_LEGOTOWER is not set -# CONFIG_USB_LCD is not set -# CONFIG_USB_LED is not set -# CONFIG_USB_CYTHERM is not set -# CONFIG_USB_PHIDGETKIT is not set -# CONFIG_USB_PHIDGETSERVO is not set -# CONFIG_USB_IDMOUSE is not set -# CONFIG_USB_SISUSBVGA is not set -# CONFIG_USB_LD is not set -# CONFIG_USB_TEST is not set +CONFIG_USB_EMI62=m +CONFIG_USB_EMI26=m +CONFIG_USB_AUERSWALD=m +CONFIG_USB_RIO500=m +CONFIG_USB_LEGOTOWER=m +CONFIG_USB_LCD=m +CONFIG_USB_LED=m +CONFIG_USB_CYTHERM=m +CONFIG_USB_PHIDGETKIT=m +CONFIG_USB_PHIDGETSERVO=m +CONFIG_USB_IDMOUSE=m +CONFIG_USB_LD=m +CONFIG_USB_TEST=m # # USB DSL modem support # -CONFIG_USB_ATM=m -CONFIG_USB_SPEEDTOUCH=m -# CONFIG_USB_CXACRU is not set -CONFIG_USB_UEAGLEATM=m -# CONFIG_USB_XUSBATM is not set # # USB Gadget Support @@ -1413,34 +1236,26 @@ CONFIG_USB_UEAGLEATM=m # # File systems # -CONFIG_EXT2_FS=m -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XIP is not set +# CONFIG_EXT2_FS is not set CONFIG_EXT3_FS=m # CONFIG_EXT3_FS_XATTR is not set CONFIG_JBD=m # CONFIG_JBD_DEBUG is not set -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_REISERFS_FS_XATTR is not set -CONFIG_JFS_FS=m -# CONFIG_JFS_POSIX_ACL is not set -# CONFIG_JFS_SECURITY is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_FS_POSIX_ACL is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +CONFIG_FS_POSIX_ACL=y CONFIG_XFS_FS=m +CONFIG_XFS_EXPORT=y # CONFIG_XFS_QUOTA is not set # CONFIG_XFS_SECURITY is not set # CONFIG_XFS_POSIX_ACL is not set # CONFIG_XFS_RT is not set # CONFIG_OCFS2_FS is not set -CONFIG_MINIX_FS=m -# CONFIG_ROMFS_FS is not set +# CONFIG_MINIX_FS is not set +CONFIG_ROMFS_FS=m CONFIG_INOTIFY=y # CONFIG_QUOTA is not set -# CONFIG_DNOTIFY is not set +CONFIG_DNOTIFY=y # CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_FUSE_FS is not set @@ -1455,26 +1270,28 @@ CONFIG_INOTIFY=y # DOS/FAT/NT Filesystems # CONFIG_FAT_FS=m -# CONFIG_MSDOS_FS is not set +CONFIG_MSDOS_FS=m CONFIG_VFAT_FS=m CONFIG_FAT_DEFAULT_CODEPAGE=437 CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -# CONFIG_NTFS_FS is not set +CONFIG_NTFS_FS=m +# CONFIG_NTFS_DEBUG is not set +CONFIG_NTFS_RW=y # # Pseudo filesystems # CONFIG_PROC_FS=y -# CONFIG_PROC_KCORE is not set +CONFIG_PROC_KCORE=y CONFIG_DEVFS_FS=y CONFIG_DEVFS_MOUNT=y -# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVFS_DEBUG=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y # CONFIG_RELAYFS_FS is not set -# CONFIG_CONFIGFS_FS is not set +CONFIG_CONFIGFS_FS=y # # Miscellaneous filesystems @@ -1490,15 +1307,12 @@ CONFIG_RAMFS=y CONFIG_JFFS2_FS=y CONFIG_JFFS2_FS_DEBUG=0 CONFIG_JFFS2_FS_WRITEBUFFER=y -# CONFIG_JFFS2_SUMMARY is not set -CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_SUMMARY=y +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set CONFIG_JFFS2_ZLIB=y CONFIG_JFFS2_RTIME=y # CONFIG_JFFS2_RUBIN is not set -# CONFIG_JFFS2_CMODE_NONE is not set -CONFIG_JFFS2_CMODE_PRIORITY=y -# CONFIG_JFFS2_CMODE_SIZE is not set -# CONFIG_CRAMFS is not set +CONFIG_CRAMFS=m CONFIG_SQUASHFS=y # CONFIG_SQUASHFS_EMBEDDED is not set CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 @@ -1512,24 +1326,32 @@ CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 # # Network File Systems # -CONFIG_NFS_FS=m +CONFIG_NFS_FS=y CONFIG_NFS_V3=y # CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=m +CONFIG_NFSD=y +CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set +CONFIG_NFSD_V4=y +CONFIG_NFSD_TCP=y +# CONFIG_ROOT_NFS is not set +CONFIG_LOCKD=y CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=y CONFIG_NFS_COMMON=y -CONFIG_SUNRPC=m -CONFIG_SUNRPC_GSS=m -CONFIG_RPCSEC_GSS_KRB5=m +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set CONFIG_SMB_FS=m # CONFIG_SMB_NLS_DEFAULT is not set CONFIG_CIFS=m -# CONFIG_CIFS_STATS is not set -# CONFIG_CIFS_XATTR is not set +CONFIG_CIFS_STATS=y +# CONFIG_CIFS_STATS2 is not set +CONFIG_CIFS_XATTR=y +CONFIG_CIFS_POSIX=y # CONFIG_CIFS_EXPERIMENTAL is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set @@ -1539,28 +1361,13 @@ CONFIG_CIFS=m # # Partition Types # -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y +# CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_KARMA_PARTITION is not set -# CONFIG_EFI_PARTITION is not set # # Native Language Support # -CONFIG_NLS=m +CONFIG_NLS=y CONFIG_NLS_DEFAULT="iso8859-1" CONFIG_NLS_CODEPAGE_437=m # CONFIG_NLS_CODEPAGE_737 is not set @@ -1610,11 +1417,11 @@ CONFIG_NLS_UTF8=m # Kernel hacking # # CONFIG_PRINTK_TIME is not set -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y # CONFIG_DEBUG_KERNEL is not set CONFIG_LOG_BUF_SHIFT=14 CONFIG_CROSSCOMPILE=y -CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 init=/etc/preinit noinitrd console=ttyS0,115200" +CONFIG_CMDLINE="init=/etc/preinit" # # Security options @@ -1627,29 +1434,29 @@ CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 init=/etc/preinit # CONFIG_CRYPTO=y CONFIG_CRYPTO_HMAC=y -# CONFIG_CRYPTO_NULL is not set -# CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_MD4=m +CONFIG_CRYPTO_MD5=y CONFIG_CRYPTO_SHA1=m -# CONFIG_CRYPTO_SHA256 is not set -# CONFIG_CRYPTO_SHA512 is not set -# CONFIG_CRYPTO_WP512 is not set -# CONFIG_CRYPTO_TGR192 is not set -CONFIG_CRYPTO_DES=m -# CONFIG_CRYPTO_BLOWFISH is not set -# CONFIG_CRYPTO_TWOFISH is not set -# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_SHA256=m +CONFIG_CRYPTO_SHA512=m +CONFIG_CRYPTO_WP512=m +CONFIG_CRYPTO_TGR192=m +CONFIG_CRYPTO_DES=y +CONFIG_CRYPTO_BLOWFISH=m +CONFIG_CRYPTO_TWOFISH=m +CONFIG_CRYPTO_SERPENT=m CONFIG_CRYPTO_AES=m -# CONFIG_CRYPTO_CAST5 is not set -# CONFIG_CRYPTO_CAST6 is not set -# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_CAST5=m +CONFIG_CRYPTO_CAST6=m +CONFIG_CRYPTO_TEA=m CONFIG_CRYPTO_ARC4=m -# CONFIG_CRYPTO_KHAZAD is not set -# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_KHAZAD=m +CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_DEFLATE=m CONFIG_CRYPTO_MICHAEL_MIC=m -# CONFIG_CRYPTO_CRC32C is not set -# CONFIG_CRYPTO_TEST is not set +CONFIG_CRYPTO_CRC32C=m +CONFIG_CRYPTO_TEST=m # # Hardware crypto devices @@ -1659,8 +1466,12 @@ CONFIG_CRYPTO_MICHAEL_MIC=m # Library routines # CONFIG_CRC_CCITT=m -CONFIG_CRC16=m +CONFIG_CRC16=y CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set +CONFIG_LIBCRC32C=m CONFIG_ZLIB_INFLATE=y CONFIG_ZLIB_DEFLATE=y +CONFIG_TEXTSEARCH=y +CONFIG_TEXTSEARCH_KMP=m +CONFIG_TEXTSEARCH_BM=m +CONFIG_TEXTSEARCH_FSM=m diff --git a/target/linux/au1000-2.6/patches/002-mtx1_flash_map.patch b/target/linux/au1000-2.6/patches/002-mtx1_flash_map.patch new file mode 100644 index 0000000000..9a6b05b146 --- /dev/null +++ b/target/linux/au1000-2.6/patches/002-mtx1_flash_map.patch @@ -0,0 +1,16 @@ +diff -urN linux-2.6.16.7/drivers/mtd/maps/alchemy-flash.c linux-2.6.16.7.new/drivers/mtd/maps/alchemy-flash.c +--- linux-2.6.16.7/drivers/mtd/maps/alchemy-flash.c 2006-04-17 23:53:25.000000000 +0200 ++++ linux-2.6.16.7.new/drivers/mtd/maps/alchemy-flash.c 2006-04-20 19:16:26.000000000 +0200 +@@ -105,6 +105,12 @@ + #define USE_LOCAL_ACCESSORS /* why? */ + #endif + ++#ifdef CONFIG_MIPS_MTX1 ++#define BOARD_MAP_NAME "MTX-1 Flash" ++#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */ ++#define BOARD_FLASH_WIDTH 4 /* 32-bits */ ++#endif ++ + static struct map_info alchemy_map = { + .name = BOARD_MAP_NAME, + }; diff --git a/target/linux/au1000-2.6/patches/003-zImage.patch b/target/linux/au1000-2.6/patches/003-zImage.patch new file mode 100644 index 0000000000..1d4c6ad5d1 --- /dev/null +++ b/target/linux/au1000-2.6/patches/003-zImage.patch @@ -0,0 +1,1364 @@ +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/au1xxx/head.S linux-2.6.16.7.new/arch/mips/boot/compressed/au1xxx/head.S +--- linux-2.6.16.7/arch/mips/boot/compressed/au1xxx/head.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/au1xxx/head.S 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,119 @@ ++/* ++ * arch/mips/kernel/head.S ++ * ++ * This file is subject to the terms and conditions of the GNU General Public ++ * License. See the file "COPYING" in the main directory of this archive ++ * for more details. ++ * ++ * Copyright (C) 1994, 1995 Waldorf Electronics ++ * Written by Ralf Baechle and Andreas Busse ++ * Copyright (C) 1995 - 1999 Ralf Baechle ++ * Copyright (C) 1996 Paul M. Antoine ++ * Modified for DECStation and hence R3000 support by Paul M. Antoine ++ * Further modifications by David S. Miller and Harald Koerfgen ++ * Copyright (C) 1999 Silicon Graphics, Inc. ++ * ++ * Head.S contains the MIPS exception handler and startup code. ++ * ++ ************************************************************************** ++ * 9 Nov, 2000. ++ * Added Cache Error exception handler and SBDDP EJTAG debug exception. ++ * ++ * Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com ++ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. ++ ************************************************************************** ++ */ ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define IndexInvalidate_I 0x00 ++#define IndexWriteBack_D 0x01 ++ ++ .set noreorder ++ .cprestore ++ LEAF(start) ++start: ++ bal locate ++ nop ++locate: ++ subu s8, ra, 8 /* Where we were loaded */ ++ la sp, (.stack + 8192) ++ ++ move s0, a0 /* Save boot rom start args */ ++ move s1, a1 ++ move s2, a2 ++ move s3, a3 ++ ++ la a0, start /* Where we were linked to run */ ++ ++ move a1, s8 ++ la a2, _edata ++ subu t1, a2, a0 ++ srl t1, t1, 2 ++ ++ /* copy text section */ ++ li t0, 0 ++1: lw v0, 0(a1) ++ nop ++ sw v0, 0(a0) ++ xor t0, t0, v0 ++ addu a0, 4 ++ bne a2, a0, 1b ++ addu a1, 4 ++ ++ /* Clear BSS */ ++ la a0, _edata ++ la a2, _end ++2: sw zero, 0(a0) ++ bne a2, a0, 2b ++ addu a0, 4 ++ ++ /* push the D-Cache and invalidate I-Cache */ ++ li k0, 0x80000000 # start address ++ li k1, 0x80004000 # end address (16KB I-Cache) ++ subu k1, 128 ++ ++1: ++ .set mips3 ++ cache IndexWriteBack_D, 0(k0) ++ cache IndexWriteBack_D, 32(k0) ++ cache IndexWriteBack_D, 64(k0) ++ cache IndexWriteBack_D, 96(k0) ++ cache IndexInvalidate_I, 0(k0) ++ cache IndexInvalidate_I, 32(k0) ++ cache IndexInvalidate_I, 64(k0) ++ cache IndexInvalidate_I, 96(k0) ++ .set mips0 ++ ++ bne k0, k1, 1b ++ addu k0, k0, 128 ++ /* done */ ++ ++ move a0, s8 /* load address */ ++ move a1, t1 /* length in words */ ++ move a2, t0 /* checksum */ ++ move a3, sp ++ ++ la ra, 1f ++ la k0, decompress_kernel ++ jr k0 ++ nop ++1: ++ ++ move a0, s0 ++ move a1, s1 ++ move a2, s2 ++ move a3, s3 ++ li k0, KERNEL_ENTRY ++ jr k0 ++ nop ++3: ++ b 3b ++ END(start) ++ .comm .stack,4096*2,4 +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/au1xxx/Makefile linux-2.6.16.7.new/arch/mips/boot/compressed/au1xxx/Makefile +--- linux-2.6.16.7/arch/mips/boot/compressed/au1xxx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/au1xxx/Makefile 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,110 @@ ++# arch/mips/boot/compressed/au1xxx/Makefile ++# ++# Makefile for AMD Alchemy Semiconductor Au1x based boards. ++# All of the boot loader code was derived from the ppc ++# boot code. ++# ++# Copyright 2001,2002 MontaVista Software Inc. ++# ++# Author: Mark A. Greer ++# mgreer@mvista.com ++# ++# Copyright 2004 Embedded Alley Solutions, Inc ++# Ported and modified for mips 2.6 support by ++# Pete Popov ++# ++# 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. ++ ++boot := arch/mips/boot ++compressed := $(boot)/compressed ++utils := $(compressed)/utils ++lib := $(compressed)/lib ++images := $(compressed)/images ++common := $(compressed)/common ++ ++######################################################################### ++# START BOARD SPECIFIC VARIABLES ++ ++# These two variables control where the zImage is stored ++# in flash and loaded in memory. It only controls how the srec ++# file is generated, the code is the same. ++RAM_RUN_ADDR = 0x81000000 ++ ++ifdef CONFIG_MIPS_XXS1500 ++FLASH_LOAD_ADDR = 0xBF000000 ++else ++FLASH_LOAD_ADDR = 0xBFD00000 ++endif ++ ++# These two variables specify the free ram region ++# that can be used for temporary malloc area ++AVAIL_RAM_START=0x80500000 ++AVAIL_RAM_END=0x80900000 ++ ++# This one must match the LOADADDR in arch/mips/Makefile! ++LOADADDR=0x80100000 ++ ++# WARNING WARNING WARNING ++# Note that with a LOADADDR of 0x80100000 and AVAIL_RAM_START of ++# 0x80500000, the max decompressed kernel size can be 4MB. Else we ++# start overwriting ourselve. You can change these vars as needed; ++# it would be much better if we just figured everything out on the fly. ++ ++# END BOARD SPECIFIC VARIABLES ++######################################################################### ++ ++OBJECTS := $(obj)/head.o $(common)/misc-common.o $(common)/misc-simple.o \ ++ $(common)/au1k_uart.o ++LIBS := $(lib)/lib.a ++ ++ENTRY := $(utils)/entry ++OFFSET := $(utils)/offset ++SIZE := $(utils)/size ++ ++LD_ARGS := -T $(compressed)/ld.script -Ttext $(RAM_RUN_ADDR) -Bstatic ++ ++ifdef CONFIG_CPU_LITTLE_ENDIAN ++OBJCOPY_ARGS = -O elf32-tradlittlemips ++else ++OBJCOPY_ARGS = -O elf32-tradbigmips ++endif ++ ++$(obj)/head.o: $(obj)/head.S $(TOPDIR)/vmlinux ++ $(CC) -I $(TOPDIR)/include $(AFLAGS) \ ++ -DKERNEL_ENTRY=$(shell sh $(ENTRY) $(NM) $(TOPDIR)/vmlinux ) \ ++ -c -o $*.o $< ++ ++$(common)/misc-simple.o: ++ $(CC) -I $(TOPDIR)/include $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ ++ -DAVAIL_RAM_START=$(AVAIL_RAM_START) \ ++ -DAVAIL_RAM_END=$(AVAIL_RAM_END) \ ++ -DLOADADDR=$(LOADADDR) \ ++ -DZIMAGE_SIZE=0 -c -o $@ $*.c ++ ++$(obj)/zvmlinux: $(OBJECTS) $(LIBS) $(srctree)/$(compressed)/ld.script $(images)/vmlinux.gz $(common)/dummy.o ++ $(OBJCOPY) \ ++ --add-section=.image=$(images)/vmlinux.gz \ ++ --set-section-flags=.image=contents,alloc,load,readonly,data \ ++ $(common)/dummy.o $(common)/image.o ++ $(LD) $(LD_ARGS) -o $@ $(OBJECTS) $(common)/image.o $(LIBS) ++ $(OBJCOPY) $(OBJCOPY_ARGS) $@ $@ -R __kcrctab -R __ksymtab_strings \ ++ -R .comment -R .stab -R .stabstr -R .initrd -R .sysmap ++ ++# Here we manipulate the image in order to get it the necessary ++# srecord file we need. ++zImage: $(obj)/zvmlinux ++ mv $(obj)/zvmlinux $(images)/zImage ++ $(OBJCOPY) -O srec $(images)/zImage $(images)/zImage.srec ++ $(OBJCOPY) -O binary $(images)/zImage $(images)/zImage.bin ++ ++zImage.flash: zImage ++ ( \ ++ flash=${FLASH_LOAD_ADDR} ; \ ++ ram=${RAM_RUN_ADDR} ; \ ++ adjust=$$[ $$flash - $$ram ] ; \ ++ $(OBJCOPY) -O srec --adjust-vma `printf '0x%08x' $$adjust` \ ++ $(images)/zImage $(images)/zImage.flash.srec ; \ ++ ) +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/common/au1k_uart.c linux-2.6.16.7.new/arch/mips/boot/compressed/common/au1k_uart.c +--- linux-2.6.16.7/arch/mips/boot/compressed/common/au1k_uart.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/common/au1k_uart.c 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,103 @@ ++/* ++ * BRIEF MODULE DESCRIPTION ++ * Simple Au1000 uart routines. ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * Author: MontaVista Software, Inc. ++ * ppopov@mvista.com or source@mvista.com ++ * ++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++#include ++#include ++#include ++#include "ns16550.h" ++ ++typedef unsigned char uint8; ++typedef unsigned int uint32; ++ ++#define UART16550_BAUD_2400 2400 ++#define UART16550_BAUD_4800 4800 ++#define UART16550_BAUD_9600 9600 ++#define UART16550_BAUD_19200 19200 ++#define UART16550_BAUD_38400 38400 ++#define UART16550_BAUD_57600 57600 ++#define UART16550_BAUD_115200 115200 ++ ++#define UART16550_PARITY_NONE 0 ++#define UART16550_PARITY_ODD 0x08 ++#define UART16550_PARITY_EVEN 0x18 ++#define UART16550_PARITY_MARK 0x28 ++#define UART16550_PARITY_SPACE 0x38 ++ ++#define UART16550_DATA_5BIT 0x0 ++#define UART16550_DATA_6BIT 0x1 ++#define UART16550_DATA_7BIT 0x2 ++#define UART16550_DATA_8BIT 0x3 ++ ++#define UART16550_STOP_1BIT 0x0 ++#define UART16550_STOP_2BIT 0x4 ++ ++/* It would be nice if we had a better way to do this. ++ * It could be a variable defined in one of the board specific files. ++ */ ++#undef UART_BASE ++#ifdef CONFIG_COGENT_CSB250 ++#define UART_BASE UART3_ADDR ++#else ++#define UART_BASE UART0_ADDR ++#endif ++ ++/* memory-mapped read/write of the port */ ++#define UART16550_READ(y) (au_readl(UART_BASE + y) & 0xff) ++#define UART16550_WRITE(y,z) (au_writel(z&0xff, UART_BASE + y)) ++ ++/* ++ * We use uart 0, which is already initialized by ++ * yamon. ++ */ ++volatile struct NS16550 * ++serial_init(int chan) ++{ ++ volatile struct NS16550 *com_port; ++ com_port = (struct NS16550 *) UART_BASE; ++ return (com_port); ++} ++ ++void ++serial_putc(volatile struct NS16550 *com_port, unsigned char c) ++{ ++ while ((UART16550_READ(UART_LSR)&0x40) == 0); ++ UART16550_WRITE(UART_TX, c); ++} ++ ++unsigned char ++serial_getc(volatile struct NS16550 *com_port) ++{ ++ while((UART16550_READ(UART_LSR) & 0x1) == 0); ++ return UART16550_READ(UART_RX); ++} ++ ++int ++serial_tstc(volatile struct NS16550 *com_port) ++{ ++ return((UART16550_READ(UART_LSR) & LSR_DR) != 0); ++} +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/common/dummy.c linux-2.6.16.7.new/arch/mips/boot/compressed/common/dummy.c +--- linux-2.6.16.7/arch/mips/boot/compressed/common/dummy.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/common/dummy.c 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,4 @@ ++int main(void) ++{ ++ return 0; ++} +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/common/Makefile linux-2.6.16.7.new/arch/mips/boot/compressed/common/Makefile +--- linux-2.6.16.7/arch/mips/boot/compressed/common/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/common/Makefile 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,14 @@ ++# ++# arch/mips/boot/compressed/common/Makefile ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++# ++# Tom Rini January 2001 ++# ++# Pete Popov, 2004 ++# ++ ++lib-y := misc-common.o no_initrd.o dummy.o ++lib-$(CONFIG_SOC_AU1X00) += au1k_uart.o +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/common/misc-common.c linux-2.6.16.7.new/arch/mips/boot/compressed/common/misc-common.c +--- linux-2.6.16.7/arch/mips/boot/compressed/common/misc-common.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/common/misc-common.c 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,434 @@ ++/* ++ * arch/mips/boot/compressed/common/misc-common.c ++ * ++ * Misc. bootloader code (almost) all platforms can use ++ * ++ * Author: Johnnie Peters ++ * Editor: Tom Rini ++ * ++ * Derived from arch/ppc/boot/prep/misc.c ++ * ++ * Ported by Pete Popov to ++ * support mips board(s). I also got rid of the vga console ++ * code. ++ * ++ * Copyright 2000-2001 MontaVista Software Inc. ++ * ++ * Ported to MIPS 2.6 by Pete Popov, ++ * ++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ */ ++ ++#include /* for va_ bits */ ++#include ++#include ++#include ++ ++extern char *avail_ram; ++extern char *end_avail; ++extern char _end[]; ++ ++void puts(const char *); ++void putc(const char c); ++void puthex(unsigned long val); ++void _bcopy(char *src, char *dst, int len); ++void gunzip(void *, int, unsigned char *, int *); ++static int _cvt(unsigned long val, char *buf, long radix, char *digits); ++ ++void _vprintk(void(*)(const char), const char *, va_list ap); ++ ++struct NS16550 *com_port; ++ ++int serial_tstc(volatile struct NS16550 *); ++unsigned char serial_getc(volatile struct NS16550 *); ++void serial_putc(volatile struct NS16550 *, unsigned char); ++ ++void pause(void) ++{ ++ puts("pause\n"); ++} ++ ++void exit(void) ++{ ++ puts("exit\n"); ++ while(1); ++} ++ ++int tstc(void) ++{ ++ return (serial_tstc(com_port)); ++} ++ ++int getc(void) ++{ ++ while (1) { ++ if (serial_tstc(com_port)) ++ return (serial_getc(com_port)); ++ } ++} ++ ++void ++putc(const char c) ++{ ++ serial_putc(com_port, c); ++ if ( c == '\n' ) ++ serial_putc(com_port, '\r'); ++} ++ ++void puts(const char *s) ++{ ++ char c; ++ while ( ( c = *s++ ) != '\0' ) { ++ serial_putc(com_port, c); ++ if ( c == '\n' ) serial_putc(com_port, '\r'); ++ } ++} ++ ++void error(char *x) ++{ ++ puts("\n\n"); ++ puts(x); ++ puts("\n\n -- System halted"); ++ ++ while(1); /* Halt */ ++} ++ ++static void *zalloc(unsigned size) ++{ ++ void *p = avail_ram; ++ ++ size = (size + 7) & -8; ++ avail_ram += size; ++ if (avail_ram > end_avail) { ++ puts("oops... out of memory\n"); ++ pause(); ++ } ++ return p; ++} ++ ++ ++#define HEAD_CRC 2 ++#define EXTRA_FIELD 4 ++#define ORIG_NAME 8 ++#define COMMENT 0x10 ++#define RESERVED 0xe0 ++ ++#define DEFLATED 8 ++ ++void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) ++{ ++ z_stream s; ++ int r, i, flags; ++ ++ /* skip header */ ++ i = 10; ++ flags = src[3]; ++ if (src[2] != Z_DEFLATED || (flags & RESERVED) != 0) { ++ puts("bad gzipped data\n"); ++ exit(); ++ } ++ if ((flags & EXTRA_FIELD) != 0) ++ i = 12 + src[10] + (src[11] << 8); ++ if ((flags & ORIG_NAME) != 0) ++ while (src[i++] != 0) ++ ; ++ if ((flags & COMMENT) != 0) ++ while (src[i++] != 0) ++ ; ++ if ((flags & HEAD_CRC) != 0) ++ i += 2; ++ if (i >= *lenp) { ++ puts("gunzip: ran out of data in header\n"); ++ exit(); ++ } ++ ++ /* Initialize ourself. */ ++ s.workspace = zalloc(zlib_inflate_workspacesize()); ++ r = zlib_inflateInit2(&s, -MAX_WBITS); ++ if (r != Z_OK) { ++ puts("zlib_inflateInit2 returned "); puthex(r); puts("\n"); ++ exit(); ++ } ++ s.next_in = src + i; ++ s.avail_in = *lenp - i; ++ s.next_out = dst; ++ s.avail_out = dstlen; ++ r = zlib_inflate(&s, Z_FINISH); ++ if (r != Z_OK && r != Z_STREAM_END) { ++ puts("inflate returned "); puthex(r); puts("\n"); ++ exit(); ++ } ++ *lenp = s.next_out - (unsigned char *) dst; ++ zlib_inflateEnd(&s); ++} ++ ++void ++puthex(unsigned long val) ++{ ++ ++ unsigned char buf[10]; ++ int i; ++ for (i = 7; i >= 0; i--) ++ { ++ buf[i] = "0123456789ABCDEF"[val & 0x0F]; ++ val >>= 4; ++ } ++ buf[8] = '\0'; ++ puts(buf); ++} ++ ++#define FALSE 0 ++#define TRUE 1 ++ ++void ++_printk(char const *fmt, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, fmt); ++ _vprintk(putc, fmt, ap); ++ va_end(ap); ++ return; ++} ++ ++#define is_digit(c) ((c >= '0') && (c <= '9')) ++ ++void ++_vprintk(void(*putc)(const char), const char *fmt0, va_list ap) ++{ ++ char c, sign, *cp = 0; ++ int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right; ++ char buf[32]; ++ long val; ++ while ((c = *fmt0++)) ++ { ++ if (c == '%') ++ { ++ c = *fmt0++; ++ left_prec = right_prec = pad_on_right = 0; ++ if (c == '-') ++ { ++ c = *fmt0++; ++ pad_on_right++; ++ } ++ if (c == '0') ++ { ++ zero_fill = TRUE; ++ c = *fmt0++; ++ } else ++ { ++ zero_fill = FALSE; ++ } ++ while (is_digit(c)) ++ { ++ left_prec = (left_prec * 10) + (c - '0'); ++ c = *fmt0++; ++ } ++ if (c == '.') ++ { ++ c = *fmt0++; ++ zero_fill++; ++ while (is_digit(c)) ++ { ++ right_prec = (right_prec * 10) + (c - '0'); ++ c = *fmt0++; ++ } ++ } else ++ { ++ right_prec = left_prec; ++ } ++ sign = '\0'; ++ switch (c) ++ { ++ case 'd': ++ case 'x': ++ case 'X': ++ val = va_arg(ap, long); ++ switch (c) ++ { ++ case 'd': ++ if (val < 0) ++ { ++ sign = '-'; ++ val = -val; ++ } ++ length = _cvt(val, buf, 10, "0123456789"); ++ break; ++ case 'x': ++ length = _cvt(val, buf, 16, "0123456789abcdef"); ++ break; ++ case 'X': ++ length = _cvt(val, buf, 16, "0123456789ABCDEF"); ++ break; ++ } ++ cp = buf; ++ break; ++ case 's': ++ cp = va_arg(ap, char *); ++ length = strlen(cp); ++ break; ++ case 'c': ++ c = va_arg(ap, long /*char*/); ++ (*putc)(c); ++ continue; ++ default: ++ (*putc)('?'); ++ } ++ pad = left_prec - length; ++ if (sign != '\0') ++ { ++ pad--; ++ } ++ if (zero_fill) ++ { ++ c = '0'; ++ if (sign != '\0') ++ { ++ (*putc)(sign); ++ sign = '\0'; ++ } ++ } else ++ { ++ c = ' '; ++ } ++ if (!pad_on_right) ++ { ++ while (pad-- > 0) ++ { ++ (*putc)(c); ++ } ++ } ++ if (sign != '\0') ++ { ++ (*putc)(sign); ++ } ++ while (length-- > 0) ++ { ++ (*putc)(c = *cp++); ++ if (c == '\n') ++ { ++ (*putc)('\r'); ++ } ++ } ++ if (pad_on_right) ++ { ++ while (pad-- > 0) ++ { ++ (*putc)(c); ++ } ++ } ++ } else ++ { ++ (*putc)(c); ++ if (c == '\n') ++ { ++ (*putc)('\r'); ++ } ++ } ++ } ++} ++ ++int ++_cvt(unsigned long val, char *buf, long radix, char *digits) ++{ ++ char temp[80]; ++ char *cp = temp; ++ int length = 0; ++ if (val == 0) ++ { /* Special case */ ++ *cp++ = '0'; ++ } else ++ while (val) ++ { ++ *cp++ = digits[val % radix]; ++ val /= radix; ++ } ++ while (cp != temp) ++ { ++ *buf++ = *--cp; ++ length++; ++ } ++ *buf = '\0'; ++ return (length); ++} ++ ++void ++_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base) ++{ ++ int i, c; ++ if ((unsigned int)s > (unsigned int)p) ++ { ++ s = (unsigned int)s - (unsigned int)p; ++ } ++ while (s > 0) ++ { ++ if (base) ++ { ++ _printk("%06X: ", (int)p - (int)base); ++ } else ++ { ++ _printk("%06X: ", p); ++ } ++ for (i = 0; i < 16; i++) ++ { ++ if (i < s) ++ { ++ _printk("%02X", p[i] & 0xFF); ++ } else ++ { ++ _printk(" "); ++ } ++ if ((i % 2) == 1) _printk(" "); ++ if ((i % 8) == 7) _printk(" "); ++ } ++ _printk(" |"); ++ for (i = 0; i < 16; i++) ++ { ++ if (i < s) ++ { ++ c = p[i] & 0xFF; ++ if ((c < 0x20) || (c >= 0x7F)) c = '.'; ++ } else ++ { ++ c = ' '; ++ } ++ _printk("%c", c); ++ } ++ _printk("|\n"); ++ s -= 16; ++ p += 16; ++ } ++} ++ ++void ++_dump_buf(unsigned char *p, int s) ++{ ++ _printk("\n"); ++ _dump_buf_with_offset(p, s, 0); ++} ++ ++/* ++ * Local variables: ++ * c-indent-level: 8 ++ * c-basic-offset: 8 ++ * tab-width: 8 ++ * End: ++ */ +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/common/misc-simple.c linux-2.6.16.7.new/arch/mips/boot/compressed/common/misc-simple.c +--- linux-2.6.16.7/arch/mips/boot/compressed/common/misc-simple.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/common/misc-simple.c 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,122 @@ ++/* ++ * arch/mips/zboot/common/misc-simple.c ++ * ++ * Misc. bootloader code for many machines. This assumes you have are using ++ * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory ++ * below 8MB is free. Finally, it assumes you have a NS16550-style uart for ++ * your serial console. If a machine meets these requirements, it can quite ++ * likely use this code during boot. ++ * ++ * Author: Matt Porter ++ * Derived from arch/ppc/boot/prep/misc.c ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * ++ * 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. ++ */ ++ ++#include ++#include ++#include ++ ++#include ++ ++#include "linux/zlib.h" ++ ++extern struct NS16550 *com_port; ++ ++char *avail_ram; ++char *end_avail; ++extern char _end[]; ++char *zimage_start; ++ ++#ifdef CONFIG_CMDLINE ++#define CMDLINE CONFIG_CMDLINE ++#else ++#define CMDLINE "" ++#endif ++char cmd_preset[] = CMDLINE; ++char cmd_buf[256]; ++char *cmd_line = cmd_buf; ++ ++/* The linker tells us where the image is. ++*/ ++extern unsigned char __image_begin, __image_end; ++extern unsigned char __ramdisk_begin, __ramdisk_end; ++unsigned long initrd_size; ++ ++extern void puts(const char *); ++extern void putc(const char c); ++extern void puthex(unsigned long val); ++extern void *memcpy(void * __dest, __const void * __src, ++ __kernel_size_t __n); ++extern void gunzip(void *, int, unsigned char *, int *); ++extern void udelay(long delay); ++extern int tstc(void); ++extern int getc(void); ++extern volatile struct NS16550 *serial_init(int chan); ++ ++void ++decompress_kernel(unsigned long load_addr, int num_words, ++ unsigned long cksum, unsigned long *sp) ++{ ++ extern unsigned long start; ++ int zimage_size; ++ ++ com_port = (struct NS16550 *)serial_init(0); ++ ++ initrd_size = (unsigned long)(&__ramdisk_end) - ++ (unsigned long)(&__ramdisk_begin); ++ ++ /* ++ * Reveal where we were loaded at and where we ++ * were relocated to. ++ */ ++ puts("loaded at: "); puthex(load_addr); ++ puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); ++ if ( (unsigned long)load_addr != (unsigned long)&start ) ++ { ++ puts("relocated to: "); puthex((unsigned long)&start); ++ puts(" "); ++ puthex((unsigned long)((unsigned long)&start + (4*num_words))); ++ puts("\n"); ++ } ++ ++ /* ++ * We link ourself to an arbitrary low address. When we run, we ++ * relocate outself to that address. __image_being points to ++ * the part of the image where the zImage is. -- Tom ++ */ ++ zimage_start = (char *)(unsigned long)(&__image_begin); ++ zimage_size = (unsigned long)(&__image_end) - ++ (unsigned long)(&__image_begin); ++ ++ /* ++ * The zImage and initrd will be between start and _end, so they've ++ * already been moved once. We're good to go now. -- Tom ++ */ ++ puts("zimage at: "); puthex((unsigned long)zimage_start); ++ puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); ++ puts("\n"); ++ ++ if ( initrd_size ) { ++ puts("initrd at: "); ++ puthex((unsigned long)(&__ramdisk_begin)); ++ puts(" "); puthex((unsigned long)(&__ramdisk_end));puts("\n"); ++ } ++ ++ /* assume the chunk below 8M is free */ ++ avail_ram = (char *)AVAIL_RAM_START; ++ end_avail = (char *)AVAIL_RAM_END; ++ ++ /* Display standard Linux/MIPS boot prompt for kernel args */ ++ puts("Uncompressing Linux at load address "); ++ puthex(LOADADDR); ++ puts("\n"); ++ /* I don't like this hard coded gunzip size (fixme) */ ++ gunzip((void *)LOADADDR, 0x400000, zimage_start, &zimage_size); ++ puts("Now booting the kernel\n"); ++} +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/common/no_initrd.c linux-2.6.16.7.new/arch/mips/boot/compressed/common/no_initrd.c +--- linux-2.6.16.7/arch/mips/boot/compressed/common/no_initrd.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/common/no_initrd.c 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,2 @@ ++char initrd_data[1]; ++int initrd_len = 0; +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/images/Makefile linux-2.6.16.7.new/arch/mips/boot/compressed/images/Makefile +--- linux-2.6.16.7/arch/mips/boot/compressed/images/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/images/Makefile 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,17 @@ ++ ++# ++# This dir holds all of the images for MIPS machines. ++# Tom Rini January 2001 ++# Pete Popov 2004 ++ ++extra-y := vmlinux.bin vmlinux.gz ++ ++OBJCOPYFLAGS_vmlinux.bin := -O binary ++$(obj)/vmlinux.bin: vmlinux FORCE ++ $(call if_changed,objcopy) ++ ++$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE ++ $(call if_changed,gzip) ++ ++# Files generated that shall be removed upon make clean ++clean-files := vmlinux* zImage* +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/include/nonstdio.h linux-2.6.16.7.new/arch/mips/boot/compressed/include/nonstdio.h +--- linux-2.6.16.7/arch/mips/boot/compressed/include/nonstdio.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/include/nonstdio.h 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,18 @@ ++/* ++ * Copyright (C) Paul Mackerras 1997. ++ * ++ * 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. ++ */ ++typedef int FILE; ++extern FILE *stdin, *stdout; ++#define NULL ((void *)0) ++#define EOF (-1) ++#define fopen(n, m) NULL ++#define fflush(f) 0 ++#define fclose(f) 0 ++extern char *fgets(); ++ ++#define perror(s) printf("%s: no files!\n", (s)) +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/include/ns16550.h linux-2.6.16.7.new/arch/mips/boot/compressed/include/ns16550.h +--- linux-2.6.16.7/arch/mips/boot/compressed/include/ns16550.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/include/ns16550.h 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,46 @@ ++/* ++ * NS16550 Serial Port ++ */ ++ ++/* ++ * Figure out which file will have the definitons of COMx ++ */ ++ ++/* Some machines have their uart registers 16 bytes apart. Most don't. ++ * TODO: Make this work like drivers/char/serial does - Tom */ ++#if !defined(UART_REG_PAD) ++#define UART_REG_PAD(x) ++#endif ++ ++struct NS16550 ++ { ++ unsigned char rbr; /* 0 */ ++ UART_REG_PAD(rbr) ++ unsigned char ier; /* 1 */ ++ UART_REG_PAD(ier) ++ unsigned char fcr; /* 2 */ ++ UART_REG_PAD(fcr) ++ unsigned char lcr; /* 3 */ ++ UART_REG_PAD(lcr) ++ unsigned char mcr; /* 4 */ ++ UART_REG_PAD(mcr) ++ unsigned char lsr; /* 5 */ ++ UART_REG_PAD(lsr) ++ unsigned char msr; /* 6 */ ++ UART_REG_PAD(msr) ++ unsigned char scr; /* 7 */ ++ }; ++ ++#define thr rbr ++#define iir fcr ++#define dll rbr ++#define dlm ier ++ ++#define LSR_DR 0x01 /* Data ready */ ++#define LSR_OE 0x02 /* Overrun */ ++#define LSR_PE 0x04 /* Parity error */ ++#define LSR_FE 0x08 /* Framing error */ ++#define LSR_BI 0x10 /* Break */ ++#define LSR_THRE 0x20 /* Xmit holding register empty */ ++#define LSR_TEMT 0x40 /* Xmitter empty */ ++#define LSR_ERR 0x80 /* Error */ +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/include/pb1000_serial.h linux-2.6.16.7.new/arch/mips/boot/compressed/include/pb1000_serial.h +--- linux-2.6.16.7/arch/mips/boot/compressed/include/pb1000_serial.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/include/pb1000_serial.h 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,20 @@ ++/* ++ * arch/ppc/boot/include/sandpoint_serial.h ++ * ++ * Location of the COM ports on Motorola SPS Sandpoint machines ++ * ++ * Author: Mark A. Greer ++ * mgreer@mvista.com ++ * ++ * Copyright 2001 MontaVista Software Inc. ++ * ++ * 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. ++ */ ++ ++#define COM1 0xfe0003f8 ++#define COM2 0xfe0002f8 ++#define COM3 0x00000000 /* No COM3 */ ++#define COM4 0x00000000 /* No COM4 */ +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/ld.script linux-2.6.16.7.new/arch/mips/boot/compressed/ld.script +--- linux-2.6.16.7/arch/mips/boot/compressed/ld.script 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/ld.script 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,151 @@ ++OUTPUT_ARCH(mips) ++ENTRY(start) ++SECTIONS ++{ ++ /* Read-only sections, merged into text segment: */ ++ /* . = 0x81000000; */ ++ .init : { *(.init) } =0 ++ .text : ++ { ++ _ftext = . ; ++ *(.text) ++ *(.rodata) *(.rodata.*) ++ *(.rodata1) ++ /* .gnu.warning sections are handled specially by elf32.em. */ ++ *(.gnu.warning) ++ } =0 ++ .kstrtab : { *(.kstrtab) } ++ ++ . = ALIGN(16); /* Exception table */ ++ __start___ex_table = .; ++ __ex_table : { *(__ex_table) } ++ __stop___ex_table = .; ++ ++ __start___dbe_table = .; /* Exception table for data bus errors */ ++ __dbe_table : { *(__dbe_table) } ++ __stop___dbe_table = .; ++ ++ __start___ksymtab = .; /* Kernel symbol table */ ++ __ksymtab : { *(__ksymtab) } ++ __stop___ksymtab = .; ++ ++ _etext = .; ++ ++ . = ALIGN(8192); ++ .data.init_task : { *(.data.init_task) } ++ ++ /* Startup code */ ++ . = ALIGN(4096); ++ __init_begin = .; ++ .text.init : { *(.text.init) } ++ .data.init : { *(.data.init) } ++ . = ALIGN(16); ++ __setup_start = .; ++ .setup.init : { *(.setup.init) } ++ __setup_end = .; ++ __initcall_start = .; ++ .initcall.init : { *(.initcall.init) } ++ __initcall_end = .; ++ . = ALIGN(4096); /* Align double page for init_task_union */ ++ __init_end = .; ++ ++ . = ALIGN(4096); ++ .data.page_aligned : { *(.data.idt) } ++ ++ . = ALIGN(32); ++ .data.cacheline_aligned : { *(.data.cacheline_aligned) } ++ ++ .fini : { *(.fini) } =0 ++ .reginfo : { *(.reginfo) } ++ /* Adjust the address for the data segment. We want to adjust up to ++ the same address within the page on the next page up. It would ++ be more correct to do this: ++ . = .; ++ The current expression does not correctly handle the case of a ++ text segment ending precisely at the end of a page; it causes the ++ data segment to skip a page. The above expression does not have ++ this problem, but it will currently (2/95) cause BFD to allocate ++ a single segment, combining both text and data, for this case. ++ This will prevent the text segment from being shared among ++ multiple executions of the program; I think that is more ++ important than losing a page of the virtual address space (note ++ that no actual memory is lost; the page which is skipped can not ++ be referenced). */ ++ . = .; ++ .data : ++ { ++ _fdata = . ; ++ *(.data) ++ ++ /* Put the compressed image here, so bss is on the end. */ ++ __image_begin = .; ++ *(.image) ++ __image_end = .; ++ /* Align the initial ramdisk image (INITRD) on page boundaries. */ ++ . = ALIGN(4096); ++ __ramdisk_begin = .; ++ *(.initrd) ++ __ramdisk_end = .; ++ . = ALIGN(4096); ++ ++ CONSTRUCTORS ++ } ++ .data1 : { *(.data1) } ++ _gp = . + 0x8000; ++ .lit8 : { *(.lit8) } ++ .lit4 : { *(.lit4) } ++ .ctors : { *(.ctors) } ++ .dtors : { *(.dtors) } ++ .got : { *(.got.plt) *(.got) } ++ .dynamic : { *(.dynamic) } ++ /* We want the small data sections together, so single-instruction offsets ++ can access them all, and initialized data all before uninitialized, so ++ we can shorten the on-disk segment size. */ ++ .sdata : { *(.sdata) } ++ . = ALIGN(4); ++ _edata = .; ++ PROVIDE (edata = .); ++ ++ __bss_start = .; ++ _fbss = .; ++ .sbss : { *(.sbss) *(.scommon) } ++ .bss : ++ { ++ *(.dynbss) ++ *(.bss) ++ *(COMMON) ++ . = ALIGN(4); ++ _end = . ; ++ PROVIDE (end = .); ++ } ++ ++ /* Sections to be discarded */ ++ /DISCARD/ : ++ { ++ *(.text.exit) ++ *(.data.exit) ++ *(.exitcall.exit) ++ } ++ ++ /* This is the MIPS specific mdebug section. */ ++ .mdebug : { *(.mdebug) } ++ /* These are needed for ELF backends which have not yet been ++ converted to the new style linker. */ ++ .stab 0 : { *(.stab) } ++ .stabstr 0 : { *(.stabstr) } ++ /* DWARF debug sections. ++ Symbols in the .debug DWARF section are relative to the beginning of the ++ section so we begin .debug at 0. It's not clear yet what needs to happen ++ for the others. */ ++ .debug 0 : { *(.debug) } ++ .debug_srcinfo 0 : { *(.debug_srcinfo) } ++ .debug_aranges 0 : { *(.debug_aranges) } ++ .debug_pubnames 0 : { *(.debug_pubnames) } ++ .debug_sfnames 0 : { *(.debug_sfnames) } ++ .line 0 : { *(.line) } ++ /* These must appear regardless of . */ ++ .gptab.sdata : { *(.gptab.data) *(.gptab.sdata) } ++ .gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) } ++ .comment : { *(.comment) } ++ .note : { *(.note) } ++} +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/lib/Makefile linux-2.6.16.7.new/arch/mips/boot/compressed/lib/Makefile +--- linux-2.6.16.7/arch/mips/boot/compressed/lib/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/lib/Makefile 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,11 @@ ++ ++# ++# Makefile for some libs needed by zImage. ++# ++ ++lib-y := $(addprefix ../../../../../lib/zlib_inflate/, \ ++ infblock.o infcodes.o inffast.o inflate.o inftrees.o infutil.o) \ ++ $(addprefix ../../../../../lib/, ctype.o string.o) \ ++ $(addprefix ../../../../../arch/mips/lib/, memcpy.o) \ ++ ++ +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/Makefile linux-2.6.16.7.new/arch/mips/boot/compressed/Makefile +--- linux-2.6.16.7/arch/mips/boot/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/Makefile 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,32 @@ ++ ++# ++# arch/mips/boot/compressed/Makefile ++# ++# This file is subject to the terms and conditions of the GNU General Public ++# License. See the file "COPYING" in the main directory of this archive ++# for more details. ++# ++# Copyright (C) 1994 by Linus Torvalds ++# Adapted for PowerPC by Gary Thomas ++# modified by Cort (cort@cs.nmt.edu) ++# ++# Ported to MIPS by Pete Popov, ppopov@embeddedalley.com ++# ++ ++boot := arch/mips/boot ++compressed := arch/mips/boot/compressed ++ ++CFLAGS += -fno-builtin -D__BOOTER__ -I$(compressed)/include ++ ++BOOT_TARGETS = zImage zImage.flash ++ ++bootdir-$(CONFIG_SOC_AU1X00) := au1xxx ++subdir-y := common lib images ++ ++.PHONY: $(BOOT_TARGETS) $(bootdir-y) ++ ++$(BOOT_TARGETS): $(bootdir-y) ++ ++$(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ ++ $(addprefix $(obj)/,$(hostprogs-y)) ++ $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/utils/entry linux-2.6.16.7.new/arch/mips/boot/compressed/utils/entry +--- linux-2.6.16.7/arch/mips/boot/compressed/utils/entry 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/utils/entry 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,12 @@ ++#!/bin/sh ++ ++# grab the kernel_entry address from the vmlinux elf image ++entry=`$1 $2 | grep kernel_entry` ++ ++fs=`echo $entry | grep ffffffff` # check toolchain output ++ ++if [ -n "$fs" ]; then ++ echo "0x"`$1 $2 | grep kernel_entry | cut -c9- | awk '{print $1}'` ++else ++ echo "0x"`$1 $2 | grep kernel_entry | cut -c1- | awk '{print $1}'` ++fi +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/utils/offset linux-2.6.16.7.new/arch/mips/boot/compressed/utils/offset +--- linux-2.6.16.7/arch/mips/boot/compressed/utils/offset 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/utils/offset 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,3 @@ ++#!/bin/sh ++ ++echo "0x"`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'` +diff -urN linux-2.6.16.7/arch/mips/boot/compressed/utils/size linux-2.6.16.7.new/arch/mips/boot/compressed/utils/size +--- linux-2.6.16.7/arch/mips/boot/compressed/utils/size 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/boot/compressed/utils/size 2006-05-04 23:08:18.000000000 +0200 +@@ -0,0 +1,4 @@ ++#!/bin/sh ++ ++OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'` ++echo "0x"$OFFSET +diff -urN linux-2.6.16.7/arch/mips/boot/Makefile linux-2.6.16.7.new/arch/mips/boot/Makefile +--- linux-2.6.16.7/arch/mips/boot/Makefile 2006-04-17 23:53:25.000000000 +0200 ++++ linux-2.6.16.7.new/arch/mips/boot/Makefile 2006-05-04 23:08:18.000000000 +0200 +@@ -16,6 +16,7 @@ + E2EFLAGS = + endif + ++ + # + # Drop some uninteresting sections in the kernel. + # This is only relevant for ELF kernels but doesn't hurt a.out +@@ -25,7 +26,10 @@ + + VMLINUX = vmlinux + +-all: vmlinux.ecoff vmlinux.srec addinitrd ++ZBOOT_TARGETS = zImage zImage.flash ++bootdir-y := compressed ++ ++all: vmlinux.ecoff vmlinux.srec addinitrd zImage + + vmlinux.ecoff: $(obj)/elf2ecoff $(VMLINUX) + $(obj)/elf2ecoff $(VMLINUX) vmlinux.ecoff $(E2EFLAGS) +@@ -51,3 +55,11 @@ + vmlinux.bin \ + vmlinux.ecoff \ + vmlinux.srec ++ ++.PHONY: $(ZBOOT_TARGETS) $(bootdir-y) ++ ++$(ZBOOT_TARGETS): $(bootdir-y) ++ ++$(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ ++ $(addprefix $(obj)/,$(hostprogs-y)) ++ $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) +diff -urN linux-2.6.16.7/arch/mips/Makefile linux-2.6.16.7.new/arch/mips/Makefile +--- linux-2.6.16.7/arch/mips/Makefile 2006-04-17 23:53:25.000000000 +0200 ++++ linux-2.6.16.7.new/arch/mips/Makefile 2006-05-04 23:09:44.000000000 +0200 +@@ -831,6 +831,10 @@ + all: vmlinux.ecoff + endif + ++ifdef CONFIG_MIPS_MTX1 ++all: vmlinux.srec zImage zImage.flash ++endif ++ + vmlinux.bin: $(vmlinux-32) + +@$(call makeboot,$@) + +@@ -840,6 +844,12 @@ + vmlinux.srec: $(vmlinux-32) + +@$(call makeboot,$@) + ++zImage: vmlinux ++ +@$(call makeboot,$@) ++ ++zImage.flash: vmlinux ++ +@$(call makeboot,$@) ++ + CLEAN_FILES += vmlinux.ecoff \ + vmlinux.srec \ + vmlinux.rm200.tmp \ +@@ -848,6 +858,7 @@ + archclean: + @$(MAKE) $(clean)=arch/mips/boot + @$(MAKE) $(clean)=arch/mips/lasat ++ @$(MAKE) $(clean)=arch/mips/boot/compressed + + CLEAN_FILES += vmlinux.32 \ + vmlinux.64 \ diff --git a/target/linux/au1000-2.6/patches/004-mtx1_watchdog.patch b/target/linux/au1000-2.6/patches/004-mtx1_watchdog.patch new file mode 100644 index 0000000000..c7e329b295 --- /dev/null +++ b/target/linux/au1000-2.6/patches/004-mtx1_watchdog.patch @@ -0,0 +1,279 @@ +diff -urN linux-2.6.16.7/drivers/char/watchdog/Kconfig linux-2.6.16.7.new/drivers/char/watchdog/Kconfig +--- linux-2.6.16.7/drivers/char/watchdog/Kconfig 2006-04-17 23:53:25.000000000 +0200 ++++ linux-2.6.16.7.new/drivers/char/watchdog/Kconfig 2006-04-22 23:23:53.000000000 +0200 +@@ -460,6 +460,14 @@ + timer expired and no process has written to /dev/watchdog during + that time. + ++config MTX1_WATCHDOG ++ tristate "MTX-1 Hardware Watchdog" ++ depends on WATCHDOG && MIPS_MTX1 ++ help ++ Hardware driver for the AccessCube MTX-1 watchdog. This is a ++ watchdog timer that will reboot the machine after a 100 seconds ++ timer expired. ++ + # S390 Architecture + + config ZVM_WATCHDOG +diff -urN linux-2.6.16.7/drivers/char/watchdog/Makefile linux-2.6.16.7.new/drivers/char/watchdog/Makefile +--- linux-2.6.16.7/drivers/char/watchdog/Makefile 2006-04-17 23:53:25.000000000 +0200 ++++ linux-2.6.16.7.new/drivers/char/watchdog/Makefile 2006-04-22 23:21:18.000000000 +0200 +@@ -65,6 +65,7 @@ + + # MIPS Architecture + obj-$(CONFIG_INDYDOG) += indydog.o ++obj-$(CONFIG_MTX1_WATCHDOG) += mtx-1_watchdog.o + + # S390 Architecture + +diff -urN linux-2.6.16.7/drivers/char/watchdog/mtx-1_watchdog.c linux-2.6.16.7.new/drivers/char/watchdog/mtx-1_watchdog.c +--- linux-2.6.16.7/drivers/char/watchdog/mtx-1_watchdog.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/drivers/char/watchdog/mtx-1_watchdog.c 2006-04-22 23:20:53.000000000 +0200 +@@ -0,0 +1,246 @@ ++/* ++ * Driver for the MTX-1 Watchdog. ++ * ++ * (c) Copyright 2005 4G Systems , All Rights Reserved. ++ * http://www.4g-systems.biz ++ * ++ * 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. ++ * ++ * Neither Michael Stickel nor 4G Systems admit liability nor provide ++ * warranty for any of this software. This material is provided ++ * "AS-IS" and at no charge. ++ * ++ * (c) Copyright 2005 4G Systems ++ * ++ * Release 0.01. ++ * ++ * Author: Michael Stickel michael.stickel@4g-systems.biz ++ * ++ * ++ * The Watchdog is configured to reset the MTX-1 ++ * if it is not triggered for 100 seconds. ++ * It should not be triggered more often than 1.6 seconds. ++ * ++ * A timer triggers the watchdog every 5 seconds, until ++ * it is opened for the first time. After the first open ++ * it MUST be triggered every 2..95 seconds. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#ifndef FALSE ++# define FALSE (0) ++#endif ++ ++#ifndef TRUE ++# define TRUE (!FALSE) ++#endif ++ ++ ++//---------[ Hardware Functions ]----------------- ++ ++static void mtx1_trigger_wd (void) ++{ ++ /* ++ * toggle GPIO2_15 ++ */ ++ ++ u32 tmp = au_readl(GPIO2_DIR); ++ tmp = (tmp & ~(1<<15)) | ((~tmp) & (1<<15)); ++ au_writel (tmp, GPIO2_DIR); ++} ++ ++static void mtx1_enable_wd (void) ++{ ++ au_writel (au_readl(GPIO2_DIR) | (u32)(1<<15), GPIO2_DIR); ++} ++ ++static void mtx1_disable_wd (void) ++{ ++ au_writel (au_readl(GPIO2_DIR) & ~((u32)(1<<15)), GPIO2_DIR); ++} ++ ++ ++//---------[ Timer Functions ]----------------- ++ ++static struct timer_list wd_trigger_timer; ++static char timer_is_running = FALSE; ++ ++static void wd_timer_callback (unsigned long data) ++{ ++ if (timer_is_running) ++ mod_timer (&wd_trigger_timer, jiffies + 5 * HZ); ++ mtx1_trigger_wd(); ++} ++ ++static void start_wd_timer (void) ++{ ++ if (!timer_is_running) { ++ struct timer_list *t = &wd_trigger_timer; ++ ++ init_timer (t); ++ t->function = wd_timer_callback; ++ t->data = (unsigned long)0L; ++ t->expires = jiffies + 5 * HZ; // 5 seconds. ++ add_timer (t); ++ timer_is_running = TRUE; ++ } ++} ++ ++ ++ ++static void stop_wd_timer (void) ++{ ++ if (timer_is_running) { ++ del_timer(&wd_trigger_timer); ++ timer_is_running = FALSE; ++ } ++} ++ ++ ++//---------[ File Functions ]----------------- ++ ++static char restart_after_close; ++ ++static int mtx1wd_open (struct inode *inode, struct file *file) ++{ ++ if (MINOR(inode->i_rdev) != WATCHDOG_MINOR) return -ENODEV; ++ //MOD_INC_USE_COUNT; ++ ++ // stop the timer, if it is running. It will not be ++ // started again, until the module is loaded again. ++ stop_wd_timer(); ++ ++ // sleep for 2 seconds, to ensure, that the wd is ++ // not triggered more often than every 2 seconds. ++ schedule_timeout (2 * HZ); ++ ++ return 0; ++} ++ ++ ++static int mtx1wd_release (struct inode *inode, struct file *file) { ++ if (MINOR(inode->i_rdev)==WATCHDOG_MINOR) { ++ } ++ if (restart_after_close) ++ start_wd_timer(); ++ //MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++ ++static ssize_t mtx1wd_write (struct file *file, const char *buf, size_t count, loff_t *ppos) { ++ ++ mtx1_trigger_wd (); ++ ++ if (count > 0) { ++ char buffer[10]; ++ int n = (count>9)?9:count; ++ ++ if (copy_from_user (&buffer, buf, n)) ++ return -EFAULT; ++ buffer[n]=0; ++ ++ if (count >= 4 && strncmp("auto", buffer, 4)==0) ++ restart_after_close = 1; ++ ++ else if (count >= 6 && strncmp("manual", buffer, 6)==0) ++ restart_after_close = 0; ++ ++ return n; ++ } ++ ++ return 0; ++} ++ ++static ssize_t mtx1wd_read (struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ char * state = restart_after_close ? "auto\n" : "manual\n"; ++ int n = strlen(state)+1; ++ ++ if (file->f_pos >= n) ++ return 0; ++ ++ if (count < n) ++ return -EINVAL; ++ ++ if(copy_to_user(buf, state, n)) ++ return -EFAULT; ++ ++ file->f_pos += n; ++ ++ return n; ++} ++ ++static struct file_operations mtx1wd_fops = { ++ .owner = THIS_MODULE, ++ .read = mtx1wd_read, ++ .write = mtx1wd_write, ++ .open = mtx1wd_open, ++ .release = mtx1wd_release ++}; ++ ++ ++static struct miscdevice mtx1wd_miscdev = { ++ WATCHDOG_MINOR, ++ "watchdog", ++ &mtx1wd_fops ++}; ++ ++ ++ ++//---------[ Module Functions ]----------------- ++ ++ ++static int __init init_mtx1_watchdog(void) ++{ ++ printk("MTX-1 watchdog driver\n"); ++ ++ misc_register(&mtx1wd_miscdev); ++ ++ restart_after_close = 0; ++ ++ mtx1_enable_wd (); ++ ++ //-- trigger it for the first time. ++ //-- We do not exactly know how long it has not been triggered. ++ mtx1_trigger_wd (); ++ ++ // start a timer, that calls mtx1_trigger_wd every 5 seconds. ++ start_wd_timer(); ++ ++ return 0; ++} ++ ++static void __exit exit_mtx1_watchdog(void) { ++ ++ // stop the timer, if it is running. ++ stop_wd_timer(); ++ ++ misc_deregister(&mtx1wd_miscdev); ++ ++ mtx1_disable_wd(); ++} ++ ++module_init(init_mtx1_watchdog); ++module_exit(exit_mtx1_watchdog); ++ ++MODULE_AUTHOR("Michael Stickel"); ++MODULE_DESCRIPTION("Driver for the MTX-1 watchdog"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/au1000-2.6/patches/005-au1000_eth_link_beat.patch b/target/linux/au1000-2.6/patches/005-au1000_eth_link_beat.patch new file mode 100644 index 0000000000..946bd84540 --- /dev/null +++ b/target/linux/au1000-2.6/patches/005-au1000_eth_link_beat.patch @@ -0,0 +1,24 @@ +diff -urN linux-2.6.16.7/drivers/net/au1000_eth.c linux-2.6.16.7.new/drivers/net/au1000_eth.c +--- linux-2.6.16.7/drivers/net/au1000_eth.c 2006-04-17 23:53:25.000000000 +0200 ++++ linux-2.6.16.7.new/drivers/net/au1000_eth.c 2006-04-23 01:42:48.000000000 +0200 +@@ -12,6 +12,9 @@ + * Author: MontaVista Software, Inc. + * ppopov@mvista.com or source@mvista.com + * ++ * Bjoern Riemer 2004 ++ * riemer@fokus.fraunhofer.de or riemer@riemer-nt.de ++ * // fixed the link beat detection with ioctls (SIOCGMIIPHY) + * ######################################################################## + * + * This program is free software; you can distribute it and/or modify it +@@ -1672,6 +1675,10 @@ + aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed); + control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE; + #ifndef CONFIG_CPU_LITTLE_ENDIAN ++ /*riemer: fix for startup without cable */ ++ if (!link) ++ dev->flags &= ~IFF_RUNNING; ++ + control |= MAC_BIG_ENDIAN; + #endif + if (link && (dev->if_port == IF_PORT_100BASEFX)) { diff --git a/target/linux/au1000-2.6/patches/006-mtx1_system_button.patch b/target/linux/au1000-2.6/patches/006-mtx1_system_button.patch new file mode 100644 index 0000000000..511df2c8da --- /dev/null +++ b/target/linux/au1000-2.6/patches/006-mtx1_system_button.patch @@ -0,0 +1,241 @@ +diff -urN linux-2.6.16.7/arch/mips/au1000/mtx-1/irqmap.c linux-2.6.16.7.new/arch/mips/au1000/mtx-1/irqmap.c +--- linux-2.6.16.7/arch/mips/au1000/mtx-1/irqmap.c 2006-04-17 23:53:25.000000000 +0200 ++++ linux-2.6.16.7.new/arch/mips/au1000/mtx-1/irqmap.c 2006-04-23 11:54:31.000000000 +0200 +@@ -64,6 +64,7 @@ + { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 }, + { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 }, ++ { AU1500_GPIO_207, INTC_INT_RISE_AND_FALL_EDGE, 0 }, + }; + + int au1xxx_nr_irqs = sizeof(au1xxx_irq_map)/sizeof(au1xxx_irq_map_t); +diff -urN linux-2.6.16.7/arch/mips/au1000/mtx-1/Makefile linux-2.6.16.7.new/arch/mips/au1000/mtx-1/Makefile +--- linux-2.6.16.7/arch/mips/au1000/mtx-1/Makefile 2006-04-17 23:53:25.000000000 +0200 ++++ linux-2.6.16.7.new/arch/mips/au1000/mtx-1/Makefile 2006-04-23 14:01:36.000000000 +0200 +@@ -8,3 +8,4 @@ + # + + lib-y := init.o board_setup.o irqmap.o ++obj-y := mtx-1_sysbtn.o +diff -urN linux-2.6.16.7/arch/mips/au1000/mtx-1/mtx-1_sysbtn.c linux-2.6.16.7.new/arch/mips/au1000/mtx-1/mtx-1_sysbtn.c +--- linux-2.6.16.7/arch/mips/au1000/mtx-1/mtx-1_sysbtn.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.7.new/arch/mips/au1000/mtx-1/mtx-1_sysbtn.c 2006-04-23 14:01:17.000000000 +0200 +@@ -0,0 +1,218 @@ ++/* ++ * Driver for the MTX-1 System Button. ++ * ++ * (c) Copyright 2005 4G Systems , All Rights Reserved. ++ * http://www.4g-systems.biz ++ * ++ * 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. ++ * ++ * Neither Michael Stickel nor 4G Systeme GmbH admit liability nor provide ++ * warranty for any of this software. This material is provided ++ * "AS-IS" and at no charge. ++ * ++ * (c) Copyright 2005 4G Systems ++ * ++ * Release 0.01. ++ * ++ * Author: Michael Stickel michael.stickel@4g-systems.biz ++ * ++ * ++ * After the module is loaded there is a device /dev/misc/btn ++ * that can be read. It returns one char '1' if the button ++ * has been pressed an '0' if it has been released. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include ++ ++ ++#ifndef FALSE ++# define FALSE (0) ++#endif ++ ++#ifndef TRUE ++# define TRUE (!FALSE) ++#endif ++ ++ ++//---------[ declarations ]----------------- ++ ++ ++static DECLARE_WAIT_QUEUE_HEAD(mtx1btn_wait_queue); ++static char state_changed; ++static char last_value; ++static char is_inuse; ++ ++ ++//---------[ Hardware Functions ]----------------- ++ ++// The MTX-1 Button is attached to GPIO207. ++#define MTX1_GPIO2_SYSBTN (7) ++#define MTX1_SYSBTN_IRQ (AU1500_GPIO_207) ++ ++ ++static char mtx1_getbtn (int btnno) ++{ ++ if (btnno==0) { ++ return (au_readl(GPIO2_PINSTATE) & (1<i_rdev)!=mtx1sysbtn_minor) return -ENODEV; ++ if (is_inuse) return -EBUSY; ++ is_inuse=1; ++ last_value = mtx1_getbtn(0); ++ state_changed = 0; ++ return 0; ++} ++ ++ ++static int mtx1sysbtn_release (struct inode *inode, struct file *file) { ++ if (MINOR(inode->i_rdev)==mtx1sysbtn_minor) { ++ is_inuse=0; ++ } ++ return 0; ++} ++ ++ ++static ssize_t mtx1sysbtn_read (struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ if (count < 1) ++ return -EINVAL; ++ if (!state_changed) ++ interruptible_sleep_on (&mtx1btn_wait_queue); ++ state_changed = 0; ++ char c = last_value ? '1' : '0'; /* mtx1_getbtn(0) */ ++ if(copy_to_user(buf, &c, 1)) ++ return -EFAULT; ++ return 1; ++} ++ ++ ++static unsigned int mtx1sysbtn_poll (struct file *file, poll_table * wait) ++{ ++ unsigned int mask = 0; ++ ++ poll_wait (file, &mtx1btn_wait_queue, wait); ++ ++ if (state_changed) // state changed since last time. ++ mask |= POLLIN | POLLRDNORM; ++ ++ return mask; ++} ++ ++ ++static struct file_operations mtx1sysbtn_fops = { ++ .owner = THIS_MODULE, ++ .read = mtx1sysbtn_read, ++ .poll = mtx1sysbtn_poll, ++ .open = mtx1sysbtn_open, ++ .release = mtx1sysbtn_release ++}; ++ ++ ++static struct miscdevice mtx1sysbtn_miscdev = { ++ MISC_DYNAMIC_MINOR /* SYSBTN_MINOR */ , ++ "btn", ++ &mtx1sysbtn_fops ++}; ++ ++ ++ ++//---------[ Module Functions ]----------------- ++ ++ ++void __exit exit_mtx1_sysbtn (void) ++{ ++ is_inuse = 1; ++ mtx1_btn_stopirq (); ++ misc_deregister(&mtx1sysbtn_miscdev); ++} ++ ++ ++static int __init init_mtx1_sysbtn (void) ++{ ++ printk("MTX-1 System Button driver\n"); ++ is_inuse = 1; ++ mtx1_initbuttons (); ++ if (misc_register (&mtx1sysbtn_miscdev) >= 0) { ++ mtx1sysbtn_minor = mtx1sysbtn_miscdev.minor; ++ if (mtx1_btn_startirq () == 0) { ++ is_inuse=0; ++ return 0; ++ } ++ misc_deregister(&mtx1sysbtn_miscdev); ++ } ++ return 1; ++} ++ ++module_init(init_mtx1_sysbtn); ++module_exit(exit_mtx1_sysbtn); ++ ++MODULE_AUTHOR("Michael Stickel"); ++MODULE_DESCRIPTION("Driver for the MTX-1 system button"); ++MODULE_LICENSE("GPL"); diff --git a/target/linux/au1000-2.6/patches/007-mtx1_sio2.patch b/target/linux/au1000-2.6/patches/007-mtx1_sio2.patch new file mode 100644 index 0000000000..34d1005347 --- /dev/null +++ b/target/linux/au1000-2.6/patches/007-mtx1_sio2.patch @@ -0,0 +1,13 @@ +--- linux-2.6.16.7/arch/mips/au1000/mtx-1/board_setup.c 2006-04-17 23:53:25.000000000 +0200 ++++ linux-2.6.16.7.new/arch/mips/au1000/mtx-1/board_setup.c 2006-04-23 14:35:42.000000000 +0200 +@@ -71,9 +71,7 @@ + #endif + + // initialize sys_pinfunc: +- // disable second ethernet port (SYS_PF_NI2) +- // set U3/GPIO23 to GPIO23 (SYS_PF_U3) +- au_writel( SYS_PF_NI2 | SYS_PF_U3, SYS_PINFUNC ); ++ au_writel( SYS_PF_NI2, SYS_PINFUNC ); + + // initialize GPIO + au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); diff --git a/target/linux/au1000-2.6/patches/008-isdel_cardbus.patch b/target/linux/au1000-2.6/patches/008-isdel_cardbus.patch new file mode 100644 index 0000000000..9e54ac1c59 --- /dev/null +++ b/target/linux/au1000-2.6/patches/008-isdel_cardbus.patch @@ -0,0 +1,63 @@ +diff -urN linux-2.6.16.7/arch/mips/au1000/mtx-1/board_setup.c linux-2.6.16.7.new/arch/mips/au1000/mtx-1/board_setup.c +--- linux-2.6.16.7/arch/mips/au1000/mtx-1/board_setup.c 2006-04-23 14:39:21.000000000 +0200 ++++ linux-2.6.16.7.new/arch/mips/au1000/mtx-1/board_setup.c 2006-04-23 14:39:03.000000000 +0200 +@@ -44,6 +44,9 @@ + #include + #include + ++extern int (*board_pci_idsel)(unsigned int devsel, int assert); ++int mtx1_pci_idsel(unsigned int devsel, int assert); ++ + void board_reset (void) + { + /* Hit BCSR.SYSTEM_CONTROL[SW_RST] */ +@@ -77,11 +80,37 @@ + au_writel( 0xFFFFFFFF, SYS_TRIOUTCLR ); + au_writel( 0x00000001, SYS_OUTPUTCLR ); // set M66EN (PCI 66MHz) to OFF + au_writel( 0x00000008, SYS_OUTPUTSET ); // set PCI CLKRUN# to OFF ++ au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON + au_writel( 0x00000020, SYS_OUTPUTCLR ); // set eth PHY TX_ER to OFF + + // enable LED and set it to green + au_writel( au_readl(GPIO2_DIR) | 0x1800, GPIO2_DIR ); + au_writel( 0x18000800, GPIO2_OUTPUT ); + ++ board_pci_idsel = mtx1_pci_idsel; ++ + printk("4G Systems MTX-1 Board\n"); + } ++ ++int ++mtx1_pci_idsel(unsigned int devsel, int assert) ++{ ++#define MTX_IDSEL_ONLY_0_AND_3 0 ++#if MTX_IDSEL_ONLY_0_AND_3 ++ if (devsel != 0 && devsel != 3) { ++ printk("*** not 0 or 3\n"); ++ return 0; ++ } ++#endif ++ ++ if (assert && devsel != 0) { ++ // supress signal to cardbus ++ au_writel( 0x00000002, SYS_OUTPUTCLR ); // set EXT_IO3 OFF ++ } ++ else { ++ au_writel( 0x00000002, SYS_OUTPUTSET ); // set EXT_IO3 ON ++ } ++ au_sync_udelay(1); ++ return 1; ++} ++ +diff -urN linux-2.6.16.7/arch/mips/au1000/mtx-1/irqmap.c linux-2.6.16.7.new/arch/mips/au1000/mtx-1/irqmap.c +--- linux-2.6.16.7/arch/mips/au1000/mtx-1/irqmap.c 2006-04-23 14:40:54.000000000 +0200 ++++ linux-2.6.16.7.new/arch/mips/au1000/mtx-1/irqmap.c 2006-04-23 14:40:12.000000000 +0200 +@@ -48,7 +48,7 @@ + #include + + char irq_tab_alchemy[][5] __initdata = { +- [0] = { -1, INTA, INTB, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */ ++ [0] = { -1, INTA, INTA, INTX, INTX}, /* IDSEL 00 - AdapterA-Slot0 (top) */ + [1] = { -1, INTB, INTA, INTX, INTX}, /* IDSEL 01 - AdapterA-Slot1 (bottom) */ + [2] = { -1, INTC, INTD, INTX, INTX}, /* IDSEL 02 - AdapterB-Slot0 (top) */ + [3] = { -1, INTD, INTC, INTX, INTX}, /* IDSEL 03 - AdapterB-Slot1 (bottom) */ diff --git a/target/linux/au1000-2.6/patches/009-boot.patch b/target/linux/au1000-2.6/patches/009-boot.patch new file mode 100644 index 0000000000..611c70d460 --- /dev/null +++ b/target/linux/au1000-2.6/patches/009-boot.patch @@ -0,0 +1,15 @@ +diff -Nur linux-cvs/arch/mips/kernel/head.S linux-aruba/arch/mips/kernel/head.S +--- linux-cvs/arch/mips/kernel/head.S 2004-12-23 00:21:39.000000000 -0800 ++++ linux-aruba/arch/mips/kernel/head.S 2005-10-20 09:16:08.000000000 -0700 +@@ -122,6 +122,10 @@ + #endif + .endm + ++ ++ j kernel_entry ++ nop ++ + /* + * Reserved space for exception handlers. + * Necessary for machines which link their kernels at KSEG0. + diff --git a/target/linux/brcm-2.4/Config.in b/target/linux/brcm-2.4/Config.in index 181014f7b3..c766a45c3d 100644 --- a/target/linux/brcm-2.4/Config.in +++ b/target/linux/brcm-2.4/Config.in @@ -6,13 +6,3 @@ config PACKAGE_KMOD_BRCM_WL help Proprietary driver for Broadcom Wireless chipsets -config PACKAGE_KMOD_BRCM_WL2 - prompt "kmod-brcm-wl2..................... Broadcom Wireless Network Driver (new)" - tristate - depends LINUX_2_4_BRCM - default m - help - Proprietary driver for Broadcom Wireless chipsets - New version with Multi-BSS capability - - diff --git a/target/linux/brcm-2.4/Makefile b/target/linux/brcm-2.4/Makefile index 06da0ac010..9447114d4e 100644 --- a/target/linux/brcm-2.4/Makefile +++ b/target/linux/brcm-2.4/Makefile @@ -12,10 +12,6 @@ $(eval $(call KMOD_template,BRCM_WL,brcm-wl,\ $(MODULES_DIR)/kernel/drivers/net/wl/wl.o \ ,CONFIG_WL,,20,wl)) -$(eval $(call KMOD_template,BRCM_WL2,brcm-wl2,\ - $(MODULES_DIR)/kernel/drivers/net/wl2/wl.o \ -,CONFIG_WL,,20,wl)) - $(eval $(call KMOD_template,LP,lp,\ $(MODULES_DIR)/kernel/drivers/parport/parport.o \ $(MODULES_DIR)/kernel/drivers/parport/parport_splink.o \ @@ -38,10 +34,10 @@ $(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked # Proprietary driver for BCM43xx ############################################### -LINUX_BINARY_DRIVER_SITE=http://openwrt.org/downloads/sources +LINUX_BINARY_DRIVER_SITE=http://downloads.openwrt.org/sources # proprietary driver, extracted from Linksys GPL sourcetree WRT54GS 4.70.6 -LINUX_BINARY_WL_DRIVER=kernel-binary-wl-0.6.tar.gz -LINUX_BINARY_WL_MD5SUM=4fc1d5b46bcb7a17d6d5dd31da9c8d7f +LINUX_BINARY_WL_DRIVER=kernel-binary-wl-0.7.tar.gz +LINUX_BINARY_WL_MD5SUM=ff50130914790cbae9b73a13513da5ee $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER): $(SCRIPT_DIR)/download.pl $(DL_DIR) $(LINUX_BINARY_WL_DRIVER) $(LINUX_BINARY_WL_MD5SUM) $(LINUX_BINARY_DRIVER_SITE) @@ -56,18 +52,15 @@ $(LINUX_DIR)/.drivers-unpacked: $(LINUX_DIR)/.unpacked zcat $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) - # copy binary wlan driver mkdir -p $(LINUX_DIR)/drivers/net/wl - $(CP) $(BUILD_DIR)/kernel-binary-wl/old/*.o $(LINUX_DIR)/drivers/net/wl - $(CP) $(BUILD_DIR)/kernel-binary-wl/new/*.o $(LINUX_DIR)/drivers/net/wl2 + $(CP) $(BUILD_DIR)/kernel-binary-wl/*.o $(LINUX_DIR)/drivers/net/wl touch $@ $(LINUX_DIR)/.drivers-installed: $(LINUX_DIR)/.modules_done mkdir -p $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl - mkdir -p $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl2 @-[ -f $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/wl.o ] || $(CP) $(LINUX_DIR)/drivers/net/wl/wl.o $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/ - @-[ -f $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl2/wl.o ] || $(CP) $(LINUX_DIR)/drivers/net/wl2/wl.o $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl2/ touch $@ linux-dirclean: drivers-clean drivers-clean: - rm -rf $(BUILD_DIR)/wl + rm -rf $(BUILD_DIR)/kernel-binary-wl diff --git a/target/linux/brcm-2.4/config b/target/linux/brcm-2.4/config index 9759b90f5f..c4cf5340ea 100644 --- a/target/linux/brcm-2.4/config +++ b/target/linux/brcm-2.4/config @@ -833,7 +833,6 @@ CONFIG_NET_RADIO=y # CONFIG_AIRO is not set # CONFIG_HERMES is not set CONFIG_WL=m -CONFIG_WL2=m # CONFIG_PLX_HERMES is not set # CONFIG_TMD_HERMES is not set # CONFIG_PCI_HERMES is not set diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch index d662b4c015..af82c3c770 100644 --- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch +++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -1,6 +1,6 @@ -diff -Naur linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile ---- linux.old/arch/mips/Makefile 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/arch/mips/Makefile 2006-04-06 15:34:15.000000000 +0200 +diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile +--- linux.old/arch/mips/Makefile 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/arch/mips/Makefile 2006-04-27 19:24:19.000000000 +0200 @@ -726,6 +726,19 @@ endif @@ -29,10 +29,10 @@ diff -Naur linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile archmrproper: @$(MAKEBOOT) mrproper -diff -Naur linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Makefile +diff -urN linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Makefile --- linux.old/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/Makefile 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,15 @@ ++++ linux.dev/arch/mips/bcm947xx/Makefile 2006-05-02 17:46:22.000000000 +0200 +@@ -0,0 +1,17 @@ +# +# Makefile for the BCM947xx specific kernel interface routines +# under Linux. @@ -42,1216 +42,1489 @@ diff -Naur linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Ma + +O_TARGET := bcm947xx.o + -+export-objs := nvram_linux.o setup.o ++export-objs := export.o +obj-y := prom.o setup.o time.o sbmips.o gpio.o +obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o ++obj-y += sbutils.o bcmutils.o bcmsrom.o hndchipc.o +obj-$(CONFIG_PCI) += sbpci.o pcibios.o ++obj-y += export.o + +include $(TOPDIR)/Rules.make -diff -Naur linux.old/arch/mips/bcm947xx/cfe_env.c linux.dev/arch/mips/bcm947xx/cfe_env.c ---- linux.old/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/cfe_env.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,234 @@ +diff -urN linux.old/arch/mips/bcm947xx/bcmsrom.c linux.dev/arch/mips/bcm947xx/bcmsrom.c +--- linux.old/arch/mips/bcm947xx/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/bcmsrom.c 2006-04-27 20:32:48.000000000 +0200 +@@ -0,0 +1,1212 @@ +/* -+ * NVRAM variable manipulation (Linux kernel half) ++ * Misc useful routines to access NIC SROM/OTP . + * -+ * Copyright 2001-2003, Broadcom Corporation ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ ++ * $Id: bcmsrom.c,v 1.1.1.14 2006/04/15 01:28:25 michael Exp $ + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ +#include ++#include +#include -+#include +#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+#define NVRAM_SIZE (0x1ff0) -+static char _nvdata[NVRAM_SIZE] __initdata; -+static char _valuestr[256] __initdata; -+ -+/* -+ * TLV types. These codes are used in the "type-length-value" -+ * encoding of the items stored in the NVRAM device (flash or EEPROM) -+ * -+ * The layout of the flash/nvram is as follows: -+ * -+ * -+ * -+ * The type code of "ENV_TLV_TYPE_END" marks the end of the list. -+ * The "length" field marks the length of the data section, not -+ * including the type and length fields. -+ * -+ * Environment variables are stored as follows: -+ * -+ * = -+ * -+ * If bit 0 (low bit) is set, the length is an 8-bit value. -+ * If bit 0 (low bit) is clear, the length is a 16-bit value -+ * -+ * Bit 7 set indicates "user" TLVs. In this case, bit 0 still -+ * indicates the size of the length field. -+ * -+ * Flags are from the constants below: -+ * -+ */ -+#define ENV_LENGTH_16BITS 0x00 /* for low bit */ -+#define ENV_LENGTH_8BITS 0x01 ++/* debug/trace */ ++#if defined(WLTEST) ++#define BS_ERROR(args) printf args ++#else ++#define BS_ERROR(args) ++#endif /* BCMDBG_ERR || WLTEST */ + -+#define ENV_TYPE_USER 0x80 ++#define VARS_MAX 4096 /* should be reduced */ + -+#define ENV_CODE_SYS(n,l) (((n)<<1)|(l)) -+#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER) ++#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */ ++#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */ + -+/* -+ * The actual TLV types we support -+ */ ++static int initvars_srom_pci(void *sbh, void *curmap, char **vars, uint *count); ++static int initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, uint *count); ++static int initvars_flash_sb(void *sbh, char **vars, uint *count); ++static int srom_parsecis(osl_t *osh, uint8 **pcis, uint ciscnt, char **vars, uint *count); ++static int sprom_cmd_pcmcia(osl_t *osh, uint8 cmd); ++static int sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data); ++static int sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data); ++static int sprom_read_pci(osl_t *osh, uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, ++ bool check_crc); + -+#define ENV_TLV_TYPE_END 0x00 -+#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS) ++static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count); ++static int initvars_flash(osl_t *osh, char **vp, uint len, char *devpath); + +/* -+ * Environment variable flags ++ * Initialize local vars from the right source for this platform. ++ * Return 0 on success, nonzero on error. + */ ++int ++srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, uint *count) ++{ ++ ASSERT(bustype == BUSTYPE(bustype)); ++ if (vars == NULL || count == NULL) ++ return (0); + -+#define ENV_FLG_NORMAL 0x00 /* normal read/write */ -+#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */ -+#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */ ++ switch (BUSTYPE(bustype)) { ++ case SB_BUS: ++ case JTAG_BUS: ++ return initvars_flash_sb(sbh, vars, count); + -+#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */ -+#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */ ++ case PCI_BUS: ++ ASSERT(curmap); /* can not be NULL */ ++ return initvars_srom_pci(sbh, curmap, vars, count); + ++ case PCMCIA_BUS: ++ return initvars_cis_pcmcia(sbh, osh, vars, count); + -+/* ********************************************************************* -+ * _nvram_read(buffer,offset,length) -+ * -+ * Read data from the NVRAM device -+ * -+ * Input parameters: -+ * buffer - destination buffer -+ * offset - offset of data to read -+ * length - number of bytes to read -+ * -+ * Return value: -+ * number of bytes read, or <0 if error occured -+ ********************************************************************* */ -+static int -+_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length) -+{ -+ int i; -+ if (offset > NVRAM_SIZE) -+ return -1; + -+ for ( i = 0; i < length; i++) { -+ buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i]; -+ } -+ return length; ++ default: ++ ASSERT(0); ++ } ++ return (-1); +} + -+ -+static char* -+_strnchr(const char *dest,int c,size_t cnt) ++/* support only 16-bit word read from srom */ ++int ++srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) +{ -+ while (*dest && (cnt > 0)) { -+ if (*dest == c) return (char *) dest; -+ dest++; -+ cnt--; -+ } -+ return NULL; -+} ++ void *srom; ++ uint i, off, nw; + ++ ASSERT(bustype == BUSTYPE(bustype)); + ++ /* check input - 16-bit access only */ ++ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) ++ return 1; + -+/* -+ * Core support API: Externally visible. -+ */ ++ off = byteoff / 2; ++ nw = nbytes / 2; + -+/* -+ * Get the value of an NVRAM variable -+ * @param name name of variable to get -+ * @return value of variable or NULL if undefined -+ */ ++ if (BUSTYPE(bustype) == PCI_BUS) { ++ if (!curmap) ++ return 1; ++ srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET; ++ if (sprom_read_pci(osh, srom, off, buf, nw, FALSE)) ++ return 1; ++ } else if (BUSTYPE(bustype) == PCMCIA_BUS) { ++ for (i = 0; i < nw; i++) { ++ if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i))) ++ return 1; ++ } ++ } else { ++ return 1; ++ } + -+char* -+cfe_env_get(unsigned char *nv_buf, char* name) ++ return 0; ++} ++ ++/* support only 16-bit word write into srom */ ++int ++srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) +{ -+ int size; -+ unsigned char *buffer; -+ unsigned char *ptr; -+ unsigned char *envval; -+ unsigned int reclen; -+ unsigned int rectype; -+ int offset; -+ int flg; -+ -+ size = NVRAM_SIZE; -+ buffer = &_nvdata[0]; ++ uint16 *srom; ++ uint i, nw, crc_range; ++ uint16 image[SPROM_SIZE]; ++ uint8 crc; ++ volatile uint32 val32; + -+ ptr = buffer; -+ offset = 0; ++ ASSERT(bustype == BUSTYPE(bustype)); + -+ /* Read the record type and length */ -+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { -+ goto error; -+ } -+ -+ while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) { ++ /* check input - 16-bit access only */ ++ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) ++ return 1; + -+ /* Adjust pointer for TLV type */ -+ rectype = *(ptr); -+ offset++; -+ size--; ++ /* Are we writing the whole thing at once? */ ++ if ((byteoff == 0) && ++ ((nbytes == SPROM_SIZE) || ++ (nbytes == (SPROM_CRC_RANGE * 2)) || ++ (nbytes == (SROM4_WORDS * 2)))) { ++ crc_range = nbytes; ++ bcopy((void*)buf, (void*)image, nbytes); ++ nw = nbytes / 2; ++ } else { ++ if ((BUSTYPE(bustype) == PCMCIA_BUS) || (BUSTYPE(bustype) == SDIO_BUS)) ++ crc_range = SPROM_SIZE; ++ else ++ crc_range = SPROM_CRC_RANGE * 2; /* Tentative */ + -+ /* -+ * Read the length. It can be either 1 or 2 bytes -+ * depending on the code -+ */ -+ if (rectype & ENV_LENGTH_8BITS) { -+ /* Read the record type and length - 8 bits */ -+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { -+ goto error; -+ } -+ reclen = *(ptr); -+ size--; -+ offset++; -+ } -+ else { -+ /* Read the record type and length - 16 bits, MSB first */ -+ if (_nvram_read(nv_buf, ptr,offset,2) != 2) { -+ goto error; -+ } -+ reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1); -+ size -= 2; -+ offset += 2; ++ nw = crc_range / 2; ++ /* read first 64 words from srom */ ++ if (srom_read(bustype, curmap, osh, 0, nw * 2, image)) ++ return 1; ++ if (image[SROM4_SIGN] == SROM4_SIGNATURE) { ++ crc_range = SROM4_WORDS; ++ nw = crc_range / 2; ++ if (srom_read(bustype, curmap, osh, 0, nw * 2, image)) ++ return 1; ++ } ++ /* make changes */ ++ bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes); + } + -+ if (reclen > size) -+ break; /* should not happen, bad NVRAM */ ++ /* calculate crc */ ++ htol16_buf(image, crc_range); ++ crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE); ++ ltoh16_buf(image, crc_range); ++ image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff); + -+ switch (rectype) { -+ case ENV_TLV_TYPE_ENV: -+ /* Read the TLV data */ -+ if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen) -+ goto error; -+ flg = *ptr++; -+ envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1)); -+ if (envval) { -+ *envval++ = '\0'; -+ memcpy(_valuestr,envval,(reclen-1)-(envval-ptr)); -+ _valuestr[(reclen-1)-(envval-ptr)] = '\0'; -+#if 0 -+ printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr); -+#endif -+ if(!strcmp(ptr, name)){ -+ return _valuestr; -+ } -+ if((strlen(ptr) > 1) && !strcmp(&ptr[1], name)) -+ return _valuestr; -+ } -+ break; -+ -+ default: -+ /* Unknown TLV type, skip it. */ -+ break; -+ } -+ -+ /* -+ * Advance to next TLV -+ */ -+ -+ size -= (int)reclen; -+ offset += reclen; -+ -+ /* Read the next record type */ -+ ptr = buffer; -+ if (_nvram_read(nv_buf, ptr,offset,1) != 1) -+ goto error; ++ if (BUSTYPE(bustype) == PCI_BUS) { ++ srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET); ++ /* enable writes to the SPROM */ ++ val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); ++ val32 |= SPROM_WRITEEN; ++ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32); ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ /* write srom */ ++ for (i = 0; i < nw; i++) { ++ W_REG(osh, &srom[i], image[i]); ++ bcm_mdelay(WRITE_WORD_DELAY); ++ } ++ /* disable writes to the SPROM */ ++ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ++ ~SPROM_WRITEEN); ++ } else if (BUSTYPE(bustype) == PCMCIA_BUS) { ++ /* enable writes to the SPROM */ ++ if (sprom_cmd_pcmcia(osh, SROM_WEN)) ++ return 1; ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ /* write srom */ ++ for (i = 0; i < nw; i++) { ++ sprom_write_pcmcia(osh, (uint16)(i), image[i]); ++ bcm_mdelay(WRITE_WORD_DELAY); ++ } ++ /* disable writes to the SPROM */ ++ if (sprom_cmd_pcmcia(osh, SROM_WDS)) ++ return 1; ++ } else { ++ return 1; + } + -+error: -+ return NULL; -+ ++ bcm_mdelay(WRITE_ENABLE_DELAY); ++ return 0; +} + -diff -Naur linux.old/arch/mips/bcm947xx/compressed/Makefile linux.dev/arch/mips/bcm947xx/compressed/Makefile ---- linux.old/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/compressed/Makefile 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,33 @@ -+# -+# Makefile for Broadcom BCM947XX boards -+# -+# Copyright 2001-2003, Broadcom Corporation -+# All Rights Reserved. -+# -+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+# -+# $Id: Makefile,v 1.2 2005/04/02 12:12:57 wbx Exp $ -+# -+ -+OBJCOPY_ARGS = -O binary -R .reginfo -R .note -R .comment -R .mdebug -S -+SYSTEM ?= $(TOPDIR)/vmlinux + -+all: vmlinuz ++static int ++srom_parsecis(osl_t *osh, uint8 **pcis, uint ciscnt, char **vars, uint *count) ++{ ++ char eabuf[32]; ++ char *vp, *base; ++ uint8 *cis, tup, tlen, sromrev = 1; ++ int i, j; ++ uint varsize; ++ bool ag_init = FALSE; ++ uint32 w32; + -+# Don't build dependencies, this may die if $(CC) isn't gcc -+dep: ++ ASSERT(vars); ++ ASSERT(count); + -+# Create a gzipped version named vmlinuz for compatibility -+vmlinuz: piggy -+ gzip -c9 $< > $@ ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return -2; + -+piggy: $(SYSTEM) -+ $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ ++ while (ciscnt--) { ++ cis = *pcis++; ++ i = 0; ++ do { ++ tup = cis[i++]; ++ tlen = cis[i++]; ++ if ((i + tlen) >= CIS_SIZE) ++ break; + -+mrproper: clean ++ switch (tup) { ++ case CISTPL_MANFID: ++ vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]); ++ vp++; ++ vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]); ++ vp++; ++ break; + -+clean: -+ rm -f vmlinuz piggy -diff -Naur linux.old/arch/mips/bcm947xx/generic/Makefile linux.dev/arch/mips/bcm947xx/generic/Makefile ---- linux.old/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/generic/Makefile 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,15 @@ -+# -+# Makefile for the BCM947xx specific kernel interface routines -+# under Linux. -+# ++ case CISTPL_FUNCE: ++ switch (cis[i]) { ++ case LAN_NID: ++ ASSERT(cis[i + 1] == 6); ++ bcm_ether_ntoa((struct ether_addr *)&cis[i + 2], eabuf); ++ vp += sprintf(vp, "il0macaddr=%s", eabuf); ++ vp++; ++ break; ++ case 1: /* SDIO Extended Data */ ++ vp += sprintf(vp, "sdmaxblk=%d", ++ (cis[i + 13] << 8) | cis[i + 12]); ++ vp++; ++ break; ++ } ++ break; + -+.S.s: -+ $(CPP) $(AFLAGS) $< -o $*.s -+.S.o: -+ $(CC) $(AFLAGS) -c $< -o $*.o ++ case CISTPL_CFTABLE: ++ vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]); ++ vp++; ++ break; + -+O_TARGET := brcm.o ++ case CISTPL_BRCM_HNBU: ++ switch (cis[i]) { ++ case HNBU_SROMREV: ++ sromrev = cis[i + 1]; ++ break; + -+obj-y := int-handler.o irq.o ++ case HNBU_CHIPID: ++ vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + ++ cis[i + 1]); ++ vp++; ++ vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + ++ cis[i + 3]); ++ vp++; ++ if (tlen == 7) { ++ vp += sprintf(vp, "chiprev=%d", ++ (cis[i + 6] << 8) + cis[i + 5]); ++ vp++; ++ } ++ break; + -+include $(TOPDIR)/Rules.make -diff -Naur linux.old/arch/mips/bcm947xx/generic/int-handler.S linux.dev/arch/mips/bcm947xx/generic/int-handler.S ---- linux.old/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/generic/int-handler.S 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,51 @@ -+/* -+ * Generic interrupt handler for Broadcom MIPS boards -+ * -+ * Copyright 2004, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id: int-handler.S,v 1.1 2005/03/16 13:50:00 wbx Exp $ -+ */ ++ case HNBU_BOARDREV: ++ vp += sprintf(vp, "boardrev=%d", cis[i + 1]); ++ vp++; ++ break; + -+#include ++ case HNBU_AA: ++ vp += sprintf(vp, "aa2g=%d", cis[i + 1]); ++ vp++; ++ break; + -+#include -+#include -+#include -+#include ++ case HNBU_AG: ++ vp += sprintf(vp, "ag0=%d", cis[i + 1]); ++ vp++; ++ ag_init = TRUE; ++ break; + -+/* -+ * MIPS IRQ Source -+ * -------- ------ -+ * 0 Software (ignored) -+ * 1 Software (ignored) -+ * 2 Combined hardware interrupt (hw0) -+ * 3 Hardware -+ * 4 Hardware -+ * 5 Hardware -+ * 6 Hardware -+ * 7 R4k timer -+ */ ++ case HNBU_CC: ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "cc=%d", cis[i + 1]); ++ vp++; ++ break; + -+ .text -+ .set noreorder -+ .set noat -+ .align 5 -+ NESTED(brcmIRQ, PT_SIZE, sp) -+ SAVE_ALL -+ CLI -+ .set at -+ .set noreorder ++ case HNBU_PAPARMS: ++ if (tlen == 2) { ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 1]); ++ vp++; ++ } else if (tlen >= 9) { ++ if (tlen == 10) { ++ ASSERT(sromrev == 2); ++ vp += sprintf(vp, "opo=%d", cis[i + 9]); ++ vp++; ++ } else ++ ASSERT(tlen == 9); ++ ++ for (j = 0; j < 3; j++) { ++ vp += sprintf(vp, "pa0b%d=%d", j, ++ (cis[i + (j * 2) + 2] << 8) + ++ cis[i + (j * 2) + 1]); ++ vp++; ++ } ++ vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]); ++ vp++; ++ vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 8]); ++ vp++; ++ } else ++ ASSERT(tlen >= 9); ++ break; + -+ jal brcm_irq_dispatch -+ move a0, sp ++ case HNBU_OEM: ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", ++ cis[i + 1], cis[i + 2], ++ cis[i + 3], cis[i + 4], ++ cis[i + 5], cis[i + 6], ++ cis[i + 7], cis[i + 8]); ++ vp++; ++ break; + -+ j ret_from_irq -+ nop -+ -+ END(brcmIRQ) -diff -Naur linux.old/arch/mips/bcm947xx/generic/irq.c linux.dev/arch/mips/bcm947xx/generic/irq.c ---- linux.old/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/generic/irq.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,130 @@ -+/* -+ * Generic interrupt control functions for Broadcom MIPS boards -+ * -+ * Copyright 2004, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id: irq.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ -+ */ ++ case HNBU_BOARDFLAGS: ++ w32 = (cis[i + 2] << 8) + cis[i + 1]; ++ if (tlen == 5) ++ w32 |= (cis[i + 4] << 24) + (cis[i + 3] << 16); ++ vp += sprintf(vp, "boardflags=0x%x", w32); ++ vp++; ++ break; + -+#include -+#include -+#include -+#include -+#include -+#include ++ case HNBU_LEDS: ++ if (cis[i + 1] != 0xff) { ++ vp += sprintf(vp, "ledbh0=%d", cis[i + 1]); ++ vp++; ++ } ++ if (cis[i + 2] != 0xff) { ++ vp += sprintf(vp, "ledbh1=%d", cis[i + 2]); ++ vp++; ++ } ++ if (cis[i + 3] != 0xff) { ++ vp += sprintf(vp, "ledbh2=%d", cis[i + 3]); ++ vp++; ++ } ++ if (cis[i + 4] != 0xff) { ++ vp += sprintf(vp, "ledbh3=%d", cis[i + 4]); ++ vp++; ++ } ++ break; + -+#include -+#include -+#include ++ case HNBU_CCODE: ++ { ++ char str[3]; ++ ASSERT(sromrev > 1); ++ str[0] = cis[i + 1]; ++ str[1] = cis[i + 2]; ++ str[2] = 0; ++ vp += sprintf(vp, "ccode=%s", str); ++ vp++; ++ vp += sprintf(vp, "cctl=0x%x", cis[i + 3]); ++ vp++; ++ break; ++ } + -+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) ++ case HNBU_CCKPO: ++ ASSERT(sromrev > 2); ++ vp += sprintf(vp, "cckpo=0x%x", ++ (cis[i + 2] << 8) | cis[i + 1]); ++ vp++; ++ break; + -+extern asmlinkage void brcmIRQ(void); -+extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); ++ case HNBU_OFDMPO: ++ ASSERT(sromrev > 2); ++ vp += sprintf(vp, "ofdmpo=0x%x", ++ (cis[i + 4] << 24) | ++ (cis[i + 3] << 16) | ++ (cis[i + 2] << 8) | ++ cis[i + 1]); ++ vp++; ++ break; ++ } ++ break; + -+void -+brcm_irq_dispatch(struct pt_regs *regs) -+{ -+ u32 cause; ++ } ++ i += tlen; ++ } while (tup != 0xff); ++ } + -+ cause = read_c0_cause() & -+ read_c0_status() & -+ CAUSEF_IP; ++ /* Set the srom version */ ++ vp += sprintf(vp, "sromrev=%d", sromrev); ++ vp++; + -+#ifdef CONFIG_KERNPROF -+ change_c0_status(cause | 1, 1); -+#else -+ clear_c0_status(cause); -+#endif ++ /* if there is no antenna gain field, set default */ ++ if (ag_init == FALSE) { ++ ASSERT(sromrev == 1); ++ vp += sprintf(vp, "ag0=%d", 0xff); ++ vp++; ++ } + -+ if (cause & CAUSEF_IP7) -+ do_IRQ(7, regs); -+ if (cause & CAUSEF_IP2) -+ do_IRQ(2, regs); -+ if (cause & CAUSEF_IP3) -+ do_IRQ(3, regs); -+ if (cause & CAUSEF_IP4) -+ do_IRQ(4, regs); -+ if (cause & CAUSEF_IP5) -+ do_IRQ(5, regs); -+ if (cause & CAUSEF_IP6) -+ do_IRQ(6, regs); -+} ++ /* final nullbyte terminator */ ++ *vp++ = '\0'; ++ varsize = (uint)(vp - base); + -+static void -+enable_brcm_irq(unsigned int irq) -+{ -+ if (irq < 8) -+ set_c0_status(1 << (irq + 8)); -+ else -+ set_c0_status(IE_IRQ0); -+} ++ ASSERT((vp - base) < VARS_MAX); + -+static void -+disable_brcm_irq(unsigned int irq) -+{ -+ if (irq < 8) -+ clear_c0_status(1 << (irq + 8)); -+ else -+ clear_c0_status(IE_IRQ0); -+} ++ if (varsize == VARS_MAX) { ++ *vars = base; ++ } else { ++ vp = MALLOC(osh, varsize); ++ ASSERT(vp); ++ if (vp) ++ bcopy(base, vp, varsize); ++ MFREE(osh, base, VARS_MAX); ++ *vars = vp; ++ if (!vp) { ++ *count = 0; ++ return -2; ++ } ++ } ++ *count = varsize; + -+static void -+ack_brcm_irq(unsigned int irq) -+{ -+ /* Already done in brcm_irq_dispatch */ ++ return (0); +} + -+static unsigned int -+startup_brcm_irq(unsigned int irq) -+{ -+ enable_brcm_irq(irq); -+ -+ return 0; /* never anything pending */ -+} + -+static void -+end_brcm_irq(unsigned int irq) ++/* set PCMCIA sprom command register */ ++static int ++sprom_cmd_pcmcia(osl_t *osh, uint8 cmd) +{ -+ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) -+ enable_brcm_irq(irq); -+} -+ -+static struct hw_interrupt_type brcm_irq_type = { -+ typename: "MIPS", -+ startup: startup_brcm_irq, -+ shutdown: disable_brcm_irq, -+ enable: enable_brcm_irq, -+ disable: disable_brcm_irq, -+ ack: ack_brcm_irq, -+ end: end_brcm_irq, -+ NULL -+}; ++ uint8 status = 0; ++ uint wait_cnt = 1000; + -+void __init -+init_IRQ(void) -+{ -+ int i; ++ /* write sprom command register */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1); + -+ for (i = 0; i < NR_IRQS; i++) { -+ irq_desc[i].status = IRQ_DISABLED; -+ irq_desc[i].action = 0; -+ irq_desc[i].depth = 1; -+ irq_desc[i].handler = &brcm_irq_type; ++ /* wait status */ ++ while (wait_cnt--) { ++ OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1); ++ if (status & SROM_DONE) ++ return 0; + } + -+ set_except_vector(0, brcmIRQ); -+ change_c0_status(ST0_IM, ALLINTS); -+ -+#ifdef CONFIG_REMOTE_DEBUG -+ printk("Breaking into debugger...\n"); -+ set_debug_traps(); -+ breakpoint(); -+#endif ++ return 1; +} -diff -Naur linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio.c ---- linux.old/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/gpio.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,158 @@ -+/* -+ * GPIO char driver -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ + -+#include -+#include -+#include -+#include -+#include ++/* read a word from the PCMCIA srom */ ++static int ++sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data) ++{ ++ uint8 addr_l, addr_h, data_l, data_h; + -+#include -+#include -+#include -+#include ++ addr_l = (uint8)((addr * 2) & 0xff); ++ addr_h = (uint8)(((addr * 2) >> 8) & 0xff); + -+static sb_t *gpio_sbh; -+static int gpio_major; -+static devfs_handle_t gpio_dir; -+static struct { -+ char *name; -+ devfs_handle_t handle; -+} gpio_file[] = { -+ { "in", NULL }, -+ { "out", NULL }, -+ { "outen", NULL }, -+ { "control", NULL } -+}; ++ /* set address */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); + -+static int -+gpio_open(struct inode *inode, struct file * file) -+{ -+ if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file)) -+ return -ENODEV; ++ /* do read */ ++ if (sprom_cmd_pcmcia(osh, SROM_READ)) ++ return 1; + -+ MOD_INC_USE_COUNT; ++ /* read data */ ++ data_h = data_l = 0; ++ OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1); ++ OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1); ++ ++ *data = (data_h << 8) | data_l; + return 0; +} + ++/* write a word to the PCMCIA srom */ +static int -+gpio_release(struct inode *inode, struct file * file) ++sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data) +{ -+ MOD_DEC_USE_COUNT; -+ return 0; -+} ++ uint8 addr_l, addr_h, data_l, data_h; + -+static ssize_t -+gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos) -+{ -+ u32 val; ++ addr_l = (uint8)((addr * 2) & 0xff); ++ addr_h = (uint8)(((addr * 2) >> 8) & 0xff); ++ data_l = (uint8)(data & 0xff); ++ data_h = (uint8)((data >> 8) & 0xff); + -+ switch (MINOR(file->f_dentry->d_inode->i_rdev)) { -+ case 0: -+ val = sb_gpioin(gpio_sbh); -+ break; -+ case 1: -+ val = sb_gpioout(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); -+ break; -+ case 2: -+ val = sb_gpioouten(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); -+ break; -+ case 3: -+ val = sb_gpiocontrol(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); -+ break; -+ default: -+ return -ENODEV; -+ } ++ /* set address */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); + -+ if (put_user(val, (u32 *) buf)) -+ return -EFAULT; ++ /* write data */ ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1); ++ OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1); + -+ return sizeof(val); ++ /* do write */ ++ return sprom_cmd_pcmcia(osh, SROM_WRITE); +} + -+static ssize_t -+gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ++/* ++ * Read in and validate sprom. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++sprom_read_pci(osl_t *osh, uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc) +{ -+ u32 val; ++ int err = 0; ++ uint i; + -+ if (get_user(val, (u32 *) buf)) -+ return -EFAULT; ++ /* read the sprom */ ++ for (i = 0; i < nwords; i++) ++ buf[i] = R_REG(osh, &sprom[wordoff + i]); + -+ switch (MINOR(file->f_dentry->d_inode->i_rdev)) { -+ case 0: -+ return -EACCES; -+ case 1: -+ sb_gpioout(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); -+ break; -+ case 2: -+ sb_gpioouten(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); -+ break; -+ case 3: -+ sb_gpiocontrol(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); -+ break; -+ default: -+ return -ENODEV; ++ if (check_crc) { ++ /* fixup the endianness so crc8 will pass */ ++ htol16_buf(buf, nwords * 2); ++ if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) ++ err = 1; ++ /* now correct the endianness of the byte array */ ++ ltoh16_buf(buf, nwords * 2); + } + -+ return sizeof(val); ++ return err; +} + -+static struct file_operations gpio_fops = { -+ owner: THIS_MODULE, -+ open: gpio_open, -+ release: gpio_release, -+ read: gpio_read, -+ write: gpio_write, -+}; -+ -+static int __init -+gpio_init(void) -+{ -+ int i; ++/* ++* Create variable table from memory. ++* Return 0 on success, nonzero on error. ++*/ ++static int ++initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count) ++{ ++ int c = (int)(end - start); + -+ if (!(gpio_sbh = sb_kattach())) -+ return -ENODEV; ++ /* do it only when there is more than just the null string */ ++ if (c > 1) { ++ char *vp = MALLOC(osh, c); ++ ASSERT(vp); ++ if (!vp) ++ return BCME_NOMEM; ++ bcopy(start, vp, c); ++ *vars = vp; ++ *count = c; ++ } ++ else { ++ *vars = NULL; ++ *count = 0; ++ } + -+ sb_gpiosetcore(gpio_sbh); ++ return 0; ++} + -+ if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0) -+ return gpio_major; ++/* ++ * Find variables with from flash. 'base' points to the beginning ++ * of the table upon enter and to the end of the table upon exit when success. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_flash(osl_t *osh, char **base, uint len, char *devpath) ++{ ++ char *vp = *base; ++ char *flash; ++ int err; ++ char *s; ++ uint l, dl, copy_len; + -+ gpio_dir = devfs_mk_dir(NULL, "gpio", NULL); ++ /* allocate memory and read in flash */ ++ if (!(flash = MALLOC(osh, NVRAM_SPACE))) ++ return BCME_NOMEM; ++ if ((err = nvram_getall(flash, NVRAM_SPACE))) ++ goto exit; + -+ for (i = 0; i < ARRAYSIZE(gpio_file); i++) { -+ gpio_file[i].handle = devfs_register(gpio_dir, -+ gpio_file[i].name, -+ DEVFS_FL_DEFAULT, gpio_major, i, -+ S_IFCHR | S_IRUGO | S_IWUGO, -+ &gpio_fops, NULL); ++ /* grab vars with the prefix in name */ ++ dl = strlen(devpath); ++ for (s = flash; s && *s; s += l + 1) { ++ l = strlen(s); ++ ++ /* skip non-matching variable */ ++ if (strncmp(s, devpath, dl)) ++ continue; ++ ++ /* is there enough room to copy? */ ++ copy_len = l - dl + 1; ++ if (len < copy_len) { ++ err = BCME_BUFTOOSHORT; ++ goto exit; ++ } ++ ++ /* no prefix, just the name=value */ ++ strcpy(vp, &s[dl]); ++ vp += copy_len; ++ len -= copy_len; + } + -+ return 0; -+} ++ /* add null string as terminator */ ++ if (len < 1) { ++ err = BCME_BUFTOOSHORT; ++ goto exit; ++ } ++ *vp++ = '\0'; + -+static void __exit -+gpio_exit(void) -+{ -+ int i; ++ *base = vp; + -+ for (i = 0; i < ARRAYSIZE(gpio_file); i++) -+ devfs_unregister(gpio_file[i].handle); -+ devfs_unregister(gpio_dir); -+ devfs_unregister_chrdev(gpio_major, "gpio"); -+ sb_detach(gpio_sbh); ++exit: MFREE(osh, flash, NVRAM_SPACE); ++ return err; +} + -+module_init(gpio_init); -+module_exit(gpio_exit); -diff -Naur linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm947xx/include/bcmdevs.h ---- linux.old/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,391 @@ +/* -+ * Broadcom device-specific manifest constants. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ ++ * Initialize nonvolatile variable table from flash. ++ * Return 0 on success, nonzero on error. + */ ++static int ++initvars_flash_sb(void *sbh, char **vars, uint *count) ++{ ++ osl_t *osh = sb_osh(sbh); ++ char devpath[SB_DEVPATH_BUFSZ]; ++ char *vp, *base; ++ int err; + -+#ifndef _BCMDEVS_H -+#define _BCMDEVS_H ++ ASSERT(vars); ++ ASSERT(count); + ++ if ((err = sb_devpath(sbh, devpath, sizeof(devpath)))) ++ return err; + -+/* Known PCI vendor Id's */ -+#define VENDOR_EPIGRAM 0xfeda -+#define VENDOR_BROADCOM 0x14e4 -+#define VENDOR_3COM 0x10b7 -+#define VENDOR_NETGEAR 0x1385 -+#define VENDOR_DIAMOND 0x1092 -+#define VENDOR_DELL 0x1028 -+#define VENDOR_HP 0x0e11 -+#define VENDOR_APPLE 0x106b ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return BCME_NOMEM; + -+/* PCI Device Id's */ -+#define BCM4210_DEVICE_ID 0x1072 /* never used */ -+#define BCM4211_DEVICE_ID 0x4211 -+#define BCM4230_DEVICE_ID 0x1086 /* never used */ -+#define BCM4231_DEVICE_ID 0x4231 ++ if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath))) ++ goto err; + -+#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */ -+#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */ -+#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */ -+#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */ ++ err = initvars_table(osh, base, vp, vars, count); + -+#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */ -+#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */ ++err: MFREE(osh, base, VARS_MAX); ++ return err; ++} + -+#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ -+#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */ ++#ifdef WLTEST ++char mfgsromvars[256]; ++char *defaultsromvars = "il0macaddr=00:11:22:33:44:51\0" ++ "et0macaddr=00:11:22:33:44:52\0" ++ "et1macaddr=00:11:22:33:44:53\0" ++ "boardtype=0xffff\0" ++ "boardrev=0x10\0" ++ "boardflags=8\0" ++ "sromrev=2\0" ++ "aa2g=3"; ++#define MFGSROM_DEFVARSLEN 147 /* default srom len */ ++#endif /* WL_TEST */ + -+#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */ -+#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */ -+#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */ -+#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */ -+#define BCM47XX_USB_ID 0x4715 /* 47xx usb */ -+#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */ -+#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */ -+#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */ -+#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ -+#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ -+#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ ++/* ++ * Initialize nonvolatile variable table from sprom. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_srom_pci(void *sbh, void *curmap, char **vars, uint *count) ++{ ++ uint16 w, *b; ++ uint8 sromrev = 0; ++ struct ether_addr ea; ++ char eabuf[32]; ++ uint32 w32; ++ int woff, i; ++ char *vp, *base; ++ osl_t *osh = sb_osh(sbh); ++ bool flash = FALSE; ++ char name[SB_DEVPATH_BUFSZ+16], *value; ++ char devpath[SB_DEVPATH_BUFSZ]; ++ int err; + -+#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ ++ /* ++ * Apply CRC over SROM content regardless SROM is present or not, ++ * and use variable sromrev's existance in flash to decide ++ * if we should return an error when CRC fails or read SROM variables ++ * from flash. ++ */ ++ b = MALLOC(osh, SROM_MAX); ++ ASSERT(b); ++ if (!b) ++ return -2; + -+#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */ -+#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */ -+#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */ -+#define BCM4610_ENET_ID 0x4613 /* 4610 enet */ -+#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */ -+#define BCM4610_USB_ID 0x4615 /* 4610 usb */ ++ err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, ++ 64, TRUE); ++ if (err == 0) { ++ /* srom is good and is rev < 4 */ ++ /* top word of sprom contains version and crc8 */ ++ sromrev = b[63] & 0xff; ++ /* bcm4401 sroms misprogrammed */ ++ if (sromrev == 0x10) ++ sromrev = 1; ++ } else if (b[SROM4_SIGN] == SROM4_SIGNATURE) { ++ /* If sromrev >= 4, read more */ ++ err = sprom_read_pci(osh, (void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, ++ SROM4_WORDS, TRUE); ++ sromrev = b[SROM4_WORDS - 1] & 0xff; ++ } ++ ++ if (err) { ++#ifdef WLTEST ++ BS_ERROR(("SROM Crc Error, so see if we could use a default\n")); ++ w32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); ++ if (w32 & SPROM_OTPIN_USE) { ++ BS_ERROR(("srom crc failed with OTP, use default vars....\n")); ++ vp = base = mfgsromvars; ++ if (sb_chip(sbh) == BCM4311_CHIP_ID) { ++ BS_ERROR(("setting the devid to be 4311\n")); ++ vp += sprintf(vp, "devid=0x4311"); ++ vp++; ++ } ++ bcopy(defaultsromvars, vp, MFGSROM_DEFVARSLEN); ++ vp += MFGSROM_DEFVARSLEN; ++ goto varsdone; ++ } else { ++ BS_ERROR(("srom crc failed with SPROM....\n")); ++#endif /* WLTEST */ ++ if ((err = sb_devpath(sbh, devpath, sizeof(devpath)))) ++ return err; ++ sprintf(name, "%ssromrev", devpath); ++ if (!(value = getvar(NULL, name))) ++ return (-1); ++ sromrev = (uint8)bcm_strtoul(value, NULL, 0); ++ flash = TRUE; ++#ifdef WLTEST ++ } ++#endif /* WLTEST */ ++ } + -+#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */ -+#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ -+#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ -+#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ ++ /* srom version check */ ++ if (sromrev > 4) ++ return (-2); + -+#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */ -+#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */ ++ ASSERT(vars); ++ ASSERT(count); + -+#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */ -+#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */ -+#define BCM4307_ENET_ID 0x4306 /* 4307 enet */ -+#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */ ++ base = vp = MALLOC(osh, VARS_MAX); ++ ASSERT(vp); ++ if (!vp) ++ return -2; + -+#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */ -+#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ -+#define BCM4306_D11G_ID2 0x4325 -+#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ -+#define BCM4306_UART_ID 0x4322 /* 4306 uart */ -+#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */ -+#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */ ++ /* read variables from flash */ ++ if (flash) { ++ if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath))) ++ goto err; ++ goto varsdone; ++ } + -+#define BCM4309_PKG_ID 1 /* 4309 package id */ ++ vp += sprintf(vp, "sromrev=%d", sromrev); ++ vp++; + -+#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ -+#define BCM4303_PKG_ID 2 /* 4303 package id */ ++ if (sromrev >= 4) { ++ uint path, pathbase; ++ const uint pathbases[MAX_PATH] = {SROM4_PATH0, SROM4_PATH1, ++ SROM4_PATH2, SROM4_PATH3}; + -+#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */ -+#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */ -+#define BCM4310_UART_ID 0x4312 /* 4310 uart */ -+#define BCM4310_ENET_ID 0x4313 /* 4310 enet */ -+#define BCM4310_USB_ID 0x4315 /* 4310 usb */ ++ vp += sprintf(vp, "boardrev=%d", b[SROM4_BREV]); ++ vp++; + -+#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ -+#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ ++ vp += sprintf(vp, "boardflags=%d", (b[SROM4_BFL1] << 16) | b[SROM4_BFL0]); ++ vp++; + ++ vp += sprintf(vp, "boardflags2=%d", (b[SROM4_BFL3] << 16) | b[SROM4_BFL2]); ++ vp++; + -+#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */ -+#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ ++ /* The macaddr */ ++ ea.octet[0] = (b[SROM4_MACHI] >> 8) & 0xff; ++ ea.octet[1] = b[SROM4_MACHI] & 0xff; ++ ea.octet[2] = (b[SROM4_MACMID] >> 8) & 0xff; ++ ea.octet[3] = b[SROM4_MACMID] & 0xff; ++ ea.octet[4] = (b[SROM4_MACLO] >> 8) & 0xff; ++ ea.octet[5] = b[SROM4_MACLO] & 0xff; ++ bcm_ether_ntoa(&ea, eabuf); ++ vp += sprintf(vp, "macaddr=%s", eabuf); ++ vp++; + -+#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */ ++ w = b[SROM4_CCODE]; ++ if (w == 0) ++ vp += sprintf(vp, "ccode="); ++ else ++ vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff)); ++ vp++; ++ vp += sprintf(vp, "regrev=%d", b[SROM4_REGREV]); ++ vp++; + -+#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */ -+#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */ -+#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */ -+#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */ ++ w = b[SROM4_LEDBH10]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* ledbh0 */ ++ vp += sprintf(vp, "ledbh0=%d", (w & 0xff)); ++ vp++; + -+#define FPGA_JTAGM_ID 0x4330 /* ??? */ -+ -+/* Address map */ -+#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */ -+#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */ -+#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */ -+#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */ -+#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ -+#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */ ++ /* ledbh1 */ ++ vp += sprintf(vp, "ledbh1=%d", (w >> 8) & 0xff); ++ vp++; ++ } ++ w = b[SROM4_LEDBH32]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* ledbh2 */ ++ vp += sprintf(vp, "ledbh2=%d", w & 0xff); ++ vp++; + -+/* Core register space */ -+#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */ -+#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */ -+#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */ -+#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */ -+#define BCM4710_REG_USB 0x18004000 /* USB core registers */ -+#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */ -+#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */ -+#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */ -+#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */ ++ /* ledbh3 */ ++ vp += sprintf(vp, "ledbh3=%d", (w >> 8) & 0xff); ++ vp++; ++ } ++ /* LED Powersave duty cycle (oncount >> 24) (offcount >> 8) */ ++ w = b[SROM4_LEDDC]; ++ w32 = ((uint32)((unsigned char)(w >> 8) & 0xff) << 24) | /* oncount */ ++ ((uint32)((unsigned char)(w & 0xff)) << 8); /* offcount */ ++ vp += sprintf(vp, "leddc=%d", w32); ++ vp++; + -+#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */ -+#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */ -+#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */ -+#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */ -+#define BCM4710_PROG 0x1f800000 /* Programable interface */ -+#define BCM4710_FLASH 0x1fc00000 /* Flash */ ++ w = b[SROM4_AA]; ++ vp += sprintf(vp, "aa2g=%d", w & SROM4_AA2G_MASK); ++ vp++; ++ vp += sprintf(vp, "aa5g=%d", w >> SROM4_AA5G_SHIFT); ++ vp++; + -+#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++ w = b[SROM4_AG10]; ++ vp += sprintf(vp, "ag0=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff); ++ vp++; ++ w = b[SROM4_AG32]; ++ vp += sprintf(vp, "ag2=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "ag3=%d", (w >> 8) & 0xff); ++ vp++; + -+#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300) ++ /* Fixed power indices when power control is disabled */ ++ for (i = 0; i < 2; i++) { ++ w = b[SROM4_TXPID2G + i]; ++ vp += sprintf(vp, "txpid2ga%d=%d", 2 * i, w & 0xff); ++ vp++; ++ vp += sprintf(vp, "txpid2ga%d=%d", (2 * i) + 1, (w >> 8) & 0xff); ++ vp++; ++ w = b[SROM4_TXPID5G + i]; ++ vp += sprintf(vp, "txpid5ga%d=%d", 2 * i, w & 0xff); ++ vp++; ++ vp += sprintf(vp, "txpid5ga%d=%d", (2 * i) + 1, (w >> 8) & 0xff); ++ vp++; ++ w = b[SROM4_TXPID5GL + i]; ++ vp += sprintf(vp, "txpid5gla%d=%d", 2 * i, w & 0xff); ++ vp++; ++ vp += sprintf(vp, "txpid5gla%d=%d", (2 * i) + 1, (w >> 8) & 0xff); ++ vp++; ++ w = b[SROM4_TXPID5GH + i]; ++ vp += sprintf(vp, "txpid5gha%d=%d", 2 * i, w & 0xff); ++ vp++; ++ vp += sprintf(vp, "txpid5gha%d=%d", (2 * i) + 1, (w >> 8) & 0xff); ++ vp++; ++ } + -+#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000) -+#define BCM4710_LED (BCM4710_EXTIF + 0x00900000) ++ /* Per path variables */ ++ for (path = 0; path < MAX_PATH; path++) { ++ pathbase = pathbases[path]; ++ w = b[pathbase + SROM4_2G_ITT_MAXP]; ++ vp += sprintf(vp, "itt2ga%d=%d", path, w >> B2G_ITT_SHIFT); ++ vp++; ++ vp += sprintf(vp, "maxp2ga%d=%d", path, w & B2G_MAXP_MASK); ++ vp++; + -+#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */ -+#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ -+#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ -+#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ -+#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ ++ for (i = 0; i < 4; i++) { ++ vp += sprintf(vp, "pa2gw%da%d=%d", i, path, ++ b[pathbase + SROM4_2G_PA + i]); ++ vp++; ++ } + -+#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */ ++ w = b[pathbase + SROM4_5G_ITT_MAXP]; ++ vp += sprintf(vp, "itt5ga%d=%d", path, w >> B5G_ITT_SHIFT); ++ vp++; ++ vp += sprintf(vp, "maxp5ga%d=%d", path, w & B5G_MAXP_MASK); ++ vp++; + -+#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */ -+#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */ -+#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */ ++ w = b[pathbase + SROM4_5GLH_MAXP]; ++ vp += sprintf(vp, "maxp5lga%d=%d", path, w >> B5GL_MAXP_SHIFT); ++ vp++; ++ vp += sprintf(vp, "maxp5gha%d=%d", path, w & B5GH_MAXP_MASK); ++ vp++; + -+#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */ ++ for (i = 0; i < 4; i++) { ++ vp += sprintf(vp, "pa5gw%da%d=%d", i, path, ++ b[pathbase + SROM4_5G_PA + i]); ++ vp++; ++ vp += sprintf(vp, "pa5glw%da%d=%d", i, path, ++ b[pathbase + SROM4_5GL_PA + i]); ++ vp++; ++ vp += sprintf(vp, "pa5hgw%da%d=%d", i, path, ++ b[pathbase + SROM4_5GH_PA + i]); ++ vp++; ++ } ++ } + -+/* PCMCIA vendor Id's */ ++ vp += sprintf(vp, "cck2gpo=%d", b[SROM4_2G_CCKPO]); ++ vp++; + -+#define VENDOR_BROADCOM_PCMCIA 0x02d0 ++ w32 = ((uint32)b[SROM4_2G_OFDMPO + 1] << 16) | b[SROM4_2G_OFDMPO]; ++ vp += sprintf(vp, "ofdm2gpo=%d", w32); ++ vp++; + -+/* SDIO vendor Id's */ -+#define VENDOR_BROADCOM_SDIO 0x00BF ++ w32 = ((uint32)b[SROM4_5G_OFDMPO + 1] << 16) | b[SROM4_5G_OFDMPO]; ++ vp += sprintf(vp, "ofdm5gpo=%d", w32); ++ vp++; + ++ w32 = ((uint32)b[SROM4_5GL_OFDMPO + 1] << 16) | b[SROM4_5GL_OFDMPO]; ++ vp += sprintf(vp, "ofdm5glpo=%d", w32); ++ vp++; + -+/* boardflags */ -+#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */ -+#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */ -+#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */ -+#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */ -+#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */ -+#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */ -+#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */ -+#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */ -+#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */ -+#define BFL_FEM 0x0800 /* This board supports the Front End Module */ -+#define BFL_EXTLNA 0x1000 /* This board has an external LNA */ -+#define BFL_HGPA 0x2000 /* This board has a high gain PA */ -+#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */ -+#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */ ++ w32 = ((uint32)b[SROM4_5GH_OFDMPO + 1] << 16) | b[SROM4_5GH_OFDMPO]; ++ vp += sprintf(vp, "ofdm5ghpo=%d", w32); ++ vp++; + -+/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ -+#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */ -+#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */ -+#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */ -+#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */ -+#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */ -+#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ -+#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ -+#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ -+#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ -+#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ ++ for (i = 0; i < 8; i++) { ++ vp += sprintf(vp, "mcs2gpo%d=%d", i, b[SROM4_2G_MCSPO]); ++ vp++; ++ vp += sprintf(vp, "mcs5gpo%d=%d", i, b[SROM4_5G_MCSPO]); ++ vp++; ++ vp += sprintf(vp, "mcs5glpo%d=%d", i, b[SROM4_5GL_MCSPO]); ++ vp++; ++ vp += sprintf(vp, "mcs5ghpo%d=%d", i, b[SROM4_5GH_MCSPO]); ++ vp++; ++ } + -+/* Bus types */ -+#define SB_BUS 0 /* Silicon Backplane */ -+#define PCI_BUS 1 /* PCI target */ -+#define PCMCIA_BUS 2 /* PCMCIA target */ -+#define SDIO_BUS 3 /* SDIO target */ -+#define JTAG_BUS 4 /* JTAG */ ++ vp += sprintf(vp, "ccdpo%d=%d", i, b[SROM4_CCDPO]); ++ vp++; ++ vp += sprintf(vp, "stbcpo%d=%d", i, b[SROM4_STBCPO]); ++ vp++; ++ vp += sprintf(vp, "bw40po%d=%d", i, b[SROM4_BW40PO]); ++ vp++; ++ vp += sprintf(vp, "bwduppo%d=%d", i, b[SROM4_BWDUPPO]); ++ vp++; + -+/* Allows optimization for single-bus support */ -+#ifdef BCMBUSTYPE -+#define BUSTYPE(bus) (BCMBUSTYPE) -+#else -+#define BUSTYPE(bus) (bus) -+#endif ++ goto done; ++ } ++ if (sromrev >= 3) { ++ /* New section takes over the 3th hardware function space */ + -+/* power control defines */ -+#define PLL_DELAY 150 /* us pll on delay */ -+#define FREF_DELAY 200 /* us fref change delay */ -+#define MIN_SLOW_CLK 32 /* us Slow clock period */ -+#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ ++ /* Words 22+23 are 11a (mid) ofdm power offsets */ ++ w32 = ((uint32)b[23] << 16) | b[22]; ++ vp += sprintf(vp, "ofdmapo=%d", w32); ++ vp++; + -+/* Reference Board Types */ ++ /* Words 24+25 are 11a (low) ofdm power offsets */ ++ w32 = ((uint32)b[25] << 16) | b[24]; ++ vp += sprintf(vp, "ofdmalpo=%d", w32); ++ vp++; + -+#define BU4710_BOARD 0x0400 -+#define VSIM4710_BOARD 0x0401 -+#define QT4710_BOARD 0x0402 ++ /* Words 26+27 are 11a (high) ofdm power offsets */ ++ w32 = ((uint32)b[27] << 16) | b[26]; ++ vp += sprintf(vp, "ofdmahpo=%d", w32); ++ vp++; + -+#define BU4610_BOARD 0x0403 -+#define VSIM4610_BOARD 0x0404 ++ /* LED Powersave duty cycle (oncount >> 24) (offcount >> 8) */ ++ w32 = ((uint32)((unsigned char)(b[21] >> 8) & 0xff) << 24) | /* oncount */ ++ ((uint32)((unsigned char)(b[21] & 0xff)) << 8); /* offcount */ ++ vp += sprintf(vp, "leddc=%d", w32); + -+#define BU4307_BOARD 0x0405 -+#define BCM94301CB_BOARD 0x0406 -+#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */ -+#define BCM94301MP_BOARD 0x0407 -+#define BCM94307MP_BOARD 0x0408 -+#define BCMAP4307_BOARD 0x0409 ++ vp++; ++ } + -+#define BU4309_BOARD 0x040a -+#define BCM94309CB_BOARD 0x040b -+#define BCM94309MP_BOARD 0x040c -+#define BCM4309AP_BOARD 0x040d ++ if (sromrev >= 2) { ++ /* New section takes over the 4th hardware function space */ + -+#define BCM94302MP_BOARD 0x040e ++ /* Word 29 is max power 11a high/low */ ++ w = b[29]; ++ vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff); ++ vp++; + -+#define VSIM4310_BOARD 0x040f -+#define BU4711_BOARD 0x0410 -+#define BCM94310U_BOARD 0x0411 -+#define BCM94310AP_BOARD 0x0412 -+#define BCM94310MP_BOARD 0x0414 ++ /* Words 30-32 set the 11alow pa settings, ++ * 33-35 are the 11ahigh ones. ++ */ ++ for (i = 0; i < 3; i++) { ++ vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]); ++ vp++; ++ vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]); ++ vp++; ++ } ++ w = b[59]; ++ if (w == 0) ++ vp += sprintf(vp, "ccode="); ++ else ++ vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff)); ++ vp++; + -+#define BU4306_BOARD 0x0416 -+#define BCM94306CB_BOARD 0x0417 -+#define BCM94306MP_BOARD 0x0418 ++ } + -+#define BCM94710D_BOARD 0x041a -+#define BCM94710R1_BOARD 0x041b -+#define BCM94710R4_BOARD 0x041c -+#define BCM94710AP_BOARD 0x041d ++ /* parameter section of sprom starts at byte offset 72 */ ++ woff = 72/2; + ++ /* first 6 bytes are il0macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += 3; ++ bcm_ether_ntoa(&ea, eabuf); ++ vp += sprintf(vp, "il0macaddr=%s", eabuf); ++ vp++; + -+#define BU2050_BOARD 0x041f ++ /* next 6 bytes are et0macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += 3; ++ bcm_ether_ntoa(&ea, eabuf); ++ vp += sprintf(vp, "et0macaddr=%s", eabuf); ++ vp++; + ++ /* next 6 bytes are et1macaddr */ ++ ea.octet[0] = (b[woff] >> 8) & 0xff; ++ ea.octet[1] = b[woff] & 0xff; ++ ea.octet[2] = (b[woff+1] >> 8) & 0xff; ++ ea.octet[3] = b[woff+1] & 0xff; ++ ea.octet[4] = (b[woff+2] >> 8) & 0xff; ++ ea.octet[5] = b[woff+2] & 0xff; ++ woff += 3; ++ bcm_ether_ntoa(&ea, eabuf); ++ vp += sprintf(vp, "et1macaddr=%s", eabuf); ++ vp++; + -+#define BCM94309G_BOARD 0x0421 ++ /* ++ * Enet phy settings one or two singles or a dual ++ * Bits 4-0 : MII address for enet0 (0x1f for not there) ++ * Bits 9-5 : MII address for enet1 (0x1f for not there) ++ * Bit 14 : Mdio for enet0 ++ * Bit 15 : Mdio for enet1 ++ */ ++ w = b[woff]; ++ vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f)); ++ vp++; ++ vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f)); ++ vp++; ++ vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1)); ++ vp++; ++ vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1)); ++ vp++; + -+#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */ ++ /* Word 46 has board rev, antennas 0/1 & Country code/control */ ++ w = b[46]; ++ vp += sprintf(vp, "boardrev=%d", w & 0xff); ++ vp++; + -+#define BU4704_BOARD 0x0423 -+#define BU4702_BOARD 0x0424 ++ if (sromrev > 1) ++ vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf); ++ else ++ vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf); ++ vp++; + -+#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ ++ vp += sprintf(vp, "aa2g=%d", (w >> 12) & 0x3); ++ vp++; + -+#define BU4317_BOARD 0x0426 ++ vp += sprintf(vp, "aa5g=%d", (w >> 14) & 0x3); ++ vp++; + ++ /* Words 47-49 set the (wl) pa settings */ ++ woff = 47; + -+#define BCM94702MN_BOARD 0x0428 ++ for (i = 0; i < 3; i++) { ++ vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]); ++ vp++; ++ vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]); ++ vp++; ++ } + -+/* BCM4702 1U CompactPCI Board */ -+#define BCM94702CPCI_BOARD 0x0429 ++ /* ++ * Words 50-51 set the customer-configured wl led behavior. ++ * 8 bits/gpio pin. High bit: activehi=0, activelo=1; ++ * LED behavior values defined in wlioctl.h . ++ */ ++ w = b[50]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* ledbh0 */ ++ vp += sprintf(vp, "ledbh0=%d", (w & 0xff)); ++ vp++; + -+/* BCM4702 with BCM95380 VLAN Router */ -+#define BCM95380RR_BOARD 0x042a ++ /* ledbh1 */ ++ vp += sprintf(vp, "ledbh1=%d", (w >> 8) & 0xff); ++ vp++; ++ } ++ w = b[51]; ++ if ((w != 0) && (w != 0xffff)) { ++ /* ledbh2 */ ++ vp += sprintf(vp, "ledbh2=%d", w & 0xff); ++ vp++; + -+/* cb4306 with SiGe PA */ -+#define BCM94306CBSG_BOARD 0x042b ++ /* ledbh */ ++ vp += sprintf(vp, "ledbh3=%d", (w >> 8) & 0xff); ++ vp++; ++ } + -+/* mp4301 with 2050 radio */ -+#define BCM94301MPL_BOARD 0x042c ++ /* Word 52 is max power 0/1 */ ++ w = b[52]; ++ vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff); ++ vp++; + -+/* cb4306 with SiGe PA */ -+#define PCSG94306_BOARD 0x042d ++ /* Word 56 is idle tssi target 0/1 */ ++ w = b[56]; ++ vp += sprintf(vp, "pa0itssit=%d", w & 0xff); ++ vp++; ++ vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff); ++ vp++; + -+/* bu4704 with sdram */ -+#define BU4704SD_BOARD 0x042e ++ /* Word 57 is boardflags, if not programmed make it zero */ ++ w32 = (uint32)b[57]; ++ if (w32 == 0xffff) w32 = 0; ++ if (sromrev > 1) { ++ /* Word 28 is the high bits of boardflags */ ++ w32 |= (uint32)b[28] << 16; ++ } ++ vp += sprintf(vp, "boardflags=%d", w32); ++ vp++; + -+/* Dual 11a/11g Router */ -+#define BCM94704AGR_BOARD 0x042f ++ /* Word 58 is antenna gain 0/1 */ ++ w = b[58]; ++ vp += sprintf(vp, "ag0=%d", w & 0xff); ++ vp++; + -+/* 11a-only minipci */ -+#define BCM94308MP_BOARD 0x0430 ++ vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff); ++ vp++; + ++ if (sromrev == 1) { ++ /* set the oem string */ ++ vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", ++ ((b[59] >> 8) & 0xff), (b[59] & 0xff), ++ ((b[60] >> 8) & 0xff), (b[60] & 0xff), ++ ((b[61] >> 8) & 0xff), (b[61] & 0xff), ++ ((b[62] >> 8) & 0xff), (b[62] & 0xff)); ++ vp++; ++ } else if (sromrev == 2) { ++ /* Word 60 OFDM tx power offset from CCK level */ ++ /* OFDM Power Offset - opo */ ++ vp += sprintf(vp, "opo=%d", b[60] & 0xff); ++ vp++; ++ } else { ++ /* Word 60: cck power offsets */ ++ vp += sprintf(vp, "cckpo=%d", b[60]); ++ vp++; + ++ /* Words 61+62: 11g ofdm power offsets */ ++ w32 = ((uint32)b[62] << 16) | b[61]; ++ vp += sprintf(vp, "ofdmgpo=%d", w32); ++ vp++; ++ } + -+/* BCM94317 boards */ -+#define BCM94317CB_BOARD 0x0440 -+#define BCM94317MP_BOARD 0x0441 -+#define BCM94317PCMCIA_BOARD 0x0442 -+#define BCM94317SDIO_BOARD 0x0443 ++ /* final nullbyte terminator */ ++done: *vp++ = '\0'; + -+#define BU4712_BOARD 0x0444 -+#define BU4712SD_BOARD 0x045d -+#define BU4712L_BOARD 0x045f ++ ASSERT((vp - base) <= VARS_MAX); + -+/* BCM4712 boards */ -+#define BCM94712AP_BOARD 0x0445 -+#define BCM94712P_BOARD 0x0446 ++varsdone: ++ err = initvars_table(osh, base, vp, vars, count); + -+/* BCM4318 boards */ -+#define BU4318_BOARD 0x0447 -+#define CB4318_BOARD 0x0448 -+#define MPG4318_BOARD 0x0449 -+#define MP4318_BOARD 0x044a -+#define SD4318_BOARD 0x044b ++err: ++#ifdef WLTEST ++ if (base != mfgsromvars) ++#endif ++ MFREE(osh, base, VARS_MAX); ++ MFREE(osh, b, SROM_MAX); ++ return err; ++} + -+/* BCM63XX boards */ -+#define BCM96338_BOARD 0x6338 -+#define BCM96345_BOARD 0x6345 -+#define BCM96348_BOARD 0x6348 ++/* ++ * Read the cis and call parsecis to initialize the vars. ++ * Return 0 on success, nonzero on error. ++ */ ++static int ++initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, uint *count) ++{ ++ uint8 *cis = NULL; ++ int rc; ++ uint data_sz; + -+/* Another mp4306 with SiGe */ -+#define BCM94306P_BOARD 0x044c ++ data_sz = (sb_pcmciarev(sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE; + -+/* CF-like 4317 modules */ -+#define BCM94317CF_BOARD 0x044d ++ if ((cis = MALLOC(osh, data_sz)) == NULL) ++ return (-2); + -+/* mp4303 */ -+#define BCM94303MP_BOARD 0x044e ++ if (sb_pcmciarev(sbh) == 1) { ++ if (srom_read(PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis)) { ++ MFREE(osh, cis, data_sz); ++ return (-1); ++ } ++ /* fix up endianess for 16-bit data vs 8-bit parsing */ ++ ltoh16_buf((uint16 *)cis, data_sz); ++ } else ++ OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz); + -+/* mpsgh4306 */ -+#define BCM94306MPSGH_BOARD 0x044f ++ rc = srom_parsecis(osh, &cis, 1, vars, count); + -+/* BRCM 4306 w/ Front End Modules */ -+#define BCM94306MPM 0x0450 -+#define BCM94306MPL 0x0453 ++ MFREE(osh, cis, data_sz); + -+/* 4712agr */ -+#define BCM94712AGR_BOARD 0x0451 ++ return (rc); ++} + -+/* The real CF 4317 board */ -+#define CFI4317_BOARD 0x0452 +diff -urN linux.old/arch/mips/bcm947xx/bcmutils.c linux.dev/arch/mips/bcm947xx/bcmutils.c +--- linux.old/arch/mips/bcm947xx/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/bcmutils.c 2006-04-28 00:34:02.000000000 +0200 +@@ -0,0 +1,247 @@ ++/* ++ * Misc useful OS-independent routines. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $ ++ */ + -+/* pcmcia 4303 */ -+#define PC4303_BOARD 0x0454 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+/* 5350K */ -+#define BCM95350K_BOARD 0x0455 ++unsigned char bcm_ctype[] = { ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ ++ _BCM_C, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C|_BCM_S, _BCM_C, ++ _BCM_C, /* 8-15 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ ++ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ ++ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ ++ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ ++ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ ++ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ ++ _BCM_P, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, _BCM_U|_BCM_X, ++ _BCM_U|_BCM_X, _BCM_U, /* 64-71 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ ++ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ ++ _BCM_P, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, _BCM_L|_BCM_X, ++ _BCM_L|_BCM_X, _BCM_L, /* 96-103 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ ++ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128-143 */ ++ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144-159 */ ++ _BCM_S|_BCM_SP, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, ++ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 160-175 */ ++ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, ++ _BCM_P, _BCM_P, _BCM_P, _BCM_P, _BCM_P, /* 176-191 */ ++ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, ++ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, /* 192-207 */ ++ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_P, _BCM_U, _BCM_U, _BCM_U, ++ _BCM_U, _BCM_U, _BCM_U, _BCM_U, _BCM_L, /* 208-223 */ ++ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, ++ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, /* 224-239 */ ++ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_P, _BCM_L, _BCM_L, _BCM_L, ++ _BCM_L, _BCM_L, _BCM_L, _BCM_L, _BCM_L /* 240-255 */ ++}; + -+/* 5350R */ -+#define BCM95350R_BOARD 0x0456 + -+/* 4306mplna */ -+#define BCM94306MPLNA_BOARD 0x0457 ++ulong ++bcm_strtoul(char *cp, char **endp, uint base) ++{ ++ ulong result, value; ++ bool minus; + -+/* 4320 boards */ -+#define BU4320_BOARD 0x0458 -+#define BU4320S_BOARD 0x0459 -+#define BCM94320PH_BOARD 0x045a ++ minus = FALSE; + -+/* 4306mph */ -+#define BCM94306MPH_BOARD 0x045b ++ while (bcm_isspace(*cp)) ++ cp++; + -+/* 4306pciv */ -+#define BCM94306PCIV_BOARD 0x045c ++ if (cp[0] == '+') ++ cp++; ++ else if (cp[0] == '-') { ++ minus = TRUE; ++ cp++; ++ } + -+#define BU4712SD_BOARD 0x045d ++ if (base == 0) { ++ if (cp[0] == '0') { ++ if ((cp[1] == 'x') || (cp[1] == 'X')) { ++ base = 16; ++ cp = &cp[2]; ++ } else { ++ base = 8; ++ cp = &cp[1]; ++ } ++ } else ++ base = 10; ++ } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { ++ cp = &cp[2]; ++ } + -+#define BCM94320PFLSH_BOARD 0x045e ++ result = 0; + -+#define BU4712L_BOARD 0x045f -+#define BCM94712LGR_BOARD 0x0460 -+#define BCM94320R_BOARD 0x0461 ++ while (bcm_isxdigit(*cp) && ++ (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { ++ result = result*base + value; ++ cp++; ++ } + -+#define BU5352_BOARD 0x0462 ++ if (minus) ++ result = (ulong)(result * -1); + -+#define BCM94318MPGH_BOARD 0x0463 ++ if (endp) ++ *endp = (char *)cp; + ++ return (result); ++} + -+#define BCM95352GR_BOARD 0x0467 ++uchar ++bcm_toupper(uchar c) ++{ ++ if (bcm_islower(c)) ++ c -= 'a'-'A'; ++ return (c); ++} + -+/* bcm95351agr */ -+#define BCM95351AGR_BOARD 0x0470 ++char* ++bcm_ether_ntoa(struct ether_addr *ea, char *buf) ++{ ++ sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", ++ ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, ++ ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); ++ return (buf); ++} + -+/* # of GPIO pins */ -+#define GPIO_NUMPINS 16 + -+#endif /* _BCMDEVS_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/bcm947xx/include/bcmendian.h ---- linux.old/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,152 @@ +/* -+ * local version of endian.h - byte order defines -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+*/ -+ -+#ifndef _BCMENDIAN_H_ -+#define _BCMENDIAN_H_ ++ * Search the name=value vars for a specific one and return its value. ++ * Returns NULL if not found. ++ */ ++char* ++getvar(char *vars, char *name) ++{ ++ char *s; ++ int len; + -+#include ++ len = strlen(name); + -+/* Byte swap a 16 bit value */ -+#define BCMSWAP16(val) \ -+ ((uint16)( \ -+ (((uint16)(val) & (uint16)0x00ffU) << 8) | \ -+ (((uint16)(val) & (uint16)0xff00U) >> 8) )) -+ -+/* Byte swap a 32 bit value */ -+#define BCMSWAP32(val) \ -+ ((uint32)( \ -+ (((uint32)(val) & (uint32)0x000000ffUL) << 24) | \ -+ (((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \ -+ (((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \ -+ (((uint32)(val) & (uint32)0xff000000UL) >> 24) )) -+ -+/* 2 Byte swap a 32 bit value */ -+#define BCMSWAP32BY16(val) \ -+ ((uint32)( \ -+ (((uint32)(val) & (uint32)0x0000ffffUL) << 16) | \ -+ (((uint32)(val) & (uint32)0xffff0000UL) >> 16) )) -+ ++ /* first look in vars[] */ ++ for (s = vars; s && *s;) { ++ /* CSTYLED */ ++ if ((memcmp(s, name, len) == 0) && (s[len] == '=')) ++ return (&s[len+1]); + -+static INLINE uint16 -+bcmswap16(uint16 val) -+{ -+ return BCMSWAP16(val); -+} ++ while (*s++) ++ ; ++ } + -+static INLINE uint32 -+bcmswap32(uint32 val) -+{ -+ return BCMSWAP32(val); ++ /* then query nvram */ ++ return (nvram_get(name)); +} + -+static INLINE uint32 -+bcmswap32by16(uint32 val) ++/* ++ * Search the vars for a specific one and return its value as ++ * an integer. Returns 0 if not found. ++ */ ++int ++getintvar(char *vars, char *name) +{ -+ return BCMSWAP32BY16(val); -+} ++ char *val; + -+/* buf - start of buffer of shorts to swap */ -+/* len - byte length of buffer */ -+static INLINE void -+bcmswap16_buf(uint16 *buf, uint len) -+{ -+ len = len/2; ++ if ((val = getvar(vars, name)) == NULL) ++ return (0); + -+ while(len--){ -+ *buf = bcmswap16(*buf); -+ buf++; -+ } ++ return (bcm_strtoul(val, NULL, 0)); +} + -+#ifndef hton16 -+#ifndef IL_BIGENDIAN -+#define HTON16(i) BCMSWAP16(i) -+#define hton16(i) bcmswap16(i) -+#define hton32(i) bcmswap32(i) -+#define ntoh16(i) bcmswap16(i) -+#define ntoh32(i) bcmswap32(i) -+#define ltoh16(i) (i) -+#define ltoh32(i) (i) -+#define htol16(i) (i) -+#define htol32(i) (i) -+#else -+#define HTON16(i) (i) -+#define hton16(i) (i) -+#define hton32(i) (i) -+#define ntoh16(i) (i) -+#define ntoh32(i) (i) -+#define ltoh16(i) bcmswap16(i) -+#define ltoh32(i) bcmswap32(i) -+#define htol16(i) bcmswap16(i) -+#define htol32(i) bcmswap32(i) -+#endif -+#endif + -+#ifndef IL_BIGENDIAN -+#define ltoh16_buf(buf, i) -+#define htol16_buf(buf, i) -+#else -+#define ltoh16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) -+#define htol16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) -+#endif ++/******************************************************************************* ++ * crc8 ++ * ++ * Computes a crc8 over the input data using the polynomial: ++ * ++ * x^8 + x^7 +x^6 + x^4 + x^2 + 1 ++ * ++ * The caller provides the initial value (either CRC8_INIT_VALUE ++ * or the previous returned value) to allow for processing of ++ * discontiguous blocks of data. When generating the CRC the ++ * caller is responsible for complementing the final return value ++ * and inserting it into the byte stream. When checking, a final ++ * return value of CRC8_GOOD_VALUE indicates a valid CRC. ++ * ++ * Reference: Dallas Semiconductor Application Note 27 ++ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", ++ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., ++ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt ++ * ++ * **************************************************************************** ++ */ + -+/* -+* load 16-bit value from unaligned little endian byte array. -+*/ -+static INLINE uint16 -+ltoh16_ua(uint8 *bytes) -+{ -+ return (bytes[1]<<8)+bytes[0]; -+} ++static uint8 crc8_table[256] = { ++ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, ++ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, ++ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, ++ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, ++ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, ++ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, ++ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, ++ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, ++ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, ++ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, ++ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, ++ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, ++ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, ++ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, ++ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, ++ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, ++ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, ++ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, ++ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, ++ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, ++ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, ++ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, ++ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, ++ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, ++ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, ++ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, ++ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, ++ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, ++ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, ++ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, ++ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, ++ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F ++}; + -+/* -+* load 32-bit value from unaligned little endian byte array. -+*/ -+static INLINE uint32 -+ltoh32_ua(uint8 *bytes) -+{ -+ return (bytes[3]<<24)+(bytes[2]<<16)+(bytes[1]<<8)+bytes[0]; -+} ++#define CRC_INNER_LOOP(n, c, x) \ ++ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] + -+/* -+* load 16-bit value from unaligned big(network) endian byte array. -+*/ -+static INLINE uint16 -+ntoh16_ua(uint8 *bytes) ++uint8 ++hndcrc8( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint8 crc /* either CRC8_INIT_VALUE or previous return value */ ++) +{ -+ return (bytes[0]<<8)+bytes[1]; -+} ++ /* hard code the crc loop instead of using CRC_INNER_LOOP macro ++ * to avoid the undefined and unnecessary (uint8 >> 8) operation. ++ */ ++ while (nbytes-- > 0) ++ crc = crc8_table[(crc ^ *pdata++) & 0xff]; + -+/* -+* load 32-bit value from unaligned big(network) endian byte array. -+*/ -+static INLINE uint32 -+ntoh32_ua(uint8 *bytes) -+{ -+ return (bytes[0]<<24)+(bytes[1]<<16)+(bytes[2]<<8)+bytes[3]; ++ return crc; +} + -+#define ltoh_ua(ptr) ( \ -+ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ -+ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] : \ -+ (((uint8 *)ptr)[3]<<24)+(((uint8 *)ptr)[2]<<16)+(((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] \ -+) -+ -+#define ntoh_ua(ptr) ( \ -+ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ -+ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[0]<<8)+((uint8 *)ptr)[1] : \ -+ (((uint8 *)ptr)[0]<<24)+(((uint8 *)ptr)[1]<<16)+(((uint8 *)ptr)[2]<<8)+((uint8 *)ptr)[3] \ -+) + -+#endif /* _BCMENDIAN_H_ */ -diff -Naur linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bcm947xx/include/bcmnvram.h ---- linux.old/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,141 @@ +diff -urN linux.old/arch/mips/bcm947xx/cfe_env.c linux.dev/arch/mips/bcm947xx/cfe_env.c +--- linux.old/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/cfe_env.c 2006-04-27 19:24:19.000000000 +0200 +@@ -0,0 +1,234 @@ +/* -+ * NVRAM variable manipulation ++ * NVRAM variable manipulation (Linux kernel half) + * -+ * Copyright 2005, Broadcom Corporation ++ * Copyright 2001-2003, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -1262,477 +1535,543 @@ diff -Naur linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/b + * $Id$ + */ + -+#ifndef _bcmnvram_h_ -+#define _bcmnvram_h_ -+ -+#ifndef _LANGUAGE_ASSEMBLY ++#include ++#include ++#include ++#include ++#include ++#include ++#include + +#include ++#include ++#include ++#include + -+struct nvram_header { -+ uint32 magic; -+ uint32 len; -+ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ -+ uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ -+ uint32 config_ncdl; /* ncdl values for memc */ -+}; -+ -+struct nvram_tuple { -+ char *name; -+ char *value; -+ struct nvram_tuple *next; -+}; -+ -+/* -+ * Initialize NVRAM access. May be unnecessary or undefined on certain -+ * platforms. -+ */ -+extern int BCMINIT(nvram_init)(void *sbh); ++#define NVRAM_SIZE (0x1ff0) ++static char _nvdata[NVRAM_SIZE] __initdata; ++static char _valuestr[256] __initdata; + +/* -+ * Disable NVRAM access. May be unnecessary or undefined on certain -+ * platforms. -+ */ -+extern void BCMINIT(nvram_exit)(void *sbh); -+ -+/* -+ * Get the value of an NVRAM variable. The pointer returned may be -+ * invalid after a set. -+ * @param name name of variable to get -+ * @return value of variable or NULL if undefined ++ * TLV types. These codes are used in the "type-length-value" ++ * encoding of the items stored in the NVRAM device (flash or EEPROM) ++ * ++ * The layout of the flash/nvram is as follows: ++ * ++ * ++ * ++ * The type code of "ENV_TLV_TYPE_END" marks the end of the list. ++ * The "length" field marks the length of the data section, not ++ * including the type and length fields. ++ * ++ * Environment variables are stored as follows: ++ * ++ * = ++ * ++ * If bit 0 (low bit) is set, the length is an 8-bit value. ++ * If bit 0 (low bit) is clear, the length is a 16-bit value ++ * ++ * Bit 7 set indicates "user" TLVs. In this case, bit 0 still ++ * indicates the size of the length field. ++ * ++ * Flags are from the constants below: ++ * + */ -+extern char * BCMINIT(nvram_get)(const char *name); ++#define ENV_LENGTH_16BITS 0x00 /* for low bit */ ++#define ENV_LENGTH_8BITS 0x01 + -+/* -+ * Read the reset GPIO value from the nvram and set the GPIO -+ * as input -+ */ -+extern int BCMINITFN(nvram_resetgpio_init)(void *sbh); ++#define ENV_TYPE_USER 0x80 + -+/* -+ * Get the value of an NVRAM variable. -+ * @param name name of variable to get -+ * @return value of variable or NUL if undefined -+ */ -+#define nvram_safe_get(name) (BCMINIT(nvram_get)(name) ? : "") ++#define ENV_CODE_SYS(n,l) (((n)<<1)|(l)) ++#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER) + +/* -+ * Match an NVRAM variable. -+ * @param name name of variable to match -+ * @param match value to compare against value of variable -+ * @return TRUE if variable is defined and its value is string equal -+ * to match or FALSE otherwise ++ * The actual TLV types we support + */ -+static INLINE int -+nvram_match(char *name, char *match) { -+ const char *value = BCMINIT(nvram_get)(name); -+ return (value && !strcmp(value, match)); -+} + -+/* -+ * Inversely match an NVRAM variable. -+ * @param name name of variable to match -+ * @param match value to compare against value of variable -+ * @return TRUE if variable is defined and its value is not string -+ * equal to invmatch or FALSE otherwise -+ */ -+static INLINE int -+nvram_invmatch(char *name, char *invmatch) { -+ const char *value = BCMINIT(nvram_get)(name); -+ return (value && strcmp(value, invmatch)); -+} ++#define ENV_TLV_TYPE_END 0x00 ++#define ENV_TLV_TYPE_ENV ENV_CODE_SYS(0,ENV_LENGTH_8BITS) + +/* -+ * Set the value of an NVRAM variable. The name and value strings are -+ * copied into private storage. Pointers to previously set values -+ * may become invalid. The new value may be immediately -+ * retrieved but will not be permanently stored until a commit. -+ * @param name name of variable to set -+ * @param value value of variable -+ * @return 0 on success and errno on failure ++ * Environment variable flags + */ -+extern int BCMINIT(nvram_set)(const char *name, const char *value); + -+/* -+ * Unset an NVRAM variable. Pointers to previously set values -+ * remain valid until a set. -+ * @param name name of variable to unset -+ * @return 0 on success and errno on failure -+ * NOTE: use nvram_commit to commit this change to flash. -+ */ -+extern int BCMINIT(nvram_unset)(const char *name); ++#define ENV_FLG_NORMAL 0x00 /* normal read/write */ ++#define ENV_FLG_BUILTIN 0x01 /* builtin - not stored in flash */ ++#define ENV_FLG_READONLY 0x02 /* read-only - cannot be changed */ + -+/* -+ * Commit NVRAM variables to permanent storage. All pointers to values -+ * may be invalid after a commit. -+ * NVRAM values are undefined after a commit. -+ * @return 0 on success and errno on failure -+ */ -+extern int BCMINIT(nvram_commit)(void); ++#define ENV_FLG_MASK 0xFF /* mask of attributes we keep */ ++#define ENV_FLG_ADMIN 0x100 /* lets us internally override permissions */ + -+/* -+ * Get all NVRAM variables (format name=value\0 ... \0\0). -+ * @param buf buffer to store variables -+ * @param count size of buffer in bytes -+ * @return 0 on success and errno on failure -+ */ -+extern int BCMINIT(nvram_getall)(char *buf, int count); + -+#endif /* _LANGUAGE_ASSEMBLY */ ++/* ********************************************************************* ++ * _nvram_read(buffer,offset,length) ++ * ++ * Read data from the NVRAM device ++ * ++ * Input parameters: ++ * buffer - destination buffer ++ * offset - offset of data to read ++ * length - number of bytes to read ++ * ++ * Return value: ++ * number of bytes read, or <0 if error occured ++ ********************************************************************* */ ++static int ++_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length) ++{ ++ int i; ++ if (offset > NVRAM_SIZE) ++ return -1; + -+#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ -+#define NVRAM_VERSION 1 -+#define NVRAM_HEADER_SIZE 20 -+#define NVRAM_SPACE 0x8000 ++ for ( i = 0; i < length; i++) { ++ buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i]; ++ } ++ return length; ++} + -+#define NVRAM_MAX_VALUE_LEN 255 -+#define NVRAM_MAX_PARAM_LEN 64 + -+#endif /* _bcmnvram_h_ */ -diff -Naur linux.old/arch/mips/bcm947xx/include/bcmsrom.h linux.dev/arch/mips/bcm947xx/include/bcmsrom.h ---- linux.old/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmsrom.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,23 @@ -+/* -+ * Misc useful routines to access NIC local SROM/OTP . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++static char* ++_strnchr(const char *dest,int c,size_t cnt) ++{ ++ while (*dest && (cnt > 0)) { ++ if (*dest == c) return (char *) dest; ++ dest++; ++ cnt--; ++ } ++ return NULL; ++} + -+#ifndef _bcmsrom_h_ -+#define _bcmsrom_h_ + -+extern int srom_var_init(void *sbh, uint bus, void *curmap, osl_t *osh, char **vars, int *count); + -+extern int srom_read(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); -+extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); ++/* ++ * Core support API: Externally visible. ++ */ + -+#endif /* _bcmsrom_h_ */ -diff -Naur linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bcm947xx/include/bcmutils.h ---- linux.old/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmutils.h 2006-04-06 17:07:30.000000000 +0200 -@@ -0,0 +1,287 @@ +/* -+ * Misc useful os-independent macros and functions. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ ++ * Get the value of an NVRAM variable ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined + */ + -+#ifndef _bcmutils_h_ -+#define _bcmutils_h_ ++char* ++cfe_env_get(unsigned char *nv_buf, char* name) ++{ ++ int size; ++ unsigned char *buffer; ++ unsigned char *ptr; ++ unsigned char *envval; ++ unsigned int reclen; ++ unsigned int rectype; ++ int offset; ++ int flg; ++ ++ size = NVRAM_SIZE; ++ buffer = &_nvdata[0]; + -+/*** driver-only section ***/ -+#ifdef BCMDRIVER -+#include ++ ptr = buffer; ++ offset = 0; + -+#define _BCM_U 0x01 /* upper */ -+#define _BCM_L 0x02 /* lower */ -+#define _BCM_D 0x04 /* digit */ -+#define _BCM_C 0x08 /* cntrl */ -+#define _BCM_P 0x10 /* punct */ -+#define _BCM_S 0x20 /* white space (space/lf/tab) */ -+#define _BCM_X 0x40 /* hex digit */ -+#define _BCM_SP 0x80 /* hard space (0x20) */ ++ /* Read the record type and length */ ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { ++ goto error; ++ } ++ ++ while ((*ptr != ENV_TLV_TYPE_END) && (size > 1)) { + -+#define GPIO_PIN_NOTDEFINED 0x20 ++ /* Adjust pointer for TLV type */ ++ rectype = *(ptr); ++ offset++; ++ size--; + -+extern unsigned char bcm_ctype[]; -+#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) ++ /* ++ * Read the length. It can be either 1 or 2 bytes ++ * depending on the code ++ */ ++ if (rectype & ENV_LENGTH_8BITS) { ++ /* Read the record type and length - 8 bits */ ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) { ++ goto error; ++ } ++ reclen = *(ptr); ++ size--; ++ offset++; ++ } ++ else { ++ /* Read the record type and length - 16 bits, MSB first */ ++ if (_nvram_read(nv_buf, ptr,offset,2) != 2) { ++ goto error; ++ } ++ reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1); ++ size -= 2; ++ offset += 2; ++ } + -+#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) -+#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) -+#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) -+#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) -+#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) -+#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) -+#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) -+#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) -+#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) -+#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) -+#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) -+ -+/* -+ * Spin at most 'us' microseconds while 'exp' is true. -+ * Caller should explicitly test 'exp' when this completes -+ * and take appropriate error action if 'exp' is still true. -+ */ -+#define SPINWAIT(exp, us) { \ -+ uint countdown = (us) + 9; \ -+ while ((exp) && (countdown >= 10)) {\ -+ OSL_DELAY(10); \ -+ countdown -= 10; \ -+ } \ -+} -+ -+/* string */ -+extern uint bcm_atoi(char *s); -+extern uchar bcm_toupper(uchar c); -+extern ulong bcm_strtoul(char *cp, char **endp, uint base); -+extern char *bcmstrstr(char *haystack, char *needle); -+extern char *bcmstrcat(char *dest, const char *src); -+extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); -+/* ethernet address */ -+extern char *bcm_ether_ntoa(char *ea, char *buf); -+extern int bcm_ether_atoe(char *p, char *ea); -+/* delay */ -+extern void bcm_mdelay(uint ms); -+/* variable access */ -+extern char *getvar(char *vars, char *name); -+extern int getintvar(char *vars, char *name); -+extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); -+#define bcmlog(fmt, a1, a2) -+#define bcmdumplog(buf, size) *buf = '\0' -+#define bcmdumplogent(buf, idx) -1 ++ if (reclen > size) ++ break; /* should not happen, bad NVRAM */ + -+#endif /* #ifdef BCMDRIVER */ ++ switch (rectype) { ++ case ENV_TLV_TYPE_ENV: ++ /* Read the TLV data */ ++ if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen) ++ goto error; ++ flg = *ptr++; ++ envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1)); ++ if (envval) { ++ *envval++ = '\0'; ++ memcpy(_valuestr,envval,(reclen-1)-(envval-ptr)); ++ _valuestr[(reclen-1)-(envval-ptr)] = '\0'; ++#if 0 ++ printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr); ++#endif ++ if(!strcmp(ptr, name)){ ++ return _valuestr; ++ } ++ if((strlen(ptr) > 1) && !strcmp(&ptr[1], name)) ++ return _valuestr; ++ } ++ break; ++ ++ default: ++ /* Unknown TLV type, skip it. */ ++ break; ++ } + -+/*** driver/apps-shared section ***/ ++ /* ++ * Advance to next TLV ++ */ ++ ++ size -= (int)reclen; ++ offset += reclen; + -+#define BCME_STRLEN 64 -+#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) ++ /* Read the next record type */ ++ ptr = buffer; ++ if (_nvram_read(nv_buf, ptr,offset,1) != 1) ++ goto error; ++ } + ++error: ++ return NULL; + -+/* -+ * error codes could be added but the defined ones shouldn't be changed/deleted -+ * these error codes are exposed to the user code -+ * when ever a new error code is added to this list -+ * please update errorstring table with the related error string and -+ * update osl files with os specific errorcode map -+*/ ++} + -+#define BCME_ERROR -1 /* Error generic */ -+#define BCME_BADARG -2 /* Bad Argument */ -+#define BCME_BADOPTION -3 /* Bad option */ -+#define BCME_NOTUP -4 /* Not up */ -+#define BCME_NOTDOWN -5 /* Not down */ -+#define BCME_NOTAP -6 /* Not AP */ -+#define BCME_NOTSTA -7 /* Not STA */ -+#define BCME_BADKEYIDX -8 /* BAD Key Index */ -+#define BCME_RADIOOFF -9 /* Radio Off */ -+#define BCME_NOTBANDLOCKED -10 /* Not bandlocked */ -+#define BCME_NOCLK -11 /* No Clock*/ -+#define BCME_BADRATESET -12 /* BAD RateSet*/ -+#define BCME_BADBAND -13 /* BAD Band */ -+#define BCME_BUFTOOSHORT -14 /* Buffer too short */ -+#define BCME_BUFTOOLONG -15 /* Buffer too Long */ -+#define BCME_BUSY -16 /* Busy*/ -+#define BCME_NOTASSOCIATED -17 /* Not associated*/ -+#define BCME_BADSSIDLEN -18 /* BAD SSID Len */ -+#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel*/ -+#define BCME_BADCHAN -20 /* BAD Channel */ -+#define BCME_BADADDR -21 /* BAD Address*/ -+#define BCME_NORESOURCE -22 /* No resources*/ -+#define BCME_UNSUPPORTED -23 /* Unsupported*/ -+#define BCME_BADLEN -24 /* Bad Length*/ -+#define BCME_NOTREADY -25 /* Not ready Yet*/ -+#define BCME_EPERM -26 /* Not Permitted */ -+#define BCME_NOMEM -27 /* No Memory */ -+#define BCME_ASSOCIATED -28 /* Associated */ -+#define BCME_RANGE -29 /* Range Error*/ -+#define BCME_NOTFOUND -30 /* Not found */ -+#define BCME_LAST BCME_NOTFOUND +diff -urN linux.old/arch/mips/bcm947xx/compressed/Makefile linux.dev/arch/mips/bcm947xx/compressed/Makefile +--- linux.old/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/compressed/Makefile 2006-04-27 19:24:19.000000000 +0200 +@@ -0,0 +1,33 @@ ++# ++# Makefile for Broadcom BCM947XX boards ++# ++# Copyright 2001-2003, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: Makefile,v 1.2 2005/04/02 12:12:57 wbx Exp $ ++# + -+#ifndef ABS -+#define ABS(a) (((a)<0)?-(a):(a)) -+#endif ++OBJCOPY_ARGS = -O binary -R .reginfo -R .note -R .comment -R .mdebug -S ++SYSTEM ?= $(TOPDIR)/vmlinux + -+#ifndef MIN -+#define MIN(a, b) (((a)<(b))?(a):(b)) -+#endif ++all: vmlinuz + -+#ifndef MAX -+#define MAX(a, b) (((a)>(b))?(a):(b)) -+#endif ++# Don't build dependencies, this may die if $(CC) isn't gcc ++dep: + -+#define CEIL(x, y) (((x) + ((y)-1)) / (y)) -+#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) -+#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) -+#define ISPOWEROF2(x) ((((x)-1)&(x))==0) -+#define VALID_MASK(mask) !((mask) & ((mask) + 1)) -+#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) -+#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) ++# Create a gzipped version named vmlinuz for compatibility ++vmlinuz: piggy ++ gzip -c9 $< > $@ + -+/* bit map related macros */ -+#ifndef setbit -+#define NBBY 8 /* 8 bits per byte */ -+#define setbit(a,i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) -+#define clrbit(a,i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) -+#define isset(a,i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) -+#define isclr(a,i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) -+#endif ++piggy: $(SYSTEM) ++ $(OBJCOPY) $(OBJCOPY_ARGS) $< $@ + -+#define NBITS(type) (sizeof(type) * 8) -+#define NBITVAL(bits) (1 << (bits)) -+#define MAXBITVAL(bits) ((1 << (bits)) - 1) ++mrproper: clean + -+/* crc defines */ -+#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ -+#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ -+#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ -+#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ -+#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ -+#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ ++clean: ++ rm -f vmlinuz piggy +diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/export.c +--- linux.old/arch/mips/bcm947xx/export.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/export.c 2006-04-28 02:57:34.000000000 +0200 +@@ -0,0 +1,62 @@ ++#include + -+/* bcm_format_flags() bit description structure */ -+typedef struct bcm_bit_desc { -+ uint32 bit; -+ char* name; -+} bcm_bit_desc_t; ++#define _export(n) \ ++ void n(void); \ ++ EXPORT_SYMBOL(n); ++ ++_export(bcm947xx_sbh) ++ ++_export(sb_attach) ++_export(sb_boardtype) ++_export(sb_boardvendor) ++_export(sb_btcgpiowar) ++_export(sb_bus) ++_export(sb_chip) ++_export(sb_chiprev) ++_export(sb_chipcrev) ++_export(sb_chippkg) ++_export(sb_clkctl_clk) ++_export(sb_clkctl_fast_pwrup_delay) ++_export(sb_clkctl_init) ++_export(sb_clkctl_xtal) ++_export(sb_core_disable) ++_export(sb_core_reset) ++_export(sb_core_tofixup) ++_export(sb_coreflags) ++_export(sb_coreflagshi) ++_export(sb_coreidx) ++_export(sb_corerev) ++_export(sb_coreunit) ++_export(sb_detach) ++_export(sb_deviceremoved) ++_export(sb_gpiocontrol) ++_export(sb_gpioled) ++_export(sb_gpioin) ++_export(sb_gpioout) ++_export(sb_gpioouten) ++_export(sb_gpiotimerval) ++_export(sb_iscoreup) ++_export(sb_pci_setup) ++_export(sb_pcirev) ++_export(sb_pcmcia_init) ++_export(sb_pcmciarev) ++_export(sb_register_intr_callback) ++_export(sb_setcore) ++_export(sb_war16165) ++_export(sb_osh) ++ ++_export(getvar) ++_export(getintvar) ++_export(bcm_strtoul) ++_export(bcm_ctype) ++_export(bcm_toupper) ++_export(bcm_ether_ntoa) ++ ++_export(nvram_get) ++_export(nvram_getall) ++_export(nvram_set) ++_export(nvram_unset) ++_export(nvram_commit) ++ ++_export(srom_read) ++_export(srom_write) +diff -urN linux.old/arch/mips/bcm947xx/generic/Makefile linux.dev/arch/mips/bcm947xx/generic/Makefile +--- linux.old/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/generic/Makefile 2006-04-27 19:24:19.000000000 +0200 +@@ -0,0 +1,15 @@ ++# ++# Makefile for the BCM947xx specific kernel interface routines ++# under Linux. ++# + -+/* tag_ID/length/value_buffer tuple */ -+typedef struct bcm_tlv { -+ uint8 id; -+ uint8 len; -+ uint8 data[1]; -+} bcm_tlv_t; ++.S.s: ++ $(CPP) $(AFLAGS) $< -o $*.s ++.S.o: ++ $(CC) $(AFLAGS) -c $< -o $*.o + -+/* Check that bcm_tlv_t fits into the given buflen */ -+#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) ++O_TARGET := brcm.o + -+/* buffer length for ethernet address from bcm_ether_ntoa() */ -+#define ETHER_ADDR_STR_LEN 18 ++obj-y := int-handler.o irq.o + -+/* unaligned load and store macros */ -+#ifdef IL_BIGENDIAN -+static INLINE uint32 -+load32_ua(uint8 *a) -+{ -+ return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); -+} ++include $(TOPDIR)/Rules.make +diff -urN linux.old/arch/mips/bcm947xx/generic/int-handler.S linux.dev/arch/mips/bcm947xx/generic/int-handler.S +--- linux.old/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/generic/int-handler.S 2006-04-27 19:24:19.000000000 +0200 +@@ -0,0 +1,51 @@ ++/* ++ * Generic interrupt handler for Broadcom MIPS boards ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: int-handler.S,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ + -+static INLINE void -+store32_ua(uint8 *a, uint32 v) -+{ -+ a[0] = (v >> 24) & 0xff; -+ a[1] = (v >> 16) & 0xff; -+ a[2] = (v >> 8) & 0xff; -+ a[3] = v & 0xff; -+} ++#include + -+static INLINE uint16 -+load16_ua(uint8 *a) -+{ -+ return ((a[0] << 8) | a[1]); -+} ++#include ++#include ++#include ++#include + -+static INLINE void -+store16_ua(uint8 *a, uint16 v) -+{ -+ a[0] = (v >> 8) & 0xff; -+ a[1] = v & 0xff; -+} ++/* ++ * MIPS IRQ Source ++ * -------- ------ ++ * 0 Software (ignored) ++ * 1 Software (ignored) ++ * 2 Combined hardware interrupt (hw0) ++ * 3 Hardware ++ * 4 Hardware ++ * 5 Hardware ++ * 6 Hardware ++ * 7 R4k timer ++ */ + -+#else ++ .text ++ .set noreorder ++ .set noat ++ .align 5 ++ NESTED(brcmIRQ, PT_SIZE, sp) ++ SAVE_ALL ++ CLI ++ .set at ++ .set noreorder + -+static INLINE uint32 -+load32_ua(uint8 *a) -+{ -+ return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]); -+} ++ jal brcm_irq_dispatch ++ move a0, sp + -+static INLINE void -+store32_ua(uint8 *a, uint32 v) -+{ -+ a[3] = (v >> 24) & 0xff; -+ a[2] = (v >> 16) & 0xff; -+ a[1] = (v >> 8) & 0xff; -+ a[0] = v & 0xff; -+} ++ j ret_from_irq ++ nop ++ ++ END(brcmIRQ) +diff -urN linux.old/arch/mips/bcm947xx/generic/irq.c linux.dev/arch/mips/bcm947xx/generic/irq.c +--- linux.old/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/generic/irq.c 2006-04-27 19:24:19.000000000 +0200 +@@ -0,0 +1,130 @@ ++/* ++ * Generic interrupt control functions for Broadcom MIPS boards ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: irq.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ */ + -+static INLINE uint16 -+load16_ua(uint8 *a) ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5) ++ ++extern asmlinkage void brcmIRQ(void); ++extern asmlinkage unsigned int do_IRQ(int irq, struct pt_regs *regs); ++ ++void ++brcm_irq_dispatch(struct pt_regs *regs) +{ -+ return ((a[1] << 8) | a[0]); ++ u32 cause; ++ ++ cause = read_c0_cause() & ++ read_c0_status() & ++ CAUSEF_IP; ++ ++#ifdef CONFIG_KERNPROF ++ change_c0_status(cause | 1, 1); ++#else ++ clear_c0_status(cause); ++#endif ++ ++ if (cause & CAUSEF_IP7) ++ do_IRQ(7, regs); ++ if (cause & CAUSEF_IP2) ++ do_IRQ(2, regs); ++ if (cause & CAUSEF_IP3) ++ do_IRQ(3, regs); ++ if (cause & CAUSEF_IP4) ++ do_IRQ(4, regs); ++ if (cause & CAUSEF_IP5) ++ do_IRQ(5, regs); ++ if (cause & CAUSEF_IP6) ++ do_IRQ(6, regs); +} + -+static INLINE void -+store16_ua(uint8 *a, uint16 v) ++static void ++enable_brcm_irq(unsigned int irq) +{ -+ a[1] = (v >> 8) & 0xff; -+ a[0] = v & 0xff; ++ if (irq < 8) ++ set_c0_status(1 << (irq + 8)); ++ else ++ set_c0_status(IE_IRQ0); +} + -+#endif ++static void ++disable_brcm_irq(unsigned int irq) ++{ ++ if (irq < 8) ++ clear_c0_status(1 << (irq + 8)); ++ else ++ clear_c0_status(IE_IRQ0); ++} + -+/* externs */ -+/* crc */ -+extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); -+extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); -+extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); -+/* format/print */ -+/* IE parsing */ -+extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); -+extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); -+extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); ++static void ++ack_brcm_irq(unsigned int irq) ++{ ++ /* Already done in brcm_irq_dispatch */ ++} + -+/* bcmerror*/ -+extern const char *bcmerrorstr(int bcmerror); ++static unsigned int ++startup_brcm_irq(unsigned int irq) ++{ ++ enable_brcm_irq(irq); + -+/* multi-bool data type: set of bools, mbool is true if any is set */ -+typedef uint32 mbool; -+#define mboolset(mb, bit) (mb |= bit) /* set one bool */ -+#define mboolclr(mb, bit) (mb &= ~bit) /* clear one bool */ -+#define mboolisset(mb, bit) ((mb & bit) != 0) /* TRUE if one bool is set */ -+#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) ++ return 0; /* never anything pending */ ++} + -+/* power conversion */ -+extern uint16 bcm_qdbm_to_mw(uint8 qdbm); -+extern uint8 bcm_mw_to_qdbm(uint16 mw); ++static void ++end_brcm_irq(unsigned int irq) ++{ ++ if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) ++ enable_brcm_irq(irq); ++} + -+/* generic datastruct to help dump routines */ -+struct fielddesc { -+ char *nameandfmt; -+ uint32 offset; -+ uint32 len; ++static struct hw_interrupt_type brcm_irq_type = { ++ typename: "MIPS", ++ startup: startup_brcm_irq, ++ shutdown: disable_brcm_irq, ++ enable: enable_brcm_irq, ++ disable: disable_brcm_irq, ++ ack: ack_brcm_irq, ++ end: end_brcm_irq, ++ NULL +}; + -+typedef uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset); -+extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str, char *buf, uint32 bufsize); ++void __init ++init_IRQ(void) ++{ ++ int i; + -+extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); ++ for (i = 0; i < NR_IRQS; i++) { ++ irq_desc[i].status = IRQ_DISABLED; ++ irq_desc[i].action = 0; ++ irq_desc[i].depth = 1; ++ irq_desc[i].handler = &brcm_irq_type; ++ } + -+#endif /* _bcmutils_h_ */ -diff -Naur linux.old/arch/mips/bcm947xx/include/hndmips.h linux.dev/arch/mips/bcm947xx/include/hndmips.h ---- linux.old/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/hndmips.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,16 @@ -+/* -+ * Alternate include file for HND sbmips.h since CFE also ships with -+ * a sbmips.h. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++ set_except_vector(0, brcmIRQ); ++ change_c0_status(ST0_IM, ALLINTS); + -+#include "sbmips.h" -diff -Naur linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/bcm947xx/include/linux_osl.h ---- linux.old/arch/mips/bcm947xx/include/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/linux_osl.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,371 @@ ++#ifdef CONFIG_REMOTE_DEBUG ++ printk("Breaking into debugger...\n"); ++ set_debug_traps(); ++ breakpoint(); ++#endif ++} +diff -urN linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio.c +--- linux.old/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/gpio.c 2006-04-27 23:09:33.000000000 +0200 +@@ -0,0 +1,159 @@ +/* -+ * Linux OS Independent Layer ++ * GPIO char driver + * + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. @@ -1745,3037 +2084,2324 @@ diff -Naur linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/ + * $Id$ + */ + -+#ifndef _linux_osl_h_ -+#define _linux_osl_h_ ++#include ++#include ++#include ++#include ++#include + +#include ++#include ++#include ++#include ++#include + -+/* use current 2.4.x calling conventions */ -+#include -+ -+/* assert and panic */ -+#ifdef __GNUC__ -+#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -+#if GCC_VERSION > 30100 -+#define ASSERT(exp) do {} while (0) -+#else -+/* ASSERT could causes segmentation fault on GCC3.1, use empty instead*/ -+#define ASSERT(exp) -+#endif -+#endif -+ -+/* microsecond delay */ -+#define OSL_DELAY(usec) osl_delay(usec) -+extern void osl_delay(uint usec); -+ -+/* PCMCIA attribute space access macros */ -+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) -+struct pcmcia_dev { -+ dev_link_t link; /* PCMCIA device pointer */ -+ dev_node_t node; /* PCMCIA node structure */ -+ void *base; /* Mapped attribute memory window */ -+ size_t size; /* Size of window */ -+ void *drv; /* Driver data */ ++static sb_t *gpio_sbh; ++static int gpio_major; ++static devfs_handle_t gpio_dir; ++static struct { ++ char *name; ++ devfs_handle_t handle; ++} gpio_file[] = { ++ { "in", NULL }, ++ { "out", NULL }, ++ { "outen", NULL }, ++ { "control", NULL } +}; -+#endif -+#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) \ -+ osl_pcmcia_read_attr((osh), (offset), (buf), (size)) -+#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) \ -+ osl_pcmcia_write_attr((osh), (offset), (buf), (size)) -+extern void osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size); -+extern void osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size); -+ -+/* PCI configuration space access macros */ -+#define OSL_PCI_READ_CONFIG(osh, offset, size) \ -+ osl_pci_read_config((osh), (offset), (size)) -+#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ -+ osl_pci_write_config((osh), (offset), (size), (val)) -+extern uint32 osl_pci_read_config(osl_t *osh, uint size, uint offset); -+extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); + -+/* PCI device bus # and slot # */ -+#define OSL_PCI_BUS(osh) osl_pci_bus(osh) -+#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -+extern uint osl_pci_bus(osl_t *osh); -+extern uint osl_pci_slot(osl_t *osh); ++static int ++gpio_open(struct inode *inode, struct file * file) ++{ ++ if (MINOR(inode->i_rdev) > ARRAYSIZE(gpio_file)) ++ return -ENODEV; + -+/* OSL initialization */ -+extern osl_t *osl_attach(void *pdev); -+extern void osl_detach(osl_t *osh); ++ MOD_INC_USE_COUNT; ++ return 0; ++} + -+/* host/bus architecture-specific byte swap */ -+#define BUS_SWAP32(v) (v) ++static int ++gpio_release(struct inode *inode, struct file * file) ++{ ++ MOD_DEC_USE_COUNT; ++ return 0; ++} + -+/* general purpose memory allocation */ ++static ssize_t ++gpio_read(struct file *file, char *buf, size_t count, loff_t *ppos) ++{ ++ u32 val; + -+#if defined(BCMDBG_MEM) ++ switch (MINOR(file->f_dentry->d_inode->i_rdev)) { ++ case 0: ++ val = sb_gpioin(gpio_sbh); ++ break; ++ case 1: ++ val = sb_gpioout(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); ++ break; ++ case 2: ++ val = sb_gpioouten(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); ++ break; ++ case 3: ++ val = sb_gpiocontrol(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); ++ break; ++ default: ++ return -ENODEV; ++ } + -+#define MALLOC(osh, size) osl_debug_malloc((osh), (size), __LINE__, __FILE__) -+#define MFREE(osh, addr, size) osl_debug_mfree((osh), (addr), (size), __LINE__, __FILE__) -+#define MALLOCED(osh) osl_malloced((osh)) -+#define MALLOC_DUMP(osh, buf, sz) osl_debug_memdump((osh), (buf), (sz)) -+extern void *osl_debug_malloc(osl_t *osh, uint size, int line, char* file); -+extern void osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file); -+extern char *osl_debug_memdump(osl_t *osh, char *buf, uint sz); ++ if (put_user(val, (u32 *) buf)) ++ return -EFAULT; + -+#else ++ return sizeof(val); ++} + -+#define MALLOC(osh, size) osl_malloc((osh), (size)) -+#define MFREE(osh, addr, size) osl_mfree((osh), (addr), (size)) -+#define MALLOCED(osh) osl_malloced((osh)) ++static ssize_t ++gpio_write(struct file *file, const char *buf, size_t count, loff_t *ppos) ++{ ++ u32 val; + -+#endif /* BCMDBG_MEM */ -+ -+#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) -+ -+extern void *osl_malloc(osl_t *osh, uint size); -+extern void osl_mfree(osl_t *osh, void *addr, uint size); -+extern uint osl_malloced(osl_t *osh); -+extern uint osl_malloc_failed(osl_t *osh); -+ -+/* allocate/free shared (dma-able) consistent memory */ -+#define DMA_CONSISTENT_ALIGN PAGE_SIZE -+#define DMA_ALLOC_CONSISTENT(osh, size, pap) \ -+ osl_dma_alloc_consistent((osh), (size), (pap)) -+#define DMA_FREE_CONSISTENT(osh, va, size, pa) \ -+ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) -+extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap); -+extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa); -+ -+/* map/unmap direction */ -+#define DMA_TX 1 -+#define DMA_RX 2 -+ -+/* map/unmap shared (dma-able) memory */ -+#define DMA_MAP(osh, va, size, direction, p) \ -+ osl_dma_map((osh), (va), (size), (direction)) -+#define DMA_UNMAP(osh, pa, size, direction, p) \ -+ osl_dma_unmap((osh), (pa), (size), (direction)) -+extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); -+extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); -+ -+/* register access macros */ -+#if defined(BCMJTAG) -+#include -+#define R_REG(r) bcmjtag_read(NULL, (uint32)(r), sizeof (*(r))) -+#define W_REG(r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof (*(r))) -+#endif -+ -+/* -+ * BINOSL selects the slightly slower function-call-based binary compatible osl. -+ * Macros expand to calls to functions defined in linux_osl.c . -+ */ -+#ifndef BINOSL -+ -+/* string library, kernel mode */ -+#define printf(fmt, args...) printk(fmt, ## args) -+#include -+#include -+ -+/* register access macros */ -+#if !defined(BCMJTAG) -+#ifndef IL_BIGENDIAN -+#define R_REG(r) ( \ -+ sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ -+ sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ -+ readl((volatile uint32*)(r)) \ -+) -+#define W_REG(r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ -+ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ -+ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ -+ } \ -+} while (0) -+#else /* IL_BIGENDIAN */ -+#define R_REG(r) ({ \ -+ __typeof(*(r)) __osl_v; \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \ -+ case sizeof(uint16): __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \ -+ case sizeof(uint32): __osl_v = readl((volatile uint32*)(r)); break; \ -+ } \ -+ __osl_v; \ -+}) -+#define W_REG(r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \ -+ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \ -+ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ -+ } \ -+} while (0) -+#endif -+#endif -+ -+#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) -+#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) -+ -+/* bcopy, bcmp, and bzero */ -+#define bcopy(src, dst, len) memcpy((dst), (src), (len)) -+#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -+#define bzero(b, len) memset((b), '\0', (len)) -+ -+/* uncached virtual address */ -+#ifdef mips -+#define OSL_UNCACHED(va) KSEG1ADDR((va)) -+#include -+#else -+#define OSL_UNCACHED(va) (va) -+#endif -+ -+/* get processor cycle count */ -+#if defined(mips) -+#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2) -+#elif defined(__i386__) -+#define OSL_GETCYCLES(x) rdtscl((x)) -+#else -+#define OSL_GETCYCLES(x) ((x) = 0) -+#endif -+ -+/* dereference an address that may cause a bus exception */ -+#ifdef mips -+#if defined(MODULE) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,17)) -+#define BUSPROBE(val, addr) panic("get_dbe() will not fixup a bus exception when compiled into a module") -+#else -+#define BUSPROBE(val, addr) get_dbe((val), (addr)) -+#include -+#endif -+#else -+#define BUSPROBE(val, addr) ({ (val) = R_REG((addr)); 0; }) -+#endif -+ -+/* map/unmap physical to virtual I/O */ -+#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) -+#define REG_UNMAP(va) iounmap((void *)(va)) -+ -+/* shared (dma-able) memory access macros */ -+#define R_SM(r) *(r) -+#define W_SM(r, v) (*(r) = (v)) -+#define BZERO_SM(r, len) memset((r), '\0', (len)) -+ -+/* packet primitives */ -+#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) -+#define PKTFREE(osh, skb, send) osl_pktfree((skb)) -+#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) -+#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) -+#define PKTHEADROOM(osh, skb) (PKTDATA(osh,skb)-(((struct sk_buff*)(skb))->head)) -+#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) -+#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) -+#define PKTSETNEXT(skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) -+#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) -+#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) -+#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) -+#define PKTDUP(osh, skb) skb_clone((struct sk_buff*)(skb), GFP_ATOMIC) -+#define PKTCOOKIE(skb) ((void*)((struct sk_buff*)(skb))->csum) -+#define PKTSETCOOKIE(skb, x) (((struct sk_buff*)(skb))->csum = (uint)(x)) -+#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) -+#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) -+#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) -+#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) -+extern void *osl_pktget(osl_t *osh, uint len, bool send); -+extern void osl_pktfree(void *skb); -+ -+#else /* BINOSL */ -+ -+/* string library */ -+#ifndef LINUX_OSL -+#undef printf -+#define printf(fmt, args...) osl_printf((fmt), ## args) -+#undef sprintf -+#define sprintf(buf, fmt, args...) osl_sprintf((buf), (fmt), ## args) -+#undef strcmp -+#define strcmp(s1, s2) osl_strcmp((s1), (s2)) -+#undef strncmp -+#define strncmp(s1, s2, n) osl_strncmp((s1), (s2), (n)) -+#undef strlen -+#define strlen(s) osl_strlen((s)) -+#undef strcpy -+#define strcpy(d, s) osl_strcpy((d), (s)) -+#undef strncpy -+#define strncpy(d, s, n) osl_strncpy((d), (s), (n)) -+#endif -+extern int osl_printf(const char *format, ...); -+extern int osl_sprintf(char *buf, const char *format, ...); -+extern int osl_strcmp(const char *s1, const char *s2); -+extern int osl_strncmp(const char *s1, const char *s2, uint n); -+extern int osl_strlen(const char *s); -+extern char* osl_strcpy(char *d, const char *s); -+extern char* osl_strncpy(char *d, const char *s, uint n); ++ if (get_user(val, (u32 *) buf)) ++ return -EFAULT; + -+/* register access macros */ -+#if !defined(BCMJTAG) -+#define R_REG(r) ( \ -+ sizeof(*(r)) == sizeof(uint8) ? osl_readb((volatile uint8*)(r)) : \ -+ sizeof(*(r)) == sizeof(uint16) ? osl_readw((volatile uint16*)(r)) : \ -+ osl_readl((volatile uint32*)(r)) \ -+) -+#define W_REG(r, v) do { \ -+ switch (sizeof(*(r))) { \ -+ case sizeof(uint8): osl_writeb((uint8)(v), (volatile uint8*)(r)); break; \ -+ case sizeof(uint16): osl_writew((uint16)(v), (volatile uint16*)(r)); break; \ -+ case sizeof(uint32): osl_writel((uint32)(v), (volatile uint32*)(r)); break; \ -+ } \ -+} while (0) -+#endif ++ switch (MINOR(file->f_dentry->d_inode->i_rdev)) { ++ case 0: ++ return -EACCES; ++ case 1: ++ sb_gpioout(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); ++ break; ++ case 2: ++ sb_gpioouten(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); ++ break; ++ case 3: ++ sb_gpiocontrol(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); ++ break; ++ default: ++ return -ENODEV; ++ } + -+#define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) -+#define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) -+extern uint8 osl_readb(volatile uint8 *r); -+extern uint16 osl_readw(volatile uint16 *r); -+extern uint32 osl_readl(volatile uint32 *r); -+extern void osl_writeb(uint8 v, volatile uint8 *r); -+extern void osl_writew(uint16 v, volatile uint16 *r); -+extern void osl_writel(uint32 v, volatile uint32 *r); ++ return sizeof(val); ++} + -+/* bcopy, bcmp, and bzero */ -+extern void bcopy(const void *src, void *dst, int len); -+extern int bcmp(const void *b1, const void *b2, int len); -+extern void bzero(void *b, int len); ++static struct file_operations gpio_fops = { ++ owner: THIS_MODULE, ++ open: gpio_open, ++ release: gpio_release, ++ read: gpio_read, ++ write: gpio_write, ++}; + -+/* uncached virtual address */ -+#define OSL_UNCACHED(va) osl_uncached((va)) -+extern void *osl_uncached(void *va); ++static int __init ++gpio_init(void) ++{ ++ int i; + -+/* get processor cycle count */ -+#define OSL_GETCYCLES(x) ((x) = osl_getcycles()) -+extern uint osl_getcycles(void); ++ if (!(gpio_sbh = sb_kattach())) ++ return -ENODEV; + -+/* dereference an address that may target abort */ -+#define BUSPROBE(val, addr) osl_busprobe(&(val), (addr)) -+extern int osl_busprobe(uint32 *val, uint32 addr); ++ sb_gpiosetcore(gpio_sbh); + -+/* map/unmap physical to virtual */ -+#define REG_MAP(pa, size) osl_reg_map((pa), (size)) -+#define REG_UNMAP(va) osl_reg_unmap((va)) -+extern void *osl_reg_map(uint32 pa, uint size); -+extern void osl_reg_unmap(void *va); ++ if ((gpio_major = devfs_register_chrdev(0, "gpio", &gpio_fops)) < 0) ++ return gpio_major; + -+/* shared (dma-able) memory access macros */ -+#define R_SM(r) *(r) -+#define W_SM(r, v) (*(r) = (v)) -+#define BZERO_SM(r, len) bzero((r), (len)) ++ gpio_dir = devfs_mk_dir(NULL, "gpio", NULL); + -+/* packet primitives */ -+#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) -+#define PKTFREE(osh, skb, send) osl_pktfree((skb)) -+#define PKTDATA(osh, skb) osl_pktdata((osh), (skb)) -+#define PKTLEN(osh, skb) osl_pktlen((osh), (skb)) -+#define PKTHEADROOM(osh, skb) osl_pktheadroom((osh), (skb)) -+#define PKTTAILROOM(osh, skb) osl_pkttailroom((osh), (skb)) -+#define PKTNEXT(osh, skb) osl_pktnext((osh), (skb)) -+#define PKTSETNEXT(skb, x) osl_pktsetnext((skb), (x)) -+#define PKTSETLEN(osh, skb, len) osl_pktsetlen((osh), (skb), (len)) -+#define PKTPUSH(osh, skb, bytes) osl_pktpush((osh), (skb), (bytes)) -+#define PKTPULL(osh, skb, bytes) osl_pktpull((osh), (skb), (bytes)) -+#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -+#define PKTCOOKIE(skb) osl_pktcookie((skb)) -+#define PKTSETCOOKIE(skb, x) osl_pktsetcookie((skb), (x)) -+#define PKTLINK(skb) osl_pktlink((skb)) -+#define PKTSETLINK(skb, x) osl_pktsetlink((skb), (x)) -+#define PKTPRIO(skb) osl_pktprio((skb)) -+#define PKTSETPRIO(skb, x) osl_pktsetprio((skb), (x)) -+extern void *osl_pktget(osl_t *osh, uint len, bool send); -+extern void osl_pktfree(void *skb); -+extern uchar *osl_pktdata(osl_t *osh, void *skb); -+extern uint osl_pktlen(osl_t *osh, void *skb); -+extern uint osl_pktheadroom(osl_t *osh, void *skb); -+extern uint osl_pkttailroom(osl_t *osh, void *skb); -+extern void *osl_pktnext(osl_t *osh, void *skb); -+extern void osl_pktsetnext(void *skb, void *x); -+extern void osl_pktsetlen(osl_t *osh, void *skb, uint len); -+extern uchar *osl_pktpush(osl_t *osh, void *skb, int bytes); -+extern uchar *osl_pktpull(osl_t *osh, void *skb, int bytes); -+extern void *osl_pktdup(osl_t *osh, void *skb); -+extern void *osl_pktcookie(void *skb); -+extern void osl_pktsetcookie(void *skb, void *x); -+extern void *osl_pktlink(void *skb); -+extern void osl_pktsetlink(void *skb, void *x); -+extern uint osl_pktprio(void *skb); -+extern void osl_pktsetprio(void *skb, uint x); ++ for (i = 0; i < ARRAYSIZE(gpio_file); i++) { ++ gpio_file[i].handle = devfs_register(gpio_dir, ++ gpio_file[i].name, ++ DEVFS_FL_DEFAULT, gpio_major, i, ++ S_IFCHR | S_IRUGO | S_IWUGO, ++ &gpio_fops, NULL); ++ } + -+#endif /* BINOSL */ ++ return 0; ++} + -+#define OSL_ERROR(bcmerror) osl_error(bcmerror) -+extern int osl_error(int bcmerror); ++static void __exit ++gpio_exit(void) ++{ ++ int i; + -+/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -+#define PKTBUFSZ 2048 ++ for (i = 0; i < ARRAYSIZE(gpio_file); i++) ++ devfs_unregister(gpio_file[i].handle); ++ devfs_unregister(gpio_dir); ++ devfs_unregister_chrdev(gpio_major, "gpio"); ++ sb_detach(gpio_sbh); ++} + -+#endif /* _linux_osl_h_ */ -diff -Naur linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bcm947xx/include/linuxver.h ---- linux.old/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/linuxver.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,411 @@ ++module_init(gpio_init); ++module_exit(gpio_exit); +diff -urN linux.old/arch/mips/bcm947xx/hndchipc.c linux.dev/arch/mips/bcm947xx/hndchipc.c +--- linux.old/arch/mips/bcm947xx/hndchipc.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/hndchipc.c 2006-04-28 00:33:05.000000000 +0200 +@@ -0,0 +1,158 @@ +/* -+ * Linux-specific abstractions to gain some independence from linux kernel versions. -+ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. ++ * BCM47XX support code for some chipcommon (old extif) facilities (uart) + * -+ * Copyright 2005, Broadcom Corporation ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ ++ * ++ * $Id: hndchipc.c,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $ + */ + -+#ifndef _linuxver_h_ -+#define _linuxver_h_ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+#include -+#include ++/* ++ * Returns TRUE if an external UART exists at the given base ++ * register. ++ */ ++static bool ++BCMINITFN(serial_exists)(osl_t *osh, uint8 *regs) ++{ ++ uint8 save_mcr, status1; + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) -+/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ -+#ifdef __UNDEF_NO_VERSION__ -+#undef __NO_VERSION__ -+#else -+#define __NO_VERSION__ -+#endif -+#endif ++ save_mcr = R_REG(osh, ®s[UART_MCR]); ++ W_REG(osh, ®s[UART_MCR], UART_MCR_LOOP | 0x0a); ++ status1 = R_REG(osh, ®s[UART_MSR]) & 0xf0; ++ W_REG(osh, ®s[UART_MCR], save_mcr); + -+#if defined(MODULE) && defined(MODVERSIONS) -+#include -+#endif ++ return (status1 == 0x90); ++} + -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) -+#include -+#endif ++/* ++ * Initializes UART access. The callback function will be called once ++ * per found UART. ++ */ ++void ++BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, ++ uint reg_shift)) ++{ ++ osl_t *osh; ++ void *regs; ++ ulong base; ++ uint irq; ++ int i, n; + ++ osh = sb_osh(sbh); + -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) -+#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") -+#define module_param_string(_name_, _string_, _size_, _perm_) MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) -+#endif ++ if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) { ++ extifregs_t *eir = (extifregs_t *) regs; ++ sbconfig_t *sb; + -+/* linux/malloc.h is deprecated, use linux/slab.h instead. */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,9)) -+#include -+#else -+#include -+#endif ++ /* Determine external UART register base */ ++ sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF); ++ base = EXTIF_CFGIF_BASE(sb_base(R_REG(osh, &sb->sbadmatch1))); + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); + -+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,41)) -+#include -+#else -+#include -+#ifndef work_struct -+#define work_struct tq_struct -+#endif -+#ifndef INIT_WORK -+#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) -+#endif -+#ifndef schedule_work -+#define schedule_work(_work) schedule_task((_work)) -+#endif -+#ifndef flush_scheduled_work -+#define flush_scheduled_work() flush_scheduled_tasks() -+#endif -+#endif ++ /* Disable GPIO interrupt initially */ ++ W_REG(osh, &eir->gpiointpolarity, 0); ++ W_REG(osh, &eir->gpiointmask, 0); + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) -+/* Some distributions have their own 2.6.x compatibility layers */ -+#ifndef IRQ_NONE -+typedef void irqreturn_t; -+#define IRQ_NONE -+#define IRQ_HANDLED -+#define IRQ_RETVAL(x) -+#endif -+#else -+typedef irqreturn_t (*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); -+#endif ++ /* Search for external UARTs */ ++ n = 2; ++ for (i = 0; i < 2; i++) { ++ regs = (void *) REG_MAP(base + (i * 8), 8); ++ if (serial_exists(osh, regs)) { ++ /* Set GPIO 1 to be the external UART IRQ */ ++ W_REG(osh, &eir->gpiointmask, 2); ++ /* XXXDetermine external UART clock */ ++ if (add) ++ add(regs, irq, 13500000, 0); ++ } ++ } + -+#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++ /* Add internal UART if enabled */ ++ if (R_REG(osh, &eir->corecontrol) & CC_UE) ++ if (add) ++ add((void *) &eir->uartdata, irq, sb_clock(sbh), 2); ++ } else if ((regs = sb_setcore(sbh, SB_CC, 0))) { ++ chipcregs_t *cc = (chipcregs_t *) regs; ++ uint32 rev, cap, pll, baud_base, div; + -+#include -+#include -+#include -+#include -+#include -+#include ++ /* Determine core revision and capabilities */ ++ rev = sb_corerev(sbh); ++ cap = R_REG(osh, &cc->capabilities); ++ pll = cap & CAP_PLL_MASK; + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)) -+/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which -+ * does this, but it's not in 2.4 so we do our own for now. */ -+static inline void -+cs_error(client_handle_t handle, int func, int ret) -+{ -+ error_info_t err = { func, ret }; -+ CardServices(ReportError, handle, &err); -+} -+#endif ++ /* Determine IRQ */ ++ irq = sb_irq(sbh); + -+#endif /* CONFIG_PCMCIA */ ++ if (pll == PLL_TYPE1) { ++ /* PLL clock */ ++ baud_base = sb_clock_rate(pll, ++ R_REG(osh, &cc->clockcontrol_n), ++ R_REG(osh, &cc->clockcontrol_m2)); ++ div = 1; ++ } else { ++ /* Fixed ALP clock */ ++ if (rev >= 11 && rev != 15) { ++ baud_base = 20000000; ++ div = 1; ++ /* Set the override bit so we don't divide it */ ++ W_REG(osh, &cc->corecontrol, CC_UARTCLKO); ++ } ++ /* Internal backplane clock */ ++ else if (rev >= 3) { ++ baud_base = sb_clock(sbh); ++ div = 2; /* Minimum divisor */ ++ W_REG(osh, &cc->clkdiv, ++ ((R_REG(osh, &cc->clkdiv) & ~CLKD_UART) | div)); ++ } ++ /* Fixed internal backplane clock */ ++ else { ++ baud_base = 88000000; ++ div = 48; ++ } + -+#ifndef __exit -+#define __exit -+#endif -+#ifndef __devexit -+#define __devexit -+#endif -+#ifndef __devinit -+#define __devinit __init -+#endif -+#ifndef __devinitdata -+#define __devinitdata -+#endif -+#ifndef __devexit_p -+#define __devexit_p(x) x -+#endif ++ /* Clock source depends on strapping if UartClkOverride is unset */ ++ if ((rev > 0) && ++ ((R_REG(osh, &cc->corecontrol) & CC_UARTCLKO) == 0)) { ++ if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) { ++ /* Internal divided backplane clock */ ++ baud_base /= div; ++ } else { ++ /* Assume external clock of 1.8432 MHz */ ++ baud_base = 1843200; ++ } ++ } ++ } + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)) ++ /* Add internal UARTs */ ++ n = cap & CAP_UARTS_MASK; ++ for (i = 0; i < n; i++) { ++ /* Register offset changed after revision 0 */ ++ if (rev) ++ regs = (void *)((ulong) &cc->uart0data + (i * 256)); ++ else ++ regs = (void *)((ulong) &cc->uart0data + (i * 8)); + -+#define pci_get_drvdata(dev) (dev)->sysdata -+#define pci_set_drvdata(dev, value) (dev)->sysdata=(value) ++ if (add) ++ add(regs, irq, baud_base, 0); ++ } ++ } ++} + +diff -urN linux.old/arch/mips/bcm947xx/include/bcm4710.h linux.dev/arch/mips/bcm947xx/include/bcm4710.h +--- linux.old/arch/mips/bcm947xx/include/bcm4710.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcm4710.h 2006-04-27 22:30:01.000000000 +0200 +@@ -0,0 +1,91 @@ +/* -+ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration ++ * BCM4710 address space map and definitions ++ * Think twice before adding to this file, this is not the kitchen sink ++ * These definitions are not guaranteed for all 47xx chips, only the 4710 ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: bcm4710.h,v 1.3 2004/09/27 07:23:30 tallest Exp $ + */ + -+struct pci_device_id { -+ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ -+ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ -+ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ -+ unsigned long driver_data; /* Data private to the driver */ -+}; -+ -+struct pci_driver { -+ struct list_head node; -+ char *name; -+ const struct pci_device_id *id_table; /* NULL if wants all devices */ -+ int (*probe)(struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ -+ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ -+ void (*suspend)(struct pci_dev *dev); /* Device suspended */ -+ void (*resume)(struct pci_dev *dev); /* Device woken up */ -+}; -+ -+#define MODULE_DEVICE_TABLE(type, name) -+#define PCI_ANY_ID (~0) ++#ifndef _bcm4710_h_ ++#define _bcm4710_h_ + -+/* compatpci.c */ -+#define pci_module_init pci_register_driver -+extern int pci_register_driver(struct pci_driver *drv); -+extern void pci_unregister_driver(struct pci_driver *drv); ++/* Address map */ ++#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */ ++#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */ ++#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */ ++#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */ ++#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */ + -+#endif /* PCI registration */ ++/* Core register space */ ++#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */ ++#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */ ++#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */ ++#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */ ++#define BCM4710_REG_USB 0x18004000 /* USB core registers */ ++#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */ ++#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */ ++#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */ ++#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */ ++ ++#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */ ++#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */ ++#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */ ++#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */ ++#define BCM4710_PROG 0x1f800000 /* Programable interface */ ++#define BCM4710_FLASH 0x1fc00000 /* Flash */ ++ ++#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++ ++#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300) ++ ++#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000) ++#define BCM4710_LED (BCM4710_EXTIF + 0x00900000) ++ ++#define SBFLAG_PCI 0 ++#define SBFLAG_ENET0 1 ++#define SBFLAG_ILINE20 2 ++#define SBFLAG_CODEC 3 ++#define SBFLAG_USB 4 ++#define SBFLAG_EXTIF 5 ++#define SBFLAG_ENET1 6 + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,2,18)) -+#ifdef MODULE -+#define module_init(x) int init_module(void) { return x(); } -+#define module_exit(x) void cleanup_module(void) { x(); } ++#ifdef CONFIG_HWSIM ++#define BCM4710_TRACE(trval) do { *((int *)0xa0000f18) = (trval); } while (0) +#else -+#define module_init(x) __initcall(x); -+#define module_exit(x) __exitcall(x); -+#endif ++#define BCM4710_TRACE(trval) +#endif + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,48)) -+#define list_for_each(pos, head) \ -+ for (pos = (head)->next; pos != (head); pos = pos->next) -+#endif + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)) -+#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) -+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,44)) -+#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) -+#endif ++/* BCM94702 CPCI -ExtIF used for LocalBus devs */ + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,23)) -+#define pci_enable_device(dev) do { } while (0) -+#endif ++#define BCM94702_CPCI_RESET_ADDR BCM4710_EXTIF ++#define BCM94702_CPCI_BOARDID_ADDR (BCM4710_EXTIF | 0x4000) ++#define BCM94702_CPCI_DOC_ADDR (BCM4710_EXTIF | 0x6000) ++#define BCM94702_DOC_ADDR BCM94702_CPCI_DOC_ADDR ++#define BCM94702_CPCI_LED_ADDR (BCM4710_EXTIF | 0xc000) ++#define BCM94702_CPCI_NVRAM_ADDR (BCM4710_EXTIF | 0xe000) ++#define BCM94702_CPCI_NVRAM_SIZE 0x1ff0 /* 8K NVRAM : DS1743/STM48txx*/ ++#define BCM94702_CPCI_TOD_REG_BASE (BCM94702_CPCI_NVRAM_ADDR | 0x1ff0) + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,14)) -+#define net_device device -+#endif ++#define LED_REG(x) \ ++ (*(volatile unsigned char *) (KSEG1ADDR(BCM94702_CPCI_LED_ADDR) + (x))) + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,42)) ++/* ++ * Reset function implemented in PLD. Read or write should trigger hard reset ++ */ ++#define SYS_HARD_RESET() \ ++ { for (;;) \ ++ *( (volatile unsigned char *)\ ++ KSEG1ADDR(BCM94702_CPCI_RESET_ADDR) ) = 0x80; \ ++ } + ++#endif /* _bcm4710_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmdefs.h linux.dev/arch/mips/bcm947xx/include/bcmdefs.h +--- linux.old/arch/mips/bcm947xx/include/bcmdefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmdefs.h 2006-04-27 20:12:21.000000000 +0200 +@@ -0,0 +1,106 @@ +/* -+ * DMA mapping ++ * Misc system wide definitions + * -+ * See linux/Documentation/DMA-mapping.txt ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: bcmdefs.h,v 1.1.1.3 2006/04/08 06:13:39 honor Exp $ + */ + -+#ifndef PCI_DMA_TODEVICE -+#define PCI_DMA_TODEVICE 1 -+#define PCI_DMA_FROMDEVICE 2 ++#ifndef _bcmdefs_h_ ++#define _bcmdefs_h_ ++ ++/* ++ * One doesn't need to include this file explicitly, gets included automatically if ++ * typedefs.h is included. ++ */ ++ ++/* Reclaiming text and data : ++ * The following macros specify special linker sections that can be reclaimed ++ * after a system is considered 'up'. ++ */ ++#if defined(__GNUC__) && defined(BCMRECLAIM) ++extern bool bcmreclaimed; ++#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data ++#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn ++#else /* #if defined(__GNUC__) && defined(BCMRECLAIM) */ ++#define BCMINITDATA(_data) _data ++#define BCMINITFN(_fn) _fn ++#define bcmreclaimed 0 ++#endif /* #if defined(__GNUC__) && defined(BCMRECLAIM) */ ++ ++/* Reclaim uninit functions if BCMNODOWN is defined */ ++/* and if they are not already removed by -gc-sections */ ++#ifdef BCMNODOWN ++#define BCMUNINITFN(_fn) BCMINITFN(_fn) ++#else ++#define BCMUNINITFN(_fn) _fn +#endif + -+typedef u32 dma_addr_t; ++#ifdef BCMRECLAIM ++#define CONST ++#else ++#define CONST const ++#endif /* BCMRECLAIM */ + -+/* Pure 2^n version of get_order */ -+static inline int get_order(unsigned long size) -+{ -+ int order; ++/* Compatibility with old-style BCMRECLAIM */ ++#define BCMINIT(_id) _id + -+ size = (size-1) >> (PAGE_SHIFT-1); -+ order = -1; -+ do { -+ size >>= 1; -+ order++; -+ } while (size); -+ return order; -+} + -+static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, -+ dma_addr_t *dma_handle) -+{ -+ void *ret; -+ int gfp = GFP_ATOMIC | GFP_DMA; ++/* Put some library data/code into ROM to reduce RAM requirements */ ++#if defined(__GNUC__) && defined(BCMROMOFFLOAD) ++#define BCMROMDATA(_data) __attribute__ ((__section__ (".datarom." #_data))) _data ++#define BCMROMFN(_fn) __attribute__ ((__section__ (".textrom." #_fn))) _fn ++#else ++#define BCMROMDATA(_data) _data ++#define BCMROMFN(_fn) _fn ++#endif + -+ ret = (void *)__get_free_pages(gfp, get_order(size)); ++/* Bus types */ ++#define SB_BUS 0 /* Silicon Backplane */ ++#define PCI_BUS 1 /* PCI target */ ++#define PCMCIA_BUS 2 /* PCMCIA target */ ++#define SDIO_BUS 3 /* SDIO target */ ++#define JTAG_BUS 4 /* JTAG */ ++#define NO_BUS 0xFF /* Bus that does not support R/W REG */ + -+ if (ret != NULL) { -+ memset(ret, 0, size); -+ *dma_handle = virt_to_bus(ret); -+ } -+ return ret; -+} -+static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, -+ void *vaddr, dma_addr_t dma_handle) -+{ -+ free_pages((unsigned long)vaddr, get_order(size)); -+} -+#ifdef ILSIM -+extern uint pci_map_single(void *dev, void *va, uint size, int direction); -+extern void pci_unmap_single(void *dev, uint pa, uint size, int direction); ++/* Allows optimization for single-bus support */ ++#ifdef BCMBUSTYPE ++#define BUSTYPE(bus) (BCMBUSTYPE) +#else -+#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) -+#define pci_unmap_single(cookie, address, size, dir) ++#define BUSTYPE(bus) (bus) +#endif + -+#endif /* DMA mapping */ ++/* Defines for DMA Address Width - Shared between OSL and HNDDMA */ ++#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */ ++#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */ ++#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */ + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,43)) ++#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ ++#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ ++#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ ++#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ + -+#define dev_kfree_skb_any(a) dev_kfree_skb(a) -+#define netif_down(dev) do { (dev)->start = 0; } while(0) ++/* packet headroom necessary to accomodate the largest header in the system, (i.e TXOFF). ++ * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. ++ * There is a compile time check in wlc.c which ensure that this value is at least as big ++ * as TXOFF. This value is used in dma_rxfill (hnddma.c). ++ */ ++#define BCMEXTRAHDROOM 160 ++ ++/* Headroom required for dongle-to-host communication. Packets allocated ++ * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should ++ * leave this much room in front for low-level message headers which may ++ * be needed to get across the dongle bus to the host. (These messages ++ * don't go over the network, so room for the full WL header above would ++ * be a waste.) ++ */ ++#define BCMDONGLEHDRSZ 8 + -+/* pcmcia-cs provides its own netdevice compatibility layer */ -+#ifndef _COMPAT_NETDEVICE_H + ++ ++#endif /* _bcmdefs_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm947xx/include/bcmdevs.h +--- linux.old/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h 2006-04-27 22:30:25.000000000 +0200 +@@ -0,0 +1,369 @@ +/* -+ * SoftNet ++ * Broadcom device-specific manifest constants. + * -+ * For pre-softnet kernels we need to tell the upper layer not to -+ * re-enter start_xmit() while we are in there. However softnet -+ * guarantees not to enter while we are in there so there is no need -+ * to do the netif_stop_queue() dance unless the transmit queue really -+ * gets stuck. This should also improve performance according to tests -+ * done by Aman Singla. ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: bcmdevs.h,v 1.1.1.17 2006/04/15 01:29:08 michael Exp $ + */ + -+#define dev_kfree_skb_irq(a) dev_kfree_skb(a) -+#define netif_wake_queue(dev) do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while(0) -+#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) ++#ifndef _BCMDEVS_H ++#define _BCMDEVS_H + -+static inline void netif_start_queue(struct net_device *dev) -+{ -+ dev->tbusy = 0; -+ dev->interrupt = 0; -+ dev->start = 1; -+} ++#include "bcm4710.h" + -+#define netif_queue_stopped(dev) (dev)->tbusy -+#define netif_running(dev) (dev)->start ++/* Known PCI vendor Id's */ ++#define VENDOR_EPIGRAM 0xfeda ++#define VENDOR_BROADCOM 0x14e4 ++#define VENDOR_3COM 0x10b7 ++#define VENDOR_NETGEAR 0x1385 ++#define VENDOR_DIAMOND 0x1092 ++#define VENDOR_DELL 0x1028 ++#define VENDOR_HP 0x0e11 ++#define VENDOR_APPLE 0x106b + -+#endif /* _COMPAT_NETDEVICE_H */ ++/* PCI Device Id's */ ++#define BCM4210_DEVICE_ID 0x1072 /* never used */ ++#define BCM4211_DEVICE_ID 0x4211 ++#define BCM4230_DEVICE_ID 0x1086 /* never used */ ++#define BCM4231_DEVICE_ID 0x4231 + -+#define netif_device_attach(dev) netif_start_queue(dev) -+#define netif_device_detach(dev) netif_stop_queue(dev) ++#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */ ++#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */ ++#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */ ++#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */ + -+/* 2.4.x renamed bottom halves to tasklets */ -+#define tasklet_struct tq_struct -+static inline void tasklet_schedule(struct tasklet_struct *tasklet) -+{ -+ queue_task(tasklet, &tq_immediate); -+ mark_bh(IMMEDIATE_BH); -+} ++#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */ ++#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */ + -+static inline void tasklet_init(struct tasklet_struct *tasklet, -+ void (*func)(unsigned long), -+ unsigned long data) -+{ -+ tasklet->next = NULL; -+ tasklet->sync = 0; -+ tasklet->routine = (void (*)(void *))func; -+ tasklet->data = (void *)data; -+} -+#define tasklet_kill(tasklet) {do{} while(0);} ++#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ ++#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */ + -+/* 2.4.x introduced del_timer_sync() */ -+#define del_timer_sync(timer) del_timer(timer) ++#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */ ++#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */ ++#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */ ++#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */ ++#define BCM47XX_USB_ID 0x4715 /* 47xx usb */ ++#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */ ++#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */ ++#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */ ++#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ ++#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ ++#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ ++#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */ ++#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */ ++#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */ + -+#else ++#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */ ++#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */ + -+#define netif_down(dev) ++#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid returned by sb_chip() */ ++#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ + -+#endif /* SoftNet */ ++#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */ ++#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ ++#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ ++#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)) ++#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */ ++#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ ++#define BCM4306_D11G_ID2 0x4325 ++#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ ++#define BCM4306_UART_ID 0x4322 /* 4306 uart */ ++#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */ ++#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */ + -+/* -+ * Emit code to initialise a tq_struct's routine and data pointers -+ */ -+#define PREPARE_TQUEUE(_tq, _routine, _data) \ -+ do { \ -+ (_tq)->routine = _routine; \ -+ (_tq)->data = _data; \ -+ } while (0) ++#define BCM4309_PKG_ID 1 /* 4309 package id */ + -+/* -+ * Emit code to initialise all of a tq_struct -+ */ -+#define INIT_TQUEUE(_tq, _routine, _data) \ -+ do { \ -+ INIT_LIST_HEAD(&(_tq)->list); \ -+ (_tq)->sync = 0; \ -+ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ -+ } while (0) ++#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */ ++#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */ ++#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */ ++#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */ + -+#endif ++#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ ++#define BCM4303_PKG_ID 2 /* 4303 package id */ + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,6)) ++#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ ++#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ + -+/* Power management related routines */ ++#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */ ++#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ + -+static inline int -+pci_save_state(struct pci_dev *dev, u32 *buffer) -+{ -+ int i; -+ if (buffer) { -+ for (i = 0; i < 16; i++) -+ pci_read_config_dword(dev, i * 4,&buffer[i]); -+ } -+ return 0; -+} ++#define BCM4318_CHIP_ID 0x4318 /* 4318 chip common chipid */ ++#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */ ++#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */ ++#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */ + -+static inline int -+pci_restore_state(struct pci_dev *dev, u32 *buffer) -+{ -+ int i; ++#define BCM4321_CHIP_ID 0x4321 /* 4321 chip common chipid */ ++#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */ ++#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Hgz band id */ ++#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */ + -+ if (buffer) { -+ for (i = 0; i < 16; i++) -+ pci_write_config_dword(dev,i * 4, buffer[i]); -+ } -+ /* -+ * otherwise, write the context information we know from bootup. -+ * This works around a problem where warm-booting from Windows -+ * combined with a D3(hot)->D0 transition causes PCI config -+ * header data to be forgotten. -+ */ -+ else { -+ for (i = 0; i < 6; i ++) -+ pci_write_config_dword(dev, -+ PCI_BASE_ADDRESS_0 + (i * 4), -+ pci_resource_start(dev, i)); -+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); -+ } -+ return 0; -+} ++#define BCM4331_CHIP_ID 0x4331 /* 4331 chip common chipid */ ++#define BCM4331_D11N2G_ID 0x4330 /* 4331 802.11n 2.4Ghz band id */ ++#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */ ++#define BCM4331_D11N5G_ID 0x4332 /* 4331 802.11n 5Ghz band id */ + -+#endif /* PCI power management */ ++#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */ ++#define HDLSIM_PKG_ID 14 /* HDL simulator package id */ ++#define HWSIM_PKG_ID 15 /* Hardware simulator package id */ + -+/* Old cp0 access macros deprecated in 2.4.19 */ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)) -+#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) -+#endif ++#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */ ++#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ ++#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ ++#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ ++#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ + -+/* Module refcount handled internally in 2.6.x */ -+#ifndef SET_MODULE_OWNER -+#define SET_MODULE_OWNER(dev) do {} while (0) -+#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT -+#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT -+#else -+#define OLD_MOD_INC_USE_COUNT do {} while (0) -+#define OLD_MOD_DEC_USE_COUNT do {} while (0) -+#endif ++#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */ ++#define BCM5350_CHIP_ID 0x5350 /* bcm5350 chipcommon chipid */ ++#define BCM5352_CHIP_ID 0x5352 /* bcm5352 chipcommon chipid */ + -+#ifndef SET_NETDEV_DEV -+#define SET_NETDEV_DEV(net, pdev) do {} while (0) -+#endif ++#define BCM4320_CHIP_ID 0x4320 /* bcm4320 chipcommon chipid */ + -+#ifndef HAVE_FREE_NETDEV -+#define free_netdev(dev) kfree(dev) -+#endif ++#define BCM4328_CHIP_ID 0x4328 /* bcm4328 chipcommon chipid */ + -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)) -+/* struct packet_type redefined in 2.6.x */ -+#define af_packet_priv data -+#endif ++#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */ ++#define BCM43XX_JTAGM_ID 0x43f1 /* 43xx jtagm device id */ ++#define BCM43XXOLD_JTAGM_ID 0x4331 /* 43xx old jtagm device id */ + -+#endif /* _linuxver_h_ */ -diff -Naur linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm947xx/include/mipsinc.h ---- linux.old/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/mipsinc.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,552 @@ -+/* -+ * HND Run Time Environment for standalone MIPS programs. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */ ++#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */ + -+#ifndef _MISPINC_H -+#define _MISPINC_H ++#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */ + ++#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */ + -+/* MIPS defines */ ++/* PCMCIA vendor Id's */ + -+#ifdef _LANGUAGE_ASSEMBLY ++#define VENDOR_BROADCOM_PCMCIA 0x02d0 + -+/* -+ * Symbolic register names for 32 bit ABI -+ */ -+#define zero $0 /* wired zero */ -+#define AT $1 /* assembler temp - uppercase because of ".set at" */ -+#define v0 $2 /* return value */ -+#define v1 $3 -+#define a0 $4 /* argument registers */ -+#define a1 $5 -+#define a2 $6 -+#define a3 $7 -+#define t0 $8 /* caller saved */ -+#define t1 $9 -+#define t2 $10 -+#define t3 $11 -+#define t4 $12 -+#define t5 $13 -+#define t6 $14 -+#define t7 $15 -+#define s0 $16 /* callee saved */ -+#define s1 $17 -+#define s2 $18 -+#define s3 $19 -+#define s4 $20 -+#define s5 $21 -+#define s6 $22 -+#define s7 $23 -+#define t8 $24 /* caller saved */ -+#define t9 $25 -+#define jp $25 /* PIC jump register */ -+#define k0 $26 /* kernel scratch */ -+#define k1 $27 -+#define gp $28 /* global pointer */ -+#define sp $29 /* stack pointer */ -+#define fp $30 /* frame pointer */ -+#define s8 $30 /* same like fp! */ -+#define ra $31 /* return address */ ++/* SDIO vendor Id's */ ++#define VENDOR_BROADCOM_SDIO 0x00BF + + -+/* -+ * CP0 Registers -+ */ ++/* boardflags */ ++#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */ ++#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */ ++#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */ ++#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */ ++#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */ ++#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */ ++#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */ ++#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */ ++#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */ ++#define BFL_FEM 0x0800 /* This board supports the Front End Module */ ++#define BFL_EXTLNA 0x1000 /* This board has an external LNA */ ++#define BFL_HGPA 0x2000 /* This board has a high gain PA */ ++#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */ ++#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */ + -+#define C0_INX $0 -+#define C0_RAND $1 -+#define C0_TLBLO0 $2 -+#define C0_TLBLO C0_TLBLO0 -+#define C0_TLBLO1 $3 -+#define C0_CTEXT $4 -+#define C0_PGMASK $5 -+#define C0_WIRED $6 -+#define C0_BADVADDR $8 -+#define C0_COUNT $9 -+#define C0_TLBHI $10 -+#define C0_COMPARE $11 -+#define C0_SR $12 -+#define C0_STATUS C0_SR -+#define C0_CAUSE $13 -+#define C0_EPC $14 -+#define C0_PRID $15 -+#define C0_CONFIG $16 -+#define C0_LLADDR $17 -+#define C0_WATCHLO $18 -+#define C0_WATCHHI $19 -+#define C0_XCTEXT $20 -+#define C0_DIAGNOSTIC $22 -+#define C0_BROADCOM C0_DIAGNOSTIC -+#define C0_PERFORMANCE $25 -+#define C0_ECC $26 -+#define C0_CACHEERR $27 -+#define C0_TAGLO $28 -+#define C0_TAGHI $29 -+#define C0_ERREPC $30 -+#define C0_DESAVE $31 ++/* boardflags2 */ ++#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* This board has an external rxbb regulator */ ++#define BFL2_SSWITCH_AVAIL 0x00000002 /* This board has a superswitch for > 2 antennas */ ++#define BFL2_TXPWRCTRL_EN 0x00000004 /* This board permits TX Power Control to be enabled */ + -+/* -+ * LEAF - declare leaf routine -+ */ -+#define LEAF(symbol) \ -+ .globl symbol; \ -+ .align 2; \ -+ .type symbol,@function; \ -+ .ent symbol,0; \ -+symbol: .frame sp,0,ra ++/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ ++#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */ ++#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */ ++#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */ ++#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */ ++#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ ++#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ ++#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ ++#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ ++#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ + -+/* -+ * END - mark end of function -+ */ -+#define END(function) \ -+ .end function; \ -+ .size function,.-function ++/* power control defines */ ++#define PLL_DELAY 150 /* us pll on delay */ ++#define FREF_DELAY 200 /* us fref change delay */ ++#define MIN_SLOW_CLK 32 /* us Slow clock period */ ++#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ + -+#define _ULCAST_ ++/* Reference Board Types */ + -+#else ++#define BU4710_BOARD 0x0400 ++#define VSIM4710_BOARD 0x0401 ++#define QT4710_BOARD 0x0402 + -+/* -+ * The following macros are especially useful for __asm__ -+ * inline assembler. -+ */ -+#ifndef __STR -+#define __STR(x) #x -+#endif -+#ifndef STR -+#define STR(x) __STR(x) -+#endif ++#define BU4309_BOARD 0x040a ++#define BCM94309CB_BOARD 0x040b ++#define BCM94309MP_BOARD 0x040c ++#define BCM4309AP_BOARD 0x040d + -+#define _ULCAST_ (unsigned long) ++#define BCM94302MP_BOARD 0x040e + ++#define BU4306_BOARD 0x0416 ++#define BCM94306CB_BOARD 0x0417 ++#define BCM94306MP_BOARD 0x0418 + -+/* -+ * CP0 Registers -+ */ ++#define BCM94710D_BOARD 0x041a ++#define BCM94710R1_BOARD 0x041b ++#define BCM94710R4_BOARD 0x041c ++#define BCM94710AP_BOARD 0x041d + -+#define C0_INX 0 /* CP0: TLB Index */ -+#define C0_RAND 1 /* CP0: TLB Random */ -+#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ -+#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ -+#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ -+#define C0_CTEXT 4 /* CP0: Context */ -+#define C0_PGMASK 5 /* CP0: TLB PageMask */ -+#define C0_WIRED 6 /* CP0: TLB Wired */ -+#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ -+#define C0_COUNT 9 /* CP0: Count */ -+#define C0_TLBHI 10 /* CP0: TLB EntryHi */ -+#define C0_COMPARE 11 /* CP0: Compare */ -+#define C0_SR 12 /* CP0: Processor Status */ -+#define C0_STATUS C0_SR /* CP0: Processor Status */ -+#define C0_CAUSE 13 /* CP0: Exception Cause */ -+#define C0_EPC 14 /* CP0: Exception PC */ -+#define C0_PRID 15 /* CP0: Processor Revision Indentifier */ -+#define C0_CONFIG 16 /* CP0: Config */ -+#define C0_LLADDR 17 /* CP0: LLAddr */ -+#define C0_WATCHLO 18 /* CP0: WatchpointLo */ -+#define C0_WATCHHI 19 /* CP0: WatchpointHi */ -+#define C0_XCTEXT 20 /* CP0: XContext */ -+#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ -+#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ -+#define C0_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */ -+#define C0_ECC 26 /* CP0: ECC */ -+#define C0_CACHEERR 27 /* CP0: CacheErr */ -+#define C0_TAGLO 28 /* CP0: TagLo */ -+#define C0_TAGHI 29 /* CP0: TagHi */ -+#define C0_ERREPC 30 /* CP0: ErrorEPC */ -+#define C0_DESAVE 31 /* CP0: DebugSave */ ++#define BU2050_BOARD 0x041f + -+#endif /* _LANGUAGE_ASSEMBLY */ + -+/* -+ * Memory segments (32bit kernel mode addresses) -+ */ -+#undef KUSEG -+#undef KSEG0 -+#undef KSEG1 -+#undef KSEG2 -+#undef KSEG3 -+#define KUSEG 0x00000000 -+#define KSEG0 0x80000000 -+#define KSEG1 0xa0000000 -+#define KSEG2 0xc0000000 -+#define KSEG3 0xe0000000 -+#define PHYSADDR_MASK 0x1fffffff ++#define BCM94309G_BOARD 0x0421 + -+/* -+ * Map an address to a certain kernel segment -+ */ -+#undef PHYSADDR -+#undef KSEG0ADDR -+#undef KSEG1ADDR -+#undef KSEG2ADDR -+#undef KSEG3ADDR ++#define BU4704_BOARD 0x0423 ++#define BU4702_BOARD 0x0424 + -+#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) -+#define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0) -+#define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1) -+#define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2) -+#define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3) ++#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ + + -+#ifndef Index_Invalidate_I -+/* -+ * Cache Operations -+ */ -+#define Index_Invalidate_I 0x00 -+#define Index_Writeback_Inv_D 0x01 -+#define Index_Invalidate_SI 0x02 -+#define Index_Writeback_Inv_SD 0x03 -+#define Index_Load_Tag_I 0x04 -+#define Index_Load_Tag_D 0x05 -+#define Index_Load_Tag_SI 0x06 -+#define Index_Load_Tag_SD 0x07 -+#define Index_Store_Tag_I 0x08 -+#define Index_Store_Tag_D 0x09 -+#define Index_Store_Tag_SI 0x0A -+#define Index_Store_Tag_SD 0x0B -+#define Create_Dirty_Excl_D 0x0d -+#define Create_Dirty_Excl_SD 0x0f -+#define Hit_Invalidate_I 0x10 -+#define Hit_Invalidate_D 0x11 -+#define Hit_Invalidate_SI 0x12 -+#define Hit_Invalidate_SD 0x13 -+#define Fill_I 0x14 -+#define Hit_Writeback_Inv_D 0x15 -+ /* 0x16 is unused */ -+#define Hit_Writeback_Inv_SD 0x17 -+#define R5K_Page_Invalidate_S 0x17 -+#define Hit_Writeback_I 0x18 -+#define Hit_Writeback_D 0x19 -+ /* 0x1a is unused */ -+#define Hit_Writeback_SD 0x1b -+ /* 0x1c is unused */ -+ /* 0x1e is unused */ -+#define Hit_Set_Virtual_SI 0x1e -+#define Hit_Set_Virtual_SD 0x1f -+#endif ++#define BCM94702MN_BOARD 0x0428 + ++/* BCM4702 1U CompactPCI Board */ ++#define BCM94702CPCI_BOARD 0x0429 + -+/* -+ * R4x00 interrupt enable / cause bits -+ */ -+#define IE_SW0 (_ULCAST_(1) << 8) -+#define IE_SW1 (_ULCAST_(1) << 9) -+#define IE_IRQ0 (_ULCAST_(1) << 10) -+#define IE_IRQ1 (_ULCAST_(1) << 11) -+#define IE_IRQ2 (_ULCAST_(1) << 12) -+#define IE_IRQ3 (_ULCAST_(1) << 13) -+#define IE_IRQ4 (_ULCAST_(1) << 14) -+#define IE_IRQ5 (_ULCAST_(1) << 15) ++/* BCM4702 with BCM95380 VLAN Router */ ++#define BCM95380RR_BOARD 0x042a + -+#ifndef ST0_UM -+/* -+ * Bitfields in the mips32 cp0 status register -+ */ -+#define ST0_IE 0x00000001 -+#define ST0_EXL 0x00000002 -+#define ST0_ERL 0x00000004 -+#define ST0_UM 0x00000010 -+#define ST0_SWINT0 0x00000100 -+#define ST0_SWINT1 0x00000200 -+#define ST0_HWINT0 0x00000400 -+#define ST0_HWINT1 0x00000800 -+#define ST0_HWINT2 0x00001000 -+#define ST0_HWINT3 0x00002000 -+#define ST0_HWINT4 0x00004000 -+#define ST0_HWINT5 0x00008000 -+#define ST0_IM 0x0000ff00 -+#define ST0_NMI 0x00080000 -+#define ST0_SR 0x00100000 -+#define ST0_TS 0x00200000 -+#define ST0_BEV 0x00400000 -+#define ST0_RE 0x02000000 -+#define ST0_RP 0x08000000 -+#define ST0_CU 0xf0000000 -+#define ST0_CU0 0x10000000 -+#define ST0_CU1 0x20000000 -+#define ST0_CU2 0x40000000 -+#define ST0_CU3 0x80000000 -+#endif ++/* cb4306 with SiGe PA */ ++#define BCM94306CBSG_BOARD 0x042b + ++/* cb4306 with SiGe PA */ ++#define PCSG94306_BOARD 0x042d + -+/* -+ * Bitfields in the mips32 cp0 cause register -+ */ -+#define C_EXC 0x0000007c -+#define C_EXC_SHIFT 2 -+#define C_INT 0x0000ff00 -+#define C_INT_SHIFT 8 -+#define C_SW0 (_ULCAST_(1) << 8) -+#define C_SW1 (_ULCAST_(1) << 9) -+#define C_IRQ0 (_ULCAST_(1) << 10) -+#define C_IRQ1 (_ULCAST_(1) << 11) -+#define C_IRQ2 (_ULCAST_(1) << 12) -+#define C_IRQ3 (_ULCAST_(1) << 13) -+#define C_IRQ4 (_ULCAST_(1) << 14) -+#define C_IRQ5 (_ULCAST_(1) << 15) -+#define C_WP 0x00400000 -+#define C_IV 0x00800000 -+#define C_CE 0x30000000 -+#define C_CE_SHIFT 28 -+#define C_BD 0x80000000 ++/* bu4704 with sdram */ ++#define BU4704SD_BOARD 0x042e + -+/* Values in C_EXC */ -+#define EXC_INT 0 -+#define EXC_TLBM 1 -+#define EXC_TLBL 2 -+#define EXC_TLBS 3 -+#define EXC_AEL 4 -+#define EXC_AES 5 -+#define EXC_IBE 6 -+#define EXC_DBE 7 -+#define EXC_SYS 8 -+#define EXC_BPT 9 -+#define EXC_RI 10 -+#define EXC_CU 11 -+#define EXC_OV 12 -+#define EXC_TR 13 -+#define EXC_WATCH 23 -+#define EXC_MCHK 24 ++/* Dual 11a/11g Router */ ++#define BCM94704AGR_BOARD 0x042f + ++/* 11a-only minipci */ ++#define BCM94308MP_BOARD 0x0430 + -+/* -+ * Bits in the cp0 config register. -+ */ -+#define CONF_CM_CACHABLE_NO_WA 0 -+#define CONF_CM_CACHABLE_WA 1 -+#define CONF_CM_UNCACHED 2 -+#define CONF_CM_CACHABLE_NONCOHERENT 3 -+#define CONF_CM_CACHABLE_CE 4 -+#define CONF_CM_CACHABLE_COW 5 -+#define CONF_CM_CACHABLE_CUW 6 -+#define CONF_CM_CACHABLE_ACCELERATED 7 -+#define CONF_CM_CMASK 7 -+#define CONF_CU (_ULCAST_(1) << 3) -+#define CONF_DB (_ULCAST_(1) << 4) -+#define CONF_IB (_ULCAST_(1) << 5) -+#define CONF_SE (_ULCAST_(1) << 12) -+#define CONF_SC (_ULCAST_(1) << 17) -+#define CONF_AC (_ULCAST_(1) << 23) -+#define CONF_HALT (_ULCAST_(1) << 25) + + -+/* -+ * Bits in the cp0 config register select 1. -+ */ -+#define CONF1_FP 0x00000001 /* FPU present */ -+#define CONF1_EP 0x00000002 /* EJTAG present */ -+#define CONF1_CA 0x00000004 /* mips16 implemented */ -+#define CONF1_WR 0x00000008 /* Watch registers present */ -+#define CONF1_PC 0x00000010 /* Performance counters present */ -+#define CONF1_DA_SHIFT 7 /* D$ associativity */ -+#define CONF1_DA_MASK 0x00000380 -+#define CONF1_DA_BASE 1 -+#define CONF1_DL_SHIFT 10 /* D$ line size */ -+#define CONF1_DL_MASK 0x00001c00 -+#define CONF1_DL_BASE 2 -+#define CONF1_DS_SHIFT 13 /* D$ sets/way */ -+#define CONF1_DS_MASK 0x0000e000 -+#define CONF1_DS_BASE 64 -+#define CONF1_IA_SHIFT 16 /* I$ associativity */ -+#define CONF1_IA_MASK 0x00070000 -+#define CONF1_IA_BASE 1 -+#define CONF1_IL_SHIFT 19 /* I$ line size */ -+#define CONF1_IL_MASK 0x00380000 -+#define CONF1_IL_BASE 2 -+#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ -+#define CONF1_IS_MASK 0x01c00000 -+#define CONF1_IS_BASE 64 -+#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */ -+#define CONF1_MS_SHIFT 25 ++#define BU4712_BOARD 0x0444 ++#define BU4712SD_BOARD 0x045d ++#define BU4712L_BOARD 0x045f + -+/* PRID register */ -+#define PRID_COPT_MASK 0xff000000 -+#define PRID_COMP_MASK 0x00ff0000 -+#define PRID_IMP_MASK 0x0000ff00 -+#define PRID_REV_MASK 0x000000ff ++/* BCM4712 boards */ ++#define BCM94712AP_BOARD 0x0445 ++#define BCM94712P_BOARD 0x0446 + -+#define PRID_COMP_LEGACY 0x000000 -+#define PRID_COMP_MIPS 0x010000 -+#define PRID_COMP_BROADCOM 0x020000 -+#define PRID_COMP_ALCHEMY 0x030000 -+#define PRID_COMP_SIBYTE 0x040000 -+#define PRID_IMP_BCM4710 0x4000 -+#define PRID_IMP_BCM3302 0x9000 -+#define PRID_IMP_BCM3303 0x9100 ++/* BCM4318 boards */ ++#define BU4318_BOARD 0x0447 ++#define CB4318_BOARD 0x0448 ++#define MPG4318_BOARD 0x0449 ++#define MP4318_BOARD 0x044a ++#define SD4318_BOARD 0x044b + -+#define PRID_IMP_UNKNOWN 0xff00 ++/* BCM63XX boards */ ++#define BCM96338_BOARD 0x6338 ++#define BCM96348_BOARD 0x6348 + -+#define BCM330X(id) \ -+ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) \ -+ || ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) ++/* Another mp4306 with SiGe */ ++#define BCM94306P_BOARD 0x044c + -+/* Bits in C0_BROADCOM */ -+#define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */ -+#define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */ -+#define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */ -+#define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */ ++/* mp4303 */ ++#define BCM94303MP_BOARD 0x044e + -+/* PreFetch Cache aka Read Ahead Cache */ ++/* mpsgh4306 */ ++#define BCM94306MPSGH_BOARD 0x044f + -+#define PFC_CR0 0xff400000 /* control reg 0 */ -+#define PFC_CR1 0xff400004 /* control reg 1 */ ++/* BRCM 4306 w/ Front End Modules */ ++#define BCM94306MPM 0x0450 ++#define BCM94306MPL 0x0453 + -+/* PFC operations */ -+#define PFC_I 0x00000001 /* Enable PFC use for instructions */ -+#define PFC_D 0x00000002 /* Enable PFC use for data */ -+#define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */ -+#define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */ -+#define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */ -+#define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */ -+#define PFC_DPF 0x00000040 /* Enable directional prefetching */ -+#define PFC_FLUSH 0x00000100 /* Flush the PFC */ -+#define PFC_BRR 0x40000000 /* Bus error indication */ -+#define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */ ++/* 4712agr */ ++#define BCM94712AGR_BOARD 0x0451 + -+/* Handy defaults */ -+#define PFC_DISABLED 0 -+#define PFC_AUTO 0xffffffff /* auto select the default mode */ -+#define PFC_INST (PFC_I | PFC_PFI | PFC_CINV) -+#define PFC_INST_NOPF (PFC_I | PFC_CINV) -+#define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV) -+#define PFC_DATA_NOPF (PFC_D | PFC_CINV) -+#define PFC_I_AND_D (PFC_INST | PFC_DATA) -+#define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF) ++/* pcmcia 4303 */ ++#define PC4303_BOARD 0x0454 + ++/* 5350K */ ++#define BCM95350K_BOARD 0x0455 + -+/* -+ * These are the UART port assignments, expressed as offsets from the base -+ * register. These assignments should hold for any serial port based on -+ * a 8250, 16450, or 16550(A). -+ */ ++/* 5350R */ ++#define BCM95350R_BOARD 0x0456 + -+#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ -+#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ -+#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ -+#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ -+#define UART_LCR 3 /* Out: Line Control Register */ -+#define UART_MCR 4 /* Out: Modem Control Register */ -+#define UART_LSR 5 /* In: Line Status Register */ -+#define UART_MSR 6 /* In: Modem Status Register */ -+#define UART_SCR 7 /* I/O: Scratch Register */ -+#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ -+#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ -+#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ -+#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ -+#define UART_LSR_RXRDY 0x01 /* Receiver ready */ ++/* 4306mplna */ ++#define BCM94306MPLNA_BOARD 0x0457 + ++/* 4320 boards */ ++#define BU4320_BOARD 0x0458 ++#define BU4320S_BOARD 0x0459 ++#define BCM94320PH_BOARD 0x045a + -+#ifndef _LANGUAGE_ASSEMBLY ++/* 4306mph */ ++#define BCM94306MPH_BOARD 0x045b + -+/* -+ * Macros to access the system control coprocessor -+ */ ++/* 4306pciv */ ++#define BCM94306PCIV_BOARD 0x045c + -+#define MFC0(source, sel) \ -+({ \ -+ int __res; \ -+ __asm__ __volatile__( \ -+ ".set\tnoreorder\n\t" \ -+ ".set\tnoat\n\t" \ -+ ".word\t"STR(0x40010000 | ((source)<<11) | (sel))"\n\t" \ -+ "move\t%0,$1\n\t" \ -+ ".set\tat\n\t" \ -+ ".set\treorder" \ -+ :"=r" (__res) \ -+ : \ -+ :"$1"); \ -+ __res; \ -+}) ++#define BU4712SD_BOARD 0x045d + -+#define MTC0(source, sel, value) \ -+do { \ -+ __asm__ __volatile__( \ -+ ".set\tnoreorder\n\t" \ -+ ".set\tnoat\n\t" \ -+ "move\t$1,%z0\n\t" \ -+ ".word\t"STR(0x40810000 | ((source)<<11) | (sel))"\n\t" \ -+ ".set\tat\n\t" \ -+ ".set\treorder" \ -+ : \ -+ :"jr" (value) \ -+ :"$1"); \ -+} while (0) ++#define BCM94320PFLSH_BOARD 0x045e + -+#define get_c0_count() \ -+({ \ -+ int __res; \ -+ __asm__ __volatile__( \ -+ ".set\tnoreorder\n\t" \ -+ ".set\tnoat\n\t" \ -+ "mfc0\t%0,$9\n\t" \ -+ ".set\tat\n\t" \ -+ ".set\treorder" \ -+ :"=r" (__res)); \ -+ __res; \ -+}) ++#define BU4712L_BOARD 0x045f ++#define BCM94712LGR_BOARD 0x0460 ++#define BCM94320R_BOARD 0x0461 + -+static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize) -+{ -+ uint lsz, sets, ways; ++#define BU5352_BOARD 0x0462 + -+ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ -+ if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT))) -+ lsz = CONF1_IL_BASE << lsz; -+ sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT); -+ ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT); -+ *size = lsz * sets * ways; -+ *lsize = lsz; -+} ++#define BCM94318MPGH_BOARD 0x0463 + -+static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize) -+{ -+ uint lsz, sets, ways; ++#define BU4311_BOARD 0x0464 ++#define BCM94311MC_BOARD 0x0465 ++#define BCM94311MCAG_BOARD 0x0466 + -+ /* Data Cache Size = Associativity * Line Size * Sets Per Way */ -+ if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT))) -+ lsz = CONF1_DL_BASE << lsz; -+ sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT); -+ ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT); -+ *size = lsz * sets * ways; -+ *lsize = lsz; -+} ++#define BCM95352GR_BOARD 0x0467 + -+#define cache_op(base, op) \ -+ __asm__ __volatile__(" \ -+ .set noreorder; \ -+ .set mips3; \ -+ cache %1, (%0); \ -+ .set mips0; \ -+ .set reorder" \ -+ : \ -+ : "r" (base), \ -+ "i" (op)); ++/* bcm95351agr */ ++#define BCM95351AGR_BOARD 0x0470 + -+#define cache_unroll4(base, delta, op) \ -+ __asm__ __volatile__(" \ -+ .set noreorder; \ -+ .set mips3; \ -+ cache %1,0(%0); \ -+ cache %1,delta(%0); \ -+ cache %1,(2 * delta)(%0); \ -+ cache %1,(3 * delta)(%0); \ -+ .set mips0; \ -+ .set reorder" \ -+ : \ -+ : "r" (base), \ -+ "i" (op)); ++/* bcm94704mpcb */ ++#define BCM94704MPCB_BOARD 0x0472 + -+#endif /* !_LANGUAGE_ASSEMBLY */ ++/* 4785 boards */ ++#define BU4785_BOARD 0x0478 + -+#endif /* _MISPINC_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947xx/include/osl.h ---- linux.old/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/osl.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,42 @@ -+/* -+ * OS Abstraction Layer -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ ++/* 4321 boards */ ++#define BU4321_BOARD 0x046b ++#define BU4321E_BOARD 0x047c ++#define MP4321_BOARD 0x046c ++#define CB2_4321_BOARD 0x046d ++#define MC4321_BOARD 0x046e + -+#ifndef _osl_h_ -+#define _osl_h_ ++/* # of GPIO pins */ ++#define GPIO_NUMPINS 16 + -+/* osl handle type forward declaration */ -+typedef struct os_handle osl_t; ++/* radio ID codes */ ++#define NORADIO_ID 0xe4f5 ++#define NORADIO_IDCODE 0x4e4f5246 + -+#if defined(linux) -+#include -+#elif defined(NDIS) -+#include -+#elif defined(_CFE_) -+#include -+#elif defined(_HNDRTE_) -+#include -+#elif defined(_MINOSL_) -+#include -+#elif PMON -+#include -+#elif defined(MACOSX) -+#include -+#else -+#error "Unsupported OSL requested" -+#endif ++#define BCM2050_ID 0x2050 ++#define BCM2050_IDCODE 0x02050000 ++#define BCM2050A0_IDCODE 0x1205017f ++#define BCM2050A1_IDCODE 0x2205017f ++#define BCM2050R8_IDCODE 0x8205017f + -+/* handy */ -+#define SET_REG(r, mask, val) W_REG((r), ((R_REG(r) & ~(mask)) | (val))) -+#define MAXPRIO 7 /* 0-7 */ ++#define BCM2055_ID 0x2055 ++#define BCM2055_IDCODE 0x02055000 ++#define BCM2055A0_IDCODE 0x1205517f + -+#endif /* _osl_h_ */ -diff -Naur linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm947xx/include/pcicfg.h ---- linux.old/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/pcicfg.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,451 @@ ++#define BCM2060_ID 0x2060 ++#define BCM2060_IDCODE 0x02060000 ++#define BCM2060WW_IDCODE 0x1206017f ++ ++#define BCM2062_ID 0x2062 ++#define BCM2062_IDCODE 0x02062000 ++#define BCM2062A0_IDCODE 0x0206217f ++ ++/* parts of an idcode: */ ++#define IDCODE_MFG_MASK 0x00000fff ++#define IDCODE_MFG_SHIFT 0 ++#define IDCODE_ID_MASK 0x0ffff000 ++#define IDCODE_ID_SHIFT 12 ++#define IDCODE_REV_MASK 0xf0000000 ++#define IDCODE_REV_SHIFT 28 ++ ++#endif /* _BCMDEVS_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bcm947xx/include/bcmdevs1.h +--- linux.old/arch/mips/bcm947xx/include/bcmdevs1.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmdevs1.h 2006-05-02 04:32:03.000000000 +0200 +@@ -0,0 +1,391 @@ +/* -+ * pcicfg.h: PCI configuration constants and structures. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * Broadcom device-specific manifest constants. + * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * $Id$ + */ + -+#ifndef _h_pci_ -+#define _h_pci_ -+ -+/* The following inside ifndef's so we don't collide with NTDDK.H */ -+#ifndef PCI_MAX_BUS -+#define PCI_MAX_BUS 0x100 -+#endif -+#ifndef PCI_MAX_DEVICES -+#define PCI_MAX_DEVICES 0x20 -+#endif -+#ifndef PCI_MAX_FUNCTION -+#define PCI_MAX_FUNCTION 0x8 -+#endif ++#ifndef _BCMDEVS_H ++#define _BCMDEVS_H + -+#ifndef PCI_INVALID_VENDORID -+#define PCI_INVALID_VENDORID 0xffff -+#endif -+#ifndef PCI_INVALID_DEVICEID -+#define PCI_INVALID_DEVICEID 0xffff -+#endif + ++/* Known PCI vendor Id's */ ++#define VENDOR_EPIGRAM 0xfeda ++#define VENDOR_BROADCOM 0x14e4 ++#define VENDOR_3COM 0x10b7 ++#define VENDOR_NETGEAR 0x1385 ++#define VENDOR_DIAMOND 0x1092 ++#define VENDOR_DELL 0x1028 ++#define VENDOR_HP 0x0e11 ++#define VENDOR_APPLE 0x106b + -+/* Convert between bus-slot-function-register and config addresses */ ++/* PCI Device Id's */ ++#define BCM4210_DEVICE_ID 0x1072 /* never used */ ++#define BCM4211_DEVICE_ID 0x4211 ++#define BCM4230_DEVICE_ID 0x1086 /* never used */ ++#define BCM4231_DEVICE_ID 0x4231 + -+#define PCICFG_BUS_SHIFT 16 /* Bus shift */ -+#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ -+#define PCICFG_FUN_SHIFT 8 /* Function shift */ -+#define PCICFG_OFF_SHIFT 0 /* Register shift */ ++#define BCM4410_DEVICE_ID 0x4410 /* bcm44xx family pci iline */ ++#define BCM4430_DEVICE_ID 0x4430 /* bcm44xx family cardbus iline */ ++#define BCM4412_DEVICE_ID 0x4412 /* bcm44xx family pci enet */ ++#define BCM4432_DEVICE_ID 0x4432 /* bcm44xx family cardbus enet */ + -+#define PCICFG_BUS_MASK 0xff /* Bus mask */ -+#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ -+#define PCICFG_FUN_MASK 7 /* Function mask */ -+#define PCICFG_OFF_MASK 0xff /* Bus mask */ ++#define BCM3352_DEVICE_ID 0x3352 /* bcm3352 device id */ ++#define BCM3360_DEVICE_ID 0x3360 /* bcm3360 device id */ + -+#define PCI_CONFIG_ADDR(b, s, f, o) \ -+ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ -+ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ -+ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ -+ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) ++#define EPI41210_DEVICE_ID 0xa0fa /* bcm4210 */ ++#define EPI41230_DEVICE_ID 0xa10e /* bcm4230 */ + -+#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) -+#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) -+#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) -+#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) ++#define BCM47XX_ILINE_ID 0x4711 /* 47xx iline20 */ ++#define BCM47XX_V90_ID 0x4712 /* 47xx v90 codec */ ++#define BCM47XX_ENET_ID 0x4713 /* 47xx enet */ ++#define BCM47XX_EXT_ID 0x4714 /* 47xx external i/f */ ++#define BCM47XX_USB_ID 0x4715 /* 47xx usb */ ++#define BCM47XX_USBH_ID 0x4716 /* 47xx usb host */ ++#define BCM47XX_USBD_ID 0x4717 /* 47xx usb device */ ++#define BCM47XX_IPSEC_ID 0x4718 /* 47xx ipsec */ ++#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ ++#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ ++#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ + -+/* PCIE Config space accessing MACROS*/ ++#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ + -+#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ -+#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ -+#define PCIECFG_FUN_SHIFT 16 /* Function shift */ -+#define PCIECFG_OFF_SHIFT 0 /* Register shift */ ++#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */ ++#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */ ++#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */ ++#define BCM4610_ENET_ID 0x4613 /* 4610 enet */ ++#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */ ++#define BCM4610_USB_ID 0x4615 /* 4610 usb */ + -+#define PCIECFG_BUS_MASK 0xff /* Bus mask */ -+#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ -+#define PCIECFG_FUN_MASK 7 /* Function mask */ -+#define PCIECFG_OFF_MASK 0x3ff /* Register mask */ ++#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */ ++#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ ++#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ ++#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ + -+#define PCIE_CONFIG_ADDR(b, s, f, o) \ -+ ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ -+ | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ -+ | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ -+ | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) ++#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */ ++#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */ + -+#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) -+#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) -+#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) -+#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) ++#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */ ++#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */ ++#define BCM4307_ENET_ID 0x4306 /* 4307 enet */ ++#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */ + -+ -+/* The actual config space */ ++#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */ ++#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ ++#define BCM4306_D11G_ID2 0x4325 ++#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ ++#define BCM4306_UART_ID 0x4322 /* 4306 uart */ ++#define BCM4306_V90_ID 0x4323 /* 4306 v90 codec */ ++#define BCM4306_D11DUAL_ID 0x4324 /* 4306 dual A+B */ + -+#define PCI_BAR_MAX 6 ++#define BCM4309_PKG_ID 1 /* 4309 package id */ + -+#define PCI_ROM_BAR 8 ++#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ ++#define BCM4303_PKG_ID 2 /* 4303 package id */ + -+#define PCR_RSVDA_MAX 2 ++#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */ ++#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */ ++#define BCM4310_UART_ID 0x4312 /* 4310 uart */ ++#define BCM4310_ENET_ID 0x4313 /* 4310 enet */ ++#define BCM4310_USB_ID 0x4315 /* 4310 usb */ + -+/* pci config status reg has a bit to indicate that capability ptr is present*/ ++#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ ++#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ + -+#define PCI_CAPPTR_PRESENT 0x0010 + -+typedef struct _pci_config_regs { -+ unsigned short vendor; -+ unsigned short device; -+ unsigned short command; -+ unsigned short status; -+ unsigned char rev_id; -+ unsigned char prog_if; -+ unsigned char sub_class; -+ unsigned char base_class; -+ unsigned char cache_line_size; -+ unsigned char latency_timer; -+ unsigned char header_type; -+ unsigned char bist; -+ unsigned long base[PCI_BAR_MAX]; -+ unsigned long cardbus_cis; -+ unsigned short subsys_vendor; -+ unsigned short subsys_id; -+ unsigned long baserom; -+ unsigned long rsvd_a[PCR_RSVDA_MAX]; -+ unsigned char int_line; -+ unsigned char int_pin; -+ unsigned char min_gnt; -+ unsigned char max_lat; -+ unsigned char dev_dep[192]; -+} pci_config_regs; ++#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */ ++#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ + -+#define SZPCR (sizeof (pci_config_regs)) -+#define MINSZPCR 64 /* offsetof (dev_dep[0] */ ++#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */ + -+/* A structure for the config registers is nice, but in most -+ * systems the config space is not memory mapped, so we need -+ * filed offsetts. :-( -+ */ -+#define PCI_CFG_VID 0 -+#define PCI_CFG_DID 2 -+#define PCI_CFG_CMD 4 -+#define PCI_CFG_STAT 6 -+#define PCI_CFG_REV 8 -+#define PCI_CFG_PROGIF 9 -+#define PCI_CFG_SUBCL 0xa -+#define PCI_CFG_BASECL 0xb -+#define PCI_CFG_CLSZ 0xc -+#define PCI_CFG_LATTIM 0xd -+#define PCI_CFG_HDR 0xe -+#define PCI_CFG_BIST 0xf -+#define PCI_CFG_BAR0 0x10 -+#define PCI_CFG_BAR1 0x14 -+#define PCI_CFG_BAR2 0x18 -+#define PCI_CFG_BAR3 0x1c -+#define PCI_CFG_BAR4 0x20 -+#define PCI_CFG_BAR5 0x24 -+#define PCI_CFG_CIS 0x28 -+#define PCI_CFG_SVID 0x2c -+#define PCI_CFG_SSID 0x2e -+#define PCI_CFG_ROMBAR 0x30 -+#define PCI_CFG_CAPPTR 0x34 -+#define PCI_CFG_INT 0x3c -+#define PCI_CFG_PIN 0x3d -+#define PCI_CFG_MINGNT 0x3e -+#define PCI_CFG_MAXLAT 0x3f ++#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */ ++#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */ ++#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */ ++#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */ + -+/* Classes and subclasses */ ++#define FPGA_JTAGM_ID 0x4330 /* ??? */ + -+typedef enum { -+ PCI_CLASS_OLD = 0, -+ PCI_CLASS_DASDI, -+ PCI_CLASS_NET, -+ PCI_CLASS_DISPLAY, -+ PCI_CLASS_MMEDIA, -+ PCI_CLASS_MEMORY, -+ PCI_CLASS_BRIDGE, -+ PCI_CLASS_COMM, -+ PCI_CLASS_BASE, -+ PCI_CLASS_INPUT, -+ PCI_CLASS_DOCK, -+ PCI_CLASS_CPU, -+ PCI_CLASS_SERIAL, -+ PCI_CLASS_INTELLIGENT = 0xe, -+ PCI_CLASS_SATELLITE, -+ PCI_CLASS_CRYPT, -+ PCI_CLASS_DSP, -+ PCI_CLASS_MAX -+} pci_classes; ++/* Address map */ ++#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */ ++#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */ ++#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */ ++#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */ ++#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */ + -+typedef enum { -+ PCI_DASDI_SCSI, -+ PCI_DASDI_IDE, -+ PCI_DASDI_FLOPPY, -+ PCI_DASDI_IPI, -+ PCI_DASDI_RAID, -+ PCI_DASDI_OTHER = 0x80 -+} pci_dasdi_subclasses; ++/* Core register space */ ++#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */ ++#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */ ++#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */ ++#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */ ++#define BCM4710_REG_USB 0x18004000 /* USB core registers */ ++#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */ ++#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */ ++#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */ ++#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */ + -+typedef enum { -+ PCI_NET_ETHER, -+ PCI_NET_TOKEN, -+ PCI_NET_FDDI, -+ PCI_NET_ATM, -+ PCI_NET_OTHER = 0x80 -+} pci_net_subclasses; ++#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */ ++#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */ ++#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */ ++#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */ ++#define BCM4710_PROG 0x1f800000 /* Programable interface */ ++#define BCM4710_FLASH 0x1fc00000 /* Flash */ + -+typedef enum { -+ PCI_DISPLAY_VGA, -+ PCI_DISPLAY_XGA, -+ PCI_DISPLAY_3D, -+ PCI_DISPLAY_OTHER = 0x80 -+} pci_display_subclasses; ++#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ + -+typedef enum { -+ PCI_MMEDIA_VIDEO, -+ PCI_MMEDIA_AUDIO, -+ PCI_MMEDIA_PHONE, -+ PCI_MEDIA_OTHER = 0x80 -+} pci_mmedia_subclasses; ++#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300) + -+typedef enum { -+ PCI_MEMORY_RAM, -+ PCI_MEMORY_FLASH, -+ PCI_MEMORY_OTHER = 0x80 -+} pci_memory_subclasses; ++#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000) ++#define BCM4710_LED (BCM4710_EXTIF + 0x00900000) + -+typedef enum { -+ PCI_BRIDGE_HOST, -+ PCI_BRIDGE_ISA, -+ PCI_BRIDGE_EISA, -+ PCI_BRIDGE_MC, -+ PCI_BRIDGE_PCI, -+ PCI_BRIDGE_PCMCIA, -+ PCI_BRIDGE_NUBUS, -+ PCI_BRIDGE_CARDBUS, -+ PCI_BRIDGE_RACEWAY, -+ PCI_BRIDGE_OTHER = 0x80 -+} pci_bridge_subclasses; ++#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */ ++#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ ++#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ ++#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ ++#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ + -+typedef enum { -+ PCI_COMM_UART, -+ PCI_COMM_PARALLEL, -+ PCI_COMM_MULTIUART, -+ PCI_COMM_MODEM, -+ PCI_COMM_OTHER = 0x80 -+} pci_comm_subclasses; ++#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */ + -+typedef enum { -+ PCI_BASE_PIC, -+ PCI_BASE_DMA, -+ PCI_BASE_TIMER, -+ PCI_BASE_RTC, -+ PCI_BASE_PCI_HOTPLUG, -+ PCI_BASE_OTHER = 0x80 -+} pci_base_subclasses; ++#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */ ++#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */ ++#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */ + -+typedef enum { -+ PCI_INPUT_KBD, -+ PCI_INPUT_PEN, -+ PCI_INPUT_MOUSE, -+ PCI_INPUT_SCANNER, -+ PCI_INPUT_GAMEPORT, -+ PCI_INPUT_OTHER = 0x80 -+} pci_input_subclasses; ++#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */ + -+typedef enum { -+ PCI_DOCK_GENERIC, -+ PCI_DOCK_OTHER = 0x80 -+} pci_dock_subclasses; ++/* PCMCIA vendor Id's */ + -+typedef enum { -+ PCI_CPU_386, -+ PCI_CPU_486, -+ PCI_CPU_PENTIUM, -+ PCI_CPU_ALPHA = 0x10, -+ PCI_CPU_POWERPC = 0x20, -+ PCI_CPU_MIPS = 0x30, -+ PCI_CPU_COPROC = 0x40, -+ PCI_CPU_OTHER = 0x80 -+} pci_cpu_subclasses; ++#define VENDOR_BROADCOM_PCMCIA 0x02d0 + -+typedef enum { -+ PCI_SERIAL_IEEE1394, -+ PCI_SERIAL_ACCESS, -+ PCI_SERIAL_SSA, -+ PCI_SERIAL_USB, -+ PCI_SERIAL_FIBER, -+ PCI_SERIAL_SMBUS, -+ PCI_SERIAL_OTHER = 0x80 -+} pci_serial_subclasses; ++/* SDIO vendor Id's */ ++#define VENDOR_BROADCOM_SDIO 0x00BF + -+typedef enum { -+ PCI_INTELLIGENT_I2O, -+} pci_intelligent_subclasses; + -+typedef enum { -+ PCI_SATELLITE_TV, -+ PCI_SATELLITE_AUDIO, -+ PCI_SATELLITE_VOICE, -+ PCI_SATELLITE_DATA, -+ PCI_SATELLITE_OTHER = 0x80 -+} pci_satellite_subclasses; ++/* boardflags */ ++#define BFL_BTCOEXIST 0x0001 /* This board implements Bluetooth coexistance */ ++#define BFL_PACTRL 0x0002 /* This board has gpio 9 controlling the PA */ ++#define BFL_AIRLINEMODE 0x0004 /* This board implements gpio13 radio disable indication */ ++#define BFL_ENETROBO 0x0010 /* This board has robo switch or core */ ++#define BFL_CCKHIPWR 0x0040 /* Can do high-power CCK transmission */ ++#define BFL_ENETADM 0x0080 /* This board has ADMtek switch */ ++#define BFL_ENETVLAN 0x0100 /* This board has vlan capability */ ++#define BFL_AFTERBURNER 0x0200 /* This board supports Afterburner mode */ ++#define BFL_NOPCI 0x0400 /* This board leaves PCI floating */ ++#define BFL_FEM 0x0800 /* This board supports the Front End Module */ ++#define BFL_EXTLNA 0x1000 /* This board has an external LNA */ ++#define BFL_HGPA 0x2000 /* This board has a high gain PA */ ++#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */ ++#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */ + -+typedef enum { -+ PCI_CRYPT_NETWORK, -+ PCI_CRYPT_ENTERTAINMENT, -+ PCI_CRYPT_OTHER = 0x80 -+} pci_crypt_subclasses; ++/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ ++#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */ ++#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */ ++#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */ ++#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */ ++#define BOARD_GPIO_BTC_OUT 0x100 /* bit 8 is BT Coexistance Out */ ++#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ ++#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ ++#define PCI_CFG_GPIO_HWRAD 0x20 /* PCI config space GPIO 13 for hw radio disable */ ++#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ ++#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ + -+typedef enum { -+ PCI_DSP_DPIO, -+ PCI_DSP_OTHER = 0x80 -+} pci_dsp_subclasses; ++/* Bus types */ ++#define SB_BUS 0 /* Silicon Backplane */ ++#define PCI_BUS 1 /* PCI target */ ++#define PCMCIA_BUS 2 /* PCMCIA target */ ++#define SDIO_BUS 3 /* SDIO target */ ++#define JTAG_BUS 4 /* JTAG */ + -+/* Header types */ -+typedef enum { -+ PCI_HEADER_NORMAL, -+ PCI_HEADER_BRIDGE, -+ PCI_HEADER_CARDBUS -+} pci_header_types; ++/* Allows optimization for single-bus support */ ++#ifdef BCMBUSTYPE ++#define BUSTYPE(bus) (BCMBUSTYPE) ++#else ++#define BUSTYPE(bus) (bus) ++#endif + ++/* power control defines */ ++#define PLL_DELAY 150 /* us pll on delay */ ++#define FREF_DELAY 200 /* us fref change delay */ ++#define MIN_SLOW_CLK 32 /* us Slow clock period */ ++#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ + -+/* Overlay for a PCI-to-PCI bridge */ ++/* Reference Board Types */ + -+#define PPB_RSVDA_MAX 2 -+#define PPB_RSVDD_MAX 8 ++#define BU4710_BOARD 0x0400 ++#define VSIM4710_BOARD 0x0401 ++#define QT4710_BOARD 0x0402 + -+typedef struct _ppb_config_regs { -+ unsigned short vendor; -+ unsigned short device; -+ unsigned short command; -+ unsigned short status; -+ unsigned char rev_id; -+ unsigned char prog_if; -+ unsigned char sub_class; -+ unsigned char base_class; -+ unsigned char cache_line_size; -+ unsigned char latency_timer; -+ unsigned char header_type; -+ unsigned char bist; -+ unsigned long rsvd_a[PPB_RSVDA_MAX]; -+ unsigned char prim_bus; -+ unsigned char sec_bus; -+ unsigned char sub_bus; -+ unsigned char sec_lat; -+ unsigned char io_base; -+ unsigned char io_lim; -+ unsigned short sec_status; -+ unsigned short mem_base; -+ unsigned short mem_lim; -+ unsigned short pf_mem_base; -+ unsigned short pf_mem_lim; -+ unsigned long pf_mem_base_hi; -+ unsigned long pf_mem_lim_hi; -+ unsigned short io_base_hi; -+ unsigned short io_lim_hi; -+ unsigned short subsys_vendor; -+ unsigned short subsys_id; -+ unsigned long rsvd_b; -+ unsigned char rsvd_c; -+ unsigned char int_pin; -+ unsigned short bridge_ctrl; -+ unsigned char chip_ctrl; -+ unsigned char diag_ctrl; -+ unsigned short arb_ctrl; -+ unsigned long rsvd_d[PPB_RSVDD_MAX]; -+ unsigned char dev_dep[192]; -+} ppb_config_regs; ++#define BU4610_BOARD 0x0403 ++#define VSIM4610_BOARD 0x0404 + ++#define BU4307_BOARD 0x0405 ++#define BCM94301CB_BOARD 0x0406 ++#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */ ++#define BCM94301MP_BOARD 0x0407 ++#define BCM94307MP_BOARD 0x0408 ++#define BCMAP4307_BOARD 0x0409 + -+/* PCI CAPABILITY DEFINES */ -+#define PCI_CAP_POWERMGMTCAP_ID 0x01 -+#define PCI_CAP_MSICAP_ID 0x05 -+#define PCI_CAP_PCIECAP_ID 0x10 ++#define BU4309_BOARD 0x040a ++#define BCM94309CB_BOARD 0x040b ++#define BCM94309MP_BOARD 0x040c ++#define BCM4309AP_BOARD 0x040d + -+/* Data structure to define the Message Signalled Interrupt facility -+ * Valid for PCI and PCIE configurations */ -+typedef struct _pciconfig_cap_msi { -+ unsigned char capID; -+ unsigned char nextptr; -+ unsigned short msgctrl; -+ unsigned int msgaddr; -+} pciconfig_cap_msi; ++#define BCM94302MP_BOARD 0x040e + -+/* Data structure to define the Power managment facility -+ * Valid for PCI and PCIE configurations */ -+typedef struct _pciconfig_cap_pwrmgmt { -+ unsigned char capID; -+ unsigned char nextptr; -+ unsigned short pme_cap; -+ unsigned short pme_sts_ctrl; -+ unsigned char pme_bridge_ext; -+ unsigned char data; -+} pciconfig_cap_pwrmgmt; ++#define VSIM4310_BOARD 0x040f ++#define BU4711_BOARD 0x0410 ++#define BCM94310U_BOARD 0x0411 ++#define BCM94310AP_BOARD 0x0412 ++#define BCM94310MP_BOARD 0x0414 + -+/* Data structure to define the PCIE capability */ -+typedef struct _pciconfig_cap_pcie { -+ unsigned char capID; -+ unsigned char nextptr; -+ unsigned short pcie_cap; -+ unsigned int dev_cap; -+ unsigned short dev_ctrl; -+ unsigned short dev_status; -+ unsigned int link_cap; -+ unsigned short link_ctrl; -+ unsigned short link_status; -+} pciconfig_cap_pcie; ++#define BU4306_BOARD 0x0416 ++#define BCM94306CB_BOARD 0x0417 ++#define BCM94306MP_BOARD 0x0418 + -+/* PCIE Enhanced CAPABILITY DEFINES */ -+#define PCIE_EXTCFG_OFFSET 0x100 -+#define PCIE_ADVERRREP_CAPID 0x0001 -+#define PCIE_VC_CAPID 0x0002 -+#define PCIE_DEVSNUM_CAPID 0x0003 -+#define PCIE_PWRBUDGET_CAPID 0x0004 ++#define BCM94710D_BOARD 0x041a ++#define BCM94710R1_BOARD 0x041b ++#define BCM94710R4_BOARD 0x041c ++#define BCM94710AP_BOARD 0x041d + -+/* Header to define the PCIE specific capabilities in the extended config space */ -+typedef struct _pcie_enhanced_caphdr { -+ unsigned short capID; -+ unsigned short cap_ver : 4; -+ unsigned short next_ptr : 12; -+} pcie_enhanced_caphdr; + ++#define BU2050_BOARD 0x041f + -+/* Everything below is BRCM HND proprietary */ + -+#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ -+#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ -+#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ -+#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ -+#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ -+#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ -+#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ -+#define PCI_BACKPLANE_ADDR 0xA0 /* address an arbitrary location on the system backplane */ -+#define PCI_BACKPLANE_DATA 0xA4 /* data at the location specified by above address register */ -+#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ -+#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ -+#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ ++#define BCM94309G_BOARD 0x0421 + -+#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ -+#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ ++#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */ + -+/* PCI_INT_STATUS */ -+#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ ++#define BU4704_BOARD 0x0423 ++#define BU4702_BOARD 0x0424 + -+/* PCI_INT_MASK */ -+#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ -+#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ -+#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ ++#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ + -+/* PCI_SPROM_CONTROL */ -+#define SPROM_BLANK 0x04 /* indicating a blank sprom */ -+#define SPROM_WRITEEN 0x10 /* sprom write enable */ -+#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ ++#define BU4317_BOARD 0x0426 + -+#define SPROM_SIZE 256 /* sprom size in 16-bit */ -+#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */ + -+/* PCI_CFG_CMD_STAT */ -+#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */ ++#define BCM94702MN_BOARD 0x0428 + -+#endif -diff -Naur linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm947xx/include/sbchipc.h ---- linux.old/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbchipc.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,440 @@ -+/* -+ * SiliconBackplane Chipcommon core hardware definitions. -+ * -+ * The chipcommon core provides chip identification, SB control, -+ * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer, -+ * gpio interface, extbus, and support for serial and parallel flashes. -+ * -+ * $Id$ -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ */ ++/* BCM4702 1U CompactPCI Board */ ++#define BCM94702CPCI_BOARD 0x0429 + -+#ifndef _SBCHIPC_H -+#define _SBCHIPC_H ++/* BCM4702 with BCM95380 VLAN Router */ ++#define BCM95380RR_BOARD 0x042a + ++/* cb4306 with SiGe PA */ ++#define BCM94306CBSG_BOARD 0x042b + -+#ifndef _LANGUAGE_ASSEMBLY ++/* mp4301 with 2050 radio */ ++#define BCM94301MPL_BOARD 0x042c + -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ ++/* cb4306 with SiGe PA */ ++#define PCSG94306_BOARD 0x042d + -+typedef volatile struct { -+ uint32 chipid; /* 0x0 */ -+ uint32 capabilities; -+ uint32 corecontrol; /* corerev >= 1 */ -+ uint32 bist; ++/* bu4704 with sdram */ ++#define BU4704SD_BOARD 0x042e + -+ /* OTP */ -+ uint32 otpstatus; /* 0x10, corerev >= 10 */ -+ uint32 otpcontrol; -+ uint32 otpprog; -+ uint32 PAD; ++/* Dual 11a/11g Router */ ++#define BCM94704AGR_BOARD 0x042f + -+ /* Interrupt control */ -+ uint32 intstatus; /* 0x20 */ -+ uint32 intmask; -+ uint32 chipcontrol; /* 0x28, rev >= 11 */ -+ uint32 chipstatus; /* 0x2c, rev >= 11 */ ++/* 11a-only minipci */ ++#define BCM94308MP_BOARD 0x0430 + -+ /* Jtag Master */ -+ uint32 jtagcmd; /* 0x30, rev >= 10 */ -+ uint32 jtagir; -+ uint32 jtagdr; -+ uint32 jtagctrl; + -+ /* serial flash interface registers */ -+ uint32 flashcontrol; /* 0x40 */ -+ uint32 flashaddress; -+ uint32 flashdata; -+ uint32 PAD[1]; + -+ /* Silicon backplane configuration broadcast control */ -+ uint32 broadcastaddress; /* 0x50 */ -+ uint32 broadcastdata; -+ uint32 PAD[2]; ++/* BCM94317 boards */ ++#define BCM94317CB_BOARD 0x0440 ++#define BCM94317MP_BOARD 0x0441 ++#define BCM94317PCMCIA_BOARD 0x0442 ++#define BCM94317SDIO_BOARD 0x0443 + -+ /* gpio - cleared only by power-on-reset */ -+ uint32 gpioin; /* 0x60 */ -+ uint32 gpioout; -+ uint32 gpioouten; -+ uint32 gpiocontrol; -+ uint32 gpiointpolarity; -+ uint32 gpiointmask; -+ uint32 PAD[2]; ++#define BU4712_BOARD 0x0444 ++#define BU4712SD_BOARD 0x045d ++#define BU4712L_BOARD 0x045f + -+ /* Watchdog timer */ -+ uint32 watchdog; /* 0x80 */ -+ uint32 PAD[1]; ++/* BCM4712 boards */ ++#define BCM94712AP_BOARD 0x0445 ++#define BCM94712P_BOARD 0x0446 + -+ /*GPIO based LED powersave registers corerev >= 16*/ -+ uint32 gpiotimerval; /*0x88 */ -+ uint32 gpiotimeroutmask; ++/* BCM4318 boards */ ++#define BU4318_BOARD 0x0447 ++#define CB4318_BOARD 0x0448 ++#define MPG4318_BOARD 0x0449 ++#define MP4318_BOARD 0x044a ++#define SD4318_BOARD 0x044b + -+ /* clock control */ -+ uint32 clockcontrol_n; /* 0x90 */ -+ uint32 clockcontrol_sb; /* aka m0 */ -+ uint32 clockcontrol_pci; /* aka m1 */ -+ uint32 clockcontrol_m2; /* mii/uart/mipsref */ -+ uint32 clockcontrol_mips; /* aka m3 */ -+ uint32 clkdiv; /* corerev >= 3 */ -+ uint32 PAD[2]; ++/* BCM63XX boards */ ++#define BCM96338_BOARD 0x6338 ++#define BCM96345_BOARD 0x6345 ++#define BCM96348_BOARD 0x6348 + -+ /* pll delay registers (corerev >= 4) */ -+ uint32 pll_on_delay; /* 0xb0 */ -+ uint32 fref_sel_delay; -+ uint32 slow_clk_ctl; /* 5 < corerev < 10 */ -+ uint32 PAD[1]; ++/* Another mp4306 with SiGe */ ++#define BCM94306P_BOARD 0x044c + -+ /* Instaclock registers (corerev >= 10) */ -+ uint32 system_clk_ctl; /* 0xc0 */ -+ uint32 clkstatestretch; -+ uint32 PAD[14]; ++/* CF-like 4317 modules */ ++#define BCM94317CF_BOARD 0x044d + -+ /* ExtBus control registers (corerev >= 3) */ -+ uint32 pcmcia_config; /* 0x100 */ -+ uint32 pcmcia_memwait; -+ uint32 pcmcia_attrwait; -+ uint32 pcmcia_iowait; -+ uint32 ide_config; -+ uint32 ide_memwait; -+ uint32 ide_attrwait; -+ uint32 ide_iowait; -+ uint32 prog_config; -+ uint32 prog_waitcount; -+ uint32 flash_config; -+ uint32 flash_waitcount; -+ uint32 PAD[116]; ++/* mp4303 */ ++#define BCM94303MP_BOARD 0x044e + -+ /* uarts */ -+ uint8 uart0data; /* 0x300 */ -+ uint8 uart0imr; -+ uint8 uart0fcr; -+ uint8 uart0lcr; -+ uint8 uart0mcr; -+ uint8 uart0lsr; -+ uint8 uart0msr; -+ uint8 uart0scratch; -+ uint8 PAD[248]; /* corerev >= 1 */ ++/* mpsgh4306 */ ++#define BCM94306MPSGH_BOARD 0x044f + -+ uint8 uart1data; /* 0x400 */ -+ uint8 uart1imr; -+ uint8 uart1fcr; -+ uint8 uart1lcr; -+ uint8 uart1mcr; -+ uint8 uart1lsr; -+ uint8 uart1msr; -+ uint8 uart1scratch; -+} chipcregs_t; ++/* BRCM 4306 w/ Front End Modules */ ++#define BCM94306MPM 0x0450 ++#define BCM94306MPL 0x0453 + -+#endif /* _LANGUAGE_ASSEMBLY */ ++/* 4712agr */ ++#define BCM94712AGR_BOARD 0x0451 + -+#define CC_CHIPID 0 -+#define CC_CAPABILITIES 4 -+#define CC_JTAGCMD 0x30 -+#define CC_JTAGIR 0x34 -+#define CC_JTAGDR 0x38 -+#define CC_JTAGCTRL 0x3c -+#define CC_WATCHDOG 0x80 -+#define CC_CLKC_N 0x90 -+#define CC_CLKC_M0 0x94 -+#define CC_CLKC_M1 0x98 -+#define CC_CLKC_M2 0x9c -+#define CC_CLKC_M3 0xa0 -+#define CC_CLKDIV 0xa4 -+#define CC_SYS_CLK_CTL 0xc0 -+#define CC_OTP 0x800 ++/* The real CF 4317 board */ ++#define CFI4317_BOARD 0x0452 + -+/* chipid */ -+#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ -+#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ -+#define CID_REV_SHIFT 16 /* Chip Revision shift */ -+#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ -+#define CID_PKG_SHIFT 20 /* Package Option shift */ -+#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ -+#define CID_CC_SHIFT 24 ++/* pcmcia 4303 */ ++#define PC4303_BOARD 0x0454 + -+/* capabilities */ -+#define CAP_UARTS_MASK 0x00000003 /* Number of uarts */ -+#define CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ -+#define CAP_UCLKSEL 0x00000018 /* UARTs clock select */ -+#define CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ -+#define CAP_UARTGPIO 0x00000020 /* UARTs own Gpio's 15:12 */ -+#define CAP_EXTBUS 0x00000040 /* External bus present */ -+#define CAP_FLASH_MASK 0x00000700 /* Type of flash */ -+#define CAP_PLL_MASK 0x00038000 /* Type of PLL */ -+#define CAP_PWR_CTL 0x00040000 /* Power control */ -+#define CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ -+#define CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ -+#define CAP_OTPSIZE_BASE 5 /* OTP Size base */ -+#define CAP_JTAGP 0x00400000 /* JTAG Master Present */ -+#define CAP_ROM 0x00800000 /* Internal boot rom active */ ++/* 5350K */ ++#define BCM95350K_BOARD 0x0455 + -+/* PLL type */ -+#define PLL_NONE 0x00000000 -+#define PLL_TYPE1 0x00010000 /* 48Mhz base, 3 dividers */ -+#define PLL_TYPE2 0x00020000 /* 48Mhz, 4 dividers */ -+#define PLL_TYPE3 0x00030000 /* 25Mhz, 2 dividers */ -+#define PLL_TYPE4 0x00008000 /* 48Mhz, 4 dividers */ -+#define PLL_TYPE5 0x00018000 /* 25Mhz, 4 dividers */ -+#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */ -+#define PLL_TYPE7 0x00038000 /* 25Mhz, 4 dividers */ ++/* 5350R */ ++#define BCM95350R_BOARD 0x0456 + -+/* corecontrol */ -+#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */ -+#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ ++/* 4306mplna */ ++#define BCM94306MPLNA_BOARD 0x0457 + -+/* Fields in the otpstatus register */ -+#define OTPS_PROGFAIL 0x80000000 -+#define OTPS_PROTECT 0x00000007 -+#define OTPS_HW_PROTECT 0x00000001 -+#define OTPS_SW_PROTECT 0x00000002 -+#define OTPS_CID_PROTECT 0x00000004 ++/* 4320 boards */ ++#define BU4320_BOARD 0x0458 ++#define BU4320S_BOARD 0x0459 ++#define BCM94320PH_BOARD 0x045a + -+/* Fields in the otpcontrol register */ -+#define OTPC_RECWAIT 0xff000000 -+#define OTPC_PROGWAIT 0x00ffff00 -+#define OTPC_PRW_SHIFT 8 -+#define OTPC_MAXFAIL 0x00000038 -+#define OTPC_VSEL 0x00000006 -+#define OTPC_SELVL 0x00000001 ++/* 4306mph */ ++#define BCM94306MPH_BOARD 0x045b + -+/* Fields in otpprog */ -+#define OTPP_COL_MASK 0x000000ff -+#define OTPP_ROW_MASK 0x0000ff00 -+#define OTPP_ROW_SHIFT 8 -+#define OTPP_READERR 0x10000000 -+#define OTPP_VALUE 0x20000000 -+#define OTPP_VALUE_SHIFT 29 -+#define OTPP_READ 0x40000000 -+#define OTPP_START 0x80000000 -+#define OTPP_BUSY 0x80000000 ++/* 4306pciv */ ++#define BCM94306PCIV_BOARD 0x045c + -+/* jtagcmd */ -+#define JCMD_START 0x80000000 -+#define JCMD_BUSY 0x80000000 -+#define JCMD_PAUSE 0x40000000 -+#define JCMD0_ACC_MASK 0x0000f000 -+#define JCMD0_ACC_IRDR 0x00000000 -+#define JCMD0_ACC_DR 0x00001000 -+#define JCMD0_ACC_IR 0x00002000 -+#define JCMD0_ACC_RESET 0x00003000 -+#define JCMD0_ACC_IRPDR 0x00004000 -+#define JCMD0_ACC_PDR 0x00005000 -+#define JCMD0_IRW_MASK 0x00000f00 -+#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */ -+#define JCMD_ACC_IRDR 0x00000000 -+#define JCMD_ACC_DR 0x00010000 -+#define JCMD_ACC_IR 0x00020000 -+#define JCMD_ACC_RESET 0x00030000 -+#define JCMD_ACC_IRPDR 0x00040000 -+#define JCMD_ACC_PDR 0x00050000 -+#define JCMD_IRW_MASK 0x00001f00 -+#define JCMD_IRW_SHIFT 8 -+#define JCMD_DRW_MASK 0x0000003f ++#define BU4712SD_BOARD 0x045d + -+/* jtagctrl */ -+#define JCTRL_FORCE_CLK 4 /* Force clock */ -+#define JCTRL_EXT_EN 2 /* Enable external targets */ -+#define JCTRL_EN 1 /* Enable Jtag master */ ++#define BCM94320PFLSH_BOARD 0x045e + -+/* Fields in clkdiv */ -+#define CLKD_SFLASH 0x0f000000 -+#define CLKD_SFLASH_SHIFT 24 -+#define CLKD_OTP 0x000f0000 -+#define CLKD_OTP_SHIFT 16 -+#define CLKD_JTAG 0x00000f00 -+#define CLKD_JTAG_SHIFT 8 -+#define CLKD_UART 0x000000ff ++#define BU4712L_BOARD 0x045f ++#define BCM94712LGR_BOARD 0x0460 ++#define BCM94320R_BOARD 0x0461 + -+/* intstatus/intmask */ -+#define CI_GPIO 0x00000001 /* gpio intr */ -+#define CI_EI 0x00000002 /* ro: ext intr pin (corerev >= 3) */ -+#define CI_WDRESET 0x80000000 /* watchdog reset occurred */ ++#define BU5352_BOARD 0x0462 + -+/* slow_clk_ctl */ -+#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ -+#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ -+#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ -+#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ -+#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ -+#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */ -+#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */ -+#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors PLL clock disable requests from core */ -+#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't disable crystal when appropriate */ -+#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ -+#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ -+#define SCC_CD_SHIFT 16 ++#define BCM94318MPGH_BOARD 0x0463 + -+/* system_clk_ctl */ -+#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ -+#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ -+#define SYCC_FP 0x00000004 /* ForcePLLOn */ -+#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ -+#define SYCC_HR 0x00000010 /* Force HT */ -+#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4+divisor)) */ -+#define SYCC_CD_SHIFT 16 + -+/* gpiotimerval*/ -+#define GPIO_ONTIME_SHIFT 16 ++#define BCM95352GR_BOARD 0x0467 + -+/* clockcontrol_n */ -+#define CN_N1_MASK 0x3f /* n1 control */ -+#define CN_N2_MASK 0x3f00 /* n2 control */ -+#define CN_N2_SHIFT 8 -+#define CN_PLLC_MASK 0xf0000 /* pll control */ -+#define CN_PLLC_SHIFT 16 ++/* bcm95351agr */ ++#define BCM95351AGR_BOARD 0x0470 + -+/* clockcontrol_sb/pci/uart */ -+#define CC_M1_MASK 0x3f /* m1 control */ -+#define CC_M2_MASK 0x3f00 /* m2 control */ -+#define CC_M2_SHIFT 8 -+#define CC_M3_MASK 0x3f0000 /* m3 control */ -+#define CC_M3_SHIFT 16 -+#define CC_MC_MASK 0x1f000000 /* mux control */ -+#define CC_MC_SHIFT 24 ++/* # of GPIO pins */ ++#define GPIO_NUMPINS 16 + -+/* N3M Clock control magic field values */ -+#define CC_F6_2 0x02 /* A factor of 2 in */ -+#define CC_F6_3 0x03 /* 6-bit fields like */ -+#define CC_F6_4 0x05 /* N1, M1 or M3 */ -+#define CC_F6_5 0x09 -+#define CC_F6_6 0x11 -+#define CC_F6_7 0x21 ++#endif /* _BCMDEVS_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/bcm947xx/include/bcmendian.h +--- linux.old/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h 2006-04-27 20:08:35.000000000 +0200 +@@ -0,0 +1,198 @@ ++/* ++ * local version of endian.h - byte order defines ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: bcmendian.h,v 1.1.1.10 2006/02/27 03:43:16 honor Exp $ ++*/ + -+#define CC_F5_BIAS 5 /* 5-bit fields get this added */ ++#ifndef _BCMENDIAN_H_ ++#define _BCMENDIAN_H_ + -+#define CC_MC_BYPASS 0x08 -+#define CC_MC_M1 0x04 -+#define CC_MC_M1M2 0x02 -+#define CC_MC_M1M2M3 0x01 -+#define CC_MC_M1M3 0x11 ++#include + -+/* Type 2 Clock control magic field values */ -+#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ -+#define CC_T2M2_BIAS 3 /* m2 bias */ ++/* Byte swap a 16 bit value */ ++#define BCMSWAP16(val) \ ++ ((uint16)(\ ++ (((uint16)(val) & (uint16)0x00ffU) << 8) | \ ++ (((uint16)(val) & (uint16)0xff00U) >> 8))) + -+#define CC_T2MC_M1BYP 1 -+#define CC_T2MC_M2BYP 2 -+#define CC_T2MC_M3BYP 4 ++/* Byte swap a 32 bit value */ ++#define BCMSWAP32(val) \ ++ ((uint32)(\ ++ (((uint32)(val) & (uint32)0x000000ffUL) << 24) | \ ++ (((uint32)(val) & (uint32)0x0000ff00UL) << 8) | \ ++ (((uint32)(val) & (uint32)0x00ff0000UL) >> 8) | \ ++ (((uint32)(val) & (uint32)0xff000000UL) >> 24))) + -+/* Type 6 Clock control magic field values */ -+#define CC_T6_MMASK 1 /* bits of interest in m */ -+#define CC_T6_M0 120000000 /* sb clock for m = 0 */ -+#define CC_T6_M1 100000000 /* sb clock for m = 1 */ -+#define SB2MIPS_T6(sb) (2 * (sb)) ++/* 2 Byte swap a 32 bit value */ ++#define BCMSWAP32BY16(val) \ ++ ((uint32)(\ ++ (((uint32)(val) & (uint32)0x0000ffffUL) << 16) | \ ++ (((uint32)(val) & (uint32)0xffff0000UL) >> 16))) + -+/* Common clock base */ -+#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */ -+#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLL's */ + -+/* Clock control values for 200Mhz in 5350 */ -+#define CLKC_5350_N 0x0311 -+#define CLKC_5350_M 0x04020009 ++static INLINE uint16 ++bcmswap16(uint16 val) ++{ ++ return BCMSWAP16(val); ++} + -+/* Flash types in the chipcommon capabilities register */ -+#define FLASH_NONE 0x000 /* No flash */ -+#define SFLASH_ST 0x100 /* ST serial flash */ -+#define SFLASH_AT 0x200 /* Atmel serial flash */ -+#define PFLASH 0x700 /* Parallel flash */ ++static INLINE uint32 ++bcmswap32(uint32 val) ++{ ++ return BCMSWAP32(val); ++} + -+/* Bits in the config registers */ -+#define CC_CFG_EN 0x0001 /* Enable */ -+#define CC_CFG_EM_MASK 0x000e /* Extif Mode */ -+#define CC_CFG_EM_ASYNC 0x0002 /* Async/Parallel flash */ -+#define CC_CFG_EM_SYNC 0x0004 /* Synchronous */ -+#define CC_CFG_EM_PCMCIA 0x0008 /* PCMCIA */ -+#define CC_CFG_EM_IDE 0x000a /* IDE */ -+#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ -+#define CC_CFG_CD_MASK 0x0060 /* Sync: Clock divisor */ -+#define CC_CFG_CE 0x0080 /* Sync: Clock enable */ -+#define CC_CFG_SB 0x0100 /* Sync: Size/Bytestrobe */ ++static INLINE uint32 ++bcmswap32by16(uint32 val) ++{ ++ return BCMSWAP32BY16(val); ++} + -+/* Start/busy bit in flashcontrol */ -+#define SFLASH_START 0x80000000 -+#define SFLASH_BUSY SFLASH_START ++/* buf - start of buffer of shorts to swap */ ++/* len - byte length of buffer */ ++static INLINE void ++bcmswap16_buf(uint16 *buf, uint len) ++{ ++ len = len/2; + -+/* flashcontrol opcodes for ST flashes */ -+#define SFLASH_ST_WREN 0x0006 /* Write Enable */ -+#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */ -+#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */ -+#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */ -+#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */ -+#define SFLASH_ST_PP 0x0302 /* Page Program */ -+#define SFLASH_ST_SE 0x02d8 /* Sector Erase */ -+#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */ -+#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */ -+#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */ ++ while (len--) { ++ *buf = bcmswap16(*buf); ++ buf++; ++ } ++} + -+/* Status register bits for ST flashes */ -+#define SFLASH_ST_WIP 0x01 /* Write In Progress */ -+#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */ -+#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */ -+#define SFLASH_ST_BP_SHIFT 2 -+#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */ ++#ifndef hton16 ++#ifndef IL_BIGENDIAN ++#define HTON16(i) BCMSWAP16(i) ++#define hton16(i) bcmswap16(i) ++#define hton32(i) bcmswap32(i) ++#define ntoh16(i) bcmswap16(i) ++#define ntoh32(i) bcmswap32(i) ++#define ltoh16(i) (i) ++#define ltoh32(i) (i) ++#define htol16(i) (i) ++#define htol32(i) (i) ++#else ++#define HTON16(i) (i) ++#define hton16(i) (i) ++#define hton32(i) (i) ++#define ntoh16(i) (i) ++#define ntoh32(i) (i) ++#define ltoh16(i) bcmswap16(i) ++#define ltoh32(i) bcmswap32(i) ++#define htol16(i) bcmswap16(i) ++#define htol32(i) bcmswap32(i) ++#endif /* IL_BIGENDIAN */ ++#endif /* hton16 */ + -+/* flashcontrol opcodes for Atmel flashes */ -+#define SFLASH_AT_READ 0x07e8 -+#define SFLASH_AT_PAGE_READ 0x07d2 -+#define SFLASH_AT_BUF1_READ -+#define SFLASH_AT_BUF2_READ -+#define SFLASH_AT_STATUS 0x01d7 -+#define SFLASH_AT_BUF1_WRITE 0x0384 -+#define SFLASH_AT_BUF2_WRITE 0x0387 -+#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 -+#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 -+#define SFLASH_AT_BUF1_PROGRAM 0x0288 -+#define SFLASH_AT_BUF2_PROGRAM 0x0289 -+#define SFLASH_AT_PAGE_ERASE 0x0281 -+#define SFLASH_AT_BLOCK_ERASE 0x0250 -+#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 -+#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 -+#define SFLASH_AT_BUF1_LOAD 0x0253 -+#define SFLASH_AT_BUF2_LOAD 0x0255 -+#define SFLASH_AT_BUF1_COMPARE 0x0260 -+#define SFLASH_AT_BUF2_COMPARE 0x0261 -+#define SFLASH_AT_BUF1_REPROGRAM 0x0258 -+#define SFLASH_AT_BUF2_REPROGRAM 0x0259 ++#ifndef IL_BIGENDIAN ++#define ltoh16_buf(buf, i) ++#define htol16_buf(buf, i) ++#else ++#define ltoh16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) ++#define htol16_buf(buf, i) bcmswap16_buf((uint16*)buf, i) ++#endif /* IL_BIGENDIAN */ + -+/* Status register bits for Atmel flashes */ -+#define SFLASH_AT_READY 0x80 -+#define SFLASH_AT_MISMATCH 0x40 -+#define SFLASH_AT_ID_MASK 0x38 -+#define SFLASH_AT_ID_SHIFT 3 ++/* ++* store 16-bit value to unaligned little endian byte array. ++*/ ++static INLINE void ++htol16_ua_store(uint16 val, uint8 *bytes) ++{ ++ bytes[0] = val&0xff; ++ bytes[1] = val>>8; ++} + -+/* OTP regions */ -+#define OTP_HW_REGION OTPS_HW_PROTECT -+#define OTP_SW_REGION OTPS_SW_PROTECT -+#define OTP_CID_REGION OTPS_CID_PROTECT ++/* ++* store 32-bit value to unaligned little endian byte array. ++*/ ++static INLINE void ++htol32_ua_store(uint32 val, uint8 *bytes) ++{ ++ bytes[0] = val&0xff; ++ bytes[1] = (val>>8)&0xff; ++ bytes[2] = (val>>16)&0xff; ++ bytes[3] = val>>24; ++} + -+/* OTP regions (Byte offsets from otp size) */ -+#define OTP_SWLIM_OFF (-8) -+#define OTP_CIDBASE_OFF 0 -+#define OTP_CIDLIM_OFF 8 ++/* ++* store 16-bit value to unaligned network(big) endian byte array. ++*/ ++static INLINE void ++hton16_ua_store(uint16 val, uint8 *bytes) ++{ ++ bytes[1] = val&0xff; ++ bytes[0] = val>>8; ++} + -+/* Predefined OTP words (Word offset from otp size) */ -+#define OTP_BOUNDARY_OFF (-4) -+#define OTP_HWSIGN_OFF (-3) -+#define OTP_SWSIGN_OFF (-2) -+#define OTP_CIDSIGN_OFF (-1) ++/* ++* store 32-bit value to unaligned network(big) endian byte array. ++*/ ++static INLINE void ++hton32_ua_store(uint32 val, uint8 *bytes) ++{ ++ bytes[3] = val&0xff; ++ bytes[2] = (val>>8)&0xff; ++ bytes[1] = (val>>16)&0xff; ++ bytes[0] = val>>24; ++} + -+#define OTP_CID_OFF 0 -+#define OTP_PKG_OFF 1 -+#define OTP_FID_OFF 2 -+#define OTP_RSV_OFF 3 -+#define OTP_LIM_OFF 4 ++/* ++* load 16-bit value from unaligned little endian byte array. ++*/ ++static INLINE uint16 ++ltoh16_ua(void *bytes) ++{ ++ return (((uint8*)bytes)[1]<<8)+((uint8 *)bytes)[0]; ++} + -+#define OTP_SIGNATURE 0x578a -+#define OTP_MAGIC 0x4e56 ++/* ++* load 32-bit value from unaligned little endian byte array. ++*/ ++static INLINE uint32 ++ltoh32_ua(void *bytes) ++{ ++ return (((uint8*)bytes)[3]<<24)+(((uint8*)bytes)[2]<<16)+ ++ (((uint8*)bytes)[1]<<8)+((uint8*)bytes)[0]; ++} + -+#endif /* _SBCHIPC_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bcm947xx/include/sbconfig.h ---- linux.old/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbconfig.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,342 @@ +/* -+ * Broadcom SiliconBackplane hardware register definitions. ++* load 16-bit value from unaligned big(network) endian byte array. ++*/ ++static INLINE uint16 ++ntoh16_ua(void *bytes) ++{ ++ return (((uint8*)bytes)[0]<<8)+((uint8*)bytes)[1]; ++} ++ ++/* ++* load 32-bit value from unaligned big(network) endian byte array. ++*/ ++static INLINE uint32 ++ntoh32_ua(void *bytes) ++{ ++ return (((uint8*)bytes)[0]<<24)+(((uint8*)bytes)[1]<<16)+ ++ (((uint8*)bytes)[2]<<8)+((uint8*)bytes)[3]; ++} ++ ++#define ltoh_ua(ptr) (\ ++ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] : \ ++ (((uint8 *)ptr)[3]<<24)+(((uint8 *)ptr)[2]<<16)+(((uint8 *)ptr)[1]<<8)+((uint8 *)ptr)[0] \ ++) ++ ++#define ntoh_ua(ptr) (\ ++ sizeof(*(ptr)) == sizeof(uint8) ? *(uint8 *)ptr : \ ++ sizeof(*(ptr)) == sizeof(uint16) ? (((uint8 *)ptr)[0]<<8)+((uint8 *)ptr)[1] : \ ++ (((uint8 *)ptr)[0]<<24)+(((uint8 *)ptr)[1]<<16)+(((uint8 *)ptr)[2]<<8)+((uint8 *)ptr)[3] \ ++) ++ ++#endif /* _BCMENDIAN_H_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bcm947xx/include/bcmnvram.h +--- linux.old/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h 2006-04-27 23:29:18.000000000 +0200 +@@ -0,0 +1,159 @@ ++/* ++ * NVRAM variable manipulation + * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: bcmnvram.h,v 1.17 2006/03/02 12:33:44 honor Exp $ + */ + -+#ifndef _SBCONFIG_H -+#define _SBCONFIG_H ++#ifndef _bcmnvram_h_ ++#define _bcmnvram_h_ + -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif ++#ifndef _LANGUAGE_ASSEMBLY ++ ++#include ++#include ++ ++struct nvram_header { ++ uint32 magic; ++ uint32 len; ++ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */ ++ uint32 config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */ ++ uint32 config_ncdl; /* ncdl values for memc */ ++}; ++ ++struct nvram_tuple { ++ char *name; ++ char *value; ++ struct nvram_tuple *next; ++}; + +/* -+ * SiliconBackplane Address Map. -+ * All regions may not exist on all chips. ++ * Initialize NVRAM access. May be unnecessary or undefined on certain ++ * platforms. + */ -+#define SB_SDRAM_BASE 0x00000000 /* Physical SDRAM */ -+#define SB_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ -+#define SB_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ -+#define SB_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ -+#define SB_ENUM_BASE 0x18000000 /* Enumeration space base */ -+#define SB_ENUM_LIM 0x18010000 /* Enumeration space limit */ ++extern int nvram_init(void *sbh); + -+#define SB_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ -+#define SB_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ ++/* ++ * Disable NVRAM access. May be unnecessary or undefined on certain ++ * platforms. ++ */ ++extern void nvram_exit(void *sbh); + -+#define SB_EXTIF_BASE 0x1f000000 /* External Interface region base address */ -+#define SB_FLASH1 0x1fc00000 /* Flash Region 1 */ -+#define SB_FLASH1_SZ 0x00400000 /* Size of Flash Region 1 */ ++/* ++ * Get the value of an NVRAM variable. The pointer returned may be ++ * invalid after a set. ++ * @param name name of variable to get ++ * @return value of variable or NULL if undefined ++ */ ++extern char * nvram_get(const char *name); + -+#define SB_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ -+#define SB_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ -+#define SB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), low 32 bits */ -+#define SB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 (2 ZettaBytes), high 32 bits */ -+#define SB_EUART (SB_EXTIF_BASE + 0x00800000) -+#define SB_LED (SB_EXTIF_BASE + 0x00900000) ++/* ++ * Read the reset GPIO value from the nvram and set the GPIO ++ * as input ++ */ ++extern int BCMINITFN(nvram_resetgpio_init)(void *sbh); ++extern int BCMINITFN(nvram_gpio_init)(const char *name, void *sbh); ++extern int BCMINITFN(nvram_gpio_set)(const char *name, void *sbh, int type); + ++/* ++ * Get the value of an NVRAM variable. ++ * @param name name of variable to get ++ * @return value of variable or NUL if undefined ++ */ ++#define nvram_safe_get(name) (nvram_get(name) ? : "") + -+/* enumeration space related defs */ -+#define SB_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ -+#define SB_MAXCORES ((SB_ENUM_LIM - SB_ENUM_BASE)/SB_CORE_SIZE) -+#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ -+#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */ ++#define nvram_safe_unset(name) ({ \ ++ if(nvram_get(name)) \ ++ nvram_unset(name); \ ++}) + -+/* mips address */ -+#define SB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++#define nvram_safe_set(name, value) ({ \ ++ if(!nvram_get(name) || strcmp(nvram_get(name), value)) \ ++ nvram_set(name, value); \ ++}) + +/* -+ * Sonics Configuration Space Registers. ++ * Match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is string equal ++ * to match or FALSE otherwise + */ -+#define SBIPSFLAG 0x08 -+#define SBTPSFLAG 0x18 -+#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */ -+#define SBTMERRLOG 0x50 /* sonics >= 2.3 */ -+#define SBADMATCH3 0x60 -+#define SBADMATCH2 0x68 -+#define SBADMATCH1 0x70 -+#define SBIMSTATE 0x90 -+#define SBINTVEC 0x94 -+#define SBTMSTATELOW 0x98 -+#define SBTMSTATEHIGH 0x9c -+#define SBBWA0 0xa0 -+#define SBIMCONFIGLOW 0xa8 -+#define SBIMCONFIGHIGH 0xac -+#define SBADMATCH0 0xb0 -+#define SBTMCONFIGLOW 0xb8 -+#define SBTMCONFIGHIGH 0xbc -+#define SBBCONFIG 0xc0 -+#define SBBSTATE 0xc8 -+#define SBACTCNFG 0xd8 -+#define SBFLAGST 0xe8 -+#define SBIDLOW 0xf8 -+#define SBIDHIGH 0xfc ++static INLINE int ++nvram_match(char *name, char *match) { ++ const char *value = nvram_get(name); ++ return (value && !strcmp(value, match)); ++} + -+#ifndef _LANGUAGE_ASSEMBLY ++/* ++ * Inversely match an NVRAM variable. ++ * @param name name of variable to match ++ * @param match value to compare against value of variable ++ * @return TRUE if variable is defined and its value is not string ++ * equal to invmatch or FALSE otherwise ++ */ ++static INLINE int ++nvram_invmatch(char *name, char *invmatch) { ++ const char *value = nvram_get(name); ++ return (value && strcmp(value, invmatch)); ++} + -+typedef volatile struct _sbconfig { -+ uint32 PAD[2]; -+ uint32 sbipsflag; /* initiator port ocp slave flag */ -+ uint32 PAD[3]; -+ uint32 sbtpsflag; /* target port ocp slave flag */ -+ uint32 PAD[11]; -+ uint32 sbtmerrloga; /* (sonics >= 2.3) */ -+ uint32 PAD; -+ uint32 sbtmerrlog; /* (sonics >= 2.3) */ -+ uint32 PAD[3]; -+ uint32 sbadmatch3; /* address match3 */ -+ uint32 PAD; -+ uint32 sbadmatch2; /* address match2 */ -+ uint32 PAD; -+ uint32 sbadmatch1; /* address match1 */ -+ uint32 PAD[7]; -+ uint32 sbimstate; /* initiator agent state */ -+ uint32 sbintvec; /* interrupt mask */ -+ uint32 sbtmstatelow; /* target state */ -+ uint32 sbtmstatehigh; /* target state */ -+ uint32 sbbwa0; /* bandwidth allocation table0 */ -+ uint32 PAD; -+ uint32 sbimconfiglow; /* initiator configuration */ -+ uint32 sbimconfighigh; /* initiator configuration */ -+ uint32 sbadmatch0; /* address match0 */ -+ uint32 PAD; -+ uint32 sbtmconfiglow; /* target configuration */ -+ uint32 sbtmconfighigh; /* target configuration */ -+ uint32 sbbconfig; /* broadcast configuration */ -+ uint32 PAD; -+ uint32 sbbstate; /* broadcast state */ -+ uint32 PAD[3]; -+ uint32 sbactcnfg; /* activate configuration */ -+ uint32 PAD[3]; -+ uint32 sbflagst; /* current sbflags */ -+ uint32 PAD[3]; -+ uint32 sbidlow; /* identification */ -+ uint32 sbidhigh; /* identification */ -+} sbconfig_t; ++/* ++ * Set the value of an NVRAM variable. The name and value strings are ++ * copied into private storage. Pointers to previously set values ++ * may become invalid. The new value may be immediately ++ * retrieved but will not be permanently stored until a commit. ++ * @param name name of variable to set ++ * @param value value of variable ++ * @return 0 on success and errno on failure ++ */ ++extern int nvram_set(const char *name, const char *value); + -+#endif /* _LANGUAGE_ASSEMBLY */ ++/* ++ * Unset an NVRAM variable. Pointers to previously set values ++ * remain valid until a set. ++ * @param name name of variable to unset ++ * @return 0 on success and errno on failure ++ * NOTE: use nvram_commit to commit this change to flash. ++ */ ++extern int nvram_unset(const char *name); + -+/* sbipsflag */ -+#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */ -+#define SBIPS_INT1_SHIFT 0 -+#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */ -+#define SBIPS_INT2_SHIFT 8 -+#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */ -+#define SBIPS_INT3_SHIFT 16 -+#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */ -+#define SBIPS_INT4_SHIFT 24 ++/* ++ * Commit NVRAM variables to permanent storage. All pointers to values ++ * may be invalid after a commit. ++ * NVRAM values are undefined after a commit. ++ * @return 0 on success and errno on failure ++ */ ++extern int nvram_commit(void); + -+/* sbtpsflag */ -+#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */ -+#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */ ++/* ++ * Get all NVRAM variables (format name=value\0 ... \0\0). ++ * @param buf buffer to store variables ++ * @param count size of buffer in bytes ++ * @return 0 on success and errno on failure ++ */ ++extern int nvram_getall(char *buf, int count); + -+/* sbtmerrlog */ -+#define SBTMEL_CM 0x00000007 /* command */ -+#define SBTMEL_CI 0x0000ff00 /* connection id */ -+#define SBTMEL_EC 0x0f000000 /* error code */ -+#define SBTMEL_ME 0x80000000 /* multiple error */ ++extern int file2nvram(char *filename, char *varname); ++extern int nvram2file(char *varname, char *filename); + -+/* sbimstate */ -+#define SBIM_PC 0xf /* pipecount */ -+#define SBIM_AP_MASK 0x30 /* arbitration policy */ -+#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */ -+#define SBIM_AP_TS 0x10 /* use timesliaces only */ -+#define SBIM_AP_TK 0x20 /* use token only */ -+#define SBIM_AP_RSV 0x30 /* reserved */ -+#define SBIM_IBE 0x20000 /* inbanderror */ -+#define SBIM_TO 0x40000 /* timeout */ -+#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ -+#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ ++#endif /* _LANGUAGE_ASSEMBLY */ + -+/* sbtmstatelow */ -+#define SBTML_RESET 0x1 /* reset */ -+#define SBTML_REJ_MASK 0x6 /* reject */ -+#define SBTML_REJ_SHIFT 1 -+#define SBTML_CLK 0x10000 /* clock enable */ -+#define SBTML_FGC 0x20000 /* force gated clocks on */ -+#define SBTML_FL_MASK 0x3ffc0000 /* core-specific flags */ -+#define SBTML_PE 0x40000000 /* pme enable */ -+#define SBTML_BE 0x80000000 /* bist enable */ ++#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ ++#define NVRAM_CLEAR_MAGIC 0x0 ++#define NVRAM_INVALID_MAGIC 0xFFFFFFFF ++#define NVRAM_VERSION 1 ++#define NVRAM_HEADER_SIZE 20 ++#define NVRAM_SPACE 0x8000 + -+/* sbtmstatehigh */ -+#define SBTMH_SERR 0x1 /* serror */ -+#define SBTMH_INT 0x2 /* interrupt */ -+#define SBTMH_BUSY 0x4 /* busy */ -+#define SBTMH_TO 0x00000020 /* timeout (sonics >= 2.3) */ -+#define SBTMH_FL_MASK 0x1fff0000 /* core-specific flags */ -+#define SBTMH_DMA64 0x10000000 /* supports DMA with 64-bit addresses */ -+#define SBTMH_GCR 0x20000000 /* gated clock request */ -+#define SBTMH_BISTF 0x40000000 /* bist failed */ -+#define SBTMH_BISTD 0x80000000 /* bist done */ ++#define NVRAM_MAX_VALUE_LEN 255 ++#define NVRAM_MAX_PARAM_LEN 64 + ++#endif /* _bcmnvram_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmsrom.h linux.dev/arch/mips/bcm947xx/include/bcmsrom.h +--- linux.old/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmsrom.h 2006-04-27 20:27:33.000000000 +0200 +@@ -0,0 +1,108 @@ ++/* ++ * Misc useful routines to access NIC local SROM/OTP . ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: bcmsrom.h,v 1.1.1.13 2006/04/15 01:29:08 michael Exp $ ++ */ + -+/* sbbwa0 */ -+#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */ -+#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */ -+#define SBBWA_TAB1_SHIFT 16 ++#ifndef _bcmsrom_h_ ++#define _bcmsrom_h_ + -+/* sbimconfiglow */ -+#define SBIMCL_STO_MASK 0x7 /* service timeout */ -+#define SBIMCL_RTO_MASK 0x70 /* request timeout */ -+#define SBIMCL_RTO_SHIFT 4 -+#define SBIMCL_CID_MASK 0xff0000 /* connection id */ -+#define SBIMCL_CID_SHIFT 16 ++/* Maximum srom: 4 Kilobits == 512 bytes */ ++#define SROM_MAX 512 + -+/* sbimconfighigh */ -+#define SBIMCH_IEM_MASK 0xc /* inband error mode */ -+#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */ -+#define SBIMCH_TEM_SHIFT 4 -+#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */ -+#define SBIMCH_BEM_SHIFT 6 ++/* SROM Rev 4: Reallocate the software part of the srom to accomodate ++ * MIMO features. It assumes up to two PCIE functions and 440 bytes ++ * of useable srom i.e. the useable storage in chips with OTP that ++ * implements hardware redundancy. ++ */ + -+/* sbadmatch0 */ -+#define SBAM_TYPE_MASK 0x3 /* address type */ -+#define SBAM_AD64 0x4 /* reserved */ -+#define SBAM_ADINT0_MASK 0xf8 /* type0 size */ -+#define SBAM_ADINT0_SHIFT 3 -+#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */ -+#define SBAM_ADINT1_SHIFT 3 -+#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */ -+#define SBAM_ADINT2_SHIFT 3 -+#define SBAM_ADEN 0x400 /* enable */ -+#define SBAM_ADNEG 0x800 /* negative decode */ -+#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */ -+#define SBAM_BASE0_SHIFT 8 -+#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */ -+#define SBAM_BASE1_SHIFT 12 -+#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */ -+#define SBAM_BASE2_SHIFT 16 ++#define SROM4_WORDS 220 ++ ++#define SROM4_SIGN 32 ++#define SROM4_SIGNATURE 0x5372 ++ ++#define SROM4_BREV 33 ++ ++#define SROM4_BFL0 34 ++#define SROM4_BFL1 35 ++#define SROM4_BFL2 36 ++#define SROM4_BFL3 37 ++ ++#define SROM4_MACHI 38 ++#define SROM4_MACMID 39 ++#define SROM4_MACLO 40 ++ ++#define SROM4_CCODE 41 ++#define SROM4_REGREV 42 ++ ++#define SROM4_LEDBH10 43 ++#define SROM4_LEDBH32 44 ++ ++#define SROM4_LEDDC 45 ++ ++#define SROM4_AA 46 ++#define SROM4_AA2G_MASK 0x00ff ++#define SROM4_AA2G_SHIFT 0 ++#define SROM4_AA5G_MASK 0xff00 ++#define SROM4_AA5G_SHIFT 8 ++ ++#define SROM4_AG10 47 ++#define SROM4_AG32 48 ++ ++#define SROM4_TXPID2G 49 ++#define SROM4_TXPID5G 51 ++#define SROM4_TXPID5GL 53 ++#define SROM4_TXPID5GH 55 ++ ++/* Per-path fields */ ++#define MAX_PATH 4 ++#define SROM4_PATH0 64 ++#define SROM4_PATH1 87 ++#define SROM4_PATH2 110 ++#define SROM4_PATH3 133 ++ ++#define SROM4_2G_ITT_MAXP 0 ++#define SROM4_2G_PA 1 ++#define SROM4_5G_ITT_MAXP 5 ++#define SROM4_5GLH_MAXP 6 ++#define SROM4_5G_PA 7 ++#define SROM4_5GL_PA 11 ++#define SROM4_5GH_PA 15 ++ ++/* Fields in the ITT_MAXP and 5GLH_MAXP words */ ++#define B2G_MAXP_MASK 0xff ++#define B2G_ITT_SHIFT 8 ++#define B5G_MAXP_MASK 0xff ++#define B5G_ITT_SHIFT 8 ++#define B5GH_MAXP_MASK 0xff ++#define B5GL_MAXP_SHIFT 8 ++ ++/* All the miriad power offsets */ ++#define SROM4_2G_CCKPO 156 ++#define SROM4_2G_OFDMPO 157 ++#define SROM4_5G_OFDMPO 159 ++#define SROM4_5GL_OFDMPO 161 ++#define SROM4_5GH_OFDMPO 163 ++#define SROM4_2G_MCSPO 165 ++#define SROM4_5G_MCSPO 173 ++#define SROM4_5GL_MCSPO 181 ++#define SROM4_5GH_MCSPO 189 ++#define SROM4_CCDPO 197 ++#define SROM4_STBCPO 198 ++#define SROM4_BW40PO 199 ++#define SROM4_BWDUPPO 200 ++ ++extern int srom_var_init(void *sbh, uint bus, void *curmap, osl_t *osh, char **vars, uint *count); + -+/* sbtmconfiglow */ -+#define SBTMCL_CD_MASK 0xff /* clock divide */ -+#define SBTMCL_CO_MASK 0xf800 /* clock offset */ -+#define SBTMCL_CO_SHIFT 11 -+#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */ -+#define SBTMCL_IF_SHIFT 18 -+#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */ -+#define SBTMCL_IM_SHIFT 24 ++extern int srom_read(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); ++extern int srom_write(uint bus, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf); + -+/* sbtmconfighigh */ -+#define SBTMCH_BM_MASK 0x3 /* busy mode */ -+#define SBTMCH_RM_MASK 0x3 /* retry mode */ -+#define SBTMCH_RM_SHIFT 2 -+#define SBTMCH_SM_MASK 0x30 /* stop mode */ -+#define SBTMCH_SM_SHIFT 4 -+#define SBTMCH_EM_MASK 0x300 /* sb error mode */ -+#define SBTMCH_EM_SHIFT 8 -+#define SBTMCH_IM_MASK 0xc00 /* int mode */ -+#define SBTMCH_IM_SHIFT 10 ++#endif /* _bcmsrom_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bcm947xx/include/bcmutils.h +--- linux.old/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmutils.h 2006-05-02 01:52:12.000000000 +0200 +@@ -0,0 +1,433 @@ ++/* ++ * Misc useful os-independent macros and functions. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $ ++ */ + -+/* sbbconfig */ -+#define SBBC_LAT_MASK 0x3 /* sb latency */ -+#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */ -+#define SBBC_MAX0_SHIFT 16 -+#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */ -+#define SBBC_MAX1_SHIFT 20 ++#ifndef _bcmutils_h_ ++#define _bcmutils_h_ + -+/* sbbstate */ -+#define SBBS_SRD 0x1 /* st reg disable */ -+#define SBBS_HRD 0x2 /* hold reg disable */ ++/* ** driver-only section ** */ ++#ifdef BCMDRIVER + -+/* sbidlow */ -+#define SBIDL_CS_MASK 0x3 /* config space */ -+#define SBIDL_AR_MASK 0x38 /* # address ranges supported */ -+#define SBIDL_AR_SHIFT 3 -+#define SBIDL_SYNCH 0x40 /* sync */ -+#define SBIDL_INIT 0x80 /* initiator */ -+#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */ -+#define SBIDL_MINLAT_SHIFT 8 -+#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */ -+#define SBIDL_MAXLAT_SHIFT 12 -+#define SBIDL_FIRST 0x10000 /* this initiator is first */ -+#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */ -+#define SBIDL_CW_SHIFT 18 -+#define SBIDL_TP_MASK 0xf00000 /* target ports */ -+#define SBIDL_TP_SHIFT 20 -+#define SBIDL_IP_MASK 0xf000000 /* initiator ports */ -+#define SBIDL_IP_SHIFT 24 -+#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */ -+#define SBIDL_RV_SHIFT 28 -+#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */ -+#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */ ++#define _BCM_U 0x01 /* upper */ ++#define _BCM_L 0x02 /* lower */ ++#define _BCM_D 0x04 /* digit */ ++#define _BCM_C 0x08 /* cntrl */ ++#define _BCM_P 0x10 /* punct */ ++#define _BCM_S 0x20 /* white space (space/lf/tab) */ ++#define _BCM_X 0x40 /* hex digit */ ++#define _BCM_SP 0x80 /* hard space (0x20) */ + -+/* sbidhigh */ -+#define SBIDH_RC_MASK 0x000f /* revision code */ -+#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ -+#define SBIDH_RCE_SHIFT 8 -+#define SBCOREREV(sbidh) \ -+ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) -+#define SBIDH_CC_MASK 0x8ff0 /* core code */ -+#define SBIDH_CC_SHIFT 4 -+#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ -+#define SBIDH_VC_SHIFT 16 ++#define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */ + -+#define SB_COMMIT 0xfd8 /* update buffered registers value */ ++extern unsigned char bcm_ctype[]; ++#define bcm_ismask(x) (bcm_ctype[(int)(unsigned char)(x)]) + -+/* vendor codes */ -+#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */ ++#define bcm_isalnum(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_isalpha(c) ((bcm_ismask(c)&(_BCM_U|_BCM_L)) != 0) ++#define bcm_iscntrl(c) ((bcm_ismask(c)&(_BCM_C)) != 0) ++#define bcm_isdigit(c) ((bcm_ismask(c)&(_BCM_D)) != 0) ++#define bcm_isgraph(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D)) != 0) ++#define bcm_islower(c) ((bcm_ismask(c)&(_BCM_L)) != 0) ++#define bcm_isprint(c) ((bcm_ismask(c)&(_BCM_P|_BCM_U|_BCM_L|_BCM_D|_BCM_SP)) != 0) ++#define bcm_ispunct(c) ((bcm_ismask(c)&(_BCM_P)) != 0) ++#define bcm_isspace(c) ((bcm_ismask(c)&(_BCM_S)) != 0) ++#define bcm_isupper(c) ((bcm_ismask(c)&(_BCM_U)) != 0) ++#define bcm_isxdigit(c) ((bcm_ismask(c)&(_BCM_D|_BCM_X)) != 0) + -+/* core codes */ -+#define SB_CC 0x800 /* chipcommon core */ -+#define SB_ILINE20 0x801 /* iline20 core */ -+#define SB_SDRAM 0x803 /* sdram core */ -+#define SB_PCI 0x804 /* pci core */ -+#define SB_MIPS 0x805 /* mips core */ -+#define SB_ENET 0x806 /* enet mac core */ -+#define SB_CODEC 0x807 /* v90 codec core */ -+#define SB_USB 0x808 /* usb 1.1 host/device core */ -+#define SB_ADSL 0x809 /* ADSL core */ -+#define SB_ILINE100 0x80a /* iline100 core */ -+#define SB_IPSEC 0x80b /* ipsec core */ -+#define SB_PCMCIA 0x80d /* pcmcia core */ -+#define SB_SOCRAM 0x80e /* internal memory core */ -+#define SB_MEMC 0x80f /* memc sdram core */ -+#define SB_EXTIF 0x811 /* external interface core */ -+#define SB_D11 0x812 /* 802.11 MAC core */ -+#define SB_MIPS33 0x816 /* mips3302 core */ -+#define SB_USB11H 0x817 /* usb 1.1 host core */ -+#define SB_USB11D 0x818 /* usb 1.1 device core */ -+#define SB_USB20H 0x819 /* usb 2.0 host core */ -+#define SB_USB20D 0x81a /* usb 2.0 device core */ -+#define SB_SDIOH 0x81b /* sdio host core */ -+#define SB_ROBO 0x81c /* roboswitch core */ -+#define SB_ATA100 0x81d /* parallel ATA core */ -+#define SB_SATAXOR 0x81e /* serial ATA & XOR DMA core */ -+#define SB_GIGETH 0x81f /* gigabit ethernet core */ -+#define SB_PCIE 0x820 /* pci express core */ -+#define SB_SRAMC 0x822 /* SRAM controller core */ -+#define SB_MINIMAC 0x823 /* MINI MAC/phy core */ ++/* ++ * Spin at most 'us' microseconds while 'exp' is true. ++ * Caller should explicitly test 'exp' when this completes ++ * and take appropriate error action if 'exp' is still true. ++ */ ++#define SPINWAIT(exp, us) { \ ++ uint countdown = (us) + 9; \ ++ while ((exp) && (countdown >= 10)) {\ ++ OSL_DELAY(10); \ ++ countdown -= 10; \ ++ } \ ++} + -+#define SB_CC_IDX 0 /* chipc, when present, is always core 0 */ ++struct ether_addr { ++ uint8 octet[6]; ++} __attribute__((packed)); + -+/* Not really related to Silicon Backplane, but a couple of software -+ * conventions for the use the flash space: ++/* string */ ++extern uchar bcm_toupper(uchar c); ++extern ulong bcm_strtoul(char *cp, char **endp, uint base); ++extern char *bcmstrstr(char *haystack, char *needle); ++extern char *bcmstrcat(char *dest, const char *src); ++extern ulong wchar2ascii(char *abuf, ushort *wbuf, ushort wbuflen, ulong abuflen); ++/* ethernet address */ ++extern char *bcm_ether_ntoa(struct ether_addr *ea, char *buf); ++/* variable access */ ++extern char *getvar(char *vars, char *name); ++extern int getintvar(char *vars, char *name); ++extern uint getgpiopin(char *vars, char *pin_name, uint def_pin); ++#ifdef BCMPERFSTATS ++extern void bcm_perf_enable(void); ++extern void bcmstats(char *fmt); ++extern void bcmlog(char *fmt, uint a1, uint a2); ++extern void bcmdumplog(char *buf, int size); ++extern int bcmdumplogent(char *buf, uint idx); ++#else ++#define bcm_perf_enable() ++#define bcmstats(fmt) ++#define bcmlog(fmt, a1, a2) ++#define bcmdumplog(buf, size) *buf = '\0' ++#define bcmdumplogent(buf, idx) -1 ++#endif /* BCMPERFSTATS */ ++extern char *bcm_nvram_vars(uint *length); ++extern int bcm_nvram_cache(void *sbh); ++ ++/* Support for sharing code across in-driver iovar implementations. ++ * The intent is that a driver use this structure to map iovar names ++ * to its (private) iovar identifiers, and the lookup function to ++ * find the entry. Macros are provided to map ids and get/set actions ++ * into a single number space for a switch statement. + */ + -+/* Minumum amount of flash we support */ -+#define FLASH_MIN 0x00020000 /* Minimum flash size */ -+ -+/* A boot/binary may have an embedded block that describes its size */ -+#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ -+#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ -+#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ -+#define BISZ_TXTST_IDX 1 /* 1: text start */ -+#define BISZ_TXTEND_IDX 2 /* 2: text start */ -+#define BISZ_DATAST_IDX 3 /* 3: text start */ -+#define BISZ_DATAEND_IDX 4 /* 4: text start */ -+#define BISZ_BSSST_IDX 5 /* 5: text start */ -+#define BISZ_BSSEND_IDX 6 /* 6: text start */ -+#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */ ++/* iovar structure */ ++typedef struct bcm_iovar { ++ const char *name; /* name for lookup and display */ ++ uint16 varid; /* id for switch */ ++ uint16 flags; /* driver-specific flag bits */ ++ uint16 type; /* base type of argument */ ++ uint16 minlen; /* min length for buffer vars */ ++} bcm_iovar_t; ++ ++/* varid definitions are per-driver, may use these get/set bits */ ++ ++/* IOVar action bits for id mapping */ ++#define IOV_GET 0 /* Get an iovar */ ++#define IOV_SET 1 /* Set an iovar */ ++ ++/* Varid to actionid mapping */ ++#define IOV_GVAL(id) ((id)*2) ++#define IOV_SVAL(id) (((id)*2)+IOV_SET) ++#define IOV_ISSET(actionid) ((actionid & IOV_SET) == IOV_SET) ++ ++/* flags are per-driver based on driver attributes */ ++ ++/* Base type definitions */ ++#define IOVT_VOID 0 /* no value (implictly set only) */ ++#define IOVT_BOOL 1 /* any value ok (zero/nonzero) */ ++#define IOVT_INT8 2 /* integer values are range-checked */ ++#define IOVT_UINT8 3 /* unsigned int 8 bits */ ++#define IOVT_INT16 4 /* int 16 bits */ ++#define IOVT_UINT16 5 /* unsigned int 16 bits */ ++#define IOVT_INT32 6 /* int 32 bits */ ++#define IOVT_UINT32 7 /* unsigned int 32 bits */ ++#define IOVT_BUFFER 8 /* buffer is size-checked as per minlen */ ++ ++extern const bcm_iovar_t *bcm_iovar_lookup(const bcm_iovar_t *table, const char *name); ++extern int bcm_iovar_lencheck(const bcm_iovar_t *table, void *arg, int len, bool set); + -+#endif /* _SBCONFIG_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbextif.h linux.dev/arch/mips/bcm947xx/include/sbextif.h ---- linux.old/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbextif.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,242 @@ -+/* -+ * Hardware-specific External Interface I/O core definitions -+ * for the BCM47xx family of SiliconBackplane-based chips. -+ * -+ * The External Interface core supports a total of three external chip selects -+ * supporting external interfaces. One of the external chip selects is -+ * used for Flash, one is used for PCMCIA, and the other may be -+ * programmed to support either a synchronous interface or an -+ * asynchronous interface. The asynchronous interface can be used to -+ * support external devices such as UARTs and the BCM2019 Bluetooth -+ * baseband processor. -+ * The external interface core also contains 2 on-chip 16550 UARTs, clock -+ * frequency control, a watchdog interrupt timer, and a GPIO interface. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ ++#endif /* #ifdef BCMDRIVER */ + -+#ifndef _SBEXTIF_H -+#define _SBEXTIF_H ++/* ** driver/apps-shared section ** */ + -+/* external interface address space */ -+#define EXTIF_PCMCIA_MEMBASE(x) (x) -+#define EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000) -+#define EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000) -+#define EXTIF_CFGIF_BASE(x) ((x) + 0x800000) -+#define EXTIF_FLASH_BASE(x) ((x) + 0xc00000) ++#define BCME_STRLEN 64 /* Max string length for BCM errors */ ++#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) + -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ + +/* -+ * The multiple instances of output and output enable registers -+ * are present to allow driver software for multiple cores to control -+ * gpio outputs without needing to share a single register pair. -+ */ -+struct gpiouser { -+ uint32 out; -+ uint32 outen; -+}; -+#define NGPIOUSER 5 ++ * error codes could be added but the defined ones shouldn't be changed/deleted ++ * these error codes are exposed to the user code ++ * when ever a new error code is added to this list ++ * please update errorstring table with the related error string and ++ * update osl files with os specific errorcode map ++*/ + -+typedef volatile struct { -+ uint32 corecontrol; -+ uint32 extstatus; -+ uint32 PAD[2]; ++#define BCME_OK 0 /* Success */ ++#define BCME_ERROR -1 /* Error generic */ ++#define BCME_BADARG -2 /* Bad Argument */ ++#define BCME_BADOPTION -3 /* Bad option */ ++#define BCME_NOTUP -4 /* Not up */ ++#define BCME_NOTDOWN -5 /* Not down */ ++#define BCME_NOTAP -6 /* Not AP */ ++#define BCME_NOTSTA -7 /* Not STA */ ++#define BCME_BADKEYIDX -8 /* BAD Key Index */ ++#define BCME_RADIOOFF -9 /* Radio Off */ ++#define BCME_NOTBANDLOCKED -10 /* Not band locked */ ++#define BCME_NOCLK -11 /* No Clock */ ++#define BCME_BADRATESET -12 /* BAD Rate valueset */ ++#define BCME_BADBAND -13 /* BAD Band */ ++#define BCME_BUFTOOSHORT -14 /* Buffer too short */ ++#define BCME_BUFTOOLONG -15 /* Buffer too long */ ++#define BCME_BUSY -16 /* Busy */ ++#define BCME_NOTASSOCIATED -17 /* Not Associated */ ++#define BCME_BADSSIDLEN -18 /* Bad SSID len */ ++#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */ ++#define BCME_BADCHAN -20 /* Bad Channel */ ++#define BCME_BADADDR -21 /* Bad Address */ ++#define BCME_NORESOURCE -22 /* Not Enough Resources */ ++#define BCME_UNSUPPORTED -23 /* Unsupported */ ++#define BCME_BADLEN -24 /* Bad length */ ++#define BCME_NOTREADY -25 /* Not Ready */ ++#define BCME_EPERM -26 /* Not Permitted */ ++#define BCME_NOMEM -27 /* No Memory */ ++#define BCME_ASSOCIATED -28 /* Associated */ ++#define BCME_RANGE -29 /* Not In Range */ ++#define BCME_NOTFOUND -30 /* Not Found */ ++#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */ ++#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */ ++#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */ ++#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */ ++#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */ ++#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */ ++#define BCME_LAST BCME_DONGLE_DOWN ++ ++/* These are collection of BCME Error strings */ ++#define BCMERRSTRINGTABLE { \ ++ "OK", \ ++ "Undefined error", \ ++ "Bad Argument", \ ++ "Bad Option", \ ++ "Not up", \ ++ "Not down", \ ++ "Not AP", \ ++ "Not STA", \ ++ "Bad Key Index", \ ++ "Radio Off", \ ++ "Not band locked", \ ++ "No clock", \ ++ "Bad Rate valueset", \ ++ "Bad Band", \ ++ "Buffer too short", \ ++ "Buffer too long", \ ++ "Busy", \ ++ "Not Associated", \ ++ "Bad SSID len", \ ++ "Out of Range Channel", \ ++ "Bad Channel", \ ++ "Bad Address", \ ++ "Not Enough Resources", \ ++ "Unsupported", \ ++ "Bad length", \ ++ "Not Ready", \ ++ "Not Permitted", \ ++ "No Memory", \ ++ "Associated", \ ++ "Not In Range", \ ++ "Not Found", \ ++ "WME Not Enabled", \ ++ "TSPEC Not Found", \ ++ "ACM Not Supported", \ ++ "Not WME Association", \ ++ "SDIO Bus Error", \ ++ "Dongle Not Accessible" \ ++} + -+ /* pcmcia control registers */ -+ uint32 pcmcia_config; -+ uint32 pcmcia_memwait; -+ uint32 pcmcia_attrwait; -+ uint32 pcmcia_iowait; ++#ifndef ABS ++#define ABS(a) (((a) < 0)?-(a):(a)) ++#endif /* ABS */ + -+ /* programmable interface control registers */ -+ uint32 prog_config; -+ uint32 prog_waitcount; ++#ifndef MIN ++#define MIN(a, b) (((a) < (b))?(a):(b)) ++#endif /* MIN */ + -+ /* flash control registers */ -+ uint32 flash_config; -+ uint32 flash_waitcount; -+ uint32 PAD[4]; ++#ifndef MAX ++#define MAX(a, b) (((a) > (b))?(a):(b)) ++#endif /* MAX */ + -+ uint32 watchdog; ++#define CEIL(x, y) (((x) + ((y)-1)) / (y)) ++#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) ++#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) ++#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) ++#define VALID_MASK(mask) !((mask) & ((mask) + 1)) ++#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) ++#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) + -+ /* clock control */ -+ uint32 clockcontrol_n; -+ uint32 clockcontrol_sb; -+ uint32 clockcontrol_pci; -+ uint32 clockcontrol_mii; -+ uint32 PAD[3]; ++/* bit map related macros */ ++#ifndef setbit ++#ifndef NBBY /* the BSD family defines NBBY */ ++#define NBBY 8 /* 8 bits per byte */ ++#endif /* #ifndef NBBY */ ++#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) ++#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) ++#define isset(a, i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) ++#define isclr(a, i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) ++#endif /* setbit */ + -+ /* gpio */ -+ uint32 gpioin; -+ struct gpiouser gpio[NGPIOUSER]; -+ uint32 PAD; -+ uint32 ejtagouten; -+ uint32 gpiointpolarity; -+ uint32 gpiointmask; -+ uint32 PAD[153]; ++#define NBITS(type) (sizeof(type) * 8) ++#define NBITVAL(nbits) (1 << (nbits)) ++#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) ++#define NBITMASK(nbits) MAXBITVAL(nbits) ++#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) + -+ uint8 uartdata; -+ uint8 PAD[3]; -+ uint8 uartimer; -+ uint8 PAD[3]; -+ uint8 uartfcr; -+ uint8 PAD[3]; -+ uint8 uartlcr; -+ uint8 PAD[3]; -+ uint8 uartmcr; -+ uint8 PAD[3]; -+ uint8 uartlsr; -+ uint8 PAD[3]; -+ uint8 uartmsr; -+ uint8 PAD[3]; -+ uint8 uartscratch; -+ uint8 PAD[3]; -+} extifregs_t; ++/* basic mux operation - can be optimized on several architectures */ ++#define MUX(pred, true, false) ((pred) ? (true) : (false)) + -+/* corecontrol */ -+#define CC_UE (1 << 0) /* uart enable */ ++/* modulo inc/dec - assumes x E [0, bound - 1] */ ++#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) ++#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) + -+/* extstatus */ -+#define ES_EM (1 << 0) /* endian mode (ro) */ -+#define ES_EI (1 << 1) /* external interrupt pin (ro) */ -+#define ES_GI (1 << 2) /* gpio interrupt pin (ro) */ ++/* modulo inc/dec, bound = 2^k */ ++#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) ++#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) + -+/* gpio bit mask */ -+#define GPIO_BIT0 (1 << 0) -+#define GPIO_BIT1 (1 << 1) -+#define GPIO_BIT2 (1 << 2) -+#define GPIO_BIT3 (1 << 3) -+#define GPIO_BIT4 (1 << 4) -+#define GPIO_BIT5 (1 << 5) -+#define GPIO_BIT6 (1 << 6) -+#define GPIO_BIT7 (1 << 7) ++/* modulo add/sub - assumes x, y E [0, bound - 1] */ ++#define MODADD(x, y, bound) \ ++ MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) ++#define MODSUB(x, y, bound) \ ++ MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) + ++/* module add/sub, bound = 2^k */ ++#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) ++#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) + -+/* pcmcia/prog/flash_config */ -+#define CF_EN (1 << 0) /* enable */ -+#define CF_EM_MASK 0xe /* mode */ -+#define CF_EM_SHIFT 1 -+#define CF_EM_FLASH 0x0 /* flash/asynchronous mode */ -+#define CF_EM_SYNC 0x2 /* synchronous mode */ -+#define CF_EM_PCMCIA 0x4 /* pcmcia mode */ -+#define CF_DS (1 << 4) /* destsize: 0=8bit, 1=16bit */ -+#define CF_BS (1 << 5) /* byteswap */ -+#define CF_CD_MASK 0xc0 /* clock divider */ -+#define CF_CD_SHIFT 6 -+#define CF_CD_DIV2 0x0 /* backplane/2 */ -+#define CF_CD_DIV3 0x40 /* backplane/3 */ -+#define CF_CD_DIV4 0x80 /* backplane/4 */ -+#define CF_CE (1 << 8) /* clock enable */ -+#define CF_SB (1 << 9) /* size/bytestrobe (synch only) */ ++/* crc defines */ ++#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ ++#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ ++#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ ++#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ ++#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ ++#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ + -+/* pcmcia_memwait */ -+#define PM_W0_MASK 0x3f /* waitcount0 */ -+#define PM_W1_MASK 0x1f00 /* waitcount1 */ -+#define PM_W1_SHIFT 8 -+#define PM_W2_MASK 0x1f0000 /* waitcount2 */ -+#define PM_W2_SHIFT 16 -+#define PM_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PM_W3_SHIFT 24 ++/* bcm_format_flags() bit description structure */ ++typedef struct bcm_bit_desc { ++ uint32 bit; ++ char* name; ++} bcm_bit_desc_t; + -+/* pcmcia_attrwait */ -+#define PA_W0_MASK 0x3f /* waitcount0 */ -+#define PA_W1_MASK 0x1f00 /* waitcount1 */ -+#define PA_W1_SHIFT 8 -+#define PA_W2_MASK 0x1f0000 /* waitcount2 */ -+#define PA_W2_SHIFT 16 -+#define PA_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PA_W3_SHIFT 24 ++/* tag_ID/length/value_buffer tuple */ ++typedef struct bcm_tlv { ++ uint8 id; ++ uint8 len; ++ uint8 data[1]; ++} bcm_tlv_t; + -+/* pcmcia_iowait */ -+#define PI_W0_MASK 0x3f /* waitcount0 */ -+#define PI_W1_MASK 0x1f00 /* waitcount1 */ -+#define PI_W1_SHIFT 8 -+#define PI_W2_MASK 0x1f0000 /* waitcount2 */ -+#define PI_W2_SHIFT 16 -+#define PI_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PI_W3_SHIFT 24 ++/* Check that bcm_tlv_t fits into the given buflen */ ++#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) + -+/* prog_waitcount */ -+#define PW_W0_MASK 0x0000001f /* waitcount0 */ -+#define PW_W1_MASK 0x00001f00 /* waitcount1 */ -+#define PW_W1_SHIFT 8 -+#define PW_W2_MASK 0x001f0000 /* waitcount2 */ -+#define PW_W2_SHIFT 16 -+#define PW_W3_MASK 0x1f000000 /* waitcount3 */ -+#define PW_W3_SHIFT 24 ++/* buffer length for ethernet address from bcm_ether_ntoa() */ ++#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ + -+#define PW_W0 0x0000000c -+#define PW_W1 0x00000a00 -+#define PW_W2 0x00020000 -+#define PW_W3 0x01000000 ++/* unaligned load and store macros */ ++#ifdef IL_BIGENDIAN ++static INLINE uint32 ++load32_ua(uint8 *a) ++{ ++ return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); ++} + -+/* flash_waitcount */ -+#define FW_W0_MASK 0x1f /* waitcount0 */ -+#define FW_W1_MASK 0x1f00 /* waitcount1 */ -+#define FW_W1_SHIFT 8 -+#define FW_W2_MASK 0x1f0000 /* waitcount2 */ -+#define FW_W2_SHIFT 16 -+#define FW_W3_MASK 0x1f000000 /* waitcount3 */ -+#define FW_W3_SHIFT 24 ++static INLINE void ++store32_ua(uint8 *a, uint32 v) ++{ ++ a[0] = (v >> 24) & 0xff; ++ a[1] = (v >> 16) & 0xff; ++ a[2] = (v >> 8) & 0xff; ++ a[3] = v & 0xff; ++} + -+/* watchdog */ -+#define WATCHDOG_CLOCK 48000000 /* Hz */ ++static INLINE uint16 ++load16_ua(uint8 *a) ++{ ++ return ((a[0] << 8) | a[1]); ++} + -+/* clockcontrol_n */ -+#define CN_N1_MASK 0x3f /* n1 control */ -+#define CN_N2_MASK 0x3f00 /* n2 control */ -+#define CN_N2_SHIFT 8 ++static INLINE void ++store16_ua(uint8 *a, uint16 v) ++{ ++ a[0] = (v >> 8) & 0xff; ++ a[1] = v & 0xff; ++} + -+/* clockcontrol_sb/pci/mii */ -+#define CC_M1_MASK 0x3f /* m1 control */ -+#define CC_M2_MASK 0x3f00 /* m2 control */ -+#define CC_M2_SHIFT 8 -+#define CC_M3_MASK 0x3f0000 /* m3 control */ -+#define CC_M3_SHIFT 16 -+#define CC_MC_MASK 0x1f000000 /* mux control */ -+#define CC_MC_SHIFT 24 ++#else + -+/* Clock control default values */ -+#define CC_DEF_N 0x0009 /* Default values for bcm4710 */ -+#define CC_DEF_100 0x04020011 -+#define CC_DEF_33 0x11030011 -+#define CC_DEF_25 0x11050011 ++static INLINE uint32 ++load32_ua(uint8 *a) ++{ ++ return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]); ++} + -+/* Clock control values for 125Mhz */ -+#define CC_125_N 0x0802 -+#define CC_125_M 0x04020009 -+#define CC_125_M25 0x11090009 -+#define CC_125_M33 0x11090005 ++static INLINE void ++store32_ua(uint8 *a, uint32 v) ++{ ++ a[3] = (v >> 24) & 0xff; ++ a[2] = (v >> 16) & 0xff; ++ a[1] = (v >> 8) & 0xff; ++ a[0] = v & 0xff; ++} + -+/* Clock control magic field values */ -+#define CC_F6_2 0x02 /* A factor of 2 in */ -+#define CC_F6_3 0x03 /* 6-bit fields like */ -+#define CC_F6_4 0x05 /* N1, M1 or M3 */ -+#define CC_F6_5 0x09 -+#define CC_F6_6 0x11 -+#define CC_F6_7 0x21 ++static INLINE uint16 ++load16_ua(uint8 *a) ++{ ++ return ((a[1] << 8) | a[0]); ++} + -+#define CC_F5_BIAS 5 /* 5-bit fields get this added */ ++static INLINE void ++store16_ua(uint8 *a, uint16 v) ++{ ++ a[1] = (v >> 8) & 0xff; ++ a[0] = v & 0xff; ++} + -+#define CC_MC_BYPASS 0x08 -+#define CC_MC_M1 0x04 -+#define CC_MC_M1M2 0x02 -+#define CC_MC_M1M2M3 0x01 -+#define CC_MC_M1M3 0x11 ++#endif /* IL_BIGENDIAN */ + -+#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */ ++/* externs */ ++/* crc */ ++extern uint8 hndcrc8(uint8 *p, uint nbytes, uint8 crc); ++extern uint16 hndcrc16(uint8 *p, uint nbytes, uint16 crc); ++extern uint32 hndcrc32(uint8 *p, uint nbytes, uint32 crc); ++/* format/print */ ++extern void printfbig(char *buf); + -+#endif /* _SBEXTIF_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm947xx/include/sbmemc.h ---- linux.old/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbmemc.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,148 @@ ++/* IE parsing */ ++extern bcm_tlv_t *bcm_next_tlv(bcm_tlv_t *elt, int *buflen); ++extern bcm_tlv_t *bcm_parse_tlvs(void *buf, int buflen, uint key); ++extern bcm_tlv_t *bcm_parse_ordered_tlvs(void *buf, int buflen, uint key); ++ ++/* bcmerror */ ++extern const char *bcmerrorstr(int bcmerror); ++ ++/* multi-bool data type: set of bools, mbool is true if any is set */ ++typedef uint32 mbool; ++#define mboolset(mb, bit) (mb |= bit) /* set one bool */ ++#define mboolclr(mb, bit) (mb &= ~bit) /* clear one bool */ ++#define mboolisset(mb, bit) ((mb & bit) != 0) /* TRUE if one bool is set */ ++#define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) ++ ++/* power conversion */ ++extern uint16 bcm_qdbm_to_mw(uint8 qdbm); ++extern uint8 bcm_mw_to_qdbm(uint16 mw); ++ ++/* generic datastruct to help dump routines */ ++struct fielddesc { ++ char *nameandfmt; ++ uint32 offset; ++ uint32 len; ++}; ++ ++/* Buffer structure for collecting string-formatted data ++* using bcm_bprintf() API. ++* Use bcm_binit() to initialize before use ++*/ ++struct bcmstrbuf ++{ ++ char *buf; /* pointer to current position in origbuf */ ++ uint size; /* current (residual) size in bytes */ ++ char *origbuf; /* unmodified pointer to orignal buffer */ ++ uint origsize; /* unmodified orignal buffer size in bytes */ ++}; ++ ++extern void bcm_binit(struct bcmstrbuf *b, char *buf, uint size); ++extern int bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...); ++ ++typedef uint32 (*readreg_rtn)(void *arg0, void *arg1, uint32 offset); ++extern uint bcmdumpfields(readreg_rtn func_ptr, void *arg0, void *arg1, struct fielddesc *str, ++ char *buf, uint32 bufsize); ++ ++extern uint bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint len); ++extern uint bcm_bitcount(uint8 *bitmap, uint bytelength); ++ ++#endif /* _bcmutils_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/hndcpu.h linux.dev/arch/mips/bcm947xx/include/hndcpu.h +--- linux.old/arch/mips/bcm947xx/include/hndcpu.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/hndcpu.h 2006-04-27 22:14:38.000000000 +0200 +@@ -0,0 +1,28 @@ +/* -+ * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. ++ * HND SiliconBackplane MIPS/ARM cores software interface. + * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id$ ++ * $Id: hndcpu.h,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $ + */ + -+#ifndef _SBMEMC_H -+#define _SBMEMC_H ++#ifndef _hndcpu_h_ ++#define _hndcpu_h_ + -+#ifdef _LANGUAGE_ASSEMBLY ++#if defined(mips) ++#include ++#elif defined(__ARM_ARCH_4T__) ++#include ++#endif + -+#define MEMC_CONTROL 0x00 -+#define MEMC_CONFIG 0x04 -+#define MEMC_REFRESH 0x08 -+#define MEMC_BISTSTAT 0x0c -+#define MEMC_MODEBUF 0x10 -+#define MEMC_BKCLS 0x14 -+#define MEMC_PRIORINV 0x18 -+#define MEMC_DRAMTIM 0x1c -+#define MEMC_INTSTAT 0x20 -+#define MEMC_INTMASK 0x24 -+#define MEMC_INTINFO 0x28 -+#define MEMC_NCDLCTL 0x30 -+#define MEMC_RDNCDLCOR 0x34 -+#define MEMC_WRNCDLCOR 0x38 -+#define MEMC_MISCDLYCTL 0x3c -+#define MEMC_DQSGATENCDL 0x40 -+#define MEMC_SPARE 0x44 -+#define MEMC_TPADDR 0x48 -+#define MEMC_TPDATA 0x4c -+#define MEMC_BARRIER 0x50 -+#define MEMC_CORE 0x54 ++extern uint sb_irq(sb_t *sbh); ++extern uint32 sb_cpu_clock(sb_t *sbh); ++extern void sb_cpu_wait(void); + ++#endif /* _hndcpu_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/hndmips.h linux.dev/arch/mips/bcm947xx/include/hndmips.h +--- linux.old/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/hndmips.h 2006-04-27 20:43:42.000000000 +0200 +@@ -0,0 +1,45 @@ ++/* ++ * HND SiliconBackplane MIPS core software interface. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: hndmips.h,v 1.1.1.8 2006/02/27 03:43:16 honor Exp $ ++ */ + -+#else -+ -+/* Sonics side: MEMC core registers */ -+typedef volatile struct sbmemcregs { -+ uint32 control; -+ uint32 config; -+ uint32 refresh; -+ uint32 biststat; -+ uint32 modebuf; -+ uint32 bkcls; -+ uint32 priorinv; -+ uint32 dramtim; -+ uint32 intstat; -+ uint32 intmask; -+ uint32 intinfo; -+ uint32 reserved1; -+ uint32 ncdlctl; -+ uint32 rdncdlcor; -+ uint32 wrncdlcor; -+ uint32 miscdlyctl; -+ uint32 dqsgatencdl; -+ uint32 spare; -+ uint32 tpaddr; -+ uint32 tpdata; -+ uint32 barrier; -+ uint32 core; -+} sbmemcregs_t; -+ -+#endif -+ -+/* MEMC Core Init values (OCP ID 0x80f) */ -+ -+/* For sdr: */ -+#define MEMC_SD_CONFIG_INIT 0x00048000 -+#define MEMC_SD_DRAMTIM2_INIT 0x000754d8 -+#define MEMC_SD_DRAMTIM3_INIT 0x000754da -+#define MEMC_SD_RDNCDLCOR_INIT 0x00000000 -+#define MEMC_SD_WRNCDLCOR_INIT 0x49351200 -+#define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 /* For corerev 1 (4712) */ -+#define MEMC_SD_MISCDLYCTL_INIT 0x00061c1b -+#define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 /* For corerev 1 (4712) */ -+#define MEMC_SD_CONTROL_INIT0 0x00000002 -+#define MEMC_SD_CONTROL_INIT1 0x00000008 -+#define MEMC_SD_CONTROL_INIT2 0x00000004 -+#define MEMC_SD_CONTROL_INIT3 0x00000010 -+#define MEMC_SD_CONTROL_INIT4 0x00000001 -+#define MEMC_SD_MODEBUF_INIT 0x00000000 -+#define MEMC_SD_REFRESH_INIT 0x0000840f -+ -+ -+/* This is for SDRM8X8X4 */ -+#define MEMC_SDR_INIT 0x0008 -+#define MEMC_SDR_MODE 0x32 -+#define MEMC_SDR_NCDL 0x00020032 -+#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */ -+ -+/* For ddr: */ -+#define MEMC_CONFIG_INIT 0x00048000 -+#define MEMC_DRAMTIM2_INIT 0x000754d8 -+#define MEMC_DRAMTIM25_INIT 0x000754d9 -+#define MEMC_RDNCDLCOR_INIT 0x00000000 -+#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */ -+#define MEMC_WRNCDLCOR_INIT 0x49351200 -+#define MEMC_1_WRNCDLCOR_INIT 0x14500200 -+#define MEMC_DQSGATENCDL_INIT 0x00030000 -+#define MEMC_MISCDLYCTL_INIT 0x21061c1b -+#define MEMC_1_MISCDLYCTL_INIT 0x21021400 -+#define MEMC_NCDLCTL_INIT 0x00002001 -+#define MEMC_CONTROL_INIT0 0x00000002 -+#define MEMC_CONTROL_INIT1 0x00000008 -+#define MEMC_MODEBUF_INIT0 0x00004000 -+#define MEMC_CONTROL_INIT2 0x00000010 -+#define MEMC_MODEBUF_INIT1 0x00000100 -+#define MEMC_CONTROL_INIT3 0x00000010 -+#define MEMC_CONTROL_INIT4 0x00000008 -+#define MEMC_REFRESH_INIT 0x0000840f -+#define MEMC_CONTROL_INIT5 0x00000004 -+#define MEMC_MODEBUF_INIT2 0x00000000 -+#define MEMC_CONTROL_INIT6 0x00000010 -+#define MEMC_CONTROL_INIT7 0x00000001 -+ -+ -+/* This is for DDRM16X16X2 */ -+#define MEMC_DDR_INIT 0x0009 -+#define MEMC_DDR_MODE 0x62 -+#define MEMC_DDR_NCDL 0x0005050a -+#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */ -+ -+/* mask for sdr/ddr calibration registers */ -+#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff -+#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff -+#define MEMC_DQSGATENCDL_G_MASK 0x000000ff -+ -+/* masks for miscdlyctl registers */ -+#define MEMC_MISC_SM_MASK 0x30000000 -+#define MEMC_MISC_SM_SHIFT 28 -+#define MEMC_MISC_SD_MASK 0x0f000000 -+#define MEMC_MISC_SD_SHIFT 24 -+ -+/* hw threshhold for calculating wr/rd for sdr memc */ -+#define MEMC_CD_THRESHOLD 128 ++#ifndef _hndmips_h_ ++#define _hndmips_h_ ++ ++extern void sb_mips_init(sb_t *sbh, uint shirq_map_base); ++extern bool sb_mips_setclock(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock); ++extern void enable_pfc(uint32 mode); ++extern uint32 sb_memc_get_ncdl(sb_t *sbh); ++ ++#if defined(BCMPERFSTATS) ++/* enable counting - exclusive version. Only one set of counters allowed at a time */ ++extern void hndmips_perf_instrcount_enable(void); ++extern void hndmips_perf_icachecount_enable(void); ++extern void hndmips_perf_dcachecount_enable(void); ++/* start and stop counting */ ++#define hndmips_perf_start01() \ ++ MTC0(C0_PERFORMANCE, 4, MFC0(C0_PERFORMANCE, 4) | 0x80008000) ++#define hndmips_perf_stop01() \ ++ MTC0(C0_PERFORMANCE, 4, MFC0(C0_PERFORMANCE, 4) & ~0x80008000) ++/* retrieve coutners - counters *decrement* */ ++#define hndmips_perf_read0() -(long)(MFC0(C0_PERFORMANCE, 0)) ++#define hndmips_perf_read1() -(long)(MFC0(C0_PERFORMANCE, 1)) ++#define hndmips_perf_read2() -(long)(MFC0(C0_PERFORMANCE, 2)) ++/* enable counting - modular version. Each counters can be enabled separately. */ ++extern void hndmips_perf_icache_hit_enable(void); ++extern void hndmips_perf_icache_miss_enable(void); ++extern uint32 hndmips_perf_read_instrcount(void); ++extern uint32 hndmips_perf_read_cache_miss(void); ++extern uint32 hndmips_perf_read_cache_hit(void); ++#endif /* defined(BCMINTERNAL) || defined (BCMPERFSTATS) */ ++ ++#endif /* _hndmips_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/hndpci.h linux.dev/arch/mips/bcm947xx/include/hndpci.h +--- linux.old/arch/mips/bcm947xx/include/hndpci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/hndpci.h 2006-04-27 20:36:48.000000000 +0200 +@@ -0,0 +1,30 @@ ++/* ++ * HND SiliconBackplane PCI core software interface. ++ * ++ * $Id: hndpci.h,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $ ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ */ + -+/* Low bit of init register says if memc is ddr or sdr */ -+#define MEMC_CONFIG_DDR 0x00000001 ++#ifndef _hndpci_h_ ++#define _hndpci_h_ ++ ++extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, ++ int len); ++extern int extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, ++ int len); ++extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, ++ int len); ++extern int extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, ++ int len); ++extern void sbpci_ban(uint16 core); ++extern int sbpci_init(sb_t *sbh); ++extern int sbpci_init_pci(sb_t *sbh); ++extern void sbpci_check(sb_t *sbh); + -+#endif /* _SBMEMC_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbmips.h linux.dev/arch/mips/bcm947xx/include/sbmips.h ---- linux.old/arch/mips/bcm947xx/include/sbmips.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbmips.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,62 @@ ++#endif /* _hndpci_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bcm947xx/include/linuxver.h +--- linux.old/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/linuxver.h 2006-04-27 20:10:08.000000000 +0200 +@@ -0,0 +1,417 @@ +/* -+ * Broadcom SiliconBackplane MIPS definitions -+ * -+ * SB MIPS cores are custom MIPS32 processors with SiliconBackplane -+ * OCP interfaces. The CP0 processor ID is 0x00024000, where bits -+ * 23:16 mean Broadcom and bits 15:8 mean a MIPS core with an OCP -+ * interface. The core revision is stored in the SB ID register in SB -+ * configuration space. ++ * Linux-specific abstractions to gain some independence from linux kernel versions. ++ * Pave over some 2.2 versus 2.4 versus 2.6 kernel differences. + * -+ * Copyright 2005, Broadcom Corporation ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -4783,1533 +4409,1651 @@ diff -Naur linux.old/arch/mips/bcm947xx/include/sbmips.h linux.dev/arch/mips/bcm + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id$ ++ * $Id: linuxver.h,v 1.1.1.10 2006/02/27 03:43:16 honor Exp $ + */ + -+#ifndef _SBMIPS_H -+#define _SBMIPS_H ++#ifndef _linuxver_h_ ++#define _linuxver_h_ + -+#include ++#include ++#include + -+#ifndef _LANGUAGE_ASSEMBLY ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0)) ++/* __NO_VERSION__ must be defined for all linkables except one in 2.2 */ ++#ifdef __UNDEF_NO_VERSION__ ++#undef __NO_VERSION__ ++#else ++#define __NO_VERSION__ ++#endif ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 0) */ + -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif /* PAD */ ++#if defined(MODULE) && defined(MODVERSIONS) ++#include ++#endif + -+typedef volatile struct { -+ uint32 corecontrol; -+ uint32 PAD[2]; -+ uint32 biststatus; -+ uint32 PAD[4]; -+ uint32 intstatus; -+ uint32 intmask; -+ uint32 timer; -+} mipsregs_t; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 0) ++#include ++#endif + -+extern uint32 sb_flag(sb_t *sbh); -+extern uint sb_irq(sb_t *sbh); + -+extern void BCMINIT(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) ++#define module_param(_name_, _type_, _perm_) MODULE_PARM(_name_, "i") ++#define module_param_string(_name_, _string_, _size_, _perm_) \ ++ MODULE_PARM(_string_, "c" __MODULE_STRING(_size_)) ++#endif + -+extern void *sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap); -+extern void sb_jtagm_disable(void *h); -+extern uint32 jtag_rwreg(void *h, uint32 ir, uint32 dr); -+extern void BCMINIT(sb_mips_init)(sb_t *sbh); -+extern uint32 BCMINIT(sb_mips_clock)(sb_t *sbh); -+extern bool BCMINIT(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock); -+extern void BCMINIT(enable_pfc)(uint32 mode); -+extern uint32 BCMINIT(sb_memc_get_ncdl)(sb_t *sbh); ++/* linux/malloc.h is deprecated, use linux/slab.h instead. */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 9)) ++#include ++#else ++#include ++#endif + ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+#endif /* _LANGUAGE_ASSEMBLY */ ++#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41)) ++#include ++#else ++#include ++#ifndef work_struct ++#define work_struct tq_struct ++#endif ++#ifndef INIT_WORK ++#define INIT_WORK(_work, _func, _data) INIT_TQUEUE((_work), (_func), (_data)) ++#endif ++#ifndef schedule_work ++#define schedule_work(_work) schedule_task((_work)) ++#endif ++#ifndef flush_scheduled_work ++#define flush_scheduled_work() flush_scheduled_tasks() ++#endif ++#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 41) */ + -+#endif /* _SBMIPS_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm947xx/include/sbpci.h ---- linux.old/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbpci.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,122 @@ -+/* -+ * BCM47XX Sonics SiliconBackplane PCI core hardware definitions. -+ * -+ * $Id$ -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) ++/* Some distributions have their own 2.6.x compatibility layers */ ++#ifndef IRQ_NONE ++typedef void irqreturn_t; ++#define IRQ_NONE ++#define IRQ_HANDLED ++#define IRQ_RETVAL(x) ++#endif ++#else ++typedef irqreturn_t(*FN_ISR) (int irq, void *dev_id, struct pt_regs *ptregs); ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) */ ++ ++#if defined(CONFIG_PCMCIA) || defined(CONFIG_PCMCIA_MODULE) ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 69)) ++/* In 2.5 (as of 2.5.69 at least) there is a cs_error exported which ++ * does this, but it's not in 2.4 so we do our own for now. + */ ++static inline void ++cs_error(client_handle_t handle, int func, int ret) ++{ ++ error_info_t err = { func, ret }; ++ CardServices(ReportError, handle, &err); ++} ++#endif + -+#ifndef _SBPCI_H -+#define _SBPCI_H ++#endif /* CONFIG_PCMCIA */ + -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) ++#ifndef __exit ++#define __exit ++#endif ++#ifndef __devexit ++#define __devexit ++#endif ++#ifndef __devinit ++#define __devinit __init ++#endif ++#ifndef __devinitdata ++#define __devinitdata ++#endif ++#ifndef __devexit_p ++#define __devexit_p(x) x +#endif + -+/* Sonics side: PCI core and host control registers */ -+typedef struct sbpciregs { -+ uint32 control; /* PCI control */ -+ uint32 PAD[3]; -+ uint32 arbcontrol; /* PCI arbiter control */ -+ uint32 PAD[3]; -+ uint32 intstatus; /* Interrupt status */ -+ uint32 intmask; /* Interrupt mask */ -+ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */ -+ uint32 PAD[9]; -+ uint32 bcastaddr; /* Sonics broadcast address */ -+ uint32 bcastdata; /* Sonics broadcast data */ -+ uint32 PAD[2]; -+ uint32 gpioin; /* ro: gpio input (>=rev2) */ -+ uint32 gpioout; /* rw: gpio output (>=rev2) */ -+ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */ -+ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */ -+ uint32 PAD[36]; -+ uint32 sbtopci0; /* Sonics to PCI translation 0 */ -+ uint32 sbtopci1; /* Sonics to PCI translation 1 */ -+ uint32 sbtopci2; /* Sonics to PCI translation 2 */ -+ uint32 PAD[445]; -+ uint16 sprom[36]; /* SPROM shadow Area */ -+ uint32 PAD[46]; -+} sbpciregs_t; ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 0)) + -+/* PCI control */ -+#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ -+#define PCI_RST 0x02 /* Value driven out to pin */ -+#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ -+#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ ++#define pci_get_drvdata(dev) (dev)->sysdata ++#define pci_set_drvdata(dev, value) (dev)->sysdata = (value) + -+/* PCI arbiter control */ -+#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ -+#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ -+#define PCI_PARKID_MASK 0x06 /* Selects which agent is parked on an idle bus */ -+#define PCI_PARKID_SHIFT 1 -+#define PCI_PARKID_LAST 0 /* Last requestor */ -+#define PCI_PARKID_4710 1 /* 4710 */ -+#define PCI_PARKID_EXTREQ0 2 /* External requestor 0 */ -+#define PCI_PARKID_EXTREQ1 3 /* External requestor 1 */ ++/* ++ * New-style (2.4.x) PCI/hot-pluggable PCI/CardBus registration ++ */ + -+/* Interrupt status/mask */ -+#define PCI_INTA 0x01 /* PCI INTA# is asserted */ -+#define PCI_INTB 0x02 /* PCI INTB# is asserted */ -+#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ -+#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ -+#define PCI_PME 0x10 /* PCI PME# is asserted */ ++struct pci_device_id { ++ unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */ ++ unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ ++ unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */ ++ unsigned long driver_data; /* Data private to the driver */ ++}; + -+/* (General) PCI/SB mailbox interrupts, two bits per pci function */ -+#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ -+#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ -+#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ -+#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ -+#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ -+#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ -+#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ -+#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ ++struct pci_driver { ++ struct list_head node; ++ char *name; ++ const struct pci_device_id *id_table; /* NULL if wants all devices */ ++ int (*probe)(struct pci_dev *dev, ++ const struct pci_device_id *id); /* New device inserted */ ++ void (*remove)(struct pci_dev *dev); /* Device removed (NULL if not a hot-plug ++ * capable driver) ++ */ ++ void (*suspend)(struct pci_dev *dev); /* Device suspended */ ++ void (*resume)(struct pci_dev *dev); /* Device woken up */ ++}; + -+/* Sonics broadcast address */ -+#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ ++#define MODULE_DEVICE_TABLE(type, name) ++#define PCI_ANY_ID (~0) + -+/* Sonics to PCI translation types */ -+#define SBTOPCI0_MASK 0xfc000000 -+#define SBTOPCI1_MASK 0xfc000000 -+#define SBTOPCI2_MASK 0xc0000000 -+#define SBTOPCI_MEM 0 -+#define SBTOPCI_IO 1 -+#define SBTOPCI_CFG0 2 -+#define SBTOPCI_CFG1 3 -+#define SBTOPCI_PREF 0x4 /* prefetch enable */ -+#define SBTOPCI_BURST 0x8 /* burst enable */ -+#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ -+#define SBTOPCI_RC_READ 0x00 /* memory read */ -+#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ -+#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ ++/* compatpci.c */ ++#define pci_module_init pci_register_driver ++extern int pci_register_driver(struct pci_driver *drv); ++extern void pci_unregister_driver(struct pci_driver *drv); + -+/* PCI core index in SROM shadow area */ -+#define SRSH_PI_OFFSET 0 /* first word */ -+#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ -+#define SRSH_PI_SHIFT 12 /* bit 15:12 */ ++#endif /* PCI registration */ + -+/* PCI side: Reserved PCI configuration registers (see pcicfg.h) */ -+#define cap_list rsvd_a[0] -+#define bar0_window dev_dep[0x80 - 0x40] -+#define bar1_window dev_dep[0x84 - 0x40] -+#define sprom_control dev_dep[0x88 - 0x40] ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18)) ++#ifdef MODULE ++#define module_init(x) int init_module(void) { return x(); } ++#define module_exit(x) void cleanup_module(void) { x(); } ++#else ++#define module_init(x) __initcall(x); ++#define module_exit(x) __exitcall(x); ++#endif ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 2, 18) */ + -+#ifndef _LANGUAGE_ASSEMBLY ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 48)) ++#define list_for_each(pos, head) \ ++ for (pos = (head)->next; pos != (head); pos = pos->next) ++#endif + -+extern int sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); -+extern int sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); -+extern void sbpci_ban(uint16 core); -+extern int sbpci_init(sb_t *sbh); -+extern void sbpci_check(sb_t *sbh); ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 13)) ++#define pci_resource_start(dev, bar) ((dev)->base_address[(bar)]) ++#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 44)) ++#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) ++#endif + -+#endif /* !_LANGUAGE_ASSEMBLY */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 23)) ++#define pci_enable_device(dev) do { } while (0) ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 14)) ++#define net_device device ++#endif ++ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 42)) + -+#endif /* _SBPCI_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbpcie.h linux.dev/arch/mips/bcm947xx/include/sbpcie.h ---- linux.old/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbpcie.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,199 @@ +/* -+ * BCM43XX SiliconBackplane PCIE core hardware definitions. ++ * DMA mapping + * -+ * $Id: -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * See linux/Documentation/DMA-mapping.txt + */ + -+#ifndef _SBPCIE_H -+#define _SBPCIE_H -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) ++#ifndef PCI_DMA_TODEVICE ++#define PCI_DMA_TODEVICE 1 ++#define PCI_DMA_FROMDEVICE 2 +#endif + -+/* PCIE Enumeration space offsets*/ -+#define PCIE_CORE_CONFIG_OFFSET 0x0 -+#define PCIE_FUNC0_CONFIG_OFFSET 0x400 -+#define PCIE_FUNC1_CONFIG_OFFSET 0x500 -+#define PCIE_FUNC2_CONFIG_OFFSET 0x600 -+#define PCIE_FUNC3_CONFIG_OFFSET 0x700 -+#define PCIE_SPROM_SHADOW_OFFSET 0x800 -+#define PCIE_SBCONFIG_OFFSET 0xE00 ++typedef u32 dma_addr_t; + -+/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */ -+#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0 -+#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000 -+#define PCIE_BAR0_PCIECORE_OFFSET 0x2000 -+#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000 ++/* Pure 2^n version of get_order */ ++static inline int get_order(unsigned long size) ++{ ++ int order; + -+/* SB side: PCIE core and host control registers */ -+typedef struct sbpcieregs { ++ size = (size-1) >> (PAGE_SHIFT-1); ++ order = -1; ++ do { ++ size >>= 1; ++ order++; ++ } while (size); ++ return order; ++} + -+ uint32 PAD[3]; -+ uint32 biststatus; /* bist Status: 0x00C*/ -+ uint32 PAD[6]; -+ uint32 sbtopcimailbox; /* sb to pcie mailbox: 0x028*/ -+ uint32 PAD[54]; -+ uint32 sbtopcie0; /* sb to pcie translation 0: 0x100 */ -+ uint32 sbtopcie1; /* sb to pcie translation 1: 0x104 */ -+ uint32 sbtopcie2; /* sb to pcie translation 2: 0x108 */ -+ uint32 PAD[4]; ++static inline void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, ++ dma_addr_t *dma_handle) ++{ ++ void *ret; ++ int gfp = GFP_ATOMIC | GFP_DMA; + -+ /* pcie core supports in direct access to config space */ -+ uint32 configaddr; /* pcie config space access: Address field: 0x120*/ -+ uint32 configdata; /* pcie config space access: Data field: 0x124*/ ++ ret = (void *)__get_free_pages(gfp, get_order(size)); + -+ /* mdio access to serdes */ -+ uint32 mdiocontrol; /* controls the mdio access: 0x128 */ -+ uint32 mdiodata; /* Data to the mdio access: 0x12c */ ++ if (ret != NULL) { ++ memset(ret, 0, size); ++ *dma_handle = virt_to_bus(ret); ++ } ++ return ret; ++} ++static inline void pci_free_consistent(struct pci_dev *hwdev, size_t size, ++ void *vaddr, dma_addr_t dma_handle) ++{ ++ free_pages((unsigned long)vaddr, get_order(size)); ++} ++#ifdef ILSIM ++extern uint pci_map_single(void *dev, void *va, uint size, int direction); ++extern void pci_unmap_single(void *dev, uint pa, uint size, int direction); ++#else ++#define pci_map_single(cookie, address, size, dir) virt_to_bus(address) ++#define pci_unmap_single(cookie, address, size, dir) ++#endif + -+ /* pcie protocol phy/dllp/tlp register access mechanism*/ -+ uint32 pcieaddr; /* address of the internal registeru: 0x130 */ -+ uint32 pciedata; /* Data to/from the internal regsiter: 0x134 */ ++#endif /* DMA mapping */ + -+ uint32 PAD[434]; -+ uint16 sprom[36]; /* SPROM shadow Area */ -+} sbpcieregs_t; ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 3, 43)) + -+/* SB to PCIE translation masks */ -+#define SBTOPCIE0_MASK 0xfc000000 -+#define SBTOPCIE1_MASK 0xfc000000 -+#define SBTOPCIE2_MASK 0xc0000000 ++#define dev_kfree_skb_any(a) dev_kfree_skb(a) ++#define netif_down(dev) do { (dev)->start = 0; } while (0) + -+/* Access type bits (0:1)*/ -+#define SBTOPCIE_MEM 0 -+#define SBTOPCIE_IO 1 -+#define SBTOPCIE_CFG0 2 -+#define SBTOPCIE_CFG1 3 ++/* pcmcia-cs provides its own netdevice compatibility layer */ ++#ifndef _COMPAT_NETDEVICE_H + -+/*Prefetch enable bit 2*/ -+#define SBTOPCIE_PF 4 ++/* ++ * SoftNet ++ * ++ * For pre-softnet kernels we need to tell the upper layer not to ++ * re-enter start_xmit() while we are in there. However softnet ++ * guarantees not to enter while we are in there so there is no need ++ * to do the netif_stop_queue() dance unless the transmit queue really ++ * gets stuck. This should also improve performance according to tests ++ * done by Aman Singla. ++ */ + -+/*Write Burst enable for memory write bit 3*/ -+#define SBTOPCIE_WR_BURST 8 ++#define dev_kfree_skb_irq(a) dev_kfree_skb(a) ++#define netif_wake_queue(dev) \ ++ do { clear_bit(0, &(dev)->tbusy); mark_bh(NET_BH); } while (0) ++#define netif_stop_queue(dev) set_bit(0, &(dev)->tbusy) + -+/* config access */ -+#define CONFIGADDR_FUNC_MASK 0x7000 -+#define CONFIGADDR_FUNC_SHF 12 -+#define CONFIGADDR_REG_MASK 0x0FFF -+#define CONFIGADDR_REG_SHF 0 ++static inline void netif_start_queue(struct net_device *dev) ++{ ++ dev->tbusy = 0; ++ dev->interrupt = 0; ++ dev->start = 1; ++} + -+/* PCIE protocol regs Indirect Address */ -+#define PCIEADDR_PROT_MASK 0x300 -+#define PCIEADDR_PROT_SHF 8 -+#define PCIEADDR_PL_TLP 0 -+#define PCIEADDR_PL_DLLP 1 -+#define PCIEADDR_PL_PLP 2 ++#define netif_queue_stopped(dev) (dev)->tbusy ++#define netif_running(dev) (dev)->start + -+/* PCIE protocol PHY diagnostic registers */ -+#define PCIE_PLP_MODEREG 0x200 /* Mode*/ -+#define PCIE_PLP_STATUSREG 0x204 /* Status*/ -+#define PCIE_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */ -+#define PCIE_PLP_LTLINKNUMREG 0x20c /* Link Training Link number*/ -+#define PCIE_PLP_LTLANENUMREG 0x210 /* Link Training Lane number*/ -+#define PCIE_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */ -+#define PCIE_PLP_ATTNREG 0x218 /* Attention */ -+#define PCIE_PLP_ATTNMASKREG 0x21C /* Attention Mask */ -+#define PCIE_PLP_RXERRCTR 0x220 /* Rx Error */ -+#define PCIE_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error*/ -+#define PCIE_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */ -+#define PCIE_PLP_TESTCTRLREG 0x22C /* Test Control reg*/ -+#define PCIE_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */ -+#define PCIE_PLP_TIMINGOVRDREG 0x234 /* Timing param override */ -+#define PCIE_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag*/ -+#define PCIE_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag*/ ++#endif /* _COMPAT_NETDEVICE_H */ + -+/* PCIE protocol DLLP diagnostic registers */ -+#define PCIE_DLLP_LCREG 0x100 /* Link Control*/ -+#define PCIE_DLLP_LSREG 0x104 /* Link Status */ -+#define PCIE_DLLP_LAREG 0x108 /* Link Attention*/ -+#define PCIE_DLLP_LAMASKREG 0x10C /* Link Attention Mask */ -+#define PCIE_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num*/ -+#define PCIE_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num*/ -+#define PCIE_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num*/ -+#define PCIE_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */ -+#define PCIE_DLLP_LRREG 0x120 /* Link Replay*/ -+#define PCIE_DLLP_LACKTOREG 0x124 /* Link Ack Timeout*/ -+#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold*/ -+#define PCIE_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr*/ -+#define PCIE_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr*/ -+#define PCIE_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr*/ -+#define PCIE_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write*/ -+#define PCIE_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */ -+#define PCIE_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */ -+#define PCIE_DLLP_ERRCTRREG 0x144 /* Error Counter*/ -+#define PCIE_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter*/ -+#define PCIE_DLLP_TESTREG 0x14C /* Test */ -+#define PCIE_DLLP_PKTBIST 0x150 /* Packet BIST*/ ++#define netif_device_attach(dev) netif_start_queue(dev) ++#define netif_device_detach(dev) netif_stop_queue(dev) + -+/* PCIE protocol TLP diagnostic registers */ -+#define PCIE_TLP_CONFIGREG 0x000 /* Configuration */ -+#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */ -+#define PCIE_TLP_WRDMAUPPER 0x010 /* Write DMA Upper Address*/ -+#define PCIE_TLP_WRDMALOWER 0x014 /* Write DMA Lower Address*/ -+#define PCIE_TLP_WRDMAREQ_LBEREG 0x018 /* Write DMA Len/ByteEn Req*/ -+#define PCIE_TLP_RDDMAUPPER 0x01C /* Read DMA Upper Address*/ -+#define PCIE_TLP_RDDMALOWER 0x020 /* Read DMA Lower Address*/ -+#define PCIE_TLP_RDDMALENREG 0x024 /* Read DMA Len Req*/ -+#define PCIE_TLP_MSIDMAUPPER 0x028 /* MSI DMA Upper Address*/ -+#define PCIE_TLP_MSIDMALOWER 0x02C /* MSI DMA Lower Address*/ -+#define PCIE_TLP_MSIDMALENREG 0x030 /* MSI DMA Len Req*/ -+#define PCIE_TLP_SLVREQLENREG 0x034 /* Slave Request Len*/ -+#define PCIE_TLP_FCINPUTSREQ 0x038 /* Flow Control Inputs*/ -+#define PCIE_TLP_TXSMGRSREQ 0x03C /* Tx StateMachine and Gated Req*/ -+#define PCIE_TLP_ADRACKCNTARBLEN 0x040 /* Address Ack XferCnt and ARB Len*/ -+#define PCIE_TLP_DMACPLHDR0 0x044 /* DMA Completion Hdr 0*/ -+#define PCIE_TLP_DMACPLHDR1 0x048 /* DMA Completion Hdr 1*/ -+#define PCIE_TLP_DMACPLHDR2 0x04C /* DMA Completion Hdr 2*/ -+#define PCIE_TLP_DMACPLMISC0 0x050 /* DMA Completion Misc0 */ -+#define PCIE_TLP_DMACPLMISC1 0x054 /* DMA Completion Misc1 */ -+#define PCIE_TLP_DMACPLMISC2 0x058 /* DMA Completion Misc2 */ -+#define PCIE_TLP_SPTCTRLLEN 0x05C /* Split Controller Req len*/ -+#define PCIE_TLP_SPTCTRLMSIC0 0x060 /* Split Controller Misc 0*/ -+#define PCIE_TLP_SPTCTRLMSIC1 0x064 /* Split Controller Misc 1*/ -+#define PCIE_TLP_BUSDEVFUNC 0x068 /* Bus/Device/Func*/ -+#define PCIE_TLP_RESETCTR 0x06C /* Reset Counter*/ -+#define PCIE_TLP_RTRYBUF 0x070 /* Retry Buffer value*/ -+#define PCIE_TLP_TGTDEBUG1 0x074 /* Target Debug Reg1*/ -+#define PCIE_TLP_TGTDEBUG2 0x078 /* Target Debug Reg2*/ -+#define PCIE_TLP_TGTDEBUG3 0x07C /* Target Debug Reg3*/ -+#define PCIE_TLP_TGTDEBUG4 0x080 /* Target Debug Reg4*/ -+ -+/* MDIO control */ -+#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ -+#define MDIOCTL_DIVISOR_VAL 0x2 -+#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */ -+#define MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */ ++/* 2.4.x renamed bottom halves to tasklets */ ++#define tasklet_struct tq_struct ++static inline void tasklet_schedule(struct tasklet_struct *tasklet) ++{ ++ queue_task(tasklet, &tq_immediate); ++ mark_bh(IMMEDIATE_BH); ++} + -+/* MDIO Data */ -+#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */ -+#define MDIODATA_TA 0x00020000 /* Turnaround */ -+#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */ -+#define MDIODATA_REGADDR_MASK 0x003c0000 /* Regaddr Mask */ -+#define MDIODATA_DEVADDR_SHF 22 /* Physmedia devaddr shift */ -+#define MDIODATA_DEVADDR_MASK 0x0fc00000 /* Physmedia devaddr Mask */ -+#define MDIODATA_WRITE 0x10000000 /* write Transaction */ -+#define MDIODATA_READ 0x20000000 /* Read Transaction */ -+#define MDIODATA_START 0x40000000 /* start of Transaction */ ++static inline void tasklet_init(struct tasklet_struct *tasklet, ++ void (*func)(unsigned long), ++ unsigned long data) ++{ ++ tasklet->next = NULL; ++ tasklet->sync = 0; ++ tasklet->routine = (void (*)(void *))func; ++ tasklet->data = (void *)data; ++} ++#define tasklet_kill(tasklet) { do{} while (0); } + -+/* MDIO devices (SERDES modules) */ -+#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */ -+#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */ -+#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */ ++/* 2.4.x introduced del_timer_sync() */ ++#define del_timer_sync(timer) del_timer(timer) + -+/* SERDES registers */ -+#define SERDES_RX_TIMER1 2 /* Rx Timer1 */ -+#define SERDES_RX_CDR 6 /* CDR */ -+#define SERDES_RX_CDRBW 7 /* CDR BW */ ++#else + -+#endif /* _SBPCIE_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbpcmcia.h linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h ---- linux.old/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,146 @@ -+/* -+ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. -+ * -+ * $Id$ -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ */ ++#define netif_down(dev) + -+#ifndef _SBPCMCIA_H -+#define _SBPCMCIA_H ++#endif /* SoftNet */ + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3)) + -+/* All the addresses that are offsets in attribute space are divided -+ * by two to account for the fact that odd bytes are invalid in -+ * attribute space and our read/write routines make the space appear -+ * as if they didn't exist. Still we want to show the original numbers -+ * as documented in the hnd_pcmcia core manual. ++/* ++ * Emit code to initialise a tq_struct's routine and data pointers + */ ++#define PREPARE_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ (_tq)->routine = _routine; \ ++ (_tq)->data = _data; \ ++ } while (0) + -+/* PCMCIA Function Configuration Registers */ -+#define PCMCIA_FCR (0x700 / 2) -+ -+#define FCR0_OFF 0 -+#define FCR1_OFF (0x40 / 2) -+#define FCR2_OFF (0x80 / 2) -+#define FCR3_OFF (0xc0 / 2) -+ -+#define PCMCIA_FCR0 (0x700 / 2) -+#define PCMCIA_FCR1 (0x740 / 2) -+#define PCMCIA_FCR2 (0x780 / 2) -+#define PCMCIA_FCR3 (0x7c0 / 2) -+ -+/* Standard PCMCIA FCR registers */ -+ -+#define PCMCIA_COR 0 ++/* ++ * Emit code to initialise all of a tq_struct ++ */ ++#define INIT_TQUEUE(_tq, _routine, _data) \ ++ do { \ ++ INIT_LIST_HEAD(&(_tq)->list); \ ++ (_tq)->sync = 0; \ ++ PREPARE_TQUEUE((_tq), (_routine), (_data)); \ ++ } while (0) + -+#define COR_RST 0x80 -+#define COR_LEV 0x40 -+#define COR_IRQEN 0x04 -+#define COR_BLREN 0x01 -+#define COR_FUNEN 0x01 ++#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 3) */ + ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 6)) + -+#define PCICIA_FCSR (2 / 2) -+#define PCICIA_PRR (4 / 2) -+#define PCICIA_SCR (6 / 2) -+#define PCICIA_ESR (8 / 2) ++/* Power management related routines */ + ++static inline int ++pci_save_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_read_config_dword(dev, i * 4, &buffer[i]); ++ } ++ return 0; ++} + -+#define PCM_MEMOFF 0x0000 -+#define F0_MEMOFF 0x1000 -+#define F1_MEMOFF 0x2000 -+#define F2_MEMOFF 0x3000 -+#define F3_MEMOFF 0x4000 ++static inline int ++pci_restore_state(struct pci_dev *dev, u32 *buffer) ++{ ++ int i; + -+/* Memory base in the function fcr's */ -+#define MEM_ADDR0 (0x728 / 2) -+#define MEM_ADDR1 (0x72a / 2) -+#define MEM_ADDR2 (0x72c / 2) ++ if (buffer) { ++ for (i = 0; i < 16; i++) ++ pci_write_config_dword(dev, i * 4, buffer[i]); ++ } ++ /* ++ * otherwise, write the context information we know from bootup. ++ * This works around a problem where warm-booting from Windows ++ * combined with a D3(hot)->D0 transition causes PCI config ++ * header data to be forgotten. ++ */ ++ else { ++ for (i = 0; i < 6; i ++) ++ pci_write_config_dword(dev, ++ PCI_BASE_ADDRESS_0 + (i * 4), ++ pci_resource_start(dev, i)); ++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); ++ } ++ return 0; ++} + -+/* PCMCIA base plus Srom access in fcr0: */ -+#define PCMCIA_ADDR0 (0x072e / 2) -+#define PCMCIA_ADDR1 (0x0730 / 2) -+#define PCMCIA_ADDR2 (0x0732 / 2) ++#endif /* PCI power management */ + -+#define MEM_SEG (0x0734 / 2) -+#define SROM_CS (0x0736 / 2) -+#define SROM_DATAL (0x0738 / 2) -+#define SROM_DATAH (0x073a / 2) -+#define SROM_ADDRL (0x073c / 2) -+#define SROM_ADDRH (0x073e / 2) ++/* Old cp0 access macros deprecated in 2.4.19 */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 19)) ++#define read_c0_count() read_32bit_cp0_register(CP0_COUNT) ++#endif + -+/* Values for srom_cs: */ -+#define SROM_IDLE 0 -+#define SROM_WRITE 1 -+#define SROM_READ 2 -+#define SROM_WEN 4 -+#define SROM_WDS 7 -+#define SROM_DONE 8 ++/* Module refcount handled internally in 2.6.x */ ++#ifndef SET_MODULE_OWNER ++#define SET_MODULE_OWNER(dev) do {} while (0) ++#define OLD_MOD_INC_USE_COUNT MOD_INC_USE_COUNT ++#define OLD_MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT ++#else ++#define OLD_MOD_INC_USE_COUNT do {} while (0) ++#define OLD_MOD_DEC_USE_COUNT do {} while (0) ++#endif + -+/* CIS stuff */ ++#ifndef SET_NETDEV_DEV ++#define SET_NETDEV_DEV(net, pdev) do {} while (0) ++#endif + -+/* The CIS stops where the FCRs start */ -+#define CIS_SIZE PCMCIA_FCR ++#ifndef HAVE_FREE_NETDEV ++#define free_netdev(dev) kfree(dev) ++#endif + -+/* Standard tuples we know about */ ++#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)) ++/* struct packet_type redefined in 2.6.x */ ++#define af_packet_priv data ++#endif + -+#define CISTPL_MANFID 0x20 /* Manufacturer and device id */ -+#define CISTPL_FUNCE 0x22 /* Function extensions */ -+#define CISTPL_CFTABLE 0x1b /* Config table entry */ ++#endif /* _linuxver_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm947xx/include/mipsinc.h +--- linux.old/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/mipsinc.h 2006-04-27 22:12:20.000000000 +0200 +@@ -0,0 +1,541 @@ ++/* ++ * HND Run Time Environment for standalone MIPS programs. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: mipsinc.h,v 1.1.1.5 2006/02/27 03:43:16 honor Exp $ ++ */ + -+/* Function extensions for LANs */ ++#ifndef _MISPINC_H ++#define _MISPINC_H + -+#define LAN_TECH 1 /* Technology type */ -+#define LAN_SPEED 2 /* Raw bit rate */ -+#define LAN_MEDIA 3 /* Transmission media */ -+#define LAN_NID 4 /* Node identification (aka MAC addr) */ -+#define LAN_CONN 5 /* Connector standard */ + ++/* MIPS defines */ + -+/* CFTable */ -+#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */ -+#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */ -+#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */ ++#ifdef _LANGUAGE_ASSEMBLY + -+/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll -+ * take one for HNBU, and use "extensions" (a la FUNCE) within it. ++/* ++ * Symbolic register names for 32 bit ABI + */ ++#define zero $0 /* wired zero */ ++#define AT $1 /* assembler temp - uppercase because of ".set at" */ ++#define v0 $2 /* return value */ ++#define v1 $3 ++#define a0 $4 /* argument registers */ ++#define a1 $5 ++#define a2 $6 ++#define a3 $7 ++#define t0 $8 /* caller saved */ ++#define t1 $9 ++#define t2 $10 ++#define t3 $11 ++#define t4 $12 ++#define t5 $13 ++#define t6 $14 ++#define t7 $15 ++#define s0 $16 /* callee saved */ ++#define s1 $17 ++#define s2 $18 ++#define s3 $19 ++#define s4 $20 ++#define s5 $21 ++#define s6 $22 ++#define s7 $23 ++#define t8 $24 /* caller saved */ ++#define t9 $25 ++#define jp $25 /* PIC jump register */ ++#define k0 $26 /* kernel scratch */ ++#define k1 $27 ++#define gp $28 /* global pointer */ ++#define sp $29 /* stack pointer */ ++#define fp $30 /* frame pointer */ ++#define s8 $30 /* same like fp! */ ++#define ra $31 /* return address */ + -+#define CISTPL_BRCM_HNBU 0x80 + -+/* Subtypes of BRCM_HNBU: */ ++/* CP0 Registers */ + -+#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */ -+#define HNBU_CHIPID 0x01 /* Six bytes with PCI vendor & -+ * device id and chiprev -+ */ -+#define HNBU_BOARDREV 0x02 /* Two bytes board revision */ -+#define HNBU_PAPARMS 0x03 /* PA parameters: 1 (old), 8 (sreomrev == 1) -+ * or 9 (sromrev > 1) bytes */ -+#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */ -+#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */ -+#define HNBU_AA 0x06 /* Antennas available */ -+#define HNBU_AG 0x07 /* Antenna gain */ -+#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */ -+#define HNBU_LEDS 0x09 /* LED set */ -+#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl) -+ * in rev 2 -+ */ -+#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */ -+#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */ -+ -+ -+/* sbtmstatelow */ -+#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */ -+#define SBTML_INT_EN 0x20000 /* enable sb interrupt */ -+ -+/* sbtmstatehigh */ -+#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */ ++#define C0_INX $0 ++#define C0_RAND $1 ++#define C0_TLBLO0 $2 ++#define C0_TLBLO C0_TLBLO0 ++#define C0_TLBLO1 $3 ++#define C0_CTEXT $4 ++#define C0_PGMASK $5 ++#define C0_WIRED $6 ++#define C0_BADVADDR $8 ++#define C0_COUNT $9 ++#define C0_TLBHI $10 ++#define C0_COMPARE $11 ++#define C0_SR $12 ++#define C0_STATUS C0_SR ++#define C0_CAUSE $13 ++#define C0_EPC $14 ++#define C0_PRID $15 ++#define C0_CONFIG $16 ++#define C0_LLADDR $17 ++#define C0_WATCHLO $18 ++#define C0_WATCHHI $19 ++#define C0_XCTEXT $20 ++#define C0_DIAGNOSTIC $22 ++#define C0_BROADCOM C0_DIAGNOSTIC ++#define C0_PERFORMANCE $25 ++#define C0_ECC $26 ++#define C0_CACHEERR $27 ++#define C0_TAGLO $28 ++#define C0_TAGHI $29 ++#define C0_ERREPC $30 ++#define C0_DESAVE $31 + -+#endif /* _SBPCMCIA_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbsdram.h linux.dev/arch/mips/bcm947xx/include/sbsdram.h ---- linux.old/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbsdram.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,75 @@ +/* -+ * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ ++ * LEAF - declare leaf routine + */ ++#define LEAF(symbol) \ ++ .globl symbol; \ ++ .align 2; \ ++ .type symbol, @function; \ ++ .ent symbol, 0; \ ++symbol: .frame sp, 0, ra + -+#ifndef _SBSDRAM_H -+#define _SBSDRAM_H -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+/* Sonics side: SDRAM core registers */ -+typedef volatile struct sbsdramregs { -+ uint32 initcontrol; /* Generates external SDRAM initialization sequence */ -+ uint32 config; /* Initializes external SDRAM mode register */ -+ uint32 refresh; /* Controls external SDRAM refresh rate */ -+ uint32 pad1; -+ uint32 pad2; -+} sbsdramregs_t; -+ -+#endif ++/* ++ * END - mark end of function ++ */ ++#define END(function) \ ++ .end function; \ ++ .size function, . - function + -+/* SDRAM initialization control (initcontrol) register bits */ -+#define SDRAM_CBR 0x0001 /* Writing 1 generates refresh cycle and toggles bit */ -+#define SDRAM_PRE 0x0002 /* Writing 1 generates precharge cycle and toggles bit */ -+#define SDRAM_MRS 0x0004 /* Writing 1 generates mode register select cycle and toggles bit */ -+#define SDRAM_EN 0x0008 /* When set, enables access to SDRAM */ -+#define SDRAM_16Mb 0x0000 /* Use 16 Megabit SDRAM */ -+#define SDRAM_64Mb 0x0010 /* Use 64 Megabit SDRAM */ -+#define SDRAM_128Mb 0x0020 /* Use 128 Megabit SDRAM */ -+#define SDRAM_RSVMb 0x0030 /* Use special SDRAM */ -+#define SDRAM_RST 0x0080 /* Writing 1 causes soft reset of controller */ -+#define SDRAM_SELFREF 0x0100 /* Writing 1 enables self refresh mode */ -+#define SDRAM_PWRDOWN 0x0200 /* Writing 1 causes controller to power down */ -+#define SDRAM_32BIT 0x0400 /* When set, indicates 32 bit SDRAM interface */ -+#define SDRAM_9BITCOL 0x0800 /* When set, indicates 9 bit column */ ++#define _ULCAST_ + -+/* SDRAM configuration (config) register bits */ -+#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */ -+#define SDRAM_BURST8 0x0001 /* Use burst of 8 */ -+#define SDRAM_BURST4 0x0002 /* Use burst of 4 */ -+#define SDRAM_BURST2 0x0003 /* Use burst of 2 */ -+#define SDRAM_CAS3 0x0000 /* Use CAS latency of 3 */ -+#define SDRAM_CAS2 0x0004 /* Use CAS latency of 2 */ ++#define MFC0_SEL(dst, src, sel) \ ++ .word\t(0x40000000 | ((dst) << 16) | ((src) << 11) | (sel)) + -+/* SDRAM refresh control (refresh) register bits */ -+#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */ -+#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */ + -+/* SDRAM Core default Init values (OCP ID 0x803) */ -+#define SDRAM_INIT MEM4MX16X2 -+#define SDRAM_CONFIG SDRAM_BURSTFULL -+#define SDRAM_REFRESH SDRAM_REF(0x40) ++#define MTC0_SEL(dst, src, sel) \ ++ .word\t(0x40800000 | ((dst) << 16) | ((src) << 11) | (sel)) + -+#define MEM1MX16 0x009 /* 2 MB */ -+#define MEM1MX16X2 0x409 /* 4 MB */ -+#define MEM2MX8X2 0x809 /* 4 MB */ -+#define MEM2MX8X4 0xc09 /* 8 MB */ -+#define MEM2MX32 0x439 /* 8 MB */ -+#define MEM4MX16 0x019 /* 8 MB */ -+#define MEM4MX16X2 0x419 /* 16 MB */ -+#define MEM8MX8X2 0x819 /* 16 MB */ -+#define MEM8MX16 0x829 /* 16 MB */ -+#define MEM4MX32 0x429 /* 16 MB */ -+#define MEM8MX8X4 0xc19 /* 32 MB */ -+#define MEM8MX16X2 0xc29 /* 32 MB */ ++#else + -+#endif /* _SBSDRAM_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbsocram.h linux.dev/arch/mips/bcm947xx/include/sbsocram.h ---- linux.old/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbsocram.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,37 @@ +/* -+ * BCM47XX Sonics SiliconBackplane embedded ram core -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ ++ * The following macros are especially useful for __asm__ ++ * inline assembler. + */ ++#ifndef __STR ++#define __STR(x) #x ++#endif ++#ifndef STR ++#define STR(x) __STR(x) ++#endif + -+#ifndef _SBSOCRAM_H -+#define _SBSOCRAM_H -+ -+#define SOCRAM_MEMSIZE 0x00 -+#define SOCRAM_BISTSTAT 0x0c ++#define _ULCAST_ (unsigned long) + + -+#ifndef _LANGUAGE_ASSEMBLY ++/* CP0 Registers */ + -+/* Memcsocram core registers */ -+typedef volatile struct sbsocramregs { -+ uint32 memsize; -+ uint32 biststat; -+} sbsocramregs_t; ++#define C0_INX 0 /* CP0: TLB Index */ ++#define C0_RAND 1 /* CP0: TLB Random */ ++#define C0_TLBLO0 2 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO C0_TLBLO0 /* CP0: TLB EntryLo0 */ ++#define C0_TLBLO1 3 /* CP0: TLB EntryLo1 */ ++#define C0_CTEXT 4 /* CP0: Context */ ++#define C0_PGMASK 5 /* CP0: TLB PageMask */ ++#define C0_WIRED 6 /* CP0: TLB Wired */ ++#define C0_BADVADDR 8 /* CP0: Bad Virtual Address */ ++#define C0_COUNT 9 /* CP0: Count */ ++#define C0_TLBHI 10 /* CP0: TLB EntryHi */ ++#define C0_COMPARE 11 /* CP0: Compare */ ++#define C0_SR 12 /* CP0: Processor Status */ ++#define C0_STATUS C0_SR /* CP0: Processor Status */ ++#define C0_CAUSE 13 /* CP0: Exception Cause */ ++#define C0_EPC 14 /* CP0: Exception PC */ ++#define C0_PRID 15 /* CP0: Processor Revision Indentifier */ ++#define C0_CONFIG 16 /* CP0: Config */ ++#define C0_LLADDR 17 /* CP0: LLAddr */ ++#define C0_WATCHLO 18 /* CP0: WatchpointLo */ ++#define C0_WATCHHI 19 /* CP0: WatchpointHi */ ++#define C0_XCTEXT 20 /* CP0: XContext */ ++#define C0_DIAGNOSTIC 22 /* CP0: Diagnostic */ ++#define C0_BROADCOM C0_DIAGNOSTIC /* CP0: Broadcom Register */ ++#define C0_PERFORMANCE 25 /* CP0: Performance Counter/Control Registers */ ++#define C0_ECC 26 /* CP0: ECC */ ++#define C0_CACHEERR 27 /* CP0: CacheErr */ ++#define C0_TAGLO 28 /* CP0: TagLo */ ++#define C0_TAGHI 29 /* CP0: TagHi */ ++#define C0_ERREPC 30 /* CP0: ErrorEPC */ ++#define C0_DESAVE 31 /* CP0: DebugSave */ + -+#endif ++#endif /* _LANGUAGE_ASSEMBLY */ + -+/* Them memory size is 2 to the power of the following -+ * base added to the contents of the memsize register. ++/* ++ * Memory segments (32bit kernel mode addresses) + */ -+#define SOCRAM_MEMSIZE_BASESHIFT 16 ++#undef KUSEG ++#undef KSEG0 ++#undef KSEG1 ++#undef KSEG2 ++#undef KSEG3 ++#define KUSEG 0x00000000 ++#define KSEG0 0x80000000 ++#define KSEG1 0xa0000000 ++#define KSEG2 0xc0000000 ++#define KSEG3 0xe0000000 ++#define PHYSADDR_MASK 0x1fffffff + -+#endif /* _SBSOCRAM_H */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm947xx/include/sbutils.h ---- linux.old/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbutils.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,140 @@ +/* -+ * Misc utility routines for accessing chip-specific features -+ * of Broadcom HNBU SiliconBackplane-based chips. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ ++ * Map an address to a certain kernel segment + */ ++#undef PHYSADDR ++#undef KSEG0ADDR ++#undef KSEG1ADDR ++#undef KSEG2ADDR ++#undef KSEG3ADDR + -+#ifndef _sbutils_h_ -+#define _sbutils_h_ -+ -+/* -+ * Datastructure to export all chip specific common variables -+ * public (read-only) portion of sbutils handle returned by -+ * sb_attach()/sb_kattach() -+*/ -+ -+struct sb_pub { -+ -+ uint bustype; /* SB_BUS, PCI_BUS */ -+ uint buscoretype; /* SB_PCI, SB_PCMCIA, SB_PCIE*/ -+ uint buscorerev; /* buscore rev */ -+ uint buscoreidx; /* buscore index */ -+ int ccrev; /* chip common core rev */ -+ uint boardtype; /* board type */ -+ uint boardvendor; /* board vendor */ -+ uint chip; /* chip number */ -+ uint chiprev; /* chip revision */ -+ uint chippkg; /* chip package option */ -+ uint sonicsrev; /* sonics backplane rev */ -+}; ++#define PHYSADDR(a) (_ULCAST_(a) & PHYSADDR_MASK) ++#define KSEG0ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG0) ++#define KSEG1ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG1) ++#define KSEG2ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG2) ++#define KSEG3ADDR(a) ((_ULCAST_(a) & PHYSADDR_MASK) | KSEG3) + -+typedef const struct sb_pub sb_t; + ++#ifndef Index_Invalidate_I +/* -+ * Many of the routines below take an 'sbh' handle as their first arg. -+ * Allocate this by calling sb_attach(). Free it by calling sb_detach(). -+ * At any one time, the sbh is logically focused on one particular sb core -+ * (the "current core"). -+ * Use sb_setcore() or sb_setcoreidx() to change the association to another core. ++ * Cache Operations + */ -+ -+/* exported externs */ -+extern sb_t * BCMINIT(sb_attach)(uint pcidev, osl_t *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz); -+extern sb_t * BCMINIT(sb_kattach)(void); -+extern void sb_detach(sb_t *sbh); -+extern uint BCMINIT(sb_chip)(sb_t *sbh); -+extern uint BCMINIT(sb_chiprev)(sb_t *sbh); -+extern uint BCMINIT(sb_chipcrev)(sb_t *sbh); -+extern uint BCMINIT(sb_chippkg)(sb_t *sbh); -+extern uint BCMINIT(sb_pcirev)(sb_t *sbh); -+extern bool BCMINIT(sb_war16165)(sb_t *sbh); -+extern uint BCMINIT(sb_pcmciarev)(sb_t *sbh); -+extern uint BCMINIT(sb_boardvendor)(sb_t *sbh); -+extern uint BCMINIT(sb_boardtype)(sb_t *sbh); -+extern uint sb_bus(sb_t *sbh); -+extern uint sb_buscoretype(sb_t *sbh); -+extern uint sb_buscorerev(sb_t *sbh); -+extern uint sb_corelist(sb_t *sbh, uint coreid[]); -+extern uint sb_coreid(sb_t *sbh); -+extern uint sb_coreidx(sb_t *sbh); -+extern uint sb_coreunit(sb_t *sbh); -+extern uint sb_corevendor(sb_t *sbh); -+extern uint sb_corerev(sb_t *sbh); -+extern void *sb_osh(sb_t *sbh); -+extern void *sb_coreregs(sb_t *sbh); -+extern uint32 sb_coreflags(sb_t *sbh, uint32 mask, uint32 val); -+extern uint32 sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val); -+extern bool sb_iscoreup(sb_t *sbh); -+extern void *sb_setcoreidx(sb_t *sbh, uint coreidx); -+extern void *sb_setcore(sb_t *sbh, uint coreid, uint coreunit); -+extern int sb_corebist(sb_t *sbh, uint coreid, uint coreunit); -+extern void sb_commit(sb_t *sbh); -+extern uint32 sb_base(uint32 admatch); -+extern uint32 sb_size(uint32 admatch); -+extern void sb_core_reset(sb_t *sbh, uint32 bits); -+extern void sb_core_tofixup(sb_t *sbh); -+extern void sb_core_disable(sb_t *sbh, uint32 bits); -+extern uint32 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m); -+extern uint32 sb_clock(sb_t *sbh); -+extern void sb_pci_setup(sb_t *sbh, uint coremask); -+extern void sb_pcmcia_init(sb_t *sbh); -+extern void sb_watchdog(sb_t *sbh, uint ticks); -+extern void *sb_gpiosetcore(sb_t *sbh); -+extern uint32 sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); -+extern uint32 sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); -+extern uint32 sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); -+extern uint32 sb_gpioin(sb_t *sbh); -+extern uint32 sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); -+extern uint32 sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); -+extern uint32 sb_gpioled(sb_t *sbh, uint32 mask, uint32 val); -+extern uint32 sb_gpioreserve(sb_t *sbh, uint32 gpio_num, uint8 priority); -+extern uint32 sb_gpiorelease(sb_t *sbh, uint32 gpio_num, uint8 priority); -+ -+extern void sb_clkctl_init(sb_t *sbh); -+extern uint16 sb_clkctl_fast_pwrup_delay(sb_t *sbh); -+extern bool sb_clkctl_clk(sb_t *sbh, uint mode); -+extern int sb_clkctl_xtal(sb_t *sbh, uint what, bool on); -+extern void sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, -+ void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg); -+extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to); -+extern void sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, -+ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif); -+extern uint sb_pcie_readreg(void *sbh, void* arg1, uint offset); -+extern uint sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val); -+extern uint32 sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 val); -+ ++#define Index_Invalidate_I 0x00 ++#define Index_Writeback_Inv_D 0x01 ++#define Index_Invalidate_SI 0x02 ++#define Index_Writeback_Inv_SD 0x03 ++#define Index_Load_Tag_I 0x04 ++#define Index_Load_Tag_D 0x05 ++#define Index_Load_Tag_SI 0x06 ++#define Index_Load_Tag_SD 0x07 ++#define Index_Store_Tag_I 0x08 ++#define Index_Store_Tag_D 0x09 ++#define Index_Store_Tag_SI 0x0A ++#define Index_Store_Tag_SD 0x0B ++#define Create_Dirty_Excl_D 0x0d ++#define Create_Dirty_Excl_SD 0x0f ++#define Hit_Invalidate_I 0x10 ++#define Hit_Invalidate_D 0x11 ++#define Hit_Invalidate_SI 0x12 ++#define Hit_Invalidate_SD 0x13 ++#define Fill_I 0x14 ++#define Hit_Writeback_Inv_D 0x15 ++ /* 0x16 is unused */ ++#define Hit_Writeback_Inv_SD 0x17 ++#define R5K_Page_Invalidate_S 0x17 ++#define Hit_Writeback_I 0x18 ++#define Hit_Writeback_D 0x19 ++ /* 0x1a is unused */ ++#define Hit_Writeback_SD 0x1b ++ /* 0x1c is unused */ ++ /* 0x1e is unused */ ++#define Hit_Set_Virtual_SI 0x1e ++#define Hit_Set_Virtual_SD 0x1f ++#endif /* !Index_Invalidate_I */ + + +/* -+* Build device path. Path size must be >= SB_DEVPATH_BUFSZ. -+* The returned path is NULL terminated and has trailing '/'. -+* Return 0 on success, nonzero otherwise. -+*/ -+extern int sb_devpath(sb_t *sbh, char *path, int size); ++ * R4x00 interrupt enable / cause bits ++ */ ++#define IE_SW0 (_ULCAST_(1) << 8) ++#define IE_SW1 (_ULCAST_(1) << 9) ++#define IE_IRQ0 (_ULCAST_(1) << 10) ++#define IE_IRQ1 (_ULCAST_(1) << 11) ++#define IE_IRQ2 (_ULCAST_(1) << 12) ++#define IE_IRQ3 (_ULCAST_(1) << 13) ++#define IE_IRQ4 (_ULCAST_(1) << 14) ++#define IE_IRQ5 (_ULCAST_(1) << 15) + -+/* clkctl xtal what flags */ -+#define XTAL 0x1 /* primary crystal oscillator (2050) */ -+#define PLL 0x2 /* main chip pll */ ++#ifndef ST0_UM ++/* ++ * Bitfields in the mips32 cp0 status register ++ */ ++#define ST0_IE 0x00000001 ++#define ST0_EXL 0x00000002 ++#define ST0_ERL 0x00000004 ++#define ST0_UM 0x00000010 ++#define ST0_SWINT0 0x00000100 ++#define ST0_SWINT1 0x00000200 ++#define ST0_HWINT0 0x00000400 ++#define ST0_HWINT1 0x00000800 ++#define ST0_HWINT2 0x00001000 ++#define ST0_HWINT3 0x00002000 ++#define ST0_HWINT4 0x00004000 ++#define ST0_HWINT5 0x00008000 ++#define ST0_IM 0x0000ff00 ++#define ST0_NMI 0x00080000 ++#define ST0_SR 0x00100000 ++#define ST0_TS 0x00200000 ++#define ST0_BEV 0x00400000 ++#define ST0_RE 0x02000000 ++#define ST0_RP 0x08000000 ++#define ST0_CU 0xf0000000 ++#define ST0_CU0 0x10000000 ++#define ST0_CU1 0x20000000 ++#define ST0_CU2 0x40000000 ++#define ST0_CU3 0x80000000 ++#endif /* !ST0_UM */ + -+/* clkctl clk mode */ -+#define CLK_FAST 0 /* force fast (pll) clock */ -+#define CLK_DYNAMIC 2 /* enable dynamic clock control */ + ++/* ++ * Bitfields in the mips32 cp0 cause register ++ */ ++#define C_EXC 0x0000007c ++#define C_EXC_SHIFT 2 ++#define C_INT 0x0000ff00 ++#define C_INT_SHIFT 8 ++#define C_SW0 (_ULCAST_(1) << 8) ++#define C_SW1 (_ULCAST_(1) << 9) ++#define C_IRQ0 (_ULCAST_(1) << 10) ++#define C_IRQ1 (_ULCAST_(1) << 11) ++#define C_IRQ2 (_ULCAST_(1) << 12) ++#define C_IRQ3 (_ULCAST_(1) << 13) ++#define C_IRQ4 (_ULCAST_(1) << 14) ++#define C_IRQ5 (_ULCAST_(1) << 15) ++#define C_WP 0x00400000 ++#define C_IV 0x00800000 ++#define C_CE 0x30000000 ++#define C_CE_SHIFT 28 ++#define C_BD 0x80000000 + -+/* GPIO usage priorities */ -+#define GPIO_DRV_PRIORITY 0 -+#define GPIO_APP_PRIORITY 1 ++/* Values in C_EXC */ ++#define EXC_INT 0 ++#define EXC_TLBM 1 ++#define EXC_TLBL 2 ++#define EXC_TLBS 3 ++#define EXC_AEL 4 ++#define EXC_AES 5 ++#define EXC_IBE 6 ++#define EXC_DBE 7 ++#define EXC_SYS 8 ++#define EXC_BPT 9 ++#define EXC_RI 10 ++#define EXC_CU 11 ++#define EXC_OV 12 ++#define EXC_TR 13 ++#define EXC_WATCH 23 ++#define EXC_MCHK 24 + -+/* device path */ -+#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ + -+#endif /* _sbutils_h_ */ -diff -Naur linux.old/arch/mips/bcm947xx/include/sflash.h linux.dev/arch/mips/bcm947xx/include/sflash.h ---- linux.old/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sflash.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,36 @@ +/* -+ * Broadcom SiliconBackplane chipcommon serial flash interface -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ ++ * Bits in the cp0 config register. + */ ++#define CONF_CM_CACHABLE_NO_WA 0 ++#define CONF_CM_CACHABLE_WA 1 ++#define CONF_CM_UNCACHED 2 ++#define CONF_CM_CACHABLE_NONCOHERENT 3 ++#define CONF_CM_CACHABLE_CE 4 ++#define CONF_CM_CACHABLE_COW 5 ++#define CONF_CM_CACHABLE_CUW 6 ++#define CONF_CM_CACHABLE_ACCELERATED 7 ++#define CONF_CM_CMASK 7 ++#define CONF_CU (_ULCAST_(1) << 3) ++#define CONF_DB (_ULCAST_(1) << 4) ++#define CONF_IB (_ULCAST_(1) << 5) ++#define CONF_SE (_ULCAST_(1) << 12) ++#ifndef CONF_BE /* duplicate in mipsregs.h */ ++#define CONF_BE (_ULCAST_(1) << 15) ++#endif ++#define CONF_SC (_ULCAST_(1) << 17) ++#define CONF_AC (_ULCAST_(1) << 23) ++#define CONF_HALT (_ULCAST_(1) << 25) ++#ifndef CONF_M /* duplicate in mipsregs.h */ ++#define CONF_M (_ULCAST_(1) << 31) ++#endif + -+#ifndef _sflash_h_ -+#define _sflash_h_ + -+#include -+#include ++/* ++ * Bits in the cp0 config register select 1. ++ */ ++#define CONF1_FP 0x00000001 /* FPU present */ ++#define CONF1_EP 0x00000002 /* EJTAG present */ ++#define CONF1_CA 0x00000004 /* mips16 implemented */ ++#define CONF1_WR 0x00000008 /* Watch registers present */ ++#define CONF1_PC 0x00000010 /* Performance counters present */ ++#define CONF1_DA_SHIFT 7 /* D$ associativity */ ++#define CONF1_DA_MASK 0x00000380 ++#define CONF1_DA_BASE 1 ++#define CONF1_DL_SHIFT 10 /* D$ line size */ ++#define CONF1_DL_MASK 0x00001c00 ++#define CONF1_DL_BASE 2 ++#define CONF1_DS_SHIFT 13 /* D$ sets/way */ ++#define CONF1_DS_MASK 0x0000e000 ++#define CONF1_DS_BASE 64 ++#define CONF1_IA_SHIFT 16 /* I$ associativity */ ++#define CONF1_IA_MASK 0x00070000 ++#define CONF1_IA_BASE 1 ++#define CONF1_IL_SHIFT 19 /* I$ line size */ ++#define CONF1_IL_MASK 0x00380000 ++#define CONF1_IL_BASE 2 ++#define CONF1_IS_SHIFT 22 /* Instruction cache sets/way */ ++#define CONF1_IS_MASK 0x01c00000 ++#define CONF1_IS_BASE 64 ++#define CONF1_MS_MASK 0x7e000000 /* Number of tlb entries */ ++#define CONF1_MS_SHIFT 25 + -+struct sflash { -+ uint blocksize; /* Block size */ -+ uint numblocks; /* Number of blocks */ -+ uint32 type; /* Type */ -+ uint size; /* Total size in bytes */ -+}; ++/* PRID register */ ++#define PRID_COPT_MASK 0xff000000 ++#define PRID_COMP_MASK 0x00ff0000 ++#define PRID_IMP_MASK 0x0000ff00 ++#define PRID_REV_MASK 0x000000ff + -+/* Utility functions */ -+extern int sflash_poll(chipcregs_t *cc, uint offset); -+extern int sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf); -+extern int sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf); -+extern int sflash_erase(chipcregs_t *cc, uint offset); -+extern int sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf); -+extern struct sflash * sflash_init(chipcregs_t *cc); ++#define PRID_COMP_LEGACY 0x000000 ++#define PRID_COMP_MIPS 0x010000 ++#define PRID_COMP_BROADCOM 0x020000 ++#define PRID_COMP_ALCHEMY 0x030000 ++#define PRID_COMP_SIBYTE 0x040000 ++#define PRID_IMP_BCM4710 0x4000 ++#define PRID_IMP_BCM3302 0x9000 ++#define PRID_IMP_BCM3303 0x9100 + -+#endif /* _sflash_h_ */ -diff -Naur linux.old/arch/mips/bcm947xx/include/trxhdr.h linux.dev/arch/mips/bcm947xx/include/trxhdr.h ---- linux.old/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/trxhdr.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,33 @@ -+/* -+ * TRX image file header format. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++#define PRID_IMP_UNKNOWN 0xff00 + -+#include ++#define BCM330X(id) \ ++ (((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == \ ++ (PRID_COMP_BROADCOM | PRID_IMP_BCM3302)) || \ ++ ((id & (PRID_COMP_MASK | PRID_IMP_MASK)) == \ ++ (PRID_COMP_BROADCOM | PRID_IMP_BCM3303))) + -+#define TRX_MAGIC 0x30524448 /* "HDR0" */ -+#define TRX_VERSION 1 -+#define TRX_MAX_LEN 0x3A0000 -+#define TRX_NO_HEADER 1 /* Do not write TRX header */ -+#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ -+#define TRX_MAX_OFFSET 3 -+ -+struct trx_header { -+ uint32 magic; /* "HDR0" */ -+ uint32 len; /* Length of file including header */ -+ uint32 crc32; /* 32-bit CRC from flag_version to end of file */ -+ uint32 flag_version; /* 0:15 flags, 16:31 version */ -+ uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ -+}; -+ -+/* Compatibility */ -+typedef struct trx_header TRXHDR, *PTRXHDR; -diff -Naur linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bcm947xx/include/typedefs.h ---- linux.old/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/typedefs.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,326 @@ -+/* -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ -+ -+#ifndef _TYPEDEFS_H_ -+#define _TYPEDEFS_H_ -+ -+ -+/* Define 'SITE_TYPEDEFS' in the compile to include a site specific -+ * typedef file "site_typedefs.h". -+ * -+ * If 'SITE_TYPEDEFS' is not defined, then the "Inferred Typedefs" -+ * section of this file makes inferences about the compile environment -+ * based on defined symbols and possibly compiler pragmas. -+ * -+ * Following these two sections is the "Default Typedefs" -+ * section. This section is only prcessed if 'USE_TYPEDEF_DEFAULTS' is -+ * defined. This section has a default set of typedefs and a few -+ * proprocessor symbols (TRUE, FALSE, NULL, ...). -+ */ ++/* Bits in C0_BROADCOM */ ++#define BRCM_PFC_AVAIL 0x20000000 /* PFC is available */ ++#define BRCM_DC_ENABLE 0x40000000 /* Enable Data $ */ ++#define BRCM_IC_ENABLE 0x80000000 /* Enable Instruction $ */ ++#define BRCM_PFC_ENABLE 0x00400000 /* Obsolete? Enable PFC (at least on 4310) */ ++#define BRCM_CLF_ENABLE 0x00100000 /* Enable cache line first feature */ + -+#ifdef SITE_TYPEDEFS ++/* PreFetch Cache aka Read Ahead Cache */ + -+/******************************************************************************* -+ * Site Specific Typedefs -+ *******************************************************************************/ ++#define PFC_CR0 0xff400000 /* control reg 0 */ ++#define PFC_CR1 0xff400004 /* control reg 1 */ + -+#include "site_typedefs.h" ++/* PFC operations */ ++#define PFC_I 0x00000001 /* Enable PFC use for instructions */ ++#define PFC_D 0x00000002 /* Enable PFC use for data */ ++#define PFC_PFI 0x00000004 /* Enable seq. prefetch for instructions */ ++#define PFC_PFD 0x00000008 /* Enable seq. prefetch for data */ ++#define PFC_CINV 0x00000010 /* Enable selective (i/d) cacheop flushing */ ++#define PFC_NCH 0x00000020 /* Disable flushing based on cacheops */ ++#define PFC_DPF 0x00000040 /* Enable directional prefetching */ ++#define PFC_FLUSH 0x00000100 /* Flush the PFC */ ++#define PFC_BRR 0x40000000 /* Bus error indication */ ++#define PFC_PWR 0x80000000 /* Disable power saving (clock gating) */ + -+#else ++/* Handy defaults */ ++#define PFC_DISABLED 0 ++#define PFC_AUTO 0xffffffff /* auto select the default mode */ ++#define PFC_INST (PFC_I | PFC_PFI | PFC_CINV) ++#define PFC_INST_NOPF (PFC_I | PFC_CINV) ++#define PFC_DATA (PFC_D | PFC_PFD | PFC_CINV) ++#define PFC_DATA_NOPF (PFC_D | PFC_CINV) ++#define PFC_I_AND_D (PFC_INST | PFC_DATA) ++#define PFC_I_AND_D_NOPF (PFC_INST_NOPF | PFC_DATA_NOPF) + -+/******************************************************************************* -+ * Inferred Typedefs -+ *******************************************************************************/ ++#ifndef _LANGUAGE_ASSEMBLY + -+/* Infer the compile environment based on preprocessor symbols and pramas. -+ * Override type definitions as needed, and include configuration dependent -+ * header files to define types. ++/* ++ * Macros to access the system control coprocessor + */ + -+#ifdef __cplusplus ++#define MFC0(source, sel) \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__(" \ ++ .set\tnoreorder; \ ++ .set\tnoat; \ ++ .word\t"STR(0x40010000 | ((source) << 11) | (sel))"; \ ++ move\t%0, $1; \ ++ .set\tat; \ ++ .set\treorder" \ ++ :"=r" (__res) \ ++ : \ ++ :"$1"); \ ++ __res; \ ++}) + -+#define TYPEDEF_BOOL -+#ifndef FALSE -+#define FALSE false -+#endif -+#ifndef TRUE -+#define TRUE true -+#endif ++#define MTC0(source, sel, value) \ ++do { \ ++ __asm__ __volatile__(" \ ++ .set\tnoreorder; \ ++ .set\tnoat; \ ++ move\t$1, %z0; \ ++ .word\t"STR(0x40810000 | ((source) << 11) | (sel))"; \ ++ .set\tat; \ ++ .set\treorder" \ ++ : \ ++ :"jr" (value) \ ++ :"$1"); \ ++} while (0) + -+#else /* ! __cplusplus */ ++#define get_c0_count() \ ++({ \ ++ int __res; \ ++ __asm__ __volatile__(" \ ++ .set\tnoreorder; \ ++ .set\tnoat; \ ++ mfc0\t%0, $9; \ ++ .set\tat; \ ++ .set\treorder" \ ++ :"=r" (__res)); \ ++ __res; \ ++}) + -+#if defined(_WIN32) ++static INLINE void icache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; + -+#define TYPEDEF_BOOL -+typedef unsigned char bool; /* consistent w/BOOL */ ++ /* Instruction Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_IL_MASK) >> CONF1_IL_SHIFT))) ++ lsz = CONF1_IL_BASE << lsz; ++ sets = CONF1_IS_BASE << ((config1 & CONF1_IS_MASK) >> CONF1_IS_SHIFT); ++ ways = CONF1_IA_BASE + ((config1 & CONF1_IA_MASK) >> CONF1_IA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} + -+#endif /* _WIN32 */ ++static INLINE void dcache_probe(uint32 config1, uint *size, uint *lsize) ++{ ++ uint lsz, sets, ways; + -+#endif /* ! __cplusplus */ ++ /* Data Cache Size = Associativity * Line Size * Sets Per Way */ ++ if ((lsz = ((config1 & CONF1_DL_MASK) >> CONF1_DL_SHIFT))) ++ lsz = CONF1_DL_BASE << lsz; ++ sets = CONF1_DS_BASE << ((config1 & CONF1_DS_MASK) >> CONF1_DS_SHIFT); ++ ways = CONF1_DA_BASE + ((config1 & CONF1_DA_MASK) >> CONF1_DA_SHIFT); ++ *size = lsz * sets * ways; ++ *lsize = lsz; ++} + -+/* use the Windows ULONG_PTR type when compiling for 64 bit */ -+#if defined(_WIN64) -+#include -+#define TYPEDEF_UINTPTR -+typedef ULONG_PTR uintptr; -+#endif ++#define cache_op(base, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1, (%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); + -+#ifdef _HNDRTE_ -+typedef long unsigned int size_t; -+#endif ++#define cache_unroll4(base, delta, op) \ ++ __asm__ __volatile__(" \ ++ .set noreorder; \ ++ .set mips3; \ ++ cache %1, 0(%0); \ ++ cache %1, delta(%0); \ ++ cache %1, (2 * delta)(%0); \ ++ cache %1, (3 * delta)(%0); \ ++ .set mips0; \ ++ .set reorder" \ ++ : \ ++ : "r" (base), \ ++ "i" (op)); + -+#ifdef _MSC_VER /* Microsoft C */ -+#define TYPEDEF_INT64 -+#define TYPEDEF_UINT64 -+typedef signed __int64 int64; -+typedef unsigned __int64 uint64; -+#endif ++#endif /* !_LANGUAGE_ASSEMBLY */ + -+#if defined(MACOSX) && defined(KERNEL) -+#define TYPEDEF_BOOL -+#endif ++#endif /* _MISPINC_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947xx/include/osl.h +--- linux.old/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/osl.h 2006-05-02 17:40:43.000000000 +0200 +@@ -0,0 +1,179 @@ ++#ifndef __osl_h ++#define __osl_h + ++#include ++#include ++#include ++#include ++#include + -+#if defined(linux) -+#define TYPEDEF_UINT -+#define TYPEDEF_USHORT -+#define TYPEDEF_ULONG -+#endif ++#define ASSERT(n) + -+#if !defined(linux) && !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_) -+#define TYPEDEF_UINT -+#define TYPEDEF_USHORT -+#endif ++/* Pkttag flag should be part of public information */ ++struct osl_pubinfo { ++ bool pkttag; ++ uint pktalloced; /* Number of allocated packet buffers */ ++}; + ++struct osl_info { ++ struct osl_pubinfo pub; ++ uint magic; ++ void *pdev; ++ uint malloced; ++ uint failed; ++ void *dbgmem_list; ++}; + -+/* Do not support the (u)int64 types with strict ansi for GNU C */ -+#if defined(__GNUC__) && defined(__STRICT_ANSI__) -+#define TYPEDEF_INT64 -+#define TYPEDEF_UINT64 -+#endif ++typedef struct osl_info osl_t; + -+/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode -+ * for singned or unsigned */ -+#if defined(__ICL) ++#define PCI_CFG_RETRY 10 + -+#define TYPEDEF_INT64 ++/* map/unmap direction */ ++#define DMA_TX 1 /* TX direction for DMA */ ++#define DMA_RX 2 /* RX direction for DMA */ + -+#if defined(__STDC__) -+#define TYPEDEF_UINT64 -+#endif ++#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) ++#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) ++#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) + -+#endif /* __ICL */ ++/* bcopy, bcmp, and bzero */ ++#define bcopy(src, dst, len) memcpy((dst), (src), (len)) ++#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) ++#define bzero(b, len) memset((b), '\0', (len)) + ++/* uncached virtual address */ ++#ifdef mips ++#define OSL_UNCACHED(va) KSEG1ADDR((va)) ++#include ++#else ++#define OSL_UNCACHED(va) (va) ++#endif /* mips */ + -+#if !defined(_WIN32) && !defined(PMON) && !defined(_CFE_) && !defined(_HNDRTE_) && !defined(_MINOSL_) + -+/* pick up ushort & uint from standard types.h */ -+#if defined(linux) && defined(__KERNEL__) ++#ifndef IL_BIGENDIAN ++#define R_REG(osh, r) (\ ++ sizeof(*(r)) == sizeof(uint8) ? readb((volatile uint8*)(r)) : \ ++ sizeof(*(r)) == sizeof(uint16) ? readw((volatile uint16*)(r)) : \ ++ readl((volatile uint32*)(r)) \ ++) ++#define W_REG(osh, r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)(r)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)(r)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#else /* IL_BIGENDIAN */ ++#define R_REG(osh, r) ({ \ ++ __typeof(*(r)) __osl_v; \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): __osl_v = readb((volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): __osl_v = readw((volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): __osl_v = readl((volatile uint32*)(r)); break; \ ++ } \ ++ __osl_v; \ ++}) ++#define W_REG(osh, r, v) do { \ ++ switch (sizeof(*(r))) { \ ++ case sizeof(uint8): writeb((uint8)(v), (volatile uint8*)((uint32)r^3)); break; \ ++ case sizeof(uint16): writew((uint16)(v), (volatile uint16*)((uint32)r^2)); break; \ ++ case sizeof(uint32): writel((uint32)(v), (volatile uint32*)(r)); break; \ ++ } \ ++} while (0) ++#endif /* IL_BIGENDIAN */ + -+#include /* sys/types.h and linux/types.h are oil and water */ ++/* dereference an address that may cause a bus exception */ ++#define BUSPROBE(val, addr) get_dbe((val), (addr)) ++#include + -+#else ++/* map/unmap physical to virtual I/O */ ++#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) ++#define REG_UNMAP(va) iounmap((void *)(va)) + -+#include ++/* shared (dma-able) memory access macros */ ++#define R_SM(r) *(r) ++#define W_SM(r, v) (*(r) = (v)) ++#define BZERO_SM(r, len) memset((r), '\0', (len)) + -+#endif ++#define MALLOC(osh, size) kmalloc((size), GFP_ATOMIC) ++#define MFREE(osh, addr, size) kfree((addr)) ++#define MALLOCED(osh) (0) + -+#endif /* !_WIN32 && !PMON && !_CFE_ && !_HNDRTE_ && !_MINOSL_ */ ++#define osl_delay OSL_DELAY ++static inline void OSL_DELAY(uint usec) ++{ ++ uint d; + -+#if defined(MACOSX) && defined(KERNEL) -+#include -+#endif ++ while (usec > 0) { ++ d = MIN(usec, 1000); ++ udelay(d); ++ usec -= d; ++ } ++} + ++static inline void ++bcm_mdelay(uint ms) ++{ ++ uint i; + -+/* use the default typedefs in the next section of this file */ -+#define USE_TYPEDEF_DEFAULTS ++ for (i = 0; i < ms; i++) { ++ OSL_DELAY(1000); ++ } ++} + -+#endif /* SITE_TYPEDEFS */ + ++#define OSL_PCMCIA_READ_ATTR(osh, offset, buf, size) ++#define OSL_PCMCIA_WRITE_ATTR(osh, offset, buf, size) + -+/******************************************************************************* -+ * Default Typedefs -+ *******************************************************************************/ ++#define OSL_PCI_READ_CONFIG(osh, offset, size) \ ++ osl_pci_read_config((osh), (offset), (size)) + -+#ifdef USE_TYPEDEF_DEFAULTS -+#undef USE_TYPEDEF_DEFAULTS ++static inline uint32 ++osl_pci_read_config(osl_t *osh, uint offset, uint size) ++{ ++ uint val; ++ uint retry = PCI_CFG_RETRY; + -+#ifndef TYPEDEF_BOOL -+typedef /*@abstract@*/ unsigned char bool; -+#endif ++ do { ++ pci_read_config_dword(osh->pdev, offset, &val); ++ if (val != 0xffffffff) ++ break; ++ } while (retry--); + -+/*----------------------- define uchar, ushort, uint, ulong ------------------*/ ++ return (val); ++} + -+#ifndef TYPEDEF_UCHAR -+typedef unsigned char uchar; -+#endif ++#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ ++ osl_pci_write_config((osh), (offset), (size), (val)) ++static inline void ++osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) ++{ ++ uint retry = PCI_CFG_RETRY; + -+#ifndef TYPEDEF_USHORT -+typedef unsigned short ushort; -+#endif ++ do { ++ pci_write_config_dword(osh->pdev, offset, val); ++ if (offset != PCI_BAR0_WIN) ++ break; ++ if (osl_pci_read_config(osh, offset, size) == val) ++ break; ++ } while (retry--); ++} + -+#ifndef TYPEDEF_UINT -+typedef unsigned int uint; -+#endif + -+#ifndef TYPEDEF_ULONG -+typedef unsigned long ulong; -+#endif ++/* return bus # for the pci device pointed by osh->pdev */ ++#define OSL_PCI_BUS(osh) osl_pci_bus(osh) ++static inline uint ++osl_pci_bus(osl_t *osh) ++{ ++ return ((struct pci_dev *)osh->pdev)->bus->number; ++} + -+/*----------------------- define [u]int8/16/32/64, uintptr --------------------*/ ++/* return slot # for the pci device pointed by osh->pdev */ ++#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) ++static inline uint ++osl_pci_slot(osl_t *osh) ++{ ++ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); ++} + -+#ifndef TYPEDEF_UINT8 -+typedef unsigned char uint8; +#endif +diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm947xx/include/pcicfg.h +--- linux.old/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/pcicfg.h 2006-04-27 20:31:41.000000000 +0200 +@@ -0,0 +1,495 @@ ++/* ++ * pcicfg.h: PCI configuration constants and structures. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: pcicfg.h,v 1.1.1.11 2006/04/08 06:13:40 honor Exp $ ++ */ + -+#ifndef TYPEDEF_UINT16 -+typedef unsigned short uint16; -+#endif ++#ifndef _h_pcicfg_ ++#define _h_pcicfg_ + -+#ifndef TYPEDEF_UINT32 -+typedef unsigned int uint32; ++/* The following inside ifndef's so we don't collide with NTDDK.H */ ++#ifndef PCI_MAX_BUS ++#define PCI_MAX_BUS 0x100 +#endif -+ -+#ifndef TYPEDEF_UINT64 -+typedef unsigned long long uint64; ++#ifndef PCI_MAX_DEVICES ++#define PCI_MAX_DEVICES 0x20 +#endif -+ -+#ifndef TYPEDEF_UINTPTR -+typedef unsigned int uintptr; ++#ifndef PCI_MAX_FUNCTION ++#define PCI_MAX_FUNCTION 0x8 +#endif + -+#ifndef TYPEDEF_INT8 -+typedef signed char int8; ++#ifndef PCI_INVALID_VENDORID ++#define PCI_INVALID_VENDORID 0xffff +#endif -+ -+#ifndef TYPEDEF_INT16 -+typedef signed short int16; ++#ifndef PCI_INVALID_DEVICEID ++#define PCI_INVALID_DEVICEID 0xffff +#endif + -+#ifndef TYPEDEF_INT32 -+typedef signed int int32; -+#endif + -+#ifndef TYPEDEF_INT64 -+typedef signed long long int64; -+#endif ++/* Convert between bus-slot-function-register and config addresses */ + -+/*----------------------- define float32/64, float_t -----------------------*/ ++#define PCICFG_BUS_SHIFT 16 /* Bus shift */ ++#define PCICFG_SLOT_SHIFT 11 /* Slot shift */ ++#define PCICFG_FUN_SHIFT 8 /* Function shift */ ++#define PCICFG_OFF_SHIFT 0 /* Register shift */ + -+#ifndef TYPEDEF_FLOAT32 -+typedef float float32; -+#endif ++#define PCICFG_BUS_MASK 0xff /* Bus mask */ ++#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ ++#define PCICFG_FUN_MASK 7 /* Function mask */ ++#define PCICFG_OFF_MASK 0xff /* Bus mask */ + -+#ifndef TYPEDEF_FLOAT64 -+typedef double float64; -+#endif ++#define PCI_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCICFG_BUS_MASK) << PCICFG_BUS_SHIFT) \ ++ | (((s) & PCICFG_SLOT_MASK) << PCICFG_SLOT_SHIFT) \ ++ | (((f) & PCICFG_FUN_MASK) << PCICFG_FUN_SHIFT) \ ++ | (((o) & PCICFG_OFF_MASK) << PCICFG_OFF_SHIFT)) + -+/* -+ * abstracted floating point type allows for compile time selection of -+ * single or double precision arithmetic. Compiling with -DFLOAT32 -+ * selects single precision; the default is double precision. -+ */ ++#define PCI_CONFIG_BUS(a) (((a) >> PCICFG_BUS_SHIFT) & PCICFG_BUS_MASK) ++#define PCI_CONFIG_SLOT(a) (((a) >> PCICFG_SLOT_SHIFT) & PCICFG_SLOT_MASK) ++#define PCI_CONFIG_FUN(a) (((a) >> PCICFG_FUN_SHIFT) & PCICFG_FUN_MASK) ++#define PCI_CONFIG_OFF(a) (((a) >> PCICFG_OFF_SHIFT) & PCICFG_OFF_MASK) + -+#ifndef TYPEDEF_FLOAT_T ++/* PCIE Config space accessing MACROS */ + -+#if defined(FLOAT32) -+typedef float32 float_t; -+#else /* default to double precision floating point */ -+typedef float64 float_t; -+#endif ++#define PCIECFG_BUS_SHIFT 24 /* Bus shift */ ++#define PCIECFG_SLOT_SHIFT 19 /* Slot/Device shift */ ++#define PCIECFG_FUN_SHIFT 16 /* Function shift */ ++#define PCIECFG_OFF_SHIFT 0 /* Register shift */ + -+#endif /* TYPEDEF_FLOAT_T */ ++#define PCIECFG_BUS_MASK 0xff /* Bus mask */ ++#define PCIECFG_SLOT_MASK 0x1f /* Slot/Device mask */ ++#define PCIECFG_FUN_MASK 7 /* Function mask */ ++#define PCIECFG_OFF_MASK 0x3ff /* Register mask */ + -+/*----------------------- define macro values -----------------------------*/ ++#define PCIE_CONFIG_ADDR(b, s, f, o) \ ++ ((((b) & PCIECFG_BUS_MASK) << PCIECFG_BUS_SHIFT) \ ++ | (((s) & PCIECFG_SLOT_MASK) << PCIECFG_SLOT_SHIFT) \ ++ | (((f) & PCIECFG_FUN_MASK) << PCIECFG_FUN_SHIFT) \ ++ | (((o) & PCIECFG_OFF_MASK) << PCIECFG_OFF_SHIFT)) + -+#ifndef FALSE -+#define FALSE 0 -+#endif ++#define PCIE_CONFIG_BUS(a) (((a) >> PCIECFG_BUS_SHIFT) & PCIECFG_BUS_MASK) ++#define PCIE_CONFIG_SLOT(a) (((a) >> PCIECFG_SLOT_SHIFT) & PCIECFG_SLOT_MASK) ++#define PCIE_CONFIG_FUN(a) (((a) >> PCIECFG_FUN_SHIFT) & PCIECFG_FUN_MASK) ++#define PCIE_CONFIG_OFF(a) (((a) >> PCIECFG_OFF_SHIFT) & PCIECFG_OFF_MASK) + -+#ifndef TRUE -+#define TRUE 1 -+#endif ++/* The actual config space */ + -+#ifndef NULL -+#define NULL 0 -+#endif ++#define PCI_BAR_MAX 6 + -+#ifndef OFF -+#define OFF 0 -+#endif ++#define PCI_ROM_BAR 8 + -+#ifndef ON -+#define ON 1 -+#endif ++#define PCR_RSVDA_MAX 2 + -+#define AUTO (-1) ++/* Bits in PCI bars' flags */ + -+/* Reclaiming text and data : -+ The following macros specify special linker sections that can be reclaimed -+ after a system is considered 'up'. -+ */ -+#if defined(__GNUC__) && defined(BCMRECLAIM) -+extern bool bcmreclaimed; -+#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data##_ini -+#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn##_ini -+#define BCMINIT(_id) _id##_ini -+#else -+#define BCMINITDATA(_data) _data -+#define BCMINITFN(_fn) _fn -+#define BCMINIT(_id) _id -+#define bcmreclaimed 0 -+#endif ++#define PCIBAR_FLAGS 0xf ++#define PCIBAR_IO 0x1 ++#define PCIBAR_MEM1M 0x2 ++#define PCIBAR_MEM64 0x4 ++#define PCIBAR_PREFETCH 0x8 ++#define PCIBAR_MEM32_MASK 0xFFFFFF80 + -+/*----------------------- define PTRSZ, INLINE ----------------------------*/ ++/* pci config status reg has a bit to indicate that capability ptr is present */ + -+#ifndef PTRSZ -+#define PTRSZ sizeof (char*) -+#endif ++#define PCI_CAPPTR_PRESENT 0x0010 + -+#ifndef INLINE ++typedef struct _pci_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long base[PCI_BAR_MAX]; ++ unsigned long cardbus_cis; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long baserom; ++ unsigned long rsvd_a[PCR_RSVDA_MAX]; ++ unsigned char int_line; ++ unsigned char int_pin; ++ unsigned char min_gnt; ++ unsigned char max_lat; ++ unsigned char dev_dep[192]; ++} pci_config_regs; + -+#ifdef _MSC_VER ++#define SZPCR (sizeof (pci_config_regs)) ++#define MINSZPCR 64 /* offsetof (dev_dep[0] */ + -+#define INLINE __inline ++/* A structure for the config registers is nice, but in most ++ * systems the config space is not memory mapped, so we need ++ * filed offsetts. :-( ++ */ ++#define PCI_CFG_VID 0 ++#define PCI_CFG_DID 2 ++#define PCI_CFG_CMD 4 ++#define PCI_CFG_STAT 6 ++#define PCI_CFG_REV 8 ++#define PCI_CFG_PROGIF 9 ++#define PCI_CFG_SUBCL 0xa ++#define PCI_CFG_BASECL 0xb ++#define PCI_CFG_CLSZ 0xc ++#define PCI_CFG_LATTIM 0xd ++#define PCI_CFG_HDR 0xe ++#define PCI_CFG_BIST 0xf ++#define PCI_CFG_BAR0 0x10 ++#define PCI_CFG_BAR1 0x14 ++#define PCI_CFG_BAR2 0x18 ++#define PCI_CFG_BAR3 0x1c ++#define PCI_CFG_BAR4 0x20 ++#define PCI_CFG_BAR5 0x24 ++#define PCI_CFG_CIS 0x28 ++#define PCI_CFG_SVID 0x2c ++#define PCI_CFG_SSID 0x2e ++#define PCI_CFG_ROMBAR 0x30 ++#define PCI_CFG_CAPPTR 0x34 ++#define PCI_CFG_INT 0x3c ++#define PCI_CFG_PIN 0x3d ++#define PCI_CFG_MINGNT 0x3e ++#define PCI_CFG_MAXLAT 0x3f + -+#elif __GNUC__ ++#ifdef __NetBSD__ ++#undef PCI_CLASS_DISPLAY ++#undef PCI_CLASS_MEMORY ++#undef PCI_CLASS_BRIDGE ++#undef PCI_CLASS_INPUT ++#undef PCI_CLASS_DOCK ++#endif /* __NetBSD__ */ + -+#define INLINE __inline__ ++/* Classes and subclasses */ + -+#else ++typedef enum { ++ PCI_CLASS_OLD = 0, ++ PCI_CLASS_DASDI, ++ PCI_CLASS_NET, ++ PCI_CLASS_DISPLAY, ++ PCI_CLASS_MMEDIA, ++ PCI_CLASS_MEMORY, ++ PCI_CLASS_BRIDGE, ++ PCI_CLASS_COMM, ++ PCI_CLASS_BASE, ++ PCI_CLASS_INPUT, ++ PCI_CLASS_DOCK, ++ PCI_CLASS_CPU, ++ PCI_CLASS_SERIAL, ++ PCI_CLASS_INTELLIGENT = 0xe, ++ PCI_CLASS_SATELLITE, ++ PCI_CLASS_CRYPT, ++ PCI_CLASS_DSP, ++ PCI_CLASS_XOR = 0xfe ++} pci_classes; + -+#define INLINE ++typedef enum { ++ PCI_DASDI_SCSI, ++ PCI_DASDI_IDE, ++ PCI_DASDI_FLOPPY, ++ PCI_DASDI_IPI, ++ PCI_DASDI_RAID, ++ PCI_DASDI_OTHER = 0x80 ++} pci_dasdi_subclasses; + -+#endif /* _MSC_VER */ ++typedef enum { ++ PCI_NET_ETHER, ++ PCI_NET_TOKEN, ++ PCI_NET_FDDI, ++ PCI_NET_ATM, ++ PCI_NET_OTHER = 0x80 ++} pci_net_subclasses; + -+#endif /* INLINE */ ++typedef enum { ++ PCI_DISPLAY_VGA, ++ PCI_DISPLAY_XGA, ++ PCI_DISPLAY_3D, ++ PCI_DISPLAY_OTHER = 0x80 ++} pci_display_subclasses; + -+#undef TYPEDEF_BOOL -+#undef TYPEDEF_UCHAR -+#undef TYPEDEF_USHORT -+#undef TYPEDEF_UINT -+#undef TYPEDEF_ULONG -+#undef TYPEDEF_UINT8 -+#undef TYPEDEF_UINT16 -+#undef TYPEDEF_UINT32 -+#undef TYPEDEF_UINT64 -+#undef TYPEDEF_UINTPTR -+#undef TYPEDEF_INT8 -+#undef TYPEDEF_INT16 -+#undef TYPEDEF_INT32 -+#undef TYPEDEF_INT64 -+#undef TYPEDEF_FLOAT32 -+#undef TYPEDEF_FLOAT64 -+#undef TYPEDEF_FLOAT_T ++typedef enum { ++ PCI_MMEDIA_VIDEO, ++ PCI_MMEDIA_AUDIO, ++ PCI_MMEDIA_PHONE, ++ PCI_MEDIA_OTHER = 0x80 ++} pci_mmedia_subclasses; + -+#endif /* USE_TYPEDEF_DEFAULTS */ ++typedef enum { ++ PCI_MEMORY_RAM, ++ PCI_MEMORY_FLASH, ++ PCI_MEMORY_OTHER = 0x80 ++} pci_memory_subclasses; + -+#endif /* _TYPEDEFS_H_ */ -diff -Naur linux.old/arch/mips/bcm947xx/nvram.c linux.dev/arch/mips/bcm947xx/nvram.c ---- linux.old/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/nvram.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,320 @@ -+/* -+ * NVRAM variable manipulation (common) -+ * -+ * Copyright 2004, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ */ ++typedef enum { ++ PCI_BRIDGE_HOST, ++ PCI_BRIDGE_ISA, ++ PCI_BRIDGE_EISA, ++ PCI_BRIDGE_MC, ++ PCI_BRIDGE_PCI, ++ PCI_BRIDGE_PCMCIA, ++ PCI_BRIDGE_NUBUS, ++ PCI_BRIDGE_CARDBUS, ++ PCI_BRIDGE_RACEWAY, ++ PCI_BRIDGE_OTHER = 0x80 ++} pci_bridge_subclasses; + -+#include -+#include -+#include -+#include -+#include -+#include ++typedef enum { ++ PCI_COMM_UART, ++ PCI_COMM_PARALLEL, ++ PCI_COMM_MULTIUART, ++ PCI_COMM_MODEM, ++ PCI_COMM_OTHER = 0x80 ++} pci_comm_subclasses; + -+extern struct nvram_tuple * BCMINIT(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value); -+extern void BCMINIT(_nvram_free)(struct nvram_tuple *t); -+extern int BCMINIT(_nvram_read)(void *buf); ++typedef enum { ++ PCI_BASE_PIC, ++ PCI_BASE_DMA, ++ PCI_BASE_TIMER, ++ PCI_BASE_RTC, ++ PCI_BASE_PCI_HOTPLUG, ++ PCI_BASE_OTHER = 0x80 ++} pci_base_subclasses; + -+char * BCMINIT(_nvram_get)(const char *name); -+int BCMINIT(_nvram_set)(const char *name, const char *value); -+int BCMINIT(_nvram_unset)(const char *name); -+int BCMINIT(_nvram_getall)(char *buf, int count); -+int BCMINIT(_nvram_commit)(struct nvram_header *header); -+int BCMINIT(_nvram_init)(void); -+void BCMINIT(_nvram_exit)(void); ++typedef enum { ++ PCI_INPUT_KBD, ++ PCI_INPUT_PEN, ++ PCI_INPUT_MOUSE, ++ PCI_INPUT_SCANNER, ++ PCI_INPUT_GAMEPORT, ++ PCI_INPUT_OTHER = 0x80 ++} pci_input_subclasses; + -+static struct nvram_tuple * BCMINITDATA(nvram_hash)[257]; -+static struct nvram_tuple * nvram_dead; ++typedef enum { ++ PCI_DOCK_GENERIC, ++ PCI_DOCK_OTHER = 0x80 ++} pci_dock_subclasses; + -+/* Free all tuples. Should be locked. */ -+static void -+BCMINITFN(nvram_free)(void) -+{ -+ uint i; -+ struct nvram_tuple *t, *next; ++typedef enum { ++ PCI_CPU_386, ++ PCI_CPU_486, ++ PCI_CPU_PENTIUM, ++ PCI_CPU_ALPHA = 0x10, ++ PCI_CPU_POWERPC = 0x20, ++ PCI_CPU_MIPS = 0x30, ++ PCI_CPU_COPROC = 0x40, ++ PCI_CPU_OTHER = 0x80 ++} pci_cpu_subclasses; + -+ /* Free hash table */ -+ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { -+ for (t = BCMINIT(nvram_hash)[i]; t; t = next) { -+ next = t->next; -+ BCMINIT(_nvram_free)(t); -+ } -+ BCMINIT(nvram_hash)[i] = NULL; -+ } ++typedef enum { ++ PCI_SERIAL_IEEE1394, ++ PCI_SERIAL_ACCESS, ++ PCI_SERIAL_SSA, ++ PCI_SERIAL_USB, ++ PCI_SERIAL_FIBER, ++ PCI_SERIAL_SMBUS, ++ PCI_SERIAL_OTHER = 0x80 ++} pci_serial_subclasses; + -+ /* Free dead table */ -+ for (t = nvram_dead; t; t = next) { -+ next = t->next; -+ BCMINIT(_nvram_free)(t); -+ } -+ nvram_dead = NULL; ++typedef enum { ++ PCI_INTELLIGENT_I2O ++} pci_intelligent_subclasses; + -+ /* Indicate to per-port code that all tuples have been freed */ -+ BCMINIT(_nvram_free)(NULL); -+} ++typedef enum { ++ PCI_SATELLITE_TV, ++ PCI_SATELLITE_AUDIO, ++ PCI_SATELLITE_VOICE, ++ PCI_SATELLITE_DATA, ++ PCI_SATELLITE_OTHER = 0x80 ++} pci_satellite_subclasses; + -+/* String hash */ -+static INLINE uint -+hash(const char *s) -+{ -+ uint hash = 0; ++typedef enum { ++ PCI_CRYPT_NETWORK, ++ PCI_CRYPT_ENTERTAINMENT, ++ PCI_CRYPT_OTHER = 0x80 ++} pci_crypt_subclasses; + -+ while (*s) -+ hash = 31 * hash + *s++; ++typedef enum { ++ PCI_DSP_DPIO, ++ PCI_DSP_OTHER = 0x80 ++} pci_dsp_subclasses; + -+ return hash; -+} ++typedef enum { ++ PCI_XOR_QDMA, ++ PCI_XOR_OTHER = 0x80 ++} pci_xor_subclasses; + -+/* (Re)initialize the hash table. Should be locked. */ -+static int -+BCMINITFN(nvram_rehash)(struct nvram_header *header) -+{ -+ char buf[] = "0xXXXXXXXX", *name, *value, *end, *eq; ++/* Header types */ ++typedef enum { ++ PCI_HEADER_NORMAL, ++ PCI_HEADER_BRIDGE, ++ PCI_HEADER_CARDBUS ++} pci_header_types; + -+ /* (Re)initialize hash table */ -+ BCMINIT(nvram_free)(); + -+ /* Parse and set "name=value\0 ... \0\0" */ -+ name = (char *) &header[1]; -+ end = (char *) header + NVRAM_SPACE - 2; -+ end[0] = end[1] = '\0'; -+ for (; *name; name = value + strlen(value) + 1) { -+ if (!(eq = strchr(name, '='))) -+ break; -+ *eq = '\0'; -+ value = eq + 1; -+ BCMINIT(_nvram_set)(name, value); -+ *eq = '='; -+ } ++/* Overlay for a PCI-to-PCI bridge */ + -+ /* Set special SDRAM parameters */ -+ if (!BCMINIT(_nvram_get)("sdram_init")) { -+ sprintf(buf, "0x%04X", (uint16)(header->crc_ver_init >> 16)); -+ BCMINIT(_nvram_set)("sdram_init", buf); -+ } -+ if (!BCMINIT(_nvram_get)("sdram_config")) { -+ sprintf(buf, "0x%04X", (uint16)(header->config_refresh & 0xffff)); -+ BCMINIT(_nvram_set)("sdram_config", buf); -+ } -+ if (!BCMINIT(_nvram_get)("sdram_refresh")) { -+ sprintf(buf, "0x%04X", (uint16)((header->config_refresh >> 16) & 0xffff)); -+ BCMINIT(_nvram_set)("sdram_refresh", buf); -+ } -+ if (!BCMINIT(_nvram_get)("sdram_ncdl")) { -+ sprintf(buf, "0x%08X", header->config_ncdl); -+ BCMINIT(_nvram_set)("sdram_ncdl", buf); -+ } ++#define PPB_RSVDA_MAX 2 ++#define PPB_RSVDD_MAX 8 + -+ return 0; -+} ++typedef struct _ppb_config_regs { ++ unsigned short vendor; ++ unsigned short device; ++ unsigned short command; ++ unsigned short status; ++ unsigned char rev_id; ++ unsigned char prog_if; ++ unsigned char sub_class; ++ unsigned char base_class; ++ unsigned char cache_line_size; ++ unsigned char latency_timer; ++ unsigned char header_type; ++ unsigned char bist; ++ unsigned long rsvd_a[PPB_RSVDA_MAX]; ++ unsigned char prim_bus; ++ unsigned char sec_bus; ++ unsigned char sub_bus; ++ unsigned char sec_lat; ++ unsigned char io_base; ++ unsigned char io_lim; ++ unsigned short sec_status; ++ unsigned short mem_base; ++ unsigned short mem_lim; ++ unsigned short pf_mem_base; ++ unsigned short pf_mem_lim; ++ unsigned long pf_mem_base_hi; ++ unsigned long pf_mem_lim_hi; ++ unsigned short io_base_hi; ++ unsigned short io_lim_hi; ++ unsigned short subsys_vendor; ++ unsigned short subsys_id; ++ unsigned long rsvd_b; ++ unsigned char rsvd_c; ++ unsigned char int_pin; ++ unsigned short bridge_ctrl; ++ unsigned char chip_ctrl; ++ unsigned char diag_ctrl; ++ unsigned short arb_ctrl; ++ unsigned long rsvd_d[PPB_RSVDD_MAX]; ++ unsigned char dev_dep[192]; ++} ppb_config_regs; + -+/* Get the value of an NVRAM variable. Should be locked. */ -+char * -+BCMINITFN(_nvram_get)(const char *name) -+{ -+ uint i; -+ struct nvram_tuple *t; -+ char *value; + -+ if (!name) -+ return NULL; ++/* PCI CAPABILITY DEFINES */ ++#define PCI_CAP_POWERMGMTCAP_ID 0x01 ++#define PCI_CAP_MSICAP_ID 0x05 ++#define PCI_CAP_PCIECAP_ID 0x10 + -+ /* Hash the name */ -+ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++/* Data structure to define the Message Signalled Interrupt facility ++ * Valid for PCI and PCIE configurations ++ */ ++typedef struct _pciconfig_cap_msi { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short msgctrl; ++ unsigned int msgaddr; ++} pciconfig_cap_msi; + -+ /* Find the associated tuple in the hash table */ -+ for (t = BCMINIT(nvram_hash)[i]; t && strcmp(t->name, name); t = t->next); ++/* Data structure to define the Power managment facility ++ * Valid for PCI and PCIE configurations ++ */ ++typedef struct _pciconfig_cap_pwrmgmt { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short pme_cap; ++ unsigned short pme_sts_ctrl; ++ unsigned char pme_bridge_ext; ++ unsigned char data; ++} pciconfig_cap_pwrmgmt; + -+ value = t ? t->value : NULL; ++/* Data structure to define the PCIE capability */ ++typedef struct _pciconfig_cap_pcie { ++ unsigned char capID; ++ unsigned char nextptr; ++ unsigned short pcie_cap; ++ unsigned int dev_cap; ++ unsigned short dev_ctrl; ++ unsigned short dev_status; ++ unsigned int link_cap; ++ unsigned short link_ctrl; ++ unsigned short link_status; ++} pciconfig_cap_pcie; + -+ return value; -+} ++/* PCIE Enhanced CAPABILITY DEFINES */ ++#define PCIE_EXTCFG_OFFSET 0x100 ++#define PCIE_ADVERRREP_CAPID 0x0001 ++#define PCIE_VC_CAPID 0x0002 ++#define PCIE_DEVSNUM_CAPID 0x0003 ++#define PCIE_PWRBUDGET_CAPID 0x0004 + -+/* Get the value of an NVRAM variable. Should be locked. */ -+int -+BCMINITFN(_nvram_set)(const char *name, const char *value) -+{ -+ uint i; -+ struct nvram_tuple *t, *u, **prev; ++/* Header to define the PCIE specific capabilities in the extended config space */ ++typedef struct _pcie_enhanced_caphdr { ++ unsigned short capID; ++ unsigned short cap_ver : 4; ++ unsigned short next_ptr : 12; ++} pcie_enhanced_caphdr; + -+ /* Hash the name */ -+ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); + -+ /* Find the associated tuple in the hash table */ -+ for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev); ++/* Everything below is BRCM HND proprietary */ + -+ /* (Re)allocate tuple */ -+ if (!(u = BCMINIT(_nvram_realloc)(t, name, value))) -+ return -12; /* -ENOMEM */ + -+ /* Value reallocated */ -+ if (t && t == u) -+ return 0; ++/* Brcm PCI configuration registers */ ++#define cap_list rsvd_a[0] ++#define bar0_window dev_dep[0x80 - 0x40] ++#define bar1_window dev_dep[0x84 - 0x40] ++#define sprom_control dev_dep[0x88 - 0x40] + -+ /* Move old tuple to the dead table */ -+ if (t) { -+ *prev = t->next; -+ t->next = nvram_dead; -+ nvram_dead = t; -+ } ++#define PCI_BAR0_WIN 0x80 /* backplane addres space accessed by BAR0 */ ++#define PCI_BAR1_WIN 0x84 /* backplane addres space accessed by BAR1 */ ++#define PCI_SPROM_CONTROL 0x88 /* sprom property control */ ++#define PCI_BAR1_CONTROL 0x8c /* BAR1 region burst control */ ++#define PCI_INT_STATUS 0x90 /* PCI and other cores interrupts */ ++#define PCI_INT_MASK 0x94 /* mask of PCI and other cores interrupts */ ++#define PCI_TO_SB_MB 0x98 /* signal backplane interrupts */ ++#define PCI_BACKPLANE_ADDR 0xA0 /* address an arbitrary location on the system backplane */ ++#define PCI_BACKPLANE_DATA 0xA4 /* data at the location specified by above address */ ++#define PCI_GPIO_IN 0xb0 /* pci config space gpio input (>=rev3) */ ++#define PCI_GPIO_OUT 0xb4 /* pci config space gpio output (>=rev3) */ ++#define PCI_GPIO_OUTEN 0xb8 /* pci config space gpio output enable (>=rev3) */ + -+ /* Add new tuple to the hash table */ -+ u->next = BCMINIT(nvram_hash)[i]; -+ BCMINIT(nvram_hash)[i] = u; ++#define PCI_BAR0_SHADOW_OFFSET (2 * 1024) /* bar0 + 2K accesses sprom shadow (in pci core) */ ++#define PCI_BAR0_SPROM_OFFSET (4 * 1024) /* bar0 + 4K accesses external sprom */ ++#define PCI_BAR0_PCIREGS_OFFSET (6 * 1024) /* bar0 + 6K accesses pci core registers */ ++#define PCI_BAR0_PCISBR_OFFSET (4 * 1024) /* pci core SB registers are at the end of the ++ * 8KB window, so their address is the "regular" ++ * address plus 4K ++ */ ++#define PCI_BAR0_WINSZ 8192 /* bar0 window size */ + -+ return 0; -+} ++/* On pci corerev >= 13 and all pcie, the bar0 is now 16KB and it maps: */ ++#define PCI_16KB0_PCIREGS_OFFSET (8 * 1024) /* bar0 + 8K accesses pci/pcie core registers */ ++#define PCI_16KB0_CCREGS_OFFSET (12 * 1024) /* bar0 + 12K accesses chipc core registers */ ++#define PCI_16KBB0_WINSZ (16 * 1024) /* bar0 window size */ + -+/* Unset the value of an NVRAM variable. Should be locked. */ -+int -+BCMINITFN(_nvram_unset)(const char *name) -+{ -+ uint i; -+ struct nvram_tuple *t, **prev; -+ -+ if (!name) -+ return 0; -+ -+ /* Hash the name */ -+ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); -+ -+ /* Find the associated tuple in the hash table */ -+ for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev); -+ -+ /* Move it to the dead table */ -+ if (t) { -+ *prev = t->next; -+ t->next = nvram_dead; -+ nvram_dead = t; -+ } -+ -+ return 0; -+} -+ -+/* Get all NVRAM variables. Should be locked. */ -+int -+BCMINITFN(_nvram_getall)(char *buf, int count) -+{ -+ uint i; -+ struct nvram_tuple *t; -+ int len = 0; -+ -+ bzero(buf, count); -+ -+ /* Write name=value\0 ... \0\0 */ -+ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { -+ for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) { -+ if ((count - len) > (strlen(t->name) + 1 + strlen(t->value) + 1)) -+ len += sprintf(buf + len, "%s=%s", t->name, t->value) + 1; -+ else -+ break; -+ } -+ } -+ -+ return 0; -+} -+ -+/* Regenerate NVRAM. Should be locked. */ -+int -+BCMINITFN(_nvram_commit)(struct nvram_header *header) -+{ -+ char *init, *config, *refresh, *ncdl; -+ char *ptr, *end; -+ int i; -+ struct nvram_tuple *t; -+ struct nvram_header tmp; -+ uint8 crc; -+ -+ /* Regenerate header */ -+ header->magic = NVRAM_MAGIC; -+ header->crc_ver_init = (NVRAM_VERSION << 8); -+ if (!(init = BCMINIT(_nvram_get)("sdram_init")) || -+ !(config = BCMINIT(_nvram_get)("sdram_config")) || -+ !(refresh = BCMINIT(_nvram_get)("sdram_refresh")) || -+ !(ncdl = BCMINIT(_nvram_get)("sdram_ncdl"))) { -+ header->crc_ver_init |= SDRAM_INIT << 16; -+ header->config_refresh = SDRAM_CONFIG; -+ header->config_refresh |= SDRAM_REFRESH << 16; -+ header->config_ncdl = 0; -+ } else { -+ header->crc_ver_init |= (bcm_strtoul(init, NULL, 0) & 0xffff) << 16; -+ header->config_refresh = bcm_strtoul(config, NULL, 0) & 0xffff; -+ header->config_refresh |= (bcm_strtoul(refresh, NULL, 0) & 0xffff) << 16; -+ header->config_ncdl = bcm_strtoul(ncdl, NULL, 0); -+ } -+ -+ /* Clear data area */ -+ ptr = (char *) header + sizeof(struct nvram_header); -+ bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header)); -+ -+ /* Leave space for a double NUL at the end */ -+ end = (char *) header + NVRAM_SPACE - 2; -+ -+ /* Write out all tuples */ -+ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { -+ for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) { -+ if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end) -+ break; -+ ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1; -+ } -+ } -+ -+ /* End with a double NUL */ -+ ptr += 2; -+ -+ /* Set new length */ -+ header->len = ROUNDUP(ptr - (char *) header, 4); -+ -+ /* Little-endian CRC8 over the last 11 bytes of the header */ -+ tmp.crc_ver_init = htol32(header->crc_ver_init); -+ tmp.config_refresh = htol32(header->config_refresh); -+ tmp.config_ncdl = htol32(header->config_ncdl); -+ crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE); -+ -+ /* Continue CRC8 over data bytes */ -+ crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc); -+ -+ /* Set new CRC8 */ -+ header->crc_ver_init |= crc; -+ -+ /* Reinitialize hash table */ -+ return BCMINIT(nvram_rehash)(header); -+} -+ -+/* Initialize hash table. Should be locked. */ -+int -+BCMINITFN(_nvram_init)(void) -+{ -+ struct nvram_header *header; -+ int ret; -+ void *osh; ++/* PCI_INT_STATUS */ ++#define PCI_SBIM_STATUS_SERR 0x4 /* backplane SBErr interrupt status */ + -+ /* get kernel osl handler */ -+ osh = osl_attach(NULL); ++/* PCI_INT_MASK */ ++#define PCI_SBIM_SHIFT 8 /* backplane core interrupt mask bits offset */ ++#define PCI_SBIM_MASK 0xff00 /* backplane core interrupt mask */ ++#define PCI_SBIM_MASK_SERR 0x4 /* backplane SBErr interrupt mask */ + -+ if (!(header = (struct nvram_header *) MALLOC(osh, NVRAM_SPACE))) { -+ printf("nvram_init: out of memory, malloced %d bytes\n", MALLOCED(osh)); -+ return -12; /* -ENOMEM */ -+ } ++/* PCI_SPROM_CONTROL */ ++#define SPROM_SZ_MSK 0x02 /* SPROM Size Mask */ ++#define SPROM_LOCKED 0x08 /* SPROM Locked */ ++#define SPROM_BLANK 0x04 /* indicating a blank SPROM */ ++#define SPROM_WRITEEN 0x10 /* SPROM write enable */ ++#define SPROM_BOOTROM_WE 0x20 /* external bootrom write enable */ ++#define SPROM_OTPIN_USE 0x80 /* device OTP In use */ + -+ if ((ret = BCMINIT(_nvram_read)(header)) == 0 && -+ header->magic == NVRAM_MAGIC) -+ BCMINIT(nvram_rehash)(header); ++#define SPROM_SIZE 256 /* sprom size in 16-bit */ ++#define SPROM_CRC_RANGE 64 /* crc cover range in 16-bit */ + -+ MFREE(osh, header, NVRAM_SPACE); -+ return ret; -+} ++/* PCI_CFG_CMD_STAT */ ++#define PCI_CFG_CMD_STAT_TA 0x08000000 /* target abort status */ + -+/* Free hash table. Should be locked. */ -+void -+BCMINITFN(_nvram_exit)(void) -+{ -+ BCMINIT(nvram_free)(); -+} -diff -Naur linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947xx/nvram_linux.c ---- linux.old/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/nvram_linux.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,653 @@ ++#endif /* _h_pcicfg_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm947xx/include/sbchipc.h +--- linux.old/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbchipc.h 2006-04-27 22:11:01.000000000 +0200 +@@ -0,0 +1,516 @@ +/* -+ * NVRAM variable manipulation (Linux kernel half) ++ * SiliconBackplane Chipcommon core hardware definitions. + * -+ * Copyright 2005, Broadcom Corporation ++ * The chipcommon core provides chip identification, SB control, ++ * jtag, 0/1/2 uarts, clock frequency control, a watchdog interrupt timer, ++ * gpio interface, extbus, and support for serial and parallel flashes. ++ * ++ * $Id: sbchipc.h,v 1.1.1.14 2006/04/15 01:29:08 michael Exp $ ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -6319,654 +6063,896 @@ diff -Naur linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947 + * + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#ifndef _SBCHIPC_H ++#define _SBCHIPC_H + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include + -+/* In BSS to minimize text size and page aligned so it can be mmap()-ed */ -+static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE))); ++#ifndef _LANGUAGE_ASSEMBLY + -+#ifdef MODULE ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ + -+#define early_nvram_get(name) nvram_get(name) ++typedef volatile struct { ++ uint32 chipid; /* 0x0 */ ++ uint32 capabilities; ++ uint32 corecontrol; /* corerev >= 1 */ ++ uint32 bist; + -+#else /* !MODULE */ ++ /* OTP */ ++ uint32 otpstatus; /* 0x10, corerev >= 10 */ ++ uint32 otpcontrol; ++ uint32 otpprog; ++ uint32 PAD; + -+/* Global SB handle */ -+extern void *bcm947xx_sbh; -+extern spinlock_t bcm947xx_sbh_lock; ++ /* Interrupt control */ ++ uint32 intstatus; /* 0x20 */ ++ uint32 intmask; ++ uint32 chipcontrol; /* 0x28, rev >= 11 */ ++ uint32 chipstatus; /* 0x2c, rev >= 11 */ + -+static int cfe_env; -+extern char *cfe_env_get(char *nv_buf, const char *name); ++ /* Jtag Master */ ++ uint32 jtagcmd; /* 0x30, rev >= 10 */ ++ uint32 jtagir; ++ uint32 jtagdr; ++ uint32 jtagctrl; + -+/* Convenience */ -+#define sbh bcm947xx_sbh -+#define sbh_lock bcm947xx_sbh_lock -+#define KB * 1024 -+#define MB * 1024 * 1024 ++ /* serial flash interface registers */ ++ uint32 flashcontrol; /* 0x40 */ ++ uint32 flashaddress; ++ uint32 flashdata; ++ uint32 PAD[1]; + -+/* Probe for NVRAM header */ -+static void __init -+early_nvram_init(void) -+{ -+ struct nvram_header *header; -+ chipcregs_t *cc; -+ struct sflash *info = NULL; -+ int i; -+ uint32 base, off, lim; -+ u32 *src, *dst; ++ /* Silicon backplane configuration broadcast control */ ++ uint32 broadcastaddress; /* 0x50 */ ++ uint32 broadcastdata; ++ uint32 PAD[2]; + -+ if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) { -+ base = KSEG1ADDR(SB_FLASH2); -+ switch (readl(&cc->capabilities) & CAP_FLASH_MASK) { -+ case PFLASH: -+ lim = SB_FLASH2_SZ; -+ break; ++ /* gpio - cleared only by power-on-reset */ ++ uint32 gpioin; /* 0x60 */ ++ uint32 gpioout; ++ uint32 gpioouten; ++ uint32 gpiocontrol; ++ uint32 gpiointpolarity; ++ uint32 gpiointmask; ++ uint32 PAD[2]; + -+ case SFLASH_ST: -+ case SFLASH_AT: -+ if ((info = sflash_init(cc)) == NULL) -+ return; -+ lim = info->size; -+ break; ++ /* Watchdog timer */ ++ uint32 watchdog; /* 0x80 */ ++ uint32 PAD[1]; + -+ case FLASH_NONE: -+ default: -+ return; -+ } -+ } else { -+ /* extif assumed, Stop at 4 MB */ -+ base = KSEG1ADDR(SB_FLASH1); -+ lim = SB_FLASH1_SZ; -+ } ++ /* GPIO based LED powersave registers corerev >= 16 */ ++ uint32 gpiotimerval; /* 0x88 */ ++ uint32 gpiotimeroutmask; + -+ /* XXX: hack for supporting the CFE environment stuff on WGT634U */ -+ src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000); -+ dst = (u32 *) nvram_buf; -+ if ((lim == 0x02000000) && ((*src & 0xff00ff) == 0x000001)) { -+ printk("early_nvram_init: WGT634U NVRAM found.\n"); ++ /* clock control */ ++ uint32 clockcontrol_n; /* 0x90 */ ++ uint32 clockcontrol_sb; /* aka m0 */ ++ uint32 clockcontrol_pci; /* aka m1 */ ++ uint32 clockcontrol_m2; /* mii/uart/mipsref */ ++ uint32 clockcontrol_m3; /* cpu */ ++ uint32 clkdiv; /* corerev >= 3 */ ++ uint32 PAD[2]; + -+ for (i = 0; i < 0x1ff0; i++) { -+ if (*src == 0xFFFFFFFF) -+ break; -+ *dst++ = *src++; -+ } -+ cfe_env = 1; -+ return; -+ } ++ /* pll delay registers (corerev >= 4) */ ++ uint32 pll_on_delay; /* 0xb0 */ ++ uint32 fref_sel_delay; ++ uint32 slow_clk_ctl; /* 5 < corerev < 10 */ ++ uint32 PAD[1]; + -+ off = FLASH_MIN; -+ while (off <= lim) { -+ /* Windowed flash access */ -+ header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE); -+ if (header->magic == NVRAM_MAGIC) -+ goto found; -+ off <<= 1; -+ } ++ /* Instaclock registers (corerev >= 10) */ ++ uint32 system_clk_ctl; /* 0xc0 */ ++ uint32 clkstatestretch; ++ uint32 PAD[14]; + -+ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ -+ header = (struct nvram_header *) KSEG1ADDR(base + 4 KB); -+ if (header->magic == NVRAM_MAGIC) -+ goto found; -+ -+ header = (struct nvram_header *) KSEG1ADDR(base + 1 KB); -+ if (header->magic == NVRAM_MAGIC) -+ goto found; -+ -+ printk("early_nvram_init: NVRAM not found\n"); -+ return; ++ /* ExtBus control registers (corerev >= 3) */ ++ uint32 pcmcia_config; /* 0x100 */ ++ uint32 pcmcia_memwait; ++ uint32 pcmcia_attrwait; ++ uint32 pcmcia_iowait; ++ uint32 ide_config; ++ uint32 ide_memwait; ++ uint32 ide_attrwait; ++ uint32 ide_iowait; ++ uint32 prog_config; ++ uint32 prog_waitcount; ++ uint32 flash_config; ++ uint32 flash_waitcount; ++ uint32 PAD[44]; + -+found: -+ src = (u32 *) header; -+ dst = (u32 *) nvram_buf; -+ for (i = 0; i < sizeof(struct nvram_header); i += 4) -+ *dst++ = *src++; -+ for (; i < header->len && i < NVRAM_SPACE; i += 4) -+ *dst++ = ltoh32(*src++); -+} ++ /* Clock control and hardware workarounds */ ++ uint32 clk_ctl_st; ++ uint32 hw_war; ++ uint32 PAD[70]; + -+/* Early (before mm or mtd) read-only access to NVRAM */ -+static char * __init -+early_nvram_get(const char *name) -+{ -+ char *var, *value, *end, *eq; ++ /* uarts */ ++ uint8 uart0data; /* 0x300 */ ++ uint8 uart0imr; ++ uint8 uart0fcr; ++ uint8 uart0lcr; ++ uint8 uart0mcr; ++ uint8 uart0lsr; ++ uint8 uart0msr; ++ uint8 uart0scratch; ++ uint8 PAD[248]; /* corerev >= 1 */ + -+ if (!name) -+ return NULL; ++ uint8 uart1data; /* 0x400 */ ++ uint8 uart1imr; ++ uint8 uart1fcr; ++ uint8 uart1lcr; ++ uint8 uart1mcr; ++ uint8 uart1lsr; ++ uint8 uart1msr; ++ uint8 uart1scratch; ++} chipcregs_t; + -+ /* Too early? */ -+ if (sbh == NULL) -+ return NULL; ++#endif /* _LANGUAGE_ASSEMBLY */ + -+ if (!nvram_buf[0]) -+ early_nvram_init(); ++#define CC_CHIPID 0 ++#define CC_CAPABILITIES 4 ++#define CC_JTAGCMD 0x30 ++#define CC_JTAGIR 0x34 ++#define CC_JTAGDR 0x38 ++#define CC_JTAGCTRL 0x3c ++#define CC_WATCHDOG 0x80 ++#define CC_CLKC_N 0x90 ++#define CC_CLKC_M0 0x94 ++#define CC_CLKC_M1 0x98 ++#define CC_CLKC_M2 0x9c ++#define CC_CLKC_M3 0xa0 ++#define CC_CLKDIV 0xa4 ++#define CC_SYS_CLK_CTL 0xc0 ++#define CC_OTP 0x800 + -+ if (cfe_env) -+ return cfe_env_get(nvram_buf, name); ++/* chipid */ ++#define CID_ID_MASK 0x0000ffff /* Chip Id mask */ ++#define CID_REV_MASK 0x000f0000 /* Chip Revision mask */ ++#define CID_REV_SHIFT 16 /* Chip Revision shift */ ++#define CID_PKG_MASK 0x00f00000 /* Package Option mask */ ++#define CID_PKG_SHIFT 20 /* Package Option shift */ ++#define CID_CC_MASK 0x0f000000 /* CoreCount (corerev >= 4) */ ++#define CID_CC_SHIFT 24 + -+ /* Look for name=value and return value */ -+ var = &nvram_buf[sizeof(struct nvram_header)]; -+ end = nvram_buf + sizeof(nvram_buf) - 2; -+ end[0] = end[1] = '\0'; -+ for (; *var; var = value + strlen(value) + 1) { -+ if (!(eq = strchr(var, '='))) -+ break; -+ value = eq + 1; -+ if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0) -+ return value; -+ } ++/* capabilities */ ++#define CAP_UARTS_MASK 0x00000003 /* Number of uarts */ ++#define CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ ++#define CAP_UCLKSEL 0x00000018 /* UARTs clock select */ ++#define CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ ++#define CAP_UARTGPIO 0x00000020 /* UARTs own Gpio's 15:12 */ ++#define CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */ ++#define CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */ ++#define CAP_EXTBUS_FULL 0x00000040 /* ExtBus: PCMCIA, IDE & Prog */ ++#define CAP_EXTBUS_PROG 0x00000080 /* ExtBus: ProgIf only */ ++#define CAP_FLASH_MASK 0x00000700 /* Type of flash */ ++#define CAP_PLL_MASK 0x00038000 /* Type of PLL */ ++#define CAP_PWR_CTL 0x00040000 /* Power control */ ++#define CAP_OTPSIZE 0x00380000 /* OTP Size (0 = none) */ ++#define CAP_OTPSIZE_SHIFT 19 /* OTP Size shift */ ++#define CAP_OTPSIZE_BASE 5 /* OTP Size base */ ++#define CAP_JTAGP 0x00400000 /* JTAG Master Present */ ++#define CAP_ROM 0x00800000 /* Internal boot rom active */ ++#define CAP_BKPLN64 0x08000000 /* 64-bit backplane */ + -+ return NULL; -+} ++/* PLL type */ ++#define PLL_NONE 0x00000000 ++#define PLL_TYPE1 0x00010000 /* 48Mhz base, 3 dividers */ ++#define PLL_TYPE2 0x00020000 /* 48Mhz, 4 dividers */ ++#define PLL_TYPE3 0x00030000 /* 25Mhz, 2 dividers */ ++#define PLL_TYPE4 0x00008000 /* 48Mhz, 4 dividers */ ++#define PLL_TYPE5 0x00018000 /* 25Mhz, 4 dividers */ ++#define PLL_TYPE6 0x00028000 /* 100/200 or 120/240 only */ ++#define PLL_TYPE7 0x00038000 /* 25Mhz, 4 dividers */ + -+#endif /* !MODULE */ ++/* corecontrol */ ++#define CC_UARTCLKO 0x00000001 /* Drive UART with internal clock */ ++#define CC_SE 0x00000002 /* sync clk out enable (corerev >= 3) */ + -+extern char * _nvram_get(const char *name); -+extern int _nvram_set(const char *name, const char *value); -+extern int _nvram_unset(const char *name); -+extern int _nvram_getall(char *buf, int count); -+extern int _nvram_commit(struct nvram_header *header); -+extern int _nvram_init(void); -+extern void _nvram_exit(void); ++/* chipcontrol */ ++#define CHIPCTRL_4321A0_DEFAULT 0x3a4 ++#define CHIPCTRL_4321A1_DEFAULT 0x0a4 + -+/* Globals */ -+static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED; -+static struct semaphore nvram_sem; -+static unsigned long nvram_offset = 0; -+static int nvram_major = -1; -+static devfs_handle_t nvram_handle = NULL; -+static struct mtd_info *nvram_mtd = NULL; ++/* Fields in the otpstatus register */ ++#define OTPS_PROGFAIL 0x80000000 ++#define OTPS_PROTECT 0x00000007 ++#define OTPS_HW_PROTECT 0x00000001 ++#define OTPS_SW_PROTECT 0x00000002 ++#define OTPS_CID_PROTECT 0x00000004 + -+int -+_nvram_read(char *buf) -+{ -+ struct nvram_header *header = (struct nvram_header *) buf; -+ size_t len; ++/* Fields in the otpcontrol register */ ++#define OTPC_RECWAIT 0xff000000 ++#define OTPC_PROGWAIT 0x00ffff00 ++#define OTPC_PRW_SHIFT 8 ++#define OTPC_MAXFAIL 0x00000038 ++#define OTPC_VSEL 0x00000006 ++#define OTPC_SELVL 0x00000001 + -+ if (!nvram_mtd || -+ MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) || -+ len != NVRAM_SPACE || -+ header->magic != NVRAM_MAGIC) { -+ /* Maybe we can recover some data from early initialization */ -+ memcpy(buf, nvram_buf, NVRAM_SPACE); -+ } ++/* Fields in otpprog */ ++#define OTPP_COL_MASK 0x000000ff ++#define OTPP_ROW_MASK 0x0000ff00 ++#define OTPP_ROW_SHIFT 8 ++#define OTPP_READERR 0x10000000 ++#define OTPP_VALUE 0x20000000 ++#define OTPP_VALUE_SHIFT 29 ++#define OTPP_READ 0x40000000 ++#define OTPP_START 0x80000000 ++#define OTPP_BUSY 0x80000000 + -+ return 0; -+} ++/* jtagcmd */ ++#define JCMD_START 0x80000000 ++#define JCMD_BUSY 0x80000000 ++#define JCMD_PAUSE 0x40000000 ++#define JCMD0_ACC_MASK 0x0000f000 ++#define JCMD0_ACC_IRDR 0x00000000 ++#define JCMD0_ACC_DR 0x00001000 ++#define JCMD0_ACC_IR 0x00002000 ++#define JCMD0_ACC_RESET 0x00003000 ++#define JCMD0_ACC_IRPDR 0x00004000 ++#define JCMD0_ACC_PDR 0x00005000 ++#define JCMD0_IRW_MASK 0x00000f00 ++#define JCMD_ACC_MASK 0x000f0000 /* Changes for corerev 11 */ ++#define JCMD_ACC_IRDR 0x00000000 ++#define JCMD_ACC_DR 0x00010000 ++#define JCMD_ACC_IR 0x00020000 ++#define JCMD_ACC_RESET 0x00030000 ++#define JCMD_ACC_IRPDR 0x00040000 ++#define JCMD_ACC_PDR 0x00050000 ++#define JCMD_IRW_MASK 0x00001f00 ++#define JCMD_IRW_SHIFT 8 ++#define JCMD_DRW_MASK 0x0000003f + -+struct nvram_tuple * -+_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value) -+{ -+ if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE) -+ return NULL; ++/* jtagctrl */ ++#define JCTRL_FORCE_CLK 4 /* Force clock */ ++#define JCTRL_EXT_EN 2 /* Enable external targets */ ++#define JCTRL_EN 1 /* Enable Jtag master */ + -+ if (!t) { -+ if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC))) -+ return NULL; ++/* Fields in clkdiv */ ++#define CLKD_SFLASH 0x0f000000 ++#define CLKD_SFLASH_SHIFT 24 ++#define CLKD_OTP 0x000f0000 ++#define CLKD_OTP_SHIFT 16 ++#define CLKD_JTAG 0x00000f00 ++#define CLKD_JTAG_SHIFT 8 ++#define CLKD_UART 0x000000ff + -+ /* Copy name */ -+ t->name = (char *) &t[1]; -+ strcpy(t->name, name); ++/* intstatus/intmask */ ++#define CI_GPIO 0x00000001 /* gpio intr */ ++#define CI_EI 0x00000002 /* ro: ext intr pin (corerev >= 3) */ ++#define CI_WDRESET 0x80000000 /* watchdog reset occurred */ + -+ t->value = NULL; -+ } ++/* slow_clk_ctl */ ++#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ ++#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ ++#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ ++#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ ++#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ ++#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, ++ * 0: LPO is enabled ++ */ ++#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, ++ * 0: power logic control ++ */ ++#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors ++ * PLL clock disable requests from core ++ */ ++#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't ++ * disable crystal when appropriate ++ */ ++#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ ++#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ ++#define SCC_CD_SHIFT 16 + -+ /* Copy value */ -+ if (!t->value || strcmp(t->value, value)) { -+ t->value = &nvram_buf[nvram_offset]; -+ strcpy(t->value, value); -+ nvram_offset += strlen(value) + 1; -+ } -+ -+ return t; -+} ++/* system_clk_ctl */ ++#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ ++#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ ++#define SYCC_FP 0x00000004 /* ForcePLLOn */ ++#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ ++#define SYCC_HR 0x00000010 /* Force HT */ ++#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ ++#define SYCC_CD_SHIFT 16 + -+void -+_nvram_free(struct nvram_tuple *t) -+{ -+ if (!t) -+ nvram_offset = 0; -+ else -+ kfree(t); -+} ++/* gpiotimerval */ ++#define GPIO_ONTIME_SHIFT 16 + -+int -+nvram_set(const char *name, const char *value) -+{ -+ unsigned long flags; -+ int ret; -+ struct nvram_header *header; ++/* clockcontrol_n */ ++#define CN_N1_MASK 0x3f /* n1 control */ ++#define CN_N2_MASK 0x3f00 /* n2 control */ ++#define CN_N2_SHIFT 8 ++#define CN_PLLC_MASK 0xf0000 /* pll control */ ++#define CN_PLLC_SHIFT 16 + -+ spin_lock_irqsave(&nvram_lock, flags); -+ if ((ret = _nvram_set(name, value))) { -+ /* Consolidate space and try again */ -+ if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) { -+ if (_nvram_commit(header) == 0) -+ ret = _nvram_set(name, value); -+ kfree(header); -+ } -+ } -+ spin_unlock_irqrestore(&nvram_lock, flags); ++/* clockcontrol_sb/pci/uart */ ++#define CC_M1_MASK 0x3f /* m1 control */ ++#define CC_M2_MASK 0x3f00 /* m2 control */ ++#define CC_M2_SHIFT 8 ++#define CC_M3_MASK 0x3f0000 /* m3 control */ ++#define CC_M3_SHIFT 16 ++#define CC_MC_MASK 0x1f000000 /* mux control */ ++#define CC_MC_SHIFT 24 + -+ return ret; -+} ++/* N3M Clock control magic field values */ ++#define CC_F6_2 0x02 /* A factor of 2 in */ ++#define CC_F6_3 0x03 /* 6-bit fields like */ ++#define CC_F6_4 0x05 /* N1, M1 or M3 */ ++#define CC_F6_5 0x09 ++#define CC_F6_6 0x11 ++#define CC_F6_7 0x21 + -+char * -+real_nvram_get(const char *name) -+{ -+ unsigned long flags; -+ char *value; ++#define CC_F5_BIAS 5 /* 5-bit fields get this added */ + -+ spin_lock_irqsave(&nvram_lock, flags); -+ value = _nvram_get(name); -+ spin_unlock_irqrestore(&nvram_lock, flags); ++#define CC_MC_BYPASS 0x08 ++#define CC_MC_M1 0x04 ++#define CC_MC_M1M2 0x02 ++#define CC_MC_M1M2M3 0x01 ++#define CC_MC_M1M3 0x11 + -+ return value; -+} ++/* Type 2 Clock control magic field values */ ++#define CC_T2_BIAS 2 /* n1, n2, m1 & m3 bias */ ++#define CC_T2M2_BIAS 3 /* m2 bias */ + -+char * -+nvram_get(const char *name) -+{ -+ if (nvram_major >= 0) -+ return real_nvram_get(name); -+ else -+ return early_nvram_get(name); -+} ++#define CC_T2MC_M1BYP 1 ++#define CC_T2MC_M2BYP 2 ++#define CC_T2MC_M3BYP 4 + -+int -+nvram_unset(const char *name) -+{ -+ unsigned long flags; -+ int ret; ++/* Type 6 Clock control magic field values */ ++#define CC_T6_MMASK 1 /* bits of interest in m */ ++#define CC_T6_M0 120000000 /* sb clock for m = 0 */ ++#define CC_T6_M1 100000000 /* sb clock for m = 1 */ ++#define SB2MIPS_T6(sb) (2 * (sb)) + -+ spin_lock_irqsave(&nvram_lock, flags); -+ ret = _nvram_unset(name); -+ spin_unlock_irqrestore(&nvram_lock, flags); ++/* Common clock base */ ++#define CC_CLOCK_BASE1 24000000 /* Half the clock freq */ ++#define CC_CLOCK_BASE2 12500000 /* Alternate crystal on some PLL's */ + -+ return ret; -+} ++/* Clock control values for 200Mhz in 5350 */ ++#define CLKC_5350_N 0x0311 ++#define CLKC_5350_M 0x04020009 + -+static void -+erase_callback(struct erase_info *done) -+{ -+ wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv; -+ wake_up(wait_q); -+} ++/* Flash types in the chipcommon capabilities register */ ++#define FLASH_NONE 0x000 /* No flash */ ++#define SFLASH_ST 0x100 /* ST serial flash */ ++#define SFLASH_AT 0x200 /* Atmel serial flash */ ++#define PFLASH 0x700 /* Parallel flash */ + -+int -+nvram_commit(void) -+{ -+ char *buf; -+ size_t erasesize, len; -+ unsigned int i; -+ int ret; -+ struct nvram_header *header; -+ unsigned long flags; -+ u_int32_t offset; -+ DECLARE_WAITQUEUE(wait, current); -+ wait_queue_head_t wait_q; -+ struct erase_info erase; ++/* Bits in the ExtBus config registers */ ++#define CC_CFG_EN 0x0001 /* Enable */ ++#define CC_CFG_EM_MASK 0x000e /* Extif Mode */ ++#define CC_CFG_EM_ASYNC 0x0000 /* Async/Parallel flash */ ++#define CC_CFG_EM_SYNC 0x0002 /* Synchronous */ ++#define CC_CFG_EM_PCMCIA 0x0004 /* PCMCIA */ ++#define CC_CFG_EM_IDE 0x0006 /* IDE */ ++#define CC_CFG_DS 0x0010 /* Data size, 0=8bit, 1=16bit */ ++#define CC_CFG_CD_MASK 0x0060 /* Sync: Clock divisor */ ++#define CC_CFG_CE 0x0080 /* Sync: Clock enable */ ++#define CC_CFG_SB 0x0100 /* Sync: Size/Bytestrobe */ + -+ if (!nvram_mtd) { -+ printk("nvram_commit: NVRAM not found\n"); -+ return -ENODEV; -+ } ++/* ExtBus address space */ ++#define CC_EB_BASE 0x1a000000 /* Chipc ExtBus base address */ ++#define CC_EB_PCMCIA_MEM 0x1a000000 /* PCMCIA 0 memory base address */ ++#define CC_EB_PCMCIA_IO 0x1a200000 /* PCMCIA 0 I/O base address */ ++#define CC_EB_PCMCIA_CFG 0x1a400000 /* PCMCIA 0 config base address */ ++#define CC_EB_IDE 0x1a800000 /* IDE memory base */ ++#define CC_EB_PCMCIA1_MEM 0x1a800000 /* PCMCIA 1 memory base address */ ++#define CC_EB_PCMCIA1_IO 0x1aa00000 /* PCMCIA 1 I/O base address */ ++#define CC_EB_PCMCIA1_CFG 0x1ac00000 /* PCMCIA 1 config base address */ ++#define CC_EB_PROGIF 0x1b000000 /* ProgIF Async/Sync base address */ + -+ if (in_interrupt()) { -+ printk("nvram_commit: not committing in interrupt\n"); -+ return -EINVAL; -+ } + -+ /* Backup sector blocks to be erased */ -+ erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize); -+ if (!(buf = kmalloc(erasesize, GFP_KERNEL))) { -+ printk("nvram_commit: out of memory\n"); -+ return -ENOMEM; -+ } ++/* Start/busy bit in flashcontrol */ ++#define SFLASH_OPCODE 0x000000ff ++#define SFLASH_ACTION 0x00000700 ++#define SFLASH_START 0x80000000 ++#define SFLASH_BUSY SFLASH_START + -+ down(&nvram_sem); ++/* flashcontrol action codes */ ++#define SFLASH_ACT_OPONLY 0x0000 /* Issue opcode only */ ++#define SFLASH_ACT_OP1D 0x0100 /* opcode + 1 data byte */ ++#define SFLASH_ACT_OP3A 0x0200 /* opcode + 3 address bytes */ ++#define SFLASH_ACT_OP3A1D 0x0300 /* opcode + 3 addres & 1 data bytes */ ++#define SFLASH_ACT_OP3A4D 0x0400 /* opcode + 3 addres & 4 data bytes */ ++#define SFLASH_ACT_OP3A4X4D 0x0500 /* opcode + 3 addres, 4 don't care & 4 data bytes */ ++#define SFLASH_ACT_OP3A1X4D 0x0700 /* opcode + 3 addres, 1 don't care & 4 data bytes */ + -+ if ((i = erasesize - NVRAM_SPACE) > 0) { -+ offset = nvram_mtd->size - erasesize; -+ len = 0; -+ ret = MTD_READ(nvram_mtd, offset, i, &len, buf); -+ if (ret || len != i) { -+ printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i); -+ ret = -EIO; -+ goto done; -+ } -+ header = (struct nvram_header *)(buf + i); -+ } else { -+ offset = nvram_mtd->size - NVRAM_SPACE; -+ header = (struct nvram_header *)buf; -+ } ++/* flashcontrol action+opcodes for ST flashes */ ++#define SFLASH_ST_WREN 0x0006 /* Write Enable */ ++#define SFLASH_ST_WRDIS 0x0004 /* Write Disable */ ++#define SFLASH_ST_RDSR 0x0105 /* Read Status Register */ ++#define SFLASH_ST_WRSR 0x0101 /* Write Status Register */ ++#define SFLASH_ST_READ 0x0303 /* Read Data Bytes */ ++#define SFLASH_ST_PP 0x0302 /* Page Program */ ++#define SFLASH_ST_SE 0x02d8 /* Sector Erase */ ++#define SFLASH_ST_BE 0x00c7 /* Bulk Erase */ ++#define SFLASH_ST_DP 0x00b9 /* Deep Power-down */ ++#define SFLASH_ST_RES 0x03ab /* Read Electronic Signature */ + -+ /* Regenerate NVRAM */ -+ spin_lock_irqsave(&nvram_lock, flags); -+ ret = _nvram_commit(header); -+ spin_unlock_irqrestore(&nvram_lock, flags); -+ if (ret) -+ goto done; ++/* Status register bits for ST flashes */ ++#define SFLASH_ST_WIP 0x01 /* Write In Progress */ ++#define SFLASH_ST_WEL 0x02 /* Write Enable Latch */ ++#define SFLASH_ST_BP_MASK 0x1c /* Block Protect */ ++#define SFLASH_ST_BP_SHIFT 2 ++#define SFLASH_ST_SRWD 0x80 /* Status Register Write Disable */ + -+ /* Erase sector blocks */ -+ init_waitqueue_head(&wait_q); -+ for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) { -+ erase.mtd = nvram_mtd; -+ erase.addr = offset; -+ erase.len = nvram_mtd->erasesize; -+ erase.callback = erase_callback; -+ erase.priv = (u_long) &wait_q; ++/* flashcontrol action+opcodes for Atmel flashes */ ++#define SFLASH_AT_READ 0x07e8 ++#define SFLASH_AT_PAGE_READ 0x07d2 ++#define SFLASH_AT_BUF1_READ ++#define SFLASH_AT_BUF2_READ ++#define SFLASH_AT_STATUS 0x01d7 ++#define SFLASH_AT_BUF1_WRITE 0x0384 ++#define SFLASH_AT_BUF2_WRITE 0x0387 ++#define SFLASH_AT_BUF1_ERASE_PROGRAM 0x0283 ++#define SFLASH_AT_BUF2_ERASE_PROGRAM 0x0286 ++#define SFLASH_AT_BUF1_PROGRAM 0x0288 ++#define SFLASH_AT_BUF2_PROGRAM 0x0289 ++#define SFLASH_AT_PAGE_ERASE 0x0281 ++#define SFLASH_AT_BLOCK_ERASE 0x0250 ++#define SFLASH_AT_BUF1_WRITE_ERASE_PROGRAM 0x0382 ++#define SFLASH_AT_BUF2_WRITE_ERASE_PROGRAM 0x0385 ++#define SFLASH_AT_BUF1_LOAD 0x0253 ++#define SFLASH_AT_BUF2_LOAD 0x0255 ++#define SFLASH_AT_BUF1_COMPARE 0x0260 ++#define SFLASH_AT_BUF2_COMPARE 0x0261 ++#define SFLASH_AT_BUF1_REPROGRAM 0x0258 ++#define SFLASH_AT_BUF2_REPROGRAM 0x0259 + -+ set_current_state(TASK_INTERRUPTIBLE); -+ add_wait_queue(&wait_q, &wait); ++/* Status register bits for Atmel flashes */ ++#define SFLASH_AT_READY 0x80 ++#define SFLASH_AT_MISMATCH 0x40 ++#define SFLASH_AT_ID_MASK 0x38 ++#define SFLASH_AT_ID_SHIFT 3 + -+ /* Unlock sector blocks */ -+ if (nvram_mtd->unlock) -+ nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize); ++/* OTP regions */ ++#define OTP_HW_REGION OTPS_HW_PROTECT ++#define OTP_SW_REGION OTPS_SW_PROTECT ++#define OTP_CID_REGION OTPS_CID_PROTECT + -+ if ((ret = MTD_ERASE(nvram_mtd, &erase))) { -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&wait_q, &wait); -+ printk("nvram_commit: erase error\n"); -+ goto done; -+ } ++/* OTP regions (Byte offsets from otp size) */ ++#define OTP_SWLIM_OFF (-8) ++#define OTP_CIDBASE_OFF 0 ++#define OTP_CIDLIM_OFF 8 + -+ /* Wait for erase to finish */ -+ schedule(); -+ remove_wait_queue(&wait_q, &wait); -+ } ++/* Predefined OTP words (Word offset from otp size) */ ++#define OTP_BOUNDARY_OFF (-4) ++#define OTP_HWSIGN_OFF (-3) ++#define OTP_SWSIGN_OFF (-2) ++#define OTP_CIDSIGN_OFF (-1) + -+ /* Write partition up to end of data area */ -+ offset = nvram_mtd->size - erasesize; -+ i = erasesize - NVRAM_SPACE + header->len; -+ ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf); -+ if (ret || len != i) { -+ printk("nvram_commit: write error\n"); -+ ret = -EIO; -+ goto done; -+ } ++#define OTP_CID_OFF 0 ++#define OTP_PKG_OFF 1 ++#define OTP_FID_OFF 2 ++#define OTP_RSV_OFF 3 ++#define OTP_LIM_OFF 4 + -+ offset = nvram_mtd->size - erasesize; -+ ret = MTD_READ(nvram_mtd, offset, 4, &len, buf); ++#define OTP_SIGNATURE 0x578a ++#define OTP_MAGIC 0x4e56 + -+ done: -+ up(&nvram_sem); -+ kfree(buf); -+ return ret; -+} -+ -+int -+nvram_getall(char *buf, int count) -+{ -+ unsigned long flags; -+ int ret; -+ -+ spin_lock_irqsave(&nvram_lock, flags); -+ ret = _nvram_getall(buf, count); -+ spin_unlock_irqrestore(&nvram_lock, flags); ++/* ++ * These are the UART port assignments, expressed as offsets from the base ++ * register. These assignments should hold for any serial port based on ++ * a 8250, 16450, or 16550(A). ++ */ + -+ return ret; -+} ++#define UART_RX 0 /* In: Receive buffer (DLAB=0) */ ++#define UART_TX 0 /* Out: Transmit buffer (DLAB=0) */ ++#define UART_DLL 0 /* Out: Divisor Latch Low (DLAB=1) */ ++#define UART_IER 1 /* In/Out: Interrupt Enable Register (DLAB=0) */ ++#define UART_DLM 1 /* Out: Divisor Latch High (DLAB=1) */ ++#define UART_IIR 2 /* In: Interrupt Identity Register */ ++#define UART_FCR 2 /* Out: FIFO Control Register */ ++#define UART_LCR 3 /* Out: Line Control Register */ ++#define UART_MCR 4 /* Out: Modem Control Register */ ++#define UART_LSR 5 /* In: Line Status Register */ ++#define UART_MSR 6 /* In: Modem Status Register */ ++#define UART_SCR 7 /* I/O: Scratch Register */ ++#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ ++#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ ++#define UART_MCR_OUT2 0x08 /* MCR GPIO out 2 */ ++#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ ++#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ ++#define UART_LSR_RXRDY 0x01 /* Receiver ready */ ++#define UART_FCR_FIFO_ENABLE 1 /* FIFO control register bit controlling FIFO enable/disable */ + -+EXPORT_SYMBOL(nvram_get); -+EXPORT_SYMBOL(nvram_getall); -+EXPORT_SYMBOL(nvram_set); -+EXPORT_SYMBOL(nvram_unset); -+EXPORT_SYMBOL(nvram_commit); ++/* Interrupt Enable Register (IER) bits */ ++#define UART_IER_EDSSI 8 /* enable modem status interrupt */ ++#define UART_IER_ELSI 4 /* enable receiver line status interrupt */ ++#define UART_IER_ETBEI 2 /* enable transmitter holding register empty interrupt */ ++#define UART_IER_ERBFI 1 /* enable data available interrupt */ + -+/* User mode interface below */ ++#endif /* _SBCHIPC_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bcm947xx/include/sbconfig.h +--- linux.old/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbconfig.h 2006-04-27 22:14:11.000000000 +0200 +@@ -0,0 +1,369 @@ ++/* ++ * Broadcom SiliconBackplane hardware register definitions. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sbconfig.h,v 1.1.1.11 2006/02/27 03:43:16 honor Exp $ ++ */ + -+static ssize_t -+dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos) -+{ -+ char tmp[100], *name = tmp, *value; -+ ssize_t ret; -+ unsigned long off; ++#ifndef _SBCONFIG_H ++#define _SBCONFIG_H + -+ if (count > sizeof(tmp)) { -+ if (!(name = kmalloc(count, GFP_KERNEL))) -+ return -ENOMEM; -+ } ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif + -+ if (copy_from_user(name, buf, count)) { -+ ret = -EFAULT; -+ goto done; -+ } ++/* ++ * SiliconBackplane Address Map. ++ * All regions may not exist on all chips. ++ */ ++#define SB_SDRAM_BASE 0x00000000 /* Physical SDRAM */ ++#define SB_PCI_MEM 0x08000000 /* Host Mode sb2pcitranslation0 (64 MB) */ ++#define SB_PCI_MEM_SZ (64 * 1024 * 1024) ++#define SB_PCI_CFG 0x0c000000 /* Host Mode sb2pcitranslation1 (64 MB) */ ++#define SB_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define SB_ENUM_BASE 0x18000000 /* Enumeration space base */ ++#define SB_ENUM_LIM 0x18010000 /* Enumeration space limit */ + -+ if (*name == '\0') { -+ /* Get all variables */ -+ ret = nvram_getall(name, count); -+ if (ret == 0) { -+ if (copy_to_user(buf, name, count)) { -+ ret = -EFAULT; -+ goto done; -+ } -+ ret = count; -+ } -+ } else { -+ if (!(value = nvram_get(name))) { -+ ret = 0; -+ goto done; -+ } ++#define SB_FLASH2 0x1c000000 /* Flash Region 2 (region 1 shadowed here) */ ++#define SB_FLASH2_SZ 0x02000000 /* Size of Flash Region 2 */ + -+ /* Provide the offset into mmap() space */ -+ off = (unsigned long) value - (unsigned long) nvram_buf; ++#define SB_EXTIF_BASE 0x1f000000 /* External Interface region base address */ ++#define SB_FLASH1 0x1fc00000 /* MIPS Flash Region 1 */ ++#define SB_FLASH1_SZ 0x00400000 /* MIPS Size of Flash Region 1 */ + -+ if (put_user(off, (unsigned long *) buf)) { -+ ret = -EFAULT; -+ goto done; -+ } ++#define SB_ROM 0x20000000 /* ARM ROM */ ++#define SB_SRAM2 0x80000000 /* ARM SRAM Region 2 */ ++#define SB_ARM_FLASH1 0xffff0000 /* ARM Flash Region 1 */ ++#define SB_ARM_FLASH1_SZ 0x00010000 /* ARM Size of Flash Region 1 */ + -+ ret = sizeof(unsigned long); -+ } ++#define SB_PCI_DMA 0x40000000 /* Client Mode sb2pcitranslation2 (1 GB) */ ++#define SB_PCI_DMA_SZ 0x40000000 /* Client Mode sb2pcitranslation2 size in bytes */ ++#define SB_PCIE_DMA_L32 0x00000000 /* PCIE Client Mode sb2pcitranslation2 ++ * (2 ZettaBytes), low 32 bits ++ */ ++#define SB_PCIE_DMA_H32 0x80000000 /* PCIE Client Mode sb2pcitranslation2 ++ * (2 ZettaBytes), high 32 bits ++ */ ++#define SB_EUART (SB_EXTIF_BASE + 0x00800000) ++#define SB_LED (SB_EXTIF_BASE + 0x00900000) + -+ flush_cache_all(); -+ -+done: -+ if (name != tmp) -+ kfree(name); + -+ return ret; -+} ++/* enumeration space related defs */ ++#define SB_CORE_SIZE 0x1000 /* each core gets 4Kbytes for registers */ ++#define SB_MAXCORES ((SB_ENUM_LIM - SB_ENUM_BASE)/SB_CORE_SIZE) ++#define SB_MAXFUNCS 4 /* max. # functions per core */ ++#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ ++#define SBCONFIGSIZE 256 /* sizeof (sbconfig_t) */ + -+static ssize_t -+dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -+{ -+ char tmp[100], *name = tmp, *value; -+ ssize_t ret; ++/* mips address */ ++#define SB_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ + -+ if (count > sizeof(tmp)) { -+ if (!(name = kmalloc(count, GFP_KERNEL))) -+ return -ENOMEM; -+ } ++/* ++ * Sonics Configuration Space Registers. ++ */ ++#define SBIPSFLAG 0x08 ++#define SBTPSFLAG 0x18 ++#define SBTMERRLOGA 0x48 /* sonics >= 2.3 */ ++#define SBTMERRLOG 0x50 /* sonics >= 2.3 */ ++#define SBADMATCH3 0x60 ++#define SBADMATCH2 0x68 ++#define SBADMATCH1 0x70 ++#define SBIMSTATE 0x90 ++#define SBINTVEC 0x94 ++#define SBTMSTATELOW 0x98 ++#define SBTMSTATEHIGH 0x9c ++#define SBBWA0 0xa0 ++#define SBIMCONFIGLOW 0xa8 ++#define SBIMCONFIGHIGH 0xac ++#define SBADMATCH0 0xb0 ++#define SBTMCONFIGLOW 0xb8 ++#define SBTMCONFIGHIGH 0xbc ++#define SBBCONFIG 0xc0 ++#define SBBSTATE 0xc8 ++#define SBACTCNFG 0xd8 ++#define SBFLAGST 0xe8 ++#define SBIDLOW 0xf8 ++#define SBIDHIGH 0xfc + -+ if (copy_from_user(name, buf, count)) { -+ ret = -EFAULT; -+ goto done; -+ } ++/* All the previous registers are above SBCONFIGOFF, but with Sonics 2.3, we have ++ * a few registers *below* that line. I think it would be very confusing to try ++ * and change the value of SBCONFIGOFF, so I'm definig them as absolute offsets here, ++ */ + -+ value = name; -+ name = strsep(&value, "="); -+ if (value) -+ ret = nvram_set(name, value) ? : count; -+ else -+ ret = nvram_unset(name) ? : count; ++#define SBIMERRLOGA 0xea8 ++#define SBIMERRLOG 0xeb0 ++#define SBTMPORTCONNID0 0xed8 ++#define SBTMPORTLOCK0 0xef8 + -+ done: -+ if (name != tmp) -+ kfree(name); ++#ifndef _LANGUAGE_ASSEMBLY + -+ return ret; -+} ++typedef volatile struct _sbconfig { ++ uint32 PAD[2]; ++ uint32 sbipsflag; /* initiator port ocp slave flag */ ++ uint32 PAD[3]; ++ uint32 sbtpsflag; /* target port ocp slave flag */ ++ uint32 PAD[11]; ++ uint32 sbtmerrloga; /* (sonics >= 2.3) */ ++ uint32 PAD; ++ uint32 sbtmerrlog; /* (sonics >= 2.3) */ ++ uint32 PAD[3]; ++ uint32 sbadmatch3; /* address match3 */ ++ uint32 PAD; ++ uint32 sbadmatch2; /* address match2 */ ++ uint32 PAD; ++ uint32 sbadmatch1; /* address match1 */ ++ uint32 PAD[7]; ++ uint32 sbimstate; /* initiator agent state */ ++ uint32 sbintvec; /* interrupt mask */ ++ uint32 sbtmstatelow; /* target state */ ++ uint32 sbtmstatehigh; /* target state */ ++ uint32 sbbwa0; /* bandwidth allocation table0 */ ++ uint32 PAD; ++ uint32 sbimconfiglow; /* initiator configuration */ ++ uint32 sbimconfighigh; /* initiator configuration */ ++ uint32 sbadmatch0; /* address match0 */ ++ uint32 PAD; ++ uint32 sbtmconfiglow; /* target configuration */ ++ uint32 sbtmconfighigh; /* target configuration */ ++ uint32 sbbconfig; /* broadcast configuration */ ++ uint32 PAD; ++ uint32 sbbstate; /* broadcast state */ ++ uint32 PAD[3]; ++ uint32 sbactcnfg; /* activate configuration */ ++ uint32 PAD[3]; ++ uint32 sbflagst; /* current sbflags */ ++ uint32 PAD[3]; ++ uint32 sbidlow; /* identification */ ++ uint32 sbidhigh; /* identification */ ++} sbconfig_t; + -+static int -+dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) -+{ -+ if (cmd != NVRAM_MAGIC) -+ return -EINVAL; -+ return nvram_commit(); -+} ++#endif /* _LANGUAGE_ASSEMBLY */ + -+static int -+dev_nvram_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ unsigned long offset = virt_to_phys(nvram_buf); ++/* sbipsflag */ ++#define SBIPS_INT1_MASK 0x3f /* which sbflags get routed to mips interrupt 1 */ ++#define SBIPS_INT1_SHIFT 0 ++#define SBIPS_INT2_MASK 0x3f00 /* which sbflags get routed to mips interrupt 2 */ ++#define SBIPS_INT2_SHIFT 8 ++#define SBIPS_INT3_MASK 0x3f0000 /* which sbflags get routed to mips interrupt 3 */ ++#define SBIPS_INT3_SHIFT 16 ++#define SBIPS_INT4_MASK 0x3f000000 /* which sbflags get routed to mips interrupt 4 */ ++#define SBIPS_INT4_SHIFT 24 + -+ if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start, -+ vma->vm_page_prot)) -+ return -EAGAIN; ++/* sbtpsflag */ ++#define SBTPS_NUM0_MASK 0x3f /* interrupt sbFlag # generated by this core */ ++#define SBTPS_F0EN0 0x40 /* interrupt is always sent on the backplane */ + -+ return 0; -+} ++/* sbtmerrlog */ ++#define SBTMEL_CM 0x00000007 /* command */ ++#define SBTMEL_CI 0x0000ff00 /* connection id */ ++#define SBTMEL_EC 0x0f000000 /* error code */ ++#define SBTMEL_ME 0x80000000 /* multiple error */ + -+static int -+dev_nvram_open(struct inode *inode, struct file * file) -+{ -+ MOD_INC_USE_COUNT; -+ return 0; -+} -+ -+static int -+dev_nvram_release(struct inode *inode, struct file * file) -+{ -+ MOD_DEC_USE_COUNT; -+ return 0; -+} ++/* sbimstate */ ++#define SBIM_PC 0xf /* pipecount */ ++#define SBIM_AP_MASK 0x30 /* arbitration policy */ ++#define SBIM_AP_BOTH 0x00 /* use both timeslaces and token */ ++#define SBIM_AP_TS 0x10 /* use timesliaces only */ ++#define SBIM_AP_TK 0x20 /* use token only */ ++#define SBIM_AP_RSV 0x30 /* reserved */ ++#define SBIM_IBE 0x20000 /* inbanderror */ ++#define SBIM_TO 0x40000 /* timeout */ ++#define SBIM_BY 0x01800000 /* busy (sonics >= 2.3) */ ++#define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ + -+static struct file_operations dev_nvram_fops = { -+ owner: THIS_MODULE, -+ open: dev_nvram_open, -+ release: dev_nvram_release, -+ read: dev_nvram_read, -+ write: dev_nvram_write, -+ ioctl: dev_nvram_ioctl, -+ mmap: dev_nvram_mmap, -+}; ++/* sbtmstatelow */ ++#define SBTML_RESET 0x1 /* reset */ ++#define SBTML_REJ_MASK 0x6 /* reject */ ++#define SBTML_REJ_SHIFT 1 ++#define SBTML_CLK 0x10000 /* clock enable */ ++#define SBTML_FGC 0x20000 /* force gated clocks on */ ++#define SBTML_FL_MASK 0x3ffc0000 /* core-specific flags */ ++#define SBTML_PE 0x40000000 /* pme enable */ ++#define SBTML_BE 0x80000000 /* bist enable */ + -+static void -+dev_nvram_exit(void) -+{ -+ int order = 0; -+ struct page *page, *end; ++/* sbtmstatehigh */ ++#define SBTMH_SERR 0x1 /* serror */ ++#define SBTMH_INT 0x2 /* interrupt */ ++#define SBTMH_BUSY 0x4 /* busy */ ++#define SBTMH_TO 0x00000020 /* timeout (sonics >= 2.3) */ ++#define SBTMH_FL_MASK 0x1fff0000 /* core-specific flags */ ++#define SBTMH_DMA64 0x10000000 /* supports DMA with 64-bit addresses */ ++#define SBTMH_GCR 0x20000000 /* gated clock request */ ++#define SBTMH_BISTF 0x40000000 /* bist failed */ ++#define SBTMH_BISTD 0x80000000 /* bist done */ + -+ if (nvram_handle) -+ devfs_unregister(nvram_handle); + -+ if (nvram_major >= 0) -+ devfs_unregister_chrdev(nvram_major, "nvram"); ++/* sbbwa0 */ ++#define SBBWA_TAB0_MASK 0xffff /* lookup table 0 */ ++#define SBBWA_TAB1_MASK 0xffff /* lookup table 1 */ ++#define SBBWA_TAB1_SHIFT 16 + -+ if (nvram_mtd) -+ put_mtd_device(nvram_mtd); ++/* sbimconfiglow */ ++#define SBIMCL_STO_MASK 0x7 /* service timeout */ ++#define SBIMCL_RTO_MASK 0x70 /* request timeout */ ++#define SBIMCL_RTO_SHIFT 4 ++#define SBIMCL_CID_MASK 0xff0000 /* connection id */ ++#define SBIMCL_CID_SHIFT 16 + -+ while ((PAGE_SIZE << order) < NVRAM_SPACE) -+ order++; -+ end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1); -+ for (page = virt_to_page(nvram_buf); page <= end; page++) -+ mem_map_unreserve(page); ++/* sbimconfighigh */ ++#define SBIMCH_IEM_MASK 0xc /* inband error mode */ ++#define SBIMCH_TEM_MASK 0x30 /* timeout error mode */ ++#define SBIMCH_TEM_SHIFT 4 ++#define SBIMCH_BEM_MASK 0xc0 /* bus error mode */ ++#define SBIMCH_BEM_SHIFT 6 + -+ _nvram_exit(); -+} ++/* sbadmatch0 */ ++#define SBAM_TYPE_MASK 0x3 /* address type */ ++#define SBAM_AD64 0x4 /* reserved */ ++#define SBAM_ADINT0_MASK 0xf8 /* type0 size */ ++#define SBAM_ADINT0_SHIFT 3 ++#define SBAM_ADINT1_MASK 0x1f8 /* type1 size */ ++#define SBAM_ADINT1_SHIFT 3 ++#define SBAM_ADINT2_MASK 0x1f8 /* type2 size */ ++#define SBAM_ADINT2_SHIFT 3 ++#define SBAM_ADEN 0x400 /* enable */ ++#define SBAM_ADNEG 0x800 /* negative decode */ ++#define SBAM_BASE0_MASK 0xffffff00 /* type0 base address */ ++#define SBAM_BASE0_SHIFT 8 ++#define SBAM_BASE1_MASK 0xfffff000 /* type1 base address for the core */ ++#define SBAM_BASE1_SHIFT 12 ++#define SBAM_BASE2_MASK 0xffff0000 /* type2 base address for the core */ ++#define SBAM_BASE2_SHIFT 16 + -+static int __init -+dev_nvram_init(void) -+{ -+ int order = 0, ret = 0; -+ struct page *page, *end; -+ unsigned int i; ++/* sbtmconfiglow */ ++#define SBTMCL_CD_MASK 0xff /* clock divide */ ++#define SBTMCL_CO_MASK 0xf800 /* clock offset */ ++#define SBTMCL_CO_SHIFT 11 ++#define SBTMCL_IF_MASK 0xfc0000 /* interrupt flags */ ++#define SBTMCL_IF_SHIFT 18 ++#define SBTMCL_IM_MASK 0x3000000 /* interrupt mode */ ++#define SBTMCL_IM_SHIFT 24 + -+ /* Allocate and reserve memory to mmap() */ -+ while ((PAGE_SIZE << order) < NVRAM_SPACE) -+ order++; -+ end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1); -+ for (page = virt_to_page(nvram_buf); page <= end; page++) -+ mem_map_reserve(page); ++/* sbtmconfighigh */ ++#define SBTMCH_BM_MASK 0x3 /* busy mode */ ++#define SBTMCH_RM_MASK 0x3 /* retry mode */ ++#define SBTMCH_RM_SHIFT 2 ++#define SBTMCH_SM_MASK 0x30 /* stop mode */ ++#define SBTMCH_SM_SHIFT 4 ++#define SBTMCH_EM_MASK 0x300 /* sb error mode */ ++#define SBTMCH_EM_SHIFT 8 ++#define SBTMCH_IM_MASK 0xc00 /* int mode */ ++#define SBTMCH_IM_SHIFT 10 + -+#ifdef CONFIG_MTD -+ /* Find associated MTD device */ -+ for (i = 0; i < MAX_MTD_DEVICES; i++) { -+ nvram_mtd = get_mtd_device(NULL, i); -+ if (nvram_mtd) { -+ if (!strcmp(nvram_mtd->name, "nvram") && -+ nvram_mtd->size >= NVRAM_SPACE) -+ break; -+ put_mtd_device(nvram_mtd); -+ } -+ } -+ if (i >= MAX_MTD_DEVICES) -+ nvram_mtd = NULL; -+#endif ++/* sbbconfig */ ++#define SBBC_LAT_MASK 0x3 /* sb latency */ ++#define SBBC_MAX0_MASK 0xf0000 /* maxccntr0 */ ++#define SBBC_MAX0_SHIFT 16 ++#define SBBC_MAX1_MASK 0xf00000 /* maxccntr1 */ ++#define SBBC_MAX1_SHIFT 20 + -+ /* Initialize hash table lock */ -+ spin_lock_init(&nvram_lock); ++/* sbbstate */ ++#define SBBS_SRD 0x1 /* st reg disable */ ++#define SBBS_HRD 0x2 /* hold reg disable */ + -+ /* Initialize commit semaphore */ -+ init_MUTEX(&nvram_sem); ++/* sbidlow */ ++#define SBIDL_CS_MASK 0x3 /* config space */ ++#define SBIDL_AR_MASK 0x38 /* # address ranges supported */ ++#define SBIDL_AR_SHIFT 3 ++#define SBIDL_SYNCH 0x40 /* sync */ ++#define SBIDL_INIT 0x80 /* initiator */ ++#define SBIDL_MINLAT_MASK 0xf00 /* minimum backplane latency */ ++#define SBIDL_MINLAT_SHIFT 8 ++#define SBIDL_MAXLAT 0xf000 /* maximum backplane latency */ ++#define SBIDL_MAXLAT_SHIFT 12 ++#define SBIDL_FIRST 0x10000 /* this initiator is first */ ++#define SBIDL_CW_MASK 0xc0000 /* cycle counter width */ ++#define SBIDL_CW_SHIFT 18 ++#define SBIDL_TP_MASK 0xf00000 /* target ports */ ++#define SBIDL_TP_SHIFT 20 ++#define SBIDL_IP_MASK 0xf000000 /* initiator ports */ ++#define SBIDL_IP_SHIFT 24 ++#define SBIDL_RV_MASK 0xf0000000 /* sonics backplane revision code */ ++#define SBIDL_RV_SHIFT 28 ++#define SBIDL_RV_2_2 0x00000000 /* version 2.2 or earlier */ ++#define SBIDL_RV_2_3 0x10000000 /* version 2.3 */ + -+ /* Register char device */ -+ if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) { -+ ret = nvram_major; -+ goto err; -+ } ++/* sbidhigh */ ++#define SBIDH_RC_MASK 0x000f /* revision code */ ++#define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ ++#define SBIDH_RCE_SHIFT 8 ++#define SBCOREREV(sbidh) \ ++ ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) ++#define SBIDH_CC_MASK 0x8ff0 /* core code */ ++#define SBIDH_CC_SHIFT 4 ++#define SBIDH_VC_MASK 0xffff0000 /* vendor code */ ++#define SBIDH_VC_SHIFT 16 + -+ /* Initialize hash table */ -+ _nvram_init(); ++#define SB_COMMIT 0xfd8 /* update buffered registers value */ + -+ /* Create /dev/nvram handle */ -+ nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0, -+ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL); ++/* vendor codes */ ++#define SB_VEND_BCM 0x4243 /* Broadcom's SB vendor code */ + -+ /* Set the SDRAM NCDL value into NVRAM if not already done */ -+ if (getintvar(NULL, "sdram_ncdl") == 0) { -+ unsigned int ncdl; -+ char buf[] = "0x00000000"; ++/* core codes */ ++#define SB_NODEV 0x700 /* Invalid coreid */ ++#define SB_CC 0x800 /* chipcommon core */ ++#define SB_ILINE20 0x801 /* iline20 core */ ++#define SB_SDRAM 0x803 /* sdram core */ ++#define SB_PCI 0x804 /* pci core */ ++#define SB_MIPS 0x805 /* mips core */ ++#define SB_ENET 0x806 /* enet mac core */ ++#define SB_CODEC 0x807 /* v90 codec core */ ++#define SB_USB 0x808 /* usb 1.1 host/device core */ ++#define SB_ADSL 0x809 /* ADSL core */ ++#define SB_ILINE100 0x80a /* iline100 core */ ++#define SB_IPSEC 0x80b /* ipsec core */ ++#define SB_PCMCIA 0x80d /* pcmcia core */ ++#define SB_SDIOD SB_PCMCIA /* pcmcia core has sdio device */ ++#define SB_SOCRAM 0x80e /* internal memory core */ ++#define SB_MEMC 0x80f /* memc sdram core */ ++#define SB_EXTIF 0x811 /* external interface core */ ++#define SB_D11 0x812 /* 802.11 MAC core */ ++#define SB_MIPS33 0x816 /* mips3302 core */ ++#define SB_USB11H 0x817 /* usb 1.1 host core */ ++#define SB_USB11D 0x818 /* usb 1.1 device core */ ++#define SB_USB20H 0x819 /* usb 2.0 host core */ ++#define SB_USB20D 0x81a /* usb 2.0 device core */ ++#define SB_SDIOH 0x81b /* sdio host core */ ++#define SB_ROBO 0x81c /* roboswitch core */ ++#define SB_ATA100 0x81d /* parallel ATA core */ ++#define SB_SATAXOR 0x81e /* serial ATA & XOR DMA core */ ++#define SB_GIGETH 0x81f /* gigabit ethernet core */ ++#define SB_PCIE 0x820 /* pci express core */ ++#define SB_MIMO 0x821 /* MIMO phy core */ ++#define SB_SRAMC 0x822 /* SRAM controller core */ ++#define SB_MINIMAC 0x823 /* MINI MAC/phy core */ ++#define SB_ARM11 0x824 /* ARM 1176 core */ ++#define SB_ARM7 0x825 /* ARM 7tdmi core */ + -+ if ((ncdl = sb_memc_get_ncdl(sbh))) { -+ sprintf(buf, "0x%08x", ncdl); -+ nvram_set("sdram_ncdl", buf); -+ nvram_commit(); -+ } -+ } ++#define SB_CC_IDX 0 /* chipc, when present, is always core 0 */ + -+ return 0; ++/* Not really related to Silicon Backplane, but a couple of software ++ * conventions for the use the flash space: ++ */ + -+ err: -+ dev_nvram_exit(); -+ return ret; -+} ++/* Minumum amount of flash we support */ ++#define FLASH_MIN 0x00020000 /* Minimum flash size */ + -+module_init(dev_nvram_init); -+module_exit(dev_nvram_exit); -diff -Naur linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/pcibios.c ---- linux.old/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/pcibios.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,355 @@ -+/* -+ * Low-Level PCI and SB support for BCM47xx (Linux support code) -+ * -+ * Copyright 2005, Broadcom Corporation ++/* A boot/binary may have an embedded block that describes its size */ ++#define BISZ_OFFSET 0x3e0 /* At this offset into the binary */ ++#define BISZ_MAGIC 0x4249535a /* Marked with this value: 'BISZ' */ ++#define BISZ_MAGIC_IDX 0 /* Word 0: magic */ ++#define BISZ_TXTST_IDX 1 /* 1: text start */ ++#define BISZ_TXTEND_IDX 2 /* 2: text start */ ++#define BISZ_DATAST_IDX 3 /* 3: text start */ ++#define BISZ_DATAEND_IDX 4 /* 4: text start */ ++#define BISZ_BSSST_IDX 5 /* 5: text start */ ++#define BISZ_BSSEND_IDX 6 /* 6: text start */ ++#define BISZ_SIZE 7 /* descriptor size in 32-bit intergers */ ++ ++#endif /* _SBCONFIG_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbextif.h linux.dev/arch/mips/bcm947xx/include/sbextif.h +--- linux.old/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbextif.h 2006-04-27 22:13:03.000000000 +0200 +@@ -0,0 +1,243 @@ ++/* ++ * Hardware-specific External Interface I/O core definitions ++ * for the BCM47xx family of SiliconBackplane-based chips. ++ * ++ * The External Interface core supports a total of three external chip selects ++ * supporting external interfaces. One of the external chip selects is ++ * used for Flash, one is used for PCMCIA, and the other may be ++ * programmed to support either a synchronous interface or an ++ * asynchronous interface. The asynchronous interface can be used to ++ * support external devices such as UARTs and the BCM2019 Bluetooth ++ * baseband processor. ++ * The external interface core also contains 2 on-chip 16550 UARTs, clock ++ * frequency control, a watchdog interrupt timer, and a GPIO interface. ++ * ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -6974,403 +6960,437 @@ diff -Naur linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/p + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id$ ++ * $Id: sbextif.h,v 1.1.1.8 2006/02/27 03:43:16 honor Exp $ + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Global SB handle */ -+extern sb_t *bcm947xx_sbh; -+extern spinlock_t bcm947xx_sbh_lock; -+ -+/* Convenience */ -+#define sbh bcm947xx_sbh -+#define sbh_lock bcm947xx_sbh_lock ++#ifndef _SBEXTIF_H ++#define _SBEXTIF_H + -+static int -+sbpci_read_config_byte(struct pci_dev *dev, int where, u8 *value) -+{ -+ unsigned long flags; -+ int ret; ++/* external interface address space */ ++#define EXTIF_PCMCIA_MEMBASE(x) (x) ++#define EXTIF_PCMCIA_IOBASE(x) ((x) + 0x100000) ++#define EXTIF_PCMCIA_CFGBASE(x) ((x) + 0x200000) ++#define EXTIF_CFGIF_BASE(x) ((x) + 0x800000) ++#define EXTIF_FLASH_BASE(x) ((x) + 0xc00000) + -+ spin_lock_irqsave(&sbh_lock, flags); -+ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value)); -+ spin_unlock_irqrestore(&sbh_lock, flags); -+ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -+} ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ + -+static int -+sbpci_read_config_word(struct pci_dev *dev, int where, u16 *value) -+{ -+ unsigned long flags; -+ int ret; ++/* ++ * The multiple instances of output and output enable registers ++ * are present to allow driver software for multiple cores to control ++ * gpio outputs without needing to share a single register pair. ++ */ ++struct gpiouser { ++ uint32 out; ++ uint32 outen; ++}; ++#define NGPIOUSER 5 + -+ spin_lock_irqsave(&sbh_lock, flags); -+ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value)); -+ spin_unlock_irqrestore(&sbh_lock, flags); -+ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -+} ++typedef volatile struct { ++ uint32 corecontrol; ++ uint32 extstatus; ++ uint32 PAD[2]; + -+static int -+sbpci_read_config_dword(struct pci_dev *dev, int where, u32 *value) -+{ -+ unsigned long flags; -+ int ret; ++ /* pcmcia control registers */ ++ uint32 pcmcia_config; ++ uint32 pcmcia_memwait; ++ uint32 pcmcia_attrwait; ++ uint32 pcmcia_iowait; + -+ spin_lock_irqsave(&sbh_lock, flags); -+ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, value, sizeof(*value)); -+ spin_unlock_irqrestore(&sbh_lock, flags); -+ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -+} ++ /* programmable interface control registers */ ++ uint32 prog_config; ++ uint32 prog_waitcount; + -+static int -+sbpci_write_config_byte(struct pci_dev *dev, int where, u8 value) -+{ -+ unsigned long flags; -+ int ret; ++ /* flash control registers */ ++ uint32 flash_config; ++ uint32 flash_waitcount; ++ uint32 PAD[4]; + -+ spin_lock_irqsave(&sbh_lock, flags); -+ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value)); -+ spin_unlock_irqrestore(&sbh_lock, flags); -+ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -+} ++ uint32 watchdog; + -+static int -+sbpci_write_config_word(struct pci_dev *dev, int where, u16 value) -+{ -+ unsigned long flags; -+ int ret; ++ /* clock control */ ++ uint32 clockcontrol_n; ++ uint32 clockcontrol_sb; ++ uint32 clockcontrol_pci; ++ uint32 clockcontrol_mii; ++ uint32 PAD[3]; + -+ spin_lock_irqsave(&sbh_lock, flags); -+ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value)); -+ spin_unlock_irqrestore(&sbh_lock, flags); -+ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -+} ++ /* gpio */ ++ uint32 gpioin; ++ struct gpiouser gpio[NGPIOUSER]; ++ uint32 PAD; ++ uint32 ejtagouten; ++ uint32 gpiointpolarity; ++ uint32 gpiointmask; ++ uint32 PAD[153]; + -+static int -+sbpci_write_config_dword(struct pci_dev *dev, int where, u32 value) -+{ -+ unsigned long flags; -+ int ret; ++ uint8 uartdata; ++ uint8 PAD[3]; ++ uint8 uartimer; ++ uint8 PAD[3]; ++ uint8 uartfcr; ++ uint8 PAD[3]; ++ uint8 uartlcr; ++ uint8 PAD[3]; ++ uint8 uartmcr; ++ uint8 PAD[3]; ++ uint8 uartlsr; ++ uint8 PAD[3]; ++ uint8 uartmsr; ++ uint8 PAD[3]; ++ uint8 uartscratch; ++ uint8 PAD[3]; ++} extifregs_t; + -+ spin_lock_irqsave(&sbh_lock, flags); -+ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), where, &value, sizeof(value)); -+ spin_unlock_irqrestore(&sbh_lock, flags); -+ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; -+} ++/* corecontrol */ ++#define CC_UE (1 << 0) /* uart enable */ + -+static struct pci_ops pcibios_ops = { -+ sbpci_read_config_byte, -+ sbpci_read_config_word, -+ sbpci_read_config_dword, -+ sbpci_write_config_byte, -+ sbpci_write_config_word, -+ sbpci_write_config_dword -+}; ++/* extstatus */ ++#define ES_EM (1 << 0) /* endian mode (ro) */ ++#define ES_EI (1 << 1) /* external interrupt pin (ro) */ ++#define ES_GI (1 << 2) /* gpio interrupt pin (ro) */ + ++/* gpio bit mask */ ++#define GPIO_BIT0 (1 << 0) ++#define GPIO_BIT1 (1 << 1) ++#define GPIO_BIT2 (1 << 2) ++#define GPIO_BIT3 (1 << 3) ++#define GPIO_BIT4 (1 << 4) ++#define GPIO_BIT5 (1 << 5) ++#define GPIO_BIT6 (1 << 6) ++#define GPIO_BIT7 (1 << 7) + -+void __init -+pcibios_init(void) -+{ -+ ulong flags; + -+ if (!(sbh = sb_kattach())) -+ panic("sb_kattach failed"); -+ spin_lock_init(&sbh_lock); ++/* pcmcia/prog/flash_config */ ++#define CF_EN (1 << 0) /* enable */ ++#define CF_EM_MASK 0xe /* mode */ ++#define CF_EM_SHIFT 1 ++#define CF_EM_FLASH 0x0 /* flash/asynchronous mode */ ++#define CF_EM_SYNC 0x2 /* synchronous mode */ ++#define CF_EM_PCMCIA 0x4 /* pcmcia mode */ ++#define CF_DS (1 << 4) /* destsize: 0=8bit, 1=16bit */ ++#define CF_BS (1 << 5) /* byteswap */ ++#define CF_CD_MASK 0xc0 /* clock divider */ ++#define CF_CD_SHIFT 6 ++#define CF_CD_DIV2 0x0 /* backplane/2 */ ++#define CF_CD_DIV3 0x40 /* backplane/3 */ ++#define CF_CD_DIV4 0x80 /* backplane/4 */ ++#define CF_CE (1 << 8) /* clock enable */ ++#define CF_SB (1 << 9) /* size/bytestrobe (synch only) */ + -+ spin_lock_irqsave(&sbh_lock, flags); -+ sbpci_init(sbh); -+ spin_unlock_irqrestore(&sbh_lock, flags); ++/* pcmcia_memwait */ ++#define PM_W0_MASK 0x3f /* waitcount0 */ ++#define PM_W1_MASK 0x1f00 /* waitcount1 */ ++#define PM_W1_SHIFT 8 ++#define PM_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PM_W2_SHIFT 16 ++#define PM_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PM_W3_SHIFT 24 + -+ set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000)); ++/* pcmcia_attrwait */ ++#define PA_W0_MASK 0x3f /* waitcount0 */ ++#define PA_W1_MASK 0x1f00 /* waitcount1 */ ++#define PA_W1_SHIFT 8 ++#define PA_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PA_W2_SHIFT 16 ++#define PA_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PA_W3_SHIFT 24 + -+ mdelay(300); //By Joey for Atheros Card ++/* pcmcia_iowait */ ++#define PI_W0_MASK 0x3f /* waitcount0 */ ++#define PI_W1_MASK 0x1f00 /* waitcount1 */ ++#define PI_W1_SHIFT 8 ++#define PI_W2_MASK 0x1f0000 /* waitcount2 */ ++#define PI_W2_SHIFT 16 ++#define PI_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PI_W3_SHIFT 24 + -+ /* Scan the SB bus */ -+ pci_scan_bus(0, &pcibios_ops, NULL); -+ -+} -+ -+char * __init -+pcibios_setup(char *str) -+{ -+ if (!strncmp(str, "ban=", 4)) { -+ sbpci_ban(simple_strtoul(str + 4, NULL, 0)); -+ return NULL; -+ } -+ -+ return (str); -+} -+ -+static u32 pci_iobase = 0x100; -+static u32 pci_membase = SB_PCI_DMA; ++/* prog_waitcount */ ++#define PW_W0_MASK 0x0000001f /* waitcount0 */ ++#define PW_W1_MASK 0x00001f00 /* waitcount1 */ ++#define PW_W1_SHIFT 8 ++#define PW_W2_MASK 0x001f0000 /* waitcount2 */ ++#define PW_W2_SHIFT 16 ++#define PW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define PW_W3_SHIFT 24 + -+void __init -+pcibios_fixup_bus(struct pci_bus *b) -+{ -+ struct list_head *ln; -+ struct pci_dev *d; -+ struct resource *res; -+ int pos, size; -+ u32 *base; -+ u8 irq; ++#define PW_W0 0x0000000c ++#define PW_W1 0x00000a00 ++#define PW_W2 0x00020000 ++#define PW_W3 0x01000000 + -+ printk("PCI: Fixing up bus %d\n", b->number); ++/* flash_waitcount */ ++#define FW_W0_MASK 0x1f /* waitcount0 */ ++#define FW_W1_MASK 0x1f00 /* waitcount1 */ ++#define FW_W1_SHIFT 8 ++#define FW_W2_MASK 0x1f0000 /* waitcount2 */ ++#define FW_W2_SHIFT 16 ++#define FW_W3_MASK 0x1f000000 /* waitcount3 */ ++#define FW_W3_SHIFT 24 + -+ /* Fix up SB */ -+ if (b->number == 0) { -+ for (ln=b->devices.next; ln != &b->devices; ln=ln->next) { -+ d = pci_dev_b(ln); -+ /* Fix up interrupt lines */ -+ pci_read_config_byte(d, PCI_INTERRUPT_LINE, &irq); -+ d->irq = irq + 2; -+ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); -+ } -+ } ++/* watchdog */ ++#define WATCHDOG_CLOCK 48000000 /* Hz */ + -+ /* Fix up external PCI */ -+ else { -+ for (ln=b->devices.next; ln != &b->devices; ln=ln->next) { -+ d = pci_dev_b(ln); -+ /* Fix up resource bases */ -+ for (pos = 0; pos < 6; pos++) { -+ res = &d->resource[pos]; -+ base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase; -+ if (res->end) { -+ size = res->end - res->start + 1; -+ if (*base & (size - 1)) -+ *base = (*base + size) & ~(size - 1); -+ res->start = *base; -+ res->end = res->start + size - 1; -+ *base += size; -+ pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start); -+ } -+ /* Fix up PCI bridge BAR0 only */ -+ if (b->number == 1 && PCI_SLOT(d->devfn) == 0) -+ break; -+ } -+ /* Fix up interrupt lines */ -+ if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL)) -+ d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq; -+ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); -+ } -+ } -+} ++/* clockcontrol_n */ ++#define CN_N1_MASK 0x3f /* n1 control */ ++#define CN_N2_MASK 0x3f00 /* n2 control */ ++#define CN_N2_SHIFT 8 + -+unsigned int -+pcibios_assign_all_busses(void) -+{ -+ return 1; -+} ++/* clockcontrol_sb/pci/mii */ ++#define CC_M1_MASK 0x3f /* m1 control */ ++#define CC_M2_MASK 0x3f00 /* m2 control */ ++#define CC_M2_SHIFT 8 ++#define CC_M3_MASK 0x3f0000 /* m3 control */ ++#define CC_M3_SHIFT 16 ++#define CC_MC_MASK 0x1f000000 /* mux control */ ++#define CC_MC_SHIFT 24 + -+void -+pcibios_align_resource(void *data, struct resource *res, -+ unsigned long size, unsigned long align) -+{ -+} ++/* Clock control default values */ ++#define CC_DEF_N 0x0009 /* Default values for bcm4710 */ ++#define CC_DEF_100 0x04020011 ++#define CC_DEF_33 0x11030011 ++#define CC_DEF_25 0x11050011 + -+int -+pcibios_enable_resources(struct pci_dev *dev) -+{ -+ u16 cmd, old_cmd; -+ int idx; -+ struct resource *r; ++/* Clock control values for 125Mhz */ ++#define CC_125_N 0x0802 ++#define CC_125_M 0x04020009 ++#define CC_125_M25 0x11090009 ++#define CC_125_M33 0x11090005 + -+ /* External PCI only */ -+ if (dev->bus->number == 0) -+ return 0; ++/* Clock control magic field values */ ++#define CC_F6_2 0x02 /* A factor of 2 in */ ++#define CC_F6_3 0x03 /* 6-bit fields like */ ++#define CC_F6_4 0x05 /* N1, M1 or M3 */ ++#define CC_F6_5 0x09 ++#define CC_F6_6 0x11 ++#define CC_F6_7 0x21 + -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ old_cmd = cmd; -+ for(idx=0; idx<6; idx++) { -+ r = &dev->resource[idx]; -+ if (r->flags & IORESOURCE_IO) -+ cmd |= PCI_COMMAND_IO; -+ if (r->flags & IORESOURCE_MEM) -+ cmd |= PCI_COMMAND_MEMORY; -+ } -+ if (dev->resource[PCI_ROM_RESOURCE].start) -+ cmd |= PCI_COMMAND_MEMORY; -+ if (cmd != old_cmd) { -+ printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ } -+ return 0; -+} ++#define CC_F5_BIAS 5 /* 5-bit fields get this added */ + -+int -+pcibios_enable_device(struct pci_dev *dev, int mask) -+{ -+ ulong flags; -+ uint coreidx; ++#define CC_MC_BYPASS 0x08 ++#define CC_MC_M1 0x04 ++#define CC_MC_M1M2 0x02 ++#define CC_MC_M1M2M3 0x01 ++#define CC_MC_M1M3 0x11 + -+ /* External PCI device enable */ -+ if (dev->bus->number != 0) -+ return pcibios_enable_resources(dev); ++#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */ + -+ /* These cores come out of reset enabled */ -+ if (dev->device == SB_MIPS || -+ dev->device == SB_MIPS33 || -+ dev->device == SB_EXTIF || -+ dev->device == SB_CC) -+ return 0; ++#endif /* _SBEXTIF_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbhndmips.h linux.dev/arch/mips/bcm947xx/include/sbhndmips.h +--- linux.old/arch/mips/bcm947xx/include/sbhndmips.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbhndmips.h 2006-04-27 20:43:56.000000000 +0200 +@@ -0,0 +1,47 @@ ++/* ++ * Broadcom SiliconBackplane MIPS definitions ++ * ++ * SB MIPS cores are custom MIPS32 processors with SiliconBackplane ++ * OCP interfaces. The CP0 processor ID is 0x00024000, where bits ++ * 23:16 mean Broadcom and bits 15:8 mean a MIPS core with an OCP ++ * interface. The core revision is stored in the SB ID register in SB ++ * configuration space. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sbhndmips.h,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $ ++ */ + -+ spin_lock_irqsave(&sbh_lock, flags); -+ coreidx = sb_coreidx(sbh); -+ if (!sb_setcoreidx(sbh, PCI_SLOT(dev->devfn))) -+ return PCIBIOS_DEVICE_NOT_FOUND; ++#ifndef _sbhndmips_h_ ++#define _sbhndmips_h_ + -+ /* -+ * The USB core requires a special bit to be set during core -+ * reset to enable host (OHCI) mode. Resetting the SB core in -+ * pcibios_enable_device() is a hack for compatibility with -+ * vanilla usb-ohci so that it does not have to know about -+ * SB. A driver that wants to use the USB core in device mode -+ * should know about SB and should reset the bit back to 0 -+ * after calling pcibios_enable_device(). -+ */ -+ if (sb_coreid(sbh) == SB_USB) { -+ sb_core_disable(sbh, sb_coreflags(sbh, 0, 0)); -+ sb_core_reset(sbh, 1 << 29); -+ } else -+ sb_core_reset(sbh, 0); ++#include + -+ sb_setcoreidx(sbh, coreidx); -+ spin_unlock_irqrestore(&sbh_lock, flags); -+ -+ return 0; -+} ++#ifndef _LANGUAGE_ASSEMBLY + -+void -+pcibios_update_resource(struct pci_dev *dev, struct resource *root, -+ struct resource *res, int resource) -+{ -+ unsigned long where, size; -+ u32 reg; ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif /* PAD */ + -+ /* External PCI only */ -+ if (dev->bus->number == 0) -+ return; ++typedef volatile struct { ++ uint32 corecontrol; ++ uint32 PAD[2]; ++ uint32 biststatus; ++ uint32 PAD[4]; ++ uint32 intstatus; ++ uint32 intmask; ++ uint32 timer; ++} mipsregs_t; + -+ where = PCI_BASE_ADDRESS_0 + (resource * 4); -+ size = res->end - res->start; -+ pci_read_config_dword(dev, where, ®); -+ reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); -+ pci_write_config_dword(dev, where, reg); -+} ++#endif /* _LANGUAGE_ASSEMBLY */ + -+static void __init -+quirk_sbpci_bridge(struct pci_dev *dev) -+{ -+ if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0) -+ return; ++#endif /* _sbhndmips_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm947xx/include/sbmemc.h +--- linux.old/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbmemc.h 2006-04-27 22:12:41.000000000 +0200 +@@ -0,0 +1,147 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sbmemc.h,v 1.6 2006/03/02 12:33:44 honor Exp $ ++ */ + -+ printk("PCI: Fixing up bridge\n"); ++#ifndef _SBMEMC_H ++#define _SBMEMC_H + -+ /* Enable PCI bridge bus mastering and memory space */ -+ pci_set_master(dev); -+ pcibios_enable_resources(dev); ++#ifdef _LANGUAGE_ASSEMBLY + -+ /* Enable PCI bridge BAR1 prefetch and burst */ -+ pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3); -+} ++#define MEMC_CONTROL 0x00 ++#define MEMC_CONFIG 0x04 ++#define MEMC_REFRESH 0x08 ++#define MEMC_BISTSTAT 0x0c ++#define MEMC_MODEBUF 0x10 ++#define MEMC_BKCLS 0x14 ++#define MEMC_PRIORINV 0x18 ++#define MEMC_DRAMTIM 0x1c ++#define MEMC_INTSTAT 0x20 ++#define MEMC_INTMASK 0x24 ++#define MEMC_INTINFO 0x28 ++#define MEMC_NCDLCTL 0x30 ++#define MEMC_RDNCDLCOR 0x34 ++#define MEMC_WRNCDLCOR 0x38 ++#define MEMC_MISCDLYCTL 0x3c ++#define MEMC_DQSGATENCDL 0x40 ++#define MEMC_SPARE 0x44 ++#define MEMC_TPADDR 0x48 ++#define MEMC_TPDATA 0x4c ++#define MEMC_BARRIER 0x50 ++#define MEMC_CORE 0x54 + -+struct pci_fixup pcibios_fixups[] = { -+ { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_sbpci_bridge }, -+ { 0 } -+}; ++#else /* !_LANGUAGE_ASSEMBLY */ + -+/* -+ * If we set up a device for bus mastering, we need to check the latency -+ * timer as certain crappy BIOSes forget to set it properly. -+ */ -+unsigned int pcibios_max_latency = 255; ++/* Sonics side: MEMC core registers */ ++typedef volatile struct sbmemcregs { ++ uint32 control; ++ uint32 config; ++ uint32 refresh; ++ uint32 biststat; ++ uint32 modebuf; ++ uint32 bkcls; ++ uint32 priorinv; ++ uint32 dramtim; ++ uint32 intstat; ++ uint32 intmask; ++ uint32 intinfo; ++ uint32 reserved1; ++ uint32 ncdlctl; ++ uint32 rdncdlcor; ++ uint32 wrncdlcor; ++ uint32 miscdlyctl; ++ uint32 dqsgatencdl; ++ uint32 spare; ++ uint32 tpaddr; ++ uint32 tpdata; ++ uint32 barrier; ++ uint32 core; ++} sbmemcregs_t; + -+void pcibios_set_master(struct pci_dev *dev) -+{ -+ u8 lat; -+ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); -+ if (lat < 16) -+ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; -+ else if (lat > pcibios_max_latency) -+ lat = pcibios_max_latency; -+ else -+ return; -+ printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat); -+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); -+} ++#endif /* _LANGUAGE_ASSEMBLY */ + -diff -Naur linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom.c ---- linux.old/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/prom.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,41 @@ -+/* -+ * Early initialization code for BCM94710 boards -+ * -+ * Copyright 2004, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id: prom.c,v 1.1 2005/03/16 13:49:59 wbx Exp $ -+ */ ++/* MEMC Core Init values (OCP ID 0x80f) */ + -+#include -+#include -+#include -+#include -+#include ++/* For sdr: */ ++#define MEMC_SD_CONFIG_INIT 0x00048000 ++#define MEMC_SD_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_SD_DRAMTIM3_INIT 0x000754da ++#define MEMC_SD_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_SD_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_SD1_WRNCDLCOR_INIT 0x14500200 /* For corerev 1 (4712) */ ++#define MEMC_SD_MISCDLYCTL_INIT 0x00061c1b ++#define MEMC_SD1_MISCDLYCTL_INIT 0x00021416 /* For corerev 1 (4712) */ ++#define MEMC_SD_CONTROL_INIT0 0x00000002 ++#define MEMC_SD_CONTROL_INIT1 0x00000008 ++#define MEMC_SD_CONTROL_INIT2 0x00000004 ++#define MEMC_SD_CONTROL_INIT3 0x00000010 ++#define MEMC_SD_CONTROL_INIT4 0x00000001 ++#define MEMC_SD_MODEBUF_INIT 0x00000000 ++#define MEMC_SD_REFRESH_INIT 0x0000840f + -+void __init -+prom_init(int argc, const char **argv) -+{ -+ unsigned long mem; + -+ mips_machgroup = MACH_GROUP_BRCM; -+ mips_machtype = MACH_BCM947XX; ++/* This is for SDRM8X8X4 */ ++#define MEMC_SDR_INIT 0x0008 ++#define MEMC_SDR_MODE 0x32 ++#define MEMC_SDR_NCDL 0x00020032 ++#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */ + -+ /* Figure out memory size by finding aliases */ -+ for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { -+ if (*(unsigned long *)((unsigned long)(prom_init) + mem) == -+ *(unsigned long *)(prom_init)) -+ break; -+ } -+ add_memory_region(0, mem, BOOT_MEM_RAM); -+} ++/* For ddr: */ ++#define MEMC_CONFIG_INIT 0x00048000 ++#define MEMC_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_DRAMTIM25_INIT 0x000754d9 ++#define MEMC_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */ ++#define MEMC_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_1_WRNCDLCOR_INIT 0x14500200 ++#define MEMC_DQSGATENCDL_INIT 0x00030000 ++#define MEMC_MISCDLYCTL_INIT 0x21061c1b ++#define MEMC_1_MISCDLYCTL_INIT 0x21021400 ++#define MEMC_NCDLCTL_INIT 0x00002001 ++#define MEMC_CONTROL_INIT0 0x00000002 ++#define MEMC_CONTROL_INIT1 0x00000008 ++#define MEMC_MODEBUF_INIT0 0x00004000 ++#define MEMC_CONTROL_INIT2 0x00000010 ++#define MEMC_MODEBUF_INIT1 0x00000100 ++#define MEMC_CONTROL_INIT3 0x00000010 ++#define MEMC_CONTROL_INIT4 0x00000008 ++#define MEMC_REFRESH_INIT 0x0000840f ++#define MEMC_CONTROL_INIT5 0x00000004 ++#define MEMC_MODEBUF_INIT2 0x00000000 ++#define MEMC_CONTROL_INIT6 0x00000010 ++#define MEMC_CONTROL_INIT7 0x00000001 + -+void __init -+prom_free_prom_memory(void) -+{ -+} -diff -Naur linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbmips.c ---- linux.old/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/sbmips.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,1038 @@ ++ ++/* This is for DDRM16X16X2 */ ++#define MEMC_DDR_INIT 0x0009 ++#define MEMC_DDR_MODE 0x62 ++#define MEMC_DDR_NCDL 0x0005050a ++#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */ ++ ++/* mask for sdr/ddr calibration registers */ ++#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff ++#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff ++#define MEMC_DQSGATENCDL_G_MASK 0x000000ff ++ ++/* masks for miscdlyctl registers */ ++#define MEMC_MISC_SM_MASK 0x30000000 ++#define MEMC_MISC_SM_SHIFT 28 ++#define MEMC_MISC_SD_MASK 0x0f000000 ++#define MEMC_MISC_SD_SHIFT 24 ++ ++/* hw threshhold for calculating wr/rd for sdr memc */ ++#define MEMC_CD_THRESHOLD 128 ++ ++/* Low bit of init register says if memc is ddr or sdr */ ++#define MEMC_CONFIG_DDR 0x00000001 ++ ++#endif /* _SBMEMC_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm947xx/include/sbpci.h +--- linux.old/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbpci.h 2006-05-02 17:20:14.000000000 +0200 +@@ -0,0 +1,114 @@ +/* -+ * BCM47XX Sonics SiliconBackplane MIPS core routines ++ * HND SiliconBackplane PCI core hardware definitions. + * -+ * Copyright 2005, Broadcom Corporation ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -7378,1041 +7398,783 @@ diff -Naur linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sb + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id$ ++ * $Id: sbpci.h,v 1.1.1.11 2006/02/27 03:43:16 honor Exp $ + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * Returns TRUE if an external UART exists at the given base -+ * register. -+ */ -+static bool -+BCMINITFN(serial_exists)(uint8 *regs) -+{ -+ uint8 save_mcr, status1; ++#ifndef _sbpci_h_ ++#define _sbpci_h_ + -+ save_mcr = R_REG(®s[UART_MCR]); -+ W_REG(®s[UART_MCR], UART_MCR_LOOP | 0x0a); -+ status1 = R_REG(®s[UART_MSR]) & 0xf0; -+ W_REG(®s[UART_MCR], save_mcr); ++#ifndef _LANGUAGE_ASSEMBLY + -+ return (status1 == 0x90); -+} ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif + -+/* -+ * Initializes UART access. The callback function will be called once -+ * per found UART. -+ */ -+void -+BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)) -+{ -+ void *regs; -+ ulong base; -+ uint irq; -+ int i, n; ++/* Sonics side: PCI core and host control registers */ ++typedef struct sbpciregs { ++ uint32 control; /* PCI control */ ++ uint32 PAD[3]; ++ uint32 arbcontrol; /* PCI arbiter control */ ++ uint32 PAD[3]; ++ uint32 intstatus; /* Interrupt status */ ++ uint32 intmask; /* Interrupt mask */ ++ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */ ++ uint32 PAD[9]; ++ uint32 bcastaddr; /* Sonics broadcast address */ ++ uint32 bcastdata; /* Sonics broadcast data */ ++ uint32 PAD[2]; ++ uint32 gpioin; /* ro: gpio input (>=rev2) */ ++ uint32 gpioout; /* rw: gpio output (>=rev2) */ ++ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */ ++ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */ ++ uint32 PAD[36]; ++ uint32 sbtopci0; /* Sonics to PCI translation 0 */ ++ uint32 sbtopci1; /* Sonics to PCI translation 1 */ ++ uint32 sbtopci2; /* Sonics to PCI translation 2 */ ++ uint32 PAD[189]; ++ uint32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */ ++ uint16 sprom[36]; /* SPROM shadow Area */ ++ uint32 PAD[46]; ++} sbpciregs_t; + -+ if ((regs = sb_setcore(sbh, SB_EXTIF, 0))) { -+ extifregs_t *eir = (extifregs_t *) regs; -+ sbconfig_t *sb; ++#endif /* _LANGUAGE_ASSEMBLY */ + -+ /* Determine external UART register base */ -+ sb = (sbconfig_t *)((ulong) eir + SBCONFIGOFF); -+ base = EXTIF_CFGIF_BASE(sb_base(R_REG(&sb->sbadmatch1))); -+ -+ /* Determine IRQ */ -+ irq = sb_irq(sbh); -+ -+ /* Disable GPIO interrupt initially */ -+ W_REG(&eir->gpiointpolarity, 0); -+ W_REG(&eir->gpiointmask, 0); -+ -+ /* Search for external UARTs */ -+ n = 2; -+ for (i = 0; i < 2; i++) { -+ regs = (void *) REG_MAP(base + (i * 8), 8); -+ if (BCMINIT(serial_exists)(regs)) { -+ /* Set GPIO 1 to be the external UART IRQ */ -+ W_REG(&eir->gpiointmask, 2); -+ if (add) -+ add(regs, irq, 13500000, 0); -+ } -+ } -+ -+ /* Add internal UART if enabled */ -+ if (R_REG(&eir->corecontrol) & CC_UE) -+ if (add) -+ add((void *) &eir->uartdata, irq, sb_clock(sbh), 2); -+ } else if ((regs = sb_setcore(sbh, SB_CC, 0))) { -+ chipcregs_t *cc = (chipcregs_t *) regs; -+ uint32 rev, cap, pll, baud_base, div; ++/* PCI control */ ++#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ ++#define PCI_RST 0x02 /* Value driven out to pin */ ++#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ ++#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ + -+ /* Determine core revision and capabilities */ -+ rev = sb_corerev(sbh); -+ cap = R_REG(&cc->capabilities); -+ pll = cap & CAP_PLL_MASK; ++/* PCI arbiter control */ ++#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ ++#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ ++/* ParkID - for PCI corerev >= 8 */ ++#define PCI_PARKID_MASK 0x1c /* Selects which agent is parked on an idle bus */ ++#define PCI_PARKID_SHIFT 2 ++#define PCI_PARKID_EXT0 0 /* External master 0 */ ++#define PCI_PARKID_EXT1 1 /* External master 1 */ ++#define PCI_PARKID_EXT2 2 /* External master 2 */ ++#define PCI_PARKID_INT 3 /* Internal master */ ++#define PCI_PARKID_LAST 4 /* Last active master */ + -+ /* Determine IRQ */ -+ irq = sb_irq(sbh); ++/* Interrupt status/mask */ ++#define PCI_INTA 0x01 /* PCI INTA# is asserted */ ++#define PCI_INTB 0x02 /* PCI INTB# is asserted */ ++#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ ++#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ ++#define PCI_PME 0x10 /* PCI PME# is asserted */ + -+ if (pll == PLL_TYPE1) { -+ /* PLL clock */ -+ baud_base = sb_clock_rate(pll, -+ R_REG(&cc->clockcontrol_n), -+ R_REG(&cc->clockcontrol_m2)); -+ div = 1; -+ } else { -+ if (rev >= 11) { -+ /* Fixed ALP clock */ -+ baud_base = 20000000; -+ div = 1; -+ /* Set the override bit so we don't divide it */ -+ W_REG(&cc->corecontrol, CC_UARTCLKO); -+ } else if (rev >= 3) { -+ /* Internal backplane clock */ -+ baud_base = sb_clock(sbh); -+ div = 2; /* Minimum divisor */ -+ W_REG(&cc->clkdiv, -+ ((R_REG(&cc->clkdiv) & ~CLKD_UART) | div)); -+ } else { -+ /* Fixed internal backplane clock */ -+ baud_base = 88000000; -+ div = 48; -+ } ++/* (General) PCI/SB mailbox interrupts, two bits per pci function */ ++#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ ++#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ ++#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ ++#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ ++#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ ++#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ ++#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ ++#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ + -+ /* Clock source depends on strapping if UartClkOverride is unset */ -+ if ((rev > 0) && -+ ((R_REG(&cc->corecontrol) & CC_UARTCLKO) == 0)) { -+ if ((cap & CAP_UCLKSEL) == CAP_UINTCLK) { -+ /* Internal divided backplane clock */ -+ baud_base /= div; -+ } else { -+ /* Assume external clock of 1.8432 MHz */ -+ baud_base = 1843200; -+ } -+ } -+ } ++/* Sonics broadcast address */ ++#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ + -+ /* Add internal UARTs */ -+ n = cap & CAP_UARTS_MASK; -+ for (i = 0; i < n; i++) { -+ /* Register offset changed after revision 0 */ -+ if (rev) -+ regs = (void *)((ulong) &cc->uart0data + (i * 256)); -+ else -+ regs = (void *)((ulong) &cc->uart0data + (i * 8)); ++/* Sonics to PCI translation types */ ++#define SBTOPCI0_MASK 0xfc000000 ++#define SBTOPCI1_MASK 0xfc000000 ++#define SBTOPCI2_MASK 0xc0000000 ++#define SBTOPCI_MEM 0 ++#define SBTOPCI_IO 1 ++#define SBTOPCI_CFG0 2 ++#define SBTOPCI_CFG1 3 ++#define SBTOPCI_PREF 0x4 /* prefetch enable */ ++#define SBTOPCI_BURST 0x8 /* burst enable */ ++#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ ++#define SBTOPCI_RC_READ 0x00 /* memory read */ ++#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ ++#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ + -+ if (add) -+ add(regs, irq, baud_base, 0); -+ } -+ } -+} ++/* PCI core index in SROM shadow area */ ++#define SRSH_PI_OFFSET 0 /* first word */ ++#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ ++#define SRSH_PI_SHIFT 12 /* bit 15:12 */ + ++#endif /* _sbpci_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbpcie.h linux.dev/arch/mips/bcm947xx/include/sbpcie.h +--- linux.old/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbpcie.h 2006-04-27 20:42:22.000000000 +0200 +@@ -0,0 +1,200 @@ +/* -+ * Initialize jtag master and return handle for -+ * jtag_rwreg. Returns NULL on failure. ++ * BCM43XX SiliconBackplane PCIE core hardware definitions. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sbpcie.h,v 1.1.1.2 2006/02/27 03:43:16 honor Exp $ + */ -+void * -+sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap) -+{ -+ void *regs; + -+ if ((regs = sb_setcore(sbh, SB_CC, 0)) != NULL) { -+ chipcregs_t *cc = (chipcregs_t *) regs; -+ uint32 tmp; -+ -+ /* -+ * Determine jtagm availability from -+ * core revision and capabilities. -+ */ -+ tmp = sb_corerev(sbh); -+ /* -+ * Corerev 10 has jtagm, but the only chip -+ * with it does not have a mips, and -+ * the layout of the jtagcmd register is -+ * different. We'll only accept >= 11. -+ */ -+ if (tmp < 11) -+ return (NULL); ++#ifndef _SBPCIE_H ++#define _SBPCIE_H + -+ tmp = R_REG(&cc->capabilities); -+ if ((tmp & CAP_JTAGP) == 0) -+ return (NULL); ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif + -+ /* Set clock divider if requested */ -+ if (clkd != 0) { -+ tmp = R_REG(&cc->clkdiv); -+ tmp = (tmp & ~CLKD_JTAG) | -+ ((clkd << CLKD_JTAG_SHIFT) & CLKD_JTAG); -+ W_REG(&cc->clkdiv, tmp); -+ } ++/* PCIE Enumeration space offsets */ ++#define PCIE_CORE_CONFIG_OFFSET 0x0 ++#define PCIE_FUNC0_CONFIG_OFFSET 0x400 ++#define PCIE_FUNC1_CONFIG_OFFSET 0x500 ++#define PCIE_FUNC2_CONFIG_OFFSET 0x600 ++#define PCIE_FUNC3_CONFIG_OFFSET 0x700 ++#define PCIE_SPROM_SHADOW_OFFSET 0x800 ++#define PCIE_SBCONFIG_OFFSET 0xE00 + -+ /* Enable jtagm */ -+ tmp = JCTRL_EN | (exttap ? JCTRL_EXT_EN : 0); -+ W_REG(&cc->jtagctrl, tmp); -+ } ++/* PCIE Bar0 Address Mapping. Each function maps 16KB config space */ ++#define PCIE_DEV_BAR0_SIZE 0x4000 ++#define PCIE_BAR0_WINMAPCORE_OFFSET 0x0 ++#define PCIE_BAR0_EXTSPROM_OFFSET 0x1000 ++#define PCIE_BAR0_PCIECORE_OFFSET 0x2000 ++#define PCIE_BAR0_CCCOREREG_OFFSET 0x3000 + -+ return (regs); -+} ++/* SB side: PCIE core and host control registers */ ++typedef struct sbpcieregs { ++ uint32 PAD[3]; ++ uint32 biststatus; /* bist Status: 0x00C */ ++ uint32 PAD[6]; ++ uint32 sbtopcimailbox; /* sb to pcie mailbox: 0x028 */ ++ uint32 PAD[54]; ++ uint32 sbtopcie0; /* sb to pcie translation 0: 0x100 */ ++ uint32 sbtopcie1; /* sb to pcie translation 1: 0x104 */ ++ uint32 sbtopcie2; /* sb to pcie translation 2: 0x108 */ ++ uint32 PAD[4]; + -+void -+sb_jtagm_disable(void *h) -+{ -+ chipcregs_t *cc = (chipcregs_t *)h; ++ /* pcie core supports in direct access to config space */ ++ uint32 configaddr; /* pcie config space access: Address field: 0x120 */ ++ uint32 configdata; /* pcie config space access: Data field: 0x124 */ + -+ W_REG(&cc->jtagctrl, R_REG(&cc->jtagctrl) & ~JCTRL_EN); -+} ++ /* mdio access to serdes */ ++ uint32 mdiocontrol; /* controls the mdio access: 0x128 */ ++ uint32 mdiodata; /* Data to the mdio access: 0x12c */ + -+/* -+ * Read/write a jtag register. Assumes a target with -+ * 8 bit IR and 32 bit DR. -+ */ -+#define IRWIDTH 8 -+#define DRWIDTH 32 -+uint32 -+jtag_rwreg(void *h, uint32 ir, uint32 dr) -+{ -+ chipcregs_t *cc = (chipcregs_t *) h; -+ uint32 tmp; -+ -+ W_REG(&cc->jtagir, ir); -+ W_REG(&cc->jtagdr, dr); -+ tmp = JCMD_START | JCMD_ACC_IRDR | -+ ((IRWIDTH - 1) << JCMD_IRW_SHIFT) | -+ (DRWIDTH - 1); -+ W_REG(&cc->jtagcmd, tmp); -+ while (((tmp = R_REG(&cc->jtagcmd)) & JCMD_BUSY) == JCMD_BUSY) { -+ /* OSL_DELAY(1); */ -+ } ++ /* pcie protocol phy/dllp/tlp register access mechanism */ ++ uint32 pcieaddr; /* address of the internal registeru: 0x130 */ ++ uint32 pciedata; /* Data to/from the internal regsiter: 0x134 */ + -+ tmp = R_REG(&cc->jtagdr); -+ return (tmp); -+} ++ uint32 PAD[434]; ++ uint16 sprom[36]; /* SPROM shadow Area */ ++} sbpcieregs_t; + -+/* Returns the SB interrupt flag of the current core. */ -+uint32 -+sb_flag(sb_t *sbh) -+{ -+ void *regs; -+ sbconfig_t *sb; ++/* SB to PCIE translation masks */ ++#define SBTOPCIE0_MASK 0xfc000000 ++#define SBTOPCIE1_MASK 0xfc000000 ++#define SBTOPCIE2_MASK 0xc0000000 + -+ regs = sb_coreregs(sbh); -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++/* Access type bits (0:1) */ ++#define SBTOPCIE_MEM 0 ++#define SBTOPCIE_IO 1 ++#define SBTOPCIE_CFG0 2 ++#define SBTOPCIE_CFG1 3 + -+ return (R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK); -+} ++/* Prefetch enable bit 2 */ ++#define SBTOPCIE_PF 4 + -+static const uint32 sbips_int_mask[] = { -+ 0, -+ SBIPS_INT1_MASK, -+ SBIPS_INT2_MASK, -+ SBIPS_INT3_MASK, -+ SBIPS_INT4_MASK -+}; ++/* Write Burst enable for memory write bit 3 */ ++#define SBTOPCIE_WR_BURST 8 + -+static const uint32 sbips_int_shift[] = { -+ 0, -+ 0, -+ SBIPS_INT2_SHIFT, -+ SBIPS_INT3_SHIFT, -+ SBIPS_INT4_SHIFT -+}; ++/* config access */ ++#define CONFIGADDR_FUNC_MASK 0x7000 ++#define CONFIGADDR_FUNC_SHF 12 ++#define CONFIGADDR_REG_MASK 0x0FFF ++#define CONFIGADDR_REG_SHF 0 + -+/* -+ * Returns the MIPS IRQ assignment of the current core. If unassigned, -+ * 0 is returned. -+ */ -+uint -+sb_irq(sb_t *sbh) -+{ -+ uint idx; -+ void *regs; -+ sbconfig_t *sb; -+ uint32 flag, sbipsflag; -+ uint irq = 0; ++/* PCIE protocol regs Indirect Address */ ++#define PCIEADDR_PROT_MASK 0x300 ++#define PCIEADDR_PROT_SHF 8 ++#define PCIEADDR_PL_TLP 0 ++#define PCIEADDR_PL_DLLP 1 ++#define PCIEADDR_PL_PLP 2 + -+ flag = sb_flag(sbh); ++/* PCIE protocol PHY diagnostic registers */ ++#define PCIE_PLP_MODEREG 0x200 /* Mode */ ++#define PCIE_PLP_STATUSREG 0x204 /* Status */ ++#define PCIE_PLP_LTSSMCTRLREG 0x208 /* LTSSM control */ ++#define PCIE_PLP_LTLINKNUMREG 0x20c /* Link Training Link number */ ++#define PCIE_PLP_LTLANENUMREG 0x210 /* Link Training Lane number */ ++#define PCIE_PLP_LTNFTSREG 0x214 /* Link Training N_FTS */ ++#define PCIE_PLP_ATTNREG 0x218 /* Attention */ ++#define PCIE_PLP_ATTNMASKREG 0x21C /* Attention Mask */ ++#define PCIE_PLP_RXERRCTR 0x220 /* Rx Error */ ++#define PCIE_PLP_RXFRMERRCTR 0x224 /* Rx Framing Error */ ++#define PCIE_PLP_RXERRTHRESHREG 0x228 /* Rx Error threshold */ ++#define PCIE_PLP_TESTCTRLREG 0x22C /* Test Control reg */ ++#define PCIE_PLP_SERDESCTRLOVRDREG 0x230 /* SERDES Control Override */ ++#define PCIE_PLP_TIMINGOVRDREG 0x234 /* Timing param override */ ++#define PCIE_PLP_RXTXSMDIAGREG 0x238 /* RXTX State Machine Diag */ ++#define PCIE_PLP_LTSSMDIAGREG 0x23C /* LTSSM State Machine Diag */ + -+ idx = sb_coreidx(sbh); ++/* PCIE protocol DLLP diagnostic registers */ ++#define PCIE_DLLP_LCREG 0x100 /* Link Control */ ++#define PCIE_DLLP_LSREG 0x104 /* Link Status */ ++#define PCIE_DLLP_LAREG 0x108 /* Link Attention */ ++#define PCIE_DLLP_LAMASKREG 0x10C /* Link Attention Mask */ ++#define PCIE_DLLP_NEXTTXSEQNUMREG 0x110 /* Next Tx Seq Num */ ++#define PCIE_DLLP_ACKEDTXSEQNUMREG 0x114 /* Acked Tx Seq Num */ ++#define PCIE_DLLP_PURGEDTXSEQNUMREG 0x118 /* Purged Tx Seq Num */ ++#define PCIE_DLLP_RXSEQNUMREG 0x11C /* Rx Sequence Number */ ++#define PCIE_DLLP_LRREG 0x120 /* Link Replay */ ++#define PCIE_DLLP_LACKTOREG 0x124 /* Link Ack Timeout */ ++#define PCIE_DLLP_PMTHRESHREG 0x128 /* Power Management Threshold */ ++#define PCIE_DLLP_RTRYWPREG 0x12C /* Retry buffer write ptr */ ++#define PCIE_DLLP_RTRYRPREG 0x130 /* Retry buffer Read ptr */ ++#define PCIE_DLLP_RTRYPPREG 0x134 /* Retry buffer Purged ptr */ ++#define PCIE_DLLP_RTRRWREG 0x138 /* Retry buffer Read/Write */ ++#define PCIE_DLLP_ECTHRESHREG 0x13C /* Error Count Threshold */ ++#define PCIE_DLLP_TLPERRCTRREG 0x140 /* TLP Error Counter */ ++#define PCIE_DLLP_ERRCTRREG 0x144 /* Error Counter */ ++#define PCIE_DLLP_NAKRXCTRREG 0x148 /* NAK Received Counter */ ++#define PCIE_DLLP_TESTREG 0x14C /* Test */ ++#define PCIE_DLLP_PKTBIST 0x150 /* Packet BIST */ + -+ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || -+ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++/* PCIE protocol TLP diagnostic registers */ ++#define PCIE_TLP_CONFIGREG 0x000 /* Configuration */ ++#define PCIE_TLP_WORKAROUNDSREG 0x004 /* TLP Workarounds */ ++#define PCIE_TLP_WRDMAUPPER 0x010 /* Write DMA Upper Address */ ++#define PCIE_TLP_WRDMALOWER 0x014 /* Write DMA Lower Address */ ++#define PCIE_TLP_WRDMAREQ_LBEREG 0x018 /* Write DMA Len/ByteEn Req */ ++#define PCIE_TLP_RDDMAUPPER 0x01C /* Read DMA Upper Address */ ++#define PCIE_TLP_RDDMALOWER 0x020 /* Read DMA Lower Address */ ++#define PCIE_TLP_RDDMALENREG 0x024 /* Read DMA Len Req */ ++#define PCIE_TLP_MSIDMAUPPER 0x028 /* MSI DMA Upper Address */ ++#define PCIE_TLP_MSIDMALOWER 0x02C /* MSI DMA Lower Address */ ++#define PCIE_TLP_MSIDMALENREG 0x030 /* MSI DMA Len Req */ ++#define PCIE_TLP_SLVREQLENREG 0x034 /* Slave Request Len */ ++#define PCIE_TLP_FCINPUTSREQ 0x038 /* Flow Control Inputs */ ++#define PCIE_TLP_TXSMGRSREQ 0x03C /* Tx StateMachine and Gated Req */ ++#define PCIE_TLP_ADRACKCNTARBLEN 0x040 /* Address Ack XferCnt and ARB Len */ ++#define PCIE_TLP_DMACPLHDR0 0x044 /* DMA Completion Hdr 0 */ ++#define PCIE_TLP_DMACPLHDR1 0x048 /* DMA Completion Hdr 1 */ ++#define PCIE_TLP_DMACPLHDR2 0x04C /* DMA Completion Hdr 2 */ ++#define PCIE_TLP_DMACPLMISC0 0x050 /* DMA Completion Misc0 */ ++#define PCIE_TLP_DMACPLMISC1 0x054 /* DMA Completion Misc1 */ ++#define PCIE_TLP_DMACPLMISC2 0x058 /* DMA Completion Misc2 */ ++#define PCIE_TLP_SPTCTRLLEN 0x05C /* Split Controller Req len */ ++#define PCIE_TLP_SPTCTRLMSIC0 0x060 /* Split Controller Misc 0 */ ++#define PCIE_TLP_SPTCTRLMSIC1 0x064 /* Split Controller Misc 1 */ ++#define PCIE_TLP_BUSDEVFUNC 0x068 /* Bus/Device/Func */ ++#define PCIE_TLP_RESETCTR 0x06C /* Reset Counter */ ++#define PCIE_TLP_RTRYBUF 0x070 /* Retry Buffer value */ ++#define PCIE_TLP_TGTDEBUG1 0x074 /* Target Debug Reg1 */ ++#define PCIE_TLP_TGTDEBUG2 0x078 /* Target Debug Reg2 */ ++#define PCIE_TLP_TGTDEBUG3 0x07C /* Target Debug Reg3 */ ++#define PCIE_TLP_TGTDEBUG4 0x080 /* Target Debug Reg4 */ + -+ /* sbipsflag specifies which core is routed to interrupts 1 to 4 */ -+ sbipsflag = R_REG(&sb->sbipsflag); -+ for (irq = 1; irq <= 4; irq++) { -+ if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag) -+ break; -+ } -+ if (irq == 5) -+ irq = 0; -+ } -+ -+ sb_setcoreidx(sbh, idx); -+ -+ return irq; -+} ++/* MDIO control */ ++#define MDIOCTL_DIVISOR_MASK 0x7f /* clock to be used on MDIO */ ++#define MDIOCTL_DIVISOR_VAL 0x2 ++#define MDIOCTL_PREAM_EN 0x80 /* Enable preamble sequnce */ ++#define MDIOCTL_ACCESS_DONE 0x100 /* Tranaction complete */ + -+/* Clears the specified MIPS IRQ. */ -+static void -+BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq) -+{ -+ void *regs; -+ sbconfig_t *sb; ++/* MDIO Data */ ++#define MDIODATA_MASK 0x0000ffff /* data 2 bytes */ ++#define MDIODATA_TA 0x00020000 /* Turnaround */ ++#define MDIODATA_REGADDR_SHF 18 /* Regaddr shift */ ++#define MDIODATA_REGADDR_MASK 0x003c0000 /* Regaddr Mask */ ++#define MDIODATA_DEVADDR_SHF 22 /* Physmedia devaddr shift */ ++#define MDIODATA_DEVADDR_MASK 0x0fc00000 /* Physmedia devaddr Mask */ ++#define MDIODATA_WRITE 0x10000000 /* write Transaction */ ++#define MDIODATA_READ 0x20000000 /* Read Transaction */ ++#define MDIODATA_START 0x40000000 /* start of Transaction */ + -+ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && -+ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) -+ ASSERT(regs); -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++/* MDIO devices (SERDES modules) */ ++#define MDIODATA_DEV_PLL 0x1d /* SERDES PLL Dev */ ++#define MDIODATA_DEV_TX 0x1e /* SERDES TX Dev */ ++#define MDIODATA_DEV_RX 0x1f /* SERDES RX Dev */ + -+ if (irq == 0) -+ W_REG(&sb->sbintvec, 0); -+ else -+ OR_REG(&sb->sbipsflag, sbips_int_mask[irq]); -+} ++/* SERDES registers */ ++#define SERDES_RX_TIMER1 2 /* Rx Timer1 */ ++#define SERDES_RX_CDR 6 /* CDR */ ++#define SERDES_RX_CDRBW 7 /* CDR BW */ + ++#endif /* _SBPCIE_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbpcmcia.h linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h +--- linux.old/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h 2006-04-27 20:29:47.000000000 +0200 +@@ -0,0 +1,147 @@ +/* -+ * Assigns the specified MIPS IRQ to the specified core. Shared MIPS -+ * IRQ 0 may be assigned more than once. ++ * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sbpcmcia.h,v 1.1.1.9 2006/02/27 03:43:16 honor Exp $ + */ -+static void -+BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit) -+{ -+ void *regs; -+ sbconfig_t *sb; -+ uint32 flag; -+ -+ regs = sb_setcore(sbh, coreid, coreunit); -+ ASSERT(regs); -+ flag = sb_flag(sbh); + -+ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && -+ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) -+ ASSERT(regs); -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++#ifndef _SBPCMCIA_H ++#define _SBPCMCIA_H + -+ if (irq == 0) -+ OR_REG(&sb->sbintvec, 1 << flag); -+ else { -+ flag <<= sbips_int_shift[irq]; -+ ASSERT(!(flag & ~sbips_int_mask[irq])); -+ flag |= R_REG(&sb->sbipsflag) & ~sbips_int_mask[irq]; -+ W_REG(&sb->sbipsflag, flag); -+ } -+} + -+/* -+ * Initializes clocks and interrupts. SB and NVRAM access must be -+ * initialized prior to calling. ++/* All the addresses that are offsets in attribute space are divided ++ * by two to account for the fact that odd bytes are invalid in ++ * attribute space and our read/write routines make the space appear ++ * as if they didn't exist. Still we want to show the original numbers ++ * as documented in the hnd_pcmcia core manual. + */ -+void -+BCMINITFN(sb_mips_init)(sb_t *sbh) -+{ -+ ulong hz, ns, tmp; -+ extifregs_t *eir; -+ chipcregs_t *cc; -+ char *value; -+ uint irq; + -+ /* Figure out current SB clock speed */ -+ if ((hz = sb_clock(sbh)) == 0) -+ hz = 100000000; -+ ns = 1000000000 / hz; ++/* PCMCIA Function Configuration Registers */ ++#define PCMCIA_FCR (0x700 / 2) + -+ /* Setup external interface timing */ -+ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { -+ /* Initialize extif so we can get to the LEDs and external UART */ -+ W_REG(&eir->prog_config, CF_EN); ++#define FCR0_OFF 0 ++#define FCR1_OFF (0x40 / 2) ++#define FCR2_OFF (0x80 / 2) ++#define FCR3_OFF (0xc0 / 2) + -+ /* Set timing for the flash */ -+ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ -+ tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */ -+ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ -+ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ ++#define PCMCIA_FCR0 (0x700 / 2) ++#define PCMCIA_FCR1 (0x740 / 2) ++#define PCMCIA_FCR2 (0x780 / 2) ++#define PCMCIA_FCR3 (0x7c0 / 2) + -+ /* Set programmable interface timing for external uart */ -+ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ -+ tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */ -+ tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */ -+ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ -+ W_REG(&eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ -+ } else if ((cc = sb_setcore(sbh, SB_CC, 0))) { -+ /* Set timing for the flash */ -+ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ -+ tmp |= CEIL(10, ns) << FW_W1_SHIFT; /* W1 = 10nS */ -+ tmp |= CEIL(120, ns); /* W0 = 120nS */ -+ -+ // Added by Chen-I for 5365 -+ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) -+ { -+ W_REG(&cc->flash_waitcount, tmp); -+ W_REG(&cc->pcmcia_memwait, tmp); -+ } -+ else -+ { -+ if (sb_corerev(sbh) < 9) -+ W_REG(&cc->flash_waitcount, tmp); ++/* Standard PCMCIA FCR registers */ + -+ if ((sb_corerev(sbh) < 9) || -+ ((BCMINIT(sb_chip)(sbh) == BCM5350_DEVICE_ID) && BCMINIT(sb_chiprev)(sbh) == 0)) { -+ W_REG(&cc->pcmcia_memwait, tmp); -+ } -+ } -+ } ++#define PCMCIA_COR 0 + -+ /* Chip specific initialization */ -+ switch (BCMINIT(sb_chip)(sbh)) { -+ case BCM4710_DEVICE_ID: -+ /* Clear interrupt map */ -+ for (irq = 0; irq <= 4; irq++) -+ BCMINIT(sb_clearirq)(sbh, irq); -+ BCMINIT(sb_setirq)(sbh, 0, SB_CODEC, 0); -+ BCMINIT(sb_setirq)(sbh, 0, SB_EXTIF, 0); -+ BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 1); -+ BCMINIT(sb_setirq)(sbh, 3, SB_ILINE20, 0); -+ BCMINIT(sb_setirq)(sbh, 4, SB_PCI, 0); -+ ASSERT(eir); -+ value = BCMINIT(nvram_get)("et0phyaddr"); -+ if (value && !strcmp(value, "31")) { -+ /* Enable internal UART */ -+ W_REG(&eir->corecontrol, CC_UE); -+ /* Give USB its own interrupt */ -+ BCMINIT(sb_setirq)(sbh, 1, SB_USB, 0); -+ } else { -+ /* Disable internal UART */ -+ W_REG(&eir->corecontrol, 0); -+ /* Give Ethernet its own interrupt */ -+ BCMINIT(sb_setirq)(sbh, 1, SB_ENET, 0); -+ BCMINIT(sb_setirq)(sbh, 0, SB_USB, 0); -+ } -+ break; -+ case BCM5350_DEVICE_ID: -+ /* Clear interrupt map */ -+ for (irq = 0; irq <= 4; irq++) -+ BCMINIT(sb_clearirq)(sbh, irq); -+ BCMINIT(sb_setirq)(sbh, 0, SB_CC, 0); -+ BCMINIT(sb_setirq)(sbh, 1, SB_D11, 0); -+ BCMINIT(sb_setirq)(sbh, 2, SB_ENET, 0); -+ BCMINIT(sb_setirq)(sbh, 3, SB_PCI, 0); -+ BCMINIT(sb_setirq)(sbh, 4, SB_USB, 0); -+ break; -+ } -+} ++#define COR_RST 0x80 ++#define COR_LEV 0x40 ++#define COR_IRQEN 0x04 ++#define COR_BLREN 0x01 ++#define COR_FUNEN 0x01 + -+uint32 -+BCMINITFN(sb_mips_clock)(sb_t *sbh) -+{ -+ extifregs_t *eir; -+ chipcregs_t *cc; -+ uint32 n, m; -+ uint idx; -+ uint32 pll_type, rate = 0; + -+ /* get index of the current core */ -+ idx = sb_coreidx(sbh); -+ pll_type = PLL_TYPE1; ++#define PCICIA_FCSR (2 / 2) ++#define PCICIA_PRR (4 / 2) ++#define PCICIA_SCR (6 / 2) ++#define PCICIA_ESR (8 / 2) + -+ /* switch to extif or chipc core */ -+ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { -+ n = R_REG(&eir->clockcontrol_n); -+ m = R_REG(&eir->clockcontrol_sb); -+ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { -+ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; -+ n = R_REG(&cc->clockcontrol_n); -+ if ((pll_type == PLL_TYPE2) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE6) || -+ (pll_type == PLL_TYPE7)) -+ m = R_REG(&cc->clockcontrol_mips); -+ else if (pll_type == PLL_TYPE5) { -+ rate = 200000000; -+ goto out; -+ } -+ else if (pll_type == PLL_TYPE3) { -+ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) { /* 5365 is also type3 */ -+ rate = 200000000; -+ goto out; -+ } else -+ m = R_REG(&cc->clockcontrol_m2); /* 5350 uses m2 to control mips */ -+ } else -+ m = R_REG(&cc->clockcontrol_sb); -+ } else -+ goto out; + -+ // Added by Chen-I for 5365 -+ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) -+ rate = 100000000; -+ else -+ /* calculate rate */ -+ rate = sb_clock_rate(pll_type, n, m); ++#define PCM_MEMOFF 0x0000 ++#define F0_MEMOFF 0x1000 ++#define F1_MEMOFF 0x2000 ++#define F2_MEMOFF 0x3000 ++#define F3_MEMOFF 0x4000 + -+ if (pll_type == PLL_TYPE6) -+ rate = SB2MIPS_T6(rate); ++/* Memory base in the function fcr's */ ++#define MEM_ADDR0 (0x728 / 2) ++#define MEM_ADDR1 (0x72a / 2) ++#define MEM_ADDR2 (0x72c / 2) + -+out: -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); ++/* PCMCIA base plus Srom access in fcr0: */ ++#define PCMCIA_ADDR0 (0x072e / 2) ++#define PCMCIA_ADDR1 (0x0730 / 2) ++#define PCMCIA_ADDR2 (0x0732 / 2) + -+ return rate; -+} ++#define MEM_SEG (0x0734 / 2) ++#define SROM_CS (0x0736 / 2) ++#define SROM_DATAL (0x0738 / 2) ++#define SROM_DATAH (0x073a / 2) ++#define SROM_ADDRL (0x073c / 2) ++#define SROM_ADDRH (0x073e / 2) + -+#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) ++/* Values for srom_cs: */ ++#define SROM_IDLE 0 ++#define SROM_WRITE 1 ++#define SROM_READ 2 ++#define SROM_WEN 4 ++#define SROM_WDS 7 ++#define SROM_DONE 8 + -+static void -+BCMINITFN(handler)(void) -+{ -+ /* Step 11 */ -+ __asm__ ( -+ ".set\tmips32\n\t" -+ "ssnop\n\t" -+ "ssnop\n\t" -+ /* Disable interrupts */ -+ /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */ -+ "mfc0 $15, $12\n\t" -+ /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */ -+ "li $14, -31746\n\t" -+ "and $15, $15, $14\n\t" -+ "mtc0 $15, $12\n\t" -+ "eret\n\t" -+ "nop\n\t" -+ "nop\n\t" -+ ".set\tmips0" -+ ); -+} ++/* CIS stuff */ + -+/* The following MUST come right after handler() */ -+static void -+BCMINITFN(afterhandler)(void) -+{ -+} ++/* The CIS stops where the FCRs start */ ++#define CIS_SIZE PCMCIA_FCR + -+/* -+ * Set the MIPS, backplane and PCI clocks as closely as possible. -+ */ -+bool -+BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock) -+{ -+ extifregs_t *eir = NULL; -+ chipcregs_t *cc = NULL; -+ mipsregs_t *mipsr = NULL; -+ volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci, *clockcontrol_m2; -+ uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, orig_ratio_cfg; -+ uint32 pll_type, sync_mode; -+ uint ic_size, ic_lsize; -+ uint idx, i; -+ typedef struct { -+ uint32 mipsclock; -+ uint16 n; -+ uint32 sb; -+ uint32 pci33; -+ uint32 pci25; -+ } n3m_table_t; -+ static n3m_table_t BCMINITDATA(type1_table)[] = { -+ { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, /* 96.000 32.000 24.000 */ -+ { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, /* 100.000 33.333 25.000 */ -+ { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, /* 104.000 31.200 24.960 */ -+ { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, /* 108.000 32.400 24.923 */ -+ { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, /* 112.000 32.000 24.889 */ -+ { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, /* 115.200 32.000 24.000 */ -+ { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, /* 120.000 30.000 24.000 */ -+ { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, /* 124.800 31.200 24.960 */ -+ { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, /* 128.000 32.000 24.000 */ -+ { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, /* 132.000 33.000 24.750 */ -+ { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, /* 136.000 32.640 24.727 */ -+ { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, /* 140.000 30.000 24.706 */ -+ { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, /* 144.000 30.857 24.686 */ -+ { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, /* 150.857 33.000 24.000 */ -+ { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, /* 152.000 32.571 24.000 */ -+ { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, /* 156.000 31.200 24.960 */ -+ { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, /* 160.000 32.000 24.000 */ -+ { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, /* 163.200 32.640 24.727 */ -+ { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, /* 168.000 32.000 24.889 */ -+ { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, /* 176.000 33.000 24.000 */ -+ }; -+ typedef struct { -+ uint32 mipsclock; -+ uint16 n; -+ uint32 m2; /* that is the clockcontrol_m2 */ -+ } type3_table_t; -+ static type3_table_t type3_table[] = { /* for 5350, mips clock is always double sb clock */ -+ { 150000000, 0x311, 0x4020005 }, -+ { 200000000, 0x311, 0x4020003 }, -+ }; -+ typedef struct { -+ uint32 mipsclock; -+ uint32 sbclock; -+ uint16 n; -+ uint32 sb; -+ uint32 pci33; -+ uint32 m2; -+ uint32 m3; -+ uint32 ratio_cfg; -+ uint32 ratio_parm; -+ } n4m_table_t; ++/* Standard tuples we know about */ + -+ static n4m_table_t BCMINITDATA(type2_table)[] = { -+ { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 8, 0x012a00a9 }, -+ { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 11, 0x0aaa0555 }, -+ { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 11, 0x0aaa0555 }, -+ { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, -+ { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, -+ { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, -+ { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 8, 0x012a00a9 }, -+ { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, -+ { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 11, 0x0aaa0555 }, -+ { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 11, 0x0aaa0555 }, -+ { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, -+ { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, -+ { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 }, -+ { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, 0x012a00a9 }, -+ { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, 0x0aaa0555 }, -+ { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01020600, 0x05000100, 8, 0x012a00a9 }, -+ { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01000100, 0x05000100, 11, 0x0aaa0555 } -+ }; ++#define CISTPL_MANFID 0x20 /* Manufacturer and device id */ ++#define CISTPL_FUNCE 0x22 /* Function extensions */ ++#define CISTPL_CFTABLE 0x1b /* Config table entry */ + -+ static n4m_table_t BCMINITDATA(type4_table)[] = { -+ { 192000000, 96000000, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, -+ { 198000000, 99000000, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 }, -+ { 204000000, 102000000, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 208000000, 104000000, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, -+ { 210000000, 105000000, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 224000000, 112000000, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, -+ { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005, 8, 0x012a00a9 }, -+ { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 240000000, 102857143, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003, 13, 0x254a14a9 }, -+ { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 11, 0x0aaa0555 }, -+ { 252000000, 100800000, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002, 9, 0x02520129 }, -+ { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 }, -+ { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, 0x0aaa0555 }, -+ { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 13, 0x254a14a9 }, -+ { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 }, -+ { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, 0x254a14a9 }, -+ { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 9, 0x02520129 }, -+ { 300000000, 150000000, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002, 11, 0x0aaa0555 } -+ }; ++/* Function extensions for LANs */ + -+ static n4m_table_t BCMINITDATA(type7_table)[] = { -+ { 183333333, 91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, -+ { 187500000, 93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, 0x0aaa0555 }, -+ { 196875000, 98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 11, 0x0aaa0555 }, -+ { 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, 0x0aaa0555 }, -+ { 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, -+ { 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, -+ { 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, 0x0aaa0555 }, -+ { 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, 0x0aaa0555 }, -+ { 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 11, 0x0aaa0555 }, -+ { 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 11, 0x0aaa0555 } -+ }; ++#define LAN_TECH 1 /* Technology type */ ++#define LAN_SPEED 2 /* Raw bit rate */ ++#define LAN_MEDIA 3 /* Transmission media */ ++#define LAN_NID 4 /* Node identification (aka MAC addr) */ ++#define LAN_CONN 5 /* Connector standard */ + -+ ulong start, end, dst; -+ bool ret = FALSE; + -+ /* get index of the current core */ -+ idx = sb_coreidx(sbh); -+ clockcontrol_m2 = NULL; ++/* CFTable */ ++#define CFTABLE_REGWIN_2K 0x08 /* 2k reg windows size */ ++#define CFTABLE_REGWIN_4K 0x10 /* 4k reg windows size */ ++#define CFTABLE_REGWIN_8K 0x20 /* 8k reg windows size */ + -+ /* switch to extif or chipc core */ -+ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { -+ pll_type = PLL_TYPE1; -+ clockcontrol_n = &eir->clockcontrol_n; -+ clockcontrol_sb = &eir->clockcontrol_sb; -+ clockcontrol_pci = &eir->clockcontrol_pci; -+ clockcontrol_m2 = &cc->clockcontrol_m2; -+ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { -+ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; -+ if (pll_type == PLL_TYPE6) { -+ clockcontrol_n = NULL; -+ clockcontrol_sb = NULL; -+ clockcontrol_pci = NULL; -+ } else { -+ clockcontrol_n = &cc->clockcontrol_n; -+ clockcontrol_sb = &cc->clockcontrol_sb; -+ clockcontrol_pci = &cc->clockcontrol_pci; -+ clockcontrol_m2 = &cc->clockcontrol_m2; -+ } -+ } else -+ goto done; ++/* Vendor unique tuples are 0x80-0x8f. Within Broadcom we'll ++ * take one for HNBU, and use "extensions" (a la FUNCE) within it. ++ */ + -+ if (pll_type == PLL_TYPE6) { -+ /* Silence compilers */ -+ orig_n = orig_sb = orig_pci = 0; -+ } else { -+ /* Store the current clock register values */ -+ orig_n = R_REG(clockcontrol_n); -+ orig_sb = R_REG(clockcontrol_sb); -+ orig_pci = R_REG(clockcontrol_pci); -+ } ++#define CISTPL_BRCM_HNBU 0x80 + -+ if (pll_type == PLL_TYPE1) { -+ /* Keep the current PCI clock if not specified */ -+ if (pciclock == 0) { -+ pciclock = sb_clock_rate(pll_type, R_REG(clockcontrol_n), R_REG(clockcontrol_pci)); -+ pciclock = (pciclock <= 25000000) ? 25000000 : 33000000; -+ } ++/* Subtypes of BRCM_HNBU: */ + -+ /* Search for the closest MIPS clock less than or equal to a preferred value */ -+ for (i = 0; i < ARRAYSIZE(BCMINIT(type1_table)); i++) { -+ ASSERT(BCMINIT(type1_table)[i].mipsclock == -+ sb_clock_rate(pll_type, BCMINIT(type1_table)[i].n, BCMINIT(type1_table)[i].sb)); -+ if (BCMINIT(type1_table)[i].mipsclock > mipsclock) -+ break; -+ } -+ if (i == 0) { -+ ret = FALSE; -+ goto done; -+ } else { -+ ret = TRUE; -+ i--; -+ } -+ ASSERT(BCMINIT(type1_table)[i].mipsclock <= mipsclock); ++#define HNBU_SROMREV 0x00 /* A byte with sromrev, 1 if not present */ ++#define HNBU_CHIPID 0x01 /* Two 16bit values: PCI vendor & device id */ ++#define HNBU_BOARDREV 0x02 /* One byte board revision */ ++#define HNBU_PAPARMS 0x03 /* PA parameters: 8 (sromrev == 1) ++ * or 9 (sromrev > 1) bytes ++ */ ++#define HNBU_OEM 0x04 /* Eight bytes OEM data (sromrev == 1) */ ++#define HNBU_CC 0x05 /* Default country code (sromrev == 1) */ ++#define HNBU_AA 0x06 /* Antennas available */ ++#define HNBU_AG 0x07 /* Antenna gain */ ++#define HNBU_BOARDFLAGS 0x08 /* board flags (2 or 4 bytes) */ ++#define HNBU_LEDS 0x09 /* LED set */ ++#define HNBU_CCODE 0x0a /* Country code (2 bytes ascii + 1 byte cctl) ++ * in rev 2 ++ */ ++#define HNBU_CCKPO 0x0b /* 2 byte cck power offsets in rev 3 */ ++#define HNBU_OFDMPO 0x0c /* 4 byte 11g ofdm power offsets in rev 3 */ ++#define HNBU_GPIOTIMER 0x0d /* 2 bytes with on/off values in rev 3 */ + -+ /* No PLL change */ -+ if ((orig_n == BCMINIT(type1_table)[i].n) && -+ (orig_sb == BCMINIT(type1_table)[i].sb) && -+ (orig_pci == BCMINIT(type1_table)[i].pci33)) -+ goto done; + -+ /* Set the PLL controls */ -+ W_REG(clockcontrol_n, BCMINIT(type1_table)[i].n); -+ W_REG(clockcontrol_sb, BCMINIT(type1_table)[i].sb); -+ if (pciclock == 25000000) -+ W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci25); -+ else -+ W_REG(clockcontrol_pci, BCMINIT(type1_table)[i].pci33); ++/* sbtmstatelow */ ++#define SBTML_INT_ACK 0x40000 /* ack the sb interrupt */ ++#define SBTML_INT_EN 0x20000 /* enable sb interrupt */ + -+ /* Reset */ -+ sb_watchdog(sbh, 1); ++/* sbtmstatehigh */ ++#define SBTMH_INT_STATUS 0x40000 /* sb interrupt status */ + -+ while (1); -+ } else if ((pll_type == PLL_TYPE3) && -+ (BCMINIT(sb_chip)(sbh) != BCM5365_DEVICE_ID)) { -+ /* 5350 */ -+ /* Search for the closest MIPS clock less than or equal to a preferred value */ ++#endif /* _SBPCMCIA_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbsdram.h linux.dev/arch/mips/bcm947xx/include/sbsdram.h +--- linux.old/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbsdram.h 2006-04-27 20:36:08.000000000 +0200 +@@ -0,0 +1,85 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sbsdram.h,v 1.1.1.9 2006/03/02 13:03:52 honor Exp $ ++ */ + -+ for (i = 0; i < ARRAYSIZE(type3_table); i++) { -+ if (type3_table[i].mipsclock > mipsclock) -+ break; -+ } -+ if (i == 0) { -+ ret = FALSE; -+ goto done; -+ } else { -+ ret = TRUE; -+ i--; -+ } -+ ASSERT(type3_table[i].mipsclock <= mipsclock); ++#ifndef _SBSDRAM_H ++#define _SBSDRAM_H + -+ /* No PLL change */ -+ orig_m2 = R_REG(&cc->clockcontrol_m2); -+ if ((orig_n == type3_table[i].n) && -+ (orig_m2 == type3_table[i].m2)) { -+ goto done; -+ } ++#ifndef _LANGUAGE_ASSEMBLY + -+ /* Set the PLL controls */ -+ W_REG(clockcontrol_n, type3_table[i].n); -+ W_REG(clockcontrol_m2, type3_table[i].m2); ++/* Sonics side: SDRAM core registers */ ++typedef volatile struct sbsdramregs { ++ uint32 initcontrol; /* Generates external SDRAM initialization sequence */ ++ uint32 config; /* Initializes external SDRAM mode register */ ++ uint32 refresh; /* Controls external SDRAM refresh rate */ ++ uint32 pad1; ++ uint32 pad2; ++} sbsdramregs_t; + -+ /* Reset */ -+ sb_watchdog(sbh, 1); -+ while (1); -+ } else if ((pll_type == PLL_TYPE2) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE6) || -+ (pll_type == PLL_TYPE7)) { -+ n4m_table_t *table = NULL, *te; -+ uint tabsz = 0; ++/* SDRAM simulation */ ++#ifdef RAMSZ ++#define SDRAMSZ RAMSZ ++#else ++#define SDRAMSZ (4 * 1024 * 1024) ++#endif + -+ ASSERT(cc); ++extern uchar sdrambuf[SDRAMSZ]; + -+ orig_mips = R_REG(&cc->clockcontrol_mips); ++#endif /* _LANGUAGE_ASSEMBLY */ + -+ if (pll_type == PLL_TYPE6) { -+ uint32 new_mips = 0; ++/* SDRAM initialization control (initcontrol) register bits */ ++#define SDRAM_CBR 0x0001 /* Writing 1 generates refresh cycle and toggles bit */ ++#define SDRAM_PRE 0x0002 /* Writing 1 generates precharge cycle and toggles bit */ ++#define SDRAM_MRS 0x0004 /* Writing 1 generates mode register select cycle and toggles bit */ ++#define SDRAM_EN 0x0008 /* When set, enables access to SDRAM */ ++#define SDRAM_16Mb 0x0000 /* Use 16 Megabit SDRAM */ ++#define SDRAM_64Mb 0x0010 /* Use 64 Megabit SDRAM */ ++#define SDRAM_128Mb 0x0020 /* Use 128 Megabit SDRAM */ ++#define SDRAM_RSVMb 0x0030 /* Use special SDRAM */ ++#define SDRAM_RST 0x0080 /* Writing 1 causes soft reset of controller */ ++#define SDRAM_SELFREF 0x0100 /* Writing 1 enables self refresh mode */ ++#define SDRAM_PWRDOWN 0x0200 /* Writing 1 causes controller to power down */ ++#define SDRAM_32BIT 0x0400 /* When set, indicates 32 bit SDRAM interface */ ++#define SDRAM_9BITCOL 0x0800 /* When set, indicates 9 bit column */ + -+ ret = TRUE; -+ if (mipsclock <= SB2MIPS_T6(CC_T6_M1)) -+ new_mips = CC_T6_MMASK; ++/* SDRAM configuration (config) register bits */ ++#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */ ++#define SDRAM_BURST8 0x0001 /* Use burst of 8 */ ++#define SDRAM_BURST4 0x0002 /* Use burst of 4 */ ++#define SDRAM_BURST2 0x0003 /* Use burst of 2 */ ++#define SDRAM_CAS3 0x0000 /* Use CAS latency of 3 */ ++#define SDRAM_CAS2 0x0004 /* Use CAS latency of 2 */ + -+ if (orig_mips == new_mips) -+ goto done; ++/* SDRAM refresh control (refresh) register bits */ ++#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */ ++#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */ + -+ W_REG(&cc->clockcontrol_mips, new_mips); -+ goto end_fill; -+ } ++/* SDRAM Core default Init values (OCP ID 0x803) */ ++#define SDRAM_INIT MEM4MX16X2 ++#define SDRAM_CONFIG SDRAM_BURSTFULL ++#define SDRAM_REFRESH SDRAM_REF(0x40) + -+ if (pll_type == PLL_TYPE2) { -+ table = BCMINIT(type2_table); -+ tabsz = ARRAYSIZE(BCMINIT(type2_table)); -+ } else if (pll_type == PLL_TYPE4) { -+ table = BCMINIT(type4_table); -+ tabsz = ARRAYSIZE(BCMINIT(type4_table)); -+ } else if (pll_type == PLL_TYPE7) { -+ table = BCMINIT(type7_table); -+ tabsz = ARRAYSIZE(BCMINIT(type7_table)); -+ } else -+ ASSERT("No table for plltype" == NULL); ++#define MEM1MX16 0x009 /* 2 MB */ ++#define MEM1MX16X2 0x409 /* 4 MB */ ++#define MEM2MX8X2 0x809 /* 4 MB */ ++#define MEM2MX8X4 0xc09 /* 8 MB */ ++#define MEM2MX32 0x439 /* 8 MB */ ++#define MEM4MX16 0x019 /* 8 MB */ ++#define MEM4MX16X2 0x419 /* 16 MB */ ++#define MEM8MX8X2 0x819 /* 16 MB */ ++#define MEM8MX16 0x829 /* 16 MB */ ++#define MEM4MX32 0x429 /* 16 MB */ ++#define MEM8MX8X4 0xc19 /* 32 MB */ ++#define MEM8MX16X2 0xc29 /* 32 MB */ + -+ /* Store the current clock register values */ -+ orig_m2 = R_REG(&cc->clockcontrol_m2); -+ orig_ratio_parm = 0; -+ orig_ratio_cfg = 0; ++#endif /* _SBSDRAM_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbsocram.h linux.dev/arch/mips/bcm947xx/include/sbsocram.h +--- linux.old/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbsocram.h 2006-04-27 22:13:19.000000000 +0200 +@@ -0,0 +1,64 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane embedded ram core ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sbsocram.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $ ++ */ + -+ /* Look up current ratio */ -+ for (i = 0; i < tabsz; i++) { -+ if ((orig_n == table[i].n) && -+ (orig_sb == table[i].sb) && -+ (orig_pci == table[i].pci33) && -+ (orig_m2 == table[i].m2) && -+ (orig_mips == table[i].m3)) { -+ orig_ratio_parm = table[i].ratio_parm; -+ orig_ratio_cfg = table[i].ratio_cfg; -+ break; -+ } -+ } -+ -+ /* Search for the closest MIPS clock greater or equal to a preferred value */ -+ for (i = 0; i < tabsz; i++) { -+ ASSERT(table[i].mipsclock == -+ sb_clock_rate(pll_type, table[i].n, table[i].m3)); -+ if ((mipsclock <= table[i].mipsclock) && -+ ((sbclock == 0) || (sbclock <= table[i].sbclock))) -+ break; -+ } -+ if (i == tabsz) { -+ ret = FALSE; -+ goto done; -+ } else { -+ te = &table[i]; -+ ret = TRUE; -+ } -+ -+ /* No PLL change */ -+ if ((orig_n == te->n) && -+ (orig_sb == te->sb) && -+ (orig_pci == te->pci33) && -+ (orig_m2 == te->m2) && -+ (orig_mips == te->m3)) -+ goto done; -+ -+ /* Set the PLL controls */ -+ W_REG(clockcontrol_n, te->n); -+ W_REG(clockcontrol_sb, te->sb); -+ W_REG(clockcontrol_pci, te->pci33); -+ W_REG(&cc->clockcontrol_m2, te->m2); -+ W_REG(&cc->clockcontrol_mips, te->m3); -+ -+ /* Set the chipcontrol bit to change mipsref to the backplane divider if needed */ -+ if ((pll_type == PLL_TYPE7) && -+ (te->sb != te->m2) && -+ (sb_clock_rate(pll_type, te->n, te->m2) == 120000000)) -+ W_REG(&cc->chipcontrol, R_REG(&cc->chipcontrol) | 0x100); -+ -+ /* No ratio change */ -+ if (orig_ratio_parm == te->ratio_parm) -+ goto end_fill; -+ -+ icache_probe(MFC0(C0_CONFIG, 1), &ic_size, &ic_lsize); -+ -+ /* Preload the code into the cache */ -+ start = ((ulong) &&start_fill) & ~(ic_lsize - 1); -+ end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1); -+ while (start < end) { -+ cache_op(start, Fill_I); -+ start += ic_lsize; -+ } -+ -+ /* Copy the handler */ -+ start = (ulong) &BCMINIT(handler); -+ end = (ulong) &BCMINIT(afterhandler); -+ dst = KSEG1ADDR(0x180); -+ for (i = 0; i < (end - start); i += 4) -+ *((ulong *)(dst + i)) = *((ulong *)(start + i)); -+ -+ /* Preload handler into the cache one line at a time */ -+ for (i = 0; i < (end - start); i += 4) -+ cache_op(dst + i, Fill_I); -+ -+ /* Clear BEV bit */ -+ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV); -+ -+ /* Enable interrupts */ -+ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) | (ALLINTS | ST0_IE)); ++#ifndef _SBSOCRAM_H ++#define _SBSOCRAM_H + -+ /* Enable MIPS timer interrupt */ -+ if (!(mipsr = sb_setcore(sbh, SB_MIPS, 0)) && -+ !(mipsr = sb_setcore(sbh, SB_MIPS33, 0))) -+ ASSERT(mipsr); -+ W_REG(&mipsr->intmask, 1); ++#define SR_COREINFO 0x00 ++#define SR_BWALLOC 0x04 ++#define SR_BISTSTAT 0x0c ++#define SR_BANKINDEX 0x10 ++#define SR_BANKSTBYCTL 0x14 + -+ start_fill: -+ /* step 1, set clock ratios */ -+ MTC0(C0_BROADCOM, 3, te->ratio_parm); -+ MTC0(C0_BROADCOM, 1, te->ratio_cfg); + -+ /* step 2: program timer intr */ -+ W_REG(&mipsr->timer, 100); -+ (void) R_REG(&mipsr->timer); ++#ifndef _LANGUAGE_ASSEMBLY + -+ /* step 3, switch to async */ -+ sync_mode = MFC0(C0_BROADCOM, 4); -+ MTC0(C0_BROADCOM, 4, 1 << 22); ++/* Memcsocram core registers */ ++typedef volatile struct sbsocramregs { ++ uint32 coreinfo; ++ uint32 bwalloc; ++ uint32 PAD; ++ uint32 biststat; ++ uint32 bankidx; ++ uint32 standbyctrl; ++} sbsocramregs_t; + -+ /* step 4, set cfg active */ -+ MTC0(C0_BROADCOM, 2, 0x9); ++#endif + ++/* Coreinfo register */ ++#define SRCI_PT_MASK 0x30000 ++#define SRCI_PT_SHIFT 16 + -+ /* steps 5 & 6 */ -+ __asm__ __volatile__ ( -+ ".set\tmips3\n\t" -+ "wait\n\t" -+ ".set\tmips0" -+ ); ++/* In corerev 0, the memory size is 2 to the power of the ++ * base plus 16 plus to the contents of the memsize field plus 1. ++ */ ++#define SRCI_MS0_MASK 0xf ++#define SR_MS0_BASE 16 + -+ /* step 7, clear cfg_active */ -+ MTC0(C0_BROADCOM, 2, 0); ++/* ++ * In corerev 1 the bank size is 2 ^ the bank size field plus 14, ++ * the memory size is number of banks times bank size. ++ * The same applies to rom size. ++ */ ++#define SRCI_ROMNB_MASK 0xf000 ++#define SRCI_ROMNB_SHIFT 12 ++#define SRCI_ROMBSZ_MASK 0xf00 ++#define SRCI_ROMBSZ_SHIFT 8 ++#define SRCI_SRNB_MASK 0xf0 ++#define SRCI_SRNB_SHIFT 4 ++#define SRCI_SRBSZ_MASK 0xf ++#define SRCI_SRBSZ_SHIFT 0 ++ ++#define SR_BSZ_BASE 14 ++#endif /* _SBSOCRAM_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm947xx/include/sbutils.h +--- linux.old/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbutils.h 2006-04-27 23:09:25.000000000 +0200 +@@ -0,0 +1,150 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of Broadcom HNBU SiliconBackplane-based chips. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sbutils.h,v 1.4 2006/04/08 07:12:42 honor Exp $ ++ */ + -+ /* Additional Step: set back to orig sync mode */ -+ MTC0(C0_BROADCOM, 4, sync_mode); ++#ifndef _sbutils_h_ ++#define _sbutils_h_ + -+ /* step 8, fake soft reset */ -+ MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | 4); ++/* ++ * Datastructure to export all chip specific common variables ++ * public (read-only) portion of sbutils handle returned by ++ * sb_attach()/sb_kattach() ++*/ + -+ end_fill: -+ /* step 9 set watchdog timer */ -+ sb_watchdog(sbh, 20); -+ (void) R_REG(&cc->chipid); -+ -+ /* step 11 */ -+ __asm__ __volatile__ ( -+ ".set\tmips3\n\t" -+ "sync\n\t" -+ "wait\n\t" -+ ".set\tmips0" -+ ); -+ while (1); -+ } ++struct sb_pub { + -+done: -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); ++ uint bustype; /* SB_BUS, PCI_BUS */ ++ uint buscoretype; /* SB_PCI, SB_PCMCIA, SB_PCIE */ ++ uint buscorerev; /* buscore rev */ ++ uint buscoreidx; /* buscore index */ ++ int ccrev; /* chip common core rev */ ++ uint boardtype; /* board type */ ++ uint boardvendor; /* board vendor */ ++ uint chip; /* chip number */ ++ uint chiprev; /* chip revision */ ++ uint chippkg; /* chip package option */ ++ uint sonicsrev; /* sonics backplane rev */ ++}; + -+ return ret; -+} ++typedef const struct sb_pub sb_t; + +/* -+ * This also must be run from the cache on 47xx -+ * so there are no mips core BIU ops in progress -+ * when the PFC is enabled. ++ * Many of the routines below take an 'sbh' handle as their first arg. ++ * Allocate this by calling sb_attach(). Free it by calling sb_detach(). ++ * At any one time, the sbh is logically focused on one particular sb core ++ * (the "current core"). ++ * Use sb_setcore() or sb_setcoreidx() to change the association to another core. + */ + -+static void -+BCMINITFN(_enable_pfc)(uint32 mode) -+{ -+ /* write range */ -+ *(volatile uint32 *)PFC_CR1 = 0xffff0000; -+ -+ /* enable */ -+ *(volatile uint32 *)PFC_CR0 = mode; -+} -+ -+void -+BCMINITFN(enable_pfc)(uint32 mode) -+{ -+ ulong start, end; -+ int i; -+ -+ /* If auto then choose the correct mode for this -+ platform, currently we only ever select one mode */ -+ if (mode == PFC_AUTO) -+ mode = PFC_INST; -+ -+ /* enable prefetch cache if available */ -+ if (MFC0(C0_BROADCOM, 0) & BRCM_PFC_AVAIL) { -+ start = (ulong) &BCMINIT(_enable_pfc); -+ end = (ulong) &BCMINIT(enable_pfc); ++#define SB_OSH NULL /* Use for sb_kattach when no osh is available */ ++/* exported externs */ ++extern sb_t *sb_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, ++ void *sdh, char **vars, uint *varsz); ++extern sb_t *sb_kattach(void); ++extern void sb_detach(sb_t *sbh); ++extern uint sb_chip(sb_t *sbh); ++extern uint sb_chiprev(sb_t *sbh); ++extern uint sb_chipcrev(sb_t *sbh); ++extern uint sb_chippkg(sb_t *sbh); ++extern uint sb_pcirev(sb_t *sbh); ++extern bool sb_war16165(sb_t *sbh); ++extern uint sb_pcmciarev(sb_t *sbh); ++extern uint sb_boardvendor(sb_t *sbh); ++extern uint sb_boardtype(sb_t *sbh); ++extern uint sb_bus(sb_t *sbh); ++extern uint sb_buscoretype(sb_t *sbh); ++extern uint sb_buscorerev(sb_t *sbh); ++extern uint sb_corelist(sb_t *sbh, uint coreid[]); ++extern uint sb_coreid(sb_t *sbh); ++extern uint sb_coreidx(sb_t *sbh); ++extern uint sb_coreunit(sb_t *sbh); ++extern uint sb_corevendor(sb_t *sbh); ++extern uint sb_corerev(sb_t *sbh); ++extern void *sb_osh(sb_t *sbh); ++extern void sb_setosh(sb_t *sbh, osl_t *osh); ++extern void *sb_coreregs(sb_t *sbh); ++extern uint32 sb_coreflags(sb_t *sbh, uint32 mask, uint32 val); ++extern uint32 sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val); ++extern bool sb_iscoreup(sb_t *sbh); ++extern void *sb_setcoreidx(sb_t *sbh, uint coreidx); ++extern void *sb_setcore(sb_t *sbh, uint coreid, uint coreunit); ++extern int sb_corebist(sb_t *sbh); ++extern void sb_commit(sb_t *sbh); ++extern uint32 sb_base(uint32 admatch); ++extern uint32 sb_size(uint32 admatch); ++extern void sb_core_reset(sb_t *sbh, uint32 bits, uint32 resetbits); ++extern void sb_core_tofixup(sb_t *sbh); ++extern void sb_core_disable(sb_t *sbh, uint32 bits); ++extern uint32 sb_clock_rate(uint32 pll_type, uint32 n, uint32 m); ++extern uint32 sb_clock(sb_t *sbh); ++extern void sb_pci_setup(sb_t *sbh, uint coremask); ++extern void sb_pcmcia_init(sb_t *sbh); ++extern void sb_watchdog(sb_t *sbh, uint ticks); ++extern void *sb_gpiosetcore(sb_t *sbh); ++extern uint32 sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioin(sb_t *sbh); ++extern uint32 sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority); ++extern uint32 sb_gpioled(sb_t *sbh, uint32 mask, uint32 val); ++extern uint32 sb_gpioreserve(sb_t *sbh, uint32 gpio_num, uint8 priority); ++extern uint32 sb_gpiorelease(sb_t *sbh, uint32 gpio_num, uint8 priority); + -+ /* Preload handler into the cache one line at a time */ -+ for (i = 0; i < (end - start); i += 4) -+ cache_op(start + i, Fill_I); ++extern void sb_clkctl_init(sb_t *sbh); ++extern uint16 sb_clkctl_fast_pwrup_delay(sb_t *sbh); ++extern bool sb_clkctl_clk(sb_t *sbh, uint mode); ++extern int sb_clkctl_xtal(sb_t *sbh, uint what, bool on); ++extern void sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, ++ void *intrsenabled_fn, void *intr_arg); ++extern uint32 sb_set_initiator_to(sb_t *sbh, uint32 to); ++extern int sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice, ++ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif, ++ uint8 *pciheader); ++extern uint sb_pcie_readreg(void *sbh, void* arg1, uint offset); ++extern uint sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val); ++extern uint32 sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 val); ++extern bool sb_backplane64(sb_t *sbh); ++extern void sb_btcgpiowar(sb_t *sbh); + -+ BCMINIT(_enable_pfc)(mode); -+ } -+} + -+/* returns the ncdl value to be programmed into sdram_ncdl for calibration */ -+uint32 -+BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh) -+{ -+ sbmemcregs_t *memc; -+ uint32 ret = 0; -+ uint32 config, rd, wr, misc, dqsg, cd, sm, sd; -+ uint idx, rev; + -+ idx = sb_coreidx(sbh); + -+ memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0); -+ if (memc == 0) -+ goto out; ++extern bool sb_deviceremoved(sb_t *sbh); ++extern uint32 sb_socram_size(sb_t *sbh); + -+ rev = sb_corerev(sbh); ++/* ++* Build device path. Path size must be >= SB_DEVPATH_BUFSZ. ++* The returned path is NULL terminated and has trailing '/'. ++* Return 0 on success, nonzero otherwise. ++*/ ++extern int sb_devpath(sb_t *sbh, char *path, int size); + -+ config = R_REG(&memc->config); -+ wr = R_REG(&memc->wrncdlcor); -+ rd = R_REG(&memc->rdncdlcor); -+ misc = R_REG(&memc->miscdlyctl); -+ dqsg = R_REG(&memc->dqsgatencdl); ++/* clkctl xtal what flags */ ++#define XTAL 0x1 /* primary crystal oscillator (2050) */ ++#define PLL 0x2 /* main chip pll */ + -+ rd &= MEMC_RDNCDLCOR_RD_MASK; -+ wr &= MEMC_WRNCDLCOR_WR_MASK; -+ dqsg &= MEMC_DQSGATENCDL_G_MASK; ++/* clkctl clk mode */ ++#define CLK_FAST 0 /* force fast (pll) clock */ ++#define CLK_DYNAMIC 2 /* enable dynamic clock control */ + -+ if (config & MEMC_CONFIG_DDR) { -+ ret = (wr << 16) | (rd << 8) | dqsg; -+ } else { -+ if (rev > 0) -+ cd = rd; -+ else -+ cd = (rd == MEMC_CD_THRESHOLD) ? rd : (wr + MEMC_CD_THRESHOLD); -+ sm = (misc & MEMC_MISC_SM_MASK) >> MEMC_MISC_SM_SHIFT; -+ sd = (misc & MEMC_MISC_SD_MASK) >> MEMC_MISC_SD_SHIFT; -+ ret = (sm << 16) | (sd << 8) | cd; -+ } + -+out: -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); ++/* GPIO usage priorities */ ++#define GPIO_DRV_PRIORITY 0 /* Driver */ ++#define GPIO_APP_PRIORITY 1 /* Application */ + -+ return ret; -+} ++/* device path */ ++#define SB_DEVPATH_BUFSZ 16 /* min buffer size in bytes */ + -diff -Naur linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpci.c ---- linux.old/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/sbpci.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,588 @@ ++#endif /* _sbutils_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/sflash.h linux.dev/arch/mips/bcm947xx/include/sflash.h +--- linux.old/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sflash.h 2006-04-27 22:13:51.000000000 +0200 +@@ -0,0 +1,36 @@ +/* -+ * Low-Level PCI and SB support for BCM47xx ++ * Broadcom SiliconBackplane chipcommon serial flash interface + * -+ * Copyright 2005, Broadcom Corporation ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -8420,9061 +8182,6930 @@ diff -Naur linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbp + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id$ ++ * $Id: sflash.h,v 1.1.1.8 2006/02/27 03:43:16 honor Exp $ + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#ifndef _sflash_h_ ++#define _sflash_h_ + -+/* Can free sbpci_init() memory after boot */ -+#ifndef linux -+#define __init -+#endif ++#include ++#include + -+/* Emulated configuration space */ -+static pci_config_regs sb_config_regs[SB_MAXCORES]; ++struct sflash { ++ uint blocksize; /* Block size */ ++ uint numblocks; /* Number of blocks */ ++ uint32 type; /* Type */ ++ uint size; /* Total size in bytes */ ++}; + -+/* Banned cores */ -+static uint16 pci_ban[32] = { 0 }; -+static uint pci_banned = 0; ++/* Utility functions */ ++extern int sflash_poll(chipcregs_t *cc, uint offset); ++extern int sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf); ++extern int sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf); ++extern int sflash_erase(chipcregs_t *cc, uint offset); ++extern int sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf); ++extern struct sflash * sflash_init(chipcregs_t *cc); + -+/* CardBus mode */ -+static bool cardbus = FALSE; ++#endif /* _sflash_h_ */ +diff -urN linux.old/arch/mips/bcm947xx/include/trxhdr.h linux.dev/arch/mips/bcm947xx/include/trxhdr.h +--- linux.old/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/trxhdr.h 2006-04-27 19:24:19.000000000 +0200 +@@ -0,0 +1,33 @@ ++/* ++ * TRX image file header format. ++ * ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id$ ++ */ + -+/* Disable PCI host core */ -+static bool pci_disabled = FALSE; ++#include ++ ++#define TRX_MAGIC 0x30524448 /* "HDR0" */ ++#define TRX_VERSION 1 ++#define TRX_MAX_LEN 0x3A0000 ++#define TRX_NO_HEADER 1 /* Do not write TRX header */ ++#define TRX_GZ_FILES 0x2 /* Contains up to TRX_MAX_OFFSET individual gzip files */ ++#define TRX_MAX_OFFSET 3 ++ ++struct trx_header { ++ uint32 magic; /* "HDR0" */ ++ uint32 len; /* Length of file including header */ ++ uint32 crc32; /* 32-bit CRC from flag_version to end of file */ ++ uint32 flag_version; /* 0:15 flags, 16:31 version */ ++ uint32 offsets[TRX_MAX_OFFSET]; /* Offsets of partitions from start of header */ ++}; + ++/* Compatibility */ ++typedef struct trx_header TRXHDR, *PTRXHDR; +diff -urN linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bcm947xx/include/typedefs.h +--- linux.old/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/typedefs.h 2006-04-27 23:47:30.000000000 +0200 +@@ -0,0 +1,361 @@ +/* -+ * Functions for accessing external PCI configuration space ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: typedefs.h,v 1.1.1.12 2006/04/08 06:13:40 honor Exp $ + */ + -+/* Assume one-hot slot wiring */ -+#define PCI_SLOT_MAX 16 ++#ifndef _TYPEDEFS_H_ ++#define _TYPEDEFS_H_ + -+static uint32 -+config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off) -+{ -+ uint coreidx; -+ sbpciregs_t *regs; -+ uint32 addr = 0; + -+ /* CardBusMode supports only one device */ -+ if (cardbus && dev > 1) -+ return 0; ++/* Define 'SITE_TYPEDEFS' in the compile to include a site specific ++ * typedef file "site_typedefs.h". ++ * ++ * If 'SITE_TYPEDEFS' is not defined, then the "Inferred Typedefs" ++ * section of this file makes inferences about the compile environment ++ * based on defined symbols and possibly compiler pragmas. ++ * ++ * Following these two sections is the "Default Typedefs" ++ * section. This section is only prcessed if 'USE_TYPEDEF_DEFAULTS' is ++ * defined. This section has a default set of typedefs and a few ++ * proprocessor symbols (TRUE, FALSE, NULL, ...). ++ */ + -+ coreidx = sb_coreidx(sbh); -+ regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); ++#ifdef SITE_TYPEDEFS + -+ /* Type 0 transaction */ -+ if (bus == 1) { -+ /* Skip unwired slots */ -+ if (dev < PCI_SLOT_MAX) { -+ /* Slide the PCI window to the appropriate slot */ -+ W_REG(®s->sbtopci1, SBTOPCI_CFG0 | ((1 << (dev + 16)) & SBTOPCI1_MASK)); -+ addr = SB_PCI_CFG | ((1 << (dev + 16)) & ~SBTOPCI1_MASK) | -+ (func << 8) | (off & ~3); -+ } -+ } ++/* ++ * Site Specific Typedefs ++ * ++ */ + -+ /* Type 1 transaction */ -+ else { -+ W_REG(®s->sbtopci1, SBTOPCI_CFG1); -+ addr = SB_PCI_CFG | (bus << 16) | (dev << 11) | (func << 8) | (off & ~3); -+ } ++#include "site_typedefs.h" + -+ sb_setcoreidx(sbh, coreidx); ++#else + -+ return addr; -+} ++/* ++ * Inferred Typedefs ++ * ++ */ + -+static int -+extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ uint32 addr, *reg = NULL, val; -+ int ret = 0; ++/* Infer the compile environment based on preprocessor symbols and pramas. ++ * Override type definitions as needed, and include configuration dependent ++ * header files to define types. ++ */ + -+ if (pci_disabled || -+ !(addr = config_cmd(sbh, bus, dev, func, off)) || -+ !(reg = (uint32 *) REG_MAP(addr, len)) || -+ BUSPROBE(val, reg)) -+ val = 0xffffffff; ++#ifdef __cplusplus + -+ val >>= 8 * (off & 3); -+ if (len == 4) -+ *((uint32 *) buf) = val; -+ else if (len == 2) -+ *((uint16 *) buf) = (uint16) val; -+ else if (len == 1) -+ *((uint8 *) buf) = (uint8) val; -+ else -+ ret = -1; ++#define TYPEDEF_BOOL ++#ifndef FALSE ++#define FALSE false ++#endif ++#ifndef TRUE ++#define TRUE true ++#endif + -+ if (reg) -+ REG_UNMAP(reg); ++#else /* ! __cplusplus */ + -+ return ret; -+} ++#if defined(_WIN32) + -+static int -+extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ uint32 addr, *reg = NULL, val; -+ int ret = 0; ++#define TYPEDEF_BOOL ++typedef unsigned char bool; /* consistent w/BOOL */ + -+ if (pci_disabled || -+ !(addr = config_cmd(sbh, bus, dev, func, off)) || -+ !(reg = (uint32 *) REG_MAP(addr, len)) || -+ BUSPROBE(val, reg)) -+ goto done; ++#endif /* _WIN32 */ + -+ if (len == 4) -+ val = *((uint32 *) buf); -+ else if (len == 2) { -+ val &= ~(0xffff << (8 * (off & 3))); -+ val |= *((uint16 *) buf) << (8 * (off & 3)); -+ } else if (len == 1) { -+ val &= ~(0xff << (8 * (off & 3))); -+ val |= *((uint8 *) buf) << (8 * (off & 3)); -+ } else -+ ret = -1; ++#endif /* ! __cplusplus */ + -+ W_REG(reg, val); ++/* use the Windows ULONG_PTR type when compiling for 64 bit */ ++#if defined(_WIN64) ++#include ++#define TYPEDEF_UINTPTR ++typedef ULONG_PTR uintptr; ++#endif + -+ done: -+ if (reg) -+ REG_UNMAP(reg); + -+ return ret; -+} ++#if defined(_MINOSL_) ++#define _NEED_SIZE_T_ ++#endif + -+/* -+ * Functions for accessing translated SB configuration space -+ */ ++#if defined(_NEED_SIZE_T_) ++typedef long unsigned int size_t; ++#endif + -+static int -+sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ pci_config_regs *cfg; ++#ifdef __DJGPP__ ++typedef long unsigned int size_t; ++#endif /* __DJGPP__ */ + -+ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) -+ return -1; -+ cfg = &sb_config_regs[dev]; ++#ifdef _MSC_VER /* Microsoft C */ ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++typedef signed __int64 int64; ++typedef unsigned __int64 uint64; ++#endif + -+ ASSERT(ISALIGNED(off, len)); -+ ASSERT(ISALIGNED((uintptr)buf, len)); ++#if defined(MACOSX) ++#define TYPEDEF_BOOL ++#endif + -+ if (len == 4) -+ *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off))); -+ else if (len == 2) -+ *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off))); -+ else if (len == 1) -+ *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off)); -+ else -+ return -1; ++#if defined(__NetBSD__) ++#define TYPEDEF_ULONG ++#endif + -+ return 0; -+} + -+static int -+sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ uint coreidx, n; -+ void *regs; -+ sbconfig_t *sb; -+ pci_config_regs *cfg; ++#if defined(linux) ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#define TYPEDEF_ULONG ++#endif + -+ if (dev >= SB_MAXCORES || (off + len) > sizeof(pci_config_regs)) -+ return -1; -+ cfg = &sb_config_regs[dev]; ++#if !defined(linux) && !defined(_WIN32) && !defined(_CFE_) && \ ++ !defined(_HNDRTE_) && !defined(_MINOSL_) && !defined(__DJGPP__) ++#define TYPEDEF_UINT ++#define TYPEDEF_USHORT ++#endif + -+ ASSERT(ISALIGNED(off, len)); -+ ASSERT(ISALIGNED((uintptr)buf, len)); + -+ /* Emulate BAR sizing */ -+ if (off >= OFFSETOF(pci_config_regs, base[0]) && off <= OFFSETOF(pci_config_regs, base[3]) && -+ len == 4 && *((uint32 *) buf) == ~0) { -+ coreidx = sb_coreidx(sbh); -+ if ((regs = sb_setcoreidx(sbh, dev))) { -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); -+ /* Highest numbered address match register */ -+ n = (R_REG(&sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT; -+ if (off == OFFSETOF(pci_config_regs, base[0])) -+ cfg->base[0] = ~(sb_size(R_REG(&sb->sbadmatch0)) - 1); -+ else if (off == OFFSETOF(pci_config_regs, base[1]) && n >= 1) -+ cfg->base[1] = ~(sb_size(R_REG(&sb->sbadmatch1)) - 1); -+ else if (off == OFFSETOF(pci_config_regs, base[2]) && n >= 2) -+ cfg->base[2] = ~(sb_size(R_REG(&sb->sbadmatch2)) - 1); -+ else if (off == OFFSETOF(pci_config_regs, base[3]) && n >= 3) -+ cfg->base[3] = ~(sb_size(R_REG(&sb->sbadmatch3)) - 1); -+ } -+ sb_setcoreidx(sbh, coreidx); -+ return 0; -+ } ++/* Do not support the (u)int64 types with strict ansi for GNU C */ ++#if defined(__GNUC__) && defined(__STRICT_ANSI__) ++#define TYPEDEF_INT64 ++#define TYPEDEF_UINT64 ++#endif + -+ if (len == 4) -+ *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf)); -+ else if (len == 2) -+ *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf)); -+ else if (len == 1) -+ *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf); -+ else -+ return -1; ++/* ICL accepts unsigned 64 bit type only, and complains in ANSI mode ++ * for singned or unsigned ++ */ ++#if defined(__ICL) + -+ return 0; -+} ++#define TYPEDEF_INT64 + -+int -+sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ if (bus == 0) -+ return sb_read_config(sbh, bus, dev, func, off, buf, len); -+ else -+ return extpci_read_config(sbh, bus, dev, func, off, buf, len); -+} ++#if defined(__STDC__) ++#define TYPEDEF_UINT64 ++#endif + -+int -+sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) -+{ -+ if (bus == 0) -+ return sb_write_config(sbh, bus, dev, func, off, buf, len); -+ else -+ return extpci_write_config(sbh, bus, dev, func, off, buf, len); -+} ++#endif /* __ICL */ + -+void -+sbpci_ban(uint16 core) -+{ -+ if (pci_banned < ARRAYSIZE(pci_ban)) -+ pci_ban[pci_banned++] = core; -+} ++#if !defined(_WIN32) && !defined(_CFE_) && !defined(_MINOSL_) && \ ++ !defined(__DJGPP__) + -+static int -+sbpci_init_pci(sb_t *sbh) -+{ -+ uint chip, chiprev, chippkg, host; -+ uint32 boardflags; -+ sbpciregs_t *pci; -+ sbconfig_t *sb; -+ uint32 val; ++/* pick up ushort & uint from standard types.h */ ++#if defined(linux) && defined(__KERNEL__) + -+ chip = sb_chip(sbh); -+ chiprev = sb_chiprev(sbh); -+ chippkg = sb_chippkg(sbh); ++#include /* sys/types.h and linux/types.h are oil and water */ + -+ if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) { -+ printf("PCI: no core\n"); -+ pci_disabled = TRUE; -+ return -1; -+ } -+ sb_core_reset(sbh, 0); ++#else + -+ boardflags = (uint32) getintvar(NULL, "boardflags"); ++#include + -+ if ((chip == BCM4310_DEVICE_ID) && (chiprev == 0)) -+ pci_disabled = TRUE; ++#endif + -+ /* -+ * The 200-pin BCM4712 package does not bond out PCI. Even when -+ * PCI is bonded out, some boards may leave the pins -+ * floating. -+ */ -+ if (((chip == BCM4712_DEVICE_ID) && -+ ((chippkg == BCM4712SMALL_PKG_ID) || -+ (chippkg == BCM4712MID_PKG_ID))) || -+ (boardflags & BFL_NOPCI)) -+ pci_disabled = TRUE; ++#endif /* !_WIN32 && !PMON && !_CFE_ && !_HNDRTE_ && !_MINOSL_ && !__DJGPP__ */ + -+ /* -+ * If the PCI core should not be touched (disabled, not bonded -+ * out, or pins floating), do not even attempt to access core -+ * registers. Otherwise, try to determine if it is in host -+ * mode. -+ */ -+ if (pci_disabled) -+ host = 0; -+ else -+ host = !BUSPROBE(val, &pci->control); ++#if defined(MACOSX) + -+ if (!host) { -+ /* Disable PCI interrupts in client mode */ -+ sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF); -+ W_REG(&sb->sbintvec, 0); ++#ifdef __BIG_ENDIAN__ ++#define IL_BIGENDIAN ++#else ++#ifdef IL_BIGENDIAN ++#error "IL_BIGENDIAN was defined for a little-endian compile" ++#endif ++#endif /* __BIG_ENDIAN__ */ + -+ /* Disable the PCI bridge in client mode */ -+ sbpci_ban(SB_PCI); -+ printf("PCI: Disabled\n"); -+ } else { -+ /* Reset the external PCI bus and enable the clock */ -+ W_REG(&pci->control, 0x5); /* enable the tristate drivers */ -+ W_REG(&pci->control, 0xd); /* enable the PCI clock */ -+ OSL_DELAY(150); /* delay > 100 us */ -+ W_REG(&pci->control, 0xf); /* deassert PCI reset */ -+ W_REG(&pci->arbcontrol, PCI_INT_ARB); /* use internal arbiter */ -+ OSL_DELAY(1); /* delay 1 us */ ++#if !defined(__cplusplus) + -+ /* Enable CardBusMode */ -+ cardbus = nvram_match("cardbus", "1"); -+ if (cardbus) { -+ printf("PCI: Enabling CardBus\n"); -+ /* GPIO 1 resets the CardBus device on bcm94710ap */ -+ sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY); -+ sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY); -+ W_REG(&pci->sprom[0], R_REG(&pci->sprom[0]) | 0x400); -+ } ++#if defined(__i386__) ++typedef unsigned char bool; ++#else ++typedef unsigned int bool; ++#endif ++#define TYPE_BOOL 1 ++enum { ++ false = 0, ++ true = 1 ++}; + -+ /* 64 MB I/O access window */ -+ W_REG(&pci->sbtopci0, SBTOPCI_IO); -+ /* 64 MB configuration access window */ -+ W_REG(&pci->sbtopci1, SBTOPCI_CFG0); -+ /* 1 GB memory access window */ -+ W_REG(&pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA); ++#if defined(KERNEL) ++#include ++#endif /* KERNEL */ + -+ /* Enable PCI bridge BAR0 prefetch and burst */ -+ val = 6; -+ sbpci_write_config(sbh, 1, 0, 0, PCI_CFG_CMD, &val, sizeof(val)); ++#endif /* __cplusplus */ + -+ /* Enable PCI interrupts */ -+ W_REG(&pci->intmask, PCI_INTA); -+ } -+ -+ return 0; -+} ++#endif /* MACOSX */ + -+static int -+sbpci_init_cores(sb_t *sbh) -+{ -+ uint chip, chiprev, chippkg, coreidx, i; -+ sbconfig_t *sb; -+ pci_config_regs *cfg; -+ void *regs; -+ char varname[8]; -+ uint wlidx = 0; -+ uint16 vendor, core; -+ uint8 class, subclass, progif; -+ uint32 val; -+ uint32 sbips_int_mask[] = { 0, SBIPS_INT1_MASK, SBIPS_INT2_MASK, SBIPS_INT3_MASK, SBIPS_INT4_MASK }; -+ uint32 sbips_int_shift[] = { 0, 0, SBIPS_INT2_SHIFT, SBIPS_INT3_SHIFT, SBIPS_INT4_SHIFT }; + -+ chip = sb_chip(sbh); -+ chiprev = sb_chiprev(sbh); -+ chippkg = sb_chippkg(sbh); -+ coreidx = sb_coreidx(sbh); ++/* use the default typedefs in the next section of this file */ ++#define USE_TYPEDEF_DEFAULTS + -+ /* Scan the SB bus */ -+ bzero(sb_config_regs, sizeof(sb_config_regs)); -+ for (cfg = sb_config_regs; cfg < &sb_config_regs[SB_MAXCORES]; cfg++) { -+ cfg->vendor = 0xffff; -+ if (!(regs = sb_setcoreidx(sbh, cfg - sb_config_regs))) -+ continue; -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++#endif /* SITE_TYPEDEFS */ + -+ /* Read ID register and parse vendor and core */ -+ val = R_REG(&sb->sbidhigh); -+ vendor = (val & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT; -+ core = (val & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; -+ progif = 0; + -+ /* Check if this core is banned */ -+ for (i = 0; i < pci_banned; i++) -+ if (core == pci_ban[i]) -+ break; -+ if (i < pci_banned) -+ continue; ++/* ++ * Default Typedefs ++ * ++ */ + -+ /* Known vendor translations */ -+ switch (vendor) { -+ case SB_VEND_BCM: -+ vendor = VENDOR_BROADCOM; -+ break; -+ } ++#ifdef USE_TYPEDEF_DEFAULTS ++#undef USE_TYPEDEF_DEFAULTS + -+ /* Determine class based on known core codes */ -+ switch (core) { -+ case SB_ILINE20: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM47XX_ILINE_ID; -+ break; -+ case SB_ILINE100: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM4610_ILINE_ID; -+ break; -+ case SB_ENET: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM47XX_ENET_ID; -+ break; -+ case SB_SDRAM: -+ case SB_MEMC: -+ class = PCI_CLASS_MEMORY; -+ subclass = PCI_MEMORY_RAM; -+ break; -+ case SB_PCI: -+ class = PCI_CLASS_BRIDGE; -+ subclass = PCI_BRIDGE_PCI; -+ break; -+ case SB_MIPS: -+ case SB_MIPS33: -+ class = PCI_CLASS_CPU; -+ subclass = PCI_CPU_MIPS; -+ break; -+ case SB_CODEC: -+ class = PCI_CLASS_COMM; -+ subclass = PCI_COMM_MODEM; -+ core = BCM47XX_V90_ID; -+ break; -+ case SB_USB: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ progif = 0x10; /* OHCI */ -+ core = BCM47XX_USB_ID; -+ break; -+ case SB_USB11H: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ progif = 0x10; /* OHCI */ -+ core = BCM47XX_USBH_ID; -+ break; -+ case SB_USB11D: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ core = BCM47XX_USBD_ID; -+ break; -+ case SB_IPSEC: -+ class = PCI_CLASS_CRYPT; -+ subclass = PCI_CRYPT_NETWORK; -+ core = BCM47XX_IPSEC_ID; -+ break; -+ case SB_ROBO: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_OTHER; -+ core = BCM47XX_ROBO_ID; -+ break; -+ case SB_EXTIF: -+ case SB_CC: -+ class = PCI_CLASS_MEMORY; -+ subclass = PCI_MEMORY_FLASH; -+ break; -+ case SB_D11: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_OTHER; -+ /* Let an nvram variable override this */ -+ sprintf(varname, "wl%did", wlidx); -+ wlidx++; -+ if ((core = getintvar(NULL, varname)) == 0) { -+ if (chip == BCM4712_DEVICE_ID) { -+ if (chippkg == BCM4712SMALL_PKG_ID) -+ core = BCM4306_D11G_ID; -+ else -+ core = BCM4306_D11DUAL_ID; -+ } else { -+ /* 4310 */ -+ core = BCM4310_D11B_ID; -+ } -+ } -+ break; ++#ifndef TYPEDEF_BOOL ++typedef /* @abstract@ */ unsigned char bool; ++#endif + -+ default: -+ class = subclass = progif = 0xff; -+ break; -+ } ++/* define uchar, ushort, uint, ulong */ + -+ /* Supported translations */ -+ cfg->vendor = htol16(vendor); -+ cfg->device = htol16(core); -+ cfg->rev_id = chiprev; -+ cfg->prog_if = progif; -+ cfg->sub_class = subclass; -+ cfg->base_class = class; -+ cfg->base[0] = htol32(sb_base(R_REG(&sb->sbadmatch0))); -+ cfg->base[1] = htol32(sb_base(R_REG(&sb->sbadmatch1))); -+ cfg->base[2] = htol32(sb_base(R_REG(&sb->sbadmatch2))); -+ cfg->base[3] = htol32(sb_base(R_REG(&sb->sbadmatch3))); -+ cfg->base[4] = 0; -+ cfg->base[5] = 0; -+ if (class == PCI_CLASS_BRIDGE && subclass == PCI_BRIDGE_PCI) -+ cfg->header_type = PCI_HEADER_BRIDGE; -+ else -+ cfg->header_type = PCI_HEADER_NORMAL; -+ /* Save core interrupt flag */ -+ cfg->int_pin = R_REG(&sb->sbtpsflag) & SBTPS_NUM0_MASK; -+ /* Default to MIPS shared interrupt 0 */ -+ cfg->int_line = 0; -+ /* MIPS sbipsflag maps core interrupt flags to interrupts 1 through 4 */ -+ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || -+ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { -+ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); -+ val = R_REG(&sb->sbipsflag); -+ for (cfg->int_line = 1; cfg->int_line <= 4; cfg->int_line++) { -+ if (((val & sbips_int_mask[cfg->int_line]) >> sbips_int_shift[cfg->int_line]) == cfg->int_pin) -+ break; -+ } -+ if (cfg->int_line > 4) -+ cfg->int_line = 0; -+ } -+ /* Emulated core */ -+ *((uint32 *) &cfg->sprom_control) = 0xffffffff; -+ } ++#ifndef TYPEDEF_UCHAR ++typedef unsigned char uchar; ++#endif + -+ sb_setcoreidx(sbh, coreidx); -+ return 0; -+} ++#ifndef TYPEDEF_USHORT ++typedef unsigned short ushort; ++#endif + -+int __init -+sbpci_init(sb_t *sbh) -+{ -+ sbpci_init_pci(sbh); -+ sbpci_init_cores(sbh); -+ return 0; -+} ++#ifndef TYPEDEF_UINT ++typedef unsigned int uint; ++#endif + -+void -+sbpci_check(sb_t *sbh) -+{ -+ uint coreidx; -+ sbpciregs_t *pci; -+ uint32 sbtopci1; -+ uint32 buf[64], *ptr, i; -+ ulong pa; -+ volatile uint j; ++#ifndef TYPEDEF_ULONG ++typedef unsigned long ulong; ++#endif + -+ coreidx = sb_coreidx(sbh); -+ pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); -+ -+ /* Clear the test array */ -+ pa = (ulong) DMA_MAP(NULL, buf, sizeof(buf), DMA_RX, NULL); -+ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); -+ memset(ptr, 0, sizeof(buf)); -+ -+ /* Point PCI window 1 to memory */ -+ sbtopci1 = R_REG(&pci->sbtopci1); -+ W_REG(&pci->sbtopci1, SBTOPCI_MEM | (pa & SBTOPCI1_MASK)); -+ -+ /* Fill the test array via PCI window 1 */ -+ ptr = (uint32 *) REG_MAP(SB_PCI_CFG + (pa & ~SBTOPCI1_MASK), sizeof(buf)); -+ for (i = 0; i < ARRAYSIZE(buf); i++) { -+ for (j = 0; j < 2; j++); -+ W_REG(&ptr[i], i); -+ } -+ REG_UNMAP(ptr); ++/* define [u]int8/16/32/64, uintptr */ + -+ /* Restore PCI window 1 */ -+ W_REG(&pci->sbtopci1, sbtopci1); ++#ifndef TYPEDEF_UINT8 ++typedef unsigned char uint8; ++#endif + -+ /* Check the test array */ -+ DMA_UNMAP(NULL, pa, sizeof(buf), DMA_RX, NULL); -+ ptr = (uint32 *) OSL_UNCACHED(&buf[0]); -+ for (i = 0; i < ARRAYSIZE(buf); i++) { -+ if (ptr[i] != i) -+ break; -+ } ++#ifndef TYPEDEF_UINT16 ++typedef unsigned short uint16; ++#endif + -+ /* Change the clock if the test fails */ -+ if (i < ARRAYSIZE(buf)) { -+ uint32 req, cur; ++#ifndef TYPEDEF_UINT32 ++typedef unsigned int uint32; ++#endif + -+ cur = sb_clock(sbh); -+ printf("PCI: Test failed at %d MHz\n", (cur + 500000) / 1000000); -+ for (req = 104000000; req < 176000000; req += 4000000) { -+ printf("PCI: Resetting to %d MHz\n", (req + 500000) / 1000000); -+ /* This will only reset if the clocks are valid and have changed */ -+ sb_mips_setclock(sbh, req, 0, 0); -+ } -+ /* Should not reach here */ -+ ASSERT(0); -+ } ++#ifndef TYPEDEF_UINT64 ++typedef unsigned long long uint64; ++#endif + -+ sb_setcoreidx(sbh, coreidx); -+} ++#ifndef TYPEDEF_UINTPTR ++typedef unsigned int uintptr; ++#endif + -diff -Naur linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setup.c ---- linux.old/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/setup.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,234 @@ -+/* -+ * Generic setup routines for Broadcom MIPS boards -+ * -+ * Copyright (C) 2005 Felix Fietkau -+ * -+ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ */ ++#ifndef TYPEDEF_INT8 ++typedef signed char int8; ++#endif + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#ifndef TYPEDEF_INT16 ++typedef signed short int16; ++#endif + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Global SB handle */ -+sb_t *bcm947xx_sbh = NULL; -+spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED; -+ -+/* Convenience */ -+#define sbh bcm947xx_sbh -+#define sbh_lock bcm947xx_sbh_lock -+ -+extern void bcm947xx_time_init(void); -+extern void bcm947xx_timer_setup(struct irqaction *irq); -+ -+#ifdef CONFIG_REMOTE_DEBUG -+extern void set_debug_traps(void); -+extern void rs_kgdb_hook(struct serial_state *); -+extern void breakpoint(void); ++#ifndef TYPEDEF_INT32 ++typedef signed int int32; +#endif + -+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) -+extern struct ide_ops std_ide_ops; ++#ifndef TYPEDEF_INT64 ++typedef signed long long int64; +#endif + -+/* Kernel command line */ -+char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE; -+ -+void -+bcm947xx_machine_restart(char *command) -+{ -+ printk("Please stand by while rebooting the system...\n"); -+ -+ /* Set the watchdog timer to reset immediately */ -+ __cli(); -+ sb_watchdog(sbh, 1); -+ while (1); -+} ++/* define float32/64, float_t */ + -+void -+bcm947xx_machine_halt(void) -+{ -+ printk("System halted\n"); ++#ifndef TYPEDEF_FLOAT32 ++typedef float float32; ++#endif + -+ /* Disable interrupts and watchdog and spin forever */ -+ __cli(); -+ sb_watchdog(sbh, 0); -+ while (1); -+} ++#ifndef TYPEDEF_FLOAT64 ++typedef double float64; ++#endif + -+#ifdef CONFIG_SERIAL ++/* ++ * abstracted floating point type allows for compile time selection of ++ * single or double precision arithmetic. Compiling with -DFLOAT32 ++ * selects single precision; the default is double precision. ++ */ + -+static int ser_line = 0; ++#ifndef TYPEDEF_FLOAT_T + -+typedef struct { -+ void *regs; -+ uint irq; -+ uint baud_base; -+ uint reg_shift; -+} serial_port; ++#if defined(FLOAT32) ++typedef float32 float_t; ++#else /* default to double precision floating point */ ++typedef float64 float_t; ++#endif + -+static serial_port ports[4]; -+static int num_ports = 0; ++#endif /* TYPEDEF_FLOAT_T */ + -+static void -+serial_add(void *regs, uint irq, uint baud_base, uint reg_shift) -+{ -+ ports[num_ports].regs = regs; -+ ports[num_ports].irq = irq; -+ ports[num_ports].baud_base = baud_base; -+ ports[num_ports].reg_shift = reg_shift; -+ num_ports++; -+} ++/* define macro values */ + -+static void -+do_serial_add(serial_port *port) -+{ -+ void *regs; -+ uint irq; -+ uint baud_base; -+ uint reg_shift; -+ struct serial_struct s; -+ -+ regs = port->regs; -+ irq = port->irq; -+ baud_base = port->baud_base; -+ reg_shift = port->reg_shift; ++#ifndef FALSE ++#define FALSE 0 ++#endif + -+ memset(&s, 0, sizeof(s)); ++#ifndef TRUE ++#define TRUE 1 /* TRUE */ ++#endif + -+ s.line = ser_line++; -+ s.iomem_base = regs; -+ s.irq = irq + 2; -+ s.baud_base = baud_base / 16; -+ s.flags = ASYNC_BOOT_AUTOCONF; -+ s.io_type = SERIAL_IO_MEM; -+ s.iomem_reg_shift = reg_shift; ++#ifndef NULL ++#define NULL 0 ++#endif + -+ if (early_serial_setup(&s) != 0) { -+ printk(KERN_ERR "Serial setup failed!\n"); -+ } -+} ++#ifndef OFF ++#define OFF 0 ++#endif + -+#endif /* CONFIG_SERIAL */ ++#ifndef ON ++#define ON 1 /* ON = 1 */ ++#endif + -+void __init -+brcm_setup(void) -+{ -+ char *s; -+ int i; -+ char *value; ++#define AUTO (-1) /* Auto = -1 */ + -+ /* Get global SB handle */ -+ sbh = sb_kattach(); ++/* define PTRSZ, INLINE */ + -+ /* Initialize clocks and interrupts */ -+ sb_mips_init(sbh); ++#ifndef PTRSZ ++#define PTRSZ sizeof(char*) ++#endif + -+ if (BCM330X(current_cpu_data.processor_id) && -+ (read_c0_diag() & BRCM_PFC_AVAIL)) { -+ /* -+ * Now that the sbh is inited set the proper PFC value -+ */ -+ printk("Setting the PFC to its default value\n"); -+ enable_pfc(PFC_AUTO); -+ } ++#ifndef INLINE + ++#ifdef _MSC_VER + -+#ifdef CONFIG_SERIAL -+ sb_serial_init(sbh, serial_add); ++#define INLINE __inline + -+ /* reverse serial ports if nvram variable starts with console=ttyS1 */ -+ /* Initialize UARTs */ -+ s = nvram_get("kernel_args"); -+ if (!s) s = ""; -+ if (!strncmp(s, "console=ttyS1", 13)) { -+ for (i = num_ports; i; i--) -+ do_serial_add(&ports[i - 1]); -+ } else { -+ for (i = 0; i < num_ports; i++) -+ do_serial_add(&ports[i]); -+ } -+#endif ++#elif __GNUC__ + -+#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) -+ ide_ops = &std_ide_ops; -+#endif ++#define INLINE __inline__ + -+ /* Override default command line arguments */ -+ value = nvram_get("kernel_cmdline"); -+ if (value && strlen(value) && strncmp(value, "empty", 5)) -+ strncpy(arcs_cmdline, value, sizeof(arcs_cmdline)); ++#else + ++#define INLINE + -+ /* Generic setup */ -+ _machine_restart = bcm947xx_machine_restart; -+ _machine_halt = bcm947xx_machine_halt; -+ _machine_power_off = bcm947xx_machine_halt; ++#endif /* _MSC_VER */ + -+ board_time_init = bcm947xx_time_init; -+ board_timer_setup = bcm947xx_timer_setup; -+} ++#endif /* INLINE */ + -+const char * -+get_system_type(void) -+{ -+ static char s[32]; ++#undef TYPEDEF_BOOL ++#undef TYPEDEF_UCHAR ++#undef TYPEDEF_USHORT ++#undef TYPEDEF_UINT ++#undef TYPEDEF_ULONG ++#undef TYPEDEF_UINT8 ++#undef TYPEDEF_UINT16 ++#undef TYPEDEF_UINT32 ++#undef TYPEDEF_UINT64 ++#undef TYPEDEF_UINTPTR ++#undef TYPEDEF_INT8 ++#undef TYPEDEF_INT16 ++#undef TYPEDEF_INT32 ++#undef TYPEDEF_INT64 ++#undef TYPEDEF_FLOAT32 ++#undef TYPEDEF_FLOAT64 ++#undef TYPEDEF_FLOAT_T + -+ if (bcm947xx_sbh) { -+ sprintf(s, "Broadcom BCM%X chip rev %d", sb_chip(bcm947xx_sbh), -+ sb_chiprev(bcm947xx_sbh)); -+ return s; -+ } -+ else -+ return "Broadcom BCM947XX"; -+} ++#endif /* USE_TYPEDEF_DEFAULTS */ + -+void __init -+bus_error_init(void) -+{ -+} ++/* ++ * Including the bcmdefs.h here, to make sure everyone including typedefs.h ++ * gets this automatically ++*/ ++#include "bcmdefs.h" + -+EXPORT_SYMBOL(bcm947xx_sbh); -diff -Naur linux.old/arch/mips/bcm947xx/sflash.c linux.dev/arch/mips/bcm947xx/sflash.c ---- linux.old/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/sflash.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,418 @@ ++#endif /* _TYPEDEFS_H_ */ +diff -urN linux.old/arch/mips/bcm947xx/nvram.c linux.dev/arch/mips/bcm947xx/nvram.c +--- linux.old/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/nvram.c 2006-04-27 23:11:58.000000000 +0200 +@@ -0,0 +1,315 @@ +/* -+ * Broadcom SiliconBackplane chipcommon serial flash interface ++ * NVRAM variable manipulation (common) + * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id$ + */ + -+#include +#include -+#include -+#include -+#include ++#include ++#include ++#include +#include -+#include -+#include -+ -+/* Private global state */ -+static struct sflash sflash; ++#include + -+/* Issue a serial flash command */ -+static INLINE void -+sflash_cmd(chipcregs_t *cc, uint opcode) -+{ -+ W_REG(&cc->flashcontrol, SFLASH_START | opcode); -+ while (R_REG(&cc->flashcontrol) & SFLASH_BUSY); -+} ++extern struct nvram_tuple * BCMINIT(_nvram_realloc)(struct nvram_tuple *t, const char *name, const char *value); ++extern void BCMINIT(_nvram_free)(struct nvram_tuple *t); ++extern int BCMINIT(_nvram_read)(void *buf); + -+/* Initialize serial flash access */ -+struct sflash * -+sflash_init(chipcregs_t *cc) -+{ -+ uint32 id, id2; ++char * BCMINIT(_nvram_get)(const char *name); ++int BCMINIT(_nvram_set)(const char *name, const char *value); ++int BCMINIT(_nvram_unset)(const char *name); ++int BCMINIT(_nvram_getall)(char *buf, int count); ++int BCMINIT(_nvram_commit)(struct nvram_header *header); ++int BCMINIT(_nvram_init)(void); ++void BCMINIT(_nvram_exit)(void); + -+ bzero(&sflash, sizeof(sflash)); ++static struct nvram_tuple * BCMINITDATA(nvram_hash)[257]; ++static struct nvram_tuple * nvram_dead; + -+ sflash.type = R_REG(&cc->capabilities) & CAP_FLASH_MASK; ++/* Free all tuples. Should be locked. */ ++static void ++BCMINITFN(nvram_free)(void) ++{ ++ uint i; ++ struct nvram_tuple *t, *next; + -+ switch (sflash.type) { -+ case SFLASH_ST: -+ /* Probe for ST chips */ -+ sflash_cmd(cc, SFLASH_ST_DP); -+ sflash_cmd(cc, SFLASH_ST_RES); -+ id = R_REG(&cc->flashdata); -+ switch (id) { -+ case 0x11: -+ /* ST M25P20 2 Mbit Serial Flash */ -+ sflash.blocksize = 64 * 1024; -+ sflash.numblocks = 4; -+ break; -+ case 0x12: -+ /* ST M25P40 4 Mbit Serial Flash */ -+ sflash.blocksize = 64 * 1024; -+ sflash.numblocks = 8; -+ break; -+ case 0x13: -+ /* ST M25P80 8 Mbit Serial Flash */ -+ sflash.blocksize = 64 * 1024; -+ sflash.numblocks = 16; -+ break; -+ case 0x14: -+ /* ST M25P16 16 Mbit Serial Flash */ -+ sflash.blocksize = 64 * 1024; -+ sflash.numblocks = 32; -+ break; -+ case 0x15: -+ /* ST M25P32 32 Mbit Serial Flash */ -+ sflash.blocksize = 64 * 1024; -+ sflash.numblocks = 64; -+ break; -+ case 0xbf: -+ W_REG(&cc->flashaddress, 1); -+ sflash_cmd(cc, SFLASH_ST_RES); -+ id2 = R_REG(&cc->flashdata); -+ if (id2 == 0x44) { -+ /* SST M25VF80 4 Mbit Serial Flash */ -+ sflash.blocksize = 64 * 1024; -+ sflash.numblocks = 8; -+ } -+ break; ++ /* Free hash table */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { ++ for (t = BCMINIT(nvram_hash)[i]; t; t = next) { ++ next = t->next; ++ BCMINIT(_nvram_free)(t); + } -+ break; ++ BCMINIT(nvram_hash)[i] = NULL; ++ } + -+ case SFLASH_AT: -+ /* Probe for Atmel chips */ -+ sflash_cmd(cc, SFLASH_AT_STATUS); -+ id = R_REG(&cc->flashdata) & 0x3c; -+ switch (id) { -+ case 0xc: -+ /* Atmel AT45DB011 1Mbit Serial Flash */ -+ sflash.blocksize = 256; -+ sflash.numblocks = 512; -+ break; -+ case 0x14: -+ /* Atmel AT45DB021 2Mbit Serial Flash */ -+ sflash.blocksize = 256; -+ sflash.numblocks = 1024; -+ break; -+ case 0x1c: -+ /* Atmel AT45DB041 4Mbit Serial Flash */ -+ sflash.blocksize = 256; -+ sflash.numblocks = 2048; -+ break; -+ case 0x24: -+ /* Atmel AT45DB081 8Mbit Serial Flash */ -+ sflash.blocksize = 256; -+ sflash.numblocks = 4096; -+ break; -+ case 0x2c: -+ /* Atmel AT45DB161 16Mbit Serial Flash */ -+ sflash.blocksize = 512; -+ sflash.numblocks = 4096; -+ break; -+ case 0x34: -+ /* Atmel AT45DB321 32Mbit Serial Flash */ -+ sflash.blocksize = 512; -+ sflash.numblocks = 8192; -+ break; -+ case 0x3c: -+ /* Atmel AT45DB642 64Mbit Serial Flash */ -+ sflash.blocksize = 1024; -+ sflash.numblocks = 8192; -+ break; -+ } -+ break; ++ /* Free dead table */ ++ for (t = nvram_dead; t; t = next) { ++ next = t->next; ++ BCMINIT(_nvram_free)(t); + } ++ nvram_dead = NULL; + -+ sflash.size = sflash.blocksize * sflash.numblocks; -+ return sflash.size ? &sflash : NULL; ++ /* Indicate to per-port code that all tuples have been freed */ ++ BCMINIT(_nvram_free)(NULL); +} + -+/* Read len bytes starting at offset into buf. Returns number of bytes read. */ -+int -+sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf) ++/* String hash */ ++static INLINE uint ++hash(const char *s) +{ -+ int cnt; -+ uint32 *from, *to; ++ uint hash = 0; + -+ if (!len) -+ return 0; ++ while (*s) ++ hash = 31 * hash + *s++; + -+ if ((offset + len) > sflash.size) -+ return -22; ++ return hash; ++} + -+ if ((len >= 4) && (offset & 3)) -+ cnt = 4 - (offset & 3); -+ else if ((len >= 4) && ((uint32)buf & 3)) -+ cnt = 4 - ((uint32)buf & 3); -+ else -+ cnt = len; ++/* (Re)initialize the hash table. Should be locked. */ ++static int ++BCMINITFN(nvram_rehash)(struct nvram_header *header) ++{ ++ char buf[] = "0xXXXXXXXX", *name, *value, *end, *eq; + -+ from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset); -+ to = (uint32 *)buf; ++ /* (Re)initialize hash table */ ++ BCMINIT(nvram_free)(); + -+ if (cnt < 4) { -+ bcopy(from, to, cnt); -+ return cnt; ++ /* Parse and set "name=value\0 ... \0\0" */ ++ name = (char *) &header[1]; ++ end = (char *) header + NVRAM_SPACE - 2; ++ end[0] = end[1] = '\0'; ++ for (; *name; name = value + strlen(value) + 1) { ++ if (!(eq = strchr(name, '='))) ++ break; ++ *eq = '\0'; ++ value = eq + 1; ++ BCMINIT(_nvram_set)(name, value); ++ *eq = '='; + } + -+ while (cnt >= 4) { -+ *to++ = *from++; -+ cnt -= 4; ++ /* Set special SDRAM parameters */ ++ if (!BCMINIT(_nvram_get)("sdram_init")) { ++ sprintf(buf, "0x%04X", (uint16)(header->crc_ver_init >> 16)); ++ BCMINIT(_nvram_set)("sdram_init", buf); ++ } ++ if (!BCMINIT(_nvram_get)("sdram_config")) { ++ sprintf(buf, "0x%04X", (uint16)(header->config_refresh & 0xffff)); ++ BCMINIT(_nvram_set)("sdram_config", buf); ++ } ++ if (!BCMINIT(_nvram_get)("sdram_refresh")) { ++ sprintf(buf, "0x%04X", (uint16)((header->config_refresh >> 16) & 0xffff)); ++ BCMINIT(_nvram_set)("sdram_refresh", buf); ++ } ++ if (!BCMINIT(_nvram_get)("sdram_ncdl")) { ++ sprintf(buf, "0x%08X", header->config_ncdl); ++ BCMINIT(_nvram_set)("sdram_ncdl", buf); + } + -+ return (len - cnt); ++ return 0; +} + -+/* Poll for command completion. Returns zero when complete. */ -+int -+sflash_poll(chipcregs_t *cc, uint offset) ++/* Get the value of an NVRAM variable. Should be locked. */ ++char * ++BCMINITFN(_nvram_get)(const char *name) +{ -+ if (offset >= sflash.size) -+ return -22; ++ uint i; ++ struct nvram_tuple *t; ++ char *value; + -+ switch (sflash.type) { -+ case SFLASH_ST: -+ /* Check for ST Write In Progress bit */ -+ sflash_cmd(cc, SFLASH_ST_RDSR); -+ return R_REG(&cc->flashdata) & SFLASH_ST_WIP; -+ case SFLASH_AT: -+ /* Check for Atmel Ready bit */ -+ sflash_cmd(cc, SFLASH_AT_STATUS); -+ return !(R_REG(&cc->flashdata) & SFLASH_AT_READY); -+ } ++ if (!name) ++ return NULL; + -+ return 0; ++ /* Hash the name */ ++ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++ ++ /* Find the associated tuple in the hash table */ ++ for (t = BCMINIT(nvram_hash)[i]; t && strcmp(t->name, name); t = t->next); ++ ++ value = t ? t->value : NULL; ++ ++ return value; +} + -+/* Write len bytes starting at offset into buf. Returns number of bytes -+ * written. Caller should poll for completion. -+ */ -+int -+sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf) ++/* Get the value of an NVRAM variable. Should be locked. */ ++int ++BCMINITFN(_nvram_set)(const char *name, const char *value) +{ -+ struct sflash *sfl; -+ int ret = 0; -+ bool is4712b0; -+ uint32 page, byte, mask; ++ uint i; ++ struct nvram_tuple *t, *u, **prev; + -+ if (!len) ++ /* Hash the name */ ++ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++ ++ /* Find the associated tuple in the hash table */ ++ for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev); ++ ++ /* (Re)allocate tuple */ ++ if (!(u = BCMINIT(_nvram_realloc)(t, name, value))) ++ return -12; /* -ENOMEM */ ++ ++ /* Value reallocated */ ++ if (t && t == u) + return 0; + -+ if ((offset + len) > sflash.size) -+ return -22; ++ /* Move old tuple to the dead table */ ++ if (t) { ++ *prev = t->next; ++ t->next = nvram_dead; ++ nvram_dead = t; ++ } + -+ sfl = &sflash; -+ switch (sfl->type) { -+ case SFLASH_ST: -+ mask = R_REG(&cc->chipid); -+ is4712b0 = (((mask & CID_ID_MASK) == BCM4712_DEVICE_ID) && -+ ((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT))); -+ /* Enable writes */ -+ sflash_cmd(cc, SFLASH_ST_WREN); -+ if (is4712b0) { -+ mask = 1 << 14; -+ W_REG(&cc->flashaddress, offset); -+ W_REG(&cc->flashdata, *buf++); -+ /* Set chip select */ -+ OR_REG(&cc->gpioout, mask); -+ /* Issue a page program with the first byte */ -+ sflash_cmd(cc, SFLASH_ST_PP); -+ ret = 1; -+ offset++; -+ len--; -+ while (len > 0) { -+ if ((offset & 255) == 0) { -+ /* Page boundary, drop cs and return */ -+ AND_REG(&cc->gpioout, ~mask); -+ if (!sflash_poll(cc, offset)) { -+ /* Flash rejected command */ -+ return -11; -+ } -+ return ret; -+ } else { -+ /* Write single byte */ -+ sflash_cmd(cc, *buf++); -+ } -+ ret++; -+ offset++; -+ len--; -+ } -+ /* All done, drop cs if needed */ -+ if ((offset & 255) != 1) { -+ /* Drop cs */ -+ AND_REG(&cc->gpioout, ~mask); -+ if (!sflash_poll(cc, offset)) { -+ /* Flash rejected command */ -+ return -12; -+ } -+ } -+ } else { -+ ret = 1; -+ W_REG(&cc->flashaddress, offset); -+ W_REG(&cc->flashdata, *buf); -+ /* Page program */ -+ sflash_cmd(cc, SFLASH_ST_PP); -+ } -+ break; -+ case SFLASH_AT: -+ mask = sfl->blocksize - 1; -+ page = (offset & ~mask) << 1; -+ byte = offset & mask; -+ /* Read main memory page into buffer 1 */ -+ if (byte || len < sfl->blocksize) { -+ W_REG(&cc->flashaddress, page); -+ sflash_cmd(cc, SFLASH_AT_BUF1_LOAD); -+ /* 250 us for AT45DB321B */ -+ SPINWAIT(sflash_poll(cc, offset), 1000); -+ ASSERT(!sflash_poll(cc, offset)); -+ } -+ /* Write into buffer 1 */ -+ for (ret = 0; ret < len && byte < sfl->blocksize; ret++) { -+ W_REG(&cc->flashaddress, byte++); -+ W_REG(&cc->flashdata, *buf++); -+ sflash_cmd(cc, SFLASH_AT_BUF1_WRITE); -+ } -+ /* Write buffer 1 into main memory page */ -+ W_REG(&cc->flashaddress, page); -+ sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM); -+ break; ++ /* Add new tuple to the hash table */ ++ u->next = BCMINIT(nvram_hash)[i]; ++ BCMINIT(nvram_hash)[i] = u; ++ ++ return 0; ++} ++ ++/* Unset the value of an NVRAM variable. Should be locked. */ ++int ++BCMINITFN(_nvram_unset)(const char *name) ++{ ++ uint i; ++ struct nvram_tuple *t, **prev; ++ ++ if (!name) ++ return 0; ++ ++ /* Hash the name */ ++ i = hash(name) % ARRAYSIZE(BCMINIT(nvram_hash)); ++ ++ /* Find the associated tuple in the hash table */ ++ for (prev = &BCMINIT(nvram_hash)[i], t = *prev; t && strcmp(t->name, name); prev = &t->next, t = *prev); ++ ++ /* Move it to the dead table */ ++ if (t) { ++ *prev = t->next; ++ t->next = nvram_dead; ++ nvram_dead = t; + } + -+ return ret; ++ return 0; +} + -+/* Erase a region. Returns number of bytes scheduled for erasure. -+ * Caller should poll for completion. -+ */ -+int -+sflash_erase(chipcregs_t *cc, uint offset) ++/* Get all NVRAM variables. Should be locked. */ ++int ++BCMINITFN(_nvram_getall)(char *buf, int count) +{ -+ struct sflash *sfl; ++ uint i; ++ struct nvram_tuple *t; ++ int len = 0; + -+ if (offset >= sflash.size) -+ return -22; ++ bzero(buf, count); + -+ sfl = &sflash; -+ switch (sfl->type) { -+ case SFLASH_ST: -+ sflash_cmd(cc, SFLASH_ST_WREN); -+ W_REG(&cc->flashaddress, offset); -+ sflash_cmd(cc, SFLASH_ST_SE); -+ return sfl->blocksize; -+ case SFLASH_AT: -+ W_REG(&cc->flashaddress, offset << 1); -+ sflash_cmd(cc, SFLASH_AT_PAGE_ERASE); -+ return sfl->blocksize; ++ /* Write name=value\0 ... \0\0 */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { ++ for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) { ++ if ((count - len) > (strlen(t->name) + 1 + strlen(t->value) + 1)) ++ len += sprintf(buf + len, "%s=%s", t->name, t->value) + 1; ++ else ++ break; ++ } + } + + return 0; +} + -+/* -+ * writes the appropriate range of flash, a NULL buf simply erases -+ * the region of flash -+ */ ++/* Regenerate NVRAM. Should be locked. */ +int -+sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf) ++BCMINITFN(_nvram_commit)(struct nvram_header *header) +{ -+ struct sflash *sfl; -+ uchar *block = NULL, *cur_ptr, *blk_ptr; -+ uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder; -+ uint blk_offset, blk_len, copied; -+ int bytes, ret = 0; -+ -+ /* Check address range */ -+ if (len <= 0) -+ return 0; ++ char *init, *config, *refresh, *ncdl; ++ char *ptr, *end; ++ int i; ++ struct nvram_tuple *t; ++ struct nvram_header tmp; ++ uint8 crc; + -+ sfl = &sflash; -+ if ((offset + len) > sfl->size) -+ return -1; ++ /* Regenerate header */ ++ header->magic = NVRAM_MAGIC; ++ header->crc_ver_init = (NVRAM_VERSION << 8); ++ if (!(init = BCMINIT(_nvram_get)("sdram_init")) || ++ !(config = BCMINIT(_nvram_get)("sdram_config")) || ++ !(refresh = BCMINIT(_nvram_get)("sdram_refresh")) || ++ !(ncdl = BCMINIT(_nvram_get)("sdram_ncdl"))) { ++ header->crc_ver_init |= SDRAM_INIT << 16; ++ header->config_refresh = SDRAM_CONFIG; ++ header->config_refresh |= SDRAM_REFRESH << 16; ++ header->config_ncdl = 0; ++ } else { ++ header->crc_ver_init |= (bcm_strtoul(init, NULL, 0) & 0xffff) << 16; ++ header->config_refresh = bcm_strtoul(config, NULL, 0) & 0xffff; ++ header->config_refresh |= (bcm_strtoul(refresh, NULL, 0) & 0xffff) << 16; ++ header->config_ncdl = bcm_strtoul(ncdl, NULL, 0); ++ } + -+ blocksize = sfl->blocksize; -+ mask = blocksize - 1; ++ /* Clear data area */ ++ ptr = (char *) header + sizeof(struct nvram_header); ++ bzero(ptr, NVRAM_SPACE - sizeof(struct nvram_header)); + -+ /* Allocate a block of mem */ -+ if (!(block = MALLOC(NULL, blocksize))) -+ return -1; ++ /* Leave space for a double NUL at the end */ ++ end = (char *) header + NVRAM_SPACE - 2; + -+ while (len) { -+ /* Align offset */ -+ cur_offset = offset & ~mask; -+ cur_length = blocksize; -+ cur_ptr = block; ++ /* Write out all tuples */ ++ for (i = 0; i < ARRAYSIZE(BCMINIT(nvram_hash)); i++) { ++ for (t = BCMINIT(nvram_hash)[i]; t; t = t->next) { ++ if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end) ++ break; ++ ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1; ++ } ++ } + -+ remainder = blocksize - (offset & mask); -+ if (len < remainder) -+ cur_retlen = len; -+ else -+ cur_retlen = remainder; ++ /* End with a double NUL */ ++ ptr += 2; + -+ /* buf == NULL means erase only */ -+ if (buf) { -+ /* Copy existing data into holding block if necessary */ -+ if ((offset & mask) || (len < blocksize)) { -+ blk_offset = cur_offset; -+ blk_len = cur_length; -+ blk_ptr = cur_ptr; ++ /* Set new length */ ++ header->len = ROUNDUP(ptr - (char *) header, 4); + -+ /* Copy entire block */ -+ while(blk_len) { -+ copied = sflash_read(cc, blk_offset, blk_len, blk_ptr); -+ blk_offset += copied; -+ blk_len -= copied; -+ blk_ptr += copied; -+ } -+ } ++ /* Little-endian CRC8 over the last 11 bytes of the header */ ++ tmp.crc_ver_init = htol32(header->crc_ver_init); ++ tmp.config_refresh = htol32(header->config_refresh); ++ tmp.config_ncdl = htol32(header->config_ncdl); ++ crc = hndcrc8((char *) &tmp + 9, sizeof(struct nvram_header) - 9, CRC8_INIT_VALUE); + -+ /* Copy input data into holding block */ -+ memcpy(cur_ptr + (offset & mask), buf, cur_retlen); -+ } ++ /* Continue CRC8 over data bytes */ ++ crc = hndcrc8((char *) &header[1], header->len - sizeof(struct nvram_header), crc); + -+ /* Erase block */ -+ if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0) -+ goto done; -+ while (sflash_poll(cc, (uint) cur_offset)); ++ /* Set new CRC8 */ ++ header->crc_ver_init |= crc; + -+ /* buf == NULL means erase only */ -+ if (!buf) { -+ offset += cur_retlen; -+ len -= cur_retlen; -+ continue; -+ } ++ /* Reinitialize hash table */ ++ return BCMINIT(nvram_rehash)(header); ++} + -+ /* Write holding block */ -+ while (cur_length > 0) { -+ if ((bytes = sflash_write(cc, -+ (uint) cur_offset, -+ (uint) cur_length, -+ (uchar *) cur_ptr)) < 0) { -+ ret = bytes; -+ goto done; -+ } -+ while (sflash_poll(cc, (uint) cur_offset)); -+ cur_offset += bytes; -+ cur_length -= bytes; -+ cur_ptr += bytes; -+ } ++/* Initialize hash table. Should be locked. */ ++int ++BCMINITFN(_nvram_init)(void) ++{ ++ struct nvram_header *header; ++ int ret; + -+ offset += cur_retlen; -+ len -= cur_retlen; -+ buf += cur_retlen; ++ if (!(header = (struct nvram_header *) kmalloc(NVRAM_SPACE, GFP_ATOMIC))) { ++ return -12; /* -ENOMEM */ + } + -+ ret = len; -+done: -+ if (block) -+ MFREE(NULL, block, blocksize); ++ if ((ret = BCMINIT(_nvram_read)(header)) == 0 && ++ header->magic == NVRAM_MAGIC) ++ BCMINIT(nvram_rehash)(header); ++ ++ kfree(header); + return ret; +} + -diff -Naur linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time.c ---- linux.old/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/time.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,118 @@ -+/* -+ * Copyright 2004, Broadcom Corporation -+ * All Rights Reserved. ++/* Free hash table. Should be locked. */ ++void ++BCMINITFN(_nvram_exit)(void) ++{ ++ BCMINIT(nvram_free)(); ++} +diff -urN linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947xx/nvram_linux.c +--- linux.old/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/nvram_linux.c 2006-04-27 23:30:07.000000000 +0200 +@@ -0,0 +1,723 @@ ++/* ++ * NVRAM variable manipulation (Linux kernel half) ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id: time.c,v 1.1 2005/03/16 13:49:59 wbx Exp $ ++ * $Id: nvram_linux.c,v 1.19 2006/04/08 07:12:42 honor Exp $ + */ ++ +#include +#include ++#include +#include -+#include -+#include ++#include +#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include +#include +#include -+#include ++#include + +#include +#include -+#include ++#include +#include ++#include +#include -+#include -+#include ++#include ++#include ++#include ++#include ++ ++/* In BSS to minimize text size and page aligned so it can be mmap()-ed */ ++static char nvram_buf[NVRAM_SPACE] __attribute__((aligned(PAGE_SIZE))); ++ ++#ifdef MODULE ++ ++#define early_nvram_get(name) nvram_get(name) ++ ++#else /* !MODULE */ + +/* Global SB handle */ +extern void *bcm947xx_sbh; +extern spinlock_t bcm947xx_sbh_lock; + ++static int cfe_env; ++extern char *cfe_env_get(char *nv_buf, const char *name); ++ +/* Convenience */ +#define sbh bcm947xx_sbh +#define sbh_lock bcm947xx_sbh_lock ++#define KB * 1024 ++#define MB * 1024 * 1024 + -+extern int panic_timeout; -+static int watchdog = 0; -+static u8 *mcr = NULL; -+ -+void __init -+bcm947xx_time_init(void) ++/* Probe for NVRAM header */ ++static void __init ++early_nvram_init(void) +{ -+ unsigned int hz; -+ extifregs_t *eir; ++ struct nvram_header *header; ++ chipcregs_t *cc; ++ struct sflash *info = NULL; ++ int i; ++ uint32 base, off, lim; ++ u32 *src, *dst; + -+ /* -+ * Use deterministic values for initial counter interrupt -+ * so that calibrate delay avoids encountering a counter wrap. -+ */ -+ write_c0_count(0); -+ write_c0_compare(0xffff); ++ if ((cc = sb_setcore(sbh, SB_CC, 0)) != NULL) { ++ base = KSEG1ADDR(SB_FLASH2); ++ switch (readl(&cc->capabilities) & CAP_FLASH_MASK) { ++ case PFLASH: ++ lim = SB_FLASH2_SZ; ++ break; + -+ if (!(hz = sb_mips_clock(sbh))) -+ hz = 100000000; ++ case SFLASH_ST: ++ case SFLASH_AT: ++ if ((info = sflash_init(cc)) == NULL) ++ return; ++ lim = info->size; ++ break; + -+ printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh), -+ (hz + 500000) / 1000000); ++ case FLASH_NONE: ++ default: ++ return; ++ } ++ } else { ++ /* extif assumed, Stop at 4 MB */ ++ base = KSEG1ADDR(SB_FLASH1); ++ lim = SB_FLASH1_SZ; ++ } + -+ /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ -+ mips_hpt_frequency = hz / 2; ++ /* XXX: hack for supporting the CFE environment stuff on WGT634U */ ++ src = (u32 *) KSEG1ADDR(base + 8 * 1024 * 1024 - 0x2000); ++ dst = (u32 *) nvram_buf; ++ if ((lim == 0x02000000) && ((*src & 0xff00ff) == 0x000001)) { ++ printk("early_nvram_init: WGT634U NVRAM found.\n"); + -+ /* Set watchdog interval in ms */ -+ watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0); -+ -+ /* Please set the watchdog to 3 sec if it is less than 3 but not equal to 0 */ -+ if (watchdog > 0) { -+ if (watchdog < 3000) -+ watchdog = 3000; ++ for (i = 0; i < 0x1ff0; i++) { ++ if (*src == 0xFFFFFFFF) ++ break; ++ *dst++ = *src++; ++ } ++ cfe_env = 1; ++ return; + } + ++ off = FLASH_MIN; ++ while (off <= lim) { ++ /* Windowed flash access */ ++ header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ off <<= 1; ++ } + -+ /* Set panic timeout in seconds */ -+ panic_timeout = watchdog / 1000; ++ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ ++ header = (struct nvram_header *) KSEG1ADDR(base + 4 KB); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ ++ header = (struct nvram_header *) KSEG1ADDR(base + 1 KB); ++ if (header->magic == NVRAM_MAGIC) ++ goto found; ++ ++ printk("early_nvram_init: NVRAM not found\n"); ++ return; + -+ /* Setup blink */ -+ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { -+ sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF); -+ unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1))); -+ mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1); ++found: ++ src = (u32 *) header; ++ dst = (u32 *) nvram_buf; ++ for (i = 0; i < sizeof(struct nvram_header); i += 4) ++ *dst++ = *src++; ++ for (; i < header->len && i < NVRAM_SPACE; i += 4) ++ *dst++ = ltoh32(*src++); ++} ++ ++/* Early (before mm or mtd) read-only access to NVRAM */ ++static char * __init ++early_nvram_get(const char *name) ++{ ++ char *var, *value, *end, *eq; ++ ++ if (!name) ++ return NULL; ++ ++ /* Too early? */ ++ if (sbh == NULL) ++ return NULL; ++ ++ if (!nvram_buf[0]) ++ early_nvram_init(); ++ ++ if (cfe_env) ++ return cfe_env_get(nvram_buf, name); ++ ++ /* Look for name=value and return value */ ++ var = &nvram_buf[sizeof(struct nvram_header)]; ++ end = nvram_buf + sizeof(nvram_buf) - 2; ++ end[0] = end[1] = '\0'; ++ for (; *var; var = value + strlen(value) + 1) { ++ if (!(eq = strchr(var, '='))) ++ break; ++ value = eq + 1; ++ if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0) ++ return value; + } ++ ++ return NULL; +} + -+static void -+bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++static int __init ++early_nvram_getall(char *buf, int count) +{ -+ /* Generic MIPS timer code */ -+ timer_interrupt(irq, dev_id, regs); ++ char *var, *end; ++ int len = 0; ++ ++ /* Too early? */ ++ if (sbh == NULL) ++ return -1; + -+ /* Set the watchdog timer to reset after the specified number of ms */ -+ if (watchdog > 0) -+ sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog); ++ if (!nvram_buf[0]) ++ early_nvram_init(); + -+#ifdef CONFIG_HWSIM -+ (*((int *)0xa0000f1c))++; -+#else -+ /* Blink one of the LEDs in the external UART */ -+ if (mcr && !(jiffies % (HZ/2))) -+ writeb(readb(mcr) ^ UART_MCR_OUT2, mcr); -+#endif ++ bzero(buf, count); ++ ++ /* Write name=value\0 ... \0\0 */ ++ var = &nvram_buf[sizeof(struct nvram_header)]; ++ end = nvram_buf + sizeof(nvram_buf) - 2; ++ end[0] = end[1] = '\0'; ++ for (; *var; var += strlen(var) + 1) { ++ if ((count - len) <= (strlen(var) + 1)) ++ break; ++ len += sprintf(buf + len, "%s", var) + 1; ++ } ++ ++ return 0; +} ++#endif /* !MODULE */ + -+static struct irqaction bcm947xx_timer_irqaction = { -+ bcm947xx_timer_interrupt, -+ SA_INTERRUPT, -+ 0, -+ "timer", -+ NULL, -+ NULL -+}; ++extern char * _nvram_get(const char *name); ++extern int _nvram_set(const char *name, const char *value); ++extern int _nvram_unset(const char *name); ++extern int _nvram_getall(char *buf, int count); ++extern int _nvram_commit(struct nvram_header *header); ++extern int _nvram_init(void *sbh); ++extern void _nvram_exit(void); + -+void __init -+bcm947xx_timer_setup(struct irqaction *irq) ++/* Globals */ ++static spinlock_t nvram_lock = SPIN_LOCK_UNLOCKED; ++static struct semaphore nvram_sem; ++static unsigned long nvram_offset = 0; ++static int nvram_major = -1; ++static devfs_handle_t nvram_handle = NULL; ++static struct mtd_info *nvram_mtd = NULL; ++ ++int ++_nvram_read(char *buf) +{ -+ /* Enable the timer interrupt */ -+ setup_irq(7, &bcm947xx_timer_irqaction); ++ struct nvram_header *header = (struct nvram_header *) buf; ++ size_t len; ++ ++ if (!nvram_mtd || ++ MTD_READ(nvram_mtd, nvram_mtd->size - NVRAM_SPACE, NVRAM_SPACE, &len, buf) || ++ len != NVRAM_SPACE || ++ header->magic != NVRAM_MAGIC) { ++ /* Maybe we can recover some data from early initialization */ ++ memcpy(buf, nvram_buf, NVRAM_SPACE); ++ } ++ ++ return 0; +} -diff -Naur linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared.in ---- linux.old/arch/mips/config-shared.in 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/arch/mips/config-shared.in 2006-04-06 15:34:14.000000000 +0200 -@@ -208,6 +208,14 @@ - fi - define_bool CONFIG_MIPS_RTC y - fi -+dep_bool 'Support for Broadcom MIPS-based boards' CONFIG_MIPS_BRCM $CONFIG_EXPERIMENTAL -+dep_bool 'Support for Broadcom BCM947XX' CONFIG_BCM947XX $CONFIG_MIPS_BRCM -+if [ "$CONFIG_BCM947XX" = "y" ] ; then -+ bool ' Support for Broadcom BCM4710' CONFIG_BCM4710 -+ bool ' Support for Broadcom BCM4310' CONFIG_BCM4310 -+ bool ' Support for Broadcom BCM4704' CONFIG_BCM4704 -+ bool ' Support for Broadcom BCM5365' CONFIG_BCM5365 -+fi - bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI - bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226 - bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229 -@@ -229,6 +237,11 @@ - define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n - - # -+# Provide an option for a default kernel command line -+# -+string 'Default kernel command string' CONFIG_CMDLINE "" -+ -+# - # Select some configuration options automatically based on user selections. - # - if [ "$CONFIG_ACER_PICA_61" = "y" ]; then -@@ -554,6 +567,13 @@ - define_bool CONFIG_SWAP_IO_SPACE_L y - define_bool CONFIG_BOOT_ELF32 y - fi -+if [ "$CONFIG_BCM947XX" = "y" ] ; then -+ define_bool CONFIG_PCI y -+ define_bool CONFIG_NONCOHERENT_IO y -+ define_bool CONFIG_NEW_TIME_C y -+ define_bool CONFIG_NEW_IRQ y -+ define_bool CONFIG_HND y -+fi - if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then - define_bool CONFIG_ARC32 y - define_bool CONFIG_ARC_MEMORY y -@@ -1042,7 +1062,11 @@ - - bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE - bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG --bool 'Remote GDB kernel debugging' CONFIG_KGDB -+if [ "$CONFIG_BCM947XX" = "y" ] ; then -+ bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG -+else -+ bool 'Remote GDB kernel debugging' CONFIG_KGDB -+fi - dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB - if [ "$CONFIG_KGDB" = "y" ]; then - define_bool CONFIG_DEBUG_INFO y -diff -Naur linux.old/arch/mips/kernel/cpu-probe.c linux.dev/arch/mips/kernel/cpu-probe.c ---- linux.old/arch/mips/kernel/cpu-probe.c 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/arch/mips/kernel/cpu-probe.c 2006-04-06 15:34:14.000000000 +0200 -@@ -162,7 +162,7 @@ - - static inline void cpu_probe_legacy(struct cpuinfo_mips *c) - { -- switch (c->processor_id & 0xff00) { -+ switch (c->processor_id & PRID_IMP_MASK) { - case PRID_IMP_R2000: - c->cputype = CPU_R2000; - c->isa_level = MIPS_CPU_ISA_I; -@@ -172,7 +172,7 @@ - c->tlbsize = 64; - break; - case PRID_IMP_R3000: -- if ((c->processor_id & 0xff) == PRID_REV_R3000A) -+ if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) - if (cpu_has_confreg()) - c->cputype = CPU_R3081E; - else -@@ -187,12 +187,12 @@ - break; - case PRID_IMP_R4000: - if (read_c0_config() & CONF_SC) { -- if ((c->processor_id & 0xff) >= PRID_REV_R4400) -+ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) - c->cputype = CPU_R4400PC; - else - c->cputype = CPU_R4000PC; - } else { -- if ((c->processor_id & 0xff) >= PRID_REV_R4400) -+ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) - c->cputype = CPU_R4400SC; - else - c->cputype = CPU_R4000SC; -@@ -438,7 +438,7 @@ - static inline void cpu_probe_mips(struct cpuinfo_mips *c) - { - decode_config1(c); -- switch (c->processor_id & 0xff00) { -+ switch (c->processor_id & PRID_IMP_MASK) { - case PRID_IMP_4KC: - c->cputype = CPU_4KC; - c->isa_level = MIPS_CPU_ISA_M32; -@@ -479,10 +479,10 @@ - { - decode_config1(c); - c->options |= MIPS_CPU_PREFETCH; -- switch (c->processor_id & 0xff00) { -+ switch (c->processor_id & PRID_IMP_MASK) { - case PRID_IMP_AU1_REV1: - case PRID_IMP_AU1_REV2: -- switch ((c->processor_id >> 24) & 0xff) { -+ switch ((c->processor_id >> 24) & PRID_REV_MASK) { - case 0: - c->cputype = CPU_AU1000; - break; -@@ -510,10 +510,34 @@ - } - } - -+static inline void cpu_probe_broadcom(struct cpuinfo_mips *c) -+{ -+ decode_config1(c); -+ c->options |= MIPS_CPU_PREFETCH; -+ switch (c->processor_id & PRID_IMP_MASK) { -+ case PRID_IMP_BCM4710: -+ c->cputype = CPU_BCM4710; -+ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | -+ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; -+ c->scache.flags = MIPS_CACHE_NOT_PRESENT; -+ break; -+ case PRID_IMP_4KC: -+ case PRID_IMP_BCM3302: -+ c->cputype = CPU_BCM3302; -+ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | -+ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; -+ c->scache.flags = MIPS_CACHE_NOT_PRESENT; -+ break; -+ default: -+ c->cputype = CPU_UNKNOWN; -+ break; -+ } -+} -+ - static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) - { - decode_config1(c); -- switch (c->processor_id & 0xff00) { -+ switch (c->processor_id & PRID_IMP_MASK) { - case PRID_IMP_SB1: - c->cputype = CPU_SB1; - c->isa_level = MIPS_CPU_ISA_M64; -@@ -535,7 +559,7 @@ - static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) - { - decode_config1(c); -- switch (c->processor_id & 0xff00) { -+ switch (c->processor_id & PRID_IMP_MASK) { - case PRID_IMP_SR71000: - c->cputype = CPU_SR71000; - c->isa_level = MIPS_CPU_ISA_M64; -@@ -560,7 +584,7 @@ - c->cputype = CPU_UNKNOWN; - - c->processor_id = read_c0_prid(); -- switch (c->processor_id & 0xff0000) { -+ switch (c->processor_id & PRID_COMP_MASK) { - - case PRID_COMP_LEGACY: - cpu_probe_legacy(c); -@@ -571,6 +595,9 @@ - case PRID_COMP_ALCHEMY: - cpu_probe_alchemy(c); - break; -+ case PRID_COMP_BROADCOM: -+ cpu_probe_broadcom(c); -+ break; - case PRID_COMP_SIBYTE: - cpu_probe_sibyte(c); - break; -diff -Naur linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S ---- linux.old/arch/mips/kernel/head.S 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/arch/mips/kernel/head.S 2006-04-06 15:34:14.000000000 +0200 -@@ -28,12 +28,20 @@ - #include - #include - -+#ifdef CONFIG_BCM4710 -+#undef eret -+#define eret nop; nop; eret -+#endif -+ - .text -+ j kernel_entry -+ nop -+ - /* - * Reserved space for exception handlers. - * Necessary for machines which link their kernels at KSEG0. - */ -- .fill 0x400 -+ .fill 0x3f4 - - /* The following two symbols are used for kernel profiling. */ - EXPORT(stext) -diff -Naur linux.old/arch/mips/kernel/proc.c linux.dev/arch/mips/kernel/proc.c ---- linux.old/arch/mips/kernel/proc.c 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/arch/mips/kernel/proc.c 2006-04-06 15:34:14.000000000 +0200 -@@ -78,9 +78,10 @@ - [CPU_AU1550] "Au1550", - [CPU_24K] "MIPS 24K", - [CPU_AU1200] "Au1200", -+ [CPU_BCM4710] "BCM4710", -+ [CPU_BCM3302] "BCM3302", - }; - -- - static int show_cpuinfo(struct seq_file *m, void *v) - { - unsigned int version = current_cpu_data.processor_id; -diff -Naur linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c ---- linux.old/arch/mips/kernel/setup.c 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/arch/mips/kernel/setup.c 2006-04-06 15:34:14.000000000 +0200 -@@ -493,6 +493,7 @@ - void swarm_setup(void); - void hp_setup(void); - void au1x00_setup(void); -+ void brcm_setup(void); - void frame_info_init(void); - - frame_info_init(); -@@ -691,6 +692,11 @@ - pmc_yosemite_setup(); - break; - #endif -+#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4310) -+ case MACH_GROUP_BRCM: -+ brcm_setup(); -+ break; -+#endif - default: - panic("Unsupported architecture"); - } -diff -Naur linux.old/arch/mips/kernel/traps.c linux.dev/arch/mips/kernel/traps.c ---- linux.old/arch/mips/kernel/traps.c 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/arch/mips/kernel/traps.c 2006-04-06 15:34:14.000000000 +0200 -@@ -920,6 +920,7 @@ - void __init trap_init(void) - { - extern char except_vec1_generic; -+ extern char except_vec2_generic; - extern char except_vec3_generic, except_vec3_r4000; - extern char except_vec_ejtag_debug; - extern char except_vec4; -@@ -927,6 +928,7 @@ - - /* Copy the generic exception handler code to it's final destination. */ - memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); -+ memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); - - /* - * Setup default vectors -@@ -985,6 +987,12 @@ - set_except_vector(13, handle_tr); - set_except_vector(22, handle_mdmx); - -+ if (current_cpu_data.cputype == CPU_SB1) { -+ /* Enable timer interrupt and scd mapped interrupt */ -+ clear_c0_status(0xf000); -+ set_c0_status(0xc00); -+ } -+ - if (cpu_has_fpu && !cpu_has_nofpuex) - set_except_vector(15, handle_fpe); - -diff -Naur linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c ---- linux.old/arch/mips/mm/c-r4k.c 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/arch/mips/mm/c-r4k.c 2006-04-06 15:34:15.000000000 +0200 -@@ -1166,3 +1166,47 @@ - build_clear_page(); - build_copy_page(); - } -+ -+#ifdef CONFIG_BCM4704 -+static void __init mips32_icache_fill(unsigned long addr, uint nbytes) -+{ -+ unsigned long ic_lsize = current_cpu_data.icache.linesz; -+ int i; -+ for (i = 0; i < nbytes; i += ic_lsize) -+ fill_icache_line((addr + i)); -+} -+ -+/* -+ * This must be run from the cache on 4704A0 -+ * so there are no mips core BIU ops in progress -+ * when the PFC is enabled. -+ */ -+#define PFC_CR0 0xff400000 /* control reg 0 */ -+#define PFC_CR1 0xff400004 /* control reg 1 */ -+static void __init enable_pfc(u32 mode) -+{ -+ /* write range */ -+ *(volatile u32 *)PFC_CR1 = 0xffff0000; -+ -+ /* enable */ -+ *(volatile u32 *)PFC_CR0 = mode; -+} -+#endif -+ -+ -+void check_enable_mips_pfc(int val) -+{ -+ -+#ifdef CONFIG_BCM4704 -+ struct cpuinfo_mips *c = ¤t_cpu_data; -+ -+ /* enable prefetch cache */ -+ if (((c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) == PRID_IMP_BCM3302) -+ && (read_c0_diag() & (1 << 29))) { -+ mips32_icache_fill((unsigned long) &enable_pfc, 64); -+ enable_pfc(val); -+ } -+#endif -+} -+ -+ -diff -Naur linux.old/arch/mips/pci/Makefile linux.dev/arch/mips/pci/Makefile ---- linux.old/arch/mips/pci/Makefile 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/arch/mips/pci/Makefile 2006-04-06 15:34:14.000000000 +0200 -@@ -13,7 +13,9 @@ - obj-$(CONFIG_MIPS_MSC) += ops-msc.o - obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o - obj-$(CONFIG_SNI_RM200_PCI) += ops-sni.o -+ifndef CONFIG_BCM947XX - obj-y += pci.o -+endif - obj-$(CONFIG_PCI_AUTO) += pci_auto.o - - include $(TOPDIR)/Rules.make -diff -Naur linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c ---- linux.old/drivers/char/serial.c 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/drivers/char/serial.c 2006-04-06 15:34:14.000000000 +0200 -@@ -444,6 +444,10 @@ - return inb(info->port+1); - #endif - case SERIAL_IO_MEM: -+#ifdef CONFIG_BCM4310 -+ readb((unsigned long) info->iomem_base + -+ (UART_SCR<iomem_reg_shift)); -+#endif - return readb((unsigned long) info->iomem_base + - (offset<iomem_reg_shift)); - default: -@@ -464,6 +468,9 @@ - case SERIAL_IO_MEM: - writeb(value, (unsigned long) info->iomem_base + - (offset<iomem_reg_shift)); -+#ifdef CONFIG_BCM4704 -+ *((volatile unsigned int *) KSEG1ADDR(0x18000000)); -+#endif - break; - default: - outb(value, info->port+offset); -@@ -1728,7 +1735,7 @@ - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) -- quot = baud_base / baud; -+ quot = (baud_base + (baud / 2)) / baud; - } - /* If the quotient is zero refuse the change */ - if (!quot && old_termios) { -@@ -1745,12 +1752,12 @@ - /* Special case since 134 is really 134.5 */ - quot = (2*baud_base / 269); - else if (baud) -- quot = baud_base / baud; -+ quot = (baud_base + (baud / 2)) / baud; - } - } - /* As a last resort, if the quotient is zero, default to 9600 bps */ - if (!quot) -- quot = baud_base / 9600; -+ quot = (baud_base + 4800) / 9600; - /* - * Work around a bug in the Oxford Semiconductor 952 rev B - * chip which causes it to seriously miscalculate baud rates -@@ -5994,6 +6001,13 @@ - * Divisor, bytesize and parity - */ - state = rs_table + co->index; -+ /* -+ * Safe guard: state structure must have been initialized -+ */ -+ if (state->iomem_base == NULL) { -+ printk("!unable to setup serial console!\n"); -+ return -1; -+ } - if (doflow) - state->flags |= ASYNC_CONS_FLOW; - info = &async_sercons; -@@ -6007,7 +6021,7 @@ - info->io_type = state->io_type; - info->iomem_base = state->iomem_base; - info->iomem_reg_shift = state->iomem_reg_shift; -- quot = state->baud_base / baud; -+ quot = (state->baud_base + (baud / 2)) / baud; - cval = cflag & (CSIZE | CSTOPB); - #if defined(__powerpc__) || defined(__alpha__) - cval >>= 8; -diff -Naur linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in ---- linux.old/drivers/net/Config.in 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/drivers/net/Config.in 2006-04-06 15:34:14.000000000 +0200 -@@ -2,6 +2,8 @@ - # Network device configuration - # - -+tristate 'Broadcom Home Network Division' CONFIG_HND $CONFIG_PCI -+ - source drivers/net/arcnet/Config.in - - tristate 'Dummy net driver support' CONFIG_DUMMY -diff -Naur linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile ---- linux.old/drivers/net/Makefile 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/drivers/net/Makefile 2006-04-06 16:45:29.000000000 +0200 -@@ -3,6 +3,8 @@ - # Makefile for the Linux network (ethercard) device drivers. - # - -+EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include -+ - obj-y := - obj-m := - obj-n := -@@ -39,6 +41,9 @@ - obj-$(CONFIG_ISDN) += slhc.o - endif - -+subdir-$(CONFIG_HND) += hnd -+subdir-$(CONFIG_WL) += wl -+subdir-$(CONFIG_WL2) += wl2 - subdir-$(CONFIG_NET_PCMCIA) += pcmcia - subdir-$(CONFIG_NET_WIRELESS) += wireless - subdir-$(CONFIG_TULIP) += tulip -@@ -69,6 +74,10 @@ - obj-$(CONFIG_MYRI_SBUS) += myri_sbus.o - obj-$(CONFIG_SUNGEM) += sungem.o - -+ifeq ($(CONFIG_HND),y) -+ obj-y += hnd/hnd.o -+endif -+ - obj-$(CONFIG_MACE) += mace.o - obj-$(CONFIG_BMAC) += bmac.o - obj-$(CONFIG_GMAC) += gmac.o -diff -Naur linux.old/drivers/net/hnd/Makefile linux.dev/drivers/net/hnd/Makefile ---- linux.old/drivers/net/hnd/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/hnd/Makefile 2006-04-06 16:20:00.000000000 +0200 -@@ -0,0 +1,19 @@ -+# -+# Makefile for the BCM47xx specific kernel interface routines -+# under Linux. -+# -+ -+EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER -+ -+O_TARGET := hnd.o -+ -+HND_OBJS := bcmutils.o linux_osl.o sbutils.o bcmsrom.o -+ -+export-objs := shared_ksyms.o -+obj-y := shared_ksyms.o $(HND_OBJS) -+obj-m := $(O_TARGET) -+ -+include $(TOPDIR)/Rules.make -+ -+shared_ksyms.c: shared_ksyms.sh $(HND_OBJS) -+ sh -e $< $(HND_OBJS) > $@ -diff -Naur linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom.c ---- linux.old/drivers/net/hnd/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/hnd/bcmsrom.c 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,938 @@ -+/* -+ * Misc useful routines to access NIC SROM/OTP . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct ether_addr { -+ uint8 octet[6]; -+} PACKED; -+ -+#define VARS_MAX 4096 /* should be reduced */ -+ -+#define WRITE_ENABLE_DELAY 500 /* 500 ms after write enable/disable toggle */ -+#define WRITE_WORD_DELAY 20 /* 20 ms between each word write */ -+ -+static int initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count); -+static int initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, int *count); -+static int initvars_flash_sb(void *sbh, char **vars, int *count); -+static int srom_parsecis(osl_t *osh, uint8 *cis, char **vars, int *count); -+static int sprom_cmd_pcmcia(osl_t *osh, uint8 cmd); -+static int sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data); -+static int sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data); -+static int sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc); -+ -+static int initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count); -+static int initvars_flash(osl_t *osh, char **vp, int len, char *devpath); -+ -+/* -+ * Initialize local vars from the right source for this platform. -+ * Return 0 on success, nonzero on error. -+ */ -+int -+srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, int *count) -+{ -+ ASSERT(bustype == BUSTYPE(bustype)); -+ if (vars == NULL || count == NULL) -+ return (0); -+ -+ switch (BUSTYPE(bustype)) { -+ case SB_BUS: -+ case JTAG_BUS: -+ return initvars_flash_sb(sbh, vars, count); -+ -+ case PCI_BUS: -+ ASSERT(curmap); /* can not be NULL */ -+ return initvars_srom_pci(sbh, curmap, vars, count); -+ -+ case PCMCIA_BUS: -+ return initvars_cis_pcmcia(sbh, osh, vars, count); -+ -+ -+ default: -+ ASSERT(0); -+ } -+ return (-1); -+} -+ -+/* support only 16-bit word read from srom */ -+int -+srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) -+{ -+ void *srom; -+ uint i, off, nw; -+ -+ ASSERT(bustype == BUSTYPE(bustype)); -+ -+ /* check input - 16-bit access only */ -+ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) -+ return 1; -+ -+ off = byteoff / 2; -+ nw = nbytes / 2; -+ -+ if (BUSTYPE(bustype) == PCI_BUS) { -+ if (!curmap) -+ return 1; -+ srom = (uchar*)curmap + PCI_BAR0_SPROM_OFFSET; -+ if (sprom_read_pci(srom, off, buf, nw, FALSE)) -+ return 1; -+ } else if (BUSTYPE(bustype) == PCMCIA_BUS) { -+ for (i = 0; i < nw; i++) { -+ if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i))) -+ return 1; -+ } -+ } else { -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/* support only 16-bit word write into srom */ -+int -+srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) -+{ -+ uint16 *srom; -+ uint i, off, nw, crc_range; -+ uint16 image[SPROM_SIZE], *p; -+ uint8 crc; -+ volatile uint32 val32; -+ -+ ASSERT(bustype == BUSTYPE(bustype)); -+ -+ /* check input - 16-bit access only */ -+ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) -+ return 1; -+ -+ crc_range = (((BUSTYPE(bustype) == PCMCIA_BUS) || (BUSTYPE(bustype) == SDIO_BUS)) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2; -+ -+ /* if changes made inside crc cover range */ -+ if (byteoff < crc_range) { -+ nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2; -+ /* read data including entire first 64 words from srom */ -+ if (srom_read(bustype, curmap, osh, 0, nw * 2, image)) -+ return 1; -+ /* make changes */ -+ bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes); -+ /* calculate crc */ -+ htol16_buf(image, crc_range); -+ crc = ~hndcrc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE); -+ ltoh16_buf(image, crc_range); -+ image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff); -+ p = image; -+ off = 0; -+ } else { -+ p = buf; -+ off = byteoff / 2; -+ nw = nbytes / 2; -+ } -+ -+ if (BUSTYPE(bustype) == PCI_BUS) { -+ srom = (uint16*)((uchar*)curmap + PCI_BAR0_SPROM_OFFSET); -+ /* enable writes to the SPROM */ -+ val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); -+ val32 |= SPROM_WRITEEN; -+ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32); -+ bcm_mdelay(WRITE_ENABLE_DELAY); -+ /* write srom */ -+ for (i = 0; i < nw; i++) { -+ W_REG(&srom[off + i], p[i]); -+ bcm_mdelay(WRITE_WORD_DELAY); -+ } -+ /* disable writes to the SPROM */ -+ OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN); -+ } else if (BUSTYPE(bustype) == PCMCIA_BUS) { -+ /* enable writes to the SPROM */ -+ if (sprom_cmd_pcmcia(osh, SROM_WEN)) -+ return 1; -+ bcm_mdelay(WRITE_ENABLE_DELAY); -+ /* write srom */ -+ for (i = 0; i < nw; i++) { -+ sprom_write_pcmcia(osh, (uint16)(off + i), p[i]); -+ bcm_mdelay(WRITE_WORD_DELAY); -+ } -+ /* disable writes to the SPROM */ -+ if (sprom_cmd_pcmcia(osh, SROM_WDS)) -+ return 1; -+ } else { -+ return 1; -+ } -+ -+ bcm_mdelay(WRITE_ENABLE_DELAY); -+ return 0; -+} -+ -+ -+static int -+srom_parsecis(osl_t *osh, uint8 *cis, char **vars, int *count) -+{ -+ char eabuf[32]; -+ char *vp, *base; -+ uint8 tup, tlen, sromrev = 1; -+ int i, j; -+ uint varsize; -+ bool ag_init = FALSE; -+ uint32 w32; -+ -+ ASSERT(vars); -+ ASSERT(count); -+ -+ base = vp = MALLOC(osh, VARS_MAX); -+ ASSERT(vp); -+ if (!vp) -+ return -2; -+ -+ i = 0; -+ do { -+ tup = cis[i++]; -+ tlen = cis[i++]; -+ if ((i + tlen) >= CIS_SIZE) -+ break; -+ -+ switch (tup) { -+ case CISTPL_MANFID: -+ vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]); -+ vp++; -+ vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]); -+ vp++; -+ break; -+ -+ case CISTPL_FUNCE: -+ if (cis[i] == LAN_NID) { -+ ASSERT(cis[i + 1] == 6); -+ bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf); -+ vp += sprintf(vp, "il0macaddr=%s", eabuf); -+ vp++; -+ } -+ break; -+ -+ case CISTPL_CFTABLE: -+ vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]); -+ vp++; -+ break; -+ -+ case CISTPL_BRCM_HNBU: -+ switch (cis[i]) { -+ case HNBU_SROMREV: -+ sromrev = cis[i + 1]; -+ break; -+ -+ case HNBU_CHIPID: -+ vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + cis[i + 1]); -+ vp++; -+ vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + cis[i + 3]); -+ vp++; -+ if (tlen == 7) { -+ vp += sprintf(vp, "chiprev=%d", (cis[i + 6] << 8) + cis[i + 5]); -+ vp++; -+ } -+ break; -+ -+ case HNBU_BOARDREV: -+ vp += sprintf(vp, "boardrev=%d", cis[i + 1]); -+ vp++; -+ break; -+ -+ case HNBU_AA: -+ vp += sprintf(vp, "aa0=%d", cis[i + 1]); -+ vp++; -+ break; -+ -+ case HNBU_AG: -+ vp += sprintf(vp, "ag0=%d", cis[i + 1]); -+ vp++; -+ ag_init = TRUE; -+ break; -+ -+ case HNBU_CC: -+ ASSERT(sromrev > 1); -+ vp += sprintf(vp, "cc=%d", cis[i + 1]); -+ vp++; -+ break; -+ -+ case HNBU_PAPARMS: -+ if (tlen == 2) { -+ ASSERT(sromrev == 1); -+ vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 1]); -+ vp++; -+ } else if (tlen >= 9) { -+ if (tlen == 10) { -+ ASSERT(sromrev == 2); -+ vp += sprintf(vp, "opo=%d", cis[i + 9]); -+ vp++; -+ } else -+ ASSERT(tlen == 9); -+ -+ for (j = 0; j < 3; j++) { -+ vp += sprintf(vp, "pa0b%d=%d", j, -+ (cis[i + (j * 2) + 2] << 8) + cis[i + (j * 2) + 1]); -+ vp++; -+ } -+ vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]); -+ vp++; -+ vp += sprintf(vp, "pa0maxpwr=%d", cis[i + 8]); -+ vp++; -+ } else -+ ASSERT(tlen >= 9); -+ break; -+ -+ case HNBU_OEM: -+ ASSERT(sromrev == 1); -+ vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", -+ cis[i + 1], cis[i + 2], cis[i + 3], cis[i + 4], -+ cis[i + 5], cis[i + 6], cis[i + 7], cis[i + 8]); -+ vp++; -+ break; -+ -+ case HNBU_BOARDFLAGS: -+ w32 = (cis[i + 2] << 8) + cis[i + 1]; -+ if (tlen == 5) -+ w32 |= (cis[i + 4] << 24) + (cis[i + 3] << 16); -+ vp += sprintf(vp, "boardflags=0x%x", w32); -+ vp++; -+ break; -+ -+ case HNBU_LEDS: -+ if (cis[i + 1] != 0xff) { -+ vp += sprintf(vp, "wl0gpio0=%d", cis[i + 1]); -+ vp++; -+ } -+ if (cis[i + 2] != 0xff) { -+ vp += sprintf(vp, "wl0gpio1=%d", cis[i + 2]); -+ vp++; -+ } -+ if (cis[i + 3] != 0xff) { -+ vp += sprintf(vp, "wl0gpio2=%d", cis[i + 3]); -+ vp++; -+ } -+ if (cis[i + 4] != 0xff) { -+ vp += sprintf(vp, "wl0gpio3=%d", cis[i + 4]); -+ vp++; -+ } -+ break; -+ -+ case HNBU_CCODE: -+ ASSERT(sromrev > 1); -+ vp += sprintf(vp, "ccode=%c%c", cis[i + 1], cis[i + 2]); -+ vp++; -+ vp += sprintf(vp, "cctl=0x%x", cis[i + 3]); -+ vp++; -+ break; -+ -+ case HNBU_CCKPO: -+ ASSERT(sromrev > 2); -+ vp += sprintf(vp, "cckpo=0x%x", (cis[i + 2] << 8) | cis[i + 1]); -+ vp++; -+ break; -+ -+ case HNBU_OFDMPO: -+ ASSERT(sromrev > 2); -+ vp += sprintf(vp, "ofdmpo=0x%x", (cis[i + 4] << 24) | -+ (cis[i + 3] << 16) | (cis[i + 2] << 8) | cis[i + 1]); -+ vp++; -+ break; -+ } -+ break; -+ -+ } -+ i += tlen; -+ } while (tup != 0xff); -+ -+ /* Set the srom version */ -+ vp += sprintf(vp, "sromrev=%d", sromrev); -+ vp++; -+ -+ /* if there is no antenna gain field, set default */ -+ if (ag_init == FALSE) { -+ ASSERT(sromrev == 1); -+ vp += sprintf(vp, "ag0=%d", 0xff); -+ vp++; -+ } -+ -+ /* final nullbyte terminator */ -+ *vp++ = '\0'; -+ varsize = (uint)(vp - base); -+ -+ ASSERT((vp - base) < VARS_MAX); -+ -+ if (varsize == VARS_MAX) { -+ *vars = base; -+ } else { -+ vp = MALLOC(osh, varsize); -+ ASSERT(vp); -+ if (vp) -+ bcopy(base, vp, varsize); -+ MFREE(osh, base, VARS_MAX); -+ *vars = vp; -+ if (!vp) { -+ *count = 0; -+ return -2; -+ } -+ } -+ *count = varsize; -+ -+ return (0); -+} -+ -+ -+/* set PCMCIA sprom command register */ -+static int -+sprom_cmd_pcmcia(osl_t *osh, uint8 cmd) -+{ -+ uint8 status = 0; -+ uint wait_cnt = 1000; -+ -+ /* write sprom command register */ -+ OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1); -+ -+ /* wait status */ -+ while (wait_cnt--) { -+ OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1); -+ if (status & SROM_DONE) -+ return 0; -+ } -+ -+ return 1; -+} -+ -+/* read a word from the PCMCIA srom */ -+static int -+sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data) -+{ -+ uint8 addr_l, addr_h, data_l, data_h; -+ -+ addr_l = (uint8)((addr * 2) & 0xff); -+ addr_h = (uint8)(((addr * 2) >> 8) & 0xff); -+ -+ /* set address */ -+ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); -+ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); -+ -+ /* do read */ -+ if (sprom_cmd_pcmcia(osh, SROM_READ)) -+ return 1; -+ -+ /* read data */ -+ data_h = data_l = 0; -+ OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1); -+ OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1); -+ -+ *data = (data_h << 8) | data_l; -+ return 0; -+} -+ -+/* write a word to the PCMCIA srom */ -+static int -+sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data) -+{ -+ uint8 addr_l, addr_h, data_l, data_h; -+ -+ addr_l = (uint8)((addr * 2) & 0xff); -+ addr_h = (uint8)(((addr * 2) >> 8) & 0xff); -+ data_l = (uint8)(data & 0xff); -+ data_h = (uint8)((data >> 8) & 0xff); -+ -+ /* set address */ -+ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); -+ OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); -+ -+ /* write data */ -+ OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1); -+ OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1); -+ -+ /* do write */ -+ return sprom_cmd_pcmcia(osh, SROM_WRITE); -+} -+ -+/* -+ * Read in and validate sprom. -+ * Return 0 on success, nonzero on error. -+ */ -+static int -+sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc) -+{ -+ int err = 0; -+ uint i; -+ -+ /* read the sprom */ -+ for (i = 0; i < nwords; i++) -+ buf[i] = R_REG(&sprom[wordoff + i]); -+ -+ if (check_crc) { -+ /* fixup the endianness so crc8 will pass */ -+ htol16_buf(buf, nwords * 2); -+ if (hndcrc8((uint8*)buf, nwords * 2, CRC8_INIT_VALUE) != CRC8_GOOD_VALUE) -+ err = 1; -+ /* now correct the endianness of the byte array */ -+ ltoh16_buf(buf, nwords * 2); -+ } -+ -+ return err; -+} -+ -+/* -+* Create variable table from memory. -+* Return 0 on success, nonzero on error. -+*/ -+static int -+initvars_table(osl_t *osh, char *start, char *end, char **vars, uint *count) -+{ -+ int c = (int)(end - start); -+ -+ /* do it only when there is more than just the null string */ -+ if (c > 1) { -+ char *vp = MALLOC(osh, c); -+ ASSERT(vp); -+ if (!vp) -+ return BCME_NOMEM; -+ bcopy(start, vp, c); -+ *vars = vp; -+ *count = c; -+ } -+ else { -+ *vars = NULL; -+ *count = 0; -+ } -+ -+ return 0; -+} -+ -+/* -+* Find variables with from flash. 'base' points to the beginning -+* of the table upon enter and to the end of the table upon exit when success. -+* Return 0 on success, nonzero on error. -+*/ -+static int -+initvars_flash(osl_t *osh, char **base, int size, char *devpath) -+{ -+ char *vp = *base; -+ char *flash; -+ int err; -+ char *s; -+ uint l, dl, copy_len; -+ -+ /* allocate memory and read in flash */ -+ if (!(flash = MALLOC(osh, NVRAM_SPACE))) -+ return BCME_NOMEM; -+ if ((err = BCMINIT(nvram_getall)(flash, NVRAM_SPACE))) -+ goto exit; -+ -+ /* grab vars with the prefix in name */ -+ dl = strlen(devpath); -+ for (s = flash; s && *s; s += l + 1) { -+ l = strlen(s); -+ -+ /* skip non-matching variable */ -+ if (strncmp(s, devpath, dl)) -+ continue; -+ -+ /* is there enough room to copy? */ -+ copy_len = l - dl + 1; -+ if (size < (int)copy_len) { -+ err = BCME_BUFTOOSHORT; -+ goto exit; -+ } -+ -+ /* no prefix, just the name=value */ -+ strcpy(vp, &s[dl]); -+ vp += copy_len; -+ size -= copy_len; -+ } -+ -+ /* add null string as terminator */ -+ if (size < 1) { -+ err = BCME_BUFTOOSHORT; -+ goto exit; -+ } -+ *vp++ = '\0'; -+ -+ *base = vp; -+ -+exit: MFREE(osh, flash, NVRAM_SPACE); -+ return err; -+} -+ -+/* -+ * Initialize nonvolatile variable table from flash. -+ * Return 0 on success, nonzero on error. -+ */ -+static int -+initvars_flash_sb(void *sbh, char **vars, int *count) -+{ -+ osl_t *osh = sb_osh(sbh); -+ char devpath[SB_DEVPATH_BUFSZ]; -+ char *vp, *base; -+ int err; -+ -+ ASSERT(vars); -+ ASSERT(count); -+ -+ if ((err = sb_devpath(sbh, devpath, sizeof(devpath)))) -+ return err; -+ -+ base = vp = MALLOC(osh, VARS_MAX); -+ ASSERT(vp); -+ if (!vp) -+ return BCME_NOMEM; -+ -+ if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath))) -+ goto err; -+ -+ err = initvars_table(osh, base, vp, vars, count); -+ -+err: MFREE(osh, base, VARS_MAX); -+ return err; -+} -+ -+/* -+ * Initialize nonvolatile variable table from sprom. -+ * Return 0 on success, nonzero on error. -+ */ -+static int -+initvars_srom_pci(void *sbh, void *curmap, char **vars, int *count) -+{ -+ uint16 w, b[64]; -+ uint8 sromrev; -+ struct ether_addr ea; -+ char eabuf[32]; -+ uint32 w32; -+ int woff, i; -+ char *vp, *base; -+ osl_t *osh = sb_osh(sbh); -+ bool flash = FALSE; -+ char name[SB_DEVPATH_BUFSZ+16], *value; -+ char devpath[SB_DEVPATH_BUFSZ]; -+ int err; -+ -+ /* -+ * Apply CRC over SROM content regardless SROM is present or not, -+ * and use variable sromrev's existance in flash to decide -+ * if we should return an error when CRC fails or read SROM variables -+ * from flash. -+ */ -+ if (sprom_read_pci((void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof(b)/sizeof(b[0]), TRUE)) { -+ if ((err = sb_devpath(sbh, devpath, sizeof(devpath)))) -+ return err; -+ sprintf(name, "%ssromrev", devpath); -+ if (!(value = getvar(NULL, name))) -+ return (-1); -+ sromrev = (uint8)bcm_strtoul(value, NULL, 0); -+ flash = TRUE; -+ } -+ /* srom is good */ -+ else { -+ /* top word of sprom contains version and crc8 */ -+ sromrev = b[63] & 0xff; -+ /* bcm4401 sroms misprogrammed */ -+ if (sromrev == 0x10) -+ sromrev = 1; -+ } -+ -+ /* srom version check */ -+ if (sromrev > 3) -+ return (-2); -+ -+ ASSERT(vars); -+ ASSERT(count); -+ -+ base = vp = MALLOC(osh, VARS_MAX); -+ ASSERT(vp); -+ if (!vp) -+ return -2; -+ -+ /* read variables from flash */ -+ if (flash) { -+ if ((err = initvars_flash(osh, &vp, VARS_MAX, devpath))) -+ goto err; -+ goto done; -+ } -+ -+ vp += sprintf(vp, "sromrev=%d", sromrev); -+ vp++; -+ -+ if (sromrev >= 3) { -+ /* New section takes over the 3th hardware function space */ -+ -+ /* Words 22+23 are 11a (mid) ofdm power offsets */ -+ w32 = ((uint32)b[23] << 16) | b[22]; -+ vp += sprintf(vp, "ofdmapo=%d", w32); -+ vp++; -+ -+ /* Words 24+25 are 11a (low) ofdm power offsets */ -+ w32 = ((uint32)b[25] << 16) | b[24]; -+ vp += sprintf(vp, "ofdmalpo=%d", w32); -+ vp++; -+ -+ /* Words 26+27 are 11a (high) ofdm power offsets */ -+ w32 = ((uint32)b[27] << 16) | b[26]; -+ vp += sprintf(vp, "ofdmahpo=%d", w32); -+ vp++; -+ -+ /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/ -+ w32 = ((uint32)b[43] << 24) | ((uint32)b[42] << 8); -+ vp += sprintf(vp, "gpiotimerval=%d", w32); -+ -+ /*GPIO LED Powersave duty cycle (oncount >> 24) (offcount >> 8)*/ -+ w32 = ((uint32)((unsigned char)(b[21] >> 8) & 0xFF) << 24) | /* oncount*/ -+ ((uint32)((unsigned char)(b[21] & 0xFF)) << 8); /* offcount */ -+ vp += sprintf(vp, "gpiotimerval=%d", w32); -+ -+ vp++; -+ } -+ -+ if (sromrev >= 2) { -+ /* New section takes over the 4th hardware function space */ -+ -+ /* Word 29 is max power 11a high/low */ -+ w = b[29]; -+ vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff); -+ vp++; -+ vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff); -+ vp++; -+ -+ /* Words 30-32 set the 11alow pa settings, -+ * 33-35 are the 11ahigh ones. -+ */ -+ for (i = 0; i < 3; i++) { -+ vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]); -+ vp++; -+ vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]); -+ vp++; -+ } -+ w = b[59]; -+ if (w == 0) -+ vp += sprintf(vp, "ccode="); -+ else -+ vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff)); -+ vp++; -+ -+ } -+ -+ /* parameter section of sprom starts at byte offset 72 */ -+ woff = 72/2; -+ -+ /* first 6 bytes are il0macaddr */ -+ ea.octet[0] = (b[woff] >> 8) & 0xff; -+ ea.octet[1] = b[woff] & 0xff; -+ ea.octet[2] = (b[woff+1] >> 8) & 0xff; -+ ea.octet[3] = b[woff+1] & 0xff; -+ ea.octet[4] = (b[woff+2] >> 8) & 0xff; -+ ea.octet[5] = b[woff+2] & 0xff; -+ woff += 3; -+ bcm_ether_ntoa((uchar*)&ea, eabuf); -+ vp += sprintf(vp, "il0macaddr=%s", eabuf); -+ vp++; -+ -+ /* next 6 bytes are et0macaddr */ -+ ea.octet[0] = (b[woff] >> 8) & 0xff; -+ ea.octet[1] = b[woff] & 0xff; -+ ea.octet[2] = (b[woff+1] >> 8) & 0xff; -+ ea.octet[3] = b[woff+1] & 0xff; -+ ea.octet[4] = (b[woff+2] >> 8) & 0xff; -+ ea.octet[5] = b[woff+2] & 0xff; -+ woff += 3; -+ bcm_ether_ntoa((uchar*)&ea, eabuf); -+ vp += sprintf(vp, "et0macaddr=%s", eabuf); -+ vp++; -+ -+ /* next 6 bytes are et1macaddr */ -+ ea.octet[0] = (b[woff] >> 8) & 0xff; -+ ea.octet[1] = b[woff] & 0xff; -+ ea.octet[2] = (b[woff+1] >> 8) & 0xff; -+ ea.octet[3] = b[woff+1] & 0xff; -+ ea.octet[4] = (b[woff+2] >> 8) & 0xff; -+ ea.octet[5] = b[woff+2] & 0xff; -+ woff += 3; -+ bcm_ether_ntoa((uchar*)&ea, eabuf); -+ vp += sprintf(vp, "et1macaddr=%s", eabuf); -+ vp++; -+ -+ /* -+ * Enet phy settings one or two singles or a dual -+ * Bits 4-0 : MII address for enet0 (0x1f for not there) -+ * Bits 9-5 : MII address for enet1 (0x1f for not there) -+ * Bit 14 : Mdio for enet0 -+ * Bit 15 : Mdio for enet1 -+ */ -+ w = b[woff]; -+ vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f)); -+ vp++; -+ vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f)); -+ vp++; -+ vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1)); -+ vp++; -+ vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1)); -+ vp++; -+ -+ /* Word 46 has board rev, antennas 0/1 & Country code/control */ -+ w = b[46]; -+ vp += sprintf(vp, "boardrev=%d", w & 0xff); -+ vp++; -+ -+ if (sromrev > 1) -+ vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf); -+ else -+ vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf); -+ vp++; -+ -+ vp += sprintf(vp, "aa0=%d", (w >> 12) & 0x3); -+ vp++; -+ -+ vp += sprintf(vp, "aa1=%d", (w >> 14) & 0x3); -+ vp++; -+ -+ /* Words 47-49 set the (wl) pa settings */ -+ woff = 47; -+ -+ for (i = 0; i < 3; i++) { -+ vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]); -+ vp++; -+ vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]); -+ vp++; -+ } -+ -+ /* -+ * Words 50-51 set the customer-configured wl led behavior. -+ * 8 bits/gpio pin. High bit: activehi=0, activelo=1; -+ * LED behavior values defined in wlioctl.h . -+ */ -+ w = b[50]; -+ if ((w != 0) && (w != 0xffff)) { -+ /* gpio0 */ -+ vp += sprintf(vp, "wl0gpio0=%d", (w & 0xff)); -+ vp++; -+ -+ /* gpio1 */ -+ vp += sprintf(vp, "wl0gpio1=%d", (w >> 8) & 0xff); -+ vp++; -+ } -+ w = b[51]; -+ if ((w != 0) && (w != 0xffff)) { -+ /* gpio2 */ -+ vp += sprintf(vp, "wl0gpio2=%d", w & 0xff); -+ vp++; -+ -+ /* gpio3 */ -+ vp += sprintf(vp, "wl0gpio3=%d", (w >> 8) & 0xff); -+ vp++; -+ } -+ -+ /* Word 52 is max power 0/1 */ -+ w = b[52]; -+ vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff); -+ vp++; -+ vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff); -+ vp++; -+ -+ /* Word 56 is idle tssi target 0/1 */ -+ w = b[56]; -+ vp += sprintf(vp, "pa0itssit=%d", w & 0xff); -+ vp++; -+ vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff); -+ vp++; -+ -+ /* Word 57 is boardflags, if not programmed make it zero */ -+ w32 = (uint32)b[57]; -+ if (w32 == 0xffff) w32 = 0; -+ if (sromrev > 1) { -+ /* Word 28 is the high bits of boardflags */ -+ w32 |= (uint32)b[28] << 16; -+ } -+ vp += sprintf(vp, "boardflags=%d", w32); -+ vp++; -+ -+ /* Word 58 is antenna gain 0/1 */ -+ w = b[58]; -+ vp += sprintf(vp, "ag0=%d", w & 0xff); -+ vp++; -+ -+ vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff); -+ vp++; -+ -+ if (sromrev == 1) { -+ /* set the oem string */ -+ vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", -+ ((b[59] >> 8) & 0xff), (b[59] & 0xff), -+ ((b[60] >> 8) & 0xff), (b[60] & 0xff), -+ ((b[61] >> 8) & 0xff), (b[61] & 0xff), -+ ((b[62] >> 8) & 0xff), (b[62] & 0xff)); -+ vp++; -+ } else if (sromrev == 2) { -+ /* Word 60 OFDM tx power offset from CCK level */ -+ /* OFDM Power Offset - opo */ -+ vp += sprintf(vp, "opo=%d", b[60] & 0xff); -+ vp++; -+ } else { -+ /* Word 60: cck power offsets */ -+ vp += sprintf(vp, "cckpo=%d", b[60]); -+ vp++; -+ -+ /* Words 61+62: 11g ofdm power offsets */ -+ w32 = ((uint32)b[62] << 16) | b[61]; -+ vp += sprintf(vp, "ofdmgpo=%d", w32); -+ vp++; -+ } -+ -+ /* final nullbyte terminator */ -+ *vp++ = '\0'; -+ -+ ASSERT((vp - base) <= VARS_MAX); -+ -+done: err = initvars_table(osh, base, vp, vars, count); -+ -+err: MFREE(osh, base, VARS_MAX); -+ return err; -+} -+ -+/* -+ * Read the cis and call parsecis to initialize the vars. -+ * Return 0 on success, nonzero on error. -+ */ -+static int -+initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, int *count) -+{ -+ uint8 *cis = NULL; -+ int rc; -+ uint data_sz; -+ -+ data_sz = (sb_pcmciarev(sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE; -+ -+ if ((cis = MALLOC(osh, data_sz)) == NULL) -+ return (-2); -+ -+ if (sb_pcmciarev(sbh) == 1) { -+ if (srom_read(PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis)) { -+ MFREE(osh, cis, data_sz); -+ return (-1); -+ } -+ /* fix up endianess for 16-bit data vs 8-bit parsing */ -+ ltoh16_buf((uint16 *)cis, data_sz); -+ } else -+ OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz); -+ -+ rc = srom_parsecis(osh, cis, vars, count); -+ -+ MFREE(osh, cis, data_sz); -+ -+ return (rc); -+} -+ -diff -Naur linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutils.c ---- linux.old/drivers/net/hnd/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/hnd/bcmutils.c 2006-04-06 16:05:56.000000000 +0200 -@@ -0,0 +1,875 @@ -+/* -+ * Misc useful OS-independent routines. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ -+ -+#include -+#ifdef BCMDRIVER -+#include -+#include -+#include -+#else -+#include -+#include -+#endif -+#include -+#include -+#include -+ -+#ifdef BCMDRIVER -+unsigned char bcm_ctype[] = { -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ -+ _BCM_C,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C,_BCM_C, /* 8-15 */ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ -+ _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ -+ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ -+ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ -+ _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ -+ _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ -+ _BCM_P,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U, /* 64-71 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ -+ _BCM_P,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L, /* 96-103 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ -+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ -+ _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 160-175 */ -+ _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 176-191 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 192-207 */ -+ _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_L, /* 208-223 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 224-239 */ -+ _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L /* 240-255 */ -+}; -+ -+uchar -+bcm_toupper(uchar c) -+{ -+ if (bcm_islower(c)) -+ c -= 'a'-'A'; -+ return (c); -+} -+ -+ulong -+bcm_strtoul(char *cp, char **endp, uint base) -+{ -+ ulong result, value; -+ bool minus; -+ -+ minus = FALSE; -+ -+ while (bcm_isspace(*cp)) -+ cp++; -+ -+ if (cp[0] == '+') -+ cp++; -+ else if (cp[0] == '-') { -+ minus = TRUE; -+ cp++; -+ } -+ -+ if (base == 0) { -+ if (cp[0] == '0') { -+ if ((cp[1] == 'x') || (cp[1] == 'X')) { -+ base = 16; -+ cp = &cp[2]; -+ } else { -+ base = 8; -+ cp = &cp[1]; -+ } -+ } else -+ base = 10; -+ } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { -+ cp = &cp[2]; -+ } -+ -+ result = 0; -+ -+ while (bcm_isxdigit(*cp) && -+ (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { -+ result = result*base + value; -+ cp++; -+ } -+ -+ if (minus) -+ result = (ulong)(result * -1); -+ -+ if (endp) -+ *endp = (char *)cp; -+ -+ return (result); -+} -+ -+uint -+bcm_atoi(char *s) -+{ -+ uint n; -+ -+ n = 0; -+ -+ while (bcm_isdigit(*s)) -+ n = (n * 10) + *s++ - '0'; -+ return (n); -+} -+ -+/* return pointer to location of substring 'needle' in 'haystack' */ -+char* -+bcmstrstr(char *haystack, char *needle) -+{ -+ int len, nlen; -+ int i; -+ -+ if ((haystack == NULL) || (needle == NULL)) -+ return (haystack); -+ -+ nlen = strlen(needle); -+ len = strlen(haystack) - nlen + 1; -+ -+ for (i = 0; i < len; i++) -+ if (bcmp(needle, &haystack[i], nlen) == 0) -+ return (&haystack[i]); -+ return (NULL); -+} -+ -+char* -+bcmstrcat(char *dest, const char *src) -+{ -+ strcpy(&dest[strlen(dest)], src); -+ return (dest); -+} -+ -+#if defined(CONFIG_USBRNDIS_RETAIL) || defined(NDIS_MINIPORT_DRIVER) -+/* registry routine buffer preparation utility functions: -+ * parameter order is like strncpy, but returns count -+ * of bytes copied. Minimum bytes copied is null char(1)/wchar(2) -+ */ -+ulong -+wchar2ascii( -+ char *abuf, -+ ushort *wbuf, -+ ushort wbuflen, -+ ulong abuflen -+) -+{ -+ ulong copyct = 1; -+ ushort i; -+ -+ if (abuflen == 0) -+ return 0; -+ -+ /* wbuflen is in bytes */ -+ wbuflen /= sizeof(ushort); -+ -+ for (i = 0; i < wbuflen; ++i) { -+ if (--abuflen == 0) -+ break; -+ *abuf++ = (char) *wbuf++; -+ ++copyct; -+ } -+ *abuf = '\0'; -+ -+ return copyct; -+} -+#endif -+ -+char* -+bcm_ether_ntoa(char *ea, char *buf) -+{ -+ sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x", -+ (uchar)ea[0]&0xff, (uchar)ea[1]&0xff, (uchar)ea[2]&0xff, -+ (uchar)ea[3]&0xff, (uchar)ea[4]&0xff, (uchar)ea[5]&0xff); -+ return (buf); -+} -+ -+/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -+int -+bcm_ether_atoe(char *p, char *ea) -+{ -+ int i = 0; -+ -+ for (;;) { -+ ea[i++] = (char) bcm_strtoul(p, &p, 16); -+ if (!*p++ || i == 6) -+ break; -+ } -+ -+ return (i == 6); -+} -+ -+void -+bcm_mdelay(uint ms) -+{ -+ uint i; -+ -+ for (i = 0; i < ms; i++) { -+ OSL_DELAY(1000); -+ } -+} -+ -+/* -+ * Search the name=value vars for a specific one and return its value. -+ * Returns NULL if not found. -+ */ -+char* -+getvar(char *vars, char *name) -+{ -+ char *s; -+ int len; -+ -+ len = strlen(name); -+ -+ /* first look in vars[] */ -+ for (s = vars; s && *s; ) { -+ if ((bcmp(s, name, len) == 0) && (s[len] == '=')) -+ return (&s[len+1]); -+ -+ while (*s++) -+ ; -+ } -+ -+ /* then query nvram */ -+ return (BCMINIT(nvram_get)(name)); -+} -+ -+/* -+ * Search the vars for a specific one and return its value as -+ * an integer. Returns 0 if not found. -+ */ -+int -+getintvar(char *vars, char *name) -+{ -+ char *val; -+ -+ if ((val = getvar(vars, name)) == NULL) -+ return (0); -+ -+ return (bcm_strtoul(val, NULL, 0)); -+} -+ -+ -+/* Search for token in comma separated token-string */ -+static int -+findmatch(char *string, char *name) -+{ -+ uint len; -+ char *c; -+ -+ len = strlen(name); -+ while ((c = strchr(string, ',')) != NULL) { -+ if (len == (uint)(c - string) && !strncmp(string, name, len)) -+ return 1; -+ string = c + 1; -+ } -+ -+ return (!strcmp(string, name)); -+} -+ -+/* Return gpio pin number assigned to the named pin */ -+/* -+* Variable should be in format: -+* -+* gpio=pin_name,pin_name -+* -+* This format allows multiple features to share the gpio with mutual -+* understanding. -+* -+* 'def_pin' is returned if a specific gpio is not defined for the requested functionality -+* and if def_pin is not used by others. -+*/ -+uint -+getgpiopin(char *vars, char *pin_name, uint def_pin) -+{ -+ char name[] = "gpioXXXX"; -+ char *val; -+ uint pin; -+ -+ /* Go thru all possibilities till a match in pin name */ -+ for (pin = 0; pin < GPIO_NUMPINS; pin ++) { -+ sprintf(name, "gpio%d", pin); -+ val = getvar(vars, name); -+ if (val && findmatch(val, pin_name)) -+ return pin; -+ } -+ -+ if (def_pin != GPIO_PIN_NOTDEFINED) { -+ /* make sure the default pin is not used by someone else */ -+ sprintf(name, "gpio%d", def_pin); -+ if (getvar(vars, name)) { -+ def_pin = GPIO_PIN_NOTDEFINED; -+ } -+ } -+ -+ return def_pin; -+} -+ -+ -+static char bcm_undeferrstr[BCME_STRLEN]; -+ -+static const char *bcmerrorstrtable[] = \ -+{ "OK", /* 0 */ -+ "Undefined error", /* BCME_ERROR */ -+ "Bad Argument", /* BCME_BADARG*/ -+ "Bad Option", /* BCME_BADOPTION*/ -+ "Not up", /* BCME_NOTUP */ -+ "Not down", /* BCME_NOTDOWN */ -+ "Not AP", /* BCME_NOTAP */ -+ "Not STA", /* BCME_NOTSTA */ -+ "Bad Key Index", /* BCME_BADKEYIDX */ -+ "Radio Off", /* BCME_RADIOOFF */ -+ "Not band locked", /* BCME_NOTBANDLOCKED */ -+ "No clock", /* BCME_NOCLK */ -+ "Bad Rate valueset", /* BCME_BADRATESET */ -+ "Bad Band", /* BCME_BADBAND */ -+ "Buffer too short", /* BCME_BUFTOOSHORT */ -+ "Buffer too length", /* BCME_BUFTOOLONG */ -+ "Busy", /* BCME_BUSY */ -+ "Not Associated", /* BCME_NOTASSOCIATED */ -+ "Bad SSID len", /* BCME_BADSSIDLEN */ -+ "Out of Range Channel", /* BCME_OUTOFRANGECHAN */ -+ "Bad Channel", /* BCME_BADCHAN */ -+ "Bad Address", /* BCME_BADADDR */ -+ "Not Enough Resources", /* BCME_NORESOURCE */ -+ "Unsupported", /* BCME_UNSUPPORTED */ -+ "Bad length", /* BCME_BADLENGTH */ -+ "Not Ready", /* BCME_NOTREADY */ -+ "Not Permitted", /* BCME_EPERM */ -+ "No Memory", /* BCME_NOMEM */ -+ "Associated", /* BCME_ASSOCIATED */ -+ "Not In Range", /* BCME_RANGE */ -+ "Not Found" /* BCME_NOTFOUND */ -+ }; -+ -+/* Convert the Error codes into related Error strings */ -+const char * -+bcmerrorstr(int bcmerror) -+{ -+ int abs_bcmerror; -+ -+ abs_bcmerror = ABS(bcmerror); -+ -+ /* check if someone added a bcmerror code but forgot to add errorstring */ -+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); -+ if ( (bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) { -+ sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror); -+ return bcm_undeferrstr; -+ } -+ -+ ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN); -+ -+ return bcmerrorstrtable[abs_bcmerror]; -+} -+#endif /* #ifdef BCMDRIVER */ -+ -+ -+/******************************************************************************* -+ * crc8 -+ * -+ * Computes a crc8 over the input data using the polynomial: -+ * -+ * x^8 + x^7 +x^6 + x^4 + x^2 + 1 -+ * -+ * The caller provides the initial value (either CRC8_INIT_VALUE -+ * or the previous returned value) to allow for processing of -+ * discontiguous blocks of data. When generating the CRC the -+ * caller is responsible for complementing the final return value -+ * and inserting it into the byte stream. When checking, a final -+ * return value of CRC8_GOOD_VALUE indicates a valid CRC. -+ * -+ * Reference: Dallas Semiconductor Application Note 27 -+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", -+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., -+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt -+ * -+ ******************************************************************************/ -+ -+static uint8 crc8_table[256] = { -+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, -+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, -+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, -+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, -+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, -+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, -+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, -+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, -+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, -+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, -+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, -+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, -+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, -+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, -+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, -+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, -+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, -+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, -+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, -+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, -+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, -+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, -+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, -+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, -+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, -+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, -+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, -+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, -+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, -+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, -+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, -+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F -+}; -+ -+#define CRC_INNER_LOOP(n, c, x) \ -+ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] -+ -+uint8 -+hndcrc8( -+ uint8 *pdata, /* pointer to array of data to process */ -+ uint nbytes, /* number of input data bytes to process */ -+ uint8 crc /* either CRC8_INIT_VALUE or previous return value */ -+) -+{ -+ /* hard code the crc loop instead of using CRC_INNER_LOOP macro -+ * to avoid the undefined and unnecessary (uint8 >> 8) operation. */ -+ while (nbytes-- > 0) -+ crc = crc8_table[(crc ^ *pdata++) & 0xff]; -+ -+ return crc; -+} -+ -+/******************************************************************************* -+ * crc16 -+ * -+ * Computes a crc16 over the input data using the polynomial: -+ * -+ * x^16 + x^12 +x^5 + 1 -+ * -+ * The caller provides the initial value (either CRC16_INIT_VALUE -+ * or the previous returned value) to allow for processing of -+ * discontiguous blocks of data. When generating the CRC the -+ * caller is responsible for complementing the final return value -+ * and inserting it into the byte stream. When checking, a final -+ * return value of CRC16_GOOD_VALUE indicates a valid CRC. -+ * -+ * Reference: Dallas Semiconductor Application Note 27 -+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", -+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., -+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt -+ * -+ ******************************************************************************/ -+ -+static uint16 crc16_table[256] = { -+ 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, -+ 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, -+ 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, -+ 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, -+ 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, -+ 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, -+ 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, -+ 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, -+ 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, -+ 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, -+ 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, -+ 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, -+ 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, -+ 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, -+ 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, -+ 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, -+ 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, -+ 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, -+ 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, -+ 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, -+ 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, -+ 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, -+ 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, -+ 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, -+ 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, -+ 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, -+ 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, -+ 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, -+ 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, -+ 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, -+ 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, -+ 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 -+}; -+ -+uint16 -+hndcrc16( -+ uint8 *pdata, /* pointer to array of data to process */ -+ uint nbytes, /* number of input data bytes to process */ -+ uint16 crc /* either CRC16_INIT_VALUE or previous return value */ -+) -+{ -+ while (nbytes-- > 0) -+ CRC_INNER_LOOP(16, crc, *pdata++); -+ return crc; -+} -+ -+static uint32 crc32_table[256] = { -+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, -+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, -+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, -+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, -+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, -+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, -+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, -+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, -+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, -+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, -+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, -+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, -+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, -+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, -+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, -+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, -+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, -+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, -+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, -+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, -+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, -+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, -+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, -+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, -+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, -+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, -+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, -+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, -+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, -+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, -+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, -+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, -+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, -+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, -+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, -+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, -+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, -+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, -+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, -+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, -+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, -+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, -+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, -+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, -+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, -+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, -+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, -+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, -+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, -+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, -+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, -+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, -+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, -+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, -+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, -+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, -+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, -+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, -+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, -+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, -+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, -+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, -+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, -+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -+}; -+ -+uint32 -+hndcrc32( -+ uint8 *pdata, /* pointer to array of data to process */ -+ uint nbytes, /* number of input data bytes to process */ -+ uint32 crc /* either CRC32_INIT_VALUE or previous return value */ -+) -+{ -+ uint8 *pend; -+#ifdef __mips__ -+ uint8 tmp[4]; -+ ulong *tptr = (ulong *)tmp; -+ -+ /* in case the beginning of the buffer isn't aligned */ -+ pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); -+ nbytes -= (pend - pdata); -+ while (pdata < pend) -+ CRC_INNER_LOOP(32, crc, *pdata++); -+ -+ /* handle bulk of data as 32-bit words */ -+ pend = pdata + (nbytes & 0xfffffffc); -+ while (pdata < pend) { -+ tptr = *((ulong *) pdata); -+ *((ulong *) pdata) += 1; -+ CRC_INNER_LOOP(32, crc, tmp[0]); -+ CRC_INNER_LOOP(32, crc, tmp[1]); -+ CRC_INNER_LOOP(32, crc, tmp[2]); -+ CRC_INNER_LOOP(32, crc, tmp[3]); -+ } -+ -+ /* 1-3 bytes at end of buffer */ -+ pend = pdata + (nbytes & 0x03); -+ while (pdata < pend) -+ CRC_INNER_LOOP(32, crc, *pdata++); -+#else -+ pend = pdata + nbytes; -+ while (pdata < pend) -+ CRC_INNER_LOOP(32, crc, *pdata++); -+#endif -+ -+ return crc; -+} -+ -+#ifdef notdef -+#define CLEN 1499 -+#define CBUFSIZ (CLEN+4) -+#define CNBUFS 5 -+ -+void testcrc32(void) -+{ -+ uint j,k,l; -+ uint8 *buf; -+ uint len[CNBUFS]; -+ uint32 crcr; -+ uint32 crc32tv[CNBUFS] = -+ {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; -+ -+ ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); -+ -+ /* step through all possible alignments */ -+ for (l=0;l<=4;l++) { -+ for (j=0; jlen; -+ elt = (bcm_tlv_t*)(elt->data + len); -+ *buflen -= (2 + len); -+ -+ /* validate next elt */ -+ if (!bcm_valid_tlv(elt, *buflen)) -+ return NULL; -+ -+ return elt; -+} -+ -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag -+ */ -+bcm_tlv_t * -+bcm_parse_tlvs(void *buf, int buflen, uint key) -+{ -+ bcm_tlv_t *elt; -+ int totlen; -+ -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; -+ -+ /* find tagged parameter */ -+ while (totlen >= 2) { -+ int len = elt->len; -+ -+ /* validate remaining totlen */ -+ if ((elt->id == key) && (totlen >= (len + 2))) -+ return (elt); -+ -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); -+ totlen -= (len + 2); -+ } -+ -+ return NULL; -+} -+ -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag. Stop parsing when we see an element whose ID is greater -+ * than the target key. -+ */ -+bcm_tlv_t * -+bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) -+{ -+ bcm_tlv_t *elt; -+ int totlen; -+ -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; -+ -+ /* find tagged parameter */ -+ while (totlen >= 2) { -+ uint id = elt->id; -+ int len = elt->len; -+ -+ /* Punt if we start seeing IDs > than target key */ -+ if (id > key) -+ return(NULL); -+ -+ /* validate remaining totlen */ -+ if ((id == key) && (totlen >= (len + 2))) -+ return (elt); -+ -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); -+ totlen -= (len + 2); -+ } -+ return NULL; -+} -+/* routine to dump fields in a fileddesc structure */ -+ -+uint -+bcmdumpfields(readreg_rtn read_rtn, void *arg0, void *arg1, struct fielddesc *fielddesc_array, char *buf, uint32 bufsize) -+{ -+ uint filled_len; -+ uint len; -+ struct fielddesc *cur_ptr; -+ -+ filled_len = 0; -+ cur_ptr = fielddesc_array; -+ -+ while (bufsize > (filled_len + 64)) { -+ if (cur_ptr->nameandfmt == NULL) -+ break; -+ len = sprintf(buf, cur_ptr->nameandfmt, read_rtn(arg0, arg1, cur_ptr->offset)); -+ buf += len; -+ filled_len += len; -+ cur_ptr++; -+ } -+ return filled_len; -+} -+ -+uint -+bcm_mkiovar(char *name, char *data, uint datalen, char *buf, uint buflen) -+{ -+ uint len; -+ -+ len = strlen(name) + 1; -+ -+ if ((len + datalen) > buflen) -+ return 0; -+ -+ strcpy(buf, name); -+ -+ /* append data onto the end of the name string */ -+ memcpy(&buf[len], data, datalen); -+ len += datalen; -+ -+ return len; -+} -+ -+/* Quarter dBm units to mW -+ * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153 -+ * Table is offset so the last entry is largest mW value that fits in -+ * a uint16. -+ */ -+ -+#define QDBM_OFFSET 153 -+#define QDBM_TABLE_LEN 40 -+ -+/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET. -+ * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2 -+ */ -+#define QDBM_TABLE_LOW_BOUND 6493 -+ -+/* Largest mW value that will round down to the last table entry, -+ * QDBM_OFFSET + QDBM_TABLE_LEN-1. -+ * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) + mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2. -+ */ -+#define QDBM_TABLE_HIGH_BOUND 64938 -+ -+static const uint16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = { -+/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */ -+/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000, -+/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849, -+/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119, -+/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811, -+/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096 -+}; -+ -+uint16 -+bcm_qdbm_to_mw(uint8 qdbm) -+{ -+ uint factor = 1; -+ int idx = qdbm - QDBM_OFFSET; -+ -+ if (idx > QDBM_TABLE_LEN) { -+ /* clamp to max uint16 mW value */ -+ return 0xFFFF; -+ } -+ -+ /* scale the qdBm index up to the range of the table 0-40 -+ * where an offset of 40 qdBm equals a factor of 10 mW. -+ */ -+ while (idx < 0) { -+ idx += 40; -+ factor *= 10; -+ } -+ -+ /* return the mW value scaled down to the correct factor of 10, -+ * adding in factor/2 to get proper rounding. */ -+ return ((nqdBm_to_mW_map[idx] + factor/2) / factor); -+} -+ -+uint8 -+bcm_mw_to_qdbm(uint16 mw) -+{ -+ uint8 qdbm; -+ int offset; -+ uint mw_uint = mw; -+ uint boundary; -+ -+ /* handle boundary case */ -+ if (mw_uint <= 1) -+ return 0; -+ -+ offset = QDBM_OFFSET; -+ -+ /* move mw into the range of the table */ -+ while (mw_uint < QDBM_TABLE_LOW_BOUND) { -+ mw_uint *= 10; -+ offset -= 40; -+ } -+ -+ for (qdbm = 0; qdbm < QDBM_TABLE_LEN-1; qdbm++) { -+ boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm+1] - nqdBm_to_mW_map[qdbm])/2; -+ if (mw_uint < boundary) break; -+ } -+ -+ qdbm += (uint8)offset; -+ -+ return(qdbm); -+} -diff -Naur linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_osl.c ---- linux.old/drivers/net/hnd/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/hnd/linux_osl.c 2006-04-06 15:34:15.000000000 +0200 -@@ -0,0 +1,708 @@ -+/* -+ * Linux OS Independent Layer -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ -+ -+#define LINUX_OSL -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef mips -+#include -+#endif -+#include -+ -+#define PCI_CFG_RETRY 10 -+ -+#define OS_HANDLE_MAGIC 0x1234abcd -+#define BCM_MEM_FILENAME_LEN 24 -+ -+typedef struct bcm_mem_link { -+ struct bcm_mem_link *prev; -+ struct bcm_mem_link *next; -+ uint size; -+ int line; -+ char file[BCM_MEM_FILENAME_LEN]; -+} bcm_mem_link_t; -+ -+struct os_handle { -+ uint magic; -+ void *pdev; -+ uint malloced; -+ uint failed; -+ bcm_mem_link_t *dbgmem_list; -+}; -+ -+static int16 linuxbcmerrormap[] = \ -+{ 0, /* 0 */ -+ -EINVAL, /* BCME_ERROR */ -+ -EINVAL, /* BCME_BADARG*/ -+ -EINVAL, /* BCME_BADOPTION*/ -+ -EINVAL, /* BCME_NOTUP */ -+ -EINVAL, /* BCME_NOTDOWN */ -+ -EINVAL, /* BCME_NOTAP */ -+ -EINVAL, /* BCME_NOTSTA */ -+ -EINVAL, /* BCME_BADKEYIDX */ -+ -EINVAL, /* BCME_RADIOOFF */ -+ -EINVAL, /* BCME_NOTBANDLOCKED */ -+ -EINVAL, /* BCME_NOCLK */ -+ -EINVAL, /* BCME_BADRATESET */ -+ -EINVAL, /* BCME_BADBAND */ -+ -E2BIG, /* BCME_BUFTOOSHORT */ -+ -E2BIG, /* BCME_BUFTOOLONG */ -+ -EBUSY, /* BCME_BUSY */ -+ -EINVAL, /* BCME_NOTASSOCIATED */ -+ -EINVAL, /* BCME_BADSSIDLEN */ -+ -EINVAL, /* BCME_OUTOFRANGECHAN */ -+ -EINVAL, /* BCME_BADCHAN */ -+ -EFAULT, /* BCME_BADADDR */ -+ -ENOMEM, /* BCME_NORESOURCE */ -+ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ -+ -EMSGSIZE, /* BCME_BADLENGTH */ -+ -EINVAL, /* BCME_NOTREADY */ -+ -EPERM, /* BCME_NOTPERMITTED */ -+ -ENOMEM, /* BCME_NOMEM */ -+ -EINVAL, /* BCME_ASSOCIATED */ -+ -ERANGE, /* BCME_RANGE */ -+ -EINVAL /* BCME_NOTFOUND */ -+}; + -+/* translate bcmerrors into linux errors*/ -+int -+osl_error(int bcmerror) ++struct nvram_tuple * ++_nvram_realloc(struct nvram_tuple *t, const char *name, const char *value) +{ -+ int abs_bcmerror; -+ int array_size = ARRAYSIZE(linuxbcmerrormap); -+ -+ abs_bcmerror = ABS(bcmerror); -+ -+ if (bcmerror > 0) -+ abs_bcmerror = 0; -+ -+ else if (abs_bcmerror >= array_size) -+ abs_bcmerror = BCME_ERROR; -+ -+ return linuxbcmerrormap[abs_bcmerror]; -+} ++ if ((nvram_offset + strlen(value) + 1) > NVRAM_SPACE) ++ return NULL; + -+osl_t * -+osl_attach(void *pdev) -+{ -+ osl_t *osh; ++ if (!t) { ++ if (!(t = kmalloc(sizeof(struct nvram_tuple) + strlen(name) + 1, GFP_ATOMIC))) ++ return NULL; + -+ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); -+ ASSERT(osh); ++ /* Copy name */ ++ t->name = (char *) &t[1]; ++ strcpy(t->name, name); + -+ /* -+ * check the cases where -+ * 1.Error code Added to bcmerror table, but forgot to add it to the OS -+ * dependent error code -+ * 2. Error code is added to the bcmerror table, but forgot to add the -+ * corresponding errorstring(dummy call to bcmerrorstr) -+ */ -+ bcmerrorstr(0); -+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); ++ t->value = NULL; ++ } + -+ osh->magic = OS_HANDLE_MAGIC; -+ osh->malloced = 0; -+ osh->failed = 0; -+ osh->dbgmem_list = NULL; -+ osh->pdev = pdev; ++ /* Copy value */ ++ if (!t->value || strcmp(t->value, value)) { ++ t->value = &nvram_buf[nvram_offset]; ++ strcpy(t->value, value); ++ nvram_offset += strlen(value) + 1; ++ } + -+ return osh; ++ return t; +} + +void -+osl_detach(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC)); -+ kfree(osh); -+} -+ -+void* -+osl_pktget(osl_t *osh, uint len, bool send) ++_nvram_free(struct nvram_tuple *t) +{ -+ struct sk_buff *skb; -+ -+ if ((skb = dev_alloc_skb(len)) == NULL) -+ return (NULL); -+ -+ skb_put(skb, len); -+ -+ /* ensure the cookie field is cleared */ -+ PKTSETCOOKIE(skb, NULL); -+ -+ return ((void*) skb); ++ if (!t) ++ nvram_offset = 0; ++ else ++ kfree(t); +} + -+void -+osl_pktfree(void *p) ++int ++nvram_set(const char *name, const char *value) +{ -+ struct sk_buff *skb, *nskb; -+ -+ skb = (struct sk_buff*) p; ++ unsigned long flags; ++ int ret; ++ struct nvram_header *header; + -+ /* perversion: we use skb->next to chain multi-skb packets */ -+ while (skb) { -+ nskb = skb->next; -+ skb->next = NULL; -+ if (skb->destructor) { -+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ -+ dev_kfree_skb_any(skb); -+ } else { -+ /* can free immediately (even in_irq()) if destructor does not exist */ -+ dev_kfree_skb(skb); ++ spin_lock_irqsave(&nvram_lock, flags); ++ if ((ret = _nvram_set(name, value))) { ++ /* Consolidate space and try again */ ++ if ((header = kmalloc(NVRAM_SPACE, GFP_ATOMIC))) { ++ if (_nvram_commit(header) == 0) ++ ret = _nvram_set(name, value); ++ kfree(header); + } -+ skb = nskb; + } -+} -+ -+uint32 -+osl_pci_read_config(osl_t *osh, uint offset, uint size) -+{ -+ uint val; -+ uint retry=PCI_CFG_RETRY; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ /* only 4byte access supported */ -+ ASSERT(size == 4); -+ -+ do { -+ pci_read_config_dword(osh->pdev, offset, &val); -+ if (val != 0xffffffff) -+ break; -+ } while (retry--); -+ ++ spin_unlock_irqrestore(&nvram_lock, flags); + -+ return (val); ++ return ret; +} + -+void -+osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) ++char * ++real_nvram_get(const char *name) +{ -+ uint retry=PCI_CFG_RETRY; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ -+ /* only 4byte access supported */ -+ ASSERT(size == 4); -+ -+ do { -+ pci_write_config_dword(osh->pdev, offset, val); -+ if (offset!=PCI_BAR0_WIN) -+ break; -+ if (osl_pci_read_config(osh,offset,size) == val) -+ break; -+ } while (retry--); -+ -+} ++ unsigned long flags; ++ char *value; + -+/* return bus # for the pci device pointed by osh->pdev */ -+uint -+osl_pci_bus(osl_t *osh) -+{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); ++ spin_lock_irqsave(&nvram_lock, flags); ++ value = _nvram_get(name); ++ spin_unlock_irqrestore(&nvram_lock, flags); + -+ return ((struct pci_dev *)osh->pdev)->bus->number; ++ return value; +} + -+/* return slot # for the pci device pointed by osh->pdev */ -+uint -+osl_pci_slot(osl_t *osh) ++char * ++nvram_get(const char *name) +{ -+ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); -+ -+ return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); ++ if (nvram_major >= 0) ++ return real_nvram_get(name); ++ else ++ return early_nvram_get(name); +} + -+static void -+osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) ++int ++nvram_unset(const char *name) +{ -+} ++ unsigned long flags; ++ int ret; + -+void -+osl_pcmcia_read_attr(osl_t *osh, uint offset, void *buf, int size) -+{ -+ osl_pcmcia_attr(osh, offset, (char *) buf, size, FALSE); -+} ++ spin_lock_irqsave(&nvram_lock, flags); ++ ret = _nvram_unset(name); ++ spin_unlock_irqrestore(&nvram_lock, flags); + -+void -+osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) -+{ -+ osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); ++ return ret; +} + -+ -+#ifdef BCMDBG_MEM -+ -+void* -+osl_debug_malloc(osl_t *osh, uint size, int line, char* file) ++static void ++erase_callback(struct erase_info *done) +{ -+ bcm_mem_link_t *p; -+ char* basename; -+ -+ ASSERT(size); -+ -+ if ((p = (bcm_mem_link_t*)osl_malloc(osh, sizeof(bcm_mem_link_t) + size)) == NULL) -+ return (NULL); -+ -+ p->size = size; -+ p->line = line; -+ -+ basename = strrchr(file, '/'); -+ /* skip the '/' */ -+ if (basename) -+ basename++; -+ -+ if (!basename) -+ basename = file; -+ -+ strncpy(p->file, basename, BCM_MEM_FILENAME_LEN); -+ p->file[BCM_MEM_FILENAME_LEN - 1] = '\0'; -+ -+ /* link this block */ -+ p->prev = NULL; -+ p->next = osh->dbgmem_list; -+ if (p->next) -+ p->next->prev = p; -+ osh->dbgmem_list = p; -+ -+ return p + 1; ++ wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv; ++ wake_up(wait_q); +} + -+void -+osl_debug_mfree(osl_t *osh, void *addr, uint size, int line, char* file) ++int ++nvram_commit(void) +{ -+ bcm_mem_link_t *p = (bcm_mem_link_t *)((int8*)addr - sizeof(bcm_mem_link_t)); -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ char *buf; ++ size_t erasesize, len, magic_len; ++ unsigned int i; ++ int ret; ++ struct nvram_header *header; ++ unsigned long flags; ++ u_int32_t offset; ++ DECLARE_WAITQUEUE(wait, current); ++ wait_queue_head_t wait_q; ++ struct erase_info erase; ++ u_int32_t magic_offset = 0; /* Offset for writing MAGIC # */ + -+ if (p->size == 0) { -+ printk("osl_debug_mfree: double free on addr 0x%x size %d at line %d file %s\n", -+ (uint)addr, size, line, file); -+ ASSERT(p->size); -+ return; ++ if (!nvram_mtd) { ++ printk("nvram_commit: NVRAM not found\n"); ++ return -ENODEV; + } + -+ if (p->size != size) { -+ printk("osl_debug_mfree: dealloc size %d does not match alloc size %d on addr 0x%x at line %d file %s\n", -+ size, p->size, (uint)addr, line, file); -+ ASSERT(p->size == size); -+ return; ++ if (in_interrupt()) { ++ printk("nvram_commit: not committing in interrupt\n"); ++ return -EINVAL; + } + -+ /* unlink this block */ -+ if (p->prev) -+ p->prev->next = p->next; -+ if (p->next) -+ p->next->prev = p->prev; -+ if (osh->dbgmem_list == p) -+ osh->dbgmem_list = p->next; -+ p->next = p->prev = NULL; -+ -+ osl_mfree(osh, p, size + sizeof(bcm_mem_link_t)); -+} -+ -+char* -+osl_debug_memdump(osl_t *osh, char *buf, uint sz) -+{ -+ bcm_mem_link_t *p; -+ char *obuf; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ obuf = buf; ++ /* Backup sector blocks to be erased */ ++ erasesize = ROUNDUP(NVRAM_SPACE, nvram_mtd->erasesize); ++ if (!(buf = kmalloc(erasesize, GFP_KERNEL))) { ++ printk("nvram_commit: out of memory\n"); ++ return -ENOMEM; ++ } + -+ buf += sprintf(buf, " Address\tSize\tFile:line\n"); -+ for (p = osh->dbgmem_list; p && ((buf - obuf) < (sz - 128)); p = p->next) -+ buf += sprintf(buf, "0x%08x\t%5d\t%s:%d\n", -+ (int)p + sizeof(bcm_mem_link_t), p->size, p->file, p->line); ++ down(&nvram_sem); + -+ return (obuf); -+} ++ if ((i = erasesize - NVRAM_SPACE) > 0) { ++ offset = nvram_mtd->size - erasesize; ++ len = 0; ++ ret = MTD_READ(nvram_mtd, offset, i, &len, buf); ++ if (ret || len != i) { ++ printk("nvram_commit: read error ret = %d, len = %d/%d\n", ret, len, i); ++ ret = -EIO; ++ goto done; ++ } ++ header = (struct nvram_header *)(buf + i); ++ magic_offset = i + ((void *)&header->magic - (void *)header); ++ } else { ++ offset = nvram_mtd->size - NVRAM_SPACE; ++ magic_offset = ((void *)&header->magic - (void *)header); ++ header = (struct nvram_header *)buf; ++ } + -+#endif /* BCMDBG_MEM */ ++ /* clear the existing magic # to mark the NVRAM as unusable ++ we can pull MAGIC bits low without erase */ ++ header->magic = NVRAM_CLEAR_MAGIC; /* All zeros magic */ + -+void* -+osl_malloc(osl_t *osh, uint size) -+{ -+ void *addr; -+ -+ /* only ASSERT if osh is defined */ -+ if (osh) -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ /* Unlock sector blocks (for Intel 28F320C3B flash) , 20060309 */ ++ if(nvram_mtd->unlock) ++ nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize); + -+ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { -+ if(osh) -+ osh->failed++; -+ return (NULL); ++ ret = MTD_WRITE(nvram_mtd, offset + magic_offset, sizeof(header->magic), ++ &magic_len, (char *)&header->magic); ++ if (ret || magic_len != sizeof(header->magic)) { ++ printk("nvram_commit: clear MAGIC error\n"); ++ ret = -EIO; ++ goto done; + } -+ if (osh) -+ osh->malloced += size; -+ -+ return (addr); -+} + -+void -+osl_mfree(osl_t *osh, void *addr, uint size) -+{ -+ if (osh) { -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ osh->malloced -= size; -+ } -+ kfree(addr); -+} ++ header->magic = NVRAM_MAGIC; /* reset MAGIC before we regenerate the NVRAM, ++ otherwise we'll have an incorrect CRC */ ++ /* Regenerate NVRAM */ ++ spin_lock_irqsave(&nvram_lock, flags); ++ ret = _nvram_commit(header); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ if (ret) ++ goto done; + -+uint -+osl_malloced(osl_t *osh) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (osh->malloced); -+} ++ /* Erase sector blocks */ ++ init_waitqueue_head(&wait_q); ++ for (; offset < nvram_mtd->size - NVRAM_SPACE + header->len; offset += nvram_mtd->erasesize) { ++ erase.mtd = nvram_mtd; ++ erase.addr = offset; ++ erase.len = nvram_mtd->erasesize; ++ erase.callback = erase_callback; ++ erase.priv = (u_long) &wait_q; + -+uint osl_malloc_failed(osl_t *osh) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (osh->failed); -+} ++ set_current_state(TASK_INTERRUPTIBLE); ++ add_wait_queue(&wait_q, &wait); + -+void* -+osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ /* Unlock sector blocks */ ++ if (nvram_mtd->unlock) ++ nvram_mtd->unlock(nvram_mtd, offset, nvram_mtd->erasesize); + -+ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); -+} ++ if ((ret = MTD_ERASE(nvram_mtd, &erase))) { ++ set_current_state(TASK_RUNNING); ++ remove_wait_queue(&wait_q, &wait); ++ printk("nvram_commit: erase error\n"); ++ goto done; ++ } + -+void -+osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ /* Wait for erase to finish */ ++ schedule(); ++ remove_wait_queue(&wait_q, &wait); ++ } + -+ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); -+} ++ /* Write partition up to end of data area */ ++ header->magic = NVRAM_INVALID_MAGIC; /* All ones magic */ ++ offset = nvram_mtd->size - erasesize; ++ i = erasesize - NVRAM_SPACE + header->len; ++ ret = MTD_WRITE(nvram_mtd, offset, i, &len, buf); ++ if (ret || len != i) { ++ printk("nvram_commit: write error\n"); ++ ret = -EIO; ++ goto done; ++ } + -+uint -+osl_dma_map(osl_t *osh, void *va, uint size, int direction) -+{ -+ int dir; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ return (pci_map_single(osh->pdev, va, size, dir)); -+} ++ /* Now mark the NVRAM in flash as "valid" by setting the correct ++ MAGIC # */ ++ header->magic = NVRAM_MAGIC; ++ ret = MTD_WRITE(nvram_mtd, offset + magic_offset, sizeof(header->magic), ++ &magic_len, (char *)&header->magic); ++ if (ret || magic_len != sizeof(header->magic)) { ++ printk("nvram_commit: write MAGIC error\n"); ++ ret = -EIO; ++ goto done; ++ } + -+void -+osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) -+{ -+ int dir; -+ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ pci_unmap_single(osh->pdev, (uint32)pa, size, dir); -+} ++ /* ++ * Reading a few bytes back here will put the device ++ * back to the correct mode on certain flashes */ ++ offset = nvram_mtd->size - erasesize; ++ ret = MTD_READ(nvram_mtd, offset, 4, &len, buf); + -+#if defined(BINOSL) -+void -+osl_assert(char *exp, char *file, int line) -+{ -+ char tempbuf[255]; ++ done: ++ up(&nvram_sem); ++ kfree(buf); + -+ sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line); -+ panic(tempbuf); ++ return ret; +} -+#endif /* BCMDBG || BINOSL */ + -+void -+osl_delay(uint usec) ++int ++nvram_getall(char *buf, int count) +{ -+ uint d; ++ unsigned long flags; ++ int ret; + -+ while (usec > 0) { -+ d = MIN(usec, 1000); -+ udelay(d); -+ usec -= d; -+ } ++ spin_lock_irqsave(&nvram_lock, flags); ++ if (nvram_major >= 0) ++ ret = _nvram_getall(buf, count); ++ else ++ ret = early_nvram_getall(buf, count); ++ spin_unlock_irqrestore(&nvram_lock, flags); ++ ++ return ret; +} + -+/* -+ * BINOSL selects the slightly slower function-call-based binary compatible osl. -+ */ -+#ifdef BINOSL + -+int -+osl_printf(const char *format, ...) -+{ -+ va_list args; -+ char buf[1024]; -+ int len; + -+ /* sprintf into a local buffer because there *is* no "vprintk()".. */ -+ va_start(args, format); -+ len = vsprintf(buf, format, args); -+ va_end(args); + -+ if (len > sizeof (buf)) { -+ printk("osl_printf: buffer overrun\n"); -+ return (0); -+ } + -+ return (printk(buf)); -+} + -+int -+osl_sprintf(char *buf, const char *format, ...) -+{ -+ va_list args; -+ int rc; + -+ va_start(args, format); -+ rc = vsprintf(buf, format, args); -+ va_end(args); -+ return (rc); -+} ++/* User mode interface below */ + -+int -+osl_strcmp(const char *s1, const char *s2) ++static ssize_t ++dev_nvram_read(struct file *file, char *buf, size_t count, loff_t *ppos) +{ -+ return (strcmp(s1, s2)); -+} ++ char tmp[100], *name = tmp, *value; ++ ssize_t ret; ++ unsigned long off; + -+int -+osl_strncmp(const char *s1, const char *s2, uint n) -+{ -+ return (strncmp(s1, s2, n)); -+} ++ if (count > sizeof(tmp)) { ++ if (!(name = kmalloc(count, GFP_KERNEL))) ++ return -ENOMEM; ++ } + -+int -+osl_strlen(const char *s) -+{ -+ return (strlen(s)); -+} ++ if (copy_from_user(name, buf, count)) { ++ ret = -EFAULT; ++ goto done; ++ } + -+char* -+osl_strcpy(char *d, const char *s) -+{ -+ return (strcpy(d, s)); -+} ++ if (*name == '\0') { ++ /* Get all variables */ ++ ret = nvram_getall(name, count); ++ if (ret == 0) { ++ if (copy_to_user(buf, name, count)) { ++ ret = -EFAULT; ++ goto done; ++ } ++ ret = count; ++ } ++ } else { ++ if (!(value = nvram_get(name))) { ++ ret = 0; ++ goto done; ++ } + -+char* -+osl_strncpy(char *d, const char *s, uint n) -+{ -+ return (strncpy(d, s, n)); -+} ++ /* Provide the offset into mmap() space */ ++ off = (unsigned long) value - (unsigned long) nvram_buf; + -+void -+bcopy(const void *src, void *dst, int len) -+{ -+ memcpy(dst, src, len); -+} ++ if (put_user(off, (unsigned long *) buf)) { ++ ret = -EFAULT; ++ goto done; ++ } + -+int -+bcmp(const void *b1, const void *b2, int len) -+{ -+ return (memcmp(b1, b2, len)); -+} ++ ret = sizeof(unsigned long); ++ } + -+void -+bzero(void *b, int len) -+{ -+ memset(b, '\0', len); -+} ++ flush_cache_all(); ++ ++done: ++ if (name != tmp) ++ kfree(name); + -+uint32 -+osl_readl(volatile uint32 *r) -+{ -+ return (readl(r)); ++ return ret; +} + -+uint16 -+osl_readw(volatile uint16 *r) ++static ssize_t ++dev_nvram_write(struct file *file, const char *buf, size_t count, loff_t *ppos) +{ -+ return (readw(r)); -+} ++ char tmp[100], *name = tmp, *value; ++ ssize_t ret; + -+uint8 -+osl_readb(volatile uint8 *r) -+{ -+ return (readb(r)); -+} ++ if (count > sizeof(tmp)) { ++ if (!(name = kmalloc(count, GFP_KERNEL))) ++ return -ENOMEM; ++ } + -+void -+osl_writel(uint32 v, volatile uint32 *r) -+{ -+ writel(v, r); -+} ++ if (copy_from_user(name, buf, count)) { ++ ret = -EFAULT; ++ goto done; ++ } + -+void -+osl_writew(uint16 v, volatile uint16 *r) -+{ -+ writew(v, r); -+} ++ value = name; ++ name = strsep(&value, "="); ++ if (value) ++ ret = nvram_set(name, value) ? : count; ++ else ++ ret = nvram_unset(name) ? : count; + -+void -+osl_writeb(uint8 v, volatile uint8 *r) -+{ -+ writeb(v, r); -+} ++ done: ++ if (name != tmp) ++ kfree(name); + -+void * -+osl_uncached(void *va) -+{ -+#ifdef mips -+ return ((void*)KSEG1ADDR(va)); -+#else -+ return ((void*)va); -+#endif -+} ++ return ret; ++} + -+uint -+osl_getcycles(void) ++static int ++dev_nvram_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) +{ -+ uint cycles; ++ if (cmd != NVRAM_MAGIC) ++ return -EINVAL; + -+#if defined(mips) -+ cycles = read_c0_count() * 2; -+#elif defined(__i386__) -+ rdtscl(cycles); -+#else -+ cycles = 0; -+#endif -+ return cycles; ++ return nvram_commit(); +} + -+void * -+osl_reg_map(uint32 pa, uint size) ++static int ++dev_nvram_mmap(struct file *file, struct vm_area_struct *vma) +{ -+ return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); -+} ++ unsigned long offset = virt_to_phys(nvram_buf); + -+void -+osl_reg_unmap(void *va) -+{ -+ iounmap(va); -+} ++ if (remap_page_range(vma->vm_start, offset, vma->vm_end-vma->vm_start, ++ vma->vm_page_prot)) ++ return -EAGAIN; + -+int -+osl_busprobe(uint32 *val, uint32 addr) -+{ -+#ifdef mips -+ return get_dbe(*val, (uint32*)addr); -+#else -+ *val = readl(addr); + return 0; -+#endif +} + -+uchar* -+osl_pktdata(osl_t *osh, void *skb) ++static int ++dev_nvram_open(struct inode *inode, struct file * file) +{ -+ return (((struct sk_buff*)skb)->data); ++ MOD_INC_USE_COUNT; ++ return 0; +} + -+uint -+osl_pktlen(osl_t *osh, void *skb) ++static int ++dev_nvram_release(struct inode *inode, struct file * file) +{ -+ return (((struct sk_buff*)skb)->len); ++ MOD_DEC_USE_COUNT; ++ return 0; +} + -+uint -+osl_pktheadroom(osl_t *osh, void *skb) -+{ -+ return (uint) skb_headroom((struct sk_buff *) skb); -+} ++static struct file_operations dev_nvram_fops = { ++ owner: THIS_MODULE, ++ open: dev_nvram_open, ++ release: dev_nvram_release, ++ read: dev_nvram_read, ++ write: dev_nvram_write, ++ ioctl: dev_nvram_ioctl, ++ mmap: dev_nvram_mmap, ++}; + -+uint -+osl_pkttailroom(osl_t *osh, void *skb) ++static void ++dev_nvram_exit(void) +{ -+ return (uint) skb_tailroom((struct sk_buff *) skb); -+} ++ int order = 0; ++ struct page *page, *end; + -+void* -+osl_pktnext(osl_t *osh, void *skb) -+{ -+ return (((struct sk_buff*)skb)->next); -+} ++ if (nvram_handle) ++ devfs_unregister(nvram_handle); + -+void -+osl_pktsetnext(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->next = (struct sk_buff*)x; -+} ++ if (nvram_major >= 0) ++ devfs_unregister_chrdev(nvram_major, "nvram"); + -+void -+osl_pktsetlen(osl_t *osh, void *skb, uint len) -+{ -+ __skb_trim((struct sk_buff*)skb, len); -+} ++ if (nvram_mtd) ++ put_mtd_device(nvram_mtd); + -+uchar* -+osl_pktpush(osl_t *osh, void *skb, int bytes) -+{ -+ return (skb_push((struct sk_buff*)skb, bytes)); -+} ++ while ((PAGE_SIZE << order) < NVRAM_SPACE) ++ order++; ++ end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1); ++ for (page = virt_to_page(nvram_buf); page <= end; page++) ++ mem_map_unreserve(page); + -+uchar* -+osl_pktpull(osl_t *osh, void *skb, int bytes) -+{ -+ return (skb_pull((struct sk_buff*)skb, bytes)); ++ _nvram_exit(); +} + -+void* -+osl_pktdup(osl_t *osh, void *skb) ++static int __init ++dev_nvram_init(void) +{ -+ return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC)); -+} ++ int order = 0, ret = 0; ++ struct page *page, *end; ++ unsigned int i; + -+void* -+osl_pktcookie(void *skb) -+{ -+ return ((void*)((struct sk_buff*)skb)->csum); -+} ++ /* Allocate and reserve memory to mmap() */ ++ while ((PAGE_SIZE << order) < NVRAM_SPACE) ++ order++; ++ end = virt_to_page(nvram_buf + (PAGE_SIZE << order) - 1); ++ for (page = virt_to_page(nvram_buf); page <= end; page++) ++ mem_map_reserve(page); + -+void -+osl_pktsetcookie(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->csum = (uint)x; -+} ++#ifdef CONFIG_MTD ++ /* Find associated MTD device */ ++ for (i = 0; i < MAX_MTD_DEVICES; i++) { ++ nvram_mtd = get_mtd_device(NULL, i); ++ if (nvram_mtd) { ++ if (!strcmp(nvram_mtd->name, "nvram") && ++ nvram_mtd->size >= NVRAM_SPACE) ++ break; ++ put_mtd_device(nvram_mtd); ++ } ++ } ++ if (i >= MAX_MTD_DEVICES) ++ nvram_mtd = NULL; ++#endif + -+void* -+osl_pktlink(void *skb) -+{ -+ return (((struct sk_buff*)skb)->prev); -+} ++ /* Initialize hash table lock */ ++ spin_lock_init(&nvram_lock); + -+void -+osl_pktsetlink(void *skb, void *x) -+{ -+ ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; -+} ++ /* Initialize commit semaphore */ ++ init_MUTEX(&nvram_sem); + -+uint -+osl_pktprio(void *skb) -+{ -+ return (((struct sk_buff*)skb)->priority); -+} ++ /* Register char device */ ++ if ((nvram_major = devfs_register_chrdev(0, "nvram", &dev_nvram_fops)) < 0) { ++ ret = nvram_major; ++ goto err; ++ } + -+void -+osl_pktsetprio(void *skb, uint x) -+{ -+ ((struct sk_buff*)skb)->priority = x; -+} ++ /* Initialize hash table */ ++ _nvram_init(sbh); ++ ++ /* Create /dev/nvram handle */ ++ nvram_handle = devfs_register(NULL, "nvram", DEVFS_FL_NONE, nvram_major, 0, ++ S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, &dev_nvram_fops, NULL); ++ ++ /* Set the SDRAM NCDL value into NVRAM if not already done */ ++ if (getintvar(NULL, "sdram_ncdl") == 0) { ++ unsigned int ncdl; ++ char buf[] = "0x00000000"; ++ ++ if ((ncdl = sb_memc_get_ncdl(sbh))) { ++ sprintf(buf, "0x%08x", ncdl); ++ nvram_set("sdram_ncdl", buf); ++ nvram_commit(); ++ } ++ } ++ ++ return 0; + ++ err: ++ dev_nvram_exit(); ++ return ret; ++} + -+#endif /* BINOSL */ -diff -Naur linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils.c ---- linux.old/drivers/net/hnd/sbutils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/hnd/sbutils.c 2006-04-06 15:34:15.000000000 +0200 -@@ -0,0 +1,2837 @@ ++module_init(dev_nvram_init); ++module_exit(dev_nvram_exit); +diff -urN linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/pcibios.c +--- linux.old/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/pcibios.c 2006-04-27 23:42:50.000000000 +0200 +@@ -0,0 +1,380 @@ +/* -+ * Misc utility routines for accessing chip-specific features -+ * of the SiliconBackplane-based Broadcom chips. ++ * Low-Level PCI and SB support for BCM47xx (Linux support code) + * -+ * Copyright 2005, Broadcom Corporation ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ ++ * ++ * $Id: pcibios.c,v 1.1.1.9 2006/02/27 03:42:55 honor Exp $ + */ + ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ +#include +#include -+#include +#include -+#include +#include -+#include -+#include -+#include ++#include ++#include +#include -+#include -+#include -+#include -+ -+/* debug/trace */ -+#define SB_ERROR(args) -+ -+ -+typedef uint32 (*sb_intrsoff_t)(void *intr_arg); -+typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg); -+typedef bool (*sb_intrsenabled_t)(void *intr_arg); -+ -+/* misc sb info needed by some of the routines */ -+typedef struct sb_info { ++#include ++#include + -+ struct sb_pub sb; /* back plane public state(must be first field of sb_info */ ++/* Global SB handle */ ++extern sb_t *bcm947xx_sbh; ++extern spinlock_t bcm947xx_sbh_lock; + -+ void *osh; /* osl os handle */ -+ void *sdh; /* bcmsdh handle */ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock + -+ void *curmap; /* current regs va */ -+ void *regs[SB_MAXCORES]; /* other regs va */ ++static int ++sbpci_read_config_byte(struct pci_dev *dev, int where, u8 *value) ++{ ++ unsigned long flags; ++ int ret; + -+ uint curidx; /* current core index */ -+ uint dev_coreid; /* the core provides driver functions */ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), ++ PCI_FUNC(dev->devfn), where, value, sizeof(*value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} + -+ bool memseg; /* flag to toggle MEM_SEG register */ ++static int ++sbpci_read_config_word(struct pci_dev *dev, int where, u16 *value) ++{ ++ unsigned long flags; ++ int ret; + -+ uint gpioidx; /* gpio control core index */ -+ uint gpioid; /* gpio control coretype */ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), ++ PCI_FUNC(dev->devfn), where, value, sizeof(*value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} + -+ uint numcores; /* # discovered cores */ -+ uint coreid[SB_MAXCORES]; /* id of each core */ ++static int ++sbpci_read_config_dword(struct pci_dev *dev, int where, u32 *value) ++{ ++ unsigned long flags; ++ int ret; + -+ void *intr_arg; /* interrupt callback function arg */ -+ sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */ -+ sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */ -+ sb_intrsenabled_t intrsenabled_fn; /* function to check if chip interrupts are enabled */ ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_read_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), ++ PCI_FUNC(dev->devfn), where, value, sizeof(*value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} + -+} sb_info_t; ++static int ++sbpci_write_config_byte(struct pci_dev *dev, int where, u8 value) ++{ ++ unsigned long flags; ++ int ret; + -+/* local prototypes */ -+static sb_info_t * BCMINIT(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, int *varsz); -+static void BCMINIT(sb_scan)(sb_info_t *si); -+static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val); -+static uint _sb_coreidx(sb_info_t *si); -+static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit); -+static uint BCMINIT(sb_pcidev2chip)(uint pcidev); -+static uint BCMINIT(sb_chip2numcores)(uint chip); -+static bool sb_ispcie(sb_info_t *si); -+static bool sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen); -+static int sb_pci_fixcfg(sb_info_t *si); ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), ++ PCI_FUNC(dev->devfn), where, &value, sizeof(value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} + -+/* routines to access mdio slave device registers */ -+static int sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint readdr, uint val); -+static void BCMINIT(sb_war30841)(sb_info_t *si); ++static int ++sbpci_write_config_word(struct pci_dev *dev, int where, u16 value) ++{ ++ unsigned long flags; ++ int ret; + -+/* delay needed between the mdio control/ mdiodata register data access */ -+#define PR28829_DELAY() OSL_DELAY(10) ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), ++ PCI_FUNC(dev->devfn), where, &value, sizeof(value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} + ++static int ++sbpci_write_config_dword(struct pci_dev *dev, int where, u32 value) ++{ ++ unsigned long flags; ++ int ret; + -+/* global variable to indicate reservation/release of gpio's*/ -+static uint32 sb_gpioreservation = 0; ++ spin_lock_irqsave(&sbh_lock, flags); ++ ret = sbpci_write_config(sbh, dev->bus->number, PCI_SLOT(dev->devfn), ++ PCI_FUNC(dev->devfn), where, &value, sizeof(value)); ++ spin_unlock_irqrestore(&sbh_lock, flags); ++ return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL; ++} + -+#define SB_INFO(sbh) (sb_info_t*)sbh -+#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val))) -+#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE)) -+#define GOODREGS(regs) ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE)) -+#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) -+#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) -+#define BADIDX (SB_MAXCORES+1) -+#define NOREV -1 ++static struct pci_ops pcibios_ops = { ++ sbpci_read_config_byte, ++ sbpci_read_config_word, ++ sbpci_read_config_dword, ++ sbpci_write_config_byte, ++ sbpci_write_config_word, ++ sbpci_write_config_dword ++}; + -+#define PCI(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI)) -+#define PCIE(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCIE)) + -+/* sonicsrev */ -+#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) -+#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) ++void __init ++pcibios_init(void) ++{ ++ ulong flags; + -+#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr)) -+#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v)) -+#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v))) -+#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v))) ++ if (!(sbh = sb_kattach())) ++ panic("sb_kattach failed"); ++ spin_lock_init(&sbh_lock); + -+/* -+ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ -+ * after core switching to avoid invalid register accesss inside ISR. -+ */ -+#define INTR_OFF(si, intr_val) \ -+ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -+#define INTR_RESTORE(si, intr_val) \ -+ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ -+ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } ++ spin_lock_irqsave(&sbh_lock, flags); ++ sbpci_init(sbh); ++ spin_unlock_irqrestore(&sbh_lock, flags); + -+/* dynamic clock control defines */ -+#define LPOMINFREQ 25000 /* low power oscillator min */ -+#define LPOMAXFREQ 43000 /* low power oscillator max */ -+#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ -+#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ -+#define PCIMINFREQ 25000000 /* 25 MHz */ -+#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ ++ set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000)); + -+#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ -+#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ ++ /* Scan the SB bus */ ++ pci_scan_bus(0, &pcibios_ops, NULL); + -+#define MIN_DUMPBUFLEN 32 /* debug */ ++} + -+/* different register spaces to access thr'u pcie indirect access*/ -+#define PCIE_CONFIGREGS 1 -+#define PCIE_PCIEREGS 2 ++char * __init ++pcibios_setup(char *str) ++{ ++ if (!strncmp(str, "ban=", 4)) { ++ sbpci_ban(simple_strtoul(str + 4, NULL, 0)); ++ return NULL; ++ } + -+/* GPIO Based LED powersave defines */ -+#define DEFAULT_GPIO_ONTIME 10 -+#define DEFAULT_GPIO_OFFTIME 90 ++ return (str); ++} + -+#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) ++static u32 pci_iobase = 0x100; ++static u32 pci_membase = SB_PCI_DMA; + -+static uint32 -+sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr) ++void __init ++pcibios_fixup_bus(struct pci_bus *b) +{ -+ uint8 tmp; -+ uint32 val, intr_val = 0; ++ struct list_head *ln; ++ struct pci_dev *d; ++ struct resource *res; ++ int pos, size; ++ u32 *base; ++ u8 irq; + ++ printk("PCI: Fixing up bus %d\n", b->number); + -+ /* -+ * compact flash only has 11 bits address, while we needs 12 bits address. -+ * MEM_SEG will be OR'd with other 11 bits address in hardware, -+ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). -+ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special -+ */ -+ if(si->memseg) { -+ INTR_OFF(si, intr_val); -+ tmp = 1; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ ++ /* Fix up SB */ ++ if (b->number == 0) { ++ for (ln = b->devices.next; ln != &b->devices; ln = ln->next) { ++ d = pci_dev_b(ln); ++ /* Fix up interrupt lines */ ++ pci_read_config_byte(d, PCI_INTERRUPT_LINE, &irq); ++ d->irq = irq + 2; ++ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); ++ } + } + -+ val = R_REG(sbr); -+ -+ if(si->memseg) { -+ tmp = 0; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ INTR_RESTORE(si, intr_val); ++ /* Fix up external PCI */ ++ else { ++ for (ln = b->devices.next; ln != &b->devices; ln = ln->next) { ++ d = pci_dev_b(ln); ++ /* Fix up resource bases */ ++ for (pos = 0; pos < 6; pos++) { ++ res = &d->resource[pos]; ++ base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase; ++ if (res->end) { ++ size = res->end - res->start + 1; ++ if (*base & (size - 1)) ++ *base = (*base + size) & ~(size - 1); ++ res->start = *base; ++ res->end = res->start + size - 1; ++ *base += size; ++ pci_write_config_dword(d, ++ PCI_BASE_ADDRESS_0 + (pos << 2), res->start); ++ } ++ /* Fix up PCI bridge BAR0 only */ ++ if (b->number == 1 && PCI_SLOT(d->devfn) == 0) ++ break; ++ } ++ /* Fix up interrupt lines */ ++ if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL)) ++ d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq; ++ pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq); ++ } + } -+ -+ return (val); +} + -+static void -+sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v) ++unsigned int ++pcibios_assign_all_busses(void) +{ -+ uint8 tmp; -+ volatile uint32 dummy; -+ uint32 intr_val = 0; -+ -+ -+ /* -+ * compact flash only has 11 bits address, while we needs 12 bits address. -+ * MEM_SEG will be OR'd with other 11 bits address in hardware, -+ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). -+ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special -+ */ -+ if(si->memseg) { -+ INTR_OFF(si, intr_val); -+ tmp = 1; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ -+ } -+ -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { -+#ifdef IL_BIGENDIAN -+ dummy = R_REG(sbr); -+ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); -+ dummy = R_REG(sbr); -+ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); -+#else -+ dummy = R_REG(sbr); -+ W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); -+ dummy = R_REG(sbr); -+ W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); -+#endif -+ } else -+ W_REG(sbr, v); ++ return 1; ++} + -+ if(si->memseg) { -+ tmp = 0; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ INTR_RESTORE(si, intr_val); -+ } ++void ++pcibios_align_resource(void *data, struct resource *res, ++ unsigned long size, unsigned long align) ++{ +} + -+/* -+ * Allocate a sb handle. -+ * devid - pci device id (used to determine chip#) -+ * osh - opaque OS handle -+ * regs - virtual address of initial core registers -+ * bustype - pci/pcmcia/sb/sdio/etc -+ * vars - pointer to a pointer area for "environment" variables -+ * varsz - pointer to int to return the size of the vars -+ */ -+sb_t * -+BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, int *varsz) ++int ++pcibios_enable_resources(struct pci_dev *dev) +{ -+ sb_info_t *si; ++ u16 cmd, old_cmd; ++ int idx; ++ struct resource *r; + -+ /* alloc sb_info_t */ -+ if ((si = MALLOC(osh, sizeof (sb_info_t))) == NULL) { -+ SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); -+ return (NULL); -+ } ++ /* External PCI only */ ++ if (dev->bus->number == 0) ++ return 0; + -+ if (BCMINIT(sb_doattach)(si, devid, osh, regs, bustype, sdh, vars, varsz) == NULL) { -+ MFREE(osh, si, sizeof (sb_info_t)); -+ return (NULL); ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ old_cmd = cmd; ++ for (idx = 0; idx < 6; idx++) { ++ r = &dev->resource[idx]; ++ if (r->flags & IORESOURCE_IO) ++ cmd |= PCI_COMMAND_IO; ++ if (r->flags & IORESOURCE_MEM) ++ cmd |= PCI_COMMAND_MEMORY; + } -+ return (sb_t *)si; ++ if (dev->resource[PCI_ROM_RESOURCE].start) ++ cmd |= PCI_COMMAND_MEMORY; ++ if (cmd != old_cmd) { ++ printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd); ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ } ++ return 0; +} + -+/* Using sb_kattach depends on SB_BUS support, either implicit */ -+/* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */ -+#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS) -+ -+/* global kernel resource */ -+static sb_info_t ksi; -+ -+/* generic kernel variant of sb_attach() */ -+sb_t * -+BCMINITFN(sb_kattach)() ++int ++pcibios_enable_device(struct pci_dev *dev, int mask) +{ -+ uint32 *regs; ++ ulong flags; ++ uint coreidx; ++ void *regs; + -+ if (ksi.curmap == NULL) { -+ uint32 cid; ++ /* External PCI device enable */ ++ if (dev->bus->number != 0) ++ return pcibios_enable_resources(dev); + -+ regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); -+ cid = R_REG((uint32 *)regs); -+ if (((cid & CID_ID_MASK) == BCM4712_DEVICE_ID) && -+ ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) && -+ ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) { -+ uint32 *scc, val; ++ /* These cores come out of reset enabled */ ++ if (dev->device == SB_MIPS || ++ dev->device == SB_MIPS33 || ++ dev->device == SB_EXTIF || ++ dev->device == SB_CC) ++ return 0; + -+ scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); -+ val = R_REG(scc); -+ SB_ERROR((" initial scc = 0x%x\n", val)); -+ val |= SCC_SS_XTAL; -+ W_REG(scc, val); ++ spin_lock_irqsave(&sbh_lock, flags); ++ coreidx = sb_coreidx(sbh); ++ regs = sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)); ++ if (!regs) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ /* ++ * The USB core requires a special bit to be set during core ++ * reset to enable host (OHCI) mode. Resetting the SB core in ++ * pcibios_enable_device() is a hack for compatibility with ++ * vanilla usb-ohci so that it does not have to know about ++ * SB. A driver that wants to use the USB core in device mode ++ * should know about SB and should reset the bit back to 0 ++ * after calling pcibios_enable_device(). ++ */ ++ if (sb_coreid(sbh) == SB_USB) { ++ sb_core_disable(sbh, sb_coreflags(sbh, 0, 0)); ++ sb_core_reset(sbh, 1 << 29, 0); ++ } ++ /* ++ * USB 2.0 special considerations: ++ * ++ * 1. Since the core supports both OHCI and EHCI functions, it must ++ * only be reset once. ++ * ++ * 2. In addition to the standard SB reset sequence, the Host Control ++ * Register must be programmed to bring the USB core and various ++ * phy components out of reset. ++ */ ++ else if (sb_coreid(sbh) == SB_USB20H) { ++ if (!sb_iscoreup(sbh)) { ++ sb_core_reset(sbh, 0, 0); ++ writel(0x7FF, (ulong)regs + 0x200); ++ udelay(1); + } ++ } else ++ sb_core_reset(sbh, 0, 0); + -+ if (BCMINIT(sb_doattach)(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, -+ SB_BUS, NULL, NULL, NULL) == NULL) { -+ return NULL; -+ } -+ } ++ sb_setcoreidx(sbh, coreidx); ++ spin_unlock_irqrestore(&sbh_lock, flags); + -+ return (sb_t *)&ksi; ++ return 0; +} -+#endif + -+static sb_info_t * -+BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, -+ uint bustype, void *sdh, char **vars, int *varsz) ++void ++pcibios_update_resource(struct pci_dev *dev, struct resource *root, ++ struct resource *res, int resource) +{ -+ uint origidx; -+ chipcregs_t *cc; -+ sbconfig_t *sb; -+ uint32 w; -+ -+ ASSERT(GOODREGS(regs)); -+ -+ bzero((uchar*)si, sizeof (sb_info_t)); ++ unsigned long where, size; ++ u32 reg; + -+ si->sb.buscoreidx = si->gpioidx = BADIDX; ++ /* External PCI only */ ++ if (dev->bus->number == 0) ++ return; + -+ si->osh = osh; -+ si->curmap = regs; -+ si->sdh = sdh; ++ where = PCI_BASE_ADDRESS_0 + (resource * 4); ++ size = res->end - res->start; ++ pci_read_config_dword(dev, where, ®); ++ reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); ++ pci_write_config_dword(dev, where, reg); ++} + -+ /* check to see if we are a sb core mimic'ing a pci core */ -+ if (bustype == PCI_BUS) { -+ if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff) -+ bustype = SB_BUS; -+ else -+ bustype = PCI_BUS; -+ } ++static void __init ++quirk_sbpci_bridge(struct pci_dev *dev) ++{ ++ if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0) ++ return; + -+ si->sb.bustype = bustype; -+ if (si->sb.bustype != BUSTYPE(si->sb.bustype)) { -+ SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n", -+ si->sb.bustype, BUSTYPE(si->sb.bustype))); -+ return NULL; -+ } ++ printk("PCI: Fixing up bridge\n"); + -+ /* need to set memseg flag for CF card first before any sb registers access */ -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) -+ si->memseg = TRUE; ++ /* Enable PCI bridge bus mastering and memory space */ ++ pci_set_master(dev); ++ pcibios_enable_resources(dev); + -+ /* kludge to enable the clock on the 4306 which lacks a slowclock */ -+ if (BUSTYPE(si->sb.bustype) == PCI_BUS) -+ sb_clkctl_xtal(&si->sb, XTAL|PLL, ON); ++ /* Enable PCI bridge BAR1 prefetch and burst */ ++ pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3); ++} + -+ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { -+ w = OSL_PCI_READ_CONFIG(osh, PCI_BAR0_WIN, sizeof (uint32)); -+ if (!GOODCOREADDR(w)) -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32), SB_ENUM_BASE); -+ } ++struct pci_fixup pcibios_fixups[] = { ++ { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, quirk_sbpci_bridge }, ++ { 0 } ++}; + -+ /* initialize current core index value */ -+ si->curidx = _sb_coreidx(si); ++/* ++ * If we set up a device for bus mastering, we need to check the latency ++ * timer as certain crappy BIOSes forget to set it properly. ++ */ ++unsigned int pcibios_max_latency = 255; + -+ if (si->curidx == BADIDX) { -+ SB_ERROR(("sb_doattach: bad core index\n")); -+ return NULL; -+ } ++void pcibios_set_master(struct pci_dev *dev) ++{ ++ u8 lat; ++ pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); ++ if (lat < 16) ++ lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; ++ else if (lat > pcibios_max_latency) ++ lat = pcibios_max_latency; ++ else ++ return; ++ printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", dev->slot_name, lat); ++ pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); ++} + -+ /* get sonics backplane revision */ -+ sb = REGS2SB(si->curmap); -+ si->sb.sonicsrev = (R_SBREG(si, &(sb)->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; +diff -urN linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom.c +--- linux.old/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/prom.c 2006-04-27 19:24:19.000000000 +0200 +@@ -0,0 +1,41 @@ ++/* ++ * Early initialization code for BCM94710 boards ++ * ++ * Copyright 2004, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: prom.c,v 1.1 2005/03/16 13:49:59 wbx Exp $ ++ */ + -+ /* keep and reuse the initial register mapping */ -+ origidx = si->curidx; -+ if (BUSTYPE(si->sb.bustype) == SB_BUS) -+ si->regs[origidx] = regs; ++#include ++#include ++#include ++#include ++#include + -+ /* is core-0 a chipcommon core? */ -+ si->numcores = 1; -+ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0); -+ if (sb_coreid(&si->sb) != SB_CC) -+ cc = NULL; ++void __init ++prom_init(int argc, const char **argv) ++{ ++ unsigned long mem; + -+ /* determine chip id and rev */ -+ if (cc) { -+ /* chip common core found! */ -+ si->sb.chip = R_REG(&cc->chipid) & CID_ID_MASK; -+ si->sb.chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; -+ si->sb.chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; -+ } else { -+ /* The only pcmcia chip without a chipcommon core is a 4301 */ -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) -+ devid = BCM4301_DEVICE_ID; ++ mips_machgroup = MACH_GROUP_BRCM; ++ mips_machtype = MACH_BCM947XX; + -+ /* no chip common core -- must convert device id to chip id */ -+ if ((si->sb.chip = BCMINIT(sb_pcidev2chip)(devid)) == 0) { -+ SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid)); -+ sb_setcoreidx(&si->sb, origidx); -+ return NULL; -+ } ++ /* Figure out memory size by finding aliases */ ++ for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) { ++ if (*(unsigned long *)((unsigned long)(prom_init) + mem) == ++ *(unsigned long *)(prom_init)) ++ break; + } ++ add_memory_region(0, mem, BOOT_MEM_RAM); ++} + -+ /* get chipcommon rev */ -+ si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV; ++void __init ++prom_free_prom_memory(void) ++{ ++} +diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbmips.c +--- linux.old/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/sbmips.c 2006-05-02 04:43:13.000000000 +0200 +@@ -0,0 +1,1132 @@ ++/* ++ * BCM47XX Sonics SiliconBackplane MIPS core routines ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: hndmips.c,v 1.1.1.1 2006/02/27 03:43:16 honor Exp $ ++ */ + -+ /* determine numcores */ -+ if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6))) -+ si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; -+ else -+ si->numcores = BCMINIT(sb_chip2numcores)(si->sb.chip); ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+ /* return to original core */ -+ sb_setcoreidx(&si->sb, origidx); ++/* sbipsflag register format, indexed by irq. */ ++static const uint32 sbips_int_mask[] = { ++ 0, /* placeholder */ ++ SBIPS_INT1_MASK, ++ SBIPS_INT2_MASK, ++ SBIPS_INT3_MASK, ++ SBIPS_INT4_MASK ++}; + -+ /* sanity checks */ -+ ASSERT(si->sb.chip); ++static const uint32 sbips_int_shift[] = { ++ 0, /* placeholder */ ++ SBIPS_INT1_SHIFT, ++ SBIPS_INT2_SHIFT, ++ SBIPS_INT3_SHIFT, ++ SBIPS_INT4_SHIFT ++}; + -+ /* scan for cores */ -+ BCMINIT(sb_scan)(si); ++/* ++ * Map SB cores sharing the MIPS hardware IRQ0 to virtual dedicated OS IRQs. ++ * Per-port BSP code is required to provide necessary translations between ++ * the shared MIPS IRQ and the virtual OS IRQs based on SB core flag. ++ * ++ * See sb_irq() for the mapping. ++ */ ++static uint shirq_map_base = 0; + -+ /* fixup necessary chip/core configurations */ -+ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { -+ if (sb_pci_fixcfg(si)) { -+ SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n")); -+ return NULL; -+ } -+ } -+ -+ /* srom_var_init() depends on sb_scan() info */ -+ if (srom_var_init(si, si->sb.bustype, si->curmap, osh, vars, varsz)) { -+ SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n")); -+ return (NULL); -+ } -+ -+ if (cc == NULL) { -+ /* -+ * The chip revision number is hardwired into all -+ * of the pci function config rev fields and is -+ * independent from the individual core revision numbers. -+ * For example, the "A0" silicon of each chip is chip rev 0. -+ * For PCMCIA we get it from the CIS instead. -+ */ -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { -+ ASSERT(vars); -+ si->sb.chiprev = getintvar(*vars, "chiprev"); -+ } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) { -+ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32)); -+ si->sb.chiprev = w & 0xff; -+ } else -+ si->sb.chiprev = 0; -+ } ++/* Returns the SB interrupt flag of the current core. */ ++static uint32 ++sb_getflag(sb_t *sbh) ++{ ++ osl_t *osh; ++ void *regs; ++ sbconfig_t *sb; + -+ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { -+ w = getintvar(*vars, "regwindowsz"); -+ si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; -+ } ++ osh = sb_osh(sbh); ++ regs = sb_coreregs(sbh); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); + -+ /* gpio control core is required */ -+ if (!GOODIDX(si->gpioidx)) { -+ SB_ERROR(("sb_doattach: gpio control core not found\n")); -+ return NULL; -+ } ++ return (R_REG(osh, &sb->sbtpsflag) & SBTPS_NUM0_MASK); ++} + -+ /* get boardtype and boardrev */ -+ switch (BUSTYPE(si->sb.bustype)) { -+ case PCI_BUS: -+ /* do a pci config read to get subsystem id and subvendor id */ -+ w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_SVID, sizeof (uint32)); -+ si->sb.boardvendor = w & 0xffff; -+ si->sb.boardtype = (w >> 16) & 0xffff; -+ break; ++/* ++ * Returns the MIPS IRQ assignment of the current core. If unassigned, ++ * 0 is returned. ++ */ ++uint ++sb_irq(sb_t *sbh) ++{ ++ osl_t *osh; ++ uint idx; ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag, sbipsflag; ++ uint irq = 0; + -+ case PCMCIA_BUS: -+ case SDIO_BUS: -+ si->sb.boardvendor = getintvar(*vars, "manfid"); -+ si->sb.boardtype = getintvar(*vars, "prodid"); -+ break; ++ osh = sb_osh(sbh); ++ flag = sb_getflag(sbh); + -+ case SB_BUS: -+ case JTAG_BUS: -+ si->sb.boardvendor = VENDOR_BROADCOM; -+ if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0) -+ si->sb.boardtype = 0xffff; -+ break; -+ } ++ idx = sb_coreidx(sbh); + -+ if (si->sb.boardtype == 0) { -+ SB_ERROR(("sb_doattach: unknown board type\n")); -+ ASSERT(si->sb.boardtype); -+ } ++ if ((regs = sb_setcore(sbh, SB_MIPS, 0)) || ++ (regs = sb_setcore(sbh, SB_MIPS33, 0))) { ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); + -+ /* setup the GPIO based LED powersave register */ -+ if (si->sb.ccrev >= 16) { -+ w = getintvar(*vars, "gpiotimerval"); -+ if (!w) -+ w = DEFAULT_GPIOTIMERVAL; -+ sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); ++ /* sbipsflag specifies which core is routed to interrupts 1 to 4 */ ++ sbipsflag = R_REG(osh, &sb->sbipsflag); ++ for (irq = 1; irq <= 4; irq++) { ++ if (((sbipsflag & sbips_int_mask[irq]) >> sbips_int_shift[irq]) == flag) ++ break; ++ } ++ if (irq == 5) ++ irq = 0; + } + ++ sb_setcoreidx(sbh, idx); + -+ return (si); ++ return irq; +} + -+uint -+sb_coreid(sb_t *sbh) ++/* Clears the specified MIPS IRQ. */ ++static void ++BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq) +{ -+ sb_info_t *si; ++ osl_t *osh; ++ void *regs; + sbconfig_t *sb; + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++ osh = sb_osh(sbh); ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); + -+ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); ++ if (irq == 0) ++ W_REG(osh, &sb->sbintvec, 0); ++ else ++ OR_REG(osh, &sb->sbipsflag, sbips_int_mask[irq]); +} + -+uint -+sb_coreidx(sb_t *sbh) ++/* ++ * Assigns the specified MIPS IRQ to the specified core. Shared MIPS ++ * IRQ 0 may be assigned more than once. ++ * ++ * The old assignment to the specified core is removed first. ++ */ ++static void ++BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit) +{ -+ sb_info_t *si; ++ osl_t *osh; ++ void *regs; ++ sbconfig_t *sb; ++ uint32 flag; ++ uint oldirq; + -+ si = SB_INFO(sbh); -+ return (si->curidx); ++ osh = sb_osh(sbh); ++ ++ regs = sb_setcore(sbh, coreid, coreunit); ++ ASSERT(regs); ++ flag = sb_getflag(sbh); ++ oldirq = sb_irq(sbh); ++ if (oldirq) ++ sb_clearirq(sbh, oldirq); ++ ++ if (!(regs = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(regs = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(regs); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ if (!oldirq) ++ AND_REG(osh, &sb->sbintvec, ~(1 << flag)); ++ ++ if (irq == 0) ++ OR_REG(osh, &sb->sbintvec, 1 << flag); ++ else { ++ flag <<= sbips_int_shift[irq]; ++ ASSERT(!(flag & ~sbips_int_mask[irq])); ++ flag |= R_REG(osh, &sb->sbipsflag) & ~sbips_int_mask[irq]; ++ W_REG(osh, &sb->sbipsflag, flag); ++ } +} + -+/* return current index of core */ -+static uint -+_sb_coreidx(sb_info_t *si) ++/* ++ * Initializes clocks and interrupts. SB and NVRAM access must be ++ * initialized prior to calling. ++ * ++ * 'shirqmap' enables virtual dedicated OS IRQ mapping if non-zero. ++ */ ++void ++BCMINITFN(sb_mips_init)(sb_t *sbh, uint shirqmap) +{ -+ sbconfig_t *sb; -+ uint32 sbaddr = 0; ++ osl_t *osh; ++ ulong hz, ns, tmp; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ char *value; ++ uint irq; + -+ ASSERT(si); ++ osh = sb_osh(sbh); + -+ switch (BUSTYPE(si->sb.bustype)) { -+ case SB_BUS: -+ sb = REGS2SB(si->curmap); -+ sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0)); -+ break; ++ /* Figure out current SB clock speed */ ++ if ((hz = sb_clock(sbh)) == 0) ++ hz = 100000000; ++ ns = 1000000000 / hz; + -+ case PCI_BUS: -+ sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32)); -+ break; ++ /* Setup external interface timing */ ++ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { ++ /* Initialize extif so we can get to the LEDs and external UART */ ++ W_REG(osh, &eir->prog_config, CF_EN); + -+ case PCMCIA_BUS: { -+ uint8 tmp = 0; ++ /* Set timing for the flash */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */ ++ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ ++ W_REG(osh, &eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ + -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); -+ sbaddr = (uint)tmp << 12; -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); -+ sbaddr |= (uint)tmp << 16; -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); -+ sbaddr |= (uint)tmp << 24; -+ break; ++ /* Set programmable interface timing for external uart */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp = tmp | (CEIL(20, ns) << FW_W2_SHIFT); /* W2 = 20nS */ ++ tmp = tmp | (CEIL(100, ns) << FW_W1_SHIFT); /* W1 = 100nS */ ++ tmp = tmp | CEIL(120, ns); /* W0 = 120nS */ ++ W_REG(osh, &eir->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ ++ } else if ((cc = sb_setcore(sbh, SB_CC, 0))) { ++ /* Set timing for the flash */ ++ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ ++ tmp |= CEIL(10, ns) << FW_W1_SHIFT; /* W1 = 10nS */ ++ tmp |= CEIL(120, ns); /* W0 = 120nS */ ++ if ((sb_corerev(sbh) < 9) || ++ (BCMINIT(sb_chip)(sbh) == 0x5365)) ++ W_REG(osh, &cc->flash_waitcount, tmp); ++ ++ if ((sb_corerev(sbh) < 9) || ++ ((sb_chip(sbh) == BCM5350_CHIP_ID) && sb_chiprev(sbh) == 0) || ++ (BCMINIT(sb_chip)(sbh) == 0x5365)) { ++ W_REG(osh, &cc->pcmcia_memwait, tmp); ++ } ++ ++ /* Save shared IRQ mapping base */ ++ shirq_map_base = shirqmap; + } + -+#ifdef BCMJTAG -+ case JTAG_BUS: -+ sbaddr = (uint32)si->curmap; ++ /* Chip specific initialization */ ++ switch (sb_chip(sbh)) { ++ case BCM4710_CHIP_ID: ++ /* Clear interrupt map */ ++ for (irq = 0; irq <= 4; irq++) ++ sb_clearirq(sbh, irq); ++ sb_setirq(sbh, 0, SB_CODEC, 0); ++ sb_setirq(sbh, 0, SB_EXTIF, 0); ++ sb_setirq(sbh, 2, SB_ENET, 1); ++ sb_setirq(sbh, 3, SB_ILINE20, 0); ++ sb_setirq(sbh, 4, SB_PCI, 0); ++ ASSERT(eir); ++ value = nvram_get("et0phyaddr"); ++ if (value && !strcmp(value, "31")) { ++ /* Enable internal UART */ ++ W_REG(osh, &eir->corecontrol, CC_UE); ++ /* Give USB its own interrupt */ ++ sb_setirq(sbh, 1, SB_USB, 0); ++ } else { ++ /* Disable internal UART */ ++ W_REG(osh, &eir->corecontrol, 0); ++ /* Give Ethernet its own interrupt */ ++ sb_setirq(sbh, 1, SB_ENET, 0); ++ sb_setirq(sbh, 0, SB_USB, 0); ++ } ++ break; ++ case BCM5350_CHIP_ID: ++ /* Clear interrupt map */ ++ for (irq = 0; irq <= 4; irq++) ++ sb_clearirq(sbh, irq); ++ sb_setirq(sbh, 0, SB_CC, 0); ++ sb_setirq(sbh, 0, SB_MIPS33, 0); ++ sb_setirq(sbh, 1, SB_D11, 0); ++ sb_setirq(sbh, 2, SB_ENET, 0); ++ sb_setirq(sbh, 3, SB_PCI, 0); ++ sb_setirq(sbh, 4, SB_USB, 0); ++ break; ++ case BCM4785_CHIP_ID: ++ /* Reassign PCI to irq 4 */ ++ sb_setirq(sbh, 4, SB_PCI, 0); + break; -+#endif /* BCMJTAG */ -+ -+ default: -+ ASSERT(0); + } -+ -+ if (!GOODCOREADDR(sbaddr)) -+ return BADIDX; -+ -+ return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE); +} + -+uint -+sb_corevendor(sb_t *sbh) ++uint32 ++BCMINITFN(sb_cpu_clock)(sb_t *sbh) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate = 0; + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ pll_type = PLL_TYPE1; + -+ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); -+} ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(osh, &eir->clockcontrol_n); ++ m = R_REG(osh, &eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(osh, &cc->capabilities) & CAP_PLL_MASK; ++ n = R_REG(osh, &cc->clockcontrol_n); ++ if ((pll_type == PLL_TYPE2) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE6) || ++ (pll_type == PLL_TYPE7)) ++ m = R_REG(osh, &cc->clockcontrol_m3); ++ else if (pll_type == PLL_TYPE5) { ++ rate = 200000000; ++ goto out; ++ } ++ else if (pll_type == PLL_TYPE3) { ++ if (sb_chip(sbh) == BCM5365_CHIP_ID) { ++ rate = 200000000; ++ goto out; ++ } ++ /* 5350 uses m2 to control mips */ ++ else ++ m = R_REG(osh, &cc->clockcontrol_m2); ++ } else ++ m = R_REG(osh, &cc->clockcontrol_sb); ++ } else ++ goto out; + -+uint -+sb_corerev(sb_t *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ uint sbidh; + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); -+ sbidh = R_SBREG(si, &(sb)->sbidhigh); ++ /* calculate rate */ ++ if (BCMINIT(sb_chip)(sbh) == 0x5365) ++ rate = 100000000; ++ else ++ rate = sb_clock_rate(pll_type, n, m); + -+ return (SBCOREREV(sbidh)); -+} ++ if (pll_type == PLL_TYPE6) ++ rate = SB2MIPS_T6(rate); + -+void * -+sb_osh(sb_t *sbh) -+{ -+ sb_info_t *si; ++out: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); + -+ si = SB_INFO(sbh); -+ return si->osh; ++ return rate; +} + -+#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK) ++#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) ++ ++static void ++BCMINITFN(handler)(void) ++{ ++ __asm__( ++ ".set\tmips32\n\t" ++ "ssnop\n\t" ++ "ssnop\n\t" ++ /* Disable interrupts */ ++ /* MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~(ALLINTS | STO_IE)); */ ++ "mfc0 $15, $12\n\t" ++ /* Just a Hack to not to use reg 'at' which was causing problems on 4704 A2 */ ++ "li $14, -31746\n\t" ++ "and $15, $15, $14\n\t" ++ "mtc0 $15, $12\n\t" ++ "eret\n\t" ++ "nop\n\t" ++ "nop\n\t" ++ ".set\tmips0"); ++} + -+/* set/clear sbtmstatelow core-specific flags */ -+uint32 -+sb_coreflags(sb_t *sbh, uint32 mask, uint32 val) ++/* The following MUST come right after handler() */ ++static void ++BCMINITFN(afterhandler)(void) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ uint32 w; ++} + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++/* ++ * Set the MIPS, backplane and PCI clocks as closely as possible. ++ * ++ * MIPS clocks synchronization function has been moved from PLL in chipcommon ++ * core rev. 15 to a DLL inside the MIPS core in 4785. ++ */ ++bool ++BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock) ++{ ++ extifregs_t *eir = NULL; ++ chipcregs_t *cc = NULL; ++ mipsregs_t *mipsr = NULL; ++ volatile uint32 *clockcontrol_n, *clockcontrol_sb, *clockcontrol_pci, *clockcontrol_m2; ++ uint32 orig_n, orig_sb, orig_pci, orig_m2, orig_mips, orig_ratio_parm, orig_ratio_cfg; ++ uint32 pll_type, sync_mode; ++ uint ic_size, ic_lsize; ++ uint idx, i; + -+ ASSERT((val & ~mask) == 0); -+ ASSERT((mask & ~SBTML_ALLOW) == 0); ++ /* PLL configuration: type 1 */ ++ typedef struct { ++ uint32 mipsclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 pci25; ++ } n3m_table_t; ++ static n3m_table_t BCMINITDATA(type1_table)[] = { ++ /* 96.000 32.000 24.000 */ ++ { 96000000, 0x0303, 0x04020011, 0x11030011, 0x11050011 }, ++ /* 100.000 33.333 25.000 */ ++ { 100000000, 0x0009, 0x04020011, 0x11030011, 0x11050011 }, ++ /* 104.000 31.200 24.960 */ ++ { 104000000, 0x0802, 0x04020011, 0x11050009, 0x11090009 }, ++ /* 108.000 32.400 24.923 */ ++ { 108000000, 0x0403, 0x04020011, 0x11050009, 0x02000802 }, ++ /* 112.000 32.000 24.889 */ ++ { 112000000, 0x0205, 0x04020011, 0x11030021, 0x02000403 }, ++ /* 115.200 32.000 24.000 */ ++ { 115200000, 0x0303, 0x04020009, 0x11030011, 0x11050011 }, ++ /* 120.000 30.000 24.000 */ ++ { 120000000, 0x0011, 0x04020011, 0x11050011, 0x11090011 }, ++ /* 124.800 31.200 24.960 */ ++ { 124800000, 0x0802, 0x04020009, 0x11050009, 0x11090009 }, ++ /* 128.000 32.000 24.000 */ ++ { 128000000, 0x0305, 0x04020011, 0x11050011, 0x02000305 }, ++ /* 132.000 33.000 24.750 */ ++ { 132000000, 0x0603, 0x04020011, 0x11050011, 0x02000305 }, ++ /* 136.000 32.640 24.727 */ ++ { 136000000, 0x0c02, 0x04020011, 0x11090009, 0x02000603 }, ++ /* 140.000 30.000 24.706 */ ++ { 140000000, 0x0021, 0x04020011, 0x11050021, 0x02000c02 }, ++ /* 144.000 30.857 24.686 */ ++ { 144000000, 0x0405, 0x04020011, 0x01020202, 0x11090021 }, ++ /* 150.857 33.000 24.000 */ ++ { 150857142, 0x0605, 0x04020021, 0x02000305, 0x02000605 }, ++ /* 152.000 32.571 24.000 */ ++ { 152000000, 0x0e02, 0x04020011, 0x11050021, 0x02000e02 }, ++ /* 156.000 31.200 24.960 */ ++ { 156000000, 0x0802, 0x04020005, 0x11050009, 0x11090009 }, ++ /* 160.000 32.000 24.000 */ ++ { 160000000, 0x0309, 0x04020011, 0x11090011, 0x02000309 }, ++ /* 163.200 32.640 24.727 */ ++ { 163200000, 0x0c02, 0x04020009, 0x11090009, 0x02000603 }, ++ /* 168.000 32.000 24.889 */ ++ { 168000000, 0x0205, 0x04020005, 0x11030021, 0x02000403 }, ++ /* 176.000 33.000 24.000 */ ++ { 176000000, 0x0602, 0x04020003, 0x11050005, 0x02000602 }, ++ }; ++ ++ /* PLL configuration: type 3 */ ++ typedef struct { ++ uint32 mipsclock; ++ uint16 n; ++ uint32 m2; /* that is the clockcontrol_m2 */ ++ } type3_table_t; ++ static type3_table_t type3_table[] = { ++ /* for 5350, mips clock is always double sb clock */ ++ { 150000000, 0x311, 0x4020005 }, ++ { 200000000, 0x311, 0x4020003 }, ++ }; + -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val; -+ W_SBREG(si, &sb->sbtmstatelow, w); -+ } ++ /* PLL configuration: type 2, 4, 7 */ ++ typedef struct { ++ uint32 mipsclock; ++ uint32 sbclock; ++ uint16 n; ++ uint32 sb; ++ uint32 pci33; ++ uint32 m2; ++ uint32 m3; ++ uint32 ratio_cfg; ++ uint32 ratio_parm; ++ uint32 d11_r1; ++ uint32 d11_r2; ++ } n4m_table_t; ++ static n4m_table_t BCMINITDATA(type2_table)[] = { ++ { 120000000, 60000000, 0x0303, 0x01000200, 0x01000600, 0x01000200, 0x05000200, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 150000000, 75000000, 0x0303, 0x01000100, 0x01000600, 0x01000100, 0x05000100, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 180000000, 80000000, 0x0403, 0x01010000, 0x01020300, 0x01020600, 0x05000100, 8, ++ 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 }, ++ { 180000000, 90000000, 0x0403, 0x01000100, 0x01020300, 0x01000100, 0x05000100, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 200000000, 100000000, 0x0303, 0x02010000, 0x02040001, 0x02010000, 0x06000001, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 211200000, 105600000, 0x0902, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 220800000, 110400000, 0x1500, 0x01000200, 0x01030400, 0x01000200, 0x05000200, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 230400000, 115200000, 0x0604, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 234000000, 104000000, 0x0b01, 0x01010000, 0x01010700, 0x01020600, 0x05000100, 8, ++ 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 }, ++ { 240000000, 120000000, 0x0803, 0x01000200, 0x01020600, 0x01000200, 0x05000200, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 252000000, 126000000, 0x0504, 0x01000100, 0x01020500, 0x01000100, 0x05000100, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 264000000, 132000000, 0x0903, 0x01000200, 0x01020700, 0x01000200, 0x05000200, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 270000000, 120000000, 0x0703, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, ++ 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 }, ++ { 276000000, 122666666, 0x1500, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, ++ 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 }, ++ { 280000000, 140000000, 0x0503, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 288000000, 128000000, 0x0604, 0x01010000, 0x01030400, 0x01020600, 0x05000100, 8, ++ 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 }, ++ { 288000000, 144000000, 0x0404, 0x01000000, 0x01010600, 0x01000000, 0x05000000, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 300000000, 133333333, 0x0803, 0x01010000, 0x01020600, 0x01010100, 0x05000100, 8, ++ 0x012a00a9, 9 /* ratio 4/9 */, 0x012a00a9 }, ++ { 300000000, 150000000, 0x0803, 0x01000100, 0x01020600, 0x01010100, 0x05000100, 11, ++ 0x0aaa0555, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 330000000, 132000000, 0x0903, 0x01000200, 0x00020200, 0x01010100, 0x05000100, 0, ++ 0, 10 /* ratio 4/10 */, 0x02520129 }, ++ { 330000000, 146666666, 0x0903, 0x01010000, 0x00020200, 0x01010100, 0x05000100, 0, ++ 0, 9 /* ratio 4/9 */, 0x012a00a9 }, ++ { 330000000, 165000000, 0x0903, 0x01000100, 0x00020200, 0x01010100, 0x05000100, 0, ++ 0, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 360000000, 120000000, 0x0a03, 0x01000300, 0x00010201, 0x01010200, 0x05000100, 0, ++ 0, 12 /* ratio 4/12 */, 0x04920492 }, ++ { 360000000, 144000000, 0x0a03, 0x01000200, 0x00010201, 0x01010200, 0x05000100, 0, ++ 0, 10 /* ratio 4/10 */, 0x02520129 }, ++ { 360000000, 160000000, 0x0a03, 0x01010000, 0x00010201, 0x01010200, 0x05000100, 0, ++ 0, 9 /* ratio 4/9 */, 0x012a00a9 }, ++ { 360000000, 180000000, 0x0a03, 0x01000100, 0x00010201, 0x01010200, 0x05000100, 0, ++ 0, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ { 390000000, 130000000, 0x0b03, 0x01010100, 0x00020101, 0x01020100, 0x05000100, 0, ++ 0, 12 /* ratio 4/12 */, 0x04920492 }, ++ { 390000000, 156000000, 0x0b03, 0x01000200, 0x00020101, 0x01020100, 0x05000100, 0, ++ 0, 10 /* ratio 4/10 */, 0x02520129 }, ++ { 390000000, 173000000, 0x0b03, 0x01010000, 0x00020101, 0x01020100, 0x05000100, 0, ++ 0, 9 /* ratio 4/9 */, 0x012a00a9 }, ++ { 390000000, 195000000, 0x0b03, 0x01000100, 0x00020101, 0x01020100, 0x05000100, 0, ++ 0, 8 /* ratio 4/8 */, 0x00aa0055 }, ++ }; ++ static n4m_table_t BCMINITDATA(type4_table)[] = { ++ { 120000000, 60000000, 0x0009, 0x11020009, 0x01030203, 0x11020009, 0x04000009, 11, ++ 0x0aaa0555 }, ++ { 150000000, 75000000, 0x0009, 0x11050002, 0x01030203, 0x11050002, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 192000000, 96000000, 0x0702, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 198000000, 99000000, 0x0603, 0x11020005, 0x11030011, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0009, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, ++ 0x0aaa0555 }, ++ { 204000000, 102000000, 0x0c02, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 208000000, 104000000, 0x0802, 0x11030002, 0x11090005, 0x11030002, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 210000000, 105000000, 0x0209, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 216000000, 108000000, 0x0111, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 224000000, 112000000, 0x0205, 0x11030002, 0x02002103, 0x11030002, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 228000000, 101333333, 0x0e02, 0x11030003, 0x11210005, 0x01030305, 0x04000005, 8, ++ 0x012a00a9 }, ++ { 228000000, 114000000, 0x0e02, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 240000000, 102857143, 0x0109, 0x04000021, 0x01050203, 0x11030021, 0x04000003, 13, ++ 0x254a14a9 }, ++ { 240000000, 120000000, 0x0109, 0x11030002, 0x01050203, 0x11030002, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 252000000, 100800000, 0x0203, 0x04000009, 0x11050005, 0x02000209, 0x04000002, 9, ++ 0x02520129 }, ++ { 252000000, 126000000, 0x0203, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, ++ 0x0aaa0555 }, ++ { 264000000, 132000000, 0x0602, 0x04000005, 0x11050005, 0x04000005, 0x04000002, 11, ++ 0x0aaa0555 }, ++ { 272000000, 116571428, 0x0c02, 0x04000021, 0x02000909, 0x02000221, 0x04000003, 13, ++ 0x254a14a9 }, ++ { 280000000, 120000000, 0x0209, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, ++ 0x254a14a9 }, ++ { 288000000, 123428571, 0x0111, 0x04000021, 0x01030303, 0x02000221, 0x04000003, 13, ++ 0x254a14a9 }, ++ { 300000000, 120000000, 0x0009, 0x04000009, 0x01030203, 0x02000902, 0x04000002, 9, ++ 0x02520129 }, ++ { 300000000, 150000000, 0x0009, 0x04000005, 0x01030203, 0x04000005, 0x04000002, 11, ++ 0x0aaa0555 } ++ }; ++ static n4m_table_t BCMINITDATA(type7_table)[] = { ++ { 183333333, 91666666, 0x0605, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 187500000, 93750000, 0x0a03, 0x04000011, 0x11030011, 0x04000011, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 196875000, 98437500, 0x1003, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0311, 0x04000011, 0x11030011, 0x04000009, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 200000000, 100000000, 0x0311, 0x04020011, 0x11030011, 0x04020011, 0x04020003, 11, ++ 0x0aaa0555 }, ++ { 206250000, 103125000, 0x1103, 0x11020005, 0x11050011, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 212500000, 106250000, 0x0c05, 0x11020005, 0x01030303, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 215625000, 107812500, 0x1203, 0x11090009, 0x11050005, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 216666666, 108333333, 0x0805, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 225000000, 112500000, 0x0d03, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 233333333, 116666666, 0x0905, 0x11020003, 0x11030011, 0x11020003, 0x04000003, 11, ++ 0x0aaa0555 }, ++ { 237500000, 118750000, 0x0e05, 0x11020005, 0x11210005, 0x11020005, 0x04000005, 11, ++ 0x0aaa0555 }, ++ { 240000000, 120000000, 0x0b11, 0x11020009, 0x11210009, 0x11020009, 0x04000009, 11, ++ 0x0aaa0555 }, ++ { 250000000, 125000000, 0x0f03, 0x11020003, 0x11210003, 0x11020003, 0x04000003, 11, ++ 0x0aaa0555 } ++ }; + -+ /* return the new value */ -+ return (R_SBREG(si, &sb->sbtmstatelow) & SBTML_ALLOW); -+} ++ ulong start, end, dst; ++ bool ret = FALSE; + -+/* set/clear sbtmstatehigh core-specific flags */ -+uint32 -+sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ uint32 w; ++ volatile uint32 *dll_ctrl = (volatile uint32 *)0xff400008; ++ volatile uint32 *dll_r1 = (volatile uint32 *)0xff400010; ++ volatile uint32 *dll_r2 = (volatile uint32 *)0xff400018; + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++ /* get index of the current core */ ++ idx = sb_coreidx(sbh); ++ clockcontrol_m2 = NULL; + -+ ASSERT((val & ~mask) == 0); -+ ASSERT((mask & ~SBTMH_FL_MASK) == 0); ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ pll_type = PLL_TYPE1; ++ clockcontrol_n = &eir->clockcontrol_n; ++ clockcontrol_sb = &eir->clockcontrol_sb; ++ clockcontrol_pci = &eir->clockcontrol_pci; ++ clockcontrol_m2 = &cc->clockcontrol_m2; ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(osh, &cc->capabilities) & CAP_PLL_MASK; ++ if (pll_type == PLL_TYPE6) { ++ clockcontrol_n = NULL; ++ clockcontrol_sb = NULL; ++ clockcontrol_pci = NULL; ++ } else { ++ clockcontrol_n = &cc->clockcontrol_n; ++ clockcontrol_sb = &cc->clockcontrol_sb; ++ clockcontrol_pci = &cc->clockcontrol_pci; ++ clockcontrol_m2 = &cc->clockcontrol_m2; ++ } ++ } else ++ goto done; + -+ /* mask and set */ -+ if (mask || val) { -+ w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val; -+ W_SBREG(si, &sb->sbtmstatehigh, w); ++ if (pll_type == PLL_TYPE6) { ++ /* Silence compilers */ ++ orig_n = orig_sb = orig_pci = 0; ++ } else { ++ /* Store the current clock register values */ ++ orig_n = R_REG(osh, clockcontrol_n); ++ orig_sb = R_REG(osh, clockcontrol_sb); ++ orig_pci = R_REG(osh, clockcontrol_pci); + } + -+ /* return the new value */ -+ return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK); -+} -+ -+/* caller needs to take care of core-specific bist hazards */ -+int -+sb_corebist(sb_t *sbh, uint coreid, uint coreunit) -+{ -+ uint32 sblo; -+ uint coreidx; -+ sb_info_t *si; -+ int result = 0; ++ if (pll_type == PLL_TYPE1) { ++ /* Keep the current PCI clock if not specified */ ++ if (pciclock == 0) { ++ pciclock = sb_clock_rate(pll_type, R_REG(osh, clockcontrol_n), ++ R_REG(osh, clockcontrol_pci)); ++ pciclock = (pciclock <= 25000000) ? 25000000 : 33000000; ++ } + -+ si = SB_INFO(sbh); ++ /* Search for the closest MIPS clock less than or equal to a preferred value */ ++ for (i = 0; i < ARRAYSIZE(type1_table); i++) { ++ ASSERT(type1_table[i].mipsclock == ++ sb_clock_rate(pll_type, type1_table[i].n, ++ type1_table[i].sb)); ++ if (type1_table[i].mipsclock > mipsclock) ++ break; ++ } ++ if (i == 0) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ i--; ++ } ++ ASSERT(type1_table[i].mipsclock <= mipsclock); + -+ coreidx = sb_findcoreidx(si, coreid, coreunit); -+ if (!GOODIDX(coreidx)) -+ result = BCME_ERROR; -+ else { -+ sblo = sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), 0, 0); -+ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, (sblo | SBTML_FGC | SBTML_BE)); -+ -+ SPINWAIT(((sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTD) == 0), 100000); -+ -+ if (sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatehigh), 0, 0) & SBTMH_BISTF) -+ result = BCME_ERROR; ++ /* No PLL change */ ++ if ((orig_n == type1_table[i].n) && ++ (orig_sb == type1_table[i].sb) && ++ (orig_pci == type1_table[i].pci33)) ++ goto done; + -+ sb_corereg(si, coreidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbtmstatelow), ~0, sblo); -+ } ++ /* Set the PLL controls */ ++ W_REG(osh, clockcontrol_n, type1_table[i].n); ++ W_REG(osh, clockcontrol_sb, type1_table[i].sb); ++ if (pciclock == 25000000) ++ W_REG(osh, clockcontrol_pci, type1_table[i].pci25); ++ else ++ W_REG(osh, clockcontrol_pci, type1_table[i].pci33); + -+ return result; -+} ++ /* Reset */ ++ sb_watchdog(sbh, 1); ++ while (1); ++ } else if (pll_type == PLL_TYPE3) { ++ /* 5350 */ ++ if (sb_chip(sbh) != BCM5365_CHIP_ID) { ++ /* ++ * Search for the closest MIPS clock less than or equal to ++ * a preferred value. ++ */ ++ for (i = 0; i < ARRAYSIZE(type3_table); i++) { ++ if (type3_table[i].mipsclock > mipsclock) ++ break; ++ } ++ if (i == 0) { ++ ret = FALSE; ++ goto done; ++ } else { ++ ret = TRUE; ++ i--; ++ } ++ ASSERT(type3_table[i].mipsclock <= mipsclock); + -+bool -+sb_iscoreup(sb_t *sbh) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; ++ /* No PLL change */ ++ orig_m2 = R_REG(osh, &cc->clockcontrol_m2); ++ if ((orig_n == type3_table[i].n) && ++ (orig_m2 == type3_table[i].m2)) { ++ goto done; ++ } + -+ si = SB_INFO(sbh); -+ sb = REGS2SB(si->curmap); ++ /* Set the PLL controls */ ++ W_REG(osh, clockcontrol_n, type3_table[i].n); ++ W_REG(osh, clockcontrol_m2, type3_table[i].m2); + -+ return ((R_SBREG(si, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK); -+} ++ /* Reset */ ++ sb_watchdog(sbh, 1); ++ while (1); ++ } ++ } else if ((pll_type == PLL_TYPE2) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE6) || ++ (pll_type == PLL_TYPE7)) { ++ n4m_table_t *table = NULL, *te; ++ uint tabsz = 0; + -+/* -+ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, -+ * switch back to the original core, and return the new value. -+ */ -+static uint -+sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val) -+{ -+ uint origidx; -+ uint32 *r; -+ uint w; -+ uint intr_val = 0; ++ ASSERT(cc); + -+ ASSERT(GOODIDX(coreidx)); -+ ASSERT(regoff < SB_CORE_SIZE); -+ ASSERT((val & ~mask) == 0); ++ orig_mips = R_REG(osh, &cc->clockcontrol_m3); + -+ INTR_OFF(si, intr_val); ++ switch (pll_type) { ++ case PLL_TYPE6: { ++ uint32 new_mips = 0; + -+ /* save current core index */ -+ origidx = sb_coreidx(&si->sb); ++ ret = TRUE; ++ if (mipsclock <= SB2MIPS_T6(CC_T6_M1)) ++ new_mips = CC_T6_MMASK; + -+ /* switch core */ -+ r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff); ++ if (orig_mips == new_mips) ++ goto done; + -+ /* mask and set */ -+ if (mask || val) { -+ if (regoff >= SBCONFIGOFF) { -+ w = (R_SBREG(si, r) & ~mask) | val; -+ W_SBREG(si, r, w); -+ } else { -+ w = (R_REG(r) & ~mask) | val; -+ W_REG(r, w); ++ W_REG(osh, &cc->clockcontrol_m3, new_mips); ++ goto end_fill; ++ } ++ case PLL_TYPE2: ++ table = type2_table; ++ tabsz = ARRAYSIZE(type2_table); ++ break; ++ case PLL_TYPE4: ++ table = type4_table; ++ tabsz = ARRAYSIZE(type4_table); ++ break; ++ case PLL_TYPE7: ++ table = type7_table; ++ tabsz = ARRAYSIZE(type7_table); ++ break; ++ default: ++ ASSERT("No table for plltype" == NULL); ++ break; + } -+ } + -+ /* readback */ -+ if (regoff >= SBCONFIGOFF) -+ w = R_SBREG(si, r); -+ else -+ w = R_REG(r); ++ /* Store the current clock register values */ ++ orig_m2 = R_REG(osh, &cc->clockcontrol_m2); ++ orig_ratio_parm = 0; ++ orig_ratio_cfg = 0; + -+ /* restore core index */ -+ if (origidx != coreidx) -+ sb_setcoreidx(&si->sb, origidx); ++ /* Look up current ratio */ ++ for (i = 0; i < tabsz; i++) { ++ if ((orig_n == table[i].n) && ++ (orig_sb == table[i].sb) && ++ (orig_pci == table[i].pci33) && ++ (orig_m2 == table[i].m2) && ++ (orig_mips == table[i].m3)) { ++ orig_ratio_parm = table[i].ratio_parm; ++ orig_ratio_cfg = table[i].ratio_cfg; ++ break; ++ } ++ } + -+ INTR_RESTORE(si, intr_val); -+ return (w); -+} ++ /* Search for the closest MIPS clock greater or equal to a preferred value */ ++ for (i = 0; i < tabsz; i++) { ++ ASSERT(table[i].mipsclock == ++ sb_clock_rate(pll_type, table[i].n, table[i].m3)); ++ if ((mipsclock <= table[i].mipsclock) && ++ ((sbclock == 0) || (sbclock <= table[i].sbclock))) ++ break; ++ } ++ if (i == tabsz) { ++ ret = FALSE; ++ goto done; ++ } else { ++ te = &table[i]; ++ ret = TRUE; ++ } + -+#define DWORD_ALIGN(x) (x & ~(0x03)) -+#define BYTE_POS(x) (x & 0x3) -+#define WORD_POS(x) (x & 0x1) ++ /* No PLL change */ ++ if ((orig_n == te->n) && ++ (orig_sb == te->sb) && ++ (orig_pci == te->pci33) && ++ (orig_m2 == te->m2) && ++ (orig_mips == te->m3)) ++ goto done; + -+#define BYTE_SHIFT(x) (8 * BYTE_POS(x)) -+#define WORD_SHIFT(x) (16 * WORD_POS(x)) ++ /* Set the PLL controls */ ++ W_REG(osh, clockcontrol_n, te->n); ++ W_REG(osh, clockcontrol_sb, te->sb); ++ W_REG(osh, clockcontrol_pci, te->pci33); ++ W_REG(osh, &cc->clockcontrol_m2, te->m2); ++ W_REG(osh, &cc->clockcontrol_m3, te->m3); + -+#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF) -+#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF) ++ /* Set the chipcontrol bit to change mipsref to the backplane divider if needed */ ++ if ((pll_type == PLL_TYPE7) && (te->sb != te->m2) && ++ (sb_clock_rate(pll_type, te->n, te->m2) == 120000000)) ++ W_REG(osh, &cc->chipcontrol, ++ R_REG(osh, &cc->chipcontrol) | 0x100); + -+#define read_pci_cfg_byte(a) \ -+ (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff) ++ /* No ratio change */ ++ if (sb_chip(sbh) != BCM4785_CHIP_ID) { ++ if (orig_ratio_parm == te->ratio_parm) ++ goto end_fill; ++ } + -+#define read_pci_cfg_write(a) \ -+ (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff) ++ /* Preload the code into the cache */ ++ icache_probe(MFC0(C0_CONFIG, 1), &ic_size, &ic_lsize); ++ if (sb_chip(sbh) == BCM4785_CHIP_ID) { ++ start = ((ulong) &&start_fill_4785) & ~(ic_lsize - 1); ++ end = ((ulong) &&end_fill_4785 + (ic_lsize - 1)) & ~(ic_lsize - 1); ++ } ++ else { ++ start = ((ulong) &&start_fill) & ~(ic_lsize - 1); ++ end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1); ++ } ++ while (start < end) { ++ cache_op(start, Fill_I); ++ start += ic_lsize; ++ } + ++ /* Copy the handler */ ++ start = (ulong) &handler; ++ end = (ulong) &afterhandler; ++ dst = KSEG1ADDR(0x180); ++ for (i = 0; i < (end - start); i += 4) ++ *((ulong *)(dst + i)) = *((ulong *)(start + i)); + -+/* return TRUE if requested capability exists in the PCI config space */ -+static bool -+sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen) -+{ -+ uint8 cap_id; -+ uint8 cap_ptr; -+ uint32 bufsize; -+ uint8 byte_val; ++ /* Preload the handler into the cache one line at a time */ ++ for (i = 0; i < (end - start); i += ic_lsize) ++ cache_op(dst + i, Fill_I); + -+ if (BUSTYPE(si->sb.bustype) != PCI_BUS) -+ return FALSE; ++ /* Clear BEV bit */ ++ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV); + -+ /* check for Header type 0*/ -+ byte_val = read_pci_cfg_byte(PCI_CFG_HDR); -+ if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) -+ return FALSE; ++ /* Enable interrupts */ ++ MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) | (ALLINTS | ST0_IE)); + -+ /* check if the capability pointer field exists */ -+ byte_val = read_pci_cfg_byte(PCI_CFG_STAT); -+ if (!(byte_val & PCI_CAPPTR_PRESENT)) -+ return FALSE; ++ /* 4785 clock freq change procedures */ ++ if (sb_chip(sbh) == BCM4785_CHIP_ID) { ++ start_fill_4785: ++ /* Switch to async */ ++ MTC0(C0_BROADCOM, 4, (1 << 22)); + -+ cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR); -+ /* check if the capability pointer is 0x00 */ -+ if (cap_ptr == 0x00) -+ return FALSE; ++ /* Set clock ratio in MIPS */ ++ *dll_r1 = (*dll_r1 & 0xfffffff0) | (te->d11_r1 - 1); ++ *dll_r2 = te->d11_r2; + ++ /* Enable new settings in MIPS */ ++ *dll_r1 = *dll_r1 | 0xc0000000; + -+ /* loop thr'u the capability list and see if the pcie capabilty exists */ ++ /* Set active cfg */ ++ MTC0(C0_BROADCOM, 2, MFC0(C0_BROADCOM, 2) | (1 << 3) | 1); + -+ cap_id = read_pci_cfg_byte(cap_ptr); ++ /* Fake soft reset (clock cfg registers not reset) */ ++ MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | (1 << 2)); + -+ while (cap_id != req_cap_id) { -+ cap_ptr = read_pci_cfg_byte((cap_ptr+1)); -+ if (cap_ptr == 0x00) break; -+ cap_id = read_pci_cfg_byte(cap_ptr); -+ } -+ if (cap_id != req_cap_id) { -+ return FALSE; -+ } -+ /* found the caller requested capability */ -+ if ((buf != NULL) && (buflen != NULL)) { -+ bufsize = *buflen; -+ if (!bufsize) goto end; -+ *buflen = 0; -+ /* copy the cpability data excluding cap ID and next ptr */ -+ cap_ptr += 2; -+ if ((bufsize + cap_ptr) > SZPCR) -+ bufsize = SZPCR - cap_ptr; -+ *buflen = bufsize; -+ while (bufsize--) { -+ *buf = read_pci_cfg_byte(cap_ptr); -+ cap_ptr++; -+ buf++; -+ } -+ } -+end: -+ return TRUE; -+} ++ /* Clear active cfg */ ++ MTC0(C0_BROADCOM, 2, MFC0(C0_BROADCOM, 2) & ~(1 << 3)); + -+/* return TRUE if PCIE capability exists the pci config space */ -+static bool -+sb_ispcie(sb_info_t *si) -+{ -+ return(sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL)); -+} ++ /* set watchdog timer */ ++ W_REG(osh, &cc->watchdog, 20); ++ (void) R_REG(osh, &cc->chipid); + -+/* scan the sb enumerated space to identify all cores */ -+static void -+BCMINITFN(sb_scan)(sb_info_t *si) -+{ -+ uint origidx; -+ uint i; -+ bool pci; -+ bool pcie; -+ uint pciidx; -+ uint pcieidx; -+ uint pcirev; -+ uint pcierev; ++ /* wait for timer interrupt */ ++ __asm__ __volatile__( ++ ".set\tmips3\n\t" ++ "sync\n\t" ++ "wait\n\t" ++ ".set\tmips0"); ++ end_fill_4785: ++ while (1); ++ } ++ /* Generic clock freq change procedures */ ++ else { ++ /* Enable MIPS timer interrupt */ ++ if (!(mipsr = sb_setcore(sbh, SB_MIPS, 0)) && ++ !(mipsr = sb_setcore(sbh, SB_MIPS33, 0))) ++ ASSERT(mipsr); ++ W_REG(osh, &mipsr->intmask, 1); + ++ start_fill: ++ /* step 1, set clock ratios */ ++ MTC0(C0_BROADCOM, 3, te->ratio_parm); ++ MTC0(C0_BROADCOM, 1, te->ratio_cfg); + ++ /* step 2: program timer intr */ ++ W_REG(osh, &mipsr->timer, 100); ++ (void) R_REG(osh, &mipsr->timer); + -+ /* numcores should already be set */ -+ ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); ++ /* step 3, switch to async */ ++ sync_mode = MFC0(C0_BROADCOM, 4); ++ MTC0(C0_BROADCOM, 4, 1 << 22); + -+ /* save current core index */ -+ origidx = sb_coreidx(&si->sb); ++ /* step 4, set cfg active */ ++ MTC0(C0_BROADCOM, 2, (1 << 3) | 1); + -+ si->sb.buscorerev = NOREV; -+ si->sb.buscoreidx = BADIDX; ++ /* steps 5 & 6 */ ++ __asm__ __volatile__( ++ ".set\tmips3\n\t" ++ "wait\n\t" ++ ".set\tmips0"); + -+ si->gpioidx = BADIDX; ++ /* step 7, clear cfg active */ ++ MTC0(C0_BROADCOM, 2, 0); + -+ pci = pcie = FALSE; -+ pcirev = pcierev = NOREV; -+ pciidx = pcieidx = BADIDX; ++ /* Additional Step: set back to orig sync mode */ ++ MTC0(C0_BROADCOM, 4, sync_mode); + -+ for (i = 0; i < si->numcores; i++) { -+ sb_setcoreidx(&si->sb, i); -+ si->coreid[i] = sb_coreid(&si->sb); ++ /* step 8, fake soft reset */ ++ MTC0(C0_BROADCOM, 5, MFC0(C0_BROADCOM, 5) | (1 << 2)); + -+ if (si->coreid[i] == SB_PCI) { -+ pciidx = i; -+ pcirev = sb_corerev(&si->sb); -+ pci = TRUE; -+ } else if (si->coreid[i] == SB_PCIE) { -+ pcieidx = i; -+ pcierev = sb_corerev(&si->sb); -+ pcie = TRUE; -+ } else if (si->coreid[i] == SB_PCMCIA) { -+ si->sb.buscorerev = sb_corerev(&si->sb); -+ si->sb.buscoretype = si->coreid[i]; -+ si->sb.buscoreidx = i; ++ end_fill: ++ /* set watchdog timer */ ++ W_REG(osh, &cc->watchdog, 20); ++ (void) R_REG(osh, &cc->chipid); ++ ++ /* wait for timer interrupt */ ++ __asm__ __volatile__( ++ ".set\tmips3\n\t" ++ "sync\n\t" ++ "wait\n\t" ++ ".set\tmips0"); ++ while (1); + } + } -+ if (pci && pcie) { -+ if (sb_ispcie(si)) -+ pci = FALSE; -+ else -+ pcie = FALSE; -+ } -+ if (pci) { -+ si->sb.buscoretype = SB_PCI; -+ si->sb.buscorerev = pcirev; -+ si->sb.buscoreidx = pciidx; -+ } -+ else if (pcie) { -+ si->sb.buscoretype = SB_PCIE; -+ si->sb.buscorerev = pcierev; -+ si->sb.buscoreidx = pcieidx; -+ } + -+ /* -+ * Find the gpio "controlling core" type and index. -+ * Precedence: -+ * - if there's a chip common core - use that -+ * - else if there's a pci core (rev >= 2) - use that -+ * - else there had better be an extif core (4710 only) -+ */ -+ if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) { -+ si->gpioidx = sb_findcoreidx(si, SB_CC, 0); -+ si->gpioid = SB_CC; -+ } else if (PCI(si) && (si->sb.buscorerev >= 2)) { -+ si->gpioidx = si->sb.buscoreidx; -+ si->gpioid = SB_PCI; -+ } else if (sb_findcoreidx(si, SB_EXTIF, 0)) { -+ si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0); -+ si->gpioid = SB_EXTIF; -+ } else -+ ASSERT(si->gpioidx != BADIDX); ++done: ++ /* Enable 4785 DLL */ ++ if (sb_chip(sbh) == BCM4785_CHIP_ID) { ++ uint32 tmp; + -+ /* return to original core index */ -+ sb_setcoreidx(&si->sb, origidx); -+} ++ /* set mask to 1e, enable DLL (bit 0) */ ++ *dll_ctrl |= 0x0041e021; + -+/* may be called with core in reset */ -+void -+sb_detach(sb_t *sbh) -+{ -+ sb_info_t *si; -+ uint idx; ++ /* enable aggressive hardware mode */ ++ *dll_ctrl |= 0x00000080; + -+ si = SB_INFO(sbh); ++ /* wait for lock flag to clear */ ++ while ((*dll_ctrl & 0x2) == 0); + -+ if (si == NULL) -+ return; ++ /* clear sticky flags (clear on write 1) */ ++ tmp = *dll_ctrl; ++ *dll_ctrl = tmp; + -+ if (BUSTYPE(si->sb.bustype) == SB_BUS) -+ for (idx = 0; idx < SB_MAXCORES; idx++) -+ if (si->regs[idx]) { -+ REG_UNMAP(si->regs[idx]); -+ si->regs[idx] = NULL; -+ } ++ /* set mask to 5b'10001 */ ++ *dll_ctrl = (*dll_ctrl & 0xfffc1fff) | 0x00022000; + -+ if (si != &ksi) -+ MFREE(si->osh, si, sizeof (sb_info_t)); -+} ++ /* enable sync mode */ ++ MTC0(C0_BROADCOM, 4, MFC0(C0_BROADCOM, 4) & 0xfe3fffff); ++ (void)MFC0(C0_BROADCOM, 4); ++ } + -+/* use pci dev id to determine chip id for chips not having a chipcommon core */ -+static uint -+BCMINITFN(sb_pcidev2chip)(uint pcidev) -+{ -+ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) -+ return (BCM4710_DEVICE_ID); -+ if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID)) -+ return (BCM4402_DEVICE_ID); -+ if (pcidev == BCM4401_ENET_ID) -+ return (BCM4402_DEVICE_ID); -+ if ((pcidev >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID)) -+ return (BCM4307_DEVICE_ID); -+ if (pcidev == BCM4301_DEVICE_ID) -+ return (BCM4301_DEVICE_ID); ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); + -+ return (0); ++ return ret; +} + -+/* convert chip number to number of i/o cores */ -+static uint -+BCMINITFN(sb_chip2numcores)(uint chip) ++void ++BCMINITFN(enable_pfc)(uint32 mode) +{ -+ if (chip == BCM4710_DEVICE_ID) -+ return (9); -+ if (chip == BCM4402_DEVICE_ID) -+ return (3); -+ if ((chip == BCM4301_DEVICE_ID) || (chip == BCM4307_DEVICE_ID)) -+ return (5); -+ if (chip == BCM4306_DEVICE_ID) /* < 4306c0 */ -+ return (6); -+ if (chip == BCM4704_DEVICE_ID) -+ return (9); -+ if (chip == BCM5365_DEVICE_ID) -+ return (7); ++ ulong start, end; ++ uint ic_size, ic_lsize; + -+ SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); -+ ASSERT(0); -+ return (1); -+} ++ /* If auto then choose the correct mode for this ++ * platform, currently we only ever select one mode ++ */ ++ if (mode == PFC_AUTO) ++ mode = PFC_INST; + -+/* return index of coreid or BADIDX if not found */ -+static uint -+sb_findcoreidx( sb_info_t *si, uint coreid, uint coreunit) -+{ -+ uint found; -+ uint i; ++ icache_probe(MFC0(C0_CONFIG, 1), &ic_size, &ic_lsize); + -+ found = 0; ++ /* enable prefetch cache if available */ ++ if (MFC0(C0_BROADCOM, 0) & BRCM_PFC_AVAIL) { ++ start = ((ulong) &&setpfc_start) & ~(ic_lsize - 1); ++ end = ((ulong) &&setpfc_end + (ic_lsize - 1)) & ~(ic_lsize - 1); + -+ for (i = 0; i < si->numcores; i++) -+ if (si->coreid[i] == coreid) { -+ if (found == coreunit) -+ return (i); -+ found++; ++ /* Preload setpfc code into the cache one line at a time */ ++ while (start < end) { ++ cache_op(start, Fill_I); ++ start += ic_lsize; + } + -+ return (BADIDX); ++ /* Now set the pfc */ ++ setpfc_start: ++ /* write range */ ++ *(volatile uint32 *)PFC_CR1 = 0xffff0000; ++ ++ /* enable */ ++ *(volatile uint32 *)PFC_CR0 = mode; ++ setpfc_end: ++ /* Compiler foder */ ++ ic_size = 0; ++ } +} + -+/* -+ * this function changes logical "focus" to the indiciated core, -+ * must be called with interrupt off. -+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core -+ */ -+void* -+sb_setcoreidx(sb_t *sbh, uint coreidx) ++/* returns the ncdl value to be programmed into sdram_ncdl for calibration */ ++uint32 ++BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh) +{ -+ sb_info_t *si; -+ uint32 sbaddr; -+ uint8 tmp; -+ -+ si = SB_INFO(sbh); -+ -+ if (coreidx >= si->numcores) -+ return (NULL); -+ -+ /* -+ * If the user has provided an interrupt mask enabled function, -+ * then assert interrupts are disabled before switching the core. -+ */ -+ ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg)); ++ osl_t *osh; ++ sbmemcregs_t *memc; ++ uint32 ret = 0; ++ uint32 config, rd, wr, misc, dqsg, cd, sm, sd; ++ uint idx, rev; + -+ sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); ++ osh = sb_osh(sbh); + -+ switch (BUSTYPE(si->sb.bustype)) { -+ case SB_BUS: -+ /* map new one */ -+ if (!si->regs[coreidx]) { -+ si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); -+ ASSERT(GOODREGS(si->regs[coreidx])); -+ } -+ si->curmap = si->regs[coreidx]; -+ break; ++ idx = sb_coreidx(sbh); + -+ case PCI_BUS: -+ /* point bar0 window */ -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); -+ break; ++ memc = (sbmemcregs_t *)sb_setcore(sbh, SB_MEMC, 0); ++ if (memc == 0) ++ goto out; + -+ case PCMCIA_BUS: -+ tmp = (sbaddr >> 12) & 0x0f; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); -+ tmp = (sbaddr >> 16) & 0xff; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); -+ tmp = (sbaddr >> 24) & 0xff; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); -+ break; -+#ifdef BCMJTAG -+ case JTAG_BUS: -+ /* map new one */ -+ if (!si->regs[coreidx]) { -+ si->regs[coreidx] = (void *)sbaddr; -+ ASSERT(GOODREGS(si->regs[coreidx])); -+ } -+ si->curmap = si->regs[coreidx]; -+ break; -+#endif /* BCMJTAG */ ++ rev = sb_corerev(sbh); ++ ++ config = R_REG(osh, &memc->config); ++ wr = R_REG(osh, &memc->wrncdlcor); ++ rd = R_REG(osh, &memc->rdncdlcor); ++ misc = R_REG(osh, &memc->miscdlyctl); ++ dqsg = R_REG(osh, &memc->dqsgatencdl); ++ ++ rd &= MEMC_RDNCDLCOR_RD_MASK; ++ wr &= MEMC_WRNCDLCOR_WR_MASK; ++ dqsg &= MEMC_DQSGATENCDL_G_MASK; ++ ++ if (config & MEMC_CONFIG_DDR) { ++ ret = (wr << 16) | (rd << 8) | dqsg; ++ } else { ++ if (rev > 0) ++ cd = rd; ++ else ++ cd = (rd == MEMC_CD_THRESHOLD) ? rd : (wr + MEMC_CD_THRESHOLD); ++ sm = (misc & MEMC_MISC_SM_MASK) >> MEMC_MISC_SM_SHIFT; ++ sd = (misc & MEMC_MISC_SD_MASK) >> MEMC_MISC_SD_SHIFT; ++ ret = (sm << 16) | (sd << 8) | cd; + } + -+ si->curidx = coreidx; ++out: ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); + -+ return (si->curmap); ++ return ret; +} + -+/* -+ * this function changes logical "focus" to the indiciated core, -+ * must be called with interrupt off. -+ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++#if defined(BCMPERFSTATS) ++/* ++ * CP0 Register 25 supports 4 semi-independent 32bit performance counters. ++ * $25 select 0, 1, 2, and 3 are the counters. The counters *decrement* (who thought this one up?) ++ * $25 select 4 and 5 each contain 2-16bit control fields, one for each of the 4 counters ++ * $25 select 6 is the global perf control register. + */ -+void* -+sb_setcore(sb_t *sbh, uint coreid, uint coreunit) -+{ -+ sb_info_t *si; -+ uint idx; -+ -+ si = SB_INFO(sbh); -+ idx = sb_findcoreidx(si, coreid, coreunit); -+ if (!GOODIDX(idx)) -+ return (NULL); ++/* enable and start instruction counting */ + -+ return (sb_setcoreidx(sbh, idx)); ++void ++hndmips_perf_instrcount_enable() ++{ ++ MTC0(C0_PERFORMANCE, 6, 0x80000200); /* global enable perf counters */ ++ MTC0(C0_PERFORMANCE, 4, ++ 0x8044 | MFC0(C0_PERFORMANCE, 4)); /* enable instruction counting for counter 0 */ ++ MTC0(C0_PERFORMANCE, 0, 0); /* zero counter zero */ +} + -+/* return chip number */ -+uint -+BCMINITFN(sb_chip)(sb_t *sbh) ++/* enable and start I$ hit and I$ miss counting */ ++void ++hndmips_perf_icachecount_enable(void) +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->sb.chip); ++ MTC0(C0_PERFORMANCE, 6, 0x80000218); /* enable I$ counting */ ++ MTC0(C0_PERFORMANCE, 4, 0x80148018); /* count I$ hits in cntr 0 and misses in cntr 1 */ ++ MTC0(C0_PERFORMANCE, 0, 0); /* zero counter 0 - # I$ hits */ ++ MTC0(C0_PERFORMANCE, 1, 0); /* zero counter 1 - # I$ misses */ +} + -+/* return chip revision number */ -+uint -+BCMINITFN(sb_chiprev)(sb_t *sbh) ++/* enable and start D$ hit and I$ miss counting */ ++void ++hndmips_perf_dcachecount_enable(void) +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->sb.chiprev); ++ MTC0(C0_PERFORMANCE, 6, 0x80000211); /* enable D$ counting */ ++ MTC0(C0_PERFORMANCE, 4, 0x80248028); /* count D$ hits in cntr 0 and misses in cntr 1 */ ++ MTC0(C0_PERFORMANCE, 0, 0); /* zero counter 0 - # D$ hits */ ++ MTC0(C0_PERFORMANCE, 1, 0); /* zero counter 1 - # D$ misses */ +} + -+/* return chip common revision number */ -+uint -+BCMINITFN(sb_chipcrev)(sb_t *sbh) ++void ++hndmips_perf_icache_miss_enable() +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->sb.ccrev); ++ MTC0(C0_PERFORMANCE, 4, ++ 0x80140000 | MFC0(C0_PERFORMANCE, 4)); /* enable cache misses counting for counter 1 */ ++ MTC0(C0_PERFORMANCE, 1, 0); /* zero counter one */ +} + -+/* return chip package option */ -+uint -+BCMINITFN(sb_chippkg)(sb_t *sbh) -+{ -+ sb_info_t *si; + -+ si = SB_INFO(sbh); -+ return (si->sb.chippkg); ++void ++hndmips_perf_icache_hit_enable() ++{ ++ MTC0(C0_PERFORMANCE, 5, 0x8018 | MFC0(C0_PERFORMANCE, 5)); ++ /* enable cache hits counting for counter 2 */ ++ MTC0(C0_PERFORMANCE, 2, 0); /* zero counter 2 */ +} + -+/* return PCI core rev. */ -+uint -+BCMINITFN(sb_pcirev)(sb_t *sbh) ++uint32 ++hndmips_perf_read_instrcount() +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ return (si->sb.buscorerev); ++ return -(long)(MFC0(C0_PERFORMANCE, 0)); +} + -+bool -+BCMINITFN(sb_war16165)(sb_t *sbh) ++uint32 ++hndmips_perf_read_cache_miss() +{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ -+ return (PCI(si) && (si->sb.buscorerev <= 10)); ++ return -(long)(MFC0(C0_PERFORMANCE, 1)); +} + -+static void -+BCMINITFN(sb_war30841)(sb_info_t *si) ++uint32 ++hndmips_perf_read_cache_hit() +{ -+ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); -+ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); -+ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); ++ return -(long)(MFC0(C0_PERFORMANCE, 2)); +} + -+/* return PCMCIA core rev. */ -+uint -+BCMINITFN(sb_pcmciarev)(sb_t *sbh) -+{ -+ sb_info_t *si; ++#endif /* BCMINTERNAL | BCMPERFSTATS */ +diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpci.c +--- linux.old/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/sbpci.c 2006-05-02 17:37:13.000000000 +0200 +@@ -0,0 +1,768 @@ ++/* ++ * Low-Level PCI and SB support for BCM47xx ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: hndpci.c,v 1.1.1.3 2006/04/08 06:13:39 honor Exp $ ++ */ + -+ si = SB_INFO(sbh); -+ return (si->sb.buscorerev); -+} ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+/* return board vendor id */ -+uint -+BCMINITFN(sb_boardvendor)(sb_t *sbh) -+{ -+ sb_info_t *si; ++/* debug/trace */ ++#ifdef BCMDBG_PCI ++#define PCI_MSG(args) printf args ++#else ++#define PCI_MSG(args) ++#endif /* BCMDBG_PCI */ + -+ si = SB_INFO(sbh); -+ return (si->sb.boardvendor); -+} ++/* Can free sbpci_init() memory after boot */ ++#ifndef linux ++#define __init ++#endif /* linux */ + -+/* return boardtype */ -+uint -+BCMINITFN(sb_boardtype)(sb_t *sbh) ++/* Emulated configuration space */ ++typedef struct { ++ int n; ++ uint size0; ++ uint size1; ++ uint size2; ++ uint size3; ++} sb_bar_cfg_t; ++static pci_config_regs sb_config_regs[SB_MAXCORES]; ++static sb_bar_cfg_t sb_bar_cfg[SB_MAXCORES]; ++ ++/* Links to emulated and real PCI configuration spaces */ ++#define MAXFUNCS 2 ++typedef struct { ++ pci_config_regs *emu; /* emulated PCI config */ ++ pci_config_regs *pci; /* real PCI config */ ++ sb_bar_cfg_t *bar; /* region sizes */ ++} sb_pci_cfg_t; ++static sb_pci_cfg_t sb_pci_cfg[SB_MAXCORES][MAXFUNCS]; ++ ++/* Special emulated config space for non-existing device */ ++static pci_config_regs sb_pci_null = { 0xffff, 0xffff }; ++ ++/* Banned cores */ ++static uint16 pci_ban[SB_MAXCORES] = { 0 }; ++static uint pci_banned = 0; ++ ++/* CardBus mode */ ++static bool cardbus = FALSE; ++ ++/* Disable PCI host core */ ++static bool pci_disabled = FALSE; ++ ++/* Host bridge slot #, default to 0 */ ++static uint8 pci_hbslot = 0; ++ ++/* Internal macros */ ++#define PCI_SLOTAD_MAP 16 /* SLOT mapps to AD */ ++#define PCI_HBSBCFG_REV 8 /* MIN. core rev. required to ++ * access host bridge PCI cfg space ++ * from SB ++ */ ++ ++/* ++ * Functions for accessing external PCI configuration space ++ */ ++ ++/* Assume one-hot slot wiring */ ++#define PCI_SLOT_MAX 16 /* Max. PCI Slots */ ++ ++static uint32 ++config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off) +{ -+ sb_info_t *si; -+ char *var; ++ uint coreidx; ++ sbpciregs_t *regs; ++ uint32 addr = 0; ++ osl_t *osh; + -+ si = SB_INFO(sbh); ++ /* CardBusMode supports only one device */ ++ if (cardbus && dev > 1) ++ return 0; + -+ if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) { -+ /* boardtype format is a hex string */ -+ si->sb.boardtype = getintvar(NULL, "boardtype"); ++ osh = sb_osh(sbh); + -+ /* backward compatibility for older boardtype string format */ -+ if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) { -+ if (!strcmp(var, "bcm94710dev")) -+ si->sb.boardtype = BCM94710D_BOARD; -+ else if (!strcmp(var, "bcm94710ap")) -+ si->sb.boardtype = BCM94710AP_BOARD; -+ else if (!strcmp(var, "bu4710")) -+ si->sb.boardtype = BU4710_BOARD; -+ else if (!strcmp(var, "bcm94702mn")) -+ si->sb.boardtype = BCM94702MN_BOARD; -+ else if (!strcmp(var, "bcm94710r1")) -+ si->sb.boardtype = BCM94710R1_BOARD; -+ else if (!strcmp(var, "bcm94710r4")) -+ si->sb.boardtype = BCM94710R4_BOARD; -+ else if (!strcmp(var, "bcm94702cpci")) -+ si->sb.boardtype = BCM94702CPCI_BOARD; -+ else if (!strcmp(var, "bcm95380_rr")) -+ si->sb.boardtype = BCM95380RR_BOARD; ++ coreidx = sb_coreidx(sbh); ++ regs = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0); ++ ++ /* Type 0 transaction */ ++ if (bus == 1) { ++ /* Skip unwired slots */ ++ if (dev < PCI_SLOT_MAX) { ++ uint32 win; ++ ++ /* Slide the PCI window to the appropriate slot */ ++ win = (SBTOPCI_CFG0 | ((1 << (dev + PCI_SLOTAD_MAP)) & SBTOPCI1_MASK)); ++ W_REG(osh, ®s->sbtopci1, win); ++ addr = SB_PCI_CFG | ++ ((1 << (dev + PCI_SLOTAD_MAP)) & ~SBTOPCI1_MASK) | ++ (func << PCICFG_FUN_SHIFT) | ++ (off & ~3); + } ++ } else { ++ /* Type 1 transaction */ ++ W_REG(osh, ®s->sbtopci1, SBTOPCI_CFG1); ++ addr = SB_PCI_CFG | ++ (bus << PCICFG_BUS_SHIFT) | ++ (dev << PCICFG_SLOT_SHIFT) | ++ (func << PCICFG_FUN_SHIFT) | ++ (off & ~3); ++ } ++ ++ sb_setcoreidx(sbh, coreidx); ++ ++ return addr; ++} ++ ++/* ++ * Read host bridge PCI config registers from Silicon Backplane (>=rev8). ++ * ++ * It returns TRUE to indicate that access to the host bridge's pci config ++ * from SB is ok, and values in 'addr' and 'val' are valid. ++ * ++ * It can only read registers at multiple of 4-bytes. Callers must pick up ++ * needed bytes from 'val' based on 'off' value. Value in 'addr' reflects ++ * the register address where value in 'val' is read. ++ */ ++static bool ++sb_pcihb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, ++ uint32 **addr, uint32 *val) ++{ ++ sbpciregs_t *regs; ++ osl_t *osh; ++ uint coreidx; ++ bool ret = FALSE; ++ ++ /* sanity check */ ++ ASSERT(bus == 1); ++ ASSERT(dev == pci_hbslot); ++ ASSERT(func == 0); ++ ++ osh = sb_osh(sbh); ++ ++ /* read pci config when core rev >= 8 */ ++ coreidx = sb_coreidx(sbh); ++ regs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0); ++ if (regs && sb_corerev(sbh) >= PCI_HBSBCFG_REV) { ++ *addr = (uint32 *)®s->pcicfg[func][off >> 2]; ++ *val = R_REG(osh, *addr); ++ ret = TRUE; + } ++ sb_setcoreidx(sbh, coreidx); + -+ return (si->sb.boardtype); ++ return ret; +} + -+/* return bus type of sbh device */ -+uint -+sb_bus(sb_t *sbh) ++int ++extpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) +{ -+ sb_info_t *si; ++ uint32 addr = 0, *reg = NULL, val; ++ int ret = 0; + -+ si = SB_INFO(sbh); -+ return (si->sb.bustype); -+} ++ /* ++ * Set value to -1 when: ++ * flag 'pci_disabled' is true; ++ * value of 'addr' is zero; ++ * REG_MAP() fails; ++ * BUSPROBE() fails; ++ */ ++ if (pci_disabled) ++ val = 0xffffffff; ++ else if (bus == 1 && dev == pci_hbslot && func == 0 && ++ sb_pcihb_read_config(sbh, bus, dev, func, off, ®, &val)) ++ ; ++ else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) || ++ ((reg = (uint32 *)REG_MAP(addr, len)) == 0) || ++ (BUSPROBE(val, reg) != 0)) ++ val = 0xffffffff; + -+/* return bus core type */ -+uint -+sb_buscoretype(sb_t *sbh) -+{ -+ sb_info_t *si; ++ PCI_MSG(("%s: 0x%x <= 0x%p(0x%x), len %d, off 0x%x, buf 0x%p\n", ++ __FUNCTION__, val, reg, addr, len, off, buf)); + -+ si = SB_INFO(sbh); ++ val >>= 8 * (off & 3); ++ if (len == 4) ++ *((uint32 *) buf) = val; ++ else if (len == 2) ++ *((uint16 *) buf) = (uint16) val; ++ else if (len == 1) ++ *((uint8 *) buf) = (uint8) val; ++ else ++ ret = -1; + -+ return (si->sb.buscoretype); ++ if (reg && addr) ++ REG_UNMAP(reg); ++ ++ return ret; +} + -+/* return bus core revision */ -+uint -+sb_buscorerev(sb_t *sbh) ++int ++extpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) +{ -+ sb_info_t *si; -+ si = SB_INFO(sbh); ++ osl_t *osh; ++ uint32 addr = 0, *reg = NULL, val; ++ int ret = 0; + -+ return (si->sb.buscorerev); -+} ++ osh = sb_osh(sbh); + -+/* return list of found cores */ -+uint -+sb_corelist(sb_t *sbh, uint coreid[]) -+{ -+ sb_info_t *si; ++ /* ++ * Ignore write attempt when: ++ * flag 'pci_disabled' is true; ++ * value of 'addr' is zero; ++ * REG_MAP() fails; ++ * BUSPROBE() fails; ++ */ ++ if (pci_disabled) ++ return 0; ++ else if (bus == 1 && dev == pci_hbslot && func == 0 && ++ sb_pcihb_read_config(sbh, bus, dev, func, off, ®, &val)) ++ ; ++ else if (((addr = config_cmd(sbh, bus, dev, func, off)) == 0) || ++ ((reg = (uint32 *) REG_MAP(addr, len)) == 0) || ++ (BUSPROBE(val, reg) != 0)) ++ goto done; + -+ si = SB_INFO(sbh); ++ if (len == 4) ++ val = *((uint32 *) buf); ++ else if (len == 2) { ++ val &= ~(0xffff << (8 * (off & 3))); ++ val |= *((uint16 *) buf) << (8 * (off & 3)); ++ } else if (len == 1) { ++ val &= ~(0xff << (8 * (off & 3))); ++ val |= *((uint8 *) buf) << (8 * (off & 3)); ++ } else { ++ ret = -1; ++ goto done; ++ } + -+ bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint))); -+ return (si->numcores); -+} ++ PCI_MSG(("%s: 0x%x => 0x%p\n", __FUNCTION__, val, reg)); + -+/* return current register mapping */ -+void * -+sb_coreregs(sb_t *sbh) -+{ -+ sb_info_t *si; ++ W_REG(osh, reg, val); + -+ si = SB_INFO(sbh); -+ ASSERT(GOODREGS(si->curmap)); ++done: ++ if (reg && addr) ++ REG_UNMAP(reg); + -+ return (si->curmap); ++ return ret; +} + -+ -+/* do buffered registers update */ -+void -+sb_commit(sb_t *sbh) ++/* ++ * Must access emulated PCI configuration at these locations even when ++ * the real PCI config space exists and is accessible. ++ * ++ * PCI_CFG_VID (0x00) ++ * PCI_CFG_DID (0x02) ++ * PCI_CFG_PROGIF (0x09) ++ * PCI_CFG_SUBCL (0x0a) ++ * PCI_CFG_BASECL (0x0b) ++ * PCI_CFG_HDR (0x0e) ++ * PCI_CFG_INT (0x3c) ++ * PCI_CFG_PIN (0x3d) ++ */ ++#define FORCE_EMUCFG(off, len) \ ++ ((off == PCI_CFG_VID) || (off == PCI_CFG_DID) || \ ++ (off == PCI_CFG_PROGIF) || \ ++ (off == PCI_CFG_SUBCL) || (off == PCI_CFG_BASECL) || \ ++ (off == PCI_CFG_HDR) || \ ++ (off == PCI_CFG_INT) || (off == PCI_CFG_PIN)) ++ ++/* Sync the emulation registers and the real PCI config registers. */ ++static void ++sb_pcid_read_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg, ++ uint off, uint len) +{ -+ sb_info_t *si; -+ uint origidx; -+ uint intr_val = 0; ++ osl_t *osh; ++ uint oldidx; + -+ si = SB_INFO(sbh); ++ ASSERT(cfg); ++ ASSERT(cfg->emu); ++ ASSERT(cfg->pci); + -+ origidx = si->curidx; -+ ASSERT(GOODIDX(origidx)); ++ /* decide if real PCI config register access is necessary */ ++ if (FORCE_EMUCFG(off, len)) ++ return; + -+ INTR_OFF(si, intr_val); ++ osh = sb_osh(sbh); + -+ /* switch over to chipcommon core if there is one, else use pci */ -+ if (si->sb.ccrev != NOREV) { -+ chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0); ++ /* access to the real pci config space only when the core is up */ ++ oldidx = sb_coreidx(sbh); ++ sb_setcoreidx(sbh, coreidx); ++ if (sb_iscoreup(sbh)) { ++ if (len == 4) ++ *(uint32 *)((ulong)cfg->emu + off) = ++ htol32(R_REG(osh, (uint32 *)((ulong)cfg->pci + off))); ++ else if (len == 2) ++ *(uint16 *)((ulong)cfg->emu + off) = ++ htol16(R_REG(osh, (uint16 *)((ulong)cfg->pci + off))); ++ else if (len == 1) ++ *(uint8 *)((ulong)cfg->emu + off) = ++ R_REG(osh, (uint8 *)((ulong)cfg->pci + off)); ++ } ++ sb_setcoreidx(sbh, oldidx); ++} + -+ /* do the buffer registers update */ -+ W_REG(&ccregs->broadcastaddress, SB_COMMIT); -+ W_REG(&ccregs->broadcastdata, 0x0); -+ } else if (PCI(si)) { -+ sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0); ++static void ++sb_pcid_write_config(sb_t *sbh, uint coreidx, sb_pci_cfg_t *cfg, ++ uint off, uint len) ++{ ++ osl_t *osh; ++ uint oldidx; + -+ /* do the buffer registers update */ -+ W_REG(&pciregs->bcastaddr, SB_COMMIT); -+ W_REG(&pciregs->bcastdata, 0x0); -+ } else -+ ASSERT(0); ++ ASSERT(cfg); ++ ASSERT(cfg->emu); ++ ASSERT(cfg->pci); + -+ /* restore core index */ -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+} ++ osh = sb_osh(sbh); + -+/* reset and re-enable a core */ -+void -+sb_core_reset(sb_t *sbh, uint32 bits) -+{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ volatile uint32 dummy; ++ /* decide if real PCI config register access is necessary */ ++ if (FORCE_EMUCFG(off, len)) ++ return; + -+ si = SB_INFO(sbh); -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); ++ /* access to the real pci config space only when the core is up */ ++ oldidx = sb_coreidx(sbh); ++ sb_setcoreidx(sbh, coreidx); ++ if (sb_iscoreup(sbh)) { ++ if (len == 4) ++ W_REG(osh, (uint32 *)((ulong)cfg->pci + off), ++ ltoh32(*(uint32 *)((ulong)cfg->emu + off))); ++ else if (len == 2) ++ W_REG(osh, (uint16 *)((ulong)cfg->pci + off), ++ ltoh16(*(uint16 *)((ulong)cfg->emu + off))); ++ else if (len == 1) ++ W_REG(osh, (uint8 *)((ulong)cfg->pci + off), ++ *(uint8 *)((ulong)cfg->emu + off)); ++ } ++ sb_setcoreidx(sbh, oldidx); ++} + -+ /* -+ * Must do the disable sequence first to work for arbitrary current core state. -+ */ -+ sb_core_disable(sbh, bits); ++/* ++ * Functions for accessing translated SB configuration space ++ */ ++static int ++sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ pci_config_regs *cfg; + -+ /* -+ * Now do the initialization sequence. -+ */ ++ if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = sb_pci_cfg[dev][func].emu; + -+ /* set reset while enabling the clock and forcing them on throughout the core */ -+ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(1); ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED((uintptr)buf, len)); + -+ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) { -+ W_SBREG(si, &sb->sbtmstatehigh, 0); -+ } -+ if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { -+ AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); -+ } ++ /* use special config space if the device does not exist */ ++ if (!cfg) ++ cfg = &sb_pci_null; ++ /* sync emulation with real PCI config if necessary */ ++ else if (sb_pci_cfg[dev][func].pci) ++ sb_pcid_read_config(sbh, dev, &sb_pci_cfg[dev][func], off, len); + -+ /* clear reset and allow it to propagate throughout the core */ -+ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(1); ++ if (len == 4) ++ *((uint32 *) buf) = ltoh32(*((uint32 *)((ulong) cfg + off))); ++ else if (len == 2) ++ *((uint16 *) buf) = ltoh16(*((uint16 *)((ulong) cfg + off))); ++ else if (len == 1) ++ *((uint8 *) buf) = *((uint8 *)((ulong) cfg + off)); ++ else ++ return -1; + -+ /* leave clock enabled */ -+ W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits)); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(1); ++ return 0; +} + -+void -+sb_core_tofixup(sb_t *sbh) ++static int ++sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; ++ uint coreidx; ++ void *regs; ++ pci_config_regs *cfg; ++ osl_t *osh; ++ sb_bar_cfg_t *bar; + -+ si = SB_INFO(sbh); ++ if (dev >= SB_MAXCORES || func >= MAXFUNCS || (off + len) > sizeof(pci_config_regs)) ++ return -1; ++ cfg = sb_pci_cfg[dev][func].emu; ++ if (!cfg) ++ return -1; + -+ if ( (BUSTYPE(si->sb.bustype) != PCI_BUS) || PCIE(si) || (PCI(si) && (si->sb.buscorerev >= 5)) ) -+ return; ++ ASSERT(ISALIGNED(off, len)); ++ ASSERT(ISALIGNED((uintptr)buf, len)); + -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); ++ osh = sb_osh(sbh); + -+ if (BUSTYPE(si->sb.bustype) == SB_BUS) { -+ SET_SBREG(si, &sb->sbimconfiglow, -+ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x5 << SBIMCL_RTO_SHIFT) | 0x3); -+ } else { -+ if (sb_coreid(sbh) == SB_PCI) { -+ SET_SBREG(si, &sb->sbimconfiglow, -+ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); -+ } else { -+ SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); ++ /* Emulate BAR sizing */ ++ if (off >= OFFSETOF(pci_config_regs, base[0]) && ++ off <= OFFSETOF(pci_config_regs, base[3]) && ++ len == 4 && *((uint32 *) buf) == ~0) { ++ coreidx = sb_coreidx(sbh); ++ if ((regs = sb_setcoreidx(sbh, dev))) { ++ bar = sb_pci_cfg[dev][func].bar; ++ /* Highest numbered address match register */ ++ if (off == OFFSETOF(pci_config_regs, base[0])) ++ cfg->base[0] = ~(bar->size0 - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[1]) && bar->n >= 1) ++ cfg->base[1] = ~(bar->size1 - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[2]) && bar->n >= 2) ++ cfg->base[2] = ~(bar->size2 - 1); ++ else if (off == OFFSETOF(pci_config_regs, base[3]) && bar->n >= 3) ++ cfg->base[3] = ~(bar->size3 - 1); + } ++ sb_setcoreidx(sbh, coreidx); + } ++ else if (len == 4) ++ *((uint32 *)((ulong) cfg + off)) = htol32(*((uint32 *) buf)); ++ else if (len == 2) ++ *((uint16 *)((ulong) cfg + off)) = htol16(*((uint16 *) buf)); ++ else if (len == 1) ++ *((uint8 *)((ulong) cfg + off)) = *((uint8 *) buf); ++ else ++ return -1; + -+ sb_commit(sbh); ++ /* sync emulation with real PCI config if necessary */ ++ if (sb_pci_cfg[dev][func].pci) ++ sb_pcid_write_config(sbh, dev, &sb_pci_cfg[dev][func], off, len); ++ ++ return 0; +} + -+/* -+ * Set the initiator timeout for the "master core". -+ * The master core is defined to be the core in control -+ * of the chip and so it issues accesses to non-memory -+ * locations (Because of dma *any* core can access memeory). -+ * -+ * The routine uses the bus to decide who is the master: -+ * SB_BUS => mips -+ * JTAG_BUS => chipc -+ * PCI_BUS => pci or pcie -+ * PCMCIA_BUS => pcmcia -+ * SDIO_BUS => pcmcia -+ * -+ * This routine exists so callers can disable initiator -+ * timeouts so accesses to very slow devices like otp -+ * won't cause an abort. The routine allows arbitrary -+ * settings of the service and request timeouts, though. -+ * -+ * Returns the timeout state before changing it or -1 -+ * on error. -+ */ ++int ++sbpci_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ if (bus == 0) ++ return sb_read_config(sbh, bus, dev, func, off, buf, len); ++ else ++ return extpci_read_config(sbh, bus, dev, func, off, buf, len); ++} ++ ++int ++sbpci_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++{ ++ if (bus == 0) ++ return sb_write_config(sbh, bus, dev, func, off, buf, len); ++ else ++ return extpci_write_config(sbh, bus, dev, func, off, buf, len); ++} + -+#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) ++void ++sbpci_ban(uint16 core) ++{ ++ if (pci_banned < ARRAYSIZE(pci_ban)) ++ pci_ban[pci_banned++] = core; ++} + -+uint32 -+sb_set_initiator_to(sb_t *sbh, uint32 to) ++/* ++ * Initiliaze PCI core. Return 0 after a successful initialization. ++ * Otherwise return -1 to indicate there is no PCI core and return 1 ++ * to indicate PCI core is disabled. ++ */ ++int __init ++sbpci_init_pci(sb_t *sbh) +{ -+ sb_info_t *si; -+ uint origidx, idx; -+ uint intr_val = 0; -+ uint32 tmp, ret = 0xffffffff; ++ uint chip, chiprev, chippkg, host; ++ uint32 boardflags; ++ sbpciregs_t *pci; + sbconfig_t *sb; ++ uint32 val; ++ int ret = 0; ++ char *hbslot; ++ osl_t *osh; + -+ si = SB_INFO(sbh); ++ chip = sb_chip(sbh); ++ chiprev = sb_chiprev(sbh); ++ chippkg = sb_chippkg(sbh); + -+ if ((to & ~TO_MASK) != 0) -+ return ret; ++ osh = sb_osh(sbh); + -+ /* Figure out the master core */ -+ idx = BADIDX; -+ switch (BUSTYPE(si->sb.bustype)) { -+ case PCI_BUS: -+ idx = si->sb.buscoreidx; -+ break; -+ case JTAG_BUS: -+ idx = SB_CC_IDX; -+ break; -+ case PCMCIA_BUS: -+ case SDIO_BUS: -+ idx = sb_findcoreidx(si, SB_PCMCIA, 0); -+ break; -+ case SB_BUS: -+ if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX) -+ idx = sb_findcoreidx(si, SB_MIPS, 0); -+ break; -+ default: -+ ASSERT(0); ++ if (!(pci = (sbpciregs_t *) sb_setcore(sbh, SB_PCI, 0))) { ++ printk("PCI: no core\n"); ++ pci_disabled = TRUE; ++ return -1; + } -+ if (idx == BADIDX) -+ return ret; + -+ INTR_OFF(si, intr_val); -+ origidx = sb_coreidx(sbh); ++ if ((chip == 0x4710) && (chiprev == 0)) ++ pci_disabled = TRUE; ++ ++ sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF); + -+ sb = REGS2SB(sb_setcoreidx(sbh, idx)); ++ boardflags = (uint32) getintvar(NULL, "boardflags"); + -+ tmp = R_SBREG(si, &sb->sbimconfiglow); -+ ret = tmp & TO_MASK; -+ W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); ++ /* ++ * The 200-pin BCM4712 package does not bond out PCI. Even when ++ * PCI is bonded out, some boards may leave the pins ++ * floating. ++ */ ++ if (((chip == BCM4712_CHIP_ID) && ++ ((chippkg == BCM4712SMALL_PKG_ID) || ++ (chippkg == BCM4712MID_PKG_ID))) || ++ (boardflags & BFL_NOPCI)) ++ pci_disabled = TRUE; + -+ sb_commit(sbh); -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return ret; -+} ++ /* Enable the core */ ++ sb_core_reset(sbh, 0, 0); + -+void -+sb_core_disable(sb_t *sbh, uint32 bits) -+{ -+ sb_info_t *si; -+ volatile uint32 dummy; -+ uint32 rej; -+ sbconfig_t *sb; ++ /* ++ * If the PCI core should not be touched (disabled, not bonded ++ * out, or pins floating), do not even attempt to access core ++ * registers. Otherwise, try to determine if it is in host ++ * mode. ++ */ ++ if (pci_disabled) ++ host = 0; ++ else ++ host = !BUSPROBE(val, &pci->control); + -+ si = SB_INFO(sbh); ++ if (!host) { ++ ret = 1; + -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); ++ /* Disable PCI interrupts in client mode */ ++ W_REG(osh, &sb->sbintvec, 0); + -+ /* if core is already in reset, just return */ -+ if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET) -+ return; ++ /* Disable the PCI bridge in client mode */ ++ sbpci_ban(SB_PCI); ++ sb_core_disable(sbh, 0); + -+ /* reject value changed between sonics 2.2 and 2.3 */ -+ if (si->sb.sonicsrev == SONICS_2_2) -+ rej = (1 << SBTML_REJ_SHIFT); -+ else -+ rej = (2 << SBTML_REJ_SHIFT); ++ printk("PCI: Disabled\n"); ++ } else { ++ printk("PCI: Initializing host\n"); + -+ /* if clocks are not enabled, put into reset and return */ -+ if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0) -+ goto disable; ++ /* Disable PCI SBReqeustTimeout for BCM4785 */ ++ if (chip == BCM4785_CHIP_ID) { ++ AND_REG(osh, &sb->sbimconfiglow, ~0x00000070); ++ sb_commit(sbh); ++ } + -+ /* set target reject and spin until busy is clear (preserve core-specific bits) */ -+ OR_SBREG(si, &sb->sbtmstatelow, rej); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(1); -+ SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); ++ /* Reset the external PCI bus and enable the clock */ ++ W_REG(osh, &pci->control, 0x5); /* enable the tristate drivers */ ++ W_REG(osh, &pci->control, 0xd); /* enable the PCI clock */ ++ OSL_DELAY(150); /* delay > 100 us */ ++ W_REG(osh, &pci->control, 0xf); /* deassert PCI reset */ ++ /* Use internal arbiter and park REQ/GRNT at external master 0 */ ++ W_REG(osh, &pci->arbcontrol, PCI_INT_ARB); ++ OSL_DELAY(1); /* delay 1 us */ ++ if (sb_corerev(sbh) >= 8) { ++ val = getintvar(NULL, "parkid"); ++ ASSERT(val <= PCI_PARKID_LAST); ++ OR_REG(osh, &pci->arbcontrol, val << PCI_PARKID_SHIFT); ++ OSL_DELAY(1); ++ } + -+ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) { -+ OR_SBREG(si, &sb->sbimstate, SBIM_RJ); -+ dummy = R_SBREG(si, &sb->sbimstate); -+ OSL_DELAY(1); -+ SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000); -+ } ++ /* Enable CardBusMode */ ++ cardbus = getintvar(NULL, "cardbus") == 1; ++ if (cardbus) { ++ printk("PCI: Enabling CardBus\n"); ++ /* GPIO 1 resets the CardBus device on bcm94710ap */ ++ sb_gpioout(sbh, 1, 1, GPIO_DRV_PRIORITY); ++ sb_gpioouten(sbh, 1, 1, GPIO_DRV_PRIORITY); ++ W_REG(osh, &pci->sprom[0], R_REG(osh, &pci->sprom[0]) | 0x400); ++ } + -+ /* set reset and reject while enabling the clocks */ -+ W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET)); -+ dummy = R_SBREG(si, &sb->sbtmstatelow); -+ OSL_DELAY(10); ++ /* 64 MB I/O access window */ ++ W_REG(osh, &pci->sbtopci0, SBTOPCI_IO); ++ /* 64 MB configuration access window */ ++ W_REG(osh, &pci->sbtopci1, SBTOPCI_CFG0); ++ /* 1 GB memory access window */ ++ W_REG(osh, &pci->sbtopci2, SBTOPCI_MEM | SB_PCI_DMA); + -+ /* don't forget to clear the initiator reject bit */ -+ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) -+ AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ); ++ /* Host bridge slot # nvram overwrite */ ++ if ((hbslot = nvram_get("pcihbslot"))) { ++ pci_hbslot = bcm_strtoul(hbslot, NULL, 0); ++ ASSERT(pci_hbslot < PCI_MAX_DEVICES); ++ } + -+disable: -+ /* leave reset and reject asserted */ -+ W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET)); -+ OSL_DELAY(1); ++ /* Enable PCI bridge BAR0 prefetch and burst */ ++ val = 6; ++ sbpci_write_config(sbh, 1, pci_hbslot, 0, PCI_CFG_CMD, &val, sizeof(val)); ++ ++ /* Enable PCI interrupts */ ++ W_REG(osh, &pci->intmask, PCI_INTA); ++ } ++ ++ return ret; +} + -+/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */ -+void -+sb_watchdog(sb_t *sbh, uint ticks) ++/* ++ * Get the PCI region address and size information. ++ */ ++static void __init ++sbpci_init_regions(sb_t *sbh, uint func, pci_config_regs *cfg, sb_bar_cfg_t *bar) +{ -+ sb_info_t *si = SB_INFO(sbh); ++ osl_t *osh; ++ uint16 coreid; ++ void *regs; ++ sbconfig_t *sb; ++ uint32 base; + -+ /* instant NMI */ -+ switch (si->gpioid) { -+ case SB_CC: -+ sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); ++ osh = sb_osh(sbh); ++ coreid = sb_coreid(sbh); ++ regs = sb_coreregs(sbh); ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ switch (coreid) { ++ case SB_USB20H: ++ base = htol32(sb_base(R_REG(osh, &sb->sbadmatch0))); ++ ++ cfg->base[0] = func == 0 ? base : base + 0x800; /* OHCI/EHCI */ ++ cfg->base[1] = 0; ++ cfg->base[2] = 0; ++ cfg->base[3] = 0; ++ cfg->base[4] = 0; ++ cfg->base[5] = 0; ++ bar->n = 1; ++ bar->size0 = func == 0 ? 0x200 : 0x100; /* OHCI/EHCI */ ++ bar->size1 = 0; ++ bar->size2 = 0; ++ bar->size3 = 0; + break; -+ case SB_EXTIF: -+ sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); ++ default: ++ cfg->base[0] = htol32(sb_base(R_REG(osh, &sb->sbadmatch0))); ++ cfg->base[1] = htol32(sb_base(R_REG(osh, &sb->sbadmatch1))); ++ cfg->base[2] = htol32(sb_base(R_REG(osh, &sb->sbadmatch2))); ++ cfg->base[3] = htol32(sb_base(R_REG(osh, &sb->sbadmatch3))); ++ cfg->base[4] = 0; ++ cfg->base[5] = 0; ++ bar->n = (R_REG(osh, &sb->sbidlow) & SBIDL_AR_MASK) >> SBIDL_AR_SHIFT; ++ bar->size0 = sb_size(R_REG(osh, &sb->sbadmatch0)); ++ bar->size1 = sb_size(R_REG(osh, &sb->sbadmatch1)); ++ bar->size2 = sb_size(R_REG(osh, &sb->sbadmatch2)); ++ bar->size3 = sb_size(R_REG(osh, &sb->sbadmatch3)); + break; + } +} + -+/* initialize the pcmcia core */ -+void -+sb_pcmcia_init(sb_t *sbh) ++/* ++ * Construct PCI config spaces for SB cores so that they ++ * can be accessed as if they were PCI devices. ++ */ ++static void __init ++sbpci_init_cores(sb_t *sbh) +{ -+ sb_info_t *si; -+ uint8 cor; ++ uint chiprev, coreidx, i; ++ sbconfig_t *sb; ++ pci_config_regs *cfg, *pci; ++ sb_bar_cfg_t *bar; ++ void *regs; ++ osl_t *osh; ++ uint16 vendor, device; ++ uint16 coreid; ++ uint8 class, subclass, progif; ++ uint dev; ++ uint8 header; ++ uint func; + -+ si = SB_INFO(sbh); ++ chiprev = sb_chiprev(sbh); ++ coreidx = sb_coreidx(sbh); + -+ /* enable d11 mac interrupts */ -+ if (si->sb.chip == BCM4301_DEVICE_ID) { -+ /* Have to use FCR2 in 4301 */ -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); -+ cor |= COR_IRQEN | COR_FUNEN; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); -+ } else { -+ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); -+ cor |= COR_IRQEN | COR_FUNEN; -+ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ osh = sb_osh(sbh); ++ ++ /* Scan the SB bus */ ++ bzero(sb_config_regs, sizeof(sb_config_regs)); ++ bzero(sb_bar_cfg, sizeof(sb_bar_cfg)); ++ bzero(sb_pci_cfg, sizeof(sb_pci_cfg)); ++ memset(&sb_pci_null, -1, sizeof(sb_pci_null)); ++ cfg = sb_config_regs; ++ bar = sb_bar_cfg; ++ for (dev = 0; dev < SB_MAXCORES; dev ++) { ++ /* Check if the core exists */ ++ if (!(regs = sb_setcoreidx(sbh, dev))) ++ continue; ++ sb = (sbconfig_t *)((ulong) regs + SBCONFIGOFF); ++ ++ /* Check if this core is banned */ ++ coreid = sb_coreid(sbh); ++ for (i = 0; i < pci_banned; i++) ++ if (coreid == pci_ban[i]) ++ break; ++ if (i < pci_banned) ++ continue; ++ ++ for (func = 0; func < MAXFUNCS; ++func) { ++ /* Make sure we won't go beyond the limit */ ++ if (cfg >= &sb_config_regs[SB_MAXCORES]) { ++ printk("PCI: too many emulated devices\n"); ++ goto done; ++ } ++ ++ /* Convert core id to pci id */ ++ if (sb_corepciid(sbh, func, &vendor, &device, &class, &subclass, ++ &progif, &header)) ++ continue; ++ ++ /* ++ * Differentiate real PCI config from emulated. ++ * non zero 'pci' indicate there is a real PCI config space ++ * for this device. ++ */ ++ switch (device) { ++ case BCM47XX_GIGETH_ID: ++ pci = (pci_config_regs *)((uint32)regs + 0x800); ++ break; ++ case BCM47XX_SATAXOR_ID: ++ pci = (pci_config_regs *)((uint32)regs + 0x400); ++ break; ++ case BCM47XX_ATA100_ID: ++ pci = (pci_config_regs *)((uint32)regs + 0x800); ++ break; ++ default: ++ pci = NULL; ++ break; ++ } ++ /* Supported translations */ ++ cfg->vendor = htol16(vendor); ++ cfg->device = htol16(device); ++ cfg->rev_id = chiprev; ++ cfg->prog_if = progif; ++ cfg->sub_class = subclass; ++ cfg->base_class = class; ++ cfg->header_type = header; ++ sbpci_init_regions(sbh, func, cfg, bar); ++ /* Save core interrupt flag */ ++ cfg->int_pin = R_REG(osh, &sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ /* Save core interrupt assignment */ ++ cfg->int_line = sb_irq(sbh); ++ /* Indicate there is no SROM */ ++ *((uint32 *) &cfg->sprom_control) = 0xffffffff; ++ ++ /* Point to the PCI config spaces */ ++ sb_pci_cfg[dev][func].emu = cfg; ++ sb_pci_cfg[dev][func].pci = pci; ++ sb_pci_cfg[dev][func].bar = bar; ++ cfg ++; ++ bar ++; ++ } + } + ++done: ++ sb_setcoreidx(sbh, coreidx); +} + -+ +/* -+ * Configure the pci core for pci client (NIC) action -+ * coremask is the bitvec of cores by index to be enabled. ++ * Initialize PCI core and construct PCI config spaces for SB cores. ++ * Must propagate sbpci_init_pci() return value to the caller to let ++ * them know the PCI core initialization status. + */ -+void -+sb_pci_setup(sb_t *sbh, uint coremask) ++int __init ++sbpci_init(sb_t *sbh) +{ -+ sb_info_t *si; -+ sbconfig_t *sb; -+ sbpciregs_t *pciregs; -+ uint32 sbflag; -+ uint32 w; -+ uint idx; -+ int reg_val; ++ int status = sbpci_init_pci(sbh); ++ sbpci_init_cores(sbh); ++ return status; ++} + -+ si = SB_INFO(sbh); +diff -urN linux.old/arch/mips/bcm947xx/sbutils.c linux.dev/arch/mips/bcm947xx/sbutils.c +--- linux.old/arch/mips/bcm947xx/sbutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/sbutils.c 2006-05-02 04:33:16.000000000 +0200 +@@ -0,0 +1,3081 @@ ++/* ++ * Misc utility routines for accessing chip-specific features ++ * of the SiliconBackplane-based Broadcom chips. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: sbutils.c,v 1.10 2006/04/08 07:12:42 honor Exp $ ++ */ + -+ /* if not pci bus, we're done */ -+ if (BUSTYPE(si->sb.bustype) != PCI_BUS) -+ return; ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef __mips__ ++#include ++#endif /* __mips__ */ + -+ ASSERT(PCI(si) || PCIE(si)); -+ ASSERT(si->sb.buscoreidx != BADIDX); ++/* debug/trace */ ++#define SB_ERROR(args) + -+ /* get current core index */ -+ idx = si->curidx; ++typedef uint32 (*sb_intrsoff_t)(void *intr_arg); ++typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg); ++typedef bool (*sb_intrsenabled_t)(void *intr_arg); + -+ /* we interrupt on this backplane flag number */ -+ ASSERT(GOODREGS(si->curmap)); -+ sb = REGS2SB(si->curmap); -+ sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK; ++/* misc sb info needed by some of the routines */ ++typedef struct sb_info { + -+ /* switch over to pci core */ -+ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx); -+ sb = REGS2SB(pciregs); ++ struct sb_pub sb; /* back plane public state (must be first field) */ + -+ /* -+ * Enable sb->pci interrupts. Assume -+ * PCI rev 2.3 support was added in pci core rev 6 and things changed.. -+ */ -+ if (PCIE(si) || (PCI(si) && ((si->sb.buscorerev) >= 6))) { -+ /* pci config write to set this core bit in PCIIntMask */ -+ w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32)); -+ w |= (coremask << PCI_SBIM_SHIFT); -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w); -+ } else { -+ /* set sbintvec bit for our flag number */ -+ OR_SBREG(si, &sb->sbintvec, (1 << sbflag)); -+ } ++ void *osh; /* osl os handle */ ++ void *sdh; /* bcmsdh handle */ + -+ if (PCI(si)) { -+ OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); -+ if (si->sb.buscorerev >= 11) -+ OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI); -+ if (si->sb.buscorerev < 5) { -+ SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); -+ sb_commit(sbh); -+ } -+ } ++ void *curmap; /* current regs va */ ++ void *regs[SB_MAXCORES]; /* other regs va */ + -+ if (PCIE(si) && (si->sb.buscorerev == 0)) { -+ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG); -+ reg_val |= 0x8; -+ sb_pcie_writereg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_TLP_WORKAROUNDSREG, reg_val); ++ uint curidx; /* current core index */ ++ uint dev_coreid; /* the core provides driver functions */ + -+ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG); -+ reg_val &= ~(0x40); -+ sb_pcie_writereg(sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG, reg_val); ++ bool memseg; /* flag to toggle MEM_SEG register */ + -+ BCMINIT(sb_war30841)(si); -+ } ++ uint gpioidx; /* gpio control core index */ ++ uint gpioid; /* gpio control coretype */ + -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); -+} ++ uint numcores; /* # discovered cores */ ++ uint coreid[SB_MAXCORES]; /* id of each core */ + -+uint32 -+sb_base(uint32 admatch) -+{ -+ uint32 base; -+ uint type; ++ void *intr_arg; /* interrupt callback function arg */ ++ sb_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ ++ sb_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ ++ sb_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ + -+ type = admatch & SBAM_TYPE_MASK; -+ ASSERT(type < 3); ++} sb_info_t; + -+ base = 0; ++/* local prototypes */ ++static sb_info_t * sb_doattach(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, uint *varsz); ++static void sb_scan(sb_info_t *si); ++static uint sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val); ++static uint _sb_coreidx(sb_info_t *si); ++static uint sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit); ++static uint sb_pcidev2chip(uint pcidev); ++static uint sb_chip2numcores(uint chip); ++static bool sb_ispcie(sb_info_t *si); ++static bool sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen); ++static int sb_pci_fixcfg(sb_info_t *si); + -+ if (type == 0) { -+ base = admatch & SBAM_BASE0_MASK; -+ } else if (type == 1) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ base = admatch & SBAM_BASE1_MASK; -+ } else if (type == 2) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ base = admatch & SBAM_BASE2_MASK; -+ } ++/* routines to access mdio slave device registers */ ++static int sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint readdr, uint val); ++static void sb_war30841(sb_info_t *si); + -+ return (base); -+} ++/* delay needed between the mdio control/ mdiodata register data access */ ++#define PR28829_DELAY() OSL_DELAY(10) + -+uint32 -+sb_size(uint32 admatch) -+{ -+ uint32 size; -+ uint type; ++/* size that can take bitfielddump */ ++#define BITFIELD_DUMP_SIZE 32 + -+ type = admatch & SBAM_TYPE_MASK; -+ ASSERT(type < 3); ++/* global variable to indicate reservation/release of gpio's */ ++static uint32 sb_gpioreservation = 0; + -+ size = 0; ++#define SB_INFO(sbh) (sb_info_t*)sbh ++#define SET_SBREG(si, r, mask, val) \ ++ W_SBREG((si), (r), ((R_SBREG((si), (r)) & ~(mask)) | (val))) ++#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && \ ++ ISALIGNED((x), SB_CORE_SIZE)) ++#define GOODREGS(regs) ((regs) && ISALIGNED((uintptr)(regs), SB_CORE_SIZE)) ++#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) ++#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) ++#define BADIDX (SB_MAXCORES+1) ++#define NOREV -1 /* Invalid rev */ + -+ if (type == 0) { -+ size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); -+ } else if (type == 1) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); -+ } else if (type == 2) { -+ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ -+ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); -+ } ++#define PCI(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCI)) ++#define PCIE(si) ((BUSTYPE(si->sb.bustype) == PCI_BUS) && (si->sb.buscoretype == SB_PCIE)) + -+ return (size); -+} ++/* sonicsrev */ ++#define SONICS_2_2 (SBIDL_RV_2_2 >> SBIDL_RV_SHIFT) ++#define SONICS_2_3 (SBIDL_RV_2_3 >> SBIDL_RV_SHIFT) + -+/* return the core-type instantiation # of the current core */ -+uint -+sb_coreunit(sb_t *sbh) -+{ -+ sb_info_t *si; -+ uint idx; -+ uint coreid; -+ uint coreunit; -+ uint i; ++#define R_SBREG(si, sbr) sb_read_sbreg((si), (sbr)) ++#define W_SBREG(si, sbr, v) sb_write_sbreg((si), (sbr), (v)) ++#define AND_SBREG(si, sbr, v) W_SBREG((si), (sbr), (R_SBREG((si), (sbr)) & (v))) ++#define OR_SBREG(si, sbr, v) W_SBREG((si), (sbr), (R_SBREG((si), (sbr)) | (v))) + -+ si = SB_INFO(sbh); -+ coreunit = 0; ++/* ++ * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ ++ * after core switching to avoid invalid register accesss inside ISR. ++ */ ++#define INTR_OFF(si, intr_val) \ ++ if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } ++#define INTR_RESTORE(si, intr_val) \ ++ if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ ++ (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } + -+ idx = si->curidx; ++/* dynamic clock control defines */ ++#define LPOMINFREQ 25000 /* low power oscillator min */ ++#define LPOMAXFREQ 43000 /* low power oscillator max */ ++#define XTALMINFREQ 19800000 /* 20 MHz - 1% */ ++#define XTALMAXFREQ 20200000 /* 20 MHz + 1% */ ++#define PCIMINFREQ 25000000 /* 25 MHz */ ++#define PCIMAXFREQ 34000000 /* 33 MHz + fudge */ + -+ ASSERT(GOODREGS(si->curmap)); -+ coreid = sb_coreid(sbh); ++#define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ ++#define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ + -+ /* count the cores of our type */ -+ for (i = 0; i < idx; i++) -+ if (si->coreid[i] == coreid) -+ coreunit++; ++/* different register spaces to access thr'u pcie indirect access */ ++#define PCIE_CONFIGREGS 1 /* Access to config space */ ++#define PCIE_PCIEREGS 2 /* Access to pcie registers */ + -+ return (coreunit); -+} ++/* GPIO Based LED powersave defines */ ++#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ ++#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ + -+static INLINE uint32 -+factor6(uint32 x) -+{ -+ switch (x) { -+ case CC_F6_2: return 2; -+ case CC_F6_3: return 3; -+ case CC_F6_4: return 4; -+ case CC_F6_5: return 5; -+ case CC_F6_6: return 6; -+ case CC_F6_7: return 7; -+ default: return 0; -+ } -+} ++#define DEFAULT_GPIOTIMERVAL ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) + -+/* calculate the speed the SB would run at given a set of clockcontrol values */ -+uint32 -+sb_clock_rate(uint32 pll_type, uint32 n, uint32 m) ++static uint32 ++sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr) +{ -+ uint32 n1, n2, clock, m1, m2, m3, mc; ++ uint8 tmp; ++ uint32 val, intr_val = 0; + -+ n1 = n & CN_N1_MASK; -+ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; + -+ if (pll_type == PLL_TYPE6) { -+ if (m & CC_T6_MMASK) -+ return CC_T6_M1; -+ else -+ return CC_T6_M0; -+ } else if ((pll_type == PLL_TYPE1) || -+ (pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE7)) { -+ n1 = factor6(n1); -+ n2 += CC_F5_BIAS; -+ } else if (pll_type == PLL_TYPE2) { -+ n1 += CC_T2_BIAS; -+ n2 += CC_T2_BIAS; -+ ASSERT((n1 >= 2) && (n1 <= 7)); -+ ASSERT((n2 >= 5) && (n2 <= 23)); -+ } else if (pll_type == PLL_TYPE5) { -+ return (100000000); -+ } else -+ ASSERT(0); -+ /* PLL types 3 and 7 use BASE2 (25Mhz) */ -+ if ((pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE7)) { -+ clock = CC_CLOCK_BASE2 * n1 * n2; ++ /* ++ * compact flash only has 11 bits address, while we needs 12 bits address. ++ * MEM_SEG will be OR'd with other 11 bits address in hardware, ++ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). ++ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special ++ */ ++ if (si->memseg) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ + } -+ else -+ clock = CC_CLOCK_BASE1 * n1 * n2; -+ -+ if (clock == 0) -+ return 0; -+ -+ m1 = m & CC_M1_MASK; -+ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; -+ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; -+ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; -+ -+ if ((pll_type == PLL_TYPE1) || -+ (pll_type == PLL_TYPE3) || -+ (pll_type == PLL_TYPE4) || -+ (pll_type == PLL_TYPE7)) { -+ m1 = factor6(m1); -+ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) -+ m2 += CC_F5_BIAS; -+ else -+ m2 = factor6(m2); -+ m3 = factor6(m3); -+ -+ switch (mc) { -+ case CC_MC_BYPASS: return (clock); -+ case CC_MC_M1: return (clock / m1); -+ case CC_MC_M1M2: return (clock / (m1 * m2)); -+ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); -+ case CC_MC_M1M3: return (clock / (m1 * m3)); -+ default: return (0); -+ } -+ } else { -+ ASSERT(pll_type == PLL_TYPE2); -+ -+ m1 += CC_T2_BIAS; -+ m2 += CC_T2M2_BIAS; -+ m3 += CC_T2_BIAS; -+ ASSERT((m1 >= 2) && (m1 <= 7)); -+ ASSERT((m2 >= 3) && (m2 <= 10)); -+ ASSERT((m3 >= 2) && (m3 <= 7)); + -+ if ((mc & CC_T2MC_M1BYP) == 0) -+ clock /= m1; -+ if ((mc & CC_T2MC_M2BYP) == 0) -+ clock /= m2; -+ if ((mc & CC_T2MC_M3BYP) == 0) -+ clock /= m3; ++ val = R_REG(si->osh, sbr); + -+ return(clock); ++ if (si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ INTR_RESTORE(si, intr_val); + } ++ ++ return (val); +} + -+/* returns the current speed the SB is running at */ -+uint32 -+sb_clock(sb_t *sbh) ++static void ++sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v) +{ -+ sb_info_t *si; -+ extifregs_t *eir; -+ chipcregs_t *cc; -+ uint32 n, m; -+ uint idx; -+ uint32 pll_type, rate; -+ uint intr_val = 0; ++ uint8 tmp; ++ volatile uint32 dummy; ++ uint32 intr_val = 0; + -+ si = SB_INFO(sbh); -+ idx = si->curidx; -+ pll_type = PLL_TYPE1; + -+ INTR_OFF(si, intr_val); ++ /* ++ * compact flash only has 11 bits address, while we needs 12 bits address. ++ * MEM_SEG will be OR'd with other 11 bits address in hardware, ++ * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). ++ * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special ++ */ ++ if (si->memseg) { ++ INTR_OFF(si, intr_val); ++ tmp = 1; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); ++ sbr = (volatile uint32 *)((uintptr)sbr & ~(1 << 11)); /* mask out bit 11 */ ++ } + -+ /* switch to extif or chipc core */ -+ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { -+ n = R_REG(&eir->clockcontrol_n); -+ m = R_REG(&eir->clockcontrol_sb); -+ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { -+ pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; -+ n = R_REG(&cc->clockcontrol_n); -+ if (pll_type == PLL_TYPE6) -+ m = R_REG(&cc->clockcontrol_mips); -+ else if (pll_type == PLL_TYPE3) -+ { -+ // Added by Chen-I for 5365 -+ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) -+ m = R_REG(&cc->clockcontrol_sb); -+ else -+ m = R_REG(&cc->clockcontrol_m2); -+ } -+ else -+ m = R_REG(&cc->clockcontrol_sb); -+ } else { ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++#ifdef IL_BIGENDIAN ++ dummy = R_REG(si->osh, sbr); ++ W_REG(si->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); ++ dummy = R_REG(si->osh, sbr); ++ W_REG(si->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++#else ++ dummy = R_REG(si->osh, sbr); ++ W_REG(si->osh, (volatile uint16 *)sbr, (uint16)(v & 0xffff)); ++ dummy = R_REG(si->osh, sbr); ++ W_REG(si->osh, ((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); ++#endif /* IL_BIGENDIAN */ ++ } else ++ W_REG(si->osh, sbr, v); ++ ++ if (si->memseg) { ++ tmp = 0; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); + INTR_RESTORE(si, intr_val); -+ return 0; + } ++} + -+ // Added by Chen-I for 5365 -+ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) -+ { -+ rate = 100000000; ++/* ++ * Allocate a sb handle. ++ * devid - pci device id (used to determine chip#) ++ * osh - opaque OS handle ++ * regs - virtual address of initial core registers ++ * bustype - pci/pcmcia/sb/sdio/etc ++ * vars - pointer to a pointer area for "environment" variables ++ * varsz - pointer to int to return the size of the vars ++ */ ++sb_t * ++BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, uint *varsz) ++{ ++ sb_info_t *si; ++ ++ /* alloc sb_info_t */ ++ if ((si = MALLOC(osh, sizeof (sb_info_t))) == NULL) { ++ SB_ERROR(("sb_attach: malloc failed! malloced %d bytes\n", MALLOCED(osh))); ++ return (NULL); + } -+ else -+ { -+ /* calculate rate */ -+ rate = sb_clock_rate(pll_type, n, m); -+ if (pll_type == PLL_TYPE3) -+ rate = rate / 2; ++ ++ if (sb_doattach(si, devid, osh, regs, bustype, sdh, vars, (uint*)varsz) == NULL) { ++ MFREE(osh, si, sizeof(sb_info_t)); ++ return (NULL); + } + -+ /* switch back to previous core */ -+ sb_setcoreidx(sbh, idx); ++ return (sb_t *)si; ++} + -+ INTR_RESTORE(si, intr_val); ++/* Using sb_kattach depends on SB_BUS support, either implicit */ ++/* no limiting BCMBUSTYPE value) or explicit (value is SB_BUS). */ ++#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS) + -+ return rate; -+} ++/* global kernel resource */ ++static sb_info_t ksi; ++static bool ksi_attached = FALSE; + -+/* change logical "focus" to the gpio core for optimized access */ -+void* -+sb_gpiosetcore(sb_t *sbh) ++/* generic kernel variant of sb_attach() */ ++sb_t * ++BCMINITFN(sb_kattach)(void) +{ -+ sb_info_t *si; ++ osl_t *osh = NULL; ++ uint32 *regs; + -+ si = SB_INFO(sbh); ++ if (!ksi_attached) { ++ uint32 cid; + -+ return (sb_setcoreidx(sbh, si->gpioidx)); ++ regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); ++ cid = R_REG(osh, (uint32 *)regs); ++ if (((cid & CID_ID_MASK) == BCM4712_CHIP_ID) && ++ ((cid & CID_PKG_MASK) != BCM4712LARGE_PKG_ID) && ++ ((cid & CID_REV_MASK) <= (3 << CID_REV_SHIFT))) { ++ uint32 *scc, val; ++ ++ scc = (uint32 *)((uchar*)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); ++ val = R_REG(osh, scc); ++ SB_ERROR((" initial scc = 0x%x\n", val)); ++ val |= SCC_SS_XTAL; ++ W_REG(osh, scc, val); ++ } ++ ++ if (sb_doattach(&ksi, BCM4710_DEVICE_ID, osh, (void*)regs, ++ SB_BUS, NULL, NULL, NULL) == NULL) { ++ return NULL; ++ } ++ else ++ ksi_attached = TRUE; ++ } ++ ++ return (sb_t *)&ksi; +} ++#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */ + -+/* mask&set gpiocontrol bits */ -+uint32 -+sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++static sb_info_t * ++BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, uint *varsz) +{ -+ sb_info_t *si; -+ uint regoff; ++ uint origidx; ++ chipcregs_t *cc; ++ sbconfig_t *sb; ++ uint32 w; + -+ si = SB_INFO(sbh); -+ regoff = 0; ++ ASSERT(GOODREGS(regs)); + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ bzero((uchar*)si, sizeof(sb_info_t)); + -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; ++ si->sb.buscoreidx = si->gpioidx = BADIDX; ++ ++ si->curmap = regs; ++ si->sdh = sdh; ++ si->osh = osh; ++ ++ /* check to see if we are a sb core mimic'ing a pci core */ ++ if (bustype == PCI_BUS) { ++ if (OSL_PCI_READ_CONFIG(si->osh, PCI_SPROM_CONTROL, sizeof(uint32)) == 0xffffffff) { ++ SB_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SB " ++ "devid:0x%x\n", __FUNCTION__, devid)); ++ bustype = SB_BUS; ++ } + } + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpiocontrol); -+ break; ++ si->sb.bustype = bustype; ++ if (si->sb.bustype != BUSTYPE(si->sb.bustype)) { ++ SB_ERROR(("sb_doattach: bus type %d does not match configured bus type %d\n", ++ si->sb.bustype, BUSTYPE(si->sb.bustype))); ++ return NULL; ++ } + -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpiocontrol); -+ break; ++ /* need to set memseg flag for CF card first before any sb registers access */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) ++ si->memseg = TRUE; + -+ case SB_EXTIF: -+ return (0); ++ /* kludge to enable the clock on the 4306 which lacks a slowclock */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) ++ sb_clkctl_xtal(&si->sb, XTAL|PLL, ON); ++ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32)); ++ if (!GOODCOREADDR(w)) ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32), SB_ENUM_BASE); + } + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); -+} ++ /* initialize current core index value */ ++ si->curidx = _sb_coreidx(si); + -+/* mask&set gpio output enable bits */ -+uint32 -+sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) -+{ -+ sb_info_t *si; -+ uint regoff; ++ if (si->curidx == BADIDX) { ++ SB_ERROR(("sb_doattach: bad core index\n")); ++ return NULL; ++ } + -+ si = SB_INFO(sbh); -+ regoff = 0; ++ /* get sonics backplane revision */ ++ sb = REGS2SB(si->curmap); ++ si->sb.sonicsrev = (R_SBREG(si, &sb->sbidlow) & SBIDL_RV_MASK) >> SBIDL_RV_SHIFT; + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ /* keep and reuse the initial register mapping */ ++ origidx = si->curidx; ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ si->regs[origidx] = regs; + -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; ++ /* is core-0 a chipcommon core? */ ++ si->numcores = 1; ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, 0); ++ if (sb_coreid(&si->sb) != SB_CC) ++ cc = NULL; ++ ++ /* determine chip id and rev */ ++ if (cc) { ++ /* chip common core found! */ ++ si->sb.chip = R_REG(si->osh, &cc->chipid) & CID_ID_MASK; ++ si->sb.chiprev = (R_REG(si->osh, &cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; ++ si->sb.chippkg = (R_REG(si->osh, &cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; ++ } else { ++ /* no chip common core -- must convert device id to chip id */ ++ if ((si->sb.chip = sb_pcidev2chip(devid)) == 0) { ++ SB_ERROR(("sb_doattach: unrecognized device id 0x%04x\n", devid)); ++ sb_setcoreidx(&si->sb, origidx); ++ return NULL; ++ } + } + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpioouten); -+ break; ++ /* get chipcommon rev */ ++ si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV; + -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpioouten); -+ break; ++ /* determine numcores */ ++ if (cc && ((si->sb.ccrev == 4) || (si->sb.ccrev >= 6))) ++ si->numcores = (R_REG(si->osh, &cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; ++ else ++ si->numcores = sb_chip2numcores(si->sb.chip); + -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpio[0].outen); -+ break; ++ /* return to original core */ ++ sb_setcoreidx(&si->sb, origidx); ++ ++ /* sanity checks */ ++ ASSERT(si->sb.chip); ++ ++ /* scan for cores */ ++ sb_scan(si); ++ ++ /* fixup necessary chip/core configurations */ ++ if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ if (sb_pci_fixcfg(si)) { ++ SB_ERROR(("sb_doattach: sb_pci_fixcfg failed\n")); ++ return NULL; ++ } ++ } ++ ++ /* srom_var_init() depends on sb_scan() info */ ++ if (srom_var_init(si, si->sb.bustype, si->curmap, si->osh, vars, varsz)) { ++ SB_ERROR(("sb_doattach: srom_var_init failed: bad srom\n")); ++ return (NULL); ++ } ++ ++ if (cc == NULL) { ++ /* ++ * The chip revision number is hardwired into all ++ * of the pci function config rev fields and is ++ * independent from the individual core revision numbers. ++ * For example, the "A0" silicon of each chip is chip rev 0. ++ * For PCMCIA we get it from the CIS instead. ++ */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++ ASSERT(vars); ++ si->sb.chiprev = getintvar(*vars, "chiprev"); ++ } else if (BUSTYPE(si->sb.bustype) == PCI_BUS) { ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_REV, sizeof(uint32)); ++ si->sb.chiprev = w & 0xff; ++ } else ++ si->sb.chiprev = 0; + } + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); -+} -+ -+/* mask&set gpio output bits */ -+uint32 -+sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) -+{ -+ sb_info_t *si; -+ uint regoff; -+ -+ si = SB_INFO(sbh); -+ regoff = 0; -+ -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { ++ w = getintvar(*vars, "regwindowsz"); ++ si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; ++ } + -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; ++ /* gpio control core is required */ ++ if (!GOODIDX(si->gpioidx)) { ++ SB_ERROR(("sb_doattach: gpio control core not found\n")); ++ return NULL; + } + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpioout); ++ /* get boardtype and boardrev */ ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ /* do a pci config read to get subsystem id and subvendor id */ ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_SVID, sizeof(uint32)); ++ si->sb.boardvendor = w & 0xffff; ++ si->sb.boardtype = (w >> 16) & 0xffff; + break; + -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpioout); ++ case PCMCIA_BUS: ++ case SDIO_BUS: ++ si->sb.boardvendor = getintvar(*vars, "manfid"); ++ si->sb.boardtype = getintvar(*vars, "prodid"); + break; + -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpio[0].out); ++ case SB_BUS: ++ case JTAG_BUS: ++ si->sb.boardvendor = VENDOR_BROADCOM; ++ if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0) ++ si->sb.boardtype = 0xffff; + break; + } + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); -+} -+ -+/* reserve one gpio */ -+uint32 -+sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) -+{ -+ sb_info_t *si; -+ -+ si = SB_INFO(sbh); -+ -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ if (si->sb.boardtype == 0) { ++ SB_ERROR(("sb_doattach: unknown board type\n")); ++ ASSERT(si->sb.boardtype); ++ } + -+ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ -+ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { -+ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); -+ return -1; ++ /* setup the GPIO based LED powersave register */ ++ if (si->sb.ccrev >= 16) { ++ if ((vars == NULL) || ((w = getintvar(*vars, "leddc")) == 0)) ++ w = DEFAULT_GPIOTIMERVAL; ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), ~0, w); + } -+ /* make sure only one bit is set */ -+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { -+ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); -+ return -1; ++ if ((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev <= 1)) { ++ /* set proper clk setup delays before forcing HT */ ++ sb_clkctl_init((void *)si); ++ sb_corereg((void*)si, SB_CC_IDX, OFFSETOF(chipcregs_t, system_clk_ctl), ++ SYCC_HR, SYCC_HR); + } + -+ /* already reserved */ -+ if (sb_gpioreservation & gpio_bitmask) -+ return -1; -+ /* set reservation */ -+ sb_gpioreservation |= gpio_bitmask; + -+ return sb_gpioreservation; ++ return (si); +} + -+/* release one gpio */ -+/* -+ * releasing the gpio doesn't change the current value on the GPIO last write value -+ * persists till some one overwrites it -+*/ -+ -+uint32 -+sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) ++uint ++sb_coreid(sb_t *sbh) +{ + sb_info_t *si; ++ sbconfig_t *sb; + + si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); + -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ -+ -+ /* only cores on SB_BUS share GPIO's and only applcation users need to reserve/release GPIO */ -+ if ( (BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { -+ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); -+ return -1; -+ } -+ /* make sure only one bit is set */ -+ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { -+ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); -+ return -1; -+ } -+ -+ /* already released */ -+ if (!(sb_gpioreservation & gpio_bitmask)) -+ return -1; -+ -+ /* clear reservation */ -+ sb_gpioreservation &= ~gpio_bitmask; -+ -+ return sb_gpioreservation; ++ return ((R_SBREG(si, &sb->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); +} + -+/* return the current gpioin register value */ -+uint32 -+sb_gpioin(sb_t *sbh) ++uint ++sb_coreidx(sb_t *sbh) +{ + sb_info_t *si; -+ uint regoff; + + si = SB_INFO(sbh); -+ regoff = 0; -+ -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpioin); -+ break; -+ -+ case SB_PCI: -+ regoff = OFFSETOF(sbpciregs_t, gpioin); -+ break; -+ -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpioin); -+ break; -+ } -+ -+ return (sb_corereg(si, si->gpioidx, regoff, 0, 0)); ++ return (si->curidx); +} + -+/* mask&set gpio interrupt polarity bits */ -+uint32 -+sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) ++/* return current index of core */ ++static uint ++_sb_coreidx(sb_info_t *si) +{ -+ sb_info_t *si; -+ uint regoff; -+ -+ si = SB_INFO(sbh); -+ regoff = 0; -+ -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ -+ -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; -+ } ++ sbconfig_t *sb; ++ uint32 sbaddr = 0; + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); -+ break; ++ ASSERT(si); + -+ case SB_PCI: -+ /* pci gpio implementation does not support interrupt polarity */ -+ ASSERT(0); ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ sb = REGS2SB(si->curmap); ++ sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0)); + break; + -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpiointpolarity); ++ case PCI_BUS: ++ sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32)); + break; -+ } + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); -+} -+ -+/* mask&set gpio interrupt mask bits */ -+uint32 -+sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) -+{ -+ sb_info_t *si; -+ uint regoff; -+ -+ si = SB_INFO(sbh); -+ regoff = 0; -+ -+ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ case PCMCIA_BUS: { ++ uint8 tmp = 0; + -+ /* gpios could be shared on router platforms */ -+ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { -+ mask = priority ? (sb_gpioreservation & mask) : -+ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); -+ val &= mask; ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); ++ sbaddr = (uint)tmp << 12; ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); ++ sbaddr |= (uint)tmp << 16; ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); ++ sbaddr |= (uint)tmp << 24; ++ break; + } + -+ switch (si->gpioid) { -+ case SB_CC: -+ regoff = OFFSETOF(chipcregs_t, gpiointmask); ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ sbaddr = (uint32)si->curmap; + break; ++#endif /* BCMJTAG */ + -+ case SB_PCI: -+ /* pci gpio implementation does not support interrupt mask */ ++ default: + ASSERT(0); -+ break; -+ -+ case SB_EXTIF: -+ regoff = OFFSETOF(extifregs_t, gpiointmask); -+ break; + } + -+ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++ if (!GOODCOREADDR(sbaddr)) ++ return BADIDX; ++ ++ return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE); +} + -+/* assign the gpio to an led */ -+uint32 -+sb_gpioled(sb_t *sbh, uint32 mask, uint32 val) ++uint ++sb_corevendor(sb_t *sbh) +{ + sb_info_t *si; ++ sbconfig_t *sb; + + si = SB_INFO(sbh); -+ if (si->sb.ccrev < 16) -+ return -1; ++ sb = REGS2SB(si->curmap); + -+ /* gpio led powersave reg */ -+ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); ++ return ((R_SBREG(si, &sb->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); +} + -+/* mask&set gpio timer val */ -+uint32 -+sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval) ++uint ++sb_corerev(sb_t *sbh) +{ + sb_info_t *si; -+ si = SB_INFO(sbh); ++ sbconfig_t *sb; ++ uint sbidh; + -+ if (si->sb.ccrev < 16) -+ return -1; ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); ++ sbidh = R_SBREG(si, &sb->sbidhigh); + -+ return(sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); ++ return (SBCOREREV(sbidh)); +} + ++void * ++sb_osh(sb_t *sbh) ++{ ++ sb_info_t *si; + -+/* return the slow clock source - LPO, XTAL, or PCI */ -+static uint -+sb_slowclk_src(sb_info_t *si) -+{ -+ chipcregs_t *cc; -+ -+ -+ ASSERT(sb_coreid(&si->sb) == SB_CC); -+ -+ if (si->sb.ccrev < 6) { -+ if ((BUSTYPE(si->sb.bustype) == PCI_BUS) -+ && (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)) & PCI_CFG_GPIO_SCS)) -+ return (SCC_SS_PCI); -+ else -+ return (SCC_SS_XTAL); -+ } else if (si->sb.ccrev < 10) { -+ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); -+ return (R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK); -+ } else /* Insta-clock */ -+ return (SCC_SS_XTAL); ++ si = SB_INFO(sbh); ++ return si->osh; +} + -+/* return the ILP (slowclock) min or max frequency */ -+static uint -+sb_slowclk_freq(sb_info_t *si, bool max) ++void ++sb_setosh(sb_t *sbh, osl_t *osh) +{ -+ chipcregs_t *cc; -+ uint32 slowclk; -+ uint div; ++ sb_info_t *si; + ++ si = SB_INFO(sbh); ++ if (si->osh != NULL) { ++ SB_ERROR(("osh is already set....\n")); ++ ASSERT(!si->osh); ++ } ++ si->osh = osh; ++} + -+ ASSERT(sb_coreid(&si->sb) == SB_CC); ++/* set/clear sbtmstatelow core-specific flags */ ++uint32 ++sb_coreflags(sb_t *sbh, uint32 mask, uint32 val) ++{ ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; + -+ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); + -+ /* shouldn't be here unless we've established the chip has dynamic clk control */ -+ ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL); ++ ASSERT((val & ~mask) == 0); + -+ slowclk = sb_slowclk_src(si); -+ if (si->sb.ccrev < 6) { -+ if (slowclk == SCC_SS_PCI) -+ return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64)); -+ else -+ return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32)); -+ } else if (si->sb.ccrev < 10) { -+ div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); -+ if (slowclk == SCC_SS_LPO) -+ return (max? LPOMAXFREQ : LPOMINFREQ); -+ else if (slowclk == SCC_SS_XTAL) -+ return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); -+ else if (slowclk == SCC_SS_PCI) -+ return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); -+ else -+ ASSERT(0); -+ } else { -+ /* Chipc rev 10 is InstaClock */ -+ div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; -+ div = 4 * (div + 1); -+ return (max ? XTALMAXFREQ : (XTALMINFREQ/div)); ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatelow, w); + } -+ return (0); ++ ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatelow)); +} + -+static void -+sb_clkctl_setdelay(sb_info_t *si, void *chipcregs) ++/* set/clear sbtmstatehigh core-specific flags */ ++uint32 ++sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val) +{ -+ chipcregs_t * cc; -+ uint slowmaxfreq, pll_delay, slowclk; -+ uint pll_on_delay, fref_sel_delay; -+ -+ pll_delay = PLL_DELAY; ++ sb_info_t *si; ++ sbconfig_t *sb; ++ uint32 w; + -+ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay -+ * since the xtal will also be powered down by dynamic clk control logic. -+ */ -+ slowclk = sb_slowclk_src(si); -+ if (slowclk != SCC_SS_XTAL) -+ pll_delay += XTAL_ON_DELAY; ++ si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); + -+ /* Starting with 4318 it is ILP that is used for the delays */ -+ slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE); ++ ASSERT((val & ~mask) == 0); ++ ASSERT((mask & ~SBTMH_FL_MASK) == 0); + -+ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; -+ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; ++ /* mask and set */ ++ if (mask || val) { ++ w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatehigh, w); ++ } + -+ cc = (chipcregs_t *)chipcregs; -+ W_REG(&cc->pll_on_delay, pll_on_delay); -+ W_REG(&cc->fref_sel_delay, fref_sel_delay); ++ /* return the new value */ ++ return (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_FL_MASK); +} + ++/* Run bist on current core. Caller needs to take care of core-specific bist hazards */ +int -+sb_pwrctl_slowclk(void *sbh, bool set, uint *div) ++sb_corebist(sb_t *sbh) +{ ++ uint32 sblo; + sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; -+ uint intr_val = 0; -+ uint err = 0; -+ ++ sbconfig_t *sb; ++ int result = 0; ++ + si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); + -+ /* chipcommon cores prior to rev6 don't support slowclkcontrol */ -+ if (si->sb.ccrev < 6) -+ return 1; ++ sblo = R_SBREG(si, &sb->sbtmstatelow); ++ W_SBREG(si, &sb->sbtmstatelow, (sblo | SBTML_FGC | SBTML_BE)); + -+ /* chipcommon cores rev10 are a whole new ball game */ -+ if (si->sb.ccrev >= 10) -+ return 1; ++ SPINWAIT(((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BISTD) == 0), 100000); + -+ if (set && ((*div % 4) || (*div < 4))) -+ return 2; -+ -+ INTR_OFF(si, intr_val); -+ origidx = si->curidx; -+ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); -+ ASSERT(cc != NULL); -+ -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) { -+ err = 3; -+ goto done; -+ } ++ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BISTF) ++ result = BCME_ERROR; + -+ if (set) { -+ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHIFT)); -+ sb_clkctl_setdelay(sbh, (void *)cc); -+ } else -+ *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ W_SBREG(si, &sb->sbtmstatelow, sblo); + -+done: -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return err; ++ return result; +} + -+/* initialize power control delay registers */ -+void sb_clkctl_init(sb_t *sbh) ++bool ++sb_iscoreup(sb_t *sbh) +{ + sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; ++ sbconfig_t *sb; + + si = SB_INFO(sbh); ++ sb = REGS2SB(si->curmap); + -+ origidx = si->curidx; ++ return ((R_SBREG(si, &sb->sbtmstatelow) & ++ (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK); ++} + -+ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) -+ return; ++/* ++ * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, ++ * switch back to the original core, and return the new value. ++ * ++ * When using the silicon backplane, no fidleing with interrupts or core switches are needed. ++ * ++ * Also, when using pci/pcie, we can optimize away the core switching for pci registers ++ * and (on newer pci cores) chipcommon registers. ++ */ ++static uint ++sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val) ++{ ++ uint origidx = 0; ++ uint32 *r = NULL; ++ uint w; ++ uint intr_val = 0; ++ bool fast = FALSE; + -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) -+ goto done; ++ ASSERT(GOODIDX(coreidx)); ++ ASSERT(regoff < SB_CORE_SIZE); ++ ASSERT((val & ~mask) == 0); + -+ /* 4317pc does not work with SlowClock less than 5 MHz */ -+ if ((BUSTYPE(si->sb.bustype) == PCMCIA_BUS) && (si->sb.ccrev >= 6) && (si->sb.ccrev < 10)) -+ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (ILP_DIV_5MHZ << SCC_CD_SHIFT)); ++#ifdef notyet ++ if (si->sb.bustype == SB_BUS) { ++ /* If internal bus, we can always get at everything */ ++ fast = TRUE; ++ r = (uint32 *)((uchar *)si->regs[coreidx] + regoff); ++ } else if (si->sb.bustype == PCI_BUS) { ++ /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ ++ ++ if ((si->coreid[coreidx] == SB_CC) && ++ ((si->sb.buscoretype == SB_PCIE) || ++ (si->sb.buscorerev >= 13))) { ++ /* Chipc registers are mapped at 12KB */ ++ ++ fast = TRUE; ++ r = (uint32 *)((char *)si->curmap + PCI_16KB0_CCREGS_OFFSET + regoff); ++ } else if (si->sb.buscoreidx == coreidx) { ++ /* pci registers are at either in the last 2KB of an 8KB window ++ * or, in pcie and pci rev 13 at 8KB ++ */ ++ fast = TRUE; ++ if ((si->sb.buscoretype == SB_PCIE) || ++ (si->sb.buscorerev >= 13)) ++ r = (uint32 *)((char *)si->curmap + ++ PCI_16KB0_PCIREGS_OFFSET + regoff); ++ else ++ r = (uint32 *)((char *)si->curmap + ++ ((regoff >= SBCONFIGOFF) ? ++ PCI_BAR0_PCISBR_OFFSET : PCI_BAR0_PCIREGS_OFFSET) + ++ regoff); ++ } ++ } ++#endif /* notyet */ + -+ /* set all Instaclk chip ILP to 1 MHz */ -+ else if (si->sb.ccrev >= 10) -+ SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); -+ -+ sb_clkctl_setdelay(si, (void *)cc); ++ if (!fast) { ++ INTR_OFF(si, intr_val); + -+done: -+ sb_setcoreidx(sbh, origidx); -+} -+void sb_pwrctl_init(sb_t *sbh) -+{ -+sb_clkctl_init(sbh); -+} -+/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ -+uint16 -+sb_clkctl_fast_pwrup_delay(sb_t *sbh) -+{ -+ sb_info_t *si; -+ uint origidx; -+ chipcregs_t *cc; -+ uint slowminfreq; -+ uint16 fpdelay; -+ uint intr_val = 0; ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); + -+ si = SB_INFO(sbh); -+ fpdelay = 0; -+ origidx = si->curidx; ++ /* switch core */ ++ r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff); ++ } ++ ASSERT(r); + -+ INTR_OFF(si, intr_val); ++ /* mask and set */ ++ if (mask || val) { ++ if (regoff >= SBCONFIGOFF) { ++ w = (R_SBREG(si, r) & ~mask) | val; ++ W_SBREG(si, r, w); ++ } else { ++ w = (R_REG(si->osh, r) & ~mask) | val; ++ W_REG(si->osh, r, w); ++ } ++ } + -+ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) -+ goto done; ++ /* readback */ ++ if (regoff >= SBCONFIGOFF) ++ w = R_SBREG(si, r); ++ else ++ w = R_REG(si->osh, r); + -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) -+ goto done; ++ if (!fast) { ++ /* restore core index */ ++ if (origidx != coreidx) ++ sb_setcoreidx(&si->sb, origidx); + -+ slowminfreq = sb_slowclk_freq(si, FALSE); -+ fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; ++ INTR_RESTORE(si, intr_val); ++ } + -+done: -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return (fpdelay); -+} -+uint16 sb_pwrctl_fast_pwrup_delay(sb_t *sbh) -+{ -+return sb_clkctl_fast_pwrup_delay(sbh); ++ return (w); +} -+/* turn primary xtal and/or pll off/on */ -+int -+sb_clkctl_xtal(sb_t *sbh, uint what, bool on) -+{ -+ sb_info_t *si; -+ uint32 in, out, outen; + -+ si = SB_INFO(sbh); ++#define DWORD_ALIGN(x) (x & ~(0x03)) ++#define BYTE_POS(x) (x & 0x3) ++#define WORD_POS(x) (x & 0x1) + -+ switch (BUSTYPE(si->sb.bustype)) { ++#define BYTE_SHIFT(x) (8 * BYTE_POS(x)) ++#define WORD_SHIFT(x) (16 * WORD_POS(x)) + ++#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF) ++#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF) + -+ case PCMCIA_BUS: -+ return (0); ++#define read_pci_cfg_byte(a) \ ++ (BYTE_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xff) + ++#define read_pci_cfg_write(a) \ ++ (WORD_VAL(OSL_PCI_READ_CONFIG(si->osh, DWORD_ALIGN(a), 4), a) & 0xffff) + -+ case PCI_BUS: + -+ /* pcie core doesn't have any mapping to control the xtal pu */ -+ if (PCIE(si)) -+ return -1; ++/* return TRUE if requested capability exists in the PCI config space */ ++static bool ++sb_find_pci_capability(sb_info_t *si, uint8 req_cap_id, uchar *buf, uint32 *buflen) ++{ ++ uint8 cap_id; ++ uint8 cap_ptr; ++ uint32 bufsize; ++ uint8 byte_val; ++ ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) ++ return FALSE; + -+ in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof (uint32)); -+ out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)); -+ outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32)); ++ /* check for Header type 0 */ ++ byte_val = read_pci_cfg_byte(PCI_CFG_HDR); ++ if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) ++ return FALSE; + -+ /* -+ * Avoid glitching the clock if GPRS is already using it. -+ * We can't actually read the state of the PLLPD so we infer it -+ * by the value of XTAL_PU which *is* readable via gpioin. -+ */ -+ if (on && (in & PCI_CFG_GPIO_XTAL)) -+ return (0); ++ /* check if the capability pointer field exists */ ++ byte_val = read_pci_cfg_byte(PCI_CFG_STAT); ++ if (!(byte_val & PCI_CAPPTR_PRESENT)) ++ return FALSE; ++ ++ cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR); ++ /* check if the capability pointer is 0x00 */ ++ if (cap_ptr == 0x00) ++ return FALSE; + -+ if (what & XTAL) -+ outen |= PCI_CFG_GPIO_XTAL; -+ if (what & PLL) -+ outen |= PCI_CFG_GPIO_PLL; + -+ if (on) { -+ /* turn primary xtal on */ -+ if (what & XTAL) { -+ out |= PCI_CFG_GPIO_XTAL; -+ if (what & PLL) -+ out |= PCI_CFG_GPIO_PLL; -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); -+ OSL_DELAY(XTAL_ON_DELAY); -+ } ++ /* loop thr'u the capability list and see if the pcie capabilty exists */ + -+ /* turn pll on */ -+ if (what & PLL) { -+ out &= ~PCI_CFG_GPIO_PLL; -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); -+ OSL_DELAY(2000); -+ } -+ } else { -+ if (what & XTAL) -+ out &= ~PCI_CFG_GPIO_XTAL; -+ if (what & PLL) -+ out |= PCI_CFG_GPIO_PLL; -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); -+ } ++ cap_id = read_pci_cfg_byte(cap_ptr); + -+ default: -+ return (-1); ++ while (cap_id != req_cap_id) { ++ cap_ptr = read_pci_cfg_byte((cap_ptr+1)); ++ if (cap_ptr == 0x00) break; ++ cap_id = read_pci_cfg_byte(cap_ptr); + } -+ -+ return (0); ++ if (cap_id != req_cap_id) { ++ return FALSE; ++ } ++ /* found the caller requested capability */ ++ if ((buf != NULL) && (buflen != NULL)) { ++ bufsize = *buflen; ++ if (!bufsize) goto end; ++ *buflen = 0; ++ /* copy the cpability data excluding cap ID and next ptr */ ++ cap_ptr += 2; ++ if ((bufsize + cap_ptr) > SZPCR) ++ bufsize = SZPCR - cap_ptr; ++ *buflen = bufsize; ++ while (bufsize--) { ++ *buf = read_pci_cfg_byte(cap_ptr); ++ cap_ptr++; ++ buf++; ++ } ++ } ++end: ++ return TRUE; +} + -+int sb_pwrctl_xtal(sb_t *sbh, uint what, bool on) ++/* return TRUE if PCIE capability exists the pci config space */ ++static inline bool ++sb_ispcie(sb_info_t *si) +{ -+return sb_clkctl_xtal(sbh,what,on); ++ return (sb_find_pci_capability(si, PCI_CAP_PCIECAP_ID, NULL, NULL)); +} + -+/* set dynamic clk control mode (forceslow, forcefast, dynamic) */ -+/* returns true if ignore pll off is set and false if it is not */ -+bool -+sb_clkctl_clk(sb_t *sbh, uint mode) ++/* scan the sb enumerated space to identify all cores */ ++static void ++BCMINITFN(sb_scan)(sb_info_t *si) +{ -+ sb_info_t *si; + uint origidx; -+ chipcregs_t *cc; -+ uint32 scc; -+ bool forcefastclk=FALSE; -+ uint intr_val = 0; -+ -+ si = SB_INFO(sbh); -+ -+ /* chipcommon cores prior to rev6 don't support dynamic clock control */ -+ if (si->sb.ccrev < 6) -+ return (FALSE); -+ -+ /* chipcommon cores rev10 are a whole new ball game */ -+ if (si->sb.ccrev >= 10) -+ return (FALSE); ++ uint i; ++ bool pci; ++ bool pcie; ++ uint pciidx; ++ uint pcieidx; ++ uint pcirev; ++ uint pcierev; + -+ INTR_OFF(si, intr_val); + -+ origidx = si->curidx; ++ /* numcores should already be set */ ++ ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); + -+ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); -+ ASSERT(cc != NULL); ++ /* save current core index */ ++ origidx = sb_coreidx(&si->sb); + -+ if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) -+ goto done; ++ si->sb.buscorerev = NOREV; ++ si->sb.buscoreidx = BADIDX; + -+ switch (mode) { -+ case CLK_FAST: /* force fast (pll) clock */ -+ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ -+ sb_clkctl_xtal(&si->sb, XTAL, ON); ++ si->gpioidx = BADIDX; + -+ SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); -+ break; ++ pci = pcie = FALSE; ++ pcirev = pcierev = NOREV; ++ pciidx = pcieidx = BADIDX; + -+ case CLK_DYNAMIC: /* enable dynamic clock control */ -+ scc = R_REG(&cc->slow_clk_ctl); -+ scc &= ~(SCC_FS | SCC_IP | SCC_XC); -+ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) -+ scc |= SCC_XC; -+ W_REG(&cc->slow_clk_ctl, scc); -+ -+ /* for dynamic control, we have to release our xtal_pu "force on" */ -+ if (scc & SCC_XC) -+ sb_clkctl_xtal(&si->sb, XTAL, OFF); -+ break; ++ for (i = 0; i < si->numcores; i++) { ++ sb_setcoreidx(&si->sb, i); ++ si->coreid[i] = sb_coreid(&si->sb); + -+ default: -+ ASSERT(0); ++ if (si->coreid[i] == SB_PCI) { ++ pciidx = i; ++ pcirev = sb_corerev(&si->sb); ++ pci = TRUE; ++ } else if (si->coreid[i] == SB_PCIE) { ++ pcieidx = i; ++ pcierev = sb_corerev(&si->sb); ++ pcie = TRUE; ++ } else if (si->coreid[i] == SB_PCMCIA) { ++ si->sb.buscorerev = sb_corerev(&si->sb); ++ si->sb.buscoretype = si->coreid[i]; ++ si->sb.buscoreidx = i; ++ } ++ } ++ if (pci && pcie) { ++ if (sb_ispcie(si)) ++ pci = FALSE; ++ else ++ pcie = FALSE; ++ } ++ if (pci) { ++ si->sb.buscoretype = SB_PCI; ++ si->sb.buscorerev = pcirev; ++ si->sb.buscoreidx = pciidx; ++ } else if (pcie) { ++ si->sb.buscoretype = SB_PCIE; ++ si->sb.buscorerev = pcierev; ++ si->sb.buscoreidx = pcieidx; + } + -+ /* Is the h/w forcing the use of the fast clk */ -+ forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP); ++ /* ++ * Find the gpio "controlling core" type and index. ++ * Precedence: ++ * - if there's a chip common core - use that ++ * - else if there's a pci core (rev >= 2) - use that ++ * - else there had better be an extif core (4710 only) ++ */ ++ if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) { ++ si->gpioidx = sb_findcoreidx(si, SB_CC, 0); ++ si->gpioid = SB_CC; ++ } else if (PCI(si) && (si->sb.buscorerev >= 2)) { ++ si->gpioidx = si->sb.buscoreidx; ++ si->gpioid = SB_PCI; ++ } else if (sb_findcoreidx(si, SB_EXTIF, 0)) { ++ si->gpioidx = sb_findcoreidx(si, SB_EXTIF, 0); ++ si->gpioid = SB_EXTIF; ++ } else ++ ASSERT(si->gpioidx != BADIDX); + -+done: -+ sb_setcoreidx(sbh, origidx); -+ INTR_RESTORE(si, intr_val); -+ return (forcefastclk); ++ /* return to original core index */ ++ sb_setcoreidx(&si->sb, origidx); +} + -+bool sb_pwrctl_clk(sb_t *sbh, uint mode) -+{ -+return sb_clkctl_clk(sbh, mode); -+} -+/* register driver interrupt disabling and restoring callback functions */ ++/* may be called with core in reset */ +void -+sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) ++sb_detach(sb_t *sbh) +{ + sb_info_t *si; ++ uint idx; + + si = SB_INFO(sbh); -+ si->intr_arg = intr_arg; -+ si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn; -+ si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn; -+ si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn; -+ /* save current core id. when this function called, the current core -+ * must be the core which provides driver functions(il, et, wl, etc.) -+ */ -+ si->dev_coreid = si->coreid[si->curidx]; -+} -+ -+ -+void -+sb_corepciid(sb_t *sbh, uint16 *pcivendor, uint16 *pcidevice, -+ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif) -+{ -+ uint vendor, core, unit; -+ uint chip, chippkg; -+ char varname[8]; -+ uint8 class, subclass, progif; -+ -+ vendor = sb_corevendor(sbh); -+ core = sb_coreid(sbh); -+ unit = sb_coreunit(sbh); -+ -+ chip = BCMINIT(sb_chip)(sbh); -+ chippkg = BCMINIT(sb_chippkg)(sbh); + -+ progif = 0; -+ -+ /* Known vendor translations */ -+ switch (vendor) { -+ case SB_VEND_BCM: -+ vendor = VENDOR_BROADCOM; -+ break; -+ } ++ if (si == NULL) ++ return; + -+ /* Determine class based on known core codes */ -+ switch (core) { -+ case SB_ILINE20: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM47XX_ILINE_ID; -+ break; -+ case SB_ENET: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_ETHER; -+ core = BCM47XX_ENET_ID; -+ break; -+ case SB_SDRAM: -+ case SB_MEMC: -+ class = PCI_CLASS_MEMORY; -+ subclass = PCI_MEMORY_RAM; -+ break; -+ case SB_PCI: -+ case SB_PCIE: -+ class = PCI_CLASS_BRIDGE; -+ subclass = PCI_BRIDGE_PCI; -+ break; -+ case SB_MIPS: -+ case SB_MIPS33: -+ class = PCI_CLASS_CPU; -+ subclass = PCI_CPU_MIPS; -+ break; -+ case SB_CODEC: -+ class = PCI_CLASS_COMM; -+ subclass = PCI_COMM_MODEM; -+ core = BCM47XX_V90_ID; -+ break; -+ case SB_USB: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ progif = 0x10; /* OHCI */ -+ core = BCM47XX_USB_ID; -+ break; -+ case SB_USB11H: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ progif = 0x10; /* OHCI */ -+ core = BCM47XX_USBH_ID; -+ break; -+ case SB_USB11D: -+ class = PCI_CLASS_SERIAL; -+ subclass = PCI_SERIAL_USB; -+ core = BCM47XX_USBD_ID; -+ break; -+ case SB_IPSEC: -+ class = PCI_CLASS_CRYPT; -+ subclass = PCI_CRYPT_NETWORK; -+ core = BCM47XX_IPSEC_ID; -+ break; -+ case SB_ROBO: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_OTHER; -+ core = BCM47XX_ROBO_ID; -+ break; -+ case SB_EXTIF: -+ case SB_CC: -+ class = PCI_CLASS_MEMORY; -+ subclass = PCI_MEMORY_FLASH; -+ break; -+ case SB_D11: -+ class = PCI_CLASS_NET; -+ subclass = PCI_NET_OTHER; -+ /* Let an nvram variable override this */ -+ sprintf(varname, "wl%did", unit); -+ if ((core = getintvar(NULL, varname)) == 0) { -+ if (chip == BCM4712_DEVICE_ID) { -+ if (chippkg == BCM4712SMALL_PKG_ID) -+ core = BCM4306_D11G_ID; -+ else -+ core = BCM4306_D11DUAL_ID; ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) ++ for (idx = 0; idx < SB_MAXCORES; idx++) ++ if (si->regs[idx]) { ++ REG_UNMAP(si->regs[idx]); ++ si->regs[idx] = NULL; + } -+ } -+ break; ++#if !defined(BCMBUSTYPE) || (BCMBUSTYPE == SB_BUS) ++ if (si != &ksi) ++#endif /* !BCMBUSTYPE || (BCMBUSTYPE == SB_BUS) */ ++ MFREE(si->osh, si, sizeof(sb_info_t)); + -+ default: -+ class = subclass = progif = 0xff; -+ break; -+ } ++} + -+ *pcivendor = (uint16)vendor; -+ *pcidevice = (uint16)core; -+ *pciclass = class; -+ *pcisubclass = subclass; -+ *pciprogif = progif; ++/* use pci dev id to determine chip id for chips not having a chipcommon core */ ++static uint ++BCMINITFN(sb_pcidev2chip)(uint pcidev) ++{ ++ if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) ++ return (BCM4710_CHIP_ID); ++ if ((pcidev >= BCM4402_ENET_ID) && (pcidev <= BCM4402_V90_ID)) ++ return (BCM4402_CHIP_ID); ++ if (pcidev == BCM4401_ENET_ID) ++ return (BCM4402_CHIP_ID); ++ ++ return (0); +} + ++/* convert chip number to number of i/o cores */ ++static uint ++BCMINITFN(sb_chip2numcores)(uint chip) ++{ ++ if (chip == BCM4710_CHIP_ID) ++ return (9); ++ if (chip == BCM4402_CHIP_ID) ++ return (3); ++ if (chip == BCM4306_CHIP_ID) /* < 4306c0 */ ++ return (6); ++ if (chip == BCM4704_CHIP_ID) ++ return (9); ++ if (chip == BCM5365_CHIP_ID) ++ return (7); ++ ++ SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); ++ ASSERT(0); ++ return (1); ++} ++ ++/* return index of coreid or BADIDX if not found */ ++static uint ++sb_findcoreidx(sb_info_t *si, uint coreid, uint coreunit) ++{ ++ uint found; ++ uint i; ++ ++ found = 0; + ++ for (i = 0; i < si->numcores; i++) ++ if (si->coreid[i] == coreid) { ++ if (found == coreunit) ++ return (i); ++ found++; ++ } + ++ return (BADIDX); ++} + -+/* use the mdio interface to write to mdio slaves */ -+static int -+sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val) ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcoreidx(sb_t *sbh, uint coreidx) +{ -+ uint mdiodata; -+ uint i = 0; -+ sbpcieregs_t *pcieregs; ++ sb_info_t *si; ++ uint32 sbaddr; ++ uint8 tmp; + -+ pcieregs = (sbpcieregs_t*) sb_setcoreidx(&si->sb, si->sb.buscoreidx); -+ ASSERT (pcieregs); ++ si = SB_INFO(sbh); ++ ++ if (coreidx >= si->numcores) ++ return (NULL); + -+ /* enable mdio access to SERDES */ -+ W_REG((&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); ++ /* ++ * If the user has provided an interrupt mask enabled function, ++ * then assert interrupts are disabled before switching the core. ++ */ ++ ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg)); + -+ mdiodata = MDIODATA_START | MDIODATA_WRITE | -+ (physmedia << MDIODATA_DEVADDR_SHF) | -+ (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val; ++ sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); + -+ W_REG((&pcieregs->mdiodata), mdiodata); ++ switch (BUSTYPE(si->sb.bustype)) { ++ case SB_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); ++ ASSERT(GOODREGS(si->regs[coreidx])); ++ } ++ si->curmap = si->regs[coreidx]; ++ break; + -+ PR28829_DELAY(); ++ case PCI_BUS: ++ /* point bar0 window */ ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); ++ break; + -+ /* retry till the transaction is complete */ -+ while ( i < 10 ) { -+ if (R_REG(&(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { -+ /* Disable mdio access to SERDES */ -+ W_REG((&pcieregs->mdiocontrol), 0); -+ return 0; ++ case PCMCIA_BUS: ++ tmp = (sbaddr >> 12) & 0x0f; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); ++ tmp = (sbaddr >> 16) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); ++ tmp = (sbaddr >> 24) & 0xff; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); ++ break; ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ /* map new one */ ++ if (!si->regs[coreidx]) { ++ si->regs[coreidx] = (void *)sbaddr; ++ ASSERT(GOODREGS(si->regs[coreidx])); + } -+ OSL_DELAY(1000); -+ i++; ++ si->curmap = si->regs[coreidx]; ++ break; ++#endif /* BCMJTAG */ + } + -+ SB_ERROR(("sb_pcie_mdiowrite: timed out\n")); -+ /* Disable mdio access to SERDES */ -+ W_REG((&pcieregs->mdiocontrol), 0); -+ ASSERT(0); -+ return 1; ++ si->curidx = coreidx; + ++ return (si->curmap); +} + -+/* indirect way to read pcie config regs*/ -+uint -+sb_pcie_readreg(void *sb, void* arg1, uint offset) ++/* ++ * this function changes logical "focus" to the indiciated core, ++ * must be called with interrupt off. ++ * Moreover, callers should keep interrupts off during switching out of and back to d11 core ++ */ ++void* ++sb_setcore(sb_t *sbh, uint coreid, uint coreunit) ++{ ++ sb_info_t *si; ++ uint idx; ++ ++ si = SB_INFO(sbh); ++ idx = sb_findcoreidx(si, coreid, coreunit); ++ if (!GOODIDX(idx)) ++ return (NULL); ++ ++ return (sb_setcoreidx(sbh, idx)); ++} ++ ++/* return chip number */ ++uint ++sb_chip(sb_t *sbh) +{ + sb_info_t *si; -+ sb_t *sbh; -+ uint retval = 0xFFFFFFFF; -+ sbpcieregs_t *pcieregs; -+ uint addrtype; + -+ sbh = (sb_t *)sb; + si = SB_INFO(sbh); -+ ASSERT (PCIE(si)); ++ return (si->sb.chip); ++} + -+ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); -+ ASSERT (pcieregs); ++/* return chip revision number */ ++uint ++sb_chiprev(sb_t *sbh) ++{ ++ sb_info_t *si; + -+ addrtype = (uint)((uintptr)arg1); -+ switch(addrtype) { -+ case PCIE_CONFIGREGS: -+ W_REG((&pcieregs->configaddr),offset); -+ retval = R_REG(&(pcieregs->configdata)); -+ break; -+ case PCIE_PCIEREGS: -+ W_REG(&(pcieregs->pcieaddr),offset); -+ retval = R_REG(&(pcieregs->pciedata)); -+ break; -+ default: -+ ASSERT(0); -+ break; -+ } -+ return retval; ++ si = SB_INFO(sbh); ++ return (si->sb.chiprev); +} + -+/* indirect way to write pcie config/mdio/pciecore regs*/ -+uint -+sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val) ++/* return chip common revision number */ ++uint ++sb_chipcrev(sb_t *sbh) +{ + sb_info_t *si; -+ sbpcieregs_t *pcieregs; -+ uint addrtype; + + si = SB_INFO(sbh); -+ ASSERT (PCIE(si)); ++ return (si->sb.ccrev); ++} + -+ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); -+ ASSERT (pcieregs); ++/* return chip package option */ ++uint ++sb_chippkg(sb_t *sbh) ++{ ++ sb_info_t *si; + -+ addrtype = (uint)((uintptr)arg1); ++ si = SB_INFO(sbh); ++ return (si->sb.chippkg); ++} + -+ switch(addrtype) { -+ case PCIE_CONFIGREGS: -+ W_REG((&pcieregs->configaddr),offset); -+ W_REG((&pcieregs->configdata),val); -+ break; -+ case PCIE_PCIEREGS: -+ W_REG((&pcieregs->pcieaddr),offset); -+ W_REG((&pcieregs->pciedata),val); -+ break; -+ default: -+ ASSERT(0); -+ break; -+ } -+ return 0; ++/* return PCI core rev. */ ++uint ++sb_pcirev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.buscorerev); +} + ++bool ++BCMINITFN(sb_war16165)(sb_t *sbh) ++{ ++ sb_info_t *si; + -+/* Build device path. Support SB, PCI, and JTAG for now. */ -+int -+sb_devpath(sb_t *sbh, char *path, int size) ++ si = SB_INFO(sbh); ++ ++ return (PCI(si) && (si->sb.buscorerev <= 10)); ++} ++ ++static void ++BCMINITFN(sb_war30841)(sb_info_t *si) +{ -+ ASSERT(path); -+ ASSERT(size >= SB_DEVPATH_BUFSZ); -+ -+ switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) { -+ case SB_BUS: -+ case JTAG_BUS: -+ sprintf(path, "sb/%u/", sb_coreidx(sbh)); -+ break; -+ case PCI_BUS: -+ ASSERT((SB_INFO(sbh))->osh); -+ sprintf(path, "pci/%u/%u/", OSL_PCI_BUS((SB_INFO(sbh))->osh), -+ OSL_PCI_SLOT((SB_INFO(sbh))->osh)); -+ break; -+ case PCMCIA_BUS: -+ SB_ERROR(("sb_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n")); -+ SB_ERROR(("sb_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n")); -+ sprintf(path, "pc/%u/%u/", 1, 1); -+ break; -+ case SDIO_BUS: -+ SB_ERROR(("sb_devpath: device 0 assumed\n")); -+ sprintf(path, "sd/%u/", sb_coreidx(sbh)); -+ break; -+ default: -+ ASSERT(0); -+ break; -+ } ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_TIMER1, 0x8128); ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDR, 0x0100); ++ sb_pcie_mdiowrite(si, MDIODATA_DEV_RX, SERDES_RX_CDRBW, 0x1466); ++} + -+ return 0; ++/* return PCMCIA core rev. */ ++uint ++BCMINITFN(sb_pcmciarev)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ ++ si = SB_INFO(sbh); ++ return (si->sb.buscorerev); +} + -+/* Fix chip's configuration. The current core may be changed upon return */ -+static int -+sb_pci_fixcfg(sb_info_t *si) ++/* return board vendor id */ ++uint ++sb_boardvendor(sb_t *sbh) +{ -+ uint origidx, pciidx; -+ sbpciregs_t *pciregs; -+ sbpcieregs_t *pcieregs; -+ uint16 val16, *reg16; -+ char name[SB_DEVPATH_BUFSZ+16], *value; -+ char devpath[SB_DEVPATH_BUFSZ]; ++ sb_info_t *si; + -+ ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS); ++ si = SB_INFO(sbh); ++ return (si->sb.boardvendor); ++} ++ ++/* return boardtype */ ++uint ++sb_boardtype(sb_t *sbh) ++{ ++ sb_info_t *si; ++ char *var; + -+ /* Fix PCI(e) SROM shadow area */ -+ /* save the current index */ -+ origidx = sb_coreidx(&si->sb); ++ si = SB_INFO(sbh); + -+ /* check 'pi' is correct and fix it if not */ -+ if (si->sb.buscoretype == SB_PCIE) { -+ pcieregs = (sbpcieregs_t *)sb_setcore(&si->sb, SB_PCIE, 0); -+ ASSERT(pcieregs); -+ reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; -+ } -+ else if (si->sb.buscoretype == SB_PCI) { -+ pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0); -+ ASSERT(pciregs); -+ reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; -+ } -+ else { -+ ASSERT(0); -+ return -1; -+ } -+ pciidx = sb_coreidx(&si->sb); -+ val16 = R_REG(reg16); -+ if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) { -+ val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK); -+ W_REG(reg16, val16); -+ } ++ if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) { ++ /* boardtype format is a hex string */ ++ si->sb.boardtype = getintvar(NULL, "boardtype"); + -+ /* restore the original index */ -+ sb_setcoreidx(&si->sb, origidx); -+ -+ /* Fix bar0window */ -+ /* !do it last, it changes the current core! */ -+ if (sb_devpath(&si->sb, devpath, sizeof(devpath))) -+ return -1; -+ sprintf(name, "%sb0w", devpath); -+ if ((value = getvar(NULL, name))) { -+ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32), -+ bcm_strtoul(value, NULL, 16)); -+ /* update curidx since the current core is changed */ -+ si->curidx = _sb_coreidx(si); -+ if (si->curidx == BADIDX) { -+ SB_ERROR(("sb_pci_fixcfg: bad core index\n")); -+ return -1; ++ /* backward compatibility for older boardtype string format */ ++ if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) { ++ if (!strcmp(var, "bcm94710dev")) ++ si->sb.boardtype = BCM94710D_BOARD; ++ else if (!strcmp(var, "bcm94710ap")) ++ si->sb.boardtype = BCM94710AP_BOARD; ++ else if (!strcmp(var, "bu4710")) ++ si->sb.boardtype = BU4710_BOARD; ++ else if (!strcmp(var, "bcm94702mn")) ++ si->sb.boardtype = BCM94702MN_BOARD; ++ else if (!strcmp(var, "bcm94710r1")) ++ si->sb.boardtype = BCM94710R1_BOARD; ++ else if (!strcmp(var, "bcm94710r4")) ++ si->sb.boardtype = BCM94710R4_BOARD; ++ else if (!strcmp(var, "bcm94702cpci")) ++ si->sb.boardtype = BCM94702CPCI_BOARD; ++ else if (!strcmp(var, "bcm95380_rr")) ++ si->sb.boardtype = BCM95380RR_BOARD; + } + } + -+ return 0; ++ return (si->sb.boardtype); +} + -diff -Naur linux.old/drivers/net/hnd/shared_ksyms.sh linux.dev/drivers/net/hnd/shared_ksyms.sh ---- linux.old/drivers/net/hnd/shared_ksyms.sh 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/hnd/shared_ksyms.sh 2006-04-06 15:34:15.000000000 +0200 -@@ -0,0 +1,21 @@ -+#!/bin/sh -+# -+# Copyright 2004, Broadcom Corporation -+# All Rights Reserved. -+# -+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+# -+# $Id: shared_ksyms.sh,v 1.1 2005/03/16 13:50:00 wbx Exp $ -+# -+ -+cat < -+#include -+EOF -+ -+for file in $* ; do -+ ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p' -+done -diff -Naur linux.old/drivers/net/wireless/Config.in linux.dev/drivers/net/wireless/Config.in ---- linux.old/drivers/net/wireless/Config.in 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/drivers/net/wireless/Config.in 2006-04-06 17:04:48.000000000 +0200 -@@ -13,6 +13,8 @@ - fi - - if [ "$CONFIG_PCI" = "y" ]; then -+ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support (old)' CONFIG_WL -+ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support (new)' CONFIG_WL2 - dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL - dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL - dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL -diff -Naur linux.old/drivers/net/wl/Makefile linux.dev/drivers/net/wl/Makefile ---- linux.old/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/Makefile 2006-04-06 16:56:38.000000000 +0200 -@@ -0,0 +1,27 @@ -+# -+# Makefile for the Broadcom wl driver -+# -+# Copyright 2004, Broadcom Corporation -+# All Rights Reserved. -+# -+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+# -+# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ ++/* return bus type of sbh device */ ++uint ++sb_bus(sb_t *sbh) ++{ ++ sb_info_t *si; + -+EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER ++ si = SB_INFO(sbh); ++ return (si->sb.bustype); ++} + -+O_TARGET := wl.o ++/* return bus core type */ ++uint ++sb_buscoretype(sb_t *sbh) ++{ ++ sb_info_t *si; + -+obj-y := apsta_aeskeywrap.o apsta_aes.o apsta_bcmwpa.o apsta_d11ucode.o -+obj-y += apsta_hmac.o apsta_md5.o apsta_passhash.o apsta_prf.o apsta_rc4.o -+obj-y += apsta_rijndael-alg-fst.o apsta_sha1.o apsta_tkhash.o apsta_wlc_led.o -+obj-y += apsta_wlc_phy.o apsta_wlc_rate.o apsta_wlc_security.o -+obj-y += apsta_wlc_sup.o apsta_wlc_wet.o apsta_wl_linux.o apsta_wlc.o -+obj-y += compat.o hnddma.o ++ si = SB_INFO(sbh); + -+obj-m := $(O_TARGET) ++ return (si->sb.buscoretype); ++} + -+include $(TOPDIR)/Rules.make -diff -Naur linux.old/drivers/net/wl/compat.c linux.dev/drivers/net/wl/compat.c ---- linux.old/drivers/net/wl/compat.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/compat.c 2006-04-06 17:12:19.000000000 +0200 -@@ -0,0 +1,237 @@ -+/* -+ * Misc useful OS-independent routines. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ ++/* return bus core revision */ ++uint ++sb_buscorerev(sb_t *sbh) ++{ ++ sb_info_t *si; ++ si = SB_INFO(sbh); + -+#include -+#ifdef BCMDRIVER -+#include -+#include -+#include -+#else -+#include -+#include -+#endif -+#include "pktq.h" -+#include -+#include -+#include ++ return (si->sb.buscorerev); ++} + -+#ifdef BCMDRIVER -+/* copy a pkt buffer chain into a buffer */ ++/* return list of found cores */ +uint -+pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) ++sb_corelist(sb_t *sbh, uint coreid[]) +{ -+ uint n, ret = 0; ++ sb_info_t *si; + -+ if (len < 0) -+ len = 4096; /* "infinite" */ ++ si = SB_INFO(sbh); + -+ /* skip 'offset' bytes */ -+ for (; p && offset; p = PKTNEXT(osh, p)) { -+ if (offset < (uint)PKTLEN(osh, p)) -+ break; -+ offset -= PKTLEN(osh, p); -+ } ++ bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof(uint))); ++ return (si->numcores); ++} + -+ if (!p) -+ return 0; ++/* return current register mapping */ ++void * ++sb_coreregs(sb_t *sbh) ++{ ++ sb_info_t *si; + -+ /* copy the data */ -+ for (; p && len; p = PKTNEXT(osh, p)) { -+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); -+ bcopy(PKTDATA(osh, p) + offset, buf, n); -+ buf += n; -+ len -= n; -+ ret += n; -+ offset = 0; -+ } ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); + -+ return ret; ++ return (si->curmap); +} + -+/* return total length of buffer chain */ -+uint -+pkttotlen(osl_t *osh, void *p) ++ ++/* do buffered registers update */ ++void ++sb_commit(sb_t *sbh) +{ -+ uint total; ++ sb_info_t *si; ++ uint origidx; ++ uint intr_val = 0; + -+ total = 0; -+ for (; p; p = PKTNEXT(osh, p)) -+ total += PKTLEN(osh, p); -+ return (total); -+} ++ si = SB_INFO(sbh); + -+void -+pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]) -+{ -+ q->head = q->tail = NULL; -+ q->maxlen = maxlen; -+ q->len = 0; -+ if (prio_map) { -+ q->priority = TRUE; -+ bcopy(prio_map, q->prio_map, sizeof(q->prio_map)); -+ } -+ else -+ q->priority = FALSE; -+} ++ origidx = si->curidx; ++ ASSERT(GOODIDX(origidx)); ++ ++ INTR_OFF(si, intr_val); ++ ++ /* switch over to chipcommon core if there is one, else use pci */ ++ if (si->sb.ccrev != NOREV) { ++ chipcregs_t *ccregs = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(si->osh, &ccregs->broadcastaddress, SB_COMMIT); ++ W_REG(si->osh, &ccregs->broadcastdata, 0x0); ++ } else if (PCI(si)) { ++ sbpciregs_t *pciregs = (sbpciregs_t *)sb_setcore(sbh, SB_PCI, 0); ++ ++ /* do the buffer registers update */ ++ W_REG(si->osh, &pciregs->bcastaddr, SB_COMMIT); ++ W_REG(si->osh, &pciregs->bcastdata, 0x0); ++ } else ++ ASSERT(0); + ++ /* restore core index */ ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++} + -+/* should always check pktq_full before calling pktenq */ ++/* reset and re-enable a core ++ * inputs: ++ * bits - core specific bits that are set during and after reset sequence ++ * resetbits - core specific bits that are set only during reset sequence ++ */ +void -+pktenq(struct pktq *q, void *p, bool lifo) ++sb_core_reset(sb_t *sbh, uint32 bits, uint32 resetbits) +{ -+ void *next, *prev; ++ sb_info_t *si; ++ sbconfig_t *sb; ++ volatile uint32 dummy; + -+ /* allow 10 pkts slack */ -+ ASSERT(q->len < (q->maxlen + 10)); ++ si = SB_INFO(sbh); ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); + -+ /* Queueing chains not allowed */ -+ ASSERT(PKTLINK(p) == NULL); ++ /* ++ * Must do the disable sequence first to work for arbitrary current core state. ++ */ ++ sb_core_disable(sbh, (bits | resetbits)); + -+ /* Queue is empty */ -+ if (q->tail == NULL) { -+ ASSERT(q->head == NULL); -+ q->head = q->tail = p; -+ } ++ /* ++ * Now do the initialization sequence. ++ */ + -+ /* Insert at head or tail */ -+ else if (q->priority == FALSE) { -+ /* Insert at head (LIFO) */ -+ if (lifo) { -+ PKTSETLINK(p, q->head); -+ q->head = p; -+ } -+ /* Insert at tail (FIFO) */ -+ else { -+ ASSERT(PKTLINK(q->tail) == NULL); -+ PKTSETLINK(q->tail, p); -+ PKTSETLINK(p, NULL); -+ q->tail = p; -+ } -+ } ++ /* set reset while enabling the clock and forcing them on throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits | resetbits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); + -+ /* Insert by priority */ -+ else { -+ /* legal priorities 0-7 */ -+ ASSERT(PKTPRIO(p) <= MAXPRIO); -+ -+ ASSERT(q->head); -+ ASSERT(q->tail); -+ /* Shortcut to insertion at tail */ -+ if (_pktq_pri(q, PKTPRIO(p)) < _pktq_pri(q, PKTPRIO(q->tail)) || -+ (!lifo && _pktq_pri(q, PKTPRIO(p)) <= _pktq_pri(q, PKTPRIO(q->tail)))) { -+ prev = q->tail; -+ next = NULL; -+ } -+ /* Insert at head or in the middle */ -+ else { -+ prev = NULL; -+ next = q->head; -+ } -+ /* Walk the queue */ -+ for (; next; prev = next, next = PKTLINK(next)) { -+ /* Priority queue invariant */ -+ ASSERT(!prev || _pktq_pri(q, PKTPRIO(prev)) >= _pktq_pri(q, PKTPRIO(next))); -+ /* Insert at head of string of packets of same priority (LIFO) */ -+ if (lifo) { -+ if (_pktq_pri(q, PKTPRIO(p)) >= _pktq_pri(q, PKTPRIO(next))) -+ break; -+ } -+ /* Insert at tail of string of packets of same priority (FIFO) */ -+ else { -+ if (_pktq_pri(q, PKTPRIO(p)) > _pktq_pri(q, PKTPRIO(next))) -+ break; -+ } -+ } -+ /* Insert at tail */ -+ if (next == NULL) { -+ ASSERT(PKTLINK(q->tail) == NULL); -+ PKTSETLINK(q->tail, p); -+ PKTSETLINK(p, NULL); -+ q->tail = p; -+ } -+ /* Insert in the middle */ -+ else if (prev) { -+ PKTSETLINK(prev, p); -+ PKTSETLINK(p, next); -+ } -+ /* Insert at head */ -+ else { -+ PKTSETLINK(p, q->head); -+ q->head = p; -+ } ++ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) { ++ W_SBREG(si, &sb->sbtmstatehigh, 0); ++ } ++ if ((dummy = R_SBREG(si, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { ++ AND_SBREG(si, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); + } + -+ /* List invariants after insertion */ -+ ASSERT(q->head); -+ ASSERT(PKTLINK(q->tail) == NULL); ++ /* clear reset and allow it to propagate throughout the core */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); + -+ q->len++; ++ /* leave clock enabled */ ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); +} + -+/* dequeue packet at head */ -+void* -+pktdeq(struct pktq *q) ++void ++sb_core_tofixup(sb_t *sbh) +{ -+ void *p; ++ sb_info_t *si; ++ sbconfig_t *sb; + -+ if ((p = q->head)) { -+ ASSERT(q->tail); -+ q->head = PKTLINK(p); -+ PKTSETLINK(p, NULL); -+ q->len--; -+ if (q->head == NULL) -+ q->tail = NULL; -+ } -+ else { -+ ASSERT(q->tail == NULL); ++ si = SB_INFO(sbh); ++ ++ if ((BUSTYPE(si->sb.bustype) != PCI_BUS) || PCIE(si) || ++ (PCI(si) && (si->sb.buscorerev >= 5))) ++ return; ++ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ ++ if (BUSTYPE(si->sb.bustype) == SB_BUS) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x5 << SBIMCL_RTO_SHIFT) | 0x3); ++ } else { ++ if (sb_coreid(sbh) == SB_PCI) { ++ SET_SBREG(si, &sb->sbimconfiglow, ++ SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ } else { ++ SET_SBREG(si, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); ++ } + } + -+ return (p); ++ sb_commit(sbh); +} + -+/* dequeue packet at tail */ -+void* -+pktdeqtail(struct pktq *q) ++/* ++ * Set the initiator timeout for the "master core". ++ * The master core is defined to be the core in control ++ * of the chip and so it issues accesses to non-memory ++ * locations (Because of dma *any* core can access memeory). ++ * ++ * The routine uses the bus to decide who is the master: ++ * SB_BUS => mips ++ * JTAG_BUS => chipc ++ * PCI_BUS => pci or pcie ++ * PCMCIA_BUS => pcmcia ++ * SDIO_BUS => pcmcia ++ * ++ * This routine exists so callers can disable initiator ++ * timeouts so accesses to very slow devices like otp ++ * won't cause an abort. The routine allows arbitrary ++ * settings of the service and request timeouts, though. ++ * ++ * Returns the timeout state before changing it or -1 ++ * on error. ++ */ ++ ++#define TO_MASK (SBIMCL_RTO_MASK | SBIMCL_STO_MASK) ++ ++uint32 ++sb_set_initiator_to(sb_t *sbh, uint32 to) +{ -+ void *p; -+ void *next, *prev; ++ sb_info_t *si; ++ uint origidx, idx; ++ uint intr_val = 0; ++ uint32 tmp, ret = 0xffffffff; ++ sbconfig_t *sb; + -+ if (q->head == q->tail) { /* last packet on queue or queue empty */ -+ p = q->head; -+ q->head = q->tail = NULL; -+ q->len = 0; -+ return(p); -+ } ++ si = SB_INFO(sbh); + -+ /* start walk at head */ -+ prev = NULL; -+ next = q->head; ++ if ((to & ~TO_MASK) != 0) ++ return ret; + -+ /* Walk the queue to find prev of q->tail */ -+ for (; next; prev = next, next = PKTLINK(next)) { -+ if (next == q->tail) -+ break; ++ /* Figure out the master core */ ++ idx = BADIDX; ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ idx = si->sb.buscoreidx; ++ break; ++ case JTAG_BUS: ++ idx = SB_CC_IDX; ++ break; ++ case PCMCIA_BUS: ++ case SDIO_BUS: ++ idx = sb_findcoreidx(si, SB_PCMCIA, 0); ++ break; ++ case SB_BUS: ++ if ((idx = sb_findcoreidx(si, SB_MIPS33, 0)) == BADIDX) ++ idx = sb_findcoreidx(si, SB_MIPS, 0); ++ break; ++ default: ++ ASSERT(0); + } ++ if (idx == BADIDX) ++ return ret; + -+ ASSERT(prev); ++ INTR_OFF(si, intr_val); ++ origidx = sb_coreidx(sbh); + -+ PKTSETLINK(prev, NULL); -+ q->tail = prev; -+ q->len--; -+ p = next; ++ sb = REGS2SB(sb_setcoreidx(sbh, idx)); + -+ return (p); -+} -+#endif ++ tmp = R_SBREG(si, &sb->sbimconfiglow); ++ ret = tmp & TO_MASK; ++ W_SBREG(si, &sb->sbimconfiglow, (tmp & ~TO_MASK) | to); + ++ sb_commit(sbh); ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return ret; ++} + -diff -Naur linux.old/drivers/net/wl/hnddma.c linux.dev/drivers/net/wl/hnddma.c ---- linux.old/drivers/net/wl/hnddma.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/hnddma.c 2006-04-06 16:58:24.000000000 +0200 -@@ -0,0 +1,1453 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA module. -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id$ -+ */ ++void ++sb_core_disable(sb_t *sbh, uint32 bits) ++{ ++ sb_info_t *si; ++ volatile uint32 dummy; ++ uint32 rej; ++ sbconfig_t *sb; + -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ si = SB_INFO(sbh); + -+struct dma_info; /* forward declaration */ -+#define di_t struct dma_info ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); + -+#include "sbhnddma.h" -+#include "hnddma.h" ++ /* if core is already in reset, just return */ ++ if (R_SBREG(si, &sb->sbtmstatelow) & SBTML_RESET) ++ return; + -+/* debug/trace */ -+#define DMA_ERROR(args) -+#define DMA_TRACE(args) ++ /* reject value changed between sonics 2.2 and 2.3 */ ++ if (si->sb.sonicsrev == SONICS_2_2) ++ rej = (1 << SBTML_REJ_SHIFT); ++ else ++ rej = (2 << SBTML_REJ_SHIFT); + -+/* default dma message level (if input msg_level pointer is null in dma_attach()) */ -+static uint dma_msg_level = -+ 0; ++ /* if clocks are not enabled, put into reset and return */ ++ if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0) ++ goto disable; + -+#define MAXNAMEL 8 ++ /* set target reject and spin until busy is clear (preserve core-specific bits) */ ++ OR_SBREG(si, &sb->sbtmstatelow, rej); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); ++ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY) ++ SB_ERROR(("%s: target state still busy\n", __FUNCTION__)); + -+/* dma engine software state */ -+typedef struct dma_info { -+ hnddma_t hnddma; /* exported structure */ -+ uint *msg_level; /* message level pointer */ -+ char name[MAXNAMEL]; /* callers name for diag msgs */ -+ -+ void *osh; /* os handle */ -+ sb_t *sbh; /* sb handle */ -+ -+ bool dma64; /* dma64 enabled */ -+ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ -+ -+ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ -+ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ -+ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ -+ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) { ++ OR_SBREG(si, &sb->sbimstate, SBIM_RJ); ++ dummy = R_SBREG(si, &sb->sbimstate); ++ OSL_DELAY(1); ++ SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000); ++ } + -+ uint32 dma64align; /* either 8k or 4k depends on number of dd */ -+ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ -+ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ -+ uint ntxd; /* # tx descriptors tunable */ -+ uint txin; /* index of next descriptor to reclaim */ -+ uint txout; /* index of next descriptor to post */ -+ uint txavail; /* # free tx descriptors */ -+ void **txp; /* pointer to parallel array of pointers to packets */ -+ ulong txdpa; /* physical address of descriptor ring */ -+ uint txdalign; /* #bytes added to alloc'd mem to align txd */ -+ uint txdalloc; /* #bytes allocated for the ring */ ++ /* set reset and reject while enabling the clocks */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | rej | SBTML_RESET)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(10); + -+ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ -+ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ -+ uint nrxd; /* # rx descriptors tunable */ -+ uint rxin; /* index of next descriptor to reclaim */ -+ uint rxout; /* index of next descriptor to post */ -+ void **rxp; /* pointer to parallel array of pointers to packets */ -+ ulong rxdpa; /* physical address of descriptor ring */ -+ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ -+ uint rxdalloc; /* #bytes allocated for the ring */ ++ /* don't forget to clear the initiator reject bit */ ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) ++ AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ); + -+ /* tunables */ -+ uint rxbufsize; /* rx buffer size in bytes */ -+ uint nrxpost; /* # rx buffers to keep posted */ -+ uint rxoffset; /* rxcontrol offset */ -+ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ -+ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */ -+ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ -+ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */ -+} dma_info_t; ++disable: ++ /* leave reset and reject asserted */ ++ W_SBREG(si, &sb->sbtmstatelow, (bits | rej | SBTML_RESET)); ++ OSL_DELAY(1); ++} + -+#ifdef BCMDMA64 -+#define DMA64_ENAB(di) ((di)->dma64) -+#else -+#define DMA64_ENAB(di) (0) -+#endif ++/* set chip watchdog reset timer to fire in 'ticks' backplane cycles */ ++void ++sb_watchdog(sb_t *sbh, uint ticks) ++{ ++ sb_info_t *si = SB_INFO(sbh); + -+/* descriptor bumping macros */ -+#define XXD(x, n) ((x) & ((n) - 1)) -+#define TXD(x) XXD((x), di->ntxd) -+#define RXD(x) XXD((x), di->nrxd) -+#define NEXTTXD(i) TXD(i + 1) -+#define PREVTXD(i) TXD(i - 1) -+#define NEXTRXD(i) RXD(i + 1) -+#define NTXDACTIVE(h, t) TXD(t - h) -+#define NRXDACTIVE(h, t) RXD(t - h) ++ /* make sure we come up in fast clock mode */ ++ sb_clkctl_clk(sbh, CLK_FAST); + -+/* macros to convert between byte offsets and indexes */ -+#define B2I(bytes, type) ((bytes) / sizeof(type)) -+#define I2B(index, type) ((index) * sizeof(type)) ++ /* instant NMI */ ++ switch (si->gpioid) { ++ case SB_CC: ++#ifdef __mips__ ++ if (sb_chip(sbh) == BCM4785_CHIP_ID && ticks <= 1) ++ MTC0(C0_BROADCOM, 4, (1 << 22)); ++#endif /* __mips__ */ ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); ++#ifdef __mips__ ++ if (sb_chip(sbh) == BCM4785_CHIP_ID && ticks <= 1) { ++ __asm__ __volatile__ ( ++ ".set\tmips3\n\t" ++ "sync\n\t" ++ "wait\n\t" ++ ".set\tmips0" ++ ); ++ while (1); ++ } ++#endif /* __mips__ */ ++ break; ++ case SB_EXTIF: ++ sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); ++ break; ++ } ++} + -+#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ -+#define PCI32ADDR_HIGH_SHIFT 30 ++/* initialize the pcmcia core */ ++void ++sb_pcmcia_init(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint8 cor = 0; + ++ si = SB_INFO(sbh); + -+/* prototypes */ -+static bool dma_isaddrext(dma_info_t *di); -+static bool dma_alloc(dma_info_t *di, uint direction); ++ /* enable d11 mac interrupts */ ++ OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); ++ cor |= COR_IRQEN | COR_FUNEN; ++ OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); + -+static bool dma32_alloc(dma_info_t *di, uint direction); -+static void dma32_txreset(dma_info_t *di); -+static void dma32_rxreset(dma_info_t *di); -+static bool dma32_txsuspendedidle(dma_info_t *di); -+static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags); -+static void* dma32_getnexttxp(dma_info_t *di, bool forceall); -+static void* dma32_getnextrxp(dma_info_t *di, bool forceall); -+static void dma32_txrotate(di_t *di); -+ -+/* prototype or stubs */ -+#ifdef BCMDMA64 -+static bool dma64_alloc(dma_info_t *di, uint direction); -+static void dma64_txreset(dma_info_t *di); -+static void dma64_rxreset(dma_info_t *di); -+static bool dma64_txsuspendedidle(dma_info_t *di); -+static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags); -+static void* dma64_getnexttxp(dma_info_t *di, bool forceall); -+static void* dma64_getnextrxp(dma_info_t *di, bool forceall); -+static void dma64_txrotate(di_t *di); -+#else -+static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; } -+static void dma64_txreset(dma_info_t *di) {} -+static void dma64_rxreset(dma_info_t *di) {} -+static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;} -+static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; } -+static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; } -+static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; } -+static void dma64_txrotate(di_t *di) { return; } -+#endif ++} + -+/* old dmaregs struct for compatibility */ -+typedef volatile struct { -+ /* transmit channel */ -+ uint32 xmtcontrol; /* enable, et al */ -+ uint32 xmtaddr; /* descriptor ring base address (4K aligned) */ -+ uint32 xmtptr; /* last descriptor posted to chip */ -+ uint32 xmtstatus; /* current active descriptor, et al */ -+ -+ /* receive channel */ -+ uint32 rcvcontrol; /* enable, et al */ -+ uint32 rcvaddr; /* descriptor ring base address (4K aligned) */ -+ uint32 rcvptr; /* last descriptor posted to chip */ -+ uint32 rcvstatus; /* current active descriptor, et al */ -+} dmaregs_t; + -+void* -+dma_attach(void *drv, void *osh, char *name, dmaregs_t *regs, uint ntxd, uint nrxd, -+ uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level) ++/* ++ * Configure the pci core for pci client (NIC) action ++ * coremask is the bitvec of cores by index to be enabled. ++ */ ++void ++BCMINITFN(sb_pci_setup)(sb_t *sbh, uint coremask) +{ -+ dma_info_t *di; -+ uint size; -+ dma32regs_t *dmaregstx = regs; -+ dma32regs_t *dmaregsrx = dmaregstx + 1; -+ -+ /* allocate private info structure */ -+ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { -+ return (NULL); -+ } -+ bzero((char*)di, sizeof (dma_info_t)); -+ di->msg_level = msg_level ? msg_level : &dma_msg_level; ++ sb_info_t *si; ++ sbconfig_t *sb; ++ sbpciregs_t *pciregs; ++ uint32 sbflag; ++ uint32 w; ++ uint idx; ++ int reg_val; + -+ /* check arguments */ -+ ASSERT(ISPOWEROF2(ntxd)); -+ ASSERT(ISPOWEROF2(nrxd)); -+ if (nrxd == 0) -+ ASSERT(dmaregsrx == NULL); -+ if (ntxd == 0) -+ ASSERT(dmaregstx == NULL); ++ si = SB_INFO(sbh); + -+ ASSERT(ntxd <= D32MAXDD); -+ ASSERT(nrxd <= D32MAXDD); -+ di->d32txregs = (dma32regs_t *)dmaregstx; -+ di->d32rxregs = (dma32regs_t *)dmaregsrx; ++ /* if not pci bus, we're done */ ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) ++ return; + -+ /* make a private copy of our callers name */ -+ strncpy(di->name, name, MAXNAMEL); -+ di->name[MAXNAMEL-1] = '\0'; ++ ASSERT(PCI(si) || PCIE(si)); ++ ASSERT(si->sb.buscoreidx != BADIDX); + -+ di->osh = osh; -+ di->sbh = NULL; ++ /* get current core index */ ++ idx = si->curidx; + -+ /* save tunables */ -+ di->ntxd = ntxd; -+ di->nrxd = nrxd; -+ di->rxbufsize = rxbufsize; -+ di->nrxpost = nrxpost; -+ di->rxoffset = rxoffset; ++ /* we interrupt on this backplane flag number */ ++ ASSERT(GOODREGS(si->curmap)); ++ sb = REGS2SB(si->curmap); ++ sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK; + -+ di->ddoffsetlow = ddoffset; -+ di->dataoffsetlow = dataoffset; -+ di->ddoffsethigh = 0; -+ di->dataoffsethigh = 0; -+ -+ di->addrext = 0; -+ -+ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", -+ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow)); ++ /* switch over to pci core */ ++ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->sb.buscoreidx); ++ sb = REGS2SB(pciregs); + -+ /* allocate tx packet pointer vector */ -+ if (ntxd) { -+ size = ntxd * sizeof (void*); -+ if ((di->txp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); -+ goto fail; ++ /* ++ * Enable sb->pci interrupts. Assume ++ * PCI rev 2.3 support was added in pci core rev 6 and things changed.. ++ */ ++ if (PCIE(si) || (PCI(si) && ((si->sb.buscorerev) >= 6))) { ++ /* pci config write to set this core bit in PCIIntMask */ ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32)); ++ w |= (coremask << PCI_SBIM_SHIFT); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_MASK, sizeof(uint32), w); ++ } else { ++ /* set sbintvec bit for our flag number */ ++ OR_SBREG(si, &sb->sbintvec, (1 << sbflag)); ++ } ++ ++ if (PCI(si)) { ++ OR_REG(si->osh, &pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); ++ if (si->sb.buscorerev >= 11) ++ OR_REG(si->osh, &pciregs->sbtopci2, SBTOPCI_RC_READMULTI); ++ if (si->sb.buscorerev < 5) { ++ SET_SBREG(si, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, ++ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); ++ sb_commit(sbh); + } -+ bzero((char*)di->txp, size); + } + -+ /* allocate rx packet pointer vector */ -+ if (nrxd) { -+ size = nrxd * sizeof (void*); -+ if ((di->rxp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); -+ goto fail; ++#ifdef PCIE_SUPPOER ++ /* PCIE workarounds */ ++ if (PCIE(si)) { ++ if ((si->sb.buscorerev == 0) || (si->sb.buscorerev == 1)) { ++ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, ++ PCIE_TLP_WORKAROUNDSREG); ++ reg_val |= 0x8; ++ sb_pcie_writereg((void *)sbh, (void *)PCIE_PCIEREGS, ++ PCIE_TLP_WORKAROUNDSREG, reg_val); + } -+ bzero((char*)di->rxp, size); -+ } + -+ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ -+ if (ntxd) { -+ if (!dma_alloc(di, DMA_TX)) -+ goto fail; -+ } ++ if (si->sb.buscorerev == 1) { ++ reg_val = sb_pcie_readreg((void *)sbh, (void *)PCIE_PCIEREGS, ++ PCIE_DLLP_LCREG); ++ reg_val |= (0x40); ++ sb_pcie_writereg(sbh, (void *)PCIE_PCIEREGS, PCIE_DLLP_LCREG, reg_val); ++ } + -+ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ -+ if (nrxd) { -+ if (!dma_alloc(di, DMA_RX)) -+ goto fail; ++ if (si->sb.buscorerev == 0) ++ sb_war30841(si); + } ++#endif + -+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { -+ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa)); -+ goto fail; -+ } -+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { -+ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa)); -+ goto fail; -+ } ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); ++} + -+ return ((void*)di); ++uint32 ++sb_base(uint32 admatch) ++{ ++ uint32 base; ++ uint type; + -+fail: -+ dma_detach((void*)di); -+ return (NULL); -+} ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); + ++ base = 0; + -+static bool -+dma_alloc(dma_info_t *di, uint direction) ++ if (type == 0) { ++ base = admatch & SBAM_BASE0_MASK; ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE1_MASK; ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ base = admatch & SBAM_BASE2_MASK; ++ } ++ ++ return (base); ++} ++ ++uint32 ++sb_size(uint32 admatch) +{ -+ if (DMA64_ENAB(di)) { -+ return dma64_alloc(di, direction); -+ } else { -+ return dma32_alloc(di, direction); ++ uint32 size; ++ uint type; ++ ++ type = admatch & SBAM_TYPE_MASK; ++ ASSERT(type < 3); ++ ++ size = 0; ++ ++ if (type == 0) { ++ size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); ++ } else if (type == 1) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); ++ } else if (type == 2) { ++ ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ ++ size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); + } ++ ++ return (size); +} + -+/* may be called with core in reset */ -+void -+dma_detach(dma_info_t *di) ++/* return the core-type instantiation # of the current core */ ++uint ++sb_coreunit(sb_t *sbh) +{ -+ if (di == NULL) -+ return; ++ sb_info_t *si; ++ uint idx; ++ uint coreid; ++ uint coreunit; ++ uint i; + -+ DMA_TRACE(("%s: dma_detach\n", di->name)); ++ si = SB_INFO(sbh); ++ coreunit = 0; + -+ /* shouldn't be here if descriptors are unreclaimed */ -+ ASSERT(di->txin == di->txout); -+ ASSERT(di->rxin == di->rxout); ++ idx = si->curidx; + -+ /* free dma descriptor rings */ -+ if (di->txd32) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign)); -+ if (di->rxd32) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign)); ++ ASSERT(GOODREGS(si->curmap)); ++ coreid = sb_coreid(sbh); + -+ /* free packet pointer vectors */ -+ if (di->txp) -+ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*))); -+ if (di->rxp) -+ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*))); ++ /* count the cores of our type */ ++ for (i = 0; i < idx; i++) ++ if (si->coreid[i] == coreid) ++ coreunit++; + -+ /* free our private info structure */ -+ MFREE(di->osh, (void*)di, sizeof (dma_info_t)); ++ return (coreunit); +} + -+/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ -+static bool -+dma_isaddrext(dma_info_t *di) ++static INLINE uint32 ++factor6(uint32 x) +{ -+ uint32 w; -+ -+ if (DMA64_ENAB(di)) { -+ OR_REG(&di->d64txregs->control, D64_XC_AE); -+ w = R_REG(&di->d32txregs->control); -+ AND_REG(&di->d32txregs->control, ~D64_XC_AE); -+ return ((w & XC_AE) == D64_XC_AE); -+ } else { -+ OR_REG(&di->d32txregs->control, XC_AE); -+ w = R_REG(&di->d32txregs->control); -+ AND_REG(&di->d32txregs->control, ~XC_AE); -+ return ((w & XC_AE) == XC_AE); ++ switch (x) { ++ case CC_F6_2: return 2; ++ case CC_F6_3: return 3; ++ case CC_F6_4: return 4; ++ case CC_F6_5: return 5; ++ case CC_F6_6: return 6; ++ case CC_F6_7: return 7; ++ default: return 0; + } +} + -+void -+dma_txreset(dma_info_t *di) ++/* calculate the speed the SB would run at given a set of clockcontrol values */ ++uint32 ++sb_clock_rate(uint32 pll_type, uint32 n, uint32 m) +{ -+ DMA_TRACE(("%s: dma_txreset\n", di->name)); ++ uint32 n1, n2, clock, m1, m2, m3, mc; + -+ if (DMA64_ENAB(di)) -+ dma64_txreset(di); -+ else -+ dma32_txreset(di); -+} ++ n1 = n & CN_N1_MASK; ++ n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; + -+void -+dma_rxreset(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxreset\n", di->name)); ++ if (pll_type == PLL_TYPE6) { ++ if (m & CC_T6_MMASK) ++ return CC_T6_M1; ++ else ++ return CC_T6_M0; ++ } else if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ n1 = factor6(n1); ++ n2 += CC_F5_BIAS; ++ } else if (pll_type == PLL_TYPE2) { ++ n1 += CC_T2_BIAS; ++ n2 += CC_T2_BIAS; ++ ASSERT((n1 >= 2) && (n1 <= 7)); ++ ASSERT((n2 >= 5) && (n2 <= 23)); ++ } else if (pll_type == PLL_TYPE5) { ++ return (100000000); ++ } else ++ ASSERT(0); ++ /* PLL types 3 and 7 use BASE2 (25Mhz) */ ++ if ((pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE7)) { ++ clock = CC_CLOCK_BASE2 * n1 * n2; ++ } else ++ clock = CC_CLOCK_BASE1 * n1 * n2; + -+ if (DMA64_ENAB(di)) -+ dma64_rxreset(di); -+ else -+ dma32_rxreset(di); -+} ++ if (clock == 0) ++ return 0; ++ ++ m1 = m & CC_M1_MASK; ++ m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; ++ m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; ++ mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; ++ ++ if ((pll_type == PLL_TYPE1) || ++ (pll_type == PLL_TYPE3) || ++ (pll_type == PLL_TYPE4) || ++ (pll_type == PLL_TYPE7)) { ++ m1 = factor6(m1); ++ if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE3)) ++ m2 += CC_F5_BIAS; ++ else ++ m2 = factor6(m2); ++ m3 = factor6(m3); + -+/* initialize descriptor table base address */ -+static void -+dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) -+{ -+ if (DMA64_ENAB(di)) { -+ if (direction == DMA_TX) { -+ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow); -+ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); -+ } else { -+ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow); -+ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); ++ switch (mc) { ++ case CC_MC_BYPASS: return (clock); ++ case CC_MC_M1: return (clock / m1); ++ case CC_MC_M1M2: return (clock / (m1 * m2)); ++ case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); ++ case CC_MC_M1M3: return (clock / (m1 * m3)); ++ default: return (0); + } + } else { -+ uint32 offset = di->ddoffsetlow; -+ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { -+ if (direction == DMA_TX) -+ W_REG(&di->d32txregs->addr, (pa + offset)); -+ else -+ W_REG(&di->d32rxregs->addr, (pa + offset)); -+ } else { -+ /* dma32 address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; -+ -+ if (direction == DMA_TX) { -+ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); -+ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT)); -+ } else { -+ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); -+ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT)); -+ } -+ } -+ } -+} ++ ASSERT(pll_type == PLL_TYPE2); + -+/* init the tx or rx descriptor */ -+static INLINE void -+dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl) -+{ -+ uint offset = di->dataoffsetlow; ++ m1 += CC_T2_BIAS; ++ m2 += CC_T2M2_BIAS; ++ m3 += CC_T2_BIAS; ++ ASSERT((m1 >= 2) && (m1 <= 7)); ++ ASSERT((m2 >= 3) && (m2 <= 10)); ++ ASSERT((m3 >= 2) && (m3 <= 7)); + -+ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { -+ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); -+ } else { -+ /* address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ if ((mc & CC_T2MC_M1BYP) == 0) ++ clock /= m1; ++ if ((mc & CC_T2MC_M2BYP) == 0) ++ clock /= m2; ++ if ((mc & CC_T2MC_M3BYP) == 0) ++ clock /= m3; + -+ *ctrl |= (ae << CTRL_AE_SHIFT); -+ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); ++ return (clock); + } +} + -+/* init the tx or rx descriptor */ -+static INLINE void -+dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount) ++/* returns the current speed the SB is running at */ ++uint32 ++sb_clock(sb_t *sbh) +{ -+ uint32 bufaddr_low = pa + di->dataoffsetlow; -+ uint32 bufaddr_high = 0 + di->dataoffsethigh; -+ -+ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; -+ -+ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low)); -+ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high)); -+ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); -+ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); -+} ++ sb_info_t *si; ++ extifregs_t *eir; ++ chipcregs_t *cc; ++ uint32 n, m; ++ uint idx; ++ uint32 pll_type, rate; ++ uint intr_val = 0; + -+void -+dma_txinit(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txinit\n", di->name)); ++ si = SB_INFO(sbh); ++ idx = si->curidx; ++ pll_type = PLL_TYPE1; + -+ di->txin = di->txout = 0; -+ di->txavail = di->ntxd - 1; ++ INTR_OFF(si, intr_val); + -+ /* clear tx descriptor ring */ -+ if (DMA64_ENAB(di)) { -+ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t))); -+ W_REG(&di->d64txregs->control, XC_XE); -+ dma_ddtable_init(di, DMA_TX, di->txdpa); ++ /* switch to extif or chipc core */ ++ if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { ++ n = R_REG(si->osh, &eir->clockcontrol_n); ++ m = R_REG(si->osh, &eir->clockcontrol_sb); ++ } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { ++ pll_type = R_REG(si->osh, &cc->capabilities) & CAP_PLL_MASK; ++ if (pll_type == PLL_NONE) { ++ INTR_RESTORE(si, intr_val); ++ return 80000000; ++ } ++ n = R_REG(si->osh, &cc->clockcontrol_n); ++ if (pll_type == PLL_TYPE6) ++ m = R_REG(si->osh, &cc->clockcontrol_m3); ++ else if ((pll_type == PLL_TYPE3) && !(BCMINIT(sb_chip)(sbh) == 0x5365)) ++ m = R_REG(si->osh, &cc->clockcontrol_m2); ++ else ++ m = R_REG(si->osh, &cc->clockcontrol_sb); + } else { -+ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t))); -+ W_REG(&di->d32txregs->control, XC_XE); -+ dma_ddtable_init(di, DMA_TX, di->txdpa); ++ INTR_RESTORE(si, intr_val); ++ return 0; + } -+} + -+bool -+dma_txenabled(dma_info_t *di) -+{ -+ uint32 xc; -+ -+ /* If the chip is dead, it is not enabled :-) */ -+ if (DMA64_ENAB(di)) { -+ xc = R_REG(&di->d64txregs->control); -+ return ((xc != 0xffffffff) && (xc & D64_XC_XE)); -+ } else { -+ xc = R_REG(&di->d32txregs->control); -+ return ((xc != 0xffffffff) && (xc & XC_XE)); ++ /* calculate rate */ ++ if (BCMINIT(sb_chip)(sbh) == 0x5365) ++ rate = 100000000; ++ else { ++ rate = sb_clock_rate(pll_type, n, m); ++ ++ if (pll_type == PLL_TYPE3) ++ rate = rate / 2; + } -+} + -+void -+dma_txsuspend(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); -+ if (DMA64_ENAB(di)) -+ OR_REG(&di->d64txregs->control, D64_XC_SE); -+ else -+ OR_REG(&di->d32txregs->control, XC_SE); -+} ++ /* switch back to previous core */ ++ sb_setcoreidx(sbh, idx); + -+void -+dma_txresume(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txresume\n", di->name)); -+ if (DMA64_ENAB(di)) -+ AND_REG(&di->d64txregs->control, ~D64_XC_SE); -+ else -+ AND_REG(&di->d32txregs->control, ~XC_SE); -+} ++ INTR_RESTORE(si, intr_val); + -+bool -+dma_txsuspendedidle(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di)) -+ return dma64_txsuspendedidle(di); -+ else -+ return dma32_txsuspendedidle(di); ++ return rate; +} + -+bool -+dma_txsuspended(dma_info_t *di) ++/* change logical "focus" to the gpio core for optimized access */ ++void* ++sb_gpiosetcore(sb_t *sbh) +{ -+ if (DMA64_ENAB(di)) -+ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); -+ else -+ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE); -+} ++ sb_info_t *si; + -+bool -+dma_txstopped(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di)) -+ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); -+ else -+ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); -+} ++ si = SB_INFO(sbh); + -+bool -+dma_rxstopped(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di)) -+ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); -+ else -+ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); ++ return (sb_setcoreidx(sbh, si->gpioidx)); +} + -+void -+dma_fifoloopbackenable(dma_info_t *di) ++/* mask&set gpiocontrol bits */ ++uint32 ++sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ -+ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); -+ if (DMA64_ENAB(di)) -+ OR_REG(&di->d64txregs->control, D64_XC_LE); -+ else -+ OR_REG(&di->d32txregs->control, XC_LE); -+} ++ sb_info_t *si; ++ uint regoff; + -+void -+dma_rxinit(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxinit\n", di->name)); ++ si = SB_INFO(sbh); ++ regoff = 0; + -+ di->rxin = di->rxout = 0; ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ + -+ /* clear rx descriptor ring */ -+ if (DMA64_ENAB(di)) { -+ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t))); -+ dma_rxenable(di); -+ dma_ddtable_init(di, DMA_RX, di->rxdpa); -+ } else { -+ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t))); -+ dma_rxenable(di); -+ dma_ddtable_init(di, DMA_RX, di->rxdpa); ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; + } -+} + -+void -+dma_rxenable(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxenable\n", di->name)); -+ if (DMA64_ENAB(di)) -+ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE)); -+ else -+ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); -+} ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiocontrol); ++ break; + -+bool -+dma_rxenabled(dma_info_t *di) -+{ -+ uint32 rc; ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpiocontrol); ++ break; + -+ if (DMA64_ENAB(di)) { -+ rc = R_REG(&di->d64rxregs->control); -+ return ((rc != 0xffffffff) && (rc & D64_RC_RE)); -+ } else { -+ rc = R_REG(&di->d32rxregs->control); -+ return ((rc != 0xffffffff) && (rc & RC_RE)); ++ case SB_EXTIF: ++ return (0); + } -+} + -+ -+/* !! tx entry routine */ -+int -+dma_txfast(dma_info_t *di, void *p0, uint32 coreflags) -+{ -+ if (DMA64_ENAB(di)) { -+ return dma64_txfast(di, p0, coreflags); -+ } else { -+ return dma32_txfast(di, p0, coreflags); -+ } ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); +} + -+/* !! rx entry routine, returns a pointer to the next frame received, or NULL if there are no more */ -+void* -+dma_rx(dma_info_t *di) ++/* mask&set gpio output enable bits */ ++uint32 ++sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ -+ void *p; -+ uint len; -+ int skiplen = 0; ++ sb_info_t *si; ++ uint regoff; + -+ while ((p = dma_getnextrxp(di, FALSE))) { -+ /* skip giant packets which span multiple rx descriptors */ -+ if (skiplen > 0) { -+ skiplen -= di->rxbufsize; -+ if (skiplen < 0) -+ skiplen = 0; -+ PKTFREE(di->osh, p, FALSE); -+ continue; -+ } ++ si = SB_INFO(sbh); ++ regoff = 0; + -+ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); -+ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ + -+ /* bad frame length check */ -+ if (len > (di->rxbufsize - di->rxoffset)) { -+ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); -+ if (len > 0) -+ skiplen = len - (di->rxbufsize - di->rxoffset); -+ PKTFREE(di->osh, p, FALSE); -+ di->hnddma.rxgiants++; -+ continue; -+ } ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } + -+ /* set actual length */ -+ PKTSETLEN(di->osh, p, (di->rxoffset + len)); ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioouten); ++ break; ++ ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioouten); ++ break; + ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].outen); + break; + } + -+ return (p); ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); +} + -+/* post receive buffers */ -+void -+dma_rxfill(dma_info_t *di) ++/* mask&set gpio output bits */ ++uint32 ++sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ -+ void *p; -+ uint rxin, rxout; -+ uint32 ctrl; -+ uint n; -+ uint i; -+ uint32 pa; -+ uint rxbufsize; ++ sb_info_t *si; ++ uint regoff; + -+ /* -+ * Determine how many receive buffers we're lacking -+ * from the full complement, allocate, initialize, -+ * and post them, then update the chip rx lastdscr. -+ */ ++ si = SB_INFO(sbh); ++ regoff = 0; + -+ rxin = di->rxin; -+ rxout = di->rxout; -+ rxbufsize = di->rxbufsize; ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ + -+ n = di->nrxpost - NRXDACTIVE(rxin, rxout); ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } + -+ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioout); ++ break; + -+ for (i = 0; i < n; i++) { -+ if ((p = PKTGET(di->osh, rxbufsize, FALSE)) == NULL) { -+ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); -+ di->hnddma.rxnobuf++; -+ break; -+ } ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioout); ++ break; + -+ /* Do a cached write instead of uncached write since DMA_MAP -+ * will flush the cache. */ -+ *(uint32*)(PKTDATA(di->osh, p)) = 0; ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpio[0].out); ++ break; ++ } + -+ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p); -+ ASSERT(ISALIGNED(pa, 4)); ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} + -+ /* save the free packet pointer */ -+ ASSERT(di->rxp[rxout] == NULL); -+ di->rxp[rxout] = p; ++/* reserve one gpio */ ++uint32 ++sb_gpioreserve(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) ++{ ++ sb_info_t *si; + -+ if (DMA64_ENAB(di)) { -+ /* prep the descriptor control value */ -+ if (rxout == (di->nrxd - 1)) -+ ctrl = CTRL_EOT; ++ si = SB_INFO(sbh); + -+ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize); -+ } else { -+ /* prep the descriptor control value */ -+ ctrl = rxbufsize; -+ if (rxout == (di->nrxd - 1)) -+ ctrl |= CTRL_EOT; -+ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl); -+ } ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ + -+ rxout = NEXTRXD(rxout); ++ /* only cores on SB_BUS share GPIO's and only applcation users need to ++ * reserve/release GPIO ++ */ ++ if ((BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; ++ } ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; + } + -+ di->rxout = rxout; ++ /* already reserved */ ++ if (sb_gpioreservation & gpio_bitmask) ++ return -1; ++ /* set reservation */ ++ sb_gpioreservation |= gpio_bitmask; + -+ /* update the chip lastdscr pointer */ -+ if (DMA64_ENAB(di)) { -+ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t)); -+ } else { -+ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); -+ } ++ return sb_gpioreservation; +} + -+void -+dma_txreclaim(dma_info_t *di, bool forceall) ++/* release one gpio */ ++/* ++ * releasing the gpio doesn't change the current value on the GPIO last write value ++ * persists till some one overwrites it ++*/ ++ ++uint32 ++sb_gpiorelease(sb_t *sbh, uint32 gpio_bitmask, uint8 priority) +{ -+ void *p; ++ sb_info_t *si; + -+ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); ++ si = SB_INFO(sbh); + -+ while ((p = dma_getnexttxp(di, forceall))) -+ PKTFREE(di->osh, p, TRUE); -+} ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ + -+/* -+ * Reclaim next completed txd (txds if using chained buffers) and -+ * return associated packet. -+ * If 'force' is true, reclaim txd(s) and return associated packet -+ * regardless of the value of the hardware "curr" pointer. -+ */ -+void* -+dma_getnexttxp(dma_info_t *di, bool forceall) -+{ -+ if (DMA64_ENAB(di)) { -+ return dma64_getnexttxp(di, forceall); -+ } else { -+ return dma32_getnexttxp(di, forceall); ++ /* only cores on SB_BUS share GPIO's and only applcation users need to ++ * reserve/release GPIO ++ */ ++ if ((BUSTYPE(si->sb.bustype) != SB_BUS) || (!priority)) { ++ ASSERT((BUSTYPE(si->sb.bustype) == SB_BUS) && (priority)); ++ return -1; + } -+} -+ -+/* like getnexttxp but no reclaim */ -+void* -+dma_peeknexttxp(dma_info_t *di) -+{ -+ uint end, i; -+ -+ if (DMA64_ENAB(di)) { -+ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); -+ } else { -+ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ /* make sure only one bit is set */ ++ if ((!gpio_bitmask) || ((gpio_bitmask) & (gpio_bitmask - 1))) { ++ ASSERT((gpio_bitmask) && !((gpio_bitmask) & (gpio_bitmask - 1))); ++ return -1; + } + -+ for (i = di->txin; i != end; i = NEXTTXD(i)) -+ if (di->txp[i]) -+ return (di->txp[i]); ++ /* already released */ ++ if (!(sb_gpioreservation & gpio_bitmask)) ++ return -1; + -+ return (NULL); -+} ++ /* clear reservation */ ++ sb_gpioreservation &= ~gpio_bitmask; + -+/* -+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). -+ */ -+void -+dma_txrotate(di_t *di) -+{ -+ if (DMA64_ENAB(di)) { -+ dma64_txrotate(di); -+ } else { -+ dma32_txrotate(di); -+ } ++ return sb_gpioreservation; +} + -+void -+dma_rxreclaim(dma_info_t *di) ++/* return the current gpioin register value */ ++uint32 ++sb_gpioin(sb_t *sbh) +{ -+ void *p; ++ sb_info_t *si; ++ uint regoff; + -+ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); ++ si = SB_INFO(sbh); ++ regoff = 0; + -+ while ((p = dma_getnextrxp(di, TRUE))) -+ PKTFREE(di->osh, p, FALSE); -+} ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpioin); ++ break; + -+void * -+dma_getnextrxp(dma_info_t *di, bool forceall) -+{ -+ if (DMA64_ENAB(di)) { -+ return dma64_getnextrxp(di, forceall); -+ } else { -+ return dma32_getnextrxp(di, forceall); -+ } -+} ++ case SB_PCI: ++ regoff = OFFSETOF(sbpciregs_t, gpioin); ++ break; + -+uintptr -+dma_getvar(dma_info_t *di, char *name) -+{ -+ if (!strcmp(name, "&txavail")) -+ return ((uintptr) &di->txavail); -+ else { -+ ASSERT(0); ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpioin); ++ break; + } -+ return (0); -+} + -+void -+dma_txblock(dma_info_t *di) -+{ -+ di->txavail = 0; ++ return (sb_corereg(si, si->gpioidx, regoff, 0, 0)); +} + -+void -+dma_txunblock(dma_info_t *di) ++/* mask&set gpio interrupt polarity bits */ ++uint32 ++sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+} ++ sb_info_t *si; ++ uint regoff; + -+uint -+dma_txactive(dma_info_t *di) -+{ -+ return (NTXDACTIVE(di->txin, di->txout)); -+} -+ -+void -+dma_rxpiomode(dma32regs_t *regs) -+{ -+ W_REG(®s->control, RC_FM); -+} ++ si = SB_INFO(sbh); ++ regoff = 0; + -+void -+dma_txpioloopback(dma32regs_t *regs) -+{ -+ OR_REG(®s->control, XC_LE); -+} ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ ++ ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } ++ ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointpolarity); ++ break; + ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt polarity */ ++ ASSERT(0); ++ break; + ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointpolarity); ++ break; ++ } + ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); ++} + -+/*** 32 bits DMA non-inline functions ***/ -+static bool -+dma32_alloc(dma_info_t *di, uint direction) ++/* mask&set gpio interrupt mask bits */ ++uint32 ++sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ -+ uint size; -+ uint ddlen; -+ void *va; ++ sb_info_t *si; ++ uint regoff; + -+ ddlen = sizeof (dma32dd_t); ++ si = SB_INFO(sbh); ++ regoff = 0; + -+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ priority = GPIO_DRV_PRIORITY; /* compatibility hack */ + -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) -+ size += D32RINGALIGN; ++ /* gpios could be shared on router platforms */ ++ if ((BUSTYPE(si->sb.bustype) == SB_BUS) && (val || mask)) { ++ mask = priority ? (sb_gpioreservation & mask) : ++ ((sb_gpioreservation | mask) & ~(sb_gpioreservation)); ++ val &= mask; ++ } + ++ switch (si->gpioid) { ++ case SB_CC: ++ regoff = OFFSETOF(chipcregs_t, gpiointmask); ++ break; + -+ if (direction == DMA_TX) { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); -+ return FALSE; -+ } ++ case SB_PCI: ++ /* pci gpio implementation does not support interrupt mask */ ++ ASSERT(0); ++ break; + -+ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); -+ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); -+ di->txdpa += di->txdalign; -+ di->txdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); -+ } else { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); -+ return FALSE; -+ } -+ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); -+ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); -+ di->rxdpa += di->rxdalign; -+ di->rxdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); ++ case SB_EXTIF: ++ regoff = OFFSETOF(extifregs_t, gpiointmask); ++ break; + } + -+ return TRUE; ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); +} + -+static void -+dma32_txreset(dma_info_t *di) ++/* assign the gpio to an led */ ++uint32 ++sb_gpioled(sb_t *sbh, uint32 mask, uint32 val) +{ -+ uint32 status; ++ sb_info_t *si; + -+ /* suspend tx DMA first */ -+ W_REG(&di->d32txregs->control, XC_SE); -+ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED && -+ status != XS_XS_IDLE && -+ status != XS_XS_STOPPED, -+ 10000); -+ -+ W_REG(&di->d32txregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED, -+ 10000); -+ -+ if (status != XS_XS_DISABLED) { -+ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); -+ } ++ si = SB_INFO(sbh); ++ if (si->sb.ccrev < 16) ++ return -1; ++ ++ /* gpio led powersave reg */ ++ return (sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimeroutmask), mask, val)); ++} ++ ++/* mask & set gpio timer val */ ++uint32 ++sb_gpiotimerval(sb_t *sbh, uint32 mask, uint32 gpiotimerval) ++{ ++ sb_info_t *si; ++ si = SB_INFO(sbh); ++ ++ if (si->sb.ccrev < 16) ++ return -1; + -+ /* wait for the last transaction to complete */ -+ OSL_DELAY(300); ++ return (sb_corereg(si, 0, OFFSETOF(chipcregs_t, gpiotimerval), mask, gpiotimerval)); +} + -+static void -+dma32_rxreset(dma_info_t *di) ++ ++/* return the slow clock source - LPO, XTAL, or PCI */ ++static uint ++sb_slowclk_src(sb_info_t *si) +{ -+ uint32 status; ++ chipcregs_t *cc; + -+ W_REG(&di->d32rxregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED, -+ 10000); + -+ if (status != RS_RS_DISABLED) { -+ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); -+ } ++ ASSERT(sb_coreid(&si->sb) == SB_CC); ++ ++ if (si->sb.ccrev < 6) { ++ if ((BUSTYPE(si->sb.bustype) == PCI_BUS) && ++ (OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32)) & ++ PCI_CFG_GPIO_SCS)) ++ return (SCC_SS_PCI); ++ else ++ return (SCC_SS_XTAL); ++ } else if (si->sb.ccrev < 10) { ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); ++ return (R_REG(si->osh, &cc->slow_clk_ctl) & SCC_SS_MASK); ++ } else /* Insta-clock */ ++ return (SCC_SS_XTAL); +} + -+static bool -+dma32_txsuspendedidle(dma_info_t *di) ++/* return the ILP (slowclock) min or max frequency */ ++static uint ++sb_slowclk_freq(sb_info_t *si, bool max) +{ -+ if (!(R_REG(&di->d32txregs->control) & XC_SE)) -+ return 0; -+ -+ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) -+ return 0; ++ chipcregs_t *cc; ++ uint32 slowclk; ++ uint div; + -+ OSL_DELAY(2); -+ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); -+} + -+/* -+ * supports full 32bit dma engine buffer addressing so -+ * dma buffers can cross 4 Kbyte page boundaries. -+ */ -+static int -+dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags) -+{ -+ void *p, *next; -+ uchar *data; -+ uint len; -+ uint txout; -+ uint32 ctrl; -+ uint32 pa; ++ ASSERT(sb_coreid(&si->sb) == SB_CC); + -+ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); + -+ txout = di->txout; -+ ctrl = 0; ++ /* shouldn't be here unless we've established the chip has dynamic clk control */ ++ ASSERT(R_REG(si->osh, &cc->capabilities) & CAP_PWR_CTL); + -+ /* -+ * Walk the chain of packet buffers -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ data = PKTDATA(di->osh, p); -+ len = PKTLEN(di->osh, p); -+ next = PKTNEXT(di->osh, p); ++ slowclk = sb_slowclk_src(si); ++ if (si->sb.ccrev < 6) { ++ if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/64) : (PCIMINFREQ/64)); ++ else ++ return (max? (XTALMAXFREQ/32) : (XTALMINFREQ/32)); ++ } else if (si->sb.ccrev < 10) { ++ div = 4 * (((R_REG(si->osh, &cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); ++ if (slowclk == SCC_SS_LPO) ++ return (max? LPOMAXFREQ : LPOMINFREQ); ++ else if (slowclk == SCC_SS_XTAL) ++ return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); ++ else if (slowclk == SCC_SS_PCI) ++ return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); ++ else ++ ASSERT(0); ++ } else { ++ /* Chipc rev 10 is InstaClock */ ++ div = R_REG(si->osh, &cc->system_clk_ctl) >> SYCC_CD_SHIFT; ++ div = 4 * (div + 1); ++ return (max ? XTALMAXFREQ : (XTALMINFREQ/div)); ++ } ++ return (0); ++} + -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) -+ goto outoftxd; ++static void ++BCMINITFN(sb_clkctl_setdelay)(sb_info_t *si, void *chipcregs) ++{ ++ chipcregs_t * cc; ++ uint slowmaxfreq, pll_delay, slowclk; ++ uint pll_on_delay, fref_sel_delay; + -+ if (len == 0) -+ continue; ++ pll_delay = PLL_DELAY; + -+ /* get physical address of buffer start */ -+ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ /* If the slow clock is not sourced by the xtal then add the xtal_on_delay ++ * since the xtal will also be powered down by dynamic clk control logic. ++ */ + -+ /* build the descriptor control value */ -+ ctrl = len & CTRL_BC_MASK; ++ slowclk = sb_slowclk_src(si); ++ if (slowclk != SCC_SS_XTAL) ++ pll_delay += XTAL_ON_DELAY; + -+ ctrl |= coreflags; -+ -+ if (p == p0) -+ ctrl |= CTRL_SOF; -+ if (next == NULL) -+ ctrl |= (CTRL_IOC | CTRL_EOF); -+ if (txout == (di->ntxd - 1)) -+ ctrl |= CTRL_EOT; ++ /* Starting with 4318 it is ILP that is used for the delays */ ++ slowmaxfreq = sb_slowclk_freq(si, (si->sb.ccrev >= 10) ? FALSE : TRUE); + -+ if (DMA64_ENAB(di)) { -+ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len); -+ } else { -+ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl); -+ } ++ pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; ++ fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; + -+ ASSERT(di->txp[txout] == NULL); ++ cc = (chipcregs_t *)chipcregs; ++ W_REG(si->osh, &cc->pll_on_delay, pll_on_delay); ++ W_REG(si->osh, &cc->fref_sel_delay, fref_sel_delay); ++} + -+ txout = NEXTTXD(txout); -+ } ++/* initialize power control delay registers */ ++void ++BCMINITFN(sb_clkctl_init)(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; + -+ /* if last txd eof not set, fix it */ -+ if (!(ctrl & CTRL_EOF)) -+ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF)); ++ si = SB_INFO(sbh); + -+ /* save the packet */ -+ di->txp[PREVTXD(txout)] = p0; ++ origidx = si->curidx; + -+ /* bump the tx descriptor index */ -+ di->txout = txout; ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ return; + -+ /* kick the chip */ -+ if (DMA64_ENAB(di)) { -+ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); -+ } else { -+ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t)); -+ } ++ if ((si->sb.chip == BCM4321_CHIP_ID) && (si->sb.chiprev < 2)) ++ W_REG(si->osh, &cc->chipcontrol, ++ (si->sb.chiprev == 0) ? CHIPCTRL_4321A0_DEFAULT : CHIPCTRL_4321A1_DEFAULT); + -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ if (!(R_REG(si->osh, &cc->capabilities) & CAP_PWR_CTL)) ++ goto done; + -+ return (0); ++ /* set all Instaclk chip ILP to 1 MHz */ ++ else if (si->sb.ccrev >= 10) ++ SET_REG(si->osh, &cc->system_clk_ctl, SYCC_CD_MASK, ++ (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); + -+ outoftxd: -+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); -+ PKTFREE(di->osh, p0, TRUE); -+ di->txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); ++ sb_clkctl_setdelay(si, (void *)cc); ++ ++done: ++ sb_setcoreidx(sbh, origidx); +} + -+static void* -+dma32_getnexttxp(dma_info_t *di, bool forceall) ++/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ ++uint16 ++sb_clkctl_fast_pwrup_delay(sb_t *sbh) +{ -+ uint start, end, i; -+ void *txp; ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint slowminfreq; ++ uint16 fpdelay; ++ uint intr_val = 0; + -+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); ++ si = SB_INFO(sbh); ++ fpdelay = 0; ++ origidx = si->curidx; + -+ txp = NULL; ++ INTR_OFF(si, intr_val); + -+ start = di->txin; -+ if (forceall) -+ end = di->txout; -+ else -+ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) ++ goto done; + -+ if ((start == 0) && (end > di->txout)) -+ goto bogus; ++ if (!(R_REG(si->osh, &cc->capabilities) & CAP_PWR_CTL)) ++ goto done; + -+ for (i = start; i != end && !txp; i = NEXTTXD(i)) { -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), -+ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]); ++ slowminfreq = sb_slowclk_freq(si, FALSE); ++ fpdelay = (((R_REG(si->osh, &cc->pll_on_delay) + 2) * 1000000) + ++ (slowminfreq - 1)) / slowminfreq; + -+ W_SM(&di->txd32[i].addr, 0xdeadbeef); -+ txp = di->txp[i]; -+ di->txp[i] = NULL; -+ } ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (fpdelay); ++} + -+ di->txin = i; ++/* turn primary xtal and/or pll off/on */ ++int ++sb_clkctl_xtal(sb_t *sbh, uint what, bool on) ++{ ++ sb_info_t *si; ++ uint32 in, out, outen; + -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ si = SB_INFO(sbh); + -+ return (txp); ++ switch (BUSTYPE(si->sb.bustype)) { + -+bogus: -+/* -+ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", -+ start, end, di->txout, forceall)); -+*/ -+ return (NULL); -+} + -+static void * -+dma32_getnextrxp(dma_info_t *di, bool forceall) -+{ -+ uint i; -+ void *rxp; ++ case PCMCIA_BUS: ++ return (0); + -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma_rxenabled(di)); + -+ i = di->rxin; ++ case PCI_BUS: + -+ /* return if no packets posted */ -+ if (i == di->rxout) -+ return (NULL); ++ /* pcie core doesn't have any mapping to control the xtal pu */ ++ if (PCIE(si)) ++ return -1; + -+ /* ignore curr if forceall */ -+ if (!forceall && (i == B2I(R_REG(&di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) -+ return (NULL); ++ in = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_IN, sizeof(uint32)); ++ out = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32)); ++ outen = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof(uint32)); + -+ /* get the packet pointer that corresponds to the rx descriptor */ -+ rxp = di->rxp[i]; -+ ASSERT(rxp); -+ di->rxp[i] = NULL; ++ /* ++ * Avoid glitching the clock if GPRS is already using it. ++ * We can't actually read the state of the PLLPD so we infer it ++ * by the value of XTAL_PU which *is* readable via gpioin. ++ */ ++ if (on && (in & PCI_CFG_GPIO_XTAL)) ++ return (0); + -+ /* clear this packet from the descriptor ring */ -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), -+ di->rxbufsize, DMA_RX, rxp); -+ W_SM(&di->rxd32[i].addr, 0xdeadbeef); ++ if (what & XTAL) ++ outen |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ outen |= PCI_CFG_GPIO_PLL; ++ ++ if (on) { ++ /* turn primary xtal on */ ++ if (what & XTAL) { ++ out |= PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, ++ sizeof(uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, ++ sizeof(uint32), outen); ++ OSL_DELAY(XTAL_ON_DELAY); ++ } ++ ++ /* turn pll on */ ++ if (what & PLL) { ++ out &= ~PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, ++ sizeof(uint32), out); ++ OSL_DELAY(2000); ++ } ++ } else { ++ if (what & XTAL) ++ out &= ~PCI_CFG_GPIO_XTAL; ++ if (what & PLL) ++ out |= PCI_CFG_GPIO_PLL; ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof(uint32), out); ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof(uint32), ++ outen); ++ } + -+ di->rxin = NEXTRXD(i); ++ default: ++ return (-1); ++ } + -+ return (rxp); ++ return (0); +} + -+static void -+dma32_txrotate(di_t *di) ++/* set dynamic clk control mode (forceslow, forcefast, dynamic) */ ++/* returns true if we are forcing fast clock */ ++bool ++sb_clkctl_clk(sb_t *sbh, uint mode) +{ -+ uint ad; -+ uint nactive; -+ uint rot; -+ uint old, new; -+ uint32 w; -+ uint first, last; -+ -+ ASSERT(dma_txsuspendedidle(di)); -+ -+ nactive = dma_txactive(di); -+ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); -+ rot = TXD(ad - di->txin); -+ -+ ASSERT(rot < di->ntxd); -+ -+ /* full-ring case is a lot harder - don't worry about this */ -+ if (rot >= (di->ntxd - nactive)) { -+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); -+ return; -+ } -+ -+ first = di->txin; -+ last = PREVTXD(di->txout); ++ sb_info_t *si; ++ uint origidx; ++ chipcregs_t *cc; ++ uint32 scc; ++ uint intr_val = 0; + -+ /* move entries starting at last and moving backwards to first */ -+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { -+ new = TXD(old + rot); ++ si = SB_INFO(sbh); + -+ /* -+ * Move the tx dma descriptor. -+ * EOT is set only in the last entry in the ring. -+ */ -+ w = R_SM(&di->txd32[old].ctrl) & ~CTRL_EOT; -+ if (new == (di->ntxd - 1)) -+ w |= CTRL_EOT; -+ W_SM(&di->txd32[new].ctrl, w); -+ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); ++ /* chipcommon cores prior to rev6 don't support dynamic clock control */ ++ if (si->sb.ccrev < 6) ++ return (FALSE); + -+ /* zap the old tx dma descriptor address field */ -+ W_SM(&di->txd32[old].addr, 0xdeadbeef); + -+ /* move the corresponding txp[] entry */ -+ ASSERT(di->txp[new] == NULL); -+ di->txp[new] = di->txp[old]; -+ di->txp[old] = NULL; -+ } ++ /* Chips with ccrev 10 are EOL and they don't have SYCC_HR which we use below */ ++ ASSERT(si->sb.ccrev != 10); + -+ /* update txin and txout */ -+ di->txin = ad; -+ di->txout = TXD(di->txout + rot); -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ INTR_OFF(si, intr_val); + -+ /* kick the chip */ -+ W_REG(&di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); -+} ++ origidx = si->curidx; + -+/*** 64 bits DMA non-inline functions ***/ ++ if (sb_setcore(sbh, SB_MIPS33, 0) && (sb_corerev(&si->sb) <= 7) && ++ (BUSTYPE(si->sb.bustype) == SB_BUS) && (si->sb.ccrev >= 10)) ++ goto done; + -+#ifdef BCMDMA64 ++ /* PR32414WAR "Force HT clock on" all the time, no dynamic clk ctl */ ++ if ((si->sb.chip == BCM4311_CHIP_ID) && (si->sb.chiprev <= 1)) ++ goto done; + -+static bool -+dma64_alloc(dma_info_t *di, uint direction) -+{ -+ uint size; -+ uint ddlen; -+ uint32 alignbytes; -+ void *va; ++ cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); ++ ASSERT(cc != NULL); + -+ ddlen = sizeof (dma64dd_t); ++ if (!(R_REG(si->osh, &cc->capabilities) & CAP_PWR_CTL)) ++ goto done; + -+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ switch (mode) { ++ case CLK_FAST: /* force fast (pll) clock */ ++ if (si->sb.ccrev < 10) { ++ /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ ++ sb_clkctl_xtal(&si->sb, XTAL, ON); + -+ alignbytes = di->dma64align; ++ SET_REG(si->osh, &cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); ++ } else ++ OR_REG(si->osh, &cc->system_clk_ctl, SYCC_HR); ++ /* wait for the PLL */ ++ OSL_DELAY(PLL_DELAY); ++ break; + -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes)) -+ size += alignbytes; ++ case CLK_DYNAMIC: /* enable dynamic clock control */ + ++ if (si->sb.ccrev < 10) { ++ scc = R_REG(si->osh, &cc->slow_clk_ctl); ++ scc &= ~(SCC_FS | SCC_IP | SCC_XC); ++ if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) ++ scc |= SCC_XC; ++ W_REG(si->osh, &cc->slow_clk_ctl, scc); + -+ if (direction == DMA_TX) { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); -+ return FALSE; ++ /* for dynamic control, we have to release our xtal_pu "force on" */ ++ if (scc & SCC_XC) ++ sb_clkctl_xtal(&si->sb, XTAL, OFF); ++ } else { ++ /* Instaclock */ ++ AND_REG(si->osh, &cc->system_clk_ctl, ~SYCC_HR); + } ++ break; + -+ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); -+ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va); -+ di->txdpa += di->txdalign; -+ di->txdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes)); -+ } else { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); -+ return FALSE; -+ } -+ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); -+ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va); -+ di->rxdpa += di->rxdalign; -+ di->rxdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes)); ++ default: ++ ASSERT(0); + } + -+ return TRUE; ++done: ++ sb_setcoreidx(sbh, origidx); ++ INTR_RESTORE(si, intr_val); ++ return (mode == CLK_FAST); +} + -+static void -+dma64_txreset(dma_info_t *di) ++/* register driver interrupt disabling and restoring callback functions */ ++void ++sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, ++ void *intrsenabled_fn, void *intr_arg) +{ -+ uint32 status; -+ -+ /* suspend tx DMA first */ -+ W_REG(&di->d64txregs->control, D64_XC_SE); -+ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED && -+ status != D64_XS0_XS_IDLE && -+ status != D64_XS0_XS_STOPPED, -+ 10000); -+ -+ W_REG(&di->d64txregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED, -+ 10000); -+ -+ if (status != D64_XS0_XS_DISABLED) { -+ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); -+ } ++ sb_info_t *si; + -+ /* wait for the last transaction to complete */ -+ OSL_DELAY(300); ++ si = SB_INFO(sbh); ++ si->intr_arg = intr_arg; ++ si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn; ++ si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn; ++ si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn; ++ /* save current core id. when this function called, the current core ++ * must be the core which provides driver functions(il, et, wl, etc.) ++ */ ++ si->dev_coreid = si->coreid[si->curidx]; +} + -+static void -+dma64_rxreset(dma_info_t *di) -+{ -+ uint32 status; -+ -+ W_REG(&di->d64rxregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED, -+ 10000); -+ -+ if (status != D64_RS0_RS_DISABLED) { -+ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); -+ } -+} + -+static bool -+dma64_txsuspendedidle(dma_info_t *di) ++int ++sb_corepciid(sb_t *sbh, uint func, uint16 *pcivendor, uint16 *pcidevice, ++ uint8 *pciclass, uint8 *pcisubclass, uint8 *pciprogif, ++ uint8 *pciheader) +{ ++ uint16 vendor = 0xffff, device = 0xffff; ++ uint core, unit; ++ uint chip, chippkg; ++ uint nfunc; ++ char varname[SB_DEVPATH_BUFSZ + 8]; ++ uint8 class, subclass, progif; ++ char devpath[SB_DEVPATH_BUFSZ]; ++ uint8 header; + -+ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE)) -+ return 0; -+ -+ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) -+ return 1; ++ core = sb_coreid(sbh); ++ unit = sb_coreunit(sbh); + -+ return 0; -+} ++ chip = sb_chip(sbh); ++ chippkg = sb_chippkg(sbh); + -+/* -+ * supports full 32bit dma engine buffer addressing so -+ * dma buffers can cross 4 Kbyte page boundaries. -+ */ -+static int -+dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) -+{ -+ void *p, *next; -+ uchar *data; -+ uint len; -+ uint txout; -+ uint32 flags; -+ uint32 pa; ++ progif = 0; ++ header = PCI_HEADER_NORMAL; + -+ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ /* Verify whether the function exists for the core */ ++ nfunc = (core == SB_USB20H) ? 2 : 1; ++ if (func >= nfunc) ++ return BCME_ERROR; + -+ txout = di->txout; -+ flags = 0; ++ /* Known vendor translations */ ++ switch (sb_corevendor(sbh)) { ++ case SB_VEND_BCM: ++ vendor = VENDOR_BROADCOM; ++ break; ++ default: ++ return BCME_ERROR; ++ } + -+ /* -+ * Walk the chain of packet buffers -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ data = PKTDATA(di->osh, p); -+ len = PKTLEN(di->osh, p); -+ next = PKTNEXT(di->osh, p); ++ /* Determine class based on known core codes */ ++ switch (core) { ++ case SB_ILINE20: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ device = BCM47XX_ILINE_ID; ++ break; ++ case SB_ENET: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ device = BCM47XX_ENET_ID; ++ break; ++ case SB_GIGETH: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_ETHER; ++ device = BCM47XX_GIGETH_ID; ++ break; ++ case SB_SDRAM: ++ case SB_MEMC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_RAM; ++ device = (uint16)core; ++ break; ++ case SB_PCI: ++ case SB_PCIE: ++ class = PCI_CLASS_BRIDGE; ++ subclass = PCI_BRIDGE_PCI; ++ device = (uint16)core; ++ header = PCI_HEADER_BRIDGE; ++ break; ++ case SB_MIPS: ++ case SB_MIPS33: ++ class = PCI_CLASS_CPU; ++ subclass = PCI_CPU_MIPS; ++ device = (uint16)core; ++ break; ++ case SB_CODEC: ++ class = PCI_CLASS_COMM; ++ subclass = PCI_COMM_MODEM; ++ device = BCM47XX_V90_ID; ++ break; ++ case SB_USB: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ device = BCM47XX_USB_ID; ++ break; ++ case SB_USB11H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = 0x10; /* OHCI */ ++ device = BCM47XX_USBH_ID; ++ break; ++ case SB_USB20H: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ progif = func == 0 ? 0x10 : 0x20; /* OHCI/EHCI */ ++ device = BCM47XX_USB20H_ID; ++ header = 0x80; /* multifunction */ ++ break; ++ case SB_USB11D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ device = BCM47XX_USBD_ID; ++ break; ++ case SB_USB20D: ++ class = PCI_CLASS_SERIAL; ++ subclass = PCI_SERIAL_USB; ++ device = BCM47XX_USB20D_ID; ++ break; ++ case SB_IPSEC: ++ class = PCI_CLASS_CRYPT; ++ subclass = PCI_CRYPT_NETWORK; ++ device = BCM47XX_IPSEC_ID; ++ break; ++ case SB_ROBO: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ device = BCM47XX_ROBO_ID; ++ break; ++ case SB_EXTIF: ++ case SB_CC: ++ class = PCI_CLASS_MEMORY; ++ subclass = PCI_MEMORY_FLASH; ++ device = (uint16)core; ++ break; ++ case SB_D11: ++ class = PCI_CLASS_NET; ++ subclass = PCI_NET_OTHER; ++ /* Let nvram variable override core ID */ ++ sb_devpath(sbh, devpath, sizeof(devpath)); ++ sprintf(varname, "%sdevid", devpath); ++ if ((device = (uint16)getintvar(NULL, varname))) ++ break; ++ /* ++ * no longer support wl%did, but keep the code ++ * here for backward compatibility. ++ */ ++ sprintf(varname, "wl%did", unit); ++ if ((device = (uint16)getintvar(NULL, varname))) ++ break; ++ /* Chip specific conversion */ ++ if (chip == BCM4712_CHIP_ID) { ++ if (chippkg == BCM4712SMALL_PKG_ID) ++ device = BCM4306_D11G_ID; ++ else ++ device = BCM4306_D11DUAL_ID; ++ break; ++ } ++ /* ignore it */ ++ device = 0xffff; ++ break; ++ case SB_SATAXOR: ++ class = PCI_CLASS_XOR; ++ subclass = PCI_XOR_QDMA; ++ device = BCM47XX_SATAXOR_ID; ++ break; ++ case SB_ATA100: ++ class = PCI_CLASS_DASDI; ++ subclass = PCI_DASDI_IDE; ++ device = BCM47XX_ATA100_ID; ++ break; + -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) -+ goto outoftxd; ++ default: ++ class = subclass = progif = 0xff; ++ device = (uint16)core; ++ break; ++ } + -+ if (len == 0) -+ continue; ++ *pcivendor = vendor; ++ *pcidevice = device; ++ *pciclass = class; ++ *pcisubclass = subclass; ++ *pciprogif = progif; ++ *pciheader = header; + -+ /* get physical address of buffer start */ -+ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ return 0; ++} + -+ flags = coreflags; -+ -+ if (p == p0) -+ flags |= D64_CTRL1_SOF; -+ if (next == NULL) -+ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); -+ if (txout == (di->ntxd - 1)) -+ flags |= D64_CTRL1_EOT; + -+ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); + -+ ASSERT(di->txp[txout] == NULL); ++/* use the mdio interface to write to mdio slaves */ ++static int ++sb_pcie_mdiowrite(sb_info_t *si, uint physmedia, uint regaddr, uint val) ++{ ++ uint mdiodata; ++ uint i = 0; ++ sbpcieregs_t *pcieregs; + -+ txout = NEXTTXD(txout); -+ } ++ pcieregs = (sbpcieregs_t*) sb_setcoreidx(&si->sb, si->sb.buscoreidx); ++ ASSERT(pcieregs); + -+ /* if last txd eof not set, fix it */ -+ if (!(flags & D64_CTRL1_EOF)) -+ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); ++ /* enable mdio access to SERDES */ ++ W_REG(si->osh, (&pcieregs->mdiocontrol), MDIOCTL_PREAM_EN | MDIOCTL_DIVISOR_VAL); + -+ /* save the packet */ -+ di->txp[PREVTXD(txout)] = p0; ++ mdiodata = MDIODATA_START | MDIODATA_WRITE | ++ (physmedia << MDIODATA_DEVADDR_SHF) | ++ (regaddr << MDIODATA_REGADDR_SHF) | MDIODATA_TA | val; + -+ /* bump the tx descriptor index */ -+ di->txout = txout; ++ W_REG(si->osh, (&pcieregs->mdiodata), mdiodata); + -+ /* kick the chip */ -+ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); ++ PR28829_DELAY(); + -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ /* retry till the transaction is complete */ ++ while (i < 10) { ++ if (R_REG(si->osh, &(pcieregs->mdiocontrol)) & MDIOCTL_ACCESS_DONE) { ++ /* Disable mdio access to SERDES */ ++ W_REG(si->osh, (&pcieregs->mdiocontrol), 0); ++ return 0; ++ } ++ OSL_DELAY(1000); ++ i++; ++ } + -+ return (0); ++ SB_ERROR(("sb_pcie_mdiowrite: timed out\n")); ++ /* Disable mdio access to SERDES */ ++ W_REG(si->osh, (&pcieregs->mdiocontrol), 0); ++ ASSERT(0); ++ return 1; + -+outoftxd: -+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); -+ PKTFREE(di->osh, p0, TRUE); -+ di->txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); +} + -+static void* -+dma64_getnexttxp(dma_info_t *di, bool forceall) ++/* indirect way to read pcie config regs */ ++uint ++sb_pcie_readreg(void *sb, void* arg1, uint offset) +{ -+ uint start, end, i; -+ void *txp; ++ sb_info_t *si; ++ sb_t *sbh; ++ uint retval = 0xFFFFFFFF; ++ sbpcieregs_t *pcieregs; ++ uint addrtype; + -+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); ++ sbh = (sb_t *)sb; ++ si = SB_INFO(sbh); ++ ASSERT(PCIE(si)); + -+ txp = NULL; ++ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); ++ ASSERT(pcieregs); + -+ start = di->txin; -+ if (forceall) -+ end = di->txout; -+ else -+ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ addrtype = (uint)((uintptr)arg1); ++ switch (addrtype) { ++ case PCIE_CONFIGREGS: ++ W_REG(si->osh, (&pcieregs->configaddr), offset); ++ retval = R_REG(si->osh, &(pcieregs->configdata)); ++ break; ++ case PCIE_PCIEREGS: ++ W_REG(si->osh, &(pcieregs->pcieaddr), offset); ++ retval = R_REG(si->osh, &(pcieregs->pciedata)); ++ break; ++ default: ++ ASSERT(0); ++ break; ++ } ++ return retval; ++} + -+ if ((start == 0) && (end > di->txout)) -+ goto bogus; ++/* indirect way to write pcie config/mdio/pciecore regs */ ++uint ++sb_pcie_writereg(sb_t *sbh, void *arg1, uint offset, uint val) ++{ ++ sb_info_t *si; ++ sbpcieregs_t *pcieregs; ++ uint addrtype; + -+ for (i = start; i != end && !txp; i = NEXTTXD(i)) { -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow), -+ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]); ++ si = SB_INFO(sbh); ++ ASSERT(PCIE(si)); ++ ++ pcieregs = (sbpcieregs_t *)sb_setcore(sbh, SB_PCIE, 0); ++ ASSERT(pcieregs); + -+ W_SM(&di->txd64[i].addrlow, 0xdeadbeef); -+ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); ++ addrtype = (uint)((uintptr)arg1); + -+ txp = di->txp[i]; -+ di->txp[i] = NULL; ++ switch (addrtype) { ++ case PCIE_CONFIGREGS: ++ W_REG(si->osh, (&pcieregs->configaddr), offset); ++ W_REG(si->osh, (&pcieregs->configdata), val); ++ break; ++ case PCIE_PCIEREGS: ++ W_REG(si->osh, (&pcieregs->pcieaddr), offset); ++ W_REG(si->osh, (&pcieregs->pciedata), val); ++ break; ++ default: ++ ASSERT(0); ++ break; + } ++ return 0; ++} + -+ di->txin = i; -+ -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++/* Build device path. Support SB, PCI, and JTAG for now. */ ++int ++sb_devpath(sb_t *sbh, char *path, int size) ++{ ++ ASSERT(path); ++ ASSERT(size >= SB_DEVPATH_BUFSZ); + -+ return (txp); ++ switch (BUSTYPE((SB_INFO(sbh))->sb.bustype)) { ++ case SB_BUS: ++ case JTAG_BUS: ++ sprintf(path, "sb/%u/", sb_coreidx(sbh)); ++ break; ++ case PCI_BUS: ++ ASSERT((SB_INFO(sbh))->osh); ++ sprintf(path, "pci/%u/%u/", OSL_PCI_BUS((SB_INFO(sbh))->osh), ++ OSL_PCI_SLOT((SB_INFO(sbh))->osh)); ++ break; ++ case PCMCIA_BUS: ++ SB_ERROR(("sb_devpath: OSL_PCMCIA_BUS() not implemented, bus 1 assumed\n")); ++ SB_ERROR(("sb_devpath: OSL_PCMCIA_SLOT() not implemented, slot 1 assumed\n")); ++ sprintf(path, "pc/%u/%u/", 1, 1); ++ break; ++ case SDIO_BUS: ++ SB_ERROR(("sb_devpath: device 0 assumed\n")); ++ sprintf(path, "sd/%u/", sb_coreidx(sbh)); ++ break; ++ default: ++ ASSERT(0); ++ break; ++ } + -+bogus: -+/* -+ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", -+ start, end, di->txout, forceall)); -+*/ -+ return (NULL); ++ return 0; +} + -+static void * -+dma64_getnextrxp(dma_info_t *di, bool forceall) ++/* ++ * Fixup SROMless PCI device's configuration. ++ * The current core may be changed upon return. ++ */ ++static int ++sb_pci_fixcfg(sb_info_t *si) +{ -+ uint i; -+ void *rxp; ++ uint origidx, pciidx; ++ sbpciregs_t *pciregs; ++ sbpcieregs_t *pcieregs; ++ uint16 val16, *reg16; ++ char name[SB_DEVPATH_BUFSZ+16], *value; ++ char devpath[SB_DEVPATH_BUFSZ]; + -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma_rxenabled(di)); ++ ASSERT(BUSTYPE(si->sb.bustype) == PCI_BUS); + -+ i = di->rxin; ++ /* Fixup PI in SROM shadow area to enable the correct PCI core access */ ++ /* save the current index */ ++ origidx = sb_coreidx(&si->sb); + -+ /* return if no packets posted */ -+ if (i == di->rxout) -+ return (NULL); ++ /* check 'pi' is correct and fix it if not */ ++ if (si->sb.buscoretype == SB_PCIE) { ++ pcieregs = (sbpcieregs_t *)sb_setcore(&si->sb, SB_PCIE, 0); ++ ASSERT(pcieregs); ++ reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; ++ } else if (si->sb.buscoretype == SB_PCI) { ++ pciregs = (sbpciregs_t *)sb_setcore(&si->sb, SB_PCI, 0); ++ ASSERT(pciregs); ++ reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; ++ } else { ++ ASSERT(0); ++ return -1; ++ } ++ pciidx = sb_coreidx(&si->sb); ++ val16 = R_REG(si->osh, reg16); ++ if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (uint16)pciidx) { ++ val16 = (uint16)(pciidx << SRSH_PI_SHIFT) | (val16 & ~SRSH_PI_MASK); ++ W_REG(si->osh, reg16, val16); ++ } + -+ /* ignore curr if forceall */ -+ if (!forceall && (i == B2I(R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t))) -+ return (NULL); ++ /* restore the original index */ ++ sb_setcoreidx(&si->sb, origidx); + -+ /* get the packet pointer that corresponds to the rx descriptor */ -+ rxp = di->rxp[i]; -+ ASSERT(rxp); -+ di->rxp[i] = NULL; ++ /* ++ * Fixup bar0window in PCI config space to make the core indicated ++ * by the nvram variable the current core. ++ * !Do it last, it may change the current core! ++ */ ++ if (sb_devpath(&si->sb, devpath, sizeof(devpath))) ++ return -1; ++ sprintf(name, "%sb0w", devpath); ++ if ((value = getvar(NULL, name))) { ++ OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, sizeof(uint32), ++ bcm_strtoul(value, NULL, 16)); ++ /* update curidx since the current core is changed */ ++ si->curidx = _sb_coreidx(si); ++ if (si->curidx == BADIDX) { ++ SB_ERROR(("sb_pci_fixcfg: bad core index\n")); ++ return -1; ++ } ++ } + -+ /* clear this packet from the descriptor ring */ -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow), -+ di->rxbufsize, DMA_RX, rxp); ++ return 0; ++} + -+ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); -+ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); ++static uint ++sb_chipc_capability(sb_t *sbh) ++{ ++ sb_info_t *si; + -+ di->rxin = NEXTRXD(i); ++ si = SB_INFO(sbh); + -+ return (rxp); ++ /* Make sure that there is ChipCommon core present */ ++ if (si->coreid[SB_CC_IDX] == SB_CC) ++ return (sb_corereg(si, SB_CC_IDX, OFFSETOF(chipcregs_t, capabilities), ++ 0, 0)); ++ return 0; +} + -+static void -+dma64_txrotate(di_t *di) ++/* Return ADDR64 capability of the backplane */ ++bool ++sb_backplane64(sb_t *sbh) +{ -+ uint ad; -+ uint nactive; -+ uint rot; -+ uint old, new; -+ uint32 w; -+ uint first, last; ++ return ((sb_chipc_capability(sbh) & CAP_BKPLN64) != 0); ++} + -+ ASSERT(dma_txsuspendedidle(di)); ++void ++sb_btcgpiowar(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ uint intr_val = 0; ++ chipcregs_t *cc; ++ si = SB_INFO(sbh); + -+ nactive = dma_txactive(di); -+ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t); -+ rot = TXD(ad - di->txin); ++ /* Make sure that there is ChipCommon core present && ++ * UART_TX is strapped to 1 ++ */ ++ if (!(sb_chipc_capability(sbh) & CAP_UARTGPIO)) ++ return; + -+ ASSERT(rot < di->ntxd); ++ /* sb_corereg cannot be used as we have to guarantee 8-bit read/writes */ ++ INTR_OFF(si, intr_val); + -+ /* full-ring case is a lot harder - don't worry about this */ -+ if (rot >= (di->ntxd - nactive)) { -+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); -+ return; -+ } ++ origidx = sb_coreidx(sbh); + -+ first = di->txin; -+ last = PREVTXD(di->txout); ++ cc = (chipcregs_t *)sb_setcore(sbh, SB_CC, 0); ++ if (cc == NULL) ++ goto end; + -+ /* move entries starting at last and moving backwards to first */ -+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { -+ new = TXD(old + rot); ++ W_REG(si->osh, &cc->uart0mcr, R_REG(si->osh, &cc->uart0mcr) | 0x04); + -+ /* -+ * Move the tx dma descriptor. -+ * EOT is set only in the last entry in the ring. -+ */ -+ w = R_SM(&di->txd64[old].ctrl1) & ~D64_CTRL1_EOT; -+ if (new == (di->ntxd - 1)) -+ w |= D64_CTRL1_EOT; -+ W_SM(&di->txd64[new].ctrl1, w); ++end: ++ /* restore the original index */ ++ sb_setcoreidx(sbh, origidx); + -+ w = R_SM(&di->txd64[old].ctrl2); -+ W_SM(&di->txd64[new].ctrl2, w); ++ INTR_RESTORE(si, intr_val); ++} + -+ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); -+ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); ++/* check if the device is removed */ ++bool ++sb_deviceremoved(sb_t *sbh) ++{ ++ uint32 w; ++ sb_info_t *si; + -+ /* zap the old tx dma descriptor address field */ -+ W_SM(&di->txd64[old].addrlow, 0xdeadbeef); -+ W_SM(&di->txd64[old].addrhigh, 0xdeadbeef); ++ si = SB_INFO(sbh); + -+ /* move the corresponding txp[] entry */ -+ ASSERT(di->txp[new] == NULL); -+ di->txp[new] = di->txp[old]; -+ di->txp[old] = NULL; ++ switch (BUSTYPE(si->sb.bustype)) { ++ case PCI_BUS: ++ ASSERT(si->osh); ++ w = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_VID, sizeof(uint32)); ++ if ((w & 0xFFFF) != VENDOR_BROADCOM) ++ return TRUE; ++ else ++ return FALSE; ++ default: ++ return FALSE; + } ++ return FALSE; ++} + -+ /* update txin and txout */ -+ di->txin = ad; -+ di->txout = TXD(di->txout + rot); -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++/* Return the RAM size of the SOCRAM core */ ++uint32 ++sb_socram_size(sb_t *sbh) ++{ ++ sb_info_t *si; ++ uint origidx; ++ uint intr_val = 0; + -+ /* kick the chip */ -+ W_REG(&di->d64txregs->ptr, I2B(di->txout, dma64dd_t)); -+} ++ sbsocramregs_t *regs; ++ bool wasup; ++ uint corerev; ++ uint32 coreinfo; ++ uint memsize = 0; + -+#endif ++ si = SB_INFO(sbh); ++ ASSERT(si); + -diff -Naur linux.old/drivers/net/wl/hnddma.h linux.dev/drivers/net/wl/hnddma.h ---- linux.old/drivers/net/wl/hnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/hnddma.h 2006-04-06 16:57:44.000000000 +0200 -@@ -0,0 +1,69 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ ++ /* Block ints and save current core */ ++ INTR_OFF(si, intr_val); ++ origidx = sb_coreidx(sbh); + -+#ifndef _hnddma_h_ -+#define _hnddma_h_ ++ /* Switch to SOCRAM core */ ++ if (!(regs = sb_setcore(sbh, SB_SOCRAM, 0))) ++ goto done; + -+/* export structure */ -+typedef volatile struct { -+ /* rx error counters */ -+ uint rxgiants; /* rx giant frames */ -+ uint rxnobuf; /* rx out of dma descriptors */ -+ /* tx error counters */ -+ uint txnobuf; /* tx out of dma descriptors */ -+} hnddma_t; ++ /* Get info for determining size */ ++ if (!(wasup = sb_iscoreup(sbh))) ++ sb_core_reset(sbh, 0, 0); ++ corerev = sb_corerev(sbh); ++ coreinfo = R_REG(si->osh, ®s->coreinfo); + -+#ifndef di_t -+#define di_t void -+#endif ++ /* Calculate size from coreinfo based on rev */ ++ switch (corerev) { ++ case 0: ++ memsize = 1 << (16 + (coreinfo & SRCI_MS0_MASK)); ++ break; ++ default: /* rev >= 1 */ ++ memsize = 1 << (SR_BSZ_BASE + (coreinfo & SRCI_SRBSZ_MASK)); ++ memsize *= (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT; ++ break; ++ } + -+#ifndef osl_t -+#define osl_t void -+#endif ++ /* Return to previous state and core */ ++ if (!wasup) ++ sb_core_disable(sbh, 0); ++ sb_setcoreidx(sbh, origidx); + -+/* externs */ -+extern void dma_detach(di_t *di); -+extern void dma_txreset(di_t *di); -+extern void dma_rxreset(di_t *di); -+extern void dma_txinit(di_t *di); -+extern bool dma_txenabled(di_t *di); -+extern void dma_rxinit(di_t *di); -+extern void dma_rxenable(di_t *di); -+extern bool dma_rxenabled(di_t *di); -+extern void dma_txsuspend(di_t *di); -+extern void dma_txresume(di_t *di); -+extern bool dma_txsuspended(di_t *di); -+extern bool dma_txsuspendedidle(di_t *di); -+extern bool dma_txstopped(di_t *di); -+extern bool dma_rxstopped(di_t *di); -+extern int dma_txfast(di_t *di, void *p, uint32 coreflags); -+extern void dma_fifoloopbackenable(di_t *di); -+extern void *dma_rx(di_t *di); -+extern void dma_rxfill(di_t *di); -+extern void dma_txreclaim(di_t *di, bool forceall); -+extern void dma_rxreclaim(di_t *di); -+extern uintptr dma_getvar(di_t *di, char *name); -+extern void *dma_getnexttxp(di_t *di, bool forceall); -+extern void *dma_peeknexttxp(di_t *di); -+extern void *dma_getnextrxp(di_t *di, bool forceall); -+extern void dma_txblock(di_t *di); -+extern void dma_txunblock(di_t *di); -+extern uint dma_txactive(di_t *di); -+extern void dma_txrotate(di_t *di); -+ -+extern void dma_rxpiomode(dma32regs_t *); -+extern void dma_txpioloopback(dma32regs_t *); ++done: ++ INTR_RESTORE(si, intr_val); ++ return memsize; ++} + + -+#endif /* _hnddma_h_ */ -diff -Naur linux.old/drivers/net/wl/pktq.h linux.dev/drivers/net/wl/pktq.h ---- linux.old/drivers/net/wl/pktq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/pktq.h 2006-04-06 17:32:52.000000000 +0200 -@@ -0,0 +1,48 @@ +diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setup.c +--- linux.old/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/setup.c 2006-04-27 23:22:53.000000000 +0200 +@@ -0,0 +1,241 @@ +/* -+ * Misc useful os-independent macros and functions. ++ * Generic setup routines for Broadcom MIPS boards ++ * ++ * Copyright (C) 2005 Felix Fietkau ++ * ++ * 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN ++ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, ++ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT ++ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF ++ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ++ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF ++ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ * ++ * You should have received a copy of the GNU General Public License along ++ * with this program; if not, write to the Free Software Foundation, Inc., ++ * 675 Mass Ave, Cambridge, MA 02139, USA. ++ * + * + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. @@ -17483,776 +15114,1315 @@ diff -Naur linux.old/drivers/net/wl/pktq.h linux.dev/drivers/net/wl/pktq.h + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ ++ * + */ + -+#ifndef _pktq_h_ -+#define _pktq_h_ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+/*** driver-only section ***/ -+#ifdef BCMDRIVER ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+/* generic osl packet queue */ -+struct pktq { -+ void *head; /* first packet to dequeue */ -+ void *tail; /* last packet to dequeue */ -+ uint len; /* number of queued packets */ -+ uint maxlen; /* maximum number of queued packets */ -+ bool priority; /* enqueue by packet priority */ -+ uint8 prio_map[MAXPRIO+1]; /* user priority to packet enqueue policy map */ -+}; -+#define DEFAULT_QLEN 128 ++/* Virtual IRQ base, after last hw IRQ */ ++#define SBMIPS_VIRTIRQ_BASE 6 + -+#define pktq_len(q) ((q)->len) -+#define pktq_avail(q) ((q)->maxlen - (q)->len) -+#define pktq_head(q) ((q)->head) -+#define pktq_full(q) ((q)->len >= (q)->maxlen) -+#define _pktq_pri(q, pri) ((q)->prio_map[pri]) -+#define pktq_tailpri(q) ((q)->tail ? _pktq_pri(q, PKTPRIO((q)->tail)) : _pktq_pri(q, 0)) ++/* # IRQs, hw and sw IRQs */ ++#define SBMIPS_NUMIRQS 8 + -+/* externs */ -+/* packet */ -+extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); -+extern uint pkttotlen(osl_t *osh, void *); -+extern void pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]); -+extern void pktenq(struct pktq *q, void *p, bool lifo); -+extern void *pktdeq(struct pktq *q); -+extern void *pktdeqtail(struct pktq *q); ++/* Global SB handle */ ++sb_t *bcm947xx_sbh = NULL; ++spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED; ++ ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock ++ ++extern void bcm947xx_time_init(void); ++extern void bcm947xx_timer_setup(struct irqaction *irq); + ++#ifdef CONFIG_REMOTE_DEBUG ++extern void set_debug_traps(void); ++extern void rs_kgdb_hook(struct serial_state *); ++extern void breakpoint(void); +#endif -+#endif /* _pktq_h_ */ -diff -Naur linux.old/drivers/net/wl/sbhnddma.h linux.dev/drivers/net/wl/sbhnddma.h ---- linux.old/drivers/net/wl/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/sbhnddma.h 2006-04-06 15:34:14.000000000 +0200 -@@ -0,0 +1,312 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ + -+#ifndef _sbhnddma_h_ -+#define _sbhnddma_h_ ++#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ++extern struct ide_ops std_ide_ops; ++#endif + -+ -+/* 2byte-wide pio register set per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint16 fifocontrol; -+ uint16 fifodata; -+ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */ -+ uint16 PAD; -+} pio2regs_t; ++/* Kernel command line */ ++char arcs_cmdline[CL_SIZE] __initdata = CONFIG_CMDLINE; ++extern void sb_serial_init(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)); + -+/* a pair of pio channels(tx and rx) */ -+typedef volatile struct { -+ pio2regs_t tx; -+ pio2regs_t rx; -+} pio2regp_t; ++void ++bcm947xx_machine_restart(char *command) ++{ ++ printk("Please stand by while rebooting the system...\n"); + -+/* 4byte-wide pio register set per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 fifocontrol; -+ uint32 fifodata; -+} pio4regs_t; ++ /* Set the watchdog timer to reset immediately */ ++ __cli(); ++ sb_watchdog(sbh, 1); ++ while (1); ++} + -+/* a pair of pio channels(tx and rx) */ -+typedef volatile struct { -+ pio4regs_t tx; -+ pio4regs_t rx; -+} pio4regp_t; ++void ++bcm947xx_machine_halt(void) ++{ ++ printk("System halted\n"); + ++ /* Disable interrupts and watchdog and spin forever */ ++ __cli(); ++ sb_watchdog(sbh, 0); ++ while (1); ++} + ++#ifdef CONFIG_SERIAL + -+/* DMA structure: -+ * support two DMA engines: 32 bits address or 64 bit addressing -+ * basic DMA register set is per channel(transmit or receive) -+ * a pair of channels is defined for convenience -+ */ ++static int ser_line = 0; + ++typedef struct { ++ void *regs; ++ uint irq; ++ uint baud_base; ++ uint reg_shift; ++} serial_port; + -+/*** 32 bits addressing ***/ ++static serial_port ports[4]; ++static int num_ports = 0; + -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 addr; /* descriptor ring base address (4K aligned) */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 status; /* current active descriptor, et al */ -+} dma32regs_t; ++static void ++serial_add(void *regs, uint irq, uint baud_base, uint reg_shift) ++{ ++ ports[num_ports].regs = regs; ++ ports[num_ports].irq = irq; ++ ports[num_ports].baud_base = baud_base; ++ ports[num_ports].reg_shift = reg_shift; ++ num_ports++; ++} + -+typedef volatile struct { -+ dma32regs_t xmt; /* dma tx channel */ -+ dma32regs_t rcv; /* dma rx channel */ -+} dma32regp_t; ++static void ++do_serial_add(serial_port *port) ++{ ++ void *regs; ++ uint irq; ++ uint baud_base; ++ uint reg_shift; ++ struct serial_struct s; ++ ++ regs = port->regs; ++ irq = port->irq; ++ baud_base = port->baud_base; ++ reg_shift = port->reg_shift; + -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma32diag_t; ++ memset(&s, 0, sizeof(s)); + -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl; /* misc control bits & bufcount */ -+ uint32 addr; /* data buffer address */ -+} dma32dd_t; ++ s.line = ser_line++; ++ s.iomem_base = regs; ++ s.irq = irq + 2; ++ s.baud_base = baud_base / 16; ++ s.flags = ASYNC_BOOT_AUTOCONF; ++ s.io_type = SERIAL_IO_MEM; ++ s.iomem_reg_shift = reg_shift; + -+/* -+ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. -+ */ -+#define D32MAXRINGSZ 4096 -+#define D32RINGALIGN 4096 -+#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) ++ if (early_serial_setup(&s) != 0) { ++ printk(KERN_ERR "Serial setup failed!\n"); ++ } ++} + -+/* transmit channel control */ -+#define XC_XE ((uint32)1 << 0) /* transmit enable */ -+#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ -+#define XC_LE ((uint32)1 << 2) /* loopback enable */ -+#define XC_FL ((uint32)1 << 4) /* flush request */ -+#define XC_AE ((uint32)3 << 16) /* address extension bits */ -+#define XC_AE_SHIFT 16 ++#endif /* CONFIG_SERIAL */ ++ ++void __init ++brcm_setup(void) ++{ ++ char *s; ++ int i; ++ char *value; ++ ++ /* Get global SB handle */ ++ sbh = sb_kattach(); ++ ++ /* Initialize clocks and interrupts */ ++ sb_mips_init(sbh, SBMIPS_VIRTIRQ_BASE); + -+/* transmit descriptor table pointer */ -+#define XP_LD_MASK 0xfff /* last valid descriptor */ ++ if (BCM330X(current_cpu_data.processor_id) && ++ (read_c0_diag() & BRCM_PFC_AVAIL)) { ++ /* ++ * Now that the sbh is inited set the proper PFC value ++ */ ++ printk("Setting the PFC to its default value\n"); ++ enable_pfc(PFC_AUTO); ++ } + -+/* transmit channel status */ -+#define XS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define XS_XS_MASK 0xf000 /* transmit state */ -+#define XS_XS_SHIFT 12 -+#define XS_XS_DISABLED 0x0000 /* disabled */ -+#define XS_XS_ACTIVE 0x1000 /* active */ -+#define XS_XS_IDLE 0x2000 /* idle wait */ -+#define XS_XS_STOPPED 0x3000 /* stopped */ -+#define XS_XS_SUSP 0x4000 /* suspend pending */ -+#define XS_XE_MASK 0xf0000 /* transmit errors */ -+#define XS_XE_SHIFT 16 -+#define XS_XE_NOERR 0x00000 /* no error */ -+#define XS_XE_DPE 0x10000 /* descriptor protocol error */ -+#define XS_XE_DFU 0x20000 /* data fifo underrun */ -+#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ -+#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ -+#define XS_AD_MASK 0xfff00000 /* active descriptor */ -+#define XS_AD_SHIFT 20 + -+/* receive channel control */ -+#define RC_RE ((uint32)1 << 0) /* receive enable */ -+#define RC_RO_MASK 0xfe /* receive frame offset */ -+#define RC_RO_SHIFT 1 -+#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ -+#define RC_AE ((uint32)3 << 16) /* address extension bits */ -+#define RC_AE_SHIFT 16 ++#ifdef CONFIG_SERIAL ++ sb_serial_init(sbh, serial_add); + -+/* receive descriptor table pointer */ -+#define RP_LD_MASK 0xfff /* last valid descriptor */ ++ /* reverse serial ports if nvram variable starts with console=ttyS1 */ ++ /* Initialize UARTs */ ++ s = nvram_get("kernel_args"); ++ if (!s) s = ""; ++ if (!strncmp(s, "console=ttyS1", 13)) { ++ for (i = num_ports; i; i--) ++ do_serial_add(&ports[i - 1]); ++ } else { ++ for (i = 0; i < num_ports; i++) ++ do_serial_add(&ports[i]); ++ } ++#endif + -+/* receive channel status */ -+#define RS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define RS_RS_MASK 0xf000 /* receive state */ -+#define RS_RS_SHIFT 12 -+#define RS_RS_DISABLED 0x0000 /* disabled */ -+#define RS_RS_ACTIVE 0x1000 /* active */ -+#define RS_RS_IDLE 0x2000 /* idle wait */ -+#define RS_RS_STOPPED 0x3000 /* reserved */ -+#define RS_RE_MASK 0xf0000 /* receive errors */ -+#define RS_RE_SHIFT 16 -+#define RS_RE_NOERR 0x00000 /* no error */ -+#define RS_RE_DPE 0x10000 /* descriptor protocol error */ -+#define RS_RE_DFO 0x20000 /* data fifo overflow */ -+#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ -+#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ -+#define RS_AD_MASK 0xfff00000 /* active descriptor */ -+#define RS_AD_SHIFT 20 ++#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ++ ide_ops = &std_ide_ops; ++#endif + -+/* fifoaddr */ -+#define FA_OFF_MASK 0xffff /* offset */ -+#define FA_SEL_MASK 0xf0000 /* select */ -+#define FA_SEL_SHIFT 16 -+#define FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define FA_SEL_RDD 0x40000 /* receive dma data */ -+#define FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ /* Override default command line arguments */ ++ value = nvram_get("kernel_cmdline"); ++ if (value && strlen(value) && strncmp(value, "empty", 5)) ++ strncpy(arcs_cmdline, value, sizeof(arcs_cmdline)); + -+/* descriptor control flags */ -+#define CTRL_BC_MASK 0x1fff /* buffer byte count */ -+#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ -+#define CTRL_AE_SHIFT 16 -+#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ -+#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ + -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define CTRL_CORE_MASK 0x0ff00000 ++ /* Generic setup */ ++ _machine_restart = bcm947xx_machine_restart; ++ _machine_halt = bcm947xx_machine_halt; ++ _machine_power_off = bcm947xx_machine_halt; + -+/*** 64 bits addressing ***/ ++ board_time_init = bcm947xx_time_init; ++ board_timer_setup = bcm947xx_timer_setup; ++} + -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ -+ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ -+ uint32 status0; /* current descriptor, xmt state */ -+ uint32 status1; /* active descriptor, xmt error */ -+} dma64regs_t; ++const char * ++get_system_type(void) ++{ ++ static char s[32]; + -+typedef volatile struct { -+ dma64regs_t tx; /* dma64 tx channel */ -+ dma64regs_t rx; /* dma64 rx channel */ -+} dma64regp_t; ++ if (bcm947xx_sbh) { ++ sprintf(s, "Broadcom BCM%X chip rev %d", sb_chip(bcm947xx_sbh), ++ sb_chiprev(bcm947xx_sbh)); ++ return s; ++ } ++ else ++ return "Broadcom BCM947XX"; ++} + -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma64diag_t; ++void __init ++bus_error_init(void) ++{ ++} + +diff -urN linux.old/arch/mips/bcm947xx/sflash.c linux.dev/arch/mips/bcm947xx/sflash.c +--- linux.old/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/sflash.c 2006-04-27 22:11:27.000000000 +0200 +@@ -0,0 +1,422 @@ +/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. ++ * Broadcom SiliconBackplane chipcommon serial flash interface ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sflash.c,v 1.1.1.13 2006/02/27 03:43:16 honor Exp $ + */ -+typedef volatile struct { -+ uint32 ctrl1; /* misc control bits & bufcount */ -+ uint32 ctrl2; /* buffer count and address extension */ -+ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */ -+ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */ -+} dma64dd_t; + -+/* -+ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. -+ */ -+#define D64MAXRINGSZ 8192 -+#define D64RINGALIGN 8192 -+#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+/* transmit channel control */ -+#define D64_XC_XE 0x00000001 /* transmit enable */ -+#define D64_XC_SE 0x00000002 /* transmit suspend request */ -+#define D64_XC_LE 0x00000004 /* loopback enable */ -+#define D64_XC_FL 0x00000010 /* flush request */ -+#define D64_XC_AE 0x00110000 /* address extension bits */ -+#define D64_XC_AE_SHIFT 16 ++/* Private global state */ ++static struct sflash sflash; + -+/* transmit descriptor table pointer */ -+#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ ++/* Issue a serial flash command */ ++static INLINE void ++sflash_cmd(chipcregs_t *cc, uint opcode) ++{ ++ W_REG(NULL, &cc->flashcontrol, SFLASH_START | opcode); ++ while (R_REG(NULL, &cc->flashcontrol) & SFLASH_BUSY); ++} + -+/* transmit channel status */ -+#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ -+#define D64_XS0_XS_SHIFT 28 -+#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ -+#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ -+#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ -+#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ -+#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ ++/* Initialize serial flash access */ ++struct sflash * ++sflash_init(chipcregs_t *cc) ++{ ++ uint32 id, id2; + -+#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ -+#define D64_XS1_XE_SHIFT 28 -+#define D64_XS1_XE_NOERR 0x00000000 /* no error */ -+#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ -+#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ -+#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ -+#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_XS1_XE_COREE 0x50000000 /* core error */ ++ bzero(&sflash, sizeof(sflash)); + -+/* receive channel control */ -+#define D64_RC_RE 0x00000001 /* receive enable */ -+#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ -+#define D64_RC_RO_SHIFT 1 -+#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ -+#define D64_RC_AE 0x00110000 /* address extension bits */ -+#define D64_RC_AE_SHIFT 16 ++ sflash.type = R_REG(NULL, &cc->capabilities) & CAP_FLASH_MASK; ++ ++ switch (sflash.type) { ++ case SFLASH_ST: ++ /* Probe for ST chips */ ++ sflash_cmd(cc, SFLASH_ST_DP); ++ sflash_cmd(cc, SFLASH_ST_RES); ++ id = R_REG(NULL, &cc->flashdata); ++ switch (id) { ++ case 0x11: ++ /* ST M25P20 2 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 4; ++ break; ++ case 0x12: ++ /* ST M25P40 4 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 8; ++ break; ++ case 0x13: ++ /* ST M25P80 8 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 16; ++ break; ++ case 0x14: ++ /* ST M25P16 16 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 32; ++ break; ++ case 0x15: ++ /* ST M25P32 32 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 64; ++ break; ++ case 0x16: ++ /* ST M25P64 64 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 128; ++ break; ++ case 0xbf: ++ W_REG(NULL, &cc->flashaddress, 1); ++ sflash_cmd(cc, SFLASH_ST_RES); ++ id2 = R_REG(NULL, &cc->flashdata); ++ if (id2 == 0x44) { ++ /* SST M25VF80 4 Mbit Serial Flash */ ++ sflash.blocksize = 64 * 1024; ++ sflash.numblocks = 8; ++ } ++ break; ++ } ++ break; + -+/* receive descriptor table pointer */ -+#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ ++ case SFLASH_AT: ++ /* Probe for Atmel chips */ ++ sflash_cmd(cc, SFLASH_AT_STATUS); ++ id = R_REG(NULL, &cc->flashdata) & 0x3c; ++ switch (id) { ++ case 0xc: ++ /* Atmel AT45DB011 1Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 512; ++ break; ++ case 0x14: ++ /* Atmel AT45DB021 2Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 1024; ++ break; ++ case 0x1c: ++ /* Atmel AT45DB041 4Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 2048; ++ break; ++ case 0x24: ++ /* Atmel AT45DB081 8Mbit Serial Flash */ ++ sflash.blocksize = 256; ++ sflash.numblocks = 4096; ++ break; ++ case 0x2c: ++ /* Atmel AT45DB161 16Mbit Serial Flash */ ++ sflash.blocksize = 512; ++ sflash.numblocks = 4096; ++ break; ++ case 0x34: ++ /* Atmel AT45DB321 32Mbit Serial Flash */ ++ sflash.blocksize = 512; ++ sflash.numblocks = 8192; ++ break; ++ case 0x3c: ++ /* Atmel AT45DB642 64Mbit Serial Flash */ ++ sflash.blocksize = 1024; ++ sflash.numblocks = 8192; ++ break; ++ } ++ break; ++ } + -+/* receive channel status */ -+#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ -+#define D64_RS0_RS_SHIFT 28 -+#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ -+#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ -+#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ -+#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ -+#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ ++ sflash.size = sflash.blocksize * sflash.numblocks; ++ return sflash.size ? &sflash : NULL; ++} + -+#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ -+#define D64_RS1_RE_SHIFT 28 -+#define D64_RS1_RE_NOERR 0x00000000 /* no error */ -+#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ -+#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ -+#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ -+#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_RS1_RE_COREE 0x50000000 /* core error */ ++/* Read len bytes starting at offset into buf. Returns number of bytes read. */ ++int ++sflash_read(chipcregs_t *cc, uint offset, uint len, uchar *buf) ++{ ++ int cnt; ++ uint32 *from, *to; + -+/* fifoaddr */ -+#define D64_FA_OFF_MASK 0xffff /* offset */ -+#define D64_FA_SEL_MASK 0xf0000 /* select */ -+#define D64_FA_SEL_SHIFT 16 -+#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ -+#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ if (!len) ++ return 0; + -+/* descriptor control flags 1 */ -+#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ -+#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ ++ if ((offset + len) > sflash.size) ++ return -22; + -+/* descriptor control flags 2 */ -+#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ -+#define D64_CTRL2_AE 0x00110000 /* address extension bits */ -+#define D64_CTRL2_AE_SHIFT 16 ++ if ((len >= 4) && (offset & 3)) ++ cnt = 4 - (offset & 3); ++ else if ((len >= 4) && ((uint32)buf & 3)) ++ cnt = 4 - ((uint32)buf & 3); ++ else ++ cnt = len; + -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define D64_CTRL_CORE_MASK 0x0ff00000 ++ from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset); ++ to = (uint32 *)buf; + ++ if (cnt < 4) { ++ bcopy(from, to, cnt); ++ return cnt; ++ } + -+#endif /* _sbhnddma_h_ */ -diff -Naur linux.old/drivers/net/wl2/Makefile linux.dev/drivers/net/wl2/Makefile ---- linux.old/drivers/net/wl2/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl2/Makefile 2006-04-06 16:56:27.000000000 +0200 -@@ -0,0 +1,23 @@ -+# -+# Makefile for the Broadcom wl driver -+# -+# Copyright 2004, Broadcom Corporation -+# All Rights Reserved. -+# -+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+# -+# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ ++ while (cnt >= 4) { ++ *to++ = *from++; ++ cnt -= 4; ++ } + -+EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER ++ return (len - cnt); ++} + -+O_TARGET := wl.o ++/* Poll for command completion. Returns zero when complete. */ ++int ++sflash_poll(chipcregs_t *cc, uint offset) ++{ ++ if (offset >= sflash.size) ++ return -22; + -+obj-y := wl_apsta.o -+obj-y += compat.o hnddma.o ++ switch (sflash.type) { ++ case SFLASH_ST: ++ /* Check for ST Write In Progress bit */ ++ sflash_cmd(cc, SFLASH_ST_RDSR); ++ return R_REG(NULL, &cc->flashdata) & SFLASH_ST_WIP; ++ case SFLASH_AT: ++ /* Check for Atmel Ready bit */ ++ sflash_cmd(cc, SFLASH_AT_STATUS); ++ return !(R_REG(NULL, &cc->flashdata) & SFLASH_AT_READY); ++ } + -+obj-m := $(O_TARGET) ++ return 0; ++} + -+include $(TOPDIR)/Rules.make -diff -Naur linux.old/drivers/net/wl2/compat.c linux.dev/drivers/net/wl2/compat.c ---- linux.old/drivers/net/wl2/compat.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl2/compat.c 2006-04-06 17:08:21.000000000 +0200 -@@ -0,0 +1,376 @@ -+/* -+ * Misc useful OS-independent routines. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ ++/* Write len bytes starting at offset into buf. Returns number of bytes ++ * written. Caller should poll for completion. + */ -+ -+#include -+#ifdef BCMDRIVER -+#include -+#include -+#include -+#else -+#include -+#include -+#endif -+#include "pktq.h" -+#include -+#include -+#include -+ -+#ifdef BCMDRIVER -+/* copy a pkt buffer chain into a buffer */ -+uint -+pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) ++int ++sflash_write(chipcregs_t *cc, uint offset, uint len, const uchar *buf) +{ -+ uint n, ret = 0; -+ -+ if (len < 0) -+ len = 4096; /* "infinite" */ -+ -+ /* skip 'offset' bytes */ -+ for (; p && offset; p = PKTNEXT(osh, p)) { -+ if (offset < (uint)PKTLEN(osh, p)) -+ break; -+ offset -= PKTLEN(osh, p); -+ } ++ struct sflash *sfl; ++ int ret = 0; ++ bool is4712b0; ++ uint32 page, byte, mask; + -+ if (!p) ++ if (!len) + return 0; + -+ /* copy the data */ -+ for (; p && len; p = PKTNEXT(osh, p)) { -+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); -+ bcopy(PKTDATA(osh, p) + offset, buf, n); -+ buf += n; -+ len -= n; -+ ret += n; -+ offset = 0; ++ if ((offset + len) > sflash.size) ++ return -22; ++ ++ sfl = &sflash; ++ switch (sfl->type) { ++ case SFLASH_ST: ++ mask = R_REG(NULL, &cc->chipid); ++ is4712b0 = (((mask & CID_ID_MASK) == BCM4712_CHIP_ID) && ++ ((mask & CID_REV_MASK) == (3 << CID_REV_SHIFT))); ++ /* Enable writes */ ++ sflash_cmd(cc, SFLASH_ST_WREN); ++ if (is4712b0) { ++ mask = 1 << 14; ++ W_REG(NULL, &cc->flashaddress, offset); ++ W_REG(NULL, &cc->flashdata, *buf++); ++ /* Set chip select */ ++ OR_REG(NULL, &cc->gpioout, mask); ++ /* Issue a page program with the first byte */ ++ sflash_cmd(cc, SFLASH_ST_PP); ++ ret = 1; ++ offset++; ++ len--; ++ while (len > 0) { ++ if ((offset & 255) == 0) { ++ /* Page boundary, drop cs and return */ ++ AND_REG(NULL, &cc->gpioout, ~mask); ++ if (!sflash_poll(cc, offset)) { ++ /* Flash rejected command */ ++ return -11; ++ } ++ return ret; ++ } else { ++ /* Write single byte */ ++ sflash_cmd(cc, *buf++); ++ } ++ ret++; ++ offset++; ++ len--; ++ } ++ /* All done, drop cs if needed */ ++ if ((offset & 255) != 1) { ++ /* Drop cs */ ++ AND_REG(NULL, &cc->gpioout, ~mask); ++ if (!sflash_poll(cc, offset)) { ++ /* Flash rejected command */ ++ return -12; ++ } ++ } ++ } else { ++ ret = 1; ++ W_REG(NULL, &cc->flashaddress, offset); ++ W_REG(NULL, &cc->flashdata, *buf); ++ /* Page program */ ++ sflash_cmd(cc, SFLASH_ST_PP); ++ } ++ break; ++ case SFLASH_AT: ++ mask = sfl->blocksize - 1; ++ page = (offset & ~mask) << 1; ++ byte = offset & mask; ++ /* Read main memory page into buffer 1 */ ++ if (byte || (len < sfl->blocksize)) { ++ W_REG(NULL, &cc->flashaddress, page); ++ sflash_cmd(cc, SFLASH_AT_BUF1_LOAD); ++ /* 250 us for AT45DB321B */ ++ SPINWAIT(sflash_poll(cc, offset), 1000); ++ ASSERT(!sflash_poll(cc, offset)); ++ } ++ /* Write into buffer 1 */ ++ for (ret = 0; (ret < (int)len) && (byte < sfl->blocksize); ret++) { ++ W_REG(NULL, &cc->flashaddress, byte++); ++ W_REG(NULL, &cc->flashdata, *buf++); ++ sflash_cmd(cc, SFLASH_AT_BUF1_WRITE); ++ } ++ /* Write buffer 1 into main memory page */ ++ W_REG(NULL, &cc->flashaddress, page); ++ sflash_cmd(cc, SFLASH_AT_BUF1_PROGRAM); ++ break; + } + + return ret; +} + -+/* return total length of buffer chain */ -+uint -+pkttotlen(osl_t *osh, void *p) -+{ -+ uint total; -+ -+ total = 0; -+ for (; p; p = PKTNEXT(osh, p)) -+ total += PKTLEN(osh, p); -+ return (total); -+} -+ -+/* -+ * osl multiple-precedence packet queue -+ * hi_prec is always >= the number of the highest non-empty queue ++/* Erase a region. Returns number of bytes scheduled for erasure. ++ * Caller should poll for completion. + */ -+ -+void * -+pktq_penq(struct pktq *pq, int prec, void *p) ++int ++sflash_erase(chipcregs_t *cc, uint offset) +{ -+ struct pktq_prec *q; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ -+ -+ ASSERT(!pktq_full(pq)); -+ ASSERT(!pktq_pfull(pq, prec)); -+ -+ q = &pq->q[prec]; -+ -+ if (q->head) -+ PKTSETLINK(q->tail, p); -+ else -+ q->head = p; -+ -+ q->tail = p; -+ q->len++; ++ struct sflash *sfl; + -+ if (pq->hi_prec < prec) -+ pq->hi_prec = (uint8)prec; ++ if (offset >= sflash.size) ++ return -22; + -+ pq->len++; ++ sfl = &sflash; ++ switch (sfl->type) { ++ case SFLASH_ST: ++ sflash_cmd(cc, SFLASH_ST_WREN); ++ W_REG(NULL, &cc->flashaddress, offset); ++ sflash_cmd(cc, SFLASH_ST_SE); ++ return sfl->blocksize; ++ case SFLASH_AT: ++ W_REG(NULL, &cc->flashaddress, offset << 1); ++ sflash_cmd(cc, SFLASH_AT_PAGE_ERASE); ++ return sfl->blocksize; ++ } + -+ return p; ++ return 0; +} + -+void * -+pktq_penq_head(struct pktq *pq, int prec, void *p) ++/* ++ * writes the appropriate range of flash, a NULL buf simply erases ++ * the region of flash ++ */ ++int ++sflash_commit(chipcregs_t *cc, uint offset, uint len, const uchar *buf) +{ -+ struct pktq_prec *q; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ -+ -+ ASSERT(!pktq_full(pq)); -+ ASSERT(!pktq_pfull(pq, prec)); -+ -+ q = &pq->q[prec]; ++ struct sflash *sfl; ++ uchar *block = NULL, *cur_ptr, *blk_ptr; ++ uint blocksize = 0, mask, cur_offset, cur_length, cur_retlen, remainder; ++ uint blk_offset, blk_len, copied; ++ int bytes, ret = 0; + -+ if (q->head) -+ PKTSETLINK(p, q->head); -+ else -+ q->tail = p; ++ /* Check address range */ ++ if (len <= 0) ++ return 0; + -+ q->head = p; -+ q->len++; ++ sfl = &sflash; ++ if ((offset + len) > sfl->size) ++ return -1; + -+ if (pq->hi_prec < prec) -+ pq->hi_prec = (uint8)prec; ++ blocksize = sfl->blocksize; ++ mask = blocksize - 1; + -+ pq->len++; ++ /* Allocate a block of mem */ ++ if (!(block = MALLOC(NULL, blocksize))) ++ return -1; + -+ return p; -+} ++ while (len) { ++ /* Align offset */ ++ cur_offset = offset & ~mask; ++ cur_length = blocksize; ++ cur_ptr = block; + -+void * -+pktq_pdeq(struct pktq *pq, int prec) -+{ -+ struct pktq_prec *q; -+ void *p; ++ remainder = blocksize - (offset & mask); ++ if (len < remainder) ++ cur_retlen = len; ++ else ++ cur_retlen = remainder; + -+ ASSERT(prec >= 0 && prec < pq->num_prec); ++ /* buf == NULL means erase only */ ++ if (buf) { ++ /* Copy existing data into holding block if necessary */ ++ if ((offset & mask) || (len < blocksize)) { ++ blk_offset = cur_offset; ++ blk_len = cur_length; ++ blk_ptr = cur_ptr; + -+ q = &pq->q[prec]; ++ /* Copy entire block */ ++ while (blk_len) { ++ copied = sflash_read(cc, blk_offset, blk_len, blk_ptr); ++ blk_offset += copied; ++ blk_len -= copied; ++ blk_ptr += copied; ++ } ++ } + -+ if ((p = q->head) == NULL) -+ return NULL; ++ /* Copy input data into holding block */ ++ memcpy(cur_ptr + (offset & mask), buf, cur_retlen); ++ } + -+ if ((q->head = PKTLINK(p)) == NULL) -+ q->tail = NULL; ++ /* Erase block */ ++ if ((ret = sflash_erase(cc, (uint) cur_offset)) < 0) ++ goto done; ++ while (sflash_poll(cc, (uint) cur_offset)); + -+ q->len--; ++ /* buf == NULL means erase only */ ++ if (!buf) { ++ offset += cur_retlen; ++ len -= cur_retlen; ++ continue; ++ } + -+ pq->len--; ++ /* Write holding block */ ++ while (cur_length > 0) { ++ if ((bytes = sflash_write(cc, ++ (uint) cur_offset, ++ (uint) cur_length, ++ (uchar *) cur_ptr)) < 0) { ++ ret = bytes; ++ goto done; ++ } ++ while (sflash_poll(cc, (uint) cur_offset)); ++ cur_offset += bytes; ++ cur_length -= bytes; ++ cur_ptr += bytes; ++ } + -+ PKTSETLINK(p, NULL); ++ offset += cur_retlen; ++ len -= cur_retlen; ++ buf += cur_retlen; ++ } + -+ return p; ++ ret = len; ++done: ++ if (block) ++ MFREE(NULL, block, blocksize); ++ return ret; +} +diff -urN linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time.c +--- linux.old/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/time.c 2006-04-28 00:45:40.000000000 +0200 +@@ -0,0 +1,119 @@ ++/* ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: time.c,v 1.1.1.10 2006/02/27 03:42:55 honor Exp $ ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+void * -+pktq_pdeq_tail(struct pktq *pq, int prec) -+{ -+ struct pktq_prec *q; -+ void *p, *prev; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ for (prev = NULL; p != q->tail; p = PKTLINK(p)) -+ prev = p; -+ -+ if (prev) -+ PKTSETLINK(prev, NULL); -+ else -+ q->head = NULL; ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include + -+ q->tail = prev; -+ q->len--; ++/* Global SB handle */ ++extern void *bcm947xx_sbh; ++extern spinlock_t bcm947xx_sbh_lock; + -+ pq->len--; ++/* Convenience */ ++#define sbh bcm947xx_sbh ++#define sbh_lock bcm947xx_sbh_lock + -+ return p; -+} ++extern int panic_timeout; ++static int watchdog = 0; ++static u8 *mcr = NULL; + -+void -+pktq_init(struct pktq *pq, int num_prec, int max) ++void __init ++bcm947xx_time_init(void) +{ -+ int prec; -+ -+ ASSERT(num_prec >= 0 && num_prec <= PKTQ_MAX_PREC); -+ -+ bzero(pq, sizeof (*pq)); -+ -+ pq->num_prec = (uint16)num_prec; ++ unsigned int hz; ++ extifregs_t *eir; + -+ pq->max = (uint16)max; ++ /* ++ * Use deterministic values for initial counter interrupt ++ * so that calibrate delay avoids encountering a counter wrap. ++ */ ++ write_c0_count(0); ++ write_c0_compare(0xffff); + -+ for (prec = 0; prec < num_prec; prec++) -+ pq->q[prec].max = pq->max; -+} ++ if (!(hz = sb_cpu_clock(sbh))) ++ hz = 100000000; + -+void * -+pktq_deq(struct pktq *pq, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; ++ printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh), ++ (hz + 500000) / 1000000); + -+ if (pq->len == 0) -+ return NULL; ++ /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ ++ mips_hpt_frequency = hz / 2; + -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; ++ /* Set watchdog interval in ms */ ++ watchdog = simple_strtoul(nvram_safe_get("watchdog"), NULL, 0); + -+ q = &pq->q[prec]; ++ /* Please set the watchdog to 3 sec if it is less than 3 but not equal to 0 */ ++ if (watchdog > 0) { ++ if (watchdog < 3000) ++ watchdog = 3000; ++ } + -+ if ((p = q->head) == NULL) -+ return NULL; ++ /* Set panic timeout in seconds */ ++ panic_timeout = watchdog / 1000; + -+ if ((q->head = PKTLINK(p)) == NULL) -+ q->tail = NULL; ++ /* Setup blink */ ++ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { ++ sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF); ++ unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1))); ++ mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1); ++ } ++} + -+ q->len--; ++static void ++bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ /* Generic MIPS timer code */ ++ timer_interrupt(irq, dev_id, regs); + -+ if (prec_out) -+ *prec_out = prec; ++ /* Set the watchdog timer to reset after the specified number of ms */ ++ if (watchdog > 0) ++ sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog); + -+ pq->len--; ++#ifdef CONFIG_HWSIM ++ (*((int *)0xa0000f1c))++; ++#else ++ /* Blink one of the LEDs in the external UART */ ++ if (mcr && !(jiffies % (HZ/2))) ++ writeb(readb(mcr) ^ UART_MCR_OUT2, mcr); ++#endif ++} + -+ PKTSETLINK(p, NULL); ++static struct irqaction bcm947xx_timer_irqaction = { ++ bcm947xx_timer_interrupt, ++ SA_INTERRUPT, ++ 0, ++ "timer", ++ NULL, ++ NULL ++}; + -+ return p; ++void __init ++bcm947xx_timer_setup(struct irqaction *irq) ++{ ++ /* Enable the timer interrupt */ ++ setup_irq(7, &bcm947xx_timer_irqaction); +} +diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared.in +--- linux.old/arch/mips/config-shared.in 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/arch/mips/config-shared.in 2006-04-27 19:24:19.000000000 +0200 +@@ -208,6 +208,14 @@ + fi + define_bool CONFIG_MIPS_RTC y + fi ++dep_bool 'Support for Broadcom MIPS-based boards' CONFIG_MIPS_BRCM $CONFIG_EXPERIMENTAL ++dep_bool 'Support for Broadcom BCM947XX' CONFIG_BCM947XX $CONFIG_MIPS_BRCM ++if [ "$CONFIG_BCM947XX" = "y" ] ; then ++ bool ' Support for Broadcom BCM4710' CONFIG_BCM4710 ++ bool ' Support for Broadcom BCM4310' CONFIG_BCM4310 ++ bool ' Support for Broadcom BCM4704' CONFIG_BCM4704 ++ bool ' Support for Broadcom BCM5365' CONFIG_BCM5365 ++fi + bool 'Support for SNI RM200 PCI' CONFIG_SNI_RM200_PCI + bool 'Support for TANBAC TB0226 (Mbase)' CONFIG_TANBAC_TB0226 + bool 'Support for TANBAC TB0229 (VR4131DIMM)' CONFIG_TANBAC_TB0229 +@@ -229,6 +237,11 @@ + define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM n + + # ++# Provide an option for a default kernel command line ++# ++string 'Default kernel command string' CONFIG_CMDLINE "" + -+void * -+pktq_deq_tail(struct pktq *pq, int *prec_out) ++# + # Select some configuration options automatically based on user selections. + # + if [ "$CONFIG_ACER_PICA_61" = "y" ]; then +@@ -554,6 +567,13 @@ + define_bool CONFIG_SWAP_IO_SPACE_L y + define_bool CONFIG_BOOT_ELF32 y + fi ++if [ "$CONFIG_BCM947XX" = "y" ] ; then ++ define_bool CONFIG_PCI y ++ define_bool CONFIG_NONCOHERENT_IO y ++ define_bool CONFIG_NEW_TIME_C y ++ define_bool CONFIG_NEW_IRQ y ++ define_bool CONFIG_HND y ++fi + if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then + define_bool CONFIG_ARC32 y + define_bool CONFIG_ARC_MEMORY y +@@ -1042,7 +1062,11 @@ + + bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE + bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG +-bool 'Remote GDB kernel debugging' CONFIG_KGDB ++if [ "$CONFIG_BCM947XX" = "y" ] ; then ++ bool 'Remote GDB kernel debugging' CONFIG_REMOTE_DEBUG ++else ++ bool 'Remote GDB kernel debugging' CONFIG_KGDB ++fi + dep_bool ' Console output to GDB' CONFIG_GDB_CONSOLE $CONFIG_KGDB + if [ "$CONFIG_KGDB" = "y" ]; then + define_bool CONFIG_DEBUG_INFO y +diff -urN linux.old/arch/mips/kernel/cpu-probe.c linux.dev/arch/mips/kernel/cpu-probe.c +--- linux.old/arch/mips/kernel/cpu-probe.c 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/arch/mips/kernel/cpu-probe.c 2006-04-27 19:24:19.000000000 +0200 +@@ -162,7 +162,7 @@ + + static inline void cpu_probe_legacy(struct cpuinfo_mips *c) + { +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_R2000: + c->cputype = CPU_R2000; + c->isa_level = MIPS_CPU_ISA_I; +@@ -172,7 +172,7 @@ + c->tlbsize = 64; + break; + case PRID_IMP_R3000: +- if ((c->processor_id & 0xff) == PRID_REV_R3000A) ++ if ((c->processor_id & PRID_REV_MASK) == PRID_REV_R3000A) + if (cpu_has_confreg()) + c->cputype = CPU_R3081E; + else +@@ -187,12 +187,12 @@ + break; + case PRID_IMP_R4000: + if (read_c0_config() & CONF_SC) { +- if ((c->processor_id & 0xff) >= PRID_REV_R4400) ++ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) + c->cputype = CPU_R4400PC; + else + c->cputype = CPU_R4000PC; + } else { +- if ((c->processor_id & 0xff) >= PRID_REV_R4400) ++ if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_R4400) + c->cputype = CPU_R4400SC; + else + c->cputype = CPU_R4000SC; +@@ -438,7 +438,7 @@ + static inline void cpu_probe_mips(struct cpuinfo_mips *c) + { + decode_config1(c); +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_4KC: + c->cputype = CPU_4KC; + c->isa_level = MIPS_CPU_ISA_M32; +@@ -479,10 +479,10 @@ + { + decode_config1(c); + c->options |= MIPS_CPU_PREFETCH; +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_AU1_REV1: + case PRID_IMP_AU1_REV2: +- switch ((c->processor_id >> 24) & 0xff) { ++ switch ((c->processor_id >> 24) & PRID_REV_MASK) { + case 0: + c->cputype = CPU_AU1000; + break; +@@ -510,10 +510,34 @@ + } + } + ++static inline void cpu_probe_broadcom(struct cpuinfo_mips *c) +{ -+ struct pktq_prec *q; -+ void *p, *prev; -+ int prec; ++ decode_config1(c); ++ c->options |= MIPS_CPU_PREFETCH; ++ switch (c->processor_id & PRID_IMP_MASK) { ++ case PRID_IMP_BCM4710: ++ c->cputype = CPU_BCM4710; ++ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | ++ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; ++ c->scache.flags = MIPS_CACHE_NOT_PRESENT; ++ break; ++ case PRID_IMP_4KC: ++ case PRID_IMP_BCM3302: ++ c->cputype = CPU_BCM3302; ++ c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | ++ MIPS_CPU_4KTLB | MIPS_CPU_COUNTER; ++ c->scache.flags = MIPS_CACHE_NOT_PRESENT; ++ break; ++ default: ++ c->cputype = CPU_UNKNOWN; ++ break; ++ } ++} ++ + static inline void cpu_probe_sibyte(struct cpuinfo_mips *c) + { + decode_config1(c); +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_SB1: + c->cputype = CPU_SB1; + c->isa_level = MIPS_CPU_ISA_M64; +@@ -535,7 +559,7 @@ + static inline void cpu_probe_sandcraft(struct cpuinfo_mips *c) + { + decode_config1(c); +- switch (c->processor_id & 0xff00) { ++ switch (c->processor_id & PRID_IMP_MASK) { + case PRID_IMP_SR71000: + c->cputype = CPU_SR71000; + c->isa_level = MIPS_CPU_ISA_M64; +@@ -560,7 +584,7 @@ + c->cputype = CPU_UNKNOWN; + + c->processor_id = read_c0_prid(); +- switch (c->processor_id & 0xff0000) { ++ switch (c->processor_id & PRID_COMP_MASK) { + + case PRID_COMP_LEGACY: + cpu_probe_legacy(c); +@@ -571,6 +595,9 @@ + case PRID_COMP_ALCHEMY: + cpu_probe_alchemy(c); + break; ++ case PRID_COMP_BROADCOM: ++ cpu_probe_broadcom(c); ++ break; + case PRID_COMP_SIBYTE: + cpu_probe_sibyte(c); + break; +diff -urN linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S +--- linux.old/arch/mips/kernel/head.S 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/arch/mips/kernel/head.S 2006-04-27 19:24:19.000000000 +0200 +@@ -28,12 +28,20 @@ + #include + #include + ++#ifdef CONFIG_BCM4710 ++#undef eret ++#define eret nop; nop; eret ++#endif + -+ if (pq->len == 0) -+ return NULL; + .text ++ j kernel_entry ++ nop + -+ for (prec = 0; prec < pq->hi_prec; prec++) -+ if (pq->q[prec].head) + /* + * Reserved space for exception handlers. + * Necessary for machines which link their kernels at KSEG0. + */ +- .fill 0x400 ++ .fill 0x3f4 + + /* The following two symbols are used for kernel profiling. */ + EXPORT(stext) +diff -urN linux.old/arch/mips/kernel/proc.c linux.dev/arch/mips/kernel/proc.c +--- linux.old/arch/mips/kernel/proc.c 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/arch/mips/kernel/proc.c 2006-04-27 19:24:19.000000000 +0200 +@@ -78,9 +78,10 @@ + [CPU_AU1550] "Au1550", + [CPU_24K] "MIPS 24K", + [CPU_AU1200] "Au1200", ++ [CPU_BCM4710] "BCM4710", ++ [CPU_BCM3302] "BCM3302", + }; + +- + static int show_cpuinfo(struct seq_file *m, void *v) + { + unsigned int version = current_cpu_data.processor_id; +diff -urN linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c +--- linux.old/arch/mips/kernel/setup.c 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/arch/mips/kernel/setup.c 2006-04-27 19:24:19.000000000 +0200 +@@ -493,6 +493,7 @@ + void swarm_setup(void); + void hp_setup(void); + void au1x00_setup(void); ++ void brcm_setup(void); + void frame_info_init(void); + + frame_info_init(); +@@ -691,6 +692,11 @@ + pmc_yosemite_setup(); + break; + #endif ++#if defined(CONFIG_BCM4710) || defined(CONFIG_BCM4310) ++ case MACH_GROUP_BRCM: ++ brcm_setup(); + break; ++#endif + default: + panic("Unsupported architecture"); + } +diff -urN linux.old/arch/mips/kernel/traps.c linux.dev/arch/mips/kernel/traps.c +--- linux.old/arch/mips/kernel/traps.c 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/arch/mips/kernel/traps.c 2006-04-27 19:24:19.000000000 +0200 +@@ -920,6 +920,7 @@ + void __init trap_init(void) + { + extern char except_vec1_generic; ++ extern char except_vec2_generic; + extern char except_vec3_generic, except_vec3_r4000; + extern char except_vec_ejtag_debug; + extern char except_vec4; +@@ -927,6 +928,7 @@ + + /* Copy the generic exception handler code to it's final destination. */ + memcpy((void *)(KSEG0 + 0x80), &except_vec1_generic, 0x80); ++ memcpy((void *)(KSEG0 + 0x100), &except_vec2_generic, 0x80); + + /* + * Setup default vectors +@@ -985,6 +987,12 @@ + set_except_vector(13, handle_tr); + set_except_vector(22, handle_mdmx); + ++ if (current_cpu_data.cputype == CPU_SB1) { ++ /* Enable timer interrupt and scd mapped interrupt */ ++ clear_c0_status(0xf000); ++ set_c0_status(0xc00); ++ } + -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ for (prev = NULL; p != q->tail; p = PKTLINK(p)) -+ prev = p; -+ -+ if (prev) -+ PKTSETLINK(prev, NULL); -+ else -+ q->head = NULL; -+ -+ q->tail = prev; -+ q->len--; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ pq->len--; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} + if (cpu_has_fpu && !cpu_has_nofpuex) + set_except_vector(15, handle_fpe); + +diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c +--- linux.old/arch/mips/mm/c-r4k.c 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/arch/mips/mm/c-r4k.c 2006-04-27 19:24:19.000000000 +0200 +@@ -1166,3 +1166,47 @@ + build_clear_page(); + build_copy_page(); + } + -+void * -+pktq_peek(struct pktq *pq, int *prec_out) ++#ifdef CONFIG_BCM4704 ++static void __init mips32_icache_fill(unsigned long addr, uint nbytes) +{ -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; -+ -+ if ((p = pq->q[prec].head) == NULL) -+ return NULL; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ return p; ++ unsigned long ic_lsize = current_cpu_data.icache.linesz; ++ int i; ++ for (i = 0; i < nbytes; i += ic_lsize) ++ fill_icache_line((addr + i)); +} + -+void * -+pktq_peek_tail(struct pktq *pq, int *prec_out) ++/* ++ * This must be run from the cache on 4704A0 ++ * so there are no mips core BIU ops in progress ++ * when the PFC is enabled. ++ */ ++#define PFC_CR0 0xff400000 /* control reg 0 */ ++#define PFC_CR1 0xff400004 /* control reg 1 */ ++static void __init enable_pfc(u32 mode) +{ -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ for (prec = 0; prec < pq->hi_prec; prec++) -+ if (pq->q[prec].head) -+ break; -+ -+ if ((p = pq->q[prec].tail) == NULL) -+ return NULL; -+ -+ if (prec_out) -+ *prec_out = prec; ++ /* write range */ ++ *(volatile u32 *)PFC_CR1 = 0xffff0000; + -+ return p; ++ /* enable */ ++ *(volatile u32 *)PFC_CR0 = mode; +} ++#endif + -+int -+pktq_mlen(struct pktq *pq, uint prec_bmp) -+{ -+ int prec, len; + -+ len = 0; ++void check_enable_mips_pfc(int val) ++{ + -+ for (prec = 0; prec <= pq->hi_prec; prec++) -+ if (prec_bmp & (1 << prec)) -+ len += pq->q[prec].len; ++#ifdef CONFIG_BCM4704 ++ struct cpuinfo_mips *c = ¤t_cpu_data; + -+ return len; ++ /* enable prefetch cache */ ++ if (((c->processor_id & (PRID_COMP_MASK | PRID_IMP_MASK)) == PRID_IMP_BCM3302) ++ && (read_c0_diag() & (1 << 29))) { ++ mips32_icache_fill((unsigned long) &enable_pfc, 64); ++ enable_pfc(val); ++ } ++#endif +} + -+void * -+pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; + -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; +diff -urN linux.old/arch/mips/pci/Makefile linux.dev/arch/mips/pci/Makefile +--- linux.old/arch/mips/pci/Makefile 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/arch/mips/pci/Makefile 2006-04-27 19:24:19.000000000 +0200 +@@ -13,7 +13,9 @@ + obj-$(CONFIG_MIPS_MSC) += ops-msc.o + obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o + obj-$(CONFIG_SNI_RM200_PCI) += ops-sni.o ++ifndef CONFIG_BCM947XX + obj-y += pci.o ++endif + obj-$(CONFIG_PCI_AUTO) += pci_auto.o + + include $(TOPDIR)/Rules.make +diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c +--- linux.old/drivers/char/serial.c 2006-04-27 18:04:37.000000000 +0200 ++++ linux.dev/drivers/char/serial.c 2006-04-27 19:24:19.000000000 +0200 +@@ -444,6 +444,10 @@ + return inb(info->port+1); + #endif + case SERIAL_IO_MEM: ++#ifdef CONFIG_BCM4310 ++ readb((unsigned long) info->iomem_base + ++ (UART_SCR<iomem_reg_shift)); ++#endif + return readb((unsigned long) info->iomem_base + + (offset<iomem_reg_shift)); + default: +@@ -464,6 +468,9 @@ + case SERIAL_IO_MEM: + writeb(value, (unsigned long) info->iomem_base + + (offset<iomem_reg_shift)); ++#ifdef CONFIG_BCM4704 ++ *((volatile unsigned int *) KSEG1ADDR(0x18000000)); ++#endif + break; + default: + outb(value, info->port+offset); +@@ -1728,7 +1735,7 @@ + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) +- quot = baud_base / baud; ++ quot = (baud_base + (baud / 2)) / baud; + } + /* If the quotient is zero refuse the change */ + if (!quot && old_termios) { +@@ -1745,12 +1752,12 @@ + /* Special case since 134 is really 134.5 */ + quot = (2*baud_base / 269); + else if (baud) +- quot = baud_base / baud; ++ quot = (baud_base + (baud / 2)) / baud; + } + } + /* As a last resort, if the quotient is zero, default to 9600 bps */ + if (!quot) +- quot = baud_base / 9600; ++ quot = (baud_base + 4800) / 9600; + /* + * Work around a bug in the Oxford Semiconductor 952 rev B + * chip which causes it to seriously miscalculate baud rates +@@ -5994,6 +6001,13 @@ + * Divisor, bytesize and parity + */ + state = rs_table + co->index; ++ /* ++ * Safe guard: state structure must have been initialized ++ */ ++ if (state->iomem_base == NULL) { ++ printk("!unable to setup serial console!\n"); ++ return -1; ++ } + if (doflow) + state->flags |= ASYNC_CONS_FLOW; + info = &async_sercons; +@@ -6007,7 +6021,7 @@ + info->io_type = state->io_type; + info->iomem_base = state->iomem_base; + info->iomem_reg_shift = state->iomem_reg_shift; +- quot = state->baud_base / baud; ++ quot = (state->baud_base + (baud / 2)) / baud; + cval = cflag & (CSIZE | CSTOPB); + #if defined(__powerpc__) || defined(__alpha__) + cval >>= 8; +diff -urN linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in +--- linux.old/drivers/net/Config.in 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/drivers/net/Config.in 2006-04-27 19:24:19.000000000 +0200 +@@ -2,6 +2,8 @@ + # Network device configuration + # + ++tristate 'Broadcom Home Network Division' CONFIG_HND $CONFIG_PCI + -+ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) -+ if (prec-- == 0) -+ return NULL; + source drivers/net/arcnet/Config.in + + tristate 'Dummy net driver support' CONFIG_DUMMY +diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile +--- linux.old/drivers/net/Makefile 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/drivers/net/Makefile 2006-05-04 01:41:03.000000000 +0200 +@@ -3,6 +3,8 @@ + # Makefile for the Linux network (ethercard) device drivers. + # + ++EXTRA_CFLAGS := -I$(TOPDIR)/arch/mips/bcm947xx/include + -+ q = &pq->q[prec]; + obj-y := + obj-m := + obj-n := +@@ -39,6 +41,7 @@ + obj-$(CONFIG_ISDN) += slhc.o + endif + ++subdir-$(CONFIG_WL) += wl + subdir-$(CONFIG_NET_PCMCIA) += pcmcia + subdir-$(CONFIG_NET_WIRELESS) += wireless + subdir-$(CONFIG_TULIP) += tulip +diff -urN linux.old/drivers/net/wireless/Config.in linux.dev/drivers/net/wireless/Config.in +--- linux.old/drivers/net/wireless/Config.in 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/drivers/net/wireless/Config.in 2006-05-04 01:42:48.000000000 +0200 +@@ -13,6 +13,7 @@ + fi + + if [ "$CONFIG_PCI" = "y" ]; then ++ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL + dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL + dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL + dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL +diff -urN linux.old/drivers/net/wl/patchtable.pl linux.dev/drivers/net/wl/patchtable.pl +--- linux.old/drivers/net/wl/patchtable.pl 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/patchtable.pl 2006-04-28 01:33:52.000000000 +0200 +@@ -0,0 +1,54 @@ ++#!/usr/bin/perl ++use strict; ++ ++my $TABLE = pack("V", 0xbadc0ded); ++my $TABLE_SIZE = 512; ++my $SLT1 = "\x01\x00\x00\x00"; ++my $SLT2 = "\x02\x00\x00\x00"; ++my $ACKW = "\x03\x00\x00\x00"; ++my $PTABLE_END = "\xff\xff\xff\xff"; ++ ++my $addr = ""; ++my $opcode = ""; ++my $function = ""; ++ ++sub add_entry { ++ my $key = shift; ++ my $value = shift; ++ my $default = shift; ++ ++ $TABLE .= $key; ++ $TABLE .= pack("V", $value); ++ $TABLE .= pack("V", $default); ++} ++ ++while (<>) { ++ $addr = $opcode = ""; ++ /^\w{8}\s*<(.*)>:$/ and $function = $1; ++ /^\s*(\w+):\s*(\w{8})\s*/ and do { ++ $addr = $1; ++ $opcode = $2; ++ }; + -+ if ((p = q->head) == NULL) -+ return NULL; ++ ($function eq 'wlc_update_slot_timing') and do { ++ # li a2,9 -- short slot time ++ ($opcode eq '24060009') and add_entry($SLT1, hex($addr), hex($opcode)); ++ # li v0,519 -- 510 + short slot time ++ ($opcode eq '24020207') and add_entry($SLT2, hex($addr), hex($opcode)); ++ ++ # li a2,20 -- long slot time ++ ($opcode eq '24060014') and add_entry($SLT1, hex($addr), hex($opcode)); ++ # li v0,530 -- 510 + long slot time ++ ($opcode eq '24020212') and add_entry($SLT2, hex($addr), hex($opcode)); ++ }; ++ ($function eq 'wlc_d11hdrs') and do { ++ # ori s6,s6,0x1 -- ack flag (new) ++ ($opcode eq '36d60001') and add_entry($ACKW, hex($addr), hex($opcode)); ++ # ori s3,s3,0x1 -- ack flag (old) ++ ($opcode eq '36730001') and add_entry($ACKW, hex($addr), hex($opcode)); ++ } ++} + -+ if ((q->head = PKTLINK(p)) == NULL) -+ q->tail = NULL; ++$TABLE .= $PTABLE_END; ++$TABLE .= ("\x00" x ($TABLE_SIZE - length($TABLE))); ++print $TABLE; +diff -urN linux.old/drivers/net/wl/Makefile linux.dev/drivers/net/wl/Makefile +--- linux.old/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/Makefile 2006-04-28 01:33:52.000000000 +0200 +@@ -0,0 +1,32 @@ ++# ++# Makefile for the Broadcom wl driver ++# ++# Copyright 2004, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ + -+ q->len--; ++EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER + -+ if (prec_out) -+ *prec_out = prec; ++O_TARGET := wl_link.o + -+ pq->len--; ++obj-y := wl_mod.o ++obj-y += bcmutils.o hnddma.o linux_osl.o + -+ PKTSETLINK(p, NULL); ++obj-m := $(O_TARGET) + -+ return p; -+} ++wl_mod.o: wl_apsta.o ++ sed -e 's,eth%d,wl%d\x00,g' < $< > $@ + -+#endif ++wl.o: wl_link.o ++ $(OBJDUMP) -d $< | perl patchtable.pl > patchtable.bin ++ cat wl_link.o patchtable.bin > $@ + ++modules: wl.o + -diff -Naur linux.old/drivers/net/wl2/hnddma.c linux.dev/drivers/net/wl2/hnddma.c ---- linux.old/drivers/net/wl2/hnddma.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl2/hnddma.c 2006-04-06 16:32:33.000000000 +0200 -@@ -0,0 +1,1487 @@ ++include $(TOPDIR)/Rules.make +diff -urN linux.old/drivers/net/wl/bcmip.h linux.dev/drivers/net/wl/bcmip.h +--- linux.old/drivers/net/wl/bcmip.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/bcmip.h 2006-04-28 02:11:28.000000000 +0200 +@@ -0,0 +1,101 @@ +/* -+ * Generic Broadcom Home Networking Division (HND) DMA module. -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2005, Broadcom Corporation ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -18260,2362 +16430,2288 @@ diff -Naur linux.old/drivers/net/wl2/hnddma.c linux.dev/drivers/net/wl2/hnddma.c + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id$ ++ * Fundamental constants relating to IP Protocol ++ * ++ * $Id: bcmip.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $ + */ + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct dma_info; /* forward declaration */ -+#define di_t struct dma_info -+ -+#include "sbhnddma.h" -+#include "hnddma.h" -+ -+/* debug/trace */ -+#define DMA_ERROR(args) -+#define DMA_TRACE(args) -+ -+/* default dma message level (if input msg_level pointer is null in dma_attach()) */ -+static uint dma_msg_level = -+ 0; -+ -+#define MAXNAMEL 8 -+ -+/* dma engine software state */ -+typedef struct dma_info { -+ hnddma_t hnddma; /* exported structure */ -+ uint *msg_level; /* message level pointer */ -+ char name[MAXNAMEL]; /* callers name for diag msgs */ -+ -+ void *osh; /* os handle */ -+ sb_t *sbh; /* sb handle */ -+ -+ bool dma64; /* dma64 enabled */ -+ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ -+ -+ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ -+ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ -+ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ -+ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ -+ -+ uint32 dma64align; /* either 8k or 4k depends on number of dd */ -+ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ -+ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ -+ uint ntxd; /* # tx descriptors tunable */ -+ uint txin; /* index of next descriptor to reclaim */ -+ uint txout; /* index of next descriptor to post */ -+ uint txavail; /* # free tx descriptors */ -+ void **txp; /* pointer to parallel array of pointers to packets */ -+ ulong txdpa; /* physical address of descriptor ring */ -+ uint txdalign; /* #bytes added to alloc'd mem to align txd */ -+ uint txdalloc; /* #bytes allocated for the ring */ -+ -+ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ -+ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ -+ uint nrxd; /* # rx descriptors tunable */ -+ uint rxin; /* index of next descriptor to reclaim */ -+ uint rxout; /* index of next descriptor to post */ -+ void **rxp; /* pointer to parallel array of pointers to packets */ -+ ulong rxdpa; /* physical address of descriptor ring */ -+ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ -+ uint rxdalloc; /* #bytes allocated for the ring */ -+ -+ /* tunables */ -+ uint rxbufsize; /* rx buffer size in bytes */ -+ uint nrxpost; /* # rx buffers to keep posted */ -+ uint rxoffset; /* rxcontrol offset */ -+ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ -+ uint ddoffsethigh; /* add to get dma address of descriptor ring, high 32 bits */ -+ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ -+ uint dataoffsethigh; /* add to get dma address of data buffer, high 32 bits */ -+} dma_info_t; -+ -+#ifdef BCMDMA64 -+#define DMA64_ENAB(di) ((di)->dma64) -+#else -+#define DMA64_ENAB(di) (0) -+#endif -+ -+/* descriptor bumping macros */ -+#define XXD(x, n) ((x) & ((n) - 1)) -+#define TXD(x) XXD((x), di->ntxd) -+#define RXD(x) XXD((x), di->nrxd) -+#define NEXTTXD(i) TXD(i + 1) -+#define PREVTXD(i) TXD(i - 1) -+#define NEXTRXD(i) RXD(i + 1) -+#define NTXDACTIVE(h, t) TXD(t - h) -+#define NRXDACTIVE(h, t) RXD(t - h) ++#ifndef _bcmip_h_ ++#define _bcmip_h_ + -+/* macros to convert between byte offsets and indexes */ -+#define B2I(bytes, type) ((bytes) / sizeof(type)) -+#define I2B(index, type) ((index) * sizeof(type)) ++/* IPV4 and IPV6 common */ ++#define IP_VER_OFFSET 0x0 /* offset to version field */ ++#define IP_VER_MASK 0xf0 /* version mask */ ++#define IP_VER_SHIFT 4 /* version shift */ ++#define IP_VER_4 4 /* version number for IPV4 */ ++#define IP_VER_6 6 /* version number for IPV6 */ + -+#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ -+#define PCI32ADDR_HIGH_SHIFT 30 ++#define IP_VER(ip_body) \ ++ ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) + ++#define IP_PROT_ICMP 0x1 /* ICMP protocol */ ++#define IP_PROT_TCP 0x6 /* TCP protocol */ ++#define IP_PROT_UDP 0x11 /* UDP protocol type */ + -+/* prototypes */ -+static bool dma_isaddrext(dma_info_t *di); -+static bool dma_alloc(dma_info_t *di, uint direction); ++/* IPV4 field offsets */ ++#define IPV4_VER_HL_OFFSET 0 /* version and ihl byte offset */ ++#define IPV4_TOS_OFFSET 1 /* type of service offset */ ++#define IPV4_PROT_OFFSET 9 /* protocol type offset */ ++#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ ++#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ ++#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ + -+static bool dma32_alloc(dma_info_t *di, uint direction); -+static void dma32_txreset(dma_info_t *di); -+static void dma32_rxreset(dma_info_t *di); -+static bool dma32_txsuspendedidle(dma_info_t *di); -+static int dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags); -+static void* dma32_getnexttxp(dma_info_t *di, bool forceall); -+static void* dma32_getnextrxp(dma_info_t *di, bool forceall); -+static void dma32_txrotate(di_t *di); -+ -+/* prototype or stubs */ -+#ifdef BCMDMA64 -+static bool dma64_alloc(dma_info_t *di, uint direction); -+static void dma64_txreset(dma_info_t *di); -+static void dma64_rxreset(dma_info_t *di); -+static bool dma64_txsuspendedidle(dma_info_t *di); -+static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags); -+static void* dma64_getnexttxp(dma_info_t *di, bool forceall); -+static void* dma64_getnextrxp(dma_info_t *di, bool forceall); -+static void dma64_txrotate(di_t *di); -+#else -+static bool dma64_alloc(dma_info_t *di, uint direction) { return TRUE; } -+static void dma64_txreset(dma_info_t *di) {} -+static void dma64_rxreset(dma_info_t *di) {} -+static bool dma64_txsuspendedidle(dma_info_t *di) { return TRUE;} -+static int dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) { return 0; } -+static void* dma64_getnexttxp(dma_info_t *di, bool forceall) { return NULL; } -+static void* dma64_getnextrxp(dma_info_t *di, bool forceall) { return NULL; } -+static void dma64_txrotate(di_t *di) { return; } -+#endif ++/* IPV4 field decodes */ ++#define IPV4_VER_MASK 0xf0 /* IPV4 version mask */ ++#define IPV4_VER_SHIFT 4 /* IPV4 version shift */ + ++#define IPV4_HLEN_MASK 0x0f /* IPV4 header length mask */ ++#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) + ++#define IPV4_ADDR_LEN 4 /* IPV4 address length */ + -+void* -+dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, -+ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) -+{ -+ dma_info_t *di; -+ uint size; ++#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ ++ ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) + -+ /* allocate private info structure */ -+ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { -+ return (NULL); -+ } -+ bzero((char*)di, sizeof (dma_info_t)); ++#define IPV4_TOS_DSCP_MASK 0xfc /* DiffServ codepoint mask */ ++#define IPV4_TOS_DSCP_SHIFT 2 /* DiffServ codepoint shift */ + -+ di->msg_level = msg_level ? msg_level : &dma_msg_level; ++#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) + -+ if (sbh != NULL) -+ di->dma64 = ((sb_coreflagshi(sbh, 0, 0) & SBTMH_DMA64) == SBTMH_DMA64); ++#define IPV4_TOS_PREC_MASK 0xe0 /* Historical precedence mask */ ++#define IPV4_TOS_PREC_SHIFT 5 /* Historical precedence shift */ + -+#ifndef BCMDMA64 -+ if (di->dma64) { -+ DMA_ERROR(("dma_attach: driver doesn't have the capability to support 64 bits DMA\n")); -+ goto fail; -+ } -+#endif -+ -+ /* check arguments */ -+ ASSERT(ISPOWEROF2(ntxd)); -+ ASSERT(ISPOWEROF2(nrxd)); -+ if (nrxd == 0) -+ ASSERT(dmaregsrx == NULL); -+ if (ntxd == 0) -+ ASSERT(dmaregstx == NULL); ++#define IPV4_TOS_LOWDELAY 0x10 /* Lowest delay requested */ ++#define IPV4_TOS_THROUGHPUT 0x8 /* Best throughput requested */ ++#define IPV4_TOS_RELIABILITY 0x4 /* Most reliable delivery requested */ + ++#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) + -+ /* init dma reg pointer */ -+ if (di->dma64) { -+ ASSERT(ntxd <= D64MAXDD); -+ ASSERT(nrxd <= D64MAXDD); -+ di->d64txregs = (dma64regs_t *)dmaregstx; -+ di->d64rxregs = (dma64regs_t *)dmaregsrx; -+ -+ di->dma64align = D64RINGALIGN; -+ if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { -+ /* for smaller dd table, HW relax the alignment requirement */ -+ di->dma64align = D64RINGALIGN / 2; -+ } -+ } else { -+ ASSERT(ntxd <= D32MAXDD); -+ ASSERT(nrxd <= D32MAXDD); -+ di->d32txregs = (dma32regs_t *)dmaregstx; -+ di->d32rxregs = (dma32regs_t *)dmaregsrx; -+ } ++#define IPV4_ADDR_STR_LEN 16 /* Max IP address length in string format */ + ++/* IPV6 field offsets */ ++#define IPV6_PAYLOAD_LEN_OFFSET 4 /* payload length offset */ ++#define IPV6_NEXT_HDR_OFFSET 6 /* next header/protocol offset */ ++#define IPV6_HOP_LIMIT_OFFSET 7 /* hop limit offset */ ++#define IPV6_SRC_IP_OFFSET 8 /* src IP addr offset */ ++#define IPV6_DEST_IP_OFFSET 24 /* dst IP addr offset */ + -+ /* make a private copy of our callers name */ -+ strncpy(di->name, name, MAXNAMEL); -+ di->name[MAXNAMEL-1] = '\0'; ++/* IPV6 field decodes */ ++#define IPV6_TRAFFIC_CLASS(ipv6_body) \ ++ (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ ++ ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) + -+ di->osh = osh; -+ di->sbh = sbh; ++#define IPV6_FLOW_LABEL(ipv6_body) \ ++ (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ ++ (((uint8 *)(ipv6_body))[2] << 8) | \ ++ (((uint8 *)(ipv6_body))[3])) + -+ /* save tunables */ -+ di->ntxd = ntxd; -+ di->nrxd = nrxd; -+ di->rxbufsize = rxbufsize; -+ di->nrxpost = nrxpost; -+ di->rxoffset = rxoffset; ++#define IPV6_PAYLOAD_LEN(ipv6_body) \ ++ ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ ++ ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) + -+ /* -+ * figure out the DMA physical address offset for dd and data -+ * for old chips w/o sb, use zero -+ * for new chips w sb, -+ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset -+ * Other bus: use zero -+ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor -+ */ -+ di->ddoffsetlow = 0; -+ di->dataoffsetlow = 0; -+ if (sbh != NULL) { -+ if (sbh->bustype == PCI_BUS) { /* for pci bus, add offset */ -+ if ((sbh->buscoretype == SB_PCIE) && di->dma64){ -+ di->ddoffsetlow = 0; -+ di->ddoffsethigh = SB_PCIE_DMA_H32; -+ } else { -+ di->ddoffsetlow = SB_PCI_DMA; -+ di->ddoffsethigh = 0; -+ } -+ di->dataoffsetlow = di->ddoffsetlow; -+ di->dataoffsethigh = di->ddoffsethigh; -+ } -+#if defined(__mips__) && defined(IL_BIGENDIAN) -+ /* use sdram swapped region for data buffers but not dma descriptors */ -+ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; -+#endif -+ } ++#define IPV6_NEXT_HDR(ipv6_body) \ ++ (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) + -+ di->addrext = dma_isaddrext(di); ++#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) + -+ DMA_TRACE(("%s: dma_attach: osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", -+ name, osh, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, di->ddoffsetlow, di->dataoffsetlow)); ++#define IPV6_ADDR_LEN 16 /* IPV6 address length */ + -+ /* allocate tx packet pointer vector */ -+ if (ntxd) { -+ size = ntxd * sizeof (void*); -+ if ((di->txp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); -+ goto fail; -+ } -+ bzero((char*)di->txp, size); -+ } ++/* IPV4 TOS or IPV6 Traffic Classifier or 0 */ ++#define IP_TOS(ip_body) \ ++ (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ ++ IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) + -+ /* allocate rx packet pointer vector */ -+ if (nrxd) { -+ size = nrxd * sizeof (void*); -+ if ((di->rxp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", di->name, MALLOCED(osh))); -+ goto fail; -+ } -+ bzero((char*)di->rxp, size); -+ } ++#endif /* _bcmip_h_ */ +diff -urN linux.old/drivers/net/wl/bcmutils.c linux.dev/drivers/net/wl/bcmutils.c +--- linux.old/drivers/net/wl/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/bcmutils.c 2006-04-28 02:27:20.000000000 +0200 +@@ -0,0 +1,857 @@ ++/* ++ * Misc useful OS-independent routines. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $ ++ */ + -+ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ -+ if (ntxd) { -+ if (!dma_alloc(di, DMA_TX)) -+ goto fail; -+ } ++#include ++#include ++#include ++#include ++#include "linux_osl.h" ++#include "pktq.h" ++#include ++#include ++#include ++#include ++#include ++#include "bcmip.h" + -+ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ -+ if (nrxd) { -+ if (!dma_alloc(di, DMA_RX)) -+ goto fail; -+ } ++#define ETHER_TYPE_8021Q 0x8100 ++#define ETHER_TYPE_IP 0x0800 ++#define VLAN_PRI_SHIFT 13 ++#define VLAN_PRI_MASK 7 + -+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { -+ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", di->name, di->txdpa)); -+ goto fail; -+ } -+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { -+ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", di->name, di->rxdpa)); -+ goto fail; -+ } + -+ return ((void*)di); ++struct ether_header { ++ uint8 ether_dhost[6]; ++ uint8 ether_shost[6]; ++ uint16 ether_type; ++} __attribute__((packed)); + -+fail: -+ dma_detach((void*)di); -+ return (NULL); -+} + -+static bool -+dma_alloc(dma_info_t *di, uint direction) -+{ -+ if (DMA64_ENAB(di)) { -+ return dma64_alloc(di, direction); -+ } else { -+ return dma32_alloc(di, direction); -+ } -+} ++struct ethervlan_header { ++ uint8 ether_dhost[6]; ++ uint8 ether_shost[6]; ++ uint16 vlan_type; /* 0x8100 */ ++ uint16 vlan_tag; /* priority, cfi and vid */ ++ uint16 ether_type; ++}; + -+/* may be called with core in reset */ -+void -+dma_detach(dma_info_t *di) ++/* copy a pkt buffer chain into a buffer */ ++uint ++pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) +{ -+ if (di == NULL) -+ return; ++ uint n, ret = 0; + -+ DMA_TRACE(("%s: dma_detach\n", di->name)); ++ if (len < 0) ++ len = 4096; /* "infinite" */ + -+ /* shouldn't be here if descriptors are unreclaimed */ -+ ASSERT(di->txin == di->txout); -+ ASSERT(di->rxin == di->rxout); ++ /* skip 'offset' bytes */ ++ for (; p && offset; p = PKTNEXT(osh, p)) { ++ if (offset < (uint)PKTLEN(osh, p)) ++ break; ++ offset -= PKTLEN(osh, p); ++ } + -+ /* free dma descriptor rings */ -+ if (di->txd32) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), di->txdalloc, (di->txdpa - di->txdalign)); -+ if (di->rxd32) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), di->rxdalloc, (di->rxdpa - di->rxdalign)); ++ if (!p) ++ return 0; + -+ /* free packet pointer vectors */ -+ if (di->txp) -+ MFREE(di->osh, (void*)di->txp, (di->ntxd * sizeof (void*))); -+ if (di->rxp) -+ MFREE(di->osh, (void*)di->rxp, (di->nrxd * sizeof (void*))); ++ /* copy the data */ ++ for (; p && len; p = PKTNEXT(osh, p)) { ++ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); ++ bcopy(PKTDATA(osh, p) + offset, buf, n); ++ buf += n; ++ len -= n; ++ ret += n; ++ offset = 0; ++ } + -+ /* free our private info structure */ -+ MFREE(di->osh, (void*)di, sizeof (dma_info_t)); ++ return ret; +} + -+/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ -+static bool -+dma_isaddrext(dma_info_t *di) ++/* return total length of buffer chain */ ++uint ++pkttotlen(osl_t *osh, void *p) +{ -+ uint32 w; ++ uint total; + -+ if (DMA64_ENAB(di)) { -+ OR_REG(&di->d64txregs->control, D64_XC_AE); -+ w = R_REG(&di->d32txregs->control); -+ AND_REG(&di->d32txregs->control, ~D64_XC_AE); -+ return ((w & XC_AE) == D64_XC_AE); -+ } else { -+ OR_REG(&di->d32txregs->control, XC_AE); -+ w = R_REG(&di->d32txregs->control); -+ AND_REG(&di->d32txregs->control, ~XC_AE); -+ return ((w & XC_AE) == XC_AE); -+ } ++ total = 0; ++ for (; p; p = PKTNEXT(osh, p)) ++ total += PKTLEN(osh, p); ++ return (total); +} + -+void -+dma_txreset(dma_info_t *di) ++/* return the last buffer of chained pkt */ ++void * ++pktlast(osl_t *osh, void *p) +{ -+ DMA_TRACE(("%s: dma_txreset\n", di->name)); ++ for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) ++ ; + -+ if (DMA64_ENAB(di)) -+ dma64_txreset(di); -+ else -+ dma32_txreset(di); ++ return (p); +} + -+void -+dma_rxreset(dma_info_t *di) ++ ++/* ++ * osl multiple-precedence packet queue ++ * hi_prec is always >= the number of the highest non-empty queue ++ */ ++void * ++pktq_penq(struct pktq *pq, int prec, void *p) +{ -+ DMA_TRACE(("%s: dma_rxreset\n", di->name)); ++ struct pktq_prec *q; ++ ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ ++ ++ ASSERT(!pktq_full(pq)); ++ ASSERT(!pktq_pfull(pq, prec)); + -+ if (DMA64_ENAB(di)) -+ dma64_rxreset(di); ++ q = &pq->q[prec]; ++ ++ if (q->head) ++ PKTSETLINK(q->tail, p); + else -+ dma32_rxreset(di); -+} ++ q->head = p; + -+/* initialize descriptor table base address */ -+static void -+dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) -+{ -+ if (DMA64_ENAB(di)) { -+ if (direction == DMA_TX) { -+ W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow); -+ W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); -+ } else { -+ W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow); -+ W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); -+ } -+ } else { -+ uint32 offset = di->ddoffsetlow; -+ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { -+ if (direction == DMA_TX) -+ W_REG(&di->d32txregs->addr, (pa + offset)); -+ else -+ W_REG(&di->d32rxregs->addr, (pa + offset)); -+ } else { -+ /* dma32 address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; -+ -+ if (direction == DMA_TX) { -+ W_REG(&di->d32txregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); -+ SET_REG(&di->d32txregs->control, XC_AE, (ae << XC_AE_SHIFT)); -+ } else { -+ W_REG(&di->d32rxregs->addr, ((pa & ~PCI32ADDR_HIGH) + offset)); -+ SET_REG(&di->d32rxregs->control, RC_AE, (ae << RC_AE_SHIFT)); -+ } -+ } -+ } -+} ++ q->tail = p; ++ q->len++; + -+/* init the tx or rx descriptor */ -+static INLINE void -+dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *ctrl) -+{ -+ uint offset = di->dataoffsetlow; ++ pq->len++; + -+ if ((offset != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { -+ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + offset)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); -+ } else { -+ /* address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ if (pq->hi_prec < prec) ++ pq->hi_prec = (uint8)prec; + -+ *ctrl |= (ae << CTRL_AE_SHIFT); -+ W_SM(&ddring[outidx].addr, BUS_SWAP32((pa & ~PCI32ADDR_HIGH) + offset)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*ctrl)); -+ } ++ return p; +} + -+/* init the tx or rx descriptor */ -+static INLINE void -+dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, ulong pa, uint outidx, uint32 *flags, uint32 bufcount) ++void * ++pktq_penq_head(struct pktq *pq, int prec, void *p) +{ -+ uint32 bufaddr_low = pa + di->dataoffsetlow; -+ uint32 bufaddr_high = 0 + di->dataoffsethigh; ++ struct pktq_prec *q; + -+ uint32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ + -+ W_SM(&ddring[outidx].addrlow, BUS_SWAP32(bufaddr_low)); -+ W_SM(&ddring[outidx].addrhigh, BUS_SWAP32(bufaddr_high)); -+ W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); -+ W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); -+} ++ ASSERT(!pktq_full(pq)); ++ ASSERT(!pktq_pfull(pq, prec)); + -+void -+dma_txinit(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txinit\n", di->name)); ++ q = &pq->q[prec]; + -+ di->txin = di->txout = 0; -+ di->txavail = di->ntxd - 1; ++ if (q->head == NULL) ++ q->tail = p; + -+ /* clear tx descriptor ring */ -+ if (DMA64_ENAB(di)) { -+ BZERO_SM((void*)di->txd64, (di->ntxd * sizeof (dma64dd_t))); -+ W_REG(&di->d64txregs->control, XC_XE); -+ dma_ddtable_init(di, DMA_TX, di->txdpa); -+ } else { -+ BZERO_SM((void*)di->txd32, (di->ntxd * sizeof (dma32dd_t))); -+ W_REG(&di->d32txregs->control, XC_XE); -+ dma_ddtable_init(di, DMA_TX, di->txdpa); -+ } -+} ++ PKTSETLINK(p, q->head); ++ q->head = p; ++ q->len++; + -+bool -+dma_txenabled(dma_info_t *di) -+{ -+ uint32 xc; -+ -+ /* If the chip is dead, it is not enabled :-) */ -+ if (DMA64_ENAB(di)) { -+ xc = R_REG(&di->d64txregs->control); -+ return ((xc != 0xffffffff) && (xc & D64_XC_XE)); -+ } else { -+ xc = R_REG(&di->d32txregs->control); -+ return ((xc != 0xffffffff) && (xc & XC_XE)); -+ } -+} ++ pq->len++; + -+void -+dma_txsuspend(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); -+ if (DMA64_ENAB(di)) -+ OR_REG(&di->d64txregs->control, D64_XC_SE); -+ else -+ OR_REG(&di->d32txregs->control, XC_SE); -+} ++ if (pq->hi_prec < prec) ++ pq->hi_prec = (uint8)prec; + -+void -+dma_txresume(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txresume\n", di->name)); -+ if (DMA64_ENAB(di)) -+ AND_REG(&di->d64txregs->control, ~D64_XC_SE); -+ else -+ AND_REG(&di->d32txregs->control, ~XC_SE); ++ return p; +} + -+bool -+dma_txsuspendedidle(dma_info_t *di) ++void * ++pktq_pdeq(struct pktq *pq, int prec) +{ -+ if (DMA64_ENAB(di)) -+ return dma64_txsuspendedidle(di); -+ else -+ return dma32_txsuspendedidle(di); -+} ++ struct pktq_prec *q; ++ void *p; + -+bool -+dma_txsuspended(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di)) -+ return ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); -+ else -+ return ((R_REG(&di->d32txregs->control) & XC_SE) == XC_SE); -+} ++ ASSERT(prec >= 0 && prec < pq->num_prec); + -+bool -+dma_txstopped(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di)) -+ return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_STOPPED); -+ else -+ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); -+} ++ q = &pq->q[prec]; + -+bool -+dma_rxstopped(dma_info_t *di) -+{ -+ if (DMA64_ENAB(di)) -+ return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == D64_RS0_RS_STOPPED); -+ else -+ return ((R_REG(&di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); -+} ++ if ((p = q->head) == NULL) ++ return NULL; + -+void -+dma_fifoloopbackenable(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); -+ if (DMA64_ENAB(di)) -+ OR_REG(&di->d64txregs->control, D64_XC_LE); -+ else -+ OR_REG(&di->d32txregs->control, XC_LE); -+} ++ if ((q->head = PKTLINK(p)) == NULL) ++ q->tail = NULL; + -+void -+dma_rxinit(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxinit\n", di->name)); ++ q->len--; + -+ di->rxin = di->rxout = 0; ++ pq->len--; + -+ /* clear rx descriptor ring */ -+ if (DMA64_ENAB(di)) { -+ BZERO_SM((void*)di->rxd64, (di->nrxd * sizeof (dma64dd_t))); -+ dma_rxenable(di); -+ dma_ddtable_init(di, DMA_RX, di->rxdpa); -+ } else { -+ BZERO_SM((void*)di->rxd32, (di->nrxd * sizeof (dma32dd_t))); -+ dma_rxenable(di); -+ dma_ddtable_init(di, DMA_RX, di->rxdpa); -+ } ++ PKTSETLINK(p, NULL); ++ ++ return p; +} + -+void -+dma_rxenable(dma_info_t *di) ++void * ++pktq_pdeq_tail(struct pktq *pq, int prec) +{ -+ DMA_TRACE(("%s: dma_rxenable\n", di->name)); -+ if (DMA64_ENAB(di)) -+ W_REG(&di->d64rxregs->control, ((di->rxoffset << D64_RC_RO_SHIFT) | D64_RC_RE)); ++ struct pktq_prec *q; ++ void *p, *prev; ++ ++ ASSERT(prec >= 0 && prec < pq->num_prec); ++ ++ q = &pq->q[prec]; ++ ++ if ((p = q->head) == NULL) ++ return NULL; ++ ++ for (prev = NULL; p != q->tail; p = PKTLINK(p)) ++ prev = p; ++ ++ if (prev) ++ PKTSETLINK(prev, NULL); + else -+ W_REG(&di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); -+} ++ q->head = NULL; + -+bool -+dma_rxenabled(dma_info_t *di) -+{ -+ uint32 rc; ++ q->tail = prev; ++ q->len--; + -+ if (DMA64_ENAB(di)) { -+ rc = R_REG(&di->d64rxregs->control); -+ return ((rc != 0xffffffff) && (rc & D64_RC_RE)); -+ } else { -+ rc = R_REG(&di->d32rxregs->control); -+ return ((rc != 0xffffffff) && (rc & RC_RE)); -+ } -+} ++ pq->len--; + ++ return p; ++} + -+/* !! tx entry routine */ -+int -+dma_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++void ++pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir) +{ -+ if (DMA64_ENAB(di)) { -+ return dma64_txfast(di, p0, coreflags); -+ } else { -+ return dma32_txfast(di, p0, coreflags); ++ struct pktq_prec *q; ++ void *p; ++ ++ q = &pq->q[prec]; ++ p = q->head; ++ while (p) { ++ q->head = PKTLINK(p); ++ PKTSETLINK(p, NULL); ++ PKTFREE(osh, p, dir); ++ q->len--; ++ pq->len--; ++ p = q->head; + } ++ ASSERT(q->len == 0); ++ q->tail = NULL; +} + -+/* !! rx entry routine, returns a pointer to the next frame received, or NULL if there are no more */ -+void* -+dma_rx(dma_info_t *di) ++bool ++pktq_pdel(struct pktq *pq, void *pktbuf, int prec) +{ ++ struct pktq_prec *q; + void *p; -+ uint len; -+ int skiplen = 0; + -+ while ((p = dma_getnextrxp(di, FALSE))) { -+ /* skip giant packets which span multiple rx descriptors */ -+ if (skiplen > 0) { -+ skiplen -= di->rxbufsize; -+ if (skiplen < 0) -+ skiplen = 0; -+ PKTFREE(di->osh, p, FALSE); -+ continue; -+ } ++ ASSERT(prec >= 0 && prec < pq->num_prec); + -+ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); -+ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); ++ if (!pktbuf) ++ return FALSE; + -+ /* bad frame length check */ -+ if (len > (di->rxbufsize - di->rxoffset)) { -+ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); -+ if (len > 0) -+ skiplen = len - (di->rxbufsize - di->rxoffset); -+ PKTFREE(di->osh, p, FALSE); -+ di->hnddma.rxgiants++; -+ continue; -+ } ++ q = &pq->q[prec]; + -+ /* set actual length */ -+ PKTSETLEN(di->osh, p, (di->rxoffset + len)); ++ if (q->head == pktbuf) { ++ if ((q->head = PKTLINK(pktbuf)) == NULL) ++ q->tail = NULL; ++ } else { ++ for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) ++ ; ++ if (p == NULL) ++ return FALSE; + -+ break; ++ PKTSETLINK(p, PKTLINK(pktbuf)); ++ if (q->tail == pktbuf) ++ q->tail = p; + } + -+ return (p); ++ q->len--; ++ pq->len--; ++ PKTSETLINK(pktbuf, NULL); ++ return TRUE; +} + -+/* post receive buffers */ +void -+dma_rxfill(dma_info_t *di) ++pktq_init(struct pktq *pq, int num_prec, int max_len) +{ -+ void *p; -+ uint rxin, rxout; -+ uint32 ctrl; -+ uint n; -+ uint i; -+ uint32 pa; -+ uint rxbufsize; ++ int prec; + -+ /* -+ * Determine how many receive buffers we're lacking -+ * from the full complement, allocate, initialize, -+ * and post them, then update the chip rx lastdscr. -+ */ ++ ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); + -+ rxin = di->rxin; -+ rxout = di->rxout; -+ rxbufsize = di->rxbufsize; ++ bzero(pq, sizeof(*pq)); + -+ n = di->nrxpost - NRXDACTIVE(rxin, rxout); ++ pq->num_prec = (uint16)num_prec; + -+ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); ++ pq->max = (uint16)max_len; + -+ for (i = 0; i < n; i++) { -+ if ((p = PKTGET(di->osh, rxbufsize, FALSE)) == NULL) { -+ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); -+ di->hnddma.rxnobuf++; -+ break; -+ } ++ for (prec = 0; prec < num_prec; prec++) ++ pq->q[prec].max = pq->max; ++} + -+ /* Do a cached write instead of uncached write since DMA_MAP -+ * will flush the cache. */ -+ *(uint32*)(PKTDATA(di->osh, p)) = 0; ++void * ++pktq_deq(struct pktq *pq, int *prec_out) ++{ ++ struct pktq_prec *q; ++ void *p; ++ int prec; + -+ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p); -+ ASSERT(ISALIGNED(pa, 4)); ++ if (pq->len == 0) ++ return NULL; + -+ /* save the free packet pointer */ -+ ASSERT(di->rxp[rxout] == NULL); -+ di->rxp[rxout] = p; ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) ++ pq->hi_prec--; + -+ if (DMA64_ENAB(di)) { -+ /* prep the descriptor control value */ -+ if (rxout == (di->nrxd - 1)) -+ ctrl = CTRL_EOT; ++ q = &pq->q[prec]; + -+ dma64_dd_upd(di, di->rxd64, pa, rxout, &ctrl, rxbufsize); -+ } else { -+ /* prep the descriptor control value */ -+ ctrl = rxbufsize; -+ if (rxout == (di->nrxd - 1)) -+ ctrl |= CTRL_EOT; -+ dma32_dd_upd(di, di->rxd32, pa, rxout, &ctrl); -+ } ++ if ((p = q->head) == NULL) ++ return NULL; + -+ rxout = NEXTRXD(rxout); -+ } ++ if ((q->head = PKTLINK(p)) == NULL) ++ q->tail = NULL; + -+ di->rxout = rxout; ++ q->len--; + -+ /* update the chip lastdscr pointer */ -+ if (DMA64_ENAB(di)) { -+ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t)); -+ } else { -+ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); -+ } -+} ++ pq->len--; + -+void -+dma_txreclaim(dma_info_t *di, bool forceall) -+{ -+ void *p; ++ if (prec_out) ++ *prec_out = prec; + -+ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); ++ PKTSETLINK(p, NULL); + -+ while ((p = dma_getnexttxp(di, forceall))) -+ PKTFREE(di->osh, p, TRUE); ++ return p; +} + -+/* -+ * Reclaim next completed txd (txds if using chained buffers) and -+ * return associated packet. -+ * If 'force' is true, reclaim txd(s) and return associated packet -+ * regardless of the value of the hardware "curr" pointer. -+ */ -+void* -+dma_getnexttxp(dma_info_t *di, bool forceall) -+{ -+ if (DMA64_ENAB(di)) { -+ return dma64_getnexttxp(di, forceall); -+ } else { -+ return dma32_getnexttxp(di, forceall); -+ } -+} -+ -+/* like getnexttxp but no reclaim */ -+void* -+dma_peeknexttxp(dma_info_t *di) ++void * ++pktq_deq_tail(struct pktq *pq, int *prec_out) +{ -+ uint end, i; ++ struct pktq_prec *q; ++ void *p, *prev; ++ int prec; + -+ if (DMA64_ENAB(di)) { -+ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); -+ } else { -+ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); -+ } ++ if (pq->len == 0) ++ return NULL; + -+ for (i = di->txin; i != end; i = NEXTTXD(i)) -+ if (di->txp[i]) -+ return (di->txp[i]); ++ for (prec = 0; prec < pq->hi_prec; prec++) ++ if (pq->q[prec].head) ++ break; + -+ return (NULL); -+} ++ q = &pq->q[prec]; + -+/* -+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). -+ */ -+void -+dma_txrotate(di_t *di) -+{ -+ if (DMA64_ENAB(di)) { -+ dma64_txrotate(di); -+ } else { -+ dma32_txrotate(di); -+ } -+} ++ if ((p = q->head) == NULL) ++ return NULL; + -+void -+dma_rxreclaim(dma_info_t *di) -+{ -+ void *p; ++ for (prev = NULL; p != q->tail; p = PKTLINK(p)) ++ prev = p; + -+ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); ++ if (prev) ++ PKTSETLINK(prev, NULL); ++ else ++ q->head = NULL; + -+ while ((p = dma_getnextrxp(di, TRUE))) -+ PKTFREE(di->osh, p, FALSE); ++ q->tail = prev; ++ q->len--; ++ ++ pq->len--; ++ ++ if (prec_out) ++ *prec_out = prec; ++ ++ PKTSETLINK(p, NULL); ++ ++ return p; +} + +void * -+dma_getnextrxp(dma_info_t *di, bool forceall) ++pktq_peek(struct pktq *pq, int *prec_out) +{ -+ if (DMA64_ENAB(di)) { -+ return dma64_getnextrxp(di, forceall); -+ } else { -+ return dma32_getnextrxp(di, forceall); -+ } -+} ++ int prec; + -+uintptr -+dma_getvar(dma_info_t *di, char *name) -+{ -+ if (!strcmp(name, "&txavail")) -+ return ((uintptr) &di->txavail); -+ else { -+ ASSERT(0); -+ } -+ return (0); -+} ++ if (pq->len == 0) ++ return NULL; + -+void -+dma_txblock(dma_info_t *di) -+{ -+ di->txavail = 0; -+} ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) ++ pq->hi_prec--; + -+void -+dma_txunblock(dma_info_t *di) -+{ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ if (prec_out) ++ *prec_out = prec; ++ ++ return (pq->q[prec].head); +} + -+uint -+dma_txactive(dma_info_t *di) ++void * ++pktq_peek_tail(struct pktq *pq, int *prec_out) +{ -+ return (NTXDACTIVE(di->txin, di->txout)); ++ int prec; ++ ++ if (pq->len == 0) ++ return NULL; ++ ++ for (prec = 0; prec < pq->hi_prec; prec++) ++ if (pq->q[prec].head) ++ break; ++ ++ if (prec_out) ++ *prec_out = prec; ++ ++ return (pq->q[prec].tail); +} -+ ++ +void -+dma_rxpiomode(dma32regs_t *regs) ++pktq_flush(osl_t *osh, struct pktq *pq, bool dir) +{ -+ W_REG(®s->control, RC_FM); ++ int prec; ++ for (prec = 0; prec < pq->num_prec; prec++) ++ pktq_pflush(osh, pq, prec, dir); ++ ASSERT(pq->len == 0); +} + -+void -+dma_txpioloopback(dma32regs_t *regs) ++/* Return sum of lengths of a specific set of precedences */ ++int ++pktq_mlen(struct pktq *pq, uint prec_bmp) +{ -+ OR_REG(®s->control, XC_LE); -+} ++ int prec, len; + ++ len = 0; + ++ for (prec = 0; prec <= pq->hi_prec; prec++) ++ if (prec_bmp & (1 << prec)) ++ len += pq->q[prec].len; + ++ return len; ++} + -+/*** 32 bits DMA non-inline functions ***/ -+static bool -+dma32_alloc(dma_info_t *di, uint direction) ++/* Priority dequeue from a specific set of precedences */ ++void * ++pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) +{ -+ uint size; -+ uint ddlen; -+ void *va; ++ struct pktq_prec *q; ++ void *p; ++ int prec; + -+ ddlen = sizeof (dma32dd_t); ++ if (pq->len == 0) ++ return NULL; + -+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); ++ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) ++ pq->hi_prec--; + -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) -+ size += D32RINGALIGN; ++ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) ++ if (prec-- == 0) ++ return NULL; + ++ q = &pq->q[prec]; + -+ if (direction == DMA_TX) { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); -+ return FALSE; -+ } ++ if ((p = q->head) == NULL) ++ return NULL; + -+ di->txd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); -+ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); -+ di->txdpa += di->txdalign; -+ di->txdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); -+ } else { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); -+ return FALSE; -+ } -+ di->rxd32 = (dma32dd_t*) ROUNDUP((uintptr)va, D32RINGALIGN); -+ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); -+ di->rxdpa += di->rxdalign; -+ di->rxdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); -+ } ++ if ((q->head = PKTLINK(p)) == NULL) ++ q->tail = NULL; + -+ return TRUE; -+} ++ q->len--; ++ ++ if (prec_out) ++ *prec_out = prec; + -+static void -+dma32_txreset(dma_info_t *di) -+{ -+ uint32 status; ++ pq->len--; + -+ /* suspend tx DMA first */ -+ W_REG(&di->d32txregs->control, XC_SE); -+ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED && -+ status != XS_XS_IDLE && -+ status != XS_XS_STOPPED, -+ 10000); -+ -+ W_REG(&di->d32txregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED, -+ 10000); -+ -+ if (status != XS_XS_DISABLED) { -+ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); -+ } ++ PKTSETLINK(p, NULL); + -+ /* wait for the last transaction to complete */ -+ OSL_DELAY(300); ++ return p; +} + -+static void -+dma32_rxreset(dma_info_t *di) ++char* ++bcmstrcat(char *dest, const char *src) +{ -+ uint32 status; -+ -+ W_REG(&di->d32rxregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED, -+ 10000); ++ strcpy(&dest[strlen(dest)], src); ++ return (dest); ++} + -+ if (status != RS_RS_DISABLED) { -+ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); -+ } ++char* ++bcm_ether_ntoa(struct ether_addr *ea, char *buf) ++{ ++ sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", ++ ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, ++ ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); ++ return (buf); +} + -+static bool -+dma32_txsuspendedidle(dma_info_t *di) ++/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ ++int ++bcm_ether_atoe(char *p, struct ether_addr *ea) +{ -+ if (!(R_REG(&di->d32txregs->control) & XC_SE)) -+ return 0; -+ -+ if ((R_REG(&di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) -+ return 0; ++ int i = 0; + -+ OSL_DELAY(2); -+ return ((R_REG(&di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); ++ for (;;) { ++ ea->octet[i++] = (char) bcm_strtoul(p, &p, 16); ++ if (!*p++ || i == 6) ++ break; ++ } ++ ++ return (i == 6); +} + -+/* -+ * supports full 32bit dma engine buffer addressing so -+ * dma buffers can cross 4 Kbyte page boundaries. ++/* Takes an Ethernet frame and sets out-of-bound PKTPRIO ++ * Also updates the inplace vlan tag if requested + */ -+static int -+dma32_txfast(dma_info_t *di, void *p0, uint32 coreflags) ++void ++pktsetprio(void *pkt, bool update_vtag) +{ -+ void *p, *next; -+ uchar *data; -+ uint len; -+ uint txout; -+ uint32 ctrl; -+ uint32 pa; -+ -+ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ struct ether_header *eh; ++ struct ethervlan_header *evh; ++ uint8 *pktdata; ++ int priority = 0; + -+ txout = di->txout; -+ ctrl = 0; ++ pktdata = (uint8 *) PKTDATA(NULL, pkt); ++ ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); + -+ /* -+ * Walk the chain of packet buffers -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ data = PKTDATA(di->osh, p); -+ len = PKTLEN(di->osh, p); -+ next = PKTNEXT(di->osh, p); ++ eh = (struct ether_header *) pktdata; + -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) -+ goto outoftxd; ++ if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { ++ uint16 vlan_tag; ++ int vlan_prio, dscp_prio = 0; + -+ if (len == 0) -+ continue; ++ evh = (struct ethervlan_header *)eh; + -+ /* get physical address of buffer start */ -+ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ vlan_tag = ntoh16(evh->vlan_tag); ++ vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; + -+ /* build the descriptor control value */ -+ ctrl = len & CTRL_BC_MASK; ++ if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { ++ uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); ++ uint8 tos_tc = IP_TOS(ip_body); ++ dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); ++ } + -+ ctrl |= coreflags; -+ -+ if (p == p0) -+ ctrl |= CTRL_SOF; -+ if (next == NULL) -+ ctrl |= (CTRL_IOC | CTRL_EOF); -+ if (txout == (di->ntxd - 1)) -+ ctrl |= CTRL_EOT; ++ /* DSCP priority gets precedence over 802.1P (vlan tag) */ ++ priority = (dscp_prio != 0) ? dscp_prio : vlan_prio; + -+ if (DMA64_ENAB(di)) { -+ dma64_dd_upd(di, di->txd64, pa, txout, &ctrl, len); -+ } else { -+ dma32_dd_upd(di, di->txd32, pa, txout, &ctrl); ++ /* ++ * If the DSCP priority is not the same as the VLAN priority, ++ * then overwrite the priority field in the vlan tag, with the ++ * DSCP priority value. This is required for Linux APs because ++ * the VLAN driver on Linux, overwrites the skb->priority field ++ * with the priority value in the vlan tag ++ */ ++ if (update_vtag && (priority != vlan_prio)) { ++ vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); ++ vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; ++ evh->vlan_tag = hton16(vlan_tag); + } ++ } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { ++ uint8 *ip_body = pktdata + sizeof(struct ether_header); ++ uint8 tos_tc = IP_TOS(ip_body); ++ priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); ++ } + -+ ASSERT(di->txp[txout] == NULL); ++ ASSERT(priority >= 0 && priority <= MAXPRIO); ++ PKTSETPRIO(pkt, priority); ++} + -+ txout = NEXTTXD(txout); -+ } ++static char bcm_undeferrstr[BCME_STRLEN]; + -+ /* if last txd eof not set, fix it */ -+ if (!(ctrl & CTRL_EOF)) -+ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(ctrl | CTRL_IOC | CTRL_EOF)); ++static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; + -+ /* save the packet */ -+ di->txp[PREVTXD(txout)] = p0; ++/* Convert the Error codes into related Error strings */ ++const char * ++bcmerrorstr(int bcmerror) ++{ ++ int abs_bcmerror; + -+ /* bump the tx descriptor index */ -+ di->txout = txout; ++ abs_bcmerror = ABS(bcmerror); + -+ /* kick the chip */ -+ if (DMA64_ENAB(di)) { -+ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); -+ } else { -+ W_REG(&di->d32txregs->ptr, I2B(txout, dma32dd_t)); ++ /* check if someone added a bcmerror code but forgot to add errorstring */ ++ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); ++ if ((bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) { ++ sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror); ++ return bcm_undeferrstr; + } + -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (0); ++ ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN); + -+ outoftxd: -+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); -+ PKTFREE(di->osh, p0, TRUE); -+ di->txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); ++ return bcmerrorstrtable[abs_bcmerror]; +} + -+static void* -+dma32_getnexttxp(dma_info_t *di, bool forceall) -+{ -+ uint start, end, i; -+ void *txp; -+ -+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); -+ -+ txp = NULL; + -+ start = di->txin; -+ if (forceall) -+ end = di->txout; -+ else -+ end = B2I(R_REG(&di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++int ++bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) ++{ ++ int bcmerror = 0; ++ ++ /* length check on io buf */ ++ switch (vi->type) { ++ case IOVT_BOOL: ++ case IOVT_INT8: ++ case IOVT_INT16: ++ case IOVT_INT32: ++ case IOVT_UINT8: ++ case IOVT_UINT16: ++ case IOVT_UINT32: ++ /* all integers are int32 sized args at the ioctl interface */ ++ if (len < (int)sizeof(int)) { ++ bcmerror = BCME_BUFTOOSHORT; ++ } ++ break; + -+ if ((start == 0) && (end > di->txout)) -+ goto bogus; ++ case IOVT_BUFFER: ++ /* buffer must meet minimum length requirement */ ++ if (len < vi->minlen) { ++ bcmerror = BCME_BUFTOOSHORT; ++ } ++ break; + -+ for (i = start; i != end && !txp; i = NEXTTXD(i)) { -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), -+ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]); ++ case IOVT_VOID: ++ if (!set) { ++ /* Cannot return nil... */ ++ bcmerror = BCME_UNSUPPORTED; ++ } else if (len) { ++ /* Set is an action w/o parameters */ ++ bcmerror = BCME_BUFTOOLONG; ++ } ++ break; + -+ W_SM(&di->txd32[i].addr, 0xdeadbeef); -+ txp = di->txp[i]; -+ di->txp[i] = NULL; ++ default: ++ /* unknown type for length check in iovar info */ ++ ASSERT(0); ++ bcmerror = BCME_UNSUPPORTED; + } + -+ di->txin = i; -+ -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ return bcmerror; ++} + -+ return (txp); ++#define CRC_INNER_LOOP(n, c, x) \ ++ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] + -+bogus: -+/* -+ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", -+ start, end, di->txout, forceall)); -+*/ -+ return (NULL); -+} ++static uint32 crc32_table[256] = { ++ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, ++ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, ++ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, ++ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, ++ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, ++ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, ++ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, ++ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, ++ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, ++ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, ++ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, ++ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, ++ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, ++ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, ++ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, ++ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, ++ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, ++ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, ++ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, ++ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, ++ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, ++ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, ++ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, ++ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, ++ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, ++ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, ++ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, ++ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, ++ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, ++ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, ++ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, ++ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, ++ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, ++ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, ++ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, ++ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, ++ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, ++ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, ++ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, ++ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, ++ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, ++ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, ++ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, ++ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, ++ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, ++ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, ++ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, ++ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, ++ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, ++ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, ++ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, ++ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, ++ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, ++ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, ++ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, ++ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, ++ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, ++ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, ++ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, ++ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, ++ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, ++ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, ++ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, ++ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D ++}; + -+static void * -+dma32_getnextrxp(dma_info_t *di, bool forceall) ++uint32 ++hndcrc32( ++ uint8 *pdata, /* pointer to array of data to process */ ++ uint nbytes, /* number of input data bytes to process */ ++ uint32 crc /* either CRC32_INIT_VALUE or previous return value */ ++) +{ -+ uint i; -+ void *rxp; ++ uint8 *pend; ++#ifdef __mips__ ++ uint8 tmp[4]; ++ ulong *tptr = (ulong *)tmp; + -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma_rxenabled(di)); ++ /* in case the beginning of the buffer isn't aligned */ ++ pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); ++ nbytes -= (pend - pdata); ++ while (pdata < pend) ++ CRC_INNER_LOOP(32, crc, *pdata++); + -+ i = di->rxin; ++ /* handle bulk of data as 32-bit words */ ++ pend = pdata + (nbytes & 0xfffffffc); ++ while (pdata < pend) { ++ *tptr = *(ulong *)pdata; ++ pdata += sizeof(ulong *); ++ CRC_INNER_LOOP(32, crc, tmp[0]); ++ CRC_INNER_LOOP(32, crc, tmp[1]); ++ CRC_INNER_LOOP(32, crc, tmp[2]); ++ CRC_INNER_LOOP(32, crc, tmp[3]); ++ } + -+ /* return if no packets posted */ -+ if (i == di->rxout) -+ return (NULL); ++ /* 1-3 bytes at end of buffer */ ++ pend = pdata + (nbytes & 0x03); ++ while (pdata < pend) ++ CRC_INNER_LOOP(32, crc, *pdata++); ++#else ++ pend = pdata + nbytes; ++ while (pdata < pend) ++ CRC_INNER_LOOP(32, crc, *pdata++); ++#endif /* __mips__ */ + -+ /* ignore curr if forceall */ -+ if (!forceall && (i == B2I(R_REG(&di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) -+ return (NULL); ++ return crc; ++} + -+ /* get the packet pointer that corresponds to the rx descriptor */ -+ rxp = di->rxp[i]; -+ ASSERT(rxp); -+ di->rxp[i] = NULL; + -+ /* clear this packet from the descriptor ring */ -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), -+ di->rxbufsize, DMA_RX, rxp); -+ W_SM(&di->rxd32[i].addr, 0xdeadbeef); ++/* ++ * Advance from the current 1-byte tag/1-byte length/variable-length value ++ * triple, to the next, returning a pointer to the next. ++ * If the current or next TLV is invalid (does not fit in given buffer length), ++ * NULL is returned. ++ * *buflen is not modified if the TLV elt parameter is invalid, or is decremented ++ * by the TLV paramter's length if it is valid. ++ */ ++bcm_tlv_t * ++bcm_next_tlv(bcm_tlv_t *elt, int *buflen) ++{ ++ int len; ++ ++ /* validate current elt */ ++ if (!bcm_valid_tlv(elt, *buflen)) ++ return NULL; + -+ di->rxin = NEXTRXD(i); ++ /* advance to next elt */ ++ len = elt->len; ++ elt = (bcm_tlv_t*)(elt->data + len); ++ *buflen -= (2 + len); + -+ return (rxp); ++ /* validate next elt */ ++ if (!bcm_valid_tlv(elt, *buflen)) ++ return NULL; ++ ++ return elt; +} + -+static void -+dma32_txrotate(di_t *di) ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag ++ */ ++bcm_tlv_t * ++bcm_parse_tlvs(void *buf, int buflen, uint key) +{ -+ uint ad; -+ uint nactive; -+ uint rot; -+ uint old, new; -+ uint32 w; -+ uint first, last; ++ bcm_tlv_t *elt; ++ int totlen; + -+ ASSERT(dma_txsuspendedidle(di)); ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; + -+ nactive = dma_txactive(di); -+ ad = B2I(((R_REG(&di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); -+ rot = TXD(ad - di->txin); ++ /* find tagged parameter */ ++ while (totlen >= 2) { ++ int len = elt->len; + -+ ASSERT(rot < di->ntxd); ++ /* validate remaining totlen */ ++ if ((elt->id == key) && (totlen >= (len + 2))) ++ return (elt); + -+ /* full-ring case is a lot harder - don't worry about this */ -+ if (rot >= (di->ntxd - nactive)) { -+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); -+ return; ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); ++ totlen -= (len + 2); + } + -+ first = di->txin; -+ last = PREVTXD(di->txout); ++ return NULL; ++} + -+ /* move entries starting at last and moving backwards to first */ -+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { -+ new = TXD(old + rot); ++/* ++ * Traverse a string of 1-byte tag/1-byte length/variable-length value ++ * triples, returning a pointer to the substring whose first element ++ * matches tag. Stop parsing when we see an element whose ID is greater ++ * than the target key. ++ */ ++bcm_tlv_t * ++bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) ++{ ++ bcm_tlv_t *elt; ++ int totlen; + -+ /* -+ * Move the tx dma descriptor. -+ * EOT is set only in the last entry in the ring. -+ */ -+ w = R_SM(&di->txd32[old].ctrl) & ~CTRL_EOT; -+ if (new == (di->ntxd - 1)) -+ w |= CTRL_EOT; -+ W_SM(&di->txd32[new].ctrl, w); -+ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); ++ elt = (bcm_tlv_t*)buf; ++ totlen = buflen; + -+ /* zap the old tx dma descriptor address field */ -+ W_SM(&di->txd32[old].addr, 0xdeadbeef); ++ /* find tagged parameter */ ++ while (totlen >= 2) { ++ uint id = elt->id; ++ int len = elt->len; + -+ /* move the corresponding txp[] entry */ -+ ASSERT(di->txp[new] == NULL); -+ di->txp[new] = di->txp[old]; -+ di->txp[old] = NULL; -+ } ++ /* Punt if we start seeing IDs > than target key */ ++ if (id > key) ++ return (NULL); + -+ /* update txin and txout */ -+ di->txin = ad; -+ di->txout = TXD(di->txout + rot); -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ /* validate remaining totlen */ ++ if ((id == key) && (totlen >= (len + 2))) ++ return (elt); + -+ /* kick the chip */ -+ W_REG(&di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); ++ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); ++ totlen -= (len + 2); ++ } ++ return NULL; +} + -+/*** 64 bits DMA non-inline functions ***/ -+ -+#ifdef BCMDMA64 + -+static bool -+dma64_alloc(dma_info_t *di, uint direction) ++/* Initialization of bcmstrbuf structure */ ++void ++bcm_binit(struct bcmstrbuf *b, char *buf, uint size) +{ -+ uint size; -+ uint ddlen; -+ uint32 alignbytes; -+ void *va; -+ -+ ddlen = sizeof (dma64dd_t); -+ -+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); -+ -+ alignbytes = di->dma64align; -+ -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, alignbytes)) -+ size += alignbytes; ++ b->origsize = b->size = size; ++ b->origbuf = b->buf = buf; ++} + ++/* Buffer sprintf wrapper to guard against buffer overflow */ ++int ++bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) ++{ ++ va_list ap; ++ int r; + -+ if (direction == DMA_TX) { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); -+ return FALSE; -+ } ++ va_start(ap, fmt); ++ r = vsnprintf(b->buf, b->size, fmt, ap); + -+ di->txd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); -+ di->txdalign = (uint)((int8*)di->txd64 - (int8*)va); -+ di->txdpa += di->txdalign; -+ di->txdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->txd64, alignbytes)); -+ } else { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); -+ return FALSE; -+ } -+ di->rxd64 = (dma64dd_t*) ROUNDUP((uintptr)va, alignbytes); -+ di->rxdalign = (uint)((int8*)di->rxd64 - (int8*)va); -+ di->rxdpa += di->rxdalign; -+ di->rxdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->rxd64, alignbytes)); ++ /* Non Ansi C99 compliant returns -1, ++ * Ansi compliant return r >= b->size, ++ * bcmstdlib returns 0, handle all ++ */ ++ if ((r == -1) || (r >= (int)b->size) || (r == 0)) ++ { ++ b->size = 0; ++ } ++ else ++ { ++ b->size -= r; ++ b->buf += r; + } + -+ return TRUE; ++ va_end(ap); ++ ++ return r; +} +diff -urN linux.old/drivers/net/wl/hnddma.c linux.dev/drivers/net/wl/hnddma.c +--- linux.old/drivers/net/wl/hnddma.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/hnddma.c 2006-05-02 17:42:13.000000000 +0200 +@@ -0,0 +1,1157 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA module. ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: hnddma.c,v 1.11 2006/04/08 07:12:42 honor Exp $ ++ */ + -+static void -+dma64_txreset(dma_info_t *di) -+{ -+ uint32 status; ++#include ++#include ++#include ++#include "linux_osl.h" ++#include ++#include ++#include ++#include ++#include + -+ /* suspend tx DMA first */ -+ W_REG(&di->d64txregs->control, D64_XC_SE); -+ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED && -+ status != D64_XS0_XS_IDLE && -+ status != D64_XS0_XS_STOPPED, -+ 10000); -+ -+ W_REG(&di->d64txregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK)) != D64_XS0_XS_DISABLED, -+ 10000); -+ -+ if (status != D64_XS0_XS_DISABLED) { -+ DMA_ERROR(("%s: dma_txreset: dma cannot be stopped\n", di->name)); -+ } ++#include "sbhnddma.h" ++#include "hnddma.h" + -+ /* wait for the last transaction to complete */ -+ OSL_DELAY(300); -+} ++/* debug/trace */ ++#define DMA_ERROR(args) ++#define DMA_TRACE(args) + -+static void -+dma64_rxreset(dma_info_t *di) -+{ -+ uint32 status; ++/* default dma message level (if input msg_level pointer is null in dma_attach()) */ ++static uint dma_msg_level = ++ 0; + -+ W_REG(&di->d64rxregs->control, 0); -+ SPINWAIT((status = (R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK)) != D64_RS0_RS_DISABLED, -+ 10000); ++#define MAXNAMEL 8 /* 8 char names */ + -+ if (status != D64_RS0_RS_DISABLED) { -+ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); -+ } -+} ++#define DI_INFO(dmah) (dma_info_t *)dmah + -+static bool -+dma64_txsuspendedidle(dma_info_t *di) -+{ ++/* dma engine software state */ ++typedef struct dma_info { ++ struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t, ++ * which could be const ++ */ ++ uint *msg_level; /* message level pointer */ ++ char name[MAXNAMEL]; /* callers name for diag msgs */ + -+ if (!(R_REG(&di->d64txregs->control) & D64_XC_SE)) -+ return 0; -+ -+ if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == D64_XS0_XS_IDLE) -+ return 1; ++ void *osh; /* os handle */ ++ sb_t *sbh; /* sb handle */ + -+ return 0; -+} ++ bool dma64; /* dma64 enabled */ ++ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ + -+/* -+ * supports full 32bit dma engine buffer addressing so -+ * dma buffers can cross 4 Kbyte page boundaries. -+ */ -+static int -+dma64_txfast(dma_info_t *di, void *p0, uint32 coreflags) -+{ -+ void *p, *next; -+ uchar *data; -+ uint len; -+ uint txout; -+ uint32 flags; -+ uint32 pa; ++ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ ++ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ ++ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ ++ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ + -+ DMA_TRACE(("%s: dma_txfast\n", di->name)); ++ uint32 dma64align; /* either 8k or 4k depends on number of dd */ ++ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ ++ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ ++ uint ntxd; /* # tx descriptors tunable */ ++ uint txin; /* index of next descriptor to reclaim */ ++ uint txout; /* index of next descriptor to post */ ++ void **txp; /* pointer to parallel array of pointers to packets */ ++ osldma_t *tx_dmah; /* DMA TX descriptor ring handle */ ++ osldma_t **txp_dmah; /* DMA TX packet data handle */ ++ ulong txdpa; /* physical address of descriptor ring */ ++ uint txdalign; /* #bytes added to alloc'd mem to align txd */ ++ uint txdalloc; /* #bytes allocated for the ring */ + -+ txout = di->txout; -+ flags = 0; ++ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ ++ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ ++ uint nrxd; /* # rx descriptors tunable */ ++ uint rxin; /* index of next descriptor to reclaim */ ++ uint rxout; /* index of next descriptor to post */ ++ void **rxp; /* pointer to parallel array of pointers to packets */ ++ osldma_t *rx_dmah; /* DMA RX descriptor ring handle */ ++ osldma_t **rxp_dmah; /* DMA RX packet data handle */ ++ ulong rxdpa; /* physical address of descriptor ring */ ++ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ ++ uint rxdalloc; /* #bytes allocated for the ring */ + -+ /* -+ * Walk the chain of packet buffers -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ data = PKTDATA(di->osh, p); -+ len = PKTLEN(di->osh, p); -+ next = PKTNEXT(di->osh, p); ++ /* tunables */ ++ uint rxbufsize; /* rx buffer size in bytes, ++ not including the extra headroom ++ */ ++ uint nrxpost; /* # rx buffers to keep posted */ ++ uint rxoffset; /* rxcontrol offset */ ++ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ ++ uint ddoffsethigh; /* high 32 bits */ ++ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ ++ uint dataoffsethigh; /* high 32 bits */ ++} dma_info_t; + -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) -+ goto outoftxd; ++/* descriptor bumping macros */ ++#define XXD(x, n) ((x) & ((n) - 1)) /* faster than %, but n must be power of 2 */ ++#define TXD(x) XXD((x), di->ntxd) ++#define RXD(x) XXD((x), di->nrxd) ++#define NEXTTXD(i) TXD(i + 1) ++#define PREVTXD(i) TXD(i - 1) ++#define NEXTRXD(i) RXD(i + 1) ++#define NTXDACTIVE(h, t) TXD(t - h) ++#define NRXDACTIVE(h, t) RXD(t - h) + -+ if (len == 0) -+ continue; ++/* macros to convert between byte offsets and indexes */ ++#define B2I(bytes, type) ((bytes) / sizeof(type)) ++#define I2B(index, type) ((index) * sizeof(type)) + -+ /* get physical address of buffer start */ -+ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ ++#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */ + -+ flags = coreflags; -+ -+ if (p == p0) -+ flags |= D64_CTRL1_SOF; -+ if (next == NULL) -+ flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); -+ if (txout == (di->ntxd - 1)) -+ flags |= D64_CTRL1_EOT; + -+ dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); ++/* common prototypes */ ++static bool _dma_isaddrext(dma_info_t *di); ++static bool dma32_alloc(dma_info_t *di, uint direction); ++static void _dma_detach(dma_info_t *di); ++static void _dma_ddtable_init(dma_info_t *di, uint direction, ulong pa); ++static void _dma_rxinit(dma_info_t *di); ++static void *_dma_rx(dma_info_t *di); ++static void _dma_rxfill(dma_info_t *di); ++static void _dma_rxreclaim(dma_info_t *di); ++static void _dma_rxenable(dma_info_t *di); ++static void * _dma_getnextrxp(dma_info_t *di, bool forceall); ++ ++static void _dma_txblock(dma_info_t *di); ++static void _dma_txunblock(dma_info_t *di); ++static uint _dma_txactive(dma_info_t *di); ++ ++static void* _dma_peeknexttxp(dma_info_t *di); ++static uintptr _dma_getvar(dma_info_t *di, char *name); ++static void _dma_counterreset(dma_info_t *di); ++static void _dma_fifoloopbackenable(dma_info_t *di); ++ ++/* ** 32 bit DMA prototypes */ ++static bool dma32_alloc(dma_info_t *di, uint direction); ++static bool dma32_txreset(dma_info_t *di); ++static bool dma32_rxreset(dma_info_t *di); ++static bool dma32_txsuspendedidle(dma_info_t *di); ++static int dma32_txfast(dma_info_t *di, void *p0, bool commit); ++static void *dma32_getnexttxp(dma_info_t *di, bool forceall); ++static void *dma32_getnextrxp(dma_info_t *di, bool forceall); ++static void dma32_txrotate(dma_info_t *di); ++static bool dma32_rxidle(dma_info_t *di); ++static void dma32_txinit(dma_info_t *di); ++static bool dma32_txenabled(dma_info_t *di); ++static void dma32_txsuspend(dma_info_t *di); ++static void dma32_txresume(dma_info_t *di); ++static bool dma32_txsuspended(dma_info_t *di); ++static void dma32_txreclaim(dma_info_t *di, bool forceall); ++static bool dma32_txstopped(dma_info_t *di); ++static bool dma32_rxstopped(dma_info_t *di); ++static bool dma32_rxenabled(dma_info_t *di); ++static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs); ++ ++ ++static di_fcn_t dma32proc = { ++ (di_detach_t)_dma_detach, ++ (di_txinit_t)dma32_txinit, ++ (di_txreset_t)dma32_txreset, ++ (di_txenabled_t)dma32_txenabled, ++ (di_txsuspend_t)dma32_txsuspend, ++ (di_txresume_t)dma32_txresume, ++ (di_txsuspended_t)dma32_txsuspended, ++ (di_txsuspendedidle_t)dma32_txsuspendedidle, ++ (di_txfast_t)dma32_txfast, ++ (di_txstopped_t)dma32_txstopped, ++ (di_txreclaim_t)dma32_txreclaim, ++ (di_getnexttxp_t)dma32_getnexttxp, ++ (di_peeknexttxp_t)_dma_peeknexttxp, ++ (di_txblock_t)_dma_txblock, ++ (di_txunblock_t)_dma_txunblock, ++ (di_txactive_t)_dma_txactive, ++ (di_txrotate_t)dma32_txrotate, ++ ++ (di_rxinit_t)_dma_rxinit, ++ (di_rxreset_t)dma32_rxreset, ++ (di_rxidle_t)dma32_rxidle, ++ (di_rxstopped_t)dma32_rxstopped, ++ (di_rxenable_t)_dma_rxenable, ++ (di_rxenabled_t)dma32_rxenabled, ++ (di_rx_t)_dma_rx, ++ (di_rxfill_t)_dma_rxfill, ++ (di_rxreclaim_t)_dma_rxreclaim, ++ (di_getnextrxp_t)_dma_getnextrxp, ++ ++ (di_fifoloopbackenable_t)_dma_fifoloopbackenable, ++ (di_getvar_t)_dma_getvar, ++ (di_counterreset_t)_dma_counterreset, ++ ++ NULL, ++ NULL, ++ NULL, ++ 34 ++}; + -+ ASSERT(di->txp[txout] == NULL); ++hnddma_t * ++dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) ++{ ++ dma_info_t *di; ++ uint size; + -+ txout = NEXTTXD(txout); ++ /* allocate private info structure */ ++ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { ++ return (NULL); + } ++ bzero((char *)di, sizeof(dma_info_t)); + -+ /* if last txd eof not set, fix it */ -+ if (!(flags & D64_CTRL1_EOF)) -+ W_SM(&di->txd64[PREVTXD(txout)].ctrl1, BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); -+ -+ /* save the packet */ -+ di->txp[PREVTXD(txout)] = p0; ++ di->msg_level = msg_level ? msg_level : &dma_msg_level; + -+ /* bump the tx descriptor index */ -+ di->txout = txout; ++ /* old chips w/o sb is no longer supported */ ++ ASSERT(sbh != NULL); + -+ /* kick the chip */ -+ W_REG(&di->d64txregs->ptr, I2B(txout, dma64dd_t)); ++ /* check arguments */ ++ ASSERT(ISPOWEROF2(ntxd)); ++ ASSERT(ISPOWEROF2(nrxd)); ++ if (nrxd == 0) ++ ASSERT(dmaregsrx == NULL); ++ if (ntxd == 0) ++ ASSERT(dmaregstx == NULL); + -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+ return (0); ++ /* init dma reg pointer */ ++ ASSERT(ntxd <= D32MAXDD); ++ ASSERT(nrxd <= D32MAXDD); ++ di->d32txregs = (dma32regs_t *)dmaregstx; ++ di->d32rxregs = (dma32regs_t *)dmaregsrx; + -+outoftxd: -+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); -+ PKTFREE(di->osh, p0, TRUE); -+ di->txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); -+} ++ DMA_TRACE(("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d " ++ "rxoffset %d dmaregstx %p dmaregsrx %p\n", ++ name, "DMA32", osh, ntxd, nrxd, rxbufsize, ++ nrxpost, rxoffset, dmaregstx, dmaregsrx)); + -+static void* -+dma64_getnexttxp(dma_info_t *di, bool forceall) -+{ -+ uint start, end, i; -+ void *txp; ++ /* make a private copy of our callers name */ ++ strncpy(di->name, name, MAXNAMEL); ++ di->name[MAXNAMEL-1] = '\0'; + -+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); ++ di->osh = osh; ++ di->sbh = sbh; + -+ txp = NULL; ++ /* save tunables */ ++ di->ntxd = ntxd; ++ di->nrxd = nrxd; + -+ start = di->txin; -+ if (forceall) -+ end = di->txout; ++ /* the actual dma size doesn't include the extra headroom */ ++ if (rxbufsize > BCMEXTRAHDROOM) ++ di->rxbufsize = rxbufsize - BCMEXTRAHDROOM; + else -+ end = B2I(R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK, dma64dd_t); ++ di->rxbufsize = rxbufsize; + -+ if ((start == 0) && (end > di->txout)) -+ goto bogus; ++ di->nrxpost = nrxpost; ++ di->rxoffset = rxoffset; + -+ for (i = start; i != end && !txp; i = NEXTTXD(i)) { -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - di->dataoffsetlow), -+ (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & D64_CTRL2_BC_MASK), DMA_TX, di->txp[i]); ++ /* ++ * figure out the DMA physical address offset for dd and data ++ * for old chips w/o sb, use zero ++ * for new chips w sb, ++ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset ++ * Other bus: use zero ++ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor ++ */ ++ di->ddoffsetlow = 0; ++ di->dataoffsetlow = 0; ++ /* for pci bus, add offset */ ++ if (sbh->bustype == PCI_BUS) { ++ di->ddoffsetlow = SB_PCI_DMA; ++ di->ddoffsethigh = 0; ++ di->dataoffsetlow = di->ddoffsetlow; ++ di->dataoffsethigh = di->ddoffsethigh; ++ } + -+ W_SM(&di->txd64[i].addrlow, 0xdeadbeef); -+ W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); ++#if defined(__mips__) && defined(IL_BIGENDIAN) ++ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; ++#endif + -+ txp = di->txp[i]; -+ di->txp[i] = NULL; -+ } ++ di->addrext = _dma_isaddrext(di); + -+ di->txin = i; ++ /* allocate tx packet pointer vector */ ++ if (ntxd) { ++ size = ntxd * sizeof(void *); ++ if ((di->txp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", ++ di->name, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero((char *)di->txp, size); ++ } + -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ /* allocate rx packet pointer vector */ ++ if (nrxd) { ++ size = nrxd * sizeof(void *); ++ if ((di->rxp = MALLOC(osh, size)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", ++ di->name, MALLOCED(osh))); ++ goto fail; ++ } ++ bzero((char *)di->rxp, size); ++ } + -+ return (txp); ++ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ ++ if (ntxd) { ++ if (!dma32_alloc(di, DMA_TX)) ++ goto fail; ++ } + -+bogus: -+/* -+ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", -+ start, end, di->txout, forceall)); -+*/ -+ return (NULL); -+} ++ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ ++ if (nrxd) { ++ if (!dma32_alloc(di, DMA_RX)) ++ goto fail; ++ } + -+static void * -+dma64_getnextrxp(dma_info_t *di, bool forceall) -+{ -+ uint i; -+ void *rxp; ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", ++ di->name, di->txdpa)); ++ goto fail; ++ } ++ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { ++ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", ++ di->name, di->rxdpa)); ++ goto fail; ++ } + -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma_rxenabled(di)); ++ DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " ++ "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, ++ di->dataoffsethigh, di->addrext)); + -+ i = di->rxin; ++ /* allocate tx packet pointer vector and DMA mapping vectors */ ++ if (ntxd) { + -+ /* return if no packets posted */ -+ if (i == di->rxout) -+ return (NULL); ++ size = ntxd * sizeof(osldma_t **); ++ if ((di->txp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) ++ goto fail; ++ bzero((char*)di->txp_dmah, size); ++ }else ++ di->txp_dmah = NULL; + -+ /* ignore curr if forceall */ -+ if (!forceall && (i == B2I(R_REG(&di->d64rxregs->status0) & D64_RS0_CD_MASK, dma64dd_t))) -+ return (NULL); ++ /* allocate rx packet pointer vector and DMA mapping vectors */ ++ if (nrxd) { + -+ /* get the packet pointer that corresponds to the rx descriptor */ -+ rxp = di->rxp[i]; -+ ASSERT(rxp); -+ di->rxp[i] = NULL; ++ size = nrxd * sizeof(osldma_t **); ++ if ((di->rxp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) ++ goto fail; ++ bzero((char*)di->rxp_dmah, size); + -+ /* clear this packet from the descriptor ring */ -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - di->dataoffsetlow), -+ di->rxbufsize, DMA_RX, rxp); ++ } else ++ di->rxp_dmah = NULL; + -+ W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); -+ W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); ++ /* initialize opsvec of function pointers */ ++ di->hnddma.di_fn = dma32proc; + -+ di->rxin = NEXTRXD(i); ++ return ((hnddma_t *)di); + -+ return (rxp); ++fail: ++ _dma_detach(di); ++ return (NULL); +} + -+static void -+dma64_txrotate(di_t *di) ++/* init the tx or rx descriptor */ ++static INLINE void ++dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *flags, ++ uint32 bufcount) +{ -+ uint ad; -+ uint nactive; -+ uint rot; -+ uint old, new; -+ uint32 w; -+ uint first, last; ++ /* dma32 uses 32 bits control to fit both flags and bufcounter */ ++ *flags = *flags | (bufcount & CTRL_BC_MASK); + -+ ASSERT(dma_txsuspendedidle(di)); -+ -+ nactive = dma_txactive(di); -+ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t); -+ rot = TXD(ad - di->txin); -+ -+ ASSERT(rot < di->ntxd); ++ if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); ++ } else { ++ /* address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ pa &= ~PCI32ADDR_HIGH; + -+ /* full-ring case is a lot harder - don't worry about this */ -+ if (rot >= (di->ntxd - nactive)) { -+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); -+ return; ++ *flags |= (ae << CTRL_AE_SHIFT); ++ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); ++ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); + } ++} + -+ first = di->txin; -+ last = PREVTXD(di->txout); ++static bool ++_dma32_addrext(osl_t *osh, dma32regs_t *dma32regs) ++{ ++ uint32 w; + -+ /* move entries starting at last and moving backwards to first */ -+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { -+ new = TXD(old + rot); ++ OR_REG(osh, &dma32regs->control, XC_AE); ++ w = R_REG(osh, &dma32regs->control); ++ AND_REG(osh, &dma32regs->control, ~XC_AE); ++ return ((w & XC_AE) == XC_AE); ++} + -+ /* -+ * Move the tx dma descriptor. -+ * EOT is set only in the last entry in the ring. -+ */ -+ w = R_SM(&di->txd64[old].ctrl1) & ~D64_CTRL1_EOT; -+ if (new == (di->ntxd - 1)) -+ w |= D64_CTRL1_EOT; -+ W_SM(&di->txd64[new].ctrl1, w); ++/* !! may be called with core in reset */ ++static void ++_dma_detach(dma_info_t *di) ++{ ++ if (di == NULL) ++ return; + -+ w = R_SM(&di->txd64[old].ctrl2); -+ W_SM(&di->txd64[new].ctrl2, w); ++ DMA_TRACE(("%s: dma_detach\n", di->name)); + -+ W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); -+ W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); ++ /* shouldn't be here if descriptors are unreclaimed */ ++ ASSERT(di->txin == di->txout); ++ ASSERT(di->rxin == di->rxout); + -+ /* zap the old tx dma descriptor address field */ -+ W_SM(&di->txd64[old].addrlow, 0xdeadbeef); -+ W_SM(&di->txd64[old].addrhigh, 0xdeadbeef); ++ /* free dma descriptor rings */ ++ if (di->txd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), ++ di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah); ++ if (di->rxd32) ++ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), ++ di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah); + -+ /* move the corresponding txp[] entry */ -+ ASSERT(di->txp[new] == NULL); -+ di->txp[new] = di->txp[old]; -+ di->txp[old] = NULL; -+ } ++ /* free packet pointer vectors */ ++ if (di->txp) ++ MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *))); ++ if (di->rxp) ++ MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *))); + -+ /* update txin and txout */ -+ di->txin = ad; -+ di->txout = TXD(di->txout + rot); -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ /* free tx packet DMA handles */ ++ if (di->txp_dmah) ++ MFREE(di->osh, (void *)di->txp_dmah, di->ntxd * sizeof(osldma_t **)); + -+ /* kick the chip */ -+ W_REG(&di->d64txregs->ptr, I2B(di->txout, dma64dd_t)); -+} ++ /* free rx packet DMA handles */ ++ if (di->rxp_dmah) ++ MFREE(di->osh, (void *)di->rxp_dmah, di->nrxd * sizeof(osldma_t **)); + -+#endif ++ /* free our private info structure */ ++ MFREE(di->osh, (void *)di, sizeof(dma_info_t)); + -diff -Naur linux.old/drivers/net/wl2/hnddma.h linux.dev/drivers/net/wl2/hnddma.h ---- linux.old/drivers/net/wl2/hnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl2/hnddma.h 2006-04-06 16:32:44.000000000 +0200 -@@ -0,0 +1,71 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ ++} + -+#ifndef _hnddma_h_ -+#define _hnddma_h_ ++/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ ++static bool ++_dma_isaddrext(dma_info_t *di) ++{ ++ if (di->d32txregs) ++ return (_dma32_addrext(di->osh, di->d32txregs)); ++ else if (di->d32rxregs) ++ return (_dma32_addrext(di->osh, di->d32rxregs)); ++ return FALSE; ++} + -+/* export structure */ -+typedef volatile struct { -+ /* rx error counters */ -+ uint rxgiants; /* rx giant frames */ -+ uint rxnobuf; /* rx out of dma descriptors */ -+ /* tx error counters */ -+ uint txnobuf; /* tx out of dma descriptors */ -+} hnddma_t; ++/* initialize descriptor table base address */ ++static void ++_dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) ++{ ++ if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { ++ if (direction == DMA_TX) ++ W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); ++ else ++ W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); ++ } else { ++ /* dma32 address extension */ ++ uint32 ae; ++ ASSERT(di->addrext); + -+#ifndef di_t -+#define di_t void -+#endif ++ /* shift the high bit(s) from pa to ae */ ++ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; ++ pa &= ~PCI32ADDR_HIGH; + -+#ifndef osl_t -+#define osl_t void -+#endif ++ if (direction == DMA_TX) { ++ W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); ++ SET_REG(di->osh, &di->d32txregs->control, XC_AE, ae <osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); ++ SET_REG(di->osh, &di->d32rxregs->control, RC_AE, ae <name)); ++ OR_REG(di->osh, &di->d32txregs->control, XC_LE); ++} + ++static void ++_dma_rxinit(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxinit\n", di->name)); + -+#endif /* _hnddma_h_ */ -diff -Naur linux.old/drivers/net/wl2/pktq.h linux.dev/drivers/net/wl2/pktq.h ---- linux.old/drivers/net/wl2/pktq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl2/pktq.h 2006-04-06 17:33:02.000000000 +0200 -@@ -0,0 +1,83 @@ -+/* -+ * Misc useful os-independent macros and functions. -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ ++ if (di->nrxd == 0) ++ return; + -+#ifndef _pktq_h_ -+#define _pktq_h_ ++ di->rxin = di->rxout = 0; + -+/*** driver-only section ***/ -+#ifdef BCMDRIVER ++ /* clear rx descriptor ring */ ++ BZERO_SM((void *)di->rxd32, (di->nrxd * sizeof(dma32dd_t))); ++ _dma_rxenable(di); ++ _dma_ddtable_init(di, DMA_RX, di->rxdpa); ++} + -+/* osl packet chain functions */ -+extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); -+extern uint pkttotlen(osl_t *osh, void *); ++static void ++_dma_rxenable(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_rxenable\n", di->name)); + -+#define pktenq(pq, p) pktq_penq((pq), 0, (p)) /* legacy */ -+#define pktdeq(pq) pktq_pdeq((pq), 0) /* legacy */ ++ W_REG(di->osh, &di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); ++} + -+/* osl multi-precedence packet queue */ ++/* !! rx entry routine, returns a pointer to the next frame received, ++ * or NULL if there are no more ++ */ ++static void * ++_dma_rx(dma_info_t *di) ++{ ++ void *p; ++ uint len; ++ int skiplen = 0; + -+#define PKTQ_LEN_DEFAULT 128 -+#define PKTQ_MAX_PREC 8 -+struct pktq_prec { -+ void *head; /* first packet to dequeue */ -+ void *tail; /* last packet to dequeue */ -+ uint16 len; /* number of queued packets */ -+ uint16 max; /* maximum number of queued packets */ -+}; ++ while ((p = _dma_getnextrxp(di, FALSE))) { ++ /* skip giant packets which span multiple rx descriptors */ ++ if (skiplen > 0) { ++ skiplen -= di->rxbufsize; ++ if (skiplen < 0) ++ skiplen = 0; ++ PKTFREE(di->osh, p, FALSE); ++ continue; ++ } + -+struct pktq { -+ struct pktq_prec q[PKTQ_MAX_PREC]; -+ uint16 num_prec; /* number of precedences in use */ -+ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ -+ uint16 max; /* total max packets */ -+ uint16 len; /* total number of packets */ -+}; ++ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); ++ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); + -+/* operations on a specific precedence in packet queue */ ++ /* bad frame length check */ ++ if (len > (di->rxbufsize - di->rxoffset)) { ++ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); ++ if (len > 0) ++ skiplen = len - (di->rxbufsize - di->rxoffset); ++ PKTFREE(di->osh, p, FALSE); ++ di->hnddma.rxgiants++; ++ continue; ++ } + -+#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) -+#define pktq_plen(pq, prec) ((pq)->q[prec].len) -+#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) -+#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) -+#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) ++ /* set actual length */ ++ PKTSETLEN(di->osh, p, (di->rxoffset + len)); + -+#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) -+#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) ++ break; ++ } + -+extern void *pktq_penq(struct pktq *pq, int prec, void *p); -+extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); -+extern void *pktq_pdeq(struct pktq *pq, int prec); -+extern void *pktq_pdeq_tail(struct pktq *pq, int prec); ++ return (p); ++} + -+/* operations on packet queue as a whole */ ++/* post receive buffers */ ++static void ++_dma_rxfill(dma_info_t *di) ++{ ++ void *p; ++ uint rxin, rxout; ++ uint32 flags = 0; ++ uint n; ++ uint i; ++ uint32 pa; ++ uint extra_offset = 0; + -+extern void pktq_init(struct pktq *pq, int num_prec, int max); ++ /* ++ * Determine how many receive buffers we're lacking ++ * from the full complement, allocate, initialize, ++ * and post them, then update the chip rx lastdscr. ++ */ + -+#define pktq_len(pq) ((int)(pq)->len) -+#define pktq_max(pq) ((int)(pq)->max) -+#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) -+#define pktq_full(pq) ((pq)->len >= (pq)->max) -+#define pktq_empty(pq) ((pq)->len == 0) ++ rxin = di->rxin; ++ rxout = di->rxout; + -+extern void *pktq_deq(struct pktq *pq, int *prec_out); -+extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); -+extern void *pktq_peek(struct pktq *pq, int *prec_out); -+extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); ++ n = di->nrxpost - NRXDACTIVE(rxin, rxout); + -+extern int pktq_mlen(struct pktq *pq, uint prec_bmp); -+extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); ++ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); + -+#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) ++ if (di->rxbufsize > BCMEXTRAHDROOM) ++ extra_offset = BCMEXTRAHDROOM; + -+#endif -+#endif /* _pktq_h_ */ -diff -Naur linux.old/drivers/net/wl2/sbhnddma.h linux.dev/drivers/net/wl2/sbhnddma.h ---- linux.old/drivers/net/wl2/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl2/sbhnddma.h 2006-04-06 16:32:44.000000000 +0200 -@@ -0,0 +1,312 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ -+ */ ++ for (i = 0; i < n; i++) { ++ /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the ++ size to be allocated ++ */ ++ if ((p = PKTGET(di->osh, di->rxbufsize + extra_offset, ++ FALSE)) == NULL) { ++ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); ++ di->hnddma.rxnobuf++; ++ break; ++ } ++ /* reserve an extra headroom, if applicable */ ++ if (extra_offset) ++ PKTPULL(di->osh, p, extra_offset); + -+#ifndef _sbhnddma_h_ -+#define _sbhnddma_h_ ++ /* Do a cached write instead of uncached write since DMA_MAP ++ * will flush the cache. ++ */ ++ *(uint32*)(PKTDATA(di->osh, p)) = 0; + -+ -+/* 2byte-wide pio register set per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint16 fifocontrol; -+ uint16 fifodata; -+ uint16 fifofree; /* only valid in xmt channel, not in rcv channel */ -+ uint16 PAD; -+} pio2regs_t; ++ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), ++ di->rxbufsize, DMA_RX, p); + -+/* a pair of pio channels(tx and rx) */ -+typedef volatile struct { -+ pio2regs_t tx; -+ pio2regs_t rx; -+} pio2regp_t; ++ ASSERT(ISALIGNED(pa, 4)); + -+/* 4byte-wide pio register set per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 fifocontrol; -+ uint32 fifodata; -+} pio4regs_t; ++ /* save the free packet pointer */ ++ ASSERT(di->rxp[rxout] == NULL); ++ di->rxp[rxout] = p; + -+/* a pair of pio channels(tx and rx) */ -+typedef volatile struct { -+ pio4regs_t tx; -+ pio4regs_t rx; -+} pio4regp_t; ++ /* reset flags for each descriptor */ ++ flags = 0; ++ if (rxout == (di->nrxd - 1)) ++ flags = CTRL_EOT; ++ dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, di->rxbufsize); ++ rxout = NEXTRXD(rxout); ++ } + ++ di->rxout = rxout; + ++ /* update the chip lastdscr pointer */ ++ W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); ++} + -+/* DMA structure: -+ * support two DMA engines: 32 bits address or 64 bit addressing -+ * basic DMA register set is per channel(transmit or receive) -+ * a pair of channels is defined for convenience -+ */ ++/* like getnexttxp but no reclaim */ ++static void * ++_dma_peeknexttxp(dma_info_t *di) ++{ ++ uint end, i; + ++ if (di->ntxd == 0) ++ return (NULL); + -+/*** 32 bits addressing ***/ ++ end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); + -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 addr; /* descriptor ring base address (4K aligned) */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 status; /* current active descriptor, et al */ -+} dma32regs_t; ++ for (i = di->txin; i != end; i = NEXTTXD(i)) ++ if (di->txp[i]) ++ return (di->txp[i]); + -+typedef volatile struct { -+ dma32regs_t xmt; /* dma tx channel */ -+ dma32regs_t rcv; /* dma rx channel */ -+} dma32regp_t; ++ return (NULL); ++} + -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma32diag_t; ++static void ++_dma_rxreclaim(dma_info_t *di) ++{ ++ void *p; + -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl; /* misc control bits & bufcount */ -+ uint32 addr; /* data buffer address */ -+} dma32dd_t; ++ /* "unused local" warning suppression for OSLs that ++ * define PKTFREE() without using the di->osh arg ++ */ ++ di = di; + -+/* -+ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. -+ */ -+#define D32MAXRINGSZ 4096 -+#define D32RINGALIGN 4096 -+#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) ++ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); + -+/* transmit channel control */ -+#define XC_XE ((uint32)1 << 0) /* transmit enable */ -+#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ -+#define XC_LE ((uint32)1 << 2) /* loopback enable */ -+#define XC_FL ((uint32)1 << 4) /* flush request */ -+#define XC_AE ((uint32)3 << 16) /* address extension bits */ -+#define XC_AE_SHIFT 16 ++ while ((p = _dma_getnextrxp(di, TRUE))) ++ PKTFREE(di->osh, p, FALSE); ++} + -+/* transmit descriptor table pointer */ -+#define XP_LD_MASK 0xfff /* last valid descriptor */ ++static void * ++_dma_getnextrxp(dma_info_t *di, bool forceall) ++{ ++ if (di->nrxd == 0) ++ return (NULL); + -+/* transmit channel status */ -+#define XS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define XS_XS_MASK 0xf000 /* transmit state */ -+#define XS_XS_SHIFT 12 -+#define XS_XS_DISABLED 0x0000 /* disabled */ -+#define XS_XS_ACTIVE 0x1000 /* active */ -+#define XS_XS_IDLE 0x2000 /* idle wait */ -+#define XS_XS_STOPPED 0x3000 /* stopped */ -+#define XS_XS_SUSP 0x4000 /* suspend pending */ -+#define XS_XE_MASK 0xf0000 /* transmit errors */ -+#define XS_XE_SHIFT 16 -+#define XS_XE_NOERR 0x00000 /* no error */ -+#define XS_XE_DPE 0x10000 /* descriptor protocol error */ -+#define XS_XE_DFU 0x20000 /* data fifo underrun */ -+#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ -+#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ -+#define XS_AD_MASK 0xfff00000 /* active descriptor */ -+#define XS_AD_SHIFT 20 ++ return dma32_getnextrxp(di, forceall); ++} + -+/* receive channel control */ -+#define RC_RE ((uint32)1 << 0) /* receive enable */ -+#define RC_RO_MASK 0xfe /* receive frame offset */ -+#define RC_RO_SHIFT 1 -+#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ -+#define RC_AE ((uint32)3 << 16) /* address extension bits */ -+#define RC_AE_SHIFT 16 ++static void ++_dma_txblock(dma_info_t *di) ++{ ++ di->hnddma.txavail = 0; ++} + -+/* receive descriptor table pointer */ -+#define RP_LD_MASK 0xfff /* last valid descriptor */ ++static void ++_dma_txunblock(dma_info_t *di) ++{ ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++} + -+/* receive channel status */ -+#define RS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define RS_RS_MASK 0xf000 /* receive state */ -+#define RS_RS_SHIFT 12 -+#define RS_RS_DISABLED 0x0000 /* disabled */ -+#define RS_RS_ACTIVE 0x1000 /* active */ -+#define RS_RS_IDLE 0x2000 /* idle wait */ -+#define RS_RS_STOPPED 0x3000 /* reserved */ -+#define RS_RE_MASK 0xf0000 /* receive errors */ -+#define RS_RE_SHIFT 16 -+#define RS_RE_NOERR 0x00000 /* no error */ -+#define RS_RE_DPE 0x10000 /* descriptor protocol error */ -+#define RS_RE_DFO 0x20000 /* data fifo overflow */ -+#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ -+#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ -+#define RS_AD_MASK 0xfff00000 /* active descriptor */ -+#define RS_AD_SHIFT 20 ++static uint ++_dma_txactive(dma_info_t *di) ++{ ++ return (NTXDACTIVE(di->txin, di->txout)); ++} ++ ++static void ++_dma_counterreset(dma_info_t *di) ++{ ++ /* reset all software counter */ ++ di->hnddma.rxgiants = 0; ++ di->hnddma.rxnobuf = 0; ++ di->hnddma.txnobuf = 0; ++} ++ ++/* get the address of the var in order to change later */ ++static uintptr ++_dma_getvar(dma_info_t *di, char *name) ++{ ++ if (!strcmp(name, "&txavail")) ++ return ((uintptr) &(di->hnddma.txavail)); ++ else { ++ ASSERT(0); ++ } ++ return (0); ++} + -+/* fifoaddr */ -+#define FA_OFF_MASK 0xffff /* offset */ -+#define FA_SEL_MASK 0xf0000 /* select */ -+#define FA_SEL_SHIFT 16 -+#define FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define FA_SEL_RDD 0x40000 /* receive dma data */ -+#define FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++void ++dma_txpioloopback(osl_t *osh, dma32regs_t *regs) ++{ ++ OR_REG(osh, ®s->control, XC_LE); ++} + -+/* descriptor control flags */ -+#define CTRL_BC_MASK 0x1fff /* buffer byte count */ -+#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ -+#define CTRL_AE_SHIFT 16 -+#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ -+#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ + -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define CTRL_CORE_MASK 0x0ff00000 + -+/*** 64 bits addressing ***/ ++/* 32 bits DMA functions */ ++static void ++dma32_txinit(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txinit\n", di->name)); + -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ -+ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ -+ uint32 status0; /* current descriptor, xmt state */ -+ uint32 status1; /* active descriptor, xmt error */ -+} dma64regs_t; ++ if (di->ntxd == 0) ++ return; + -+typedef volatile struct { -+ dma64regs_t tx; /* dma64 tx channel */ -+ dma64regs_t rx; /* dma64 rx channel */ -+} dma64regp_t; ++ di->txin = di->txout = 0; ++ di->hnddma.txavail = di->ntxd - 1; + -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma64diag_t; ++ /* clear tx descriptor ring */ ++ BZERO_SM((void *)di->txd32, (di->ntxd * sizeof(dma32dd_t))); ++ W_REG(di->osh, &di->d32txregs->control, XC_XE); ++ _dma_ddtable_init(di, DMA_TX, di->txdpa); ++} + -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl1; /* misc control bits & bufcount */ -+ uint32 ctrl2; /* buffer count and address extension */ -+ uint32 addrlow; /* memory address of the first byte of the date buffer, bits 31:0 */ -+ uint32 addrhigh; /* memory address of the first byte of the date buffer, bits 63:32 */ -+} dma64dd_t; ++static bool ++dma32_txenabled(dma_info_t *di) ++{ ++ uint32 xc; + -+/* -+ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. -+ */ -+#define D64MAXRINGSZ 8192 -+#define D64RINGALIGN 8192 -+#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) ++ /* If the chip is dead, it is not enabled :-) */ ++ xc = R_REG(di->osh, &di->d32txregs->control); ++ return ((xc != 0xffffffff) && (xc & XC_XE)); ++} + -+/* transmit channel control */ -+#define D64_XC_XE 0x00000001 /* transmit enable */ -+#define D64_XC_SE 0x00000002 /* transmit suspend request */ -+#define D64_XC_LE 0x00000004 /* loopback enable */ -+#define D64_XC_FL 0x00000010 /* flush request */ -+#define D64_XC_AE 0x00110000 /* address extension bits */ -+#define D64_XC_AE_SHIFT 16 ++static void ++dma32_txsuspend(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); + -+/* transmit descriptor table pointer */ -+#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ ++ if (di->ntxd == 0) ++ return; + -+/* transmit channel status */ -+#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ -+#define D64_XS0_XS_SHIFT 28 -+#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ -+#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ -+#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ -+#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ -+#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ ++ OR_REG(di->osh, &di->d32txregs->control, XC_SE); ++} + -+#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ -+#define D64_XS1_XE_SHIFT 28 -+#define D64_XS1_XE_NOERR 0x00000000 /* no error */ -+#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ -+#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ -+#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ -+#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_XS1_XE_COREE 0x50000000 /* core error */ ++static void ++dma32_txresume(dma_info_t *di) ++{ ++ DMA_TRACE(("%s: dma_txresume\n", di->name)); + -+/* receive channel control */ -+#define D64_RC_RE 0x00000001 /* receive enable */ -+#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ -+#define D64_RC_RO_SHIFT 1 -+#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ -+#define D64_RC_AE 0x00110000 /* address extension bits */ -+#define D64_RC_AE_SHIFT 16 ++ if (di->ntxd == 0) ++ return; + -+/* receive descriptor table pointer */ -+#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ ++ AND_REG(di->osh, &di->d32txregs->control, ~XC_SE); ++} + -+/* receive channel status */ -+#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ -+#define D64_RS0_RS_SHIFT 28 -+#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ -+#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ -+#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ -+#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ -+#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ ++static bool ++dma32_txsuspended(dma_info_t *di) ++{ ++ return (di->ntxd == 0) || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE); ++} + -+#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ -+#define D64_RS1_RE_SHIFT 28 -+#define D64_RS1_RE_NOERR 0x00000000 /* no error */ -+#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ -+#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ -+#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ -+#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_RS1_RE_COREE 0x50000000 /* core error */ ++static void ++dma32_txreclaim(dma_info_t *di, bool forceall) ++{ ++ void *p; + -+/* fifoaddr */ -+#define D64_FA_OFF_MASK 0xffff /* offset */ -+#define D64_FA_SEL_MASK 0xf0000 /* select */ -+#define D64_FA_SEL_SHIFT 16 -+#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ -+#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); + -+/* descriptor control flags 1 */ -+#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ -+#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ ++ while ((p = dma32_getnexttxp(di, forceall))) ++ PKTFREE(di->osh, p, TRUE); ++} + -+/* descriptor control flags 2 */ -+#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ -+#define D64_CTRL2_AE 0x00110000 /* address extension bits */ -+#define D64_CTRL2_AE_SHIFT 16 ++static bool ++dma32_txstopped(dma_info_t *di) ++{ ++ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); ++} + -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define D64_CTRL_CORE_MASK 0x0ff00000 ++static bool ++dma32_rxstopped(dma_info_t *di) ++{ ++ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); ++} + ++static bool ++dma32_alloc(dma_info_t *di, uint direction) ++{ ++ uint size; ++ uint ddlen; ++ void *va; + -+#endif /* _sbhnddma_h_ */ -diff -Naur linux.old/drivers/parport/Config.in linux.dev/drivers/parport/Config.in ---- linux.old/drivers/parport/Config.in 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/drivers/parport/Config.in 2006-04-06 15:34:15.000000000 +0200 -@@ -11,6 +11,7 @@ - tristate 'Parallel port support' CONFIG_PARPORT - if [ "$CONFIG_PARPORT" != "n" ]; then - dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT -+ dep_tristate ' Asus WL500g parallel port' CONFIG_PARPORT_SPLINK $CONFIG_PARPORT - if [ "$CONFIG_PARPORT_PC" != "n" -a "$CONFIG_SERIAL" != "n" ]; then - if [ "$CONFIG_SERIAL" = "m" ]; then - define_tristate CONFIG_PARPORT_PC_CML1 m -diff -Naur linux.old/drivers/parport/Makefile linux.dev/drivers/parport/Makefile ---- linux.old/drivers/parport/Makefile 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/drivers/parport/Makefile 2006-04-06 15:34:15.000000000 +0200 -@@ -22,6 +22,7 @@ - - obj-$(CONFIG_PARPORT) += parport.o - obj-$(CONFIG_PARPORT_PC) += parport_pc.o -+obj-$(CONFIG_PARPORT_SPLINK) += parport_splink.o - obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o - obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o - obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o -diff -Naur linux.old/drivers/parport/parport_splink.c linux.dev/drivers/parport/parport_splink.c ---- linux.old/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/parport/parport_splink.c 2006-04-06 15:34:15.000000000 +0200 -@@ -0,0 +1,345 @@ -+/* Low-level parallel port routines for the ASUS WL-500g built-in port -+ * -+ * Author: Nuno Grilo -+ * Based on parport_pc source -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++ ddlen = sizeof(dma32dd_t); + -+#define SPLINK_ADDRESS 0xBF800010 ++ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); + -+#undef DEBUG ++ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) ++ size += D32RINGALIGN; + -+#ifdef DEBUG -+#define DPRINTK printk -+#else -+#define DPRINTK(stuff...) -+#endif + ++ if (direction == DMA_TX) { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa, &di->tx_dmah)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", ++ di->name)); ++ return FALSE; ++ } + -+/* __parport_splink_frob_control differs from parport_splink_frob_control in that -+ * it doesn't do any extra masking. */ -+static __inline__ unsigned char __parport_splink_frob_control (struct parport *p, -+ unsigned char mask, -+ unsigned char val) -+{ -+ struct parport_pc_private *priv = p->physport->private_data; -+ unsigned char *io = (unsigned char *) p->base; -+ unsigned char ctr = priv->ctr; -+#ifdef DEBUG_PARPORT -+ printk (KERN_DEBUG -+ "__parport_splink_frob_control(%02x,%02x): %02x -> %02x\n", -+ mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable); -+#endif -+ ctr = (ctr & ~mask) ^ val; -+ ctr &= priv->ctr_writable; /* only write writable bits. */ -+ *(io+2) = ctr; -+ priv->ctr = ctr; /* Update soft copy */ -+ return ctr; ++ di->txd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); ++ di->txdpa += di->txdalign; ++ di->txdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); ++ } else { ++ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa, &di->rx_dmah)) == NULL) { ++ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", ++ di->name)); ++ return FALSE; ++ } ++ di->rxd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); ++ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); ++ di->rxdpa += di->rxdalign; ++ di->rxdalloc = size; ++ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); ++ } ++ ++ return TRUE; +} + ++static bool ++dma32_txreset(dma_info_t *di) ++{ ++ uint32 status; + ++ if (di->ntxd == 0) ++ return TRUE; + -+static void parport_splink_data_forward (struct parport *p) -+{ -+ DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n"); -+ __parport_splink_frob_control (p, 0x20, 0); -+} ++ /* suspend tx DMA first */ ++ W_REG(di->osh, &di->d32txregs->control, XC_SE); ++ SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK)) ++ != XS_XS_DISABLED) && ++ (status != XS_XS_IDLE) && ++ (status != XS_XS_STOPPED), ++ (10000)); ++ ++ W_REG(di->osh, &di->d32txregs->control, 0); ++ SPINWAIT(((status = (R_REG(di->osh, ++ &di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED), ++ 10000); + -+static void parport_splink_data_reverse (struct parport *p) -+{ -+ DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n"); -+ __parport_splink_frob_control (p, 0x20, 0x20); -+} ++ /* wait for the last transaction to complete */ ++ OSL_DELAY(300); + -+/* -+static void parport_splink_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ DPRINTK(KERN_DEBUG "parport_splink: IRQ handler called\n"); -+ parport_generic_irq(irq, (struct parport *) dev_id, regs); ++ return (status == XS_XS_DISABLED); +} -+*/ + -+static void parport_splink_enable_irq(struct parport *p) ++static bool ++dma32_rxidle(dma_info_t *di) +{ -+ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_enable_irq called\n"); -+ __parport_splink_frob_control (p, 0x10, 0x10); ++ DMA_TRACE(("%s: dma_rxidle\n", di->name)); ++ ++ if (di->nrxd == 0) ++ return TRUE; ++ ++ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) == ++ R_REG(di->osh, &di->d32rxregs->ptr)); +} + -+static void parport_splink_disable_irq(struct parport *p) ++static bool ++dma32_rxreset(dma_info_t *di) +{ -+ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_disable_irq called\n"); -+ __parport_splink_frob_control (p, 0x10, 0); ++ uint32 status; ++ ++ if (di->nrxd == 0) ++ return TRUE; ++ ++ W_REG(di->osh, &di->d32rxregs->control, 0); ++ SPINWAIT(((status = (R_REG(di->osh, ++ &di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED), ++ 10000); ++ ++ return (status == RS_RS_DISABLED); +} + -+static void parport_splink_init_state(struct pardevice *dev, struct parport_state *s) ++static bool ++dma32_rxenabled(dma_info_t *di) +{ -+ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_init_state called\n"); -+ s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0); -+ if (dev->irq_func && -+ dev->port->irq != PARPORT_IRQ_NONE) -+ /* Set ackIntEn */ -+ s->u.pc.ctr |= 0x10; ++ uint32 rc; ++ ++ rc = R_REG(di->osh, &di->d32rxregs->control); ++ return ((rc != 0xffffffff) && (rc & RC_RE)); +} + -+static void parport_splink_save_state(struct parport *p, struct parport_state *s) ++static bool ++dma32_txsuspendedidle(dma_info_t *di) +{ -+ const struct parport_pc_private *priv = p->physport->private_data; -+ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_save_state called\n"); -+ s->u.pc.ctr = priv->ctr; ++ if (di->ntxd == 0) ++ return TRUE; ++ ++ if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE)) ++ return 0; ++ ++ if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) ++ return 0; ++ ++ OSL_DELAY(2); ++ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); +} + -+static void parport_splink_restore_state(struct parport *p, struct parport_state *s) ++/* !! tx entry routine ++ * supports full 32bit dma engine buffer addressing so ++ * dma buffers can cross 4 Kbyte page boundaries. ++ */ ++static int ++dma32_txfast(dma_info_t *di, void *p0, bool commit) +{ -+ struct parport_pc_private *priv = p->physport->private_data; -+ unsigned char *io = (unsigned char *) p->base; -+ unsigned char ctr = s->u.pc.ctr; ++ void *p, *next; ++ uchar *data; ++ uint len; ++ uint txout; ++ uint32 flags = 0; ++ uint32 pa; + -+ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_restore_state called\n"); -+ *(io+2) = ctr; -+ priv->ctr = ctr; -+} ++ DMA_TRACE(("%s: dma_txfast\n", di->name)); + -+static void parport_splink_setup_interrupt(void) { -+ return; -+} ++ txout = di->txout; + -+static void parport_splink_write_data(struct parport *p, unsigned char d) { -+ DPRINTK(KERN_DEBUG "parport_splink: write data called\n"); -+ unsigned char *io = (unsigned char *) p->base; -+ *io = d; -+} ++ /* ++ * Walk the chain of packet buffers ++ * allocating and initializing transmit descriptor entries. ++ */ ++ for (p = p0; p; p = next) { ++ data = PKTDATA(di->osh, p); ++ len = PKTLEN(di->osh, p); ++ next = PKTNEXT(di->osh, p); + -+static unsigned char parport_splink_read_data(struct parport *p) { -+ DPRINTK(KERN_DEBUG "parport_splink: read data called\n"); -+ unsigned char *io = (unsigned char *) p->base; -+ return *io; -+} ++ /* return nonzero if out of tx descriptors */ ++ if (NEXTTXD(txout) == di->txin) ++ goto outoftxd; + -+static void parport_splink_write_control(struct parport *p, unsigned char d) -+{ -+ const unsigned char wm = (PARPORT_CONTROL_STROBE | -+ PARPORT_CONTROL_AUTOFD | -+ PARPORT_CONTROL_INIT | -+ PARPORT_CONTROL_SELECT); ++ if (len == 0) ++ continue; + -+ DPRINTK(KERN_DEBUG "parport_splink: write control called\n"); -+ /* Take this out when drivers have adapted to the newer interface. */ -+ if (d & 0x20) { -+ printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n", -+ p->name, p->cad->name); -+ parport_splink_data_reverse (p); ++ /* get physical address of buffer start */ ++ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); ++ ++ flags = 0; ++ if (p == p0) ++ flags |= CTRL_SOF; ++ if (next == NULL) ++ flags |= (CTRL_IOC | CTRL_EOF); ++ if (txout == (di->ntxd - 1)) ++ flags |= CTRL_EOT; ++ ++ dma32_dd_upd(di, di->txd32, pa, txout, &flags, len); ++ ASSERT(di->txp[txout] == NULL); ++ ++ txout = NEXTTXD(txout); + } + -+ __parport_splink_frob_control (p, wm, d & wm); -+} ++ /* if last txd eof not set, fix it */ ++ if (!(flags & CTRL_EOF)) ++ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF)); + -+static unsigned char parport_splink_read_control(struct parport *p) -+{ -+ const unsigned char wm = (PARPORT_CONTROL_STROBE | -+ PARPORT_CONTROL_AUTOFD | -+ PARPORT_CONTROL_INIT | -+ PARPORT_CONTROL_SELECT); -+ DPRINTK(KERN_DEBUG "parport_splink: read control called\n"); -+ const struct parport_pc_private *priv = p->physport->private_data; -+ return priv->ctr & wm; /* Use soft copy */ ++ /* save the packet */ ++ di->txp[PREVTXD(txout)] = p0; ++ ++ /* bump the tx descriptor index */ ++ di->txout = txout; ++ ++ /* kick the chip */ ++ if (commit) ++ W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t)); ++ ++ /* tx flow control */ ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; ++ ++ return (0); ++ ++outoftxd: ++ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); ++ PKTFREE(di->osh, p0, TRUE); ++ di->hnddma.txavail = 0; ++ di->hnddma.txnobuf++; ++ return (-1); +} + -+static unsigned char parport_splink_frob_control (struct parport *p, unsigned char mask, -+ unsigned char val) ++/* ++ * Reclaim next completed txd (txds if using chained buffers) and ++ * return associated packet. ++ * If 'force' is true, reclaim txd(s) and return associated packet ++ * regardless of the value of the hardware "curr" pointer. ++ */ ++static void * ++dma32_getnexttxp(dma_info_t *di, bool forceall) +{ -+ const unsigned char wm = (PARPORT_CONTROL_STROBE | -+ PARPORT_CONTROL_AUTOFD | -+ PARPORT_CONTROL_INIT | -+ PARPORT_CONTROL_SELECT); ++ uint start, end, i; ++ void *txp; + -+ DPRINTK(KERN_DEBUG "parport_splink: frob control called\n"); -+ /* Take this out when drivers have adapted to the newer interface. */ -+ if (mask & 0x20) { -+ printk (KERN_DEBUG "%s (%s): use data_%s for this!\n", -+ p->name, p->cad->name, -+ (val & 0x20) ? "reverse" : "forward"); -+ if (val & 0x20) -+ parport_splink_data_reverse (p); -+ else -+ parport_splink_data_forward (p); ++ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); ++ ++ if (di->ntxd == 0) ++ return (NULL); ++ ++ txp = NULL; ++ ++ start = di->txin; ++ if (forceall) ++ end = di->txout; ++ else ++ end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); ++ ++ if ((start == 0) && (end > di->txout)) ++ goto bogus; ++ ++ for (i = start; i != end && !txp; i = NEXTTXD(i)) { ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), ++ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), ++ DMA_TX, di->txp[i]); ++ ++ W_SM(&di->txd32[i].addr, 0xdeadbeef); ++ txp = di->txp[i]; ++ di->txp[i] = NULL; + } + -+ /* Restrict mask and val to control lines. */ -+ mask &= wm; -+ val &= wm; ++ di->txin = i; + -+ return __parport_splink_frob_control (p, mask, val); -+} ++ /* tx flow control */ ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+static unsigned char parport_splink_read_status(struct parport *p) -+{ -+ DPRINTK(KERN_DEBUG "parport_splink: read status called\n"); -+ unsigned char *io = (unsigned char *) p->base; -+ return *(io+1); ++ return (txp); ++ ++bogus: ++/* ++ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", ++ start, end, di->txout, forceall)); ++*/ ++ return (NULL); +} + -+static void parport_splink_inc_use_count(void) ++static void * ++dma32_getnextrxp(dma_info_t *di, bool forceall) +{ -+#ifdef MODULE -+ MOD_INC_USE_COUNT; -+#endif -+} ++ uint i; ++ void *rxp; ++ ++ /* if forcing, dma engine must be disabled */ ++ ASSERT(!forceall || !dma32_rxenabled(di)); ++ ++ i = di->rxin; ++ ++ /* return if no packets posted */ ++ if (i == di->rxout) ++ return (NULL); ++ ++ /* ignore curr if forceall */ ++ if (!forceall && (i == B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) ++ return (NULL); ++ ++ /* get the packet pointer that corresponds to the rx descriptor */ ++ rxp = di->rxp[i]; ++ ASSERT(rxp); ++ di->rxp[i] = NULL; ++ ++ /* clear this packet from the descriptor ring */ ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), ++ di->rxbufsize, DMA_RX, rxp); ++ ++ W_SM(&di->rxd32[i].addr, 0xdeadbeef); ++ ++ di->rxin = NEXTRXD(i); + -+static void parport_splink_dec_use_count(void) -+{ -+#ifdef MODULE -+ MOD_DEC_USE_COUNT; -+#endif ++ return (rxp); +} + -+static struct parport_operations parport_splink_ops = ++/* ++ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). ++ */ ++static void ++dma32_txrotate(dma_info_t *di) +{ -+ parport_splink_write_data, -+ parport_splink_read_data, -+ -+ parport_splink_write_control, -+ parport_splink_read_control, -+ parport_splink_frob_control, ++ uint ad; ++ uint nactive; ++ uint rot; ++ uint old, new; ++ uint32 w; ++ uint first, last; + -+ parport_splink_read_status, ++ ASSERT(dma32_txsuspendedidle(di)); + -+ parport_splink_enable_irq, -+ parport_splink_disable_irq, ++ nactive = _dma_txactive(di); ++ ad = B2I(((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); ++ rot = TXD(ad - di->txin); + -+ parport_splink_data_forward, -+ parport_splink_data_reverse, ++ ASSERT(rot < di->ntxd); + -+ parport_splink_init_state, -+ parport_splink_save_state, -+ parport_splink_restore_state, ++ /* full-ring case is a lot harder - don't worry about this */ ++ if (rot >= (di->ntxd - nactive)) { ++ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); ++ return; ++ } + -+ parport_splink_inc_use_count, -+ parport_splink_dec_use_count, ++ first = di->txin; ++ last = PREVTXD(di->txout); + -+ parport_ieee1284_epp_write_data, -+ parport_ieee1284_epp_read_data, -+ parport_ieee1284_epp_write_addr, -+ parport_ieee1284_epp_read_addr, ++ /* move entries starting at last and moving backwards to first */ ++ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { ++ new = TXD(old + rot); + -+ parport_ieee1284_ecp_write_data, -+ parport_ieee1284_ecp_read_data, -+ parport_ieee1284_ecp_write_addr, ++ /* ++ * Move the tx dma descriptor. ++ * EOT is set only in the last entry in the ring. ++ */ ++ w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT; ++ if (new == (di->ntxd - 1)) ++ w |= CTRL_EOT; ++ W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w)); ++ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); + -+ parport_ieee1284_write_compat, -+ parport_ieee1284_read_nibble, -+ parport_ieee1284_read_byte, -+}; ++ /* zap the old tx dma descriptor address field */ ++ W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef)); + -+/* --- Initialisation code -------------------------------- */ ++ /* move the corresponding txp[] entry */ ++ ASSERT(di->txp[new] == NULL); ++ di->txp[new] = di->txp[old]; ++ di->txp[old] = NULL; ++ } + -+static struct parport *parport_splink_probe_port (unsigned long int base) -+{ -+ struct parport_pc_private *priv; -+ struct parport_operations *ops; -+ struct parport *p; ++ /* update txin and txout */ ++ di->txin = ad; ++ di->txout = TXD(di->txout + rot); ++ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + -+ if (check_mem_region(base, 3)) { -+ printk (KERN_DEBUG "parport (0x%lx): iomem region not available\n", base); -+ return NULL; -+ } -+ priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL); -+ if (!priv) { -+ printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); -+ return NULL; -+ } -+ ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); -+ if (!ops) { -+ printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n", -+ base); -+ kfree (priv); -+ return NULL; -+ } -+ memcpy (ops, &parport_splink_ops, sizeof (struct parport_operations)); -+ priv->ctr = 0xc; -+ priv->ctr_writable = 0xff; ++ /* kick the chip */ ++ W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); ++} + -+ if (!(p = parport_register_port(base, PARPORT_IRQ_NONE, -+ PARPORT_DMA_NONE, ops))) { -+ printk (KERN_DEBUG "parport (0x%lx): registration failed!\n", -+ base); -+ kfree (priv); -+ kfree (ops); -+ return NULL; -+ } + -+ p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; -+ p->size = (p->modes & PARPORT_MODE_EPP)?8:3; -+ p->private_data = priv; ++uint ++dma_addrwidth(sb_t *sbh, void *dmaregs) ++{ ++ dma32regs_t *dma32regs; ++ osl_t *osh; + -+ parport_proc_register(p); -+ request_mem_region (p->base, 3, p->name); ++ osh = sb_osh(sbh); + -+ /* Done probing. Now put the port into a sensible start-up state. */ -+ parport_splink_write_data(p, 0); -+ parport_splink_data_forward (p); ++ /* Start checking for 32-bit / 30-bit addressing */ ++ dma32regs = (dma32regs_t *)dmaregs; + -+ /* Now that we've told the sharing engine about the port, and -+ found out its characteristics, let the high-level drivers -+ know about it. */ -+ parport_announce_port (p); ++ /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */ ++ if ((BUSTYPE(sbh->bustype) == SB_BUS) || ++ ((BUSTYPE(sbh->bustype) == PCI_BUS) && sbh->buscoretype == SB_PCIE) || ++ (_dma32_addrext(osh, dma32regs))) ++ return (DMADDRWIDTH_32); + -+ DPRINTK(KERN_DEBUG "parport (0x%lx): init ok!\n", -+ base); -+ return p; ++ /* Fallthru */ ++ return (DMADDRWIDTH_30); +} +diff -urN linux.old/drivers/net/wl/hnddma.h linux.dev/drivers/net/wl/hnddma.h +--- linux.old/drivers/net/wl/hnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/hnddma.h 2006-04-28 02:20:44.000000000 +0200 +@@ -0,0 +1,156 @@ ++/* ++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: hnddma.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $ ++ */ + -+static void parport_splink_unregister_port(struct parport *p) { -+ struct parport_pc_private *priv = p->private_data; -+ struct parport_operations *ops = p->ops; ++#ifndef _hnddma_h_ ++#define _hnddma_h_ + -+ if (p->irq != PARPORT_IRQ_NONE) -+ free_irq(p->irq, p); -+ release_mem_region(p->base, 3); -+ parport_proc_unregister(p); -+ kfree (priv); -+ parport_unregister_port(p); -+ kfree (ops); -+} ++typedef const struct hnddma_pub hnddma_t; ++ ++/* dma function type */ ++typedef void (*di_detach_t)(hnddma_t *dmah); ++typedef bool (*di_txreset_t)(hnddma_t *dmah); ++typedef bool (*di_rxreset_t)(hnddma_t *dmah); ++typedef bool (*di_rxidle_t)(hnddma_t *dmah); ++typedef void (*di_txinit_t)(hnddma_t *dmah); ++typedef bool (*di_txenabled_t)(hnddma_t *dmah); ++typedef void (*di_rxinit_t)(hnddma_t *dmah); ++typedef void (*di_txsuspend_t)(hnddma_t *dmah); ++typedef void (*di_txresume_t)(hnddma_t *dmah); ++typedef bool (*di_txsuspended_t)(hnddma_t *dmah); ++typedef bool (*di_txsuspendedidle_t)(hnddma_t *dmah); ++typedef int (*di_txfast_t)(hnddma_t *dmah, void *p, bool commit); ++typedef void (*di_fifoloopbackenable_t)(hnddma_t *dmah); ++typedef bool (*di_txstopped_t)(hnddma_t *dmah); ++typedef bool (*di_rxstopped_t)(hnddma_t *dmah); ++typedef bool (*di_rxenable_t)(hnddma_t *dmah); ++typedef bool (*di_rxenabled_t)(hnddma_t *dmah); ++typedef void* (*di_rx_t)(hnddma_t *dmah); ++typedef void (*di_rxfill_t)(hnddma_t *dmah); ++typedef void (*di_txreclaim_t)(hnddma_t *dmah, bool forceall); ++typedef void (*di_rxreclaim_t)(hnddma_t *dmah); ++typedef uintptr (*di_getvar_t)(hnddma_t *dmah, char *name); ++typedef void* (*di_getnexttxp_t)(hnddma_t *dmah, bool forceall); ++typedef void* (*di_getnextrxp_t)(hnddma_t *dmah, bool forceall); ++typedef void* (*di_peeknexttxp_t)(hnddma_t *dmah); ++typedef void (*di_txblock_t)(hnddma_t *dmah); ++typedef void (*di_txunblock_t)(hnddma_t *dmah); ++typedef uint (*di_txactive_t)(hnddma_t *dmah); ++typedef void (*di_txrotate_t)(hnddma_t *dmah); ++typedef void (*di_counterreset_t)(hnddma_t *dmah); ++typedef char* (*di_dump_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); ++typedef char* (*di_dumptx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); ++typedef char* (*di_dumprx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); ++ ++/* dma opsvec */ ++typedef struct di_fcn_s { ++ di_detach_t detach; ++ di_txinit_t txinit; ++ di_txreset_t txreset; ++ di_txenabled_t txenabled; ++ di_txsuspend_t txsuspend; ++ di_txresume_t txresume; ++ di_txsuspended_t txsuspended; ++ di_txsuspendedidle_t txsuspendedidle; ++ di_txfast_t txfast; ++ di_txstopped_t txstopped; ++ di_txreclaim_t txreclaim; ++ di_getnexttxp_t getnexttxp; ++ di_peeknexttxp_t peeknexttxp; ++ di_txblock_t txblock; ++ di_txunblock_t txunblock; ++ di_txactive_t txactive; ++ di_txrotate_t txrotate; ++ ++ di_rxinit_t rxinit; ++ di_rxreset_t rxreset; ++ di_rxidle_t rxidle; ++ di_rxstopped_t rxstopped; ++ di_rxenable_t rxenable; ++ di_rxenabled_t rxenabled; ++ di_rx_t rx; ++ di_rxfill_t rxfill; ++ di_rxreclaim_t rxreclaim; ++ di_getnextrxp_t getnextrxp; ++ ++ di_fifoloopbackenable_t fifoloopbackenable; ++ di_getvar_t d_getvar; ++ di_counterreset_t counterreset; ++ di_dump_t dump; ++ di_dumptx_t dumptx; ++ di_dumprx_t dumprx; ++ uint endnum; ++} di_fcn_t; + ++/* ++ * Exported data structure (read-only) ++ */ ++/* export structure */ ++struct hnddma_pub { ++ di_fcn_t di_fn; /* DMA function pointers */ ++ uint txavail; /* # free tx descriptors */ + -+int parport_splink_init(void) -+{ -+ int ret; -+ -+ DPRINTK(KERN_DEBUG "parport_splink init called\n"); -+ parport_splink_setup_interrupt(); -+ ret = !parport_splink_probe_port(SPLINK_ADDRESS); -+ -+ return ret; -+} ++ /* rx error counters */ ++ uint rxgiants; /* rx giant frames */ ++ uint rxnobuf; /* rx out of dma descriptors */ ++ /* tx error counters */ ++ uint txnobuf; /* tx out of dma descriptors */ ++}; + -+void parport_splink_cleanup(void) { -+ struct parport *p = parport_enumerate(), *tmp; -+ DPRINTK(KERN_DEBUG "parport_splink cleanup called\n"); -+ if (p->size) { -+ if (p->modes & PARPORT_MODE_PCSPP) { -+ while(p) { -+ tmp = p->next; -+ parport_splink_unregister_port(p); -+ p = tmp; -+ } -+ } -+ } -+} + -+MODULE_AUTHOR("Nuno Grilo "); -+MODULE_DESCRIPTION("Parport Driver for ASUS WL-500g router builtin Port"); -+MODULE_SUPPORTED_DEVICE("ASUS WL-500g builtin Parallel Port"); -+MODULE_LICENSE("GPL"); ++extern hnddma_t * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, ++ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, ++ uint *msg_level); ++#define dma_detach(di) ((di)->di_fn.detach(di)) ++#define dma_txreset(di) ((di)->di_fn.txreset(di)) ++#define dma_rxreset(di) ((di)->di_fn.rxreset(di)) ++#define dma_rxidle(di) ((di)->di_fn.rxidle(di)) ++#define dma_txinit(di) ((di)->di_fn.txinit(di)) ++#define dma_txenabled(di) ((di)->di_fn.txenabled(di)) ++#define dma_rxinit(di) ((di)->di_fn.rxinit(di)) ++#define dma_txsuspend(di) ((di)->di_fn.txsuspend(di)) ++#define dma_txresume(di) ((di)->di_fn.txresume(di)) ++#define dma_txsuspended(di) ((di)->di_fn.txsuspended(di)) ++#define dma_txsuspendedidle(di) ((di)->di_fn.txsuspendedidle(di)) ++#define dma_txfast(di, p, commit) ((di)->di_fn.txfast(di, p, commit)) ++#define dma_fifoloopbackenable(di) ((di)->di_fn.fifoloopbackenable(di)) ++#define dma_txstopped(di) ((di)->di_fn.txstopped(di)) ++#define dma_rxstopped(di) ((di)->di_fn.rxstopped(di)) ++#define dma_rxenable(di) ((di)->di_fn.rxenable(di)) ++#define dma_rxenabled(di) ((di)->di_fn.rxenabled(di)) ++#define dma_rx(di) ((di)->di_fn.rx(di)) ++#define dma_rxfill(di) ((di)->di_fn.rxfill(di)) ++#define dma_txreclaim(di, forceall) ((di)->di_fn.txreclaim(di, forceall)) ++#define dma_rxreclaim(di) ((di)->di_fn.rxreclaim(di)) ++#define dma_getvar(di, name) ((di)->di_fn.d_getvar(di, name)) ++#define dma_getnexttxp(di, forceall) ((di)->di_fn.getnexttxp(di, forceall)) ++#define dma_getnextrxp(di, forceall) ((di)->di_fn.getnextrxp(di, forceall)) ++#define dma_peeknexttxp(di) ((di)->di_fn.peeknexttxp(di)) ++#define dma_txblock(di) ((di)->di_fn.txblock(di)) ++#define dma_txunblock(di) ((di)->di_fn.txunblock(di)) ++#define dma_txactive(di) ((di)->di_fn.txactive(di)) ++#define dma_txrotate(di) ((di)->di_fn.txrotate(di)) ++#define dma_counterreset(di) ((di)->di_fn.counterreset(di)) ++ ++#define DMA_DUMP_SIZE 2048 ++/* return addresswidth allowed ++ * This needs to be done after SB attach but before dma attach. ++ * SB attach provides ability to probe backplane and dma core capabilities ++ * This info is needed by DMA_ALLOC_CONSISTENT in dma attach ++ */ ++extern uint dma_addrwidth(sb_t *sbh, void *dmaregs); + -+module_init(parport_splink_init) -+module_exit(parport_splink_cleanup) ++/* pio helpers */ ++void dma_txpioloopback(osl_t *osh, dma32regs_t *); + -diff -Naur linux.old/drivers/pcmcia/Makefile linux.dev/drivers/pcmcia/Makefile ---- linux.old/drivers/pcmcia/Makefile 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/drivers/pcmcia/Makefile 2006-04-06 15:34:15.000000000 +0200 -@@ -74,6 +74,10 @@ - au1000_ss-objs-$(CONFIG_MIPS_HYDROGEN3) += au1000_hydrogen3.o - au1000_ss-objs-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o - -+obj-$(CONFIG_PCMCIA_BCM4710) += bcm4710_ss.o -+bcm4710_ss-objs := bcm4710_generic.o -+bcm4710_ss-objs += bcm4710_pcmcia.o -+ - obj-$(CONFIG_PCMCIA_SA1100) += sa1100_cs.o - obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o - obj-$(CONFIG_PCMCIA_SIBYTE) += sibyte_generic.o -@@ -112,5 +116,8 @@ - au1x00_ss.o: $(au1000_ss-objs-y) - $(LD) -r -o $@ $(au1000_ss-objs-y) - -+bcm4710_ss.o: $(bcm4710_ss-objs) -+ $(LD) -r -o $@ $(bcm4710_ss-objs) -+ - yenta_socket.o: $(yenta_socket-objs) - $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs) -diff -Naur linux.old/drivers/pcmcia/bcm4710_generic.c linux.dev/drivers/pcmcia/bcm4710_generic.c ---- linux.old/drivers/pcmcia/bcm4710_generic.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/pcmcia/bcm4710_generic.c 2006-04-06 15:34:15.000000000 +0200 -@@ -0,0 +1,912 @@ ++#endif /* _hnddma_h_ */ +diff -urN linux.old/drivers/net/wl/linux_osl.c linux.dev/drivers/net/wl/linux_osl.c +--- linux.old/drivers/net/wl/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/linux_osl.c 2006-04-28 02:29:46.000000000 +0200 +@@ -0,0 +1,269 @@ +/* ++ * Linux OS Independent Layer + * -+ * bcm47xx pcmcia driver -+ * -+ * Copyright 2004, Broadcom Corporation ++ * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -20623,1301 +18719,1202 @@ diff -Naur linux.old/drivers/pcmcia/bcm4710_generic.c linux.dev/drivers/pcmcia/b + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * Based on sa1100_generic.c from www.handhelds.org, -+ * and au1000_generic.c from oss.sgi.com. -+ * -+ * $Id: bcm4710_generic.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ * $Id: linux_osl.c,v 1.1.1.14 2006/04/08 06:13:39 honor Exp $ + */ ++ ++#define LINUX_OSL ++ ++#include ++#include +#include -+#include -+#include ++#include ++#include ++#include ++#include "linux_osl.h" ++#include +#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#ifdef mips ++#include ++#endif /* mips */ ++#include + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "cs_internal.h" ++#define PCI_CFG_RETRY 10 ++ ++#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */ ++#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ ++ ++typedef struct bcm_mem_link { ++ struct bcm_mem_link *prev; ++ struct bcm_mem_link *next; ++ uint size; ++ int line; ++ char file[BCM_MEM_FILENAME_LEN]; ++} bcm_mem_link_t; ++ ++static int16 linuxbcmerrormap[] = \ ++{ 0, /* 0 */ ++ -EINVAL, /* BCME_ERROR */ ++ -EINVAL, /* BCME_BADARG */ ++ -EINVAL, /* BCME_BADOPTION */ ++ -EINVAL, /* BCME_NOTUP */ ++ -EINVAL, /* BCME_NOTDOWN */ ++ -EINVAL, /* BCME_NOTAP */ ++ -EINVAL, /* BCME_NOTSTA */ ++ -EINVAL, /* BCME_BADKEYIDX */ ++ -EINVAL, /* BCME_RADIOOFF */ ++ -EINVAL, /* BCME_NOTBANDLOCKED */ ++ -EINVAL, /* BCME_NOCLK */ ++ -EINVAL, /* BCME_BADRATESET */ ++ -EINVAL, /* BCME_BADBAND */ ++ -E2BIG, /* BCME_BUFTOOSHORT */ ++ -E2BIG, /* BCME_BUFTOOLONG */ ++ -EBUSY, /* BCME_BUSY */ ++ -EINVAL, /* BCME_NOTASSOCIATED */ ++ -EINVAL, /* BCME_BADSSIDLEN */ ++ -EINVAL, /* BCME_OUTOFRANGECHAN */ ++ -EINVAL, /* BCME_BADCHAN */ ++ -EFAULT, /* BCME_BADADDR */ ++ -ENOMEM, /* BCME_NORESOURCE */ ++ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ ++ -EMSGSIZE, /* BCME_BADLENGTH */ ++ -EINVAL, /* BCME_NOTREADY */ ++ -EPERM, /* BCME_NOTPERMITTED */ ++ -ENOMEM, /* BCME_NOMEM */ ++ -EINVAL, /* BCME_ASSOCIATED */ ++ -ERANGE, /* BCME_RANGE */ ++ -EINVAL, /* BCME_NOTFOUND */ ++ -EINVAL, /* BCME_WME_NOT_ENABLED */ ++ -EINVAL, /* BCME_TSPEC_NOTFOUND */ ++ -EINVAL, /* BCME_ACM_NOTSUPPORTED */ ++ -EINVAL, /* BCME_NOT_WME_ASSOCIATION */ ++ -EIO, /* BCME_SDIO_ERROR */ ++ -ENODEV /* BCME_DONGLE_DOWN */ ++}; + -+#include -+#include -+#include ++/* translate bcmerrors into linux errors */ ++int ++osl_error(int bcmerror) ++{ ++ int abs_bcmerror; ++ int array_size = ARRAYSIZE(linuxbcmerrormap); + -+#include -+#include -+#include ++ abs_bcmerror = ABS(bcmerror); + -+#include "bcm4710pcmcia.h" ++ if (bcmerror > 0) ++ abs_bcmerror = 0; + -+#ifdef PCMCIA_DEBUG -+static int pc_debug = PCMCIA_DEBUG; -+#endif ++ else if (abs_bcmerror >= array_size) ++ abs_bcmerror = BCME_ERROR; + -+MODULE_DESCRIPTION("Linux PCMCIA Card Services: bcm47xx Socket Controller"); ++ return linuxbcmerrormap[abs_bcmerror]; ++} + -+/* This structure maintains housekeeping state for each socket, such -+ * as the last known values of the card detect pins, or the Card Services -+ * callback value associated with the socket: -+ */ -+static struct bcm47xx_pcmcia_socket *pcmcia_socket; -+static int socket_count; ++osl_t * ++osl_attach(void *pdev, bool pkttag) ++{ ++ osl_t *osh; + ++ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); ++ ASSERT(osh); + -+/* Returned by the low-level PCMCIA interface: */ -+static struct pcmcia_low_level *pcmcia_low_level; ++ bzero(osh, sizeof(osl_t)); + -+/* Event poll timer structure */ -+static struct timer_list poll_timer; ++ /* ++ * check the cases where ++ * 1.Error code Added to bcmerror table, but forgot to add it to the OS ++ * dependent error code ++ * 2. Error code is added to the bcmerror table, but forgot to add the ++ * corresponding errorstring(dummy call to bcmerrorstr) ++ */ ++ bcmerrorstr(0); ++ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); + ++ osh->magic = OS_HANDLE_MAGIC; ++ osh->malloced = 0; ++ osh->failed = 0; ++ osh->dbgmem_list = NULL; ++ osh->pdev = pdev; ++ osh->pub.pkttag = pkttag; + -+/* Prototypes for routines which are used internally: */ ++ return osh; ++} + -+static int bcm47xx_pcmcia_driver_init(void); -+static void bcm47xx_pcmcia_driver_shutdown(void); -+static void bcm47xx_pcmcia_task_handler(void *data); -+static void bcm47xx_pcmcia_poll_event(unsigned long data); -+static void bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs); -+static struct tq_struct bcm47xx_pcmcia_task; ++void ++osl_detach(osl_t *osh) ++{ ++ if (osh == NULL) ++ return; + -+#ifdef CONFIG_PROC_FS -+static int bcm47xx_pcmcia_proc_status(char *buf, char **start, -+ off_t pos, int count, int *eof, void *data); -+#endif ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ kfree(osh); ++} + ++/* Return a new packet. zero out pkttag */ ++void* ++osl_pktget(osl_t *osh, uint len, bool send) ++{ ++ struct sk_buff *skb; + -+/* Prototypes for operations which are exported to the -+ * in-kernel PCMCIA core: -+ */ ++ if ((skb = dev_alloc_skb(len))) { ++ skb_put(skb, len); ++ skb->priority = 0; + -+static int bcm47xx_pcmcia_init(unsigned int sock); -+static int bcm47xx_pcmcia_suspend(unsigned int sock); -+static int bcm47xx_pcmcia_register_callback(unsigned int sock, -+ void (*handler)(void *, unsigned int), void *info); -+static int bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap); -+static int bcm47xx_pcmcia_get_status(unsigned int sock, u_int *value); -+static int bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state); -+static int bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state); -+static int bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *io); -+static int bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *io); -+static int bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *mem); -+static int bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *mem); -+#ifdef CONFIG_PROC_FS -+static void bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base); -+#endif ++#ifdef BCMDBG_PKT ++ pktlist_add(&(osh->pktlist), (void *) skb); ++#endif /* BCMDBG_PKT */ + -+static struct pccard_operations bcm47xx_pcmcia_operations = { -+ bcm47xx_pcmcia_init, -+ bcm47xx_pcmcia_suspend, -+ bcm47xx_pcmcia_register_callback, -+ bcm47xx_pcmcia_inquire_socket, -+ bcm47xx_pcmcia_get_status, -+ bcm47xx_pcmcia_get_socket, -+ bcm47xx_pcmcia_set_socket, -+ bcm47xx_pcmcia_get_io_map, -+ bcm47xx_pcmcia_set_io_map, -+ bcm47xx_pcmcia_get_mem_map, -+ bcm47xx_pcmcia_set_mem_map, -+#ifdef CONFIG_PROC_FS -+ bcm47xx_pcmcia_proc_setup -+#endif -+}; ++ osh->pub.pktalloced++; ++ } + ++ return ((void*) skb); ++} + -+/* -+ * bcm47xx_pcmcia_driver_init() -+ * -+ * This routine performs a basic sanity check to ensure that this -+ * kernel has been built with the appropriate board-specific low-level -+ * PCMCIA support, performs low-level PCMCIA initialization, registers -+ * this socket driver with Card Services, and then spawns the daemon -+ * thread which is the real workhorse of the socket driver. -+ * -+ * Please see linux/Documentation/arm/SA1100/PCMCIA for more information -+ * on the low-level kernel interface. -+ * -+ * Returns: 0 on success, -1 on error -+ */ -+static int __init bcm47xx_pcmcia_driver_init(void) ++/* Free the driver packet. Free the tag if present */ ++void ++osl_pktfree(osl_t *osh, void *p) +{ -+ servinfo_t info; -+ struct pcmcia_init pcmcia_init; -+ struct pcmcia_state state; -+ unsigned int i; -+ unsigned long tmp; -+ -+ -+ printk("\nBCM47XX PCMCIA (CS release %s)\n", CS_RELEASE); ++ struct sk_buff *skb, *nskb; + -+ CardServices(GetCardServicesInfo, &info); ++ skb = (struct sk_buff*) p; + -+ if (info.Revision != CS_RELEASE_CODE) { -+ printk(KERN_ERR "Card Services release codes do not match\n"); -+ return -1; -+ } ++ /* perversion: we use skb->next to chain multi-skb packets */ ++ while (skb) { ++ nskb = skb->next; ++ skb->next = NULL; + -+#ifdef CONFIG_BCM4710 -+ pcmcia_low_level=&bcm4710_pcmcia_ops; -+#else -+#error Unsupported Broadcom BCM47XX board. -+#endif ++#ifdef BCMDBG_PKT ++ pktlist_remove(&(osh->pktlist), (void *) skb); ++#endif /* BCMDBG_PKT */ + -+ pcmcia_init.handler=bcm47xx_pcmcia_interrupt; ++ if (skb->destructor) { ++ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists ++ */ ++ dev_kfree_skb_any(skb); ++ } else { ++ /* can free immediately (even in_irq()) if destructor does not exist */ ++ dev_kfree_skb(skb); ++ } + -+ if ((socket_count = pcmcia_low_level->init(&pcmcia_init)) < 0) { -+ printk(KERN_ERR "Unable to initialize PCMCIA service.\n"); -+ return -EIO; -+ } else { -+ printk("\t%d PCMCIA sockets initialized.\n", socket_count); -+ } ++ osh->pub.pktalloced--; + -+ pcmcia_socket = -+ kmalloc(sizeof(struct bcm47xx_pcmcia_socket) * socket_count, -+ GFP_KERNEL); -+ memset(pcmcia_socket, 0, -+ sizeof(struct bcm47xx_pcmcia_socket) * socket_count); -+ if (!pcmcia_socket) { -+ printk(KERN_ERR "Card Services can't get memory \n"); -+ return -1; -+ } -+ -+ for (i = 0; i < socket_count; i++) { -+ if (pcmcia_low_level->socket_state(i, &state) < 0) { -+ printk(KERN_ERR "Unable to get PCMCIA status\n"); -+ return -EIO; -+ } -+ pcmcia_socket[i].k_state = state; -+ pcmcia_socket[i].cs_state.csc_mask = SS_DETECT; -+ -+ if (i == 0) { -+ pcmcia_socket[i].virt_io = -+ (unsigned long)ioremap_nocache(EXTIF_PCMCIA_IOBASE(BCM4710_EXTIF), 0x1000); -+ /* Substract ioport base which gets added by in/out */ -+ pcmcia_socket[i].virt_io -= mips_io_port_base; -+ pcmcia_socket[i].phys_attr = -+ (unsigned long)EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF); -+ pcmcia_socket[i].phys_mem = -+ (unsigned long)EXTIF_PCMCIA_MEMBASE(BCM4710_EXTIF); -+ } else { -+ printk(KERN_ERR "bcm4710: socket 1 not supported\n"); -+ return 1; -+ } ++ skb = nskb; + } ++} + -+ /* Only advertise as many sockets as we can detect: */ -+ if (register_ss_entry(socket_count, &bcm47xx_pcmcia_operations) < 0) { -+ printk(KERN_ERR "Unable to register socket service routine\n"); -+ return -ENXIO; -+ } ++void* ++osl_malloc(osl_t *osh, uint size) ++{ ++ void *addr; + -+ /* Start the event poll timer. -+ * It will reschedule by itself afterwards. -+ */ -+ bcm47xx_pcmcia_poll_event(0); ++ /* only ASSERT if osh is defined */ ++ if (osh) ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); + -+ DEBUG(1, "bcm4710: initialization complete\n"); -+ return 0; ++ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { ++ if (osh) ++ osh->failed++; ++ return (NULL); ++ } ++ if (osh) ++ osh->malloced += size; + ++ return (addr); +} + -+module_init(bcm47xx_pcmcia_driver_init); -+ -+ -+/* -+ * bcm47xx_pcmcia_driver_shutdown() -+ * -+ * Invokes the low-level kernel service to free IRQs associated with this -+ * socket controller and reset GPIO edge detection. -+ */ -+static void __exit bcm47xx_pcmcia_driver_shutdown(void) ++void ++osl_mfree(osl_t *osh, void *addr, uint size) +{ -+ int i; -+ -+ del_timer_sync(&poll_timer); -+ unregister_ss_entry(&bcm47xx_pcmcia_operations); -+ pcmcia_low_level->shutdown(); -+ flush_scheduled_tasks(); -+ for (i = 0; i < socket_count; i++) { -+ if (pcmcia_socket[i].virt_io) -+ iounmap((void *)pcmcia_socket[i].virt_io); -+ if (pcmcia_socket[i].phys_attr) -+ iounmap((void *)pcmcia_socket[i].phys_attr); -+ if (pcmcia_socket[i].phys_mem) -+ iounmap((void *)pcmcia_socket[i].phys_mem); ++ if (osh) { ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ osh->malloced -= size; + } -+ DEBUG(1, "bcm4710: shutdown complete\n"); ++ kfree(addr); +} + -+module_exit(bcm47xx_pcmcia_driver_shutdown); ++uint ++osl_malloced(osl_t *osh) ++{ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->malloced); ++} + -+/* -+ * bcm47xx_pcmcia_init() -+ * We perform all of the interesting initialization tasks in -+ * bcm47xx_pcmcia_driver_init(). -+ * -+ * Returns: 0 -+ */ -+static int bcm47xx_pcmcia_init(unsigned int sock) ++uint osl_malloc_failed(osl_t *osh) +{ -+ DEBUG(1, "%s(): initializing socket %u\n", __FUNCTION__, sock); ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->failed); ++} + -+ return 0; ++#undef osl_delay ++void ++osl_delay(uint usec) ++{ ++ OSL_DELAY(usec); +} + -+/* -+ * bcm47xx_pcmcia_suspend() -+ * -+ * We don't currently perform any actions on a suspend. -+ * -+ * Returns: 0 ++/* Clone a packet. ++ * The pkttag contents are NOT cloned. + */ -+static int bcm47xx_pcmcia_suspend(unsigned int sock) ++void * ++osl_pktdup(osl_t *osh, void *skb) +{ -+ DEBUG(1, "%s(): suspending socket %u\n", __FUNCTION__, sock); ++ void * p; + -+ return 0; ++ if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL) ++ return NULL; ++ ++ /* skb_clone copies skb->cb.. we don't want that */ ++ if (osh->pub.pkttag) ++ bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); ++ ++ /* Increment the packet counter */ ++ osh->pub.pktalloced++; ++ return (p); +} + ++uint ++osl_pktalloced(osl_t *osh) ++{ ++ return (osh->pub.pktalloced); ++} + +diff -urN linux.old/drivers/net/wl/linux_osl.h linux.dev/drivers/net/wl/linux_osl.h +--- linux.old/drivers/net/wl/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/linux_osl.h 2006-05-02 17:44:29.000000000 +0200 +@@ -0,0 +1,171 @@ +/* -+ * bcm47xx_pcmcia_events() ++ * Linux OS Independent Layer + * -+ * Helper routine to generate a Card Services event mask based on -+ * state information obtained from the kernel low-level PCMCIA layer -+ * in a recent (and previous) sampling. Updates `prev_state'. ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * Returns: an event mask for the given socket state. ++ * $Id: linux_osl.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $ + */ -+static inline unsigned -+bcm47xx_pcmcia_events(struct pcmcia_state *state, -+ struct pcmcia_state *prev_state, -+ unsigned int mask, unsigned int flags) -+{ -+ unsigned int events=0; + -+ if (state->bvd1 != prev_state->bvd1) { ++#ifndef _linux_osl_h_ ++#define _linux_osl_h_ + -+ DEBUG(3, "%s(): card BVD1 value %u\n", __FUNCTION__, state->bvd1); ++#include ++#include ++#include + -+ events |= mask & (flags & SS_IOCARD) ? SS_STSCHG : SS_BATDEAD; -+ } ++#define OSL_PKTTAG_SZ 32 /* Size of PktTag */ + -+ if (state->bvd2 != prev_state->bvd2) { ++/* osl handle type forward declaration */ ++typedef struct osl_dmainfo osldma_t; + -+ DEBUG(3, "%s(): card BVD2 value %u\n", __FUNCTION__, state->bvd2); ++/* OSL initialization */ ++extern osl_t *osl_attach(void *pdev, bool pkttag); ++extern void osl_detach(osl_t *osh); + -+ events |= mask & (flags & SS_IOCARD) ? 0 : SS_BATWARN; -+ } ++/* host/bus architecture-specific byte swap */ ++#define BUS_SWAP32(v) (v) ++#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) + -+ if (state->detect != prev_state->detect) { ++extern void *osl_malloc(osl_t *osh, uint size); ++extern void osl_mfree(osl_t *osh, void *addr, uint size); ++extern uint osl_malloced(osl_t *osh); ++extern uint osl_malloc_failed(osl_t *osh); + -+ DEBUG(3, "%s(): card detect value %u\n", __FUNCTION__, state->detect); ++/* API for DMA addressing capability */ ++#define DMA_MAP(osh, va, size, direction, p) \ ++ osl_dma_map((osh), (va), (size), (direction)) ++#define DMA_UNMAP(osh, pa, size, direction, p) \ ++ osl_dma_unmap((osh), (pa), (size), (direction)) ++static inline uint ++osl_dma_map(void *osh, void *va, uint size, int direction) ++{ ++ int dir; ++ struct pci_dev *dev; + -+ events |= mask & SS_DETECT; -+ } ++ dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev); ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ return (pci_map_single(dev, va, size, dir)); ++} + ++static inline void ++osl_dma_unmap(void *osh, uint pa, uint size, int direction) ++{ ++ int dir; ++ struct pci_dev *dev; + -+ if (state->ready != prev_state->ready) { ++ dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev); ++ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; ++ pci_unmap_single(dev, (uint32)pa, size, dir); ++} + -+ DEBUG(3, "%s(): card ready value %u\n", __FUNCTION__, state->ready); ++#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) ++#define DMA_CONSISTENT_ALIGN PAGE_SIZE ++#define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah) \ ++ osl_dma_alloc_consistent((osh), (size), (pap)) ++#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ ++ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) ++static inline void* ++osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) ++{ ++ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); ++} + -+ events |= mask & ((flags & SS_IOCARD) ? 0 : SS_READY); -+ } ++static inline void ++osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) ++{ ++ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); ++} + -+ if (events != 0) { -+ DEBUG(2, "events: %s%s%s%s%s\n", -+ (events & SS_DETECT) ? "DETECT " : "", -+ (events & SS_READY) ? "READY " : "", -+ (events & SS_BATDEAD) ? "BATDEAD " : "", -+ (events & SS_BATWARN) ? "BATWARN " : "", -+ (events & SS_STSCHG) ? "STSCHG " : ""); -+ } + -+ *prev_state=*state; -+ return events; -+} ++/* register access macros */ ++#if defined(BCMJTAG) ++#include ++#define R_REG(osh, r) bcmjtag_read(NULL, (uint32)(r), sizeof(*(r))) ++#define W_REG(osh, r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof(*(r))) ++#endif /* defined(BCMSDIO) */ + ++/* packet primitives */ ++#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) ++#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb)) ++#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) ++#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) ++#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) ++#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) ++#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) ++#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) ++#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) ++#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) ++#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) ++#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) ++#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) ++#define PKTALLOCED(osh) osl_pktalloced((osh)) ++#define PKTLIST_DUMP(osh, buf) + -+/* -+ * bcm47xx_pcmcia_task_handler() -+ * -+ * Processes serviceable socket events using the "eventd" thread context. -+ * -+ * Event processing (specifically, the invocation of the Card Services event -+ * callback) occurs in this thread rather than in the actual interrupt -+ * handler due to the use of scheduling operations in the PCMCIA core. ++/* Convert a native(OS) packet to driver packet. ++ * In the process, native packet is destroyed, there is no copying ++ * Also, a packettag is zeroed out + */ -+static void bcm47xx_pcmcia_task_handler(void *data) ++static INLINE void * ++osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb) +{ -+ struct pcmcia_state state; -+ int i, events, irq_status; -+ -+ DEBUG(4, "%s(): entering PCMCIA monitoring thread\n", __FUNCTION__); ++ struct sk_buff *nskb; + -+ for (i = 0; i < socket_count; i++) { -+ if ((irq_status = pcmcia_low_level->socket_state(i, &state)) < 0) -+ printk(KERN_ERR "Error in kernel low-level PCMCIA service.\n"); ++ if (osh->pkttag) ++ bzero((void*)skb->cb, OSL_PKTTAG_SZ); + -+ events = bcm47xx_pcmcia_events(&state, -+ &pcmcia_socket[i].k_state, -+ pcmcia_socket[i].cs_state.csc_mask, -+ pcmcia_socket[i].cs_state.flags); -+ -+ if (pcmcia_socket[i].handler != NULL) { -+ pcmcia_socket[i].handler(pcmcia_socket[i].handler_info, -+ events); -+ } ++ /* Increment the packet counter */ ++ for (nskb = skb; nskb; nskb = nskb->next) { ++ osh->pktalloced++; + } -+} -+ -+static struct tq_struct bcm47xx_pcmcia_task = { -+ routine: bcm47xx_pcmcia_task_handler -+}; + ++ return (void *)skb; ++} ++#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((struct osl_pubinfo *)osh), \ ++ (struct sk_buff*)(skb)) + -+/* -+ * bcm47xx_pcmcia_poll_event() -+ * -+ * Let's poll for events in addition to IRQs since IRQ only is unreliable... ++/* Convert a driver packet to native(OS) packet ++ * In the process, packettag is zeroed out before sending up ++ * IP code depends on skb->cb to be setup correctly with various options ++ * In our case, that means it should be 0 + */ -+static void bcm47xx_pcmcia_poll_event(unsigned long dummy) ++static INLINE struct sk_buff * ++osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) +{ -+ DEBUG(4, "%s(): polling for events\n", __FUNCTION__); ++ struct sk_buff *nskb; + -+ poll_timer.function = bcm47xx_pcmcia_poll_event; -+ poll_timer.expires = jiffies + BCM47XX_PCMCIA_POLL_PERIOD; -+ add_timer(&poll_timer); -+ schedule_task(&bcm47xx_pcmcia_task); -+} ++ if (osh->pkttag) ++ bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); + ++ /* Decrement the packet counter */ ++ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { ++ osh->pktalloced--; ++ } + -+/* -+ * bcm47xx_pcmcia_interrupt() -+ * -+ * Service routine for socket driver interrupts (requested by the -+ * low-level PCMCIA init() operation via bcm47xx_pcmcia_thread()). -+ * -+ * The actual interrupt-servicing work is performed by -+ * bcm47xx_pcmcia_task(), largely because the Card Services event- -+ * handling code performs scheduling operations which cannot be -+ * executed from within an interrupt context. -+ */ -+static void -+bcm47xx_pcmcia_interrupt(int irq, void *dev, struct pt_regs *regs) -+{ -+ DEBUG(3, "%s(): servicing IRQ %d\n", __FUNCTION__, irq); -+ schedule_task(&bcm47xx_pcmcia_task); ++ return (struct sk_buff *)pkt; +} ++#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt)) ++ ++#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) ++#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) ++#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) ++#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) ++#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) + ++extern void *osl_pktget(osl_t *osh, uint len, bool send); ++extern void osl_pktfree(osl_t *osh, void *skb); ++extern void *osl_pktdup(osl_t *osh, void *skb); ++extern uint osl_pktalloced(osl_t *osh); + -+/* -+ * bcm47xx_pcmcia_register_callback() -+ * -+ * Implements the register_callback() operation for the in-kernel -+ * PCMCIA service (formerly SS_RegisterCallback in Card Services). If -+ * the function pointer `handler' is not NULL, remember the callback -+ * location in the state for `sock', and increment the usage counter -+ * for the driver module. (The callback is invoked from the interrupt -+ * service routine, bcm47xx_pcmcia_interrupt(), to notify Card Services -+ * of interesting events.) Otherwise, clear the callback pointer in the -+ * socket state and decrement the module usage count. -+ * -+ * Returns: 0 -+ */ -+static int -+bcm47xx_pcmcia_register_callback(unsigned int sock, -+ void (*handler)(void *, unsigned int), void *info) -+{ -+ if (handler == NULL) { -+ pcmcia_socket[sock].handler = NULL; -+ MOD_DEC_USE_COUNT; -+ } else { -+ MOD_INC_USE_COUNT; -+ pcmcia_socket[sock].handler = handler; -+ pcmcia_socket[sock].handler_info = info; -+ } -+ return 0; -+} ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++extern int osl_error(int bcmerror); + ++/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ ++#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ + ++#endif /* _linux_osl_h_ */ +diff -urN linux.old/drivers/net/wl/pktq.h linux.dev/drivers/net/wl/pktq.h +--- linux.old/drivers/net/wl/pktq.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/pktq.h 2006-04-28 02:11:49.000000000 +0200 +@@ -0,0 +1,97 @@ +/* -+ * bcm47xx_pcmcia_inquire_socket() -+ * -+ * Implements the inquire_socket() operation for the in-kernel PCMCIA -+ * service (formerly SS_InquireSocket in Card Services). Of note is -+ * the setting of the SS_CAP_PAGE_REGS bit in the `features' field of -+ * `cap' to "trick" Card Services into tolerating large "I/O memory" -+ * addresses. Also set is SS_CAP_STATIC_MAP, which disables the memory -+ * resource database check. (Mapped memory is set up within the socket -+ * driver itself.) -+ * -+ * In conjunction with the STATIC_MAP capability is a new field, -+ * `io_offset', recommended by David Hinds. Rather than go through -+ * the SetIOMap interface (which is not quite suited for communicating -+ * window locations up from the socket driver), we just pass up -+ * an offset which is applied to client-requested base I/O addresses -+ * in alloc_io_space(). ++ * Misc useful os-independent macros and functions. + * -+ * Returns: 0 on success, -1 if no pin has been configured for `sock' ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $ + */ -+static int -+bcm47xx_pcmcia_inquire_socket(unsigned int sock, socket_cap_t *cap) -+{ -+ struct pcmcia_irq_info irq_info; + -+ if (sock >= socket_count) { -+ printk(KERN_ERR "bcm47xx: socket %u not configured\n", sock); -+ return -1; -+ } -+ -+ /* SS_CAP_PAGE_REGS: used by setup_cis_mem() in cistpl.c to set the -+ * force_low argument to validate_mem() in rsrc_mgr.c -- since in -+ * general, the mapped * addresses of the PCMCIA memory regions -+ * will not be within 0xffff, setting force_low would be -+ * undesirable. -+ * -+ * SS_CAP_STATIC_MAP: don't bother with the (user-configured) memory -+ * resource database; we instead pass up physical address ranges -+ * and allow other parts of Card Services to deal with remapping. -+ * -+ * SS_CAP_PCCARD: we can deal with 16-bit PCMCIA & CF cards, but -+ * not 32-bit CardBus devices. -+ */ -+ cap->features = (SS_CAP_PAGE_REGS | SS_CAP_STATIC_MAP | SS_CAP_PCCARD); ++#ifndef _pktq_h_ ++#define _pktq_h_ ++#include + -+ irq_info.sock = sock; -+ irq_info.irq = -1; ++/* osl multi-precedence packet queue */ + -+ if (pcmcia_low_level->get_irq_info(&irq_info) < 0) { -+ printk(KERN_ERR "Error obtaining IRQ info socket %u\n", sock); -+ return -1; -+ } ++#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ ++#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ + -+ cap->irq_mask = 0; -+ cap->map_size = PAGE_SIZE; -+ cap->pci_irq = irq_info.irq; -+ cap->io_offset = pcmcia_socket[sock].virt_io; ++struct pktq { ++ struct pktq_prec { ++ void *head; /* first packet to dequeue */ ++ void *tail; /* last packet to dequeue */ ++ uint16 len; /* number of queued packets */ ++ uint16 max; /* maximum number of queued packets */ ++ } q[PKTQ_MAX_PREC]; ++ uint16 num_prec; /* number of precedences in use */ ++ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ ++ uint16 max; /* total max packets */ ++ uint16 len; /* total number of packets */ ++}; + -+ return 0; -+} ++#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) + ++/* forward definition of ether_addr structure used by some function prototypes */ + -+/* -+ * bcm47xx_pcmcia_get_status() -+ * -+ * Implements the get_status() operation for the in-kernel PCMCIA -+ * service (formerly SS_GetStatus in Card Services). Essentially just -+ * fills in bits in `status' according to internal driver state or -+ * the value of the voltage detect chipselect register. -+ * -+ * As a debugging note, during card startup, the PCMCIA core issues -+ * three set_socket() commands in a row the first with RESET deasserted, -+ * the second with RESET asserted, and the last with RESET deasserted -+ * again. Following the third set_socket(), a get_status() command will -+ * be issued. The kernel is looking for the SS_READY flag (see -+ * setup_socket(), reset_socket(), and unreset_socket() in cs.c). -+ * -+ * Returns: 0 -+ */ -+static int -+bcm47xx_pcmcia_get_status(unsigned int sock, unsigned int *status) -+{ -+ struct pcmcia_state state; ++struct ether_addr; + ++/* operations on a specific precedence in packet queue */ + -+ if ((pcmcia_low_level->socket_state(sock, &state)) < 0) { -+ printk(KERN_ERR "Unable to get PCMCIA status from kernel.\n"); -+ return -1; -+ } ++#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) ++#define pktq_plen(pq, prec) ((pq)->q[prec].len) ++#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) ++#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) ++#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) + -+ pcmcia_socket[sock].k_state = state; ++#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) ++#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) + -+ *status = state.detect ? SS_DETECT : 0; ++extern void *pktq_penq(struct pktq *pq, int prec, void *p); ++extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); ++extern void *pktq_pdeq(struct pktq *pq, int prec); ++extern void *pktq_pdeq_tail(struct pktq *pq, int prec); ++/* Empty the queue at particular precedence level */ ++extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir); ++/* Remove a specified packet from its queue */ ++extern bool pktq_pdel(struct pktq *pq, void *p, int prec); + -+ *status |= state.ready ? SS_READY : 0; ++/* operations on a set of precedences in packet queue */ + -+ /* The power status of individual sockets is not available -+ * explicitly from the hardware, so we just remember the state -+ * and regurgitate it upon request: -+ */ -+ *status |= pcmcia_socket[sock].cs_state.Vcc ? SS_POWERON : 0; ++extern int pktq_mlen(struct pktq *pq, uint prec_bmp); ++extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); + -+ if (pcmcia_socket[sock].cs_state.flags & SS_IOCARD) -+ *status |= state.bvd1 ? SS_STSCHG : 0; -+ else { -+ if (state.bvd1 == 0) -+ *status |= SS_BATDEAD; -+ else if (state.bvd2 == 0) -+ *status |= SS_BATWARN; -+ } ++/* operations on packet queue as a whole */ + -+ *status |= state.vs_3v ? SS_3VCARD : 0; ++#define pktq_len(pq) ((int)(pq)->len) ++#define pktq_max(pq) ((int)(pq)->max) ++#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) ++#define pktq_full(pq) ((pq)->len >= (pq)->max) ++#define pktq_empty(pq) ((pq)->len == 0) + -+ *status |= state.vs_Xv ? SS_XVCARD : 0; ++/* operations for single precedence queues */ ++#define pktenq(pq, p) pktq_penq((pq), 0, (p)) ++#define pktenq_head(pq, p) pktq_penq_head((pq), 0, (p)) ++#define pktdeq(pq) pktq_pdeq((pq), 0) ++#define pktdeq_tail(pq) pktq_pdeq_tail((pq), 0) + -+ DEBUG(2, "\tstatus: %s%s%s%s%s%s%s%s\n", -+ (*status&SS_DETECT)?"DETECT ":"", -+ (*status&SS_READY)?"READY ":"", -+ (*status&SS_BATDEAD)?"BATDEAD ":"", -+ (*status&SS_BATWARN)?"BATWARN ":"", -+ (*status&SS_POWERON)?"POWERON ":"", -+ (*status&SS_STSCHG)?"STSCHG ":"", -+ (*status&SS_3VCARD)?"3VCARD ":"", -+ (*status&SS_XVCARD)?"XVCARD ":""); ++extern void pktq_init(struct pktq *pq, int num_prec, int max_len); ++/* prec_out may be NULL if caller is not interested in return value */ ++extern void *pktq_deq(struct pktq *pq, int *prec_out); ++extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); ++extern void *pktq_peek(struct pktq *pq, int *prec_out); ++extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); ++extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); /* Empty the entire queue */ + -+ return 0; -+} ++/* externs */ ++/* packet */ ++extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); ++extern uint pkttotlen(osl_t *osh, void *p); ++extern void *pktlast(osl_t *osh, void *p); + ++extern void pktsetprio(void *pkt, bool update_vtag); + ++#endif /* _pktq_h_ */ +diff -urN linux.old/drivers/net/wl/sbhnddma.h linux.dev/drivers/net/wl/sbhnddma.h +--- linux.old/drivers/net/wl/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/net/wl/sbhnddma.h 2006-04-28 02:20:47.000000000 +0200 +@@ -0,0 +1,284 @@ +/* -+ * bcm47xx_pcmcia_get_socket() ++ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface ++ * This supports the following chips: BCM42xx, 44xx, 47xx . + * -+ * Implements the get_socket() operation for the in-kernel PCMCIA -+ * service (formerly SS_GetSocket in Card Services). Not a very -+ * exciting routine. ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * Returns: 0 ++ * $Id: sbhnddma.h,v 1.1.1.2 2006/02/27 03:43:16 honor Exp $ + */ -+static int -+bcm47xx_pcmcia_get_socket(unsigned int sock, socket_state_t *state) -+{ -+ DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock); -+ -+ /* This information was given to us in an earlier call to set_socket(), -+ * so we're just regurgitating it here: -+ */ -+ *state = pcmcia_socket[sock].cs_state; -+ return 0; -+} + ++#ifndef _sbhnddma_h_ ++#define _sbhnddma_h_ + -+/* -+ * bcm47xx_pcmcia_set_socket() -+ * -+ * Implements the set_socket() operation for the in-kernel PCMCIA -+ * service (formerly SS_SetSocket in Card Services). We more or -+ * less punt all of this work and let the kernel handle the details -+ * of power configuration, reset, &c. We also record the value of -+ * `state' in order to regurgitate it to the PCMCIA core later. -+ * -+ * Returns: 0 ++/* DMA structure: ++ * support two DMA engines: 32 bits address or 64 bit addressing ++ * basic DMA register set is per channel(transmit or receive) ++ * a pair of channels is defined for convenience + */ -+static int -+bcm47xx_pcmcia_set_socket(unsigned int sock, socket_state_t *state) -+{ -+ struct pcmcia_configure configure; -+ -+ DEBUG(2, "\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n" -+ "\tVcc %d Vpp %d irq %d\n", -+ (state->csc_mask == 0) ? "" : "", -+ (state->csc_mask & SS_DETECT) ? "DETECT " : "", -+ (state->csc_mask & SS_READY) ? "READY " : "", -+ (state->csc_mask & SS_BATDEAD) ? "BATDEAD " : "", -+ (state->csc_mask & SS_BATWARN) ? "BATWARN " : "", -+ (state->csc_mask & SS_STSCHG) ? "STSCHG " : "", -+ (state->flags == 0) ? "" : "", -+ (state->flags & SS_PWR_AUTO) ? "PWR_AUTO " : "", -+ (state->flags & SS_IOCARD) ? "IOCARD " : "", -+ (state->flags & SS_RESET) ? "RESET " : "", -+ (state->flags & SS_SPKR_ENA) ? "SPKR_ENA " : "", -+ (state->flags & SS_OUTPUT_ENA) ? "OUTPUT_ENA " : "", -+ state->Vcc, state->Vpp, state->io_irq); -+ -+ configure.sock = sock; -+ configure.vcc = state->Vcc; -+ configure.vpp = state->Vpp; -+ configure.output = (state->flags & SS_OUTPUT_ENA) ? 1 : 0; -+ configure.speaker = (state->flags & SS_SPKR_ENA) ? 1 : 0; -+ configure.reset = (state->flags & SS_RESET) ? 1 : 0; -+ -+ if (pcmcia_low_level->configure_socket(&configure) < 0) { -+ printk(KERN_ERR "Unable to configure socket %u\n", sock); -+ return -1; -+ } + -+ pcmcia_socket[sock].cs_state = *state; -+ return 0; -+} + ++/* 32 bits addressing */ + -+/* -+ * bcm47xx_pcmcia_get_io_map() -+ * -+ * Implements the get_io_map() operation for the in-kernel PCMCIA -+ * service (formerly SS_GetIOMap in Card Services). Just returns an -+ * I/O map descriptor which was assigned earlier by a set_io_map(). -+ * -+ * Returns: 0 on success, -1 if the map index was out of range -+ */ -+static int -+bcm47xx_pcmcia_get_io_map(unsigned int sock, struct pccard_io_map *map) -+{ -+ DEBUG(2, "bcm47xx_pcmcia_get_io_map: sock %d\n", sock); ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 addr; /* descriptor ring base address (4K aligned) */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 status; /* current active descriptor, et al */ ++} dma32regs_t; + -+ if (map->map >= MAX_IO_WIN) { -+ printk(KERN_ERR "%s(): map (%d) out of range\n", -+ __FUNCTION__, map->map); -+ return -1; -+ } ++typedef volatile struct { ++ dma32regs_t xmt; /* dma tx channel */ ++ dma32regs_t rcv; /* dma rx channel */ ++} dma32regp_t; + -+ *map = pcmcia_socket[sock].io_map[map->map]; -+ return 0; -+} ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma32diag_t; + ++/* ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. ++ */ ++typedef volatile struct { ++ uint32 ctrl; /* misc control bits & bufcount */ ++ uint32 addr; /* data buffer address */ ++} dma32dd_t; + +/* -+ * bcm47xx_pcmcia_set_io_map() -+ * -+ * Implements the set_io_map() operation for the in-kernel PCMCIA -+ * service (formerly SS_SetIOMap in Card Services). We configure -+ * the map speed as requested, but override the address ranges -+ * supplied by Card Services. -+ * -+ * Returns: 0 on success, -1 on error ++ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. + */ -+int -+bcm47xx_pcmcia_set_io_map(unsigned int sock, struct pccard_io_map *map) -+{ -+ unsigned int speed; -+ unsigned long start; -+ -+ DEBUG(2, "\tmap %u speed %u\n\tstart 0x%08lx stop 0x%08lx\n" -+ "\tflags: %s%s%s%s%s%s%s%s\n", -+ map->map, map->speed, map->start, map->stop, -+ (map->flags == 0) ? "" : "", -+ (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", -+ (map->flags & MAP_16BIT) ? "16BIT " : "", -+ (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", -+ (map->flags & MAP_0WS) ? "0WS " : "", -+ (map->flags & MAP_WRPROT) ? "WRPROT " : "", -+ (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : "", -+ (map->flags & MAP_PREFETCH) ? "PREFETCH " : ""); -+ -+ if (map->map >= MAX_IO_WIN) { -+ printk(KERN_ERR "%s(): map (%d) out of range\n", -+ __FUNCTION__, map->map); -+ return -1; -+ } ++#define D32MAXRINGSZ 4096 ++#define D32RINGALIGN 4096 ++#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) + -+ if (map->flags & MAP_ACTIVE) { -+ speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_IO_SPEED; -+ pcmcia_socket[sock].speed_io = speed; -+ } ++/* transmit channel control */ ++#define XC_XE ((uint32)1 << 0) /* transmit enable */ ++#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ ++#define XC_LE ((uint32)1 << 2) /* loopback enable */ ++#define XC_FL ((uint32)1 << 4) /* flush request */ ++#define XC_AE ((uint32)3 << 16) /* address extension bits */ ++#define XC_AE_SHIFT 16 + -+ start = map->start; ++/* transmit descriptor table pointer */ ++#define XP_LD_MASK 0xfff /* last valid descriptor */ + -+ if (map->stop == 1) { -+ map->stop = PAGE_SIZE - 1; -+ } ++/* transmit channel status */ ++#define XS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define XS_XS_MASK 0xf000 /* transmit state */ ++#define XS_XS_SHIFT 12 ++#define XS_XS_DISABLED 0x0000 /* disabled */ ++#define XS_XS_ACTIVE 0x1000 /* active */ ++#define XS_XS_IDLE 0x2000 /* idle wait */ ++#define XS_XS_STOPPED 0x3000 /* stopped */ ++#define XS_XS_SUSP 0x4000 /* suspend pending */ ++#define XS_XE_MASK 0xf0000 /* transmit errors */ ++#define XS_XE_SHIFT 16 ++#define XS_XE_NOERR 0x00000 /* no error */ ++#define XS_XE_DPE 0x10000 /* descriptor protocol error */ ++#define XS_XE_DFU 0x20000 /* data fifo underrun */ ++#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ ++#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ ++#define XS_AD_MASK 0xfff00000 /* active descriptor */ ++#define XS_AD_SHIFT 20 + -+ map->start = pcmcia_socket[sock].virt_io; -+ map->stop = map->start + (map->stop - start); -+ pcmcia_socket[sock].io_map[map->map] = *map; -+ DEBUG(2, "set_io_map %d start %x stop %x\n", -+ map->map, map->start, map->stop); -+ return 0; -+} ++/* receive channel control */ ++#define RC_RE ((uint32)1 << 0) /* receive enable */ ++#define RC_RO_MASK 0xfe /* receive frame offset */ ++#define RC_RO_SHIFT 1 ++#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ ++#define RC_AE ((uint32)3 << 16) /* address extension bits */ ++#define RC_AE_SHIFT 16 ++ ++/* receive descriptor table pointer */ ++#define RP_LD_MASK 0xfff /* last valid descriptor */ ++ ++/* receive channel status */ ++#define RS_CD_MASK 0x0fff /* current descriptor pointer */ ++#define RS_RS_MASK 0xf000 /* receive state */ ++#define RS_RS_SHIFT 12 ++#define RS_RS_DISABLED 0x0000 /* disabled */ ++#define RS_RS_ACTIVE 0x1000 /* active */ ++#define RS_RS_IDLE 0x2000 /* idle wait */ ++#define RS_RS_STOPPED 0x3000 /* reserved */ ++#define RS_RE_MASK 0xf0000 /* receive errors */ ++#define RS_RE_SHIFT 16 ++#define RS_RE_NOERR 0x00000 /* no error */ ++#define RS_RE_DPE 0x10000 /* descriptor protocol error */ ++#define RS_RE_DFO 0x20000 /* data fifo overflow */ ++#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ ++#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ ++#define RS_AD_MASK 0xfff00000 /* active descriptor */ ++#define RS_AD_SHIFT 20 ++ ++/* fifoaddr */ ++#define FA_OFF_MASK 0xffff /* offset */ ++#define FA_SEL_MASK 0xf0000 /* select */ ++#define FA_SEL_SHIFT 16 ++#define FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define FA_SEL_RDD 0x40000 /* receive dma data */ ++#define FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ ++ ++/* descriptor control flags */ ++#define CTRL_BC_MASK 0x1fff /* buffer byte count */ ++#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ ++#define CTRL_AE_SHIFT 16 ++#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ ++#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ ++ ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define CTRL_CORE_MASK 0x0ff00000 ++ ++/* 64 bits addressing */ ++ ++/* dma registers per channel(xmt or rcv) */ ++typedef volatile struct { ++ uint32 control; /* enable, et al */ ++ uint32 ptr; /* last descriptor posted to chip */ ++ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ ++ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ ++ uint32 status0; /* current descriptor, xmt state */ ++ uint32 status1; /* active descriptor, xmt error */ ++} dma64regs_t; ++ ++typedef volatile struct { ++ dma64regs_t tx; /* dma64 tx channel */ ++ dma64regs_t rx; /* dma64 rx channel */ ++} dma64regp_t; + ++typedef volatile struct { /* diag access */ ++ uint32 fifoaddr; /* diag address */ ++ uint32 fifodatalow; /* low 32bits of data */ ++ uint32 fifodatahigh; /* high 32bits of data */ ++ uint32 pad; /* reserved */ ++} dma64diag_t; + +/* -+ * bcm47xx_pcmcia_get_mem_map() -+ * -+ * Implements the get_mem_map() operation for the in-kernel PCMCIA -+ * service (formerly SS_GetMemMap in Card Services). Just returns a -+ * memory map descriptor which was assigned earlier by a -+ * set_mem_map() request. -+ * -+ * Returns: 0 on success, -1 if the map index was out of range ++ * DMA Descriptor ++ * Descriptors are only read by the hardware, never written back. + */ -+static int -+bcm47xx_pcmcia_get_mem_map(unsigned int sock, struct pccard_mem_map *map) -+{ -+ DEBUG(2, "%s() for sock %u\n", __FUNCTION__, sock); -+ -+ if (map->map >= MAX_WIN) { -+ printk(KERN_ERR "%s(): map (%d) out of range\n", -+ __FUNCTION__, map->map); -+ return -1; -+ } -+ -+ *map = pcmcia_socket[sock].mem_map[map->map]; -+ return 0; -+} -+ ++typedef volatile struct { ++ uint32 ctrl1; /* misc control bits & bufcount */ ++ uint32 ctrl2; /* buffer count and address extension */ ++ uint32 addrlow; /* memory address of the date buffer, bits 31:0 */ ++ uint32 addrhigh; /* memory address of the date buffer, bits 63:32 */ ++} dma64dd_t; + +/* -+ * bcm47xx_pcmcia_set_mem_map() -+ * -+ * Implements the set_mem_map() operation for the in-kernel PCMCIA -+ * service (formerly SS_SetMemMap in Card Services). We configure -+ * the map speed as requested, but override the address ranges -+ * supplied by Card Services. -+ * -+ * Returns: 0 on success, -1 on error ++ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. + */ -+static int -+bcm47xx_pcmcia_set_mem_map(unsigned int sock, struct pccard_mem_map *map) -+{ -+ unsigned int speed; -+ unsigned long start; -+ u_long flags; ++#define D64MAXRINGSZ 8192 ++#define D64RINGALIGN 8192 ++#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) + -+ if (map->map >= MAX_WIN) { -+ printk(KERN_ERR "%s(): map (%d) out of range\n", -+ __FUNCTION__, map->map); -+ return -1; -+ } ++/* transmit channel control */ ++#define D64_XC_XE 0x00000001 /* transmit enable */ ++#define D64_XC_SE 0x00000002 /* transmit suspend request */ ++#define D64_XC_LE 0x00000004 /* loopback enable */ ++#define D64_XC_FL 0x00000010 /* flush request */ ++#define D64_XC_AE 0x00030000 /* address extension bits */ ++#define D64_XC_AE_SHIFT 16 + -+ DEBUG(2, "\tmap %u speed %u\n\tsys_start %#lx\n" -+ "\tsys_stop %#lx\n\tcard_start %#x\n" -+ "\tflags: %s%s%s%s%s%s%s%s\n", -+ map->map, map->speed, map->sys_start, map->sys_stop, -+ map->card_start, (map->flags == 0) ? "" : "", -+ (map->flags & MAP_ACTIVE) ? "ACTIVE " : "", -+ (map->flags & MAP_16BIT) ? "16BIT " : "", -+ (map->flags & MAP_AUTOSZ) ? "AUTOSZ " : "", -+ (map->flags & MAP_0WS) ? "0WS " : "", -+ (map->flags & MAP_WRPROT) ? "WRPROT " : "", -+ (map->flags & MAP_ATTRIB) ? "ATTRIB " : "", -+ (map->flags & MAP_USE_WAIT) ? "USE_WAIT " : ""); -+ -+ if (map->flags & MAP_ACTIVE) { -+ /* When clients issue RequestMap, the access speed is not always -+ * properly configured: -+ */ -+ speed = (map->speed > 0) ? map->speed : BCM47XX_PCMCIA_MEM_SPEED; ++/* transmit descriptor table pointer */ ++#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ + -+ /* TBD */ -+ if (map->flags & MAP_ATTRIB) { -+ pcmcia_socket[sock].speed_attr = speed; -+ } else { -+ pcmcia_socket[sock].speed_mem = speed; -+ } -+ } ++/* transmit channel status */ ++#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ ++#define D64_XS0_XS_SHIFT 28 ++#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ ++#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ ++#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ ++#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ ++#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ + -+ save_flags(flags); -+ cli(); -+ start = map->sys_start; ++#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ ++#define D64_XS1_XE_SHIFT 28 ++#define D64_XS1_XE_NOERR 0x00000000 /* no error */ ++#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ ++#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ ++#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ ++#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_XS1_XE_COREE 0x50000000 /* core error */ + -+ if (map->sys_stop == 0) -+ map->sys_stop = PAGE_SIZE - 1; ++/* receive channel control */ ++#define D64_RC_RE 0x00000001 /* receive enable */ ++#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ ++#define D64_RC_RO_SHIFT 1 ++#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ ++#define D64_RC_AE 0x00030000 /* address extension bits */ ++#define D64_RC_AE_SHIFT 16 + -+ if (map->flags & MAP_ATTRIB) { -+ map->sys_start = pcmcia_socket[sock].phys_attr + -+ map->card_start; -+ } else { -+ map->sys_start = pcmcia_socket[sock].phys_mem + -+ map->card_start; -+ } ++/* receive descriptor table pointer */ ++#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ + -+ map->sys_stop = map->sys_start + (map->sys_stop - start); -+ pcmcia_socket[sock].mem_map[map->map] = *map; -+ restore_flags(flags); -+ DEBUG(2, "set_mem_map %d start %x stop %x card_start %x\n", -+ map->map, map->sys_start, map->sys_stop, -+ map->card_start); -+ return 0; -+} ++/* receive channel status */ ++#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ ++#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ ++#define D64_RS0_RS_SHIFT 28 ++#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ ++#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ ++#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ ++#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ ++#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ + ++#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ ++#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ ++#define D64_RS1_RE_SHIFT 28 ++#define D64_RS1_RE_NOERR 0x00000000 /* no error */ ++#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ ++#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ ++#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ ++#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ ++#define D64_RS1_RE_COREE 0x50000000 /* core error */ + -+#if defined(CONFIG_PROC_FS) ++/* fifoaddr */ ++#define D64_FA_OFF_MASK 0xffff /* offset */ ++#define D64_FA_SEL_MASK 0xf0000 /* select */ ++#define D64_FA_SEL_SHIFT 16 ++#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ ++#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ ++#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ ++#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ ++#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ ++#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ ++#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ ++#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ ++#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ ++#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ + -+/* -+ * bcm47xx_pcmcia_proc_setup() -+ * -+ * Implements the proc_setup() operation for the in-kernel PCMCIA -+ * service (formerly SS_ProcSetup in Card Services). -+ * -+ * Returns: 0 on success, -1 on error -+ */ -+static void -+bcm47xx_pcmcia_proc_setup(unsigned int sock, struct proc_dir_entry *base) -+{ -+ struct proc_dir_entry *entry; ++/* descriptor control flags 1 */ ++#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ ++#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ ++#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ ++#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ + -+ if ((entry = create_proc_entry("status", 0, base)) == NULL) { -+ printk(KERN_ERR "Unable to install \"status\" procfs entry\n"); -+ return; -+ } ++/* descriptor control flags 2 */ ++#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ ++#define D64_CTRL2_AE 0x00030000 /* address extension bits */ ++#define D64_CTRL2_AE_SHIFT 16 + -+ entry->read_proc = bcm47xx_pcmcia_proc_status; -+ entry->data = (void *)sock; -+} ++/* control flags in the range [27:20] are core-specific and not defined here */ ++#define D64_CTRL_CORE_MASK 0x0ff00000 + + -+/* -+ * bcm47xx_pcmcia_proc_status() -+ * -+ * Implements the /proc/bus/pccard/??/status file. -+ * -+ * Returns: the number of characters added to the buffer -+ */ -+static int -+bcm47xx_pcmcia_proc_status(char *buf, char **start, off_t pos, -+ int count, int *eof, void *data) -+{ -+ char *p = buf; -+ unsigned int sock = (unsigned int)data; -+ -+ p += sprintf(p, "k_flags : %s%s%s%s%s%s%s\n", -+ pcmcia_socket[sock].k_state.detect ? "detect " : "", -+ pcmcia_socket[sock].k_state.ready ? "ready " : "", -+ pcmcia_socket[sock].k_state.bvd1 ? "bvd1 " : "", -+ pcmcia_socket[sock].k_state.bvd2 ? "bvd2 " : "", -+ pcmcia_socket[sock].k_state.wrprot ? "wrprot " : "", -+ pcmcia_socket[sock].k_state.vs_3v ? "vs_3v " : "", -+ pcmcia_socket[sock].k_state.vs_Xv ? "vs_Xv " : ""); -+ -+ p += sprintf(p, "status : %s%s%s%s%s%s%s%s%s\n", -+ pcmcia_socket[sock].k_state.detect ? "SS_DETECT " : "", -+ pcmcia_socket[sock].k_state.ready ? "SS_READY " : "", -+ pcmcia_socket[sock].cs_state.Vcc ? "SS_POWERON " : "", -+ pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? "SS_IOCARD " : "", -+ (pcmcia_socket[sock].cs_state.flags & SS_IOCARD && -+ pcmcia_socket[sock].k_state.bvd1) ? "SS_STSCHG " : "", -+ ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 && -+ (pcmcia_socket[sock].k_state.bvd1 == 0)) ? "SS_BATDEAD " : "", -+ ((pcmcia_socket[sock].cs_state.flags & SS_IOCARD) == 0 && -+ (pcmcia_socket[sock].k_state.bvd2 == 0)) ? "SS_BATWARN " : "", -+ pcmcia_socket[sock].k_state.vs_3v ? "SS_3VCARD " : "", -+ pcmcia_socket[sock].k_state.vs_Xv ? "SS_XVCARD " : ""); -+ -+ p += sprintf(p, "mask : %s%s%s%s%s\n", -+ pcmcia_socket[sock].cs_state.csc_mask & SS_DETECT ? "SS_DETECT " : "", -+ pcmcia_socket[sock].cs_state.csc_mask & SS_READY ? "SS_READY " : "", -+ pcmcia_socket[sock].cs_state.csc_mask & SS_BATDEAD ? "SS_BATDEAD " : "", -+ pcmcia_socket[sock].cs_state.csc_mask & SS_BATWARN ? "SS_BATWARN " : "", -+ pcmcia_socket[sock].cs_state.csc_mask & SS_STSCHG ? "SS_STSCHG " : ""); -+ -+ p += sprintf(p, "cs_flags : %s%s%s%s%s\n", -+ pcmcia_socket[sock].cs_state.flags & SS_PWR_AUTO ? -+ "SS_PWR_AUTO " : "", -+ pcmcia_socket[sock].cs_state.flags & SS_IOCARD ? -+ "SS_IOCARD " : "", -+ pcmcia_socket[sock].cs_state.flags & SS_RESET ? -+ "SS_RESET " : "", -+ pcmcia_socket[sock].cs_state.flags & SS_SPKR_ENA ? -+ "SS_SPKR_ENA " : "", -+ pcmcia_socket[sock].cs_state.flags & SS_OUTPUT_ENA ? -+ "SS_OUTPUT_ENA " : ""); -+ -+ p += sprintf(p, "Vcc : %d\n", pcmcia_socket[sock].cs_state.Vcc); -+ p += sprintf(p, "Vpp : %d\n", pcmcia_socket[sock].cs_state.Vpp); -+ p += sprintf(p, "irq : %d\n", pcmcia_socket[sock].cs_state.io_irq); -+ p += sprintf(p, "I/O : %u\n", pcmcia_socket[sock].speed_io); -+ p += sprintf(p, "attribute: %u\n", pcmcia_socket[sock].speed_attr); -+ p += sprintf(p, "common : %u\n", pcmcia_socket[sock].speed_mem); -+ return p-buf; -+} -+ -+ -+#endif /* defined(CONFIG_PROC_FS) */ -diff -Naur linux.old/drivers/pcmcia/bcm4710_pcmcia.c linux.dev/drivers/pcmcia/bcm4710_pcmcia.c ---- linux.old/drivers/pcmcia/bcm4710_pcmcia.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/pcmcia/bcm4710_pcmcia.c 2006-04-06 15:34:15.000000000 +0200 -@@ -0,0 +1,266 @@ -+/* -+ * BCM4710 specific pcmcia routines. -+ * -+ * Copyright 2004, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++#endif /* _sbhnddma_h_ */ +diff -urN linux.old/drivers/parport/Config.in linux.dev/drivers/parport/Config.in +--- linux.old/drivers/parport/Config.in 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/drivers/parport/Config.in 2006-04-27 19:24:19.000000000 +0200 +@@ -11,6 +11,7 @@ + tristate 'Parallel port support' CONFIG_PARPORT + if [ "$CONFIG_PARPORT" != "n" ]; then + dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT ++ dep_tristate ' Asus WL500g parallel port' CONFIG_PARPORT_SPLINK $CONFIG_PARPORT + if [ "$CONFIG_PARPORT_PC" != "n" -a "$CONFIG_SERIAL" != "n" ]; then + if [ "$CONFIG_SERIAL" = "m" ]; then + define_tristate CONFIG_PARPORT_PC_CML1 m +diff -urN linux.old/drivers/parport/Makefile linux.dev/drivers/parport/Makefile +--- linux.old/drivers/parport/Makefile 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/drivers/parport/Makefile 2006-04-27 19:24:19.000000000 +0200 +@@ -22,6 +22,7 @@ + + obj-$(CONFIG_PARPORT) += parport.o + obj-$(CONFIG_PARPORT_PC) += parport_pc.o ++obj-$(CONFIG_PARPORT_SPLINK) += parport_splink.o + obj-$(CONFIG_PARPORT_PC_PCMCIA) += parport_cs.o + obj-$(CONFIG_PARPORT_AMIGA) += parport_amiga.o + obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o +diff -urN linux.old/drivers/parport/parport_splink.c linux.dev/drivers/parport/parport_splink.c +--- linux.old/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/drivers/parport/parport_splink.c 2006-04-27 19:24:19.000000000 +0200 +@@ -0,0 +1,345 @@ ++/* Low-level parallel port routines for the ASUS WL-500g built-in port + * -+ * $Id: bcm4710_pcmcia.c,v 1.1 2005/03/16 13:50:00 wbx Exp $ ++ * Author: Nuno Grilo ++ * Based on parport_pc source + */ ++ ++#include +#include +#include -+#include -+#include +#include +#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include ++#include ++#include ++#include + -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "cs_internal.h" ++#define SPLINK_ADDRESS 0xBF800010 + -+#include -+#include -+#include ++#undef DEBUG ++ ++#ifdef DEBUG ++#define DPRINTK printk ++#else ++#define DPRINTK(stuff...) ++#endif + + -+#include -+#include -+#include -+#include -+#include ++/* __parport_splink_frob_control differs from parport_splink_frob_control in that ++ * it doesn't do any extra masking. */ ++static __inline__ unsigned char __parport_splink_frob_control (struct parport *p, ++ unsigned char mask, ++ unsigned char val) ++{ ++ struct parport_pc_private *priv = p->physport->private_data; ++ unsigned char *io = (unsigned char *) p->base; ++ unsigned char ctr = priv->ctr; ++#ifdef DEBUG_PARPORT ++ printk (KERN_DEBUG ++ "__parport_splink_frob_control(%02x,%02x): %02x -> %02x\n", ++ mask, val, ctr, ((ctr & ~mask) ^ val) & priv->ctr_writable); ++#endif ++ ctr = (ctr & ~mask) ^ val; ++ ctr &= priv->ctr_writable; /* only write writable bits. */ ++ *(io+2) = ctr; ++ priv->ctr = ctr; /* Update soft copy */ ++ return ctr; ++} + -+#include "bcm4710pcmcia.h" + -+/* Use a static var for irq dev_id */ -+static int bcm47xx_pcmcia_dev_id; + -+/* Do we think we have a card or not? */ -+static int bcm47xx_pcmcia_present = 0; ++static void parport_splink_data_forward (struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n"); ++ __parport_splink_frob_control (p, 0x20, 0); ++} + ++static void parport_splink_data_reverse (struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_data_forward called\n"); ++ __parport_splink_frob_control (p, 0x20, 0x20); ++} + -+static void bcm4710_pcmcia_reset(void) ++/* ++static void parport_splink_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ -+ extifregs_t *eir; -+ unsigned long s; -+ uint32 out0, out1, outen; ++ DPRINTK(KERN_DEBUG "parport_splink: IRQ handler called\n"); ++ parport_generic_irq(irq, (struct parport *) dev_id, regs); ++} ++*/ ++ ++static void parport_splink_enable_irq(struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_enable_irq called\n"); ++ __parport_splink_frob_control (p, 0x10, 0x10); ++} + ++static void parport_splink_disable_irq(struct parport *p) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_disable_irq called\n"); ++ __parport_splink_frob_control (p, 0x10, 0); ++} ++ ++static void parport_splink_init_state(struct pardevice *dev, struct parport_state *s) ++{ ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_init_state called\n"); ++ s->u.pc.ctr = 0xc | (dev->irq_func ? 0x10 : 0x0); ++ if (dev->irq_func && ++ dev->port->irq != PARPORT_IRQ_NONE) ++ /* Set ackIntEn */ ++ s->u.pc.ctr |= 0x10; ++} + -+ eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t)); ++static void parport_splink_save_state(struct parport *p, struct parport_state *s) ++{ ++ const struct parport_pc_private *priv = p->physport->private_data; ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_save_state called\n"); ++ s->u.pc.ctr = priv->ctr; ++} + -+ save_and_cli(s); ++static void parport_splink_restore_state(struct parport *p, struct parport_state *s) ++{ ++ struct parport_pc_private *priv = p->physport->private_data; ++ unsigned char *io = (unsigned char *) p->base; ++ unsigned char ctr = s->u.pc.ctr; + -+ /* Use gpio7 to reset the pcmcia slot */ -+ outen = readl(&eir->gpio[0].outen); -+ outen |= BCM47XX_PCMCIA_RESET; -+ out0 = readl(&eir->gpio[0].out); -+ out0 &= ~(BCM47XX_PCMCIA_RESET); -+ out1 = out0 | BCM47XX_PCMCIA_RESET; ++ DPRINTK(KERN_DEBUG "parport_splink: parport_splink_restore_state called\n"); ++ *(io+2) = ctr; ++ priv->ctr = ctr; ++} + -+ writel(out0, &eir->gpio[0].out); -+ writel(outen, &eir->gpio[0].outen); -+ mdelay(1); -+ writel(out1, &eir->gpio[0].out); -+ mdelay(1); -+ writel(out0, &eir->gpio[0].out); ++static void parport_splink_setup_interrupt(void) { ++ return; ++} + -+ restore_flags(s); ++static void parport_splink_write_data(struct parport *p, unsigned char d) { ++ DPRINTK(KERN_DEBUG "parport_splink: write data called\n"); ++ unsigned char *io = (unsigned char *) p->base; ++ *io = d; +} + ++static unsigned char parport_splink_read_data(struct parport *p) { ++ DPRINTK(KERN_DEBUG "parport_splink: read data called\n"); ++ unsigned char *io = (unsigned char *) p->base; ++ return *io; ++} + -+static int bcm4710_pcmcia_init(struct pcmcia_init *init) ++static void parport_splink_write_control(struct parport *p, unsigned char d) +{ -+ struct pci_dev *pdev; -+ extifregs_t *eir; -+ uint32 outen, intp, intm, tmp; -+ uint16 *attrsp; -+ int rc = 0, i; -+ extern unsigned long bcm4710_cpu_cycle; -+ -+ -+ if (!(pdev = pci_find_device(VENDOR_BROADCOM, SB_EXTIF, NULL))) { -+ printk(KERN_ERR "bcm4710_pcmcia: extif not found\n"); -+ return -ENODEV; -+ } -+ eir = (extifregs_t *) ioremap_nocache(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); -+ -+ /* Initialize the pcmcia i/f: 16bit no swap */ -+ writel(CF_EM_PCMCIA | CF_DS | CF_EN, &eir->pcmcia_config); -+ -+#ifdef notYet -+ -+ /* Set the timing for memory accesses */ -+ tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */ -+ tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */ -+ tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */ -+ tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */ -+ writel(tmp, &eir->pcmcia_memwait); /* 0x01020a0c for a 100Mhz clock */ -+ -+ /* Set the timing for I/O accesses */ -+ tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */ -+ tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */ -+ tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */ -+ tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */ -+ writel(tmp, &eir->pcmcia_iowait); /* 0x01020a0c for a 100Mhz clock */ -+ -+ /* Set the timing for attribute accesses */ -+ tmp = (19 / bcm4710_cpu_cycle) << 24; /* W3 = 10nS */ -+ tmp = tmp | ((29 / bcm4710_cpu_cycle) << 16); /* W2 = 20nS */ -+ tmp = tmp | ((109 / bcm4710_cpu_cycle) << 8); /* W1 = 100nS */ -+ tmp = tmp | (129 / bcm4710_cpu_cycle); /* W0 = 120nS */ -+ writel(tmp, &eir->pcmcia_attrwait); /* 0x01020a0c for a 100Mhz clock */ -+ -+#endif -+ /* Make sure gpio0 and gpio5 are inputs */ -+ outen = readl(&eir->gpio[0].outen); -+ outen &= ~(BCM47XX_PCMCIA_WP | BCM47XX_PCMCIA_STSCHG | BCM47XX_PCMCIA_RESET); -+ writel(outen, &eir->gpio[0].outen); -+ -+ /* Issue a reset to the pcmcia socket */ -+ bcm4710_pcmcia_reset(); -+ -+#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS -+ /* Setup gpio5 to be the STSCHG interrupt */ -+ intp = readl(&eir->gpiointpolarity); -+ writel(intp | BCM47XX_PCMCIA_STSCHG, &eir->gpiointpolarity); /* Active low */ -+ intm = readl(&eir->gpiointmask); -+ writel(intm | BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Enable it */ -+#endif -+ -+ DEBUG(2, "bcm4710_pcmcia after reset:\n"); -+ DEBUG(2, "\textstatus\t= 0x%08x:\n", readl(&eir->extstatus)); -+ DEBUG(2, "\tpcmcia_config\t= 0x%08x:\n", readl(&eir->pcmcia_config)); -+ DEBUG(2, "\tpcmcia_memwait\t= 0x%08x:\n", readl(&eir->pcmcia_memwait)); -+ DEBUG(2, "\tpcmcia_attrwait\t= 0x%08x:\n", readl(&eir->pcmcia_attrwait)); -+ DEBUG(2, "\tpcmcia_iowait\t= 0x%08x:\n", readl(&eir->pcmcia_iowait)); -+ DEBUG(2, "\tgpioin\t\t= 0x%08x:\n", readl(&eir->gpioin)); -+ DEBUG(2, "\tgpio_outen0\t= 0x%08x:\n", readl(&eir->gpio[0].outen)); -+ DEBUG(2, "\tgpio_out0\t= 0x%08x:\n", readl(&eir->gpio[0].out)); -+ DEBUG(2, "\tgpiointpolarity\t= 0x%08x:\n", readl(&eir->gpiointpolarity)); -+ DEBUG(2, "\tgpiointmask\t= 0x%08x:\n", readl(&eir->gpiointmask)); -+ -+#ifdef DO_BCM47XX_PCMCIA_INTERRUPTS -+ /* Request pcmcia interrupt */ -+ rc = request_irq(BCM47XX_PCMCIA_IRQ, init->handler, SA_INTERRUPT, -+ "PCMCIA Interrupt", &bcm47xx_pcmcia_dev_id); -+#endif ++ const unsigned char wm = (PARPORT_CONTROL_STROBE | ++ PARPORT_CONTROL_AUTOFD | ++ PARPORT_CONTROL_INIT | ++ PARPORT_CONTROL_SELECT); + -+ attrsp = (uint16 *)ioremap_nocache(EXTIF_PCMCIA_CFGBASE(BCM4710_EXTIF), 0x1000); -+ tmp = readw(&attrsp[0]); -+ DEBUG(2, "\tattr[0] = 0x%04x\n", tmp); -+ if ((tmp == 0x7fff) || (tmp == 0x7f00)) { -+ bcm47xx_pcmcia_present = 0; -+ } else { -+ bcm47xx_pcmcia_present = 1; ++ DPRINTK(KERN_DEBUG "parport_splink: write control called\n"); ++ /* Take this out when drivers have adapted to the newer interface. */ ++ if (d & 0x20) { ++ printk (KERN_DEBUG "%s (%s): use data_reverse for this!\n", ++ p->name, p->cad->name); ++ parport_splink_data_reverse (p); + } + -+ /* There's only one socket */ -+ return 1; ++ __parport_splink_frob_control (p, wm, d & wm); +} + -+static int bcm4710_pcmcia_shutdown(void) ++static unsigned char parport_splink_read_control(struct parport *p) +{ -+ extifregs_t *eir; -+ uint32 intm; -+ -+ eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t)); -+ -+ /* Disable the pcmcia i/f */ -+ writel(0, &eir->pcmcia_config); -+ -+ /* Reset gpio's */ -+ intm = readl(&eir->gpiointmask); -+ writel(intm & ~BCM47XX_PCMCIA_STSCHG, &eir->gpiointmask); /* Disable it */ -+ -+ free_irq(BCM47XX_PCMCIA_IRQ, &bcm47xx_pcmcia_dev_id); -+ -+ return 0; ++ const unsigned char wm = (PARPORT_CONTROL_STROBE | ++ PARPORT_CONTROL_AUTOFD | ++ PARPORT_CONTROL_INIT | ++ PARPORT_CONTROL_SELECT); ++ DPRINTK(KERN_DEBUG "parport_splink: read control called\n"); ++ const struct parport_pc_private *priv = p->physport->private_data; ++ return priv->ctr & wm; /* Use soft copy */ +} + -+static int -+bcm4710_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state) ++static unsigned char parport_splink_frob_control (struct parport *p, unsigned char mask, ++ unsigned char val) +{ -+ extifregs_t *eir; -+ -+ eir = (extifregs_t *) ioremap_nocache(BCM4710_REG_EXTIF, sizeof(extifregs_t)); -+ ++ const unsigned char wm = (PARPORT_CONTROL_STROBE | ++ PARPORT_CONTROL_AUTOFD | ++ PARPORT_CONTROL_INIT | ++ PARPORT_CONTROL_SELECT); + -+ if (sock != 0) { -+ printk(KERN_ERR "bcm4710 socket_state bad sock %d\n", sock); -+ return -1; ++ DPRINTK(KERN_DEBUG "parport_splink: frob control called\n"); ++ /* Take this out when drivers have adapted to the newer interface. */ ++ if (mask & 0x20) { ++ printk (KERN_DEBUG "%s (%s): use data_%s for this!\n", ++ p->name, p->cad->name, ++ (val & 0x20) ? "reverse" : "forward"); ++ if (val & 0x20) ++ parport_splink_data_reverse (p); ++ else ++ parport_splink_data_forward (p); + } + -+ if (bcm47xx_pcmcia_present) { -+ state->detect = 1; -+ state->ready = 1; -+ state->bvd1 = 1; -+ state->bvd2 = 1; -+ state->wrprot = (readl(&eir->gpioin) & BCM47XX_PCMCIA_WP) == BCM47XX_PCMCIA_WP; -+ state->vs_3v = 0; -+ state->vs_Xv = 0; -+ } else { -+ state->detect = 0; -+ state->ready = 0; -+ } ++ /* Restrict mask and val to control lines. */ ++ mask &= wm; ++ val &= wm; + -+ return 1; ++ return __parport_splink_frob_control (p, mask, val); +} + -+ -+static int bcm4710_pcmcia_get_irq_info(struct pcmcia_irq_info *info) ++static unsigned char parport_splink_read_status(struct parport *p) +{ -+ if (info->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1; -+ -+ info->irq = BCM47XX_PCMCIA_IRQ; -+ -+ return 0; ++ DPRINTK(KERN_DEBUG "parport_splink: read status called\n"); ++ unsigned char *io = (unsigned char *) p->base; ++ return *(io+1); +} + -+ -+static int -+bcm4710_pcmcia_configure_socket(const struct pcmcia_configure *configure) ++static void parport_splink_inc_use_count(void) +{ -+ if (configure->sock >= BCM47XX_PCMCIA_MAX_SOCK) return -1; -+ ++#ifdef MODULE ++ MOD_INC_USE_COUNT; ++#endif ++} + -+ DEBUG(2, "Vcc %dV Vpp %dV output %d speaker %d reset %d\n", configure->vcc, -+ configure->vpp, configure->output, configure->speaker, configure->reset); ++static void parport_splink_dec_use_count(void) ++{ ++#ifdef MODULE ++ MOD_DEC_USE_COUNT; ++#endif ++} + -+ if ((configure->vcc != 50) || (configure->vpp != 50)) { -+ printk("%s: bad Vcc/Vpp (%d:%d)\n", __FUNCTION__, configure->vcc, -+ configure->vpp); -+ } ++static struct parport_operations parport_splink_ops = ++{ ++ parport_splink_write_data, ++ parport_splink_read_data, + -+ if (configure->reset) { -+ /* Issue a reset to the pcmcia socket */ -+ DEBUG(1, "%s: Reseting socket\n", __FUNCTION__); -+ bcm4710_pcmcia_reset(); -+ } ++ parport_splink_write_control, ++ parport_splink_read_control, ++ parport_splink_frob_control, + ++ parport_splink_read_status, + -+ return 0; -+} ++ parport_splink_enable_irq, ++ parport_splink_disable_irq, + -+struct pcmcia_low_level bcm4710_pcmcia_ops = { -+ bcm4710_pcmcia_init, -+ bcm4710_pcmcia_shutdown, -+ bcm4710_pcmcia_socket_state, -+ bcm4710_pcmcia_get_irq_info, -+ bcm4710_pcmcia_configure_socket -+}; ++ parport_splink_data_forward, ++ parport_splink_data_reverse, + -diff -Naur linux.old/drivers/pcmcia/bcm4710pcmcia.h linux.dev/drivers/pcmcia/bcm4710pcmcia.h ---- linux.old/drivers/pcmcia/bcm4710pcmcia.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/pcmcia/bcm4710pcmcia.h 2006-04-06 15:34:15.000000000 +0200 -@@ -0,0 +1,118 @@ -+/* -+ * -+ * bcm47xx pcmcia driver -+ * -+ * Copyright 2004, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * Based on sa1100.h and include/asm-arm/arch-sa1100/pcmica.h -+ * from www.handhelds.org, -+ * and au1000_generic.c from oss.sgi.com. -+ * -+ * $Id: bcm4710pcmcia.h,v 1.1 2005/03/16 13:50:00 wbx Exp $ -+ */ ++ parport_splink_init_state, ++ parport_splink_save_state, ++ parport_splink_restore_state, + -+#if !defined(_BCM4710PCMCIA_H) -+#define _BCM4710PCMCIA_H ++ parport_splink_inc_use_count, ++ parport_splink_dec_use_count, + -+#include -+#include -+#include -+#include -+#include "cs_internal.h" ++ parport_ieee1284_epp_write_data, ++ parport_ieee1284_epp_read_data, ++ parport_ieee1284_epp_write_addr, ++ parport_ieee1284_epp_read_addr, + ++ parport_ieee1284_ecp_write_data, ++ parport_ieee1284_ecp_read_data, ++ parport_ieee1284_ecp_write_addr, + -+/* The 47xx can only support one socket */ -+#define BCM47XX_PCMCIA_MAX_SOCK 1 ++ parport_ieee1284_write_compat, ++ parport_ieee1284_read_nibble, ++ parport_ieee1284_read_byte, ++}; + -+/* In the bcm947xx gpio's are used for some pcmcia functions */ -+#define BCM47XX_PCMCIA_WP 0x01 /* Bit 0 is WP input */ -+#define BCM47XX_PCMCIA_STSCHG 0x20 /* Bit 5 is STSCHG input/interrupt */ -+#define BCM47XX_PCMCIA_RESET 0x80 /* Bit 7 is RESET */ ++/* --- Initialisation code -------------------------------- */ + -+#define BCM47XX_PCMCIA_IRQ 2 ++static struct parport *parport_splink_probe_port (unsigned long int base) ++{ ++ struct parport_pc_private *priv; ++ struct parport_operations *ops; ++ struct parport *p; + -+/* The socket driver actually works nicely in interrupt-driven form, -+ * so the (relatively infrequent) polling is "just to be sure." -+ */ -+#define BCM47XX_PCMCIA_POLL_PERIOD (2 * HZ) ++ if (check_mem_region(base, 3)) { ++ printk (KERN_DEBUG "parport (0x%lx): iomem region not available\n", base); ++ return NULL; ++ } ++ priv = kmalloc (sizeof (struct parport_pc_private), GFP_KERNEL); ++ if (!priv) { ++ printk (KERN_DEBUG "parport (0x%lx): no memory!\n", base); ++ return NULL; ++ } ++ ops = kmalloc (sizeof (struct parport_operations), GFP_KERNEL); ++ if (!ops) { ++ printk (KERN_DEBUG "parport (0x%lx): no memory for ops!\n", ++ base); ++ kfree (priv); ++ return NULL; ++ } ++ memcpy (ops, &parport_splink_ops, sizeof (struct parport_operations)); ++ priv->ctr = 0xc; ++ priv->ctr_writable = 0xff; + -+#define BCM47XX_PCMCIA_IO_SPEED (255) -+#define BCM47XX_PCMCIA_MEM_SPEED (300) ++ if (!(p = parport_register_port(base, PARPORT_IRQ_NONE, ++ PARPORT_DMA_NONE, ops))) { ++ printk (KERN_DEBUG "parport (0x%lx): registration failed!\n", ++ base); ++ kfree (priv); ++ kfree (ops); ++ return NULL; ++ } + ++ p->modes = PARPORT_MODE_PCSPP | PARPORT_MODE_SAFEININT; ++ p->size = (p->modes & PARPORT_MODE_EPP)?8:3; ++ p->private_data = priv; + -+struct pcmcia_state { -+ unsigned detect: 1, -+ ready: 1, -+ bvd1: 1, -+ bvd2: 1, -+ wrprot: 1, -+ vs_3v: 1, -+ vs_Xv: 1; -+}; ++ parport_proc_register(p); ++ request_mem_region (p->base, 3, p->name); + ++ /* Done probing. Now put the port into a sensible start-up state. */ ++ parport_splink_write_data(p, 0); ++ parport_splink_data_forward (p); + -+struct pcmcia_configure { -+ unsigned sock: 8, -+ vcc: 8, -+ vpp: 8, -+ output: 1, -+ speaker: 1, -+ reset: 1; -+}; ++ /* Now that we've told the sharing engine about the port, and ++ found out its characteristics, let the high-level drivers ++ know about it. */ ++ parport_announce_port (p); + -+struct pcmcia_irq_info { -+ unsigned int sock; -+ unsigned int irq; -+}; ++ DPRINTK(KERN_DEBUG "parport (0x%lx): init ok!\n", ++ base); ++ return p; ++} + -+/* This structure encapsulates per-socket state which we might need to -+ * use when responding to a Card Services query of some kind. -+ */ -+struct bcm47xx_pcmcia_socket { -+ socket_state_t cs_state; -+ struct pcmcia_state k_state; -+ unsigned int irq; -+ void (*handler)(void *, unsigned int); -+ void *handler_info; -+ pccard_io_map io_map[MAX_IO_WIN]; -+ pccard_mem_map mem_map[MAX_WIN]; -+ ioaddr_t virt_io, phys_attr, phys_mem; -+ unsigned short speed_io, speed_attr, speed_mem; -+}; ++static void parport_splink_unregister_port(struct parport *p) { ++ struct parport_pc_private *priv = p->private_data; ++ struct parport_operations *ops = p->ops; + -+struct pcmcia_init { -+ void (*handler)(int irq, void *dev, struct pt_regs *regs); -+}; ++ if (p->irq != PARPORT_IRQ_NONE) ++ free_irq(p->irq, p); ++ release_mem_region(p->base, 3); ++ parport_proc_unregister(p); ++ kfree (priv); ++ parport_unregister_port(p); ++ kfree (ops); ++} + -+struct pcmcia_low_level { -+ int (*init)(struct pcmcia_init *); -+ int (*shutdown)(void); -+ int (*socket_state)(unsigned sock, struct pcmcia_state *); -+ int (*get_irq_info)(struct pcmcia_irq_info *); -+ int (*configure_socket)(const struct pcmcia_configure *); -+}; + -+extern struct pcmcia_low_level bcm47xx_pcmcia_ops; ++int parport_splink_init(void) ++{ ++ int ret; ++ ++ DPRINTK(KERN_DEBUG "parport_splink init called\n"); ++ parport_splink_setup_interrupt(); ++ ret = !parport_splink_probe_port(SPLINK_ADDRESS); ++ ++ return ret; ++} + -+/* I/O pins replacing memory pins -+ * (PCMCIA System Architecture, 2nd ed., by Don Anderson, p.75) -+ * -+ * These signals change meaning when going from memory-only to -+ * memory-or-I/O interface: -+ */ -+#define iostschg bvd1 -+#define iospkr bvd2 ++void parport_splink_cleanup(void) { ++ struct parport *p = parport_enumerate(), *tmp; ++ DPRINTK(KERN_DEBUG "parport_splink cleanup called\n"); ++ if (p->size) { ++ if (p->modes & PARPORT_MODE_PCSPP) { ++ while(p) { ++ tmp = p->next; ++ parport_splink_unregister_port(p); ++ p = tmp; ++ } ++ } ++ } ++} + ++MODULE_AUTHOR("Nuno Grilo "); ++MODULE_DESCRIPTION("Parport Driver for ASUS WL-500g router builtin Port"); ++MODULE_SUPPORTED_DEVICE("ASUS WL-500g builtin Parallel Port"); ++MODULE_LICENSE("GPL"); + -+/* -+ * Declaration for implementation specific low_level operations. -+ */ -+extern struct pcmcia_low_level bcm4710_pcmcia_ops; ++module_init(parport_splink_init) ++module_exit(parport_splink_cleanup) + -+#endif /* !defined(_BCM4710PCMCIA_H) */ -diff -Naur linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h ---- linux.old/include/asm-mips/bootinfo.h 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/include/asm-mips/bootinfo.h 2006-04-06 15:34:15.000000000 +0200 +diff -urN linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h +--- linux.old/include/asm-mips/bootinfo.h 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/include/asm-mips/bootinfo.h 2006-04-27 19:24:19.000000000 +0200 @@ -37,6 +37,7 @@ #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ #define MACH_GROUP_LASAT 21 @@ -21942,9 +19939,9 @@ diff -Naur linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/boot * Valid machtype for group TITAN */ #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ -diff -Naur linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h ---- linux.old/include/asm-mips/cpu.h 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/include/asm-mips/cpu.h 2006-04-06 15:34:15.000000000 +0200 +diff -urN linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h +--- linux.old/include/asm-mips/cpu.h 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/include/asm-mips/cpu.h 2006-04-27 19:24:19.000000000 +0200 @@ -22,6 +22,11 @@ spec. */ @@ -21993,9 +19990,9 @@ diff -Naur linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h /* * ISA Level encodings -diff -Naur linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h ---- linux.old/include/asm-mips/r4kcache.h 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/include/asm-mips/r4kcache.h 2006-04-06 15:34:15.000000000 +0200 +diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h +--- linux.old/include/asm-mips/r4kcache.h 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/include/asm-mips/r4kcache.h 2006-04-27 19:24:19.000000000 +0200 @@ -658,4 +658,17 @@ cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } @@ -22014,9 +20011,9 @@ diff -Naur linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kc +} + #endif /* __ASM_R4KCACHE_H */ -diff -Naur linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial.h ---- linux.old/include/asm-mips/serial.h 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/include/asm-mips/serial.h 2006-04-06 15:34:15.000000000 +0200 +diff -urN linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial.h +--- linux.old/include/asm-mips/serial.h 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/include/asm-mips/serial.h 2006-04-27 19:24:19.000000000 +0200 @@ -223,6 +223,13 @@ #define TXX927_SERIAL_PORT_DEFNS #endif @@ -22039,9 +20036,9 @@ diff -Naur linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial COBALT_SERIAL_PORT_DEFNS \ DDB5477_SERIAL_PORT_DEFNS \ EV96100_SERIAL_PORT_DEFNS \ -diff -Naur linux.old/init/do_mounts.c linux.dev/init/do_mounts.c ---- linux.old/init/do_mounts.c 2006-04-06 15:38:09.000000000 +0200 -+++ linux.dev/init/do_mounts.c 2006-04-06 15:34:15.000000000 +0200 +diff -urN linux.old/init/do_mounts.c linux.dev/init/do_mounts.c +--- linux.old/init/do_mounts.c 2006-04-27 18:04:38.000000000 +0200 ++++ linux.dev/init/do_mounts.c 2006-04-27 19:24:19.000000000 +0200 @@ -254,7 +254,13 @@ { "ftlb", 0x2c08 }, { "ftlc", 0x2c10 }, diff --git a/target/linux/brcm-2.4/patches/009-wrt54g3g_pcmcia.patch b/target/linux/brcm-2.4/patches/009-wrt54g3g_pcmcia.patch new file mode 100644 index 0000000000..0759eeb40e --- /dev/null +++ b/target/linux/brcm-2.4/patches/009-wrt54g3g_pcmcia.patch @@ -0,0 +1,119 @@ +diff -urN linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/pcibios.c +--- linux.old/arch/mips/bcm947xx/pcibios.c 2006-04-07 21:20:59.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/pcibios.c 2006-04-08 03:17:59.000000000 +0200 +@@ -157,6 +157,7 @@ + + static u32 pci_iobase = 0x100; + static u32 pci_membase = SB_PCI_DMA; ++static u32 pcmcia_membase = 0x40004000; + + void __init + pcibios_fixup_bus(struct pci_bus *b) +@@ -188,7 +189,7 @@ + /* Fix up resource bases */ + for (pos = 0; pos < 6; pos++) { + res = &d->resource[pos]; +- base = (res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase; ++ base = (res->flags & IORESOURCE_IO) ? &pci_iobase : ((b->number == 2) ? &pcmcia_membase : &pci_membase); + if (res->end) { + size = res->end - res->start + 1; + if (*base & (size - 1)) +@@ -308,7 +309,12 @@ + where = PCI_BASE_ADDRESS_0 + (resource * 4); + size = res->end - res->start; + pci_read_config_dword(dev, where, ®); +- reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); ++ ++ if (dev->bus->number == 1) ++ reg = (reg & size) | (((u32)(res->start - root->start)) & ~size); ++ else ++ reg = res->start; ++ + pci_write_config_dword(dev, where, reg); + } + +diff -urN linux.old/drivers/pcmcia/yenta.c linux.dev/drivers/pcmcia/yenta.c +--- linux.old/drivers/pcmcia/yenta.c 2004-11-17 12:54:21.000000000 +0100 ++++ linux.dev/drivers/pcmcia/yenta.c 2006-04-11 17:47:45.000000000 +0200 +@@ -543,6 +543,9 @@ + * Probe for usable interrupts using the force + * register to generate bogus card status events. + */ ++ ++#ifndef CONFIG_BCM947XX ++ /* WRT54G3G does not like this */ + cb_writel(socket, CB_SOCKET_EVENT, -1); + cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK); + exca_writeb(socket, I365_CSCINT, 0); +@@ -557,7 +560,8 @@ + } + cb_writel(socket, CB_SOCKET_MASK, 0); + exca_writeb(socket, I365_CSCINT, 0); +- ++#endif ++ + mask = probe_irq_mask(val) & 0xffff; + + bridge_ctrl &= ~CB_BRIDGE_INTR; +@@ -578,6 +582,12 @@ + socket->cap.cb_dev = socket->dev; + socket->cap.bus = NULL; + ++#ifdef CONFIG_BCM947XX ++ /* irq mask probing is broken for the WRT54G3G */ ++ if (socket->cap.irq_mask == 0) ++ socket->cap.irq_mask = 0x6f8; ++#endif ++ + printk(KERN_INFO "Yenta ISA IRQ mask 0x%04x, PCI irq %d\n", + socket->cap.irq_mask, socket->cb_irq); + } +@@ -609,6 +619,15 @@ + printk(KERN_INFO "Socket status: %08x\n", + cb_readl(socket, CB_SOCKET_STATE)); + ++ /* Generate an interrupt on card insert/remove */ ++ config_writew(socket, CB_SOCKET_MASK, CB_CSTSMASK | CB_CDMASK); ++ ++ /* Set up Multifunction Routing Status Register */ ++ config_writew(socket, 0x8C, 0x1000 /* MFUNC3 to GPIO3 */ | 0x2 /* MFUNC0 to INTA */); ++ ++ /* Switch interrupts to parallelized */ ++ config_writeb(socket, 0x92, 0x64); ++ + /* Register it with the pcmcia layer.. */ + cardbus_register(socket); + +@@ -731,7 +750,7 @@ + { + struct pci_bus *bus; + struct resource *root, *res; +- u32 start, end; ++ u32 start = 0, end = 0; + u32 align, size, min, max; + unsigned offset; + unsigned mask; +@@ -750,6 +769,15 @@ + res->end = 0; + root = pci_find_parent_resource(socket->dev, res); + ++#ifdef CONFIG_BCM947XX ++ /* default mem resources are completely fscked up on the wrt54g3g */ ++ /* bypass the entire resource allocation stuff below and just set it statically */ ++ if (type & IORESOURCE_MEM) { ++ res->start = 0x40004000; ++ res->end = res->start + 0x3fff; ++ } ++ ++#else + if (!root) + return; + +@@ -794,6 +822,7 @@ + res->start = res->end = 0; + return; + } ++#endif + + config_writel(socket, offset, res->start); + config_writel(socket, offset+4, res->end); diff --git a/target/linux/brcm-2.6/Makefile b/target/linux/brcm-2.6/Makefile index 9f99fbd635..5926e6ebcd 100644 --- a/target/linux/brcm-2.6/Makefile +++ b/target/linux/brcm-2.6/Makefile @@ -1,8 +1,8 @@ include $(TOPDIR)/rules.mk -LINUX_VERSION:=2.6.16.4 +LINUX_VERSION:=2.6.16.7 LINUX_RELEASE:=1 -LINUX_KERNEL_MD5SUM:=cb675279c9711237a06ebb8379a4da27 +LINUX_KERNEL_MD5SUM:=9682b2bd6e02f3087982d7c3f5ba824e include ../rules.mk include ./config diff --git a/target/linux/control/kernel.control b/target/linux/control/kernel.control index 5432d21a0f..be5f10940d 100644 --- a/target/linux/control/kernel.control +++ b/target/linux/control/kernel.control @@ -1,6 +1,4 @@ Package: kernel Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Virtual package for the Kernel diff --git a/target/linux/control/kmod-arptables.control b/target/linux/control/kmod-arptables.control index 757db61bb0..6896388e6e 100644 --- a/target/linux/control/kmod-arptables.control +++ b/target/linux/control/kmod-arptables.control @@ -1,6 +1,4 @@ Package: kmod-arptables Priority: optional Section: net -Maintainer: Felix Fietkau -Source: buildroot internal Description: ARP firewalling kernel modules diff --git a/target/linux/control/kmod-atm.control b/target/linux/control/kmod-atm.control index ee78ebaf14..ae07126a6a 100644 --- a/target/linux/control/kmod-atm.control +++ b/target/linux/control/kmod-atm.control @@ -1,6 +1,4 @@ Package: kmod-atm Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: ATM/ADSL support diff --git a/target/linux/control/kmod-ax25.control b/target/linux/control/kmod-ax25.control index c080d45854..18c4cef8fe 100644 --- a/target/linux/control/kmod-ax25.control +++ b/target/linux/control/kmod-ax25.control @@ -1,6 +1,4 @@ Package: kmod-ax25 Priority: optional Section: net -Maintainer: Michael Conrad -Source: buildroot internal Description: Kernel AX25 driver diff --git a/target/linux/control/kmod-bluetooth.control b/target/linux/control/kmod-bluetooth.control index a9bd41ac3b..9f5409a9b7 100644 --- a/target/linux/control/kmod-bluetooth.control +++ b/target/linux/control/kmod-bluetooth.control @@ -1,6 +1,4 @@ Package: kmod-bluetooth Priority: optional Section: sys -Maintainer: Markus Becker -Source: http://bluez.org Description: Bluetooth support diff --git a/target/linux/control/kmod-brcm-et.control b/target/linux/control/kmod-brcm-et.control index a99a79aa90..3e65bc906a 100644 --- a/target/linux/control/kmod-brcm-et.control +++ b/target/linux/control/kmod-brcm-et.control @@ -1,6 +1,4 @@ Package: kmod-brcm-et Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Proprietary driver for Broadcom Ethernet chipsets diff --git a/target/linux/control/kmod-brcm-wl.control b/target/linux/control/kmod-brcm-wl.control index c8ec871226..cf610c3673 100644 --- a/target/linux/control/kmod-brcm-wl.control +++ b/target/linux/control/kmod-brcm-wl.control @@ -1,6 +1,4 @@ Package: kmod-brcm-wl Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Proprietary driver for Broadcom Wireless chipsets diff --git a/target/linux/control/kmod-brcm-wl2.control b/target/linux/control/kmod-brcm-wl2.control index 39f714c0c5..4ae019ddf9 100644 --- a/target/linux/control/kmod-brcm-wl2.control +++ b/target/linux/control/kmod-brcm-wl2.control @@ -1,7 +1,5 @@ Package: kmod-brcm-wl2 Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Proprietary driver for Broadcom Wireless chipsets New version with multi-BSS support diff --git a/target/linux/control/kmod-cpmac.control b/target/linux/control/kmod-cpmac.control index 35d75da0f8..18f8e901b6 100644 --- a/target/linux/control/kmod-cpmac.control +++ b/target/linux/control/kmod-cpmac.control @@ -1,6 +1,4 @@ Package: kmod-cpmac Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: AR7 CPMAC ethernet driver diff --git a/target/linux/control/kmod-crypto.control b/target/linux/control/kmod-crypto.control index 1d95456b33..199d33cd7d 100644 --- a/target/linux/control/kmod-crypto.control +++ b/target/linux/control/kmod-crypto.control @@ -1,6 +1,4 @@ Package: kmod-crypto Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: CryptoAPI kernel modules diff --git a/target/linux/control/kmod-ebtables.control b/target/linux/control/kmod-ebtables.control index 3437759e2d..85c2af9bcc 100644 --- a/target/linux/control/kmod-ebtables.control +++ b/target/linux/control/kmod-ebtables.control @@ -1,6 +1,4 @@ Package: kmod-ebtables Priority: optional Section: net -Maintainer: Felix Fietkau -Source: buildroot internal Description: Ethernet bridge firewalling kernel modules diff --git a/target/linux/control/kmod-gre.control b/target/linux/control/kmod-gre.control index bcf9a62554..42db0cce54 100644 --- a/target/linux/control/kmod-gre.control +++ b/target/linux/control/kmod-gre.control @@ -1,6 +1,4 @@ Package: kmod-gre Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel GRE tunneling support diff --git a/target/linux/control/kmod-ide.control b/target/linux/control/kmod-ide.control index 52cd4747ce..2b02d82257 100644 --- a/target/linux/control/kmod-ide.control +++ b/target/linux/control/kmod-ide.control @@ -1,6 +1,4 @@ Package: kmod-ide Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel modules IDE support diff --git a/target/linux/control/kmod-ip6tables.control b/target/linux/control/kmod-ip6tables.control index 777ab14bc4..6ccf422ffb 100644 --- a/target/linux/control/kmod-ip6tables.control +++ b/target/linux/control/kmod-ip6tables.control @@ -1,6 +1,4 @@ Package: kmod-ip6tables Priority: optional Section: net -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel modules for ip6tables diff --git a/target/linux/control/kmod-ipip.control b/target/linux/control/kmod-ipip.control new file mode 100644 index 0000000000..99bf0ec34b --- /dev/null +++ b/target/linux/control/kmod-ipip.control @@ -0,0 +1,4 @@ +Package: kmod-ipip +Section: sys +Priority: optional +Description: IP in IP encapsulation support diff --git a/target/linux/control/kmod-iptables-extra.control b/target/linux/control/kmod-iptables-extra.control index 2fd67d254b..96a3b1acc0 100644 --- a/target/linux/control/kmod-iptables-extra.control +++ b/target/linux/control/kmod-iptables-extra.control @@ -1,6 +1,4 @@ Package: kmod-iptables-extra Priority: optional Section: net -Maintainer: Felix Fietkau -Source: buildroot internal Description: Extra kernel modules for iptables diff --git a/target/linux/control/kmod-iptables.control b/target/linux/control/kmod-iptables.control index 259f802a4a..7f97cc44b6 100644 --- a/target/linux/control/kmod-iptables.control +++ b/target/linux/control/kmod-iptables.control @@ -1,6 +1,4 @@ Package: kmod-iptables Priority: optional Section: net -Maintainer: OpenWrt Development Team -Source: buildroot internal Description: kernel modules for iptables diff --git a/target/linux/control/kmod-ipv6.control b/target/linux/control/kmod-ipv6.control index b2b74a1202..3a6ccc9920 100644 --- a/target/linux/control/kmod-ipv6.control +++ b/target/linux/control/kmod-ipv6.control @@ -1,6 +1,4 @@ Package: kmod-ipv6 Priority: optional Section: net -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel modules for the IPv6 protocol diff --git a/target/linux/control/kmod-loop.control b/target/linux/control/kmod-loop.control index b84e84da57..48bcb835d6 100644 --- a/target/linux/control/kmod-loop.control +++ b/target/linux/control/kmod-loop.control @@ -1,6 +1,4 @@ Package: kmod-loop Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel module for mount loopback support diff --git a/target/linux/control/kmod-lp.control b/target/linux/control/kmod-lp.control index 7cc358edf5..5d40813159 100644 --- a/target/linux/control/kmod-lp.control +++ b/target/linux/control/kmod-lp.control @@ -1,6 +1,4 @@ Package: kmod-lp Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel modules for parallel port support and line printer diff --git a/target/linux/control/kmod-mppe.control b/target/linux/control/kmod-mppe.control index f5170168b9..e4aa4c963a 100644 --- a/target/linux/control/kmod-mppe.control +++ b/target/linux/control/kmod-mppe.control @@ -1,6 +1,4 @@ Package: kmod-mppe Priority: optional Section: net -Maintainer: Felix Fietkau -Source: buildroot internal Description: Microsoft PPP Encryption/Compression support diff --git a/target/linux/control/kmod-nbd.control b/target/linux/control/kmod-nbd.control index 899e2df352..3c467223bf 100644 --- a/target/linux/control/kmod-nbd.control +++ b/target/linux/control/kmod-nbd.control @@ -1,6 +1,4 @@ Package: kmod-nbd Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel module for network block device diff --git a/target/linux/control/kmod-nls-base.control b/target/linux/control/kmod-nls-base.control index 8e5514eea8..067f5dec86 100644 --- a/target/linux/control/kmod-nls-base.control +++ b/target/linux/control/kmod-nls-base.control @@ -1,6 +1,4 @@ Package: kmod-nls-base Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel modules for basic native language support diff --git a/target/linux/control/kmod-nls-cp437.control b/target/linux/control/kmod-nls-cp437.control index 0beb993d80..f47146083f 100644 --- a/target/linux/control/kmod-nls-cp437.control +++ b/target/linux/control/kmod-nls-cp437.control @@ -1,6 +1,4 @@ Package: kmod-nls-cp437 Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel module for codepage 437 diff --git a/target/linux/control/kmod-nls-cp850.control b/target/linux/control/kmod-nls-cp850.control index 8631ba2ae8..1a7d083f90 100644 --- a/target/linux/control/kmod-nls-cp850.control +++ b/target/linux/control/kmod-nls-cp850.control @@ -1,6 +1,4 @@ Package: kmod-nls-cp850 Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel module for codepage 850 diff --git a/target/linux/control/kmod-nls-iso8859-1.control b/target/linux/control/kmod-nls-iso8859-1.control index d4e88250e6..91e40faa7a 100644 --- a/target/linux/control/kmod-nls-iso8859-1.control +++ b/target/linux/control/kmod-nls-iso8859-1.control @@ -1,6 +1,4 @@ Package: kmod-nls-iso8859-1 Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel module for iso8859-1 charset support diff --git a/target/linux/control/kmod-nls-iso8859-15.control b/target/linux/control/kmod-nls-iso8859-15.control index 33b598eca0..f565e379e9 100644 --- a/target/linux/control/kmod-nls-iso8859-15.control +++ b/target/linux/control/kmod-nls-iso8859-15.control @@ -1,6 +1,4 @@ Package: kmod-nls-iso8859-15 Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel module for iso8859-15 charset support diff --git a/target/linux/control/kmod-nls-utf8.control b/target/linux/control/kmod-nls-utf8.control index cbbd14b8a4..8c5b23c37e 100644 --- a/target/linux/control/kmod-nls-utf8.control +++ b/target/linux/control/kmod-nls-utf8.control @@ -1,6 +1,4 @@ Package: kmod-nls-utf8 Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel module for utf8 support diff --git a/target/linux/control/kmod-ppp.control b/target/linux/control/kmod-ppp.control index c1d9875d53..d851e6526e 100644 --- a/target/linux/control/kmod-ppp.control +++ b/target/linux/control/kmod-ppp.control @@ -1,6 +1,4 @@ Package: kmod-ppp Priority: optional Section: net -Maintainer: Felix Fietkau -Source: buildroot internal Description: PPP support diff --git a/target/linux/control/kmod-pppoatm.control b/target/linux/control/kmod-pppoatm.control index 31c9550c12..c777362ab7 100644 --- a/target/linux/control/kmod-pppoatm.control +++ b/target/linux/control/kmod-pppoatm.control @@ -1,6 +1,4 @@ Package: kmod-pppoatm Priority: optional Section: net -Maintainer: Felix Fietkau -Source: buildroot internal Description: PPP over ATM support diff --git a/target/linux/control/kmod-pppoe.control b/target/linux/control/kmod-pppoe.control index 23986d4382..3216e2c889 100644 --- a/target/linux/control/kmod-pppoe.control +++ b/target/linux/control/kmod-pppoe.control @@ -1,6 +1,4 @@ Package: kmod-pppoe Priority: optional Section: net -Maintainer: Felix Fietkau -Source: buildroot internal Description: PPP over Ethernet support diff --git a/target/linux/control/kmod-pwc.control b/target/linux/control/kmod-pwc.control index ecd5485b44..2860eedf3d 100644 --- a/target/linux/control/kmod-pwc.control +++ b/target/linux/control/kmod-pwc.control @@ -1,6 +1,4 @@ Package: kmod-pwc Priority: optional Section: sys -Maintainer: Nicolas Thill -Source: http://openwrt.org/cgi-bin/viewcvs.cgi/openwrt/target/linux/linux-2.4/ Description: Kernel driver for USB Philips Cameras diff --git a/target/linux/control/kmod-sangam-atm-annex-a.control b/target/linux/control/kmod-sangam-atm-annex-a.control index 8406d7034d..e07e724565 100644 --- a/target/linux/control/kmod-sangam-atm-annex-a.control +++ b/target/linux/control/kmod-sangam-atm-annex-a.control @@ -1,6 +1,4 @@ Package: kmod-sangam-atm-annex-a Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: AR7 Sangam ATM/ADSL driver (Annex A version) diff --git a/target/linux/control/kmod-sangam-atm-annex-b.control b/target/linux/control/kmod-sangam-atm-annex-b.control index 487fe88fb7..7e6ff3f63e 100644 --- a/target/linux/control/kmod-sangam-atm-annex-b.control +++ b/target/linux/control/kmod-sangam-atm-annex-b.control @@ -1,6 +1,4 @@ Package: kmod-sangam-atm-annex-b Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: AR7 Sangam ATM/ADSL driver (Annex B version) diff --git a/target/linux/control/kmod-sched.control b/target/linux/control/kmod-sched.control index 8d1363f541..53e993de47 100644 --- a/target/linux/control/kmod-sched.control +++ b/target/linux/control/kmod-sched.control @@ -1,6 +1,4 @@ Package: kmod-sched Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel schedulers for IP traffic diff --git a/target/linux/control/kmod-softdog.control b/target/linux/control/kmod-softdog.control index 88a7400572..01aff7fe8e 100644 --- a/target/linux/control/kmod-softdog.control +++ b/target/linux/control/kmod-softdog.control @@ -1,6 +1,4 @@ Package: kmod-softdog Priority: optional Section: sys -Maintainer: OpenWrt Developers Team -Source: buildroot internal Description: Kernel software watchdog driver diff --git a/target/linux/control/kmod-soundcore.control b/target/linux/control/kmod-soundcore.control index ea0323b10f..6b4fffa058 100644 --- a/target/linux/control/kmod-soundcore.control +++ b/target/linux/control/kmod-soundcore.control @@ -1,6 +1,4 @@ Package: kmod-soundcore Priority: optional Section: sys -Maintainer: OpenWrt Developers Team , David Collett -Source: buildroot internal Description: Kernel support for audio soundcards diff --git a/target/linux/control/kmod-tun.control b/target/linux/control/kmod-tun.control index c70b75353c..b60a8feee5 100644 --- a/target/linux/control/kmod-tun.control +++ b/target/linux/control/kmod-tun.control @@ -1,6 +1,4 @@ Package: kmod-tun Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel TUN/TAP extension diff --git a/target/linux/control/kmod-usb-acm.control b/target/linux/control/kmod-usb-acm.control index 1a9a2de74e..8d1fca496b 100644 --- a/target/linux/control/kmod-usb-acm.control +++ b/target/linux/control/kmod-usb-acm.control @@ -1,6 +1,4 @@ Package: kmod-usb-acm Priority: optional Section: sys -Maintainer: Waldemar Brodkorb -Source: buildroot internal Description: Kernel modules for USB modems and ISDN diff --git a/target/linux/control/kmod-usb-atm-speedtouch.control b/target/linux/control/kmod-usb-atm-speedtouch.control index 25e20739d5..e8ded69d48 100644 --- a/target/linux/control/kmod-usb-atm-speedtouch.control +++ b/target/linux/control/kmod-usb-atm-speedtouch.control @@ -1,6 +1,4 @@ Package: kmod-usb-atm-speedtouch Priority: optional Section: sys -Maintainer: Jonathan McDowell -Source: buildroot internal Description: Kernel driver for USB Speedtouch ADSL modem diff --git a/target/linux/control/kmod-usb-audio.control b/target/linux/control/kmod-usb-audio.control index 367c590570..d30b8f2c70 100644 --- a/target/linux/control/kmod-usb-audio.control +++ b/target/linux/control/kmod-usb-audio.control @@ -1,7 +1,5 @@ Package: kmod-usb-audio Priority: optional Section: sys -Maintainer: David Collett -Source: buildroot internal Depends: kmod-soundcore Description: Kernel Support for USB Soundcards diff --git a/target/linux/control/kmod-usb-core.control b/target/linux/control/kmod-usb-core.control index 2e69662969..fa1c13bbd8 100644 --- a/target/linux/control/kmod-usb-core.control +++ b/target/linux/control/kmod-usb-core.control @@ -1,6 +1,4 @@ Package: kmod-usb-core Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel Support for USB diff --git a/target/linux/control/kmod-usb-ohci.control b/target/linux/control/kmod-usb-ohci.control index adb6e27635..3d0edc863c 100644 --- a/target/linux/control/kmod-usb-ohci.control +++ b/target/linux/control/kmod-usb-ohci.control @@ -1,6 +1,4 @@ Package: kmod-usb-ohci Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel driver for OHCI USB controllers diff --git a/target/linux/control/kmod-usb-printer.control b/target/linux/control/kmod-usb-printer.control index b9f13fec6c..1c47a3d176 100644 --- a/target/linux/control/kmod-usb-printer.control +++ b/target/linux/control/kmod-usb-printer.control @@ -1,6 +1,4 @@ Package: kmod-usb-printer Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel modules for USB Printer support diff --git a/target/linux/control/kmod-usb-serial-belkin.control b/target/linux/control/kmod-usb-serial-belkin.control index 708cc44351..d907a9702b 100644 --- a/target/linux/control/kmod-usb-serial-belkin.control +++ b/target/linux/control/kmod-usb-serial-belkin.control @@ -1,6 +1,4 @@ Package: kmod-usb-serial-belkin Priority: optional Section: sys -Maintainer: OpenWrt Developers Team -Source: buildroot internal Description: Kernel Support for Belkin USB-to-Serial converters diff --git a/target/linux/control/kmod-usb-serial-ftdi.control b/target/linux/control/kmod-usb-serial-ftdi.control index 16bcdca254..e845294a5f 100644 --- a/target/linux/control/kmod-usb-serial-ftdi.control +++ b/target/linux/control/kmod-usb-serial-ftdi.control @@ -1,6 +1,4 @@ Package: kmod-usb-serial-ftdi Priority: optional Section: sys -Maintainer: OpenWrt Developers Team -Source: buildroot internal Description: Kernel Support for FTDI USB-to-Serial converters diff --git a/target/linux/control/kmod-usb-serial-mct-u232.control b/target/linux/control/kmod-usb-serial-mct-u232.control index 00f2038bf0..b52b7ca7b3 100644 --- a/target/linux/control/kmod-usb-serial-mct-u232.control +++ b/target/linux/control/kmod-usb-serial-mct-u232.control @@ -1,6 +1,4 @@ Package: kmod-usb-serial-mct-u232 Priority: optional Section: sys -Maintainer: OpenWrt Developers Team -Source: buildroot internal Description: Kernel Support for Magic Control Technology USB-to-Serial converters diff --git a/target/linux/control/kmod-usb-serial-pl2303.control b/target/linux/control/kmod-usb-serial-pl2303.control index bccbdd8924..4de43bd510 100644 --- a/target/linux/control/kmod-usb-serial-pl2303.control +++ b/target/linux/control/kmod-usb-serial-pl2303.control @@ -1,6 +1,4 @@ Package: kmod-usb-serial-pl2303 Priority: optional Section: sys -Maintainer: OpenWrt Developers Team -Source: buildroot internal Description: Kernel Support for Prolific PL2303 USB-to-Serial converters diff --git a/target/linux/control/kmod-usb-serial-visor.control b/target/linux/control/kmod-usb-serial-visor.control index 7b993beafd..951c00c51f 100644 --- a/target/linux/control/kmod-usb-serial-visor.control +++ b/target/linux/control/kmod-usb-serial-visor.control @@ -1,7 +1,4 @@ Package: kmod-usb-serial-visor Priority: optional Section: sys -Maintainer: OpenWrt Developers Team -Source: buildroot internal -Description: Kernel Support for Handspring Visor / Palm m50x / Sony Clie -Driver +Description: Kernel Support for Handspring Visor / Palm m50x / Sony Clie Driver diff --git a/target/linux/control/kmod-usb-serial.control b/target/linux/control/kmod-usb-serial.control index dda5f9d01a..136fca752f 100644 --- a/target/linux/control/kmod-usb-serial.control +++ b/target/linux/control/kmod-usb-serial.control @@ -1,6 +1,4 @@ Package: kmod-usb-serial Priority: optional Section: sys -Maintainer: OpenWrt Developers Team -Source: buildroot internal Description: Kernel Support for USB-to-Serial converters diff --git a/target/linux/control/kmod-usb-storage.control b/target/linux/control/kmod-usb-storage.control index 4156a0d91d..4ee70eb8a9 100644 --- a/target/linux/control/kmod-usb-storage.control +++ b/target/linux/control/kmod-usb-storage.control @@ -1,6 +1,4 @@ Package: kmod-usb-storage Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel modules for USB storage support diff --git a/target/linux/control/kmod-usb-uhci.control b/target/linux/control/kmod-usb-uhci.control index c7e678f188..09966a8a0e 100644 --- a/target/linux/control/kmod-usb-uhci.control +++ b/target/linux/control/kmod-usb-uhci.control @@ -1,6 +1,4 @@ Package: kmod-usb-uhci Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel driver for UHCI USB controllers diff --git a/target/linux/control/kmod-usb2.control b/target/linux/control/kmod-usb2.control index 48da3a6fc8..338865e524 100644 --- a/target/linux/control/kmod-usb2.control +++ b/target/linux/control/kmod-usb2.control @@ -1,6 +1,4 @@ Package: kmod-usb2 Priority: optional Section: sys -Maintainer: Felix Fietkau -Source: buildroot internal Description: Kernel driver for USB2 controllers diff --git a/target/linux/control/kmod-videodev.control b/target/linux/control/kmod-videodev.control index c8526835c4..57c0b1cdfe 100644 --- a/target/linux/control/kmod-videodev.control +++ b/target/linux/control/kmod-videodev.control @@ -1,6 +1,4 @@ Package: kmod-videodev Priority: optional Section: sys -Maintainer: Nicolas Thill -Source: http://openwrt.org/cgi-bin/viewcvs.cgi/openwrt/target/linux/linux-2.4/ Description: Video For Linux kernel support diff --git a/target/linux/control/kmod-wd1100.control b/target/linux/control/kmod-wd1100.control index d81924e8a8..32163200ec 100644 --- a/target/linux/control/kmod-wd1100.control +++ b/target/linux/control/kmod-wd1100.control @@ -1,6 +1,4 @@ Package: kmod-wd1100 Priority: optional Section: sys -Maintainer: OpenWrt Developers Team -Source: http://openwrt.org/cgi-bin/viewcvs.cgi/openwrt/target/linux/ Description: NatSemi SC1x00 series Watchdog kernel support diff --git a/target/linux/generic-2.4/modules.mk b/target/linux/generic-2.4/modules.mk index f35e9ba56b..540ac715cc 100644 --- a/target/linux/generic-2.4/modules.mk +++ b/target/linux/generic-2.4/modules.mk @@ -12,9 +12,12 @@ $(eval $(call KMOD_template,GRE,gre,\ ,CONFIG_NET_IPGRE)) $(eval $(call KMOD_template,IMQ,imq,\ - $(MODULES_DIR)/kernel/net/*/netfilter/*IMQ*.o \ + $(MODULES_DIR)/kernel/net/ipv4/netfilter/*IMQ*.o \ $(MODULES_DIR)/kernel/drivers/net/imq.o \ )) +$(eval $(call KMOD_template,IPIP,ipip,\ + $(MODULES_DIR)/kernel/net/ipv4/ipip.o \ +,CONFIG_NET_IPIP,,60,ipip)) $(eval $(call KMOD_template,IPV6,ipv6,\ $(MODULES_DIR)/kernel/net/ipv6/ipv6.o \ @@ -39,12 +42,9 @@ $(eval $(call KMOD_template,PPPOE,pppoe,\ $(MODULES_DIR)/kernel/drivers/net/pppoe.o \ ,CONFIG_PPPOE)) -ifneq ($(wildcard $(MODULES_DIR)/kernel/net/sched/*.o),) -CONFIG_SCHED:=m -endif $(eval $(call KMOD_template,SCHED,sched,\ $(MODULES_DIR)/kernel/net/sched/*.o \ -,CONFIG_SCHED)) +)) $(eval $(call KMOD_template,TUN,tun,\ $(MODULES_DIR)/kernel/drivers/net/tun.o \ diff --git a/target/linux/generic-2.6/modules.mk b/target/linux/generic-2.6/modules.mk index ab8a5f5d51..b582400bd6 100644 --- a/target/linux/generic-2.6/modules.mk +++ b/target/linux/generic-2.6/modules.mk @@ -14,10 +14,14 @@ $(eval $(call KMOD_template,GRE,gre,\ ,CONFIG_NET_IPGRE)) $(eval $(call KMOD_template,IMQ,imq,\ - $(MODULES_DIR)/kernel/net/*/netfilter/*IMQ*.ko \ + $(MODULES_DIR)/kernel/net/ipv4/netfilter/*IMQ*.ko \ $(MODULES_DIR)/kernel/drivers/net/imq.ko \ )) +$(eval $(call KMOD_template,IPIP,ipip,\ + $(MODULES_DIR)/kernel/net/ipv4/ipip.ko \ +,CONFIG_NET_IPIP,,60,ipip)) + $(eval $(call KMOD_template,IPV6,ipv6,\ $(MODULES_DIR)/kernel/net/ipv6/ipv6.ko \ ,CONFIG_IPV6,,20,ipv6)) diff --git a/target/linux/generic-2.6/patches/005-gcc4_fix.patch b/target/linux/generic-2.6/patches/005-gcc4_fix.patch index 91da40ac37..72df58184d 100644 --- a/target/linux/generic-2.6/patches/005-gcc4_fix.patch +++ b/target/linux/generic-2.6/patches/005-gcc4_fix.patch @@ -179,7 +179,19 @@ diff -Nur linux-2.6.15.1/lib/Makefile linux-2.6.15.1-openwrt/lib/Makefile sha1.o lib-y += kobject.o kref.o kobject_uevent.o klist.o -+lib-y += ashldi3.o ashrdi3.o lshrdi3.o ++obj-y += ashldi3.o ashrdi3.o lshrdi3.o obj-y += sort.o parser.o halfmd4.o +diff -Nur linux-2.6.15.1/include/asm-arm/libgcc.h linux-2.6.15.1-openwrt/include/asm-arm/libgcc.h +--- linux-2.6.15.1/include/asm-arm/libgcc.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.15.1-openwrt/include/asm-arm/libgcc.h 2006-04-12 23:01:18.000000000 +0200 +@@ -0,0 +1,8 @@ ++#ifndef __ASM_LIBGCC_H ++#define __ASM_LIBGCC_H ++ ++#undef ARCH_NEEDS_ashldi3 ++#undef ARCH_NEEDS_ashrdi3 ++#undef ARCH_NEEDS_lshrdi3 ++ ++#endif /* __ASM_LIBGCC_H */ diff --git a/target/linux/image/au1000/Makefile b/target/linux/image/au1000/Makefile index 04a89f9b19..c7158ca761 100644 --- a/target/linux/image/au1000/Makefile +++ b/target/linux/image/au1000/Makefile @@ -1,17 +1,42 @@ include $(TOPDIR)/rules.mk -KDIR:=$(BUILD_DIR)/linux-$(KERNEL)-$(BOARD) +LOADADDR = 0x8108c8f4 # RAM start + 16M +KERNEL_ENTRY = 0x80100000 # Default kernel entry in arch/mips/Makefile +RAMSIZE = 0x04000000 # 64MB +LOADER_MAKEOPTS= \ + KDIR=$(KDIR) \ + LOADADDR=$(LOADADDR) \ + KERNEL_ENTRY=$(KERNEL_ENTRY) \ + RAMSIZE=$(RAMSIZE) -ifeq ($(FS),jffs2-8MB) +KDIR:=$(BUILD_DIR)/linux-$(KERNEL)-$(BOARD) -$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS).img: $(KDIR)/root.$(FS) - $(CP) $^ $@ +lzma-loader-clean: + $(MAKE) -C ../generic/lzma-loader $(LOADER_MAKEOPTS) clean -install: $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS).img +lzma-loader-prepare: + $(MAKE) -C ../generic/lzma-loader $(LOADER_MAKEOPTS) prepare +lzma-loader-compile: $(KDIR)/vmlinux.lzma lzma-loader-prepare + $(MAKE) -C ../generic/lzma-loader $(LOADER_MAKEOPTS) compile + +ifeq ($(IB),) +$(KDIR)/vmlinux.lzma: $(KDIR)/vmlinux + cat $^ | $(STAGING_DIR)/bin/lzma e -si -so -eos -lc1 -lp2 -pb2 > $@ || (rm -f $@ && false) + +install: $(KDIR)/vmlinux.lzma endif +ifeq ($(FS),jffs2-8MB) + +$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FSNAME).bin: $(KDIR)/root.$(FS) + $(TARGET_CROSS)objcopy -O srec -I binary --adjust-vma 0xbe000000 $(KDIR)/root.$(FS) $(KDIR)/root.srec + grep -v S7 $(KDIR)/root.srec > $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS).img + grep -v S0 $(LINUX_DIR)/arch/mips/boot/compressed/images/zImage.flash.srec >> $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS).img + +install: $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FSNAME).bin +endif ifeq ($(FS),tgz) @@ -22,15 +47,30 @@ install: $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-rootfs.tar.gz endif +ifeq ($(FS),squashfs) +$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FSNAME).bin: $(KDIR)/root.$(FS) + $(TARGET_CROSS)objcopy -O srec -I binary --adjust-vma 0xbe000000 $(KDIR)/root.$(FS) $(KDIR)/root.srec + grep -v S7 $(KDIR)/root.srec > $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS).img + grep -v S0 $(LINUX_DIR)/arch/mips/boot/compressed/images/zImage.flash.srec >> $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS).img -$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-vmlinuz: $(KDIR)/vmlinux - $(CP) $^ $@ +endif +$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-vmlinuz: $(KDIR)/zImage.flash + $(CP) $^ $@ +ifeq ($(IB),) +clean: lzma-loader-clean +prepare: lzma-loader-prepare +compile: lzma-loader-compile +else clean: prepare: compile: -install: $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-vmlinuz +endif install-ib: + mkdir -p $(IB_DIR)/staging_dir_$(ARCH)/bin mkdir -p $(IB_DIR)/build_$(ARCH)/linux-$(KERNEL)-$(BOARD) - $(CP) $(KDIR)/bzImage $(IB_DIR)/build_$(ARCH)/linux-$(KERNEL)-$(BOARD)/ + $(CP) $(KDIR)/loader.elf $(IB_DIR)/build_$(ARCH)/ + $(CP) $(KDIR)/vmlinux.lzma $(IB_DIR)/build_$(ARCH)/linux-$(KERNEL)-$(BOARD)/ + $(TARGET_CROSS)objcopy -O srec -I binary --adjust-vma 0xbe000000 $(KDIR)/loader.elf $(KDIR)/loader.srec + grep -v S0 $(KDIR)/loader.srec > $(KDIR)/kernel.srec diff --git a/target/linux/image/jffs2.mk b/target/linux/image/jffs2.mk index 7df3aedbcf..432df3e2b1 100644 --- a/target/linux/image/jffs2.mk +++ b/target/linux/image/jffs2.mk @@ -1,4 +1,4 @@ -ifneq ($(CONFIG_mips),y) +ifneq ($(CONFIG_BIG_ENDIAN),y) JFFS2OPTS := --pad --little-endian --squash else JFFS2OPTS := --pad --big-endian --squash diff --git a/target/linux/image/squashfs.mk b/target/linux/image/squashfs.mk index 29ce5522d5..abc58da1e4 100644 --- a/target/linux/image/squashfs.mk +++ b/target/linux/image/squashfs.mk @@ -1,7 +1,7 @@ +ifneq ($(CONFIG_BIG_ENDIAN),y) endian := le - -ifeq ($(ARCH),mips) - endian := be +else +endian := be endif squashfs-prepare: diff --git a/target/linux/image/xscale/Makefile b/target/linux/image/xscale/Makefile new file mode 100644 index 0000000000..04a89f9b19 --- /dev/null +++ b/target/linux/image/xscale/Makefile @@ -0,0 +1,36 @@ +include $(TOPDIR)/rules.mk + +KDIR:=$(BUILD_DIR)/linux-$(KERNEL)-$(BOARD) + + +ifeq ($(FS),jffs2-8MB) + +$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS).img: $(KDIR)/root.$(FS) + $(CP) $^ $@ + +install: $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-$(FS).img + +endif + + +ifeq ($(FS),tgz) + +$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-rootfs.tar.gz: $(KDIR)/root.tar.gz + $(CP) $^ $@ + +install: $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-rootfs.tar.gz + +endif + + +$(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-vmlinuz: $(KDIR)/vmlinux + $(CP) $^ $@ + + +clean: +prepare: +compile: +install: $(BIN_DIR)/openwrt-$(BOARD)-$(KERNEL)-vmlinuz +install-ib: + mkdir -p $(IB_DIR)/build_$(ARCH)/linux-$(KERNEL)-$(BOARD) + $(CP) $(KDIR)/bzImage $(IB_DIR)/build_$(ARCH)/linux-$(KERNEL)-$(BOARD)/ diff --git a/target/linux/kernel.mk b/target/linux/kernel.mk index 00ff102d58..f8f4700525 100644 --- a/target/linux/kernel.mk +++ b/target/linux/kernel.mk @@ -103,8 +103,10 @@ mostlyclean: rebuild: -$(MAKE) mostlyclean - @[ -f $(LINUX_KERNEL) ] && $(MAKE) clean - $(MAKE) compile + if [ -f $(LINUX_KERNEL) ]; then \ + $(MAKE) clean; \ + fi + $(MAKE) compile $(MAKE_TRACE) clean: rm -f $(STAMP_DIR)/.linux-compile diff --git a/target/linux/package/Makefile b/target/linux/package/Makefile index 792fb7bd67..f24c845d79 100644 --- a/target/linux/package/Makefile +++ b/target/linux/package/Makefile @@ -6,8 +6,6 @@ package-y += base-files package-$(CONFIG_PACKAGE_KMOD_ALSA) += alsa package-$(CONFIG_PACKAGE_KMOD_FUSE) += fuse package-$(CONFIG_PACKAGE_KMOD_HOSTAP) += hostap -package-$(CONFIG_PACKAGE_KMOD_BCM43XX_STANDALONE) += bcm43xx-standalone -package-$(CONFIG_PACKAGE_KMOD_IEEE80211_DSCAPE) += ieee80211-dscape package-$(CONFIG_PACKAGE_KMOD_MADWIFI) += madwifi package-$(CONFIG_PACKAGE_KMOD_MADWIFI_OLD) += madwifi-old package-$(CONFIG_PACKAGE_KMOD_MINI_FO) += mini_fo @@ -20,7 +18,6 @@ package-$(CONFIG_PACKAGE_KMOD_DIAG) += diag package-$(CONFIG_PACKAGE_KMOD_WLCOMPAT) += wlcompat package-$(CONFIG_PACKAGE_KMOD_ZD1211) += zd1211 -bcm43xx-standalone-compile: ieee80211-dscape-compile wlcompat-compile: base-files-compile all: compile install diff --git a/target/linux/package/base-files/files/au1000-2.6/sbin/mount_root b/target/linux/package/base-files/files/au1000-2.6/sbin/mount_root new file mode 100755 index 0000000000..5dd1b0c562 --- /dev/null +++ b/target/linux/package/base-files/files/au1000-2.6/sbin/mount_root @@ -0,0 +1,23 @@ +#!/bin/sh +size=$(awk '/Mem:/ {l=5242880;print((s=$2/2)&- + if [ $? = 0 ] ; then + if [ $(cat /proc/mtd | wc -l) = 6 ]; then + mtd erase filesystem + jffs2root --move + else + mount -o remount,rw /dev/root / + fi + else + . /bin/firstboot + fi +fi + +mount none /tmp -t tmpfs -o remount,nosuid,nodev,mode=1777 +mkdir -p /dev/pts +mount none /dev/pts -t devpts +mount -t sysfs none /sys 2>&- diff --git a/target/linux/package/base-files/files/brcm-2.4/etc/hotplug.d/net/09-net b/target/linux/package/base-files/files/brcm-2.4/etc/hotplug.d/net/09-net index 856d26b653..9dd77963ba 100644 --- a/target/linux/package/base-files/files/brcm-2.4/etc/hotplug.d/net/09-net +++ b/target/linux/package/base-files/files/brcm-2.4/etc/hotplug.d/net/09-net @@ -1,5 +1,5 @@ #!/bin/sh -setup_eth() +setup_wl() { [ -f /proc/net/wl0 ] && { lsmod | grep wlcompat >&- || insmod wlcompat @@ -7,6 +7,9 @@ setup_eth() iwconfig "$INTERFACE" 2>&- | grep -v 'no wireless' >&- && { /sbin/wifi } +} +setup_eth() +{ [ -d /proc/switch ] || { insmod switch-core insmod switch-robo || insmod switch-adm @@ -30,6 +33,7 @@ do_register() { case "${INTERFACE%%[0-9]*}" in eth) setup_eth;; + wl) setup_wl;; esac } diff --git a/target/linux/package/base-files/files/sibyte-2.6/etc/config/network b/target/linux/package/base-files/files/sibyte-2.6/etc/config/network new file mode 100644 index 0000000000..2cc9e26717 --- /dev/null +++ b/target/linux/package/base-files/files/sibyte-2.6/etc/config/network @@ -0,0 +1,12 @@ +# Network configuration file + +## LAN configuration +lan_ifname="br0" +lan_ifnames="eth0 ath0" +lan_proto="static" +lan_ipaddr="192.168.1.1" +lan_netmask="255.255.255.0" + +## WAN configuration +wan_ifname="" +wan_proto="none" diff --git a/target/linux/package/base-files/files/sibyte-2.6/etc/inittab b/target/linux/package/base-files/files/sibyte-2.6/etc/inittab new file mode 100644 index 0000000000..6eef29efba --- /dev/null +++ b/target/linux/package/base-files/files/sibyte-2.6/etc/inittab @@ -0,0 +1,3 @@ +::sysinit:/etc/init.d/rcS +duart/0::askfirst:/bin/ash --login +#tts/1::askfirst:/bin/ash --login diff --git a/target/linux/package/base-files/files/sibyte-2.6/init b/target/linux/package/base-files/files/sibyte-2.6/init new file mode 100755 index 0000000000..1f98589eb6 --- /dev/null +++ b/target/linux/package/base-files/files/sibyte-2.6/init @@ -0,0 +1,6 @@ +#!/bin/ash +mount none /dev -t devfs +mount none /proc -t proc +mount_root failsafe +mount -o remount,rw /dev/root / +exec /bin/busybox init diff --git a/target/linux/package/base-files/files/xscale-2.6/etc/config/network b/target/linux/package/base-files/files/xscale-2.6/etc/config/network new file mode 100644 index 0000000000..f60332cd8c --- /dev/null +++ b/target/linux/package/base-files/files/xscale-2.6/etc/config/network @@ -0,0 +1,5 @@ +# Network configuration file + +## LAN configuration +lan_ifname="eth0" +lan_proto="dhcp" diff --git a/target/linux/package/base-files/files/xscale-2.6/etc/init.d/S00xscale b/target/linux/package/base-files/files/xscale-2.6/etc/init.d/S00xscale new file mode 100755 index 0000000000..9836de423b --- /dev/null +++ b/target/linux/package/base-files/files/xscale-2.6/etc/init.d/S00xscale @@ -0,0 +1,4 @@ +#!/bin/sh +mount none /proc -t proc +mount_root failsafe +mount -o remount,rw /dev/root / diff --git a/target/linux/package/base-files/files/xscale-2.6/init b/target/linux/package/base-files/files/xscale-2.6/init new file mode 100755 index 0000000000..8ca48a04c1 --- /dev/null +++ b/target/linux/package/base-files/files/xscale-2.6/init @@ -0,0 +1,3 @@ +#!/bin/ash +mount none /dev -t devfs +exec /bin/busybox init diff --git a/target/linux/package/bcm43xx-standalone/Config.in b/target/linux/package/bcm43xx-standalone/Config.in deleted file mode 100644 index 84a4702cf2..0000000000 --- a/target/linux/package/bcm43xx-standalone/Config.in +++ /dev/null @@ -1,12 +0,0 @@ -config PACKAGE_KMOD_BCM43XX_STANDALONE - prompt "kmod-bcm43xx-standalone............... Free Broadcom 43xx wireless driver (devicescape stack)" - tristate - depends LINUX_2_6_BRCM - select PACKAGE_KMOD_IEEE80211_DSCAPE - default n - help - Free driver for the Broadcom 43xx wireless chipset - This driver uses the DeviceScape 802.11 stack - - http://bcm43xx.berlios.de - diff --git a/target/linux/package/bcm43xx-standalone/Makefile b/target/linux/package/bcm43xx-standalone/Makefile deleted file mode 100644 index fed1628eee..0000000000 --- a/target/linux/package/bcm43xx-standalone/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -# $Id$ - -include $(TOPDIR)/rules.mk -include ../../rules.mk - -PKG_NAME := bcm43xx-standalone -PKG_VERSION := 060313 -PKG_RELEASE := 1 -PKG_MD%SUM := 773b26a164a54f0da544764969ca019b - -PKG_SOURCE_URL := ftp://bu3sch.de/bcm43xx-snapshots/standalone/bcm43xx/ -PKG_SOURCE := $(PKG_NAME)-$(PKG_VERSION).tar.bz2 -PKG_CAT := bzcat - -PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) - -FIRMWARE_BLOB := wl_apsta-3.130.20.0.o -FIRMWARE_BLOB_URL := http://downloads.openwrt.org/sources -FIRMWARE_BLOB_MD5SUM := e08665c5c5b66beb9c3b2dd54aa80cb3 - -include $(TOPDIR)/package/rules.mk - -$(eval $(call PKG_template,KMOD_BCM43XX_DSCAPE,kmod-$(PKG_NAME),$(LINUX_VERSION)-$(BOARD)+0.$(PKG_VERSION)-$(PKG_RELEASE),$(ARCH),kernel ($(LINUX_VERSION)-$(BOARD)-$(LINUX_RELEASE)))) - -$(PKG_BUILD_DIR)/.configured: - touch $@ - -$(PKG_BUILD_DIR)/fwcutter/.built: - mkdir -p $(PKG_BUILD_DIR)/fwcutter - $(CP) ./fwcutter/* $(PKG_BUILD_DIR)/fwcutter/ - $(SCRIPT_DIR)/download.pl "$(PKG_BUILD_DIR)/fwcutter" "$(FIRMWARE_BLOB)" "$(FIRMWARE_BLOB_MD5SUM)" $(FIRMWARE_BLOB_URL) - $(MAKE) -C $(PKG_BUILD_DIR)/fwcutter - $(PKG_BUILD_DIR)/fwcutter/fwcutter -w $(PKG_BUILD_DIR)/fwcutter $(PKG_BUILD_DIR)/fwcutter/$(FIRMWARE_BLOB) - touch $@ - -$(PKG_BUILD_DIR)/.built: $(PKG_BUILD_DIR)/fwcutter/.built - $(MAKE) -C "$(LINUX_DIR)" \ - CROSS_COMPILE="$(TARGET_CROSS)" \ - ARCH="$(LINUX_KARCH)" \ - PATH="$(TARGET_PATH)" \ - SUBDIRS="$(PKG_BUILD_DIR)" \ - LINUXINCLUDE="-I$(STAGING_DIR)/usr/include/ieee80211-dscape -I$(LINUX_DIR)/include -DBCM47XX=1" \ - modules - touch $@ - -$(IPKG_KMOD_BCM43XX_DSCAPE): - install -m0755 -d $(IDIR_KMOD_BCM43XX_DSCAPE)/lib/modules/$(LINUX_VERSION) - install -m0755 -d $(IDIR_KMOD_BCM43XX_DSCAPE)/etc/modules.d - ( \ - echo 80211; \ - echo rate_control; \ - echo bcm43xx; \ - ) >& $(IDIR_KMOD_BCM43XX_DSCAPE)/etc/modules.d/50-bcm43xx - $(CP) $(PKG_BUILD_DIR)/*.ko $(IDIR_KMOD_BCM43XX_DSCAPE)/lib/modules/$(LINUX_VERSION) - install -m0755 -d $(IDIR_KMOD_BCM43XX_DSCAPE)/lib/firmware - $(CP) $(PKG_BUILD_DIR)/fwcutter/*.fw $(IDIR_KMOD_BCM43XX_DSCAPE)/lib/firmware/ - $(IPKG_BUILD) $(IDIR_KMOD_BCM43XX_DSCAPE) $(PACKAGE_DIR) diff --git a/target/linux/package/bcm43xx-standalone/fwcutter/Makefile b/target/linux/package/bcm43xx-standalone/fwcutter/Makefile deleted file mode 100644 index 6402dca85f..0000000000 --- a/target/linux/package/bcm43xx-standalone/fwcutter/Makefile +++ /dev/null @@ -1,32 +0,0 @@ -VERSION = 0.0.1 - -FIRMWARE_INSTALL_DIR ?= /lib/firmware - -CC = cc -PREFIX = /usr/local -CFLAGS = -std=c99 -O2 -fomit-frame-pointer -Wall -pedantic -D_BSD_SOURCE -LDFLAGS = - - -OBJECTS = fwcutter.o md5.o - -CFLAGS += -DFWCUTTER_VERSION_=$(VERSION) - -all: fwcutter - -fwcutter: $(OBJECTS) - $(CC) $(CFLAGS) -o fwcutter $(OBJECTS) $(LDFLAGS) - -install: all - -install -o 0 -g 0 -m 755 fwcutter $(PREFIX)/bin/ - -clean: - -rm -f *~ *.o *.orig *.rej *.fw fwcutter - -installfw: - -if ! [ -d $(FIRMWARE_INSTALL_DIR) ]; then mkdir $(FIRMWARE_INSTALL_DIR); fi - -install -o 0 -g 0 -m 600 bcm43xx_*.fw $(FIRMWARE_INSTALL_DIR) - -# dependencies -fwcutter.o: md5.h fwcutter_list.h -md5.o: md5.h diff --git a/target/linux/package/bcm43xx-standalone/fwcutter/fwcutter.c b/target/linux/package/bcm43xx-standalone/fwcutter/fwcutter.c deleted file mode 100644 index ea98880dff..0000000000 --- a/target/linux/package/bcm43xx-standalone/fwcutter/fwcutter.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * firmware cutter for broadcom 43xx wireless driver files - * - * Copyright (c) 2005 Martin Langer , - * 2005 Michael Buesch - * 2005 Alex Beregszaszi - * - * 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 - -typedef unsigned char byte; - -#define DRIVER_UNSUPPORTED 0x01 /* no support for this driver file */ -#define BYTE_ORDER_BIG_ENDIAN 0x02 /* ppc driver files */ -#define BYTE_ORDER_LITTLE_ENDIAN 0x04 /* x86, mips driver files */ - -#define MISSING_INITVAL_08 0x10 /* initval 8 is missing */ -#define MISSING_INITVAL_80211_A 0x20 /* initvals 3,7,9,10 (802.11a cards) are empty */ - -#define FIRMWARE_UCODE_OFFSET 100 -#define FIRMWARE_UNDEFINED 0 -#define FIRMWARE_PCM_4 4 -#define FIRMWARE_PCM_5 5 -#define FIRMWARE_UCODE_2 (FIRMWARE_UCODE_OFFSET + 2) -#define FIRMWARE_UCODE_4 (FIRMWARE_UCODE_OFFSET + 4) -#define FIRMWARE_UCODE_5 (FIRMWARE_UCODE_OFFSET + 5) -#define FIRMWARE_UCODE_11 (FIRMWARE_UCODE_OFFSET + 11) - - -#define fwcutter_stringify_1(x) #x -#define fwcutter_stringify(x) fwcutter_stringify_1(x) -#define FWCUTTER_VERSION fwcutter_stringify(FWCUTTER_VERSION_) - -#include "md5.h" -#include "fwcutter_list.h" - - -struct cmdline_args { - const char *infile; - const char *postfix; - const char *target_dir; - int identify_only; -}; - -static struct cmdline_args cmdargs; -int big_endian_cpu; - - -static void write_little_endian(FILE *f, byte *buffer, int len) -{ - byte swapbuf[4]; - - while (len > 0) { - swapbuf[0] = buffer[3]; swapbuf[1] = buffer[2]; - swapbuf[2] = buffer[1]; swapbuf[3] = buffer[0]; - fwrite(swapbuf, 4, 1, f); - buffer = buffer + 4; - len = len - 4; - } -} - -static void write_big_endian(FILE *f, byte *buffer, int len) -{ - while (len > 0) { - fwrite(buffer, 4, 1, f); - buffer = buffer + 4; - len = len - 4; - } -} - -static void write_fw(const char *outfilename, uint8_t flags, byte *data, int len) -{ - FILE* fw; - char outfile[2048]; - - snprintf(outfile, sizeof(outfile), - "%s/%s", cmdargs.target_dir, outfilename); - - fw = fopen(outfile, "w"); - if (!fw) { - perror(outfile); - exit(1); - } - - if (flags & BYTE_ORDER_LITTLE_ENDIAN) - write_little_endian(fw, data, len); - else if (flags & BYTE_ORDER_BIG_ENDIAN) - write_big_endian(fw, data, len); - else - printf("unknown byteorder...\n"); - - fflush(fw); - fclose(fw); -} - -static void write_iv(uint8_t flags, byte *data) -{ - FILE* fw; - char ivfilename[2048]; - int i; - - for (i = 1; i <= 10; i++) { - - if ((flags & MISSING_INITVAL_08) && (i==8)) { - printf("*****: Sorry, initval08 is not available in driver file \"%s\".\n", cmdargs.infile); - printf("*****: Extracting firmware from an old driver is bad. Choose a more recent one.\n"); - printf("*****: Luckily bcm43xx driver doesn't include initval08 uploads at the moment.\n"); - printf("*****: But this can be added in the future...\n"); - i++; - } - - snprintf(ivfilename, sizeof(ivfilename), - "%s/bcm43xx_initval%02d%s.fw", - cmdargs.target_dir, i, cmdargs.postfix); - fw = fopen(ivfilename, "w"); - - if (!fw) { - perror(ivfilename); - exit(1); - } - - printf("extracting bcm43xx_initval%02d%s.fw ...\n", i, cmdargs.postfix); - - while (1) { - - if ((data[0]==0xff) && (data[1]==0xff) && (data[2]==0x00) && (data[3]==0x00)) { - data = data + 8; - break; - } - - if (flags & BYTE_ORDER_LITTLE_ENDIAN) - fprintf(fw, "%c%c%c%c%c%c%c%c", - data[1], data[0], /* offset */ - data[3], data[2], /* size */ - data[7], data[6], data[5], data[4]); /* value */ - else if (flags & BYTE_ORDER_BIG_ENDIAN) - fprintf(fw, "%c%c%c%c%c%c%c%c", - data[0], data[1], /* offset */ - data[2], data[3], /* size */ - data[4], data[5], data[6], data[7]); /* value */ - else { - printf("unknown byteorder...\n"); - exit(1); - } - - data = data + 8; - } - fflush(fw); - fclose(fw); - } -} - -static byte* read_file(const char* filename) -{ - FILE* file; - long len; - byte* data; - - file = fopen(filename, "rb"); - if (!file) { - perror(filename); - exit(1); - } - if (fseek(file, 0, SEEK_END)) { - perror("cannot seek"); - exit(1); - } - len = ftell(file); - fseek(file, 0, SEEK_SET); - data = malloc(len); - if (!data) { - fputs("out of memory\n", stderr); - exit(1); - } - if (fread(data, 1, len, file) != len) { - perror("cannot read"); - exit(1); - } - fclose(file); - return data; -} - -static void extract_fw(uint8_t fwtype, uint8_t flags, uint32_t pos, uint32_t length) -{ - byte* filedata; - char outfile[1024]; - - switch (fwtype) { - case FIRMWARE_UCODE_2: - case FIRMWARE_UCODE_4: - case FIRMWARE_UCODE_5: - case FIRMWARE_UCODE_11: - snprintf(outfile, sizeof(outfile), "bcm43xx_microcode%i%s.fw", - fwtype - FIRMWARE_UCODE_OFFSET, cmdargs.postfix); - break; - case FIRMWARE_PCM_4: - case FIRMWARE_PCM_5: - snprintf(outfile, sizeof(outfile), "bcm43xx_pcm%i%s.fw", - fwtype, cmdargs.postfix); - break; - default: - snprintf(outfile, sizeof(outfile), "bcm43xx_unknown.fw"); - } - - if (length > 0) { - printf("extracting %s ...\n", outfile); - filedata = read_file(cmdargs.infile); - write_fw(outfile, flags, filedata + pos, length); - free(filedata); - } else { - printf("*****: Sorry, it's not posible to extract \"%s\".\n", outfile); - printf("*****: Extracting firmware from an old driver is bad. Choose a more recent one.\n"); - - switch (fwtype) { - case FIRMWARE_UCODE_2: - printf("*****: bcm43xx driver will not work with with core revision 2.\n"); - break; - case FIRMWARE_UCODE_4: - printf("*****: bcm43xx driver will not work with with core revision 4.\n"); - break; - case FIRMWARE_UCODE_5: - printf("*****: bcm43xx driver will not work with with core revision 5 or higher.\n"); - break; - case FIRMWARE_UCODE_11: - printf("*****: Luckily bcm43xx driver doesn't include microcode11 uploads at the moment.\n"); - printf("*****: But this can be added in the future...\n"); - break; - case FIRMWARE_PCM_4: - printf("*****: bcm43xx driver will not work with with core revision 4 or smaller.\n"); - break; - case FIRMWARE_PCM_5: - printf("*****: bcm43xx driver will not work with with core revision 5 or higher.\n"); - break; - } - } -} - -static void extract_iv(uint8_t flags, uint32_t pos) -{ - byte* filedata; - - if (pos > 0) { - filedata = read_file(cmdargs.infile); - write_iv(flags, filedata + pos); - free(filedata); - } -} - -static void print_banner(void) -{ - printf("fwcutter " FWCUTTER_VERSION "\n"); -} - -static void print_file(const struct file *file) -{ - printf("%s\t", file->name); - if (strlen(file->name) < 8) - printf("\t"); - - printf("%s\t", file->version); - if (strlen(file->version) < 8) - printf("\t"); - if (strlen(file->version) < 16) - printf("\t"); - - if (!(file->flags & DRIVER_UNSUPPORTED)) { - if (file->flags & MISSING_INITVAL_80211_A) - printf("b/g "); - else - printf("a/b/g"); - } - - printf(" %s", file->md5); - printf("\n"); -} - -static void print_supported_files(void) -{ - int i; - - print_banner(); - printf("\nExtracting firmware is possible from these binary driver files:\n\n"); - printf("\t\t <802.11>\n\n"); - for (i = 0; i < FILES; i++) { - if (files[i].flags & DRIVER_UNSUPPORTED) - continue; - print_file(&files[i]); - } - printf("\n\nExtracting firmware is IMPOSSIBLE from these binary driver files:\n\n"); - printf("\t\t \n\n"); - for (i = 0; i < FILES; i++) { - if (!(files[i].flags & DRIVER_UNSUPPORTED)) - continue; - print_file(&files[i]); - } -} - -static const struct file * find_file(FILE *fd) -{ - unsigned char buffer[16384], signature[16]; - struct MD5Context md5c; - char md5sig[33]; - int i; - - MD5Init(&md5c); - while ((i = (int) fread(buffer, 1, sizeof(buffer), fd)) > 0) - MD5Update(&md5c, buffer, (unsigned) i); - MD5Final(signature, &md5c); - - snprintf(md5sig, sizeof(md5sig), - "%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", - signature[0], signature[1], signature[2], signature[3], - signature[4], signature[5], signature[6], signature[7], - signature[8], signature[9], signature[10], signature[11], - signature[12], signature[13], signature[14], signature[15]); - - for (i = 0; i < FILES; ++i) { - if (strcasecmp(md5sig, files[i].md5) == 0) { - if (files[i].flags & DRIVER_UNSUPPORTED) { - printf("Extracting firmware from this file is IMPOSSIBLE. (too old)\n"); - return 0; - } - printf("fwcutter can cut the firmware out of %s\n", cmdargs.infile); - printf(" filename : %s\n", files[i].name); - printf(" version : %s\n", files[i].version); - printf(" MD5 : %s\n\n", files[i].md5); - if (files[i].flags & MISSING_INITVAL_80211_A) { - printf("WARNING! This firmware doesn't include support for 802.11a cards.\n"); - printf("WARNING! Use this firmware only for 802.11b/g cards.\n\n"); - } - return &(files[i]); - } - } - printf("Sorry, the input file is either wrong or not supported by fwcutter.\n"); - printf("I can't find the MD5sum %s :(\n", md5sig); - - return 0; -} - -static void get_endianess(void) -{ - const unsigned char x[] = { 0xde, 0xad, 0xbe, 0xef, }; - const uint32_t *p = (uint32_t *)x; - - if (*p == 0xdeadbeef) { - big_endian_cpu = 1; - } else if (*p == 0xefbeadde) { - big_endian_cpu = 0; - } else { - printf("Confused: NUXI endian machine??\n"); - exit(-1); - } -} - -static void print_usage(int argc, char *argv[]) -{ - print_banner(); - printf("\nUsage: %s [OPTION] [driver.sys]\n", argv[0]); - printf(" -l|--list List supported driver versions\n"); - printf(" -i|--identify Only identify the driver file (don't extract)\n"); - printf(" -w|--target-dir DIR Extract and write firmware to DIR\n"); - printf(" -p|--postfix \".FOO\" Postfix for firmware filenames (.FOO.fw)\n"); - printf(" -v|--version Print fwcutter version\n"); - printf(" -h|--help Print this help\n"); - printf("\nExample: %s bcmwl5.sys\n" - " to extract the firmware blobs from bcmwl5.sys\n", argv[0]); -} - -#define ARG_MATCH 0 -#define ARG_NOMATCH 1 -#define ARG_ERROR -1 - -static int do_cmp_arg(char **argv, int *pos, - const char *template, - int allow_merged, - char **param) -{ - char *arg; - char *next_arg; - size_t arg_len, template_len; - - arg = argv[*pos]; - next_arg = argv[*pos + 1]; - arg_len = strlen(arg); - template_len = strlen(template); - - if (param) { - /* Maybe we have a merged parameter here. - * A merged parameter is "-pfoobar" for example. - */ - if (allow_merged && arg_len > template_len) { - if (memcmp(arg, template, template_len) == 0) { - *param = arg + template_len; - return ARG_MATCH; - } - return ARG_NOMATCH; - } else if (arg_len != template_len) - return ARG_NOMATCH; - *param = next_arg; - } - if (strcmp(arg, template) == 0) { - if (param) { - /* Skip the parameter on the next iteration. */ - (*pos)++; - if (*param == 0) { - printf("%s needs a parameter\n", arg); - return ARG_ERROR; - } - } - return ARG_MATCH; - } - - return ARG_NOMATCH; -} - -/* Simple and lean command line argument parsing. */ -static int cmp_arg(char **argv, int *pos, - const char *long_template, - const char *short_template, - char **param) -{ - int err; - - if (long_template) { - err = do_cmp_arg(argv, pos, long_template, 0, param); - if (err == ARG_MATCH || err == ARG_ERROR) - return err; - } - err = ARG_NOMATCH; - if (short_template) - err = do_cmp_arg(argv, pos, short_template, 1, param); - return err; -} - -static int parse_args(int argc, char *argv[]) -{ - int i, res; - char *param; - - if (argc < 2) - goto out_usage; - for (i = 1; i < argc; i++) { - res = cmp_arg(argv, &i, "--list", "-l", 0); - if (res == ARG_MATCH) { - print_supported_files(); - return 1; - } else if (res == ARG_ERROR) - goto out; - - res = cmp_arg(argv, &i, "--version", "-v", 0); - if (res == ARG_MATCH) { - print_banner(); - return 1; - } else if (res == ARG_ERROR) - goto out; - - res = cmp_arg(argv, &i, "--help", "-h", 0); - if (res == ARG_MATCH) - goto out_usage; - else if (res == ARG_ERROR) - goto out; - - res = cmp_arg(argv, &i, "--identify", "-i", 0); - if (res == ARG_MATCH) { - cmdargs.identify_only = 1; - continue; - } else if (res == ARG_ERROR) - goto out; - - res = cmp_arg(argv, &i, "--target-dir", "-w", ¶m); - if (res == ARG_MATCH) { - cmdargs.target_dir = param; - continue; - } else if (res == ARG_ERROR) - goto out; - - res = cmp_arg(argv, &i, "--postfix", "-p", ¶m); - if (res == ARG_MATCH) { - cmdargs.postfix = param; - continue; - } else if (res == ARG_ERROR) - goto out; - - cmdargs.infile = argv[i]; - break; - } - - if (!cmdargs.infile) - goto out_usage; - return 0; - -out_usage: - print_usage(argc, argv); -out: - return -1; -} - -int main(int argc, char *argv[]) -{ - FILE *fd; - const struct file *file; - int err; - - get_endianess(); - - cmdargs.target_dir = "."; - cmdargs.postfix = ""; - err = parse_args(argc, argv); - if (err == 1) - return 0; - else if (err != 0) - return err; - - fd = fopen(cmdargs.infile, "rb"); - if (!fd) { - fprintf(stderr, "Cannot open input file %s\n", cmdargs.infile); - return 2; - } - - err = -1; - file = find_file(fd); - if (!file) - goto out_close; - if (cmdargs.identify_only) { - err = 0; - goto out_close; - } - - extract_fw(FIRMWARE_UCODE_2, file->flags, file->uc2_pos, file->uc2_length); - extract_fw(FIRMWARE_UCODE_4, file->flags, file->uc4_pos, file->uc4_length); - extract_fw(FIRMWARE_UCODE_5, file->flags, file->uc5_pos, file->uc5_length); - extract_fw(FIRMWARE_UCODE_11, file->flags, file->uc11_pos, file->uc11_length); - extract_fw(FIRMWARE_PCM_4, file->flags, file->pcm4_pos, file->pcm4_length); - extract_fw(FIRMWARE_PCM_5, file->flags, file->pcm5_pos, file->pcm5_length); - extract_iv(file->flags, file->iv_pos); - - err = 0; -out_close: - fclose(fd); - - return err; -} diff --git a/target/linux/package/bcm43xx-standalone/fwcutter/fwcutter_list.h b/target/linux/package/bcm43xx-standalone/fwcutter/fwcutter_list.h deleted file mode 100644 index e855b6d6da..0000000000 --- a/target/linux/package/bcm43xx-standalone/fwcutter/fwcutter_list.h +++ /dev/null @@ -1,810 +0,0 @@ - -static const struct file { - const char *name; - const char *version; - const char *md5; - const uint8_t flags; - const uint32_t iv_pos; - const uint32_t uc2_pos; - const uint32_t uc2_length; - const uint32_t uc4_pos; - const uint32_t uc4_length; - const uint32_t uc5_pos; - const uint32_t uc5_length; - const uint32_t uc11_pos; - const uint32_t uc11_length; - const uint32_t pcm4_pos; - const uint32_t pcm4_length; - const uint32_t pcm5_pos; - const uint32_t pcm5_length; -} files[] = -{ - { - .name = "AppleAirPort2", - .version = "3.30.15.p3 (3.1.1b2)", - .md5 = "a8275cc50107a13b5be15d067b2245a0", - .flags = BYTE_ORDER_BIG_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x42550, - .uc2_pos = 0x45630, .uc2_length = 0x3d88, - .uc4_pos = 0x493bc, .uc4_length = 0x44a0, - .uc5_pos = 0x4d860, .uc5_length = 0x4ec0, - .pcm4_pos = 0x52724, .pcm4_length = 0x478, - .pcm5_pos = 0x52ba0, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.30.15.p3 (3.1.2b3)", - .md5 = "55134c1298abaa85f190331f016d4d36", - .flags = BYTE_ORDER_BIG_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x42c24, - .uc2_pos = 0x45d04, .uc2_length = 0x3d88, - .uc4_pos = 0x49a90, .uc4_length = 0x44a0, - .uc5_pos = 0x4df34, .uc5_length = 0x4ec0, - .pcm4_pos = 0x52df8, .pcm4_length = 0x478, - .pcm5_pos = 0x53274, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.30.15.p7 (3.2)", - .md5 = "e74e8d2df2e4eb97e28602f3b2dd4647", - .flags = BYTE_ORDER_BIG_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x40efc, - .uc2_pos = 0x43fdc, .uc2_length = 0x3d88, - .uc4_pos = 0x47d68, .uc4_length = 0x44a0, - .uc5_pos = 0x4c20c, .uc5_length = 0x4ec0, - .pcm4_pos = 0x510d0, .pcm4_length = 0x478, - .pcm5_pos = 0x5154c, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.30.15.p8 (3.3b1)", /* 01/19/2004 */ - .md5 = "87c74c55d2501d2e968f8c132e160b6e", - .flags = BYTE_ORDER_BIG_ENDIAN, - .iv_pos = 0x41c8c, - .uc2_pos = 0x43fe4, .uc2_length = 0x3d88, - .uc4_pos = 0x47d70, .uc4_length = 0x44b2, - .uc5_pos = 0x4c214, .uc5_length = 0x4ec0, - .pcm4_pos = 0x510d8, .pcm4_length = 0x478, - .pcm5_pos = 0x51554, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.50.37.p4 (3.4.2b1)", - .md5 = "1739c357ade1d04c9be47e8604afb1c2", - .flags = BYTE_ORDER_BIG_ENDIAN, - .iv_pos = 0x4f2b8, - .uc2_pos = 0x52da0, .uc2_length = 0x3d30, - .uc4_pos = 0x56ad4, .uc4_length = 0x45c8, - .uc5_pos = 0x5b0a0, .uc5_length = 0x5500, - .pcm4_pos = 0x605a4, .pcm4_length = 0x478, - .pcm5_pos = 0x60a20, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.50.37.p4 (3.4.3f1)", /* 09/29/2004 */ - .md5 = "c672b8c218c5dc4a55060bdfa9f58a69", - .flags = BYTE_ORDER_BIG_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x4f378, - .uc2_pos = 0x52e60, .uc2_length = 0x3d30, - .uc4_pos = 0x56b94, .uc4_length = 0x45c8, - .uc5_pos = 0x5b160, .uc5_length = 0x5500, - .pcm4_pos = 0x60664, .pcm4_length = 0x478, - .pcm5_pos = 0x60ae0, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.50.37.p4 (3.4.4f5)", - .md5 = "2c388e3e8ea9310a58cf76a3757e8ccc", - .flags = BYTE_ORDER_BIG_ENDIAN, - .iv_pos = 0x4f5f0, - .uc2_pos = 0x530d8, .uc2_length = 0x3d30, - .uc4_pos = 0x56e0c, .uc4_length = 0x45c8, - .uc5_pos = 0x5b3d8, .uc5_length = 0x5500, - .pcm4_pos = 0x608dc, .pcm4_length = 0x478, - .pcm5_pos = 0x60d58, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.50.37.p4 (3.4.4f5)", - .md5 = "3860545266b554d2955664db55452f5a", - .flags = BYTE_ORDER_BIG_ENDIAN, - .iv_pos = 0x4f5f0, - .uc2_pos = 0x530d8, .uc2_length = 0x3d30, - .uc4_pos = 0x56e0c, .uc4_length = 0x45c8, - .uc5_pos = 0x5b3d8, .uc5_length = 0x5500, - .pcm4_pos = 0x608dc, .pcm4_length = 0x478, - .pcm5_pos = 0x60d58, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.50.37.p6 (3.5f1)", - .md5 = "a62e35ee9956b286c46b145d35bd6e0c", - .flags = BYTE_ORDER_BIG_ENDIAN, - .iv_pos = 0x4f9b8, - .uc2_pos = 0x534a0, .uc2_length = 0x3d30, - .uc4_pos = 0x571d4, .uc4_length = 0x45c8, - .uc5_pos = 0x5b7a0, .uc5_length = 0x5500, - .pcm4_pos = 0x60ca4, .pcm4_length = 0x478, - .pcm5_pos = 0x61120, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.50.37.p6 (3.5f1)", - .md5 = "b6f3d2437c40277c197f0afcf12208e9", - .flags = BYTE_ORDER_BIG_ENDIAN, - .iv_pos = 0x4f9b8, - .uc2_pos = 0x534a0, .uc2_length = 0x3d30, - .uc4_pos = 0x571d4, .uc4_length = 0x45c8, - .uc5_pos = 0x5b7a0, .uc5_length = 0x5500, - .pcm4_pos = 0x60ca4, .pcm4_length = 0x478, - .pcm5_pos = 0x61120, .pcm5_length = 0x478, - }, - { - .name = "AppleAirPort2", - .version = "3.90.34.0.p11 (400.17)", /* 09/13/2005 (??) */ - .md5 = "ca0f34df2f0bfb8b5cfd83b5848d2bf5", - .flags = BYTE_ORDER_BIG_ENDIAN | - MISSING_INITVAL_80211_A, - .iv_pos = 0x4ff2c, /* A-PHY init vals empty */ - .uc2_pos = 0x5181c, .uc2_length = 0x3f48, - .uc4_pos = 0x55764, .uc4_length = 0x4df0, - .uc5_pos = 0x5a554, .uc5_length = 0x57e0, - .pcm4_pos = 0x5fd34, .pcm4_length = 0x520, - .pcm5_pos = 0x60254, .pcm5_length = 0x520, - }, - { - .name = "AppleAirPort2", - .version = "3.90.34.0.p11 (400.17)", - .md5 = "dc3a69aac95c68fe8edc760e39bbb2c9", - .flags = BYTE_ORDER_BIG_ENDIAN | - MISSING_INITVAL_80211_A, - .iv_pos = 0x50efc, /* A-PHY init vals empty */ - .uc2_pos = 0x527ec, .uc2_length = 0x3f48, - .uc4_pos = 0x56734, .uc4_length = 0x4df0, - .uc5_pos = 0x5b524, .uc5_length = 0x57e0, - .pcm4_pos = 0x60d04, .pcm4_length = 0x520, - .pcm5_pos = 0x61224, .pcm5_length = 0x520, - }, - { - .name = "AppleAirPort2", - .version = "3.90.34.0.p13 (401.2)", /* 07/10/2005 */ - .md5 = "6ecf38e5ab6997c7ec483c0d637f5c68", - .flags = BYTE_ORDER_BIG_ENDIAN | - MISSING_INITVAL_80211_A, - .iv_pos = 0x50fcc, /* A-PHY init vals empty */ - .uc2_pos = 0x528bc, .uc2_length = 0x3f48, - .uc4_pos = 0x56804, .uc4_length = 0x4df0, - .uc5_pos = 0x5b5f4, .uc5_length = 0x57e0, - .pcm4_pos = 0x60dd4, .pcm4_length = 0x520, - .pcm5_pos = 0x612f4, .pcm5_length = 0x520, - }, - { - .name = "AppleAirPort2", - .version = "3.90.34.0.p16 (404.2)", - .md5 = "7200d1aef5f413ebc811046d068b40dc", - .flags = BYTE_ORDER_BIG_ENDIAN | - MISSING_INITVAL_80211_A, - .iv_pos = 0x511ec, /* A-PHY init vals empty */ - .uc2_pos = 0x52adc, .uc2_length = 0x3f48, - .uc4_pos = 0x56a24, .uc4_length = 0x4df0, - .uc5_pos = 0x5b814, .uc5_length = 0x57f0, - .pcm4_pos = 0x61004, .pcm4_length = 0x520, - .pcm5_pos = 0x61524, .pcm5_length = 0x520, - }, - { - .name = "AppleAirPort2", - .version = "3.90.34.0.p16 (404.2)", - .md5 = "86cc708e8df3b035a1dbea41ac4eb7d2", - .flags = BYTE_ORDER_BIG_ENDIAN | - MISSING_INITVAL_80211_A, - .iv_pos = 0x5021c, /* A-PHY init vals empty */ - .uc2_pos = 0x51b0c, .uc2_length = 0x3f48, - .uc4_pos = 0x55a54, .uc4_length = 0x4df0, - .uc5_pos = 0x5a844, .uc5_length = 0x57f0, - .pcm4_pos = 0x60034, .pcm4_length = 0x520, - .pcm5_pos = 0x60554, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5.sys", - .version = "3.10.8.0", /* 10/04/2002 */ - .md5 = "288923b401e87ef76b7ae2652601ee47", - .flags = DRIVER_UNSUPPORTED, /* file differs from later ones */ - }, - { - .name = "bcmwl5.sys", - .version = "3.10.53.6", /* 04/28/2003 */ - .md5 = "b43c593fd7c2a47cdc40580fe341f674", - .flags = DRIVER_UNSUPPORTED, /* file differs from later ones */ - }, - { - .name = "bcmwl5.sys", - .version = "3.20.23.0", /* 06/13/2003 */ - .md5 = "1b1cf5e962c15abca83d1ef2b3906e2f", /* pcm5 not available, driver is too old */ - .flags = BYTE_ORDER_LITTLE_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x2a1d0, - .uc2_pos = 0x2d228, .uc2_length = 0x3da8, - .uc4_pos = 0x30fd8, .uc4_length = 0x4470, - .uc5_pos = 0x35450, .uc5_length = 0x4ba0, - .pcm4_pos = 0x39ff8, .pcm4_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.30.15.0", /* 07/17/2003 */ - .md5 = "ebf36d658d0da5b1ea667fa403919c26", - .flags = BYTE_ORDER_LITTLE_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x2c658, - .uc2_pos = 0x2f738, .uc2_length = 0x3d88, - .uc4_pos = 0x334c8, .uc4_length = 0x44a0, - .uc5_pos = 0x37970, .uc5_length = 0x4ec0, - .pcm4_pos = 0x3c838, .pcm4_length = 0x478, - .pcm5_pos = 0x3ccb8, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.40.20.0", /* 09/24/2003 */ - .md5 = "0c3fc803184f6f85e665dd012611225b", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x302f0, - .uc2_pos = 0x33d88, .uc2_length = 0x3db8, - .uc4_pos = 0x37b48, .uc4_length = 0x45d8, - .uc5_pos = 0x3c128, .uc5_length = 0x5050, - .pcm4_pos = 0x41180, .pcm4_length = 0x478, - .pcm5_pos = 0x41600, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.40.25.3", /* 10/28/2003 */ - .md5 = "5e58a3148b98c9f356cde6049435cb21", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x30970, - .uc2_pos = 0x34408, .uc2_length = 0x3db0, - .uc4_pos = 0x381c0, .uc4_length = 0x45d0, - .uc5_pos = 0x3c798, .uc5_length = 0x5050, - .pcm4_pos = 0x417f0, .pcm4_length = 0x478, - .pcm5_pos = 0x41c70, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.40.73.0", /* 06/25/2004 */ - .md5 = "52d67c5465c01913b03b7daca0cc4077", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x37398, - .uc2_pos = 0x3ae30, .uc2_length = 0x3ff0, - .uc4_pos = 0x3ee28, .uc4_length = 0x47f0, - .uc5_pos = 0x43620, .uc5_length = 0x5260, - .pcm4_pos = 0x48888, .pcm4_length = 0x478, - .pcm5_pos = 0x48d08, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.40.100.0", /* 02/07/2004 */ - .md5 = "431195b941dff794f23c2077fcbf8377", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x34d18, - .uc2_pos = 0x387b0, .uc2_length = 0x3ff0, - .uc4_pos = 0x3c7a8, .uc4_length = 0x47f0, - .uc5_pos = 0x40fa0, .uc5_length = 0x5260, - .pcm4_pos = 0x46208, .pcm4_length = 0x478, - .pcm5_pos = 0x46688, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.50.21.11", /* 02/19/2004 */ - .md5 = "ae96075a3aed5c40f1ead477ea94acd7", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x33370, - .uc2_pos = 0x36e58, .uc2_length = 0x3e00, - .uc4_pos = 0x3ac60, .uc4_length = 0x4628, - .uc5_pos = 0x3f290, .uc5_length = 0x5548, - .pcm4_pos = 0x447e0, .pcm4_length = 0x478, - .pcm5_pos = 0x44c60, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.60.7.0", /* 03/22/2004 */ - .md5 = "c5616736df4e83930780dca5795387ca", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3b988, - .uc2_pos = 0x3f580, .uc2_length = 0x3e08, - .uc4_pos = 0x43390, .uc4_length = 0x4e58, - .uc5_pos = 0x481f0, .uc5_length = 0x5608, - .pcm4_pos = 0x4d800, .pcm4_length = 0x478, - .pcm5_pos = 0x4dc80, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.60.7.5", /* 06/07/2004 */ - .md5 = "d2ae116c741c215ef3ef68603db9917f", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3b988, - .uc2_pos = 0x3f580, .uc2_length = 0x3e08, - .uc4_pos = 0x43390, .uc4_length = 0x4e58, - .uc5_pos = 0x481f0, .uc5_length = 0x5608, - .pcm4_pos = 0x4d800, .pcm4_length = 0x478, - .pcm5_pos = 0x4dc80, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.70.12.0", /* 06/02/2004 */ - .md5 = "d409b089370486521d5408baed9bffde", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x39480, - .uc2_pos = 0x3d0c8, .uc2_length = 0x3e80, - .uc4_pos = 0x40f50, .uc4_length = 0x4ed0, - .uc5_pos = 0x45e28, .uc5_length = 0x5680, - .pcm4_pos = 0x4b4b0, .pcm4_length = 0x478, - .pcm5_pos = 0x4b930, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.70.17.0", /* 06/25/2004 */ - .md5 = "d87b4e14e890091d8e64fb5c570cf192", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x39600, - .uc2_pos = 0x3d248, .uc2_length = 0x3e80, - .uc4_pos = 0x410d0, .uc4_length = 0x4ed0, - .uc5_pos = 0x45fa8, .uc5_length = 0x5680, - .pcm4_pos = 0x4b630, .pcm4_length = 0x478, - .pcm5_pos = 0x4bab0, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.70.22.0", /* 10/20/2004 */ - .md5 = "185a6dc6d655dc31c0b228cc94fb99ac", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x39a88, - .uc2_pos = 0x3d6d0, .uc2_length = 0x3e80, - .uc4_pos = 0x41558, .uc4_length = 0x4ed0, - .uc5_pos = 0x46430, .uc5_length = 0x5680, - .pcm4_pos = 0x4bab8, .pcm4_length = 0x478, - .pcm5_pos = 0x4bf38, .pcm5_length = 0x478, - }, - { - .name = "bcmwl5.sys", - .version = "3.90.41.1", /* 07/04/2005 */ - .md5 = "0a87541dd24c6f046a4bf8f671f74de2", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3bec8, - .uc2_pos = 0x3fb38, .uc2_length = 0x3f48, - .uc4_pos = 0x43a88, .uc4_length = 0x4df0, - .uc5_pos = 0x48880, .uc5_length = 0x57e0, - .pcm4_pos = 0x4e068, .pcm4_length = 0x520, - .pcm5_pos = 0x4e590, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5.sys", - .version = "3.100.35.0", /* 11/27/2004 */ - .md5 = "c3ab2d6954c7b5103770832a3a6a591b", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3de80, - .uc2_pos = 0x41af0, .uc2_length = 0x3f58, - .uc4_pos = 0x45a50, .uc4_length = 0x4df8, - .uc5_pos = 0x4a850, .uc5_length = 0x57f8, - .pcm4_pos = 0x50050, .pcm4_length = 0x520, - .pcm5_pos = 0x50578, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5.sys", - .version = "3.100.35.1", /* 02/10/2005 */ - .md5 = "da7ca369a1a3593ceac85dec2d267a08", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3df00, - .uc2_pos = 0x41b70, .uc2_length = 0x3f58, - .uc4_pos = 0x45ad0, .uc4_length = 0x4df8, - .uc5_pos = 0x4a8d0, .uc5_length = 0x57f8, - .pcm4_pos = 0x500d0, .pcm4_length = 0x520, - .pcm5_pos = 0x505f8, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5.sys", - .version = "3.100.46.0", /* 12/22/2004 */ - .md5 = "38ca1443660d0f5f06887c6a2e692aeb", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3de80, - .uc2_pos = 0x41af0, .uc2_length = 0x3f58, - .uc4_pos = 0x45a50, .uc4_length = 0x4df8, - .uc5_pos = 0x4a850, .uc5_length = 0x57f8, - .pcm4_pos = 0x50050, .pcm4_length = 0x520, - .pcm5_pos = 0x50578, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5.sys", - .version = "3.100.64.0", /* 02/11/2005 */ - .md5 = "e7debb46b9ef1f28932e533be4a3d1a9", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3e980, - .uc2_pos = 0x425f0, .uc2_length = 0x3f58, - .uc4_pos = 0x46550, .uc4_length = 0x4e00, - .uc5_pos = 0x4b358, .uc5_length = 0x5800, - .pcm4_pos = 0x50b60, .pcm4_length = 0x520, - .pcm5_pos = 0x51088, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5.sys", - .version = "3.100.64.50", /* 04/05/2005 */ - .md5 = "4b3e367b829b9b2c0c088909a617e04e", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3e900, - .uc2_pos = 0x42570, .uc2_length = 0x3f58, - .uc4_pos = 0x464d0, .uc4_length = 0x4e00, - .uc5_pos = 0x4b2d8, .uc5_length = 0x5800, - .pcm4_pos = 0x50ae0, .pcm4_length = 0x520, - .pcm5_pos = 0x51008, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5.sys", - .version = "3.100.65.1", /* 04/21/2005 */ - .md5 = "d5f1ab1aab8b81bca6f19da9554a267a", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3e980, - .uc2_pos = 0x425f0, .uc2_length = 0x3f58, - .uc4_pos = 0x46550, .uc4_length = 0x4e00, - .uc5_pos = 0x4b358, .uc5_length = 0x5800, - .pcm4_pos = 0x50b60, .pcm4_length = 0x520, - .pcm5_pos = 0x51088, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5.sys", - .version = "3.120.27.0", /* 05/19/2005 */ - .md5 = "8d49f11238815a320880fee9f98b2c92", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3f700, - .uc2_pos = 0x43370, .uc2_length = 0x3f68, - .uc4_pos = 0x472e0, .uc4_length = 0x4e10, - .uc5_pos = 0x4c0f8, .uc5_length = 0x5800, - .pcm4_pos = 0x51900, .pcm4_length = 0x520, - .pcm5_pos = 0x51e28, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5.sys", - .version = "3.140.16.0", /* 07/21/2005 */ - .md5 = "fa4a4a50b4b2647afedc676cc68c69cc", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3f700, - .uc2_pos = 0x43370, .uc2_length = 0x3f68, - .uc4_pos = 0x472e0, .uc4_length = 0x4e10, - .uc5_pos = 0x4c0f8, .uc5_length = 0x5800, - .pcm4_pos = 0x51900, .pcm4_length = 0x520, - .pcm5_pos = 0x51e28, .pcm5_length = 0x520, - }, - { - .name = "bcmwl564.sys", - .version = "3.70.17.5", /* 09/21/2004 */ - .md5 = "f5590c8784b91dfd9ee092d3040b6e40", /* for 64bit machines */ - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x566f0, - .uc2_pos = 0x5a360, .uc2_length = 0x3e80, - .uc4_pos = 0x5e1f0, .uc4_length = 0x4ed0, - .uc5_pos = 0x630d0, .uc5_length = 0x5680, - .pcm4_pos = 0x68760, .pcm4_length = 0x478, - .pcm5_pos = 0x68be0, .pcm5_length = 0x478, - }, - { - .name = "bcmwl564.sys", - .version = "3.100.64.10", /* 05/12/2005 */ - .md5 = "b8d76da338ecf2c650f5f7ca226ccf89", /* for 64bit machines */ - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x50bf0, - .uc2_pos = 0x54860, .uc2_length = 0x3f58, - .uc4_pos = 0x587c0, .uc4_length = 0x4e00, - .uc5_pos = 0x5d5d0, .uc5_length = 0x5800, - .pcm4_pos = 0x62de0, .pcm4_length = 0x520, - .pcm5_pos = 0x63310, .pcm5_length = 0x520, - }, - { - .name = "bcmwl5a.sys", - .version = "3.90.16.0", /* 12/06/2004 */ - .md5 = "e6d927deea6c75bddf84080e6c3837b7", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3b4c8, - .uc2_pos = 0x3f138, .uc2_length = 0x3f48, - .uc4_pos = 0x43088, .uc4_length = 0x4de8, - .uc5_pos = 0x47e78, .uc5_length = 0x57d8, - .pcm4_pos = 0x4d658, .pcm4_length = 0x520, - .pcm5_pos = 0x4db80, .pcm5_length = 0x520, - }, - { - .name = "d11ucode.o", - .version = "3.31.16.0 ?", /*FIXME: version correct? */ - .md5 = "31e6cac8a8129bf8f91291293e017329", - .flags = BYTE_ORDER_LITTLE_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x40, - .uc2_pos = 0x3120, .uc2_length = 0x3d88, - .uc4_pos = 0x6eac, .uc4_length = 0x44a0, - .uc5_pos = 0xb350, .uc5_length = 0x4ec0, - .pcm4_pos = 0x10214, .pcm4_length = 0x478, - .pcm5_pos = 0x10690, .pcm5_length = 0x478, - }, - { - .name = "d11ucode.o", - .version = "3.60.7.0 ? (1.3.2)", /* no version number found */ - .md5 = "7774e5dda1daa2b3f83d279552ca1cc4", /* but same fw files are also */ - .flags = BYTE_ORDER_LITTLE_ENDIAN, /* in bcmwl5.sys 3.60.7.0 */ - .iv_pos = 0x40, - .uc2_pos = 0x3c38, .uc2_length = 0x3e08, - .uc4_pos = 0x7a44, .uc4_length = 0x4e58, - .uc5_pos = 0xc8a0, .uc5_length = 0x5608, - .pcm4_pos = 0x11eac, .pcm4_length = 0x478, - .pcm5_pos = 0x12328, .pcm5_length = 0x478, - }, - { - .name = "d11ucode.o", - .version = "3.90.7.0 ? (3.90.RC7)", /* 10/14/2004 */ - .md5 = "b2580361620881b06fa810422ec8b7ce", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x60, - .uc2_pos = 0x3cd0, .uc2_length = 0x3ec0, - .uc4_pos = 0x7b94, .uc4_length = 0x4d60, - .uc5_pos = 0xc8f8, .uc5_length = 0x5750, - .pcm4_pos = 0x1204c, .pcm4_length = 0x520, - .pcm5_pos = 0x12570, .pcm5_length = 0x520, - }, - { - .name = "d11ucode.o", - .version = "3.90.37.0", - .md5 = "2543935259739a8a879ccb8386647ac7", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x60, - .uc2_pos = 0x3cd0, .uc2_length = 0x3f48, - .uc4_pos = 0x7c1c, .uc4_length = 0x4df0, - .uc5_pos = 0xca10, .uc5_length = 0x57e0, - .pcm4_pos = 0x121f4, .pcm4_length = 0x520, - .pcm5_pos = 0x12718, .pcm5_length = 0x520, - }, - { - .name = "wl.o", - .version = "3.31.15.0", /* 07/28/2003 */ - .md5 = "a85af65b5ae1d64ee11eab714faab843", - .flags = BYTE_ORDER_LITTLE_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x32270, - .uc2_pos = 0x35350, .uc2_length = 0x3d88, - .uc4_pos = 0x390dc, .uc4_length = 0x44a0, - .uc5_pos = 0x3d580, .uc5_length = 0x4ec0, - .pcm4_pos = 0x42444, .pcm4_length = 0x478, - .pcm5_pos = 0x428c0, .pcm5_length = 0x478, - }, - { - .name = "wl.o", - .version = "3.31.15.0", /* 07/28/2003 */ - .md5 = "98dd50a95b02c8bcb3725c770df81dfc", - .flags = BYTE_ORDER_LITTLE_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x32270, - .uc2_pos = 0x35350, .uc2_length = 0x3d88, - .uc4_pos = 0x390dc, .uc4_length = 0x44a0, - .uc5_pos = 0x3d580, .uc5_length = 0x4ec0, - .pcm4_pos = 0x42444, .pcm4_length = 0x478, - .pcm5_pos = 0x428c0, .pcm5_length = 0x478, - }, - { - .name = "wl.o", - .version = "3.50.21.0", /* 05/11/2003 */ - .md5 = "f71be0e1d14f68c98d916465a300d835", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x38990, - .uc2_pos = 0x3c428, .uc2_length = 0x3db8, - .uc4_pos = 0x401e4, .uc4_length = 0x45d8, - .uc5_pos = 0x447c0, .uc5_length = 0x5050, - .pcm4_pos = 0x49814, .pcm4_length = 0x478, - .pcm5_pos = 0x49c90, .pcm5_length = 0x478, - }, - { - .name = "wl.o", - .version = "3.50.21.10", /* 01/21/2004 */ - .md5 = "191029d5e7097ed7db92cbd6e6131f85", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3a5d0, - .uc2_pos = 0x3e0b8, .uc2_length = 0x3e00, - .uc4_pos = 0x41ebc, .uc4_length = 0x4628, - .uc5_pos = 0x464e8, .uc5_length = 0x5548, - .pcm4_pos = 0x4ba34, .pcm4_length = 0x478, - .pcm5_pos = 0x4beb0, .pcm5_length = 0x478, - }, - { - .name = "wl.o", - .version = "3.60.7.0 ? (1.3.2.0)", /* 02/04/2004 */ - .md5 = "7009220d84c445797443aa0221b7d8a4", /* no bcm version found */ - .flags = BYTE_ORDER_LITTLE_ENDIAN, /* but same fw files are also */ - .iv_pos = 0x545e0, /* in bcmwl5.sys 3.60.7.0, */ - .uc2_pos = 0x581d8, .uc2_length = 0x3e08, - .uc4_pos = 0x5bfe4, .uc4_length = 0x4e58, - .uc5_pos = 0x60e40, .uc5_length = 0x5608, - .pcm4_pos = 0x6644c, .pcm4_length = 0x478, - .pcm5_pos = 0x668c8, .pcm5_length = 0x478, - }, - { - .name = "wl.o", - .version = "3.60.13.0", /* 05/05/2004 */ - .md5 = "275dd4958eb94058d4650f58d534c635", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3b740, - .uc2_pos = 0x3f388, .uc2_length = 0x3e30, - .uc4_pos = 0x431bc, .uc4_length = 0x4e80, - .uc5_pos = 0x48040, .uc5_length = 0x5630, - .pcm4_pos = 0x4d674, .pcm4_length = 0x478, - .pcm5_pos = 0x4daf0, .pcm5_length = 0x478, - }, - { - .name = "wl.o", - .version = "3.60.13.0", /* 08/02/2004 */ - .md5 = "4f20653a0b7c0bb3bd1ee0dd79f77785", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3b730, - .uc2_pos = 0x3f378, .uc2_length = 0x3e30, - .uc4_pos = 0x431ac, .uc4_length = 0x4e80, - .uc5_pos = 0x48030, .uc5_length = 0x5630, - .pcm4_pos = 0x4d664, .pcm4_length = 0x478, - .pcm5_pos = 0x4dae0, .pcm5_length = 0x478, - }, - { - .name = "wl.o", - .version = "3.90.7.0", /* 14/10/2004 */ - .md5 = "f15b59ad4d6f6ad2c7f45193d033aff8", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x4d890, - .uc2_pos = 0x51500, .uc2_length = 0x3ec0, - .uc4_pos = 0x553c4, .uc4_length = 0x4d60, - .uc5_pos = 0x5a128, .uc5_length = 0x5750, - .pcm4_pos = 0x5f87c, .pcm4_length = 0x520, - .pcm5_pos = 0x5fda0, .pcm5_length = 0x520, - }, - { - .name = "wl.o", - .version = "3.90.37.0", /* 15/02/2005 */ - .md5 = "984c42947552652d5ab61b78e7d12227", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x4cf50, - .uc2_pos = 0x50bc0, .uc2_length = 0x3f48, - .uc4_pos = 0x54b0c, .uc4_length = 0x4df0, - .uc5_pos = 0x59900, .uc5_length = 0x57e0, - .pcm4_pos = 0x5f0e4, .pcm4_length = 0x520, - .pcm5_pos = 0x5f608, .pcm5_length = 0x520, - }, - { - .name = "wl_ap.o", - .version = "3.31.16.0", /* 08/06/2003 */ - .md5 = "463633e7bf0efc6c0f8eac2514a71024", - .flags = BYTE_ORDER_LITTLE_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x32270, - .uc2_pos = 0x35350, .uc2_length = 0x3d88, - .uc4_pos = 0x390dc, .uc4_length = 0x44a0, - .uc5_pos = 0x3d580, .uc5_length = 0x4ec0, - .pcm4_pos = 0x42444, .pcm4_length = 0x478, - .pcm5_pos = 0x428c0, .pcm5_length = 0x478, - }, - { - .name = "wl_ap.o", - .version = "3.90.37.0", /* 15/02/2005 */ - .md5 = "0538296d46a854d2facc9a0db2088180", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3eac0, - .uc2_pos = 0x42730, .uc2_length = 0x3f48, - .uc4_pos = 0x4667c, .uc4_length = 0x4df0, - .uc5_pos = 0x4b470, .uc5_length = 0x57e0, - .pcm4_pos = 0x50c54, .pcm4_length = 0x520, - .pcm5_pos = 0x51178, .pcm5_length = 0x520, - }, - { - .name = "wl_ap.o", - .version = "3.90.37.0", /* 15/02/2005 */ - .md5 = "6c9073531a528dd455b716b5e821e696", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x3eac0, - .uc2_pos = 0x42730, .uc2_length = 0x3f48, - .uc4_pos = 0x4667c, .uc4_length = 0x4df0, - .uc5_pos = 0x4b470, .uc5_length = 0x57e0, - .pcm4_pos = 0x50c54, .pcm4_length = 0x520, - .pcm5_pos = 0x51178, .pcm5_length = 0x520, - }, - { - .name = "wl_apsta.o", - .version = "3.31.16.0", /* 06/08/2003 */ - .md5 = "22b90e4cbeee45ad7f78ff536c65712a", - .flags = BYTE_ORDER_LITTLE_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x38020, - .uc2_pos = 0x3b100, .uc2_length = 0x3d88, - .uc4_pos = 0x3ee8c, .uc4_length = 0x44a0, - .uc5_pos = 0x43330, .uc5_length = 0x4ec0, - .pcm4_pos = 0x481f4, .pcm4_length = 0x478, - .pcm5_pos = 0x48670, .pcm5_length = 0x478, - }, - { - .name = "wl_apsta.o", - .version = "3.31.16.0", /* 06/08/2003 */ - .md5 = "dfce35a8b5cb6e53e1ab75342c7e7194", - .flags = BYTE_ORDER_LITTLE_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x38020, - .uc2_pos = 0x3b100, .uc2_length = 0x3d88, - .uc4_pos = 0x3ee8c, .uc4_length = 0x44a0, - .uc5_pos = 0x43330, .uc5_length = 0x4ec0, - .pcm4_pos = 0x481f4, .pcm4_length = 0x478, - .pcm5_pos = 0x48670, .pcm5_length = 0x478, - }, - { - .name = "wl_apsta.o", - .version = "3.90.37.0", /* 15/02/2005 */ - .md5 = "2922e6c48917eacd6c8c094347d2ec4b", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x4ebc0, - .uc2_pos = 0x52830, .uc2_length = 0x3f48, - .uc4_pos = 0x5677c, .uc4_length = 0x4df0, - .uc5_pos = 0x5b570, .uc5_length = 0x57e0, - .pcm4_pos = 0x60d54, .pcm4_length = 0x520, - .pcm5_pos = 0x61278, .pcm5_length = 0x520, - }, - { - .name = "wl_apsta.o", - .version = "3.90.37.0", /* 15/02/2005 */ - .md5 = "f9fa565a766e8befeb495a8a8c0c134b", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x4ebc0, - .uc2_pos = 0x52830, .uc2_length = 0x3f48, - .uc4_pos = 0x5677c, .uc4_length = 0x4df0, - .uc5_pos = 0x5b570, .uc5_length = 0x57e0, - .pcm4_pos = 0x60d54, .pcm4_length = 0x520, - .pcm5_pos = 0x61278, .pcm5_length = 0x520, - }, - { - .name = "wl_apsta.o", - .version = "3.130.20.0", /* 19/05/2005 */ - .md5 = "e08665c5c5b66beb9c3b2dd54aa80cb3", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x56020, - .uc2_pos = 0x59ca0, .uc2_length = 0x3fe0, - .uc4_pos = 0x5dc84, .uc4_length = 0x4e78, - .uc5_pos = 0x62b00, .uc5_length = 0x5700, - .uc11_pos = 0x68204, .uc11_length = 0x54a8, - .pcm4_pos = 0x6d6b0, .pcm4_length = 0x520, - .pcm5_pos = 0x6dbd4, .pcm5_length = 0x520, - }, - { - .name = "wl_sta.o", - .version = "3.31.16.0", /* 08/06/2003 */ - .md5 = "c3e663cb78b2fc299088de69fc11a9a9", - .flags = BYTE_ORDER_LITTLE_ENDIAN | - MISSING_INITVAL_08, - .iv_pos = 0x317b0, - .uc2_pos = 0x34890, .uc2_length = 0x3d88, - .uc4_pos = 0x3861c, .uc4_length = 0x44a0, - .uc5_pos = 0x3cac0, .uc5_length = 0x4ec0, - .pcm4_pos = 0x41984, .pcm4_length = 0x478, - .pcm5_pos = 0x41e00, .pcm5_length = 0x478, - }, - { - .name = "wl_sta.o", - .version = "3.90.37.0", /* 15/02/2005 */ - .md5 = "4631d4d4c3ab943462e1ea24f4dba7bd", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x47040, - .uc2_pos = 0x4acb0, .uc2_length = 0x3f48, - .uc4_pos = 0x4ebfc, .uc4_length = 0x4df0, - .uc5_pos = 0x539f0, .uc5_length = 0x57e0, - .pcm4_pos = 0x591d4, .pcm4_length = 0x520, - .pcm5_pos = 0x596f8, .pcm5_length = 0x520, - }, - { - .name = "wl_sta.o", - .version = "3.90.37.0", /* 15/02/2005 */ - .md5 = "bf824b38b3993e0a8b5a9bf717c428ed", - .flags = BYTE_ORDER_LITTLE_ENDIAN, - .iv_pos = 0x47040, - .uc2_pos = 0x4acb0, .uc2_length = 0x3f48, - .uc4_pos = 0x4ebfc, .uc4_length = 0x4df0, - .uc5_pos = 0x539f0, .uc5_length = 0x57e0, - .pcm4_pos = 0x591d4, .pcm4_length = 0x520, - .pcm5_pos = 0x596f8, .pcm5_length = 0x520, - }, -}; - -#define FILES (sizeof(files) / sizeof(files[0])) diff --git a/target/linux/package/bcm43xx-standalone/fwcutter/md5.c b/target/linux/package/bcm43xx-standalone/fwcutter/md5.c deleted file mode 100644 index ad134146e4..0000000000 --- a/target/linux/package/bcm43xx-standalone/fwcutter/md5.c +++ /dev/null @@ -1,253 +0,0 @@ -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, declare an - * MD5Context structure, pass it to MD5Init, call MD5Update as - * needed on buffers full of bytes, and then call MD5Final, which - * will fill a supplied 16-byte array with the digest. - */ - -/* Brutally hacked by John Walker back from ANSI C to K&R (no - prototypes) to maintain the tradition that Netfone will compile - with Sun's original "cc". */ -/* Ripped out ugly K&R again ;) --mbuesch */ - -#include /* for memcpy() */ -#include "md5.h" - -extern int big_endian_cpu; - -/* - * Note: this code is harmless on little-endian machines, - * but we return early nevertheless. - */ -static void byteReverse(unsigned char *buf, unsigned longs) -{ - uint32_t t; - - if (!big_endian_cpu) - return; - - do { - t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 | - ((unsigned) buf[1] << 8 | buf[0]); - *(uint32_t *) buf = t; - buf += 4; - } while (--longs); -} - -/* The four core functions - F1 is optimized somewhat */ - -/* #define F1(x, y, z) (x & y | ~x & z) */ -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -/* This is the central step in the MD5 algorithm. */ -#define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<>(32-s), w += x ) - -/* - * The core of the MD5 algorithm, this alters an existing MD5 hash to - * reflect the addition of 16 longwords of new data. MD5Update blocks - * the data and converts bytes into longwords for this routine. - */ -static void MD5Transform(uint32_t *buf, uint32_t *in) -{ - register uint32_t a, b, c, d; - - a = buf[0]; - b = buf[1]; - c = buf[2]; - d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -/* - * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious - * initialization constants. - */ -void MD5Init(struct MD5Context *ctx) -{ - ctx->buf[0] = 0x67452301; - ctx->buf[1] = 0xefcdab89; - ctx->buf[2] = 0x98badcfe; - ctx->buf[3] = 0x10325476; - - ctx->bits[0] = 0; - ctx->bits[1] = 0; -} - -/* - * Update context to reflect the concatenation of another buffer full - * of bytes. - */ -void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len) -{ - uint32_t t; - - /* Update bitcount */ - - t = ctx->bits[0]; - if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) - ctx->bits[1]++; /* Carry from low to high */ - ctx->bits[1] += len >> 29; - - t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */ - - /* Handle any leading odd-sized chunks */ - - if (t) { - unsigned char *p = (unsigned char *) ctx->in + t; - - t = 64 - t; - if (len < t) { - memcpy(p, buf, len); - return; - } - memcpy(p, buf, t); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (uint32_t *) ctx->in); - buf += t; - len -= t; - } - /* Process data in 64-byte chunks */ - - while (len >= 64) { - memcpy(ctx->in, buf, 64); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (uint32_t *) ctx->in); - buf += 64; - len -= 64; - } - - /* Handle any remaining bytes of data. */ - - memcpy(ctx->in, buf, len); -} - -/* - * Final wrapup - pad to 64-byte boundary with the bit pattern - * 1 0* (64-bit count of bits processed, MSB-first) - */ -void MD5Final(unsigned char *digest, struct MD5Context *ctx) -{ - unsigned count; - unsigned char *p; - - /* Compute number of bytes mod 64 */ - count = (ctx->bits[0] >> 3) & 0x3F; - - /* Set the first char of padding to 0x80. This is safe since there is - always at least one byte free */ - p = ctx->in + count; - *p++ = 0x80; - - /* Bytes of padding needed to make 64 bytes */ - count = 64 - 1 - count; - - /* Pad out to 56 mod 64 */ - if (count < 8) { - /* Two lots of padding: Pad the first block to 64 bytes */ - memset(p, 0, count); - byteReverse(ctx->in, 16); - MD5Transform(ctx->buf, (uint32_t *) ctx->in); - - /* Now fill the next block with 56 bytes */ - memset(ctx->in, 0, 56); - } else { - /* Pad block to 56 bytes */ - memset(p, 0, count - 8); - } - byteReverse(ctx->in, 14); - - /* Append length in bits and transform */ - ((uint32_t *) ctx->in)[14] = ctx->bits[0]; - ((uint32_t *) ctx->in)[15] = ctx->bits[1]; - - MD5Transform(ctx->buf, (uint32_t *) ctx->in); - byteReverse((unsigned char *) ctx->buf, 4); - memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ -} diff --git a/target/linux/package/bcm43xx-standalone/fwcutter/md5.h b/target/linux/package/bcm43xx-standalone/fwcutter/md5.h deleted file mode 100644 index ee574e4133..0000000000 --- a/target/linux/package/bcm43xx-standalone/fwcutter/md5.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FWCUTTER_MD5_H_ -#define FWCUTTER_MD5_H_ - -#include - -struct MD5Context { - uint32_t buf[4]; - uint32_t bits[2]; - unsigned char in[64]; -}; - -void MD5Init(struct MD5Context *ctx); -void MD5Update(struct MD5Context *ctx, unsigned char *buf, unsigned len); -void MD5Final(unsigned char *digest, struct MD5Context *ctx); - -#endif /* FWCUTTER_MD5_H_ */ diff --git a/target/linux/package/bcm43xx-standalone/ipkg/kmod-bcm43xx-standalone.control b/target/linux/package/bcm43xx-standalone/ipkg/kmod-bcm43xx-standalone.control deleted file mode 100644 index 5dcc79f829..0000000000 --- a/target/linux/package/bcm43xx-standalone/ipkg/kmod-bcm43xx-standalone.control +++ /dev/null @@ -1,4 +0,0 @@ -Package: kmod-bcm43xx-standalone -Priority: optional -Section: sys -Description: Free BCM43xx wireless driver (devicescape) diff --git a/target/linux/package/ieee80211-dscape/Config.in b/target/linux/package/ieee80211-dscape/Config.in deleted file mode 100644 index d747ed2fba..0000000000 --- a/target/linux/package/ieee80211-dscape/Config.in +++ /dev/null @@ -1,10 +0,0 @@ -config PACKAGE_KMOD_IEEE80211_DSCAPE - prompt "kmod-ieee80211-dscape............. IEEE 802.11 stack (devicescape)" - tristate - default n - depends LINUX_2_6_BRCM || LINUX_2_6_X86 - - help - IEEE 802.11 stack (devicescape) - - http://ftp.kernel.org/pub/linux/kernel/people/jbenc/ diff --git a/target/linux/package/ieee80211-dscape/Makefile b/target/linux/package/ieee80211-dscape/Makefile deleted file mode 100644 index 3de9b34fb8..0000000000 --- a/target/linux/package/ieee80211-dscape/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# $Id$ - -include $(TOPDIR)/rules.mk -include ../../rules.mk - -PKG_NAME := kmod-ieee80211-dscape -PKG_RELEASE := 1 -PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) - -include $(TOPDIR)/package/rules.mk - -$(eval $(call PKG_template,KMOD_IEEE80211_DSCAPE,$(PKG_NAME),$(LINUX_VERSION)-$(BOARD)-$(PKG_RELEASE),$(ARCH),kernel ($(LINUX_VERSION)-$(BOARD)-$(LINUX_RELEASE)))) - -$(PKG_BUILD_DIR)/.prepared: - mkdir -p $(PKG_BUILD_DIR) - $(CP) ./src/* $(PKG_BUILD_DIR)/ - touch $@ - -$(PKG_BUILD_DIR)/.configured: - touch $@ - -$(PKG_BUILD_DIR)/.built: - $(MAKE) -C "$(LINUX_DIR)" \ - CROSS_COMPILE="$(TARGET_CROSS)" \ - ARCH="$(LINUX_KARCH)" \ - PATH="$(TARGET_PATH)" \ - SUBDIRS="$(PKG_BUILD_DIR)" \ - LINUXINCLUDE="-I$(shell pwd)/src/include -I$(LINUX_DIR)/include" \ - modules - touch $@ - -$(IPKG_KMOD_IEEE80211_DSCAPE): - install -m0755 -d $(IDIR_KMOD_IEEE80211_DSCAPE)/lib/modules/$(LINUX_VERSION) - #install -m0755 -d $(IDIR_KMOD_IEEE80211_DSCAPE)/etc/modules.d - $(CP) $(PKG_BUILD_DIR)/*.ko $(IDIR_KMOD_IEEE80211_DSCAPE)/lib/modules/$(LINUX_VERSION) - $(IPKG_BUILD) $(IDIR_KMOD_IEEE80211_DSCAPE) $(PACKAGE_DIR) - -install-dev: - mkdir -p $(STAGING_DIR)/usr/include/ieee80211-dscape - $(CP) src/include/* $(STAGING_DIR)/usr/include/ieee80211-dscape/ - -uninstall-dev: - rm -rf $(STAGING_DIR)/usr/include/ieee80211-dscape - -compile-targets: install-dev -clean-targets: uninstall-dev diff --git a/target/linux/package/ieee80211-dscape/ipkg/kmod-ieee80211-dscape.control b/target/linux/package/ieee80211-dscape/ipkg/kmod-ieee80211-dscape.control deleted file mode 100644 index f510d2d18c..0000000000 --- a/target/linux/package/ieee80211-dscape/ipkg/kmod-ieee80211-dscape.control +++ /dev/null @@ -1,4 +0,0 @@ -Package: kmod-ieee80211-dscape -Priority: optional -Section: sys -Description: IEEE 802.11 stack (devicescape) diff --git a/target/linux/package/ieee80211-dscape/src/Kconfig b/target/linux/package/ieee80211-dscape/src/Kconfig deleted file mode 100644 index 052a4190e5..0000000000 --- a/target/linux/package/ieee80211-dscape/src/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -config IEEE80211 - tristate "Generic IEEE 802.11 Networking Stack" - ---help--- - This option enables the hardware independent IEEE 802.11 - networking stack. - -config IEEE80211_DEBUG - bool "Enable debugging output" - depends on IEEE80211 - ---help--- - This option will enable debug tracing output for the - ieee80211 network stack. - - If you are not trying to debug or develop the ieee80211 - subsystem, you most likely want to say N here. - -config IEEE80211_VERBOSE_DEBUG - bool "Verbose debugging output" - depends on IEEE80211_DEBUG - -config TKIP_DEBUG - bool "TKIP debugging" - depends on IEEE80211_DEBUG - -config IEEE80211_DEBUG_COUNTERS - bool "Extra statistics for TX/RX debugging" - depends on IEEE80211_DEBUG - -config HOSTAPD_WPA_TESTING - bool "Support for TKIP countermeasures testing" - depends on IEEE80211_DEBUG - diff --git a/target/linux/package/ieee80211-dscape/src/Makefile b/target/linux/package/ieee80211-dscape/src/Makefile deleted file mode 100644 index ac4ab887ba..0000000000 --- a/target/linux/package/ieee80211-dscape/src/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -obj-$(CONFIG_IEEE80211) += 80211.o rate_control.o - -80211-objs := \ - ieee80211.o \ - ieee80211_ioctl.o \ - sta_info.o \ - wep.o \ - wpa.o \ - ieee80211_proc.o \ - ieee80211_scan.o \ - ieee80211_sta.o \ - michael.o \ - tkip.o \ - aes_ccm.o \ - wme.o - -ifeq ($(CONFIG_NET_SCHED),) - 80211-objs += fifo_qdisc.o -endif - -ifeq ($(CONFIG_IEEE80211_LEDS),y) - 80211-objs += ieee80211_led.o -endif diff --git a/target/linux/package/ieee80211-dscape/src/aes.c b/target/linux/package/ieee80211-dscape/src/aes.c deleted file mode 100644 index 085e4a9938..0000000000 --- a/target/linux/package/ieee80211-dscape/src/aes.c +++ /dev/null @@ -1,564 +0,0 @@ -/* Based on Rijndael implementation that has been placed in the public domain, - * although heavily modified. - * - * Modifications Copyright 2003, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * Optimized both speed and size by removing not used key lengths (only - * 128-bit is used in IEEE 802.11i). - */ - -/* Use 256-byte Te4 table instead of larger 1024-byte */ -#define SMALL_TE4 - -/* Save data size by using only one 1k table, but with a drawback of having to - * rotate entries at lookup. This can be useful, if the CPU supports free - * rotate on memory read. However, if this is not the case, this is much slower - * than four-table implementation. */ -/* #define ONLY_ONE_TABLE */ - - -/* --- start of code that is based on public domain AES implementation --- */ - -/** - * rijndael-alg-fst.c - * - * @version 3.0 (December 2000) - * - * Optimised ANSI C code for the Rijndael cipher (now AES) - * - * @author Vincent Rijmen - * @author Antoon Bosselaers - * @author Paulo Barreto - * - * This code is hereby placed in the public domain. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR - * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE - * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, - * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* -Te0[x] = S [x].[02, 01, 01, 03]; -Te1[x] = S [x].[03, 02, 01, 01]; -Te2[x] = S [x].[01, 03, 02, 01]; -Te3[x] = S [x].[01, 01, 03, 02]; -Te4[x] = S [x].[01, 01, 01, 01]; -*/ - -static const u32 Te0[256] = -{ - 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, - 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, - 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, - 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, - 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, - 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, - 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, - 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, - 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, - 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, - 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, - 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, - 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, - 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, - 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, - 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, - 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, - 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, - 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, - 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, - 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, - 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, - 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, - 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, - 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, - 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, - 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, - 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, - 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, - 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, - 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, - 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, - 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, - 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, - 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, - 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, - 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, - 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, - 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, - 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, - 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, - 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, - 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, - 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, - 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, - 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, - 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, - 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, - 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, - 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, - 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, - 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, - 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, - 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, - 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, - 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, - 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, - 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, - 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, - 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, - 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, - 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, - 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, - 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, -}; - -#ifndef ONLY_ONE_TABLE -static const u32 Te1[256] = -{ - 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, - 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, - 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, - 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, - 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, - 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, - 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, - 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, - 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, - 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, - 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, - 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, - 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, - 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, - 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, - 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, - 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, - 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, - 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, - 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, - 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, - 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, - 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, - 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, - 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, - 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, - 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, - 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, - 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, - 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, - 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, - 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, - 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, - 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, - 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, - 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, - 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, - 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, - 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, - 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, - 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, - 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, - 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, - 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, - 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, - 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, - 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, - 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, - 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, - 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, - 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, - 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, - 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, - 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, - 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, - 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, - 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, - 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, - 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, - 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, - 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, - 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, - 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, - 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, -}; - -static const u32 Te2[256] = -{ - 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, - 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, - 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, - 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, - 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, - 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, - 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, - 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, - 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, - 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, - 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, - 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, - 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, - 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, - 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, - 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, - 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, - 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, - 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, - 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, - 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, - 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, - 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, - 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, - 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, - 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, - 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, - 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, - 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, - 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, - 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, - 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, - 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, - 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, - 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, - 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, - 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, - 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, - 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, - 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, - 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, - 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, - 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, - 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, - 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, - 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, - 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, - 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, - 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, - 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, - 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, - 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, - 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, - 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, - 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, - 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, - 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, - 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, - 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, - 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, - 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, - 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, - 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, - 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, -}; - -static const u32 Te3[256] = -{ - 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, - 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, - 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, - 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, - 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, - 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, - 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, - 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, - 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, - 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, - 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, - 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, - 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, - 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, - 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, - 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, - 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, - 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, - 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, - 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, - 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, - 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, - 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, - 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, - 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, - 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, - 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, - 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, - 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, - 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, - 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, - 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, - 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, - 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, - 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, - 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, - 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, - 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, - 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, - 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, - 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, - 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, - 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, - 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, - 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, - 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, - 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, - 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, - 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, - 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, - 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, - 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, - 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, - 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, - 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, - 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, - 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, - 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, - 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, - 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, - 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, - 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, - 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, - 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, -}; - -#define TE0(v) (Te0[(v) >> 24]) -#define TE1(v) (Te1[((v) >> 16) & 0xff]) -#define TE2(v) (Te2[((v) >> 8) & 0xff]) -#define TE3(v) (Te3[(v) & 0xff]) - -#else /* ONLY_ONE_TABLE */ - - -static inline u32 ROR8(u32 v) -{ - return (v >> 8) | (v << 24); -} - -static inline u32 ROR16(u32 v) -{ - return (v >> 16) | (v << 16); -} - -static inline u32 ROR24(u32 v) -{ - return (v >> 24) | (v << 8); -} - -#define TE0(v) (Te0[(v) >> 24]) -#define TE1(v) (ROR8(Te0[((v) >> 16) & 0xff])) -#define TE2(v) (ROR16(Te0[((v) >> 8) & 0xff])) -#define TE3(v) (ROR24(Te0[(v) & 0xff])) - -#endif /* ONLY_ONE_TABLE */ - - - -#ifdef SMALL_TE4 -static const u8 Te4s[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, -}; - -#define TE4_1(v) (Te4s[(v) & 0xff] << 24) -#define TE4_2(v) (Te4s[(v) & 0xff] << 16) -#define TE4_3(v) (Te4s[(v) & 0xff] << 8) -#define TE4_4(v) (Te4s[(v) & 0xff]) - -#else /* SMALL_TE4 */ - -static const u32 Te4[256] = -{ - 0x63636363U, 0x7c7c7c7cU, 0x77777777U, 0x7b7b7b7bU, - 0xf2f2f2f2U, 0x6b6b6b6bU, 0x6f6f6f6fU, 0xc5c5c5c5U, - 0x30303030U, 0x01010101U, 0x67676767U, 0x2b2b2b2bU, - 0xfefefefeU, 0xd7d7d7d7U, 0xababababU, 0x76767676U, - 0xcacacacaU, 0x82828282U, 0xc9c9c9c9U, 0x7d7d7d7dU, - 0xfafafafaU, 0x59595959U, 0x47474747U, 0xf0f0f0f0U, - 0xadadadadU, 0xd4d4d4d4U, 0xa2a2a2a2U, 0xafafafafU, - 0x9c9c9c9cU, 0xa4a4a4a4U, 0x72727272U, 0xc0c0c0c0U, - 0xb7b7b7b7U, 0xfdfdfdfdU, 0x93939393U, 0x26262626U, - 0x36363636U, 0x3f3f3f3fU, 0xf7f7f7f7U, 0xccccccccU, - 0x34343434U, 0xa5a5a5a5U, 0xe5e5e5e5U, 0xf1f1f1f1U, - 0x71717171U, 0xd8d8d8d8U, 0x31313131U, 0x15151515U, - 0x04040404U, 0xc7c7c7c7U, 0x23232323U, 0xc3c3c3c3U, - 0x18181818U, 0x96969696U, 0x05050505U, 0x9a9a9a9aU, - 0x07070707U, 0x12121212U, 0x80808080U, 0xe2e2e2e2U, - 0xebebebebU, 0x27272727U, 0xb2b2b2b2U, 0x75757575U, - 0x09090909U, 0x83838383U, 0x2c2c2c2cU, 0x1a1a1a1aU, - 0x1b1b1b1bU, 0x6e6e6e6eU, 0x5a5a5a5aU, 0xa0a0a0a0U, - 0x52525252U, 0x3b3b3b3bU, 0xd6d6d6d6U, 0xb3b3b3b3U, - 0x29292929U, 0xe3e3e3e3U, 0x2f2f2f2fU, 0x84848484U, - 0x53535353U, 0xd1d1d1d1U, 0x00000000U, 0xededededU, - 0x20202020U, 0xfcfcfcfcU, 0xb1b1b1b1U, 0x5b5b5b5bU, - 0x6a6a6a6aU, 0xcbcbcbcbU, 0xbebebebeU, 0x39393939U, - 0x4a4a4a4aU, 0x4c4c4c4cU, 0x58585858U, 0xcfcfcfcfU, - 0xd0d0d0d0U, 0xefefefefU, 0xaaaaaaaaU, 0xfbfbfbfbU, - 0x43434343U, 0x4d4d4d4dU, 0x33333333U, 0x85858585U, - 0x45454545U, 0xf9f9f9f9U, 0x02020202U, 0x7f7f7f7fU, - 0x50505050U, 0x3c3c3c3cU, 0x9f9f9f9fU, 0xa8a8a8a8U, - 0x51515151U, 0xa3a3a3a3U, 0x40404040U, 0x8f8f8f8fU, - 0x92929292U, 0x9d9d9d9dU, 0x38383838U, 0xf5f5f5f5U, - 0xbcbcbcbcU, 0xb6b6b6b6U, 0xdadadadaU, 0x21212121U, - 0x10101010U, 0xffffffffU, 0xf3f3f3f3U, 0xd2d2d2d2U, - 0xcdcdcdcdU, 0x0c0c0c0cU, 0x13131313U, 0xececececU, - 0x5f5f5f5fU, 0x97979797U, 0x44444444U, 0x17171717U, - 0xc4c4c4c4U, 0xa7a7a7a7U, 0x7e7e7e7eU, 0x3d3d3d3dU, - 0x64646464U, 0x5d5d5d5dU, 0x19191919U, 0x73737373U, - 0x60606060U, 0x81818181U, 0x4f4f4f4fU, 0xdcdcdcdcU, - 0x22222222U, 0x2a2a2a2aU, 0x90909090U, 0x88888888U, - 0x46464646U, 0xeeeeeeeeU, 0xb8b8b8b8U, 0x14141414U, - 0xdedededeU, 0x5e5e5e5eU, 0x0b0b0b0bU, 0xdbdbdbdbU, - 0xe0e0e0e0U, 0x32323232U, 0x3a3a3a3aU, 0x0a0a0a0aU, - 0x49494949U, 0x06060606U, 0x24242424U, 0x5c5c5c5cU, - 0xc2c2c2c2U, 0xd3d3d3d3U, 0xacacacacU, 0x62626262U, - 0x91919191U, 0x95959595U, 0xe4e4e4e4U, 0x79797979U, - 0xe7e7e7e7U, 0xc8c8c8c8U, 0x37373737U, 0x6d6d6d6dU, - 0x8d8d8d8dU, 0xd5d5d5d5U, 0x4e4e4e4eU, 0xa9a9a9a9U, - 0x6c6c6c6cU, 0x56565656U, 0xf4f4f4f4U, 0xeaeaeaeaU, - 0x65656565U, 0x7a7a7a7aU, 0xaeaeaeaeU, 0x08080808U, - 0xbabababaU, 0x78787878U, 0x25252525U, 0x2e2e2e2eU, - 0x1c1c1c1cU, 0xa6a6a6a6U, 0xb4b4b4b4U, 0xc6c6c6c6U, - 0xe8e8e8e8U, 0xddddddddU, 0x74747474U, 0x1f1f1f1fU, - 0x4b4b4b4bU, 0xbdbdbdbdU, 0x8b8b8b8bU, 0x8a8a8a8aU, - 0x70707070U, 0x3e3e3e3eU, 0xb5b5b5b5U, 0x66666666U, - 0x48484848U, 0x03030303U, 0xf6f6f6f6U, 0x0e0e0e0eU, - 0x61616161U, 0x35353535U, 0x57575757U, 0xb9b9b9b9U, - 0x86868686U, 0xc1c1c1c1U, 0x1d1d1d1dU, 0x9e9e9e9eU, - 0xe1e1e1e1U, 0xf8f8f8f8U, 0x98989898U, 0x11111111U, - 0x69696969U, 0xd9d9d9d9U, 0x8e8e8e8eU, 0x94949494U, - 0x9b9b9b9bU, 0x1e1e1e1eU, 0x87878787U, 0xe9e9e9e9U, - 0xcecececeU, 0x55555555U, 0x28282828U, 0xdfdfdfdfU, - 0x8c8c8c8cU, 0xa1a1a1a1U, 0x89898989U, 0x0d0d0d0dU, - 0xbfbfbfbfU, 0xe6e6e6e6U, 0x42424242U, 0x68686868U, - 0x41414141U, 0x99999999U, 0x2d2d2d2dU, 0x0f0f0f0fU, - 0xb0b0b0b0U, 0x54545454U, 0xbbbbbbbbU, 0x16161616U, -}; - -#define TE4_1(v) (Te4[(v) & 0xff] & 0xff000000) -#define TE4_2(v) (Te4[(v) & 0xff] & 0x00ff0000) -#define TE4_3(v) (Te4[(v) & 0xff] & 0x0000ff00) -#define TE4_4(v) (Te4[(v) & 0xff] & 0x000000ff) - -#endif /* SMALL_TE4 */ - - -static const u32 rcon[] = { - 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, - 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, -}; - -#define GETU32(pt) \ -(((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ \ -((u32)(pt)[3])) -#define PUTU32(ct, st) \ -{ (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); \ -(ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } - - -/* Expand the cipher key into the encryption key schedule. */ -void ieee80211_aes_key_setup_encrypt(u32 rk[/*44*/], const u8 key[]) -{ - int i; - u32 temp; - - rk[0] = GETU32(key ); - rk[1] = GETU32(key + 4); - rk[2] = GETU32(key + 8); - rk[3] = GETU32(key + 12); - - for (i = 0; i < 10; i++) { - temp = rk[3]; - rk[4] = rk[0] ^ TE4_1(temp >> 16) ^ TE4_2(temp >> 8) ^ - TE4_3(temp) ^ TE4_4(temp >> 24) ^ rcon[i]; - rk[5] = rk[1] ^ rk[4]; - rk[6] = rk[2] ^ rk[5]; - rk[7] = rk[3] ^ rk[6]; - rk += 4; - } -} - - -void ieee80211_aes_encrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16]) -{ - const int Nr = 10; - u32 s0, s1, s2, s3, t0, t1, t2, t3; - - /* Map byte array block to cipher state and add initial round key */ - s0 = GETU32(pt ) ^ rk[0]; - s1 = GETU32(pt + 4) ^ rk[1]; - s2 = GETU32(pt + 8) ^ rk[2]; - s3 = GETU32(pt + 12) ^ rk[3]; - -#define ROUND(r,d,s,i) \ -d##0 = TE0(s##0) ^ TE1(s##1) ^ TE2(s##2) ^ TE3(s##3) ^ rk[i]; \ -d##1 = TE0(s##1) ^ TE1(s##2) ^ TE2(s##3) ^ TE3(s##0) ^ rk[i + 1]; \ -d##2 = TE0(s##2) ^ TE1(s##3) ^ TE2(s##0) ^ TE3(s##1) ^ rk[i + 2]; \ -d##3 = TE0(s##3) ^ TE1(s##0) ^ TE2(s##1) ^ TE3(s##2) ^ rk[i + 3] - ROUND(1,t,s,4); - ROUND(2,s,t,8); - ROUND(3,t,s,12); - ROUND(4,s,t,16); - ROUND(5,t,s,20); - ROUND(6,s,t,24); - ROUND(7,t,s,28); - ROUND(8,s,t,32); - ROUND(9,t,s,36); -#undef ROUND - - rk += Nr << 2; - - /* Apply the last round and map cipher state to byte array block */ - s0 = TE4_1(t0 >> 24) ^ TE4_2(t1 >> 16) ^ TE4_3(t2 >> 8) ^ TE4_4(t3) ^ - rk[0]; - PUTU32(ct, s0); - s0 = TE4_1(t1 >> 24) ^ TE4_2(t2 >> 16) ^ TE4_3(t3 >> 8) ^ TE4_4(t0) ^ - rk[1]; - PUTU32(ct + 4, s0); - s0 = TE4_1(t2 >> 24) ^ TE4_2(t3 >> 16) ^ TE4_3(t0 >> 8) ^ TE4_4(t1) ^ - rk[2]; - PUTU32(ct + 8, s0); - s0 = TE4_1(t3 >> 24) ^ TE4_2(t0 >> 16) ^ TE4_3(t1 >> 8) ^ TE4_4(t2) ^ - rk[3]; - PUTU32(ct + 12, s0); -} - -/* --- end of code that is based on public domain AES implementation --- */ diff --git a/target/linux/package/ieee80211-dscape/src/aes_ccm.c b/target/linux/package/ieee80211-dscape/src/aes_ccm.c deleted file mode 100644 index bbc1f7bc96..0000000000 --- a/target/linux/package/ieee80211-dscape/src/aes_ccm.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2003-2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include - -#include -#include "ieee80211_key.h" -#include "aes_ccm.h" - -#include "aes.c" - -static inline void aes_ccm_prepare(u32 *rk, u8 *b_0, u8 *aad, u8 *b, - u8 *s_0, u8 *a) -{ - int i; - - ieee80211_aes_encrypt(rk, b_0, b); - - /* Extra Authenticate-only data (always two AES blocks) */ - for (i = 0; i < AES_BLOCK_LEN; i++) - aad[i] ^= b[i]; - ieee80211_aes_encrypt(rk, aad, b); - - aad += AES_BLOCK_LEN; - - for (i = 0; i < AES_BLOCK_LEN; i++) - aad[i] ^= b[i]; - ieee80211_aes_encrypt(rk, aad, a); - - /* Mask out bits from auth-only-b_0 */ - b_0[0] &= 0x07; - - /* S_0 is used to encrypt T (= MIC) */ - b_0[14] = 0; - b_0[15] = 0; - ieee80211_aes_encrypt(rk, b_0, s_0); -} - - -void ieee80211_aes_ccm_encrypt(u32 *rk, u8 *b_0, u8 *aad, u8 *data, - size_t data_len, u8 *cdata, u8 *mic) -{ - int i, j, last_len, num_blocks; - u8 *pos, *cpos; - u8 b[AES_BLOCK_LEN], s_0[AES_BLOCK_LEN], e[AES_BLOCK_LEN]; - - num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; - last_len = data_len % AES_BLOCK_LEN; - aes_ccm_prepare(rk, b_0, aad, b, s_0, b); - - /* Process payload blocks */ - pos = data; - cpos = cdata; - for (j = 1; j <= num_blocks; j++) { - int blen = (j == num_blocks && last_len) ? - last_len : AES_BLOCK_LEN; - - /* Authentication followed by encryption */ - for (i = 0; i < blen; i++) - b[i] ^= pos[i]; - ieee80211_aes_encrypt(rk, b, b); - - b_0[14] = (j >> 8) & 0xff; - b_0[15] = j & 0xff; - ieee80211_aes_encrypt(rk, b_0, e); - for (i = 0; i < blen; i++) - *cpos++ = *pos++ ^ e[i]; - } - - for (i = 0; i < CCMP_MIC_LEN; i++) - mic[i] = b[i] ^ s_0[i]; -} - - -int ieee80211_aes_ccm_decrypt(u32 *rk, u8 *b_0, u8 *aad, u8 *cdata, - size_t data_len, u8 *mic, u8 *data) -{ - int i, j, last_len, num_blocks; - u8 *pos, *cpos; - u8 b[AES_BLOCK_LEN], s_0[AES_BLOCK_LEN], a[AES_BLOCK_LEN]; - - num_blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; - last_len = data_len % AES_BLOCK_LEN; - aes_ccm_prepare(rk, b_0, aad, b, s_0, a); - - /* Process payload blocks */ - cpos = cdata; - pos = data; - for (j = 1; j <= num_blocks; j++) { - int blen = (j == num_blocks && last_len) ? - last_len : AES_BLOCK_LEN; - - /* Decryption followed by authentication */ - b_0[14] = (j >> 8) & 0xff; - b_0[15] = j & 0xff; - ieee80211_aes_encrypt(rk, b_0, b); - for (i = 0; i < blen; i++) { - *pos = *cpos++ ^ b[i]; - a[i] ^= *pos++; - } - - ieee80211_aes_encrypt(rk, a, a); - } - - for (i = 0; i < CCMP_MIC_LEN; i++) { - if ((mic[i] ^ s_0[i]) != a[i]) - return -1; - } - - return 0; -} - diff --git a/target/linux/package/ieee80211-dscape/src/aes_ccm.h b/target/linux/package/ieee80211-dscape/src/aes_ccm.h deleted file mode 100644 index f741b088ed..0000000000 --- a/target/linux/package/ieee80211-dscape/src/aes_ccm.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2003-2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef AES_CCM_H -#define AES_CCM_H - -#define AES_BLOCK_LEN 16 -#define AES_STATE_LEN 44 - -void ieee80211_aes_key_setup_encrypt(u32 rk[/*44*/], const u8 key[]); -void ieee80211_aes_encrypt(const u32 rk[/*44*/], const u8 pt[16], u8 ct[16]); -void ieee80211_aes_ccm_encrypt(u32 rk[/*44*/], u8 *b_0, u8 *aad, u8 *data, - size_t data_len, u8 *cdata, u8 *mic); -int ieee80211_aes_ccm_decrypt(u32 rk[/*44*/], u8 *b_0, u8 *aad, u8 *cdata, - size_t data_len, u8 *mic, u8 *data); - -#endif /* AES_CCM_H */ diff --git a/target/linux/package/ieee80211-dscape/src/fifo_qdisc.c b/target/linux/package/ieee80211-dscape/src/fifo_qdisc.c deleted file mode 100644 index 95bc0b5777..0000000000 --- a/target/linux/package/ieee80211-dscape/src/fifo_qdisc.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * If building without CONFIG_NET_SCHED we need a simple - * fifo qdisc to install by default as the sub-qdisc. - * This is a simple replacement for sch_fifo. - */ - -#include -#include -#include -#include -#include "ieee80211_i.h" -#include "wme.h" - -static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* qd) -{ - struct sk_buff_head *q = qdisc_priv(qd); - - if (skb_queue_len(q) > qd->dev->tx_queue_len) { - qd->qstats.drops++; - kfree_skb(skb); - return NET_XMIT_DROP; - } - - skb_queue_tail(q, skb); - qd->q.qlen++; - qd->bstats.bytes += skb->len; - qd->bstats.packets++; - - return NET_XMIT_SUCCESS; -} - - -static int pfifo_requeue(struct sk_buff *skb, struct Qdisc* qd) -{ - struct sk_buff_head *q = qdisc_priv(qd); - - skb_queue_head(q, skb); - qd->q.qlen++; - qd->bstats.bytes += skb->len; - qd->bstats.packets++; - - return NET_XMIT_SUCCESS; -} - - -static struct sk_buff *pfifo_dequeue(struct Qdisc* qd) -{ - struct sk_buff_head *q = qdisc_priv(qd); - - return skb_dequeue(q); -} - - -static int pfifo_init(struct Qdisc* qd, struct rtattr *opt) -{ - struct sk_buff_head *q = qdisc_priv(qd); - - skb_queue_head_init(q); - return 0; -} - - -static void pfifo_reset(struct Qdisc* qd) -{ - struct sk_buff_head *q = qdisc_priv(qd); - - skb_queue_purge(q); - qd->q.qlen = 0; -} - - -static int pfifo_dump(struct Qdisc *qd, struct sk_buff *skb) -{ - return skb->len; -} - - -struct Qdisc_ops pfifo_qdisc_ops = -{ - .next = NULL, - .cl_ops = NULL, - .id = "ieee80211_pfifo", - .priv_size = sizeof(struct sk_buff_head), - - .enqueue = pfifo_enqueue, - .dequeue = pfifo_dequeue, - .requeue = pfifo_requeue, - .drop = NULL, - - .init = pfifo_init, - .reset = pfifo_reset, - .destroy = NULL, - .change = NULL, - - .dump = pfifo_dump, -}; - diff --git a/target/linux/package/ieee80211-dscape/src/hostapd_ioctl.h b/target/linux/package/ieee80211-dscape/src/hostapd_ioctl.h deleted file mode 100644 index eff4858353..0000000000 --- a/target/linux/package/ieee80211-dscape/src/hostapd_ioctl.h +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Host AP (software wireless LAN access point) user space daemon for - * Host AP kernel driver - * Copyright 2002-2003, Jouni Malinen - * Copyright 2002-2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef HOSTAPD_IOCTL_H -#define HOSTAPD_IOCTL_H - -#ifndef __KERNEL__ -#include "ieee80211_shared.h" -#endif /* __KERNEL__ */ - -#define PRISM2_IOCTL_PRISM2_PARAM (SIOCIWFIRSTPRIV + 0) -#define PRISM2_IOCTL_GET_PRISM2_PARAM (SIOCIWFIRSTPRIV + 1) -#define PRISM2_IOCTL_HOSTAPD (SIOCIWFIRSTPRIV + 3) -#define PRISM2_IOCTL_TEST_PARAM (SIOCIWFIRSTPRIV + 4) - -/* PRISM2_IOCTL_PRISM2_PARAM ioctl() subtypes: */ -enum { - PRISM2_PARAM_PTYPE = 1, - PRISM2_PARAM_TXRATECTRL = 2, - PRISM2_PARAM_BEACON_INT = 3, - PRISM2_PARAM_PSEUDO_IBSS = 4, - PRISM2_PARAM_ALC = 5, - PRISM2_PARAM_TXPOWER = 6, - PRISM2_PARAM_DUMP = 7, - PRISM2_PARAM_OTHER_AP_POLICY = 8, - PRISM2_PARAM_AP_MAX_INACTIVITY = 9, - PRISM2_PARAM_AP_BRIDGE_PACKETS = 10, - PRISM2_PARAM_DTIM_PERIOD = 11, - PRISM2_PARAM_AP_NULLFUNC_ACK = 12, - PRISM2_PARAM_MAX_WDS = 13, - PRISM2_PARAM_AP_AUTOM_AP_WDS = 14, - PRISM2_PARAM_AP_AUTH_ALGS = 15, - PRISM2_PARAM_MONITOR_ALLOW_FCSERR = 16, - PRISM2_PARAM_HOST_ENCRYPT = 17, - PRISM2_PARAM_HOST_DECRYPT = 18, - PRISM2_PARAM_BUS_MASTER_THRESHOLD_RX = 19, - PRISM2_PARAM_BUS_MASTER_THRESHOLD_TX = 20, - PRISM2_PARAM_HOST_ROAMING = 21, - PRISM2_PARAM_BCRX_STA_KEY = 22, - PRISM2_PARAM_IEEE_802_1X = 23, - PRISM2_PARAM_ANTSEL_TX = 24, - PRISM2_PARAM_ANTSEL_RX = 25, - PRISM2_PARAM_MONITOR_TYPE = 26, - PRISM2_PARAM_WDS_TYPE = 27, - PRISM2_PARAM_HOSTSCAN = 28, - PRISM2_PARAM_AP_SCAN = 29, - - /* Instant802 additions */ - PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES = 1001, - PRISM2_PARAM_DROP_UNENCRYPTED = 1002, - PRISM2_PARAM_PREAMBLE = 1003, - PRISM2_PARAM_RATE_LIMIT = 1004, - PRISM2_PARAM_RATE_LIMIT_BURST = 1005, - PRISM2_PARAM_SHORT_SLOT_TIME = 1006, - PRISM2_PARAM_TEST_MODE = 1007, - PRISM2_PARAM_NEXT_MODE = 1008, - PRISM2_PARAM_CLEAR_KEYS = 1009, - PRISM2_PARAM_ADM_STATUS = 1010, - PRISM2_PARAM_ANTENNA_SEL = 1011, - PRISM2_PARAM_CALIB_INT = 1012, - PRISM2_PARAM_ANTENNA_MODE = 1013, - PRISM2_PARAM_PRIVACY_INVOKED = 1014, - PRISM2_PARAM_BROADCAST_SSID = 1015, - PRISM2_PARAM_STAT_TIME = 1016, - PRISM2_PARAM_STA_ANTENNA_SEL = 1017, - PRISM2_PARAM_FORCE_UNICAST_RATE = 1018, - PRISM2_PARAM_RATE_CTRL_NUM_UP = 1019, - PRISM2_PARAM_RATE_CTRL_NUM_DOWN = 1020, - PRISM2_PARAM_MAX_RATECTRL_RATE = 1021, - PRISM2_PARAM_TX_POWER_REDUCTION = 1022, - PRISM2_PARAM_EAPOL = 1023, - PRISM2_PARAM_KEY_TX_RX_THRESHOLD = 1024, - PRISM2_PARAM_KEY_INDEX = 1025, - PRISM2_PARAM_DEFAULT_WEP_ONLY = 1026, - PRISM2_PARAM_WIFI_WME_NOACK_TEST = 1033, - PRISM2_PARAM_ALLOW_BROADCAST_ALWAYS = 1034, - PRISM2_PARAM_SCAN_FLAGS = 1035, - PRISM2_PARAM_HW_MODES = 1036, - PRISM2_PARAM_CREATE_IBSS = 1037, - PRISM2_PARAM_WMM_ENABLED = 1038, - PRISM2_PARAM_MIXED_CELL = 1039, - PRISM2_PARAM_KEY_MGMT = 1040, - PRISM2_PARAM_RADAR_DETECT = 1043, - PRISM2_PARAM_SPECTRUM_MGMT = 1044, - /* NOTE: Please try to coordinate with other active development - * branches before allocating new param numbers so that each new param - * will be unique within all branches and the allocated number will not - * need to be changed when merging new features. Existing numbers in - * the mainline (or main devel branch) must not be changed when merging - * in new features. */ -}; - -/* PRISM2_IOCTL_HOSTAPD ioctl() cmd: */ -enum { - PRISM2_HOSTAPD_FLUSH = 1, - PRISM2_HOSTAPD_ADD_STA = 2, - PRISM2_HOSTAPD_REMOVE_STA = 3, - PRISM2_HOSTAPD_GET_INFO_STA = 4, - /* REMOVED: PRISM2_HOSTAPD_RESET_TXEXC_STA = 5, */ - PRISM2_SET_ENCRYPTION = 6, - PRISM2_GET_ENCRYPTION = 7, - PRISM2_HOSTAPD_SET_FLAGS_STA = 8, - PRISM2_HOSTAPD_GET_RID = 9, - PRISM2_HOSTAPD_SET_RID = 10, - PRISM2_HOSTAPD_SET_ASSOC_AP_ADDR = 11, - PRISM2_HOSTAPD_MLME = 13, - - /* Instant802 additions */ - PRISM2_HOSTAPD_SET_BEACON = 1001, - PRISM2_HOSTAPD_GET_HW_FEATURES = 1002, - PRISM2_HOSTAPD_SCAN = 1003, - PRISM2_HOSTAPD_WPA_TRIGGER = 1004, - PRISM2_HOSTAPD_SET_RATE_SETS = 1005, - PRISM2_HOSTAPD_ADD_IF = 1006, - PRISM2_HOSTAPD_REMOVE_IF = 1007, - PRISM2_HOSTAPD_GET_DOT11COUNTERSTABLE = 1008, - PRISM2_HOSTAPD_GET_LOAD_STATS = 1009, - PRISM2_HOSTAPD_SET_STA_VLAN = 1010, - PRISM2_HOSTAPD_SET_GENERIC_INFO_ELEM = 1011, - PRISM2_HOSTAPD_SET_CHANNEL_FLAG = 1012, - PRISM2_HOSTAPD_SET_REGULATORY_DOMAIN = 1013, - PRISM2_HOSTAPD_SET_TX_QUEUE_PARAMS = 1014, - PRISM2_HOSTAPD_SET_BSS = 1015, - PRISM2_HOSTAPD_GET_TX_STATS = 1016, - PRISM2_HOSTAPD_UPDATE_IF = 1017, - PRISM2_HOSTAPD_SCAN_REQ = 1019, - PRISM2_STA_GET_STATE = 1020, - PRISM2_HOSTAPD_FLUSH_IFS = 1021, - PRISM2_HOSTAPD_SET_RADAR_PARAMS = 1023, - PRISM2_HOSTAPD_SET_QUIET_PARAMS = 1024, - PRISM2_HOSTAPD_GET_TX_POWER = 1025, - /* NOTE: Please try to coordinate with other active development - * branches before allocating new param numbers so that each new param - * will be unique within all branches and the allocated number will not - * need to be changed when merging new features. Existing numbers in - * the mainline (or main devel branch) must not be changed when merging - * in new features. */ -}; - - /* these definitions mirror the ieee80211_i.h - * IEEE80211_DISABLED, ... IEEE80211_ASSOCIATED enumeration */ -enum { - PRISM2_PARAM_STA_DISABLED, - PRISM2_PARAM_STA_AUTHENTICATE, - PRISM2_PARAM_STA_ASSOCIATE, - PRISM2_PARAM_STA_ASSOCIATED, -}; - -#define PRISM2_HOSTAPD_MAX_BUF_SIZE 2048 -#define HOSTAP_CRYPT_ALG_NAME_LEN 16 - -/* Use this to make sure that structure elements are correctly aligned - * for access as other types. Most commonly, this affects the placeholder - * types used for data at the end of a structure in this union. - */ -#ifdef __GNUC__ -#undef ALIGNED -#define ALIGNED __attribute__ ((aligned)) -#else -/* Check if it has been defined elsewhere */ -#ifndef ALIGNED -#error "Must define ALIGNED to generate aligned structure elements" -#endif -#endif - -struct prism2_hostapd_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - u8 pad[2]; - union { - struct { - u16 aid; - u16 capability; - u8 supp_rates[32]; - /* atheros_super_ag and enc_flags are only used with - * IEEE80211_ATHEROS_SUPER_AG - */ - u8 atheros_super_ag; - u8 atheros_xr_mode; - u8 wds_flags; -#define IEEE80211_STA_DYNAMIC_ENC BIT(0) - u8 enc_flags; - } add_sta; - struct { - u32 inactive_msec; - u32 rx_packets; - u32 tx_packets; - u32 rx_bytes; - u32 tx_bytes; - u32 current_tx_rate; /* in 100 kbps */ - u32 channel_use; - u32 flags; - u32 num_ps_buf_frames; - u32 tx_retry_failed; - u32 tx_retry_count; - u32 last_rssi; - u32 last_ack_rssi; - } get_info_sta; - struct { - u8 alg[HOSTAP_CRYPT_ALG_NAME_LEN]; - u32 flags; - u32 err; - u8 idx; -#define HOSTAP_SEQ_COUNTER_SIZE 8 - u8 seq_counter[HOSTAP_SEQ_COUNTER_SIZE]; - u16 key_len; - u8 key[0] ALIGNED; - } crypt; - struct { - u32 flags_and; - u32 flags_or; - } set_flags_sta; - struct { - u16 rid; - u16 len; - u8 data[0] ALIGNED; - } rid; - struct { - u16 head_len; - u16 tail_len; - u8 data[0] ALIGNED; /* head_len + tail_len bytes */ - } beacon; - struct { - u16 num_modes; - u16 flags; - u8 data[0] ALIGNED; /* num_modes * feature data */ - } hw_features; - struct { - u8 now; - s8 our_mode_only; - s16 last_rx; - u16 channel; - s16 interval; /* seconds */ - s32 listen; /* microseconds */ - } scan; - struct { -#define WPA_TRIGGER_FAIL_TX_MIC BIT(0) -#define WPA_TRIGGER_FAIL_TX_ICV BIT(1) -#define WPA_TRIGGER_FAIL_RX_MIC BIT(2) -#define WPA_TRIGGER_FAIL_RX_ICV BIT(3) -#define WPA_TRIGGER_TX_REPLAY BIT(4) -#define WPA_TRIGGER_TX_REPLAY_FRAG BIT(5) -#define WPA_TRIGGER_TX_SKIP_SEQ BIT(6) - u32 trigger; - } wpa_trigger; - struct { - u16 mode; /* MODE_* */ - u16 num_supported_rates; - u16 num_basic_rates; - u8 data[0] ALIGNED; /* num_supported_rates * u16 + - * num_basic_rates * u16 */ - } set_rate_sets; - struct { - u8 type; /* WDS, VLAN, etc */ - u8 name[IFNAMSIZ]; - u8 data[0] ALIGNED; - } if_info; - struct dot11_counters { - u32 dot11TransmittedFragmentCount; - u32 dot11MulticastTransmittedFrameCount; - u32 dot11FailedCount; - u32 dot11ReceivedFragmentCount; - u32 dot11MulticastReceivedFrameCount; - u32 dot11FCSErrorCount; - u32 dot11TransmittedFrameCount; - u32 dot11WEPUndecryptableCount; - u32 dot11ACKFailureCount; - u32 dot11RTSFailureCount; - u32 dot11RTSSuccessCount; - } dot11CountersTable; - struct { -#define LOAD_STATS_CLEAR BIT(1) - u32 flags; - u32 channel_use; - } get_load_stats; - struct { - char vlan_name[IFNAMSIZ]; - int vlan_id; - } set_sta_vlan; - struct { - u8 len; - u8 data[0] ALIGNED; - } set_generic_info_elem; - struct { - u16 mode; /* MODE_* */ - u16 chan; - u32 flag; - u8 power_level; /* regulatory limit in dBm */ - u8 antenna_max; - } set_channel_flag; - struct { - u32 rd; - } set_regulatory_domain; - struct { - u32 queue; - s32 aifs; - u32 cw_min; - u32 cw_max; - u32 burst_time; /* maximum burst time in 0.1 ms, i.e., - * 10 = 1 ms */ - } tx_queue_params; - struct { - u32 bss_count; - u8 bssid_mask[ETH_ALEN]; - } set_bss; - struct ieee80211_tx_stats { - struct { - unsigned int len; /* num packets in queue */ - unsigned int limit; /* queue len (soft) limit - */ - unsigned int count; /* total num frames sent */ - } data[4]; - } get_tx_stats; - struct { - u8 ssid_len; - u8 ssid[0] ALIGNED; - } scan_req; - struct { - u32 state; - } sta_get_state; - struct { -#define MLME_STA_DEAUTH 0 -#define MLME_STA_DISASSOC 1 - u16 cmd; - u16 reason_code; - } mlme; - struct { - unsigned int value; - /* TODO - int pulse_width; - int num_pulse; - int period; - */ - }radar; - struct { - unsigned int period; - unsigned int offset; - unsigned int duration; - }quiet; - struct { - unsigned int tx_power_min; - unsigned int tx_power_max; - }tx_power; - struct { - u8 dummy[80]; /* Make sizeof() this struct large enough - * with some compiler versions. */ - } dummy; - } u; -}; - - -#ifndef IEEE80211_TX_QUEUE_NUMS -#define IEEE80211_TX_QUEUE_NUMS -/* TODO: these need to be synchronized with ieee80211.h; make a shared header - * file that can be included into low-level drivers, 80211.o, and hostapd */ -/* tx_queue_params - queue */ -enum { - IEEE80211_TX_QUEUE_DATA0 = 0, /* used for EDCA AC_VO data */ - IEEE80211_TX_QUEUE_DATA1 = 1, /* used for EDCA AC_VI data */ - IEEE80211_TX_QUEUE_DATA2 = 2, /* used for EDCA AC_BE data */ - IEEE80211_TX_QUEUE_DATA3 = 3, /* used for EDCA AC_BK data */ - IEEE80211_TX_QUEUE_DATA4 = 4, - IEEE80211_TX_QUEUE_AFTER_BEACON = 6, - IEEE80211_TX_QUEUE_BEACON = 7 -}; -#endif /* IEEE80211_TX_QUEUE_NUMS */ - - -#define HOSTAP_CRYPT_FLAG_SET_TX_KEY BIT(0) -#define HOSTAP_CRYPT_FLAG_PERMANENT BIT(1) - -#define HOSTAP_CRYPT_ERR_UNKNOWN_ALG 2 -#define HOSTAP_CRYPT_ERR_UNKNOWN_ADDR 3 -#define HOSTAP_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define HOSTAP_CRYPT_ERR_KEY_SET_FAILED 5 -#define HOSTAP_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define HOSTAP_CRYPT_ERR_CARD_CONF_FAILED 7 - -#define HOSTAP_HW_FLAG_NULLFUNC_OK BIT(0) - -enum { - IEEE80211_KEY_MGMT_NONE = 0, - IEEE80211_KEY_MGMT_IEEE8021X = 1, - IEEE80211_KEY_MGMT_WPA_PSK = 2, - IEEE80211_KEY_MGMT_WPA_EAP = 3, -}; - - -/* Data structures used for get_hw_features ioctl */ -struct hostapd_ioctl_hw_modes_hdr { - int mode; - int num_channels; - int num_rates; -}; - -struct ieee80211_channel_data { - short chan; /* channel number (IEEE 802.11) */ - short freq; /* frequency in MHz */ - int flag; /* flag for hostapd use (IEEE80211_CHAN_*) */ -}; - -struct ieee80211_rate_data { - int rate; /* rate in 100 kbps */ - int flags; /* IEEE80211_RATE_ flags */ -}; - - -/* ADD_IF, REMOVE_IF, and UPDATE_IF 'type' argument */ -enum { - HOSTAP_IF_WDS = 1, HOSTAP_IF_VLAN = 2, HOSTAP_IF_BSS = 3, - HOSTAP_IF_STA = 4 -}; - -struct hostapd_if_wds { - u8 remote_addr[ETH_ALEN]; -}; - -struct hostapd_if_vlan { - u8 id; -}; - -struct hostapd_if_bss { - u8 bssid[ETH_ALEN]; -}; - -struct hostapd_if_sta { -}; - -#endif /* HOSTAPD_IOCTL_H */ diff --git a/target/linux/package/ieee80211-dscape/src/ieee80211.c b/target/linux/package/ieee80211-dscape/src/ieee80211.c deleted file mode 100644 index 5e4e7acfba..0000000000 --- a/target/linux/package/ieee80211-dscape/src/ieee80211.c +++ /dev/null @@ -1,4895 +0,0 @@ -/* - * Copyright 2002-2005, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef EXPORT_SYMTAB -#define EXPORT_SYMTAB -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "ieee80211_i.h" -#include "ieee80211_proc.h" -#include "rate_control.h" -#include "wep.h" -#include "wpa.h" -#include "tkip.h" -#include "wme.h" - - -/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ -/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -static unsigned char rfc1042_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; -/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -static unsigned char bridge_tunnel_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; -/* No encapsulation header if EtherType < 0x600 (=length) */ - -static unsigned char eapol_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x88, 0x8e }; - - -struct rate_control_algs { - struct rate_control_algs *next; - struct rate_control_ops *ops; -}; - -static struct rate_control_algs *ieee80211_rate_ctrl_algs; - -static int rate_control_initialize(struct ieee80211_local *local); - - -static u8 * ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len); - - -struct ieee80211_key_conf * -ieee80211_key_data2conf(struct ieee80211_local *local, - struct ieee80211_key *data) -{ - struct ieee80211_key_conf *conf; - - conf = kmalloc(sizeof(*conf) + data->keylen, GFP_ATOMIC); - if (conf == NULL) - return NULL; - - conf->hw_key_idx = data->hw_key_idx; - conf->alg = data->alg; - conf->keylen = data->keylen; - conf->force_sw_encrypt = data->force_sw_encrypt; - conf->keyidx = data->keyidx; - conf->default_tx_key = data->default_tx_key; - conf->default_wep_only = local->default_wep_only; - memcpy(conf->key, data->key, data->keylen); - - return conf; -} - - -static int rate_list_match(int *rate_list, int rate) -{ - int i; - - if (rate_list == NULL) - return 0; - - for (i = 0; rate_list[i] >= 0; i++) - if (rate_list[i] == rate) - return 1; - - return 0; -} - - -void ieee80211_prepare_rates(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - int i; - - for (i = 0; i < local->num_curr_rates; i++) { - struct ieee80211_rate *rate = &local->curr_rates[i]; - - rate->flags &= ~(IEEE80211_RATE_SUPPORTED | - IEEE80211_RATE_BASIC); - - if (local->supp_rates[local->conf.phymode]) { - if (!rate_list_match(local->supp_rates - [local->conf.phymode], - rate->rate)) - continue; - } - - rate->flags |= IEEE80211_RATE_SUPPORTED; - - /* Use configured basic rate set if it is available. If not, - * use defaults that are sane for most cases. */ - if (local->basic_rates[local->conf.phymode]) { - if (rate_list_match(local->basic_rates - [local->conf.phymode], - rate->rate)) - rate->flags |= IEEE80211_RATE_BASIC; - } else switch (local->conf.phymode) { - case MODE_IEEE80211A: - if (rate->rate == 60 || rate->rate == 120 || - rate->rate == 240) - rate->flags |= IEEE80211_RATE_BASIC; - break; - case MODE_IEEE80211B: - if (rate->rate == 10 || rate->rate == 20) - rate->flags |= IEEE80211_RATE_BASIC; - break; - case MODE_ATHEROS_TURBO: - if (rate->rate == 120 || rate->rate == 240 || - rate->rate == 480) - rate->flags |= IEEE80211_RATE_BASIC; - break; - case MODE_IEEE80211G: - if (rate->rate == 10 || rate->rate == 20 || - rate->rate == 55 || rate->rate == 110) - rate->flags |= IEEE80211_RATE_BASIC; - break; - } - - /* Set ERP and MANDATORY flags based on phymode */ - switch (local->conf.phymode) { - case MODE_IEEE80211A: - if (rate->rate == 60 || rate->rate == 120 || - rate->rate == 240) - rate->flags |= IEEE80211_RATE_MANDATORY; - break; - case MODE_IEEE80211B: - if (rate->rate == 10) - rate->flags |= IEEE80211_RATE_MANDATORY; - break; - case MODE_ATHEROS_TURBO: - break; - case MODE_IEEE80211G: - if (rate->rate == 10 || rate->rate == 20 || - rate->rate == 55 || rate->rate == 110 || - rate->rate == 60 || rate->rate == 120 || - rate->rate == 240) - rate->flags |= IEEE80211_RATE_MANDATORY; - if (rate->rate != 10 && rate->rate != 20 && - rate->rate != 55 && rate->rate != 110) - rate->flags |= IEEE80211_RATE_ERP; - break; - } - } -} - - -static void ieee80211_key_threshold_notify(struct net_device *dev, - struct ieee80211_key *key, - struct sta_info *sta) -{ - struct sk_buff *skb; - struct ieee80211_msg_key_notification *msg; - - skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) + - sizeof(struct ieee80211_msg_key_notification)); - if (skb == NULL) - return; - - skb_reserve(skb, sizeof(struct ieee80211_frame_info)); - msg = (struct ieee80211_msg_key_notification *) - skb_put(skb, sizeof(struct ieee80211_msg_key_notification)); - msg->tx_rx_count = key->tx_rx_count; - memcpy(msg->ifname, dev->name, IFNAMSIZ); - if (sta) - memcpy(msg->addr, sta->addr, ETH_ALEN); - else - memset(msg->addr, 0xff, ETH_ALEN); - - key->tx_rx_count = 0; - - ieee80211_rx_mgmt(dev, skb, 0, - ieee80211_msg_key_threshold_notification); -} - - -int ieee80211_get_hdrlen(u16 fc) -{ - int hdrlen = 24; - - switch (WLAN_FC_GET_TYPE(fc)) { - case WLAN_FC_TYPE_DATA: - if ((fc & WLAN_FC_FROMDS) && (fc & WLAN_FC_TODS)) - hdrlen = 30; /* Addr4 */ - if (WLAN_FC_GET_STYPE(fc) & 0x08) - hdrlen += 2; /* QoS Control Field */ - break; - case WLAN_FC_TYPE_CTRL: - switch (WLAN_FC_GET_STYPE(fc)) { - case WLAN_FC_STYPE_CTS: - case WLAN_FC_STYPE_ACK: - hdrlen = 10; - break; - default: - hdrlen = 16; - break; - } - break; - } - - return hdrlen; -} - - -int ieee80211_get_hdrlen_from_skb(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - int hdrlen; - - if (unlikely(skb->len < 10)) - return 0; - hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); - if (unlikely(hdrlen > skb->len)) - return 0; - return hdrlen; -} - - -#ifdef IEEE80211_VERBOSE_DEBUG_FRAME_DUMP -static void ieee80211_dump_frame(const char *ifname, const char *title, - struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - u16 fc; - int hdrlen; - - printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len); - if (skb->len < 4) { - printk("\n"); - return; - } - - fc = le16_to_cpu(hdr->frame_control); - hdrlen = ieee80211_get_hdrlen(fc); - if (hdrlen > skb->len) - hdrlen = skb->len; - if (hdrlen >= 4) - printk(" FC=0x%04x DUR=0x%04x", - fc, le16_to_cpu(hdr->duration_id)); - if (hdrlen >= 10) - printk(" A1=" MACSTR, MAC2STR(hdr->addr1)); - if (hdrlen >= 16) - printk(" A2=" MACSTR, MAC2STR(hdr->addr2)); - if (hdrlen >= 24) - printk(" A3=" MACSTR, MAC2STR(hdr->addr3)); - if (hdrlen >= 30) - printk(" A4=" MACSTR, MAC2STR(hdr->addr4)); - printk("\n"); -} -#else /* IEEE80211_VERBOSE_DEBUG_FRAME_DUMP */ -static inline void ieee80211_dump_frame(const char *ifname, const char *title, - struct sk_buff *skb) -{ -} -#endif /* IEEE80211_VERBOSE_DEBUG_FRAME_DUMP */ - - -static int ieee80211_is_eapol(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr; - u16 fc; - int hdrlen; - - if (unlikely(skb->len < 10)) - return 0; - - hdr = (struct ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - - if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) - return 0; - - hdrlen = ieee80211_get_hdrlen(fc); - - if (unlikely(skb->len >= hdrlen + sizeof(eapol_header) && - memcmp(skb->data + hdrlen, eapol_header, - sizeof(eapol_header)) == 0)) - return 1; - - return 0; -} - - -static ieee80211_txrx_result -ieee80211_tx_h_rate_ctrl(struct ieee80211_txrx_data *tx) -{ - struct rate_control_extra extra; - - memset(&extra, 0, sizeof(extra)); - extra.mgmt_data = tx->sdata && - tx->sdata->type == IEEE80211_SUB_IF_TYPE_MGMT; - extra.ethertype = tx->ethertype; - extra.startidx = 0; - extra.endidx = tx->local->num_curr_rates; - - - tx->u.tx.rate = rate_control_get_rate(tx->dev, tx->skb, &extra); - if (unlikely(extra.probe != NULL)) { - tx->u.tx.control->rate_ctrl_probe = 1; - tx->u.tx.probe_last_frag = 1; -// tx->u.tx.control->alt_retry_rate = tx->u.tx.rate->val; - tx->u.tx.rate = extra.probe; - } else { -// tx->u.tx.control->alt_retry_rate = -1; - } - if (!tx->u.tx.rate) - return TXRX_DROP; - if (tx->local->conf.phymode == MODE_IEEE80211G && - tx->local->cts_protect_erp_frames && tx->fragmented && - extra.nonerp) { - tx->u.tx.last_frag_rate = tx->u.tx.rate; - tx->u.tx.last_frag_rateidx = extra.rateidx; - tx->u.tx.probe_last_frag = extra.probe ? 1 : 0; - - tx->u.tx.rate = extra.nonerp; -// tx->u.tx.control->rateidx = extra.nonerp_idx; - tx->u.tx.control->rate_ctrl_probe = 0; - } else { - tx->u.tx.last_frag_rate = tx->u.tx.rate; - tx->u.tx.last_frag_rateidx = extra.rateidx; -// tx->u.tx.control->rateidx = extra.rateidx; - } - tx->u.tx.control->tx_rate = tx->u.tx.rate->val; - if ((tx->u.tx.rate->flags & IEEE80211_RATE_PREAMBLE2) && - tx->local->short_preamble && - (!tx->sta || (tx->sta->flags & WLAN_STA_SHORT_PREAMBLE))) { - tx->u.tx.short_preamble = 1; - tx->u.tx.control->tx_rate = tx->u.tx.rate->val2; - } - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_tx_h_select_key(struct ieee80211_txrx_data *tx) -{ - if (tx->sta) - tx->u.tx.control->key_idx = tx->sta->key_idx_compression; - else - tx->u.tx.control->key_idx = HW_KEY_IDX_INVALID; - - if (unlikely(tx->u.tx.control->do_not_encrypt)) - tx->key = NULL; - else if (tx->sta && tx->sta->key) - tx->key = tx->sta->key; - else if (tx->sdata->default_key) - tx->key = tx->sdata->default_key; - else if (tx->sdata->drop_unencrypted && !(tx->sdata->eapol && ieee80211_is_eapol(tx->skb))) { - I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); - return TXRX_DROP; - } else - tx->key = NULL; - - if (tx->key) { - tx->key->tx_rx_count++; - if (unlikely(tx->local->key_tx_rx_threshold && - tx->key->tx_rx_count > - tx->local->key_tx_rx_threshold)) { - ieee80211_key_threshold_notify(tx->dev, tx->key, - tx->sta); - } - } - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_tx_h_fragment(struct ieee80211_txrx_data *tx) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; - size_t hdrlen, per_fragm, num_fragm, payload_len, left; - struct sk_buff **frags, *first, *frag; - int i; - u8 *pos; - int frag_threshold = tx->local->fragmentation_threshold; - - if (!tx->fragmented) - return TXRX_CONTINUE; - - - first = tx->skb; - - hdrlen = ieee80211_get_hdrlen(tx->fc); - payload_len = first->len - hdrlen; - per_fragm = frag_threshold - hdrlen - 4 /* FCS */; - num_fragm = (payload_len + per_fragm - 1) / per_fragm; - - frags = (struct sk_buff **) - kmalloc(num_fragm * sizeof(struct sk_buff *), GFP_ATOMIC); - if (frags == NULL) - goto fail; - memset(frags, 0, num_fragm * sizeof(struct sk_buff *)); - - hdr->frame_control |= cpu_to_le16(WLAN_FC_MOREFRAG); - pos = first->data + hdrlen + per_fragm; - left = payload_len - per_fragm; - for (i = 0; i < num_fragm - 1; i++) { - struct ieee80211_hdr *fhdr; - size_t copylen; - - if (left <= 0) - goto fail; - - /* reserve enough extra head and tail room for possible - * encryption */ -#define IEEE80211_ENCRYPT_HEADROOM 8 -#define IEEE80211_ENCRYPT_TAILROOM 12 - frag = frags[i] = - dev_alloc_skb(frag_threshold + - IEEE80211_ENCRYPT_HEADROOM + - IEEE80211_ENCRYPT_TAILROOM); - if (!frag) - goto fail; - /* Make sure that all fragments use the same priority so - * that they end up using the same TX queue */ - frag->priority = first->priority; - skb_reserve(frag, IEEE80211_ENCRYPT_HEADROOM); - fhdr = (struct ieee80211_hdr *) skb_put(frag, hdrlen); - memcpy(fhdr, first->data, hdrlen); - if (i == num_fragm - 2) - fhdr->frame_control &= cpu_to_le16(~WLAN_FC_MOREFRAG); - fhdr->seq_ctrl = cpu_to_le16(i + 1); - copylen = left > per_fragm ? per_fragm : left; - memcpy(skb_put(frag, copylen), pos, copylen); - - pos += copylen; - left -= copylen; - } - skb_trim(first, hdrlen + per_fragm); - - tx->u.tx.num_extra_frag = num_fragm - 1; - tx->u.tx.extra_frag = frags; - - return TXRX_CONTINUE; - - fail: - printk(KERN_DEBUG "%s: failed to fragment frame\n", tx->dev->name); - if (frags) { - for (i = 0; i < num_fragm - 1; i++) - if (frags[i]) - dev_kfree_skb(frags[i]); - kfree(frags); - } - I802_DEBUG_INC(tx->local->tx_handlers_drop_fragment); - return TXRX_DROP; -} - - -static int wep_encrypt_skb(struct ieee80211_txrx_data *tx, struct sk_buff *skb) -{ - if (tx->key->force_sw_encrypt || tx->local->conf.sw_encrypt) { - if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) - return -1; - } else { - tx->u.tx.control->key_idx = tx->key->hw_key_idx; - if (tx->local->hw->wep_include_iv) { - if (ieee80211_wep_add_iv(tx->local, skb, tx->key) == - NULL) - return -1; - } - } - return 0; -} - - -void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; - - hdr->frame_control |= cpu_to_le16(WLAN_FC_ISWEP); - if (tx->u.tx.extra_frag) { - struct ieee80211_hdr *fhdr; - int i; - for (i = 0; i < tx->u.tx.num_extra_frag; i++) { - fhdr = (struct ieee80211_hdr *) - tx->u.tx.extra_frag[i]->data; - fhdr->frame_control |= cpu_to_le16(WLAN_FC_ISWEP); - } - } -} - - -static ieee80211_txrx_result -ieee80211_tx_h_wep_encrypt(struct ieee80211_txrx_data *tx) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; - u16 fc; - - fc = le16_to_cpu(hdr->frame_control); - - if (!tx->key || tx->key->alg != ALG_WEP || - (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_DATA && - (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_MGMT || - WLAN_FC_GET_STYPE(fc) != WLAN_FC_STYPE_AUTH))) - return TXRX_CONTINUE; - - tx->u.tx.control->iv_len = WEP_IV_LEN; - tx->u.tx.control->icv_len = WEP_ICV_LEN; - ieee80211_tx_set_iswep(tx); - - if (wep_encrypt_skb(tx, tx->skb) < 0) { - I802_DEBUG_INC(tx->local->tx_handlers_drop_wep); - return TXRX_DROP; - } - - if (tx->u.tx.extra_frag) { - int i; - for (i = 0; i < tx->u.tx.num_extra_frag; i++) { - if (wep_encrypt_skb(tx, tx->u.tx.extra_frag[i]) < 0) { - I802_DEBUG_INC(tx->local-> - tx_handlers_drop_wep); - return TXRX_DROP; - } - } - } - - return TXRX_CONTINUE; -} - - -static inline int ceiling_div(int dividend, int divisor) -{ - return ((dividend + divisor - 1) / divisor); -} - - -static int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, - int rate, int erp, int short_preamble) -{ - int dur; - - /* calculate duration (in microseconds, rounded up to next higher - * integer if it includes a fractional microsecond) to send frame of - * len bytes (does not include FCS) at the given rate. Duration will - * also include SIFS. - * - * rate is in 100 kbps, so divident is multiplied by 10 in the - * ceiling_div() operations. - */ - - if (local->conf.phymode == MODE_IEEE80211A || erp || - local->conf.phymode == MODE_ATHEROS_TURBO) { - /* - * OFDM: - * - * N_DBPS = DATARATE x 4 - * N_SYM = Ceiling((16+8xLENGTH+6) / N_DBPS) - * (16 = SIGNAL time, 6 = tail bits) - * TXTIME = T_PREAMBLE + T_SIGNAL + T_SYM x N_SYM + Signal Ext - * - * T_SYM = 4 usec - * 802.11a - 17.5.2: aSIFSTime = 16 usec - * 802.11g - 19.8.4: aSIFSTime = 10 usec + - * signal ext = 6 usec - */ - /* FIX: Atheros Turbo may have different (shorter) duration? */ - dur = 16; /* SIFS + signal ext */ - dur += 16; /* 17.3.2.3: T_PREAMBLE = 16 usec */ - dur += 4; /* 17.3.2.3: T_SIGNAL = 4 usec */ - dur += 4 * ceiling_div((16 + 8 * (len + 4) + 6) * 10, - 4 * rate); /* T_SYM x N_SYM */ - } else { - /* - * 802.11b or 802.11g with 802.11b compatibility: - * 18.3.4: TXTIME = PreambleLength + PLCPHeaderTime + - * Ceiling(((LENGTH+PBCC)x8)/DATARATE). PBCC=0. - * - * 802.11 (DS): 15.3.3, 802.11b: 18.3.4 - * aSIFSTime = 10 usec - * aPreambleLength = 144 usec or 72 usec with short preamble - * aPLCPHeaderLength = 48 ms or 24 ms with short preamble - */ - dur = 10; /* aSIFSTime = 10 usec */ - dur += short_preamble ? (72 + 24) : (144 + 48); - - dur += ceiling_div(8 * (len + 4) * 10, rate); - } - - return dur; -} - - -static u16 ieee80211_duration(struct ieee80211_txrx_data *tx, int group_addr, - int next_frag_len) -{ - int rate, mrate, erp, dur, i; - struct ieee80211_rate *txrate = tx->u.tx.rate; - struct ieee80211_local *local = tx->local; - - erp = txrate->flags & IEEE80211_RATE_ERP; - - /* - * data and mgmt (except PS Poll): - * - during CFP: 32768 - * - during contention period: - * if addr1 is group address: 0 - * if more fragments = 0 and addr1 is individual address: time to - * transmit one ACK plus SIFS - * if more fragments = 1 and addr1 is individual address: time to - * transmit next fragment plus 2 x ACK plus 3 x SIFS - * - * IEEE 802.11, 9.6: - * - control response frame (CTS or ACK) shall be transmitted using the - * same rate as the immediately previous frame in the frame exchange - * sequence, if this rate belongs to the PHY mandatory rates, or else - * at the highest possible rate belonging to the PHY rates in the - * BSSBasicRateSet - */ - - if (WLAN_FC_GET_TYPE(tx->fc) == WLAN_FC_TYPE_CTRL) { - /* TODO: These control frames are not currently sent by - * 80211.o, but should they be implemented, this function - * needs to be updated to support duration field calculation. - * - * RTS: time needed to transmit pending data/mgmt frame plus - * one CTS frame plus one ACK frame plus 3 x SIFS - * CTS: duration of immediately previous RTS minus time - * required to transmit CTS and its SIFS - * ACK: 0 if immediately previous directed data/mgmt had - * more=0, with more=1 duration in ACK frame is duration - * from previous frame minus time needed to transmit ACK - * and its SIFS - * PS Poll: BIT(15) | BIT(14) | aid - */ - return 0; - } - - /* data/mgmt */ - if (0 /* FIX: data/mgmt during CFP */) - return 32768; - - if (group_addr) /* Group address as the destination - no ACK */ - return 0; - - /* Individual destination address: - * IEEE 802.11, Ch. 9.6 (after IEEE 802.11g changes) - * CTS and ACK frames shall be transmitted using the highest rate in - * basic rate set that is less than or equal to the rate of the - * immediately previous frame and that is using the same modulation - * (CCK or OFDM). If no basic rate set matches with these requirements, - * the highest mandatory rate of the PHY that is less than or equal to - * the rate of the previous frame is used. - * Mandatory rates for IEEE 802.11g PHY: 1, 2, 5.5, 11, 6, 12, 24 Mbps - */ - rate = -1; - mrate = 10; /* use 1 Mbps if everything fails */ - for (i = 0; i < local->num_curr_rates; i++) { - struct ieee80211_rate *r = &local->curr_rates[i]; - if (r->rate > txrate->rate) - break; - - if (IEEE80211_RATE_MODULATION(txrate->flags) != - IEEE80211_RATE_MODULATION(r->flags)) - continue; - - if (r->flags & IEEE80211_RATE_BASIC) - rate = r->rate; - else if (r->flags & IEEE80211_RATE_MANDATORY) - mrate = r->rate; - } - if (rate == -1) { - /* No matching basic rate found; use highest suitable mandatory - * PHY rate */ - rate = mrate; - } - - /* Time needed to transmit ACK - * (10 bytes + 4-byte FCS = 112 bits) plus SIFS; rounded up - * to closest integer */ - - dur = ieee80211_frame_duration(local, 10, rate, erp, - local->short_preamble); - - if (next_frag_len) { - /* Frame is fragmented: duration increases with time needed to - * transmit next fragment plus ACK and 2 x SIFS. */ - dur *= 2; /* ACK + SIFS */ - /* next fragment */ - dur += ieee80211_frame_duration(local, next_frag_len, - txrate->rate, erp, - local->short_preamble); - } - - return dur; -} - - -static ieee80211_txrx_result -ieee80211_tx_h_misc(struct ieee80211_txrx_data *tx) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; - u16 dur; - struct ieee80211_tx_control *control = tx->u.tx.control; - - if (!MULTICAST_ADDR(hdr->addr1)) { - if (tx->skb->len >= tx->local->rts_threshold && - tx->local->rts_threshold < IEEE80211_MAX_RTS_THRESHOLD) { - control->use_rts_cts = 1; - control->retry_limit = - tx->local->long_retry_limit; - } else { - control->retry_limit = - tx->local->short_retry_limit; - } - } else { - control->retry_limit = 1; - } - - if (tx->fragmented) { - /* Do not use multiple retry rates when sending fragmented - * frames. - * TODO: The last fragment could still use multiple retry - * rates. */ -// control->alt_retry_rate = -1; - } - - /* Use CTS protection for unicast frames sent using extended rates if - * there are associated non-ERP stations and RTS/CTS is not configured - * for the frame. */ - if (tx->local->conf.phymode == MODE_IEEE80211G && - (tx->u.tx.rate->flags & IEEE80211_RATE_ERP) && - tx->u.tx.unicast && - tx->local->cts_protect_erp_frames && - !control->use_rts_cts) - control->use_cts_protect = 1; - - - /* Setup duration field for the first fragment of the frame. Duration - * for remaining fragments will be updated when they are being sent - * to low-level driver in ieee80211_tx(). */ - dur = ieee80211_duration(tx, MULTICAST_ADDR(hdr->addr1), - tx->fragmented ? tx->u.tx.extra_frag[0]->len : - 0); - hdr->duration_id = cpu_to_le16(dur); - - if (control->use_rts_cts || control->use_cts_protect) { - struct ieee80211_rate *rate; - int erp = tx->u.tx.rate->flags & IEEE80211_RATE_ERP; - - /* Do not use multiple retry rates when using RTS/CTS */ -// control->alt_retry_rate = -1; - - /* Use min(data rate, max base rate) as CTS/RTS rate */ - rate = tx->u.tx.rate; - while (rate > tx->local->curr_rates && - !(rate->flags & IEEE80211_RATE_BASIC)) - rate--; - - - if (control->use_rts_cts) - dur += ieee80211_frame_duration(tx->local, 10, - rate->rate, erp, - tx->local-> - short_preamble); - dur += ieee80211_frame_duration(tx->local, tx->skb->len, - tx->u.tx.rate->rate, erp, - tx->u.tx.short_preamble); - control->rts_cts_duration = dur; - control->rts_cts_rate = rate->val; - } - - if (tx->sta) { - tx->sta->tx_packets++; - tx->sta->tx_fragments++; - tx->sta->tx_bytes += tx->skb->len; - if (tx->u.tx.extra_frag) { - int i; - tx->sta->tx_fragments += tx->u.tx.num_extra_frag; - for (i = 0; i < tx->u.tx.num_extra_frag; i++) { - tx->sta->tx_bytes += - tx->u.tx.extra_frag[i]->len; - } - } - } - tx->local->scan.txrx_count++; - - return TXRX_CONTINUE; -} - - -static void ieee80211_rate_limit(unsigned long data) -{ - struct ieee80211_local *local = (struct ieee80211_local *) data; - - if (local->rate_limit) { - local->rate_limit_bucket += local->rate_limit; - if (local->rate_limit_bucket > local->rate_limit_burst) - local->rate_limit_bucket = local->rate_limit_burst; - local->rate_limit_timer.expires = jiffies + HZ; - add_timer(&local->rate_limit_timer); - } - -} - -static ieee80211_txrx_result -ieee80211_tx_h_rate_limit(struct ieee80211_txrx_data *tx) -{ - - if (likely(!tx->local->rate_limit || tx->u.tx.unicast)) - return TXRX_CONTINUE; - - /* rate limit */ - if (tx->local->rate_limit_bucket) { - tx->local->rate_limit_bucket--; - return TXRX_CONTINUE; - } - - I802_DEBUG_INC(tx->local->tx_handlers_drop_rate_limit); - return TXRX_DROP; -} - - - -static ieee80211_txrx_result -ieee80211_tx_h_check_assoc(struct ieee80211_txrx_data *tx) -{ -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - struct sk_buff *skb = tx->skb; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - u32 sta_flags; - - if (unlikely(tx->local->sta_scanning != 0) && - (WLAN_FC_GET_TYPE(tx->fc) != WLAN_FC_TYPE_MGMT || - WLAN_FC_GET_STYPE(tx->fc) != WLAN_FC_STYPE_PROBE_REQ)) - return TXRX_DROP; - - if (tx->u.tx.ps_buffered) - return TXRX_CONTINUE; - - sta_flags = tx->sta ? tx->sta->flags : 0; - - if (likely(tx->u.tx.unicast)) { - if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && - tx->local->conf.mode != IW_MODE_ADHOC && - WLAN_FC_GET_TYPE(tx->fc) == WLAN_FC_TYPE_DATA)) { -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: dropped data frame to not " - "associated station " MACSTR "\n", - tx->dev->name, MAC2STR(hdr->addr1)); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); - return TXRX_DROP; - } - } else { - if (unlikely(WLAN_FC_GET_TYPE(tx->fc) == WLAN_FC_TYPE_DATA && - tx->local->num_sta == 0 && - !tx->local->allow_broadcast_always && - tx->local->conf.mode != IW_MODE_ADHOC)) { - /* - * No associated STAs - no need to send multicast - * frames. - */ - return TXRX_DROP; - } - return TXRX_CONTINUE; - } - - if (unlikely(!tx->u.tx.mgmt_interface && tx->sdata->ieee802_1x && - !(sta_flags & WLAN_STA_AUTHORIZED))) { -#ifdef CONFIG_IEEE80211_DEBUG - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *) tx->skb->data; - printk(KERN_DEBUG "%s: dropped frame to " MACSTR - " (unauthorized port)\n", tx->dev->name, - MAC2STR(hdr->addr1)); -#endif - I802_DEBUG_INC(tx->local->tx_handlers_drop_unauth_port); - return TXRX_DROP; - } - - return TXRX_CONTINUE; -} - - -/* This function is called whenever the AP is about to exceed the maximum limit - * of buffered frames for power saving STAs. This situation should not really - * happen often during normal operation, so dropping the oldest buffered packet - * from each queue should be OK to make some room for new frames. */ -static void purge_old_ps_buffers(struct ieee80211_local *local) -{ - int total = 0, purged = 0; - struct sk_buff *skb; - struct list_head *ptr; - - spin_lock_bh(&local->sub_if_lock); - list_for_each(ptr, &local->sub_if_list) { - struct ieee80211_if_norm *norm; - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - if (sdata->dev == local->mdev || - sdata->type != IEEE80211_SUB_IF_TYPE_NORM) - continue; - norm = &sdata->u.norm; - skb = skb_dequeue(&norm->ps_bc_buf); - if (skb) { - purged++; - dev_kfree_skb(skb); - } - total += skb_queue_len(&norm->ps_bc_buf); - } - spin_unlock_bh(&local->sub_if_lock); - - spin_lock_bh(&local->sta_lock); - list_for_each(ptr, &local->sta_list) { - struct sta_info *sta = - list_entry(ptr, struct sta_info, list); - skb = skb_dequeue(&sta->ps_tx_buf); - if (skb) { - purged++; - dev_kfree_skb(skb); - } - total += skb_queue_len(&sta->ps_tx_buf); - } - spin_unlock_bh(&local->sta_lock); - - local->total_ps_buffered = total; - printk(KERN_DEBUG "%s: PS buffers full - purged %d frames\n", - local->mdev->name, purged); -} - - -static inline ieee80211_txrx_result -ieee80211_tx_h_multicast_ps_buf(struct ieee80211_txrx_data *tx) -{ - /* broadcast/multicast frame */ - /* If any of the associated stations is in power save mode, - * the frame is buffered to be sent after DTIM beacon frame */ - if (tx->local->hw->host_broadcast_ps_buffering && - tx->sdata->type != IEEE80211_SUB_IF_TYPE_WDS && - tx->sdata->bss && atomic_read(&tx->sdata->bss->num_sta_ps) && - !(tx->fc & WLAN_FC_ORDER)) { - if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) - purge_old_ps_buffers(tx->local); - if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= - AP_MAX_BC_BUFFER) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: BC TX buffer full - " - "dropping the oldest frame\n", - tx->dev->name); - } - dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); - } else - tx->local->total_ps_buffered++; - skb_queue_tail(&tx->sdata->bss->ps_bc_buf, tx->skb); - return TXRX_QUEUED; - } - - return TXRX_CONTINUE; -} - - -static inline ieee80211_txrx_result -ieee80211_tx_h_unicast_ps_buf(struct ieee80211_txrx_data *tx) -{ - struct sta_info *sta = tx->sta; - - if (unlikely(!sta || - (WLAN_FC_GET_TYPE(tx->fc) == WLAN_FC_TYPE_MGMT && - WLAN_FC_GET_STYPE(tx->fc) == WLAN_FC_STYPE_PROBE_RESP))) - return TXRX_CONTINUE; - - if (unlikely((sta->flags & WLAN_STA_PS) && !sta->pspoll)) { - struct ieee80211_tx_packet_data *pkt_data; -#ifdef IEEE80211_VERBOSE_DEBUG_PS - printk(KERN_DEBUG "STA " MACSTR " aid %d: PS buffer (entries " - "before %d)\n", - MAC2STR(sta->addr), sta->aid, - skb_queue_len(&sta->ps_tx_buf)); -#endif /* IEEE80211_VERBOSE_DEBUG_PS */ - sta->flags |= WLAN_STA_TIM; - if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) - purge_old_ps_buffers(tx->local); - if (skb_queue_len(&sta->ps_tx_buf) >= STA_MAX_TX_BUFFER) { - struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf); - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: STA " MACSTR " TX " - "buffer full - dropping oldest frame\n", - tx->dev->name, MAC2STR(sta->addr)); - } - dev_kfree_skb(old); - } else - tx->local->total_ps_buffered++; - /* Queue frame to be sent after STA sends an PS Poll frame */ - if (skb_queue_empty(&sta->ps_tx_buf) && tx->local->hw->set_tim) - tx->local->hw->set_tim(tx->dev, sta->aid, 1); - pkt_data = (struct ieee80211_tx_packet_data *)tx->skb->cb; - pkt_data->jiffies = jiffies; - skb_queue_tail(&sta->ps_tx_buf, tx->skb); - return TXRX_QUEUED; - } -#ifdef IEEE80211_VERBOSE_DEBUG_PS - else if (unlikely(sta->flags & WLAN_STA_PS)) { - printk(KERN_DEBUG "%s: STA " MACSTR " in PS mode, but pspoll " - "set -> send frame\n", tx->dev->name, - MAC2STR(sta->addr)); - } -#endif /* IEEE80211_VERBOSE_DEBUG_PS */ - sta->pspoll = 0; - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_tx_h_ps_buf(struct ieee80211_txrx_data *tx) -{ - if (unlikely(tx->u.tx.ps_buffered)) - return TXRX_CONTINUE; - - if (tx->u.tx.unicast) - return ieee80211_tx_h_unicast_ps_buf(tx); - else - return ieee80211_tx_h_multicast_ps_buf(tx); -} - - -static void inline ieee80211_tx_prepare(struct ieee80211_txrx_data *tx, - struct sk_buff *skb, - struct net_device *dev, - struct ieee80211_tx_control *control) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct ieee80211_tx_packet_data *pkt_data; - int hdrlen; - - pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; - - memset(tx, 0, sizeof(*tx)); - tx->skb = skb; - tx->dev = pkt_data->sdata->dev; /* use original interface */ - tx->local = local; - tx->sdata = pkt_data->sdata; - tx->sta = sta_info_get(local, hdr->addr1); - tx->fc = le16_to_cpu(hdr->frame_control); - control->power_level = local->conf.power_level; - tx->u.tx.control = control; - tx->u.tx.unicast = !MULTICAST_ADDR(hdr->addr1); - control->no_ack = MULTICAST_ADDR(hdr->addr1); - tx->fragmented = local->fragmentation_threshold < - IEEE80211_MAX_FRAG_THRESHOLD && tx->u.tx.unicast && - skb->len + 4 /* FCS */ > local->fragmentation_threshold && - (local->hw->set_frag_threshold == NULL); - if (tx->sta == NULL) - control->clear_dst_mask = 1; - else if (tx->sta->clear_dst_mask) { - control->clear_dst_mask = 1; - tx->sta->clear_dst_mask = 0; - } - control->antenna_sel = local->conf.antenna_sel; - if (local->sta_antenna_sel != STA_ANTENNA_SEL_AUTO && tx->sta) - control->antenna_sel = tx->sta->antenna_sel; - hdrlen = ieee80211_get_hdrlen(tx->fc); - if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { - u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; - tx->ethertype = (pos[0] << 8) | pos[1]; - } - -} - - -static int ieee80211_tx(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_tx_control *control, int mgmt) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - ieee80211_tx_handler *handler; - struct ieee80211_txrx_data tx; - ieee80211_txrx_result res = TXRX_DROP; - int ret, i; - - if (unlikely(skb->len < 10)) { - dev_kfree_skb(skb); - return 0; - } - - ieee80211_tx_prepare(&tx, skb, dev, control); - sta = tx.sta; - tx.u.tx.mgmt_interface = mgmt; - - for (handler = local->tx_handlers; *handler != NULL; handler++) { - res = (*handler)(&tx); - if (res != TXRX_CONTINUE) - break; - } - - skb = tx.skb; /* handlers are allowed to change skb */ - - if (sta) - sta_info_release(local, sta); - - if (unlikely(res == TXRX_DROP)) { - I802_DEBUG_INC(local->tx_handlers_drop); - goto drop; - } - - if (unlikely(res == TXRX_QUEUED)) { - I802_DEBUG_INC(local->tx_handlers_queued); - return 0; - } - - ieee80211_dump_frame(dev->name, "TX to low-level driver", skb); - ret = local->hw->tx(dev, skb, control); -#ifdef IEEE80211_LEDS - if (!ret && local->tx_led_counter++ == 0) { - ieee80211_tx_led(1, dev); - } -#endif /* IEEE80211_LEDS */ - if (tx.u.tx.extra_frag) { - if (ret > 0) { - /* Must free all fragments and return 0 since skb data - * has been fragmented into multiple buffers. - * TODO: could free extra fragments and restore skb to - * the original form since the data is still there and - * then return nonzero so that Linux netif would - * retry. */ - goto drop; - } - - skb = NULL; /* skb is now owned by low-level driver */ - control->use_rts_cts = 0; - control->use_cts_protect = 0; - control->clear_dst_mask = 0; - for (i = 0; i < tx.u.tx.num_extra_frag; i++) { - int next_len, dur; - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *) - tx.u.tx.extra_frag[i]->data; - if (i + 1 < tx.u.tx.num_extra_frag) - next_len = tx.u.tx.extra_frag[i + 1]->len; - else { - next_len = 0; - tx.u.tx.rate = tx.u.tx.last_frag_rate; - tx.u.tx.control->tx_rate = tx.u.tx.rate->val; -// tx.u.tx.control->rateidx = -// tx.u.tx.last_frag_rateidx; - tx.u.tx.control->rate_ctrl_probe = - tx.u.tx.probe_last_frag; - } - dur = ieee80211_duration(&tx, 0, next_len); - hdr->duration_id = cpu_to_le16(dur); - - ieee80211_dump_frame(dev->name, - "TX to low-level driver", skb); - ret = local->hw->tx(dev, tx.u.tx.extra_frag[i], - control); - if (ret > 0) - goto drop; -#ifdef IEEE80211_LEDS - if (local->tx_led_counter++ == 0) { - ieee80211_tx_led(1, dev); - } -#endif /* IEEE80211_LEDS */ - tx.u.tx.extra_frag[i] = NULL; - } - kfree(tx.u.tx.extra_frag); - } - if (ret == -1) - ret = 0; - return ret; - - drop: - if (skb) - dev_kfree_skb(skb); - for (i = 0; i < tx.u.tx.num_extra_frag; i++) - if (tx.u.tx.extra_frag[i]) - dev_kfree_skb(tx.u.tx.extra_frag[i]); - kfree(tx.u.tx.extra_frag); - return 0; -} - - -static int ieee80211_master_start_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct ieee80211_tx_control control; - struct ieee80211_tx_packet_data *pkt_data; - struct ieee80211_sub_if_data *sdata; - int ret = 1; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - /* - * copy control out of the skb so other people can use skb->cb - */ - pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; - if (unlikely(pkt_data->magic != IEEE80211_CB_MAGIC)) { - printk(KERN_WARNING "%s: Someone messed with our skb->cb\n", - dev->name); - dev_kfree_skb(skb); - return 0; - } - memcpy(&control, &pkt_data->control, - sizeof(struct ieee80211_tx_control)); - - ret = ieee80211_tx(dev, skb, &control, - pkt_data->sdata->type == - IEEE80211_SUB_IF_TYPE_MGMT); - - return ret; -} - - -/** - * ieee80211_subif_start_xmit - netif start_xmit function for Ethernet-type - * subinterfaces (wlan#, WDS, and VLAN interfaces) - * @skb: packet to be sent - * @dev: incoming interface - * - * Returns: 0 on success (and frees skb in this case) or 1 on failure (skb will - * not be freed, and caller is responsible for either retrying later or freeing - * skb). - * - * This function takes in an Ethernet header and encapsulates it with suitable - * IEEE 802.11 header based on which interface the packet is coming in. The - * encapsulated packet will then be passed to master interface, wlan#.11, for - * transmission (through low-level driver). - */ -static int ieee80211_subif_start_xmit(struct sk_buff *skb, - struct net_device *dev) -{ - struct ieee80211_local *local = (struct ieee80211_local *) dev->priv; - struct ieee80211_tx_packet_data *pkt_data; - struct ieee80211_sub_if_data *sdata; - int ret = 1, head_need; - u16 ethertype, hdrlen, fc; - struct ieee80211_hdr hdr; - u8 *encaps_data; - int encaps_len, skip_header_bytes; - int nh_pos, h_pos, no_encrypt = 0; - struct sta_info *sta; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (unlikely(skb->len < ETH_HLEN)) { - printk(KERN_DEBUG "%s: short skb (len=%d)\n", - dev->name, skb->len); - ret = 0; - goto fail; - } - - nh_pos = skb->nh.raw - skb->data; - h_pos = skb->h.raw - skb->data; - - /* convert Ethernet header to proper 802.11 header (based on - * operation mode) */ - ethertype = (skb->data[12] << 8) | skb->data[13]; - /* TODO: handling for 802.1x authorized/unauthorized port */ - fc = (WLAN_FC_TYPE_DATA << 2) | (WLAN_FC_STYPE_DATA << 4); - - if (likely(sdata->type == IEEE80211_SUB_IF_TYPE_NORM || - sdata->type == IEEE80211_SUB_IF_TYPE_VLAN)) { - if (local->conf.mode == IW_MODE_MASTER) { - fc |= WLAN_FC_FROMDS; - /* DA BSSID SA */ - memcpy(hdr.addr1, skb->data, ETH_ALEN); - memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); - memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); - } else if (local->conf.mode == IW_MODE_INFRA) { - fc |= WLAN_FC_TODS; - /* BSSID SA DA */ - memcpy(hdr.addr1, local->bssid, ETH_ALEN); - memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); - memcpy(hdr.addr3, skb->data, ETH_ALEN); - } else if (local->conf.mode == IW_MODE_ADHOC) { - /* DA SA BSSID */ - memcpy(hdr.addr1, skb->data, ETH_ALEN); - memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); - memcpy(hdr.addr3, local->bssid, ETH_ALEN); - } - hdrlen = 24; - } else if (sdata->type == IEEE80211_SUB_IF_TYPE_WDS) { - fc |= WLAN_FC_FROMDS | WLAN_FC_TODS; - /* RA TA DA SA */ - memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); - memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN); - memcpy(hdr.addr3, skb->data, ETH_ALEN); - memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); - hdrlen = 30; - } else if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - if (local->conf.mode == IW_MODE_INFRA) { - fc |= WLAN_FC_TODS; - /* BSSID SA DA */ - memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN); - memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); - memcpy(hdr.addr3, skb->data, ETH_ALEN); - } else { - /* DA SA BSSID */ - memcpy(hdr.addr1, skb->data, ETH_ALEN); - memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); - memcpy(hdr.addr3, sdata->u.sta.bssid, ETH_ALEN); - } - hdrlen = 24; - } else { - ret = 0; - goto fail; - } - - /* receiver is QoS enabled, use a QoS type frame */ - sta = sta_info_get(local, hdr.addr1); - if (sta) { - if (sta->flags & WLAN_STA_WME) { - fc |= WLAN_FC_STYPE_QOS_DATA << 4; - hdrlen += 2; - } - sta_info_release(local, sta); - } - - hdr.frame_control = cpu_to_le16(fc); - hdr.duration_id = 0; - hdr.seq_ctrl = 0; - - skip_header_bytes = ETH_HLEN; - if (ethertype == ETH_P_AARP || ethertype == ETH_P_IPX) { - encaps_data = bridge_tunnel_header; - encaps_len = sizeof(bridge_tunnel_header); - skip_header_bytes -= 2; - } else if (ethertype >= 0x600) { - encaps_data = rfc1042_header; - encaps_len = sizeof(rfc1042_header); - skip_header_bytes -= 2; - } else { - encaps_data = NULL; - encaps_len = 0; - } - - skb_pull(skb, skip_header_bytes); - nh_pos -= skip_header_bytes; - h_pos -= skip_header_bytes; - - /* TODO: implement support for fragments so that there is no need to - * reallocate and copy payload; it might be enough to support one - * extra fragment that would be copied in the beginning of the frame - * data.. anyway, it would be nice to include this into skb structure - * somehow - * - * There are few options for this: - * use skb->cb as an extra space for 802.11 header - * allocate new buffer if not enough headroom - * make sure that there is enough headroom in every skb by increasing - * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and - * alloc_skb() (net/core/skbuff.c) - */ - head_need = hdrlen + encaps_len + (local->hw->extra_hdr_room ? 2 : 0); - head_need -= skb_headroom(skb); - - /* We are going to modify skb data, so make a copy of it if happens to - * be cloned. This could happen, e.g., with Linux bridge code passing - * us broadcast frames. */ - - if (head_need > 0 || skb_cloned(skb)) { -#if 0 - printk(KERN_DEBUG "%s: need to reallocate buffer for %d bytes " - "of headroom\n", dev->name, head_need); -#endif - - if (skb_cloned(skb)) - I802_DEBUG_INC(local->tx_expand_skb_head_cloned); - else - I802_DEBUG_INC(local->tx_expand_skb_head); - /* Since we have to reallocate the buffer, make sure that there - * is enough room for possible WEP IV/ICV and TKIP (8 bytes - * before payload and 12 after). */ - if (pskb_expand_head(skb, (head_need > 0 ? head_need + 8 : 8), - 12, GFP_ATOMIC)) { - printk(KERN_DEBUG "%s: failed to reallocate TX buffer" - "\n", dev->name); - goto fail; - } - } - - if (encaps_data) { - memcpy(skb_push(skb, encaps_len), encaps_data, encaps_len); - nh_pos += encaps_len; - h_pos += encaps_len; - } - memcpy(skb_push(skb, hdrlen), &hdr, hdrlen); - nh_pos += hdrlen; - h_pos += hdrlen; - - pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; - memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); - pkt_data->magic = IEEE80211_CB_MAGIC; - pkt_data->sdata = sdata; - pkt_data->control.do_not_encrypt = no_encrypt; - - skb->dev = sdata->master; - sdata->stats.tx_packets++; - sdata->stats.tx_bytes += skb->len; - - /* Update skb pointers to various headers since this modified frame - * is going to go through Linux networking code that may potentially - * need things like pointer to IP header. */ - skb->mac.raw = skb->data; - skb->nh.raw = skb->data + nh_pos; - skb->h.raw = skb->data + h_pos; - - - dev_queue_xmit(skb); - - return 0; - - fail: - if (!ret) - dev_kfree_skb(skb); - - return ret; -} - - -/* - * This is the transmit routine for the 802.11 type interfaces - * called by upper layers of the linux networking - * stack when it has a frame to transmit - */ -static int -ieee80211_mgmt_start_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct ieee80211_sub_if_data *sdata; - struct ieee80211_tx_packet_data *pkt_data; - struct ieee80211_hdr *hdr; - u16 fc; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - if (skb->len < 10) { - dev_kfree_skb(skb); - return 0; - } - - hdr = (struct ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - - pkt_data = (struct ieee80211_tx_packet_data *)skb->cb; - memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); - pkt_data->magic = IEEE80211_CB_MAGIC; - pkt_data->sdata = sdata; - - if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && - WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) - pkt_data->control.pkt_type = PKT_PROBE_RESP; - - skb->priority = 20; /* use hardcode priority for mgmt TX queue */ - skb->dev = sdata->master; - - /* - * We're using the protocol field of the the frame control header - * to request TX callback for hostapd. BIT(1) is checked. - */ - if ((fc & BIT(1)) == BIT(1)) { - pkt_data->control.req_tx_status = 1; - fc &= ~BIT(1); - hdr->frame_control = cpu_to_le16(fc); - } - - - - pkt_data->control.do_not_encrypt = !(fc & WLAN_FC_ISWEP); - - sdata->stats.tx_packets++; - sdata->stats.tx_bytes += skb->len; - - dev_queue_xmit(skb); - - return 0; -} - - -static void ieee80211_beacon_add_tim(struct ieee80211_local *local, - struct ieee80211_if_norm *bss, - struct sk_buff *skb) -{ - u8 *pos, *tim; - int aid0 = 0; - int i, num_bits = 0, n1, n2; - u8 bitmap[251]; - - /* Generate bitmap for TIM only if there are any STAs in power save - * mode. */ - if (atomic_read(&bss->num_sta_ps) > 0 && bss->max_aid > 0) { - memset(bitmap, 0, sizeof(bitmap)); - spin_lock_bh(&local->sta_lock); - for (i = 0; i < bss->max_aid; i++) { - if (bss->sta_aid[i] && - (!skb_queue_empty(&bss->sta_aid[i]->ps_tx_buf) || - !skb_queue_empty(&bss->sta_aid[i]->tx_filtered))) - { - bitmap[(i + 1) / 8] |= 1 << (i + 1) % 8; - num_bits++; - } - } - spin_unlock_bh(&local->sta_lock); - } - - if (bss->dtim_count == 0) - bss->dtim_count = bss->dtim_period - 1; - else - bss->dtim_count--; - - tim = pos = (u8 *) skb_put(skb, 6); - *pos++ = WLAN_EID_TIM; - *pos++ = 4; - *pos++ = bss->dtim_count; - *pos++ = bss->dtim_period; - - if (bss->dtim_count == 0 && !skb_queue_empty(&bss->ps_bc_buf)) { - aid0 = 1; - } - - if (num_bits) { - /* Find largest even number N1 so that bits numbered 1 through - * (N1 x 8) - 1 in the bitmap are 0 and number N2 so that bits - * (N2 + 1) x 8 through 2007 are 0. */ - n1 = 0; - for (i = 0; i < sizeof(bitmap); i++) { - if (bitmap[i]) { - n1 = i & 0xfe; - break; - } - } - n2 = n1; - for (i = sizeof(bitmap) - 1; i >= n1; i--) { - if (bitmap[i]) { - n2 = i; - break; - } - } - - /* Bitmap control */ - *pos++ = n1 | (aid0 ? 1 : 0); - /* Part Virt Bitmap */ - memcpy(pos, bitmap + n1, n2 - n1 + 1); - - tim[1] = n2 - n1 + 4; - skb_put(skb, n2 - n1); - } else { - *pos++ = aid0 ? 1 : 0; /* Bitmap control */ - *pos++ = 0; /* Part Virt Bitmap */ - } -} - - - - -struct sk_buff * ieee80211_beacon_get(struct net_device *dev, int bss_idx, - struct ieee80211_tx_control *control) -{ - struct ieee80211_local *local = dev->priv; - struct sk_buff *skb; - struct net_device *bdev; - struct ieee80211_sub_if_data *sdata = NULL; - struct ieee80211_if_norm *norm = NULL; - struct ieee80211_rate *rate; - struct rate_control_extra extra; - u8 *b_head, *b_tail; - int bh_len, bt_len; - - - spin_lock_bh(&local->sub_if_lock); - if (bss_idx < 0 || bss_idx >= local->bss_dev_count) - bdev = NULL; - else { - bdev = local->bss_devs[bss_idx]; - sdata = IEEE80211_DEV_TO_SUB_IF(bdev); - norm = &sdata->u.norm; - } - spin_unlock_bh(&local->sub_if_lock); - - if (bdev == NULL || norm == NULL || norm->beacon_head == NULL) { -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - if (net_ratelimit()) - printk(KERN_DEBUG "no beacon data avail for idx=%d " - "(%s)\n", bss_idx, bdev ? bdev->name : "N/A"); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - return NULL; - } - - /* Assume we are generating the normal beacon locally */ - b_head = norm->beacon_head; - b_tail = norm->beacon_tail; - bh_len = norm->beacon_head_len; - bt_len = norm->beacon_tail_len; - - - skb = dev_alloc_skb(bh_len + bt_len + 256 /* maximum TIM len */); - if (!skb) - return NULL; - - memcpy(skb_put(skb, bh_len), b_head, bh_len); - - ieee80211_beacon_add_tim(local, norm, skb); - - if (b_tail) { - memcpy(skb_put(skb, bt_len), b_tail, bt_len); - } - - memset(&extra, 0, sizeof(extra)); - extra.endidx = local->num_curr_rates; - - - rate = rate_control_get_rate(dev, skb, &extra); - if (rate == NULL) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: ieee80211_beacon_get: no rate " - "found\n", dev->name); - } - dev_kfree_skb(skb); - return NULL; - } - - control->tx_rate = (local->short_preamble && - (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? - rate->val2 : rate->val; - control->antenna_sel = local->conf.antenna_sel; - control->power_level = local->conf.power_level; - control->no_ack = 1; - control->retry_limit = 1; - control->rts_cts_duration = 0; - control->clear_dst_mask = 1; - - - norm->num_beacons++; - return skb; -} - -struct sk_buff * -ieee80211_get_buffered_bc(struct net_device *dev, int bss_idx, - struct ieee80211_tx_control *control) -{ - struct ieee80211_local *local = dev->priv; - struct sk_buff *skb; - struct sta_info *sta; - ieee80211_tx_handler *handler; - struct ieee80211_txrx_data tx; - ieee80211_txrx_result res = TXRX_DROP; - struct net_device *bdev; - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_norm *bss; - - - spin_lock_bh(&local->sub_if_lock); - if (bss_idx < 0 || bss_idx >= local->bss_dev_count) { - bdev = NULL; - bss = NULL; - } else { - bdev = local->bss_devs[bss_idx]; - sdata = IEEE80211_DEV_TO_SUB_IF(bdev); - bss = &sdata->u.norm; - } - spin_unlock_bh(&local->sub_if_lock); - if (bdev == NULL || bss == NULL || bss->beacon_head == NULL) - return NULL; - - if (bss->dtim_count != 0) - return NULL; /* send buffered bc/mc only after DTIM beacon */ - skb = skb_dequeue(&bss->ps_bc_buf); - memset(control, 0, sizeof(*control)); - if (skb == NULL) - return NULL; - local->total_ps_buffered--; - - if (!skb_queue_empty(&bss->ps_bc_buf) && skb->len >= 2) { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - /* more buffered multicast/broadcast frames ==> set MoreData - * flag in IEEE 802.11 header to inform PS STAs */ - hdr->frame_control |= cpu_to_le16(WLAN_FC_MOREDATA); - } - - ieee80211_tx_prepare(&tx, skb, dev, control); - sta = tx.sta; - tx.u.tx.ps_buffered = 1; - - for (handler = local->tx_handlers; *handler != NULL; handler++) { - res = (*handler)(&tx); - if (res == TXRX_DROP || res == TXRX_QUEUED) - break; - } - - if (res == TXRX_DROP) { - I802_DEBUG_INC(local->tx_handlers_drop); - dev_kfree_skb(skb); - skb = NULL; - } else if (res == TXRX_QUEUED) { - I802_DEBUG_INC(local->tx_handlers_queued); - skb = NULL; - } - - if (sta) - sta_info_release(local, sta); - - return skb; -} - - -int ieee80211_hw_config(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - int i, ret = 0; - -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "HW CONFIG: channel=%d freq=%d mode=%d " - "phymode=%d\n", local->conf.channel, local->conf.freq, - local->conf.mode, local->conf.phymode); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - - if (local->hw->config) - ret = local->hw->config(dev, &local->conf); - - for (i = 0; i < local->hw->num_modes; i++) { - struct ieee80211_hw_modes *mode = &local->hw->modes[i]; - if (mode->mode == local->conf.phymode) { - if (local->curr_rates != mode->rates) { - rate_control_clear(local); - } - local->curr_rates = mode->rates; - local->num_curr_rates = mode->num_rates; - ieee80211_prepare_rates(dev); - break; - } - } - - return ret; -} - - -struct ieee80211_conf *ieee80211_get_hw_conf(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - return &local->conf; -} - - -static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) -{ - /* FIX: what would be proper limits for MTU? - * This interface uses 802.3 frames. */ - if (new_mtu < 256 || new_mtu > 2304 - 24 - 6) { - printk(KERN_WARNING "%s: invalid MTU %d\n", - dev->name, new_mtu); - return -EINVAL; - } - -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - dev->mtu = new_mtu; - return 0; -} - - -static int ieee80211_change_mtu_apdev(struct net_device *dev, int new_mtu) -{ - /* FIX: what would be proper limits for MTU? - * This interface uses 802.11 frames. */ - if (new_mtu < 256 || new_mtu > 2304) { - printk(KERN_WARNING "%s: invalid MTU %d\n", - dev->name, new_mtu); - return -EINVAL; - } - -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - dev->mtu = new_mtu; - return 0; -} - - -static void ieee80211_tx_timeout(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - - printk(KERN_WARNING "%s: resetting interface.\n", dev->name); - - if (local->hw->reset(dev)) - printk(KERN_ERR "%s: failed to reset interface.\n", dev->name); - else - netif_wake_queue(dev); -} - - -static int ieee80211_set_mac_address(struct net_device *dev, void *addr) -{ - struct ieee80211_local *local = dev->priv; - struct sockaddr *a = addr; - struct list_head *ptr; - int res; - - if (!local->hw->set_mac_address) - return -EOPNOTSUPP; - - res = local->hw->set_mac_address(dev, addr); - if (res) - return res; - - list_for_each(ptr, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - memcpy(sdata->dev->dev_addr, a->sa_data, ETH_ALEN); - } - - return 0; -} - - -static struct net_device_stats *ieee80211_get_stats(struct net_device *dev) -{ - struct ieee80211_sub_if_data *sdata; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - return &(sdata->stats); -} - - -static int ieee80211_open(struct net_device *dev) -{ - struct ieee80211_sub_if_data *sdata; - struct ieee80211_local *local = dev->priv; - int res; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - if (local->open_count == 0) { - res = local->hw->open(sdata->master); - if (res) - return res; - ieee80211_init_scan(sdata->master); - } - local->open_count++; - - netif_start_queue(dev); - return 0; -} - - -static int ieee80211_stop(struct net_device *dev) -{ - struct ieee80211_sub_if_data *sdata; - struct ieee80211_local *local = dev->priv; - int res; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - netif_stop_queue(dev); - - local->open_count--; - if (local->open_count == 0) { - ieee80211_stop_scan(sdata->master); - res = local->hw->stop(sdata->master); - if (res) - return res; - } - - return 0; -} - - -static int header_parse_80211(struct sk_buff *skb, unsigned char *haddr) -{ - memcpy(haddr, skb->mac.raw + 10, ETH_ALEN); /* addr2 */ - return ETH_ALEN; -} - - -static struct net_device * -ieee80211_get_wds_dev(struct ieee80211_local *local, u8 *addr) -{ - struct list_head *ptr; - - list_for_each(ptr, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - if (sdata->type == IEEE80211_SUB_IF_TYPE_WDS && - memcmp(addr, sdata->u.wds.remote_addr, ETH_ALEN) == 0) - return sdata->dev; - } - - return NULL; -} - - -static struct net_device * ieee80211_own_bssid(struct ieee80211_local *local, - u8 *addr) -{ - int i; - struct net_device *dev = NULL; - - spin_lock_bh(&local->sub_if_lock); - for (i = 0; i < local->bss_dev_count; i++) { - if ((memcmp(local->bss_devs[i]->dev_addr, addr, ETH_ALEN) == 0) - ) { - dev = local->bss_devs[i]; - break; - } - } - spin_unlock_bh(&local->sub_if_lock); - - return dev; -} - - - - -static struct net_device * ieee80211_sta_bssid(struct ieee80211_local *local, - u8 *addr, u8 *a1, - int *sta_multicast) -{ - struct list_head *ptr; - int multicast; - u8 *own_addr = local->mdev->dev_addr; - - multicast = a1[0] & 0x01; - - /* Try O(1) lookup for a common case of only one AP being used. */ - if (own_addr[0] == a1[0] && own_addr[1] == a1[1] && - own_addr[2] == a1[2]) { - int index = (((int) a1[3] << 16) | ((int) a1[4] << 8) | a1[5]) - - (((int) own_addr[3] << 16) | - ((int) own_addr[4] << 8) | own_addr[5]); - if (index >= 0 && index < local->conf.bss_count && - local->sta_devs[index]) { - struct net_device *dev = local->sta_devs[index]; - struct ieee80211_sub_if_data *sdata; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (memcmp(addr, sdata->u.sta.bssid, ETH_ALEN) == 0) { - *sta_multicast = multicast; - return dev; - } - } - } - - if (!multicast) - return NULL; - - /* Could not find station interface, resort to O(n) lookup. */ - list_for_each(ptr, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - continue; - if (!multicast && - memcmp(a1, sdata->dev->dev_addr, ETH_ALEN) != 0) - continue; - - if (memcmp(addr, sdata->u.sta.bssid, ETH_ALEN) == 0 || - (memcmp(addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) == 0 && - local->conf.mode == IW_MODE_ADHOC)) { - *sta_multicast = multicast; - return sdata->dev; - } - } - - return NULL; -} - - -static int ieee80211_own_addr(struct net_device *dev, u8 *addr) -{ - struct ieee80211_local *local = dev->priv; - u8 *own = dev->dev_addr; - int index; - - /* Optimization: assume that BSSID mask does not change for first - * three octets. */ - if (own[0] != addr[0] || own[1] != addr[1] || own[2] != addr[2]) - return 0; - - index = (((int) addr[3] << 16) | ((int) addr[4] << 8) | addr[5]) - - (((int) own[3] << 16) | ((int) own[4] << 8) | own[5]); - if (index >= 0 && index < local->conf.bss_count && - local->sta_devs[index]) - return 1; - - return 0; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_data(struct ieee80211_txrx_data *rx) -{ - struct net_device *dev = rx->dev; - struct ieee80211_local *local = rx->local; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; - u16 fc, hdrlen, ethertype; - u8 *payload; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - struct sk_buff *skb = rx->skb, *skb2; - struct ieee80211_sub_if_data *sdata; - - fc = rx->fc; - if (unlikely(WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_DATA)) - return TXRX_CONTINUE; - - if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) - return TXRX_DROP; - - hdrlen = ieee80211_get_hdrlen(fc); - - /* convert IEEE 802.11 header + possible LLC headers into Ethernet - * header - * IEEE 802.11 address fields: - * ToDS FromDS Addr1 Addr2 Addr3 Addr4 - * 0 0 DA SA BSSID n/a - * 0 1 DA BSSID SA n/a - * 1 0 BSSID SA DA n/a - * 1 1 RA TA DA SA - */ - - switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) { - case WLAN_FC_TODS: - /* BSSID SA DA */ - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - - if (unlikely(local->conf.mode != IW_MODE_MASTER || - !ieee80211_own_bssid(local, hdr->addr1))) { - printk(KERN_DEBUG "%s: dropped ToDS frame (BSSID=" - MACSTR " SA=" MACSTR " DA=" MACSTR ")\n", - dev->name, MAC2STR(hdr->addr1), - MAC2STR(hdr->addr2), MAC2STR(hdr->addr3)); - return TXRX_DROP; - } - break; - case (WLAN_FC_TODS | WLAN_FC_FROMDS): - /* RA TA DA SA */ - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr4, ETH_ALEN); - - dev = ieee80211_get_wds_dev(local, hdr->addr2); - if (!dev || memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) != 0) { - printk(KERN_DEBUG "%s: dropped FromDS&ToDS frame (RA=" - MACSTR " TA=" MACSTR " DA=" MACSTR " SA=" - MACSTR ")\n", - rx->dev->name, MAC2STR(hdr->addr1), - MAC2STR(hdr->addr2), MAC2STR(hdr->addr3), - MAC2STR(hdr->addr4)); - return TXRX_DROP; - } - break; - case WLAN_FC_FROMDS: - /* DA BSSID SA */ - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr3, ETH_ALEN); - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA || - memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0 || - memcmp(hdr->addr2, sdata->u.sta.bssid, ETH_ALEN) != 0) { - return TXRX_DROP; - } - break; - case 0: - /* DA SA BSSID */ - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - - if (local->conf.mode != IW_MODE_ADHOC || - memcmp(hdr->addr3, local->bssid, ETH_ALEN) != 0) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: dropped IBSS frame (DA=" - MACSTR " SA=" MACSTR " BSSID=" MACSTR - ")\n", - dev->name, MAC2STR(hdr->addr1), - MAC2STR(hdr->addr2), - MAC2STR(hdr->addr3)); - } - return TXRX_DROP; - } - break; - } - - payload = skb->data + hdrlen; - - if (unlikely(skb->len - hdrlen < 8)) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: RX too short data frame " - "payload\n", dev->name); - } - return TXRX_DROP; - } - - ethertype = (payload[6] << 8) | payload[7]; - - if (likely((memcmp(payload, rfc1042_header, 6) == 0 && - ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - memcmp(payload, bridge_tunnel_header, 6) == 0)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType */ - skb_pull(skb, hdrlen + 6); - memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN); - memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN); - } else { - struct ethhdr *ehdr; - unsigned short len; - skb_pull(skb, hdrlen); - len = htons(skb->len); - ehdr = (struct ethhdr *)skb_push(skb, sizeof(struct ethhdr)); - memcpy(ehdr->h_dest, dst, ETH_ALEN); - memcpy(ehdr->h_source, src, ETH_ALEN); - ehdr->h_proto = len; - } - - if (rx->sta && !rx->sta->assoc_ap && - !(rx->sta && (rx->sta->flags & WLAN_STA_WDS))) - skb->dev = rx->sta->dev; - else - skb->dev = dev; - - skb2 = NULL; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - /* - * don't count the master since the low level code - * counts it already for us. - */ - if (skb->dev != sdata->master) { - sdata->stats.rx_packets++; - sdata->stats.rx_bytes += skb->len; - } - - if (local->bridge_packets && sdata->type != IEEE80211_SUB_IF_TYPE_WDS - && sdata->type != IEEE80211_SUB_IF_TYPE_STA) { - if (MULTICAST_ADDR(skb->data)) { - /* send multicast frames both to higher layers in - * local net stack and back to the wireless media */ - skb2 = skb_copy(skb, GFP_ATOMIC); - if (skb2 == NULL) - printk(KERN_DEBUG "%s: failed to clone " - "multicast frame\n", dev->name); - } else { - struct sta_info *dsta; - dsta = sta_info_get(local, skb->data); - if (dsta && dsta->dev == NULL) { - printk(KERN_DEBUG "Station with null dev " - "structure!\n"); - } else if (dsta && dsta->dev == dev) { - /* Destination station is associated to this - * AP, so send the frame directly to it and - * do not pass the frame to local net stack. - */ - skb2 = skb; - skb = NULL; - } - if (dsta) - sta_info_release(local, dsta); - } - } - - if (skb) { - /* deliver to local stack */ - skb->protocol = eth_type_trans(skb, dev); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); - } - - if (skb2) { - /* send to wireless media */ - skb2->protocol = __constant_htons(ETH_P_802_3); - skb2->mac.raw = skb2->nh.raw = skb2->data; - dev_queue_xmit(skb2); - } - - return TXRX_QUEUED; -} - - -static struct ieee80211_rate * -ieee80211_get_rate(struct ieee80211_local *local, int phymode, int hw_rate) -{ - int m, r; - - for (m = 0; m < local->hw->num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw->modes[m]; - if (mode->mode != phymode) - continue; - for (r = 0; r < mode->num_rates; r++) { - struct ieee80211_rate *rate = &mode->rates[r]; - if (rate->val == hw_rate || - (rate->flags & IEEE80211_RATE_PREAMBLE2 && - rate->val2 == hw_rate)) - return rate; - } - } - - return NULL; -} - - -void -ieee80211_rx_mgmt(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *status, u32 msg_type) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_frame_info *fi; - size_t hlen; - struct ieee80211_sub_if_data *sdata; - - dev = local->apdev; - skb->dev = dev; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - if (skb_headroom(skb) < sizeof(struct ieee80211_frame_info)) { - I802_DEBUG_INC(local->rx_expand_skb_head); - if (pskb_expand_head(skb, sizeof(struct ieee80211_frame_info), - 0, GFP_ATOMIC)) { - dev_kfree_skb(skb); - return; - } - } - - hlen = sizeof(struct ieee80211_frame_info); - if (msg_type == ieee80211_msg_monitor) - hlen -= sizeof(fi->msg_type); - - fi = (struct ieee80211_frame_info *) skb_push(skb, hlen); - memset(fi, 0, hlen); - if (msg_type != ieee80211_msg_monitor) - fi->msg_type = htonl(msg_type); - fi->version = htonl(IEEE80211_FI_VERSION); - fi->length = htonl(hlen); - if (status) { -// struct timespec ts; - struct ieee80211_rate *rate; - -#if 0 - jiffies_to_timespec(status->hosttime, &ts); - fi->hosttime = cpu_to_be64(ts.tv_sec * 1000000 + - ts.tv_nsec / 1000); - fi->mactime = cpu_to_be64(status->mactime); -#endif - switch (status->phymode) { - case MODE_IEEE80211A: - fi->phytype = htonl(ieee80211_phytype_ofdm_dot11_a); - break; - case MODE_IEEE80211B: - fi->phytype = htonl(ieee80211_phytype_dsss_dot11_b); - break; - case MODE_IEEE80211G: - fi->phytype = htonl(ieee80211_phytype_pbcc_dot11_g); - break; - case MODE_ATHEROS_TURBO: - fi->phytype = - htonl(ieee80211_phytype_dsss_dot11_turbo); - break; - default: - fi->phytype = 0xAAAAAAAA; - break; - } - fi->channel = htonl(status->channel); - rate = ieee80211_get_rate(local, status->phymode, - status->rate); - if (rate) { - fi->datarate = htonl(rate->rate); - if (rate->flags & IEEE80211_RATE_PREAMBLE2) { - if (status->rate == rate->val) - fi->preamble = htonl(2); /* long */ - else if (status->rate == rate->val2) - fi->preamble = htonl(1); /* short */ - } else - fi->preamble = htonl(0); - } else { - fi->datarate = htonl(0); - fi->preamble = htonl(0); - } - - fi->antenna = htonl(status->antenna); - fi->priority = 0xffffffff; /* no clue */ - fi->ssi_type = htonl(ieee80211_ssi_raw); - fi->ssi_signal = htonl(status->ssi); - fi->ssi_noise = 0x00000000; - fi->encoding = 0; - } else { - fi->ssi_type = htonl(ieee80211_ssi_none); - } - - sdata->stats.rx_packets++; - sdata->stats.rx_bytes += skb->len; - - skb->mac.raw = skb->data; - skb->ip_summed = CHECKSUM_UNNECESSARY; - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = __constant_htons(ETH_P_802_2); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); -} - - -int ieee80211_radar_status(struct net_device *dev, int channel, int radar, - int radar_type) -{ - struct sk_buff *skb; - struct ieee80211_radar_info *msg; - - skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) + - sizeof(struct ieee80211_radar_info)); - - if (skb == NULL) - return -ENOMEM; - skb_reserve(skb, sizeof(struct ieee80211_frame_info)); - - msg = (struct ieee80211_radar_info *) - skb_put(skb, sizeof(struct ieee80211_radar_info)); - msg->channel = channel; - msg->radar = radar; - msg->radar_type = radar_type; - - ieee80211_rx_mgmt(dev, skb, 0, ieee80211_msg_radar); - return 0; -} - - -int ieee80211_set_aid_for_sta(struct net_device *dev, u8 *peer_address, - u16 aid) -{ - struct sk_buff *skb; - struct ieee80211_msg_set_aid_for_sta *msg; - - skb = dev_alloc_skb(sizeof(struct ieee80211_frame_info) + - sizeof(struct ieee80211_msg_set_aid_for_sta)); - - if (skb == NULL) - return -ENOMEM; - skb_reserve(skb, sizeof(struct ieee80211_frame_info)); - - msg = (struct ieee80211_msg_set_aid_for_sta *) - skb_put(skb, sizeof(struct ieee80211_msg_set_aid_for_sta)); - memcpy(msg->sta_address, peer_address, ETH_ALEN); - msg->aid = aid; - - ieee80211_rx_mgmt(dev, skb, 0, ieee80211_msg_set_aid_for_sta); - return 0; -} - - -static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) -{ - struct ieee80211_sub_if_data *sdata; - sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); - - if (sdata->bss) - atomic_inc(&sdata->bss->num_sta_ps); - sta->flags |= WLAN_STA_PS; - sta->pspoll = 0; -#ifdef IEEE80211_VERBOSE_DEBUG_PS - printk(KERN_DEBUG "%s: STA " MACSTR " aid %d enters power " - "save mode\n", dev->name, MAC2STR(sta->addr), sta->aid); -#endif /* IEEE80211_VERBOSE_DEBUG_PS */ -} - - -static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) -{ - struct ieee80211_local *local = dev->priv; - struct sk_buff *skb; - int sent = 0; - struct ieee80211_sub_if_data *sdata; - struct ieee80211_tx_packet_data *pkt_data; - - sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); - if (sdata->bss) - atomic_dec(&sdata->bss->num_sta_ps); - sta->flags &= ~(WLAN_STA_PS | WLAN_STA_TIM); - sta->pspoll = 0; - if (!skb_queue_empty(&sta->ps_tx_buf) && local->hw->set_tim) - local->hw->set_tim(dev, sta->aid, 0); -#ifdef IEEE80211_VERBOSE_DEBUG_PS - printk(KERN_DEBUG "%s: STA " MACSTR " aid %d exits power " - "save mode\n", dev->name, MAC2STR(sta->addr), sta->aid); -#endif /* IEEE80211_VERBOSE_DEBUG_PS */ - /* Send all buffered frames to the station */ - while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { - pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; - sent++; - pkt_data->control.requeue = 1; - dev_queue_xmit(skb); - } - while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { - pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; - local->total_ps_buffered--; - sent++; -#ifdef IEEE80211_VERBOSE_DEBUG_PS - printk(KERN_DEBUG "%s: STA " MACSTR " aid %d send PS frame " - "since STA not sleeping anymore\n", dev->name, - MAC2STR(sta->addr), sta->aid); -#endif /* IEEE80211_VERBOSE_DEBUG_PS */ - pkt_data->control.requeue = 1; - dev_queue_xmit(skb); - } - - return sent; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_ieee80211_rx_h_ps_poll(struct ieee80211_txrx_data *rx) -{ - struct sk_buff *skb; - int no_pending_pkts; - - if (likely(!rx->sta || WLAN_FC_GET_TYPE(rx->fc) != WLAN_FC_TYPE_CTRL || - WLAN_FC_GET_STYPE(rx->fc) != WLAN_FC_STYPE_PSPOLL)) - return TXRX_CONTINUE; - - skb = skb_dequeue(&rx->sta->tx_filtered); - if (skb == NULL) { - skb = skb_dequeue(&rx->sta->ps_tx_buf); - if (skb) - rx->local->total_ps_buffered--; - } - no_pending_pkts = skb_queue_empty(&rx->sta->tx_filtered) && - skb_queue_empty(&rx->sta->ps_tx_buf); - - if (skb) { - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *) skb->data; - - /* tell TX path to send one frame even though the STA may - * still remain is PS mode after this frame exchange */ - rx->sta->pspoll = 1; - -#ifdef IEEE80211_VERBOSE_DEBUG_PS - printk(KERN_DEBUG "STA " MACSTR " aid %d: PS Poll (entries " - "after %d)\n", - MAC2STR(rx->sta->addr), rx->sta->aid, - skb_queue_len(&rx->sta->ps_tx_buf)); -#endif /* IEEE80211_VERBOSE_DEBUG_PS */ - - /* Use MoreData flag to indicate whether there are more - * buffered frames for this STA */ - if (no_pending_pkts) { - hdr->frame_control &= cpu_to_le16(~WLAN_FC_MOREDATA); - rx->sta->flags &= ~WLAN_STA_TIM; - } else - hdr->frame_control |= cpu_to_le16(WLAN_FC_MOREDATA); - - dev_queue_xmit(skb); - - if (no_pending_pkts && rx->local->hw->set_tim) - rx->local->hw->set_tim(rx->dev, rx->sta->aid, 0); -#ifdef IEEE80211_VERBOSE_DEBUG_PS - } else if (!rx->u.rx.sent_ps_buffered) { - printk(KERN_DEBUG "%s: STA " MACSTR " sent PS Poll even " - "though there is no buffered frames for it\n", - rx->dev->name, MAC2STR(rx->sta->addr)); -#endif /* IEEE80211_VERBOSE_DEBUG_PS */ - - } - - /* Free PS Poll skb here instead of returning TXRX_DROP that would - * count as an dropped frame. */ - dev_kfree_skb(rx->skb); - - return TXRX_QUEUED; -} - - -static inline struct ieee80211_fragment_entry * -ieee80211_reassemble_add(struct ieee80211_local *local, - unsigned int frag, unsigned int seq, int rx_queue, - struct sk_buff **skb) -{ - struct ieee80211_fragment_entry *entry; - int idx; - - idx = local->fragment_next; - entry = &local->fragments[local->fragment_next++]; - if (local->fragment_next >= IEEE80211_FRAGMENT_MAX) - local->fragment_next = 0; - - if (entry->skb) { -#ifdef CONFIG_IEEE80211_DEBUG - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *) entry->skb->data; - printk(KERN_DEBUG "%s: RX reassembly removed oldest " - "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " - "addr1=" MACSTR " addr2=" MACSTR "\n", - local->mdev->name, idx, - jiffies - entry->first_frag_time, entry->seq, - entry->last_frag, MAC2STR(hdr->addr1), - MAC2STR(hdr->addr2)); -#endif /* CONFIG_IEEE80211_DEBUG */ - dev_kfree_skb(entry->skb); - } - - entry->skb = *skb; - *skb = NULL; - entry->first_frag_time = jiffies; - entry->seq = seq; - entry->rx_queue = rx_queue; - entry->last_frag = frag; - entry->ccmp = 0; - - return entry; -} - - -static inline struct ieee80211_fragment_entry * -ieee80211_reassemble_find(struct ieee80211_local *local, - u16 fc, unsigned int frag, unsigned int seq, - int rx_queue, struct ieee80211_hdr *hdr) -{ - struct ieee80211_fragment_entry *entry; - int i, idx; - - idx = local->fragment_next; - for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { - struct ieee80211_hdr *f_hdr; - u16 f_fc; - - idx--; - if (idx < 0) - idx = IEEE80211_FRAGMENT_MAX - 1; - - entry = &local->fragments[idx]; - if (!entry->skb || entry->seq != seq || - entry->rx_queue != rx_queue || - entry->last_frag + 1 != frag) - continue; - - f_hdr = (struct ieee80211_hdr *) entry->skb->data; - f_fc = le16_to_cpu(f_hdr->frame_control); - - if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_GET_TYPE(f_fc) || - memcmp(hdr->addr1, f_hdr->addr1, ETH_ALEN) != 0 || - memcmp(hdr->addr2, f_hdr->addr2, ETH_ALEN) != 0) - continue; - - if (entry->first_frag_time + 2 * HZ < jiffies) { - dev_kfree_skb(entry->skb); - entry->skb = NULL; - continue; - } - return entry; - } - - return NULL; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_defragment(struct ieee80211_txrx_data *rx) -{ - struct ieee80211_hdr *hdr; - u16 sc; - unsigned int frag, seq; - struct ieee80211_fragment_entry *entry; - - hdr = (struct ieee80211_hdr *) rx->skb->data; - sc = le16_to_cpu(hdr->seq_ctrl); - frag = WLAN_GET_SEQ_FRAG(sc); - - if (likely((!(rx->fc & WLAN_FC_MOREFRAG) && frag == 0) || - (rx->skb)->len < 24 || MULTICAST_ADDR(hdr->addr1))) { - /* not fragmented */ - goto out; - } - I802_DEBUG_INC(rx->local->rx_handlers_fragments); - - seq = WLAN_GET_SEQ_SEQ(sc); - - if (frag == 0) { - /* This is the first fragment of a new frame. */ - entry = ieee80211_reassemble_add(rx->local, frag, seq, - rx->u.rx.queue, &(rx->skb)); - if (rx->key && rx->key->alg == ALG_CCMP && - (rx->fc & WLAN_FC_ISWEP)) { - /* Store CCMP PN so that we can verify that the next - * fragment has a sequential PN value. */ - entry->ccmp = 1; - memcpy(entry->last_pn, - rx->key->u.ccmp.rx_pn[rx->u.rx.queue], - CCMP_PN_LEN); - } - return TXRX_QUEUED; - } - - /* This is a fragment for a frame that should already be pending in - * fragment cache. Add this fragment to the end of the pending entry. - */ - entry = ieee80211_reassemble_find(rx->local, rx->fc, frag, seq, - rx->u.rx.queue, hdr); - if (!entry) { - I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); - return TXRX_DROP; - } - - /* Verify that MPDUs within one MSDU have sequential PN values. - * (IEEE 802.11i, 8.3.3.4.5) */ - if (entry->ccmp) { - int i; - u8 pn[CCMP_PN_LEN], *rpn; - if (rx->key == NULL || rx->key->alg != ALG_CCMP) - return TXRX_DROP; - memcpy(pn, entry->last_pn, CCMP_PN_LEN); - for (i = CCMP_PN_LEN - 1; i >= 0; i--) { - pn[i]++; - if (pn[i]) - break; - } - rpn = rx->key->u.ccmp.rx_pn[rx->u.rx.queue]; - if (memcmp(pn, rpn, CCMP_PN_LEN) != 0) { - printk(KERN_DEBUG "%s: defrag: CCMP PN not sequential" - " A2=" MACSTR " PN=%02x%02x%02x%02x%02x%02x " - "(expected %02x%02x%02x%02x%02x%02x)\n", - rx->dev->name, MAC2STR(hdr->addr2), - rpn[0], rpn[1], rpn[2], rpn[3], rpn[4], rpn[5], - pn[0], pn[1], pn[2], pn[3], pn[4], pn[5]); - return TXRX_DROP; - } - memcpy(entry->last_pn, pn, CCMP_PN_LEN); - } - - /* TODO: could gather list of skb's and reallocate data buffer only - * after finding out the total length of the frame */ - skb_pull(rx->skb, ieee80211_get_hdrlen(rx->fc)); - if (skb_tailroom(entry->skb) < rx->skb->len) { - I802_DEBUG_INC(rx->local->rx_expand_skb_head2); - if (unlikely(pskb_expand_head(entry->skb, 0, rx->skb->len, - GFP_ATOMIC))) { - I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); - return TXRX_DROP; - } - } - memcpy(skb_put(entry->skb, rx->skb->len), rx->skb->data, rx->skb->len); - entry->last_frag = frag; - dev_kfree_skb(rx->skb); - - if (rx->fc & WLAN_FC_MOREFRAG) { - rx->skb = NULL; - return TXRX_QUEUED; - } - - /* Complete frame has been reassembled - process it now */ - rx->skb = entry->skb; - rx->fragmented = 1; - entry->skb = NULL; - - out: - if (rx->sta) - rx->sta->rx_packets++; - if (MULTICAST_ADDR(hdr->addr1)) - rx->local->dot11MulticastReceivedFrameCount++; -#ifdef IEEE80211_LEDS - else - ieee80211_rx_led(2, rx->dev); -#endif /* IEEE80211_LEDS */ - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_monitor(struct ieee80211_txrx_data *rx) -{ - if (rx->local->conf.mode == IW_MODE_MONITOR) { - ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status, - ieee80211_msg_monitor); - return TXRX_QUEUED; - } - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_check(struct ieee80211_txrx_data *rx) -{ - struct ieee80211_hdr *hdr; - int always_sta_key; - hdr = (struct ieee80211_hdr *) rx->skb->data; - - /* Drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.2.9) */ - if (rx->sta && !MULTICAST_ADDR(hdr->addr1)) { - if (unlikely(rx->fc & WLAN_FC_RETRY && - rx->sta->last_seq_ctrl[rx->u.rx.queue] == - hdr->seq_ctrl)) { - rx->local->dot11FrameDuplicateCount++; - rx->sta->num_duplicates++; - return TXRX_DROP; - } else - rx->sta->last_seq_ctrl[rx->u.rx.queue] = hdr->seq_ctrl; - } - - if (rx->local->hw->rx_includes_fcs && rx->skb->len > FCS_LEN) - skb_trim(rx->skb, rx->skb->len - FCS_LEN); - - if (unlikely(rx->skb->len < 16)) { - I802_DEBUG_INC(rx->local->rx_handlers_drop_short); - return TXRX_DROP; - } - - /* Filter out foreign unicast packets when in promiscuous mode. - * FIX: Filter out multicast to foreign BSSID. */ - if (rx->local->conf.mode == IW_MODE_INFRA && - !MULTICAST_ADDR(hdr->addr1) && - !ieee80211_own_addr(rx->dev, hdr->addr1)) - return TXRX_DROP; - - /* Drop disallowed frame classes based on STA auth/assoc state; - * IEEE 802.11, Chap 5.5. - * - * 80211.o does filtering only based on association state, i.e., it - * drops Class 3 frames from not associated stations. hostapd sends - * deauth/disassoc frames when needed. In addition, hostapd is - * responsible for filtering on both auth and assoc states. - */ - if (unlikely((WLAN_FC_GET_TYPE(rx->fc) == WLAN_FC_TYPE_DATA || - (WLAN_FC_GET_TYPE(rx->fc) == WLAN_FC_TYPE_CTRL && - WLAN_FC_GET_STYPE(rx->fc) == WLAN_FC_STYPE_PSPOLL)) && - rx->local->conf.mode != IW_MODE_ADHOC && - (!rx->sta || !(rx->sta->flags & WLAN_STA_ASSOC)))) { - if (!(rx->fc & WLAN_FC_FROMDS) && !(rx->fc & WLAN_FC_TODS)) { - /* Drop IBSS frames silently. */ - return TXRX_DROP; - } - - ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status, - ieee80211_msg_sta_not_assoc); - return TXRX_QUEUED; - } - - if (rx->local->conf.mode == IW_MODE_INFRA) - always_sta_key = 0; - else - always_sta_key = 1; - - if (rx->sta && rx->sta->key && always_sta_key) { - rx->key = rx->sta->key; - } else { - if (!rx->sdata) { - printk(KERN_DEBUG "%s: sdata was null in packet!!\n", - rx->dev->name); - printk(KERN_DEBUG "%s: Addr1: " MACSTR "\n", - rx->dev->name, MAC2STR(hdr->addr1)); - printk(KERN_DEBUG "%s: Addr2: " MACSTR "\n", - rx->dev->name, MAC2STR(hdr->addr2)); - printk(KERN_DEBUG "%s: Addr3: " MACSTR "\n", - rx->dev->name, MAC2STR(hdr->addr3)); - return TXRX_DROP; - } - if (rx->sta && rx->sta->key) - rx->key = rx->sta->key; - else - rx->key = rx->sdata->default_key; - - if (rx->local->hw->wep_include_iv && - rx->fc & WLAN_FC_ISWEP) { - int keyidx = ieee80211_wep_get_keyidx(rx->skb); - - if (keyidx >= 0 && keyidx < NUM_DEFAULT_KEYS && - (rx->sta == NULL || rx->sta->key == NULL || - keyidx > 0)) { - rx->key = rx->sdata->keys[keyidx]; - } - if (!rx->key) { - printk(KERN_DEBUG "%s: RX WEP frame with " - "unknown keyidx %d (A1=" MACSTR " A2=" - MACSTR " A3=" MACSTR ")\n", - rx->dev->name, keyidx, - MAC2STR(hdr->addr1), - MAC2STR(hdr->addr2), - MAC2STR(hdr->addr3)); - ieee80211_rx_mgmt( - rx->dev, rx->skb, rx->u.rx.status, - ieee80211_msg_wep_frame_unknown_key); - return TXRX_QUEUED; - } - } - } - - if (rx->fc & WLAN_FC_ISWEP && rx->key) { - rx->key->tx_rx_count++; - if (unlikely(rx->local->key_tx_rx_threshold && - rx->key->tx_rx_count > - rx->local->key_tx_rx_threshold)) { - ieee80211_key_threshold_notify(rx->dev, rx->key, - rx->sta); - } - } - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_sta_process(struct ieee80211_txrx_data *rx) -{ - struct sta_info *sta = rx->sta; - struct net_device *dev = rx->dev; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; - - if (!sta) - return TXRX_CONTINUE; - - /* Update last_rx only for IBSS packets which are for the current - * BSSID to avoid keeping the current IBSS network alive in cases where - * other STAs are using different BSSID. */ - if (rx->local->conf.mode == IW_MODE_ADHOC) { - u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len); - if (memcmp(bssid, rx->local->bssid, ETH_ALEN) == 0) - sta->last_rx = jiffies; - } else - if (!MULTICAST_ADDR(hdr->addr1) || - rx->local->conf.mode == IW_MODE_INFRA) { - /* Update last_rx only for unicast frames in order to prevent - * the Probe Request frames (the only broadcast frames from a - * STA in infrastructure mode) from keeping a connection alive. - */ - sta->last_rx = jiffies; - } - sta->rx_fragments++; - sta->rx_bytes += rx->skb->len; - sta->last_rssi = rx->u.rx.status->ssi; - - if (!(rx->fc & WLAN_FC_MOREFRAG)) { - /* Change STA power saving mode only in the end of a frame - * exchange sequence */ - if ((sta->flags & WLAN_STA_PS) && !(rx->fc & WLAN_FC_PWRMGT)) - rx->u.rx.sent_ps_buffered += ap_sta_ps_end(dev, sta); - else if (!(sta->flags & WLAN_STA_PS) && - (rx->fc & WLAN_FC_PWRMGT)) - ap_sta_ps_start(dev, sta); - } - - /* Drop data::nullfunc frames silently, since they are used only to - * control station power saving mode. */ - if (WLAN_FC_GET_TYPE(rx->fc) == WLAN_FC_TYPE_DATA && - WLAN_FC_GET_STYPE(rx->fc) == WLAN_FC_STYPE_NULLFUNC) { - I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); - /* Update counter and free packet here to avoid counting this - * as a dropped packed. */ - sta->rx_packets++; - dev_kfree_skb(rx->skb); - return TXRX_QUEUED; - } - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_wep_weak_iv_detection(struct ieee80211_txrx_data *rx) -{ - if (!rx->sta || !(rx->fc & WLAN_FC_ISWEP) || - WLAN_FC_GET_TYPE(rx->fc) != WLAN_FC_TYPE_DATA || !rx->key || - rx->key->alg != ALG_WEP) - return TXRX_CONTINUE; - - /* Check for weak IVs, if hwaccel did not remove IV from the frame */ - if (rx->local->hw->wep_include_iv || - rx->key->force_sw_encrypt || rx->local->conf.sw_decrypt) { - u8 *iv = ieee80211_wep_is_weak_iv(rx->skb, rx->key); - if (iv) { - rx->sta->wep_weak_iv_count++; - } - } - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_wep_decrypt(struct ieee80211_txrx_data *rx) -{ - /* If the device handles decryption totally, skip this test */ - if (rx->local->hw->device_hides_wep) - return TXRX_CONTINUE; - - if ((rx->key && rx->key->alg != ALG_WEP) || - !(rx->fc & WLAN_FC_ISWEP) || - (WLAN_FC_GET_TYPE(rx->fc) != WLAN_FC_TYPE_DATA && - (WLAN_FC_GET_TYPE(rx->fc) != WLAN_FC_TYPE_MGMT || - WLAN_FC_GET_STYPE(rx->fc) != WLAN_FC_STYPE_AUTH))) - return TXRX_CONTINUE; - - if (!rx->key) { - printk(KERN_DEBUG "%s: RX WEP frame, but no key set\n", - rx->dev->name); - return TXRX_DROP; - } - - if (!(rx->u.rx.status->flag & RX_FLAG_DECRYPTED) || - rx->key->force_sw_encrypt || rx->local->conf.sw_decrypt) { - if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) { - printk(KERN_DEBUG "%s: RX WEP frame, decrypt " - "failed\n", rx->dev->name); - return TXRX_DROP; - } - } else if (rx->local->hw->wep_include_iv) { - ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); - /* remove ICV */ - skb_trim(rx->skb, rx->skb->len - 4); - } - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_802_1x_pae(struct ieee80211_txrx_data *rx) -{ - if (rx->sdata->eapol && ieee80211_is_eapol(rx->skb) && - rx->local->conf.mode != IW_MODE_INFRA) { - /* Pass both encrypted and unencrypted EAPOL frames to user - * space for processing. */ - ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status, - ieee80211_msg_normal); - return TXRX_QUEUED; - } - - if (unlikely(rx->sdata->ieee802_1x && - WLAN_FC_GET_TYPE(rx->fc) == WLAN_FC_TYPE_DATA && - WLAN_FC_GET_STYPE(rx->fc) != WLAN_FC_STYPE_NULLFUNC && - (!rx->sta || !(rx->sta->flags & WLAN_STA_AUTHORIZED)) && - !ieee80211_is_eapol(rx->skb))) { -#ifdef CONFIG_IEEE80211_DEBUG - struct ieee80211_hdr *hdr = - (struct ieee80211_hdr *) rx->skb->data; - printk(KERN_DEBUG "%s: dropped frame from " MACSTR - " (unauthorized port)\n", rx->dev->name, - MAC2STR(hdr->addr2)); -#endif /* CONFIG_IEEE80211_DEBUG */ - return TXRX_DROP; - } - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_drop_unencrypted(struct ieee80211_txrx_data *rx) -{ - /* If the device handles decryption totally, skip this test */ - if (rx->local->hw->device_hides_wep) - return TXRX_CONTINUE; - - /* Drop unencrypted frames if key is set. */ - if (unlikely(!(rx->fc & WLAN_FC_ISWEP) && - WLAN_FC_GET_TYPE(rx->fc) == WLAN_FC_TYPE_DATA && - WLAN_FC_GET_STYPE(rx->fc) != WLAN_FC_STYPE_NULLFUNC && - (rx->key || rx->sdata->drop_unencrypted) && - (rx->sdata->eapol == 0 || - !ieee80211_is_eapol(rx->skb)))) { - printk(KERN_DEBUG "%s: RX non-WEP frame, but expected " - "encryption\n", rx->dev->name); - return TXRX_DROP; - } - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_mgmt(struct ieee80211_txrx_data *rx) -{ - struct ieee80211_sub_if_data *sdata; - sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status); - } else { - /* Management frames are sent to hostapd for processing */ - ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status, - ieee80211_msg_normal); - } - return TXRX_QUEUED; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_passive_scan(struct ieee80211_txrx_data *rx) -{ - struct ieee80211_local *local = rx->local; - struct sk_buff *skb = rx->skb; - - if (unlikely(local->sta_scanning != 0)) { - ieee80211_sta_rx_scan(rx->dev, skb, rx->u.rx.status); - return TXRX_QUEUED; - } - - if (WLAN_FC_GET_TYPE(rx->fc) == WLAN_FC_TYPE_DATA) - local->scan.txrx_count++; - if (unlikely(local->scan.in_scan != 0 && - rx->u.rx.status->freq == local->scan.freq)) { - struct ieee80211_hdr *hdr; - u16 fc; - - local->scan.rx_packets++; - - hdr = (struct ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - - if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT && - WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) { - local->scan.rx_beacon++; - /* Need to trim FCS here because it is normally - * removed only after this passive scan handler. */ - if (rx->local->hw->rx_includes_fcs && - rx->skb->len > FCS_LEN) - skb_trim(rx->skb, rx->skb->len - FCS_LEN); - - ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status, - ieee80211_msg_passive_scan); - return TXRX_QUEUED; - } else { - I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); - return TXRX_DROP; - } - } - - return TXRX_CONTINUE; -} - - -static u8 * ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len) -{ - u16 fc; - - if (len < 24) - return NULL; - - fc = le16_to_cpu(hdr->frame_control); - - switch (WLAN_FC_GET_TYPE(fc)) { - case WLAN_FC_TYPE_DATA: - switch (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) { - case WLAN_FC_TODS: - return hdr->addr1; - case (WLAN_FC_TODS | WLAN_FC_FROMDS): - return NULL; - case WLAN_FC_FROMDS: - return hdr->addr2; - case 0: - return hdr->addr3; - } - break; - case WLAN_FC_TYPE_MGMT: - return hdr->addr3; - case WLAN_FC_TYPE_CTRL: - if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PSPOLL) - return hdr->addr1; - else - return NULL; - } - - return NULL; -} - - -static struct net_device * ieee80211_get_rx_dev(struct ieee80211_local *local, - struct ieee80211_hdr *hdr, - size_t len, int *sta_broadcast) -{ - u8 *bssid; - struct net_device *dev; - u16 fc; - - bssid = ieee80211_get_bssid(hdr, len); - if (bssid) { - dev = ieee80211_own_bssid(local, bssid); - if (!dev && (local->conf.mode == IW_MODE_INFRA || - local->conf.mode == IW_MODE_ADHOC)) - dev = ieee80211_sta_bssid(local, bssid, hdr->addr1, - sta_broadcast); - if (dev) - return dev; - } - - if (len >= 30) { - fc = le16_to_cpu(hdr->frame_control); - if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA && - (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == - (WLAN_FC_TODS | WLAN_FC_FROMDS)) { - dev = ieee80211_get_wds_dev(local, hdr->addr2); - if (dev) - return dev; - } - } - - /* Default to default device if nothing else matches */ - return local->wdev; -} - - -static void ieee80211_rx_michael_mic_report(struct net_device *dev, - struct ieee80211_hdr *hdr, - struct sta_info *sta, - struct ieee80211_txrx_data *rx) -{ - int keyidx, hdrlen; - - hdrlen = ieee80211_get_hdrlen_from_skb(rx->skb); - if (rx->skb->len >= hdrlen + 4) - keyidx = rx->skb->data[hdrlen + 3] >> 6; - else - keyidx = -1; - - /* TODO: verify that this is not triggered by fragmented - * frames (hw does not verify MIC for them). */ - printk(KERN_DEBUG "%s: TKIP hwaccel reported Michael MIC " - "failure from " MACSTR " to " MACSTR " keyidx=%d\n", - dev->name, MAC2STR(hdr->addr2), MAC2STR(hdr->addr1), keyidx); - - if (sta == NULL) { - /* Some hardware versions seem to generate incorrect - * Michael MIC reports; ignore them to avoid triggering - * countermeasures. */ - printk(KERN_DEBUG "%s: ignored spurious Michael MIC " - "error for unknown address " MACSTR "\n", - dev->name, MAC2STR(hdr->addr2)); - goto ignore; - } - - if (!(rx->fc & WLAN_FC_ISWEP)) { - printk(KERN_DEBUG "%s: ignored spurious Michael MIC " - "error for a frame with no ISWEP flag (src " - MACSTR ")\n", dev->name, MAC2STR(hdr->addr2)); - goto ignore; - } - - if (rx->local->hw->wep_include_iv && - rx->local->conf.mode == IW_MODE_MASTER) { - int keyidx = ieee80211_wep_get_keyidx(rx->skb); - /* AP with Pairwise keys support should never receive Michael - * MIC errors for non-zero keyidx because these are reserved - * for group keys and only the AP is sending real multicast - * frames in BSS. */ - if (keyidx) { - printk(KERN_DEBUG "%s: ignored Michael MIC error for " - "a frame with non-zero keyidx (%d) (src " MACSTR - ")\n", dev->name, keyidx, MAC2STR(hdr->addr2)); - goto ignore; - } - } - - if (WLAN_FC_GET_TYPE(rx->fc) != WLAN_FC_TYPE_DATA && - (WLAN_FC_GET_TYPE(rx->fc) != WLAN_FC_TYPE_MGMT || - WLAN_FC_GET_STYPE(rx->fc) != WLAN_FC_STYPE_AUTH)) { - printk(KERN_DEBUG "%s: ignored spurious Michael MIC " - "error for a frame that cannot be encrypted " - "(fc=0x%04x) (src " MACSTR ")\n", - dev->name, rx->fc, MAC2STR(hdr->addr2)); - goto ignore; - } - - do { - union iwreq_data wrqu; - char *buf = kmalloc(128, GFP_ATOMIC); - if (buf == NULL) - break; - - /* TODO: needed parameters: count, key type, TSC */ - sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" - "keyid=%d %scast addr=" MACSTR ")", - keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", - MAC2STR(hdr->addr2)); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(rx->dev, IWEVCUSTOM, &wrqu, buf); - kfree(buf); - } while (0); - - /* TODO: consider verifying the MIC error report with software - * implementation if we get too many spurious reports from the - * hardware. */ - ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status, - ieee80211_msg_michael_mic_failure); - return; - - ignore: - dev_kfree_skb(rx->skb); - rx->skb = NULL; -} - - -static void ieee80211_sta_rx_broadcast(struct ieee80211_txrx_data *rx) -{ - struct ieee80211_local *local = rx->dev->priv; - u8 *_bssid, bssid[ETH_ALEN]; - struct sk_buff *orig_skb = rx->skb, *skb; - struct ieee80211_hdr *hdr; - ieee80211_rx_handler *handler; - ieee80211_txrx_result res; - struct list_head *ptr; - - hdr = (struct ieee80211_hdr *) orig_skb->data; - _bssid = ieee80211_get_bssid(hdr, orig_skb->len); - if (_bssid == NULL) { - dev_kfree_skb(orig_skb); - return; - } - memcpy(bssid, _bssid, ETH_ALEN); - - list_for_each(ptr, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA || - (memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) != 0 && - !(bssid[0] & 0x01))) - continue; - - skb = skb_copy(orig_skb, GFP_ATOMIC); - if (skb == NULL) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: failed to copy " - "multicast frame for %s", - rx->dev->name, sdata->dev->name); - } - continue; - } - - hdr = (struct ieee80211_hdr *) skb->data; - rx->skb = skb; - rx->dev = sdata->dev; - rx->sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); - - res = TXRX_DROP; - for (handler = local->rx_handlers; *handler != NULL; handler++) - { - res = (*handler)(rx); - if (res == TXRX_DROP || res == TXRX_QUEUED) - break; - } - - if (res == TXRX_DROP || *handler == NULL) - dev_kfree_skb(skb); - } - - dev_kfree_skb(orig_skb); -} - - -/* - * This is the receive path handler. It is called by a low level driver when an - * 802.11 MPDU is received from the hardware. - */ -void ieee80211_rx(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *status) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - struct ieee80211_hdr *hdr; - ieee80211_rx_handler *handler; - struct ieee80211_txrx_data rx; - ieee80211_txrx_result res = TXRX_DROP; - u16 type; - int sta_broadcast = 0; - - hdr = (struct ieee80211_hdr *) skb->data; - memset(&rx, 0, sizeof(rx)); - rx.skb = skb; - rx.local = local; - if (skb->len >= 16) { - sta = rx.sta = sta_info_get(local, hdr->addr2); - if (unlikely(sta == NULL && - local->conf.mode == IW_MODE_ADHOC)) { - u8 *bssid = ieee80211_get_bssid(hdr, skb->len); - if (bssid && - memcmp(bssid, local->bssid, ETH_ALEN) == 0) - sta = rx.sta = - ieee80211_ibss_add_sta(dev, skb, bssid, - hdr->addr2); - } - } else - sta = rx.sta = NULL; - if (sta && !sta->assoc_ap && !(sta->flags & WLAN_STA_WDS)) - rx.dev = sta->dev; - else - rx.dev = ieee80211_get_rx_dev(local, hdr, skb->len, - &sta_broadcast); - - rx.sdata = IEEE80211_DEV_TO_SUB_IF(rx.dev); - rx.u.rx.status = status; - rx.fc = skb->len >= 2 ? le16_to_cpu(hdr->frame_control) : 0; - type = WLAN_FC_GET_TYPE(rx.fc); - if (type == WLAN_FC_TYPE_DATA || type == WLAN_FC_TYPE_MGMT) - local->dot11ReceivedFragmentCount++; - if (sta_broadcast) { - ieee80211_sta_rx_broadcast(&rx); - goto end; - } - - if ((status->flag & RX_FLAG_MMIC_ERROR)) { - ieee80211_rx_michael_mic_report(dev, hdr, sta, &rx); - goto end; - } - - for (handler = local->rx_handlers; *handler != NULL; handler++) { - res = (*handler)(&rx); - if (res != TXRX_CONTINUE) { - if (res == TXRX_DROP) { - I802_DEBUG_INC(local->rx_handlers_drop); - if (sta) - sta->rx_dropped++; - } - if (res == TXRX_QUEUED) - I802_DEBUG_INC(local->rx_handlers_queued); - break; - } - } - - if (res == TXRX_DROP || *handler == NULL) - dev_kfree_skb(skb); - - end: - if (sta) - sta_info_release(local, sta); -} - - -static ieee80211_txrx_result -ieee80211_tx_h_load_stats(struct ieee80211_txrx_data *tx) -{ - struct ieee80211_local *local = tx->local; - struct sk_buff *skb = tx->skb; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - u32 load = 0, hdrtime; - - /* TODO: this could be part of tx_status handling, so that the number - * of retries would be known; TX rate should in that case be stored - * somewhere with the packet */ - - /* Estimate total channel use caused by this frame */ - - /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, - * 1 usec = 1/8 * (1080 / 10) = 13.5 */ - - if (local->conf.phymode == MODE_IEEE80211A || - local->conf.phymode == MODE_ATHEROS_TURBO || - local->conf.phymode == MODE_ATHEROS_TURBOG || - (local->conf.phymode == MODE_IEEE80211G && - tx->u.tx.rate->flags & IEEE80211_RATE_ERP)) - hdrtime = CHAN_UTIL_HDR_SHORT; - else - hdrtime = CHAN_UTIL_HDR_LONG; - - load = hdrtime; - if (!MULTICAST_ADDR(hdr->addr1)) - load += hdrtime; - - if (tx->u.tx.control->use_rts_cts) - load += 2 * hdrtime; - else if (tx->u.tx.control->use_cts_protect) - load += hdrtime; - - load += skb->len * tx->u.tx.rate->rate_inv; - - if (tx->u.tx.extra_frag) { - int i; - for (i = 0; i < tx->u.tx.num_extra_frag; i++) { - load += 2 * hdrtime; - load += tx->u.tx.extra_frag[i]->len * - tx->u.tx.rate->rate; - } - } - - /* Divide channel_use by 8 to avoid wrapping around the counter */ - load >>= CHAN_UTIL_SHIFT; - local->channel_use_raw += load; - if (tx->sta) - tx->sta->channel_use_raw += load; - tx->sdata->channel_use_raw += load; - - return TXRX_CONTINUE; -} - - -static ieee80211_txrx_result -ieee80211_rx_h_load_stats(struct ieee80211_txrx_data *rx) -{ - struct ieee80211_local *local = rx->local; - struct sk_buff *skb = rx->skb; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - u32 load = 0, hdrtime; - struct ieee80211_rate *rate; - int i; - - /* Estimate total channel use caused by this frame */ - - if (unlikely(local->num_curr_rates < 0)) - return TXRX_CONTINUE; - - rate = &local->curr_rates[0]; - for (i = 0; i < local->num_curr_rates; i++) { - if (local->curr_rates[i].val == rx->u.rx.status->rate) { - rate = &local->curr_rates[i]; - break; - } - } - - /* 1 bit at 1 Mbit/s takes 1 usec; in channel_use values, - * 1 usec = 1/8 * (1080 / 10) = 13.5 */ - - if (local->conf.phymode == MODE_IEEE80211A || - local->conf.phymode == MODE_ATHEROS_TURBO || - local->conf.phymode == MODE_ATHEROS_TURBOG || - (local->conf.phymode == MODE_IEEE80211G && - rate->flags & IEEE80211_RATE_ERP)) - hdrtime = CHAN_UTIL_HDR_SHORT; - else - hdrtime = CHAN_UTIL_HDR_LONG; - - load = hdrtime; - if (!MULTICAST_ADDR(hdr->addr1)) - load += hdrtime; - - load += skb->len * rate->rate_inv; - - /* Divide channel_use by 8 to avoid wrapping around the counter */ - load >>= CHAN_UTIL_SHIFT; - local->channel_use_raw += load; - if (rx->sta) - rx->sta->channel_use_raw += load; - rx->sdata->channel_use_raw += load; - - return TXRX_CONTINUE; -} - - -static void ieee80211_stat_refresh(unsigned long data) -{ - struct ieee80211_local *local = (struct ieee80211_local *) data; - struct list_head *ptr, *n; - - if (!local->stat_time) - return; - - /* go through all stations */ - spin_lock_bh(&local->sta_lock); - list_for_each(ptr, &local->sta_list) { - struct sta_info *sta = - list_entry(ptr, struct sta_info, list); - sta->channel_use = (sta->channel_use_raw / local->stat_time) / - CHAN_UTIL_PER_10MS; - sta->channel_use_raw = 0; - } - spin_unlock_bh(&local->sta_lock); - - /* go through all subinterfaces */ - list_for_each_safe(ptr, n, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - sdata->channel_use = (sdata->channel_use_raw / - local->stat_time) / CHAN_UTIL_PER_10MS; - sdata->channel_use_raw = 0; - - } - - /* hardware interface */ - local->channel_use = (local->channel_use_raw / - local->stat_time) / CHAN_UTIL_PER_10MS; - local->channel_use_raw = 0; - - local->stat_timer.expires = jiffies + HZ * local->stat_time / 100; - add_timer(&local->stat_timer); -} - - -/* This is a version of the rx handler that can be called from hard irq - * context. Post the skb on the queue and schedule the tasklet */ -void ieee80211_rx_irqsafe(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *status) -{ - struct ieee80211_local *local = dev->priv; - - skb->dev = dev; - memcpy(skb->cb, status, sizeof(struct ieee80211_rx_status)); - skb->pkt_type = ieee80211_rx_msg; - skb_queue_tail(&local->skb_queue, skb); - tasklet_schedule(&local->tasklet); -} - - -void ieee80211_tx_status_irqsafe(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_tx_status *status) -{ - struct ieee80211_local *local = dev->priv; - int tmp; - - if (status->tx_filtered || status->excessive_retries) { - /* Need to save a copy of skb->cb somewhere. Storing it in the - * end of the data might not be the most efficient way of doing - * this (since it may require reallocation of packet data), but - * should be good enough for now since tx_filtered or - * excessive_retries should not be triggered that often. */ - if (skb_is_nonlinear(skb)) { - if (skb_linearize(skb, GFP_ATOMIC)) { - printk(KERN_DEBUG "%s: Failed to linearize " - "skb\n", dev->name); - dev_kfree_skb_irq(skb); - return; - } - } - if (skb_tailroom(skb) < sizeof(skb->cb) && - pskb_expand_head(skb, 0, sizeof(skb->cb), GFP_ATOMIC)) { - printk(KERN_DEBUG "%s: Failed to store skb->cb " - "in skb->data for TX filtered frame\n", - dev->name); - dev_kfree_skb_irq(skb); - return; - } - memcpy(skb_put(skb, sizeof(skb->cb)), skb->cb, - sizeof(skb->cb)); - } - - skb->dev = dev; - memcpy(skb->cb, status, sizeof(struct ieee80211_tx_status)); - skb->pkt_type = ieee80211_tx_status_msg; - skb_queue_tail(status->req_tx_status ? - &local->skb_queue : &local->skb_queue_unreliable, skb); - tmp = skb_queue_len(&local->skb_queue) + - skb_queue_len(&local->skb_queue_unreliable); - while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && - (skb = skb_dequeue(&local->skb_queue_unreliable))) { - dev_kfree_skb_irq(skb); - tmp--; - I802_DEBUG_INC(local->tx_status_drop); - } - tasklet_schedule(&local->tasklet); -} - - -static void ieee80211_tasklet_handler(unsigned long data) -{ - struct ieee80211_local *local = (struct ieee80211_local *) data; - struct sk_buff *skb; - struct ieee80211_rx_status rx_status; - struct ieee80211_tx_status tx_status; - - while ((skb = skb_dequeue(&local->skb_queue)) || - (skb = skb_dequeue(&local->skb_queue_unreliable))) { - switch (skb->pkt_type) { - case ieee80211_rx_msg: - /* Make a copy of the RX status because the original - * skb may be freed during processing. Clear skb->type - * in order to not confuse kernel netstack. */ - memcpy(&rx_status, skb->cb, sizeof(rx_status)); - skb->pkt_type = 0; - ieee80211_rx(skb->dev, skb, &rx_status); - break; - case ieee80211_tx_status_msg: - /* Make a copy of the TX status because the original - * skb may be freed during processing. */ - memcpy(&tx_status, skb->cb, sizeof(tx_status)); - skb->pkt_type = 0; - if ((tx_status.tx_filtered || - tx_status.excessive_retries) && - skb->len >= sizeof(skb->cb)) { - /* Restore skb->cb from the copy that was made - * in ieee80211_tx_status_irqsafe() */ - memcpy(skb->cb, - skb->data + skb->len - sizeof(skb->cb), - sizeof(skb->cb)); - skb_trim(skb, skb->len - sizeof(skb->cb)); - } - ieee80211_tx_status(skb->dev, skb, &tx_status); - break; - default: /* should never get here! */ - printk(KERN_ERR "%s: Unknown message type (%d)\n", - local->wdev->name, skb->pkt_type); - dev_kfree_skb(skb); - break; - } - } -} - - -/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to - * make a prepared TX frame (one that has been given to hw) to look like brand - * new IEEE 802.11 frame that is ready to go through TX processing again. */ -static void ieee80211_remove_tx_extra(struct ieee80211_local *local, - struct ieee80211_key *key, - struct sk_buff *skb) -{ - int hdrlen, iv_len, mic_len; - - if (key == NULL) - return; - - hdrlen = ieee80211_get_hdrlen_from_skb(skb); - - switch (key->alg) { - case ALG_WEP: - iv_len = WEP_IV_LEN; - mic_len = WEP_ICV_LEN; - break; - case ALG_TKIP: - iv_len = TKIP_IV_LEN; - mic_len = TKIP_ICV_LEN; - break; - case ALG_CCMP: - iv_len = CCMP_HDR_LEN; - mic_len = CCMP_MIC_LEN; - break; - default: - return; - } - - if (skb->len >= mic_len && key->force_sw_encrypt) - skb_trim(skb, skb->len - mic_len); - if (skb->len >= iv_len && skb->len > hdrlen) { - memmove(skb->data + iv_len, skb->data, hdrlen); - skb_pull(skb, iv_len); - } - - { - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - u16 fc = le16_to_cpu(hdr->frame_control); - if ((fc & 0x8C) == 0x88) /* QoS Control Field */ { - fc &= ~(WLAN_FC_STYPE_QOS_DATA << 4); - hdr->frame_control = cpu_to_le16(fc); - memmove(skb->data + 2, skb->data, hdrlen - 2); - skb_pull(skb, 2); - } - } -} - - -void ieee80211_tx_status(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_tx_status *status) -{ - struct sk_buff *skb2; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct ieee80211_local *local = dev->priv; - struct ieee80211_tx_packet_data *pkt_data = - (struct ieee80211_tx_packet_data *) skb->cb; - u16 frag, type; - u32 msg_type; - - if (!status) { - printk(KERN_ERR - "%s: ieee80211_tx_status called with NULL status\n", - dev->name); - dev_kfree_skb(skb); - return; - } - - if (status->excessive_retries) { - struct sta_info *sta; - - - sta = sta_info_get(local, hdr->addr1); - if (sta) { - if (sta->flags & WLAN_STA_PS) { - /* The STA is in power save mode, so assume - * that this TX packet failed because of that. - */ - status->excessive_retries = 0; - status->tx_filtered = 1; - } - sta_info_release(local, sta); - } - } - - if (status->tx_filtered) { - struct sta_info *sta; - sta = sta_info_get(local, hdr->addr1); - if (sta) { - - sta->tx_filtered_count++; - - /* Clear the TX filter mask for this STA when sending - * the next packet. If the STA went to power save mode, - * this will happen when it is waking up for the next - * time. */ - sta->clear_dst_mask = 1; - - /* TODO: Is the WLAN_STA_PS flag always set here or is - * the race between RX and TX status causing some - * packets to be filtered out before 80211.o gets an - * update for PS status? This seems to be the case, so - * no changes are likely to be needed. */ - if (sta->flags & WLAN_STA_PS && - skb_queue_len(&sta->tx_filtered) < - STA_MAX_TX_BUFFER) { - ieee80211_remove_tx_extra(local, sta->key, - skb); - skb_queue_tail(&sta->tx_filtered, skb); - } else if (!(sta->flags & WLAN_STA_PS) && - !pkt_data->control.requeue) { - /* Software retry the packet once */ - pkt_data->control.requeue = 1; - ieee80211_remove_tx_extra(local, sta->key, - skb); - dev_queue_xmit(skb); - } else { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: dropped TX " - "filtered frame queue_len=%d " - "PS=%d @%lu\n", - dev->name, - skb_queue_len( - &sta->tx_filtered), - !!(sta->flags & WLAN_STA_PS), - jiffies); - } - dev_kfree_skb(skb); - } - sta_info_release(local, sta); - return; - } - } else { - rate_control_tx_status(dev, skb, status); - } - -#ifdef IEEE80211_LEDS - if (local->tx_led_counter && (local->tx_led_counter-- == 1)) { - ieee80211_tx_led(0, dev); - } -#endif /* IEEE80211_LEDS */ - /* SNMP counters - * Fragments are passed to low-level drivers as separate skbs, so these - * are actually fragments, not frames. Update frame counters only for - * the first fragment of the frame. */ - - frag = WLAN_GET_SEQ_FRAG(le16_to_cpu(hdr->seq_ctrl)); - type = WLAN_FC_GET_TYPE(le16_to_cpu(hdr->frame_control)); - - if (status->ack) { - if (frag == 0) { - local->dot11TransmittedFrameCount++; - if (MULTICAST_ADDR(hdr->addr1)) - local->dot11MulticastTransmittedFrameCount++; - if (status->retry_count > 0) - local->dot11RetryCount++; - if (status->retry_count > 1) - local->dot11MultipleRetryCount++; - } - - /* This counter shall be incremented for an acknowledged MPDU - * with an individual address in the address 1 field or an MPDU - * with a multicast address in the address 1 field of type Data - * or Management. */ - if (!MULTICAST_ADDR(hdr->addr1) || type == WLAN_FC_TYPE_DATA || - type == WLAN_FC_TYPE_MGMT) - local->dot11TransmittedFragmentCount++; - } else { - if (frag == 0) - local->dot11FailedCount++; - } - - if (!status->req_tx_status) { - dev_kfree_skb(skb); - return; - } - - msg_type = status->ack ? ieee80211_msg_tx_callback_ack : - ieee80211_msg_tx_callback_fail; - - /* skb was the original skb used for TX. Clone it and give the clone - * to netif_rx(). Free original skb. */ - skb2 = skb_copy(skb, GFP_ATOMIC); - if (!skb2) { - dev_kfree_skb(skb); - return; - } - dev_kfree_skb(skb); - skb = skb2; - - /* Send frame to hostapd */ - ieee80211_rx_mgmt(dev, skb, NULL, msg_type); -} - - -/* TODO: implement register/unregister functions for adding TX/RX handlers - * into ordered list */ - -static ieee80211_rx_handler ieee80211_rx_handlers[] = -{ - ieee80211_rx_h_parse_qos, - ieee80211_rx_h_load_stats, - ieee80211_rx_h_monitor, - ieee80211_rx_h_passive_scan, - ieee80211_rx_h_check, - ieee80211_rx_h_sta_process, - ieee80211_rx_h_ccmp_decrypt, - ieee80211_rx_h_tkip_decrypt, - ieee80211_rx_h_wep_weak_iv_detection, - ieee80211_rx_h_wep_decrypt, - ieee80211_rx_h_defragment, - ieee80211_rx_h_ieee80211_rx_h_ps_poll, - ieee80211_rx_h_michael_mic_verify, - /* this must be after decryption - so header is counted in MPDU mic - * must be before pae and data, so QOS_DATA format frames - * are not passed to user space by these functions - */ - ieee80211_rx_h_remove_qos_control, - ieee80211_rx_h_802_1x_pae, - ieee80211_rx_h_drop_unencrypted, - ieee80211_rx_h_data, - ieee80211_rx_h_mgmt, - NULL -}; - -static ieee80211_tx_handler ieee80211_tx_handlers[] = -{ - ieee80211_tx_h_rate_limit, - ieee80211_tx_h_check_assoc, - ieee80211_tx_h_ps_buf, - ieee80211_tx_h_select_key, - ieee80211_tx_h_michael_mic_add, - ieee80211_tx_h_fragment, - ieee80211_tx_h_tkip_encrypt, - ieee80211_tx_h_ccmp_encrypt, - ieee80211_tx_h_wep_encrypt, - ieee80211_tx_h_rate_ctrl, - ieee80211_tx_h_misc, - ieee80211_tx_h_load_stats, - NULL -}; - - -static void ieee80211_if_sdata_init(struct ieee80211_sub_if_data *sdata) -{ - /* Default values for sub-interface parameters */ - sdata->drop_unencrypted = 0; - sdata->eapol = 1; -} - - -static struct net_device *ieee80211_if_add(struct net_device *dev, - char *name, int locked) -{ - struct net_device *wds_dev = NULL, *tmp_dev; - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata = NULL, *sdata_parent; - int alloc_size; - int ret; - int i; - - /* ensure 32-bit alignment of our private data and hw private data */ - alloc_size = sizeof(struct net_device) + 3 + - sizeof(struct ieee80211_sub_if_data) + 3; - - wds_dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL); - if (wds_dev == NULL) - return NULL; - - memset(wds_dev, 0, alloc_size); - wds_dev->priv = local; - ether_setup(wds_dev); - if (strlen(name) == 0) { - i = 0; - do { - sprintf(wds_dev->name, "%s.%d", dev->name, i++); - tmp_dev = dev_get_by_name(wds_dev->name); - if (tmp_dev == NULL) - break; - dev_put(tmp_dev); - } while (i < 10000); - } else { - snprintf(wds_dev->name, IFNAMSIZ, "%s", name); - } - - memcpy(wds_dev->dev_addr, dev->dev_addr, ETH_ALEN); - wds_dev->hard_start_xmit = ieee80211_subif_start_xmit; - wds_dev->do_ioctl = ieee80211_ioctl; - wds_dev->change_mtu = ieee80211_change_mtu; - wds_dev->tx_timeout = ieee80211_tx_timeout; - wds_dev->get_stats = ieee80211_get_stats; - wds_dev->open = ieee80211_open; - wds_dev->stop = ieee80211_stop; - wds_dev->base_addr = dev->base_addr; - wds_dev->irq = dev->irq; - wds_dev->mem_start = dev->mem_start; - wds_dev->mem_end = dev->mem_end; - wds_dev->tx_queue_len = 0; - - sdata = IEEE80211_DEV_TO_SUB_IF(wds_dev); - sdata->type = IEEE80211_SUB_IF_TYPE_NORM; - sdata->master = local->mdev; - sdata->dev = wds_dev; - sdata->local = local; - memset(&sdata->stats, 0, sizeof(struct net_device_stats)); - sdata_parent = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata_parent->type == IEEE80211_SUB_IF_TYPE_NORM) - sdata->bss = &sdata_parent->u.norm; - else { - printk(KERN_DEBUG "%s: could not set BSS pointer for new " - "interface %s\n", dev->name, wds_dev->name); - } - ieee80211_if_sdata_init(sdata); - - if (locked) - ret = register_netdevice(wds_dev); - else - ret = register_netdev(wds_dev); - if (ret) { - kfree(wds_dev); - return NULL; - } - - list_add(&sdata->list, &local->sub_if_list); - - strcpy(name, wds_dev->name); - - return wds_dev; -} - - -int ieee80211_if_add_wds(struct net_device *dev, char *name, - struct ieee80211_if_wds *wds, int locked) -{ - struct net_device *wds_dev = NULL; - struct ieee80211_sub_if_data *sdata = NULL; - - if (strlen(name) != 0) { - wds_dev = dev_get_by_name(name); - if (wds_dev) { - dev_put(wds_dev); - return -EEXIST; - } - } - - wds_dev = ieee80211_if_add(dev, name, locked); - if (wds_dev == NULL) - return -ENOANO; - - sdata = IEEE80211_DEV_TO_SUB_IF(wds_dev); - sdata->type = IEEE80211_SUB_IF_TYPE_WDS; - memcpy(&sdata->u.wds, wds, sizeof(struct ieee80211_if_wds)); - -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG - "%s: Added WDS Link to " MACSTR "\n", - wds_dev->name, MAC2STR(sdata->u.wds.remote_addr)); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - - - ieee80211_proc_init_virtual(wds_dev); - - return 0; -} - - -int ieee80211_if_update_wds(struct net_device *dev, char *name, - struct ieee80211_if_wds *wds, int locked) -{ - struct net_device *wds_dev = NULL; - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata = NULL; - struct sta_info *sta; - struct list_head *ptr; - - list_for_each(ptr, &local->sub_if_list) { - sdata = list_entry(ptr, struct ieee80211_sub_if_data, list); - if (strcmp(name, sdata->dev->name) == 0) { - wds_dev = sdata->dev; - break; - } - } - - if (wds_dev == NULL || sdata->type != IEEE80211_SUB_IF_TYPE_WDS) - return -ENODEV; - - /* Remove STA entry for the old peer */ - sta = sta_info_get(local, sdata->u.wds.remote_addr); - if (sta) { - sta_info_release(local, sta); - sta_info_free(local, sta, 0); - } else { - printk(KERN_DEBUG "%s: could not find STA entry for WDS link " - "%s peer " MACSTR "\n", - dev->name, wds_dev->name, - MAC2STR(sdata->u.wds.remote_addr)); - } - - /* Update WDS link data */ - memcpy(&sdata->u.wds, wds, sizeof(struct ieee80211_if_wds)); - - - return 0; -} - - -static void ieee80211_if_init(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - - spin_lock_init(&local->sub_if_lock); - INIT_LIST_HEAD(&local->sub_if_list); - -} - - -int ieee80211_if_add_vlan(struct net_device *dev, - char *name, - struct ieee80211_if_vlan *vlan, - int locked) -{ - struct net_device *vlan_dev = NULL; - struct ieee80211_sub_if_data *sdata = NULL; - - if (strlen(name) != 0) { - vlan_dev = dev_get_by_name(name); - if (vlan_dev) { - dev_put(vlan_dev); - return -EEXIST; - } - } - - vlan_dev = ieee80211_if_add(dev, name, locked); - if (vlan_dev == NULL) - return -ENOANO; - - sdata = IEEE80211_DEV_TO_SUB_IF(vlan_dev); - sdata->type = IEEE80211_SUB_IF_TYPE_VLAN; - ieee80211_proc_init_virtual(vlan_dev); - return 0; -} - - -static void ieee80211_if_norm_init(struct ieee80211_sub_if_data *sdata) -{ - sdata->type = IEEE80211_SUB_IF_TYPE_NORM; - sdata->u.norm.dtim_period = 2; - sdata->u.norm.force_unicast_rateidx = -1; - sdata->u.norm.max_ratectrl_rateidx = -1; - skb_queue_head_init(&sdata->u.norm.ps_bc_buf); - sdata->bss = &sdata->u.norm; -} - - -int ieee80211_if_add_norm(struct net_device *dev, char *name, u8 *bssid, - int locked) -{ - struct ieee80211_local *local = dev->priv; - struct net_device *norm_dev = NULL; - struct ieee80211_sub_if_data *sdata = NULL; - - if (local->bss_dev_count >= local->conf.bss_count) - return -ENOBUFS; - - if (strlen(name) != 0) { - norm_dev = dev_get_by_name(name); - if (norm_dev) { - dev_put(norm_dev); - return -EEXIST; - } - } - - norm_dev = ieee80211_if_add(dev, name, locked); - if (norm_dev == NULL) - return -ENOANO; - - memcpy(norm_dev->dev_addr, bssid, ETH_ALEN); - sdata = IEEE80211_DEV_TO_SUB_IF(norm_dev); - ieee80211_if_norm_init(sdata); - ieee80211_proc_init_virtual(norm_dev); - spin_lock_bh(&local->sub_if_lock); - local->bss_devs[local->bss_dev_count] = norm_dev; - local->bss_dev_count++; - spin_unlock_bh(&local->sub_if_lock); - - return 0; -} - - -static void ieee80211_addr_inc(u8 *addr) -{ - int pos = 5; - while (pos >= 0) { - addr[pos]++; - if (addr[pos] != 0) - break; - pos--; - } -} - - -int ieee80211_if_add_sta(struct net_device *dev, char *name, int locked) -{ - struct ieee80211_local *local = dev->priv; - struct net_device *sta_dev; - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_sta *ifsta; - int i; - - if (local->sta_dev_count >= local->conf.bss_count) - return -ENOBUFS; - - if (strlen(name) != 0) { - sta_dev = dev_get_by_name(name); - if (sta_dev) { - dev_put(sta_dev); - return -EEXIST; - } - } - - sta_dev = ieee80211_if_add(dev, name, locked); - if (sta_dev == NULL) - return -ENOANO; - - sdata = IEEE80211_DEV_TO_SUB_IF(sta_dev); - ifsta = &sdata->u.sta; - sdata->type = IEEE80211_SUB_IF_TYPE_STA; - ieee80211_proc_init_virtual(sta_dev); - - spin_lock_bh(&local->sub_if_lock); - for (i = 0; i < local->conf.bss_count; i++) { - if (local->sta_devs[i] == NULL) { - local->sta_devs[i] = sta_dev; - local->sta_dev_count++; - printk(KERN_DEBUG "%s: using STA entry %d\n", - sta_dev->name, i); - while (i > 0) { - ieee80211_addr_inc(sta_dev->dev_addr); - i--; - } - printk(KERN_DEBUG "%s: MAC address " MACSTR "\n", - sta_dev->name, MAC2STR(sta_dev->dev_addr)); - break; - } - } - spin_unlock_bh(&local->sub_if_lock); - - init_timer(&ifsta->timer); - ifsta->timer.data = (unsigned long) sta_dev; - ifsta->timer.function = ieee80211_sta_timer; - - ifsta->capab = WLAN_CAPABILITY_ESS; - ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN | - IEEE80211_AUTH_ALG_SHARED_KEY; - ifsta->create_ibss = 1; - ifsta->wmm_enabled = 1; - - return 0; -} - - -static void ieee80211_if_del(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata, int locked) -{ - struct sta_info *sta; - u8 addr[ETH_ALEN]; - int i, j; - struct list_head *ptr, *n; - - memset(addr, 0xff, ETH_ALEN); - for (i = 0; i < NUM_DEFAULT_KEYS; i++) { - if (!sdata->keys[i]) - continue; -#if 0 - /* Low-level driver has probably disabled hw - * already, so there is not really much point - * in disabling the keys at this point. */ - if (local->hw->set_key) - local->hw->set_key(dev, DISABLE_KEY, addr, - local->keys[i], 0); -#endif - kfree(sdata->keys[i]); - } - - switch (sdata->type) { - case IEEE80211_SUB_IF_TYPE_NORM: - /* Remove all virtual interfaces that use this BSS - * as their sdata->bss */ - list_for_each_safe(ptr, n, &local->sub_if_list) { - struct ieee80211_sub_if_data *tsdata = - list_entry(ptr, struct ieee80211_sub_if_data, - list); - - if (tsdata != sdata && tsdata->bss == &sdata->u.norm) { - printk(KERN_DEBUG "%s: removing virtual " - "interface %s because its BSS interface" - " is being removed\n", - sdata->dev->name, tsdata->dev->name); - ieee80211_if_del(local, tsdata, locked); - } - } - - kfree(sdata->u.norm.beacon_head); - kfree(sdata->u.norm.beacon_tail); - spin_lock_bh(&local->sub_if_lock); - for (j = 0; j < local->bss_dev_count; j++) { - if (sdata->dev == local->bss_devs[j]) { - if (j + 1 < local->bss_dev_count) { - memcpy(&local->bss_devs[j], - &local->bss_devs[j + 1], - (local->bss_dev_count - j - 1) * - sizeof(local->bss_devs[0])); - local->bss_devs[local->bss_dev_count - - 1] = NULL; - } else - local->bss_devs[j] = NULL; - local->bss_dev_count--; - break; - } - } - spin_unlock_bh(&local->sub_if_lock); - - if (sdata->dev != local->mdev) { - struct sk_buff *skb; - while ((skb = skb_dequeue(&sdata->u.norm.ps_bc_buf))) { - local->total_ps_buffered--; - dev_kfree_skb(skb); - } - } - - break; - case IEEE80211_SUB_IF_TYPE_WDS: - sta = sta_info_get(local, sdata->u.wds.remote_addr); - if (sta) { - sta_info_release(local, sta); - sta_info_free(local, sta, 0); - } else { -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Someone had deleted my STA " - "entry for the WDS link\n", sdata->dev->name); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - } - break; - case IEEE80211_SUB_IF_TYPE_STA: - del_timer_sync(&sdata->u.sta.timer); - if (local->scan_timer.data == (unsigned long) sdata->dev) - del_timer_sync(&local->scan_timer); - kfree(sdata->u.sta.extra_ie); - sdata->u.sta.extra_ie = NULL; - kfree(sdata->u.sta.assocreq_ies); - sdata->u.sta.assocreq_ies = NULL; - kfree(sdata->u.sta.assocresp_ies); - sdata->u.sta.assocresp_ies = NULL; - if (sdata->u.sta.probe_resp) { - dev_kfree_skb(sdata->u.sta.probe_resp); - sdata->u.sta.probe_resp = NULL; - } - for (i = 0; i < local->conf.bss_count; i++) { - if (local->sta_devs[i] == sdata->dev) { - local->sta_devs[i] = NULL; - local->sta_dev_count--; - break; - } - } - - break; - } - - /* remove all STAs that are bound to this virtual interface */ - sta_info_flush(local, sdata->dev); - - list_del(&sdata->list); - ieee80211_proc_deinit_virtual(sdata->dev); - if (locked) - unregister_netdevice(sdata->dev); - else - unregister_netdev(sdata->dev); - /* Default data device and management device are allocated with the - * master device. All other devices are separately allocated and will - * be freed here. */ - if (sdata->dev != local->mdev && sdata->dev != local->wdev && - sdata->dev != local->apdev) - kfree(sdata->dev); -} - - -static int ieee80211_if_remove(struct net_device *dev, char *name, int id, - int locked) -{ - struct ieee80211_local *local = dev->priv; - struct list_head *ptr, *n; - - /* Make sure not to touch sdata->master since it may - * have already been deleted, etc. */ - - list_for_each_safe(ptr, n, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - - if (sdata->type == id && strcmp(name, sdata->dev->name) == 0) { - ieee80211_if_del(local, sdata, locked); - break; - } - } - - return 0; -} - - -int ieee80211_if_remove_wds(struct net_device *dev, char *name, int locked) -{ - return ieee80211_if_remove(dev, name, IEEE80211_SUB_IF_TYPE_WDS, - locked); -} - - -int ieee80211_if_remove_vlan(struct net_device *dev, char *name, int locked) -{ - return ieee80211_if_remove(dev, name, IEEE80211_SUB_IF_TYPE_VLAN, - locked); -} - - -int ieee80211_if_remove_norm(struct net_device *dev, char *name, int locked) -{ - return ieee80211_if_remove(dev, name, IEEE80211_SUB_IF_TYPE_NORM, - locked); -} - - -int ieee80211_if_remove_sta(struct net_device *dev, char *name, int locked) -{ - return ieee80211_if_remove(dev, name, IEEE80211_SUB_IF_TYPE_STA, - locked); -} - - -int ieee80211_if_flush(struct net_device *dev, int locked) -{ - struct ieee80211_local *local = dev->priv; - struct list_head *ptr, *n; - - list_for_each_safe(ptr, n, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - - if (sdata->dev != local->mdev && - sdata->dev != local->wdev && - sdata->dev != local->apdev) - ieee80211_if_del(local, sdata, locked); - } - - return 0; -} - - -static void ieee80211_precalc_rates(struct ieee80211_hw *hw) -{ - struct ieee80211_hw_modes *mode; - struct ieee80211_rate *rate; - int m, r; - - for (m = 0; m < hw->num_modes; m++) { - mode = &hw->modes[m]; - for (r = 0; r < mode->num_rates; r++) { - rate = &mode->rates[r]; - rate->rate_inv = CHAN_UTIL_RATE_LCM / rate->rate; - } - } -} - - -struct net_device *ieee80211_alloc_hw(size_t priv_data_len, - void (*setup)(struct net_device *)) -{ - struct net_device *dev, *apdev, *mdev; - struct ieee80211_local *local; - struct ieee80211_sub_if_data *sdata; - int alloc_size; - - /* Ensure 32-bit alignment of our private data and hw private data. - * Each net_device is followed by a sub_if_data which which is used - * for wds/vlan information; it is aligned as well. - * - * Sample memory map looks something like: - * - * 0000 ***************** - * * net_dev * - * 015c ***************** - * * sub_if * - * 017c ***************** - * * local * - * 0b84 ***************** - * * hw_priv * - * 1664 ***************** - * * ap net_dev * - * 17c0 ***************** - * * sub_if * - * ***************** - * * master net_dev* - * ***************** - * * sub_if * - * ***************** - */ - alloc_size = sizeof(struct net_device) + - sizeof(struct ieee80211_sub_if_data) + 3 + - sizeof(struct ieee80211_local) + 3 + - priv_data_len + 3 + - sizeof(struct net_device) + 3 + - sizeof(struct ieee80211_sub_if_data) + 3 + - sizeof(struct net_device) + 3 + - sizeof(struct ieee80211_sub_if_data) + 3 + - 4096; - mdev = (struct net_device *) kzalloc(alloc_size, GFP_KERNEL); - if (mdev == NULL) - return NULL; - - mdev->priv = (struct net_device *) - (((long) mdev + - sizeof(struct net_device) + - sizeof(struct ieee80211_sub_if_data) + 3) - & ~3); - local = mdev->priv; - local->hw_priv = (void *) - (((long) local + sizeof(struct ieee80211_local) + 3) & ~3); - apdev = (struct net_device *) - (((long) local->hw_priv + priv_data_len + 3) & ~3); - dev = (struct net_device *) - (((long) apdev + - sizeof(struct net_device) + - sizeof(struct ieee80211_sub_if_data) + 3) - & ~3); - dev->priv = local; - - ether_setup(dev); - memcpy(dev->name, "wlan%d", 7); - - dev->hard_start_xmit = ieee80211_subif_start_xmit; - dev->do_ioctl = ieee80211_ioctl; - dev->change_mtu = ieee80211_change_mtu; - dev->tx_timeout = ieee80211_tx_timeout; - dev->get_stats = ieee80211_get_stats; - dev->open = ieee80211_open; - dev->stop = ieee80211_stop; - dev->tx_queue_len = 0; - dev->set_mac_address = ieee80211_set_mac_address; - - local->wdev = dev; - local->mdev = mdev; - local->rx_handlers = ieee80211_rx_handlers; - local->tx_handlers = ieee80211_tx_handlers; - - local->bridge_packets = 1; - - local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; - local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; - local->short_retry_limit = 7; - local->long_retry_limit = 4; - local->conf.calib_int = 60; - local->rate_ctrl_num_up = RATE_CONTROL_NUM_UP; - local->rate_ctrl_num_down = RATE_CONTROL_NUM_DOWN; - local->conf.bss_count = 1; - memset(local->conf.bssid_mask, 0xff, ETH_ALEN); - local->bss_devs = kmalloc(sizeof(struct net_device *), GFP_KERNEL); - if (local->bss_devs == NULL) - goto fail; - local->bss_devs[0] = local->wdev; - local->bss_dev_count = 1; - local->sta_devs = kmalloc(sizeof(struct net_device *), GFP_KERNEL); - if (local->sta_devs == NULL) - goto fail; - local->sta_devs[0] = NULL; - - local->scan.in_scan = 0; - local->hw_modes = (unsigned int) -1; - - init_timer(&local->scan.timer); /* clear it out */ - - spin_lock_init(&local->generic_lock); - init_timer(&local->rate_limit_timer); - local->rate_limit_timer.function = ieee80211_rate_limit; - local->rate_limit_timer.data = (unsigned long) local; - init_timer(&local->stat_timer); - local->stat_timer.function = ieee80211_stat_refresh; - local->stat_timer.data = (unsigned long) local; - ieee80211_rx_bss_list_init(dev); - - sta_info_init(local); - - ieee80211_if_init(dev); - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - sdata->dev = dev; - sdata->master = mdev; - sdata->local = local; - ieee80211_if_sdata_init(sdata); - ieee80211_if_norm_init(sdata); - list_add_tail(&sdata->list, &local->sub_if_list); - - if (strlen(dev->name) + 2 >= sizeof(dev->name)) - goto fail; - - apdev = (struct net_device *) - (((long) local->hw_priv + priv_data_len + 3) & ~3); - local->apdev = apdev; - ether_setup(apdev); - apdev->priv = local; - apdev->hard_start_xmit = ieee80211_mgmt_start_xmit; - apdev->change_mtu = ieee80211_change_mtu_apdev; - apdev->get_stats = ieee80211_get_stats; - apdev->open = ieee80211_open; - apdev->stop = ieee80211_stop; - apdev->type = ARPHRD_IEEE80211_PRISM; - apdev->hard_header_parse = header_parse_80211; - apdev->tx_queue_len = 0; - sprintf(apdev->name, "%sap", dev->name); - - sdata = IEEE80211_DEV_TO_SUB_IF(apdev); - sdata->type = IEEE80211_SUB_IF_TYPE_MGMT; - sdata->dev = apdev; - sdata->master = mdev; - sdata->local = local; - list_add_tail(&sdata->list, &local->sub_if_list); - - ether_setup(mdev); - mdev->hard_start_xmit = ieee80211_master_start_xmit; - mdev->do_ioctl = ieee80211_ioctl; - mdev->change_mtu = ieee80211_change_mtu; - mdev->tx_timeout = ieee80211_tx_timeout; - mdev->get_stats = ieee80211_get_stats; - mdev->open = ieee80211_open; - mdev->stop = ieee80211_stop; - mdev->type = ARPHRD_IEEE80211; - mdev->hard_header_parse = header_parse_80211; - sprintf(mdev->name, "%s.11", dev->name); - - sdata = IEEE80211_DEV_TO_SUB_IF(mdev); - sdata->type = IEEE80211_SUB_IF_TYPE_NORM; - sdata->dev = mdev; - sdata->master = mdev; - sdata->local = local; - list_add_tail(&sdata->list, &local->sub_if_list); - - tasklet_init(&local->tasklet, - ieee80211_tasklet_handler, - (unsigned long) local); - skb_queue_head_init(&local->skb_queue); - skb_queue_head_init(&local->skb_queue_unreliable); - - if (setup) - setup(mdev); - - return mdev; - - fail: - ieee80211_free_hw(mdev); - return NULL; -} - -int ieee80211_register_hw(struct net_device *dev, struct ieee80211_hw *hw) -{ - struct ieee80211_local *local = dev->priv; - int result; - - if (!hw) - return -1; - - if (hw->version != IEEE80211_VERSION) { - printk("ieee80211_register_hw - version mismatch: 80211.o " - "version %d, low-level driver version %d\n", - IEEE80211_VERSION, hw->version); - return -1; - } - - local->conf.mode = IW_MODE_MASTER; - local->conf.beacon_int = 1000; - - ieee80211_update_hw(dev, hw); /* Don't care about the result. */ - - sta_info_start(local); - - result = register_netdev(local->wdev); - if (result < 0) - return -1; - - result = register_netdev(local->apdev); - if (result < 0) - goto fail_2nd_dev; - - if (hw->fraglist) - dev->features |= NETIF_F_FRAGLIST; - result = register_netdev(dev); - if (result < 0) - goto fail_3rd_dev; - - if (rate_control_initialize(local) < 0) { - printk(KERN_DEBUG "%s: Failed to initialize rate control " - "algorithm\n", dev->name); - goto fail_rate; - } - - /* TODO: add rtnl locking around device creation and qdisc install */ - ieee80211_install_qdisc(dev); - - ieee80211_wep_init(local); - ieee80211_proc_init_interface(local); - return 0; - -fail_rate: - unregister_netdev(dev); -fail_3rd_dev: - unregister_netdev(local->apdev); -fail_2nd_dev: - unregister_netdev(local->wdev); - sta_info_stop(local); - return result; -} - -int ieee80211_update_hw(struct net_device *dev, struct ieee80211_hw *hw) -{ - struct ieee80211_local *local = dev->priv; - - local->hw = hw; - - /* Backwards compatibility for low-level drivers that do not set number - * of TX queues. */ - if (hw->queues == 0) - hw->queues = 1; - - memcpy(local->apdev->dev_addr, dev->dev_addr, ETH_ALEN); - local->apdev->base_addr = dev->base_addr; - local->apdev->irq = dev->irq; - local->apdev->mem_start = dev->mem_start; - local->apdev->mem_end = dev->mem_end; - - memcpy(local->wdev->dev_addr, dev->dev_addr, ETH_ALEN); - local->wdev->base_addr = dev->base_addr; - local->wdev->irq = dev->irq; - local->wdev->mem_start = dev->mem_start; - local->wdev->mem_end = dev->mem_end; - - if (!hw->modes || !hw->modes->channels || !hw->modes->rates || - !hw->modes->num_channels || !hw->modes->num_rates) - return -1; - - ieee80211_precalc_rates(hw); - local->conf.phymode = hw->modes[0].mode; - local->curr_rates = hw->modes[0].rates; - local->num_curr_rates = hw->modes[0].num_rates; - ieee80211_prepare_rates(dev); - - local->conf.freq = local->hw->modes[0].channels[0].freq; - local->conf.channel = local->hw->modes[0].channels[0].chan; - local->conf.channel_val = local->hw->modes[0].channels[0].val; - /* FIXME: Invoke config to allow driver to set the channel. */ - - return 0; -} - -void ieee80211_unregister_hw(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - struct list_head *ptr, *n; - int i; - - tasklet_disable(&local->tasklet); - /* TODO: skb_queue should be empty here, no need to do anything? */ - - if (local->rate_limit) - del_timer_sync(&local->rate_limit_timer); - if (local->stat_time) - del_timer_sync(&local->stat_timer); - if (local->scan_timer.data) - del_timer_sync(&local->scan_timer); - ieee80211_rx_bss_list_deinit(dev); - - list_for_each_safe(ptr, n, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - ieee80211_if_del(local, sdata, 0); - } - - sta_info_stop(local); - - for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) - if (local->fragments[i].skb) - dev_kfree_skb(local->fragments[i].skb); - - for (i = 0; i < NUM_IEEE80211_MODES; i++) { - kfree(local->supp_rates[i]); - kfree(local->basic_rates[i]); - } - - kfree(local->conf.ssid); - kfree(local->conf.generic_elem); - - ieee80211_proc_deinit_interface(local); - - skb_queue_purge(&local->skb_queue); - skb_queue_purge(&local->skb_queue_unreliable); - - rate_control_free(local); -} - -void ieee80211_free_hw(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - - kfree(local->sta_devs); - kfree(local->bss_devs); - kfree(dev); -} - -/* Perform netif operations on all configured interfaces */ -int ieee80211_netif_oper(struct net_device *sdev, Netif_Oper op) -{ - struct ieee80211_local *local = sdev->priv; - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sdev); - struct net_device *dev = sdata->master; - - switch (op) { - case NETIF_ATTACH: - netif_device_attach(dev); - break; - case NETIF_DETACH: - netif_device_detach(dev); - break; - case NETIF_START: - netif_start_queue(dev); - break; - case NETIF_STOP: - break; - case NETIF_WAKE: - if (local->scan.in_scan == 0) { - netif_wake_queue(dev); -#if 1 - if (/* FIX: 802.11 qdisc in use */ 1) - __netif_schedule(dev); -#endif - } - break; - case NETIF_IS_STOPPED: - if (netif_queue_stopped(dev)) - return 1; - break; - case NETIF_UPDATE_TX_START: - dev->trans_start = jiffies; - break; - } - - return 0; -} - - -void * ieee80211_dev_hw_data(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - return local->hw_priv; -} - - -void * ieee80211_dev_stats(struct net_device *dev) -{ - struct ieee80211_sub_if_data *sdata; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - return &(sdata->stats); -} - - -int ieee80211_rate_control_register(struct rate_control_ops *ops) -{ - struct rate_control_algs *alg; - - alg = kmalloc(sizeof(*alg), GFP_KERNEL); - if (alg == NULL) { - return -1; - } - memset(alg, 0, sizeof(*alg)); - alg->next = ieee80211_rate_ctrl_algs; - alg->ops = ops; - ieee80211_rate_ctrl_algs = alg; - - return 0; -} - - -void ieee80211_rate_control_unregister(struct rate_control_ops *ops) -{ - struct rate_control_algs *alg, *prev; - - prev = NULL; - alg = ieee80211_rate_ctrl_algs; - while (alg) { - if (alg->ops == ops) { - if (prev) - prev->next = alg->next; - else - ieee80211_rate_ctrl_algs = alg->next; - kfree(alg); - break; - } - prev = alg; - alg = alg->next; - } -} - - -static int rate_control_initialize(struct ieee80211_local *local) -{ - struct rate_control_algs *algs; - for (algs = ieee80211_rate_ctrl_algs; algs; algs = algs->next) { - local->rate_ctrl = algs->ops; - local->rate_ctrl_priv = rate_control_alloc(local); - if (local->rate_ctrl_priv) { - printk(KERN_DEBUG "%s: Selected rate control " - "algorithm '%s'\n", local->wdev->name, - local->rate_ctrl->name); - return 0; - } - } - - printk(KERN_WARNING "%s: Failed to select rate control algorithm\n", - local->wdev->name); - return -1; -} - - -static int __init ieee80211_init(void) -{ - struct sk_buff *skb; - if (sizeof(struct ieee80211_tx_packet_data) > (sizeof(skb->cb))) { - printk("80211: ieee80211_tx_packet_data is bigger " - "than the skb->cb (%d > %d)\n", - (int) sizeof(struct ieee80211_tx_packet_data), - (int) sizeof(skb->cb)); - return -EINVAL; - } - if (sizeof(struct ieee80211_rx_status) > sizeof(skb->cb)) { - printk("80211: ieee80211_rx_status is bigger " - "than the skb->cb (%d > %d)\n", - (int) sizeof(struct ieee80211_rx_status), - (int) sizeof(skb->cb)); - return -EINVAL; - } - - ieee80211_proc_init(); - { - int ret = ieee80211_wme_register(); - if (ret) { - printk(KERN_DEBUG "ieee80211_init: failed to " - "initialize WME (err=%d)\n", ret); - ieee80211_proc_deinit(); - return ret; - } - } - - return 0; -} - - -static void __exit ieee80211_exit(void) -{ - ieee80211_wme_unregister(); - ieee80211_proc_deinit(); -} - - -EXPORT_SYMBOL(ieee80211_alloc_hw); -EXPORT_SYMBOL(ieee80211_register_hw); -EXPORT_SYMBOL(ieee80211_update_hw); -EXPORT_SYMBOL(ieee80211_unregister_hw); -EXPORT_SYMBOL(ieee80211_free_hw); -EXPORT_SYMBOL(ieee80211_rx); -EXPORT_SYMBOL(ieee80211_tx_status); -EXPORT_SYMBOL(ieee80211_beacon_get); -EXPORT_SYMBOL(ieee80211_get_buffered_bc); -EXPORT_SYMBOL(ieee80211_netif_oper); -EXPORT_SYMBOL(ieee80211_dev_hw_data); -EXPORT_SYMBOL(ieee80211_dev_stats); -EXPORT_SYMBOL(ieee80211_get_hw_conf); -EXPORT_SYMBOL(ieee80211_set_aid_for_sta); -EXPORT_SYMBOL(ieee80211_rx_irqsafe); -EXPORT_SYMBOL(ieee80211_tx_status_irqsafe); -EXPORT_SYMBOL(ieee80211_get_hdrlen); -EXPORT_SYMBOL(ieee80211_get_hdrlen_from_skb); -EXPORT_SYMBOL(ieee80211_rate_control_register); -EXPORT_SYMBOL(ieee80211_rate_control_unregister); -EXPORT_SYMBOL(sta_info_get); -EXPORT_SYMBOL(sta_info_release); -EXPORT_SYMBOL(ieee80211_radar_status); - -module_init(ieee80211_init); -module_exit(ieee80211_exit); diff --git a/target/linux/package/ieee80211-dscape/src/ieee80211_i.h b/target/linux/package/ieee80211-dscape/src/ieee80211_i.h deleted file mode 100644 index 7127f8d67b..0000000000 --- a/target/linux/package/ieee80211-dscape/src/ieee80211_i.h +++ /dev/null @@ -1,571 +0,0 @@ -/* - * Copyright 2002-2005, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef IEEE80211_I_H -#define IEEE80211_I_H - -/* ieee80211.o internal definitions, etc. These are not included into - * low-level drivers. */ - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#endif /* ETH_P_PAE */ - -#define IEEE80211_MAX_SSID_LEN 32 - -struct ieee80211_local; - -#include "ieee80211_key.h" -#include "sta_info.h" - -#define BIT(x) (1 << (x)) - -#define IEEE80211_ALIGN32_PAD(a) ((4 - ((a) & 3)) & 3) - - -/* Maximum number of broadcast/multicast frames to buffer when some of the - * associated stations are using power saving. */ -#define AP_MAX_BC_BUFFER 128 - -/* Maximum number of frames buffered to all STAs, including multicast frames. - * Note: increasing this limit increases the potential memory requirement. Each - * frame can be up to about 2 kB long. */ -#define TOTAL_MAX_TX_BUFFER 512 - - -#define MAC2STR(a) ((a)[0] & 0xff), ((a)[1] & 0xff), ((a)[2] & 0xff), \ - ((a)[3] & 0xff), ((a)[4] & 0xff), ((a)[5] & 0xff) -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" - -#define MULTICAST_ADDR(a) ((a)[0] & 0x01) - - -/* IEEE 802.11 (Ch. 9.5 Defragmentation) requires support for concurrent - * reception of at least three fragmented frames. This limit can be increased - * by changing this define, at the cost of slower frame reassembly and - * increased memory use (about 2 kB of RAM per entry). */ -#define IEEE80211_FRAGMENT_MAX 4 - -struct ieee80211_fragment_entry { - unsigned long first_frag_time; - unsigned int seq; - unsigned int rx_queue; - unsigned int last_frag; - struct sk_buff *skb; - int ccmp; /* Whether fragments were encrypted with CCMP */ - u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ -}; - - -struct ieee80211_sta_bss { - struct list_head list; - struct ieee80211_sta_bss *hnext; - atomic_t users; - - u8 bssid[ETH_ALEN]; - u8 ssid[IEEE80211_MAX_SSID_LEN]; - size_t ssid_len; - u16 capability; /* host byte order */ - int hw_mode; - int channel; - int freq; - int rssi; - u8 *wpa_ie; - size_t wpa_ie_len; - u8 *rsn_ie; - size_t rsn_ie_len; - u8 *wmm_ie; - size_t wmm_ie_len; -#define IEEE80211_MAX_SUPP_RATES 32 - u8 supp_rates[IEEE80211_MAX_SUPP_RATES]; - size_t supp_rates_len; - int beacon_int; - u64 timestamp; - - int probe_resp; - unsigned long last_update; - -}; - - -typedef enum { - TXRX_CONTINUE, TXRX_DROP, TXRX_QUEUED -} ieee80211_txrx_result; - -struct ieee80211_txrx_data { - struct sk_buff *skb; - struct net_device *dev; - struct ieee80211_local *local; - struct ieee80211_sub_if_data *sdata; - struct sta_info *sta; - u16 fc, ethertype; - struct ieee80211_key *key; - unsigned int fragmented:1; /* whether the MSDU was fragmented */ - union { - struct { - struct ieee80211_tx_control *control; - int unicast:1; - int ps_buffered:1; - int short_preamble:1; - int probe_last_frag:1; - struct ieee80211_rate *rate; - /* use this rate (if set) for last fragment; rate can - * be set to lower rate for the first fragments, e.g., - * when using CTS protection with IEEE 802.11g. */ - struct ieee80211_rate *last_frag_rate; - int last_frag_rateidx; - int mgmt_interface; - - /* Extra fragments (in addition to the first fragment - * in skb) */ - int num_extra_frag; - struct sk_buff **extra_frag; - } tx; - struct { - struct ieee80211_rx_status *status; - int sent_ps_buffered; - int queue; - } rx; - } u; -#ifdef CONFIG_HOSTAPD_WPA_TESTING - int wpa_test; -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ -}; - -struct ieee80211_passive_scan { - unsigned int in_scan:1; /* this must be cleared before calling - * netif_oper(WAKEUP) */ - unsigned int our_mode_only:1; /* only scan our physical mode a/b/g/etc - */ - int interval; /* time in seconds between scans */ - int time; /* time in microseconds to scan for */ - int channel; /* channel to be scanned */ - int tries; - - int mode_idx; - int chan_idx; - - int freq; - int rx_packets; - int rx_beacon; - int txrx_count; - - struct timer_list timer; - - struct sk_buff *skb; /* skb to transmit before changing channels, - * maybe null for none */ - struct ieee80211_tx_control tx_control; - - unsigned int num_scans; -}; - -typedef ieee80211_txrx_result (*ieee80211_tx_handler) -(struct ieee80211_txrx_data *tx); - -typedef ieee80211_txrx_result (*ieee80211_rx_handler) -(struct ieee80211_txrx_data *rx); - -struct ieee80211_if_norm { - u8 *beacon_head, *beacon_tail; - int beacon_head_len, beacon_tail_len; - - /* TODO: sta_aid could be replaced by 2008-bit large bitfield of - * that could be used in TIM element generation. This would also - * make TIM element generation a bit faster. */ - /* AID mapping to station data. NULL, if AID is free. AID is in the - * range 1..2007 and sta_aid[i] corresponds to AID i+1. */ - struct sta_info *sta_aid[MAX_AID_TABLE_SIZE]; - int max_aid; /* largest aid currently in use */ - atomic_t num_sta_ps; /* number of stations in PS mode */ - struct sk_buff_head ps_bc_buf; - int dtim_period, dtim_count; - int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ - int max_ratectrl_rateidx; /* max TX rateidx for rate control */ - int num_beacons; /* number of TXed beacon frames for this BSS */ -}; - -struct ieee80211_if_wds { - u8 remote_addr[ETH_ALEN]; - struct sta_info *sta; -}; - -struct ieee80211_if_vlan { - u8 id; -}; - -struct ieee80211_if_sta { - enum { - IEEE80211_DISABLED, IEEE80211_AUTHENTICATE, - IEEE80211_ASSOCIATE, IEEE80211_ASSOCIATED, - IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED - } state; - struct timer_list timer; - u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; - u8 ssid[IEEE80211_MAX_SSID_LEN]; - size_t ssid_len; - u16 aid; - u16 ap_capab, capab; - u8 *extra_ie; /* to be added to the end of AssocReq */ - size_t extra_ie_len; - - /* The last AssocReq/Resp IEs */ - u8 *assocreq_ies, *assocresp_ies; - size_t assocreq_ies_len, assocresp_ies_len; - - int auth_tries, assoc_tries; - - int ssid_set:1; - int bssid_set:1; - int prev_bssid_set:1; - int authenticated:1; - int associated:1; - int probereq_poll:1; - int use_protection:1; - int create_ibss:1; - int mixed_cell:1; - int wmm_enabled:1; - - int key_mgmt; - unsigned long last_probe; - -#define IEEE80211_AUTH_ALG_OPEN BIT(0) -#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1) -#define IEEE80211_AUTH_ALG_LEAP BIT(2) - unsigned int auth_algs; /* bitfield of allowed auth algs */ - int auth_alg; /* currently used IEEE 802.11 authentication algorithm */ - int auth_transaction; - - unsigned long ibss_join_req; - struct sk_buff *probe_resp; /* ProbeResp template for IBSS */ - u32 supp_rates_bits; - - int wmm_last_param_set; -}; - - -#define IEEE80211_SUB_IF_TYPE_NORM 0x00000000 -#define IEEE80211_SUB_IF_TYPE_MGMT 0x00000001 -#define IEEE80211_SUB_IF_TYPE_STA 0x00000002 -#define IEEE80211_SUB_IF_TYPE_WDS 0x5A580211 -#define IEEE80211_SUB_IF_TYPE_VLAN 0x00080211 - -struct ieee80211_sub_if_data { - struct list_head list; - unsigned int type; - - struct net_device *dev; - struct net_device *master; - struct ieee80211_local *local; - - struct net_device_stats stats; - int drop_unencrypted; - int eapol; /* 0 = process EAPOL frames as normal data frames, - * 1 = send EAPOL frames through wlan#ap to hostapd - * (default) */ - int ieee802_1x; /* IEEE 802.1X PAE - drop packet to/from unauthorized - * port */ - -#define NUM_DEFAULT_KEYS 4 - struct ieee80211_key *keys[NUM_DEFAULT_KEYS]; - struct ieee80211_key *default_key; - - struct ieee80211_if_norm *bss; /* BSS that this device belongs to */ - - union { - struct ieee80211_if_norm norm; - struct ieee80211_if_wds wds; - struct ieee80211_if_vlan vlan; - struct ieee80211_if_sta sta; - } u; - int channel_use; - int channel_use_raw; -}; - -#define IEEE80211_DEV_TO_SUB_IF(dev) ((struct ieee80211_sub_if_data *) \ - (((long)dev + sizeof(struct net_device) + 3) & ~3)) - - -struct ieee80211_local { - struct ieee80211_hw *hw; - void *hw_priv; - struct net_device *mdev; /* wlan#.11 - "master" 802.11 device */ - struct net_device *wdev; /* wlan# - default Ethernet (data) devide */ - struct net_device *apdev; /* wlan#ap - management frames (hostapd) */ - int open_count; - struct ieee80211_conf conf; - - /* Tasklet and skb queue to process calls from IRQ mode. All frames - * added to skb_queue will be processed, but frames in - * skb_queue_unreliable may be dropped if the total length of these - * queues increases over the limit. */ -#define IEEE80211_IRQSAFE_QUEUE_LIMIT 128 - struct tasklet_struct tasklet; - struct sk_buff_head skb_queue; - struct sk_buff_head skb_queue_unreliable; - enum { - ieee80211_rx_msg = 1, - ieee80211_tx_status_msg = 2 - } ieee80211_msg_enum; - - spinlock_t generic_lock; - /* Station data structures */ - spinlock_t sta_lock; /* mutex for STA data structures */ - int num_sta; /* number of stations in sta_list */ - struct list_head sta_list; - struct sta_info *sta_hash[STA_HASH_SIZE]; - struct timer_list sta_cleanup; - - /* Current rate table. This is a pointer to hw->modes structure. */ - struct ieee80211_rate *curr_rates; - int num_curr_rates; - - void *rate_ctrl_priv; - struct rate_control_ops *rate_ctrl; - - int next_mode; /* MODE_IEEE80211* - * The mode preference for next channel change. This is - * used to select .11g vs. .11b channels (or 4.9 GHz vs. - * .11a) when the channel number is not unique. */ - - /* Supported and basic rate filters for different modes. These are - * pointers to -1 terminated lists and rates in 100 kbps units. */ - int *supp_rates[NUM_IEEE80211_MODES]; - int *basic_rates[NUM_IEEE80211_MODES]; - - int rts_threshold; - int cts_protect_erp_frames; - int fragmentation_threshold; - int short_retry_limit; /* dot11ShortRetryLimit */ - int long_retry_limit; /* dot11LongRetryLimit */ - int short_preamble; /* use short preamble with IEEE 802.11b */ - - u32 wep_iv; - int key_tx_rx_threshold; /* number of times any key can be used in TX - * or RX before generating a rekey - * notification; 0 = notification disabled. */ - - /* Fragment table for host-based reassembly */ - struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; - unsigned int fragment_next; - - int bridge_packets; /* bridge packets between associated stations and - * deliver multicast frames both back to wireless - * media and to the local net stack */ - - struct ieee80211_passive_scan scan; - - - ieee80211_rx_handler *rx_handlers; - ieee80211_tx_handler *tx_handlers; - - spinlock_t sub_if_lock; /* mutex for STA data structures */ - struct list_head sub_if_list; - struct net_device **bss_devs; /* pointer to IF_TYPE_NORM devices for - * quick access to BSS data */ - int bss_dev_count; /* number of used entries in bss_devs; note: the - * total size of bss_devs array is stored in - * conf.bss_count */ - struct net_device **sta_devs; /* pointer to IF_TYPE_STA devices */ - int sta_dev_count; /* number of used entries in sta_devs */ - int sta_scanning; - int scan_hw_mode_idx; - int scan_channel_idx; - enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; - unsigned long last_scan_completed; - struct timer_list scan_timer; - int scan_oper_channel; - int scan_oper_channel_val; - int scan_oper_power_level; - int scan_oper_freq; - int scan_oper_phymode; - int scan_oper_antenna_max; - u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; - size_t scan_ssid_len; - int scan_skip_11b; - struct list_head sta_bss_list; - struct ieee80211_sta_bss *sta_bss_hash[STA_HASH_SIZE]; - spinlock_t sta_bss_lock; -#define IEEE80211_SCAN_MATCH_SSID BIT(0) -#define IEEE80211_SCAN_WPA_ONLY BIT(1) -#define IEEE80211_SCAN_EXTRA_INFO BIT(2) - int scan_flags; - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - u32 wpa_trigger; -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - /* SNMP counters */ - /* dot11CountersTable */ - u32 dot11TransmittedFragmentCount; - u32 dot11MulticastTransmittedFrameCount; - u32 dot11FailedCount; - u32 dot11RetryCount; - u32 dot11MultipleRetryCount; - u32 dot11FrameDuplicateCount; - u32 dot11ReceivedFragmentCount; - u32 dot11MulticastReceivedFrameCount; - u32 dot11TransmittedFrameCount; - u32 dot11WEPUndecryptableCount; - - int tx_led_counter; - - u32 channel_use; - u32 channel_use_raw; - u32 stat_time; - struct timer_list stat_timer; - - u8 bssid[ETH_ALEN]; /* BSSID for STA modes (Adhoc/Managed) */ - struct timer_list rate_limit_timer; - u32 rate_limit; - u32 rate_limit_burst; - u32 rate_limit_bucket; - struct proc_dir_entry *proc, *proc_sta, *proc_iface; - - struct work_struct sta_proc_add; - - enum { - STA_ANTENNA_SEL_AUTO = 0, - STA_ANTENNA_SEL_SW_CTRL = 1, - STA_ANTENNA_SEL_SW_CTRL_DEBUG = 2 - } sta_antenna_sel; - - int rate_ctrl_num_up, rate_ctrl_num_down; - -#ifdef CONFIG_IEEE80211_DEBUG_COUNTERS - /* TX/RX handler statistics */ - unsigned int tx_handlers_drop; - unsigned int tx_handlers_queued; - unsigned int tx_handlers_drop_unencrypted; - unsigned int tx_handlers_drop_fragment; - unsigned int tx_handlers_drop_wep; - unsigned int tx_handlers_drop_rate_limit; - unsigned int tx_handlers_drop_not_assoc; - unsigned int tx_handlers_drop_unauth_port; - unsigned int rx_handlers_drop; - unsigned int rx_handlers_queued; - unsigned int rx_handlers_drop_nullfunc; - unsigned int rx_handlers_drop_defrag; - unsigned int rx_handlers_drop_short; - unsigned int rx_handlers_drop_passive_scan; - unsigned int tx_expand_skb_head; - unsigned int tx_expand_skb_head_cloned; - unsigned int rx_expand_skb_head; - unsigned int rx_expand_skb_head2; - unsigned int rx_handlers_fragments; - unsigned int tx_status_drop; - unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES]; - unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; -#define I802_DEBUG_INC(c) (c)++ -#else /* CONFIG_IEEE80211_DEBUG_COUNTERS */ -#define I802_DEBUG_INC(c) do { } while (0) -#endif /* CONFIG_IEEE80211_DEBUG_COUNTERS */ - - - int default_wep_only; /* only default WEP keys are used with this - * interface; this is used to decide when hwaccel - * can be used with default keys */ - int total_ps_buffered; /* total number of all buffered unicast and - * multicast packets for power saving stations - */ - int allow_broadcast_always; /* whether to allow TX of broadcast frames - * even when there are no associated STAs - */ - - int wifi_wme_noack_test; - unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ - - unsigned int hw_modes; /* bitfield of allowed hardware modes; - * (1 << MODE_*) */ -}; - - -/* ieee80211.c */ -int ieee80211_hw_config(struct net_device *dev); -struct ieee80211_key_conf * -ieee80211_key_data2conf(struct ieee80211_local *local, - struct ieee80211_key *data); -void ieee80211_rx_mgmt(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *status, u32 msg_type); -void ieee80211_prepare_rates(struct net_device *dev); -void ieee80211_tx_set_iswep(struct ieee80211_txrx_data *tx); -int ieee80211_if_add_wds(struct net_device *dev, - char *name, - struct ieee80211_if_wds *wds, int locked); -int ieee80211_if_add_vlan(struct net_device *dev, char *name, - struct ieee80211_if_vlan *vlan, int locked); -int ieee80211_if_add_norm(struct net_device *dev, char *name, u8 *bssid, - int locked); - -int ieee80211_if_remove_wds(struct net_device *dev, char *name, int locked); -int ieee80211_if_remove_vlan(struct net_device *dev, char *name, int locked); -int ieee80211_if_remove_norm(struct net_device *dev, char *name, int locked); -int ieee80211_if_flush(struct net_device *dev, int locked); -int ieee80211_if_update_wds(struct net_device *dev, char *name, - struct ieee80211_if_wds *wds, int locked); - -/* ieee80211_ioctl.c */ -int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); -/* Set hw encryption from ieee80211 */ -int ieee80211_set_hw_encryption(struct net_device *dev, - struct sta_info *sta, u8 addr[ETH_ALEN], - struct ieee80211_key *key); - -/* ieee80211_scan.c */ -void ieee80211_init_scan(struct net_device *dev); -void ieee80211_stop_scan(struct net_device *dev); - - - -/* Least common multiple of the used rates (in 100 kbps). This is used to - * calculate rate_inv values for each rate so that only integers are needed. */ -#define CHAN_UTIL_RATE_LCM 95040 -/* 1 usec is 1/8 * (95040/10) = 1188 */ -#define CHAN_UTIL_PER_USEC 1188 -/* Amount of bits to shift the result right to scale the total utilization - * to values that will not wrap around 32-bit integers. */ -#define CHAN_UTIL_SHIFT 9 -/* Theoretical maximum of channel utilization counter in 10 ms (stat_time=1): - * (CHAN_UTIL_PER_USEC * 10000) >> CHAN_UTIL_SHIFT = 23203. So dividing the - * raw value with about 23 should give utilization in 10th of a percentage - * (1/1000). However, utilization is only estimated and not all intervals - * between frames etc. are calculated. 18 seems to give numbers that are closer - * to the real maximum. */ -#define CHAN_UTIL_PER_10MS 18 -#define CHAN_UTIL_HDR_LONG (202 * CHAN_UTIL_PER_USEC) -#define CHAN_UTIL_HDR_SHORT (40 * CHAN_UTIL_PER_USEC) - - - -/* ieee80211.c */ -int ieee80211_if_add_sta(struct net_device *dev, char *name, int locked); -int ieee80211_if_remove_sta(struct net_device *dev, char *name, int locked); -/* ieee80211_ioctl.c */ -int ieee80211_set_compression(struct ieee80211_local *local, - struct net_device *dev, struct sta_info *sta); -/* ieee80211_sta.c */ -void ieee80211_sta_timer(unsigned long ptr); -void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *rx_status); -int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len); -int ieee80211_sta_get_ssid(struct net_device *dev, char *ssid, size_t *len); -int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid); -int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); -int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len); -void ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *rx_status); -void ieee80211_rx_bss_list_init(struct net_device *dev); -void ieee80211_rx_bss_list_deinit(struct net_device *dev); -int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len); -struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, - struct sk_buff *skb, u8 *bssid, - u8 *addr); -int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); -int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); - - -#endif /* IEEE80211_I_H */ diff --git a/target/linux/package/ieee80211-dscape/src/ieee80211_ioctl.c b/target/linux/package/ieee80211-dscape/src/ieee80211_ioctl.c deleted file mode 100644 index a44b02e8ee..0000000000 --- a/target/linux/package/ieee80211-dscape/src/ieee80211_ioctl.c +++ /dev/null @@ -1,2832 +0,0 @@ -/* - * Copyright 2002-2005, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "ieee80211_i.h" -#include "hostapd_ioctl.h" -#include "rate_control.h" -#include "wpa.h" -#include "aes_ccm.h" - - -static int ieee80211_regdom = 0x10; /* FCC */ -MODULE_PARM(ieee80211_regdom, "i"); -MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain; 64=MKK"); - -/* - * If firmware is upgraded by the vendor, additional channels can be used based - * on the new Japanese regulatory rules. This is indicated by setting - * ieee80211_japan_5ghz module parameter to one when loading the 80211 kernel - * module. - */ -static int ieee80211_japan_5ghz /* = 0 */; -MODULE_PARM(ieee80211_japan_5ghz, "i"); -MODULE_PARM_DESC(ieee80211_japan_5ghz, "Vendor-updated firmware for 5 GHz"); - - -static int ieee80211_ioctl_set_beacon(struct net_device *dev, - struct prism2_hostapd_param *param, - int param_len, - int flag) -{ - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_norm *norm; - u8 **b_head, **b_tail; - int *b_head_len, *b_tail_len; - int len; - - len = ((char *) param->u.beacon.data - (char *) param) + - param->u.beacon.head_len + param->u.beacon.tail_len; - - if (param_len > len) - param_len = len; - else if (param_len != len) - return -EINVAL; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_SUB_IF_TYPE_NORM) - return -EINVAL; - norm = &sdata->u.norm; - - switch (flag) { - case 0: - b_head = &norm->beacon_head; - b_tail = &norm->beacon_tail; - b_head_len = &norm->beacon_head_len; - b_tail_len = &norm->beacon_tail_len; - break; - default: - printk(KERN_DEBUG "%s: unknown beacon flag %d\n", - dev->name, flag); - return -EINVAL; - } - - kfree(*b_head); - kfree(*b_tail); - *b_head = NULL; - *b_tail = NULL; - - *b_head_len = param->u.beacon.head_len; - *b_tail_len = param->u.beacon.tail_len; - - *b_head = kmalloc(*b_head_len, GFP_KERNEL); - if (*b_head) - memcpy(*b_head, param->u.beacon.data, *b_head_len); - else { - printk(KERN_DEBUG "%s: failed to allocate beacon_head\n", - dev->name); - return -ENOMEM; - } - - if (*b_tail_len > 0) { - *b_tail = kmalloc(*b_tail_len, GFP_KERNEL); - if (*b_tail) - memcpy(*b_tail, param->u.beacon.data + (*b_head_len), - (*b_tail_len)); - else { - printk(KERN_DEBUG "%s: failed to allocate " - "beacon_tail\n", dev->name); - return -ENOMEM; - } - } - - return 0; -} - - -static int ieee80211_ioctl_get_hw_features(struct net_device *dev, - struct prism2_hostapd_param *param, - int param_len) -{ - struct ieee80211_local *local = dev->priv; - u8 *pos = param->u.hw_features.data; - int left = param_len - (pos - (u8 *) param); - int mode, i; - struct hostapd_ioctl_hw_modes_hdr *hdr; - struct ieee80211_rate_data *rate; - struct ieee80211_channel_data *chan; - - param->u.hw_features.flags = 0; - if (local->hw->data_nullfunc_ack) - param->u.hw_features.flags |= HOSTAP_HW_FLAG_NULLFUNC_OK; - - param->u.hw_features.num_modes = local->hw->num_modes; - for (mode = 0; mode < local->hw->num_modes; mode++) { - int clen, rlen; - struct ieee80211_hw_modes *m = &local->hw->modes[mode]; - clen = m->num_channels * sizeof(struct ieee80211_channel_data); - rlen = m->num_rates * sizeof(struct ieee80211_rate_data); - if (left < sizeof(*hdr) + clen + rlen) - return -E2BIG; - left -= sizeof(*hdr) + clen + rlen; - - hdr = (struct hostapd_ioctl_hw_modes_hdr *) pos; - hdr->mode = m->mode; - hdr->num_channels = m->num_channels; - hdr->num_rates = m->num_rates; - - pos = (u8 *) (hdr + 1); - chan = (struct ieee80211_channel_data *) pos; - for (i = 0; i < m->num_channels; i++) { - chan[i].chan = m->channels[i].chan; - chan[i].freq = m->channels[i].freq; - chan[i].flag = m->channels[i].flag; - } - pos += clen; - - rate = (struct ieee80211_rate_data *) pos; - for (i = 0; i < m->num_rates; i++) { - rate[i].rate = m->rates[i].rate; - rate[i].flags = m->rates[i].flags; - } - pos += rlen; - } - - return 0; -} - - -static int ieee80211_ioctl_scan(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - - if (local->hw->passive_scan == NULL) - return -EOPNOTSUPP; - - if ((param->u.scan.now == 1) && (local->scan.in_scan == 1)) - return -EBUSY; - - if (param->u.scan.our_mode_only >= 0) - local->scan.our_mode_only = param->u.scan.our_mode_only; - if (param->u.scan.interval >= 0) - local->scan.interval = param->u.scan.interval; - if (param->u.scan.listen >= 0) - local->scan.time = param->u.scan.listen; - if (param->u.scan.channel > 0) - local->scan.channel = param->u.scan.channel; - if (param->u.scan.now == 1) { - local->scan.in_scan = 0; - mod_timer(&local->scan.timer, jiffies); - } - - param->u.scan.our_mode_only = local->scan.our_mode_only; - param->u.scan.interval = local->scan.interval; - param->u.scan.listen = local->scan.time; - if (local->scan.in_scan == 1) - param->u.scan.last_rx = -1; - else { - param->u.scan.last_rx = local->scan.rx_packets; - local->scan.rx_packets = -1; - } - param->u.scan.channel = local->hw->modes[local->scan.mode_idx]. - channels[local->scan.chan_idx].chan; - - return 0; -} - - -static int ieee80211_ioctl_flush(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - sta_info_flush(local, NULL); - return 0; -} - - - - -static int ieee80211_ioctl_add_sta(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - u32 rates; - int i, j; - struct ieee80211_sub_if_data *sdata; - int add_key_entry = 1; - - sta = sta_info_get(local, param->sta_addr); - - if (sta == NULL) { - sta = sta_info_add(local, dev, param->sta_addr); - if (sta == NULL) - return -ENOMEM; - } - - if (sta->dev != dev) { - /* Binding STA to a new interface, so remove all references to - * the old BSS. */ - sta_info_remove_aid_ptr(sta); - } - - /* TODO - * We "steal" the device in case someone owns it - * This will hurt WDS links and such when we have a - * WDS link and a client associating from the same station - */ - sta->dev = dev; - sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); - - sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; - sta->aid = param->u.add_sta.aid; - if (sta->aid > MAX_AID_TABLE_SIZE) - sta->aid = 0; - if (sta->aid > 0 && sdata->bss) - sdata->bss->sta_aid[sta->aid - 1] = sta; - if (sdata->bss && sta->aid > sdata->bss->max_aid) - sdata->bss->max_aid = sta->aid; - - rates = 0; - for (i = 0; i < sizeof(param->u.add_sta.supp_rates); i++) { - int rate = (param->u.add_sta.supp_rates[i] & 0x7f) * 5; - if (local->conf.phymode == MODE_ATHEROS_TURBO || - local->conf.phymode == MODE_ATHEROS_TURBOG) - rate *= 2; - for (j = 0; j < local->num_curr_rates; j++) { - if (local->curr_rates[j].rate == rate) - rates |= BIT(j); - } - - } - sta->supp_rates = rates; - - rate_control_rate_init(local, sta); - - - - if (param->u.add_sta.wds_flags & 0x01) - sta->flags |= WLAN_STA_WDS; - else - sta->flags &= ~WLAN_STA_WDS; - - if (add_key_entry && sta->key == NULL && sdata->default_key == NULL && - local->hw->set_key) { - struct ieee80211_key_conf conf; - /* Add key cache entry with NULL key type because this may used - * for TX filtering. */ - memset(&conf, 0, sizeof(conf)); - conf.hw_key_idx = HW_KEY_IDX_INVALID; - conf.alg = ALG_NULL; - conf.force_sw_encrypt = 1; - if (local->hw->set_key(dev, SET_KEY, sta->addr, &conf, - sta->aid)) { - sta->key_idx_compression = HW_KEY_IDX_INVALID; - } else { - sta->key_idx_compression = conf.hw_key_idx; - } - } - - sta_info_release(local, sta); - - return 0; -} - - -static int ieee80211_ioctl_remove_sta(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - - sta = sta_info_get(local, param->sta_addr); - if (sta) { - sta_info_release(local, sta); - sta_info_free(local, sta, 1); - } - - return sta ? 0 : -ENOENT; -} - - -static int ieee80211_ioctl_get_dot11counterstable(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_low_level_stats stats; - - memset(&stats, 0, sizeof(stats)); - if (local->hw->get_stats) - local->hw->get_stats(dev, &stats); - param->u.dot11CountersTable.dot11TransmittedFragmentCount = - local->dot11TransmittedFragmentCount; - param->u.dot11CountersTable.dot11MulticastTransmittedFrameCount = - local->dot11MulticastTransmittedFrameCount; - param->u.dot11CountersTable.dot11ReceivedFragmentCount = - local->dot11ReceivedFragmentCount; - param->u.dot11CountersTable.dot11MulticastReceivedFrameCount = - local->dot11MulticastReceivedFrameCount; - param->u.dot11CountersTable.dot11TransmittedFrameCount = - local->dot11TransmittedFrameCount; - param->u.dot11CountersTable.dot11FCSErrorCount = - stats.dot11FCSErrorCount; - param->u.dot11CountersTable.dot11ACKFailureCount = - stats.dot11ACKFailureCount; - param->u.dot11CountersTable.dot11RTSFailureCount = - stats.dot11RTSFailureCount; - param->u.dot11CountersTable.dot11RTSSuccessCount = - stats.dot11RTSSuccessCount; - - return 0; -} - -static int ieee80211_ioctl_get_info_sta(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - struct ieee80211_sub_if_data *sdata; - struct net_device_stats *stats; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - stats = ieee80211_dev_stats(sdata->master); - param->u.get_info_sta.rx_bytes = stats->rx_bytes; - param->u.get_info_sta.tx_bytes = stats->tx_bytes; - /* go through all STAs and get STA with lowest max. rate */ - param->u.get_info_sta.current_tx_rate = - local->curr_rates[sta_info_min_txrate_get(local)].rate; - return 0; - } - - sta = sta_info_get(local, param->sta_addr); - - if (!sta) - return -ENOENT; - - param->u.get_info_sta.inactive_msec = - jiffies_to_msecs(jiffies - sta->last_rx); - param->u.get_info_sta.rx_packets = sta->rx_packets; - param->u.get_info_sta.tx_packets = sta->tx_packets; - param->u.get_info_sta.rx_bytes = sta->rx_bytes; - param->u.get_info_sta.tx_bytes = sta->tx_bytes; - param->u.get_info_sta.channel_use = sta->channel_use; - param->u.get_info_sta.flags = sta->flags; - if (sta->txrate >= 0 && sta->txrate < local->num_curr_rates) - param->u.get_info_sta.current_tx_rate = - local->curr_rates[sta->txrate].rate; - param->u.get_info_sta.num_ps_buf_frames = - skb_queue_len(&sta->ps_tx_buf); - param->u.get_info_sta.tx_retry_failed = sta->tx_retry_failed; - param->u.get_info_sta.tx_retry_count = sta->tx_retry_count; - param->u.get_info_sta.last_rssi = sta->last_rssi; - param->u.get_info_sta.last_ack_rssi = sta->last_ack_rssi[2]; - - sta_info_release(local, sta); - - return 0; -} - - -static int ieee80211_ioctl_set_flags_sta(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - - sta = sta_info_get(local, param->sta_addr); - if (sta) { - sta->flags |= param->u.set_flags_sta.flags_or; - sta->flags &= param->u.set_flags_sta.flags_and; - if (local->hw->set_port_auth && - (param->u.set_flags_sta.flags_or & WLAN_STA_AUTHORIZED) && - local->hw->set_port_auth(local->mdev, sta->addr, 1)) - printk(KERN_DEBUG "%s: failed to set low-level driver " - "PAE state (authorized) for " MACSTR "\n", - dev->name, MAC2STR(sta->addr)); - if (local->hw->set_port_auth && - !(param->u.set_flags_sta.flags_and & WLAN_STA_AUTHORIZED) - && local->hw->set_port_auth(local->mdev, sta->addr, 0)) - printk(KERN_DEBUG "%s: failed to set low-level driver " - "PAE state (unauthorized) for " MACSTR "\n", - dev->name, MAC2STR(sta->addr)); - sta_info_release(local, sta); - } - - return sta ? 0 : -ENOENT; -} - - -int ieee80211_set_hw_encryption(struct net_device *dev, - struct sta_info *sta, u8 addr[ETH_ALEN], - struct ieee80211_key *key) -{ - struct ieee80211_key_conf *keyconf = NULL; - struct ieee80211_local *local = dev->priv; - int rc = 0; - - /* default to sw encryption; this will be cleared by low-level - * driver if the hw supports requested encryption */ - if (key) - key->force_sw_encrypt = 1; - - if (key && local->hw->set_key && - (!local->conf.sw_encrypt || !local->conf.sw_decrypt) && - (keyconf = ieee80211_key_data2conf(local, key)) != NULL) { - if (local->hw->set_key(dev, SET_KEY, addr, - keyconf, sta ? sta->aid : 0)) { - rc = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; - key->force_sw_encrypt = 1; - key->hw_key_idx = HW_KEY_IDX_INVALID; - } else { - key->force_sw_encrypt = - keyconf->force_sw_encrypt; - key->hw_key_idx = - keyconf->hw_key_idx; - - } - } - kfree(keyconf); - - return rc; -} - - -static int ieee80211_ioctl_set_encryption(struct net_device *dev, - struct prism2_hostapd_param *param, - int param_len) -{ - struct ieee80211_local *local = dev->priv; - int alg, ret = 0; - struct sta_info *sta; - struct ieee80211_key **key; - int set_tx_key = 0, try_hwaccel = 1; - struct ieee80211_key_conf *keyconf; - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - param->u.crypt.err = 0; - param->u.crypt.alg[HOSTAP_CRYPT_ALG_NAME_LEN - 1] = '\0'; - - if (param_len < - (int) ((char *) param->u.crypt.key - (char *) param) + - param->u.crypt.key_len) { - printk(KERN_DEBUG "%s: set_encrypt - invalid param_lem\n", - dev->name); - return -EINVAL; - } - - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - sta = NULL; - if (param->u.crypt.idx >= NUM_DEFAULT_KEYS) { - printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n", - dev->name, param->u.crypt.idx); - return -EINVAL; - } - key = &sdata->keys[param->u.crypt.idx]; - if (param->u.crypt.flags & HOSTAP_CRYPT_FLAG_SET_TX_KEY) - set_tx_key = 1; - - /* Disable hwaccel for default keys when the interface is not - * the default one. - * TODO: consider adding hwaccel support for these; at least - * Atheros key cache should be able to handle this since AP is - * only transmitting frames with default keys. */ - /* FIX: hw key cache can be used when only one virtual - * STA is associated with each AP. If more than one STA - * is associated to the same AP, software encryption - * must be used. This should be done automatically - * based on configured station devices. For the time - * being, this can be only set at compile time. */ - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - if (0 /* FIX: more than one STA per AP */) - try_hwaccel = 0; - } else - if (sdata->type != IEEE80211_SUB_IF_TYPE_NORM || - dev != local->wdev) - try_hwaccel = 0; - } else { - if (param->u.crypt.idx != 0) { - printk(KERN_DEBUG "%s: set_encrypt - non-zero idx for " - "individual key\n", dev->name); - return -EINVAL; - } - - sta = sta_info_get(local, param->sta_addr); - if (sta == NULL) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: set_encrypt - unknown addr " - MACSTR "\n", - dev->name, MAC2STR(param->sta_addr)); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - - return -ENOENT; - } - - key = &sta->key; - } - - if (strcmp(param->u.crypt.alg, "none") == 0) { - alg = ALG_NONE; - } else if (strcmp(param->u.crypt.alg, "WEP") == 0) { - alg = ALG_WEP; - } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { - if (param->u.crypt.key_len != ALG_TKIP_KEY_LEN) { - printk(KERN_DEBUG "%s: set_encrypt - invalid TKIP key " - "length %d\n", dev->name, - param->u.crypt.key_len); - ret = -EINVAL; - goto done; - } - alg = ALG_TKIP; - } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { - if (param->u.crypt.key_len != ALG_CCMP_KEY_LEN) { - printk(KERN_DEBUG "%s: set_encrypt - invalid CCMP key " - "length %d\n", dev->name, - param->u.crypt.key_len); - ret = -EINVAL; - goto done; - } - alg = ALG_CCMP; - } else { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ALG; - printk(KERN_DEBUG "%s: set_encrypt - unknown alg\n", - dev->name); - ret = -EINVAL; - goto done; - } - - /* FIX: - * Cannot configure default hwaccel keys with WEP algorithm, if - * any of the virtual interfaces is using static WEP - * configuration because hwaccel would otherwise try to decrypt - * these frames. - * - * For now, just disable WEP hwaccel for broadcast when there is - * possibility of conflict with default keys. This can maybe later be - * optimized by using non-default keys (at least with Atheros ar521x). - */ - if (!sta && alg == ALG_WEP && !local->default_wep_only && - local->conf.mode != IW_MODE_ADHOC && - local->conf.mode != IW_MODE_INFRA) { - try_hwaccel = 0; - } - - if (local->hw->device_hides_wep) { - /* Software encryption cannot be used with devices that hide - * encryption from the host system, so always try to use - * hardware acceleration with such devices. */ - try_hwaccel = 1; - } - - if (local->hw->no_tkip_wmm_hwaccel && alg == ALG_TKIP) { - if (sta && (sta->flags & WLAN_STA_WME)) { - /* Hardware does not support hwaccel with TKIP when using WMM. - */ - try_hwaccel = 0; - } - else if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - sta = sta_info_get(local, sdata->u.sta.bssid); - if (sta) { - if (sta->flags & WLAN_STA_WME) { - try_hwaccel = 0; - } - sta_info_release(local, sta); - sta = NULL; - } - } - } - - - if (alg == ALG_NONE) { - keyconf = NULL; - if (try_hwaccel && *key && local->hw->set_key && - (keyconf = ieee80211_key_data2conf(local, *key)) != NULL && - local->hw->set_key(dev, DISABLE_KEY, param->sta_addr, - keyconf, sta ? sta->aid : 0)) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_KEY_SET_FAILED; - printk(KERN_DEBUG "%s: set_encrypt - low-level disable" - " failed\n", dev->name); - ret = -EINVAL; - } - kfree(keyconf); - - if (sdata->default_key == *key) - sdata->default_key = NULL; - kfree(*key); - *key = NULL; - } else { - if (*key == NULL || (*key)->keylen < param->u.crypt.key_len) { - kfree(*key); - *key = kmalloc(sizeof(struct ieee80211_key) + - param->u.crypt.key_len, GFP_ATOMIC); - if (*key == NULL) { - ret = -ENOMEM; - goto done; - } - } - memset(*key, 0, sizeof(struct ieee80211_key) + - param->u.crypt.key_len); - /* default to sw encryption; low-level driver sets these if the - * requested encryption is supported */ - (*key)->hw_key_idx = HW_KEY_IDX_INVALID; - (*key)->force_sw_encrypt = 1; - - (*key)->alg = alg; - (*key)->keyidx = param->u.crypt.idx; - (*key)->keylen = param->u.crypt.key_len; - memcpy((*key)->key, param->u.crypt.key, - param->u.crypt.key_len); - if (set_tx_key) - (*key)->default_tx_key = 1; - - if (alg == ALG_CCMP) { - /* Initialize AES key state here as an optimization - * so that it does not need to be initialized for every - * packet. */ - ieee80211_aes_key_setup_encrypt( - (*key)->u.ccmp.aes_state, (*key)->key); - } - - if (try_hwaccel && - (alg == ALG_WEP || alg == ALG_TKIP || alg == ALG_CCMP)) - param->u.crypt.err = ieee80211_set_hw_encryption( - dev, sta, param->sta_addr, *key); - } - - if (set_tx_key || (sta == NULL && sdata->default_key == NULL)) { - sdata->default_key = *key; - if (local->hw->set_key_idx && - local->hw->set_key_idx(dev, param->u.crypt.idx)) - printk(KERN_DEBUG "%s: failed to set TX key idx for " - "low-level driver\n", dev->name); - } - - done: - if (sta) - sta_info_release(local, sta); - - return ret; -} - -static int ieee80211_ioctl_get_encryption(struct net_device *dev, - struct prism2_hostapd_param *param, - int param_len) -{ - struct ieee80211_local *local = dev->priv; - int ret = 0; - struct sta_info *sta; - struct ieee80211_key **key; - int max_key_len; - struct ieee80211_sub_if_data *sdata; - u8 *pos; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - param->u.crypt.err = 0; - - max_key_len = param_len - - (int) ((char *) param->u.crypt.key - (char *) param); - if (max_key_len < 0) - return -EINVAL; - - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - sta = NULL; - if (param->u.crypt.idx > NUM_DEFAULT_KEYS) { - param->u.crypt.idx = sdata->default_key ? - sdata->default_key->keyidx : 0; - return 0; - } else - key = &sdata->keys[param->u.crypt.idx]; - } else { - sta = sta_info_get(local, param->sta_addr); - if (sta == NULL) { - param->u.crypt.err = HOSTAP_CRYPT_ERR_UNKNOWN_ADDR; - return -EINVAL; - } - - key = &sta->key; - } - - - memset(param->u.crypt.seq_counter, 0, HOSTAP_SEQ_COUNTER_SIZE); - if (*key == NULL) { - memcpy(param->u.crypt.alg, "none", 5); - param->u.crypt.key_len = 0; - param->u.crypt.idx = 0xff; - } else { - switch ((*key)->alg) { - case ALG_WEP: - memcpy(param->u.crypt.alg, "WEP", 4); - break; - case ALG_TKIP: - { - u32 iv32; - u16 iv16; - - memcpy(param->u.crypt.alg, "TKIP", 5); - if (local->hw->get_sequence_counter) { - /* Get transmit counter from low level driver */ - if (local->hw->get_sequence_counter(dev, - param->sta_addr, - (*key)->keyidx, - IEEE80211_SEQ_COUNTER_TX, - &iv32, - &iv16)) { - /* Error getting value from device */ - return -EIO; - } - } else { - /* Get it from our own local data */ - iv32 = (*key)->u.tkip.iv32; - iv16 = (*key)->u.tkip.iv16; - } - pos = param->u.crypt.seq_counter; - *pos++ = iv16 & 0xff; - *pos++ = (iv16 >> 8) & 0xff; - *pos++ = iv32 & 0xff; - *pos++ = (iv32 >> 8) & 0xff; - *pos++ = (iv32 >> 16) & 0xff; - *pos++ = (iv32 >> 24) & 0xff; - break; - } - case ALG_CCMP: - { - u8 *pn; - memcpy(param->u.crypt.alg, "CCMP", 5); - pos = param->u.crypt.seq_counter; - pn = (*key)->u.ccmp.tx_pn; - *pos++ = pn[5]; - *pos++ = pn[4]; - *pos++ = pn[3]; - *pos++ = pn[2]; - *pos++ = pn[1]; - *pos++ = pn[0]; - break; - } - default: - memcpy(param->u.crypt.alg, "unknown", 8); - break; - } - - if (max_key_len < (*key)->keylen) - ret = -E2BIG; - else { - param->u.crypt.key_len = (*key)->keylen; - memcpy(param->u.crypt.key, (*key)->key, - (*key)->keylen); - } - } - - if (sta) - sta_info_release(local, sta); - - return ret; -} - - -#ifdef CONFIG_HOSTAPD_WPA_TESTING -static int ieee80211_ioctl_wpa_trigger(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - local->wpa_trigger = param->u.wpa_trigger.trigger; - return 0; - } - - sta = sta_info_get(local, param->sta_addr); - if (sta == NULL) { - printk(KERN_DEBUG "%s: wpa_trigger - unknown addr\n", - dev->name); - return -EINVAL; - } - - sta->wpa_trigger = param->u.wpa_trigger.trigger; - - sta_info_release(local, sta); - return 0; -} -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - -static int ieee80211_ioctl_set_rate_sets(struct net_device *dev, - struct prism2_hostapd_param *param, - int param_len) -{ - struct ieee80211_local *local = dev->priv; - u16 *pos = (u16 *) param->u.set_rate_sets.data; - int left = param_len - ((u8 *) pos - (u8 *) param); - int i, mode, num_supp, num_basic, *supp, *basic, *prev; - - mode = param->u.set_rate_sets.mode; - num_supp = param->u.set_rate_sets.num_supported_rates; - num_basic = param->u.set_rate_sets.num_basic_rates; - - if (left < (num_supp + num_basic) * 2) { - printk(KERN_WARNING "%s: invalid length in hostapd set rate " - "sets ioctl (%d != %d)\n", dev->name, left, - (num_supp + num_basic) * 2); - return -EINVAL; - } - - supp = (int *) kmalloc((num_supp + 1) * sizeof(int), GFP_KERNEL); - basic = (int *) kmalloc((num_basic + 1) * sizeof(int), GFP_KERNEL); - - if (!supp || !basic) { - kfree(supp); - kfree(basic); - return -ENOMEM; - } - - for (i = 0; i < num_supp; i++) - supp[i] = *pos++; - supp[i] = -1; - - for (i = 0; i < num_basic; i++) - basic[i] = *pos++; - basic[i] = -1; - - if (num_supp == 0) { - kfree(supp); - supp = NULL; - } - - if (num_basic == 0) { - kfree(basic); - basic = NULL; - } - - prev = local->supp_rates[mode]; - local->supp_rates[mode] = supp; - kfree(prev); - - prev = local->basic_rates[mode]; - local->basic_rates[mode] = basic; - kfree(prev); - - if (mode == local->conf.phymode) { - /* TODO: should update STA TX rates and remove STAs if they - * do not have any remaining supported rates after the change - */ - ieee80211_prepare_rates(dev); - } - - return 0; -} - - -static int ieee80211_ioctl_add_if(struct net_device *dev, - struct prism2_hostapd_param *param, - int param_len) -{ - u8 *pos = param->u.if_info.data; - int left = param_len - ((u8 *) pos - (u8 *) param); - - if (param->u.if_info.type == HOSTAP_IF_WDS) { - struct ieee80211_if_wds iwds; - struct hostapd_if_wds *wds = - (struct hostapd_if_wds *) param->u.if_info.data; - - if (left < sizeof(struct ieee80211_if_wds)) - return -EPROTO; - - memcpy(iwds.remote_addr, wds->remote_addr, ETH_ALEN); - - return ieee80211_if_add_wds(dev, param->u.if_info.name, - &iwds, 1); - } else if (param->u.if_info.type == HOSTAP_IF_VLAN) { - struct hostapd_if_vlan *vlan = (struct hostapd_if_vlan *) pos; - struct ieee80211_if_vlan ivlan; - - if (left < sizeof(struct hostapd_if_vlan)) - return -EPROTO; - - ivlan.id = vlan->id; - - return ieee80211_if_add_vlan(dev, param->u.if_info.name, - &ivlan, 1); - } else if (param->u.if_info.type == HOSTAP_IF_BSS) { - struct hostapd_if_bss *bss = - (struct hostapd_if_bss *) param->u.if_info.data; - - if (left < sizeof(struct hostapd_if_bss)) - return -EPROTO; - - return ieee80211_if_add_norm(dev, param->u.if_info.name, - bss->bssid, 1); - } else if (param->u.if_info.type == HOSTAP_IF_STA) { -#if 0 - struct hostapd_if_sta *sta = - (struct hostapd_if_sta *) param->u.if_info.data; -#endif - - if (left < sizeof(struct hostapd_if_sta)) - return -EPROTO; - - return ieee80211_if_add_sta(dev, param->u.if_info.name, 1); - } else - return -EINVAL; - - return 0; -} - - -static int ieee80211_ioctl_remove_if(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - if (param->u.if_info.type == HOSTAP_IF_WDS) { - return ieee80211_if_remove_wds(dev, param->u.if_info.name, 1); - } else if (param->u.if_info.type == HOSTAP_IF_VLAN) { - return ieee80211_if_remove_vlan(dev, param->u.if_info.name, 1); - } else if (param->u.if_info.type == HOSTAP_IF_BSS) { - return ieee80211_if_remove_norm(dev, param->u.if_info.name, 1); - } else if (param->u.if_info.type == HOSTAP_IF_STA) { - return ieee80211_if_remove_sta(dev, param->u.if_info.name, 1); - } else { - return -EINVAL; - } -} - - -static int ieee80211_ioctl_update_if(struct net_device *dev, - struct prism2_hostapd_param *param, - int param_len) -{ - u8 *pos = param->u.if_info.data; - int left = param_len - ((u8 *) pos - (u8 *) param); - - if (param->u.if_info.type == HOSTAP_IF_WDS) { - struct ieee80211_if_wds iwds; - struct hostapd_if_wds *wds = - (struct hostapd_if_wds *) param->u.if_info.data; - - if (left < sizeof(struct ieee80211_if_wds)) - return -EPROTO; - - memcpy(iwds.remote_addr, wds->remote_addr, ETH_ALEN); - - return ieee80211_if_update_wds(dev, param->u.if_info.name, - &iwds, 1); - } else { - return -EOPNOTSUPP; - } -} - - -static int ieee80211_ioctl_flush_ifs(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - return ieee80211_if_flush(dev, 1); -} - - -static int ieee80211_ioctl_scan_req(struct net_device *dev, - struct prism2_hostapd_param *param, - int param_len) -{ - u8 *pos = param->u.scan_req.ssid; - int left = param_len - ((u8 *) pos - (u8 *) param); - int len = param->u.scan_req.ssid_len; - - if (left < len || len > IEEE80211_MAX_SSID_LEN) - return -EINVAL; - - return ieee80211_sta_req_scan(dev, pos, len); -} - - -static int ieee80211_ioctl_sta_get_state(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - return -EINVAL; - param->u.sta_get_state.state = sdata->u.sta.state; - return 0; -} - - -static int ieee80211_ioctl_mlme(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - return -EINVAL; - switch (param->u.mlme.cmd) { - case MLME_STA_DEAUTH: - ieee80211_sta_deauthenticate(dev, param->u.mlme.reason_code); - break; - case MLME_STA_DISASSOC: - ieee80211_sta_disassociate(dev, param->u.mlme.reason_code); - break; - } - return 0; -} - - -static int ieee80211_ioctl_get_load_stats(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - - param->u.get_load_stats.channel_use = local->channel_use; -/* if (param->u.get_load_stats.flags & LOAD_STATS_CLEAR) - local->channel_use = 0; */ /* now it's not raw counter */ - - return 0; -} - - -static int ieee80211_ioctl_set_sta_vlan(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - - sta = sta_info_get(local, param->sta_addr); - if (sta) { - struct net_device *new_vlan_dev; - new_vlan_dev = - dev_get_by_name(param->u.set_sta_vlan.vlan_name); - if (new_vlan_dev) { -#if 0 - printk("%s: Station " MACSTR " moved to vlan: %s\n", - dev->name, MAC2STR(param->sta_addr), - new_vlan_dev->name); -#endif - sta->dev = new_vlan_dev; - sta->vlan_id = param->u.set_sta_vlan.vlan_id; - dev_put(new_vlan_dev); - } - sta_info_release(local, sta); - } - - return sta ? 0 : -ENOENT; -} - - -static int -ieee80211_ioctl_set_generic_info_elem(struct net_device *dev, - struct prism2_hostapd_param *param, - int param_len) -{ - struct ieee80211_local *local = dev->priv; - u8 *pos = param->u.set_generic_info_elem.data; - int left = param_len - ((u8 *) pos - (u8 *) param); - int len = param->u.set_generic_info_elem.len; - - if (left < len) - return -EINVAL; - - { - struct ieee80211_sub_if_data *sdata; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) - return ieee80211_sta_set_extra_ie(dev, pos, len); - } - kfree(local->conf.generic_elem); - local->conf.generic_elem = kmalloc(len, GFP_KERNEL); - if (local->conf.generic_elem == NULL) - return -ENOMEM; - memcpy(local->conf.generic_elem, pos, len); - local->conf.generic_elem_len = len; - - return ieee80211_hw_config(dev); -} - - -static int ieee80211_ioctl_set_regulatory_domain(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev); - conf->regulatory_domain = param->u.set_regulatory_domain.rd; - return 0; -} - - -static int ieee80211_ioctl_set_adm_status(struct net_device *dev, - int val) -{ - struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev); - conf->adm_status = val; - return ieee80211_hw_config(dev); -} - -static int -ieee80211_ioctl_set_tx_queue_params(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_tx_queue_params qparam; - - if (!local->hw->conf_tx) { - printk(KERN_DEBUG "%s: low-level driver does not support TX " - "queue configuration\n", dev->name); - return -EOPNOTSUPP; - } - - memset(&qparam, 0, sizeof(qparam)); - qparam.aifs = param->u.tx_queue_params.aifs; - qparam.cw_min = param->u.tx_queue_params.cw_min; - qparam.cw_max = param->u.tx_queue_params.cw_max; - qparam.burst_time = param->u.tx_queue_params.burst_time; - - return local->hw->conf_tx(dev, param->u.tx_queue_params.queue, - &qparam); -} - - -static int ieee80211_ioctl_get_tx_stats(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_tx_queue_stats stats; - int ret, i; - - if (!local->hw->get_tx_stats) - return -EOPNOTSUPP; - - memset(&stats, 0, sizeof(stats)); - ret = local->hw->get_tx_stats(dev, &stats); - if (ret) - return ret; - - for (i = 0; i < 4; i++) { - param->u.get_tx_stats.data[i].len = stats.data[i].len; - param->u.get_tx_stats.data[i].limit = stats.data[i].limit; - param->u.get_tx_stats.data[i].count = stats.data[i].count; - } - - return 0; -} - - -static int ieee80211_ioctl_set_bss(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev); - int i, bss_count; - int new_count = param->u.set_bss.bss_count; - struct net_device **bss_devs, **prev; - struct net_device **sta_devs, **prev_sta_devs; - - bss_count = 0; - for (i = 0; i < conf->bss_count; i++) { - if (local->bss_devs[i]) - bss_count++; - } - - if (new_count < bss_count) { - printk(KERN_DEBUG "%s: invalid BSS count %d (in use: %d)\n", - dev->name, new_count, bss_count); - return -EINVAL; - } - - bss_devs = kmalloc(new_count * sizeof(struct net_device *), - GFP_KERNEL); - if (bss_devs == NULL) - return -ENOMEM; - sta_devs = kmalloc(new_count * sizeof(struct net_device *), - GFP_KERNEL); - if (sta_devs == NULL) { - kfree(bss_devs); - return -ENOMEM; - } - - spin_lock_bh(&local->sub_if_lock); - memcpy(bss_devs, local->bss_devs, - bss_count * sizeof(struct net_device *)); - memset(&bss_devs[bss_count], 0, - (new_count - bss_count) * sizeof(struct net_device *)); - - memcpy(conf->bssid_mask, param->u.set_bss.bssid_mask, ETH_ALEN); - - prev = local->bss_devs; - local->bss_devs = bss_devs; - conf->bss_count = new_count; - - memcpy(sta_devs, local->sta_devs, - bss_count * sizeof(struct net_device *)); - memset(&sta_devs[bss_count], 0, - (new_count - bss_count) * sizeof(struct net_device *)); - prev_sta_devs = local->sta_devs; - local->sta_devs = sta_devs; - - spin_unlock_bh(&local->sub_if_lock); - kfree(prev); - kfree(prev_sta_devs); - - return ieee80211_hw_config(dev); -} - - -static int ieee80211_ioctl_set_channel_flag(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_hw_modes *mode = NULL; - struct ieee80211_channel *chan = NULL; - int i; - - for (i = 0; i < local->hw->num_modes; i++) { - mode = &local->hw->modes[i]; - if (mode->mode == param->u.set_channel_flag.mode) - break; - mode = NULL; - } - - if (!mode) - return -ENOENT; - - for (i = 0; i < mode->num_channels; i++) { - chan = &mode->channels[i]; - if (chan->chan == param->u.set_channel_flag.chan) - break; - chan = NULL; - } - - if (!chan) - return -ENOENT; - - chan->flag = param->u.set_channel_flag.flag; - chan->power_level = param->u.set_channel_flag.power_level; - chan->antenna_max = param->u.set_channel_flag.antenna_max; - - return 0; -} - - -static int ieee80211_ioctl_set_quiet_params(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev); - conf->quiet_duration = param->u.quiet.duration; - conf->quiet_offset = param->u.quiet.offset; - conf->quiet_period = param->u.quiet.period; - return 0; -} - - -static int ieee80211_ioctl_set_radar_params(struct net_device *dev, - struct prism2_hostapd_param *param) -{ - /* struct ieee80211_conf *conf = ieee80211_get_hw_conf(dev); */ - return 0; -} - - -static int ieee80211_ioctl_priv_hostapd(struct net_device *dev, - struct iw_point *p) -{ - struct prism2_hostapd_param *param; - int ret = 0; - - if (p->length < sizeof(struct prism2_hostapd_param) || - p->length > PRISM2_HOSTAPD_MAX_BUF_SIZE || !p->pointer) { - printk(KERN_DEBUG "%s: hostapd ioctl: ptr=%p len=%d min=%d " - "max=%d\n", dev->name, p->pointer, p->length, - (int)sizeof(struct prism2_hostapd_param), - PRISM2_HOSTAPD_MAX_BUF_SIZE); - return -EINVAL; - } - - param = (struct prism2_hostapd_param *) kmalloc(p->length, GFP_KERNEL); - if (param == NULL) - return -ENOMEM; - - if (copy_from_user(param, p->pointer, p->length)) { - ret = -EFAULT; - goto out; - } - - switch (param->cmd) { - case PRISM2_HOSTAPD_FLUSH: - ret = ieee80211_ioctl_flush(dev, param); - break; - case PRISM2_HOSTAPD_ADD_STA: - ret = ieee80211_ioctl_add_sta(dev, param); - break; - case PRISM2_HOSTAPD_REMOVE_STA: - ret = ieee80211_ioctl_remove_sta(dev, param); - break; - case PRISM2_HOSTAPD_GET_INFO_STA: - ret = ieee80211_ioctl_get_info_sta(dev, param); - break; - case PRISM2_SET_ENCRYPTION: - ret = ieee80211_ioctl_set_encryption(dev, param, p->length); - break; - case PRISM2_GET_ENCRYPTION: - ret = ieee80211_ioctl_get_encryption(dev, param, p->length); - break; - case PRISM2_HOSTAPD_SET_FLAGS_STA: - ret = ieee80211_ioctl_set_flags_sta(dev, param); - break; - case PRISM2_HOSTAPD_SET_BEACON: - ret = ieee80211_ioctl_set_beacon(dev, param, p->length, 0); - break; - case PRISM2_HOSTAPD_GET_HW_FEATURES: - ret = ieee80211_ioctl_get_hw_features(dev, param, p->length); - break; - case PRISM2_HOSTAPD_SCAN: - ret = ieee80211_ioctl_scan(dev, param); - break; -#ifdef CONFIG_HOSTAPD_WPA_TESTING - case PRISM2_HOSTAPD_WPA_TRIGGER: - ret = ieee80211_ioctl_wpa_trigger(dev, param); - break; -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - case PRISM2_HOSTAPD_SET_RATE_SETS: - ret = ieee80211_ioctl_set_rate_sets(dev, param, p->length); - break; - case PRISM2_HOSTAPD_ADD_IF: - ret = ieee80211_ioctl_add_if(dev, param, p->length); - break; - case PRISM2_HOSTAPD_REMOVE_IF: - ret = ieee80211_ioctl_remove_if(dev, param); - break; - case PRISM2_HOSTAPD_GET_DOT11COUNTERSTABLE: - ret = ieee80211_ioctl_get_dot11counterstable(dev, param); - break; - case PRISM2_HOSTAPD_GET_LOAD_STATS: - ret = ieee80211_ioctl_get_load_stats(dev, param); - break; - case PRISM2_HOSTAPD_SET_STA_VLAN: - ret = ieee80211_ioctl_set_sta_vlan(dev, param); - break; - case PRISM2_HOSTAPD_SET_GENERIC_INFO_ELEM: - ret = ieee80211_ioctl_set_generic_info_elem(dev, param, - p->length); - break; - case PRISM2_HOSTAPD_SET_CHANNEL_FLAG: - ret = ieee80211_ioctl_set_channel_flag(dev, param); - break; - case PRISM2_HOSTAPD_SET_REGULATORY_DOMAIN: - ret = ieee80211_ioctl_set_regulatory_domain(dev, param); - break; - case PRISM2_HOSTAPD_SET_TX_QUEUE_PARAMS: - ret = ieee80211_ioctl_set_tx_queue_params(dev, param); - break; - case PRISM2_HOSTAPD_SET_BSS: - ret = ieee80211_ioctl_set_bss(dev, param); - break; - case PRISM2_HOSTAPD_GET_TX_STATS: - ret = ieee80211_ioctl_get_tx_stats(dev, param); - break; - case PRISM2_HOSTAPD_UPDATE_IF: - ret = ieee80211_ioctl_update_if(dev, param, p->length); - break; - case PRISM2_HOSTAPD_SCAN_REQ: - ret = ieee80211_ioctl_scan_req(dev, param, p->length); - break; - case PRISM2_STA_GET_STATE: - ret = ieee80211_ioctl_sta_get_state(dev, param); - break; - case PRISM2_HOSTAPD_MLME: - ret = ieee80211_ioctl_mlme(dev, param); - break; - case PRISM2_HOSTAPD_FLUSH_IFS: - ret = ieee80211_ioctl_flush_ifs(dev, param); - break; - case PRISM2_HOSTAPD_SET_RADAR_PARAMS: - ret = ieee80211_ioctl_set_radar_params(dev, param); - break; - case PRISM2_HOSTAPD_SET_QUIET_PARAMS: - ret = ieee80211_ioctl_set_quiet_params(dev, param); - break; - default: - ret = -EOPNOTSUPP; - break; - } - - if (copy_to_user(p->pointer, param, p->length)) - ret = -EFAULT; - - out: - kfree(param); - - return ret; -} - - -static int ieee80211_ioctl_giwname(struct net_device *dev, - struct iw_request_info *info, - char *name, char *extra) -{ - struct ieee80211_local *local = dev->priv; - - switch (local->conf.phymode) { - case MODE_IEEE80211A: - strcpy(name, "IEEE 802.11a"); - break; - case MODE_IEEE80211B: - strcpy(name, "IEEE 802.11b"); - break; - case MODE_IEEE80211G: - strcpy(name, "IEEE 802.11g"); - break; - case MODE_ATHEROS_TURBO: - strcpy(name, "5GHz Turbo"); - break; - default: - strcpy(name, "IEEE 802.11"); - break; - } - - return 0; -} - - -static int ieee80211_ioctl_giwrange(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct iw_range *range = (struct iw_range *) extra; - - data->length = sizeof(struct iw_range); - memset(range, 0, sizeof(struct iw_range)); - - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 14; - range->retry_capa = IW_RETRY_LIMIT; - range->retry_flags = IW_RETRY_LIMIT; - range->min_retry = 0; - range->max_retry = 255; - range->min_rts = 0; - range->max_rts = 2347; - range->min_frag = 256; - range->max_frag = 2346; - - return 0; -} - - -struct ieee80211_channel_range { - short start_freq; - short end_freq; - unsigned char power_level; - unsigned char antenna_max; -}; - -static const struct ieee80211_channel_range ieee80211_fcc_channels[] = { - { 2412, 2462, 27, 6 } /* IEEE 802.11b/g, channels 1..11 */, - { 5180, 5240, 17, 6 } /* IEEE 802.11a, channels 36..48 */, - { 5260, 5320, 23, 6 } /* IEEE 802.11a, channels 52..64 */, - { 5745, 5825, 30, 6 } /* IEEE 802.11a, channels 149..165, outdoor */, - { 0 } -}; - -static const struct ieee80211_channel_range ieee80211_mkk_channels[] = { - { 2412, 2472, 20, 6 } /* IEEE 802.11b/g, channels 1..13 */, - { 5170, 5240, 20, 6 } /* IEEE 802.11a, channels 34..48 */, - { 5260, 5320, 20, 6 } /* IEEE 802.11a, channels 52..64 */, - { 0 } -}; - - -static const struct ieee80211_channel_range *channel_range = - ieee80211_fcc_channels; - - -static void ieee80211_unmask_channel(struct net_device *dev, int mode, - struct ieee80211_channel *chan) -{ - int i; - - chan->flag = 0; - - if (ieee80211_regdom == 64 && - (mode == MODE_ATHEROS_TURBO || mode == MODE_ATHEROS_TURBOG)) { - /* Do not allow Turbo modes in Japan. */ - return; - } - - for (i = 0; channel_range[i].start_freq; i++) { - const struct ieee80211_channel_range *r = &channel_range[i]; - if (r->start_freq <= chan->freq && r->end_freq >= chan->freq) { - if (ieee80211_regdom == 64 && !ieee80211_japan_5ghz && - chan->freq >= 5260 && chan->freq <= 5320) { - /* - * Skip new channels in Japan since the - * firmware was not marked having been upgraded - * by the vendor. - */ - continue; - } - - if (ieee80211_regdom == 0x10 && - (chan->freq == 5190 || chan->freq == 5210 || - chan->freq == 5230)) { - /* Skip MKK channels when in FCC domain. */ - continue; - } - - chan->flag |= IEEE80211_CHAN_W_SCAN | - IEEE80211_CHAN_W_ACTIVE_SCAN | - IEEE80211_CHAN_W_IBSS; - chan->power_level = r->power_level; - chan->antenna_max = r->antenna_max; - - if (ieee80211_regdom == 64 && - (chan->freq == 5170 || chan->freq == 5190 || - chan->freq == 5210 || chan->freq == 5230)) { - /* - * New regulatory rules in Japan have backwards - * compatibility with old channels in 5.15-5.25 - * GHz band, but the station is not allowed to - * use active scan on these old channels. - */ - chan->flag &= ~IEEE80211_CHAN_W_ACTIVE_SCAN; - } - - if (ieee80211_regdom == 64 && - (chan->freq == 5260 || chan->freq == 5280 || - chan->freq == 5300 || chan->freq == 5320)) { - /* - * IBSS is not allowed on 5.25-5.35 GHz band - * due to radar detection requirements. - */ - chan->flag &= ~IEEE80211_CHAN_W_IBSS; - } - - break; - } - } -} - - -static int ieee80211_unmask_channels(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - int m, c; - - for (m = 0; m < local->hw->num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw->modes[m]; - for (c = 0; c < mode->num_channels; c++) { - ieee80211_unmask_channel(dev, mode->mode, - &mode->channels[c]); - } - } - return 0; -} - - -static int ieee80211_init_client(struct net_device *dev) -{ - if (ieee80211_regdom == 0x40) - channel_range = ieee80211_mkk_channels; - ieee80211_unmask_channels(dev); - ieee80211_ioctl_set_adm_status(dev, 1); - return 0; -} - - -static int ieee80211_is_client_mode(int iw_mode) -{ - return (iw_mode == IW_MODE_INFRA || iw_mode == IW_MODE_ADHOC); -} - - -static int ieee80211_ioctl_siwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct ieee80211_local *local = dev->priv; - - if (!ieee80211_is_client_mode(local->conf.mode) && - ieee80211_is_client_mode(*mode)) { - ieee80211_init_client(dev); - } - if (local->conf.mode != *mode) { - struct ieee80211_sub_if_data *sdata = - IEEE80211_DEV_TO_SUB_IF(dev); - sta_info_flush(local, NULL); - if (local->conf.mode == IW_MODE_ADHOC && - sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - /* Clear drop_unencrypted when leaving adhoc mode since - * only adhoc mode is using automatic setting for this - * in 80211.o. */ - sdata->drop_unencrypted = 0; - } - if (*mode == IW_MODE_MASTER) { - /* AP mode does not currently use ACM bits to limit - * TX, so clear the bitfield here. */ - local->wmm_acm = 0; - } - } - local->conf.mode = *mode; - return ieee80211_hw_config(dev); -} - - -static int ieee80211_ioctl_giwmode(struct net_device *dev, - struct iw_request_info *info, - __u32 *mode, char *extra) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - if (local->conf.mode == IW_MODE_ADHOC) - *mode = IW_MODE_ADHOC; - else - *mode = IW_MODE_INFRA; - } else - *mode = local->conf.mode; - return 0; -} - - -int ieee80211_ioctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct ieee80211_local *local = dev->priv; - int m, c, nfreq, set = 0; - - /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ - if (freq->e == 0) - nfreq = -1; - else { - int i, div = 1000000; - for (i = 0; i < freq->e; i++) - div /= 10; - if (div > 0) - nfreq = freq->m / div; - else - return -EINVAL; - } - - for (m = 0; m < local->hw->num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw->modes[m]; - for (c = 0; c < mode->num_channels; c++) { - struct ieee80211_channel *chan = &mode->channels[c]; - if (chan->flag & IEEE80211_CHAN_W_SCAN && - ((freq->e == 0 && chan->chan == freq->m) || - (freq->e > 0 && nfreq == chan->freq)) && - (local->hw_modes & (1 << mode->mode))) { - /* Use next_mode as the mode preference to - * resolve non-unique channel numbers. */ - if (set && mode->mode != local->next_mode) - continue; - - local->conf.channel = chan->chan; - local->conf.channel_val = chan->val; - local->conf.power_level = chan->power_level; - local->conf.freq = chan->freq; - local->conf.phymode = mode->mode; - local->conf.antenna_max = chan->antenna_max; - set++; - } - } - } - - if (set) { - local->sta_scanning = 0; /* Abort possible scan */ - return ieee80211_hw_config(dev); - } - - return -EINVAL; -} - - -static int ieee80211_ioctl_giwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra) -{ - struct ieee80211_local *local = dev->priv; - - /* TODO: in station mode (Managed/Ad-hoc) might need to poll low-level - * driver for the current channel with firmware-based management */ - - freq->m = local->conf.freq; - freq->e = 6; - - return 0; -} - - -static int ieee80211_ioctl_siwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata; - size_t len = data->length; - - /* iwconfig uses nul termination in SSID.. */ - if (len > 0 && ssid[len - 1] == '\0') - len--; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) - return ieee80211_sta_set_ssid(dev, ssid, len); - - kfree(local->conf.ssid); - local->conf.ssid = kmalloc(len + 1, GFP_KERNEL); - if (local->conf.ssid == NULL) - return -ENOMEM; - memcpy(local->conf.ssid, ssid, len); - local->conf.ssid[len] = '\0'; - local->conf.ssid_len = len; - return ieee80211_hw_config(dev); -} - - -static int ieee80211_ioctl_giwessid(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *ssid) -{ - struct ieee80211_local *local = dev->priv; - size_t len; - - struct ieee80211_sub_if_data *sdata; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - int res = ieee80211_sta_get_ssid(dev, ssid, &len); - if (res == 0) - data->length = len; - return res; - } - - len = local->conf.ssid_len; - if (len > IW_ESSID_MAX_SIZE) - len = IW_ESSID_MAX_SIZE; - memcpy(ssid, local->conf.ssid, len); - data->length = len; - return 0; -} - - -static int ieee80211_ioctl_siwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - int changed_bssid = 0; - if (memcmp(local->conf.client_bssid, (u8 *) &ap_addr->sa_data, - ETH_ALEN) != 0) - changed_bssid = 1; - memcpy(local->conf.client_bssid, (u8 *) &ap_addr->sa_data, - ETH_ALEN); - if (changed_bssid && ieee80211_hw_config(dev)) { - printk(KERN_DEBUG "%s: Failed to config new BSSID to " - "the low-level driver\n", dev->name); - } - return ieee80211_sta_set_bssid(dev, (u8 *) &ap_addr->sa_data); - } - - return -EOPNOTSUPP; -} - - -static int ieee80211_ioctl_giwap(struct net_device *dev, - struct iw_request_info *info, - struct sockaddr *ap_addr, char *extra) -{ - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - ap_addr->sa_family = ARPHRD_ETHER; - memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN); - return 0; - } - - return -EOPNOTSUPP; -} - - -static int ieee80211_ioctl_siwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - struct ieee80211_local *local = dev->priv; - u8 *ssid = NULL; - size_t ssid_len = 0; - - if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID) { - ssid = local->conf.ssid; - ssid_len = local->conf.ssid_len; - } - return ieee80211_sta_req_scan(dev, ssid, ssid_len); -} - - -static int ieee80211_ioctl_giwscan(struct net_device *dev, - struct iw_request_info *info, - struct iw_point *data, char *extra) -{ - int res; - struct ieee80211_local *local = dev->priv; - if (local->sta_scanning) - return -EAGAIN; - res = ieee80211_sta_scan_results(dev, extra, IW_SCAN_MAX_DATA); - if (res >= 0) { - data->length = res; - return 0; - } - data->length = 0; - return res; -} - - -static int ieee80211_ioctl_siwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct ieee80211_local *local = dev->priv; - - if (rts->disabled) - local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; - else if (rts->value < 0 || rts->value > IEEE80211_MAX_RTS_THRESHOLD) - return -EINVAL; - else - local->rts_threshold = rts->value; - - /* If the wlan card performs RTS/CTS in hardware/firmware, - * configure it here */ - - if (local->hw->set_rts_threshold) { - local->hw->set_rts_threshold(dev, local->rts_threshold); - } - - return 0; -} - -static int ieee80211_ioctl_giwrts(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *rts, char *extra) -{ - struct ieee80211_local *local = dev->priv; - - rts->value = local->rts_threshold; - rts->disabled = (rts->value >= IEEE80211_MAX_RTS_THRESHOLD); - rts->fixed = 1; - - return 0; -} - - -static int ieee80211_ioctl_siwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct ieee80211_local *local = dev->priv; - - if (frag->disabled) - local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; - else if (frag->value < 256 || - frag->value > IEEE80211_MAX_FRAG_THRESHOLD) - return -EINVAL; - else { - /* Fragment length must be even, so strip LSB. */ - local->fragmentation_threshold = frag->value & ~0x1; - } - - /* If the wlan card performs fragmentation in hardware/firmware, - * configure it here */ - - if (local->hw->set_frag_threshold) { - local->hw->set_frag_threshold( - dev, local->fragmentation_threshold); - } - - return 0; -} - -static int ieee80211_ioctl_giwfrag(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *frag, char *extra) -{ - struct ieee80211_local *local = dev->priv; - - frag->value = local->fragmentation_threshold; - frag->disabled = (frag->value >= IEEE80211_MAX_RTS_THRESHOLD); - frag->fixed = 1; - - return 0; -} - - -static int ieee80211_ioctl_siwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *retry, char *extra) -{ - struct ieee80211_local *local = dev->priv; - - if (retry->disabled || - (retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) - return -EINVAL; - - if (retry->flags & IW_RETRY_MAX) - local->long_retry_limit = retry->value; - else if (retry->flags & IW_RETRY_MIN) - local->short_retry_limit = retry->value; - else { - local->long_retry_limit = retry->value; - local->short_retry_limit = retry->value; - } - - if (local->hw->set_retry_limit) { - return local->hw->set_retry_limit( - dev, local->short_retry_limit, - local->long_retry_limit); - } - - return 0; -} - - -static int ieee80211_ioctl_giwretry(struct net_device *dev, - struct iw_request_info *info, - struct iw_param *retry, char *extra) -{ - struct ieee80211_local *local = dev->priv; - - retry->disabled = 0; - if ((retry->flags & IW_RETRY_TYPE) != IW_RETRY_LIMIT) - return -EINVAL; - if (retry->flags & IW_RETRY_MAX) { - retry->flags = IW_RETRY_LIMIT | IW_RETRY_MAX; - retry->value = local->long_retry_limit; - } else { - retry->flags = IW_RETRY_LIMIT; - retry->value = local->short_retry_limit; - if (local->long_retry_limit != local->short_retry_limit) - retry->flags |= IW_RETRY_MIN; - } - - return 0; -} - - -static void ieee80211_ioctl_unmask_channels(struct ieee80211_local *local) -{ - int m, c; - - for (m = 0; m < local->hw->num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw->modes[m]; - for (c = 0; c < mode->num_channels; c++) { - struct ieee80211_channel *chan = &mode->channels[c]; - chan->flag |= IEEE80211_CHAN_W_SCAN; - } - } -} - - -static int ieee80211_ioctl_test_mode(struct net_device *dev, int mode) -{ - struct ieee80211_local *local = dev->priv; - int ret = -EOPNOTSUPP; - - if (mode == IEEE80211_TEST_UNMASK_CHANNELS) { - ieee80211_ioctl_unmask_channels(local); - ret = 0; - } - - if (local->hw->test_mode) - ret = local->hw->test_mode(dev, mode); - - return ret; -} - - -static int ieee80211_ioctl_clear_keys(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_key_conf key; - struct list_head *ptr; - int i; - u8 addr[ETH_ALEN]; - struct ieee80211_key_conf *keyconf; - - memset(addr, 0xff, ETH_ALEN); - list_for_each(ptr, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - for (i = 0; i < NUM_DEFAULT_KEYS; i++) { - keyconf = NULL; - if (sdata->keys[i] && - !sdata->keys[i]->force_sw_encrypt && - local->hw->set_key && - (keyconf = ieee80211_key_data2conf(local, - sdata->keys[i])) - != NULL) - local->hw->set_key(dev, DISABLE_KEY, addr, - keyconf, 0); - kfree(keyconf); - kfree(sdata->keys[i]); - sdata->keys[i] = NULL; - } - sdata->default_key = NULL; - } - - spin_lock_bh(&local->sta_lock); - list_for_each(ptr, &local->sta_list) { - struct sta_info *sta = - list_entry(ptr, struct sta_info, list); - keyconf = NULL; - if (sta->key && !sta->key->force_sw_encrypt && - local->hw->set_key && - (keyconf = ieee80211_key_data2conf(local, sta->key)) - != NULL) - local->hw->set_key(dev, DISABLE_KEY, sta->addr, - keyconf, sta->aid); - kfree(keyconf); - kfree(sta->key); - sta->key = NULL; - } - spin_unlock_bh(&local->sta_lock); - - - memset(&key, 0, sizeof(key)); - if (local->hw->set_key && - local->hw->set_key(dev, REMOVE_ALL_KEYS, NULL, - &key, 0)) - printk(KERN_DEBUG "%s: failed to remove hwaccel keys\n", - dev->name); - - return 0; -} - - -static int -ieee80211_ioctl_force_unicast_rate(struct net_device *dev, - struct ieee80211_sub_if_data *sdata, - int rate) -{ - struct ieee80211_local *local = dev->priv; - int i; - - if (sdata->type != IEEE80211_SUB_IF_TYPE_NORM) - return -ENOENT; - - if (rate == 0) { - sdata->u.norm.force_unicast_rateidx = -1; - return 0; - } - - for (i = 0; i < local->num_curr_rates; i++) { - if (local->curr_rates[i].rate == rate) { - sdata->u.norm.force_unicast_rateidx = i; - return 0; - } - } - return -EINVAL; -} - - -static int -ieee80211_ioctl_max_ratectrl_rate(struct net_device *dev, - struct ieee80211_sub_if_data *sdata, - int rate) -{ - struct ieee80211_local *local = dev->priv; - int i; - - if (sdata->type != IEEE80211_SUB_IF_TYPE_NORM) - return -ENOENT; - - if (rate == 0) { - sdata->u.norm.max_ratectrl_rateidx = -1; - return 0; - } - - for (i = 0; i < local->num_curr_rates; i++) { - if (local->curr_rates[i].rate == rate) { - sdata->u.norm.max_ratectrl_rateidx = i; - return 0; - } - } - return -EINVAL; -} - - -static void ieee80211_key_enable_hwaccel(struct ieee80211_local *local, - struct ieee80211_key *key) -{ - struct ieee80211_key_conf *keyconf; - u8 addr[ETH_ALEN]; - - if (key == NULL || key->alg != ALG_WEP || !key->force_sw_encrypt || - local->hw->device_hides_wep) - return; - - memset(addr, 0xff, ETH_ALEN); - keyconf = ieee80211_key_data2conf(local, key); - if (keyconf && local->hw->set_key && - local->hw->set_key(local->mdev, SET_KEY, addr, keyconf, 0) == 0) { - key->force_sw_encrypt = keyconf->force_sw_encrypt; - key->hw_key_idx = keyconf->hw_key_idx; - } - kfree(keyconf); -} - - -static void ieee80211_key_disable_hwaccel(struct ieee80211_local *local, - struct ieee80211_key *key) -{ - struct ieee80211_key_conf *keyconf; - u8 addr[ETH_ALEN]; - - if (key == NULL || key->alg != ALG_WEP || key->force_sw_encrypt || - local->hw->device_hides_wep) - return; - - memset(addr, 0xff, ETH_ALEN); - keyconf = ieee80211_key_data2conf(local, key); - if (keyconf && local->hw->set_key) - local->hw->set_key(local->mdev, DISABLE_KEY, addr, keyconf, 0); - kfree(keyconf); - key->force_sw_encrypt = 1; -} - - -static int ieee80211_ioctl_default_wep_only(struct ieee80211_local *local, - int value) -{ - int i; - struct list_head *ptr; - - local->default_wep_only = value; - list_for_each(ptr, &local->sub_if_list) { - struct ieee80211_sub_if_data *sdata = - list_entry(ptr, struct ieee80211_sub_if_data, list); - for (i = 0; i < NUM_DEFAULT_KEYS; i++) { - if (value) { - ieee80211_key_enable_hwaccel(local, - sdata->keys[i]); - } else { - ieee80211_key_disable_hwaccel(local, - sdata->keys[i]); - } - } - } - - return 0; -} - - -static int ieee80211_ioctl_prism2_param(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, char *extra) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata; - int *i = (int *) extra; - int param = *i; - int value = *(i + 1); - int ret = 0; - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - switch (param) { - case PRISM2_PARAM_HOST_ENCRYPT: - case PRISM2_PARAM_HOST_DECRYPT: - /* TODO: implement these; return success now to prevent - * hostapd from aborting */ - break; - - case PRISM2_PARAM_BEACON_INT: - local->conf.beacon_int = value; - if (ieee80211_hw_config(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_AP_BRIDGE_PACKETS: - local->bridge_packets = value; - break; - - case PRISM2_PARAM_AP_AUTH_ALGS: - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - sdata->u.sta.auth_algs = value; - } else - ret = -EOPNOTSUPP; - break; - - case PRISM2_PARAM_DTIM_PERIOD: - if (value < 1) - ret = -EINVAL; - else if (sdata->type != IEEE80211_SUB_IF_TYPE_NORM) - ret = -ENOENT; - else - sdata->u.norm.dtim_period = value; - break; - - case PRISM2_PARAM_IEEE_802_1X: - sdata->ieee802_1x = value; - if (local->hw->set_ieee8021x && - local->hw->set_ieee8021x(dev, value)) - printk(KERN_DEBUG "%s: failed to set IEEE 802.1X (%d) " - "for low-level driver\n", dev->name, value); - break; - - case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: - local->cts_protect_erp_frames = value; - break; - - case PRISM2_PARAM_DROP_UNENCRYPTED: - sdata->drop_unencrypted = value; - break; - - case PRISM2_PARAM_PREAMBLE: - local->short_preamble = value; - break; - - case PRISM2_PARAM_RATE_LIMIT_BURST: - local->rate_limit_burst = value; - local->rate_limit_bucket = value; - break; - - case PRISM2_PARAM_RATE_LIMIT: - /* number of packets (tokens) allowed per second */ - if (!local->rate_limit && value) { - if (!local->rate_limit_burst) local->rate_limit_burst = - value; - local->rate_limit_bucket = local->rate_limit_burst; - local->rate_limit_timer.expires = jiffies + HZ; - add_timer(&local->rate_limit_timer); - } else if (local->rate_limit && !value) { - del_timer_sync(&local->rate_limit_timer); - } - local->rate_limit = value; - break; - - case PRISM2_PARAM_STAT_TIME: - if (!local->stat_time && value) { - local->stat_timer.expires = jiffies + HZ * value / 100; - add_timer(&local->stat_timer); - } else if (local->stat_time && !value) { - del_timer_sync(&local->stat_timer); - } - local->stat_time = value; - break; - case PRISM2_PARAM_SHORT_SLOT_TIME: - local->conf.short_slot_time = value; - if (ieee80211_hw_config(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_PRIVACY_INVOKED: - if (local->hw->set_privacy_invoked) - ret = local->hw->set_privacy_invoked(dev, value); - break; - - case PRISM2_PARAM_TEST_MODE: - ret = ieee80211_ioctl_test_mode(dev, value); - break; - - case PRISM2_PARAM_NEXT_MODE: - local->next_mode = value; - break; - - case PRISM2_PARAM_CLEAR_KEYS: - ret = ieee80211_ioctl_clear_keys(dev); - break; - - case PRISM2_PARAM_ADM_STATUS: - ret = ieee80211_ioctl_set_adm_status(dev, value); - break; - - case PRISM2_PARAM_ANTENNA_SEL: - local->conf.antenna_sel = value; - if (ieee80211_hw_config(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_CALIB_INT: - local->conf.calib_int = value; - if (ieee80211_hw_config(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_ANTENNA_MODE: - local->conf.antenna_mode = value; - if (ieee80211_hw_config(dev)) - ret = -EINVAL; - break; - - case PRISM2_PARAM_BROADCAST_SSID: - if ((value < 0) || (value > 1)) - ret = -EINVAL; - else - local->conf.ssid_hidden = value; - break; - - case PRISM2_PARAM_STA_ANTENNA_SEL: - local->sta_antenna_sel = value; - break; - - case PRISM2_PARAM_FORCE_UNICAST_RATE: - ret = ieee80211_ioctl_force_unicast_rate(dev, sdata, value); - break; - - case PRISM2_PARAM_MAX_RATECTRL_RATE: - ret = ieee80211_ioctl_max_ratectrl_rate(dev, sdata, value); - break; - - case PRISM2_PARAM_RATE_CTRL_NUM_UP: - local->rate_ctrl_num_up = value; - break; - - case PRISM2_PARAM_RATE_CTRL_NUM_DOWN: - local->rate_ctrl_num_down = value; - break; - - case PRISM2_PARAM_TX_POWER_REDUCTION: - if (value < 0) - ret = -EINVAL; - else - local->conf.tx_power_reduction = value; - break; - - case PRISM2_PARAM_EAPOL: - sdata->eapol = value; - break; - - case PRISM2_PARAM_KEY_TX_RX_THRESHOLD: - local->key_tx_rx_threshold = value; - break; - - case PRISM2_PARAM_KEY_INDEX: - if (value < 0 || value >= NUM_DEFAULT_KEYS) - ret = -EINVAL; - else if (sdata->keys[value] == NULL) - ret = -ENOENT; - else - sdata->default_key = sdata->keys[value]; - break; - - case PRISM2_PARAM_DEFAULT_WEP_ONLY: - ret = ieee80211_ioctl_default_wep_only(local, value); - break; - - case PRISM2_PARAM_WIFI_WME_NOACK_TEST: - local->wifi_wme_noack_test = value; - break; - - - - case PRISM2_PARAM_ALLOW_BROADCAST_ALWAYS: - local->allow_broadcast_always = value; - break; - - case PRISM2_PARAM_SCAN_FLAGS: - local->scan_flags = value; - break; - - case PRISM2_PARAM_MIXED_CELL: - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - ret = -EINVAL; - else - sdata->u.sta.mixed_cell = !!value; - break; - - case PRISM2_PARAM_KEY_MGMT: - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - ret = -EINVAL; - else - sdata->u.sta.key_mgmt = value; - break; - - case PRISM2_PARAM_HW_MODES: - local->hw_modes = value; - break; - - case PRISM2_PARAM_CREATE_IBSS: - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - ret = -EINVAL; - else - sdata->u.sta.create_ibss = !!value; - break; - case PRISM2_PARAM_WMM_ENABLED: - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - ret = -EINVAL; - else - sdata->u.sta.wmm_enabled = !!value; - break; - case PRISM2_PARAM_RADAR_DETECT: - local->conf.radar_detect = value; - break; - case PRISM2_PARAM_SPECTRUM_MGMT: - local->conf.spect_mgmt = value; - break; - default: - ret = -EOPNOTSUPP; - break; - } - - return ret; -} - - -static int ieee80211_ioctl_get_prism2_param(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, char *extra) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata; - int *param = (int *) extra; - int ret = 0; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - switch (*param) { - case PRISM2_PARAM_BEACON_INT: - *param = local->conf.beacon_int; - break; - - case PRISM2_PARAM_AP_BRIDGE_PACKETS: - *param = local->bridge_packets; - break; - - case PRISM2_PARAM_AP_AUTH_ALGS: - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - *param = sdata->u.sta.auth_algs; - } else - ret = -EOPNOTSUPP; - break; - - case PRISM2_PARAM_DTIM_PERIOD: - if (sdata->type != IEEE80211_SUB_IF_TYPE_NORM) - ret = -ENOENT; - else - *param = sdata->u.norm.dtim_period; - break; - - case PRISM2_PARAM_IEEE_802_1X: - *param = sdata->ieee802_1x; - break; - - case PRISM2_PARAM_CTS_PROTECT_ERP_FRAMES: - *param = local->cts_protect_erp_frames; - break; - - case PRISM2_PARAM_DROP_UNENCRYPTED: - *param = sdata->drop_unencrypted; - break; - - case PRISM2_PARAM_PREAMBLE: - *param = local->short_preamble; - break; - - case PRISM2_PARAM_RATE_LIMIT_BURST: - *param = local->rate_limit_burst; - break; - - case PRISM2_PARAM_RATE_LIMIT: - *param = local->rate_limit; - break; - - case PRISM2_PARAM_STAT_TIME: - *param = local->stat_time; - break; - case PRISM2_PARAM_SHORT_SLOT_TIME: - *param = local->conf.short_slot_time; - break; - - case PRISM2_PARAM_NEXT_MODE: - *param = local->next_mode; - break; - - case PRISM2_PARAM_ANTENNA_SEL: - *param = local->conf.antenna_sel; - break; - - case PRISM2_PARAM_CALIB_INT: - *param = local->conf.calib_int; - break; - - case PRISM2_PARAM_ANTENNA_MODE: - *param = local->conf.antenna_mode; - break; - - case PRISM2_PARAM_BROADCAST_SSID: - *param = local->conf.ssid_hidden; - break; - - case PRISM2_PARAM_STA_ANTENNA_SEL: - *param = local->sta_antenna_sel; - break; - - case PRISM2_PARAM_RATE_CTRL_NUM_UP: - *param = local->rate_ctrl_num_up; - break; - - case PRISM2_PARAM_RATE_CTRL_NUM_DOWN: - *param = local->rate_ctrl_num_down; - break; - - case PRISM2_PARAM_TX_POWER_REDUCTION: - *param = local->conf.tx_power_reduction; - break; - - case PRISM2_PARAM_EAPOL: - *param = sdata->eapol; - break; - - case PRISM2_PARAM_KEY_TX_RX_THRESHOLD: - *param = local->key_tx_rx_threshold; - break; - - case PRISM2_PARAM_KEY_INDEX: - if (sdata->default_key == NULL) - ret = -ENOENT; - else if (sdata->default_key == sdata->keys[0]) - *param = 0; - else if (sdata->default_key == sdata->keys[1]) - *param = 1; - else if (sdata->default_key == sdata->keys[2]) - *param = 2; - else if (sdata->default_key == sdata->keys[3]) - *param = 3; - else - ret = -ENOENT; - break; - - case PRISM2_PARAM_DEFAULT_WEP_ONLY: - *param = local->default_wep_only; - break; - - case PRISM2_PARAM_WIFI_WME_NOACK_TEST: - *param = local->wifi_wme_noack_test; - break; - - - - case PRISM2_PARAM_ALLOW_BROADCAST_ALWAYS: - *param = local->allow_broadcast_always; - break; - - case PRISM2_PARAM_SCAN_FLAGS: - *param = local->scan_flags; - break; - - case PRISM2_PARAM_HW_MODES: - *param = local->hw_modes; - break; - - case PRISM2_PARAM_CREATE_IBSS: - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - ret = -EINVAL; - else - *param = !!sdata->u.sta.create_ibss; - break; - - case PRISM2_PARAM_MIXED_CELL: - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - ret = -EINVAL; - else - *param = !!sdata->u.sta.mixed_cell; - break; - - case PRISM2_PARAM_KEY_MGMT: - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - ret = -EINVAL; - else - *param = sdata->u.sta.key_mgmt; - break; - case PRISM2_PARAM_WMM_ENABLED: - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - ret = -EINVAL; - else - *param = !!sdata->u.sta.wmm_enabled; - break; - - default: - ret = -EOPNOTSUPP; - break; - } - - return ret; -} - - -static int ieee80211_ioctl_test_param(struct net_device *dev, - struct iw_request_info *info, - void *wrqu, char *extra) -{ - struct ieee80211_local *local = dev->priv; - int *i = (int *) extra; - int param = *i; - int value = *(i + 1); - - if (!capable(CAP_NET_ADMIN)) - return -EPERM; - - if (local->hw->test_param) - return local->hw->test_param(local->mdev, param, value); - - return -EOPNOTSUPP; -} - - -static const struct iw_priv_args ieee80211_ioctl_priv[] = { - { PRISM2_IOCTL_PRISM2_PARAM, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "param" }, - { PRISM2_IOCTL_GET_PRISM2_PARAM, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_param" }, - { PRISM2_IOCTL_TEST_PARAM, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "test_param" }, -}; - - -static int ieee80211_ioctl_giwpriv(struct net_device *dev, - struct iw_point *data) -{ - - if (!data->pointer || - !access_ok(VERIFY_WRITE, data->pointer, - sizeof(ieee80211_ioctl_priv))) - return -EINVAL; - - data->length = sizeof(ieee80211_ioctl_priv) / - sizeof(ieee80211_ioctl_priv[0]); - if (copy_to_user(data->pointer, ieee80211_ioctl_priv, - sizeof(ieee80211_ioctl_priv))) - return -EINVAL; - return 0; -} - - -int ieee80211_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct iwreq *wrq = (struct iwreq *) rq; - int ret = 0; - char ssid[IW_ESSID_MAX_SIZE + 1]; - - switch (cmd) { - case SIOCGIWNAME: - ret = ieee80211_ioctl_giwname(dev, NULL, (char *) &wrq->u, - NULL); - break; - case SIOCSIWESSID: - if (!wrq->u.essid.pointer) - ret = -EINVAL; - else if (wrq->u.essid.length > IW_ESSID_MAX_SIZE) - ret = -E2BIG; - else { - if (copy_from_user(ssid, wrq->u.essid.pointer, - wrq->u.essid.length)) { - ret = -EFAULT; - break; - } - ret = ieee80211_ioctl_siwessid(dev, NULL, - &wrq->u.essid, ssid); - } - break; - case SIOCGIWESSID: - if (!wrq->u.essid.pointer) { - ret = -EINVAL; - } else { - memset(ssid, 0, IW_ESSID_MAX_SIZE + 1); - ret = ieee80211_ioctl_giwessid(dev, NULL, - &wrq->u.essid, ssid); - if (copy_to_user(wrq->u.essid.pointer, ssid, - wrq->u.essid.length)) { - ret = -EFAULT; - break; - } - } - break; - - case SIOCGIWRANGE: - { - struct iw_range range; - if (!access_ok(VERIFY_WRITE, wrq->u.data.pointer, - sizeof(range))) { - ret = -EFAULT; - break; - } - ret = ieee80211_ioctl_giwrange(dev, NULL, &wrq->u.data, - (char *) &range); - if (ret) - break; - if (copy_to_user(wrq->u.data.pointer, &range, sizeof(range))) - ret = -EFAULT; - break; - } - - case SIOCSIWAP: - ret = ieee80211_ioctl_siwap(dev, NULL, &wrq->u.ap_addr, NULL); - break; - case SIOCGIWAP: - ret = ieee80211_ioctl_giwap(dev, NULL, &wrq->u.ap_addr, NULL); - break; - case SIOCSIWSCAN: - ret = ieee80211_ioctl_siwscan(dev, NULL, &wrq->u.data, NULL); - break; - case SIOCGIWSCAN: - { - char *buf = kmalloc(IW_SCAN_MAX_DATA, GFP_KERNEL); - if (buf == NULL) { - ret = -ENOMEM; - break; - } - ret = ieee80211_ioctl_giwscan(dev, NULL, &wrq->u.data, buf); - if (ret == 0 && - copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) - ret = -EFAULT; - kfree(buf); - break; - } - - case SIOCSIWFREQ: - ret = ieee80211_ioctl_siwfreq(dev, NULL, &wrq->u.freq, NULL); - break; - case SIOCGIWFREQ: - ret = ieee80211_ioctl_giwfreq(dev, NULL, &wrq->u.freq, NULL); - break; - case SIOCSIWMODE: - ret = ieee80211_ioctl_siwmode(dev, NULL, &wrq->u.mode, NULL); - break; - case SIOCGIWMODE: - ret = ieee80211_ioctl_giwmode(dev, NULL, &wrq->u.mode, NULL); - break; - - case SIOCSIWRTS: - ret = ieee80211_ioctl_siwrts(dev, NULL, &wrq->u.rts, NULL); - break; - case SIOCGIWRTS: - ret = ieee80211_ioctl_giwrts(dev, NULL, &wrq->u.rts, NULL); - break; - - case SIOCSIWFRAG: - ret = ieee80211_ioctl_siwfrag(dev, NULL, &wrq->u.frag, NULL); - break; - case SIOCGIWFRAG: - ret = ieee80211_ioctl_giwfrag(dev, NULL, &wrq->u.frag, NULL); - break; - - case SIOCSIWRETRY: - ret = ieee80211_ioctl_siwretry(dev, NULL, &wrq->u.retry, NULL); - break; - case SIOCGIWRETRY: - ret = ieee80211_ioctl_giwretry(dev, NULL, &wrq->u.retry, NULL); - break; - - case PRISM2_IOCTL_PRISM2_PARAM: - ret = ieee80211_ioctl_prism2_param(dev, NULL, &wrq->u, - (char *) &wrq->u); - break; - case PRISM2_IOCTL_GET_PRISM2_PARAM: - ret = ieee80211_ioctl_get_prism2_param(dev, NULL, &wrq->u, - (char *) &wrq->u); - break; - case PRISM2_IOCTL_TEST_PARAM: - ret = ieee80211_ioctl_test_param(dev, NULL, &wrq->u, - (char *) &wrq->u); - break; - case PRISM2_IOCTL_HOSTAPD: - if (!capable(CAP_NET_ADMIN)) ret = -EPERM; - else ret = ieee80211_ioctl_priv_hostapd(dev, &wrq->u.data); - break; - case SIOCGIWPRIV: - ret = ieee80211_ioctl_giwpriv(dev, &wrq->u.data); - break; - default: - ret = -EOPNOTSUPP; - break; - } - - return ret; -} diff --git a/target/linux/package/ieee80211-dscape/src/ieee80211_key.h b/target/linux/package/ieee80211-dscape/src/ieee80211_key.h deleted file mode 100644 index 7a2415dec4..0000000000 --- a/target/linux/package/ieee80211-dscape/src/ieee80211_key.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2002-2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef IEEE80211_KEY_H -#define IEEE80211_KEY_H - -/* ALG_TKIP - * struct ieee80211_key::key is encoded as a 256-bit (32 byte) data block: - * Temporal Encryption Key (128 bits) - * Temporal Authenticator Tx MIC Key (64 bits) - * Temporal Authenticator Rx MIC Key (64 bits) - */ - -#define WEP_IV_LEN 4 -#define WEP_ICV_LEN 4 - -#define ALG_TKIP_KEY_LEN 32 -/* Starting offsets for each key */ -#define ALG_TKIP_TEMP_ENCR_KEY 0 -#define ALG_TKIP_TEMP_AUTH_TX_MIC_KEY 16 -#define ALG_TKIP_TEMP_AUTH_RX_MIC_KEY 24 -#define TKIP_IV_LEN 8 -#define TKIP_ICV_LEN 4 - -#define ALG_CCMP_KEY_LEN 16 -#define CCMP_HDR_LEN 8 -#define CCMP_MIC_LEN 8 -#define CCMP_TK_LEN 16 -#define CCMP_PN_LEN 6 - -#define NUM_RX_DATA_QUEUES 17 - -struct ieee80211_key { - int hw_key_idx; /* filled and used by low-level driver */ - ieee80211_key_alg alg; - union { - struct { - /* last used TSC */ - u32 iv32; - u16 iv16; - u16 p1k[5]; - int tx_initialized; - - /* last received RSC */ - u32 iv32_rx[NUM_RX_DATA_QUEUES]; - u16 iv16_rx[NUM_RX_DATA_QUEUES]; - u16 p1k_rx[NUM_RX_DATA_QUEUES][5]; - int rx_initialized[NUM_RX_DATA_QUEUES]; - } tkip; - struct { - u8 tx_pn[6]; - /* TODO: for WME make this replay counter per AC */ - u8 rx_pn[NUM_RX_DATA_QUEUES][6]; -#ifndef AES_STATE_LEN -#define AES_STATE_LEN 44 -#endif - u32 aes_state[AES_STATE_LEN]; - u32 replays; /* dot11RSNAStatsCCMPReplays */ - } ccmp; - } u; - int tx_rx_count; /* number of times this key has been used */ - int keylen; - - /* if the low level driver can provide hardware acceleration it should - * clear this flag */ - int force_sw_encrypt:1; - int keyidx:8; /* WEP key index */ - int default_tx_key:1; /* This key is the new default TX key - * (used only for broadcast keys). */ - - u8 key[0]; -}; - -#endif /* IEEE80211_KEY_H */ diff --git a/target/linux/package/ieee80211-dscape/src/ieee80211_led.c b/target/linux/package/ieee80211-dscape/src/ieee80211_led.c deleted file mode 100644 index de3f52cc7f..0000000000 --- a/target/linux/package/ieee80211-dscape/src/ieee80211_led.c +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright 2002-2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include - -#ifdef CONFIG_OAP_LEDS_WLAN -extern void leds_wlan_set(int unit, int tx, int state); -#endif - -void ieee80211_rx_led(int state, struct net_device *dev) { -#ifdef CONFIG_OAP_LEDS_WLAN - static unsigned int count = 0; - - if (state == 2) { - leds_wlan_set(0, 0, (++count) & 1); - } -#endif -} - -void ieee80211_tx_led(int state, struct net_device *dev) { -#ifdef CONFIG_OAP_LEDS_WLAN - leds_wlan_set(0, 1, state); -#endif -} - diff --git a/target/linux/package/ieee80211-dscape/src/ieee80211_proc.c b/target/linux/package/ieee80211-dscape/src/ieee80211_proc.c deleted file mode 100644 index 1f74f29942..0000000000 --- a/target/linux/package/ieee80211-dscape/src/ieee80211_proc.c +++ /dev/null @@ -1,777 +0,0 @@ -/* - * Copyright 2003-2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_PROC_FS - -#include -#include -#include -#include "ieee80211_i.h" -#include "sta_info.h" -#include "ieee80211_proc.h" -#include "rate_control.h" - - -static struct proc_dir_entry *ieee80211_proc; - -#define PROC_LIMIT (PAGE_SIZE - 80) - - -static char * ieee80211_proc_key(char *p, struct ieee80211_key *key, - int idx, int def_key) -{ - int i; - u8 *tpn, *rpn; - - if (!key) - return p; - - p += sprintf(p, "key[%d]%s len=%d sw_encrypt=%d idx=%d hwidx=%d " - "tx_rx_count=%d", - idx, def_key ? "*" : "", key->keylen, - key->force_sw_encrypt, key->keyidx, key->hw_key_idx, - key->tx_rx_count); - switch (key->alg) { - case ALG_WEP: - p += sprintf(p, " alg=WEP"); - break; - case ALG_TKIP: - p += sprintf(p, " alg=TKIP iv(tx)=%08x %04x", - key->u.tkip.iv32, key->u.tkip.iv16); - for (i = 0; i < NUM_RX_DATA_QUEUES; i++) { - if (key->u.tkip.iv32_rx[i] == 0 && - key->u.tkip.iv16_rx[i] == 0) - continue; - p += sprintf(p, " iv(rx %d)=%08x %04x", i, - key->u.tkip.iv32_rx[i], - key->u.tkip.iv16_rx[i]); - } - break; - case ALG_CCMP: - tpn = key->u.ccmp.tx_pn; - p += sprintf(p, " alg=CCMP PN(tx)=%02x%02x%02x%02x%02x%02x", - tpn[0], tpn[1], tpn[2], tpn[3], tpn[4], tpn[5]); - for (i = 0; i < NUM_RX_DATA_QUEUES; i++) { - rpn = key->u.ccmp.rx_pn[i]; - if (memcmp(rpn, "\x00\x00\x00\x00\x00\x00", 6) == 0) - continue; - p += sprintf(p, " PN(rx %d)=%02x%02x%02x%02x%02x%02x", - i, rpn[0], rpn[1], rpn[2], rpn[3], rpn[4], - rpn[5]); - } - p += sprintf(p, " replays=%u", key->u.ccmp.replays); - break; - default: - break; - } - - p += sprintf(p, " key="); - for (i = 0; i < key->keylen; i++) - p += sprintf(p, "%02x", key->key[i]); - p += sprintf(p, "\n"); - return p; -} - - -static char * ieee80211_proc_sub_if_norm(char *p, - struct ieee80211_if_norm *norm) -{ - p += sprintf(p, "type=norm\n"); - if (norm->beacon_head) - p += sprintf(p, "beacon_head_len=%d\n", norm->beacon_head_len); - if (norm->beacon_tail) - p += sprintf(p, "beacon_tail_len=%d\n", norm->beacon_tail_len); - p += sprintf(p, - "max_aid=%d\n" - "num_sta_ps=%d\n" - "num_buffered_multicast=%u\n" - "dtim_period=%d\n" - "dtim_count=%d\n" - "num_beacons=%d\n" - "force_unicast_rateidx=%d\n" - "max_ratectrl_rateidx=%d\n", - norm->max_aid, atomic_read(&norm->num_sta_ps), - skb_queue_len(&norm->ps_bc_buf), - norm->dtim_period, norm->dtim_count, norm->num_beacons, - norm->force_unicast_rateidx, norm->max_ratectrl_rateidx); - return p; -} - - -static char * ieee80211_proc_sub_if_sta(char *p, - struct ieee80211_if_sta *ifsta) -{ - p += sprintf(p, "type=sta\n"); - p += sprintf(p, - "state=%d\n" - "bssid=" MACSTR "\n" - "prev_bssid=" MACSTR "\n" - "ssid_len=%zd\n" - "aid=%d\n" - "ap_capab=0x%x\n" - "capab=0x%x\n" - "extra_ie_len=%zd\n" - "auth_tries=%d\n" - "assoc_tries=%d\n" - "flags=%s%s%s%s%s%s%s\n" - "auth_algs=0x%x\n" - "auth_alg=%d\n" - "auth_transaction=%d\n", - ifsta->state, - MAC2STR(ifsta->bssid), - MAC2STR(ifsta->prev_bssid), - ifsta->ssid_len, - ifsta->aid, - ifsta->ap_capab, - ifsta->capab, - ifsta->extra_ie_len, - ifsta->auth_tries, - ifsta->assoc_tries, - ifsta->ssid_set ? "[SSID]" : "", - ifsta->bssid_set ? "[BSSID]" : "", - ifsta->prev_bssid_set ? "[prev BSSID" : "", - ifsta->authenticated ? "[AUTH]" : "", - ifsta->associated ? "[ASSOC]" : "", - ifsta->probereq_poll ? "[PROBEREQ POLL]" : "", - ifsta->use_protection ? "[CTS prot]" : "", - ifsta->auth_algs, - ifsta->auth_alg, - ifsta->auth_transaction); - return p; -} - - -static char * ieee80211_proc_sub_if(char *p, - struct ieee80211_sub_if_data *sdata) -{ - if (sdata == NULL) - return p; - - if (sdata->bss) - p += sprintf(p, "bss=%p\n", sdata->bss); - - switch (sdata->type) { - case IEEE80211_SUB_IF_TYPE_NORM: - p = ieee80211_proc_sub_if_norm(p, &sdata->u.norm); - break; - case IEEE80211_SUB_IF_TYPE_WDS: - p += sprintf(p, "type=wds\n"); - p += sprintf(p, "wds.peer=" MACSTR "\n", - MAC2STR(sdata->u.wds.remote_addr)); - break; - case IEEE80211_SUB_IF_TYPE_VLAN: - p += sprintf(p, "type=vlan\n"); - p += sprintf(p, "vlan.id=%d\n", sdata->u.vlan.id); - break; - case IEEE80211_SUB_IF_TYPE_STA: - p = ieee80211_proc_sub_if_sta(p, &sdata->u.sta); - break; - } - p += sprintf(p, "channel_use=%d\n", sdata->channel_use); - p += sprintf(p, "drop_unencrypted=%d\n", sdata->drop_unencrypted); - p += sprintf(p, "eapol=%d\n", sdata->eapol); - p += sprintf(p, "ieee802_1x=%d\n", sdata->ieee802_1x); - - return p; -} - - -static int ieee80211_proc_iface_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct net_device *dev = (struct net_device *) data; - struct ieee80211_sub_if_data *sdata; - int i; - - if (off != 0) { - *eof = 1; - return 0; - } - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (!sdata) - return -1; - - p = ieee80211_proc_sub_if(p, sdata); - - for (i = 0; i < NUM_DEFAULT_KEYS; i++) { - if (sdata->keys[i] == NULL) - continue; - - p = ieee80211_proc_key(p, sdata->keys[i], i, - sdata->keys[i] == sdata->default_key); - } - - return (p - page); -} - - -static int ieee80211_proc_sta_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct sta_info *sta = (struct sta_info *) data; - struct ieee80211_local *local; - int inactive, i; - - if (off != 0) { - *eof = 1; - return 0; - } - - if (!sta || !sta->dev) - return -1; - - p += sprintf(p, "users=%d\n", atomic_read(&sta->users)); - p += sprintf(p, "aid=%d\n", sta->aid); - p += sprintf(p, "flags=0x%x %s%s%s%s%s%s%s%s%s%s\n", sta->flags, - sta->flags & WLAN_STA_AUTH ? "[AUTH]" : "", - sta->flags & WLAN_STA_ASSOC ? "[ASSOC]" : "", - sta->flags & WLAN_STA_PS ? "[PS]" : "", - sta->flags & WLAN_STA_TIM ? "[TIM]" : "", - sta->flags & WLAN_STA_PERM ? "[PERM]" : "", - sta->flags & WLAN_STA_AUTHORIZED ? "[AUTHORIZED]" : "", - sta->flags & WLAN_STA_SHORT_PREAMBLE ? - "[SHORT PREAMBLE]" : "", - sta->flags & WLAN_STA_WME ? "[WME]" : "", - sta->flags & WLAN_STA_WDS ? "[WDS]" : "", - sta->flags & WLAN_STA_XR ? "[XR]" : ""); - p += sprintf(p, "key_idx_compression=%d\n", - sta->key_idx_compression); - p += sprintf(p, "dev=%s\n", sta->dev->name); - if (sta->vlan_id > 0) - p += sprintf(p, "vlan_id=%d\n", sta->vlan_id); - p += sprintf(p, "rx_packets=%lu\ntx_packets=%lu\nrx_bytes=%lu\n" - "tx_bytes=%lu\nrx_duplicates=%lu\nrx_fragments=%lu\n" - "rx_dropped=%lu\ntx_fragments=%lu\ntx_filtered=%lu\n", - sta->rx_packets, sta->tx_packets, - sta->rx_bytes, sta->tx_bytes, - sta->num_duplicates, sta->rx_fragments, sta->rx_dropped, - sta->tx_fragments, sta->tx_filtered_count); - p = ieee80211_proc_key(p, sta->key, 0, 1); - - local = (struct ieee80211_local *) sta->dev->priv; - if (sta->txrate >= 0 && sta->txrate < local->num_curr_rates) { - p += sprintf(p, "txrate=%d\n", - local->curr_rates[sta->txrate].rate); - } - if (sta->last_txrate >= 0 && - sta->last_txrate < local->num_curr_rates) { - p += sprintf(p, "last_txrate=%d\n", - local->curr_rates[sta->last_txrate].rate); - } - p += sprintf(p, "num_ps_buf_frames=%u\n", - skb_queue_len(&sta->ps_tx_buf)); - p += sprintf(p, "tx_retry_failed=%lu\n", sta->tx_retry_failed); - p += sprintf(p, "tx_retry_count=%lu\n", sta->tx_retry_count); - p += sprintf(p, "last_rssi=%d\n", sta->last_rssi); - p += sprintf(p, "last_ack_rssi=%d %d %d\n", - sta->last_ack_rssi[0], sta->last_ack_rssi[1], - sta->last_ack_rssi[2]); - if (sta->last_ack) - p += sprintf(p, "last_ack_ms=%d\n", - jiffies_to_msecs(jiffies - sta->last_ack)); - inactive = jiffies - sta->last_rx; - p += sprintf(p, "inactive_msec=%d\n", jiffies_to_msecs(inactive)); - p += sprintf(p, "channel_use=%d\n", sta->channel_use); - p += sprintf(p, "wep_weak_iv_count=%d\n", sta->wep_weak_iv_count); -#ifdef CONFIG_IEEE80211_DEBUG_COUNTERS - p += sprintf(p, "wme_rx_queue="); - for (i = 0; i < NUM_RX_DATA_QUEUES; i++) - p += sprintf(p, "%u ", sta->wme_rx_queue[i]); - p += sprintf(p, "\n"); - - p += sprintf(p, "wme_tx_queue="); - for (i = 0; i < NUM_RX_DATA_QUEUES; i++) - p += sprintf(p, "%u ", sta->wme_tx_queue[i]); - p += sprintf(p, "\n"); -#endif /* CONFIG_IEEE80211_DEBUG_COUNTERS */ - p += sprintf(p, "last_seq_ctrl="); - for (i = 0; i < NUM_RX_DATA_QUEUES; i++) { - p += sprintf(p, "%x ", sta->last_seq_ctrl[i]); - } - p += sprintf(p, "\n"); - - p += rate_control_status_sta(local, sta, p); - - return (p - page); -} - - -static int ieee80211_proc_counters_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ieee80211_local *local = (struct ieee80211_local *) data; - struct ieee80211_low_level_stats stats; - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, - "TransmittedFragmentCount=%u\n" - "MulticastTransmittedFrameCount=%u\n" - "FailedCount=%u\n" - "RetryCount=%u\n" - "MultipleRetryCount=%d\n" - "FrameDuplicateCount=%d\n" - "ReceivedFragmentCount=%u\n" - "MulticastReceivedFrameCount=%u\n" - "TransmittedFrameCount=%u\n" - "WEPUndecryptableCount=%u\n", - local->dot11TransmittedFragmentCount, - local->dot11MulticastTransmittedFrameCount, - local->dot11FailedCount, - local->dot11RetryCount, - local->dot11MultipleRetryCount, - local->dot11FrameDuplicateCount, - local->dot11ReceivedFragmentCount, - local->dot11MulticastReceivedFrameCount, - local->dot11TransmittedFrameCount, - local->dot11WEPUndecryptableCount); - - memset(&stats, 0, sizeof(stats)); - if (local->hw->get_stats && - local->hw->get_stats(local->mdev, &stats) == 0) { - p += sprintf(p, - "ACKFailureCount=%u\n" - "RTSFailureCount=%u\n" - "FCSErrorCount=%u\n" - "RTSSuccessCount=%u\n", - stats.dot11ACKFailureCount, - stats.dot11RTSFailureCount, - stats.dot11FCSErrorCount, - stats.dot11RTSSuccessCount); - } - - return (p - page); -} - - -static int ieee80211_proc_debug_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ieee80211_local *local = (struct ieee80211_local *) data; - int i; - - if (off != 0) { - *eof = 1; - return 0; - } - -#ifdef CONFIG_IEEE80211_DEBUG_COUNTERS - p += sprintf(p, - "tx_handlers_drop=%u\n" - "tx_handlers_queued=%u\n" - "tx_handlers_drop_unencrypted=%u\n" - "tx_handlers_drop_fragment=%u\n" - "tx_handlers_drop_wep=%u\n" - "tx_handlers_drop_rate_limit=%u\n" - "tx_handlers_drop_not_assoc=%u\n" - "tx_handlers_drop_unauth_port=%u\n" - "rx_handlers_drop=%u\n" - "rx_handlers_queued=%u\n" - "rx_handlers_drop_nullfunc=%u\n" - "rx_handlers_drop_defrag=%u\n" - "rx_handlers_drop_short=%u\n" - "rx_handlers_drop_passive_scan=%u\n" - "tx_expand_skb_head=%u\n" - "tx_expand_skb_head_cloned=%u\n" - "rx_expand_skb_head=%u\n" - "rx_expand_skb_head2=%u\n" - "rx_handlers_fragments=%u\n" - "tx_status_drop=%u\n", - local->tx_handlers_drop, - local->tx_handlers_queued, - local->tx_handlers_drop_unencrypted, - local->tx_handlers_drop_fragment, - local->tx_handlers_drop_wep, - local->tx_handlers_drop_rate_limit, - local->tx_handlers_drop_not_assoc, - local->tx_handlers_drop_unauth_port, - local->rx_handlers_drop, - local->rx_handlers_queued, - local->rx_handlers_drop_nullfunc, - local->rx_handlers_drop_defrag, - local->rx_handlers_drop_short, - local->rx_handlers_drop_passive_scan, - local->tx_expand_skb_head, - local->tx_expand_skb_head_cloned, - local->rx_expand_skb_head, - local->rx_expand_skb_head2, - local->rx_handlers_fragments, - local->tx_status_drop); - { - int i; - p += sprintf(p, "wme_rx_queue="); - for (i = 0; i < NUM_RX_DATA_QUEUES; i++) - p += sprintf(p, " %u", local->wme_rx_queue[i]); - p += sprintf(p, "\n"); - - p += sprintf(p, "wme_tx_queue="); - for (i = 0; i < NUM_RX_DATA_QUEUES; i++) - p += sprintf(p, " %u", local->wme_tx_queue[i]); - p += sprintf(p, "\n"); - } -#endif /* CONFIG_IEEE80211_DEBUG_COUNTERS */ - - p += sprintf(p, "num_scans=%u\n", local->scan.num_scans); - - p += sprintf(p, - "conf.bss_count=%d\n" - "bss_dev_count=%u\n", - local->conf.bss_count, local->bss_dev_count); - for (i = 0; i < local->conf.bss_count; i++) { - p += sprintf(p, "bss_dev[%d]=%p (%s)\n", - i, local->bss_devs[i], - (i < local->bss_dev_count && local->bss_devs[i]) ? - local->bss_devs[i]->name : "N/A"); - } - - return (p - page); -} - - -static const char * ieee80211_mode_str_short(int mode) -{ - switch (mode) { - case MODE_IEEE80211A: - return "802.11a"; - case MODE_IEEE80211B: - return "802.11b"; - case MODE_IEEE80211G: - return "802.11g"; - case MODE_ATHEROS_TURBO: - return "AtherosTurbo"; - default: - return "UNKNOWN"; - } -} - - -static const char * ieee80211_mode_str(int mode) -{ - switch (mode) { - case MODE_IEEE80211A: - return "IEEE 802.11a"; - case MODE_IEEE80211B: - return "IEEE 802.11b"; - case MODE_IEEE80211G: - return "IEEE 802.11g"; - case MODE_ATHEROS_TURBO: - return "Atheros Turbo (5 GHz)"; - default: - return "UNKNOWN"; - } -} - - -static int ieee80211_proc_info_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ieee80211_local *local = (struct ieee80211_local *) data; - int m; - struct ieee80211_hw_modes *mode; - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "hw_name=%s\n", local->hw->name); - p += sprintf(p, "modes="); - for (m = 0; m < local->hw->num_modes; m++) { - mode = &local->hw->modes[m]; - p += sprintf(p, "[%s]", ieee80211_mode_str_short(mode->mode)); - } - p += sprintf(p, "\n"); - if (local->rate_ctrl && local->rate_ctrl_priv) - p+= sprintf(p, "rate_ctrl_alg=%s\n", local->rate_ctrl->name); - return (p - page); -} - - -static int ieee80211_proc_config_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ieee80211_local *local = (struct ieee80211_local *) data; - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, - "low_level_driver=%s\n" - "channel=%d\n" - "freq=%d\n" - "mode=%s\n" - "802.11h=%d\n" - "wep_iv=0x%06x\n" - "antenna_sel=%d\n" - "calib_int=%d\n" - "tx_power_reduction=%d.%d dBm\n" - "bridge_packets=%d\n" - "key_tx_rx_threshold=%d\n" - "rts_threshold=%d\n" - "fragmentation_threshold=%d\n" - "short_retry_limit=%d\n" - "long_retry_limit=%d\n" - "total_ps_buffered=%d\n", - local->hw->name ? local->hw->name : "N/A", - local->conf.channel, - local->conf.freq, - ieee80211_mode_str(local->conf.phymode), - local->conf.radar_detect, - local->wep_iv & 0xffffff, - local->conf.antenna_sel, - local->conf.calib_int, - local->conf.tx_power_reduction / 10, - local->conf.tx_power_reduction % 10, - local->bridge_packets, - local->key_tx_rx_threshold, - local->rts_threshold, - local->fragmentation_threshold, - local->short_retry_limit, - local->long_retry_limit, - local->total_ps_buffered); - - return (p - page); -} - - -static int ieee80211_proc_channels_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ieee80211_local *local = (struct ieee80211_local *) data; - int m, c; - struct ieee80211_hw_modes *mode; - struct ieee80211_channel *chan; - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "MODE CHAN FREQ TXPOWER ANTMAX FLAGS\n"); - for (m = 0; m < local->hw->num_modes; m++) { - mode = &local->hw->modes[m]; - for (c = 0; c < mode->num_channels; c++) { - chan = &mode->channels[c]; - p += sprintf(p, "%d %d %d %d %d %s%s%s\n", - mode->mode, chan->chan, chan->freq, - chan->power_level, chan->antenna_max, - chan->flag & IEEE80211_CHAN_W_SCAN ? - "[W_SCAN]" : "", - chan->flag & IEEE80211_CHAN_W_ACTIVE_SCAN - ? "[W_ACTIVE_SCAN]" : "", - chan->flag & IEEE80211_CHAN_W_IBSS ? - "[W_IBSS]" : ""); - } - } - return (p - page); -} - - -static int ieee80211_proc_rates_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ieee80211_local *local = (struct ieee80211_local *) data; - int r; - struct ieee80211_rate *rate; - - if (off != 0) { - *eof = 1; - return 0; - } - - p += sprintf(p, "RATE VAL VAL2 MIN_RSSI_ACK MIN_RSSI_ACK_DELTA " - "FLAGS\n"); - for (r = 0; r < local->num_curr_rates; r++) { - rate = &local->curr_rates[r]; - p += sprintf(p, "%d %d %d %d %d 0x%x %s%s%s%s%s%s%s%s\n", - rate->rate, rate->val, rate->val2, - rate->min_rssi_ack, rate->min_rssi_ack_delta, - rate->flags, - rate->flags & IEEE80211_RATE_ERP ? "[ERP]" : "", - rate->flags & IEEE80211_RATE_BASIC ? - "[BASIC]" : "", - rate->flags & IEEE80211_RATE_PREAMBLE2 ? - "[PREAMBLE2]" : "", - rate->flags & IEEE80211_RATE_SUPPORTED ? - "[SUPPORTED]" : "", - rate->flags & IEEE80211_RATE_OFDM ? "[OFDM]" : "", - rate->flags & IEEE80211_RATE_CCK ? "[CCK]" : "", - rate->flags & IEEE80211_RATE_TURBO ? - "[TURBO]" : "", - rate->flags & IEEE80211_RATE_MANDATORY ? - "[MANDATORY]" : ""); - } - return (p - page); -} - - -static int ieee80211_proc_multicast_read(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - char *p = page; - struct ieee80211_local *local = (struct ieee80211_local *) data; - - if (off != 0) { - *eof = 1; - return 0; - } - - return rate_control_status_global(local, p); - -} - - -void ieee80211_proc_init_sta(struct ieee80211_local *local, - struct sta_info *sta) -{ - char buf[30]; - struct proc_dir_entry *entry; - - sprintf(buf, MACSTR, MAC2STR(sta->addr)); - - if (!local->proc_sta) - return; - - entry = create_proc_read_entry(buf, 0, local->proc_sta, - ieee80211_proc_sta_read, sta); - if (entry) { - entry->mode &= ~(S_IRWXG | S_IRWXO); - sta->proc_entry_added = 1; - } -} - - -void ieee80211_proc_deinit_sta(struct ieee80211_local *local, - struct sta_info *sta) -{ - char buf[30]; - sprintf(buf, MACSTR, MAC2STR(sta->addr)); - if (local->proc_sta) { - remove_proc_entry(buf, local->proc_sta); - sta->proc_entry_added = 0; - } -} - - -void ieee80211_proc_init_virtual(struct net_device *dev) -{ - struct proc_dir_entry *entry; - struct ieee80211_local *local = (struct ieee80211_local *) dev->priv; - - if (!local->proc_iface) - return; - - entry = create_proc_read_entry(dev->name, 0, local->proc_iface, - ieee80211_proc_iface_read, dev); - if (entry) - entry->mode &= ~(S_IRWXG | S_IRWXO); -} - - -void ieee80211_proc_deinit_virtual(struct net_device *dev) -{ - struct ieee80211_local *local = (struct ieee80211_local *) dev->priv; - - if (local->proc_iface) - remove_proc_entry(dev->name, local->proc_iface); -} - - -void ieee80211_proc_init_interface(struct ieee80211_local *local) -{ - if (!ieee80211_proc) - return; - - local->proc = proc_mkdir(local->wdev->name, ieee80211_proc); - if (!local->proc) - return; - - local->proc_sta = proc_mkdir("sta", local->proc); - local->proc_iface = proc_mkdir("iface", local->proc); - create_proc_read_entry("counters", 0, local->proc, - ieee80211_proc_counters_read, local); - create_proc_read_entry("config", 0, local->proc, - ieee80211_proc_config_read, local); - create_proc_read_entry("channels", 0, local->proc, - ieee80211_proc_channels_read, local); - create_proc_read_entry("rates", 0, local->proc, - ieee80211_proc_rates_read, local); - create_proc_read_entry("multicast", 0, local->proc, - ieee80211_proc_multicast_read, local); - create_proc_read_entry("debug", 0, local->proc, - ieee80211_proc_debug_read, local); - create_proc_read_entry("info", 0, local->proc, - ieee80211_proc_info_read, local); - ieee80211_proc_init_virtual(local->wdev); -} - - -void ieee80211_proc_deinit_interface(struct ieee80211_local *local) -{ - if (!local->proc) - return; - - ieee80211_proc_deinit_virtual(local->wdev); - remove_proc_entry("iface", local->proc); - remove_proc_entry("sta", local->proc); - remove_proc_entry("counters", local->proc); - remove_proc_entry("debug", local->proc); - remove_proc_entry("config", local->proc); - remove_proc_entry("channels", local->proc); - remove_proc_entry("rates", local->proc); - remove_proc_entry("multicast", local->proc); - remove_proc_entry("info", local->proc); - local->proc = NULL; - remove_proc_entry(local->wdev->name, ieee80211_proc); -} - - -void ieee80211_proc_init(void) -{ - if (proc_net == NULL) { - ieee80211_proc = NULL; - return; - } - - ieee80211_proc = proc_mkdir("ieee80211", proc_net); - if (!ieee80211_proc) - printk(KERN_WARNING "Failed to mkdir /proc/net/ieee80211\n"); -} - - -void ieee80211_proc_deinit(void) -{ - if (!ieee80211_proc) - return; - - ieee80211_proc = NULL; - remove_proc_entry("ieee80211", proc_net); -} - -#endif /* CONFIG_PROC_FS */ diff --git a/target/linux/package/ieee80211-dscape/src/ieee80211_proc.h b/target/linux/package/ieee80211-dscape/src/ieee80211_proc.h deleted file mode 100644 index a8e49e9763..0000000000 --- a/target/linux/package/ieee80211-dscape/src/ieee80211_proc.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2003-2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef IEEE80211_PROC_H -#define IEEE80211_PROC_H - -#ifdef CONFIG_PROC_FS - -void ieee80211_proc_init_sta(struct ieee80211_local *local, - struct sta_info *sta); -void ieee80211_proc_deinit_sta(struct ieee80211_local *local, - struct sta_info *sta); -void ieee80211_proc_init_virtual(struct net_device *dev); -void ieee80211_proc_deinit_virtual(struct net_device *dev); -void ieee80211_proc_init_interface(struct ieee80211_local *local); -void ieee80211_proc_deinit_interface(struct ieee80211_local *local); -void ieee80211_proc_init(void); -void ieee80211_proc_deinit(void); - -#else /* CONFIG_PROC_FS */ - -static inline void ieee80211_proc_init_sta(struct ieee80211_local *local, - struct sta_info *sta) {} -static inline void ieee80211_proc_deinit_sta(struct ieee80211_local *local, - struct sta_info *sta) {} -static inline void ieee80211_proc_init_virtual(struct net_device *dev) {} -static inline void ieee80211_proc_deinit_virtual(struct net_device *dev) {} -static inline void -ieee80211_proc_init_interface(struct ieee80211_local *local) {} -static inline void -ieee80211_proc_deinit_interface(struct ieee80211_local *local) {} -static inline void ieee80211_proc_init(void) {} -static inline void ieee80211_proc_deinit(void) {} -#endif /* CONFIG_PROC_FS */ - -#endif /* IEEE80211_PROC_H */ diff --git a/target/linux/package/ieee80211-dscape/src/ieee80211_scan.c b/target/linux/package/ieee80211-dscape/src/ieee80211_scan.c deleted file mode 100644 index 7d4effe829..0000000000 --- a/target/linux/package/ieee80211-dscape/src/ieee80211_scan.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * Copyright 2002-2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include "ieee80211_i.h" -#include "rate_control.h" - - -/* Maximum number of seconds to wait for the traffic load to get below - * threshold before forcing a passive scan. */ -#define MAX_SCAN_WAIT 60 -/* Threshold (pkts/sec TX or RX) for delaying passive scan */ -#define SCAN_TXRX_THRESHOLD 75 - -static void get_channel_params(struct ieee80211_local *local, int channel, - struct ieee80211_hw_modes **mode, - struct ieee80211_channel **chan) -{ - int m; - - for (m = 0; m < local->hw->num_modes; m++) { - *mode = &local->hw->modes[m]; - if ((*mode)->mode == local->conf.phymode) - break; - } - local->scan.mode_idx = m; - local->scan.chan_idx = 0; - do { - *chan = &(*mode)->channels[local->scan.chan_idx]; - if ((*chan)->chan == channel) { - return; - } - local->scan.chan_idx++; - } while (local->scan.chan_idx < (*mode)->num_channels); - *chan = NULL; -} - - -static void next_chan_same_mode(struct ieee80211_local *local, - struct ieee80211_hw_modes **mode, - struct ieee80211_channel **chan) -{ - int m, prev; - - for (m = 0; m < local->hw->num_modes; m++) { - *mode = &local->hw->modes[m]; - if ((*mode)->mode == local->conf.phymode) - break; - } - local->scan.mode_idx = m; - - /* Select next channel - scan only channels marked with W_SCAN flag */ - prev = local->scan.chan_idx; - do { - local->scan.chan_idx++; - if (local->scan.chan_idx >= (*mode)->num_channels) - local->scan.chan_idx = 0; - *chan = &(*mode)->channels[local->scan.chan_idx]; - if ((*chan)->flag & IEEE80211_CHAN_W_SCAN) - break; - } while (local->scan.chan_idx != prev); -} - - -static void next_chan_all_modes(struct ieee80211_local *local, - struct ieee80211_hw_modes **mode, - struct ieee80211_channel **chan) -{ - int prev, prev_m; - - if (local->scan.mode_idx >= local->hw->num_modes) { - local->scan.mode_idx = 0; - local->scan.chan_idx = 0; - } - - /* Select next channel - scan only channels marked with W_SCAN flag */ - prev = local->scan.chan_idx; - prev_m = local->scan.mode_idx; - do { - *mode = &local->hw->modes[local->scan.mode_idx]; - local->scan.chan_idx++; - if (local->scan.chan_idx >= (*mode)->num_channels) { - local->scan.chan_idx = 0; - local->scan.mode_idx++; - if (local->scan.mode_idx >= local->hw->num_modes) - local->scan.mode_idx = 0; - *mode = &local->hw->modes[local->scan.mode_idx]; - } - *chan = &(*mode)->channels[local->scan.chan_idx]; - if ((*chan)->flag & IEEE80211_CHAN_W_SCAN) - break; - } while (local->scan.chan_idx != prev || - local->scan.mode_idx != prev_m); -} - - -static void ieee80211_scan_start(struct net_device *dev, - struct ieee80211_scan_conf *conf) -{ - struct ieee80211_local *local = dev->priv; - int old_mode_idx = local->scan.mode_idx; - int old_chan_idx = local->scan.chan_idx; - struct ieee80211_hw_modes *mode = NULL; - struct ieee80211_channel *chan = NULL; - int ret; - - if (local->hw->passive_scan == 0) { - printk(KERN_DEBUG "%s: Scan handler called, yet the hardware " - "does not support passive scanning. Disabled.\n", - dev->name); - return; - } - - if ((local->scan.tries < MAX_SCAN_WAIT && - local->scan.txrx_count > SCAN_TXRX_THRESHOLD)) { - local->scan.tries++; - /* Count TX/RX packets during one second interval and allow - * scan to start only if the number of packets is below the - * threshold. */ - local->scan.txrx_count = 0; - local->scan.timer.expires = jiffies + HZ; - add_timer(&local->scan.timer); - return; - } - - if (local->scan.skb == NULL) { - printk(KERN_DEBUG "%s: Scan start called even though scan.skb " - "is not set\n", dev->name); - } - - if (local->scan.our_mode_only) { - if (local->scan.channel > 0) { - get_channel_params(local, local->scan.channel, &mode, - &chan); - } else - next_chan_same_mode(local, &mode, &chan); - } - else - next_chan_all_modes(local, &mode, &chan); - - conf->scan_channel = chan->chan; - conf->scan_freq = chan->freq; - conf->scan_channel_val = chan->val; - conf->scan_phymode = mode->mode; - conf->scan_power_level = chan->power_level; - conf->scan_antenna_max = chan->antenna_max; - conf->scan_time = 2 * local->hw->channel_change_time + - local->scan.time; /* 10ms scan time+hardware changes */ - conf->skb = local->scan.skb ? - skb_clone(local->scan.skb, GFP_ATOMIC) : NULL; - conf->tx_control = &local->scan.tx_control; -#if 0 - printk(KERN_DEBUG "%s: Doing scan on mode: %d freq: %d chan: %d " - "for %d ms\n", - dev->name, conf->scan_phymode, conf->scan_freq, - conf->scan_channel, conf->scan_time); -#endif - local->scan.rx_packets = 0; - local->scan.rx_beacon = 0; - local->scan.freq = chan->freq; - local->scan.in_scan = 1; - - ieee80211_netif_oper(dev, NETIF_STOP); - - ret = local->hw->passive_scan(dev, IEEE80211_SCAN_START, conf); - - if (ret == 0) { - long usec = local->hw->channel_change_time + - local->scan.time; - usec += 1000000L / HZ - 1; - usec /= 1000000L / HZ; - local->scan.timer.expires = jiffies + usec; - } else { - local->scan.in_scan = 0; - if (conf->skb) - dev_kfree_skb(conf->skb); - ieee80211_netif_oper(dev, NETIF_WAKE); - if (ret == -EAGAIN) { - local->scan.timer.expires = jiffies + - (local->scan.interval * HZ / 100); - local->scan.mode_idx = old_mode_idx; - local->scan.chan_idx = old_chan_idx; - } else { - printk(KERN_DEBUG "%s: Got unknown error from " - "passive_scan %d\n", dev->name, ret); - local->scan.timer.expires = jiffies + - (local->scan.interval * HZ); - } - local->scan.in_scan = 0; - } - - add_timer(&local->scan.timer); -} - - -static void ieee80211_scan_stop(struct net_device *dev, - struct ieee80211_scan_conf *conf) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_hw_modes *mode; - struct ieee80211_channel *chan; - int wait; - - if (local->hw->passive_scan == NULL) - return; - - if (local->scan.mode_idx >= local->hw->num_modes) { - local->scan.mode_idx = 0; - local->scan.chan_idx = 0; - } - - mode = &local->hw->modes[local->scan.mode_idx]; - - if (local->scan.chan_idx >= mode->num_channels) { - local->scan.chan_idx = 0; - } - - chan = &mode->channels[local->scan.chan_idx]; - - local->hw->passive_scan(dev, IEEE80211_SCAN_END, conf); - -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Did scan on mode: %d freq: %d chan: %d " - "GOT: %d Beacon: %d (%d)\n", - dev->name, - mode->mode, chan->freq, chan->chan, - local->scan.rx_packets, local->scan.rx_beacon, - local->scan.tries); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - local->scan.num_scans++; - - local->scan.in_scan = 0; - ieee80211_netif_oper(dev, NETIF_WAKE); - - local->scan.tries = 0; - /* Use random interval of scan.interval .. 2 * scan.interval */ - wait = (local->scan.interval * HZ * ((net_random() & 127) + 128)) / - 128; - local->scan.timer.expires = jiffies + wait; - - add_timer(&local->scan.timer); -} - - -static void ieee80211_scan_handler(unsigned long uldev) -{ - struct net_device *dev = (struct net_device *) uldev; - struct ieee80211_local *local = dev->priv; - struct ieee80211_scan_conf conf; - - if (local->scan.interval == 0 && !local->scan.in_scan) { - /* Passive scanning is disabled - keep the timer always - * running to make code cleaner. */ - local->scan.timer.expires = jiffies + 10 * HZ; - add_timer(&local->scan.timer); - return; - } - - memset(&conf, 0, sizeof(struct ieee80211_scan_conf)); - conf.running_freq = local->conf.freq; - conf.running_channel = local->conf.channel; - conf.running_phymode = local->conf.phymode; - conf.running_channel_val = local->conf.channel_val; - conf.running_power_level = local->conf.power_level; - conf.running_antenna_max = local->conf.antenna_max; - - if (local->scan.in_scan == 0) - ieee80211_scan_start(dev, &conf); - else - ieee80211_scan_stop(dev, &conf); -} - - -void ieee80211_init_scan(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_hdr hdr; - u16 fc; - int len = 10; - struct rate_control_extra extra; - - /* Only initialize passive scanning if the hardware supports it */ - if (!local->hw->passive_scan) { - local->scan.skb = NULL; - memset(&local->scan.tx_control, 0, - sizeof(local->scan.tx_control)); - printk(KERN_DEBUG "%s: Does not support passive scan, " - "disabled\n", dev->name); - return; - } - - local->scan.interval = 0; - local->scan.our_mode_only = 1; - local->scan.time = 10000; - local->scan.timer.function = ieee80211_scan_handler; - local->scan.timer.data = (unsigned long) dev; - local->scan.timer.expires = jiffies + local->scan.interval * HZ; - add_timer(&local->scan.timer); - - /* Create a CTS from for broadcasting before - * the low level changes channels */ - local->scan.skb = alloc_skb(len, GFP_KERNEL); - if (local->scan.skb == NULL) { - printk(KERN_WARNING "%s: Failed to allocate CTS packet for " - "passive scan\n", dev->name); - return; - } - - fc = (WLAN_FC_TYPE_CTRL << 2) | (WLAN_FC_STYPE_CTS << 4); - hdr.frame_control = cpu_to_le16(fc); - hdr.duration_id = - cpu_to_le16(2 * local->hw->channel_change_time + - local->scan.time); - memcpy(hdr.addr1, dev->dev_addr, ETH_ALEN); /* DA */ - hdr.seq_ctrl = 0; - - memcpy(skb_put(local->scan.skb, len), &hdr, len); - - memset(&local->scan.tx_control, 0, sizeof(local->scan.tx_control)); - local->scan.tx_control.key_idx = HW_KEY_IDX_INVALID; - local->scan.tx_control.do_not_encrypt = 1; - memset(&extra, 0, sizeof(extra)); - extra.endidx = local->num_curr_rates; - local->scan.tx_control.tx_rate = - rate_control_get_rate(dev, local->scan.skb, &extra)->val; - local->scan.tx_control.no_ack = 1; -} - - -void ieee80211_stop_scan(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - - if (local->hw->passive_scan != 0) { - del_timer_sync(&local->scan.timer); - dev_kfree_skb(local->scan.skb); - local->scan.skb = NULL; - } -} diff --git a/target/linux/package/ieee80211-dscape/src/ieee80211_sta.c b/target/linux/package/ieee80211-dscape/src/ieee80211_sta.c deleted file mode 100644 index be73032354..0000000000 --- a/target/linux/package/ieee80211-dscape/src/ieee80211_sta.c +++ /dev/null @@ -1,2868 +0,0 @@ -/* - * BSS client mode implementation - * Copyright 2003, Jouni Malinen - * Copyright 2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -/* TODO: - * BSS table: use as the key to support multi-SSID APs - * order BSS list by RSSI(?) ("quality of AP") - * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, - * SSID) - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "ieee80211_i.h" -#include "rate_control.h" -#include "hostapd_ioctl.h" - -/* #define IEEE80211_IBSS_DEBUG */ - -#define IEEE80211_AUTH_TIMEOUT (HZ / 5) -#define IEEE80211_AUTH_MAX_TRIES 3 -#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) -#define IEEE80211_ASSOC_MAX_TRIES 3 -#define IEEE80211_MONITORING_INTERVAL (2 * HZ) -#define IEEE80211_PROBE_INTERVAL (60 * HZ) -#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ) -#define IEEE80211_SCAN_INTERVAL (2 * HZ) -#define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ) -#define IEEE80211_IBSS_JOIN_TIMEOUT (20 * HZ) - -#define IEEE80211_PROBE_DELAY (HZ / 33) -#define IEEE80211_CHANNEL_TIME (HZ / 33) -#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5) -#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ) -#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) -#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ) - -#define IEEE80211_IBSS_MAX_STA_ENTRIES 128 - - -#define IEEE80211_FC(type, stype) cpu_to_le16((type << 2) | (stype << 4)) - -#define ERP_INFO_USE_PROTECTION BIT(1) - -static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, - u8 *ssid, size_t ssid_len); -static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid); -static void ieee80211_rx_bss_put(struct net_device *dev, - struct ieee80211_sta_bss *bss); -static int ieee80211_sta_find_ibss(struct net_device *dev, - struct ieee80211_if_sta *ifsta); -static int ieee80211_sta_wep_configured(struct net_device *dev); - - -/* Parsed Information Elements */ -struct ieee802_11_elems { - u8 *ssid; - u8 ssid_len; - u8 *supp_rates; - u8 supp_rates_len; - u8 *fh_params; - u8 fh_params_len; - u8 *ds_params; - u8 ds_params_len; - u8 *cf_params; - u8 cf_params_len; - u8 *tim; - u8 tim_len; - u8 *ibss_params; - u8 ibss_params_len; - u8 *challenge; - u8 challenge_len; - u8 *wpa; - u8 wpa_len; - u8 *rsn; - u8 rsn_len; - u8 *erp_info; - u8 erp_info_len; - u8 *ext_supp_rates; - u8 ext_supp_rates_len; - u8 *wmm_info; - u8 wmm_info_len; - u8 *wmm_param; - u8 wmm_param_len; -}; - -typedef enum { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 } ParseRes; - - -static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, - struct ieee802_11_elems *elems) -{ - size_t left = len; - u8 *pos = start; - int unknown = 0; - - memset(elems, 0, sizeof(*elems)); - - while (left >= 2) { - u8 id, elen; - - id = *pos++; - elen = *pos++; - left -= 2; - - if (elen > left) { -#if 0 - if (net_ratelimit()) - printk(KERN_DEBUG "IEEE 802.11 element parse " - "failed (id=%d elen=%d left=%d)\n", - id, elen, left); -#endif - return ParseFailed; - } - - switch (id) { - case WLAN_EID_SSID: - elems->ssid = pos; - elems->ssid_len = elen; - break; - case WLAN_EID_SUPP_RATES: - elems->supp_rates = pos; - elems->supp_rates_len = elen; - break; - case WLAN_EID_FH_PARAMS: - elems->fh_params = pos; - elems->fh_params_len = elen; - break; - case WLAN_EID_DS_PARAMS: - elems->ds_params = pos; - elems->ds_params_len = elen; - break; - case WLAN_EID_CF_PARAMS: - elems->cf_params = pos; - elems->cf_params_len = elen; - break; - case WLAN_EID_TIM: - elems->tim = pos; - elems->tim_len = elen; - break; - case WLAN_EID_IBSS_PARAMS: - elems->ibss_params = pos; - elems->ibss_params_len = elen; - break; - case WLAN_EID_CHALLENGE: - elems->challenge = pos; - elems->challenge_len = elen; - break; - case WLAN_EID_WPA: - if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && - pos[2] == 0xf2) { - /* Microsoft OUI (00:50:F2) */ - if (pos[3] == 1) { - /* OUI Type 1 - WPA IE */ - elems->wpa = pos; - elems->wpa_len = elen; - } else if (elen >= 5 && pos[3] == 2) { - if (pos[4] == 0) { - elems->wmm_info = pos; - elems->wmm_info_len = elen; - } else if (pos[4] == 1) { - elems->wmm_param = pos; - elems->wmm_param_len = elen; - } - } - } - break; - case WLAN_EID_RSN: - elems->rsn = pos; - elems->rsn_len = elen; - break; - case WLAN_EID_ERP_INFO: - elems->erp_info = pos; - elems->erp_info_len = elen; - break; - case WLAN_EID_EXT_SUPP_RATES: - elems->ext_supp_rates = pos; - elems->ext_supp_rates_len = elen; - break; - default: -#if 0 - printk(KERN_DEBUG "IEEE 802.11 element parse ignored " - "unknown element (id=%d elen=%d)\n", - id, elen); -#endif - unknown++; - break; - } - - left -= elen; - pos += elen; - } - - if (left) - return ParseFailed; - - return unknown ? ParseUnknown : ParseOK; -} - - - - -static int ecw2cw(int ecw) -{ - int cw = 1; - while (ecw > 0) { - cw <<= 1; - ecw--; - } - return cw - 1; -} - - -static void ieee80211_sta_wmm_params(struct net_device *dev, - struct ieee80211_if_sta *ifsta, - u8 *wmm_param, size_t wmm_param_len) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_tx_queue_params params; - size_t left; - int count; - u8 *pos; - - if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) - return; - count = wmm_param[6] & 0x0f; - if (count == ifsta->wmm_last_param_set) - return; - ifsta->wmm_last_param_set = count; - - pos = wmm_param + 8; - left = wmm_param_len - 8; - - memset(¶ms, 0, sizeof(params)); - - if (local->hw->conf_tx == NULL) - return; - - local->wmm_acm = 0; - for (; left >= 4; left -= 4, pos += 4) { - int aci = (pos[0] >> 5) & 0x03; - int acm = (pos[0] >> 4) & 0x01; - int queue; - - switch (aci) { - case 1: - queue = IEEE80211_TX_QUEUE_DATA3; - if (acm) { - local->wmm_acm |= BIT(1) | BIT(2); - } - break; - case 2: - queue = IEEE80211_TX_QUEUE_DATA1; - if (acm) { - local->wmm_acm |= BIT(4) | BIT(5); - } - break; - case 3: - queue = IEEE80211_TX_QUEUE_DATA0; - if (acm) { - local->wmm_acm |= BIT(6) | BIT(7); - } - break; - case 0: - default: - queue = IEEE80211_TX_QUEUE_DATA2; - if (acm) { - local->wmm_acm |= BIT(0) | BIT(3); - } - break; - } - - params.aifs = pos[0] & 0x0f; - params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); - params.cw_min = ecw2cw(pos[1] & 0x0f); - /* TXOP is in units of 32 usec; burst_time in 0.1 ms */ - params.burst_time = (pos[2] | (pos[3] << 8)) * 32 / 100; - printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " - "cWmin=%d cWmax=%d burst=%d\n", - dev->name, queue, aci, acm, params.aifs, params.cw_min, - params.cw_max, params.burst_time); - /* TODO: handle ACM (block TX, fallback to next lowest allowed - * AC for now) */ - if (local->hw->conf_tx(local->mdev, queue, ¶ms)) { - printk(KERN_DEBUG "%s: failed to set TX queue " - "parameters for queue %d\n", dev->name, queue); - } - } -} - - -static void ieee80211_sta_send_associnfo(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - char *buf; - size_t len; - int i; - union iwreq_data wrqu; - - if (ifsta->assocreq_ies == NULL && ifsta->assocresp_ies == NULL) - return; - - buf = kmalloc(50 + 2 * (ifsta->assocreq_ies_len + - ifsta->assocresp_ies_len), GFP_ATOMIC); - if (buf == NULL) - return; - - len = sprintf(buf, "ASSOCINFO("); - if (ifsta->assocreq_ies) { - len += sprintf(buf + len, "ReqIEs="); - for (i = 0; i < ifsta->assocreq_ies_len; i++) { - len += sprintf(buf + len, "%02x", - ifsta->assocreq_ies[i]); - } - } - if (ifsta->assocresp_ies) { - if (ifsta->assocreq_ies) - len += sprintf(buf + len, " "); - len += sprintf(buf + len, "RespIEs="); - for (i = 0; i < ifsta->assocresp_ies_len; i++) { - len += sprintf(buf + len, "%02x", - ifsta->assocresp_ies[i]); - } - } - len += sprintf(buf + len, ")"); - - if (len > IW_CUSTOM_MAX) { - len = sprintf(buf, "ASSOCRESPIE="); - for (i = 0; i < ifsta->assocresp_ies_len; i++) { - len += sprintf(buf + len, "%02x", - ifsta->assocresp_ies[i]); - } - } - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = len; - wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); - - kfree(buf); -} - - -static void ieee80211_set_associated(struct net_device *dev, - struct ieee80211_if_sta *ifsta, int assoc) -{ - union iwreq_data wrqu; - - if (ifsta->associated == assoc) - return; - - ifsta->associated = assoc; - - if (assoc) { - struct ieee80211_sub_if_data *sdata; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - return; - ifsta->prev_bssid_set = 1; - memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); - memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); - ieee80211_sta_send_associnfo(dev, ifsta); - } else { - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - } - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); - ifsta->last_probe = jiffies; -} - - -static void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, - int encrypt, int probe_resp) -{ - struct ieee80211_sub_if_data *sdata; - struct ieee80211_tx_packet_data *pkt_data; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - skb->dev = sdata->master; - skb->mac.raw = skb->nh.raw = skb->h.raw = skb->data; - - pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; - memset(pkt_data, 0, sizeof(struct ieee80211_tx_packet_data)); - pkt_data->magic = IEEE80211_CB_MAGIC; - pkt_data->sdata = sdata; - pkt_data->control.do_not_encrypt = !encrypt; - if (probe_resp) - pkt_data->control.pkt_type = PKT_PROBE_RESP; - - dev_queue_xmit(skb); -} - - -static void ieee80211_send_auth(struct net_device *dev, - struct ieee80211_if_sta *ifsta, - int transaction, u8 *extra, size_t extra_len, - int encrypt) -{ - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; - - skb = dev_alloc_skb(sizeof(*mgmt) + 6 + extra_len); - if (skb == NULL) { - printk(KERN_DEBUG "%s: failed to allocate buffer for auth " - "frame\n", dev->name); - return; - } - - mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); - memset(mgmt, 0, 24 + 6); - mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, - WLAN_FC_STYPE_AUTH); - if (encrypt) - mgmt->frame_control |= cpu_to_le16(WLAN_FC_ISWEP); - memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); - memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); - memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); - mgmt->u.auth.auth_alg = cpu_to_le16(ifsta->auth_alg); - mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); - ifsta->auth_transaction = transaction + 1; - mgmt->u.auth.status_code = cpu_to_le16(0); - if (extra) - memcpy(skb_put(skb, extra_len), extra, extra_len); - - ieee80211_sta_tx(dev, skb, encrypt, 0); -} - - -static void ieee80211_authenticate(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - ifsta->auth_tries++; - if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) { - printk(KERN_DEBUG "%s: authentication with AP " MACSTR - " timed out\n", - dev->name, MAC2STR(ifsta->bssid)); - return; - } - - ifsta->state = IEEE80211_AUTHENTICATE; - printk(KERN_DEBUG "%s: authenticate with AP " MACSTR "\n", - dev->name, MAC2STR(ifsta->bssid)); - - ieee80211_send_auth(dev, ifsta, 1, NULL, 0, 0); - - mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT); -} - - -static void ieee80211_send_assoc(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - struct ieee80211_local *local = dev->priv; - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; - u8 *pos, *ies; - int i, len; - u16 capab; - struct ieee80211_sta_bss *bss; - int wmm = 0; - - skb = dev_alloc_skb(sizeof(*mgmt) + 200 + ifsta->extra_ie_len + - ifsta->ssid_len); - if (skb == NULL) { - printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " - "frame\n", dev->name); - return; - } - - capab = ifsta->capab; - if (local->conf.phymode == MODE_IEEE80211G) { - capab |= WLAN_CAPABILITY_SHORT_SLOT_TIME | - WLAN_CAPABILITY_SHORT_PREAMBLE; - } - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); - if (bss) { - if (bss->capability & WLAN_CAPABILITY_PRIVACY) - capab |= WLAN_CAPABILITY_PRIVACY; - if (bss->wmm_ie) { - wmm = 1; - } - ieee80211_rx_bss_put(dev, bss); - } - - mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); - memset(mgmt, 0, 24); - memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); - memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); - memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); - - if (ifsta->prev_bssid_set) { - skb_put(skb, 10); - mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, - WLAN_FC_STYPE_REASSOC_REQ); - mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab); - mgmt->u.reassoc_req.listen_interval = cpu_to_le16(1); - memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid, - ETH_ALEN); - } else { - skb_put(skb, 4); - mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, - WLAN_FC_STYPE_ASSOC_REQ); - mgmt->u.assoc_req.capab_info = cpu_to_le16(capab); - mgmt->u.assoc_req.listen_interval = cpu_to_le16(1); - } - - /* SSID */ - ies = pos = skb_put(skb, 2 + ifsta->ssid_len); - *pos++ = WLAN_EID_SSID; - *pos++ = ifsta->ssid_len; - memcpy(pos, ifsta->ssid, ifsta->ssid_len); - - len = local->num_curr_rates; - if (len > 8) - len = 8; - pos = skb_put(skb, len + 2); - *pos++ = WLAN_EID_SUPP_RATES; - *pos++ = len; - for (i = 0; i < len; i++) { - int rate = local->curr_rates[i].rate; - if (local->conf.phymode == MODE_ATHEROS_TURBO) - rate /= 2; - *pos++ = (u8) (rate / 5); - } - - if (local->num_curr_rates > len) { - pos = skb_put(skb, local->num_curr_rates - len + 2); - *pos++ = WLAN_EID_EXT_SUPP_RATES; - *pos++ = local->num_curr_rates - len; - for (i = len; i < local->num_curr_rates; i++) { - int rate = local->curr_rates[i].rate; - if (local->conf.phymode == MODE_ATHEROS_TURBO) - rate /= 2; - *pos++ = (u8) (rate / 5); - } - } - - if (ifsta->extra_ie) { - pos = skb_put(skb, ifsta->extra_ie_len); - memcpy(pos, ifsta->extra_ie, ifsta->extra_ie_len); - } - - if (wmm && ifsta->wmm_enabled) { - pos = skb_put(skb, 9); - *pos++ = WLAN_EID_VENDOR_SPECIFIC; - *pos++ = 7; /* len */ - *pos++ = 0x00; /* Microsoft OUI 00:50:F2 */ - *pos++ = 0x50; - *pos++ = 0xf2; - *pos++ = 2; /* WME */ - *pos++ = 0; /* WME info */ - *pos++ = 1; /* WME ver */ - *pos++ = 0; - } - - kfree(ifsta->assocreq_ies); - ifsta->assocreq_ies_len = (skb->data + skb->len) - ies; - ifsta->assocreq_ies = kmalloc(ifsta->assocreq_ies_len, GFP_ATOMIC); - if (ifsta->assocreq_ies) - memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len); - - ieee80211_sta_tx(dev, skb, 0, 0); -} - - -static void ieee80211_send_deauth(struct net_device *dev, - struct ieee80211_if_sta *ifsta, u16 reason) -{ - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; - - skb = dev_alloc_skb(sizeof(*mgmt)); - if (skb == NULL) { - printk(KERN_DEBUG "%s: failed to allocate buffer for deauth " - "frame\n", dev->name); - return; - } - - mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); - memset(mgmt, 0, 24); - memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); - memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); - memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); - mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, - WLAN_FC_STYPE_DEAUTH); - skb_put(skb, 2); - mgmt->u.deauth.reason_code = cpu_to_le16(reason); - - ieee80211_sta_tx(dev, skb, 0, 0); -} - - -static void ieee80211_send_disassoc(struct net_device *dev, - struct ieee80211_if_sta *ifsta, u16 reason) -{ - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; - - skb = dev_alloc_skb(sizeof(*mgmt)); - if (skb == NULL) { - printk(KERN_DEBUG "%s: failed to allocate buffer for disassoc " - "frame\n", dev->name); - return; - } - - mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); - memset(mgmt, 0, 24); - memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); - memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); - memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); - mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, - WLAN_FC_STYPE_DISASSOC); - skb_put(skb, 2); - mgmt->u.disassoc.reason_code = cpu_to_le16(reason); - - ieee80211_sta_tx(dev, skb, 0, 0); -} - - -static int ieee80211_privacy_mismatch(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - struct ieee80211_sta_bss *bss; - int res = 0; - - if (ifsta == NULL || ifsta->mixed_cell || - ifsta->key_mgmt != IEEE80211_KEY_MGMT_NONE) - return 0; - - bss = ieee80211_rx_bss_get(dev, ifsta->bssid); - if (bss == NULL) - return 0; - - if (ieee80211_sta_wep_configured(dev) != - !!(bss->capability & WLAN_CAPABILITY_PRIVACY)) - res = 1; - - ieee80211_rx_bss_put(dev, bss); - - return res; -} - - -static void ieee80211_associate(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - ifsta->assoc_tries++; - if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { - printk(KERN_DEBUG "%s: association with AP " MACSTR - " timed out\n", - dev->name, MAC2STR(ifsta->bssid)); - return; - } - - ifsta->state = IEEE80211_ASSOCIATE; - printk(KERN_DEBUG "%s: associate with AP " MACSTR "\n", - dev->name, MAC2STR(ifsta->bssid)); - if (ieee80211_privacy_mismatch(dev, ifsta)) { - printk(KERN_DEBUG "%s: mismatch in privacy configuration and " - "mixed-cell disabled - abort association\n", dev->name); - return; - } - - ieee80211_send_assoc(dev, ifsta); - - mod_timer(&ifsta->timer, jiffies + IEEE80211_ASSOC_TIMEOUT); -} - - -static void ieee80211_associated(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - int disassoc; - - /* TODO: start monitoring current AP signal quality and number of - * missed beacons. Scan other channels every now and then and search - * for better APs. */ - /* TODO: remove expired BSSes */ - - ifsta->state = IEEE80211_ASSOCIATED; - - sta = sta_info_get(local, ifsta->bssid); - if (sta == NULL) { - printk(KERN_DEBUG "%s: No STA entry for own AP " MACSTR "\n", - dev->name, MAC2STR(ifsta->bssid)); - disassoc = 1; - } else { - disassoc = 0; - if (time_after(jiffies, - sta->last_rx + IEEE80211_MONITORING_INTERVAL)) { - if (ifsta->probereq_poll) { - printk(KERN_DEBUG "%s: No ProbeResp from " - "current AP " MACSTR " - assume out of " - "range\n", - dev->name, MAC2STR(ifsta->bssid)); - disassoc = 1; - } else { - ieee80211_send_probe_req(dev, ifsta->bssid, - local->scan_ssid, - local->scan_ssid_len); - ifsta->probereq_poll = 1; - } - } else { - ifsta->probereq_poll = 0; - if (time_after(jiffies, ifsta->last_probe + - IEEE80211_PROBE_INTERVAL)) { - ifsta->last_probe = jiffies; - ieee80211_send_probe_req(dev, ifsta->bssid, - ifsta->ssid, - ifsta->ssid_len); - } - } - sta_info_release(local, sta); - } - if (disassoc) { - union iwreq_data wrqu; - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); - mod_timer(&ifsta->timer, - jiffies + IEEE80211_MONITORING_INTERVAL + 30 * HZ); - } else { - mod_timer(&ifsta->timer, - jiffies + IEEE80211_MONITORING_INTERVAL); - } -} - - -static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, - u8 *ssid, size_t ssid_len) -{ - struct ieee80211_local *local = dev->priv; - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; - u8 *pos, *supp_rates, *esupp_rates = NULL; - int i; - - skb = dev_alloc_skb(sizeof(*mgmt) + 200); - if (skb == NULL) { - printk(KERN_DEBUG "%s: failed to allocate buffer for probe " - "request\n", dev->name); - return; - } - - mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); - memset(mgmt, 0, 24); - mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, - WLAN_FC_STYPE_PROBE_REQ); - memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); - if (dst) { - memcpy(mgmt->da, dst, ETH_ALEN); - memcpy(mgmt->bssid, dst, ETH_ALEN); - } else { - memset(mgmt->da, 0xff, ETH_ALEN); - memset(mgmt->bssid, 0xff, ETH_ALEN); - } - pos = skb_put(skb, 2 + ssid_len); - *pos++ = WLAN_EID_SSID; - *pos++ = ssid_len; - memcpy(pos, ssid, ssid_len); - - supp_rates = skb_put(skb, 2); - supp_rates[0] = WLAN_EID_SUPP_RATES; - supp_rates[1] = 0; - for (i = 0; i < local->num_curr_rates; i++) { - struct ieee80211_rate *rate = &local->curr_rates[i]; - if (!(rate->flags & IEEE80211_RATE_SUPPORTED)) - continue; - if (esupp_rates) { - pos = skb_put(skb, 1); - esupp_rates[1]++; - } else if (supp_rates[1] == 8) { - esupp_rates = skb_put(skb, 3); - esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES; - esupp_rates[1] = 1; - pos = &esupp_rates[2]; - } else { - pos = skb_put(skb, 1); - supp_rates[1]++; - } - if (local->conf.phymode == MODE_ATHEROS_TURBO) - *pos = rate->rate / 10; - else - *pos = rate->rate / 5; - } - - ieee80211_sta_tx(dev, skb, 0, 0); -} - - -static int ieee80211_sta_wep_configured(struct net_device *dev) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata == NULL || sdata->default_key == NULL || - sdata->default_key->alg != ALG_WEP) - return 0; - return 1; -} - - -static void ieee80211_auth_completed(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - printk(KERN_DEBUG "%s: authenticated\n", dev->name); - ifsta->authenticated = 1; - ieee80211_associate(dev, ifsta); -} - - -static void ieee80211_auth_challenge(struct net_device *dev, - struct ieee80211_if_sta *ifsta, - struct ieee80211_mgmt *mgmt, - size_t len, - struct ieee80211_rx_status *rx_status) -{ - u8 *pos; - struct ieee802_11_elems elems; - - printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); - pos = mgmt->u.auth.variable; - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { - printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n", - dev->name); - return; - } - if (elems.challenge == NULL) { - printk(KERN_DEBUG "%s: no challenge IE in shared key auth " - "frame\n", dev->name); - return; - } - ieee80211_send_auth(dev, ifsta, 3, elems.challenge - 2, - elems.challenge_len + 2, 1); -} - - -static void ieee80211_rx_mgmt_auth(struct net_device *dev, - struct ieee80211_if_sta *ifsta, - struct ieee80211_mgmt *mgmt, - size_t len, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_local *local = dev->priv; - u16 auth_alg, auth_transaction, status_code; - - if (ifsta->state != IEEE80211_AUTHENTICATE && - local->conf.mode != IW_MODE_ADHOC) { - printk(KERN_DEBUG "%s: authentication frame received from " - MACSTR ", but not in authenticate state - ignored\n", - dev->name, MAC2STR(mgmt->sa)); - return; - } - - if (len < 24 + 6) { - printk(KERN_DEBUG "%s: too short (%zd) authentication frame " - "received from " MACSTR " - ignored\n", - dev->name, len, MAC2STR(mgmt->sa)); - return; - } - - if (local->conf.mode != IW_MODE_ADHOC && - memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { - printk(KERN_DEBUG "%s: authentication frame received from " - "unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - " - "ignored\n", dev->name, MAC2STR(mgmt->sa), - MAC2STR(mgmt->bssid)); - return; - } - - if (local->conf.mode == IW_MODE_ADHOC && - memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) { - printk(KERN_DEBUG "%s: authentication frame received from " - "unknown BSSID (SA=" MACSTR " BSSID=" MACSTR ") - " - "ignored\n", dev->name, MAC2STR(mgmt->sa), - MAC2STR(mgmt->bssid)); - return; - } - - auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); - auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); - status_code = le16_to_cpu(mgmt->u.auth.status_code); - - printk(KERN_DEBUG "%s: RX authentication from " MACSTR " (alg=%d " - "transaction=%d status=%d)\n", - dev->name, MAC2STR(mgmt->sa), auth_alg, - auth_transaction, status_code); - - if (local->conf.mode == IW_MODE_ADHOC) { - /* IEEE 802.11 standard does not require authentication in IBSS - * networks and most implementations do not seem to use it. - * However, try to reply to authentication attempts if someone - * has actually implemented this. - * TODO: Could implement shared key authentication. */ - if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) { - printk(KERN_DEBUG "%s: unexpected IBSS authentication " - "frame (alg=%d transaction=%d)\n", - dev->name, auth_alg, auth_transaction); - return; - } - ieee80211_send_auth(dev, ifsta, 2, NULL, 0, 0); - } - - if (auth_alg != ifsta->auth_alg || - auth_transaction != ifsta->auth_transaction) { - printk(KERN_DEBUG "%s: unexpected authentication frame " - "(alg=%d transaction=%d)\n", - dev->name, auth_alg, auth_transaction); - return; - } - - if (status_code != WLAN_STATUS_SUCCESS) { - printk(KERN_DEBUG "%s: AP denied authentication (auth_alg=%d " - "code=%d)\n", dev->name, ifsta->auth_alg, status_code); - if (status_code == WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG) { - const int num_algs = 3; - u8 algs[num_algs]; - int i, pos; - algs[0] = algs[1] = algs[2] = 0xff; - if (ifsta->auth_algs & IEEE80211_AUTH_ALG_OPEN) - algs[0] = WLAN_AUTH_OPEN; - if (ifsta->auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY) - algs[1] = WLAN_AUTH_SHARED_KEY; - if (ifsta->auth_algs & IEEE80211_AUTH_ALG_LEAP) - algs[2] = WLAN_AUTH_LEAP; - if (ifsta->auth_alg == WLAN_AUTH_OPEN) - pos = 0; - else if (ifsta->auth_alg == WLAN_AUTH_SHARED_KEY) - pos = 1; - else - pos = 2; - for (i = 0; i < num_algs; i++) { - pos++; - if (pos >= num_algs) - pos = 0; - if (algs[pos] == ifsta->auth_alg || - algs[pos] == 0xff) - continue; - if (algs[pos] == WLAN_AUTH_SHARED_KEY && - !ieee80211_sta_wep_configured(dev)) - continue; - ifsta->auth_alg = algs[pos]; - printk(KERN_DEBUG "%s: set auth_alg=%d for " - "next try\n", - dev->name, ifsta->auth_alg); - break; - } - } - return; - } - - switch (ifsta->auth_alg) { - case WLAN_AUTH_OPEN: - case WLAN_AUTH_LEAP: - ieee80211_auth_completed(dev, ifsta); - break; - case WLAN_AUTH_SHARED_KEY: - if (ifsta->auth_transaction == 4) - ieee80211_auth_completed(dev, ifsta); - else - ieee80211_auth_challenge(dev, ifsta, mgmt, len, - rx_status); - break; - } -} - - -static void ieee80211_rx_mgmt_deauth(struct net_device *dev, - struct ieee80211_if_sta *ifsta, - struct ieee80211_mgmt *mgmt, - size_t len, - struct ieee80211_rx_status *rx_status) -{ - u16 reason_code; - - if (len < 24 + 2) { - printk(KERN_DEBUG "%s: too short (%zd) deauthentication frame " - "received from " MACSTR " - ignored\n", - dev->name, len, MAC2STR(mgmt->sa)); - return; - } - - if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { - printk(KERN_DEBUG "%s: deauthentication frame received from " - "unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - " - "ignored\n", dev->name, MAC2STR(mgmt->sa), - MAC2STR(mgmt->bssid)); - return; - } - - reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); - - printk(KERN_DEBUG "%s: RX deauthentication from " MACSTR - " (reason=%d)\n", - dev->name, MAC2STR(mgmt->sa), reason_code); - - if (ifsta->authenticated) { - printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); - } - - if (ifsta->state == IEEE80211_AUTHENTICATE || - ifsta->state == IEEE80211_ASSOCIATE || - ifsta->state == IEEE80211_ASSOCIATED) { - ifsta->state = IEEE80211_AUTHENTICATE; - mod_timer(&ifsta->timer, - jiffies + IEEE80211_RETRY_AUTH_INTERVAL); - } - - ieee80211_set_associated(dev, ifsta, 0); - ifsta->authenticated = 0; -} - - -static void ieee80211_rx_mgmt_disassoc(struct net_device *dev, - struct ieee80211_if_sta *ifsta, - struct ieee80211_mgmt *mgmt, - size_t len, - struct ieee80211_rx_status *rx_status) -{ - u16 reason_code; - - if (len < 24 + 2) { - printk(KERN_DEBUG "%s: too short (%zd) disassociation frame " - "received from " MACSTR " - ignored\n", - dev->name, len, MAC2STR(mgmt->sa)); - return; - } - - if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { - printk(KERN_DEBUG "%s: disassociation frame received from " - "unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - " - "ignored\n", dev->name, MAC2STR(mgmt->sa), - MAC2STR(mgmt->bssid)); - return; - } - - reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); - - printk(KERN_DEBUG "%s: RX disassociation from " MACSTR - " (reason=%d)\n", - dev->name, MAC2STR(mgmt->sa), reason_code); - - if (ifsta->associated) - printk(KERN_DEBUG "%s: disassociated\n", dev->name); - - if (ifsta->state == IEEE80211_ASSOCIATED) { - ifsta->state = IEEE80211_ASSOCIATE; - mod_timer(&ifsta->timer, - jiffies + IEEE80211_RETRY_AUTH_INTERVAL); - } - - ieee80211_set_associated(dev, ifsta, 0); -} - - -static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, - struct ieee80211_if_sta *ifsta, - struct ieee80211_mgmt *mgmt, - size_t len, - struct ieee80211_rx_status *rx_status, - int reassoc) -{ - struct ieee80211_local *local = dev->priv; - struct sta_info *sta; - u32 rates; - u16 capab_info, status_code, aid; - struct ieee802_11_elems elems; - u8 *pos; - int i, j; - - /* AssocResp and ReassocResp have identical structure, so process both - * of them in this function. */ - - if (ifsta->state != IEEE80211_ASSOCIATE) { - printk(KERN_DEBUG "%s: association frame received from " - MACSTR ", but not in associate state - ignored\n", - dev->name, MAC2STR(mgmt->sa)); - return; - } - - if (len < 24 + 6) { - printk(KERN_DEBUG "%s: too short (%zd) association frame " - "received from " MACSTR " - ignored\n", - dev->name, len, MAC2STR(mgmt->sa)); - return; - } - - if (memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) { - printk(KERN_DEBUG "%s: association frame received from " - "unknown AP (SA=" MACSTR " BSSID=" MACSTR ") - " - "ignored\n", dev->name, MAC2STR(mgmt->sa), - MAC2STR(mgmt->bssid)); - return; - } - - capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); - status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); - aid = le16_to_cpu(mgmt->u.assoc_resp.aid); - if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) - printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " - "set\n", dev->name, aid); - aid &= ~(BIT(15) | BIT(14)); - - printk(KERN_DEBUG "%s: RX %sssocResp from " MACSTR " (capab=0x%x " - "status=%d aid=%d)\n", - dev->name, reassoc ? "Rea" : "A", MAC2STR(mgmt->sa), - capab_info, status_code, aid); - - if (status_code != WLAN_STATUS_SUCCESS) { - printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", - dev->name, status_code); - return; - } - - pos = mgmt->u.assoc_resp.variable; - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { - printk(KERN_DEBUG "%s: failed to parse AssocResp\n", - dev->name); - return; - } - - if (elems.supp_rates == NULL) { - printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", - dev->name); - return; - } - - printk(KERN_DEBUG "%s: associated\n", dev->name); - ifsta->aid = aid; - ifsta->ap_capab = capab_info; - - kfree(ifsta->assocresp_ies); - ifsta->assocresp_ies_len = len - (pos - (u8 *) mgmt); - ifsta->assocresp_ies = kmalloc(ifsta->assocresp_ies_len, GFP_ATOMIC); - if (ifsta->assocresp_ies) - memcpy(ifsta->assocresp_ies, pos, ifsta->assocresp_ies_len); - - ieee80211_set_associated(dev, ifsta, 1); - - /* Add STA entry for the AP */ - sta = sta_info_get(local, ifsta->bssid); - if (sta == NULL) { - sta = sta_info_add(local, dev, ifsta->bssid); - if (sta == NULL) { - printk(KERN_DEBUG "%s: failed to add STA entry for the" - " AP\n", dev->name); - return; - } - } - - sta->dev = dev; - sta->flags |= WLAN_STA_AUTH | WLAN_STA_ASSOC; - sta->assoc_ap = 1; - - rates = 0; - for (i = 0; i < elems.supp_rates_len; i++) { - int rate = (elems.supp_rates[i] & 0x7f) * 5; - if (local->conf.phymode == MODE_ATHEROS_TURBO) - rate *= 2; - for (j = 0; j < local->num_curr_rates; j++) - if (local->curr_rates[j].rate == rate) - rates |= BIT(j); - } - for (i = 0; i < elems.ext_supp_rates_len; i++) { - int rate = (elems.ext_supp_rates[i] & 0x7f) * 5; - if (local->conf.phymode == MODE_ATHEROS_TURBO) - rate *= 2; - for (j = 0; j < local->num_curr_rates; j++) - if (local->curr_rates[j].rate == rate) - rates |= BIT(j); - } - sta->supp_rates = rates; - - rate_control_rate_init(local, sta); - - if (elems.wmm_param && ifsta->wmm_enabled) { - sta->flags |= WLAN_STA_WME; - ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, - elems.wmm_param_len); - } - - - sta_info_release(local, sta); - - ieee80211_associated(dev, ifsta); -} - - -/* Caller must hold local->sta_bss_lock */ -static void __ieee80211_rx_bss_hash_add(struct net_device *dev, - struct ieee80211_sta_bss *bss) -{ - struct ieee80211_local *local = dev->priv; - bss->hnext = local->sta_bss_hash[STA_HASH(bss->bssid)]; - local->sta_bss_hash[STA_HASH(bss->bssid)] = bss; -} - - -/* Caller must hold local->sta_bss_lock */ -static void __ieee80211_rx_bss_hash_del(struct net_device *dev, - struct ieee80211_sta_bss *bss) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sta_bss *b, *prev = NULL; - b = local->sta_bss_hash[STA_HASH(bss->bssid)]; - while (b) { - if (b == bss) { - if (prev == NULL) { - local->sta_bss_hash[STA_HASH(bss->bssid)] = - bss->hnext; - } else { - prev->hnext = bss->hnext; - } - break; - } - prev = b; - b = b->hnext; - } -} - - -static struct ieee80211_sta_bss * -ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sta_bss *bss; - - bss = kmalloc(sizeof(*bss), GFP_ATOMIC); - if (bss == NULL) - return NULL; - memset(bss, 0, sizeof(*bss)); - atomic_inc(&bss->users); - atomic_inc(&bss->users); - memcpy(bss->bssid, bssid, ETH_ALEN); - - spin_lock_bh(&local->sta_bss_lock); - /* TODO: order by RSSI? */ - list_add_tail(&bss->list, &local->sta_bss_list); - __ieee80211_rx_bss_hash_add(dev, bss); - spin_unlock_bh(&local->sta_bss_lock); - return bss; -} - - -static struct ieee80211_sta_bss * -ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sta_bss *bss; - - spin_lock_bh(&local->sta_bss_lock); - bss = local->sta_bss_hash[STA_HASH(bssid)]; - while (bss) { - if (memcmp(bss->bssid, bssid, ETH_ALEN) == 0) { - atomic_inc(&bss->users); - break; - } - bss = bss->hnext; - } - spin_unlock_bh(&local->sta_bss_lock); - return bss; -} - - -static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss) -{ - kfree(bss->wpa_ie); - kfree(bss->rsn_ie); - kfree(bss->wmm_ie); - kfree(bss); -} - - -static void ieee80211_rx_bss_put(struct net_device *dev, - struct ieee80211_sta_bss *bss) -{ - struct ieee80211_local *local = dev->priv; - if (!atomic_dec_and_test(&bss->users)) - return; - - spin_lock_bh(&local->sta_bss_lock); - __ieee80211_rx_bss_hash_del(dev, bss); - list_del(&bss->list); - spin_unlock_bh(&local->sta_bss_lock); - ieee80211_rx_bss_free(bss); -} - - -void ieee80211_rx_bss_list_init(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - spin_lock_init(&local->sta_bss_lock); - INIT_LIST_HEAD(&local->sta_bss_list); -} - - -void ieee80211_rx_bss_list_deinit(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sta_bss *bss; - struct list_head *ptr; - - for (;;) { - ptr = local->sta_bss_list.next; - if (!ptr || ptr == &local->sta_bss_list) - break; - bss = list_entry(ptr, struct ieee80211_sta_bss, list); - ieee80211_rx_bss_put(dev, bss); - } -} - - -static void ieee80211_rx_bss_info(struct net_device *dev, - struct ieee80211_mgmt *mgmt, - size_t len, - struct ieee80211_rx_status *rx_status, - int beacon) -{ - struct ieee80211_local *local = dev->priv; - struct ieee802_11_elems elems; - size_t baselen; - int channel, invalid = 0, clen; - struct ieee80211_sta_bss *bss; - struct sta_info *sta; - struct ieee80211_sub_if_data *sdata; - u64 timestamp; - u8 *pos; - - if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN)) - return; /* ignore ProbeResp to foreign address */ - -#if 0 - printk(KERN_DEBUG "%s: RX %s from " MACSTR " to " MACSTR "\n", - dev->name, beacon ? "Beacon" : "Probe Response", - MAC2STR(mgmt->sa), MAC2STR(mgmt->da)); -#endif - - baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; - if (baselen > len) - return; - - pos = mgmt->u.beacon.timestamp; - timestamp = ((u64) pos[7] << 56) | ((u64) pos[6] << 48) | - ((u64) pos[5] << 40) | ((u64) pos[4] << 32) | - ((u64) pos[3] << 24) | ((u64) pos[2] << 16) | - ((u64) pos[1] << 8) | ((u64) pos[0]); - - if (local->conf.mode == IW_MODE_ADHOC && beacon && - memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0) { -#ifdef IEEE80211_IBSS_DEBUG - static unsigned long last_tsf_debug = 0; - u64 tsf; - if (local->hw->get_tsf) - tsf = local->hw->get_tsf(local->mdev); - else - tsf = -1LLU; - if (time_after(jiffies, last_tsf_debug + 5 * HZ)) { - printk(KERN_DEBUG "RX beacon SA=" MACSTR " BSSID=" - MACSTR " TSF=0x%llx BCN=0x%llx diff=%lld " - "@%ld\n", - MAC2STR(mgmt->sa), MAC2STR(mgmt->bssid), - tsf, timestamp, tsf - timestamp, jiffies); - last_tsf_debug = jiffies; - } -#endif /* IEEE80211_IBSS_DEBUG */ - } - - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) - invalid = 1; - - if (local->conf.mode == IW_MODE_ADHOC && elems.supp_rates && - memcmp(mgmt->bssid, local->bssid, ETH_ALEN) == 0 && - (sta = sta_info_get(local, mgmt->sa)) && - (sdata = IEEE80211_DEV_TO_SUB_IF(dev)) && - sdata->type == IEEE80211_SUB_IF_TYPE_STA) { - struct ieee80211_rate *rates; - size_t num_rates; - u32 supp_rates, prev_rates; - int i, j, oper_mode; - - rates = local->curr_rates; - num_rates = local->num_curr_rates; - oper_mode = local->sta_scanning ? local->scan_oper_phymode : - local->conf.phymode; - for (i = 0; i < local->hw->num_modes; i++) { - struct ieee80211_hw_modes *mode = &local->hw->modes[i]; - if (oper_mode == mode->mode) { - rates = mode->rates; - num_rates = mode->num_rates; - break; - } - } - - supp_rates = 0; - for (i = 0; i < elems.supp_rates_len + - elems.ext_supp_rates_len; i++) { - u8 rate = 0; - int own_rate; - if (i < elems.supp_rates_len) - rate = elems.supp_rates[i]; - else if (elems.ext_supp_rates) - rate = elems.ext_supp_rates - [i - elems.supp_rates_len]; - own_rate = 5 * (rate & 0x7f); - if (oper_mode == MODE_ATHEROS_TURBO) - own_rate *= 2; - for (j = 0; j < num_rates; j++) - if (rates[j].rate == own_rate) - supp_rates |= BIT(j); - } - - prev_rates = sta->supp_rates; - sta->supp_rates &= supp_rates; - if (sta->supp_rates == 0) { - /* No matching rates - this should not really happen. - * Make sure that at least one rate is marked - * supported to avoid issues with TX rate ctrl. */ - - sta->supp_rates = sdata->u.sta.supp_rates_bits; - } - if (sta->supp_rates != prev_rates) { - printk(KERN_DEBUG "%s: updated supp_rates set for " - MACSTR " based on beacon info (0x%x & 0x%x -> " - "0x%x)\n", - dev->name, MAC2STR(sta->addr), prev_rates, - supp_rates, sta->supp_rates); - } - sta_info_release(local, sta); - } - - if (elems.ssid == NULL) - return; - - if (elems.ds_params && elems.ds_params_len == 1) - channel = elems.ds_params[0]; - else - channel = rx_status->channel; - - bss = ieee80211_rx_bss_get(dev, mgmt->bssid); - if (bss == NULL) { - bss = ieee80211_rx_bss_add(dev, mgmt->bssid); - if (bss == NULL) - return; - } else { -#if 0 - /* TODO: order by RSSI? */ - spin_lock_bh(&local->sta_bss_lock); - list_move_tail(&bss->list, &local->sta_bss_list); - spin_unlock_bh(&local->sta_bss_lock); -#endif - } - - if (bss->probe_resp && beacon) { - /* Do not allow beacon to override data from Probe Response. */ - ieee80211_rx_bss_put(dev, bss); - return; - } - - bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); - bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); - if (elems.ssid && elems.ssid_len <= IEEE80211_MAX_SSID_LEN) { - memcpy(bss->ssid, elems.ssid, elems.ssid_len); - bss->ssid_len = elems.ssid_len; - } - - bss->supp_rates_len = 0; - if (elems.supp_rates) { - clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; - if (clen > elems.supp_rates_len) - clen = elems.supp_rates_len; - memcpy(&bss->supp_rates[bss->supp_rates_len], elems.supp_rates, - clen); - bss->supp_rates_len += clen; - } - if (elems.ext_supp_rates) { - clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; - if (clen > elems.ext_supp_rates_len) - clen = elems.ext_supp_rates_len; - memcpy(&bss->supp_rates[bss->supp_rates_len], - elems.ext_supp_rates, clen); - bss->supp_rates_len += clen; - } - - if (elems.wpa && - (bss->wpa_ie == NULL || bss->wpa_ie_len != elems.wpa_len || - memcmp(bss->wpa_ie, elems.wpa, elems.wpa_len))) { - kfree(bss->wpa_ie); - bss->wpa_ie = kmalloc(elems.wpa_len + 2, GFP_ATOMIC); - if (bss->wpa_ie) { - memcpy(bss->wpa_ie, elems.wpa - 2, elems.wpa_len + 2); - bss->wpa_ie_len = elems.wpa_len + 2; - } else - bss->wpa_ie_len = 0; - } else if (!elems.wpa && bss->wpa_ie) { - kfree(bss->wpa_ie); - bss->wpa_ie = NULL; - bss->wpa_ie_len = 0; - } - - if (elems.rsn && - (bss->rsn_ie == NULL || bss->rsn_ie_len != elems.rsn_len || - memcmp(bss->rsn_ie, elems.rsn, elems.rsn_len))) { - kfree(bss->rsn_ie); - bss->rsn_ie = kmalloc(elems.rsn_len + 2, GFP_ATOMIC); - if (bss->rsn_ie) { - memcpy(bss->rsn_ie, elems.rsn - 2, elems.rsn_len + 2); - bss->rsn_ie_len = elems.rsn_len + 2; - } else - bss->rsn_ie_len = 0; - } else if (!elems.rsn && bss->rsn_ie) { - kfree(bss->rsn_ie); - bss->rsn_ie = NULL; - bss->rsn_ie_len = 0; - } - - if (elems.wmm_param && - (bss->wmm_ie == NULL || bss->wmm_ie_len != elems.wmm_param_len || - memcmp(bss->wmm_ie, elems.wmm_param, elems.wmm_param_len))) { - kfree(bss->wmm_ie); - bss->wmm_ie = kmalloc(elems.wmm_param_len + 2, GFP_ATOMIC); - if (bss->wmm_ie) { - memcpy(bss->wmm_ie, elems.wmm_param - 2, - elems.wmm_param_len + 2); - bss->wmm_ie_len = elems.wmm_param_len + 2; - } else - bss->wmm_ie_len = 0; - } else if (!elems.wmm_param && bss->wmm_ie) { - kfree(bss->wmm_ie); - bss->wmm_ie = NULL; - bss->wmm_ie_len = 0; - } - - - bss->hw_mode = local->conf.phymode; - bss->channel = channel; - bss->freq = local->conf.freq; - if (channel != local->conf.channel && - (local->conf.phymode == MODE_IEEE80211G || - local->conf.phymode == MODE_IEEE80211B) && - channel >= 1 && channel <= 14) { - static const int freq_list[] = { - 2412, 2417, 2422, 2427, 2432, 2437, 2442, - 2447, 2452, 2457, 2462, 2467, 2472, 2484 - }; - /* IEEE 802.11g/b mode can receive packets from neighboring - * channels, so map the channel into frequency. */ - bss->freq = freq_list[channel - 1]; - } - bss->timestamp = timestamp; - bss->last_update = jiffies; - bss->rssi = rx_status->ssi; - if (!beacon) - bss->probe_resp++; - ieee80211_rx_bss_put(dev, bss); -} - - -static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev, - struct ieee80211_mgmt *mgmt, - size_t len, - struct ieee80211_rx_status *rx_status) -{ - ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 0); -} - - -static void ieee80211_rx_mgmt_beacon(struct net_device *dev, - struct ieee80211_mgmt *mgmt, - size_t len, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_sta *ifsta; - int use_protection; - size_t baselen; - struct ieee802_11_elems elems; - - ieee80211_rx_bss_info(dev, mgmt, len, rx_status, 1); - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - return; - ifsta = &sdata->u.sta; - - if (!ifsta->associated || - memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) - return; - - /* Process beacon from the current BSS */ - baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; - if (baselen > len) - return; - - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) - return; - - use_protection = 0; - if (elems.erp_info && elems.erp_info_len >= 1) { - use_protection = - (elems.erp_info[0] & ERP_INFO_USE_PROTECTION) != 0; - } - - if (use_protection != !!ifsta->use_protection) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: CTS protection %s (BSSID=" - MACSTR ")\n", - dev->name, - use_protection ? "enabled" : "disabled", - MAC2STR(ifsta->bssid)); - } - ifsta->use_protection = use_protection ? 1 : 0; - local->cts_protect_erp_frames = use_protection; - } - - if (elems.wmm_param && ifsta->wmm_enabled) { - ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, - elems.wmm_param_len); - } -} - - -static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, - struct ieee80211_if_sta *ifsta, - struct ieee80211_mgmt *mgmt, - size_t len, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_local *local = dev->priv; - int tx_last_beacon; - struct sk_buff *skb; - struct ieee80211_mgmt *resp; - u8 *pos, *end; - - if (local->conf.mode != IW_MODE_ADHOC || - ifsta->state != IEEE80211_IBSS_JOINED || - len < 24 + 2 || ifsta->probe_resp == NULL) - return; - - if (local->hw->tx_last_beacon) - tx_last_beacon = local->hw->tx_last_beacon(local->mdev); - else - tx_last_beacon = 1; - -#ifdef IEEE80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: RX ProbeReq SA=" MACSTR " DA=" MACSTR " BSSID=" - MACSTR " (tx_last_beacon=%d)\n", - dev->name, MAC2STR(mgmt->sa), MAC2STR(mgmt->da), - MAC2STR(mgmt->bssid), tx_last_beacon); -#endif /* IEEE80211_IBSS_DEBUG */ - - if (!tx_last_beacon) - return; - - if (memcmp(mgmt->bssid, ifsta->bssid, ETH_ALEN) != 0 && - memcmp(mgmt->bssid, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0) - return; - - end = ((u8 *) mgmt) + len; - pos = mgmt->u.probe_req.variable; - if (pos[0] != WLAN_EID_SSID || - pos + 2 + pos[1] > end) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " - "from " MACSTR "\n", - dev->name, MAC2STR(mgmt->sa)); - } - return; - } - if (pos[1] != 0 && - (pos[1] != ifsta->ssid_len || - memcmp(pos + 2, ifsta->ssid, ifsta->ssid_len) != 0)) { - /* Ignore ProbeReq for foreign SSID */ - return; - } - - /* Reply with ProbeResp */ - skb = skb_copy(ifsta->probe_resp, GFP_ATOMIC); - if (skb == NULL) - return; - - resp = (struct ieee80211_mgmt *) skb->data; - memcpy(resp->da, mgmt->sa, ETH_ALEN); -#ifdef IEEE80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: Sending ProbeResp to " MACSTR "\n", - dev->name, MAC2STR(resp->da)); -#endif /* IEEE80211_IBSS_DEBUG */ - ieee80211_sta_tx(dev, skb, 0, 1); -} - - -void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_sta *ifsta; - struct ieee80211_mgmt *mgmt; - u16 fc; - - if (skb->len < 24) - goto fail; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) { - printk(KERN_DEBUG "%s: ieee80211_sta_rx_mgmt: non-STA " - "interface (type=%d)\n", dev->name, sdata->type); - goto fail; - } - ifsta = &sdata->u.sta; - - mgmt = (struct ieee80211_mgmt *) skb->data; - fc = le16_to_cpu(mgmt->frame_control); - - switch (WLAN_FC_GET_STYPE(fc)) { - case WLAN_FC_STYPE_PROBE_REQ: - ieee80211_rx_mgmt_probe_req(dev, ifsta, mgmt, skb->len, - rx_status); - break; - case WLAN_FC_STYPE_PROBE_RESP: - ieee80211_rx_mgmt_probe_resp(dev, mgmt, skb->len, rx_status); - break; - case WLAN_FC_STYPE_BEACON: - ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, rx_status); - break; - case WLAN_FC_STYPE_AUTH: - ieee80211_rx_mgmt_auth(dev, ifsta, mgmt, skb->len, rx_status); - break; - case WLAN_FC_STYPE_ASSOC_RESP: - ieee80211_rx_mgmt_assoc_resp(dev, ifsta, mgmt, skb->len, - rx_status, 0); - break; - case WLAN_FC_STYPE_REASSOC_RESP: - ieee80211_rx_mgmt_assoc_resp(dev, ifsta, mgmt, skb->len, - rx_status, 1); - break; - case WLAN_FC_STYPE_DEAUTH: - ieee80211_rx_mgmt_deauth(dev, ifsta, mgmt, skb->len, - rx_status); - break; - case WLAN_FC_STYPE_DISASSOC: - ieee80211_rx_mgmt_disassoc(dev, ifsta, mgmt, skb->len, - rx_status); - break; - default: - printk(KERN_DEBUG "%s: received unknown management frame - " - "stype=%d\n", dev->name, WLAN_FC_GET_STYPE(fc)); - break; - } - - fail: - dev_kfree_skb(skb); -} - - -void ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *rx_status) -{ - struct ieee80211_mgmt *mgmt; - u16 fc; - - if (skb->len < 24) { - dev_kfree_skb(skb); - return; - } - - mgmt = (struct ieee80211_mgmt *) skb->data; - fc = le16_to_cpu(mgmt->frame_control); - - if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_MGMT) { - if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_PROBE_RESP) { - ieee80211_rx_mgmt_probe_resp(dev, mgmt, - skb->len, rx_status); - } else if (WLAN_FC_GET_STYPE(fc) == WLAN_FC_STYPE_BEACON) { - ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, - rx_status); - } - } - - dev_kfree_skb(skb); -} - - -static int ieee80211_sta_active_ibss(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - struct list_head *ptr; - int active = 0; - struct sta_info *sta; - - spin_lock_bh(&local->sta_lock); - list_for_each(ptr, &local->sta_list) { - sta = list_entry(ptr, struct sta_info, list); - if (sta->dev == dev && - time_after(sta->last_rx + IEEE80211_IBSS_MERGE_INTERVAL, - jiffies)) { - active++; - break; - } - } - spin_unlock_bh(&local->sta_lock); - - return active; -} - - -static void ieee80211_sta_expire(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - struct list_head *ptr, *n; - struct sta_info *sta; - - spin_lock_bh(&local->sta_lock); - list_for_each_safe(ptr, n, &local->sta_list) { - sta = list_entry(ptr, struct sta_info, list); - if (time_after(jiffies, sta->last_rx + - IEEE80211_IBSS_INACTIVITY_LIMIT)) { - printk(KERN_DEBUG "%s: expiring inactive STA " MACSTR - "\n", dev->name, MAC2STR(sta->addr)); - sta_info_free(local, sta, 1); - } - } - spin_unlock_bh(&local->sta_lock); -} - - -static void ieee80211_sta_merge_ibss(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); - - ieee80211_sta_expire(dev); - if (ieee80211_sta_active_ibss(dev)) - return; - - printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " - "IBSS networks with same SSID (merge)\n", dev->name); - ieee80211_sta_req_scan(dev, ifsta->ssid, ifsta->ssid_len); -} - - -void ieee80211_sta_timer(unsigned long ptr) -{ - struct net_device *dev; - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_sta *ifsta; - - dev = (struct net_device *) ptr; - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) { - printk(KERN_DEBUG "%s: ieee80211_sta_timer: non-STA interface " - "(type=%d)\n", dev->name, sdata->type); - return; - } - ifsta = &sdata->u.sta; - - switch (ifsta->state) { - case IEEE80211_DISABLED: - break; - case IEEE80211_AUTHENTICATE: - ieee80211_authenticate(dev, ifsta); - break; - case IEEE80211_ASSOCIATE: - ieee80211_associate(dev, ifsta); - break; - case IEEE80211_ASSOCIATED: - ieee80211_associated(dev, ifsta); - break; - case IEEE80211_IBSS_SEARCH: - ieee80211_sta_find_ibss(dev, ifsta); - break; - case IEEE80211_IBSS_JOINED: - ieee80211_sta_merge_ibss(dev, ifsta); - break; - default: - printk(KERN_DEBUG "ieee80211_sta_timer: Unknown state %d\n", - ifsta->state); - break; - } - - if (ieee80211_privacy_mismatch(dev, ifsta)) { - printk(KERN_DEBUG "%s: privacy configuration mismatch and " - "mixed-cell disabled - disassociate\n", dev->name); - - ieee80211_send_disassoc(dev, ifsta, WLAN_REASON_UNSPECIFIED); - ieee80211_set_associated(dev, ifsta, 0); - } -} - - -static void ieee80211_sta_new_auth(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - struct ieee80211_local *local = dev->priv; - - if (local->conf.mode != IW_MODE_INFRA) - return; - - if (local->hw->reset_tsf) { - /* Reset own TSF to allow time synchronization work. */ - local->hw->reset_tsf(local->mdev); - } - - ifsta->wmm_last_param_set = -1; /* allow any WMM update */ - - - if (ifsta->auth_algs & IEEE80211_AUTH_ALG_OPEN) - ifsta->auth_alg = WLAN_AUTH_OPEN; - else if (ifsta->auth_algs & IEEE80211_AUTH_ALG_SHARED_KEY) - ifsta->auth_alg = WLAN_AUTH_SHARED_KEY; - else if (ifsta->auth_algs & IEEE80211_AUTH_ALG_LEAP) - ifsta->auth_alg = WLAN_AUTH_LEAP; - else - ifsta->auth_alg = WLAN_AUTH_OPEN; - printk(KERN_DEBUG "%s: Initial auth_alg=%d\n", dev->name, - ifsta->auth_alg); - ifsta->auth_transaction = -1; - ifsta->auth_tries = ifsta->assoc_tries = 0; - ieee80211_authenticate(dev, ifsta); -} - - -static int ieee80211_ibss_allowed(struct ieee80211_local *local) -{ - int m, c; - - for (m = 0; m < local->hw->num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw->modes[m]; - if (mode->mode != local->conf.phymode) - continue; - for (c = 0; c < mode->num_channels; c++) { - struct ieee80211_channel *chan = &mode->channels[c]; - if (chan->flag & IEEE80211_CHAN_W_SCAN && - chan->chan == local->conf.channel) { - if (chan->flag & IEEE80211_CHAN_W_IBSS) - return 1; - break; - } - } - } - - return 0; -} - - -extern int ieee80211_ioctl_siwfreq(struct net_device *dev, - struct iw_request_info *info, - struct iw_freq *freq, char *extra); - -static int ieee80211_sta_join_ibss(struct net_device *dev, - struct ieee80211_if_sta *ifsta, - struct ieee80211_sta_bss *bss) -{ - struct ieee80211_local *local = dev->priv; - struct iw_freq rq; - int res, rates, i, j; - struct sk_buff *skb; - struct ieee80211_mgmt *mgmt; - struct ieee80211_tx_control control; - struct ieee80211_rate *rate; - struct rate_control_extra extra; - u8 *pos; - struct ieee80211_sub_if_data *sdata; - - /* Remove possible STA entries from other IBSS networks. */ - sta_info_flush(local, NULL); - - if (local->hw->reset_tsf) { - /* Reset own TSF to allow time synchronization work. */ - local->hw->reset_tsf(local->mdev); - } - memcpy(ifsta->bssid, bss->bssid, ETH_ALEN); - memcpy(local->bssid, bss->bssid, ETH_ALEN); - memcpy(local->conf.client_bssid, bss->bssid, ETH_ALEN); - - local->conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - sdata->drop_unencrypted = bss->capability & - cpu_to_le16(WLAN_CAPABILITY_PRIVACY) ? 1 : 0; - - memset(&rq, 0, sizeof(rq)); - rq.m = bss->freq * 100000; - rq.e = 1; - res = ieee80211_ioctl_siwfreq(dev, NULL, &rq, NULL); - - if (!ieee80211_ibss_allowed(local)) { - printk(KERN_DEBUG "%s: IBSS not allowed on channel %d " - "(%d MHz)\n", dev->name, local->conf.channel, - local->conf.freq); - return -1; - } - - /* Set beacon template based on scan results */ - skb = dev_alloc_skb(400); - do { - if (skb == NULL) - break; - - mgmt = (struct ieee80211_mgmt *) - skb_put(skb, 24 + sizeof(mgmt->u.beacon)); - memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); - mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT, - WLAN_FC_STYPE_BEACON); - memset(mgmt->da, 0xff, ETH_ALEN); - memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); - memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); - mgmt->u.beacon.beacon_int = - cpu_to_le16(local->conf.beacon_int); - mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability); - - pos = skb_put(skb, 2 + ifsta->ssid_len); - *pos++ = WLAN_EID_SSID; - *pos++ = ifsta->ssid_len; - memcpy(pos, ifsta->ssid, ifsta->ssid_len); - - rates = bss->supp_rates_len; - if (rates > 8) - rates = 8; - pos = skb_put(skb, 2 + rates); - *pos++ = WLAN_EID_SUPP_RATES; - *pos++ = rates; - memcpy(pos, bss->supp_rates, rates); - - pos = skb_put(skb, 2 + 1); - *pos++ = WLAN_EID_DS_PARAMS; - *pos++ = 1; - *pos++ = bss->channel; - - pos = skb_put(skb, 2 + 2); - *pos++ = WLAN_EID_IBSS_PARAMS; - *pos++ = 2; - /* FIX: set ATIM window based on scan results */ - *pos++ = 0; - *pos++ = 0; - - if (bss->supp_rates_len > 8) { - rates = bss->supp_rates_len - 8; - pos = skb_put(skb, 2 + rates); - *pos++ = WLAN_EID_EXT_SUPP_RATES; - *pos++ = rates; - memcpy(pos, &bss->supp_rates[8], rates); - } - - memset(&control, 0, sizeof(control)); - control.pkt_type = PKT_PROBE_RESP; - memset(&extra, 0, sizeof(extra)); - extra.endidx = local->num_curr_rates; - rate = rate_control_get_rate(dev, skb, &extra); - if (rate == NULL) { - printk(KERN_DEBUG "%s: Failed to determine TX rate " - "for IBSS beacon\n", dev->name); - break; - } - control.tx_rate = (local->short_preamble && - (rate->flags & IEEE80211_RATE_PREAMBLE2)) ? - rate->val2 : rate->val; - control.antenna_sel = local->conf.antenna_sel; - control.power_level = local->conf.power_level; - control.no_ack = 1; - control.retry_limit = 1; - control.rts_cts_duration = 0; - - ifsta->probe_resp = skb_copy(skb, GFP_ATOMIC); - if (ifsta->probe_resp) { - mgmt = (struct ieee80211_mgmt *) - ifsta->probe_resp->data; - mgmt->frame_control = - IEEE80211_FC(WLAN_FC_TYPE_MGMT, - WLAN_FC_STYPE_PROBE_RESP); - } else { - printk(KERN_DEBUG "%s: Could not allocate ProbeResp " - "template for IBSS\n", dev->name); - } - - if (local->hw->beacon_update && - local->hw->beacon_update(dev, skb, &control) == 0) { - printk(KERN_DEBUG "%s: Configured IBSS beacon " - "template based on scan results\n", dev->name); - skb = NULL; - } - - rates = 0; - for (i = 0; i < bss->supp_rates_len; i++) { - int rate = (bss->supp_rates[i] & 0x7f) * 5; - if (local->conf.phymode == MODE_ATHEROS_TURBO) - rate *= 2; - for (j = 0; j < local->num_curr_rates; j++) - if (local->curr_rates[j].rate == rate) - rates |= BIT(j); - } - ifsta->supp_rates_bits = rates; - } while (0); - - if (skb) { - printk(KERN_DEBUG "%s: Failed to configure IBSS beacon " - "template\n", dev->name); - dev_kfree_skb(skb); - } - - ifsta->state = IEEE80211_IBSS_JOINED; - mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); - - ieee80211_rx_bss_put(dev, bss); - - return res; -} - - -static int ieee80211_sta_create_ibss(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sta_bss *bss; - struct ieee80211_sub_if_data *sdata; - u8 bssid[ETH_ALEN], *pos; - int i; - -#if 0 - /* Easier testing, use fixed BSSID. */ - memset(bssid, 0xfe, ETH_ALEN); -#else - /* Generate random, not broadcast, locally administered BSSID. Mix in - * own MAC address to make sure that devices that do not have proper - * random number generator get different BSSID. */ - get_random_bytes(bssid, ETH_ALEN); - for (i = 0; i < ETH_ALEN; i++) - bssid[i] ^= dev->dev_addr[i]; - bssid[0] &= ~0x01; - bssid[0] |= 0x02; -#endif - - printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID " MACSTR "\n", - dev->name, MAC2STR(bssid)); - - bss = ieee80211_rx_bss_add(dev, bssid); - if (bss == NULL) - return -ENOMEM; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - - if (local->conf.beacon_int == 0) - local->conf.beacon_int = 100; - bss->beacon_int = local->conf.beacon_int; - bss->hw_mode = local->conf.phymode; - bss->channel = local->conf.channel; - bss->freq = local->conf.freq; - bss->last_update = jiffies; - bss->capability = cpu_to_le16(WLAN_CAPABILITY_IBSS); - if (sdata->default_key) { - bss->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - } else - sdata->drop_unencrypted = 0; - bss->supp_rates_len = local->num_curr_rates; - pos = bss->supp_rates; - for (i = 0; i < local->num_curr_rates; i++) { - int rate = local->curr_rates[i].rate; - if (local->conf.phymode == MODE_ATHEROS_TURBO) - rate /= 2; - *pos++ = (u8) (rate / 5); - } - - return ieee80211_sta_join_ibss(dev, ifsta, bss); -} - - -static int ieee80211_sta_find_ibss(struct net_device *dev, - struct ieee80211_if_sta *ifsta) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sta_bss *bss; - int found = 0; - u8 bssid[ETH_ALEN]; - struct list_head *ptr; - int active_ibss; - - if (ifsta->ssid_len == 0) - return -EINVAL; - - active_ibss = ieee80211_sta_active_ibss(dev); -#ifdef IEEE80211_IBSS_DEBUG - printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", - dev->name, active_ibss); -#endif /* IEEE80211_IBSS_DEBUG */ - spin_lock_bh(&local->sta_bss_lock); - list_for_each(ptr, &local->sta_bss_list) { - bss = list_entry(ptr, struct ieee80211_sta_bss, list); - if (ifsta->ssid_len != bss->ssid_len || - memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0 - || !(bss->capability & WLAN_CAPABILITY_IBSS)) - continue; -#ifdef IEEE80211_IBSS_DEBUG - printk(KERN_DEBUG " bssid=" MACSTR " found\n", - MAC2STR(bss->bssid)); -#endif /* IEEE80211_IBSS_DEBUG */ - memcpy(bssid, bss->bssid, ETH_ALEN); - found = 1; - if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0) - break; - } - spin_unlock_bh(&local->sta_bss_lock); - -#ifdef IEEE80211_IBSS_DEBUG - printk(KERN_DEBUG " sta_find_ibss: selected " MACSTR " current " - MACSTR "\n", MAC2STR(bssid), MAC2STR(ifsta->bssid)); -#endif /* IEEE80211_IBSS_DEBUG */ - if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && - (bss = ieee80211_rx_bss_get(dev, bssid))) { - printk(KERN_DEBUG "%s: Selected IBSS BSSID " MACSTR - " based on configured SSID\n", - dev->name, MAC2STR(bssid)); - return ieee80211_sta_join_ibss(dev, ifsta, bss); - } -#ifdef IEEE80211_IBSS_DEBUG - printk(KERN_DEBUG " did not try to join ibss\n"); -#endif /* IEEE80211_IBSS_DEBUG */ - - /* Selected IBSS not found in current scan results - try to scan */ - if (ifsta->state == IEEE80211_IBSS_JOINED && - !ieee80211_sta_active_ibss(dev)) { - mod_timer(&ifsta->timer, - jiffies + IEEE80211_IBSS_MERGE_INTERVAL); - } else if (time_after(jiffies, local->last_scan_completed + - IEEE80211_SCAN_INTERVAL)) { - printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " - "join\n", dev->name); - return ieee80211_sta_req_scan(dev, ifsta->ssid, - ifsta->ssid_len); - } else if (ifsta->state != IEEE80211_IBSS_JOINED) { - int interval = IEEE80211_SCAN_INTERVAL; - - if (time_after(jiffies, ifsta->ibss_join_req + - IEEE80211_IBSS_JOIN_TIMEOUT)) { - if (ifsta->create_ibss && - ieee80211_ibss_allowed(local)) - return ieee80211_sta_create_ibss(dev, ifsta); - if (ifsta->create_ibss) { - printk(KERN_DEBUG "%s: IBSS not allowed on the" - " configured channel %d (%d MHz)\n", - dev->name, local->conf.channel, - local->conf.freq); - } - - /* No IBSS found - decrease scan interval and continue - * scanning. */ - interval = IEEE80211_SCAN_INTERVAL_SLOW; - } - - ifsta->state = IEEE80211_IBSS_SEARCH; - mod_timer(&ifsta->timer, jiffies + interval); - return 0; - } - - return 0; -} - - -int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) -{ - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_sta *ifsta; - struct ieee80211_local *local = dev->priv; - - if (len > IEEE80211_MAX_SSID_LEN) - return -EINVAL; - - /* TODO: This should always be done for IBSS, even if IEEE80211_QOS is - * not defined. */ - if (local->hw->conf_tx) { - struct ieee80211_tx_queue_params qparam; - int i; - - memset(&qparam, 0, sizeof(qparam)); - /* TODO: are these ok defaults for all hw_modes? */ - qparam.aifs = 2; - qparam.cw_min = - local->conf.phymode == MODE_IEEE80211B ? 31 : 15; - qparam.cw_max = 1023; - qparam.burst_time = 0; - for (i = IEEE80211_TX_QUEUE_DATA0; i < NUM_TX_DATA_QUEUES; i++) - { - local->hw->conf_tx(dev, i + IEEE80211_TX_QUEUE_DATA0, - &qparam); - } - /* IBSS uses different parameters for Beacon sending */ - qparam.cw_min++; - qparam.cw_min *= 2; - qparam.cw_min--; - local->hw->conf_tx(dev, IEEE80211_TX_QUEUE_BEACON, &qparam); - } - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - ifsta = &sdata->u.sta; - - if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) - ifsta->prev_bssid_set = 0; - memcpy(ifsta->ssid, ssid, len); - memset(ifsta->ssid + len, 0, IEEE80211_MAX_SSID_LEN - len); - ifsta->ssid_len = len; - - ifsta->ssid_set = 1; - if (local->conf.mode == IW_MODE_ADHOC && !ifsta->bssid_set) { - ifsta->ibss_join_req = jiffies; - ifsta->state = IEEE80211_IBSS_SEARCH; - return ieee80211_sta_find_ibss(dev, ifsta); - } - - if (ifsta->bssid_set && ifsta->state != IEEE80211_AUTHENTICATE) - ieee80211_sta_new_auth(dev, ifsta); - - return 0; -} - - -int ieee80211_sta_get_ssid(struct net_device *dev, char *ssid, size_t *len) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_if_sta *ifsta = &sdata->u.sta; - memcpy(ssid, ifsta->ssid, ifsta->ssid_len); - *len = ifsta->ssid_len; - return 0; -} - - -int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata; - struct ieee80211_if_sta *ifsta; - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - ifsta = &sdata->u.sta; - - memcpy(ifsta->bssid, bssid, ETH_ALEN); - if (local->conf.mode == IW_MODE_ADHOC) - memcpy(local->bssid, bssid, ETH_ALEN); - - if (memcmp(bssid, "\x00\x00\x00\x00\x00\x00", ETH_ALEN) == 0) - ifsta->bssid_set = 0; - else - ifsta->bssid_set = 1; - if (ifsta->ssid_set) - ieee80211_sta_new_auth(dev, ifsta); - - return 0; -} - - -static void ieee80211_sta_save_oper_chan(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - local->scan_oper_channel = local->conf.channel; - local->scan_oper_channel_val = local->conf.channel_val; - local->scan_oper_power_level = local->conf.power_level; - local->scan_oper_freq = local->conf.freq; - local->scan_oper_phymode = local->conf.phymode; - local->scan_oper_antenna_max = local->conf.antenna_max; -} - - -static int ieee80211_sta_restore_oper_chan(struct net_device *dev) -{ - struct ieee80211_local *local = dev->priv; - local->conf.channel = local->scan_oper_channel; - local->conf.channel_val = local->scan_oper_channel_val; - local->conf.power_level = local->scan_oper_power_level; - local->conf.freq = local->scan_oper_freq; - local->conf.phymode = local->scan_oper_phymode; - local->conf.antenna_max = local->scan_oper_antenna_max; - return ieee80211_hw_config(dev); -} - - -static int ieee80211_active_scan(struct ieee80211_local *local) -{ - int m, c; - - for (m = 0; m < local->hw->num_modes; m++) { - struct ieee80211_hw_modes *mode = &local->hw->modes[m]; - if (mode->mode != local->conf.phymode) - continue; - for (c = 0; c < mode->num_channels; c++) { - struct ieee80211_channel *chan = &mode->channels[c]; - if (chan->flag & IEEE80211_CHAN_W_SCAN && - chan->chan == local->conf.channel) { - if (chan->flag & IEEE80211_CHAN_W_ACTIVE_SCAN) - return 1; - break; - } - } - } - - return 0; -} - - -static void ieee80211_sta_scan_timer(unsigned long ptr) -{ - struct net_device *dev = (struct net_device *) ptr; - struct ieee80211_local *local = dev->priv; - struct ieee80211_hw_modes *mode; - struct ieee80211_channel *chan; - int skip; - union iwreq_data wrqu; - - if (!local->sta_scanning) - return; - - switch (local->scan_state) { - case SCAN_SET_CHANNEL: - mode = &local->hw->modes[local->scan_hw_mode_idx]; - if (local->scan_hw_mode_idx >= local->hw->num_modes || - (local->scan_hw_mode_idx + 1 == local->hw->num_modes && - local->scan_channel_idx >= mode->num_channels)) { - if (ieee80211_sta_restore_oper_chan(dev)) { - printk(KERN_DEBUG "%s: failed to restore " - "operational channel after scan\n", - dev->name); - } - printk(KERN_DEBUG "%s: scan completed\n", dev->name); - local->sta_scanning = 0; - local->last_scan_completed = jiffies; - memset(&wrqu, 0, sizeof(wrqu)); - wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); - if (local->conf.mode == IW_MODE_ADHOC) { - struct ieee80211_sub_if_data *sdata = - IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_if_sta *ifsta = &sdata->u.sta; - if (!ifsta->bssid_set || - (ifsta->state == IEEE80211_IBSS_JOINED && - !ieee80211_sta_active_ibss(dev))) - ieee80211_sta_find_ibss(dev, ifsta); - } - return; - } - skip = !(local->hw_modes & (1 << mode->mode)); - chan = &mode->channels[local->scan_channel_idx]; - if (!(chan->flag & IEEE80211_CHAN_W_SCAN) || - (local->conf.mode == IW_MODE_ADHOC && - !(chan->flag & IEEE80211_CHAN_W_IBSS)) || - (local->hw_modes & (1 << MODE_IEEE80211G) && - mode->mode == MODE_IEEE80211B && local->scan_skip_11b)) - skip = 1; - - if (!skip) { -#if 0 - printk(KERN_DEBUG "%s: scan channel %d (%d MHz)\n", - dev->name, chan->chan, chan->freq); -#endif - - local->conf.channel = chan->chan; - local->conf.channel_val = chan->val; - local->conf.power_level = chan->power_level; - local->conf.freq = chan->freq; - local->conf.phymode = mode->mode; - local->conf.antenna_max = chan->antenna_max; - if (ieee80211_hw_config(dev)) { - printk(KERN_DEBUG "%s: failed to set channel " - "%d (%d MHz) for scan\n", dev->name, - chan->chan, chan->freq); - skip = 1; - } - } - - local->scan_channel_idx++; - if (local->scan_channel_idx >= - local->hw->modes[local->scan_hw_mode_idx].num_channels) { - local->scan_hw_mode_idx++; - local->scan_channel_idx = 0; - } - - if (skip) { - local->scan_timer.expires = jiffies; - break; - } - - local->scan_timer.expires = jiffies + IEEE80211_PROBE_DELAY; - local->scan_state = SCAN_SEND_PROBE; - break; - case SCAN_SEND_PROBE: - if (ieee80211_active_scan(local)) { - ieee80211_send_probe_req(dev, NULL, local->scan_ssid, - local->scan_ssid_len); - local->scan_timer.expires = - jiffies + IEEE80211_CHANNEL_TIME; - } else { - local->scan_timer.expires = - jiffies + IEEE80211_PASSIVE_CHANNEL_TIME; - } - local->scan_state = SCAN_SET_CHANNEL; - break; - } - - add_timer(&local->scan_timer); -} - - -int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len) -{ - struct ieee80211_local *local = dev->priv; - - if (ssid_len > IEEE80211_MAX_SSID_LEN) - return -EINVAL; - - /* MLME-SCAN.request (page 118) page 144 (11.1.3.1) - * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS - * BSSID: MACAddress - * SSID - * ScanType: ACTIVE, PASSIVE - * ProbeDelay: delay (in microseconds) to be used prior to transmitting - * a Probe frame during active scanning - * ChannelList - * MinChannelTime (>= ProbeDelay), in TU - * MaxChannelTime: (>= MinChannelTime), in TU - */ - - /* MLME-SCAN.confirm - * BSSDescriptionSet - * ResultCode: SUCCESS, INVALID_PARAMETERS - */ - - /* TODO: if assoc, move to power save mode for the duration of the - * scan */ - - if (local->sta_scanning) - return -EBUSY; - - printk(KERN_DEBUG "%s: starting scan\n", dev->name); - - ieee80211_sta_save_oper_chan(dev); - - local->sta_scanning = 1; - /* TODO: stop TX queue? */ - - if (ssid) { - local->scan_ssid_len = ssid_len; - memcpy(local->scan_ssid, ssid, ssid_len); - } else - local->scan_ssid_len = 0; - local->scan_skip_11b = 1; /* FIX: clear this is 11g is not supported */ - local->scan_state = SCAN_SET_CHANNEL; - local->scan_hw_mode_idx = 0; - local->scan_channel_idx = 0; - init_timer(&local->scan_timer); - local->scan_timer.data = (unsigned long) dev; - local->scan_timer.function = ieee80211_sta_scan_timer; - local->scan_timer.expires = jiffies + 1; - add_timer(&local->scan_timer); - - return 0; -} - - -static char * -ieee80211_sta_scan_result(struct net_device *dev, - struct ieee80211_sta_bss *bss, - char *current_ev, char *end_buf) -{ - struct ieee80211_local *local = dev->priv; - struct iw_event iwe; - - if (time_after(jiffies, - bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE)) - return current_ev; - - if (!(local->hw_modes & (1 << bss->hw_mode))) - return current_ev; - - if (local->scan_flags & IEEE80211_SCAN_WPA_ONLY && - bss->wpa_ie == NULL && bss->rsn_ie == NULL) - return current_ev; - - if (local->scan_flags & IEEE80211_SCAN_MATCH_SSID && - (local->scan_ssid_len != bss->ssid_len || - memcmp(local->scan_ssid, bss->ssid, bss->ssid_len) != 0)) - return current_ev; - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_ADDR_LEN); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWESSID; - iwe.u.data.length = bss->ssid_len; - iwe.u.data.flags = 1; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, - bss->ssid); - - if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWMODE; - if (bss->capability & WLAN_CAPABILITY_ESS) - iwe.u.mode = IW_MODE_MASTER; - else - iwe.u.mode = IW_MODE_ADHOC; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_UINT_LEN); - } - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWFREQ; - iwe.u.freq.m = bss->freq * 100000; - iwe.u.freq.e = 1; - current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, - IW_EV_FREQ_LEN); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = SIOCGIWENCODE; - if (bss->capability & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); - - if (bss && bss->wpa_ie) { - char *buf, *p; - int i; - buf = kmalloc(30 + bss->wpa_ie_len * 2, GFP_ATOMIC); - if (buf) { - p = buf; - p += sprintf(p, "wpa_ie="); - for (i = 0; i < bss->wpa_ie_len; i++) - p+= sprintf(p, "%02x", bss->wpa_ie[i]); - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, buf); - kfree(buf); - } - } - - if (bss && bss->rsn_ie) { - char *buf, *p; - int i; - buf = kmalloc(30 + bss->rsn_ie_len * 2, GFP_ATOMIC); - if (buf) { - p = buf; - p += sprintf(p, "rsn_ie="); - for (i = 0; i < bss->rsn_ie_len; i++) - p+= sprintf(p, "%02x", bss->rsn_ie[i]); - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, buf); - kfree(buf); - } - } - - if (bss) { - char *buf; - buf = kmalloc(30, GFP_ATOMIC); - if (buf) { - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "tsf=%016llx", bss->timestamp); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, - &iwe, buf); - kfree(buf); - } - } - - do { - char *buf, *p; - int i; - - if (!(local->scan_flags & IEEE80211_SCAN_EXTRA_INFO)) - break; - - buf = kmalloc(100, GFP_ATOMIC); - if (buf == NULL) - break; - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "bcn_int=%d", bss->beacon_int); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, - buf); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "rssi=%d", bss->rssi); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, - buf); - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - sprintf(buf, "capab=0x%04x", bss->capability); - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, - buf); - - p = buf; - p += sprintf(p, "supp_rates="); - for (i = 0; i < bss->supp_rates_len; i++) - p+= sprintf(p, "%02x", bss->supp_rates[i]); - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = strlen(buf); - current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, - buf); - - kfree(buf); - break; - } while (0); - - return current_ev; -} - - -int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len) -{ - struct ieee80211_local *local = dev->priv; - struct list_head *ptr; - char *current_ev = buf; - char *end_buf = buf + len; - struct ieee80211_sta_bss *bss; - - spin_lock_bh(&local->sta_bss_lock); - list_for_each(ptr, &local->sta_bss_list) { - bss = list_entry(ptr, struct ieee80211_sta_bss, list); - current_ev = ieee80211_sta_scan_result(dev, bss, current_ev, - end_buf); - } - spin_unlock_bh(&local->sta_bss_lock); - return current_ev - buf; -} - - -int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_if_sta *ifsta = &sdata->u.sta; - kfree(ifsta->extra_ie); - if (len == 0) { - ifsta->extra_ie = NULL; - ifsta->extra_ie_len = 0; - return 0; - } - ifsta->extra_ie = kmalloc(len, GFP_KERNEL); - if (ifsta->extra_ie == NULL) { - ifsta->extra_ie_len = 0; - return -ENOMEM; - } - memcpy(ifsta->extra_ie, ie, len); - ifsta->extra_ie_len = len; - if (ifsta->bssid_set && ifsta->ssid_set && - ifsta->state != IEEE80211_AUTHENTICATE) - ieee80211_sta_new_auth(dev, ifsta); - return 0; -} - - -struct sta_info * ieee80211_ibss_add_sta(struct net_device *dev, - struct sk_buff *skb, u8 *bssid, - u8 *addr) -{ - struct ieee80211_local *local = dev->priv; - struct list_head *ptr; - struct sta_info *sta; - struct ieee80211_sub_if_data *sdata = NULL; - struct net_device *sta_dev = NULL; - - /* TODO: Could consider removing the least recently used entry and - * allow new one to be added. */ - if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: No room for a new IBSS STA " - "entry " MACSTR "\n", dev->name, MAC2STR(addr)); - } - return NULL; - } - - spin_lock_bh(&local->sub_if_lock); - list_for_each(ptr, &local->sub_if_list) { - sdata = list_entry(ptr, struct ieee80211_sub_if_data, list); - if (sdata->type == IEEE80211_SUB_IF_TYPE_STA && - memcmp(bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) { - sta_dev = sdata->dev; - break; - } - } - spin_unlock_bh(&local->sub_if_lock); - - if (sta_dev == NULL) - return NULL; - - printk(KERN_DEBUG "%s: Adding new IBSS station " MACSTR " (dev=%s)\n", - dev->name, MAC2STR(addr), sta_dev->name); - - sta = sta_info_add(local, dev, addr); - if (sta == NULL) { - return NULL; - } - - sta->dev = sta_dev; - sta->supp_rates = sdata->u.sta.supp_rates_bits; - - rate_control_rate_init(local, sta); - - return sta; /* caller will call sta_info_release() */ -} - - -int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_if_sta *ifsta = &sdata->u.sta; - - printk(KERN_DEBUG "%s: deauthenticate(reason=%d)\n", - dev->name, reason); - - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - return -EINVAL; - - ieee80211_send_deauth(dev, ifsta, reason); - ieee80211_set_associated(dev, ifsta, 0); - return 0; -} - - -int ieee80211_sta_disassociate(struct net_device *dev, u16 reason) -{ - struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); - struct ieee80211_if_sta *ifsta = &sdata->u.sta; - - printk(KERN_DEBUG "%s: disassociate(reason=%d)\n", - dev->name, reason); - - if (sdata->type != IEEE80211_SUB_IF_TYPE_STA) - return -EINVAL; - - if (!ifsta->associated) - return -1; - - ieee80211_send_disassoc(dev, ifsta, reason); - ieee80211_set_associated(dev, ifsta, 0); - return 0; -} diff --git a/target/linux/package/ieee80211-dscape/src/include/net/ieee80211.h b/target/linux/package/ieee80211-dscape/src/include/net/ieee80211.h deleted file mode 100644 index 5d8975527a..0000000000 --- a/target/linux/package/ieee80211-dscape/src/include/net/ieee80211.h +++ /dev/null @@ -1,872 +0,0 @@ -/* - * Low-level hardware driver -- IEEE 802.11 driver (80211.o) interface - * Copyright 2002-2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef IEEE80211_H -#define IEEE80211_H - -#include "ieee80211_shared.h" - -/* Note! Only ieee80211_tx_status_irqsafe() and ieee80211_rx_irqsave() can be - * called in hardware interrupt context. The low-level driver must not call any - * other functions in hardware interrupt context. If there is a need for such - * call, the low-level driver should first ACK the interrupt and perform the - * IEEE 802.11 code call after this, e.g., from a scheduled tasklet (in - * software interrupt context). - */ - -/* - * Frame format used when passing frame between low-level hardware drivers - * and IEEE 802.11 driver the same as used in the wireless media, i.e., - * buffers start with IEEE 802.11 header and include the same octets that - * are sent over air. - * - * If hardware uses IEEE 802.3 headers (and perform 802.3 <-> 802.11 - * conversion in firmware), upper layer 802.11 code needs to be changed to - * support this. - * - * If the receive frame format is not the same as the real frame sent - * on the wireless media (e.g., due to padding etc.), upper layer 802.11 code - * could be updated to provide support for such format assuming this would - * optimize the performance, e.g., by removing need to re-allocation and - * copying of the data. - */ - -/* Interface version (used for compatibility verification) */ -#define IEEE80211_VERSION 2 - - -/* Channel information structure. Low-level driver is expected to fill in chan, - * freq, and val fields. Other fields will be filled in by 80211.o based on - * hostapd information and low-level driver does not need to use them. The - * limits for each channel will be provided in 'struct ieee80211_conf' when - * configuring the low-level driver with hw->config callback. */ -struct ieee80211_channel { - short chan; /* channel number (IEEE 802.11) */ - short freq; /* frequency in MHz */ - int val; /* hw specific value for the channel */ - int flag; /* flag for hostapd use (IEEE80211_CHAN_*) */ - unsigned char power_level; - unsigned char antenna_max; -}; - -struct ieee80211_rate { - int rate; /* rate in 100 kbps */ - int val; /* hw specific value for the rate */ - int flags; /* IEEE80211_RATE_ flags */ - int val2; /* hw specific value for the rate when using short preamble - * (only when IEEE80211_RATE_PREAMBLE2 flag is set, i.e., for - * 2, 5.5, and 11 Mbps) */ - signed char min_rssi_ack; - unsigned char min_rssi_ack_delta; - - /* following fields are set by 80211.o and need not be filled by the - * low-level driver */ - int rate_inv; /* inverse of the rate (LCM(all rates) / rate) for - * optimizing channel utilization estimates */ -}; - -struct ieee80211_hw_modes { - int mode; - int num_channels; - struct ieee80211_channel *channels; - int num_rates; - struct ieee80211_rate *rates; - int xr_end; /* only used with Atheros XR */ -}; - -struct ieee80211_tx_queue_params { - int aifs; /* 0 .. 255; -1 = use default */ - int cw_min; /* 2^n-1: 1, 3, 7, .. , 1023; 0 = use default */ - int cw_max; /* 2^n-1: 1, 3, 7, .. , 1023; 0 = use default */ - int burst_time; /* maximum burst time in 0.1 ms (i.e., 10 = 1 ms); - * 0 = disabled */ -}; - -#define NUM_TX_DATA_QUEUES 6 - -struct ieee80211_tx_queue_stats_data { - unsigned int len; /* num packets in queue */ - unsigned int limit; /* queue len (soft) limit */ - unsigned int count; /* total num frames sent */ -}; - -struct ieee80211_tx_queue_stats { - struct ieee80211_tx_queue_stats_data data[NUM_TX_DATA_QUEUES]; -}; - -#ifndef IEEE80211_TX_QUEUE_NUMS -#define IEEE80211_TX_QUEUE_NUMS -/* TODO: these need to be synchronized with hostapd_ioctl.h; make a shared - * header file that can be included into low-level drivers, 80211.o, and - * hostapd */ -enum { - IEEE80211_TX_QUEUE_DATA0 = 0, - IEEE80211_TX_QUEUE_DATA1 = 1, - IEEE80211_TX_QUEUE_DATA2 = 2, - IEEE80211_TX_QUEUE_DATA3 = 3, - IEEE80211_TX_QUEUE_DATA4 = 4, - IEEE80211_TX_QUEUE_SVP = 5, - IEEE80211_TX_QUEUE_AFTER_BEACON = 6, - IEEE80211_TX_QUEUE_BEACON = 7 -}; -#endif /* IEEE80211_TX_QUEUE_NUMS */ - - -struct ieee80211_low_level_stats { - unsigned int dot11ACKFailureCount; - unsigned int dot11RTSFailureCount; - unsigned int dot11FCSErrorCount; - unsigned int dot11RTSSuccessCount; -}; - -/* Transmit control fields. This data structure is passed to low-level driver - * with each TX frame. The low-level driver is responsible of configuring - * hardware to use given values (depending on what is supported). */ -#define HW_KEY_IDX_INVALID -1 - -struct ieee80211_tx_control { - enum { PKT_NORMAL = 0, PKT_PROBE_RESP } pkt_type; - int tx_rate; /* Transmit rate, given as the hw specific value for the - * rate (from struct ieee80211_rate) */ - int rts_cts_rate; /* Transmit rate for RTS/CTS frame, given as the hw - * specific value for the rate (from - * struct ieee80211_rate) */ - /* 1 = only first attempt, 2 = one retry, .. */ - unsigned int retry_limit:8; - /* duration field for RTS/CTS frame */ - unsigned int rts_cts_duration:16; - /* TODO: change these bit flags to use one unsigned int variable and - * defines with BIT(n). These are copied to TX status structure and - * this will make the code faster and smaller. */ - unsigned int req_tx_status:1; /* request TX status callback for this - * frame */ - unsigned int do_not_encrypt:1; /* send this frame without encryption; - * e.g., for EAPOL frames */ - unsigned int use_rts_cts:1; /* Use RTS-CTS before sending frame. */ - unsigned int use_cts_protect:1; /* Use CTS protection for the frame - * (e.g., for combined 802.11g / - * 802.11b networks) */ - unsigned int no_ack:1; /* Tell the low level not to wait for an ack */ - unsigned int rate_ctrl_probe:1; - unsigned int clear_dst_mask:1; - unsigned int requeue:1; - /* following three flags are only used with Atheros Super A/G */ - unsigned int compress:1; - unsigned int turbo_prime_notify:1; /* notify HostaAPd after frame - * transmission */ - unsigned int fast_frame:1; - - unsigned int atheros_xr:1; /* only used with Atheros XR */ - - unsigned int power_level:8; /* per-packet transmit power level, in dBm - */ - unsigned int antenna_sel:4; /* 0 = default/diversity, - * 1 = Ant0, 2 = Ant1 */ - int key_idx:8; /* -1 = do not encrypt, >= 0 keyidx from hw->set_key() - */ - int icv_len:8; /* Length of the ICV/MIC field in octets */ - int iv_len:8; /* Length of the IV field in octets */ - unsigned int queue:4; /* hardware queue to use for this frame; - * 0 = highest, hw->queues-1 = lowest */ - unsigned int sw_retry_attempt:4; /* no. of times hw has tried to - * transmit frame (not incl. hw retries) */ - -#if 0 - int rateidx; /* internal 80211.o rateidx, to be copied to tx_status */ - int alt_retry_rate; /* retry rate for the last retries, given as the - * hw specific value for the rate (from - * struct ieee80211_rate). To be used to limit - * packet dropping when probing higher rates, if hw - * supports multiple retry rates. -1 = not used */ -#endif -}; - -#define IEEE80211_CB_MAGIC 0xAAB80211 - -struct ieee80211_tx_packet_data { - unsigned int magic; - struct ieee80211_tx_control control; - unsigned long jiffies; - struct ieee80211_sub_if_data *sdata; -}; - -#define RX_FLAG_MMIC_ERROR 0x1 -#define RX_FLAG_DECRYPTED 0x2 -#define RX_FLAG_XR_DOUBLE_CHIRP 0x4 - -/* Receive status. The low-level driver should provide this information - * (the subset supported by hardware) to the 802.11 code with each received - * frame. - * Current implementation copies this into skb->cb, so it must be less than - * 48 bytes. */ -struct ieee80211_rx_status { -#if 0 - u64 hosttime; - u64 mactime; -#endif - int freq; /* receive frequency in Mhz */ - int channel; - int phymode; - int ssi; - int antenna; - int rate; - int flag; -}; - -/* Transmit status. The low-level driver should provide this information - * (the subset supported by hardware) to the 802.11 code for each transmit - * frame. */ -struct ieee80211_tx_status { - /* flags copied from struct ieee80211_tx_control) */ - unsigned int req_tx_status:1; /* whether TX status was explicitly - * requested */ - unsigned int rate_ctrl_probe:1; /* whether this was a probe packet from - * rate control */ - unsigned int tx_filtered:1; - - /* following three fields are only used with Atheros Super A/G */ - unsigned int turbo_prime_notify:1; /* notify HostAPd - CTS for Turbo - * Prime is sent */ - int queue_length; /* information about TX queue */ - int queue_number; - - int ack; /* whether the TX frame was ACKed */ - int ack_signal; /* measured signal strength of the ACK frame */ - int excessive_retries; - int retry_count; - int rateidx; /* internal 80211.o rateidx, to be copied to tx_status */ -}; - - -struct ieee80211_conf { - int channel; /* IEEE 802.11 channel number */ - int freq; /* MHz */ - int channel_val; /* hw specific value for the channel */ - - int mode; /* IW_MODE_ */ - - int phymode; /* MODE_IEEE80211A, .. */ - unsigned int regulatory_domain; - int adm_status; - - int beacon_int; - - /* Bitfields, grouped together */ - - int sw_encrypt:1; - int sw_decrypt:1; - int short_slot_time:1; /* use IEEE 802.11g Short Slot Time */ - int ssid_hidden:1; /* do not broadcast the ssid */ - - /* these fields are used by low level drivers for hardware - * that generate beacons independently */ - u8 *ssid; - size_t ssid_len; - u8 *generic_elem; - size_t generic_elem_len; - - u8 power_level; /* transmit power limit for current - * regulatory domain; in dBm */ - u8 antenna_max; /* maximum antenna gain */ - short tx_power_reduction; /* in 0.1 dBm */ - - int antenna_sel; /* default antenna conf: - * 0 = default/diversity, - * 1 = Ant0, - * 2 = Ant1 */ - - int calib_int; /* hw/radio calibration interval in - * seconds */ - int antenna_def; - int antenna_mode; - - u8 bssid_mask[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff = 1 BSSID */ - int bss_count; - - int atheros_super_ag_compression; - int atheros_super_ag_fast_frame; - int atheros_super_ag_burst; - int atheros_super_ag_wme_ele; - int atheros_super_ag_turbo_g; - int atheros_super_ag_turbo_prime; - - int atheros_xr; - - u8 client_bssid[ETH_ALEN]; - - /* Following five fields are used for IEEE 802.11H */ - unsigned int radar_detect; - unsigned int spect_mgmt; - unsigned int quiet_duration; /* duration of quiet period */ - unsigned int quiet_offset; /* how far into the beacon is the quiet - * period */ - unsigned int quiet_period; -}; - - -typedef enum { ALG_NONE, ALG_WEP, ALG_TKIP, ALG_CCMP, ALG_NULL } -ieee80211_key_alg; - - -struct ieee80211_key_conf { - - int hw_key_idx; /* filled + used by low-level driver */ - ieee80211_key_alg alg; - int keylen; - - int force_sw_encrypt:1; /* to be cleared by low-level driver */ - int keyidx:8; /* WEP key index */ - int default_tx_key:1; /* This key is the new default TX key - * (used only for broadcast keys). */ - int default_wep_only:1; /* static WEP is the only configured security - * policy; this allows some low-level drivers - * to determine when hwaccel can be used */ - u8 key[0]; -}; - -#define IEEE80211_SCAN_START 1 -#define IEEE80211_SCAN_END 2 - -struct ieee80211_scan_conf { - int scan_channel; /* IEEE 802.11 channel number to do passive scan - * on */ - int scan_freq; /* new freq in MHz to switch to for passive scan - */ - int scan_channel_val; /* hw specific value for the channel */ - int scan_phymode; /* MODE_IEEE80211A, .. */ - unsigned char scan_power_level; - unsigned char scan_antenna_max; - - - int running_channel; /* IEEE 802.11 channel number we operate on - * normally */ - int running_freq; /* freq in MHz we're operating on normally */ - int running_channel_val; /* hw specific value for the channel */ - int running_phymode; - unsigned char running_power_level; - unsigned char running_antenna_max; - - int scan_time; /* time a scan will take in us */ - int tries; - - struct sk_buff *skb; /* skb to transmit before changing channels, maybe - * NULL for none */ - struct ieee80211_tx_control *tx_control; - -}; - -#ifndef IW_MODE_ADHOC -#define IW_MODE_ADHOC 1 -#endif - -#ifndef IW_MODE_INFRA -#define IW_MODE_INFRA 2 -#endif - -#ifndef IW_MODE_MASTER -#define IW_MODE_MASTER 3 -#endif - -#ifndef IW_MODE_MONITOR -#define IW_MODE_MONITOR 6 -#endif - -#define IEEE80211_SEQ_COUNTER_RX 0 -#define IEEE80211_SEQ_COUNTER_TX 1 - -typedef enum { - SET_KEY, DISABLE_KEY, REMOVE_ALL_KEYS, - ENABLE_COMPRESSION, DISABLE_COMPRESSION -} set_key_cmd; - -/* Configuration block used by the low-level driver to tell 802.11 code about - * supported hardware features and to pass function pointers for callback - * functions. */ -struct ieee80211_hw { - int version; /* IEEE80211_VERSION */ - - /* Driver name */ - char *name; - - /* TODO: frame_type 802.11/802.3, sw_encryption requirements */ - - /* Some wireless LAN chipsets generate beacons in the hardware/firmware - * and others rely on host generated beacons. This option is used to - * configure upper layer IEEE 802.11 module to generate beacons. The - * low-level driver can use ieee80211_beacon_get() to fetch next - * beacon frame. */ - int host_gen_beacon:1; - - - /* Some devices handle decryption internally and do not - * indicate whether the frame was encrypted (unencrypted frames - * will be dropped by the hardware, unless specifically allowed - * through) */ - int device_hides_wep:1; - - /* Whether RX frames passed to ieee80211_rx() include FCS in the end - */ - int rx_includes_fcs:1; - - /* Some wireless LAN chipsets buffer broadcast/multicast frames for - * power saving stations in the hardware/firmware and others rely on - * the host system for such buffering. This option is used to - * configure upper layer IEEE 802.11 to buffer broadcast/multicast - * frames when there are power saving stations so that low-level driver - * can fetch them with ieee80211_get_buffered_bc(). */ - int host_broadcast_ps_buffering:1; - - int wep_include_iv:1; - int data_nullfunc_ack:1; /* will data nullfunc frames get proper - * TX status callback */ - - /* Force sw version of encryption for TKIP packets if WMM is enabled. - */ - int no_tkip_wmm_hwaccel:1; - - /* 1 if the payload needs to be padded at even boundaries after the - * header */ - unsigned int extra_hdr_room:1; - - /* Some devices handle Michael MIC internally and do not include MIC in - * the received packets given to 80211.o. device_strips_mic must be set - * for such devices. ISWEP bit is still expected to be set in the IEEE - * 802.11 header with this option unlike with device_hides_wep option. - */ - unsigned int device_strips_mic:1; - - /* 1 = low-level driver supports skb fraglist (NETIF_F_FRAGLIST), i.e., - * more than one skb per frame */ - unsigned int fraglist; - - /* This is the time in us to change channels - */ - int channel_change_time; - - int num_modes; - struct ieee80211_hw_modes *modes; - - /* Handler that 802.11 module calls for each transmitted frame. - * skb contains the buffer starting from the IEEE 802.11 header. - * The low-level driver should send the frame out based on - * configuration in the TX control data. */ - int (*tx)(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_tx_control *control); - - /* Handler for performing hardware reset. */ - int (*reset)(struct net_device *dev); - - /* Handler that is called when any netdevice attached to the hardware - * device is set UP for the first time. This can be used, e.g., to - * enable interrupts and beacon sending. */ - int (*open)(struct net_device *dev); - - /* Handler that is called when the last netdevice attached to the - * hardware device is set DOWN. This can be used, e.g., to disable - * interrupts and beacon sending. */ - int (*stop)(struct net_device *dev); - - /* Handler for configuration requests. IEEE 802.11 code calls this - * function to change hardware configuration, e.g., channel. */ - int (*config)(struct net_device *dev, struct ieee80211_conf *conf); - - /* Set TIM bit handler. If the hardware/firmware takes care of beacon - * generation, IEEE 802.11 code uses this function to tell the - * low-level to set (or clear if set==0) TIM bit for the given aid. If - * host system is used to generate beacons, this handler is not used - * and low-level driver should set it to NULL. */ - int (*set_tim)(struct net_device *dev, int aid, int set); - - /* Set encryption key. IEEE 802.11 module calls this function to set - * encryption keys. addr is ff:ff:ff:ff:ff:ff for default keys and - * station hwaddr for individual keys. aid of the station is given - * to help low-level driver in selecting which key->hw_key_idx to use - * for this key. TX control data will use the hw_key_idx selected by - * the low-level driver. */ - int (*set_key)(struct net_device *dev, set_key_cmd cmd, u8 *addr, - struct ieee80211_key_conf *key, int aid); - - /* Set TX key index for default/broadcast keys. This is needed in cases - * where wlan card is doing full WEP/TKIP encapsulation (wep_include_iv - * is not set), in other cases, this function pointer can be set to - * NULL since 80211.o takes care of selecting the key index for each - * TX frame. */ - int (*set_key_idx)(struct net_device *dev, int idx); - - /* Enable/disable IEEE 802.1X. This item requests wlan card to pass - * unencrypted EAPOL-Key frames even when encryption is configured. - * If the wlan card does not require such a configuration, this - * function pointer can be set to NULL. 80211.o */ - int (*set_ieee8021x)(struct net_device *dev, int use_ieee8021x); - - /* Set port authorization state (IEEE 802.1X PAE) to be authorized - * (authorized=1) or unauthorized (authorized=0). This function can be - * used if the wlan hardware or low-level driver implements PAE. - * 80211.o module will anyway filter frames based on authorization - * state, so this function pointer can be NULL if low-level driver does - * not require event notification about port state changes. */ - int (*set_port_auth)(struct net_device *dev, u8 *addr, int authorized); - - /* Ask the hardware to do a passive scan on a new channel. The hardware - * will do what ever is required to nicely leave the current channel - * including transmit any CTS packets, etc. */ - int (*passive_scan)(struct net_device *dev, int state, - struct ieee80211_scan_conf *conf); - - /* return low-level statistics */ - int (*get_stats)(struct net_device *dev, - struct ieee80211_low_level_stats *stats); - - /* Enable/disable test modes; mode = IEEE80211_TEST_* */ - int (*test_mode)(struct net_device *dev, int mode); - - /* Configuration of test parameters */ - int (*test_param)(struct net_device *dev, int param, int value); - - /* Change MAC address. addr is pointer to struct sockaddr. */ - int (*set_mac_address)(struct net_device *dev, void *addr); - - /* For devices that generate their own beacons and probe response - * or association responses this updates the state of privacy_invoked - * returns 0 for success or an error number */ - - int (*set_privacy_invoked)(struct net_device *dev, - int privacy_invoked); - - /* For devices that have internal sequence counters, allow 802.11 - * code to access the current value of a counter */ - int (*get_sequence_counter)(struct net_device *dev, - u8* addr, u8 keyidx, u8 txrx, - u32* iv32, u16* iv16); - - /* Configuration of RTS threshold (if device needs it) */ - int (*set_rts_threshold)(struct net_device *dev, u32 value); - - /* Configuration of fragmentation threshold (if device needs it) */ - int (*set_frag_threshold)(struct net_device *dev, u32 value); - - /* Configuration of retry limits (if device needs it) */ - int (*set_retry_limit)(struct net_device *dev, u32 short_retry, - u32 long_retr); - - /* Number of STAs in STA table notification (NULL = disabled) */ - void (*sta_table_notification)(struct net_device *dev, int num_sta); - - /* Configure TX queue parameters (EDCF (aifs, cw_min, cw_max), - * bursting) for a hardware TX queue. - * queue = IEEE80211_TX_QUEUE_*. */ - int (*conf_tx)(struct net_device *dev, int queue, - const struct ieee80211_tx_queue_params *params); - - /* Get statistics of the current TX queue status. This is used to get - * number of currently queued packets (queue length), maximum queue - * size (limit), and total number of packets sent using each TX queue - * (count). This information is used for WMM to find out which TX - * queues have room for more packets and by hostapd to provide - * statistics about the current queueing state to external programs. */ - int (*get_tx_stats)(struct net_device *dev, - struct ieee80211_tx_queue_stats *stats); - - /* Number of available hardware TX queues for data packets. - * WMM requires at least four queues. */ - int queues; - - /* Get the current TSF timer value from firmware/hardware. Currently, - * this is only used for IBSS mode debugging and, as such, is not a - * required function. */ - u64 (*get_tsf)(struct net_device *dev); - - /* Reset the TSF timer and allow firmware/hardware to synchronize with - * other STAs in the IBSS. This is only used in IBSS mode. This - * function is optional if the firmware/hardware takes full care of - * TSF synchronization. */ - void (*reset_tsf)(struct net_device *dev); - - /* Setup beacon data for IBSS beacons. Unlike access point (Master), - * IBSS uses a fixed beacon frame which is configured using this - * function. This handler is required only for IBSS mode. */ - int (*beacon_update)(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_tx_control *control); - - /* Determine whether the last IBSS beacon was sent by us. This is - * needed only for IBSS mode and the result of this function is used to - * determine whether to reply to Probe Requests. */ - int (*tx_last_beacon)(struct net_device *dev); - - /* Optional handler for XR-in-use notification. */ - int (*atheros_xr_in_use)(struct net_device *dev, int in_use); -}; - -/* Allocate a new hardware device. This must be called once for each - * hardware device. The returned pointer must be used to refer to this - * device when calling other functions. 802.11 code allocates a private data - * area for the low-level driver. The size of this area is given as - * priv_data_len. ieee80211_dev_hw_data() is used to get a pointer to the - * private data area. - * - * Note: in this version of the interface the returned pointer is struct - * net_device *. This may change in the future and low-level driver should - * not refer the device data directly to remain compatible with the future - * versions of the interface. */ -struct net_device *ieee80211_alloc_hw(size_t priv_data_len, - void (*setup)(struct net_device *)); - -/* Register hardware device to the IEEE 802.11 code and kernel. Low-level - * drivers must call this function before using any other IEEE 802.11 - * function. */ -int ieee80211_register_hw(struct net_device *dev, struct ieee80211_hw *hw); - -/* This function is allowed to update hardware configuration (e.g., list of - * supported operation modes and rates). */ -int ieee80211_update_hw(struct net_device *dev, struct ieee80211_hw *hw); - -/* Unregister a hardware device. This function instructs 802.11 code to free - * allocated resources and unregister netdevices from the kernel. */ -void ieee80211_unregister_hw(struct net_device *dev); - -/* Free allocated net_device including private data of a driver. */ -void ieee80211_free_hw(struct net_device *dev); - -/* Receive frame callback function. The low-level driver uses this function to - * send received frames to the IEEE 802.11 code. Receive buffer (skb) must - * start with IEEE 802.11 header. */ -void ieee80211_rx(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *status); -void ieee80211_rx_irqsafe(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_rx_status *status); - -/* Transmit status callback function. The low-level driver must call this - * function to report transmit status for all the TX frames that had - * req_tx_status set in the transmit control fields. In addition, this should - * be called at least for all unicast frames to provide information for TX rate - * control algorithm. In order to maintain all statistics, this function is - * recommended to be called after each frame, including multicast/broadcast, is - * sent. */ -void ieee80211_tx_status(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_tx_status *status); -void ieee80211_tx_status_irqsafe(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_tx_status *status); - -/* Beacon generation function. If the beacon frames are generated by the host - * system (i.e., not in hardware/firmware), the low-level driver uses this - * function to receive the next beacon frame from the 802.11 code. The - * low-level is responsible for calling this function before beacon data is - * needed (e.g., based on hardware interrupt). Returned skb is used only once - * and low-level driver is responsible of freeing it. */ -struct sk_buff * ieee80211_beacon_get(struct net_device *dev, int bss_idx, - struct ieee80211_tx_control *control); - -/* Function for accessing buffered broadcast and multicast frames. If - * hardware/firmware does not implement buffering of broadcast/multicast - * frames when power saving is used, 802.11 code buffers them in the host - * memory. The low-level driver uses this function to fetch next buffered - * frame. In most cases, this is used when generating beacon frame. This - * function returns a pointer to the next buffered skb or NULL if no more - * buffered frames are available. - * - * Note: buffered frames are returned only after DTIM beacon frame was - * generated with ieee80211_beacon_get() and the low-level driver must thus - * call ieee80211_beacon_get() first. ieee80211_get_buffered_bc() returns - * NULL if the previous generated beacon was not DTIM, so the low-level driver - * does not need to check for DTIM beacons separately and should be able to - * use common code for all beacons. */ -struct sk_buff * -ieee80211_get_buffered_bc(struct net_device *dev, int bss_idx, - struct ieee80211_tx_control *control); - -/* Low level drivers that have their own MLME and MAC indicate - * the aid for an associating station with this call */ -int ieee80211_set_aid_for_sta(struct net_device *dev, u8 *peer_address, - u16 aid); - - -/* Given an sk_buff with a raw 802.11 header at the data pointer this function - * returns the 802.11 header length in bytes (not including encryption - * headers). If the data in the sk_buff is too short to contain a valid 802.11 - * header the function returns 0. - */ -int ieee80211_get_hdrlen_from_skb(struct sk_buff *skb); - -/* Like ieee80211_get_hdrlen_from_skb() but takes a FC in CPU order. */ -int ieee80211_get_hdrlen(u16 fc); - -/* Function for net interface operation. IEEE 802.11 may use multiple kernel - * netdevices for each hardware device. The low-level driver does not "see" - * these interfaces, so it should use this function to perform netif - * operations on all interface. */ -typedef enum { - NETIF_ATTACH, NETIF_DETACH, NETIF_START, NETIF_STOP, NETIF_WAKE, - NETIF_IS_STOPPED, NETIF_UPDATE_TX_START -} Netif_Oper; -int ieee80211_netif_oper(struct net_device *dev, Netif_Oper op); - - -/* - * Function to get hardware configuration information - * by the low level driver should it need it. - */ -struct ieee80211_conf * -ieee80211_get_hw_conf(struct net_device *dev); - - -/* Return a pointer to the low-level private data area for the given device. */ -void * ieee80211_dev_hw_data(struct net_device *dev); -/* Return a pointer to network statistics data area for the given device. */ -void * ieee80211_dev_stats(struct net_device *dev); - -/* Function to indicate Radar Detection. The low level driver must call this - * function to indicate the presence of radar in the current channel. - * Additionally the radar type also could be sent */ -int ieee80211_radar_status(struct net_device *dev, int channel, int radar, - int radar_type); - -/* Test modes */ -enum { - IEEE80211_TEST_DISABLE = 0 /* terminate testing */, - IEEE80211_TEST_UNMASK_CHANNELS = 1 /* allow all channels to be used */, - IEEE80211_TEST_CONTINUOUS_TX = 2, -}; - -/* Test parameters */ -enum { - /* TX power in hardware specific raw value */ - IEEE80211_TEST_PARAM_TX_POWER_RAW = 0, - /* TX rate in hardware specific raw value */ - IEEE80211_TEST_PARAM_TX_RATE_RAW = 1, - /* Continuous TX pattern (32-bit) */ - IEEE80211_TEST_PARAM_TX_PATTERN = 2, - /* TX power in 0.1 dBm, 100 = 10 dBm */ - IEEE80211_TEST_PARAM_TX_POWER = 3, - /* TX rate in 100 kbps, 540 = 54 Mbps */ - IEEE80211_TEST_PARAM_TX_RATE = 4, - IEEE80211_TEST_PARAM_TX_ANT_SEL_RAW = 5, -}; - -/* ieee80211_tx_led called with state == 1 when the first frame is queued - * with state == 0 when the last frame is transmitted and tx queue is empty - */ -void ieee80211_tx_led(int state, struct net_device *dev); -/* ieee80211_rx_led is called each time frame is received, state is not used - * (== 2) - */ -void ieee80211_rx_led(int state, struct net_device *dev); - - -/* IEEE 802.11 defines */ - -#define FCS_LEN 4 - -#define WLAN_FC_PVER 0x0003 -#define WLAN_FC_TODS 0x0100 -#define WLAN_FC_FROMDS 0x0200 -#define WLAN_FC_MOREFRAG 0x0400 -#define WLAN_FC_RETRY 0x0800 -#define WLAN_FC_PWRMGT 0x1000 -#define WLAN_FC_MOREDATA 0x2000 -#define WLAN_FC_ISWEP 0x4000 -#define WLAN_FC_ORDER 0x8000 - -#define WLAN_FC_GET_TYPE(fc) (((fc) & 0x000c) >> 2) -#define WLAN_FC_GET_STYPE(fc) (((fc) & 0x00f0) >> 4) - -#define WLAN_GET_SEQ_FRAG(seq) ((seq) & 0x000f) -#define WLAN_GET_SEQ_SEQ(seq) ((seq) >> 4) - -#define WLAN_FC_DATA_PRESENT(fc) (((fc) & 0x4c) == 0x08) - -#define WLAN_FC_TYPE_MGMT 0 -#define WLAN_FC_TYPE_CTRL 1 -#define WLAN_FC_TYPE_DATA 2 - -/* management */ -#define WLAN_FC_STYPE_ASSOC_REQ 0 -#define WLAN_FC_STYPE_ASSOC_RESP 1 -#define WLAN_FC_STYPE_REASSOC_REQ 2 -#define WLAN_FC_STYPE_REASSOC_RESP 3 -#define WLAN_FC_STYPE_PROBE_REQ 4 -#define WLAN_FC_STYPE_PROBE_RESP 5 -#define WLAN_FC_STYPE_BEACON 8 -#define WLAN_FC_STYPE_ATIM 9 -#define WLAN_FC_STYPE_DISASSOC 10 -#define WLAN_FC_STYPE_AUTH 11 -#define WLAN_FC_STYPE_DEAUTH 12 -#define WLAN_FC_STYPE_ACTION 13 - -/* control */ -#define WLAN_FC_STYPE_PSPOLL 10 -#define WLAN_FC_STYPE_RTS 11 -#define WLAN_FC_STYPE_CTS 12 -#define WLAN_FC_STYPE_ACK 13 -#define WLAN_FC_STYPE_CFEND 14 -#define WLAN_FC_STYPE_CFENDACK 15 - -/* data */ -#define WLAN_FC_STYPE_DATA 0 -#define WLAN_FC_STYPE_DATA_CFACK 1 -#define WLAN_FC_STYPE_DATA_CFPOLL 2 -#define WLAN_FC_STYPE_DATA_CFACKPOLL 3 -#define WLAN_FC_STYPE_NULLFUNC 4 -#define WLAN_FC_STYPE_CFACK 5 -#define WLAN_FC_STYPE_CFPOLL 6 -#define WLAN_FC_STYPE_CFACKPOLL 7 -#define WLAN_FC_STYPE_QOS_DATA 8 -#define WLAN_FC_STYPE_QOS_DATA_CFACK 9 -#define WLAN_FC_STYPE_QOS_DATA_CFPOLL 10 -#define WLAN_FC_STYPE_QOS_DATA_CFACKPOLL 11 -#define WLAN_FC_STYPE_QOS_NULLFUNC 12 -#define WLAN_FC_STYPE_QOS_CFACK 13 -#define WLAN_FC_STYPE_QOS_CFPOLL 14 -#define WLAN_FC_STYPE_QOS_CFACKPOLL 15 - - -#define IEEE80211_MAX_FRAG_THRESHOLD 2346 -#define IEEE80211_MAX_RTS_THRESHOLD 2347 - -struct ieee80211_hdr { - u16 frame_control; - u16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; - u16 seq_ctrl; - u8 addr4[6]; -} __attribute__ ((packed)); - -/* return a pointer to the source address (SA) */ -static inline u8 *ieee80211_get_SA(struct ieee80211_hdr *hdr) -{ - u8 *raw = (u8 *) hdr; - u8 tofrom = (*(raw+1)) & 3; /* get the TODS and FROMDS bits */ - - switch (tofrom) { - case 2: - return hdr->addr3; - case 3: - return hdr->addr4; - } - return hdr->addr2; -} - -/* return a pointer to the destination address (DA) */ -static inline u8 *ieee80211_get_DA(struct ieee80211_hdr *hdr) -{ - u8 *raw = (u8 *) hdr; - u8 to_ds = (*(raw+1)) & 1; /* get the TODS bit */ - - if (to_ds) - return hdr->addr3; - return hdr->addr1; -} - -static inline int ieee80211_get_morefrag(struct ieee80211_hdr *hdr) -{ - return (le16_to_cpu(hdr->frame_control) & WLAN_FC_MOREFRAG) != 0; -} - -#endif /* IEEE80211_H */ diff --git a/target/linux/package/ieee80211-dscape/src/include/net/ieee80211_common.h b/target/linux/package/ieee80211-dscape/src/include/net/ieee80211_common.h deleted file mode 100644 index 68c1663861..0000000000 --- a/target/linux/package/ieee80211-dscape/src/include/net/ieee80211_common.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * IEEE 802.11 driver (80211.o) -- hostapd interface - * Copyright 2002-2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef IEEE80211_COMMON_H -#define IEEE80211_COMMON_H - -/* - * This is common header information with user space. It is used on all - * frames sent to wlan#ap interface. - */ - -#define IEEE80211_FI_VERSION 0x80211001 - -struct ieee80211_frame_info { - u32 version; - u32 length; - u64 mactime; - u64 hosttime; - u32 phytype; - u32 channel; - u32 datarate; - u32 antenna; - u32 priority; - u32 ssi_type; - u32 ssi_signal; - u32 ssi_noise; - u32 preamble; - u32 encoding; - - /* Note: this structure is otherwise identical to capture format used - * in linux-wlan-ng, but this additional field is used to provide meta - * data about the frame to hostapd. This was the easiest method for - * providing this information, but this might change in the future. */ - u32 msg_type; -} __attribute__ ((packed)); - - -enum ieee80211_msg_type { - ieee80211_msg_normal = 0, - ieee80211_msg_tx_callback_ack = 1, - ieee80211_msg_tx_callback_fail = 2, - ieee80211_msg_passive_scan = 3, - ieee80211_msg_wep_frame_unknown_key = 4, - ieee80211_msg_michael_mic_failure = 5, - ieee80211_msg_monitor = 6, - ieee80211_msg_sta_not_assoc = 7, - ieee80211_msg_set_aid_for_sta = 8 /* used by Intersil MVC driver */, - ieee80211_msg_key_threshold_notification = 9, - ieee80211_msg_radar = 11, -}; - -struct ieee80211_msg_set_aid_for_sta { - char sta_address[ETH_ALEN]; - u16 aid; -}; - -struct ieee80211_msg_key_notification { - int tx_rx_count; - char ifname[IFNAMSIZ]; - u8 addr[ETH_ALEN]; /* ff:ff:ff:ff:ff:ff for broadcast keys */ -}; - - -enum ieee80211_phytype { - ieee80211_phytype_fhss_dot11_97 = 1, - ieee80211_phytype_dsss_dot11_97 = 2, - ieee80211_phytype_irbaseband = 3, - ieee80211_phytype_dsss_dot11_b = 4, - ieee80211_phytype_pbcc_dot11_b = 5, - ieee80211_phytype_ofdm_dot11_g = 6, - ieee80211_phytype_pbcc_dot11_g = 7, - ieee80211_phytype_ofdm_dot11_a = 8, - ieee80211_phytype_dsss_dot11_turbog = 255, - ieee80211_phytype_dsss_dot11_turbo = 256, -}; - -enum ieee80211_ssi_type { - ieee80211_ssi_none = 0, - ieee80211_ssi_norm = 1, /* normalized, 0-1000 */ - ieee80211_ssi_dbm = 2, - ieee80211_ssi_raw = 3, /* raw SSI */ -}; - -struct ieee80211_radar_info { - int channel; - int radar; - int radar_type; -}; - -#endif /* IEEE80211_COMMON_H */ diff --git a/target/linux/package/ieee80211-dscape/src/include/net/ieee80211_mgmt.h b/target/linux/package/ieee80211-dscape/src/include/net/ieee80211_mgmt.h deleted file mode 100644 index 86732684ea..0000000000 --- a/target/linux/package/ieee80211-dscape/src/include/net/ieee80211_mgmt.h +++ /dev/null @@ -1,196 +0,0 @@ -/* - * IEEE 802.11 -- shared defines for 80211.o and hostapd - * Copyright 2002, Jouni Malinen - * Copyright 2002-2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef IEEE802_11_MGMT_H -#define IEEE802_11_MGMT_H - - -struct ieee80211_mgmt { - u16 frame_control; - u16 duration; - u8 da[6]; - u8 sa[6]; - u8 bssid[6]; - u16 seq_ctrl; - union { - struct { - u16 auth_alg; - u16 auth_transaction; - u16 status_code; - /* possibly followed by Challenge text */ - u8 variable[0]; - } __attribute__ ((packed)) auth; - struct { - u16 reason_code; - } __attribute__ ((packed)) deauth; - struct { - u16 capab_info; - u16 listen_interval; - /* followed by SSID and Supported rates */ - u8 variable[0]; - } __attribute__ ((packed)) assoc_req; - struct { - u16 capab_info; - u16 status_code; - u16 aid; - /* followed by Supported rates */ - u8 variable[0]; - } __attribute__ ((packed)) assoc_resp, reassoc_resp; - struct { - u16 capab_info; - u16 listen_interval; - u8 current_ap[6]; - /* followed by SSID and Supported rates */ - u8 variable[0]; - } __attribute__ ((packed)) reassoc_req; - struct { - u16 reason_code; - } __attribute__ ((packed)) disassoc; - struct { - u8 timestamp[8]; - u16 beacon_int; - u16 capab_info; - /* followed by some of SSID, Supported rates, - * FH Params, DS Params, CF Params, IBSS Params, TIM */ - u8 variable[0]; - } __attribute__ ((packed)) beacon; - struct { - /* only variable items: SSID, Supported rates */ - u8 variable[0]; - } __attribute__ ((packed)) probe_req; - struct { - u8 timestamp[8]; - u16 beacon_int; - u16 capab_info; - /* followed by some of SSID, Supported rates, - * FH Params, DS Params, CF Params, IBSS Params */ - u8 variable[0]; - } __attribute__ ((packed)) probe_resp; - struct { - u8 category; - union { - struct { - u8 action_code; - u8 dialog_token; - u8 status_code; - u8 variable[0]; - } __attribute__ ((packed)) wme_action; - struct{ - u8 action_code; - u8 element_id; - u8 length; - u8 switch_mode; - u8 new_chan; - u8 switch_count; - } __attribute__((packed)) chan_switch; - } u; - } __attribute__ ((packed)) action; - } u; -} __attribute__ ((packed)); - - -/* Authentication algorithms */ -#define WLAN_AUTH_OPEN 0 -#define WLAN_AUTH_SHARED_KEY 1 -#define WLAN_AUTH_LEAP 128 - -#define WLAN_AUTH_CHALLENGE_LEN 128 - -#define WLAN_CAPABILITY_ESS BIT(0) -#define WLAN_CAPABILITY_IBSS BIT(1) -#define WLAN_CAPABILITY_CF_POLLABLE BIT(2) -#define WLAN_CAPABILITY_CF_POLL_REQUEST BIT(3) -#define WLAN_CAPABILITY_PRIVACY BIT(4) -#define WLAN_CAPABILITY_SHORT_PREAMBLE BIT(5) -#define WLAN_CAPABILITY_PBCC BIT(6) -#define WLAN_CAPABILITY_CHANNEL_AGILITY BIT(7) -/* 802.11h */ -#define WLAN_CAPABILITY_SPECTRUM_MGMT BIT(8) -#define WLAN_CAPABILITY_SHORT_SLOT_TIME BIT(10) -#define WLAN_CAPABILITY_DSSS_OFDM BIT(13) - -/* Status codes */ -#define WLAN_STATUS_SUCCESS 0 -#define WLAN_STATUS_UNSPECIFIED_FAILURE 1 -#define WLAN_STATUS_CAPS_UNSUPPORTED 10 -#define WLAN_STATUS_REASSOC_NO_ASSOC 11 -#define WLAN_STATUS_ASSOC_DENIED_UNSPEC 12 -#define WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG 13 -#define WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION 14 -#define WLAN_STATUS_CHALLENGE_FAIL 15 -#define WLAN_STATUS_AUTH_TIMEOUT 16 -#define WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA 17 -#define WLAN_STATUS_ASSOC_DENIED_RATES 18 -/* 802.11b */ -#define WLAN_STATUS_ASSOC_DENIED_NOSHORT 19 -#define WLAN_STATUS_ASSOC_DENIED_NOPBCC 20 -#define WLAN_STATUS_ASSOC_DENIED_NOAGILITY 21 -/* 802.11h */ -#define WLAN_STATUS_SPEC_MGMT_REQUIRED 22 -#define WLAN_STATUS_PWR_CAPABILITY_NOT_VALID 23 -#define WLAN_STATUS_SUPPORTED_CHANNEL_NOT_VALID 24 -/* 802.11g */ -#define WLAN_STATUS_ASSOC_DENOED_NO_SHORT_SLOT_TIME 25 -#define WLAN_STATUS_ASSOC_DENOED_NO_ER_PBCC 26 -#define WLAN_STATUS_ASSOC_DENOED_NO_DSSS_OFDM 27 - - -/* Reason codes */ -#define WLAN_REASON_UNSPECIFIED 1 -#define WLAN_REASON_PREV_AUTH_NOT_VALID 2 -#define WLAN_REASON_DEAUTH_LEAVING 3 -#define WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY 4 -#define WLAN_REASON_DISASSOC_AP_BUSY 5 -#define WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 -#define WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA 7 -#define WLAN_REASON_DISASSOC_STA_HAS_LEFT 8 -#define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 -/* 802.11h */ -#define WLAN_REASON_PWR_CAPABILITY_NOT_VALID 10 -#define WLAN_REASON_SUPPORTED_CHANNEL_NOT_VALID 11 - -#define WLAN_REASON_MIC_FAILURE 14 - - -/* Information Element IDs */ -#define WLAN_EID_SSID 0 -#define WLAN_EID_SUPP_RATES 1 -#define WLAN_EID_FH_PARAMS 2 -#define WLAN_EID_DS_PARAMS 3 -#define WLAN_EID_CF_PARAMS 4 -#define WLAN_EID_TIM 5 -#define WLAN_EID_IBSS_PARAMS 6 -#define WLAN_EID_COUNTRY 7 -#define WLAN_EID_CHALLENGE 16 -/* EIDs defined as part fo 11h - starts */ -#define WLAN_EID_PWR_CONSTRAINT 32 -#define WLAN_EID_PWR_CAPABILITY 33 -#define WLAN_EID_TPC_REQUEST 34 -#define WLAN_EID_TPC_REPORT 35 -#define WLAN_EID_SUPPORTED_CHANNELS 36 -#define WLAN_EID_CHANNEL_SWITCH 37 -#define WLAN_EID_MEASURE_REQUEST 38 -#define WLAN_EID_MEASURE_REPORT 39 -#define WLAN_EID_QUITE 40 -#define WLAN_EID_IBSS_DFS 41 -/* EIDs defined as part fo 11h - ends */ -#define WLAN_EID_ERP_INFO 42 -#define WLAN_EID_RSN 48 -#define WLAN_EID_EXT_SUPP_RATES 50 -#define WLAN_EID_WPA 221 -#define WLAN_EID_GENERIC 221 -#define WLAN_EID_VENDOR_SPECIFIC 221 - - - -#define ATHEROS_INFO_USEXR BIT(3) - -#endif /* IEEE802_11_MGMT_H */ diff --git a/target/linux/package/ieee80211-dscape/src/include/net/ieee80211_shared.h b/target/linux/package/ieee80211-dscape/src/include/net/ieee80211_shared.h deleted file mode 100644 index 95355bb222..0000000000 --- a/target/linux/package/ieee80211-dscape/src/include/net/ieee80211_shared.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * IEEE 802.11 -- shared defines for low-level drivers, 80211.o, and hostapd - * Copyright 2002-2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef IEEE80211_SHARED_H -#define IEEE80211_SHARED_H - -/* 802.11g is backwards-compatible with 802.11b, so a wlan card can - * actually be both in 11b and 11g modes at the same time. */ -enum { - MODE_IEEE80211A = 0 /* IEEE 802.11a */, - MODE_IEEE80211B = 1 /* IEEE 802.11b only */, - MODE_ATHEROS_TURBO = 2 /* Atheros Turbo mode (2x.11a at 5 GHz) */, - MODE_IEEE80211G = 3 /* IEEE 802.11g (and 802.11b compatibility) */, - MODE_ATHEROS_TURBOG = 4 /* Atheros Turbo mode (2x.11g at 2.4 GHz) */, - MODE_ATHEROS_PRIME = 5 /* Atheros Dynamic Turbo mode */, - MODE_ATHEROS_PRIMEG = 6 /* Atheros Dynamic Turbo mode G */, - MODE_ATHEROS_XR = 7 /* Atheros XR mode */, - NUM_IEEE80211_MODES = 8 -}; - -#define IEEE80211_CHAN_W_SCAN 0x00000001 -#define IEEE80211_CHAN_W_ACTIVE_SCAN 0x00000002 -#define IEEE80211_CHAN_W_IBSS 0x00000004 - -/* Low-level driver should set PREAMBLE2, OFDM, CCK, and TURBO flags. - * BASIC, SUPPORTED, ERP, and MANDATORY flags are set in 80211.o based on the - * configuration. */ -#define IEEE80211_RATE_ERP 0x00000001 -#define IEEE80211_RATE_BASIC 0x00000002 -#define IEEE80211_RATE_PREAMBLE2 0x00000004 -#define IEEE80211_RATE_SUPPORTED 0x00000010 -#define IEEE80211_RATE_OFDM 0x00000020 -#define IEEE80211_RATE_CCK 0x00000040 -#define IEEE80211_RATE_TURBO 0x00000080 -#define IEEE80211_RATE_MANDATORY 0x00000100 -#define IEEE80211_RATE_XR 0x00000200 - -#define IEEE80211_RATE_CCK_2 (IEEE80211_RATE_CCK | IEEE80211_RATE_PREAMBLE2) -#define IEEE80211_RATE_MODULATION(f) \ -(f & (IEEE80211_RATE_CCK | IEEE80211_RATE_OFDM)) - - -#endif /* IEEE80211_SHARED_H */ diff --git a/target/linux/package/ieee80211-dscape/src/michael.c b/target/linux/package/ieee80211-dscape/src/michael.c deleted file mode 100644 index 0f844f7895..0000000000 --- a/target/linux/package/ieee80211-dscape/src/michael.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Michael MIC implementation - optimized for TKIP MIC operations - * Copyright 2002-2003, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include - -#include "michael.h" - -static inline u32 rotr(u32 val, int bits) -{ - return (val >> bits) | (val << (32 - bits)); -} - - -static inline u32 rotl(u32 val, int bits) -{ - return (val << bits) | (val >> (32 - bits)); -} - - -static inline u32 xswap(u32 val) -{ - return ((val & 0xff00ff00) >> 8) | ((val & 0x00ff00ff) << 8); -} - - -#define michael_block(l, r) \ -do { \ - r ^= rotl(l, 17); \ - l += r; \ - r ^= xswap(l); \ - l += r; \ - r ^= rotl(l, 3); \ - l += r; \ - r ^= rotr(l, 2); \ - l += r; \ -} while (0) - - -static inline u32 michael_get32(u8 *data) -{ - return data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24); -} - - -static inline void michael_put32(u32 val, u8 *data) -{ - data[0] = val & 0xff; - data[1] = (val >> 8) & 0xff; - data[2] = (val >> 16) & 0xff; - data[3] = (val >> 24) & 0xff; -} - - -void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, - u8 *data, size_t data_len, u8 *mic) -{ - u32 l, r, val; - size_t block, blocks, left; - - l = michael_get32(key); - r = michael_get32(key + 4); - - /* A pseudo header (DA, SA, Priority, 0, 0, 0) is used in Michael MIC - * calculation, but it is _not_ transmitted */ - l ^= michael_get32(da); - michael_block(l, r); - l ^= da[4] | (da[5] << 8) | (sa[0] << 16) | (sa[1] << 24); - michael_block(l, r); - l ^= michael_get32(&sa[2]); - michael_block(l, r); - l ^= priority; - michael_block(l, r); - - /* Real data */ - blocks = data_len / 4; - left = data_len % 4; - - for (block = 0; block < blocks; block++) { - l ^= michael_get32(&data[block * 4]); - michael_block(l, r); - } - - /* Partial block of 0..3 bytes and padding: 0x5a + 4..7 zeros to make - * total length a multiple of 4. */ - val = 0x5a; - while (left > 0) { - val <<= 8; - left--; - val |= data[blocks * 4 + left]; - } - l ^= val; - michael_block(l, r); - /* last block is zero, so l ^ 0 = l */ - michael_block(l, r); - - michael_put32(l, mic); - michael_put32(r, mic + 4); -} diff --git a/target/linux/package/ieee80211-dscape/src/michael.h b/target/linux/package/ieee80211-dscape/src/michael.h deleted file mode 100644 index 5acd8fd946..0000000000 --- a/target/linux/package/ieee80211-dscape/src/michael.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Michael MIC implementation - optimized for TKIP MIC operations - * Copyright 2002-2003, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef MICHAEL_H -#define MICHAEL_H - -#define MICHAEL_MIC_LEN 8 - -void michael_mic(u8 *key, u8 *da, u8 *sa, u8 priority, - u8 *data, size_t data_len, u8 *mic); - -#endif /* MICHAEL_H */ diff --git a/target/linux/package/ieee80211-dscape/src/rate_control.c b/target/linux/package/ieee80211-dscape/src/rate_control.c deleted file mode 100644 index 8782a756da..0000000000 --- a/target/linux/package/ieee80211-dscape/src/rate_control.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright 2002-2005, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "ieee80211_i.h" -#include "rate_control.h" - - -/* This is a minimal implementation of TX rate controlling that can be used - * as the default when no improved mechanisms are available. */ - - -#define RATE_CONTROL_EMERG_DEC 2 -#define RATE_CONTROL_INTERVAL (HZ / 20) -#define RATE_CONTROL_MIN_TX 10 - - -static void rate_control_rate_inc(struct ieee80211_local *local, - struct sta_info *sta) -{ - struct ieee80211_sub_if_data *sdata; - int i = sta->txrate; - int maxrate; - - sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); - if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { - /* forced unicast rate - do not change STA rate */ - return; - } - - maxrate = sdata->bss ? sdata->bss->max_ratectrl_rateidx : -1; - - if (i > local->num_curr_rates) - i = local->num_curr_rates - 2; - - while (i + 1 < local->num_curr_rates) { - i++; - if (sta->supp_rates & BIT(i) && - local->curr_rates[i].flags & IEEE80211_RATE_SUPPORTED && - (maxrate < 0 || i <= maxrate)) { - sta->txrate = i; - break; - } - } -} - - -static void rate_control_rate_dec(struct ieee80211_local *local, - struct sta_info *sta) -{ - struct ieee80211_sub_if_data *sdata; - int i = sta->txrate; - - sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); - if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) { - /* forced unicast rate - do not change STA rate */ - return; - } - - if (i > local->num_curr_rates) - i = local->num_curr_rates; - - while (i > 0) { - i--; - if (sta->supp_rates & BIT(i) && - local->curr_rates[i].flags & IEEE80211_RATE_SUPPORTED) { - sta->txrate = i; - break; - } - } -} - - -static struct ieee80211_rate * -rate_control_lowest_rate(struct ieee80211_local *local) -{ - int i; - - for (i = 0; i < local->num_curr_rates; i++) { - struct ieee80211_rate *rate = &local->curr_rates[i]; - - if (rate->flags & IEEE80211_RATE_SUPPORTED - ) - return rate; - } - - printk(KERN_DEBUG "rate_control_lowest_rate - no supported rates " - "found\n"); - return &local->curr_rates[0]; -} - - -struct global_rate_control { - int dummy; -}; - -struct sta_rate_control { - unsigned long last_rate_change; - u32 tx_num_failures; - u32 tx_num_xmit; - - unsigned long avg_rate_update; - u32 tx_avg_rate_sum; - u32 tx_avg_rate_num; -}; - - -static void rate_control_simple_tx_status(struct net_device *dev, - struct sk_buff *skb, - struct ieee80211_tx_status *status) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct sta_info *sta; - struct sta_rate_control *srctrl; - - sta = sta_info_get(local, hdr->addr1); - - if (!sta) - return; - - srctrl = sta->rate_ctrl_priv; - srctrl->tx_num_xmit++; - if (status->excessive_retries) { - sta->antenna_sel = sta->antenna_sel == 1 ? 2 : 1; - if (local->sta_antenna_sel == STA_ANTENNA_SEL_SW_CTRL_DEBUG) { - printk(KERN_DEBUG "%s: " MACSTR " TX antenna --> %d " - "(@%lu)\n", - dev->name, MAC2STR(hdr->addr1), - sta->antenna_sel, jiffies); - } - srctrl->tx_num_failures++; - sta->tx_retry_failed++; - sta->tx_num_consecutive_failures++; - sta->tx_num_mpdu_fail++; - } else { - sta->last_ack_rssi[0] = sta->last_ack_rssi[1]; - sta->last_ack_rssi[1] = sta->last_ack_rssi[2]; - sta->last_ack_rssi[2] = status->ack_signal; - sta->tx_num_consecutive_failures = 0; - sta->tx_num_mpdu_ok++; - } - sta->tx_retry_count += status->retry_count; - sta->tx_num_mpdu_fail += status->retry_count; - - if (time_after(jiffies, - srctrl->last_rate_change + RATE_CONTROL_INTERVAL) && - srctrl->tx_num_xmit > RATE_CONTROL_MIN_TX) { - u32 per_failed; - srctrl->last_rate_change = jiffies; - - per_failed = (100 * sta->tx_num_mpdu_fail) / - (sta->tx_num_mpdu_fail + sta->tx_num_mpdu_ok); - /* TODO: calculate average per_failed to make adjusting - * parameters easier */ -#if 0 - if (net_ratelimit()) { - printk(KERN_DEBUG "MPDU fail=%d ok=%d per_failed=%d\n", - sta->tx_num_mpdu_fail, sta->tx_num_mpdu_ok, - per_failed); - } -#endif - - if (per_failed > local->rate_ctrl_num_down) { - rate_control_rate_dec(local, sta); - } else if (per_failed < local->rate_ctrl_num_up) { - rate_control_rate_inc(local, sta); - } - srctrl->tx_avg_rate_sum += local->curr_rates[sta->txrate].rate; - srctrl->tx_avg_rate_num++; - srctrl->tx_num_failures = 0; - srctrl->tx_num_xmit = 0; - } else if (sta->tx_num_consecutive_failures >= - RATE_CONTROL_EMERG_DEC) { - rate_control_rate_dec(local, sta); - } - - if (srctrl->avg_rate_update + 60 * HZ < jiffies) { - srctrl->avg_rate_update = jiffies; - if (srctrl->tx_avg_rate_num > 0) { -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: STA " MACSTR " Average rate: " - "%d (%d/%d)\n", - dev->name, MAC2STR(sta->addr), - srctrl->tx_avg_rate_sum / - srctrl->tx_avg_rate_num, - srctrl->tx_avg_rate_sum, - srctrl->tx_avg_rate_num); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - srctrl->tx_avg_rate_sum = 0; - srctrl->tx_avg_rate_num = 0; - } - } - - sta_info_release(local, sta); -} - - -static struct ieee80211_rate * -rate_control_simple_get_rate(struct net_device *dev, struct sk_buff *skb, - struct rate_control_extra *extra) -{ - struct ieee80211_local *local = dev->priv; - struct ieee80211_sub_if_data *sdata; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct sta_info *sta; - int rateidx, nonerp_idx; - u16 fc; - - memset(extra, 0, sizeof(*extra)); - - fc = le16_to_cpu(hdr->frame_control); - if (WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_DATA || - (hdr->addr1[0] & 0x01)) { - /* Send management frames and broadcast/multicast data using - * lowest rate. */ - /* TODO: this could probably be improved.. */ - return rate_control_lowest_rate(local); - } - - sta = sta_info_get(local, hdr->addr1); - - if (!sta) - return rate_control_lowest_rate(local); - - sdata = IEEE80211_DEV_TO_SUB_IF(dev); - if (sdata->bss && sdata->bss->force_unicast_rateidx > -1) - sta->txrate = sdata->bss->force_unicast_rateidx; - - rateidx = sta->txrate; - - if (rateidx >= local->num_curr_rates) - rateidx = local->num_curr_rates - 1; - - sta->last_txrate = rateidx; - nonerp_idx = rateidx; - while (nonerp_idx > 0 && - ((local->curr_rates[nonerp_idx].flags & IEEE80211_RATE_ERP) || - !(local->curr_rates[nonerp_idx].flags & - IEEE80211_RATE_SUPPORTED) || - !(sta->supp_rates & BIT(nonerp_idx)))) - nonerp_idx--; - extra->nonerp_idx = nonerp_idx; - extra->nonerp = &local->curr_rates[extra->nonerp_idx]; - - sta_info_release(local, sta); - - return &local->curr_rates[rateidx]; -} - - -static void rate_control_simple_rate_init(struct ieee80211_local *local, - struct sta_info *sta) -{ - int i; - sta->txrate = 0; - /* TODO: what is a good starting rate for STA? About middle? Maybe not - * the lowest or the highest rate.. Could consider using RSSI from - * previous packets? Need to have IEEE 802.1X auth succeed immediately - * after assoc.. */ - for (i = 0; i < local->num_curr_rates; i++) { - if ((sta->supp_rates & BIT(i)) && - (local->curr_rates[i].flags & IEEE80211_RATE_SUPPORTED)) - sta->txrate = i; - } -} - - -static void * rate_control_simple_alloc(struct ieee80211_local *local) -{ - struct global_rate_control *rctrl; - - rctrl = kmalloc(sizeof(*rctrl), GFP_ATOMIC); - if (rctrl == NULL) { - return NULL; - } - memset(rctrl, 0, sizeof(*rctrl)); - return rctrl; -} - - -static void rate_control_simple_free(void *priv) -{ - struct global_rate_control *rctrl = priv; - kfree(rctrl); -} - - -static void rate_control_simple_clear(void *priv) -{ -} - - -static void * rate_control_simple_alloc_sta(void) -{ - struct sta_rate_control *rctrl; - - rctrl = kmalloc(sizeof(*rctrl), GFP_ATOMIC); - if (rctrl == NULL) { - return NULL; - } - memset(rctrl, 0, sizeof(*rctrl)); - return rctrl; -} - - -static void rate_control_simple_free_sta(void *priv) -{ - struct sta_rate_control *rctrl = priv; - kfree(rctrl); -} - - -static int rate_control_simple_status_sta(struct ieee80211_local *local, - struct sta_info *sta, char *buf) -{ - char *p = buf; - struct sta_rate_control *srctrl = sta->rate_ctrl_priv; - - p += sprintf(p, "tx_avg_rate_sum=%d\n", srctrl->tx_avg_rate_sum); - p += sprintf(p, "tx_avg_rate_num=%d\n", srctrl->tx_avg_rate_num); - if (srctrl->tx_avg_rate_num) - p += sprintf(p, "tx_avg_rate_avg=%d\n", - srctrl->tx_avg_rate_sum / - srctrl->tx_avg_rate_num); - return p - buf; -} - - -static int rate_control_simple_status_global(struct ieee80211_local *local, - char *buf) -{ - return 0; -} - - -static struct rate_control_ops rate_control_simple = { - .name = "simple", - .tx_status = rate_control_simple_tx_status, - .get_rate = rate_control_simple_get_rate, - .rate_init = rate_control_simple_rate_init, - .clear = rate_control_simple_clear, - .status_sta = rate_control_simple_status_sta, - .status_global = rate_control_simple_status_global, - .alloc = rate_control_simple_alloc, - .free = rate_control_simple_free, - .alloc_sta = rate_control_simple_alloc_sta, - .free_sta = rate_control_simple_free_sta, -}; - - -int __init rate_control_simple_init(void) -{ - return ieee80211_rate_control_register(&rate_control_simple); -} - - -static void __exit rate_control_simple_exit(void) -{ - ieee80211_rate_control_unregister(&rate_control_simple); -} - - -module_init(rate_control_simple_init); -module_exit(rate_control_simple_exit); diff --git a/target/linux/package/ieee80211-dscape/src/rate_control.h b/target/linux/package/ieee80211-dscape/src/rate_control.h deleted file mode 100644 index 9ceea7da57..0000000000 --- a/target/linux/package/ieee80211-dscape/src/rate_control.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2002-2005, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef RATE_CONTROL -#define RATE_CONTROL - -#define RATE_CONTROL_NUM_DOWN 20 -#define RATE_CONTROL_NUM_UP 15 - - -struct rate_control_extra { - /* values from rate_control_get_rate() to the caller: */ - struct ieee80211_rate *probe; /* probe with this rate, or NULL for no - * probing */ - int startidx, endidx, rateidx; - struct ieee80211_rate *nonerp; - int nonerp_idx; - - /* parameters from the caller to rate_control_get_rate(): */ - int mgmt_data; /* this is data frame that is used for management - * (e.g., IEEE 802.1X EAPOL) */ - u16 ethertype; -}; - - -struct rate_control_ops { - const char *name; - void (*tx_status)(struct net_device *dev, struct sk_buff *skb, - struct ieee80211_tx_status *status); - struct ieee80211_rate * - (*get_rate)(struct net_device *dev, struct sk_buff *skb, - struct rate_control_extra *extra); - void (*rate_init)(struct ieee80211_local *local, struct sta_info *sta); - void (*clear)(void *priv); - int (*status_sta)(struct ieee80211_local *local, - struct sta_info *sta, char *buf); - int (*status_global)(struct ieee80211_local *local, char *buf); - - void * (*alloc)(struct ieee80211_local *local); - void (*free)(void *priv); - void * (*alloc_sta)(void); - void (*free_sta)(void *priv); -}; - - -int ieee80211_rate_control_register(struct rate_control_ops *ops); -void ieee80211_rate_control_unregister(struct rate_control_ops *ops); - - -static inline void rate_control_tx_status(struct net_device *dev, - struct sk_buff *skb, - struct ieee80211_tx_status *status) -{ - struct ieee80211_local *local = dev->priv; - local->rate_ctrl->tx_status(dev, skb, status); -} - - -static inline struct ieee80211_rate * -rate_control_get_rate(struct net_device *dev, struct sk_buff *skb, - struct rate_control_extra *extra) -{ - struct ieee80211_local *local = dev->priv; - return local->rate_ctrl->get_rate(dev, skb, extra); -} - - -static inline void rate_control_rate_init(struct ieee80211_local *local, - struct sta_info *sta) -{ - local->rate_ctrl->rate_init(local, sta); -} - - -static inline void rate_control_clear(struct ieee80211_local *local) -{ - local->rate_ctrl->clear(local->rate_ctrl_priv); -} - - -static inline int rate_control_status_sta(struct ieee80211_local *local, - struct sta_info *sta, char *buf) -{ - return local->rate_ctrl->status_sta(local, sta, buf); -} - - -static inline int rate_control_status_global(struct ieee80211_local *local, - char *buf) -{ - return local->rate_ctrl->status_global(local, buf); -} - - -static inline void * rate_control_alloc(struct ieee80211_local *local) -{ - return local->rate_ctrl->alloc(local); -} - - -static inline void rate_control_free(struct ieee80211_local *local) -{ - if (local->rate_ctrl == NULL || local->rate_ctrl_priv == NULL) - return; - local->rate_ctrl->free(local->rate_ctrl_priv); - local->rate_ctrl_priv = NULL; -} - - -static inline void * rate_control_alloc_sta(struct ieee80211_local *local) -{ - return local->rate_ctrl->alloc_sta(); -} - - -static inline void rate_control_free_sta(struct ieee80211_local *local, - void *priv) -{ - local->rate_ctrl->free_sta(priv); -} - -#endif /* RATE_CONTROL */ diff --git a/target/linux/package/ieee80211-dscape/src/sta_info.c b/target/linux/package/ieee80211-dscape/src/sta_info.c deleted file mode 100644 index 4bb9f74ba0..0000000000 --- a/target/linux/package/ieee80211-dscape/src/sta_info.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright 2002-2005, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "ieee80211_i.h" -#include "ieee80211_proc.h" -#include "rate_control.h" - - -/* Caller must hold local->sta_lock */ -static void sta_info_hash_add(struct ieee80211_local *local, - struct sta_info *sta) -{ - sta->hnext = local->sta_hash[STA_HASH(sta->addr)]; - local->sta_hash[STA_HASH(sta->addr)] = sta; -} - - -/* Caller must hold local->sta_lock */ -static void sta_info_hash_del(struct ieee80211_local *local, - struct sta_info *sta) -{ - struct sta_info *s; - - s = local->sta_hash[STA_HASH(sta->addr)]; - if (s == NULL) - return; - if (memcmp(s->addr, sta->addr, ETH_ALEN) == 0) { - local->sta_hash[STA_HASH(sta->addr)] = s->hnext; - return; - } - - while (s->hnext != NULL && - memcmp(s->hnext->addr, sta->addr, ETH_ALEN) != 0) - s = s->hnext; - if (s->hnext != NULL) - s->hnext = s->hnext->hnext; - else - printk(KERN_ERR "%s: could not remove STA " MACSTR " from " - "hash table\n", local->mdev->name, MAC2STR(sta->addr)); -} - - -struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr) -{ - struct sta_info *sta; - - spin_lock_bh(&local->sta_lock); - sta = local->sta_hash[STA_HASH(addr)]; - while (sta) { - if (memcmp(sta->addr, addr, ETH_ALEN) == 0) { - atomic_inc(&sta->users); - break; - } - sta = sta->hnext; - } - spin_unlock_bh(&local->sta_lock); - - return sta; -} - - -int sta_info_min_txrate_get(struct ieee80211_local *local) -{ - struct sta_info *sta; - int min_txrate = 9999999; - int i; - - spin_lock_bh(&local->sta_lock); - for (i = 0; i < STA_HASH_SIZE; i++) { - sta = local->sta_hash[i]; - while (sta) { - if (sta->txrate < min_txrate) - min_txrate = sta->txrate; - sta = sta->hnext; - } - } - spin_unlock_bh(&local->sta_lock); - if (min_txrate == 9999999) - min_txrate = 0; - - return min_txrate; -} - - -void sta_info_release(struct ieee80211_local *local, struct sta_info *sta) -{ - struct sk_buff *skb; - - if (!atomic_dec_and_test(&sta->users)) - return; - - /* free sta structure; it has already been removed from - * hash table etc. external structures. Make sure that all - * buffered frames are release (one might have been added - * after sta_info_free() was called). */ - while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { - local->total_ps_buffered--; - dev_kfree_skb_any(skb); - } - while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { - dev_kfree_skb_any(skb); - } - rate_control_free_sta(local, sta->rate_ctrl_priv); - kfree(sta); -} - - -struct sta_info * sta_info_add(struct ieee80211_local *local, - struct net_device *dev, u8 *addr) -{ - struct sta_info *sta; - - sta = kmalloc(sizeof(*sta), GFP_ATOMIC); - if (!sta) - return NULL; - - memset(sta, 0, sizeof(*sta)); - - sta->rate_ctrl_priv = rate_control_alloc_sta(local); - if (sta->rate_ctrl_priv == NULL) { - kfree(sta); - return NULL; - } - - memcpy(sta->addr, addr, ETH_ALEN); - sta->dev = dev; - skb_queue_head_init(&sta->ps_tx_buf); - skb_queue_head_init(&sta->tx_filtered); - atomic_inc(&sta->users); /* sta in hashlist etc, decremented by - * sta_info_free() */ - atomic_inc(&sta->users); /* sta used by caller, decremented by - * sta_info_release() */ - spin_lock_bh(&local->sta_lock); - list_add(&sta->list, &local->sta_list); - local->num_sta++; - sta_info_hash_add(local, sta); - spin_unlock_bh(&local->sta_lock); - if (local->hw->sta_table_notification) - local->hw->sta_table_notification(local->mdev, local->num_sta); - sta->key_idx_compression = HW_KEY_IDX_INVALID; - -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Added STA " MACSTR "\n", - dev->name, MAC2STR(addr)); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - - if (!in_interrupt()) { - ieee80211_proc_init_sta(local, sta); - } else { - /* procfs entry adding might sleep, so schedule process context - * task for adding proc entry for STAs that do not yet have - * one. */ - schedule_work(&local->sta_proc_add); - } - - return sta; -} - - -void sta_info_free(struct ieee80211_local *local, struct sta_info *sta, - int locked) -{ - struct sk_buff *skb; - struct ieee80211_sub_if_data *sdata; - - if (!locked) - spin_lock_bh(&local->sta_lock); - sta_info_hash_del(local, sta); - list_del(&sta->list); - sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); - if (sta->flags & WLAN_STA_PS) { - sta->flags &= ~WLAN_STA_PS; - if (sdata->bss) - atomic_dec(&sdata->bss->num_sta_ps); - } - local->num_sta--; - sta_info_remove_aid_ptr(sta); - if (!locked) - spin_unlock_bh(&local->sta_lock); - if (local->hw->sta_table_notification) - local->hw->sta_table_notification(local->mdev, local->num_sta); - - while ((skb = skb_dequeue(&sta->ps_tx_buf)) != NULL) { - local->total_ps_buffered--; - dev_kfree_skb_any(skb); - } - while ((skb = skb_dequeue(&sta->tx_filtered)) != NULL) { - dev_kfree_skb_any(skb); - } - - if (sta->key) { - if (local->hw->set_key) { - struct ieee80211_key_conf *key; - key = ieee80211_key_data2conf(local, sta->key); - if (key) { - local->hw->set_key(local->mdev, DISABLE_KEY, - sta->addr, key, sta->aid); - kfree(key); - } - } - kfree(sta->key); - sta->key = NULL; - } else if (sta->key_idx_compression != HW_KEY_IDX_INVALID) { - struct ieee80211_key_conf conf; - memset(&conf, 0, sizeof(conf)); - conf.hw_key_idx = sta->key_idx_compression; - conf.alg = ALG_NULL; - conf.force_sw_encrypt = 1; - local->hw->set_key(local->mdev, DISABLE_KEY, sta->addr, &conf, - sta->aid); - sta->key_idx_compression = HW_KEY_IDX_INVALID; - } - -#ifdef CONFIG_IEEE80211_VERBOSE_DEBUG - printk(KERN_DEBUG "%s: Removed STA " MACSTR "\n", - local->mdev->name, MAC2STR(sta->addr)); -#endif /* CONFIG_IEEE80211_VERBOSE_DEBUG */ - - ieee80211_proc_deinit_sta(local, sta); - - if (atomic_read(&sta->users) != 1) { - /* This is OK, but printed for debugging. The station structure - * will be removed when the other user of the data calls - * sta_info_release(). */ - printk(KERN_DEBUG "%s: STA " MACSTR " users count %d when " - "removing it\n", local->mdev->name, MAC2STR(sta->addr), - atomic_read(&sta->users)); - } - - sta_info_release(local, sta); -} - - -static inline int sta_info_buffer_expired(struct sk_buff *skb) -{ - struct ieee80211_tx_packet_data *pkt_data; - if (!skb) - return 0; - - /* TODO: this could be improved by passing STA listen interval into - * the kernel driver and expiring frames after 2 x listen_interval x - * beacon interval */ - - pkt_data = (struct ieee80211_tx_packet_data *) skb->cb; - - if (pkt_data->magic != IEEE80211_CB_MAGIC) - return 1; - - return time_after(jiffies, pkt_data->jiffies + STA_TX_BUFFER_EXPIRE); -} - - -static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local, - struct sta_info *sta) -{ - unsigned long flags; - struct sk_buff *skb; - - if (skb_queue_empty(&sta->ps_tx_buf)) - return; - - for (;;) { - spin_lock_irqsave(&sta->ps_tx_buf.lock, flags); - skb = skb_peek(&sta->ps_tx_buf); - if (sta_info_buffer_expired(skb)) - skb = __skb_dequeue(&sta->ps_tx_buf); - else - skb = NULL; - spin_unlock_irqrestore(&sta->ps_tx_buf.lock, flags); - - if (skb) { - local->total_ps_buffered--; - printk(KERN_DEBUG "Buffered frame expired (STA " - MACSTR ")\n", MAC2STR(sta->addr)); - dev_kfree_skb(skb); - } else - break; - } -} - - -static void sta_info_cleanup(unsigned long data) -{ - struct ieee80211_local *local = (struct ieee80211_local *) data; - struct list_head *ptr; - - spin_lock_bh(&local->sta_lock); - ptr = local->sta_list.next; - while (ptr && ptr != &local->sta_list) { - struct sta_info *sta = (struct sta_info *) ptr; - atomic_inc(&sta->users); - sta_info_cleanup_expire_buffered(local, sta); - sta_info_release(local, sta); - ptr = ptr->next; - } - spin_unlock_bh(&local->sta_lock); - - local->sta_cleanup.expires = jiffies + STA_INFO_CLEANUP_INTERVAL; - add_timer(&local->sta_cleanup); -} - - -static void sta_info_proc_add_task(void *data) -{ - struct ieee80211_local *local = data; - struct list_head *ptr; - struct sta_info *sta; - int max_adds = 100; - - while (max_adds > 0) { - sta = NULL; - spin_lock_bh(&local->sta_lock); - list_for_each(ptr, &local->sta_list) { - sta = list_entry(ptr, struct sta_info, list); - if (!sta->proc_entry_added) { - atomic_inc(&sta->users); - break; - } - sta = NULL; - } - spin_unlock_bh(&local->sta_lock); - - if (!sta) - break; - - ieee80211_proc_init_sta(local, sta); - atomic_dec(&sta->users); - - max_adds--; - } -} - - -void sta_info_init(struct ieee80211_local *local) -{ - spin_lock_init(&local->sta_lock); - INIT_LIST_HEAD(&local->sta_list); - - init_timer(&local->sta_cleanup); - local->sta_cleanup.expires = jiffies + STA_INFO_CLEANUP_INTERVAL; - local->sta_cleanup.data = (unsigned long) local; - local->sta_cleanup.function = sta_info_cleanup; - - INIT_WORK(&local->sta_proc_add, sta_info_proc_add_task, local); -} - -void sta_info_start(struct ieee80211_local *local) -{ - add_timer(&local->sta_cleanup); -} - -void sta_info_stop(struct ieee80211_local *local) -{ - struct list_head *ptr; - - del_timer(&local->sta_cleanup); - - ptr = local->sta_list.next; - while (ptr && ptr != &local->sta_list) { - struct sta_info *sta = (struct sta_info *) ptr; - ptr = ptr->next; - sta_info_free(local, sta, 0); - } -} - - -void sta_info_remove_aid_ptr(struct sta_info *sta) -{ - struct ieee80211_sub_if_data *sdata; - - sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); - if (sta->aid <= 0 || !sdata->bss) - return; - - sdata->bss->sta_aid[sta->aid - 1] = NULL; - if (sta->aid == sdata->bss->max_aid) { - while (sdata->bss->max_aid > 0 && - sdata->bss->sta_aid[sdata->bss->max_aid - 1] == NULL) - sdata->bss->max_aid--; - } -} - - -/** - * sta_info_flush - flush matching STA entries from the STA table - * @local: local interface data - * @dev: matching rule for the net device (sta->dev) or %NULL to match all STAs - */ -void sta_info_flush(struct ieee80211_local *local, struct net_device *dev) -{ - struct list_head *ptr, *n; - - spin_lock_bh(&local->sta_lock); - - list_for_each_safe(ptr, n, &local->sta_list) { - struct sta_info *sta = list_entry(ptr, struct sta_info, list); - if (dev == NULL || dev == sta->dev) - sta_info_free(local, sta, 1); - } - spin_unlock_bh(&local->sta_lock); -} diff --git a/target/linux/package/ieee80211-dscape/src/sta_info.h b/target/linux/package/ieee80211-dscape/src/sta_info.h deleted file mode 100644 index ef6906d56d..0000000000 --- a/target/linux/package/ieee80211-dscape/src/sta_info.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2002-2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef STA_INFO_H -#define STA_INFO_H - -/* Stations flags (struct sta_info::flags) */ -#define WLAN_STA_AUTH BIT(0) -#define WLAN_STA_ASSOC BIT(1) -#define WLAN_STA_PS BIT(2) -#define WLAN_STA_TIM BIT(3) /* TIM bit is on for PS stations */ -#define WLAN_STA_PERM BIT(4) /* permanent; do not remove entry on expiration */ -#define WLAN_STA_AUTHORIZED BIT(5) /* If 802.1X is used, this flag is - * controlling whether STA is authorized to - * send and receive non-IEEE 802.1X frames - */ -#define WLAN_STA_SHORT_PREAMBLE BIT(7) -#define WLAN_STA_WME BIT(9) -#define WLAN_STA_XR BIT(26) -#define WLAN_STA_WDS BIT(27) - - -struct sta_info { - struct list_head list; - struct sta_info *hnext; /* next entry in hash table list */ - atomic_t users; /* number of users (do not remove if > 0) */ - - u8 addr[ETH_ALEN]; - u16 aid; /* STA's unique AID (1..2007), 0 = not yet assigned */ - u32 flags; /* WLAN_STA_ */ - - struct sk_buff_head ps_tx_buf; /* buffer of TX frames for station in - * power saving state */ - int pspoll; /* whether STA has send a PS Poll frame */ - struct sk_buff_head tx_filtered; /* buffer of TX frames that were - * already given to low-level driver, - * but were filtered */ - int clear_dst_mask; - - unsigned long rx_packets, tx_packets; /* number of RX/TX MSDUs */ - unsigned long rx_bytes, tx_bytes; - unsigned long tx_retry_failed, tx_retry_count; - unsigned long tx_filtered_count; - - unsigned int wep_weak_iv_count; /* number of RX frames with weak IV */ - - unsigned long last_rx; - u32 supp_rates; /* bitmap of supported rates in local->curr_rates */ - int txrate; /* index in local->curr_rates */ - int last_txrate; /* last rate used to send a frame to this STA */ - int last_nonerp_idx; - - struct net_device *dev; /* which net device is this station associated - * to */ - - struct ieee80211_key *key; - - u32 tx_num_consecutive_failures; - u32 tx_num_mpdu_ok; - u32 tx_num_mpdu_fail; - - void *rate_ctrl_priv; - - /* last received seq/frag number from this STA (per RX queue) */ - u16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; - unsigned long num_duplicates; /* number of duplicate frames received - * from this STA */ - unsigned long tx_fragments; /* number of transmitted MPDUs */ - unsigned long rx_fragments; /* number of received MPDUs */ - unsigned long rx_dropped; /* number of dropped MPDUs from this STA */ - - int last_rssi; /* RSSI of last received frame from this STA */ - int last_ack_rssi[3]; /* RSSI of last received ACKs from this STA */ - unsigned long last_ack; - int channel_use; - int channel_use_raw; - - int antenna_sel; - - - int key_idx_compression; /* key table index for compression and TX - * filtering; used only if sta->key is not - * set */ - - int proc_entry_added:1; - int assoc_ap:1; /* whether this is an AP that we are associated with - * as a client */ - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - u32 wpa_trigger; -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - -#ifdef CONFIG_IEEE80211_DEBUG_COUNTERS - unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES]; - unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES]; -#endif /* CONFIG_IEEE80211_DEBUG_COUNTERS */ - - int vlan_id; -}; - - -/* Maximum number of concurrently registered stations */ -#define MAX_STA_COUNT 2007 - -/* Maximum number of AIDs to use for STAs; must be 2007 or lower - * (IEEE 802.11 beacon format limitation) */ -#define MAX_AID_TABLE_SIZE 2007 - -#define STA_HASH_SIZE 256 -#define STA_HASH(sta) (sta[5]) - - -/* Maximum number of frames to buffer per power saving station */ -#define STA_MAX_TX_BUFFER 128 - -/* Buffered frame expiry time */ -#define STA_TX_BUFFER_EXPIRE (10 * HZ) - -/* How often station data is cleaned up (e.g., expiration of buffered frames) - */ -#define STA_INFO_CLEANUP_INTERVAL (10 * HZ) - - -struct sta_info * sta_info_get(struct ieee80211_local *local, u8 *addr); -int sta_info_min_txrate_get(struct ieee80211_local *local); -void sta_info_release(struct ieee80211_local *local, struct sta_info *sta); -struct sta_info * sta_info_add(struct ieee80211_local *local, - struct net_device *dev, u8 *addr); -void sta_info_free(struct ieee80211_local *local, struct sta_info *sta, - int locked); -void sta_info_init(struct ieee80211_local *local); -void sta_info_start(struct ieee80211_local *local); -void sta_info_stop(struct ieee80211_local *local); -void sta_info_remove_aid_ptr(struct sta_info *sta); -void sta_info_flush(struct ieee80211_local *local, struct net_device *dev); - -#endif /* STA_INFO_H */ diff --git a/target/linux/package/ieee80211-dscape/src/tkip.c b/target/linux/package/ieee80211-dscape/src/tkip.c deleted file mode 100644 index 41e0b8ea05..0000000000 --- a/target/linux/package/ieee80211-dscape/src/tkip.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Copyright 2002-2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifdef CONFIG_TKIP_DEBUG -#include -#include -#include -#include -#include -#endif /* CONFIG_TKIP_DEBUG */ - -#include -#include - -#include -#include "ieee80211_key.h" -#ifdef CONFIG_TKIP_DEBUG -#include "ieee80211_i.h" -#endif /* CONFIG_TKIP_DEBUG */ -#include "tkip.h" - -/* Dummy prototypes for structures used in wep.h, but not really needed for - * TKIP. */ -struct ieee80211_local; -struct sk_buff; -#include "wep.h" - - -/* TKIP key mixing functions */ - - -#define PHASE1_LOOP_COUNT 8 - - -/* 2-byte by 2-byte subset of the full AES S-box table; second part of this - * table is identical to first part but byte-swapped */ -static const u16 tkip_sbox[256] = -{ - 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, - 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, - 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, - 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B, - 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F, - 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F, - 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5, - 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F, - 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB, - 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397, - 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED, - 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A, - 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194, - 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3, - 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104, - 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D, - 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39, - 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695, - 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83, - 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76, - 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4, - 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B, - 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0, - 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018, - 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751, - 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85, - 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12, - 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9, - 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7, - 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A, - 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8, - 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A, -}; - - -static inline u16 Mk16(u8 x, u8 y) -{ - return ((u16) x << 8) | (u16) y; -} - - -static inline u8 Hi8(u16 v) -{ - return v >> 8; -} - - -static inline u8 Lo8(u16 v) -{ - return v & 0xff; -} - - -static inline u16 Hi16(u32 v) -{ - return v >> 16; -} - - -static inline u16 Lo16(u32 v) -{ - return v & 0xffff; -} - - -static inline u16 RotR1(u16 v) -{ - return (v >> 1) | ((v & 0x0001) << 15); -} - - -static inline u16 tkip_S(u16 val) -{ - u16 a = tkip_sbox[Hi8(val)]; - - return tkip_sbox[Lo8(val)] ^ Hi8(a) ^ (Lo8(a) << 8); -} - - - -/* P1K := Phase1(TA, TK, TSC) - * TA = transmitter address (48 bits) - * TK = dot11DefaultKeyValue or dot11KeyMappingValue (128 bits) - * TSC = TKIP sequence counter (48 bits, only 32 msb bits used) - * P1K: 80 bits - */ -static void tkip_mixing_phase1(const u8 *ta, const u8 *tk, u32 tsc_IV32, - u16 *p1k) -{ - int i, j; - - p1k[0] = Lo16(tsc_IV32); - p1k[1] = Hi16(tsc_IV32); - p1k[2] = Mk16(ta[1], ta[0]); - p1k[3] = Mk16(ta[3], ta[2]); - p1k[4] = Mk16(ta[5], ta[4]); - - for (i = 0; i < PHASE1_LOOP_COUNT; i++) { - j = 2 * (i & 1); - p1k[0] += tkip_S(p1k[4] ^ Mk16(tk[ 1 + j], tk[ 0 + j])); - p1k[1] += tkip_S(p1k[0] ^ Mk16(tk[ 5 + j], tk[ 4 + j])); - p1k[2] += tkip_S(p1k[1] ^ Mk16(tk[ 9 + j], tk[ 8 + j])); - p1k[3] += tkip_S(p1k[2] ^ Mk16(tk[13 + j], tk[12 + j])); - p1k[4] += tkip_S(p1k[3] ^ Mk16(tk[ 1 + j], tk[ 0 + j])) + i; - } -} - - -static void tkip_mixing_phase2(const u16 *p1k, const u8 *tk, u16 tsc_IV16, - u8 *rc4key) -{ - u16 ppk[6]; - int i; - - ppk[0] = p1k[0]; - ppk[1] = p1k[1]; - ppk[2] = p1k[2]; - ppk[3] = p1k[3]; - ppk[4] = p1k[4]; - ppk[5] = p1k[4] + tsc_IV16; - - ppk[0] += tkip_S(ppk[5] ^ Mk16(tk[ 1], tk[ 0])); - ppk[1] += tkip_S(ppk[0] ^ Mk16(tk[ 3], tk[ 2])); - ppk[2] += tkip_S(ppk[1] ^ Mk16(tk[ 5], tk[ 4])); - ppk[3] += tkip_S(ppk[2] ^ Mk16(tk[ 7], tk[ 6])); - ppk[4] += tkip_S(ppk[3] ^ Mk16(tk[ 9], tk[ 8])); - ppk[5] += tkip_S(ppk[4] ^ Mk16(tk[11], tk[10])); - ppk[0] += RotR1(ppk[5] ^ Mk16(tk[13], tk[12])); - ppk[1] += RotR1(ppk[0] ^ Mk16(tk[15], tk[14])); - ppk[2] += RotR1(ppk[1]); - ppk[3] += RotR1(ppk[2]); - ppk[4] += RotR1(ppk[3]); - ppk[5] += RotR1(ppk[4]); - - rc4key[0] = Hi8(tsc_IV16); - rc4key[1] = (Hi8(tsc_IV16) | 0x20) & 0x7f; - rc4key[2] = Lo8(tsc_IV16); - rc4key[3] = Lo8((ppk[5] ^ Mk16(tk[1], tk[0])) >> 1); - - for (i = 0; i < 6; i++) { - rc4key[4 + 2 * i] = Lo8(ppk[i]); - rc4key[5 + 2 * i] = Hi8(ppk[i]); - } -} - - -/* Add TKIP IV and Ext. IV at @pos. @iv0, @iv1, and @iv2 are the first octets - * of the IV. Returns pointer to the octet following IVs (i.e., beginning of - * the packet payload). */ -u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, - u8 iv0, u8 iv1, u8 iv2) -{ - *pos++ = iv0; - *pos++ = iv1; - *pos++ = iv2; - *pos++ = (key->keyidx << 6) | (1 << 5) /* Ext IV */; - *pos++ = key->u.tkip.iv32 & 0xff; - *pos++ = (key->u.tkip.iv32 >> 8) & 0xff; - *pos++ = (key->u.tkip.iv32 >> 16) & 0xff; - *pos++ = (key->u.tkip.iv32 >> 24) & 0xff; - return pos; -} - - -/* Encrypt packet payload with TKIP using @key. @pos is a pointer to the - * beginning of the buffer containing payload. This payload must include - * headroom of eight octets for IV and Ext. IV and taildroom of four octets - * for ICV. @payload_len is the length of payload (_not_ including extra - * headroom and tailroom). @ta is the transmitter addresses. */ -void ieee80211_tkip_encrypt_data(struct ieee80211_key *key, u8 *pos, - size_t payload_len, u8 *ta) -{ - u8 rc4key[16]; - - /* Calculate per-packet key */ - if (key->u.tkip.iv16 == 0 || !key->u.tkip.tx_initialized) { - /* IV16 wrapped around - perform TKIP phase 1 */ - tkip_mixing_phase1(ta, &key->key[ALG_TKIP_TEMP_ENCR_KEY], - key->u.tkip.iv32, key->u.tkip.p1k); - key->u.tkip.tx_initialized = 1; - } - - tkip_mixing_phase2(key->u.tkip.p1k, &key->key[ALG_TKIP_TEMP_ENCR_KEY], - key->u.tkip.iv16, rc4key); - - pos = ieee80211_tkip_add_iv(pos, key, rc4key[0], rc4key[1], rc4key[2]); - ieee80211_wep_encrypt_data(rc4key, 16, pos, payload_len); -} - - -/* Decrypt packet payload with TKIP using @key. @pos is a pointer to the - * beginning of the buffer containing IEEE 802.11 header payload, i.e., - * including IV, Ext. IV, real data, Michael MIC, ICV. @payload_len is the - * length of payload, including IV, Ext. IV, MIC, ICV. */ -int ieee80211_tkip_decrypt_data(struct ieee80211_key *key, u8 *payload, - size_t payload_len, u8 *ta, int only_iv, - int queue) -{ - u32 iv32; - u32 iv16; - u8 rc4key[16], keyid, *pos = payload; - int res; - - if (payload_len < 12) - return -1; - - iv16 = (pos[0] << 8) | pos[2]; - keyid = pos[3]; - iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); - pos += 8; -#ifdef CONFIG_TKIP_DEBUG - { - int i; - printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len); - for (i = 0; i < payload_len; i++) - printk(" %02x", payload[i]); - printk("\n"); - printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n", - iv16, iv32); - } -#endif /* CONFIG_TKIP_DEBUG */ - - if (!(keyid & (1 << 5))) - return TKIP_DECRYPT_NO_EXT_IV; - - if ((keyid >> 6) != key->keyidx) - return TKIP_DECRYPT_INVALID_KEYIDX; - - if (key->u.tkip.rx_initialized[queue] && - (iv32 < key->u.tkip.iv32_rx[queue] || - (iv32 == key->u.tkip.iv32_rx[queue] && - iv16 <= key->u.tkip.iv16_rx[queue]))) { -#ifdef CONFIG_TKIP_DEBUG - printk(KERN_DEBUG "TKIP replay detected for RX frame from " - MACSTR " (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", - MAC2STR(ta), - iv32, iv16, key->u.tkip.iv32_rx[queue], - key->u.tkip.iv16_rx[queue]); -#endif /* CONFIG_TKIP_DEBUG */ - return TKIP_DECRYPT_REPLAY; - } - - if (only_iv) { - res = TKIP_DECRYPT_OK; - goto done; - } - - if (!key->u.tkip.rx_initialized[queue] || - key->u.tkip.iv32_rx[queue] != iv32) { - key->u.tkip.rx_initialized[queue] = 1; - /* IV16 wrapped around - perform TKIP phase 1 */ - tkip_mixing_phase1(ta, &key->key[ALG_TKIP_TEMP_ENCR_KEY], - iv32, key->u.tkip.p1k_rx[queue]); -#ifdef CONFIG_TKIP_DEBUG - { - int i; - printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=" MACSTR - " TK=", MAC2STR(ta)); - for (i = 0; i < 16; i++) - printk("%02x ", - key->key[ALG_TKIP_TEMP_ENCR_KEY + i]); - printk("\n"); - printk(KERN_DEBUG "TKIP decrypt: P1K="); - for (i = 0; i < 5; i++) - printk("%04x ", key->u.tkip.p1k_rx[queue][i]); - printk("\n"); - } -#endif /* CONFIG_TKIP_DEBUG */ - } - - tkip_mixing_phase2(key->u.tkip.p1k_rx[queue], - &key->key[ALG_TKIP_TEMP_ENCR_KEY], - iv16, rc4key); -#ifdef CONFIG_TKIP_DEBUG - { - int i; - printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key="); - for (i = 0; i < 16; i++) - printk("%02x ", rc4key[i]); - printk("\n"); - } -#endif /* CONFIG_TKIP_DEBUG */ - - res = ieee80211_wep_decrypt_data(rc4key, 16, pos, payload_len - 12); - done: - if (res == TKIP_DECRYPT_OK) { - /* FIX: these should be updated only after Michael MIC has been - * verified */ - /* Record previously received IV */ - key->u.tkip.iv32_rx[queue] = iv32; - key->u.tkip.iv16_rx[queue] = iv16; - } - - return res; -} - - diff --git a/target/linux/package/ieee80211-dscape/src/tkip.h b/target/linux/package/ieee80211-dscape/src/tkip.h deleted file mode 100644 index 6c4ab7f698..0000000000 --- a/target/linux/package/ieee80211-dscape/src/tkip.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2002-2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef TKIP_H -#define TKIP_H - -u8 * ieee80211_tkip_add_iv(u8 *pos, struct ieee80211_key *key, - u8 iv0, u8 iv1, u8 iv2); -void ieee80211_tkip_encrypt_data(struct ieee80211_key *key, u8 *pos, - size_t payload_len, u8 *ta); -enum { - TKIP_DECRYPT_OK = 0, - TKIP_DECRYPT_NO_EXT_IV = -1, - TKIP_DECRYPT_INVALID_KEYIDX = -2, - TKIP_DECRYPT_REPLAY = -3, -}; -int ieee80211_tkip_decrypt_data(struct ieee80211_key *key, u8 *payload, - size_t payload_len, u8 *ta, int only_iv, - int queue); - -#endif /* TKIP_H */ diff --git a/target/linux/package/ieee80211-dscape/src/wep.c b/target/linux/package/ieee80211-dscape/src/wep.c deleted file mode 100644 index 57c2f603c0..0000000000 --- a/target/linux/package/ieee80211-dscape/src/wep.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Software WEP encryption implementation - * Copyright 2002, Jouni Malinen - * Copyright 2003, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include "ieee80211_i.h" -#include "wep.h" - - -static const __u32 crc32_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; - - -void ieee80211_wep_init(struct ieee80211_local *local) -{ - /* start WEP IV from a random value */ - get_random_bytes(&local->wep_iv, WEP_IV_LEN); -} - - -static inline int ieee80211_wep_weak_iv(u32 iv, int keylen) -{ - /* Fluhrer, Mantin, and Shamir have reported weaknesses in the - * key scheduling algorithm of RC4. At least IVs (KeyByte + 3, - * 0xff, N) can be used to speedup attacks, so avoid using them. */ - if ((iv & 0xff00) == 0xff00) { - u8 B = (iv >> 16) & 0xff; - if (B >= 3 && B < 3 + keylen) - return 1; - } - return 0; -} - - -void ieee80211_wep_get_iv(struct ieee80211_local *local, - struct ieee80211_key *key, u8 *iv) -{ - local->wep_iv++; - if (ieee80211_wep_weak_iv(local->wep_iv, key->keylen)) - local->wep_iv += 0x0100; - - if (iv == NULL) - return; - - *iv++ = (local->wep_iv >> 16) & 0xff; - *iv++ = (local->wep_iv >> 8) & 0xff; - *iv++ = local->wep_iv & 0xff; - *iv++ = key->keyidx << 6; -} - - -u8 * ieee80211_wep_add_iv(struct ieee80211_local *local, - struct sk_buff *skb, - struct ieee80211_key *key) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - u16 fc; - int hdrlen; - u8 *newhdr; - - fc = le16_to_cpu(hdr->frame_control); - fc |= WLAN_FC_ISWEP; - hdr->frame_control = cpu_to_le16(fc); - - if ((skb_headroom(skb) < WEP_IV_LEN || - skb_tailroom(skb) < WEP_ICV_LEN)) { - I802_DEBUG_INC(local->tx_expand_skb_head); - if (unlikely(pskb_expand_head(skb, WEP_IV_LEN, WEP_ICV_LEN, - GFP_ATOMIC))) - return NULL; - } - - hdrlen = ieee80211_get_hdrlen(fc); - newhdr = skb_push(skb, WEP_IV_LEN); - memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); - ieee80211_wep_get_iv(local, key, newhdr + hdrlen); - return newhdr + hdrlen; -} - - -void ieee80211_wep_remove_iv(struct ieee80211_local *local, - struct sk_buff *skb, - struct ieee80211_key *key) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - u16 fc; - int hdrlen; - - fc = le16_to_cpu(hdr->frame_control); - hdrlen = ieee80211_get_hdrlen(fc); - memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); - skb_pull(skb, WEP_IV_LEN); -} - - -/* Perform WEP encryption using given key. data buffer must have tailroom - * for 4-byte ICV. data_len must not include this ICV. Note: this function - * does _not_ add IV. data = RC4(data | CRC32(data)) */ -void ieee80211_wep_encrypt_data(u8 *rc4key, size_t klen, u8 *data, - size_t data_len) -{ - u32 i, j, k, crc; - u8 S[256]; - u8 kpos, *pos; -#define S_SWAP(a,b) do { u8 t = S[a]; S[a] = S[b]; S[b] = t; } while(0) - - /* Setup RC4 state */ - for (i = 0; i < 256; i++) - S[i] = i; - j = 0; - kpos = 0; - for (i = 0; i < 256; i++) { - j = (j + S[i] + rc4key[kpos]) & 0xff; - kpos++; - if (kpos >= klen) - kpos = 0; - S_SWAP(i, j); - } - - /* Compute CRC32 over unencrypted data and apply RC4 to data */ - pos = data; - crc = ~0; - i = j = 0; - for (k = 0; k < data_len; k++) { - crc = crc32_table[(crc ^ *pos) & 0xff] ^ (crc >> 8); - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - *pos++ ^= S[(S[i] + S[j]) & 0xff]; - } - crc = ~crc; - - /* Append little-endian CRC32 and encrypt it to produce ICV */ - pos[0] = crc; - pos[1] = crc >> 8; - pos[2] = crc >> 16; - pos[3] = crc >> 24; - for (k = 0; k < 4; k++) { - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - *pos++ ^= S[(S[i] + S[j]) & 0xff]; - } -} - - -/* Perform WEP encryption on given skb. 4 bytes of extra space (IV) in the - * beginning of the buffer 4 bytes of extra space (ICV) in the end of the - * buffer will be added. Both IV and ICV will be transmitted, so the - * payload length increases with 8 bytes. - * - * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) - */ -int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, - struct ieee80211_key *key) -{ - u32 klen; - u8 *rc4key, *iv; - size_t len; - - if (key == NULL || key->alg != ALG_WEP) - return -1; - - klen = 3 + key->keylen; - rc4key = kmalloc(klen, GFP_ATOMIC); - if (rc4key == NULL) - return -1; - - iv = ieee80211_wep_add_iv(local, skb, key); - if (iv == NULL) { - kfree(rc4key); - return -1; - } - - len = skb->len - (iv + WEP_IV_LEN - skb->data); - - /* Prepend 24-bit IV to RC4 key */ - memcpy(rc4key, iv, 3); - - /* Copy rest of the WEP key (the secret part) */ - memcpy(rc4key + 3, key->key, key->keylen); - - /* Add room for ICV */ - skb_put(skb, WEP_ICV_LEN); - - ieee80211_wep_encrypt_data(rc4key, klen, iv + WEP_IV_LEN, len); - - kfree(rc4key); - - return 0; -} - - -/* Perform WEP decryption using given key. data buffer includes encrypted - * payload, including 4-byte ICV, but _not_ IV. data_len must not include ICV. - * Return 0 on success and -1 on ICV mismatch. */ -int ieee80211_wep_decrypt_data(u8 *rc4key, size_t klen, u8 *data, - size_t data_len) -{ - u32 i, j, k, crc; - u8 S[256]; - u8 kpos, *pos, crcbuf[WEP_ICV_LEN], *cpos; - - /* Setup RC4 state */ - for (i = 0; i < 256; i++) - S[i] = i; - j = 0; - kpos = 0; - for (i = 0; i < 256; i++) { - j = (j + S[i] + rc4key[kpos]) & 0xff; - kpos++; - if (kpos >= klen) - kpos = 0; - S_SWAP(i, j); - } - - /* Apply RC4 to data and compute CRC32 over decrypted data */ - pos = data; - crc = ~0; - i = j = 0; - for (k = 0; k < data_len; k++) { - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - *pos ^= S[(S[i] + S[j]) & 0xff]; - crc = crc32_table[(crc ^ *pos++) & 0xff] ^ (crc >> 8); - } - crc = ~crc; - - /* Decrypt little-endian CRC32 and verify that it matches with the - * received ICV */ - cpos = crcbuf; - crcbuf[0] = crc; - crcbuf[1] = crc >> 8; - crcbuf[2] = crc >> 16; - crcbuf[3] = crc >> 24; - for (k = 0; k < WEP_ICV_LEN; k++) { - i = (i + 1) & 0xff; - j = (j + S[i]) & 0xff; - S_SWAP(i, j); - if (*cpos++ != (*pos++ ^ S[(S[i] + S[j]) & 0xff])) { - /* ICV mismatch */ - return -1; - } - } - - return 0; -} - - -/* Perform WEP decryption on given skb. Buffer includes whole WEP part of - * the frame: IV (4 bytes), encrypted payload (including SNAP header), - * ICV (4 bytes). skb->len includes both IV and ICV. - * - * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on - * failure. If frame is OK, IV and ICV will be removed, i.e., decrypted payload - * is moved to the beginning of the skb and skb length will be reduced. - */ -int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, - struct ieee80211_key *key) -{ - u32 klen; - u8 *rc4key; - u8 keyidx; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - u16 fc; - int hdrlen; - size_t len; - int ret = 0; - - fc = le16_to_cpu(hdr->frame_control); - if (!(fc & WLAN_FC_ISWEP)) - return -1; - - hdrlen = ieee80211_get_hdrlen(fc); - - if (skb->len < 8 + hdrlen) - return -1; - - len = skb->len - hdrlen - 8; - - keyidx = skb->data[hdrlen + 3] >> 6; - - if (key == NULL || keyidx != key->keyidx || key->alg != ALG_WEP) - return -1; - - klen = 3 + key->keylen; - - rc4key = kmalloc(klen, GFP_ATOMIC); - if (rc4key == NULL) - return -1; - - /* Prepend 24-bit IV to RC4 key */ - memcpy(rc4key, skb->data + hdrlen, 3); - - /* Copy rest of the WEP key (the secret part) */ - memcpy(rc4key + 3, key->key, key->keylen); - - if (ieee80211_wep_decrypt_data(rc4key, klen, - skb->data + hdrlen + WEP_IV_LEN, - len)) { - printk(KERN_DEBUG "WEP decrypt failed (ICV)\n"); - ret = -1; - } - - kfree(rc4key); - - /* Trim ICV */ - skb_trim(skb, skb->len - WEP_ICV_LEN); - - /* Remove IV */ - memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); - skb_pull(skb, WEP_IV_LEN); - - return ret; -} - - -int ieee80211_wep_get_keyidx(struct sk_buff *skb) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - u16 fc; - int hdrlen; - - fc = le16_to_cpu(hdr->frame_control); - if (!(fc & WLAN_FC_ISWEP)) - return -1; - - hdrlen = ieee80211_get_hdrlen(fc); - - if (skb->len < 8 + hdrlen) - return -1; - - return skb->data[hdrlen + 3] >> 6; -} - - -u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - u16 fc; - int hdrlen; - u8 *ivpos; - u32 iv; - - fc = le16_to_cpu(hdr->frame_control); - if (!(fc & WLAN_FC_ISWEP)) - return NULL; - - hdrlen = ieee80211_get_hdrlen(fc); - ivpos = skb->data + hdrlen; - iv = (ivpos[0] << 16) | (ivpos[1] << 8) | ivpos[2]; - - if (ieee80211_wep_weak_iv(iv, key->keylen)) - return ivpos; - - return NULL; -} diff --git a/target/linux/package/ieee80211-dscape/src/wep.h b/target/linux/package/ieee80211-dscape/src/wep.h deleted file mode 100644 index 6f693945af..0000000000 --- a/target/linux/package/ieee80211-dscape/src/wep.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Software WEP encryption implementation - * Copyright 2002, Jouni Malinen - * Copyright 2003, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef WEP_H -#define WEP_H - -void ieee80211_wep_init(struct ieee80211_local *local); -void ieee80211_wep_get_iv(struct ieee80211_local *local, - struct ieee80211_key *key, u8 *iv); -u8 * ieee80211_wep_add_iv(struct ieee80211_local *local, - struct sk_buff *skb, - struct ieee80211_key *key); -void ieee80211_wep_remove_iv(struct ieee80211_local *local, - struct sk_buff *skb, - struct ieee80211_key *key); -void ieee80211_wep_encrypt_data(u8 *rc4key, size_t klen, u8 *data, - size_t data_len); -int ieee80211_wep_decrypt_data(u8 *rc4key, size_t klen, u8 *data, - size_t data_len); -int ieee80211_wep_encrypt(struct ieee80211_local *local, struct sk_buff *skb, - struct ieee80211_key *key); -int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb, - struct ieee80211_key *key); -int ieee80211_wep_get_keyidx(struct sk_buff *skb); -u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); - -#endif /* WEP_H */ diff --git a/target/linux/package/ieee80211-dscape/src/wme.c b/target/linux/package/ieee80211-dscape/src/wme.c deleted file mode 100644 index b3fdd59e5a..0000000000 --- a/target/linux/package/ieee80211-dscape/src/wme.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * Copyright 2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include "ieee80211_i.h" -#include "wme.h" - -#define CHILD_QDISC_OPS pfifo_qdisc_ops - -static inline int WLAN_FC_IS_QOS_DATA(u16 fc) -{ - return (fc & 0x8C) == 0x88; -} - - -ieee80211_txrx_result -ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx) -{ - u8 *data = rx->skb->data; - int tid; - - /* does the frame have a qos control field? */ - if (WLAN_FC_IS_QOS_DATA(rx->fc)) { - u8 *qc = data + ieee80211_get_hdrlen(rx->fc) - QOS_CONTROL_LEN; - /* frame has qos control */ - tid = qc[0] & QOS_CONTROL_TID_MASK; - } else { - if (unlikely(WLAN_FC_GET_TYPE(rx->fc) == WLAN_FC_TYPE_MGMT)) { - /* Separate TID for management frames */ - tid = NUM_RX_DATA_QUEUES - 1; - } else { - /* no qos control present */ - tid = 0; /* 802.1d - Best Effort */ - } - } -#ifdef CONFIG_IEEE80211_DEBUG_COUNTERS - I802_DEBUG_INC(rx->local->wme_rx_queue[tid]); - if (rx->sta) { - I802_DEBUG_INC(rx->sta->wme_rx_queue[tid]); - } -#endif /* CONFIG_IEEE80211_DEBUG_COUNTERS */ - - rx->u.rx.queue = tid; - /* Set skb->priority to 1d tag if highest order bit of TID is not set. - * For now, set skb->priority to 0 for other cases. */ - rx->skb->priority = (tid > 7) ? 0 : tid; - - return TXRX_CONTINUE; -} - - -ieee80211_txrx_result -ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx) -{ - u16 fc = rx->fc; - u8 *data = rx->skb->data; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) data; - - if (!WLAN_FC_IS_QOS_DATA(fc)) - return TXRX_CONTINUE; - - /* remove the qos control field, update frame type and meta-data */ - memmove(data + 2, data, ieee80211_get_hdrlen(fc) - 2); - hdr = (struct ieee80211_hdr *) skb_pull(rx->skb, 2); - /* change frame type to non QOS */ - rx->fc = fc &= ~(WLAN_FC_STYPE_QOS_DATA << 4); - hdr->frame_control = cpu_to_le16(fc); - - return TXRX_CONTINUE; -} - - -/* maximum number of hardware queues we support. */ -#define TC_80211_MAX_QUEUES 8 - -struct ieee80211_sched_data -{ - struct tcf_proto *filter_list; - struct Qdisc *queues[TC_80211_MAX_QUEUES]; - struct sk_buff_head requeued[TC_80211_MAX_QUEUES]; -}; - - -/* given a data frame determine the 802.1p/1d tag to use */ -static inline unsigned classify_1d(struct sk_buff *skb, struct Qdisc *qd) -{ - struct iphdr *ip; - int dscp; - int offset; - -#ifdef CONFIG_NET_SCHED - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct tcf_result res = { -1, 0 }; - - /* if there is a user set filter list, call out to that */ - if (q->filter_list) { - tc_classify(skb, q->filter_list, &res); - if (res.class != -1) - return res.class; - } -#endif /* CONFIG_NET_SCHED */ - - /* skb->priority values from 256->263 are magic values to - * directly indicate a specific 802.1d priority. - * This is used to allow 802.1d priority to be passed directly in - * from VLAN tags, etc. */ - if (skb->priority >= 256 && skb->priority <= 263) - return skb->priority - 256; - - /* check there is a valid IP header present */ - offset = ieee80211_get_hdrlen_from_skb(skb) + 8 /* LLC + proto */; - if (skb->protocol != __constant_htons(ETH_P_IP) || - skb->len < offset + sizeof(*ip)) - return 0; - - ip = (struct iphdr *) (skb->data + offset); - - dscp = ip->tos & 0xfc; - switch (dscp) { - case 0x20: - return 2; - case 0x40: - return 1; - case 0x60: - return 3; - case 0x80: - return 4; - case 0xa0: - return 5; - case 0xc0: - return 6; - case 0xe0: - return 7; - default: - return 0; - } -} - - - - -static inline int wme_downgrade_ac(struct sk_buff *skb) -{ - switch (skb->priority) { - case 6: - case 7: - skb->priority = 5; /* VO -> VI */ - return 0; - case 4: - case 5: - skb->priority = 3; /* VI -> BE */ - return 0; - case 0: - case 3: - skb->priority = 2; /* BE -> BK */ - return 0; - default: - return -1; - } -} - - -/* positive return value indicates which queue to use - * negative return value indicates to drop the frame */ -static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) -{ - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_tx_packet_data *pkt_data = - (struct ieee80211_tx_packet_data *) skb->cb; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - unsigned short fc = le16_to_cpu(hdr->frame_control); - int qos; - const int ieee802_1d_to_ac[8] = { 2, 3, 3, 2, 1, 1, 0, 0 }; - - if (unlikely(pkt_data->magic != IEEE80211_CB_MAGIC)) - return -1; - - /* see if frame is data or non data frame */ - if (unlikely(WLAN_FC_GET_TYPE(fc) != WLAN_FC_TYPE_DATA)) { - /* management frames go on AC_VO queue, but are sent - * without QoS control fields */ - return IEEE80211_TX_QUEUE_DATA0; - } - - if (unlikely(pkt_data->sdata->type == IEEE80211_SUB_IF_TYPE_MGMT)) { - /* Data frames from hostapd (mainly, EAPOL) use AC_VO - * and they will include QoS control fields if - * the target STA is using WME. */ - skb->priority = 7; - return ieee802_1d_to_ac[skb->priority]; - } - - - /* is this a QoS frame? */ - qos = fc & (WLAN_FC_STYPE_QOS_DATA << 4); - - - if (!qos) { - skb->priority = 0; /* required for correct WPA/11i MIC */ - return ieee802_1d_to_ac[skb->priority]; - } - - /* use the data classifier to determine what 802.1d tag the - * data frame has */ - skb->priority = classify_1d(skb, qd); - - - /* incase we are a client verify acm is not set for this ac */ - for (; unlikely(local->wmm_acm & BIT(skb->priority)); ) - { - if (wme_downgrade_ac(skb)) { - /* No AC with lower priority has acm=0, - * drop packet. */ - return -1; - } - } - - /* look up which queue to use for frames with this 1d tag */ - return ieee802_1d_to_ac[skb->priority]; -} - - -static int wme_qdiscop_enqueue(struct sk_buff *skb, struct Qdisc* qd) -{ - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct ieee80211_tx_packet_data *pkt_data = - (struct ieee80211_tx_packet_data *) skb->cb; - struct ieee80211_tx_control *control = &pkt_data->control; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - unsigned short fc = le16_to_cpu(hdr->frame_control); - struct Qdisc *qdisc; - int err, queue; - - if (control->requeue) { - skb_queue_tail(&q->requeued[control->queue], skb); - return 0; - } - - queue = classify80211(skb, qd); - - /* now we know the 1d priority, fill in the QoS header if there is one */ - if (WLAN_FC_IS_QOS_DATA(fc)) { - struct qos_control *qc = (struct qos_control *) (skb->data + ieee80211_get_hdrlen(fc) - 2); - u8 *p = (u8 *) qc; - *p++ = 0; /* do this due to gcc's lack of optimization on bitfield ops */ - *p = 0; - qc->tag1d = skb->priority; - if (local->wifi_wme_noack_test) - qc->ack_policy = 1; - } - - if (unlikely(queue >= local->hw->queues)) { -#if 0 - if (net_ratelimit()) { - printk(KERN_DEBUG "%s - queue=%d (hw does not " - "support) -> %d\n", - __func__, queue, local->hw->queues - 1); - } -#endif - queue = local->hw->queues - 1; - } - - if (unlikely(queue < 0)) { - kfree_skb(skb); - err = NET_XMIT_DROP; - } else { - control->queue = (unsigned int) queue; - qdisc = q->queues[queue]; - err = qdisc->enqueue(skb, qdisc); - if (err == NET_XMIT_SUCCESS) { - qd->q.qlen++; - qd->bstats.bytes += skb->len; - qd->bstats.packets++; - return NET_XMIT_SUCCESS; - } - } - qd->qstats.drops++; - return err; -} - - -/* TODO: clean up the cases where master_hard_start_xmit - * returns non 0 - it shouldn't ever do that. Once done we - * can remove this function */ -static int wme_qdiscop_requeue(struct sk_buff *skb, struct Qdisc* qd) -{ - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct ieee80211_tx_packet_data *pkt_data = - (struct ieee80211_tx_packet_data *) skb->cb; - struct Qdisc *qdisc; - int err; - - /* we recorded which queue to use earlier! */ - qdisc = q->queues[pkt_data->control.queue]; - - if ((err = qdisc->ops->requeue(skb, qdisc)) == 0) { - qd->q.qlen++; - return 0; - } - qd->qstats.drops++; - return err; -} - - -static struct sk_buff *wme_qdiscop_dequeue(struct Qdisc* qd) -{ - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct net_device *dev = qd->dev; - struct ieee80211_local *local = dev->priv; - struct ieee80211_hw *hw = local->hw; - struct ieee80211_tx_queue_stats stats; - struct sk_buff *skb; - struct Qdisc *qdisc; - int queue; - - /* find which hardware queues have space in them */ - hw->get_tx_stats(dev, &stats); - - /* check all the h/w queues in numeric/priority order */ - for (queue = 0; queue < hw->queues; queue++) { - /* see if there is room in this hardware queue */ - if (stats.data[queue].len >= stats.data[queue].limit) - continue; - - /* there is space - try and get a frame */ - skb = skb_dequeue(&q->requeued[queue]); - if (skb) - return skb; - - qdisc = q->queues[queue]; - skb = qdisc->dequeue(qdisc); - if (skb) { - qd->q.qlen--; - return skb; - } - } - /* returning a NULL here when all the h/w queues are full means we - * never need to call netif_stop_queue in the driver */ - return NULL; -} - - -static void wme_qdiscop_reset(struct Qdisc* qd) -{ - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_hw *hw = local->hw; - int queue; - - /* QUESTION: should we have some hardware flush functionality here? */ - - for (queue = 0; queue < hw->queues; queue++) { - skb_queue_purge(&q->requeued[queue]); - qdisc_reset(q->queues[queue]); - } - qd->q.qlen = 0; -} - - -static void wme_qdiscop_destroy(struct Qdisc* qd) -{ - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_hw *hw = local->hw; - struct tcf_proto *tp; - int queue; - - while ((tp = q->filter_list) != NULL) { - q->filter_list = tp->next; - tp->ops->destroy(tp); - } - - for (queue=0; queue < hw->queues; queue++) { - skb_queue_purge(&q->requeued[queue]); - qdisc_destroy(q->queues[queue]); - q->queues[queue] = &noop_qdisc; - } -} - - -/* called whenever parameters are updated on existing qdisc */ -static int wme_qdiscop_tune(struct Qdisc *qd, struct rtattr *opt) -{ -/* struct ieee80211_sched_data *q = qdisc_priv(qd); -*/ - /* check our options block is the right size */ - /* copy any options to our local structure */ -/* Ignore options block for now - always use static mapping - struct tc_ieee80211_qopt *qopt = RTA_DATA(opt); - - if (opt->rta_len < RTA_LENGTH(sizeof(*qopt))) - return -EINVAL; - memcpy(q->tag2queue, qopt->tag2queue, sizeof(qopt->tag2queue)); -*/ - return 0; -} - - -/* called during initial creation of qdisc on device */ -static int wme_qdiscop_init(struct Qdisc *qd, struct rtattr *opt) -{ - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct net_device *dev = qd->dev; - struct ieee80211_local *local = dev->priv; - int queues = local->hw->queues; - int err = 0, i; - - /* check this device is an ieee80211 master type device */ - if (dev->type != ARPHRD_IEEE80211) - return -EINVAL; - - /* check that there is no qdisc currently attached to device - * this ensures that we will be the root qdisc. (I can't find a better - * way to test this explicitly) */ - if (dev->qdisc_sleeping != &noop_qdisc) - return -EINVAL; - - if (qd->flags & TCQ_F_INGRESS) - return -EINVAL; - - /* if options were passed in, set them */ - if (opt) { - err = wme_qdiscop_tune(qd, opt); - } - - /* create child queues */ - for (i = 0; i < queues; i++) { - skb_queue_head_init(&q->requeued[i]); - q->queues[i] = qdisc_create_dflt(qd->dev, &CHILD_QDISC_OPS); - if (q->queues[i] == 0) { - q->queues[i] = &noop_qdisc; - printk(KERN_ERR "%s child qdisc %i creation failed", dev->name, i); - } - } - - return err; -} - -static int wme_qdiscop_dump(struct Qdisc *qd, struct sk_buff *skb) -{ -/* struct ieee80211_sched_data *q = qdisc_priv(qd); - unsigned char *p = skb->tail; - struct tc_ieee80211_qopt opt; - - memcpy(&opt.tag2queue, q->tag2queue, TC_80211_MAX_TAG + 1); - RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt); -*/ return skb->len; -/* -rtattr_failure: - skb_trim(skb, p - skb->data);*/ - return -1; -} - - -static int wme_classop_graft(struct Qdisc *qd, unsigned long arg, - struct Qdisc *new, struct Qdisc **old) -{ - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_hw *hw = local->hw; - unsigned long queue = arg - 1; - - if (queue >= hw->queues) - return -EINVAL; - - if (new == NULL) - new = &noop_qdisc; - - sch_tree_lock(qd); - *old = q->queues[queue]; - q->queues[queue] = new; - qdisc_reset(*old); - sch_tree_unlock(qd); - - return 0; -} - - -static struct Qdisc * -wme_classop_leaf(struct Qdisc *qd, unsigned long arg) -{ - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_hw *hw = local->hw; - unsigned long queue = arg - 1; - - if (queue >= hw->queues) - return NULL; - - return q->queues[queue]; -} - - -static unsigned long wme_classop_get(struct Qdisc *qd, u32 classid) -{ - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_hw *hw = local->hw; - unsigned long queue = TC_H_MIN(classid); - - if (queue - 1 >= hw->queues) - return 0; - - return queue; -} - - -static unsigned long wme_classop_bind(struct Qdisc *qd, unsigned long parent, - u32 classid) -{ - return wme_classop_get(qd, classid); -} - - -static void wme_classop_put(struct Qdisc *q, unsigned long cl) -{ - /* printk(KERN_DEBUG "entering %s\n", __func__); */ -} - - -static int wme_classop_change(struct Qdisc *qd, u32 handle, u32 parent, - struct rtattr **tca, unsigned long *arg) -{ - unsigned long cl = *arg; - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_hw *hw = local->hw; - /* printk(KERN_DEBUG "entering %s\n", __func__); */ - - if (cl - 1 > hw->queues) - return -ENOENT; - - /* TODO: put code to program hardware queue parameters here, - * to allow programming from tc command line */ - - return 0; -} - - -/* we don't support deleting hardware queues - * when we add WMM-SA support - TSPECs may be deleted here */ -static int wme_classop_delete(struct Qdisc *qd, unsigned long cl) -{ - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_hw *hw = local->hw; - /* printk(KERN_DEBUG "entering %s\n", __func__); */ - - if (cl - 1 > hw->queues) - return -ENOENT; - return 0; -} - - -static int wme_classop_dump_class(struct Qdisc *qd, unsigned long cl, - struct sk_buff *skb, struct tcmsg *tcm) -{ - struct ieee80211_sched_data *q = qdisc_priv(qd); - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_hw *hw = local->hw; - /* printk(KERN_DEBUG "entering %s\n", __func__); */ - - if (cl - 1 > hw->queues) - return -ENOENT; - tcm->tcm_handle = TC_H_MIN(cl); - tcm->tcm_parent = qd->handle; - tcm->tcm_info = q->queues[cl-1]->handle; /* do we need this? */ - return 0; -} - - -static void wme_classop_walk(struct Qdisc *qd, struct qdisc_walker *arg) -{ - struct ieee80211_local *local = qd->dev->priv; - struct ieee80211_hw *hw = local->hw; - int queue; - /* printk(KERN_DEBUG "entering %s\n", __func__); */ - - if (arg->stop) - return; - - for (queue = 0; queue < hw->queues; queue++) { - if (arg->count < arg->skip) { - arg->count++; - continue; - } - /* we should return classids for our internal queues here - * as well as the external ones */ - if (arg->fn(qd, queue+1, arg) < 0) { - arg->stop = 1; - break; - } - arg->count++; - } -} - - -static struct tcf_proto ** wme_classop_find_tcf(struct Qdisc *qd, - unsigned long cl) -{ - struct ieee80211_sched_data *q = qdisc_priv(qd); - /* printk("entering %s\n", __func__); */ - - if (cl) - return NULL; - - return &q->filter_list; -} - - -/* this qdisc is classful (i.e. has classes, some of which may have leaf qdiscs attached) - * - these are the operations on the classes */ -static struct Qdisc_class_ops class_ops = -{ - .graft = wme_classop_graft, - .leaf = wme_classop_leaf, - - .get = wme_classop_get, - .put = wme_classop_put, - .change = wme_classop_change, - .delete = wme_classop_delete, - .walk = wme_classop_walk, - - .tcf_chain = wme_classop_find_tcf, - .bind_tcf = wme_classop_bind, - .unbind_tcf = wme_classop_put, - - .dump = wme_classop_dump_class, -}; - - -/* queueing discipline operations */ -static struct Qdisc_ops wme_qdisc_ops = -{ - .next = NULL, - .cl_ops = &class_ops, - .id = "ieee80211", - .priv_size = sizeof(struct ieee80211_sched_data), - - .enqueue = wme_qdiscop_enqueue, - .dequeue = wme_qdiscop_dequeue, - .requeue = wme_qdiscop_requeue, - .drop = NULL, /* drop not needed since we are always the root qdisc */ - - .init = wme_qdiscop_init, - .reset = wme_qdiscop_reset, - .destroy = wme_qdiscop_destroy, - .change = wme_qdiscop_tune, - - .dump = wme_qdiscop_dump, -}; - - -void ieee80211_install_qdisc(struct net_device *dev) -{ - struct Qdisc *qdisc; - - qdisc = qdisc_create_dflt(dev, &wme_qdisc_ops); - if (qdisc == NULL) { - printk(KERN_ERR "%s: qdisc installation failed\n", dev->name); - return; - } - - /* same handle as would be allocated by qdisc_alloc_handle() */ - qdisc->handle = 0x80010000; - - write_lock(&qdisc_tree_lock); - list_add_tail(&qdisc->list, &dev->qdisc_list); - dev->qdisc_sleeping = qdisc; - write_unlock(&qdisc_tree_lock); -} - - -int ieee80211_wme_register(void) -{ - int err = 0; - -#ifdef CONFIG_NET_SCHED - err = register_qdisc(&wme_qdisc_ops); -#endif - return err; -} - - -void ieee80211_wme_unregister(void) -{ -#ifdef CONFIG_NET_SCHED - unregister_qdisc(&wme_qdisc_ops); -#endif -} diff --git a/target/linux/package/ieee80211-dscape/src/wme.h b/target/linux/package/ieee80211-dscape/src/wme.h deleted file mode 100644 index 9b27947807..0000000000 --- a/target/linux/package/ieee80211-dscape/src/wme.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * IEEE 802.11 driver (80211.o) - QoS datatypes - * Copyright 2004, Instant802 Networks, Inc. - * Copyright 2005, Devicescape Software, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include - -#define QOS_CONTROL_LEN 2 - -#define QOS_CONTROL_ACK_POLICY_NORMAL 0 -#define QOS_CONTROL_ACK_POLICY_NOACK 1 - -#define QOS_CONTROL_TID_MASK 0x0f -#define QOS_CONTROL_ACK_POLICY_SHIFT 5 - -/* This bit field structure should not be used; it can cause compiler to - * generate unaligned accesses and inefficient code. */ -struct qos_control { -#if defined(__LITTLE_ENDIAN_BITFIELD) - u8 tag1d:3, /* bits 0-2 */ - reserved1:1, - eosp:1, - ack_policy:2, - reserved2:1; -#elif defined (__BIG_ENDIAN_BITFIELD) - u8 reserved2:1, - ack_policy:2, - eosp:1, - reserved1:1, - tag1d:3; /* bits 0-2 */ -#else -#error "Please fix " -#endif - u8 reserved; -} __attribute__ ((packed)); - -ieee80211_txrx_result -ieee80211_rx_h_parse_qos(struct ieee80211_txrx_data *rx); - -ieee80211_txrx_result -ieee80211_rx_h_remove_qos_control(struct ieee80211_txrx_data *rx); - -void ieee80211_install_qdisc(struct net_device *dev); - -int ieee80211_wme_register(void); -void ieee80211_wme_unregister(void); - diff --git a/target/linux/package/ieee80211-dscape/src/wpa.c b/target/linux/package/ieee80211-dscape/src/wpa.c deleted file mode 100644 index e0050dbd8f..0000000000 --- a/target/linux/package/ieee80211-dscape/src/wpa.c +++ /dev/null @@ -1,825 +0,0 @@ -/* - * Copyright 2002-2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "ieee80211_i.h" -#include "michael.h" -#include "tkip.h" -#include "aes_ccm.h" -#include "wpa.h" -#ifdef CONFIG_HOSTAPD_WPA_TESTING -#include "hostapd_ioctl.h" -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - -#define MICHAEL_MIC_HWACCEL - - -int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, - u8 *qos_tid, u8 **data, size_t *data_len) -{ - struct ieee80211_hdr *hdr; - size_t hdrlen; - u16 fc; - int a4_included; - u8 *pos; - - hdr = (struct ieee80211_hdr *) skb->data; - fc = le16_to_cpu(hdr->frame_control); - - hdrlen = 24; - if ((fc & (WLAN_FC_FROMDS | WLAN_FC_TODS)) == - (WLAN_FC_FROMDS | WLAN_FC_TODS)) { - hdrlen += ETH_ALEN; - *sa = hdr->addr4; - *da = hdr->addr3; - } else if (fc & WLAN_FC_FROMDS) { - *sa = hdr->addr3; - *da = hdr->addr1; - } else if (fc & WLAN_FC_TODS) { - *sa = hdr->addr2; - *da = hdr->addr3; - } else { - *sa = hdr->addr2; - *da = hdr->addr1; - } - - if (fc & 0x80) - hdrlen += 2; - - *data = skb->data + hdrlen; - *data_len = skb->len - hdrlen; - - a4_included = (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == - (WLAN_FC_TODS | WLAN_FC_FROMDS); - if (WLAN_FC_GET_TYPE(fc) == WLAN_FC_TYPE_DATA && - WLAN_FC_GET_STYPE(fc) & 0x08) { - pos = (u8 *) &hdr->addr4; - if (a4_included) - pos += 6; - *qos_tid = pos[0] & 0x0f; - *qos_tid |= 0x80; /* qos_included flag */ - } else - *qos_tid = 0; - - return skb->len < hdrlen ? -1 : 0; -} - - -ieee80211_txrx_result -ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx) -{ - u8 *data, *sa, *da, *key, *mic, qos_tid; - size_t data_len; - u16 fc; - struct sk_buff *skb = tx->skb; - int authenticator; -#if defined(CONFIG_HOSTAPD_WPA_TESTING) || defined(MICHAEL_MIC_HWACCEL) - int wpa_test = 0; -#endif - - fc = tx->fc; - - if (!tx->key || tx->key->alg != ALG_TKIP || skb->len < 24 || - !WLAN_FC_DATA_PRESENT(fc)) - return TXRX_CONTINUE; - - if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len)) - return TXRX_DROP; - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if ((tx->sta && tx->sta->wpa_trigger & WPA_TRIGGER_FAIL_TX_MIC) || - (!tx->u.tx.unicast && - tx->local->wpa_trigger & WPA_TRIGGER_FAIL_TX_MIC)) { - wpa_test = 1; - } -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - -#ifdef MICHAEL_MIC_HWACCEL - if (!tx->key->force_sw_encrypt && !tx->local->conf.sw_decrypt && - !tx->fragmented && !wpa_test) { - /* hwaccel - with no need for preallocated room for Michael MIC - */ - return TXRX_CONTINUE; - } -#endif /* MICHAEL_MIC_HWACCEL */ - - if (skb_tailroom(skb) < MICHAEL_MIC_LEN) { - I802_DEBUG_INC(tx->local->tx_expand_skb_head); - if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, - MICHAEL_MIC_LEN + TKIP_ICV_LEN, - GFP_ATOMIC))) { - printk(KERN_DEBUG "%s: failed to allocate more memory " - "for Michael MIC\n", tx->dev->name); - return TXRX_DROP; - } - } - -#if 0 - authenticator = fc & WLAN_FC_FROMDS; /* FIX */ -#else - authenticator = 1; -#endif - key = &tx->key->key[authenticator ? ALG_TKIP_TEMP_AUTH_TX_MIC_KEY : - ALG_TKIP_TEMP_AUTH_RX_MIC_KEY]; - mic = skb_put(skb, MICHAEL_MIC_LEN); - michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (tx->sta && tx->sta->wpa_trigger & WPA_TRIGGER_FAIL_TX_MIC) { - printk(KERN_INFO "%s: WPA testing - corrupting TX Michael MIC " - "for STA " MACSTR "\n", - tx->dev->name, MAC2STR(tx->sta->addr)); - tx->u.tx.control->key_idx = HW_KEY_IDX_INVALID; - tx->sta->wpa_trigger &= ~WPA_TRIGGER_FAIL_TX_MIC; - tx->wpa_test = 1; - mic[0]++; - } else if (!tx->u.tx.unicast && - tx->local->wpa_trigger & WPA_TRIGGER_FAIL_TX_MIC) { - printk(KERN_INFO "%s: WPA testing - corrupting TX Michael MIC " - "for Group Key\n", tx->dev->name); - tx->u.tx.control->key_idx = HW_KEY_IDX_INVALID; - tx->local->wpa_trigger &= ~WPA_TRIGGER_FAIL_TX_MIC; - tx->wpa_test = 1; - mic[0]++; - } -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - return TXRX_CONTINUE; -} - - -ieee80211_txrx_result -ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx) -{ - u8 *data, *sa, *da, *key = NULL, qos_tid; - size_t data_len; - u16 fc; - u8 mic[MICHAEL_MIC_LEN]; - struct sk_buff *skb = rx->skb; - int authenticator = 1, wpa_test = 0; - - fc = rx->fc; - - /* If device handles decryption totally, skip this check */ - if (rx->local->hw->device_hides_wep || - rx->local->hw->device_strips_mic) - return TXRX_CONTINUE; - - if (!rx->key || rx->key->alg != ALG_TKIP || - !(rx->fc & WLAN_FC_ISWEP) || !WLAN_FC_DATA_PRESENT(fc)) - return TXRX_CONTINUE; - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (rx->sta && rx->sta->wpa_trigger & WPA_TRIGGER_FAIL_RX_MIC) { - wpa_test = 1; - } -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - -#ifdef MICHAEL_MIC_HWACCEL - if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && - !rx->key->force_sw_encrypt && !rx->local->conf.sw_decrypt) { - if (rx->local->hw->wep_include_iv) { - if (skb->len < MICHAEL_MIC_LEN) - return TXRX_DROP; - } - /* Need to verify Michael MIC sometimes in software even when - * hwaccel is used. Atheros ar5212: fragmented frames and QoS - * frames. */ - if (!rx->fragmented && !wpa_test) - goto remove_mic; - } -#endif /* MICHAEL_MIC_HWACCEL */ - - if (ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len) - || data_len < MICHAEL_MIC_LEN) - return TXRX_DROP; - - data_len -= MICHAEL_MIC_LEN; - -#if 0 - authenticator = fc & WLAN_FC_TODS; /* FIX */ -#else - authenticator = 1; -#endif - key = &rx->key->key[authenticator ? ALG_TKIP_TEMP_AUTH_RX_MIC_KEY : - ALG_TKIP_TEMP_AUTH_TX_MIC_KEY]; - michael_mic(key, da, sa, qos_tid & 0x0f, data, data_len, mic); -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (rx->sta && rx->sta->wpa_trigger & WPA_TRIGGER_FAIL_RX_MIC) { - printk(KERN_INFO "%s: WPA testing - corrupting RX Michael MIC " - "for STA " MACSTR "\n", - rx->dev->name, MAC2STR(rx->sta->addr)); - rx->sta->wpa_trigger &= ~WPA_TRIGGER_FAIL_RX_MIC; - mic[0]++; - } -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - if (memcmp(mic, data + data_len, MICHAEL_MIC_LEN) != 0 || wpa_test) { -#ifdef CONFIG_HOSTAPD_WPA_TESTING - int i; -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - printk(KERN_DEBUG "%s: invalid Michael MIC in data frame from " - MACSTR "\n", rx->dev->name, MAC2STR(sa)); -#ifdef CONFIG_HOSTAPD_WPA_TESTING - printk(KERN_DEBUG " received"); - for (i = 0; i < MICHAEL_MIC_LEN; i++) - printk(" %02x", data[data_len + i]); - printk(" expected"); - for (i = 0; i < MICHAEL_MIC_LEN; i++) - printk(" %02x", mic[i]); - printk("\n"); - printk(KERN_DEBUG " SA=" MACSTR " DA=" MACSTR " key", - MAC2STR(sa), MAC2STR(da)); - for (i = 0; i < 8; i++) - printk(" %02x", key[i]); - printk(" (%d)\n", authenticator); -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - do { - struct ieee80211_hdr *hdr; - union iwreq_data wrqu; - char *buf = kmalloc(128, GFP_ATOMIC); - if (buf == NULL) - break; - - /* TODO: needed parameters: count, key type, TSC */ - hdr = (struct ieee80211_hdr *) skb->data; - sprintf(buf, "MLME-MICHAELMICFAILURE.indication(" - "keyid=%d %scast addr=" MACSTR ")", - rx->key->keyidx, - hdr->addr1[0] & 0x01 ? "broad" : "uni", - MAC2STR(hdr->addr2)); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(rx->dev, IWEVCUSTOM, &wrqu, buf); - kfree(buf); - } while (0); - - ieee80211_rx_mgmt(rx->dev, rx->skb, rx->u.rx.status, - ieee80211_msg_michael_mic_failure); - - return TXRX_QUEUED; - } - -#ifdef MICHAEL_MIC_HWACCEL - remove_mic: -#endif /* MICHAEL_MIC_HWACCEL */ - /* remove Michael MIC from payload */ - skb_trim(skb, skb->len - MICHAEL_MIC_LEN); - - return TXRX_CONTINUE; -} - - -static int tkip_encrypt_skb(struct ieee80211_txrx_data *tx, - struct sk_buff *skb, int test) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct ieee80211_key *key = tx->key; - int hdrlen, len, tailneed; - u16 fc; - u8 *pos; - - fc = le16_to_cpu(hdr->frame_control); - hdrlen = ieee80211_get_hdrlen(fc); - len = skb->len - hdrlen; - - tailneed = (!tx->key->force_sw_encrypt && !tx->local->conf.sw_decrypt) - ? 0 : TKIP_ICV_LEN; - if ((skb_headroom(skb) < TKIP_IV_LEN || - skb_tailroom(skb) < tailneed)) { - I802_DEBUG_INC(tx->local->tx_expand_skb_head); - if (unlikely(pskb_expand_head(skb, TKIP_IV_LEN, tailneed, - GFP_ATOMIC))) - return -1; - } - - pos = skb_push(skb, TKIP_IV_LEN); - memmove(pos, pos + TKIP_IV_LEN, hdrlen); - pos += hdrlen; - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (test & WPA_TRIGGER_TX_REPLAY) - goto skip_iv_inc; -iv_inc: -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - /* Increase IV for the frame */ - key->u.tkip.iv16++; - if (key->u.tkip.iv16 == 0) - key->u.tkip.iv32++; - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (test & WPA_TRIGGER_TX_SKIP_SEQ) { - test = 0; - goto iv_inc; - } -skip_iv_inc: -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - if (!tx->key->force_sw_encrypt && !tx->local->conf.sw_decrypt -#ifdef CONFIG_HOSTAPD_WPA_TESTING - && !tx->wpa_test -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - ) { - /* hwaccel - with preallocated room for IV */ - - ieee80211_tkip_add_iv(pos, key, - (u8) (key->u.tkip.iv16 >> 8), - (u8) (((key->u.tkip.iv16 >> 8) | 0x20) & - 0x7f), - (u8) key->u.tkip.iv16); - - tx->u.tx.control->key_idx = tx->key->hw_key_idx; - return 0; - } - - /* Add room for ICV */ - skb_put(skb, TKIP_ICV_LEN); - - hdr = (struct ieee80211_hdr *) skb->data; - ieee80211_tkip_encrypt_data(key, pos, len, hdr->addr2); - return 0; -} - - -ieee80211_txrx_result -ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; - u16 fc; - struct ieee80211_key *key = tx->key; - struct sk_buff *skb = tx->skb; - int wpa_test = 0, test = 0; - - fc = le16_to_cpu(hdr->frame_control); - - if (!key || key->alg != ALG_TKIP || !WLAN_FC_DATA_PRESENT(fc)) - return TXRX_CONTINUE; - - tx->u.tx.control->icv_len = TKIP_ICV_LEN; - tx->u.tx.control->iv_len = TKIP_IV_LEN; - ieee80211_tx_set_iswep(tx); - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if ((tx->sta && tx->sta->wpa_trigger & WPA_TRIGGER_FAIL_TX_ICV) || - (!tx->u.tx.unicast && - tx->local->wpa_trigger & WPA_TRIGGER_FAIL_TX_ICV)) { - wpa_test = 1; - } - - if (tx->sta) { - test = tx->sta->wpa_trigger; - tx->sta->wpa_trigger &= - ~(WPA_TRIGGER_TX_REPLAY | WPA_TRIGGER_TX_REPLAY_FRAG | - WPA_TRIGGER_TX_SKIP_SEQ); - } else { - test = tx->local->wpa_trigger; - tx->local->wpa_trigger &= - ~(WPA_TRIGGER_TX_REPLAY | WPA_TRIGGER_TX_REPLAY_FRAG | - WPA_TRIGGER_TX_SKIP_SEQ); - } - if (test & - (WPA_TRIGGER_TX_REPLAY | WPA_TRIGGER_TX_REPLAY_FRAG | - WPA_TRIGGER_TX_SKIP_SEQ)) { - printk(KERN_INFO "%s: WPA testing - TKIP TX packet number " - "%s%s%s%s\n", tx->dev->name, - tx->sta ? "[UNICAST]" : "[MULTICAST]", - test & WPA_TRIGGER_TX_REPLAY ? "[REPLAY]" : "", - test & WPA_TRIGGER_TX_REPLAY_FRAG ? - "[REPLAY FRAG]" : "", - test & WPA_TRIGGER_TX_SKIP_SEQ ? "[SKIP SEQ]" : ""); - } -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - if (!tx->key->force_sw_encrypt && !tx->local->conf.sw_decrypt && - !tx->local->hw->wep_include_iv && !wpa_test) { - /* hwaccel - with no need for preallocated room for IV/ICV */ - tx->u.tx.control->key_idx = tx->key->hw_key_idx; - return TXRX_CONTINUE; - } - - if (tkip_encrypt_skb(tx, skb, test) < 0) - return TXRX_DROP; - - if (tx->u.tx.extra_frag) { - int i; -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (test & WPA_TRIGGER_TX_REPLAY_FRAG) - test |= WPA_TRIGGER_TX_REPLAY; -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - for (i = 0; i < tx->u.tx.num_extra_frag; i++) { - if (tkip_encrypt_skb(tx, tx->u.tx.extra_frag[i], test) - < 0) - return TXRX_DROP; - } - } - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (tx->sta && tx->sta->wpa_trigger & WPA_TRIGGER_FAIL_TX_ICV) { - printk(KERN_INFO "%s: WPA testing - corrupting TX TKIP ICV " - "for STA " MACSTR "\n", - tx->dev->name, MAC2STR(tx->sta->addr)); - tx->u.tx.control->key_idx = HW_KEY_IDX_INVALID; - tx->sta->wpa_trigger &= ~WPA_TRIGGER_FAIL_TX_ICV; - skb->data[skb->len - 1]++; - } else if (!tx->u.tx.unicast && - tx->local->wpa_trigger & WPA_TRIGGER_FAIL_TX_ICV) { - printk(KERN_INFO "%s: WPA testing - corrupting TX TKIP ICV " - "for Group Key\n", - tx->dev->name); - tx->u.tx.control->key_idx = HW_KEY_IDX_INVALID; - tx->local->wpa_trigger &= ~WPA_TRIGGER_FAIL_TX_ICV; - skb->data[skb->len - 1]++; - } -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - return TXRX_CONTINUE; -} - - -ieee80211_txrx_result -ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; - u16 fc; - int hdrlen, res, hwaccel = 0, wpa_test = 0; - struct ieee80211_key *key = rx->key; - struct sk_buff *skb = rx->skb; - - fc = le16_to_cpu(hdr->frame_control); - hdrlen = ieee80211_get_hdrlen(fc); - - if (!rx->key || rx->key->alg != ALG_TKIP || - !(rx->fc & WLAN_FC_ISWEP) || - WLAN_FC_GET_TYPE(rx->fc) != WLAN_FC_TYPE_DATA) - return TXRX_CONTINUE; - - if (!rx->sta || skb->len - hdrlen < 12) - return TXRX_DROP; - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (rx->sta && rx->sta->wpa_trigger & WPA_TRIGGER_FAIL_RX_ICV) { - printk(KERN_INFO "%s: WPA testing - corrupting RX TKIP ICV " - "for STA " MACSTR "\n", - rx->dev->name, MAC2STR(rx->sta->addr)); - rx->sta->wpa_trigger &= ~WPA_TRIGGER_FAIL_RX_ICV; - skb->data[skb->len - 1]++; - wpa_test = 1; - } -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && - !rx->key->force_sw_encrypt && !rx->local->conf.sw_decrypt) { - if (!rx->local->hw->wep_include_iv) { - /* Hardware takes care of all processing, including - * replay protection, so no need to continue here. */ - return TXRX_CONTINUE; - } - - /* let TKIP code verify IV, but skip decryption */ - hwaccel = 1; - } - - res = ieee80211_tkip_decrypt_data(key, skb->data + hdrlen, - skb->len - hdrlen, rx->sta->addr, - hwaccel, rx->u.rx.queue); - if (res != TKIP_DECRYPT_OK || wpa_test) { - printk(KERN_DEBUG "%s: TKIP decrypt failed for RX frame from " - MACSTR " (res=%d)\n", - rx->dev->name, MAC2STR(rx->sta->addr), res); - return TXRX_DROP; - } - - /* Trim ICV */ - skb_trim(skb, skb->len - TKIP_ICV_LEN); - - /* Remove IV */ - memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen); - skb_pull(skb, TKIP_IV_LEN); - - return TXRX_CONTINUE; -} - - -static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad, - int encrypted) -{ - u16 fc; - int a4_included, qos_included; - u8 qos_tid, *fc_pos, *data, *sa, *da; - int len_a; - size_t data_len; - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - - fc_pos = (u8 *) &hdr->frame_control; - fc = fc_pos[0] ^ (fc_pos[1] << 8); - a4_included = (fc & (WLAN_FC_TODS | WLAN_FC_FROMDS)) == - (WLAN_FC_TODS | WLAN_FC_FROMDS); - - ieee80211_get_hdr_info(skb, &sa, &da, &qos_tid, &data, &data_len); - data_len -= CCMP_HDR_LEN + (encrypted ? CCMP_MIC_LEN : 0); - if (qos_tid & 0x80) { - qos_included = 1; - qos_tid &= 0x0f; - } else - qos_included = 0; - /* First block, b_0 */ - - b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ - /* Nonce: QoS Priority | A2 | PN */ - b_0[1] = qos_tid; - memcpy(&b_0[2], hdr->addr2, 6); - memcpy(&b_0[8], pn, CCMP_PN_LEN); - /* l(m) */ - b_0[14] = (data_len >> 8) & 0xff; - b_0[15] = data_len & 0xff; - - - /* AAD (extra authenticate-only data) / masked 802.11 header - * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ - - len_a = a4_included ? 28 : 22; - if (qos_included) - len_a += 2; - - aad[0] = 0; /* (len_a >> 8) & 0xff; */ - aad[1] = len_a & 0xff; - /* Mask FC: zero subtype b4 b5 b6 */ - aad[2] = fc_pos[0] & ~(BIT(4) | BIT(5) | BIT(6)); - /* Retry, PwrMgt, MoreData; set Protected */ - aad[3] = (fc_pos[1] & ~(BIT(3) | BIT(4) | BIT(5))) | BIT(6); - memcpy(&aad[4], &hdr->addr1, 18); - - /* Mask Seq#, leave Frag# */ - aad[22] = *((u8 *) &hdr->seq_ctrl) & 0x0f; - aad[23] = 0; - if (a4_included) { - memcpy(&aad[24], hdr->addr4, 6); - aad[30] = 0; - aad[31] = 0; - } else - memset(&aad[24], 0, 8); - if (qos_included) { - u8 *dpos = &aad[a4_included ? 30 : 24]; - - /* Mask QoS Control field */ - dpos[0] = qos_tid; - dpos[1] = 0; - } -} - - -static inline void ccmp_pn2hdr(u8 *hdr, u8 *pn, int key_id) -{ - hdr[0] = pn[5]; - hdr[1] = pn[4]; - hdr[2] = 0; - hdr[3] = 0x20 | (key_id << 6); - hdr[4] = pn[3]; - hdr[5] = pn[2]; - hdr[6] = pn[1]; - hdr[7] = pn[0]; -} - - -static inline int ccmp_hdr2pn(u8 *pn, u8 *hdr) -{ - pn[0] = hdr[7]; - pn[1] = hdr[6]; - pn[2] = hdr[5]; - pn[3] = hdr[4]; - pn[4] = hdr[1]; - pn[5] = hdr[0]; - return (hdr[3] >> 6) & 0x03; -} - - -static int ccmp_encrypt_skb(struct ieee80211_txrx_data *tx, - struct sk_buff *skb, int test) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; - struct ieee80211_key *key = tx->key; - int hdrlen, len, tailneed; - u16 fc; - u8 *pos, *pn; - u8 b_0[AES_BLOCK_LEN], aad[2 * AES_BLOCK_LEN]; - int i; - - fc = le16_to_cpu(hdr->frame_control); - hdrlen = ieee80211_get_hdrlen(fc); - len = skb->len - hdrlen; - - tailneed = (!tx->key->force_sw_encrypt && !tx->local->conf.sw_decrypt) - ? 0 : CCMP_MIC_LEN; - - if ((skb_headroom(skb) < CCMP_HDR_LEN || - skb_tailroom(skb) < tailneed)) { - I802_DEBUG_INC(tx->local->tx_expand_skb_head); - if (unlikely(pskb_expand_head(skb, CCMP_HDR_LEN, tailneed, - GFP_ATOMIC))) - return -1; - } - - pos = skb_push(skb, CCMP_HDR_LEN); - memmove(pos, pos + CCMP_HDR_LEN, hdrlen); - hdr = (struct ieee80211_hdr *) pos; - pos += hdrlen; - - /* PN = PN + 1 */ - pn = key->u.ccmp.tx_pn; - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (test & WPA_TRIGGER_TX_REPLAY) - goto skip_pn_inc; -pn_inc: -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - for (i = CCMP_PN_LEN - 1; i >= 0; i--) { - pn[i]++; - if (pn[i]) - break; - } - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (test & WPA_TRIGGER_TX_SKIP_SEQ) { - test = 0; - goto pn_inc; - } -skip_pn_inc: -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - ccmp_pn2hdr(pos, pn, key->keyidx); - - if (!tx->key->force_sw_encrypt && !tx->local->conf.sw_decrypt) { - /* hwaccel - with preallocated room for CCMP header */ - tx->u.tx.control->key_idx = tx->key->hw_key_idx; - return 0; - } - - pos += CCMP_HDR_LEN; - ccmp_special_blocks(skb, pn, b_0, aad, 0); - ieee80211_aes_ccm_encrypt(key->u.ccmp.aes_state, b_0, aad, pos, len, - pos, skb_put(skb, CCMP_MIC_LEN)); - - return 0; -} - - -ieee80211_txrx_result -ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx->skb->data; - struct ieee80211_key *key = tx->key; - u16 fc; - struct sk_buff *skb = tx->skb; - int test = 0; - - fc = le16_to_cpu(hdr->frame_control); - - if (!key || key->alg != ALG_CCMP || !WLAN_FC_DATA_PRESENT(fc)) - return TXRX_CONTINUE; - -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (tx->sta) { - test = tx->sta->wpa_trigger; - tx->sta->wpa_trigger = 0; - } else { - test = tx->local->wpa_trigger; - tx->local->wpa_trigger = 0; - } - if (test & - (WPA_TRIGGER_TX_REPLAY | WPA_TRIGGER_TX_REPLAY_FRAG | - WPA_TRIGGER_TX_SKIP_SEQ)) { - printk(KERN_INFO "%s: WPA testing - CCMP TX packet number " - "%s%s%s%s\n", tx->dev->name, - tx->sta ? "[UNICAST]" : "[MULTICAST]", - test & WPA_TRIGGER_TX_REPLAY ? "[REPLAY]" : "", - test & WPA_TRIGGER_TX_REPLAY_FRAG ? - "[REPLAY FRAG]" : "", - test & WPA_TRIGGER_TX_SKIP_SEQ ? "[SKIP SEQ]" : ""); - } -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - - tx->u.tx.control->icv_len = CCMP_MIC_LEN; - tx->u.tx.control->iv_len = CCMP_HDR_LEN; - ieee80211_tx_set_iswep(tx); - - if (!tx->key->force_sw_encrypt && !tx->local->conf.sw_decrypt && - !tx->local->hw->wep_include_iv) { - /* hwaccel - with no need for preallocated room for CCMP " - * header or MIC fields */ - tx->u.tx.control->key_idx = tx->key->hw_key_idx; - return TXRX_CONTINUE; - } - - if (ccmp_encrypt_skb(tx, skb, test) < 0) - return TXRX_DROP; - - if (tx->u.tx.extra_frag) { - int i; -#ifdef CONFIG_HOSTAPD_WPA_TESTING - if (test & WPA_TRIGGER_TX_REPLAY_FRAG) - test |= WPA_TRIGGER_TX_REPLAY; -#endif /* CONFIG_HOSTAPD_WPA_TESTING */ - for (i = 0; i < tx->u.tx.num_extra_frag; i++) { - if (ccmp_encrypt_skb(tx, tx->u.tx.extra_frag[i], test) - < 0) - return TXRX_DROP; - } - } - - return TXRX_CONTINUE; -} - - -ieee80211_txrx_result -ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx) -{ - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; - u16 fc; - int hdrlen; - struct ieee80211_key *key = rx->key; - struct sk_buff *skb = rx->skb; - u8 b_0[AES_BLOCK_LEN], aad[2 * AES_BLOCK_LEN]; - u8 pn[CCMP_PN_LEN]; - int data_len; - - fc = le16_to_cpu(hdr->frame_control); - hdrlen = ieee80211_get_hdrlen(fc); - - if (!rx->key || rx->key->alg != ALG_CCMP || - !(rx->fc & WLAN_FC_ISWEP) || - WLAN_FC_GET_TYPE(rx->fc) != WLAN_FC_TYPE_DATA) - return TXRX_CONTINUE; - - data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; - if (!rx->sta || data_len < 0) - return TXRX_DROP; - - if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && - !rx->key->force_sw_encrypt && !rx->local->conf.sw_decrypt && - !rx->local->hw->wep_include_iv) - return TXRX_CONTINUE; - - (void) ccmp_hdr2pn(pn, skb->data + hdrlen); - - if (memcmp(pn, key->u.ccmp.rx_pn[rx->u.rx.queue], CCMP_PN_LEN) <= 0) { -#ifdef CONFIG_IEEE80211_DEBUG - u8 *ppn = key->u.ccmp.rx_pn[rx->u.rx.queue]; - printk(KERN_DEBUG "%s: CCMP replay detected for RX frame from " - MACSTR " (RX PN %02x%02x%02x%02x%02x%02x <= prev. PN " - "%02x%02x%02x%02x%02x%02x)\n", rx->dev->name, - MAC2STR(rx->sta->addr), - pn[0], pn[1], pn[2], pn[3], pn[4], pn[5], - ppn[0], ppn[1], ppn[2], ppn[3], ppn[4], ppn[5]); -#endif /* CONFIG_IEEE80211_DEBUG */ - key->u.ccmp.replays++; - return TXRX_DROP; - } - - if ((rx->u.rx.status->flag & RX_FLAG_DECRYPTED) && - !rx->key->force_sw_encrypt && !rx->local->conf.sw_decrypt) { - /* hwaccel has already decrypted frame and verified MIC */ - } else { - ccmp_special_blocks(skb, pn, b_0, aad, 1); - - if (ieee80211_aes_ccm_decrypt( - key->u.ccmp.aes_state, b_0, aad, - skb->data + hdrlen + CCMP_HDR_LEN, data_len, - skb->data + skb->len - CCMP_MIC_LEN, - skb->data + hdrlen + CCMP_HDR_LEN)) { - printk(KERN_DEBUG "%s: CCMP decrypt failed for RX " - "frame from " MACSTR "\n", rx->dev->name, - MAC2STR(rx->sta->addr)); - return TXRX_DROP; - } - } - - memcpy(key->u.ccmp.rx_pn[rx->u.rx.queue], pn, CCMP_PN_LEN); - - /* Remove CCMP header and MIC */ - skb_trim(skb, skb->len - CCMP_MIC_LEN); - memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); - skb_pull(skb, CCMP_HDR_LEN); - - return TXRX_CONTINUE; -} - diff --git a/target/linux/package/ieee80211-dscape/src/wpa.h b/target/linux/package/ieee80211-dscape/src/wpa.h deleted file mode 100644 index 9ad7c0813e..0000000000 --- a/target/linux/package/ieee80211-dscape/src/wpa.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2002-2004, Instant802 Networks, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#ifndef WPA_H -#define WPA_H - -ieee80211_txrx_result -ieee80211_tx_h_michael_mic_add(struct ieee80211_txrx_data *tx); -ieee80211_txrx_result -ieee80211_rx_h_michael_mic_verify(struct ieee80211_txrx_data *rx); - -ieee80211_txrx_result -ieee80211_tx_h_tkip_encrypt(struct ieee80211_txrx_data *tx); -ieee80211_txrx_result -ieee80211_rx_h_tkip_decrypt(struct ieee80211_txrx_data *rx); - -ieee80211_txrx_result -ieee80211_tx_h_ccmp_encrypt(struct ieee80211_txrx_data *tx); -ieee80211_txrx_result -ieee80211_rx_h_ccmp_decrypt(struct ieee80211_txrx_data *rx); - -int ieee80211_get_hdr_info(const struct sk_buff *skb, u8 **sa, u8 **da, - u8 *qos_tid, u8 **data, size_t *data_len); - -#endif /* WPA_H */ diff --git a/target/linux/package/madwifi/Config.in b/target/linux/package/madwifi/Config.in index 6eda342f81..168f1e7b8b 100644 --- a/target/linux/package/madwifi/Config.in +++ b/target/linux/package/madwifi/Config.in @@ -1,7 +1,7 @@ config PACKAGE_KMOD_MADWIFI prompt "kmod-madwifi...................... Atheros Wifi driver" tristate - default y if LINUX_2_6_BRCM || LINUX_2_6_ARUBA || LINUX_2_4_AR531X + default y if LINUX_2_6_BRCM || LINUX_2_6_ARUBA || LINUX_2_4_AR531X || LINUX_2_6_XSCALE default m if DEVEL default n help diff --git a/target/linux/package/madwifi/Makefile b/target/linux/package/madwifi/Makefile index d42372b52e..97cb0bd5e5 100644 --- a/target/linux/package/madwifi/Makefile +++ b/target/linux/package/madwifi/Makefile @@ -4,9 +4,9 @@ include $(TOPDIR)/rules.mk include ../../rules.mk PKG_NAME:=madwifi-ng -PKG_VERSION:=r1486-20060329 +PKG_VERSION:=r1543-20060506 PKG_RELEASE:=1 -PKG_MD5SUM:=71f1c654531ca8516bf7cdb5e80eb10f +PKG_MD5SUM:=3d89e5197c7e43eb37564c176140b2bf PKG_SOURCE_URL:=http://snapshots.madwifi.org/$(PKG_NAME) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz @@ -23,6 +23,9 @@ endif ifeq ($(ARCH),i386) HAL_TARGET:=i386-elf endif +ifeq ($(ARCH),armeb) +HAL_TARGET:=xscale-be-elf +endif BUS := PCI diff --git a/target/linux/package/madwifi/patches/100-kernel_cflags.patch b/target/linux/package/madwifi/patches/100-kernel_cflags.patch index 39aac7626a..b67183c384 100644 --- a/target/linux/package/madwifi/patches/100-kernel_cflags.patch +++ b/target/linux/package/madwifi/patches/100-kernel_cflags.patch @@ -30,3 +30,14 @@ diff -ru madwifi-ng-r1486-20060329/hal/public/mips-le-elf.inc madwifi-ng-r1486-2 -COPTS+= -G 0 -EL -mno-abicalls -fno-pic -Wa,--trap \ +COPTS+= -G 0 -EL -mno-abicalls -fno-pic -Wa,--trap -mips32 \ -fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls +diff -ur madwifi-ng-r1486-20060329/hal/public/xscale-be-elf.inc madwifi-ng-r1486-20060329-patch/hal/public/xscale-be-elf.inc +--- madwifi-ng-r1486-20060329/hal/public/xscale-be-elf.inc 2006-02-11 13:04:39.000000000 +0100 ++++ madwifi-ng-r1486-20060329-patch/hal/public/xscale-be-elf.inc 2006-04-16 15:07:59.000000000 +0200 +@@ -72,5 +72,5 @@ + + LDOPTS= -EB + COPTS+= -DAH_BYTE_ORDER=AH_BIG_ENDIAN -DAH_REGOPS_FUNC +-COPTS+= -march=armv4 -mbig-endian -fno-strict-aliasing -fno-common -mapcs-32 \ +- -mtune=xscale -mshort-load-bytes -msoft-float -mfp=2 ++COPTS+= -mcpu=xscale -mbig-endian -fno-strict-aliasing -fno-common \ ++ -msoft-float -mfp=2 diff --git a/target/linux/package/wlcompat/Config.in b/target/linux/package/wlcompat/Config.in index 904d1e6645..00774c1792 100644 --- a/target/linux/package/wlcompat/Config.in +++ b/target/linux/package/wlcompat/Config.in @@ -2,7 +2,7 @@ config PACKAGE_KMOD_WLCOMPAT prompt "kmod-wlcompat..................... Wrapper providing Wireless Extensions for Broadcom wl module" tristate default y - depends PACKAGE_KMOD_BRCM_WL || PACKAGE_KMOD_BRCM_WL2 + depends PACKAGE_KMOD_BRCM_WL help A wrapper module, that provides Wireless Extension support for the proprietary Broadcom wl module. @@ -11,7 +11,7 @@ config PACKAGE_KMOD_WLCOMPAT_DEBUG prompt "kmod-wlcompat-debug............... Wrapper providing Wireless Extensions for Broadcom wl module (debug)" tristate default m - depends PACKAGE_KMOD_BRCM_WL || PACKAGE_KMOD_BRCM_WL2 + depends PACKAGE_KMOD_BRCM_WL help A wrapper module, that provides Wireless Extension support for the proprietary Broadcom wl module. (debug version) diff --git a/target/linux/package/wlcompat/wlcompat.c b/target/linux/package/wlcompat/wlcompat.c index 7063c809a6..1540a21167 100644 --- a/target/linux/package/wlcompat/wlcompat.c +++ b/target/linux/package/wlcompat/wlcompat.c @@ -980,13 +980,13 @@ static int new_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { static int __init wlcompat_init() { int found = 0, i; - char *devname = "eth0"; + char devname[4] = "wl0"; bss_force = 0; while (!found && (dev = dev_get_by_name(devname))) { if ((dev->wireless_handlers == NULL) && ((wl_ioctl(dev, WLC_GET_MAGIC, &i, sizeof(i)) == 0) && i == WLC_IOCTL_MAGIC)) found = 1; - devname[3]++; + devname[2]++; } if (!found) { diff --git a/target/linux/rules.mk b/target/linux/rules.mk index 8490d110de..da32ed8b04 100644 --- a/target/linux/rules.mk +++ b/target/linux/rules.mk @@ -20,6 +20,7 @@ LINUX_KARCH:=$(shell echo $(ARCH) | sed -e 's/i[3-9]86/i386/' \ -e 's/mipseb/mips/' \ -e 's/powerpc/ppc/' \ -e 's/sh[234]/sh/' \ + -e 's/armeb/arm/' \ ) KPKG_MAKEOPTS:= IPKG="$(IPKG_KERNEL)" \ @@ -75,6 +76,11 @@ ifneq ($(6),) for module in $(7); do \ echo $$$$module >> $$(I_$(1))/etc/modules.d/$(6)-$(2); \ done + echo "#!/bin/sh" >> $$(I_$(1))/CONTROL/postinst + echo "[ -z \"\$$$$IPKG_INSTROOT\" ] || exit" >> $$(I_$(1))/CONTROL/postinst + echo ". /etc/functions.sh" >> $$(I_$(1))/CONTROL/postinst + echo "load_modules /etc/modules.d/$(6)-$(2)" >> $$(I_$(1))/CONTROL/postinst + chmod 0755 $$(I_$(1))/CONTROL/postinst endif $(8) $(IPKG_BUILD) $$(I_$(1)) $(PACKAGE_DIR) diff --git a/target/linux/sibyte-2.6/Makefile b/target/linux/sibyte-2.6/Makefile new file mode 100644 index 0000000000..3309a84e55 --- /dev/null +++ b/target/linux/sibyte-2.6/Makefile @@ -0,0 +1,19 @@ +include $(TOPDIR)/rules.mk + +LINUX_VERSION:=2.6.16.7 +LINUX_RELEASE:=1 +LINUX_KERNEL_MD5SUM:=9682b2bd6e02f3087982d7c3f5ba824e + +include ../rules.mk +include ./config + +include ../generic-$(KERNEL)/modules.mk +include ../kernel.mk + + +$(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked + [ -d ../generic-$(KERNEL)/patches ] && $(PATCH) $(LINUX_DIR) ../generic-$(KERNEL)/patches + [ -d ./patches ] && $(PATCH) $(LINUX_DIR) ./patches + @$(CP) config $(LINUX_DIR)/.config + touch $@ + diff --git a/target/linux/sibyte-2.6/config b/target/linux/sibyte-2.6/config new file mode 100644 index 0000000000..221d833b89 --- /dev/null +++ b/target/linux/sibyte-2.6/config @@ -0,0 +1,1311 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.16.4 +# Fri Apr 21 16:08:33 2006 +# +CONFIG_MIPS=y + +# +# Machine selection +# +# CONFIG_MIPS_MTX1 is not set +# CONFIG_MIPS_BOSPORUS is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_MIPS_PB1550 is not set +# CONFIG_MIPS_PB1200 is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_DB1550 is not set +# CONFIG_MIPS_DB1200 is not set +# CONFIG_MIPS_MIRAGE is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_MACH_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MACH_JAZZ is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MIPS_SIM is not set +# CONFIG_MOMENCO_JAGUAR_ATX is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_3 is not set +# CONFIG_MOMENCO_OCELOT_C is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_MIPS_XXS1500 is not set +# CONFIG_PNX8550_V2PCI is not set +# CONFIG_PNX8550_JBS is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_MACH_VR41XX is not set +# CONFIG_PMC_YOSEMITE is not set +# CONFIG_QEMU is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_BIGSUR is not set +CONFIG_SIBYTE_SWARM=y +# CONFIG_SIBYTE_SENTOSA is not set +# CONFIG_SIBYTE_RHONE is not set +# CONFIG_SIBYTE_CARMEL is not set +# CONFIG_SIBYTE_PTSWARM is not set +# CONFIG_SIBYTE_LITTLESUR is not set +# CONFIG_SIBYTE_CRHINE is not set +# CONFIG_SIBYTE_CRHONE is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_TOSHIBA_RBTX4927 is not set +# CONFIG_TOSHIBA_RBTX4938 is not set +CONFIG_SIBYTE_SB1250=y +CONFIG_SIBYTE_SB1xxx_SOC=y +# CONFIG_CPU_SB1_PASS_1 is not set +# CONFIG_CPU_SB1_PASS_2_1250 is not set +# CONFIG_CPU_SB1_PASS_2_2 is not set +CONFIG_CPU_SB1_PASS_4=y +# CONFIG_CPU_SB1_PASS_2_112x is not set +# CONFIG_CPU_SB1_PASS_3 is not set +CONFIG_SIBYTE_HAS_LDT=y +# CONFIG_SIMULATION is not set +# CONFIG_SB1_CEX_ALWAYS_FATAL is not set +# CONFIG_SB1_CERR_STALL is not set +CONFIG_SIBYTE_CFE=y +CONFIG_SIBYTE_CFE_CONSOLE=y +# CONFIG_SIBYTE_BUS_WATCHER is not set +# CONFIG_SIBYTE_SB1250_PROF is not set +# CONFIG_SIBYTE_TBPROF is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_DMA_COHERENT=y +CONFIG_CPU_BIG_ENDIAN=y +# CONFIG_CPU_LITTLE_ENDIAN is not set +CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y +CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y +CONFIG_SWAP_IO_SPACE=y +CONFIG_BOOT_ELF32=y +CONFIG_MIPS_L1_CACHE_SHIFT=5 + +# +# CPU selection +# +# CONFIG_CPU_MIPS32_R1 is not set +# CONFIG_CPU_MIPS32_R2 is not set +# CONFIG_CPU_MIPS64_R1 is not set +# CONFIG_CPU_MIPS64_R2 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_RM9000 is not set +CONFIG_CPU_SB1=y +CONFIG_SYS_HAS_CPU_SB1=y +CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y +CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y +CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y + +# +# Kernel type +# +# CONFIG_32BIT is not set +CONFIG_64BIT=y +CONFIG_PAGE_SIZE_4KB=y +# CONFIG_PAGE_SIZE_8KB is not set +# CONFIG_PAGE_SIZE_16KB is not set +# CONFIG_PAGE_SIZE_64KB is not set +# CONFIG_SIBYTE_DMA_PAGEOPS is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_MIPS_MT is not set +CONFIG_CPU_HAS_LLSC=y +CONFIG_CPU_HAS_SYNC=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_CPU_SUPPORTS_HIGHMEM=y +CONFIG_SYS_SUPPORTS_HIGHMEM=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_SMP=y +CONFIG_NR_CPUS=2 +CONFIG_PREEMPT_NONE=y +# CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPT is not set +# CONFIG_PREEMPT_BKL is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_CPUSETS=y +CONFIG_INITRAMFS_SOURCE="../root" +CONFIG_INITRAMFS_ROOT_UID=0 +CONFIG_INITRAMFS_ROOT_GID=0 +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_SLAB is not set +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +CONFIG_SLOB=y +CONFIG_OBSOLETE_INTERMODULE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set +CONFIG_STOP_MACHINE=y + +# +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +CONFIG_DEFAULT_AS=y +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +# CONFIG_DEFAULT_NOOP is not set +CONFIG_DEFAULT_IOSCHED="anticipatory" + +# +# Bus options (PCI, PCMCIA, EISA, ISA, TC) +# +CONFIG_HW_HAS_PCI=y +CONFIG_PCI=y +# CONFIG_PCI_LEGACY_PROC is not set +CONFIG_MMU=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Executable file formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +CONFIG_BUILD_ELF64=y +CONFIG_MIPS32_COMPAT=y +CONFIG_COMPAT=y +CONFIG_MIPS32_O32=y +# CONFIG_MIPS32_N32 is not set +CONFIG_BINFMT_ELF32=y + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_ASK_IP_FIB_HASH=y +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_MULTIPATH=y +# CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_NET_IPGRE_BROADCAST is not set +CONFIG_IPSEC_NAT_TRAVERSAL=y +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y + +# +# TCP congestion control +# +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=m +CONFIG_TCP_CONG_HTCP=m +CONFIG_TCP_CONG_HSTCP=m +CONFIG_TCP_CONG_HYBLA=m +CONFIG_TCP_CONG_VEGAS=y +CONFIG_TCP_CONG_SCALABLE=m + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_BRIDGE_NETFILTER is not set + +# +# Core Netfilter Configuration +# +# CONFIG_NETFILTER_NETLINK is not set +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +CONFIG_NETFILTER_XT_TARGET_CONNMARK=m +CONFIG_NETFILTER_XT_TARGET_MARK=m +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +CONFIG_NETFILTER_XT_MATCH_CONNMARK=m +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +CONFIG_NETFILTER_XT_MATCH_HELPER=m +CONFIG_NETFILTER_XT_MATCH_LENGTH=m +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=y +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +CONFIG_NETFILTER_XT_MATCH_TCPMSS=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=y +CONFIG_IP_NF_IRC=y +# CONFIG_IP_NF_NETBIOS_NS is not set +CONFIG_IP_NF_TFTP=m +CONFIG_IP_NF_AMANDA=m +CONFIG_IP_NF_PPTP=m +CONFIG_IP_NF_SIP=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_LAYER7=m +# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_IPP2P=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TIME=m +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +# CONFIG_IP_NF_MATCH_POLICY is not set +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_IMQ=m +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_REDIRECT=y +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_SAME is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=y +CONFIG_IP_NF_NAT_FTP=y +CONFIG_IP_NF_NAT_TFTP=m +CONFIG_IP_NF_NAT_AMANDA=m +CONFIG_IP_NF_NAT_PPTP=m +CONFIG_IP_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_TTL=m +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set +CONFIG_IP_NF_SET=m +CONFIG_IP_NF_SET_MAX=256 +CONFIG_IP_NF_SET_HASHSIZE=1024 +CONFIG_IP_NF_SET_IPMAP=m +CONFIG_IP_NF_SET_MACIPMAP=m +CONFIG_IP_NF_SET_PORTMAP=m +CONFIG_IP_NF_SET_IPHASH=m +CONFIG_IP_NF_SET_NETHASH=m +CONFIG_IP_NF_SET_IPTREE=m +CONFIG_IP_NF_MATCH_SET=m +CONFIG_IP_NF_TARGET_SET=m + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_AHESP is not set +CONFIG_IP6_NF_MATCH_EUI64=m +# CONFIG_IP6_NF_MATCH_POLICY is not set +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_IMQ=m +# CONFIG_IP6_NF_TARGET_LOG is not set +CONFIG_IP6_NF_TARGET_REJECT=m +CONFIG_IP6_NF_MANGLE=m +# CONFIG_IP6_NF_TARGET_HL is not set +# CONFIG_IP6_NF_RAW is not set + +# +# Bridge: Netfilter Configuration +# +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_ARP=m +CONFIG_BRIDGE_EBT_IP=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_MARK=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_MARK_T=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_ULOG=m + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +CONFIG_ATM=m +CONFIG_ATM_CLIP=m +CONFIG_ATM_CLIP_NO_ICMP=y +CONFIG_ATM_LANE=m +CONFIG_ATM_MPOA=m +CONFIG_ATM_BR2684=m +CONFIG_ATM_BR2684_IPFILTER=y +CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_ATM=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_ESFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +# CONFIG_NET_SCH_NETEM is not set +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +# CONFIG_CLS_U32_PERF is not set +# CONFIG_CLS_U32_MARK is not set +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_ESTIMATOR=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +CONFIG_HAMRADIO=y + +# +# Packet Radio protocols +# +CONFIG_AX25=m +# CONFIG_AX25_DAMA_SLAVE is not set +# CONFIG_NETROM is not set +# CONFIG_ROSE is not set + +# +# AX.25 network device drivers +# +CONFIG_MKISS=m +# CONFIG_6PACK is not set +# CONFIG_BPQETHER is not set +# CONFIG_BAYCOM_SER_FDX is not set +# CONFIG_BAYCOM_SER_HDX is not set +# CONFIG_YAM is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m + +# +# Connector - unified userspace <-> kernelspace linker +# +CONFIG_CONNECTOR=m + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_REDBOOT_PARTS is not set +# CONFIG_MTD_CMDLINE_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_AMDSTD_RETRY=0 +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +CONFIG_BLK_DEV_CRYPTOLOOP=m +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_IMQ=m +# CONFIG_IMQ_BEHAVIOR_AA is not set +# CONFIG_IMQ_BEHAVIOR_AB is not set +CONFIG_IMQ_BEHAVIOR_BA=y +# CONFIG_IMQ_BEHAVIOR_BB is not set +CONFIG_IMQ_NUM_DEVS=2 +CONFIG_TUN=m + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +CONFIG_NET_SB1250_MAC=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_DM9000 is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +# CONFIG_NET_PCI is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +# CONFIG_IPW2100 is not set +# CONFIG_IPW2200 is not set +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +# CONFIG_PRISM54 is not set +CONFIG_HOSTAP=m +CONFIG_HOSTAP_FIRMWARE=y +CONFIG_HOSTAP_FIRMWARE_NVRAM=y +# CONFIG_HOSTAP_PLX is not set +# CONFIG_HOSTAP_PCI is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# ATM drivers +# +CONFIG_ATM_DUMMY=m +CONFIG_ATM_TCP=m +# CONFIG_ATM_LANAI is not set +# CONFIG_ATM_ENI is not set +# CONFIG_ATM_FIRESTREAM is not set +# CONFIG_ATM_ZATM is not set +# CONFIG_ATM_IDT77252 is not set +# CONFIG_ATM_AMBASSADOR is not set +# CONFIG_ATM_HORIZON is not set +# CONFIG_ATM_FORE200E_MAYBE is not set +# CONFIG_ATM_HE is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +CONFIG_PPP=m +# CONFIG_PPP_MULTILINK is not set +CONFIG_PPP_FILTER=y +CONFIG_PPP_ASYNC=m +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=m +CONFIG_PPP_BSDCOMP=m +CONFIG_PPP_MPPE=m +CONFIG_PPPOE=m +CONFIG_PPPOATM=m +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=m + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +CONFIG_INPUT_EVDEV=m +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL_NONSTANDARD=y +# CONFIG_COMPUTONE is not set +# CONFIG_ROCKETPORT is not set +# CONFIG_CYCLADES is not set +# CONFIG_DIGIEPCA is not set +# CONFIG_MOXA_INTELLIO is not set +# CONFIG_MOXA_SMARTIO is not set +# CONFIG_ISI is not set +# CONFIG_SYNCLINKMP is not set +# CONFIG_SYNCLINK_GT is not set +# CONFIG_N_HDLC is not set +# CONFIG_SPECIALIX is not set +# CONFIG_SX is not set +# CONFIG_STALDRV is not set +CONFIG_SIBYTE_SB1250_DUART=y +CONFIG_SIBYTE_SB1250_DUART_CONSOLE=y +# CONFIG_AU1000_UART is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_RTC is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +# CONFIG_HWMON is not set +# CONFIG_HWMON_VID is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# File systems +# +CONFIG_EXT2_FS=m +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_REISERFS_FS=m +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_REISERFS_FS_XATTR is not set +CONFIG_JFS_FS=m +# CONFIG_JFS_POSIX_ACL is not set +# CONFIG_JFS_SECURITY is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_FS_POSIX_ACL is not set +CONFIG_XFS_FS=m +# CONFIG_XFS_QUOTA is not set +# CONFIG_XFS_SECURITY is not set +# CONFIG_XFS_POSIX_ACL is not set +# CONFIG_XFS_RT is not set +# CONFIG_OCFS2_FS is not set +CONFIG_MINIX_FS=m +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +CONFIG_JFFS2_COMPRESSION_OPTIONS=y +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_JFFS2_CMODE_NONE is not set +CONFIG_JFFS2_CMODE_PRIORITY=y +# CONFIG_JFFS2_CMODE_SIZE is not set +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_SQUASHFS_VMALLOC is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +CONFIG_SUNRPC_GSS=m +CONFIG_RPCSEC_GSS_KRB5=m +# CONFIG_RPCSEC_GSS_SPKM3 is not set +CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +CONFIG_MAC_PARTITION=y +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=m +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +CONFIG_NLS_CODEPAGE_850=m +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +CONFIG_NLS_ISO8859_1=m +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +CONFIG_NLS_ISO8859_15=m +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +CONFIG_NLS_UTF8=m + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=15 +CONFIG_CROSSCOMPILE=y +CONFIG_CMDLINE="" +# CONFIG_SB1XXX_CORELIS is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +CONFIG_CRYPTO_HMAC=y +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_SHA1=m +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=m +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +CONFIG_CRYPTO_DEFLATE=m +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +CONFIG_CRC_CCITT=m +CONFIG_CRC16=m +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/target/linux/sibyte-2.6/patches/000-DUART.patch b/target/linux/sibyte-2.6/patches/000-DUART.patch new file mode 100644 index 0000000000..480287ffa0 --- /dev/null +++ b/target/linux/sibyte-2.6/patches/000-DUART.patch @@ -0,0 +1,956 @@ +--- linux-2.6.16.7/drivers/char/Kconfig 2006-04-21 14:38:30.000000000 -0700 ++++ linux-2.6.16.7/drivers/char/Kconfig 2006-04-21 14:39:29.000000000 -0700 +@@ -340,6 +340,14 @@ + To compile this driver as a module, choose M here: the + module will be called istallion. + ++config SIBYTE_SB1250_DUART ++ bool "Support for BCM1xxx onchip DUART" ++ depends on MIPS && SIBYTE_SB1xxx_SOC=y ++ ++config SIBYTE_SB1250_DUART_CONSOLE ++ bool "Console on BCM1xxx DUART" ++ depends on SIBYTE_SB1250_DUART ++ + config AU1000_UART + bool "Enable Au1000 UART Support" + depends on SERIAL_NONSTANDARD && MIPS +diff -Nurb linux-2.6.16.7/drivers/char/Makefile linux-2.6.16.7/drivers/char/Makefile +--- linux-2.6.16.7/drivers/char/Makefile 2006-04-17 14:53:25.000000000 -0700 ++++ linux-2.6.16.7/drivers/char/Makefile 2006-04-28 12:14:24.000000000 -0700 +@@ -31,6 +31,7 @@ + obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o + obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o + obj-$(CONFIG_MOXA_SMARTIO) += mxser.o ++obj-$(CONFIG_SIBYTE_SB1250_DUART) += sb1250_duart.o + obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o + obj-$(CONFIG_RISCOM8) += riscom8.o + obj-$(CONFIG_ISI) += isicom.o +diff -Nurb linux-2.6.16.7/drivers/char/sb1250_duart.c linux-2.6.16.7/drivers/char/sb1250_duart.c +--- linux-2.6.16.7/drivers/char/sb1250_duart.c 1969-12-31 16:00:00.000000000 -0800 ++++ linux-2.6.16.7/drivers/char/sb1250_duart.c 2006-04-28 12:13:49.000000000 -0700 +@@ -0,0 +1,911 @@ ++/* ++ * Copyright (C) 2000,2001,2002,2003,2004 Broadcom 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; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ */ ++ ++/* ++ * Driver support for the on-chip sb1250 dual-channel serial port, ++ * running in asynchronous mode. Also, support for doing a serial console ++ * on one of those ports ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) ++#include ++#include ++#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) ++#include ++#include ++#else ++#error invalid SiByte UART configuation ++#endif ++#include ++#include ++ ++#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) ++#define UNIT_CHANREG(n,reg) A_BCM1480_DUART_CHANREG((n),(reg)) ++#define UNIT_IMRREG(n) A_BCM1480_DUART_IMRREG(n) ++#define UNIT_INT(n) (K_BCM1480_INT_UART_0 + (n)) ++#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) ++#define UNIT_CHANREG(n,reg) A_DUART_CHANREG((n),(reg)) ++#define UNIT_IMRREG(n) A_DUART_IMRREG(n) ++#define UNIT_INT(n) (K_INT_UART_0 + (n)) ++#else ++#error invalid SiByte UART configuation ++#endif ++ ++/* Toggle spewing of debugging output */ ++#undef DEBUG ++ ++#define DEFAULT_CFLAGS (CS8 | B115200) ++ ++#define TX_INTEN 1 ++#define DUART_INITIALIZED 2 ++ ++#define DUART_MAX_LINE 4 ++char sb1250_duart_present[DUART_MAX_LINE]; ++EXPORT_SYMBOL(sb1250_duart_present); ++ ++/* ++ * Still not sure what the termios structures set up here are for, ++ * but we have to supply pointers to them to register the tty driver ++ */ ++static struct tty_driver *sb1250_duart_driver; //, sb1250_duart_callout_driver; ++ ++/* ++ * This lock protects both the open flags for all the uart states as ++ * well as the reference count for the module ++ */ ++static DEFINE_SPINLOCK(open_lock); ++ ++typedef struct { ++ unsigned char outp_buf[SERIAL_XMIT_SIZE]; ++ unsigned int outp_head; ++ unsigned int outp_tail; ++ unsigned int outp_count; ++ spinlock_t outp_lock; ++ unsigned int open; ++ unsigned int line; ++ unsigned int last_cflags; ++ unsigned long flags; ++ struct tty_struct *tty; ++ /* CSR addresses */ ++ volatile u32 *status; ++ volatile u32 *imr; ++ volatile u32 *tx_hold; ++ volatile u32 *rx_hold; ++ volatile u32 *mode_1; ++ volatile u32 *mode_2; ++ volatile u32 *clk_sel; ++ volatile u32 *cmd; ++} uart_state_t; ++ ++static uart_state_t uart_states[DUART_MAX_LINE]; ++ ++/* ++ * Inline functions local to this module ++ */ ++ ++/* ++ * In bug 1956, we get glitches that can mess up uart registers. This ++ * "write-mode-1 after any register access" is the accepted ++ * workaround. ++ */ ++#if SIBYTE_1956_WAR ++static unsigned int last_mode1[DUART_MAX_LINE]; ++#endif ++ ++static inline u32 READ_SERCSR(volatile u32 *addr, int line) ++{ ++ u32 val = csr_in32(addr); ++#if SIBYTE_1956_WAR ++ csr_out32(last_mode1[line], uart_states[line].mode_1); ++#endif ++ return val; ++} ++ ++static inline void WRITE_SERCSR(u32 val, volatile u32 *addr, int line) ++{ ++ csr_out32(val, addr); ++#if SIBYTE_1956_WAR ++ csr_out32(last_mode1[line], uart_states[line].mode_1); ++#endif ++} ++ ++static void init_duart_port(uart_state_t *port, int line) ++{ ++ if (!(port->flags & DUART_INITIALIZED)) { ++ port->line = line; ++ port->status = IOADDR(UNIT_CHANREG(line, R_DUART_STATUS)); ++ port->imr = IOADDR(UNIT_IMRREG(line)); ++ port->tx_hold = IOADDR(UNIT_CHANREG(line, R_DUART_TX_HOLD)); ++ port->rx_hold = IOADDR(UNIT_CHANREG(line, R_DUART_RX_HOLD)); ++ port->mode_1 = IOADDR(UNIT_CHANREG(line, R_DUART_MODE_REG_1)); ++ port->mode_2 = IOADDR(UNIT_CHANREG(line, R_DUART_MODE_REG_2)); ++ port->clk_sel = IOADDR(UNIT_CHANREG(line, R_DUART_CLK_SEL)); ++ port->cmd = IOADDR(UNIT_CHANREG(line, R_DUART_CMD)); ++ port->flags |= DUART_INITIALIZED; ++ } ++} ++ ++/* ++ * Mask out the passed interrupt lines at the duart level. This should be ++ * called while holding the associated outp_lock. ++ */ ++static inline void duart_mask_ints(unsigned int line, unsigned int mask) ++{ ++ uart_state_t *port = uart_states + line; ++ u64 tmp = READ_SERCSR(port->imr, line); ++ WRITE_SERCSR(tmp & ~mask, port->imr, line); ++} ++ ++ ++/* Unmask the passed interrupt lines at the duart level */ ++static inline void duart_unmask_ints(unsigned int line, unsigned int mask) ++{ ++ uart_state_t *port = uart_states + line; ++ u64 tmp = READ_SERCSR(port->imr, line); ++ WRITE_SERCSR(tmp | mask, port->imr, line); ++} ++ ++static inline void transmit_char_pio(uart_state_t *us) ++{ ++ struct tty_struct *tty = us->tty; ++ int blocked = 0; ++ ++ if (spin_trylock(&us->outp_lock)) { ++ for (;;) { ++ if (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_RDY)) ++ break; ++ if (us->outp_count <= 0 || tty->stopped || tty->hw_stopped) { ++ break; ++ } else { ++ WRITE_SERCSR(us->outp_buf[us->outp_head], ++ us->tx_hold, us->line); ++ us->outp_head = (us->outp_head + 1) & (SERIAL_XMIT_SIZE-1); ++ if (--us->outp_count <= 0) ++ break; ++ } ++ udelay(10); ++ } ++ spin_unlock(&us->outp_lock); ++ } else { ++ blocked = 1; ++ } ++ ++ if (!us->outp_count || tty->stopped || ++ tty->hw_stopped || blocked) { ++ us->flags &= ~TX_INTEN; ++ duart_mask_ints(us->line, M_DUART_IMR_TX); ++ } ++ ++ if (us->open && ++ (us->outp_count < (SERIAL_XMIT_SIZE/2))) { ++ /* ++ * We told the discipline at one point that we had no ++ * space, so it went to sleep. Wake it up when we hit ++ * half empty ++ */ ++ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && ++ tty->ldisc.write_wakeup) ++ tty->ldisc.write_wakeup(tty); ++ wake_up_interruptible(&tty->write_wait); ++ } ++} ++ ++/* ++ * Generic interrupt handler for both channels. dev_id is a pointer ++ * to the proper uart_states structure, so from that we can derive ++ * which port interrupted ++ */ ++ ++static irqreturn_t duart_int(int irq, void *dev_id, struct pt_regs *regs) ++{ ++ uart_state_t *us = (uart_state_t *)dev_id; ++ struct tty_struct *tty = us->tty; ++ unsigned int status = READ_SERCSR(us->status, us->line); ++ ++ pr_debug("DUART INT\n"); ++ ++ if (status & M_DUART_RX_RDY) { ++ int counter = 2048; ++ unsigned int ch; ++ ++ if (status & M_DUART_OVRUN_ERR) ++ tty_insert_flip_char(tty, 0, TTY_OVERRUN); ++ if (status & M_DUART_PARITY_ERR) { ++ printk("Parity error!\n"); ++ } else if (status & M_DUART_FRM_ERR) { ++ printk("Frame error!\n"); ++ } ++ ++ while (counter > 0) { ++ if (!(READ_SERCSR(us->status, us->line) & M_DUART_RX_RDY)) ++ break; ++ ch = READ_SERCSR(us->rx_hold, us->line); ++ tty_insert_flip_char(tty, ch, 0); ++ udelay(1); ++ counter--; ++ } ++ tty_flip_buffer_push(tty); ++ } ++ ++ if (status & M_DUART_TX_RDY) { ++ transmit_char_pio(us); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * Actual driver functions ++ */ ++ ++/* Return the number of characters we can accomodate in a write at this instant */ ++static int duart_write_room(struct tty_struct *tty) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ int retval; ++ ++ retval = SERIAL_XMIT_SIZE - us->outp_count; ++ ++ pr_debug("duart_write_room called, returning %i\n", retval); ++ ++ return retval; ++} ++ ++/* memcpy the data from src to destination, but take extra care if the ++ data is coming from user space */ ++static inline int copy_buf(char *dest, const char *src, int size, int from_user) ++{ ++ if (from_user) { ++ (void) copy_from_user(dest, src, size); ++ } else { ++ memcpy(dest, src, size); ++ } ++ return size; ++} ++ ++/* ++ * Buffer up to count characters from buf to be written. If we don't have ++ * other characters buffered, enable the tx interrupt to start sending ++ */ ++static int duart_write(struct tty_struct *tty, const unsigned char *buf, ++ int count) ++{ ++ uart_state_t *us; ++ int c, t, total = 0; ++ unsigned long flags; ++ ++ if (!tty) return 0; ++ ++ us = tty->driver_data; ++ if (!us) return 0; ++ ++ pr_debug("duart_write called for %i chars by %i (%s)\n", count, current->pid, current->comm); ++ ++ spin_lock_irqsave(&us->outp_lock, flags); ++ ++ for (;;) { ++ c = count; ++ ++ t = SERIAL_XMIT_SIZE - us->outp_tail; ++ if (t < c) c = t; ++ ++ t = SERIAL_XMIT_SIZE - 1 - us->outp_count; ++ if (t < c) c = t; ++ ++ if (c <= 0) break; ++ ++ memcpy(us->outp_buf + us->outp_tail, buf, c); ++ ++ us->outp_count += c; ++ us->outp_tail = (us->outp_tail + c) & (SERIAL_XMIT_SIZE - 1); ++ buf += c; ++ count -= c; ++ total += c; ++ } ++ ++ spin_unlock_irqrestore(&us->outp_lock, flags); ++ ++ if (us->outp_count && !tty->stopped && ++ !tty->hw_stopped && !(us->flags & TX_INTEN)) { ++ us->flags |= TX_INTEN; ++ duart_unmask_ints(us->line, M_DUART_IMR_TX); ++ } ++ ++ return total; ++} ++ ++ ++/* Buffer one character to be written. If there's not room for it, just drop ++ it on the floor. This is used for echo, among other things */ ++static void duart_put_char(struct tty_struct *tty, u_char ch) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ unsigned long flags; ++ ++ pr_debug("duart_put_char called. Char is %x (%c)\n", (int)ch, ch); ++ ++ spin_lock_irqsave(&us->outp_lock, flags); ++ ++ if (us->outp_count == SERIAL_XMIT_SIZE) { ++ spin_unlock_irqrestore(&us->outp_lock, flags); ++ return; ++ } ++ ++ us->outp_buf[us->outp_tail] = ch; ++ us->outp_tail = (us->outp_tail + 1) &(SERIAL_XMIT_SIZE-1); ++ us->outp_count++; ++ ++ spin_unlock_irqrestore(&us->outp_lock, flags); ++} ++ ++static void duart_flush_chars(struct tty_struct * tty) ++{ ++ uart_state_t *port; ++ ++ if (!tty) return; ++ ++ port = tty->driver_data; ++ ++ if (!port) return; ++ ++ if (port->outp_count <= 0 || tty->stopped || tty->hw_stopped) { ++ return; ++ } ++ ++ port->flags |= TX_INTEN; ++ duart_unmask_ints(port->line, M_DUART_IMR_TX); ++} ++ ++/* Return the number of characters in the output buffer that have yet to be ++ written */ ++static int duart_chars_in_buffer(struct tty_struct *tty) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ int retval; ++ ++ retval = us->outp_count; ++ ++ pr_debug("duart_chars_in_buffer returning %i\n", retval); ++ ++ return retval; ++} ++ ++/* Kill everything we haven't yet shoved into the FIFO. Turn off the ++ transmit interrupt since we've nothing more to transmit */ ++static void duart_flush_buffer(struct tty_struct *tty) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ unsigned long flags; ++ ++ pr_debug("duart_flush_buffer called\n"); ++ spin_lock_irqsave(&us->outp_lock, flags); ++ us->outp_head = us->outp_tail = us->outp_count = 0; ++ spin_unlock_irqrestore(&us->outp_lock, flags); ++ ++ wake_up_interruptible(&us->tty->write_wait); ++ if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && ++ tty->ldisc.write_wakeup) ++ tty->ldisc.write_wakeup(tty); ++} ++ ++ ++/* See sb1250 user manual for details on these registers */ ++static inline void duart_set_cflag(unsigned int line, unsigned int cflag) ++{ ++ unsigned int mode_reg1 = 0, mode_reg2 = 0; ++ unsigned int clk_divisor; ++ uart_state_t *port = uart_states + line; ++ ++ switch (cflag & CSIZE) { ++ case CS7: ++ mode_reg1 |= V_DUART_BITS_PER_CHAR_7; ++ ++ default: ++ /* We don't handle CS5 or CS6...is there a way we're supposed to flag this? ++ right now we just force them to CS8 */ ++ mode_reg1 |= 0x0; ++ break; ++ } ++ if (cflag & CSTOPB) { ++ mode_reg2 |= M_DUART_STOP_BIT_LEN_2; ++ } ++ if (!(cflag & PARENB)) { ++ mode_reg1 |= V_DUART_PARITY_MODE_NONE; ++ } ++ if (cflag & PARODD) { ++ mode_reg1 |= M_DUART_PARITY_TYPE_ODD; ++ } ++ ++ /* Formula for this is (5000000/baud)-1, but we saturate ++ at 12 bits, which means we can't actually do anything less ++ that 1200 baud */ ++ switch (cflag & CBAUD) { ++ case B200: ++ case B300: ++ case B1200: clk_divisor = 4095; break; ++ case B1800: clk_divisor = 2776; break; ++ case B2400: clk_divisor = 2082; break; ++ case B4800: clk_divisor = 1040; break; ++ default: ++ case B9600: clk_divisor = 519; break; ++ case B19200: clk_divisor = 259; break; ++ case B38400: clk_divisor = 129; break; ++ case B57600: clk_divisor = 85; break; ++ case B115200: clk_divisor = 42; break; ++ } ++ WRITE_SERCSR(mode_reg1, port->mode_1, port->line); ++ WRITE_SERCSR(mode_reg2, port->mode_2, port->line); ++ WRITE_SERCSR(clk_divisor, port->clk_sel, port->line); ++ port->last_cflags = cflag; ++} ++ ++ ++/* Handle notification of a termios change. */ ++static void duart_set_termios(struct tty_struct *tty, struct termios *old) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ ++ pr_debug("duart_set_termios called by %i (%s)\n", current->pid, current->comm); ++ if (old && tty->termios->c_cflag == old->c_cflag) ++ return; ++ duart_set_cflag(us->line, tty->termios->c_cflag); ++} ++ ++static int get_serial_info(uart_state_t *us, struct serial_struct * retinfo) { ++ ++ struct serial_struct tmp; ++ ++ memset(&tmp, 0, sizeof(tmp)); ++ ++ tmp.type=PORT_SB1250; ++ tmp.line=us->line; ++ tmp.port=UNIT_CHANREG(tmp.line,0); ++ tmp.irq=UNIT_INT(tmp.line); ++ tmp.xmit_fifo_size=16; /* fixed by hw */ ++ tmp.baud_base=5000000; ++ tmp.io_type=SERIAL_IO_MEM; ++ ++ if (copy_to_user(retinfo,&tmp,sizeof(*retinfo))) ++ return -EFAULT; ++ ++ return 0; ++} ++ ++static int duart_ioctl(struct tty_struct *tty, struct file * file, ++ unsigned int cmd, unsigned long arg) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ ++/* if (serial_paranoia_check(info, tty->device, "rs_ioctl")) ++ return -ENODEV;*/ ++ switch (cmd) { ++ case TIOCMGET: ++ printk("Ignoring TIOCMGET\n"); ++ break; ++ case TIOCMBIS: ++ printk("Ignoring TIOCMBIS\n"); ++ break; ++ case TIOCMBIC: ++ printk("Ignoring TIOCMBIC\n"); ++ break; ++ case TIOCMSET: ++ printk("Ignoring TIOCMSET\n"); ++ break; ++ case TIOCGSERIAL: ++ return get_serial_info(us,(struct serial_struct *) arg); ++ case TIOCSSERIAL: ++ printk("Ignoring TIOCSSERIAL\n"); ++ break; ++ case TIOCSERCONFIG: ++ printk("Ignoring TIOCSERCONFIG\n"); ++ break; ++ case TIOCSERGETLSR: /* Get line status register */ ++ printk("Ignoring TIOCSERGETLSR\n"); ++ break; ++ case TIOCSERGSTRUCT: ++ printk("Ignoring TIOCSERGSTRUCT\n"); ++ break; ++ case TIOCMIWAIT: ++ printk("Ignoring TIOCMIWAIT\n"); ++ break; ++ case TIOCGICOUNT: ++ printk("Ignoring TIOCGICOUNT\n"); ++ break; ++ case TIOCSERGWILD: ++ printk("Ignoring TIOCSERGWILD\n"); ++ break; ++ case TIOCSERSWILD: ++ printk("Ignoring TIOCSERSWILD\n"); ++ break; ++ default: ++ break; ++ } ++// printk("Ignoring IOCTL %x from pid %i (%s)\n", cmd, current->pid, current->comm); ++ return -ENOIOCTLCMD; ++} ++ ++/* XXXKW locking? */ ++static void duart_start(struct tty_struct *tty) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ ++ pr_debug("duart_start called\n"); ++ ++ if (us->outp_count && !(us->flags & TX_INTEN)) { ++ us->flags |= TX_INTEN; ++ duart_unmask_ints(us->line, M_DUART_IMR_TX); ++ } ++} ++ ++/* XXXKW locking? */ ++static void duart_stop(struct tty_struct *tty) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ ++ pr_debug("duart_stop called\n"); ++ ++ if (us->outp_count && (us->flags & TX_INTEN)) { ++ us->flags &= ~TX_INTEN; ++ duart_mask_ints(us->line, M_DUART_IMR_TX); ++ } ++} ++ ++/* Not sure on the semantics of this; are we supposed to wait until the stuff ++ already in the hardware FIFO drains, or are we supposed to wait until ++ we've drained the output buffer, too? I'm assuming the former, 'cause thats ++ what the other drivers seem to assume ++*/ ++ ++static void duart_wait_until_sent(struct tty_struct *tty, int timeout) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ unsigned long orig_jiffies; ++ ++ orig_jiffies = jiffies; ++ pr_debug("duart_wait_until_sent(%d)+\n", timeout); ++ while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT)) { ++ set_current_state(TASK_INTERRUPTIBLE); ++ schedule_timeout(1); ++ if (signal_pending(current)) ++ break; ++ if (timeout && time_after(jiffies, orig_jiffies + timeout)) ++ break; ++ } ++ pr_debug("duart_wait_until_sent()-\n"); ++} ++ ++/* ++ * duart_hangup() --- called by tty_hangup() when a hangup is signaled. ++ */ ++static void duart_hangup(struct tty_struct *tty) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ ++ duart_flush_buffer(tty); ++ us->open = 0; ++ us->tty = 0; ++} ++ ++/* ++ * Open a tty line. Note that this can be called multiple times, so ->open can ++ * be >1. Only set up the tty struct if this is a "new" open, e.g. ->open was ++ * zero ++ */ ++static int duart_open(struct tty_struct *tty, struct file *filp) ++{ ++ uart_state_t *us; ++ unsigned int line = tty->index; ++ unsigned long flags; ++ ++ if ((line >= tty->driver->num) || !sb1250_duart_present[line]) ++ return -ENODEV; ++ ++ pr_debug("duart_open called by %i (%s), tty is %p, rw is %p, ww is %p\n", ++ current->pid, current->comm, tty, tty->read_wait, ++ tty->write_wait); ++ ++ us = uart_states + line; ++ tty->driver_data = us; ++ ++ spin_lock_irqsave(&open_lock, flags); ++ if (!us->open) { ++ us->tty = tty; ++ us->tty->termios->c_cflag = us->last_cflags; ++ } ++ us->open++; ++ us->flags &= ~TX_INTEN; ++ duart_unmask_ints(line, M_DUART_IMR_RX); ++ spin_unlock_irqrestore(&open_lock, flags); ++ ++ return 0; ++} ++ ++ ++/* ++ * Close a reference count out. If reference count hits zero, null the ++ * tty, kill the interrupts. The tty_io driver is responsible for making ++ * sure we've cleared out our internal buffers before calling close() ++ */ ++static void duart_close(struct tty_struct *tty, struct file *filp) ++{ ++ uart_state_t *us = (uart_state_t *) tty->driver_data; ++ unsigned long flags; ++ ++ pr_debug("duart_close called by %i (%s)\n", current->pid, current->comm); ++ ++ if (!us || !us->open) ++ return; ++ ++ spin_lock_irqsave(&open_lock, flags); ++ if (tty_hung_up_p(filp)) { ++ spin_unlock_irqrestore(&open_lock, flags); ++ return; ++ } ++ ++ if (--us->open < 0) { ++ us->open = 0; ++ printk(KERN_ERR "duart: bad open count: %d\n", us->open); ++ } ++ if (us->open) { ++ spin_unlock_irqrestore(&open_lock, flags); ++ return; ++ } ++ ++ spin_unlock_irqrestore(&open_lock, flags); ++ ++ tty->closing = 1; ++ ++ /* Stop accepting input */ ++ duart_mask_ints(us->line, M_DUART_IMR_RX); ++ /* Wait for FIFO to drain */ ++ while (!(READ_SERCSR(us->status, us->line) & M_DUART_TX_EMT)) ++ ; ++ ++ if (tty->driver->flush_buffer) ++ tty->driver->flush_buffer(tty); ++ if (tty->ldisc.flush_buffer) ++ tty->ldisc.flush_buffer(tty); ++ tty->closing = 0; ++} ++ ++ ++static struct tty_operations duart_ops = { ++ .open = duart_open, ++ .close = duart_close, ++ .write = duart_write, ++ .put_char = duart_put_char, ++ .flush_chars = duart_flush_chars, ++ .write_room = duart_write_room, ++ .chars_in_buffer = duart_chars_in_buffer, ++ .flush_buffer = duart_flush_buffer, ++ .ioctl = duart_ioctl, ++// .throttle = duart_throttle, ++// .unthrottle = duart_unthrottle, ++ .set_termios = duart_set_termios, ++ .stop = duart_stop, ++ .start = duart_start, ++ .hangup = duart_hangup, ++ .wait_until_sent = duart_wait_until_sent, ++}; ++ ++/* Initialize the sb1250_duart_present array based on SOC type. */ ++static void __init sb1250_duart_init_present_lines(void) ++{ ++ int i, max_lines; ++ ++ /* Set the number of available units based on the SOC type. */ ++ switch (soc_type) { ++ case K_SYS_SOC_TYPE_BCM1x55: ++ case K_SYS_SOC_TYPE_BCM1x80: ++ max_lines = 4; ++ break; ++ default: ++ /* Assume at least two serial ports at the normal address. */ ++ max_lines = 2; ++ break; ++ } ++ if (max_lines > DUART_MAX_LINE) ++ max_lines = DUART_MAX_LINE; ++ ++ for (i = 0; i < max_lines; i++) ++ sb1250_duart_present[i] = 1; ++} ++ ++/* Set up the driver and register it, register the UART interrupts. This ++ is called from tty_init, or as a part of the module init */ ++static int __init sb1250_duart_init(void) ++{ ++ int i; ++ ++ sb1250_duart_init_present_lines(); ++ ++ sb1250_duart_driver = alloc_tty_driver(DUART_MAX_LINE); ++ if (!sb1250_duart_driver) ++ return -ENOMEM; ++ ++ sb1250_duart_driver->owner = THIS_MODULE; ++ sb1250_duart_driver->name = "duart"; ++ sb1250_duart_driver->devfs_name = "duart/"; ++ sb1250_duart_driver->major = TTY_MAJOR; ++ sb1250_duart_driver->minor_start = SB1250_DUART_MINOR_BASE; ++ sb1250_duart_driver->type = TTY_DRIVER_TYPE_SERIAL; ++ sb1250_duart_driver->subtype = SERIAL_TYPE_NORMAL; ++ sb1250_duart_driver->init_termios = tty_std_termios; ++ sb1250_duart_driver->flags = TTY_DRIVER_REAL_RAW; ++ tty_set_operations(sb1250_duart_driver, &duart_ops); ++ ++ for (i=0; ioutp_lock); ++ duart_mask_ints(i, M_DUART_IMR_ALL); ++ if (request_irq(UNIT_INT(i), duart_int, 0, "uart", port)) { ++ panic("Couldn't get uart0 interrupt line"); ++ } ++ __raw_writeq(M_DUART_RX_EN|M_DUART_TX_EN, ++ IOADDR(UNIT_CHANREG(i, R_DUART_CMD))); ++ duart_set_cflag(i, DEFAULT_CFLAGS); ++ } ++ ++ /* Interrupts are now active, our ISR can be called. */ ++ ++ if (tty_register_driver(sb1250_duart_driver)) { ++ printk(KERN_ERR "Couldn't register sb1250 duart serial driver\n"); ++ put_tty_driver(sb1250_duart_driver); ++ return 1; ++ } ++ return 0; ++} ++ ++/* Unload the driver. Unregister stuff, get ready to go away */ ++static void __exit sb1250_duart_fini(void) ++{ ++ unsigned long flags; ++ int i; ++ ++ local_irq_save(flags); ++ tty_unregister_driver(sb1250_duart_driver); ++ put_tty_driver(sb1250_duart_driver); ++ ++ for (i=0; istatus, line) & M_DUART_TX_RDY)) ; ++ WRITE_SERCSR(c, port->tx_hold, line); ++ while (!(READ_SERCSR(port->status, port->line) & M_DUART_TX_EMT)) ; ++} ++ ++static void ser_console_write(struct console *cons, const char *s, ++ unsigned int count) ++{ ++ int line = cons->index; ++ uart_state_t *port = uart_states + line; ++ u32 imr; ++ ++ imr = READ_SERCSR(port->imr, line); ++ WRITE_SERCSR(0, port->imr, line); ++ while (count--) { ++ if (*s == '\n') ++ serial_outc('\r', line); ++ serial_outc(*s++, line); ++ } ++ WRITE_SERCSR(imr, port->imr, line); ++} ++ ++static struct tty_driver *ser_console_device(struct console *c, int *index) ++{ ++ *index = c->index; ++ return sb1250_duart_driver; ++} ++ ++static int ser_console_setup(struct console *cons, char *str) ++{ ++ int i; ++ ++ sb1250_duart_init_present_lines(); ++ ++ for (i=0; imode_1, i); ++ WRITE_SERCSR(M_DUART_STOP_BIT_LEN_1, ++ port->mode_2, i); ++ WRITE_SERCSR(V_DUART_BAUD_RATE(115200), ++ port->clk_sel, i); ++ WRITE_SERCSR(M_DUART_RX_EN|M_DUART_TX_EN, ++ port->cmd, i); ++ } ++ return 0; ++} ++ ++static struct console sb1250_ser_cons = { ++ .name = "duart", ++ .write = ser_console_write, ++ .device = ser_console_device, ++ .setup = ser_console_setup, ++ .flags = CON_PRINTBUFFER, ++ .index = -1, ++}; ++ ++static int __init sb1250_serial_console_init(void) ++{ ++ register_console(&sb1250_ser_cons); ++ return 0; ++} ++ ++console_initcall(sb1250_serial_console_init); ++ ++#endif /* CONFIG_SIBYTE_SB1250_DUART_CONSOLE */ +diff -Nurb linux-2.6.16.7/include/linux/serial.h linux-2.6.16.7/include/linux/serial.h +--- linux-2.6.16.7/include/linux/serial.h 2006-04-17 14:53:25.000000000 -0700 ++++ linux-2.6.16.7/include/linux/serial.h 2006-04-28 12:25:19.000000000 -0700 +@@ -76,7 +76,8 @@ + #define PORT_16654 11 + #define PORT_16850 12 + #define PORT_RSA 13 /* RSA-DV II/S card */ +-#define PORT_MAX 13 ++#define PORT_SB1250 14 ++#define PORT_MAX 14 + + #define SERIAL_IO_PORT 0 + #define SERIAL_IO_HUB6 1 diff --git a/target/linux/sibyte-2.6/patches/001-bcm112x_ax.patch b/target/linux/sibyte-2.6/patches/001-bcm112x_ax.patch new file mode 100644 index 0000000000..c80d4aea54 --- /dev/null +++ b/target/linux/sibyte-2.6/patches/001-bcm112x_ax.patch @@ -0,0 +1,17 @@ +--- linux-2.6.16.4/arch/mips/sibyte/sb1250/setup.c 2006-04-21 16:16:18.000000000 -0700 ++++ linux-2.6.16.4/arch/mips/sibyte/sb1250/setup.c 2006-04-21 16:15:22.000000000 -0700 +@@ -140,6 +140,14 @@ + periph_rev = 3; + pass_str = "A2"; + break; ++ case K_SYS_REVISION_BCM112x_A3: ++ periph_rev = 3; ++ pass_str = "A3"; ++ break; ++ case K_SYS_REVISION_BCM112x_A4: ++ periph_rev = 3; ++ pass_str = "A4"; ++ break; + default: + prom_printf("Unknown %s rev %x\n", soc_str, soc_pass); + ret = 1; diff --git a/target/linux/x86-2.6/Makefile b/target/linux/x86-2.6/Makefile index 48417d20c8..2a9ab2c971 100644 --- a/target/linux/x86-2.6/Makefile +++ b/target/linux/x86-2.6/Makefile @@ -1,8 +1,8 @@ include $(TOPDIR)/rules.mk -LINUX_VERSION:=2.6.16.4 +LINUX_VERSION:=2.6.16.7 LINUX_RELEASE:=1 -LINUX_KERNEL_MD5SUM:=cb675279c9711237a06ebb8379a4da27 +LINUX_KERNEL_MD5SUM:=9682b2bd6e02f3087982d7c3f5ba824e include ../rules.mk include ./config diff --git a/target/linux/xscale-2.6/Makefile b/target/linux/xscale-2.6/Makefile new file mode 100644 index 0000000000..4f6a5db833 --- /dev/null +++ b/target/linux/xscale-2.6/Makefile @@ -0,0 +1,18 @@ +include $(TOPDIR)/rules.mk + +LINUX_VERSION:=2.6.16.7 +LINUX_RELEASE:=1 +LINUX_KERNEL_MD5SUM:=9682b2bd6e02f3087982d7c3f5ba824e + +include ../rules.mk +include ./config + +include ../generic-$(KERNEL)/modules.mk +include ../kernel.mk + + +$(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked + [ -d ../generic-$(KERNEL)/patches ] && $(PATCH) $(LINUX_DIR) ../generic-$(KERNEL)/patches + [ -d ./patches ] && $(PATCH) $(LINUX_DIR) ./patches + @$(CP) config $(LINUX_DIR)/.config + touch $@ diff --git a/target/linux/xscale-2.6/config b/target/linux/xscale-2.6/config new file mode 100644 index 0000000000..92d4657e3e --- /dev/null +++ b/target/linux/xscale-2.6/config @@ -0,0 +1,1363 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.16.4 +# Mon Apr 17 16:00:49 2006 +# +CONFIG_ARM=y +CONFIG_MMU=y +CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_CALIBRATE_DELAY=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_BSD_PROCESS_ACCT=y +# CONFIG_BSD_PROCESS_ACCT_V3 is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +CONFIG_INITRAMFS_SOURCE="" +CONFIG_UID16=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_ELF_CORE is not set +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +# CONFIG_SHMEM is not set +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_SLAB is not set +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=0 +CONFIG_SLOB=y +CONFIG_OBSOLETE_INTERMODULE=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +# CONFIG_MODULE_FORCE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Block layer +# + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_DEFAULT_AS is not set +# CONFIG_DEFAULT_DEADLINE is not set +# CONFIG_DEFAULT_CFQ is not set +CONFIG_DEFAULT_NOOP=y +CONFIG_DEFAULT_IOSCHED="noop" + +# +# System Type +# +# CONFIG_ARCH_CLPS7500 is not set +# CONFIG_ARCH_CLPS711X is not set +# CONFIG_ARCH_CO285 is not set +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_IOP3XX is not set +CONFIG_ARCH_IXP4XX=y +# CONFIG_ARCH_IXP2000 is not set +# CONFIG_ARCH_L7200 is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C2410 is not set +# CONFIG_ARCH_SHARK is not set +# CONFIG_ARCH_LH7A40X is not set +# CONFIG_ARCH_OMAP is not set +# CONFIG_ARCH_VERSATILE is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_IMX is not set +# CONFIG_ARCH_H720X is not set +# CONFIG_ARCH_AAEC2000 is not set +# CONFIG_ARCH_AT91RM9200 is not set +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y + +# +# Intel IXP4xx Implementation Options +# + +# +# IXP4xx Platforms +# +# CONFIG_MACH_NSLU2 is not set +# CONFIG_ARCH_AVILA is not set +# CONFIG_ARCH_ADI_COYOTE is not set +CONFIG_MACH_GATEWAY7001=y +# CONFIG_ARCH_IXDP425 is not set +# CONFIG_MACH_IXDPG425 is not set +# CONFIG_MACH_IXDP465 is not set +# CONFIG_ARCH_PRPMC1100 is not set +# CONFIG_MACH_NAS100D is not set +# CONFIG_MACH_GTWX5715 is not set + +# +# IXP4xx Options +# +# CONFIG_IXP4XX_INDIRECT_PCI is not set + +# +# Processor Type +# +CONFIG_CPU_32=y +CONFIG_CPU_XSCALE=y +CONFIG_CPU_32v5=y +CONFIG_CPU_ABRT_EV5T=y +CONFIG_CPU_CACHE_VIVT=y +CONFIG_CPU_TLB_V4WBI=y + +# +# Processor Features +# +# CONFIG_ARM_THUMB is not set +CONFIG_CPU_BIG_ENDIAN=y +CONFIG_XSCALE_PMU=y +CONFIG_DMABOUNCE=y + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_LEGACY_PROC=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +# CONFIG_PREEMPT is not set +# CONFIG_NO_IDLE_HZ is not set +# CONFIG_AEABI is not set +# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4096 +CONFIG_ALIGNMENT_TRAP=y + +# +# Boot options +# +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=jffs2 init=/etc/preinit noinitrd console=ttyS0,115200" +# CONFIG_XIP_KERNEL is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +CONFIG_FPE_NWFPE=y +# CONFIG_FPE_NWFPE_XP is not set +# CONFIG_FPE_FASTFPE is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_AOUT is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_ARTHUR is not set + +# +# Power management options +# +# CONFIG_PM is not set +# CONFIG_APM is not set + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=m +CONFIG_PACKET_MMAP=y +CONFIG_UNIX=y +CONFIG_XFRM=y +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +# CONFIG_ASK_IP_FIB_HASH is not set +# CONFIG_IP_FIB_TRIE is not set +CONFIG_IP_FIB_HASH=y +# CONFIG_IP_PNP is not set +# CONFIG_NET_IPIP is not set +CONFIG_NET_IPGRE=m +CONFIG_NET_IPGRE_BROADCAST=y +CONFIG_IPSEC_NAT_TRAVERSAL=y +CONFIG_IP_MROUTE=y +CONFIG_IP_PIMSM_V1=y +CONFIG_IP_PIMSM_V2=y +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +CONFIG_INET_TUNNEL=m +CONFIG_INET_DIAG=m +CONFIG_INET_TCP_DIAG=m +CONFIG_TCP_CONG_ADVANCED=y + +# +# TCP congestion control +# +CONFIG_TCP_CONG_BIC=m +CONFIG_TCP_CONG_CUBIC=m +CONFIG_TCP_CONG_WESTWOOD=y +CONFIG_TCP_CONG_HTCP=m +# CONFIG_TCP_CONG_HSTCP is not set +# CONFIG_TCP_CONG_HYBLA is not set +CONFIG_TCP_CONG_VEGAS=m +# CONFIG_TCP_CONG_SCALABLE is not set + +# +# IP: Virtual Server Configuration +# +# CONFIG_IP_VS is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_NETLINK=m +# CONFIG_NETFILTER_NETLINK_QUEUE is not set +# CONFIG_NETFILTER_NETLINK_LOG is not set +CONFIG_NETFILTER_XTABLES=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +CONFIG_NETFILTER_XT_TARGET_MARK=m +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set +# CONFIG_NETFILTER_XT_MATCH_CONNBYTES is not set +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m +# CONFIG_NETFILTER_XT_MATCH_DCCP is not set +CONFIG_NETFILTER_XT_MATCH_HELPER=m +# CONFIG_NETFILTER_XT_MATCH_LENGTH is not set +CONFIG_NETFILTER_XT_MATCH_LIMIT=m +CONFIG_NETFILTER_XT_MATCH_MAC=m +CONFIG_NETFILTER_XT_MATCH_MARK=m +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV is not set +# CONFIG_NETFILTER_XT_MATCH_PKTTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_REALM is not set +# CONFIG_NETFILTER_XT_MATCH_SCTP is not set +CONFIG_NETFILTER_XT_MATCH_STATE=y +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +CONFIG_NETFILTER_XT_MATCH_TCPMSS=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +CONFIG_IP_NF_CT_ACCT=y +CONFIG_IP_NF_CONNTRACK_MARK=y +# CONFIG_IP_NF_CONNTRACK_EVENTS is not set +# CONFIG_IP_NF_CT_PROTO_SCTP is not set +CONFIG_IP_NF_FTP=y +CONFIG_IP_NF_IRC=y +# CONFIG_IP_NF_NETBIOS_NS is not set +# CONFIG_IP_NF_TFTP is not set +# CONFIG_IP_NF_AMANDA is not set +# CONFIG_IP_NF_PPTP is not set +CONFIG_IP_NF_SIP=m +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_LAYER7=m +# CONFIG_IP_NF_MATCH_LAYER7_DEBUG is not set +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_IPP2P=m +CONFIG_IP_NF_MATCH_TOS=m +# CONFIG_IP_NF_MATCH_TIME is not set +# CONFIG_IP_NF_MATCH_RECENT is not set +# CONFIG_IP_NF_MATCH_ECN is not set +# CONFIG_IP_NF_MATCH_DSCP is not set +# CONFIG_IP_NF_MATCH_AH_ESP is not set +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_OWNER=m +# CONFIG_IP_NF_MATCH_ADDRTYPE is not set +# CONFIG_IP_NF_MATCH_HASHLIMIT is not set +# CONFIG_IP_NF_MATCH_POLICY is not set +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_IMQ=m +# CONFIG_IP_NF_TARGET_LOG is not set +# CONFIG_IP_NF_TARGET_ULOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_TARGET_NETMAP is not set +# CONFIG_IP_NF_TARGET_SAME is not set +# CONFIG_IP_NF_NAT_SNMP_BASIC is not set +CONFIG_IP_NF_NAT_IRC=y +CONFIG_IP_NF_NAT_FTP=y +CONFIG_IP_NF_NAT_SIP=m +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_TARGET_TOS=m +# CONFIG_IP_NF_TARGET_ECN is not set +# CONFIG_IP_NF_TARGET_DSCP is not set +# CONFIG_IP_NF_TARGET_TTL is not set +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +# CONFIG_IP_NF_RAW is not set +# CONFIG_IP_NF_ARPTABLES is not set +# CONFIG_IP_NF_SET is not set + +# +# IPv6: Netfilter Configuration (EXPERIMENTAL) +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +# CONFIG_IP6_NF_MATCH_MULTIPORT is not set +# CONFIG_IP6_NF_MATCH_OWNER is not set +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_AHESP is not set +# CONFIG_IP6_NF_MATCH_EUI64 is not set +# CONFIG_IP6_NF_MATCH_POLICY is not set +CONFIG_IP6_NF_FILTER=m +# CONFIG_IP6_NF_TARGET_LOG is not set +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_MANGLE is not set +# CONFIG_IP6_NF_RAW is not set + +# +# Bridge: Netfilter Configuration +# +# CONFIG_BRIDGE_NF_EBTABLES is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +CONFIG_BRIDGE=y +CONFIG_VLAN_8021Q=y +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CLK_JIFFIES=y +# CONFIG_NET_SCH_CLK_GETTIMEOFDAY is not set +# CONFIG_NET_SCH_CLK_CPU is not set + +# +# Queueing/Scheduling +# +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_HFSC=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_ESFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +# CONFIG_NET_SCH_NETEM is not set +CONFIG_NET_SCH_INGRESS=m + +# +# Classification +# +CONFIG_NET_CLS=y +CONFIG_NET_CLS_BASIC=m +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_CLS_U32_PERF=y +CONFIG_CLS_U32_MARK=y +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +# CONFIG_NET_EMATCH is not set +# CONFIG_NET_CLS_ACT is not set +CONFIG_NET_CLS_POLICE=y +# CONFIG_NET_CLS_IND is not set +CONFIG_NET_ESTIMATOR=y + +# +# Network testing +# +CONFIG_NET_PKTGEN=m +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_IEEE80211=m +# CONFIG_IEEE80211_DEBUG is not set +CONFIG_IEEE80211_CRYPT_WEP=m +CONFIG_IEEE80211_CRYPT_CCMP=m +CONFIG_IEEE80211_CRYPT_TKIP=m + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +CONFIG_FW_LOADER=m + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +# CONFIG_MTD_CONCAT is not set +CONFIG_MTD_PARTITIONS=y +CONFIG_MTD_REDBOOT_PARTS=y +CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1 +CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y +CONFIG_MTD_REDBOOT_PARTS_READONLY=y +# CONFIG_MTD_CMDLINE_PARTS is not set +# CONFIG_MTD_AFS_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +CONFIG_MTD_BLOCK=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set +# CONFIG_INFTL is not set +# CONFIG_RFD_FTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set +CONFIG_MTD_CFI_I1=y +CONFIG_MTD_CFI_I2=y +# CONFIG_MTD_CFI_I4 is not set +# CONFIG_MTD_CFI_I8 is not set +CONFIG_MTD_CFI_INTELEXT=y +# CONFIG_MTD_CFI_AMDSTD is not set +# CONFIG_MTD_CFI_STAA is not set +CONFIG_MTD_CFI_UTIL=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set + +# +# Mapping drivers for chip access +# +CONFIG_MTD_COMPLEX_MAPPINGS=y +# CONFIG_MTD_PHYSMAP is not set +# CONFIG_MTD_ARM_INTEGRATOR is not set +CONFIG_MTD_IXP4XX=y +# CONFIG_MTD_PCI is not set +# CONFIG_MTD_PLATRAM is not set + +# +# Self-contained MTD device drivers +# +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_PHRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set +# CONFIG_MTD_BLOCK2MTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOC2001PLUS is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# OneNAND Flash Device Drivers +# +# CONFIG_MTD_ONENAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=m +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +# CONFIG_BLK_DEV_UB is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=m +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=m +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# SCSI low-level drivers +# +# CONFIG_ISCSI_TCP is not set +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_3W_9XXX is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +# CONFIG_SCSI_SATA is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +CONFIG_IMQ=m +# CONFIG_IMQ_BEHAVIOR_AA is not set +# CONFIG_IMQ_BEHAVIOR_AB is not set +CONFIG_IMQ_BEHAVIOR_BA=y +# CONFIG_IMQ_BEHAVIOR_BB is not set +CONFIG_IMQ_NUM_DEVS=2 +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +# CONFIG_PHYLIB is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_SMC91X is not set +# CONFIG_DM9000 is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +# CONFIG_E100 is not set +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y + +# +# Obsolete Wireless cards support (pre-802.11) +# +# CONFIG_STRIP is not set + +# +# Wireless 802.11b ISA/PCI cards support +# +CONFIG_IPW2100=m +CONFIG_IPW2100_MONITOR=y +# CONFIG_IPW2100_DEBUG is not set +CONFIG_IPW2200=m +# CONFIG_IPW2200_DEBUG is not set +# CONFIG_HERMES is not set +# CONFIG_ATMEL is not set + +# +# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support +# +# CONFIG_PRISM54 is not set +# CONFIG_HOSTAP is not set +CONFIG_NET_WIRELESS=y + +# +# Wan interfaces +# +CONFIG_WAN=y +# CONFIG_DSCC4 is not set +# CONFIG_LANMEDIA is not set +# CONFIG_SYNCLINK_SYNCPPP is not set +CONFIG_HDLC=m +CONFIG_HDLC_RAW=y +# CONFIG_HDLC_RAW_ETH is not set +CONFIG_HDLC_CISCO=y +CONFIG_HDLC_FR=y +CONFIG_HDLC_PPP=y + +# +# X.25/LAPB support is disabled +# +# CONFIG_PCI200SYN is not set +# CONFIG_WANXL is not set +# CONFIG_PC300 is not set +# CONFIG_FARSYNC is not set +CONFIG_DLCI=m +CONFIG_DLCI_COUNT=24 +CONFIG_DLCI_MAX=8 +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_NR_UARTS=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +# CONFIG_WATCHDOG_NOWAYOUT is not set + +# +# Watchdog Device Drivers +# +# CONFIG_SOFT_WATCHDOG is not set +CONFIG_IXP4XX_WATCHDOG=y + +# +# PCI-based Watchdog Cards +# +# CONFIG_PCIPCWATCHDOG is not set +# CONFIG_WDTPCI is not set + +# +# USB-based Watchdog Cards +# +# CONFIG_USBPCWATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia Capabilities Port drivers +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB=m +# CONFIG_USB_DEBUG is not set + +# +# Miscellaneous USB options +# +CONFIG_USB_DEVICEFS=y +CONFIG_USB_BANDWIDTH=y +# CONFIG_USB_DYNAMIC_MINORS is not set +# CONFIG_USB_OTG is not set + +# +# USB Host Controller Drivers +# +CONFIG_USB_EHCI_HCD=m +# CONFIG_USB_EHCI_SPLIT_ISO is not set +# CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set +CONFIG_USB_OHCI_HCD=m +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y +CONFIG_USB_UHCI_HCD=m +# CONFIG_USB_SL811_HCD is not set + +# +# USB Device Class drivers +# +# CONFIG_USB_ACM is not set +# CONFIG_USB_PRINTER is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# may also be needed; see USB_STORAGE Help for more information +# +CONFIG_USB_STORAGE=m +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_DPCM is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_LIBUSUAL is not set + +# +# USB Input Devices +# +# CONFIG_USB_HID is not set + +# +# USB HID Boot Protocol drivers +# + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set + +# +# USB Multimedia devices +# +# CONFIG_USB_DABUSB is not set + +# +# Video4Linux support is needed for USB Multimedia device support +# + +# +# USB Network Adapters +# +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_ZD1201 is not set +# CONFIG_USB_MON is not set + +# +# USB port drivers +# + +# +# USB Serial Converter support +# +# CONFIG_USB_SERIAL is not set + +# +# USB Miscellaneous drivers +# +# CONFIG_USB_EMI62 is not set +# CONFIG_USB_EMI26 is not set +# CONFIG_USB_AUERSWALD is not set +# CONFIG_USB_RIO500 is not set +# CONFIG_USB_LEGOTOWER is not set +# CONFIG_USB_LCD is not set +# CONFIG_USB_LED is not set +# CONFIG_USB_CYTHERM is not set +# CONFIG_USB_PHIDGETKIT is not set +# CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set +# CONFIG_USB_LD is not set +# CONFIG_USB_TEST is not set + +# +# USB DSL modem support +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# File systems +# +CONFIG_EXT2_FS=m +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=m +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=m +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=m +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=m +# CONFIG_MSDOS_FS is not set +CONFIG_VFAT_FS=m +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_RELAYFS_FS is not set +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +# CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +CONFIG_NFSD=m +# CONFIG_NFSD_V3 is not set +CONFIG_NFSD_TCP=y +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +CONFIG_EXPORTFS=m +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=m +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +CONFIG_CIFS=m +# CONFIG_CIFS_STATS is not set +# CONFIG_CIFS_XATTR is not set +# CONFIG_CIFS_EXPERIMENTAL is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +CONFIG_NLS=m +CONFIG_NLS_DEFAULT="iso8859-1" +# CONFIG_NLS_CODEPAGE_437 is not set +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1250 is not set +# CONFIG_NLS_CODEPAGE_1251 is not set +# CONFIG_NLS_ASCII is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_BUGVERBOSE is not set +CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_USER is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +# CONFIG_CRYPTO_MD5 is not set +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +# CONFIG_CRYPTO_DES is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +CONFIG_CRYPTO_AES=m +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +CONFIG_CRYPTO_ARC4=m +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +CONFIG_CRYPTO_MICHAEL_MIC=m +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/target/linux/xscale-2.6/patches/001-gateway_7001.patch b/target/linux/xscale-2.6/patches/001-gateway_7001.patch new file mode 100644 index 0000000000..8942679000 --- /dev/null +++ b/target/linux/xscale-2.6/patches/001-gateway_7001.patch @@ -0,0 +1,159 @@ +diff -Nur linux-2.6.16.4/arch/arm/boot/compressed/head-xscale.S linux-2.6.16.4-owrt/arch/arm/boot/compressed/head-xscale.S +--- linux-2.6.16.4/arch/arm/boot/compressed/head-xscale.S 2006-04-11 19:19:28.000000000 +0200 ++++ linux-2.6.16.4-owrt/arch/arm/boot/compressed/head-xscale.S 2006-04-16 16:51:05.000000000 +0200 +@@ -47,6 +47,11 @@ + orr r7, r7, #(MACH_TYPE_GTWX5715 & 0xff00) + #endif + ++#ifdef CONFIG_MACH_GATEWAY7001 ++ mov r7, #(MACH_TYPE_GATEWAY7001 & 0xff) ++ orr r7, r7, #(MACH_TYPE_GATEWAY7001 & 0xff00) ++#endif ++ + #ifdef CONFIG_ARCH_IXP2000 + mov r1, #-1 + mov r0, #0xd6000000 +diff -Nur linux-2.6.16.4/arch/arm/mach-ixp4xx/gateway7001-pci.c linux-2.6.16.4-owrt/arch/arm/mach-ixp4xx/gateway7001-pci.c +--- linux-2.6.16.4/arch/arm/mach-ixp4xx/gateway7001-pci.c 1970-01-01 01:00:00.000000000 +0100 ++++ linux-2.6.16.4-owrt/arch/arm/mach-ixp4xx/gateway7001-pci.c 2006-04-17 19:21:55.000000000 +0200 +@@ -0,0 +1,67 @@ ++/* ++ * arch/arch/mach-ixp4xx/gateway7001-pci.c ++ * ++ * PCI setup routines for Gateway 7001 ++ * ++ * Copyright (C) 2006 Imre Kaloz ++ * ++ * based on coyote-pci.c: ++ * Copyright (C) 2002 Jungo Software Technologies. ++ * Copyright (C) 2003 MontaVista Softwrae, Inc. ++ * ++ * Maintainer: Imre Kaloz ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++ ++#include ++ ++extern void ixp4xx_pci_preinit(void); ++extern int ixp4xx_setup(int nr, struct pci_sys_data *sys); ++extern struct pci_bus *ixp4xx_scan_bus(int nr, struct pci_sys_data *sys); ++ ++void __init gateway7001_pci_preinit(void) ++{ ++ set_irq_type(IRQ_IXP4XX_GPIO10, IRQT_LOW); ++ set_irq_type(IRQ_IXP4XX_GPIO11, IRQT_LOW); ++ ++ ixp4xx_pci_preinit(); ++} ++ ++static int __init gateway7001_map_irq(struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ if (slot == 0) ++ return IRQ_IXP4XX_GPIO10; ++ else if (slot == 1) ++ return IRQ_IXP4XX_GPIO11; ++ else return -1; ++} ++ ++struct hw_pci gateway7001_pci __initdata = { ++ .nr_controllers = 1, ++ .preinit = gateway7001_pci_preinit, ++ .swizzle = pci_std_swizzle, ++ .setup = ixp4xx_setup, ++ .scan = ixp4xx_scan_bus, ++ .map_irq = gateway7001_map_irq, ++}; ++ ++int __init gateway7001_pci_init(void) ++{ ++ if (machine_is_gateway7001()) ++ pci_common_init(&gateway7001_pci); ++ return 0; ++} ++ ++subsys_initcall(gateway7001_pci_init); +diff -Nur linux-2.6.16.4/arch/arm/mach-ixp4xx/Kconfig linux-2.6.16.4-owrt/arch/arm/mach-ixp4xx/Kconfig +--- linux-2.6.16.4/arch/arm/mach-ixp4xx/Kconfig 2006-04-11 19:19:28.000000000 +0200 ++++ linux-2.6.16.4-owrt/arch/arm/mach-ixp4xx/Kconfig 2006-04-16 15:58:37.000000000 +0200 +@@ -30,6 +30,13 @@ + Engineering Coyote Gateway Reference Platform. For more + information on this platform, see . + ++config MACH_GATEWAY7001 ++ bool "Gateway 7001" ++ help ++ Say 'Y' here if you want your kernel to support Gateway's ++ 7001 Access Point. For more information on this platform, ++ see http://openwrt.org ++ + config ARCH_IXDP425 + bool "IXDP425" + help +diff -Nur linux-2.6.16.4/arch/arm/mach-ixp4xx/Makefile linux-2.6.16.4-owrt/arch/arm/mach-ixp4xx/Makefile +--- linux-2.6.16.4/arch/arm/mach-ixp4xx/Makefile 2006-04-11 19:19:28.000000000 +0200 ++++ linux-2.6.16.4-owrt/arch/arm/mach-ixp4xx/Makefile 2006-04-16 16:03:42.000000000 +0200 +@@ -10,4 +10,5 @@ + obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o gtwx5715-setup.o + obj-$(CONFIG_MACH_NSLU2) += nslu2-pci.o nslu2-setup.o nslu2-power.o + obj-$(CONFIG_MACH_NAS100D) += nas100d-pci.o nas100d-setup.o nas100d-power.o ++obj-$(CONFIG_MACH_GATEWAY7001) += gateway7001-pci.o coyote-setup.o + +diff -Nur linux-2.6.16.4/include/asm-arm/arch-ixp4xx/uncompress.h linux-2.6.16.4-owrt/include/asm-arm/arch-ixp4xx/uncompress.h +--- linux-2.6.16.4/include/asm-arm/arch-ixp4xx/uncompress.h 2006-04-11 19:19:28.000000000 +0200 ++++ linux-2.6.16.4-owrt/include/asm-arm/arch-ixp4xx/uncompress.h 2006-04-16 16:25:34.000000000 +0200 +@@ -48,7 +48,7 @@ + /* + * Coyote and gtwx5715 only have UART2 connected + */ +- if (machine_is_adi_coyote() || machine_is_gtwx5715()) ++ if (machine_is_adi_coyote() || machine_is_gtwx5715() || machine_is_gateway7001()) + uart_base = (volatile u32*) IXP4XX_UART2_BASE_PHYS; + else + uart_base = (volatile u32*) IXP4XX_UART1_BASE_PHYS; +diff -Nur linux-2.6.16.4/arch/arm/mach-ixp4xx/coyote-setup.c linux-2.6.16.4-owrt/arch/arm/mach-ixp4xx/coyote-setup.c +--- linux-2.6.16.4/arch/arm/mach-ixp4xx/coyote-setup.c 2006-04-11 19:19:28.000000000 +0200 ++++ linux-2.6.16.4-owrt/arch/arm/mach-ixp4xx/coyote-setup.c 2006-04-16 16:03:23.000000000 +0200 +@@ -1,9 +1,10 @@ + /* + * arch/arm/mach-ixp4xx/coyote-setup.c + * +- * Board setup for ADI Engineering and IXDGP425 boards ++ * Board setup for ADI Engineering, IXDGP425 and Gateway 7001 boards + * + * Copyright (C) 2003-2005 MontaVista Software, Inc. ++ * Copyright (C) 2006 Imre Kaloz + * + * Author: Deepak Saxena + */ +@@ -111,6 +112,19 @@ + MACHINE_END + #endif + ++#ifdef CONFIG_MACH_GATEWAY7001 ++MACHINE_START(GATEWAY7001, "Gateway 7001") ++ /* Maintainer: Imre Kaloz */ ++ .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, ++ .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, ++ .map_io = ixp4xx_map_io, ++ .init_irq = ixp4xx_init_irq, ++ .timer = &ixp4xx_timer, ++ .boot_params = 0x0100, ++ .init_machine = coyote_init, ++MACHINE_END ++#endif ++ + /* + * IXDPG425 is identical to Coyote except for which serial port + * is connected. -- cgit v1.2.3 From 988fa852ad321fa2052fb8a2f566bfe2e1540272 Mon Sep 17 00:00:00 2001 From: nbd Date: Wed, 31 May 2006 18:32:57 +0000 Subject: remove some debugging junk (#492) git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@3868 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/brcm-2.4/patches/001-bcm47xx.patch | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'target/linux/brcm-2.4/patches/001-bcm47xx.patch') diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch index af82c3c770..b17b543945 100644 --- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch +++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -15751,7 +15751,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sflash.c linux.dev/arch/mips/bcm947xx/sfl diff -urN linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time.c --- linux.old/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.dev/arch/mips/bcm947xx/time.c 2006-04-28 00:45:40.000000000 +0200 -@@ -0,0 +1,119 @@ +@@ -0,0 +1,104 @@ +/* + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. @@ -15828,13 +15828,6 @@ diff -urN linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time. + + /* Set panic timeout in seconds */ + panic_timeout = watchdog / 1000; -+ -+ /* Setup blink */ -+ if ((eir = sb_setcore(sbh, SB_EXTIF, 0))) { -+ sbconfig_t *sb = (sbconfig_t *)((unsigned int) eir + SBCONFIGOFF); -+ unsigned long base = EXTIF_CFGIF_BASE(sb_base(readl(&sb->sbadmatch1))); -+ mcr = (u8 *) ioremap_nocache(base + UART_MCR, 1); -+ } +} + +static void @@ -15846,14 +15839,6 @@ diff -urN linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time. + /* Set the watchdog timer to reset after the specified number of ms */ + if (watchdog > 0) + sb_watchdog(sbh, WATCHDOG_CLOCK / 1000 * watchdog); -+ -+#ifdef CONFIG_HWSIM -+ (*((int *)0xa0000f1c))++; -+#else -+ /* Blink one of the LEDs in the external UART */ -+ if (mcr && !(jiffies % (HZ/2))) -+ writeb(readb(mcr) ^ UART_MCR_OUT2, mcr); -+#endif +} + +static struct irqaction bcm947xx_timer_irqaction = { -- cgit v1.2.3 From cee33e241a7974dc808b91a325d6777fc18280c0 Mon Sep 17 00:00:00 2001 From: nbd Date: Sun, 18 Jun 2006 22:30:14 +0000 Subject: fix typo in brcm-2.4 system code git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@4003 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/brcm-2.4/patches/001-bcm47xx.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'target/linux/brcm-2.4/patches/001-bcm47xx.patch') diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch index b17b543945..e1bd00bae2 100644 --- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch +++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -11723,7 +11723,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc + return -1; + } + -+ if ((chip == 0x4710) && (chiprev == 0)) ++ if ((chip == 0x4310) && (chiprev == 0)) + pci_disabled = TRUE; + + sb = (sbconfig_t *)((ulong) pci + SBCONFIGOFF); -- cgit v1.2.3 From 8afe76304a4a092f6100c0f75df0e58bb2821833 Mon Sep 17 00:00:00 2001 From: nbd Date: Mon, 19 Jun 2006 19:59:53 +0000 Subject: remove the wl.o build from the kernel patch and move the driver along with wl, nas and wlc into packages/broadcom-wl git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@4009 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/broadcom-wl/Makefile | 96 + package/broadcom-wl/src/kmod/Makefile | 32 + package/broadcom-wl/src/kmod/bcmip.h | 101 + package/broadcom-wl/src/kmod/bcmutils.c | 857 ++++++ package/broadcom-wl/src/kmod/hnddma.c | 1157 +++++++ package/broadcom-wl/src/kmod/hnddma.h | 156 + package/broadcom-wl/src/kmod/linux_osl.c | 269 ++ package/broadcom-wl/src/kmod/linux_osl.h | 171 + package/broadcom-wl/src/kmod/patchtable.pl | 54 + package/broadcom-wl/src/kmod/pktq.h | 97 + package/broadcom-wl/src/kmod/sbhnddma.h | 284 ++ package/broadcom-wl/src/wlc/Makefile | 9 + package/broadcom-wl/src/wlc/include/bcmdefs.h | 106 + package/broadcom-wl/src/wlc/include/bcmutils.h | 258 ++ package/broadcom-wl/src/wlc/include/proto/802.11.h | 1258 ++++++++ package/broadcom-wl/src/wlc/include/proto/bcmeth.h | 101 + .../broadcom-wl/src/wlc/include/proto/bcmevent.h | 152 + .../broadcom-wl/src/wlc/include/proto/ethernet.h | 165 + package/broadcom-wl/src/wlc/include/proto/wpa.h | 148 + package/broadcom-wl/src/wlc/include/typedefs.h | 230 ++ package/broadcom-wl/src/wlc/include/wlioctl.h | 1384 +++++++++ package/broadcom-wl/src/wlc/include/wlutils.h | 102 + package/broadcom-wl/src/wlc/ioctl.c | 298 ++ package/broadcom-wl/src/wlc/wlc.c | 1138 +++++++ package/wlc/Makefile | 40 - package/wlc/src/Makefile | 9 - package/wlc/src/include/bcmdefs.h | 106 - package/wlc/src/include/bcmutils.h | 258 -- package/wlc/src/include/proto/802.11.h | 1258 -------- package/wlc/src/include/proto/bcmeth.h | 101 - package/wlc/src/include/proto/bcmevent.h | 152 - package/wlc/src/include/proto/ethernet.h | 165 - package/wlc/src/include/proto/wpa.h | 148 - package/wlc/src/include/typedefs.h | 230 -- package/wlc/src/include/wlioctl.h | 1384 --------- package/wlc/src/include/wlutils.h | 102 - package/wlc/src/ioctl.c | 298 -- package/wlc/src/wlc.c | 1138 ------- target/linux/brcm-2.4/Config.in | 8 - target/linux/brcm-2.4/Makefile | 39 - target/linux/brcm-2.4/config | 3 - target/linux/brcm-2.4/patches/001-bcm47xx.patch | 3252 +------------------- 42 files changed, 8624 insertions(+), 8690 deletions(-) create mode 100644 package/broadcom-wl/Makefile create mode 100644 package/broadcom-wl/src/kmod/Makefile create mode 100644 package/broadcom-wl/src/kmod/bcmip.h create mode 100644 package/broadcom-wl/src/kmod/bcmutils.c create mode 100644 package/broadcom-wl/src/kmod/hnddma.c create mode 100644 package/broadcom-wl/src/kmod/hnddma.h create mode 100644 package/broadcom-wl/src/kmod/linux_osl.c create mode 100644 package/broadcom-wl/src/kmod/linux_osl.h create mode 100644 package/broadcom-wl/src/kmod/patchtable.pl create mode 100644 package/broadcom-wl/src/kmod/pktq.h create mode 100644 package/broadcom-wl/src/kmod/sbhnddma.h create mode 100644 package/broadcom-wl/src/wlc/Makefile create mode 100644 package/broadcom-wl/src/wlc/include/bcmdefs.h create mode 100644 package/broadcom-wl/src/wlc/include/bcmutils.h create mode 100644 package/broadcom-wl/src/wlc/include/proto/802.11.h create mode 100644 package/broadcom-wl/src/wlc/include/proto/bcmeth.h create mode 100644 package/broadcom-wl/src/wlc/include/proto/bcmevent.h create mode 100644 package/broadcom-wl/src/wlc/include/proto/ethernet.h create mode 100644 package/broadcom-wl/src/wlc/include/proto/wpa.h create mode 100644 package/broadcom-wl/src/wlc/include/typedefs.h create mode 100644 package/broadcom-wl/src/wlc/include/wlioctl.h create mode 100644 package/broadcom-wl/src/wlc/include/wlutils.h create mode 100644 package/broadcom-wl/src/wlc/ioctl.c create mode 100644 package/broadcom-wl/src/wlc/wlc.c delete mode 100644 package/wlc/Makefile delete mode 100644 package/wlc/src/Makefile delete mode 100644 package/wlc/src/include/bcmdefs.h delete mode 100644 package/wlc/src/include/bcmutils.h delete mode 100644 package/wlc/src/include/proto/802.11.h delete mode 100644 package/wlc/src/include/proto/bcmeth.h delete mode 100644 package/wlc/src/include/proto/bcmevent.h delete mode 100644 package/wlc/src/include/proto/ethernet.h delete mode 100644 package/wlc/src/include/proto/wpa.h delete mode 100644 package/wlc/src/include/typedefs.h delete mode 100644 package/wlc/src/include/wlioctl.h delete mode 100644 package/wlc/src/include/wlutils.h delete mode 100644 package/wlc/src/ioctl.c delete mode 100644 package/wlc/src/wlc.c delete mode 100644 target/linux/brcm-2.4/Config.in (limited to 'target/linux/brcm-2.4/patches/001-bcm47xx.patch') diff --git a/package/broadcom-wl/Makefile b/package/broadcom-wl/Makefile new file mode 100644 index 0000000000..782dfdaf57 --- /dev/null +++ b/package/broadcom-wl/Makefile @@ -0,0 +1,96 @@ +# $Id: Makefile 2480 2005-11-14 02:07:33Z nbd $ + +include $(TOPDIR)/rules.mk +include $(TOPDIR)/package/kernel.mk + +PKG_NAME:=broadcom-wl +PKG_VERSION:=4.80.9.2 +PKG_RELEASE:=1 +WLC_VERSION:=0.1 + +PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2 +PKG_SOURCE_URL:=http://downloads.openwrt.org/sources +PKG_MD5SUM:=8ff7481425e0b04fc66f2bf950474cbc +PKG_CAT:=bzcat + +include $(TOPDIR)/package/rules.mk + +define Package/kmod-brcm-wl + SECTION:=drivers + CATEGORY:=Drivers + DEPENDS:=@LINUX_2_4_BRCM + DEFAULT:=y + MENU:=1 + TITLE:=Proprietary BCM43xx WiFi driver + DESCRIPTION:=Proprietary Wireless driver for the Broadcom BCM43xx chipset + VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(PKG_RELEASE) +endef + +define Package/wlc + $(call Package/kmod-brcm-wl) + DEPENDS:=kmod-brcm-wl + TITLE:=Setup utility + DESCRIPTION:=Utility for initializing the Broadcom wl driver + VERSION:=$(WLC_VERSION)-$(PKG_RELEASE) +endef + +define Package/wl + $(call Package/wlc) + TITLE:=Utility for changing the driver's parameters + DESCRIPTION:=Utility for changing the Broadcom wl driver's parameters + VERSION:=$(PKG_VERSION)-$(PKG_RELEASE) +endef + +define Package/nas + $(call Package/wl) + TITLE:=Proprietary WPA/WPA2 authenticator + DESCRIPTION:=Proprietary WPA/WPA2 authenticator for the Broadcom wl driver +endef + +define Build/Prepare + $(call Build/Prepare/Default) + $(CP) src/* $(PKG_BUILD_DIR)/ +endef + +define Build/Compile + # Compile the kernel part + $(MAKE) -C "$(LINUX_DIR)" \ + CROSS_COMPILE="$(TARGET_CROSS)" \ + ARCH="$(LINUX_KARCH)" \ + PATH="$(TARGET_PATH)" \ + SUBDIRS="$(PKG_BUILD_DIR)/kmod" \ + modules + + # Compile wlc + $(MAKE) -C $(PKG_BUILD_DIR)/wlc \ + $(TARGET_CONFIGURE_OPTS) \ + CC="$(TARGET_CC)" \ + CFLAGS="-I$(PKG_BUILD_DIR)/wlc/include $(TARGET_CFLAGS)" \ + all +endef + +define Package/kmod-brcm-wl/install + install -d -m0755 $(1)/lib/modules/$(LINUX_VERSION) + install -m0644 $(PKG_BUILD_DIR)/kmod/wl.o $(1)/lib/modules/$(LINUX_VERSION)/ +endef + +define Package/wlc/install + install -d -m0755 $(1)/sbin + install -m0755 $(PKG_BUILD_DIR)/wlc/wlc $(1)/sbin/ +endef + +define Package/wl/install + install -d -m0755 $(1)/usr/sbin + install -m0755 $(PKG_BUILD_DIR)/wl $(1)/usr/sbin/ +endef + +define Package/nas/install + install -d -m0755 $(1)/usr/sbin + install -m0755 $(PKG_BUILD_DIR)/nas $(1)/usr/sbin/ +endef + +$(eval $(call BuildPackage,kmod-brcm-wl)) +$(eval $(call BuildPackage,wlc)) +$(eval $(call BuildPackage,wl)) +$(eval $(call BuildPackage,nas)) diff --git a/package/broadcom-wl/src/kmod/Makefile b/package/broadcom-wl/src/kmod/Makefile new file mode 100644 index 0000000000..672384035f --- /dev/null +++ b/package/broadcom-wl/src/kmod/Makefile @@ -0,0 +1,32 @@ +# +# Makefile for the Broadcom wl driver +# +# Copyright 2004, Broadcom Corporation +# All Rights Reserved. +# +# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY +# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM +# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. +# +# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ + +EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER + +O_TARGET := wl_link.o + +obj-y := wl_mod.o +obj-y += bcmutils.o hnddma.o linux_osl.o + +obj-m := $(O_TARGET) + +wl_mod.o: wl_apsta.o + sed -e 's,eth%d,wl%d\x00,g' < $< > $@ + +wl.o: wl_link.o + $(OBJDUMP) -d $< | perl patchtable.pl > patchtable.bin + cat wl_link.o patchtable.bin > $@ + +modules: wl.o + +include $(TOPDIR)/Rules.make diff --git a/package/broadcom-wl/src/kmod/bcmip.h b/package/broadcom-wl/src/kmod/bcmip.h new file mode 100644 index 0000000000..423a0e5c5c --- /dev/null +++ b/package/broadcom-wl/src/kmod/bcmip.h @@ -0,0 +1,101 @@ +/* + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * Fundamental constants relating to IP Protocol + * + * $Id: bcmip.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $ + */ + +#ifndef _bcmip_h_ +#define _bcmip_h_ + +/* IPV4 and IPV6 common */ +#define IP_VER_OFFSET 0x0 /* offset to version field */ +#define IP_VER_MASK 0xf0 /* version mask */ +#define IP_VER_SHIFT 4 /* version shift */ +#define IP_VER_4 4 /* version number for IPV4 */ +#define IP_VER_6 6 /* version number for IPV6 */ + +#define IP_VER(ip_body) \ + ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) + +#define IP_PROT_ICMP 0x1 /* ICMP protocol */ +#define IP_PROT_TCP 0x6 /* TCP protocol */ +#define IP_PROT_UDP 0x11 /* UDP protocol type */ + +/* IPV4 field offsets */ +#define IPV4_VER_HL_OFFSET 0 /* version and ihl byte offset */ +#define IPV4_TOS_OFFSET 1 /* type of service offset */ +#define IPV4_PROT_OFFSET 9 /* protocol type offset */ +#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ +#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ +#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ + +/* IPV4 field decodes */ +#define IPV4_VER_MASK 0xf0 /* IPV4 version mask */ +#define IPV4_VER_SHIFT 4 /* IPV4 version shift */ + +#define IPV4_HLEN_MASK 0x0f /* IPV4 header length mask */ +#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) + +#define IPV4_ADDR_LEN 4 /* IPV4 address length */ + +#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ + ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) + +#define IPV4_TOS_DSCP_MASK 0xfc /* DiffServ codepoint mask */ +#define IPV4_TOS_DSCP_SHIFT 2 /* DiffServ codepoint shift */ + +#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) + +#define IPV4_TOS_PREC_MASK 0xe0 /* Historical precedence mask */ +#define IPV4_TOS_PREC_SHIFT 5 /* Historical precedence shift */ + +#define IPV4_TOS_LOWDELAY 0x10 /* Lowest delay requested */ +#define IPV4_TOS_THROUGHPUT 0x8 /* Best throughput requested */ +#define IPV4_TOS_RELIABILITY 0x4 /* Most reliable delivery requested */ + +#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) + +#define IPV4_ADDR_STR_LEN 16 /* Max IP address length in string format */ + +/* IPV6 field offsets */ +#define IPV6_PAYLOAD_LEN_OFFSET 4 /* payload length offset */ +#define IPV6_NEXT_HDR_OFFSET 6 /* next header/protocol offset */ +#define IPV6_HOP_LIMIT_OFFSET 7 /* hop limit offset */ +#define IPV6_SRC_IP_OFFSET 8 /* src IP addr offset */ +#define IPV6_DEST_IP_OFFSET 24 /* dst IP addr offset */ + +/* IPV6 field decodes */ +#define IPV6_TRAFFIC_CLASS(ipv6_body) \ + (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ + ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) + +#define IPV6_FLOW_LABEL(ipv6_body) \ + (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ + (((uint8 *)(ipv6_body))[2] << 8) | \ + (((uint8 *)(ipv6_body))[3])) + +#define IPV6_PAYLOAD_LEN(ipv6_body) \ + ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ + ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) + +#define IPV6_NEXT_HDR(ipv6_body) \ + (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) + +#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) + +#define IPV6_ADDR_LEN 16 /* IPV6 address length */ + +/* IPV4 TOS or IPV6 Traffic Classifier or 0 */ +#define IP_TOS(ip_body) \ + (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ + IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) + +#endif /* _bcmip_h_ */ diff --git a/package/broadcom-wl/src/kmod/bcmutils.c b/package/broadcom-wl/src/kmod/bcmutils.c new file mode 100644 index 0000000000..c264ea500b --- /dev/null +++ b/package/broadcom-wl/src/kmod/bcmutils.c @@ -0,0 +1,857 @@ +/* + * Misc useful OS-independent routines. + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $ + */ + +#include +#include +#include +#include +#include "linux_osl.h" +#include "pktq.h" +#include +#include +#include +#include +#include +#include "bcmip.h" + +#define ETHER_TYPE_8021Q 0x8100 +#define ETHER_TYPE_IP 0x0800 +#define VLAN_PRI_SHIFT 13 +#define VLAN_PRI_MASK 7 + + +struct ether_header { + uint8 ether_dhost[6]; + uint8 ether_shost[6]; + uint16 ether_type; +} __attribute__((packed)); + + +struct ethervlan_header { + uint8 ether_dhost[6]; + uint8 ether_shost[6]; + uint16 vlan_type; /* 0x8100 */ + uint16 vlan_tag; /* priority, cfi and vid */ + uint16 ether_type; +}; + +/* copy a pkt buffer chain into a buffer */ +uint +pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) +{ + uint n, ret = 0; + + if (len < 0) + len = 4096; /* "infinite" */ + + /* skip 'offset' bytes */ + for (; p && offset; p = PKTNEXT(osh, p)) { + if (offset < (uint)PKTLEN(osh, p)) + break; + offset -= PKTLEN(osh, p); + } + + if (!p) + return 0; + + /* copy the data */ + for (; p && len; p = PKTNEXT(osh, p)) { + n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); + bcopy(PKTDATA(osh, p) + offset, buf, n); + buf += n; + len -= n; + ret += n; + offset = 0; + } + + return ret; +} + +/* return total length of buffer chain */ +uint +pkttotlen(osl_t *osh, void *p) +{ + uint total; + + total = 0; + for (; p; p = PKTNEXT(osh, p)) + total += PKTLEN(osh, p); + return (total); +} + +/* return the last buffer of chained pkt */ +void * +pktlast(osl_t *osh, void *p) +{ + for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) + ; + + return (p); +} + + +/* + * osl multiple-precedence packet queue + * hi_prec is always >= the number of the highest non-empty queue + */ +void * +pktq_penq(struct pktq *pq, int prec, void *p) +{ + struct pktq_prec *q; + + ASSERT(prec >= 0 && prec < pq->num_prec); + ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ + + ASSERT(!pktq_full(pq)); + ASSERT(!pktq_pfull(pq, prec)); + + q = &pq->q[prec]; + + if (q->head) + PKTSETLINK(q->tail, p); + else + q->head = p; + + q->tail = p; + q->len++; + + pq->len++; + + if (pq->hi_prec < prec) + pq->hi_prec = (uint8)prec; + + return p; +} + +void * +pktq_penq_head(struct pktq *pq, int prec, void *p) +{ + struct pktq_prec *q; + + ASSERT(prec >= 0 && prec < pq->num_prec); + ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ + + ASSERT(!pktq_full(pq)); + ASSERT(!pktq_pfull(pq, prec)); + + q = &pq->q[prec]; + + if (q->head == NULL) + q->tail = p; + + PKTSETLINK(p, q->head); + q->head = p; + q->len++; + + pq->len++; + + if (pq->hi_prec < prec) + pq->hi_prec = (uint8)prec; + + return p; +} + +void * +pktq_pdeq(struct pktq *pq, int prec) +{ + struct pktq_prec *q; + void *p; + + ASSERT(prec >= 0 && prec < pq->num_prec); + + q = &pq->q[prec]; + + if ((p = q->head) == NULL) + return NULL; + + if ((q->head = PKTLINK(p)) == NULL) + q->tail = NULL; + + q->len--; + + pq->len--; + + PKTSETLINK(p, NULL); + + return p; +} + +void * +pktq_pdeq_tail(struct pktq *pq, int prec) +{ + struct pktq_prec *q; + void *p, *prev; + + ASSERT(prec >= 0 && prec < pq->num_prec); + + q = &pq->q[prec]; + + if ((p = q->head) == NULL) + return NULL; + + for (prev = NULL; p != q->tail; p = PKTLINK(p)) + prev = p; + + if (prev) + PKTSETLINK(prev, NULL); + else + q->head = NULL; + + q->tail = prev; + q->len--; + + pq->len--; + + return p; +} + +void +pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir) +{ + struct pktq_prec *q; + void *p; + + q = &pq->q[prec]; + p = q->head; + while (p) { + q->head = PKTLINK(p); + PKTSETLINK(p, NULL); + PKTFREE(osh, p, dir); + q->len--; + pq->len--; + p = q->head; + } + ASSERT(q->len == 0); + q->tail = NULL; +} + +bool +pktq_pdel(struct pktq *pq, void *pktbuf, int prec) +{ + struct pktq_prec *q; + void *p; + + ASSERT(prec >= 0 && prec < pq->num_prec); + + if (!pktbuf) + return FALSE; + + q = &pq->q[prec]; + + if (q->head == pktbuf) { + if ((q->head = PKTLINK(pktbuf)) == NULL) + q->tail = NULL; + } else { + for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) + ; + if (p == NULL) + return FALSE; + + PKTSETLINK(p, PKTLINK(pktbuf)); + if (q->tail == pktbuf) + q->tail = p; + } + + q->len--; + pq->len--; + PKTSETLINK(pktbuf, NULL); + return TRUE; +} + +void +pktq_init(struct pktq *pq, int num_prec, int max_len) +{ + int prec; + + ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); + + bzero(pq, sizeof(*pq)); + + pq->num_prec = (uint16)num_prec; + + pq->max = (uint16)max_len; + + for (prec = 0; prec < num_prec; prec++) + pq->q[prec].max = pq->max; +} + +void * +pktq_deq(struct pktq *pq, int *prec_out) +{ + struct pktq_prec *q; + void *p; + int prec; + + if (pq->len == 0) + return NULL; + + while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) + pq->hi_prec--; + + q = &pq->q[prec]; + + if ((p = q->head) == NULL) + return NULL; + + if ((q->head = PKTLINK(p)) == NULL) + q->tail = NULL; + + q->len--; + + pq->len--; + + if (prec_out) + *prec_out = prec; + + PKTSETLINK(p, NULL); + + return p; +} + +void * +pktq_deq_tail(struct pktq *pq, int *prec_out) +{ + struct pktq_prec *q; + void *p, *prev; + int prec; + + if (pq->len == 0) + return NULL; + + for (prec = 0; prec < pq->hi_prec; prec++) + if (pq->q[prec].head) + break; + + q = &pq->q[prec]; + + if ((p = q->head) == NULL) + return NULL; + + for (prev = NULL; p != q->tail; p = PKTLINK(p)) + prev = p; + + if (prev) + PKTSETLINK(prev, NULL); + else + q->head = NULL; + + q->tail = prev; + q->len--; + + pq->len--; + + if (prec_out) + *prec_out = prec; + + PKTSETLINK(p, NULL); + + return p; +} + +void * +pktq_peek(struct pktq *pq, int *prec_out) +{ + int prec; + + if (pq->len == 0) + return NULL; + + while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) + pq->hi_prec--; + + if (prec_out) + *prec_out = prec; + + return (pq->q[prec].head); +} + +void * +pktq_peek_tail(struct pktq *pq, int *prec_out) +{ + int prec; + + if (pq->len == 0) + return NULL; + + for (prec = 0; prec < pq->hi_prec; prec++) + if (pq->q[prec].head) + break; + + if (prec_out) + *prec_out = prec; + + return (pq->q[prec].tail); +} + +void +pktq_flush(osl_t *osh, struct pktq *pq, bool dir) +{ + int prec; + for (prec = 0; prec < pq->num_prec; prec++) + pktq_pflush(osh, pq, prec, dir); + ASSERT(pq->len == 0); +} + +/* Return sum of lengths of a specific set of precedences */ +int +pktq_mlen(struct pktq *pq, uint prec_bmp) +{ + int prec, len; + + len = 0; + + for (prec = 0; prec <= pq->hi_prec; prec++) + if (prec_bmp & (1 << prec)) + len += pq->q[prec].len; + + return len; +} + +/* Priority dequeue from a specific set of precedences */ +void * +pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) +{ + struct pktq_prec *q; + void *p; + int prec; + + if (pq->len == 0) + return NULL; + + while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) + pq->hi_prec--; + + while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) + if (prec-- == 0) + return NULL; + + q = &pq->q[prec]; + + if ((p = q->head) == NULL) + return NULL; + + if ((q->head = PKTLINK(p)) == NULL) + q->tail = NULL; + + q->len--; + + if (prec_out) + *prec_out = prec; + + pq->len--; + + PKTSETLINK(p, NULL); + + return p; +} + +char* +bcmstrcat(char *dest, const char *src) +{ + strcpy(&dest[strlen(dest)], src); + return (dest); +} + +char* +bcm_ether_ntoa(struct ether_addr *ea, char *buf) +{ + sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", + ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, + ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); + return (buf); +} + +/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ +int +bcm_ether_atoe(char *p, struct ether_addr *ea) +{ + int i = 0; + + for (;;) { + ea->octet[i++] = (char) bcm_strtoul(p, &p, 16); + if (!*p++ || i == 6) + break; + } + + return (i == 6); +} + +/* Takes an Ethernet frame and sets out-of-bound PKTPRIO + * Also updates the inplace vlan tag if requested + */ +void +pktsetprio(void *pkt, bool update_vtag) +{ + struct ether_header *eh; + struct ethervlan_header *evh; + uint8 *pktdata; + int priority = 0; + + pktdata = (uint8 *) PKTDATA(NULL, pkt); + ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); + + eh = (struct ether_header *) pktdata; + + if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { + uint16 vlan_tag; + int vlan_prio, dscp_prio = 0; + + evh = (struct ethervlan_header *)eh; + + vlan_tag = ntoh16(evh->vlan_tag); + vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; + + if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { + uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); + uint8 tos_tc = IP_TOS(ip_body); + dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); + } + + /* DSCP priority gets precedence over 802.1P (vlan tag) */ + priority = (dscp_prio != 0) ? dscp_prio : vlan_prio; + + /* + * If the DSCP priority is not the same as the VLAN priority, + * then overwrite the priority field in the vlan tag, with the + * DSCP priority value. This is required for Linux APs because + * the VLAN driver on Linux, overwrites the skb->priority field + * with the priority value in the vlan tag + */ + if (update_vtag && (priority != vlan_prio)) { + vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); + vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; + evh->vlan_tag = hton16(vlan_tag); + } + } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { + uint8 *ip_body = pktdata + sizeof(struct ether_header); + uint8 tos_tc = IP_TOS(ip_body); + priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); + } + + ASSERT(priority >= 0 && priority <= MAXPRIO); + PKTSETPRIO(pkt, priority); +} + +static char bcm_undeferrstr[BCME_STRLEN]; + +static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; + +/* Convert the Error codes into related Error strings */ +const char * +bcmerrorstr(int bcmerror) +{ + int abs_bcmerror; + + abs_bcmerror = ABS(bcmerror); + + /* check if someone added a bcmerror code but forgot to add errorstring */ + ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); + if ((bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) { + sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror); + return bcm_undeferrstr; + } + + ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN); + + return bcmerrorstrtable[abs_bcmerror]; +} + + +int +bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) +{ + int bcmerror = 0; + + /* length check on io buf */ + switch (vi->type) { + case IOVT_BOOL: + case IOVT_INT8: + case IOVT_INT16: + case IOVT_INT32: + case IOVT_UINT8: + case IOVT_UINT16: + case IOVT_UINT32: + /* all integers are int32 sized args at the ioctl interface */ + if (len < (int)sizeof(int)) { + bcmerror = BCME_BUFTOOSHORT; + } + break; + + case IOVT_BUFFER: + /* buffer must meet minimum length requirement */ + if (len < vi->minlen) { + bcmerror = BCME_BUFTOOSHORT; + } + break; + + case IOVT_VOID: + if (!set) { + /* Cannot return nil... */ + bcmerror = BCME_UNSUPPORTED; + } else if (len) { + /* Set is an action w/o parameters */ + bcmerror = BCME_BUFTOOLONG; + } + break; + + default: + /* unknown type for length check in iovar info */ + ASSERT(0); + bcmerror = BCME_UNSUPPORTED; + } + + return bcmerror; +} + +#define CRC_INNER_LOOP(n, c, x) \ + (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] + +static uint32 crc32_table[256] = { + 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, + 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, + 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, + 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, + 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, + 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, + 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, + 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, + 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, + 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, + 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, + 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, + 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, + 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, + 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, + 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, + 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, + 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, + 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, + 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, + 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, + 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, + 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, + 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, + 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, + 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, + 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, + 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, + 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, + 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, + 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, + 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, + 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, + 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, + 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, + 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, + 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, + 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, + 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, + 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, + 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, + 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, + 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, + 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, + 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, + 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, + 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, + 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, + 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, + 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, + 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, + 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, + 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, + 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, + 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, + 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, + 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, + 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, + 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, + 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, + 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, + 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, + 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, + 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D +}; + +uint32 +hndcrc32( + uint8 *pdata, /* pointer to array of data to process */ + uint nbytes, /* number of input data bytes to process */ + uint32 crc /* either CRC32_INIT_VALUE or previous return value */ +) +{ + uint8 *pend; +#ifdef __mips__ + uint8 tmp[4]; + ulong *tptr = (ulong *)tmp; + + /* in case the beginning of the buffer isn't aligned */ + pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); + nbytes -= (pend - pdata); + while (pdata < pend) + CRC_INNER_LOOP(32, crc, *pdata++); + + /* handle bulk of data as 32-bit words */ + pend = pdata + (nbytes & 0xfffffffc); + while (pdata < pend) { + *tptr = *(ulong *)pdata; + pdata += sizeof(ulong *); + CRC_INNER_LOOP(32, crc, tmp[0]); + CRC_INNER_LOOP(32, crc, tmp[1]); + CRC_INNER_LOOP(32, crc, tmp[2]); + CRC_INNER_LOOP(32, crc, tmp[3]); + } + + /* 1-3 bytes at end of buffer */ + pend = pdata + (nbytes & 0x03); + while (pdata < pend) + CRC_INNER_LOOP(32, crc, *pdata++); +#else + pend = pdata + nbytes; + while (pdata < pend) + CRC_INNER_LOOP(32, crc, *pdata++); +#endif /* __mips__ */ + + return crc; +} + + +/* + * Advance from the current 1-byte tag/1-byte length/variable-length value + * triple, to the next, returning a pointer to the next. + * If the current or next TLV is invalid (does not fit in given buffer length), + * NULL is returned. + * *buflen is not modified if the TLV elt parameter is invalid, or is decremented + * by the TLV paramter's length if it is valid. + */ +bcm_tlv_t * +bcm_next_tlv(bcm_tlv_t *elt, int *buflen) +{ + int len; + + /* validate current elt */ + if (!bcm_valid_tlv(elt, *buflen)) + return NULL; + + /* advance to next elt */ + len = elt->len; + elt = (bcm_tlv_t*)(elt->data + len); + *buflen -= (2 + len); + + /* validate next elt */ + if (!bcm_valid_tlv(elt, *buflen)) + return NULL; + + return elt; +} + +/* + * Traverse a string of 1-byte tag/1-byte length/variable-length value + * triples, returning a pointer to the substring whose first element + * matches tag + */ +bcm_tlv_t * +bcm_parse_tlvs(void *buf, int buflen, uint key) +{ + bcm_tlv_t *elt; + int totlen; + + elt = (bcm_tlv_t*)buf; + totlen = buflen; + + /* find tagged parameter */ + while (totlen >= 2) { + int len = elt->len; + + /* validate remaining totlen */ + if ((elt->id == key) && (totlen >= (len + 2))) + return (elt); + + elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); + totlen -= (len + 2); + } + + return NULL; +} + +/* + * Traverse a string of 1-byte tag/1-byte length/variable-length value + * triples, returning a pointer to the substring whose first element + * matches tag. Stop parsing when we see an element whose ID is greater + * than the target key. + */ +bcm_tlv_t * +bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) +{ + bcm_tlv_t *elt; + int totlen; + + elt = (bcm_tlv_t*)buf; + totlen = buflen; + + /* find tagged parameter */ + while (totlen >= 2) { + uint id = elt->id; + int len = elt->len; + + /* Punt if we start seeing IDs > than target key */ + if (id > key) + return (NULL); + + /* validate remaining totlen */ + if ((id == key) && (totlen >= (len + 2))) + return (elt); + + elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); + totlen -= (len + 2); + } + return NULL; +} + + +/* Initialization of bcmstrbuf structure */ +void +bcm_binit(struct bcmstrbuf *b, char *buf, uint size) +{ + b->origsize = b->size = size; + b->origbuf = b->buf = buf; +} + +/* Buffer sprintf wrapper to guard against buffer overflow */ +int +bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) +{ + va_list ap; + int r; + + va_start(ap, fmt); + r = vsnprintf(b->buf, b->size, fmt, ap); + + /* Non Ansi C99 compliant returns -1, + * Ansi compliant return r >= b->size, + * bcmstdlib returns 0, handle all + */ + if ((r == -1) || (r >= (int)b->size) || (r == 0)) + { + b->size = 0; + } + else + { + b->size -= r; + b->buf += r; + } + + va_end(ap); + + return r; +} diff --git a/package/broadcom-wl/src/kmod/hnddma.c b/package/broadcom-wl/src/kmod/hnddma.c new file mode 100644 index 0000000000..4336560888 --- /dev/null +++ b/package/broadcom-wl/src/kmod/hnddma.c @@ -0,0 +1,1157 @@ +/* + * Generic Broadcom Home Networking Division (HND) DMA module. + * This supports the following chips: BCM42xx, 44xx, 47xx . + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: hnddma.c,v 1.11 2006/04/08 07:12:42 honor Exp $ + */ + +#include +#include +#include +#include "linux_osl.h" +#include +#include +#include +#include +#include + +#include "sbhnddma.h" +#include "hnddma.h" + +/* debug/trace */ +#define DMA_ERROR(args) +#define DMA_TRACE(args) + +/* default dma message level (if input msg_level pointer is null in dma_attach()) */ +static uint dma_msg_level = + 0; + +#define MAXNAMEL 8 /* 8 char names */ + +#define DI_INFO(dmah) (dma_info_t *)dmah + +/* dma engine software state */ +typedef struct dma_info { + struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t, + * which could be const + */ + uint *msg_level; /* message level pointer */ + char name[MAXNAMEL]; /* callers name for diag msgs */ + + void *osh; /* os handle */ + sb_t *sbh; /* sb handle */ + + bool dma64; /* dma64 enabled */ + bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ + + dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ + dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ + dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ + dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ + + uint32 dma64align; /* either 8k or 4k depends on number of dd */ + dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ + dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ + uint ntxd; /* # tx descriptors tunable */ + uint txin; /* index of next descriptor to reclaim */ + uint txout; /* index of next descriptor to post */ + void **txp; /* pointer to parallel array of pointers to packets */ + osldma_t *tx_dmah; /* DMA TX descriptor ring handle */ + osldma_t **txp_dmah; /* DMA TX packet data handle */ + ulong txdpa; /* physical address of descriptor ring */ + uint txdalign; /* #bytes added to alloc'd mem to align txd */ + uint txdalloc; /* #bytes allocated for the ring */ + + dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ + dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ + uint nrxd; /* # rx descriptors tunable */ + uint rxin; /* index of next descriptor to reclaim */ + uint rxout; /* index of next descriptor to post */ + void **rxp; /* pointer to parallel array of pointers to packets */ + osldma_t *rx_dmah; /* DMA RX descriptor ring handle */ + osldma_t **rxp_dmah; /* DMA RX packet data handle */ + ulong rxdpa; /* physical address of descriptor ring */ + uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ + uint rxdalloc; /* #bytes allocated for the ring */ + + /* tunables */ + uint rxbufsize; /* rx buffer size in bytes, + not including the extra headroom + */ + uint nrxpost; /* # rx buffers to keep posted */ + uint rxoffset; /* rxcontrol offset */ + uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ + uint ddoffsethigh; /* high 32 bits */ + uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ + uint dataoffsethigh; /* high 32 bits */ +} dma_info_t; + +/* descriptor bumping macros */ +#define XXD(x, n) ((x) & ((n) - 1)) /* faster than %, but n must be power of 2 */ +#define TXD(x) XXD((x), di->ntxd) +#define RXD(x) XXD((x), di->nrxd) +#define NEXTTXD(i) TXD(i + 1) +#define PREVTXD(i) TXD(i - 1) +#define NEXTRXD(i) RXD(i + 1) +#define NTXDACTIVE(h, t) TXD(t - h) +#define NRXDACTIVE(h, t) RXD(t - h) + +/* macros to convert between byte offsets and indexes */ +#define B2I(bytes, type) ((bytes) / sizeof(type)) +#define I2B(index, type) ((index) * sizeof(type)) + +#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ +#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */ + + +/* common prototypes */ +static bool _dma_isaddrext(dma_info_t *di); +static bool dma32_alloc(dma_info_t *di, uint direction); +static void _dma_detach(dma_info_t *di); +static void _dma_ddtable_init(dma_info_t *di, uint direction, ulong pa); +static void _dma_rxinit(dma_info_t *di); +static void *_dma_rx(dma_info_t *di); +static void _dma_rxfill(dma_info_t *di); +static void _dma_rxreclaim(dma_info_t *di); +static void _dma_rxenable(dma_info_t *di); +static void * _dma_getnextrxp(dma_info_t *di, bool forceall); + +static void _dma_txblock(dma_info_t *di); +static void _dma_txunblock(dma_info_t *di); +static uint _dma_txactive(dma_info_t *di); + +static void* _dma_peeknexttxp(dma_info_t *di); +static uintptr _dma_getvar(dma_info_t *di, char *name); +static void _dma_counterreset(dma_info_t *di); +static void _dma_fifoloopbackenable(dma_info_t *di); + +/* ** 32 bit DMA prototypes */ +static bool dma32_alloc(dma_info_t *di, uint direction); +static bool dma32_txreset(dma_info_t *di); +static bool dma32_rxreset(dma_info_t *di); +static bool dma32_txsuspendedidle(dma_info_t *di); +static int dma32_txfast(dma_info_t *di, void *p0, bool commit); +static void *dma32_getnexttxp(dma_info_t *di, bool forceall); +static void *dma32_getnextrxp(dma_info_t *di, bool forceall); +static void dma32_txrotate(dma_info_t *di); +static bool dma32_rxidle(dma_info_t *di); +static void dma32_txinit(dma_info_t *di); +static bool dma32_txenabled(dma_info_t *di); +static void dma32_txsuspend(dma_info_t *di); +static void dma32_txresume(dma_info_t *di); +static bool dma32_txsuspended(dma_info_t *di); +static void dma32_txreclaim(dma_info_t *di, bool forceall); +static bool dma32_txstopped(dma_info_t *di); +static bool dma32_rxstopped(dma_info_t *di); +static bool dma32_rxenabled(dma_info_t *di); +static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs); + + +static di_fcn_t dma32proc = { + (di_detach_t)_dma_detach, + (di_txinit_t)dma32_txinit, + (di_txreset_t)dma32_txreset, + (di_txenabled_t)dma32_txenabled, + (di_txsuspend_t)dma32_txsuspend, + (di_txresume_t)dma32_txresume, + (di_txsuspended_t)dma32_txsuspended, + (di_txsuspendedidle_t)dma32_txsuspendedidle, + (di_txfast_t)dma32_txfast, + (di_txstopped_t)dma32_txstopped, + (di_txreclaim_t)dma32_txreclaim, + (di_getnexttxp_t)dma32_getnexttxp, + (di_peeknexttxp_t)_dma_peeknexttxp, + (di_txblock_t)_dma_txblock, + (di_txunblock_t)_dma_txunblock, + (di_txactive_t)_dma_txactive, + (di_txrotate_t)dma32_txrotate, + + (di_rxinit_t)_dma_rxinit, + (di_rxreset_t)dma32_rxreset, + (di_rxidle_t)dma32_rxidle, + (di_rxstopped_t)dma32_rxstopped, + (di_rxenable_t)_dma_rxenable, + (di_rxenabled_t)dma32_rxenabled, + (di_rx_t)_dma_rx, + (di_rxfill_t)_dma_rxfill, + (di_rxreclaim_t)_dma_rxreclaim, + (di_getnextrxp_t)_dma_getnextrxp, + + (di_fifoloopbackenable_t)_dma_fifoloopbackenable, + (di_getvar_t)_dma_getvar, + (di_counterreset_t)_dma_counterreset, + + NULL, + NULL, + NULL, + 34 +}; + +hnddma_t * +dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, + uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) +{ + dma_info_t *di; + uint size; + + /* allocate private info structure */ + if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { + return (NULL); + } + bzero((char *)di, sizeof(dma_info_t)); + + di->msg_level = msg_level ? msg_level : &dma_msg_level; + + /* old chips w/o sb is no longer supported */ + ASSERT(sbh != NULL); + + /* check arguments */ + ASSERT(ISPOWEROF2(ntxd)); + ASSERT(ISPOWEROF2(nrxd)); + if (nrxd == 0) + ASSERT(dmaregsrx == NULL); + if (ntxd == 0) + ASSERT(dmaregstx == NULL); + + + /* init dma reg pointer */ + ASSERT(ntxd <= D32MAXDD); + ASSERT(nrxd <= D32MAXDD); + di->d32txregs = (dma32regs_t *)dmaregstx; + di->d32rxregs = (dma32regs_t *)dmaregsrx; + + DMA_TRACE(("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d " + "rxoffset %d dmaregstx %p dmaregsrx %p\n", + name, "DMA32", osh, ntxd, nrxd, rxbufsize, + nrxpost, rxoffset, dmaregstx, dmaregsrx)); + + /* make a private copy of our callers name */ + strncpy(di->name, name, MAXNAMEL); + di->name[MAXNAMEL-1] = '\0'; + + di->osh = osh; + di->sbh = sbh; + + /* save tunables */ + di->ntxd = ntxd; + di->nrxd = nrxd; + + /* the actual dma size doesn't include the extra headroom */ + if (rxbufsize > BCMEXTRAHDROOM) + di->rxbufsize = rxbufsize - BCMEXTRAHDROOM; + else + di->rxbufsize = rxbufsize; + + di->nrxpost = nrxpost; + di->rxoffset = rxoffset; + + /* + * figure out the DMA physical address offset for dd and data + * for old chips w/o sb, use zero + * for new chips w sb, + * PCI/PCIE: they map silicon backplace address to zero based memory, need offset + * Other bus: use zero + * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor + */ + di->ddoffsetlow = 0; + di->dataoffsetlow = 0; + /* for pci bus, add offset */ + if (sbh->bustype == PCI_BUS) { + di->ddoffsetlow = SB_PCI_DMA; + di->ddoffsethigh = 0; + di->dataoffsetlow = di->ddoffsetlow; + di->dataoffsethigh = di->ddoffsethigh; + } + +#if defined(__mips__) && defined(IL_BIGENDIAN) + di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; +#endif + + di->addrext = _dma_isaddrext(di); + + /* allocate tx packet pointer vector */ + if (ntxd) { + size = ntxd * sizeof(void *); + if ((di->txp = MALLOC(osh, size)) == NULL) { + DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", + di->name, MALLOCED(osh))); + goto fail; + } + bzero((char *)di->txp, size); + } + + /* allocate rx packet pointer vector */ + if (nrxd) { + size = nrxd * sizeof(void *); + if ((di->rxp = MALLOC(osh, size)) == NULL) { + DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", + di->name, MALLOCED(osh))); + goto fail; + } + bzero((char *)di->rxp, size); + } + + /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ + if (ntxd) { + if (!dma32_alloc(di, DMA_TX)) + goto fail; + } + + /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ + if (nrxd) { + if (!dma32_alloc(di, DMA_RX)) + goto fail; + } + + if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { + DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", + di->name, di->txdpa)); + goto fail; + } + if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { + DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", + di->name, di->rxdpa)); + goto fail; + } + + DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " + "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, + di->dataoffsethigh, di->addrext)); + + /* allocate tx packet pointer vector and DMA mapping vectors */ + if (ntxd) { + + size = ntxd * sizeof(osldma_t **); + if ((di->txp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) + goto fail; + bzero((char*)di->txp_dmah, size); + }else + di->txp_dmah = NULL; + + /* allocate rx packet pointer vector and DMA mapping vectors */ + if (nrxd) { + + size = nrxd * sizeof(osldma_t **); + if ((di->rxp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) + goto fail; + bzero((char*)di->rxp_dmah, size); + + } else + di->rxp_dmah = NULL; + + /* initialize opsvec of function pointers */ + di->hnddma.di_fn = dma32proc; + + return ((hnddma_t *)di); + +fail: + _dma_detach(di); + return (NULL); +} + +/* init the tx or rx descriptor */ +static INLINE void +dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *flags, + uint32 bufcount) +{ + /* dma32 uses 32 bits control to fit both flags and bufcounter */ + *flags = *flags | (bufcount & CTRL_BC_MASK); + + if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { + W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); + W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); + } else { + /* address extension */ + uint32 ae; + ASSERT(di->addrext); + ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; + pa &= ~PCI32ADDR_HIGH; + + *flags |= (ae << CTRL_AE_SHIFT); + W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); + W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); + } +} + +static bool +_dma32_addrext(osl_t *osh, dma32regs_t *dma32regs) +{ + uint32 w; + + OR_REG(osh, &dma32regs->control, XC_AE); + w = R_REG(osh, &dma32regs->control); + AND_REG(osh, &dma32regs->control, ~XC_AE); + return ((w & XC_AE) == XC_AE); +} + +/* !! may be called with core in reset */ +static void +_dma_detach(dma_info_t *di) +{ + if (di == NULL) + return; + + DMA_TRACE(("%s: dma_detach\n", di->name)); + + /* shouldn't be here if descriptors are unreclaimed */ + ASSERT(di->txin == di->txout); + ASSERT(di->rxin == di->rxout); + + /* free dma descriptor rings */ + if (di->txd32) + DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), + di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah); + if (di->rxd32) + DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), + di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah); + + /* free packet pointer vectors */ + if (di->txp) + MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *))); + if (di->rxp) + MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *))); + + /* free tx packet DMA handles */ + if (di->txp_dmah) + MFREE(di->osh, (void *)di->txp_dmah, di->ntxd * sizeof(osldma_t **)); + + /* free rx packet DMA handles */ + if (di->rxp_dmah) + MFREE(di->osh, (void *)di->rxp_dmah, di->nrxd * sizeof(osldma_t **)); + + /* free our private info structure */ + MFREE(di->osh, (void *)di, sizeof(dma_info_t)); + +} + +/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ +static bool +_dma_isaddrext(dma_info_t *di) +{ + if (di->d32txregs) + return (_dma32_addrext(di->osh, di->d32txregs)); + else if (di->d32rxregs) + return (_dma32_addrext(di->osh, di->d32rxregs)); + return FALSE; +} + +/* initialize descriptor table base address */ +static void +_dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) +{ + if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { + if (direction == DMA_TX) + W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); + else + W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); + } else { + /* dma32 address extension */ + uint32 ae; + ASSERT(di->addrext); + + /* shift the high bit(s) from pa to ae */ + ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; + pa &= ~PCI32ADDR_HIGH; + + if (direction == DMA_TX) { + W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); + SET_REG(di->osh, &di->d32txregs->control, XC_AE, ae <osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); + SET_REG(di->osh, &di->d32rxregs->control, RC_AE, ae <name)); + OR_REG(di->osh, &di->d32txregs->control, XC_LE); +} + +static void +_dma_rxinit(dma_info_t *di) +{ + DMA_TRACE(("%s: dma_rxinit\n", di->name)); + + if (di->nrxd == 0) + return; + + di->rxin = di->rxout = 0; + + /* clear rx descriptor ring */ + BZERO_SM((void *)di->rxd32, (di->nrxd * sizeof(dma32dd_t))); + _dma_rxenable(di); + _dma_ddtable_init(di, DMA_RX, di->rxdpa); +} + +static void +_dma_rxenable(dma_info_t *di) +{ + DMA_TRACE(("%s: dma_rxenable\n", di->name)); + + W_REG(di->osh, &di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); +} + +/* !! rx entry routine, returns a pointer to the next frame received, + * or NULL if there are no more + */ +static void * +_dma_rx(dma_info_t *di) +{ + void *p; + uint len; + int skiplen = 0; + + while ((p = _dma_getnextrxp(di, FALSE))) { + /* skip giant packets which span multiple rx descriptors */ + if (skiplen > 0) { + skiplen -= di->rxbufsize; + if (skiplen < 0) + skiplen = 0; + PKTFREE(di->osh, p, FALSE); + continue; + } + + len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); + DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); + + /* bad frame length check */ + if (len > (di->rxbufsize - di->rxoffset)) { + DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); + if (len > 0) + skiplen = len - (di->rxbufsize - di->rxoffset); + PKTFREE(di->osh, p, FALSE); + di->hnddma.rxgiants++; + continue; + } + + /* set actual length */ + PKTSETLEN(di->osh, p, (di->rxoffset + len)); + + break; + } + + return (p); +} + +/* post receive buffers */ +static void +_dma_rxfill(dma_info_t *di) +{ + void *p; + uint rxin, rxout; + uint32 flags = 0; + uint n; + uint i; + uint32 pa; + uint extra_offset = 0; + + /* + * Determine how many receive buffers we're lacking + * from the full complement, allocate, initialize, + * and post them, then update the chip rx lastdscr. + */ + + rxin = di->rxin; + rxout = di->rxout; + + n = di->nrxpost - NRXDACTIVE(rxin, rxout); + + DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); + + if (di->rxbufsize > BCMEXTRAHDROOM) + extra_offset = BCMEXTRAHDROOM; + + for (i = 0; i < n; i++) { + /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the + size to be allocated + */ + if ((p = PKTGET(di->osh, di->rxbufsize + extra_offset, + FALSE)) == NULL) { + DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); + di->hnddma.rxnobuf++; + break; + } + /* reserve an extra headroom, if applicable */ + if (extra_offset) + PKTPULL(di->osh, p, extra_offset); + + /* Do a cached write instead of uncached write since DMA_MAP + * will flush the cache. + */ + *(uint32*)(PKTDATA(di->osh, p)) = 0; + + pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), + di->rxbufsize, DMA_RX, p); + + ASSERT(ISALIGNED(pa, 4)); + + /* save the free packet pointer */ + ASSERT(di->rxp[rxout] == NULL); + di->rxp[rxout] = p; + + /* reset flags for each descriptor */ + flags = 0; + if (rxout == (di->nrxd - 1)) + flags = CTRL_EOT; + dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, di->rxbufsize); + rxout = NEXTRXD(rxout); + } + + di->rxout = rxout; + + /* update the chip lastdscr pointer */ + W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); +} + +/* like getnexttxp but no reclaim */ +static void * +_dma_peeknexttxp(dma_info_t *di) +{ + uint end, i; + + if (di->ntxd == 0) + return (NULL); + + end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); + + for (i = di->txin; i != end; i = NEXTTXD(i)) + if (di->txp[i]) + return (di->txp[i]); + + return (NULL); +} + +static void +_dma_rxreclaim(dma_info_t *di) +{ + void *p; + + /* "unused local" warning suppression for OSLs that + * define PKTFREE() without using the di->osh arg + */ + di = di; + + DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); + + while ((p = _dma_getnextrxp(di, TRUE))) + PKTFREE(di->osh, p, FALSE); +} + +static void * +_dma_getnextrxp(dma_info_t *di, bool forceall) +{ + if (di->nrxd == 0) + return (NULL); + + return dma32_getnextrxp(di, forceall); +} + +static void +_dma_txblock(dma_info_t *di) +{ + di->hnddma.txavail = 0; +} + +static void +_dma_txunblock(dma_info_t *di) +{ + di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; +} + +static uint +_dma_txactive(dma_info_t *di) +{ + return (NTXDACTIVE(di->txin, di->txout)); +} + +static void +_dma_counterreset(dma_info_t *di) +{ + /* reset all software counter */ + di->hnddma.rxgiants = 0; + di->hnddma.rxnobuf = 0; + di->hnddma.txnobuf = 0; +} + +/* get the address of the var in order to change later */ +static uintptr +_dma_getvar(dma_info_t *di, char *name) +{ + if (!strcmp(name, "&txavail")) + return ((uintptr) &(di->hnddma.txavail)); + else { + ASSERT(0); + } + return (0); +} + +void +dma_txpioloopback(osl_t *osh, dma32regs_t *regs) +{ + OR_REG(osh, ®s->control, XC_LE); +} + + + +/* 32 bits DMA functions */ +static void +dma32_txinit(dma_info_t *di) +{ + DMA_TRACE(("%s: dma_txinit\n", di->name)); + + if (di->ntxd == 0) + return; + + di->txin = di->txout = 0; + di->hnddma.txavail = di->ntxd - 1; + + /* clear tx descriptor ring */ + BZERO_SM((void *)di->txd32, (di->ntxd * sizeof(dma32dd_t))); + W_REG(di->osh, &di->d32txregs->control, XC_XE); + _dma_ddtable_init(di, DMA_TX, di->txdpa); +} + +static bool +dma32_txenabled(dma_info_t *di) +{ + uint32 xc; + + /* If the chip is dead, it is not enabled :-) */ + xc = R_REG(di->osh, &di->d32txregs->control); + return ((xc != 0xffffffff) && (xc & XC_XE)); +} + +static void +dma32_txsuspend(dma_info_t *di) +{ + DMA_TRACE(("%s: dma_txsuspend\n", di->name)); + + if (di->ntxd == 0) + return; + + OR_REG(di->osh, &di->d32txregs->control, XC_SE); +} + +static void +dma32_txresume(dma_info_t *di) +{ + DMA_TRACE(("%s: dma_txresume\n", di->name)); + + if (di->ntxd == 0) + return; + + AND_REG(di->osh, &di->d32txregs->control, ~XC_SE); +} + +static bool +dma32_txsuspended(dma_info_t *di) +{ + return (di->ntxd == 0) || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE); +} + +static void +dma32_txreclaim(dma_info_t *di, bool forceall) +{ + void *p; + + DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); + + while ((p = dma32_getnexttxp(di, forceall))) + PKTFREE(di->osh, p, TRUE); +} + +static bool +dma32_txstopped(dma_info_t *di) +{ + return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); +} + +static bool +dma32_rxstopped(dma_info_t *di) +{ + return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); +} + +static bool +dma32_alloc(dma_info_t *di, uint direction) +{ + uint size; + uint ddlen; + void *va; + + ddlen = sizeof(dma32dd_t); + + size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); + + if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) + size += D32RINGALIGN; + + + if (direction == DMA_TX) { + if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa, &di->tx_dmah)) == NULL) { + DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", + di->name)); + return FALSE; + } + + di->txd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); + di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); + di->txdpa += di->txdalign; + di->txdalloc = size; + ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); + } else { + if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa, &di->rx_dmah)) == NULL) { + DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", + di->name)); + return FALSE; + } + di->rxd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); + di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); + di->rxdpa += di->rxdalign; + di->rxdalloc = size; + ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); + } + + return TRUE; +} + +static bool +dma32_txreset(dma_info_t *di) +{ + uint32 status; + + if (di->ntxd == 0) + return TRUE; + + /* suspend tx DMA first */ + W_REG(di->osh, &di->d32txregs->control, XC_SE); + SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK)) + != XS_XS_DISABLED) && + (status != XS_XS_IDLE) && + (status != XS_XS_STOPPED), + (10000)); + + W_REG(di->osh, &di->d32txregs->control, 0); + SPINWAIT(((status = (R_REG(di->osh, + &di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED), + 10000); + + /* wait for the last transaction to complete */ + OSL_DELAY(300); + + return (status == XS_XS_DISABLED); +} + +static bool +dma32_rxidle(dma_info_t *di) +{ + DMA_TRACE(("%s: dma_rxidle\n", di->name)); + + if (di->nrxd == 0) + return TRUE; + + return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) == + R_REG(di->osh, &di->d32rxregs->ptr)); +} + +static bool +dma32_rxreset(dma_info_t *di) +{ + uint32 status; + + if (di->nrxd == 0) + return TRUE; + + W_REG(di->osh, &di->d32rxregs->control, 0); + SPINWAIT(((status = (R_REG(di->osh, + &di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED), + 10000); + + return (status == RS_RS_DISABLED); +} + +static bool +dma32_rxenabled(dma_info_t *di) +{ + uint32 rc; + + rc = R_REG(di->osh, &di->d32rxregs->control); + return ((rc != 0xffffffff) && (rc & RC_RE)); +} + +static bool +dma32_txsuspendedidle(dma_info_t *di) +{ + if (di->ntxd == 0) + return TRUE; + + if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE)) + return 0; + + if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) + return 0; + + OSL_DELAY(2); + return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); +} + +/* !! tx entry routine + * supports full 32bit dma engine buffer addressing so + * dma buffers can cross 4 Kbyte page boundaries. + */ +static int +dma32_txfast(dma_info_t *di, void *p0, bool commit) +{ + void *p, *next; + uchar *data; + uint len; + uint txout; + uint32 flags = 0; + uint32 pa; + + DMA_TRACE(("%s: dma_txfast\n", di->name)); + + txout = di->txout; + + /* + * Walk the chain of packet buffers + * allocating and initializing transmit descriptor entries. + */ + for (p = p0; p; p = next) { + data = PKTDATA(di->osh, p); + len = PKTLEN(di->osh, p); + next = PKTNEXT(di->osh, p); + + /* return nonzero if out of tx descriptors */ + if (NEXTTXD(txout) == di->txin) + goto outoftxd; + + if (len == 0) + continue; + + /* get physical address of buffer start */ + pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); + + flags = 0; + if (p == p0) + flags |= CTRL_SOF; + if (next == NULL) + flags |= (CTRL_IOC | CTRL_EOF); + if (txout == (di->ntxd - 1)) + flags |= CTRL_EOT; + + dma32_dd_upd(di, di->txd32, pa, txout, &flags, len); + ASSERT(di->txp[txout] == NULL); + + txout = NEXTTXD(txout); + } + + /* if last txd eof not set, fix it */ + if (!(flags & CTRL_EOF)) + W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF)); + + /* save the packet */ + di->txp[PREVTXD(txout)] = p0; + + /* bump the tx descriptor index */ + di->txout = txout; + + /* kick the chip */ + if (commit) + W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t)); + + /* tx flow control */ + di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + + return (0); + +outoftxd: + DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); + PKTFREE(di->osh, p0, TRUE); + di->hnddma.txavail = 0; + di->hnddma.txnobuf++; + return (-1); +} + +/* + * Reclaim next completed txd (txds if using chained buffers) and + * return associated packet. + * If 'force' is true, reclaim txd(s) and return associated packet + * regardless of the value of the hardware "curr" pointer. + */ +static void * +dma32_getnexttxp(dma_info_t *di, bool forceall) +{ + uint start, end, i; + void *txp; + + DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); + + if (di->ntxd == 0) + return (NULL); + + txp = NULL; + + start = di->txin; + if (forceall) + end = di->txout; + else + end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); + + if ((start == 0) && (end > di->txout)) + goto bogus; + + for (i = start; i != end && !txp; i = NEXTTXD(i)) { + DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), + (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), + DMA_TX, di->txp[i]); + + W_SM(&di->txd32[i].addr, 0xdeadbeef); + txp = di->txp[i]; + di->txp[i] = NULL; + } + + di->txin = i; + + /* tx flow control */ + di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + + return (txp); + +bogus: +/* + DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", + start, end, di->txout, forceall)); +*/ + return (NULL); +} + +static void * +dma32_getnextrxp(dma_info_t *di, bool forceall) +{ + uint i; + void *rxp; + + /* if forcing, dma engine must be disabled */ + ASSERT(!forceall || !dma32_rxenabled(di)); + + i = di->rxin; + + /* return if no packets posted */ + if (i == di->rxout) + return (NULL); + + /* ignore curr if forceall */ + if (!forceall && (i == B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) + return (NULL); + + /* get the packet pointer that corresponds to the rx descriptor */ + rxp = di->rxp[i]; + ASSERT(rxp); + di->rxp[i] = NULL; + + /* clear this packet from the descriptor ring */ + DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), + di->rxbufsize, DMA_RX, rxp); + + W_SM(&di->rxd32[i].addr, 0xdeadbeef); + + di->rxin = NEXTRXD(i); + + return (rxp); +} + +/* + * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). + */ +static void +dma32_txrotate(dma_info_t *di) +{ + uint ad; + uint nactive; + uint rot; + uint old, new; + uint32 w; + uint first, last; + + ASSERT(dma32_txsuspendedidle(di)); + + nactive = _dma_txactive(di); + ad = B2I(((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); + rot = TXD(ad - di->txin); + + ASSERT(rot < di->ntxd); + + /* full-ring case is a lot harder - don't worry about this */ + if (rot >= (di->ntxd - nactive)) { + DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); + return; + } + + first = di->txin; + last = PREVTXD(di->txout); + + /* move entries starting at last and moving backwards to first */ + for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { + new = TXD(old + rot); + + /* + * Move the tx dma descriptor. + * EOT is set only in the last entry in the ring. + */ + w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT; + if (new == (di->ntxd - 1)) + w |= CTRL_EOT; + W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w)); + W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); + + /* zap the old tx dma descriptor address field */ + W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef)); + + /* move the corresponding txp[] entry */ + ASSERT(di->txp[new] == NULL); + di->txp[new] = di->txp[old]; + di->txp[old] = NULL; + } + + /* update txin and txout */ + di->txin = ad; + di->txout = TXD(di->txout + rot); + di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + + /* kick the chip */ + W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); +} + + +uint +dma_addrwidth(sb_t *sbh, void *dmaregs) +{ + dma32regs_t *dma32regs; + osl_t *osh; + + osh = sb_osh(sbh); + + /* Start checking for 32-bit / 30-bit addressing */ + dma32regs = (dma32regs_t *)dmaregs; + + /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */ + if ((BUSTYPE(sbh->bustype) == SB_BUS) || + ((BUSTYPE(sbh->bustype) == PCI_BUS) && sbh->buscoretype == SB_PCIE) || + (_dma32_addrext(osh, dma32regs))) + return (DMADDRWIDTH_32); + + /* Fallthru */ + return (DMADDRWIDTH_30); +} diff --git a/package/broadcom-wl/src/kmod/hnddma.h b/package/broadcom-wl/src/kmod/hnddma.h new file mode 100644 index 0000000000..de74c067b2 --- /dev/null +++ b/package/broadcom-wl/src/kmod/hnddma.h @@ -0,0 +1,156 @@ +/* + * Generic Broadcom Home Networking Division (HND) DMA engine SW interface + * This supports the following chips: BCM42xx, 44xx, 47xx . + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * $Id: hnddma.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $ + */ + +#ifndef _hnddma_h_ +#define _hnddma_h_ + +typedef const struct hnddma_pub hnddma_t; + +/* dma function type */ +typedef void (*di_detach_t)(hnddma_t *dmah); +typedef bool (*di_txreset_t)(hnddma_t *dmah); +typedef bool (*di_rxreset_t)(hnddma_t *dmah); +typedef bool (*di_rxidle_t)(hnddma_t *dmah); +typedef void (*di_txinit_t)(hnddma_t *dmah); +typedef bool (*di_txenabled_t)(hnddma_t *dmah); +typedef void (*di_rxinit_t)(hnddma_t *dmah); +typedef void (*di_txsuspend_t)(hnddma_t *dmah); +typedef void (*di_txresume_t)(hnddma_t *dmah); +typedef bool (*di_txsuspended_t)(hnddma_t *dmah); +typedef bool (*di_txsuspendedidle_t)(hnddma_t *dmah); +typedef int (*di_txfast_t)(hnddma_t *dmah, void *p, bool commit); +typedef void (*di_fifoloopbackenable_t)(hnddma_t *dmah); +typedef bool (*di_txstopped_t)(hnddma_t *dmah); +typedef bool (*di_rxstopped_t)(hnddma_t *dmah); +typedef bool (*di_rxenable_t)(hnddma_t *dmah); +typedef bool (*di_rxenabled_t)(hnddma_t *dmah); +typedef void* (*di_rx_t)(hnddma_t *dmah); +typedef void (*di_rxfill_t)(hnddma_t *dmah); +typedef void (*di_txreclaim_t)(hnddma_t *dmah, bool forceall); +typedef void (*di_rxreclaim_t)(hnddma_t *dmah); +typedef uintptr (*di_getvar_t)(hnddma_t *dmah, char *name); +typedef void* (*di_getnexttxp_t)(hnddma_t *dmah, bool forceall); +typedef void* (*di_getnextrxp_t)(hnddma_t *dmah, bool forceall); +typedef void* (*di_peeknexttxp_t)(hnddma_t *dmah); +typedef void (*di_txblock_t)(hnddma_t *dmah); +typedef void (*di_txunblock_t)(hnddma_t *dmah); +typedef uint (*di_txactive_t)(hnddma_t *dmah); +typedef void (*di_txrotate_t)(hnddma_t *dmah); +typedef void (*di_counterreset_t)(hnddma_t *dmah); +typedef char* (*di_dump_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); +typedef char* (*di_dumptx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); +typedef char* (*di_dumprx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); + +/* dma opsvec */ +typedef struct di_fcn_s { + di_detach_t detach; + di_txinit_t txinit; + di_txreset_t txreset; + di_txenabled_t txenabled; + di_txsuspend_t txsuspend; + di_txresume_t txresume; + di_txsuspended_t txsuspended; + di_txsuspendedidle_t txsuspendedidle; + di_txfast_t txfast; + di_txstopped_t txstopped; + di_txreclaim_t txreclaim; + di_getnexttxp_t getnexttxp; + di_peeknexttxp_t peeknexttxp; + di_txblock_t txblock; + di_txunblock_t txunblock; + di_txactive_t txactive; + di_txrotate_t txrotate; + + di_rxinit_t rxinit; + di_rxreset_t rxreset; + di_rxidle_t rxidle; + di_rxstopped_t rxstopped; + di_rxenable_t rxenable; + di_rxenabled_t rxenabled; + di_rx_t rx; + di_rxfill_t rxfill; + di_rxreclaim_t rxreclaim; + di_getnextrxp_t getnextrxp; + + di_fifoloopbackenable_t fifoloopbackenable; + di_getvar_t d_getvar; + di_counterreset_t counterreset; + di_dump_t dump; + di_dumptx_t dumptx; + di_dumprx_t dumprx; + uint endnum; +} di_fcn_t; + +/* + * Exported data structure (read-only) + */ +/* export structure */ +struct hnddma_pub { + di_fcn_t di_fn; /* DMA function pointers */ + uint txavail; /* # free tx descriptors */ + + /* rx error counters */ + uint rxgiants; /* rx giant frames */ + uint rxnobuf; /* rx out of dma descriptors */ + /* tx error counters */ + uint txnobuf; /* tx out of dma descriptors */ +}; + + +extern hnddma_t * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, + uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, + uint *msg_level); +#define dma_detach(di) ((di)->di_fn.detach(di)) +#define dma_txreset(di) ((di)->di_fn.txreset(di)) +#define dma_rxreset(di) ((di)->di_fn.rxreset(di)) +#define dma_rxidle(di) ((di)->di_fn.rxidle(di)) +#define dma_txinit(di) ((di)->di_fn.txinit(di)) +#define dma_txenabled(di) ((di)->di_fn.txenabled(di)) +#define dma_rxinit(di) ((di)->di_fn.rxinit(di)) +#define dma_txsuspend(di) ((di)->di_fn.txsuspend(di)) +#define dma_txresume(di) ((di)->di_fn.txresume(di)) +#define dma_txsuspended(di) ((di)->di_fn.txsuspended(di)) +#define dma_txsuspendedidle(di) ((di)->di_fn.txsuspendedidle(di)) +#define dma_txfast(di, p, commit) ((di)->di_fn.txfast(di, p, commit)) +#define dma_fifoloopbackenable(di) ((di)->di_fn.fifoloopbackenable(di)) +#define dma_txstopped(di) ((di)->di_fn.txstopped(di)) +#define dma_rxstopped(di) ((di)->di_fn.rxstopped(di)) +#define dma_rxenable(di) ((di)->di_fn.rxenable(di)) +#define dma_rxenabled(di) ((di)->di_fn.rxenabled(di)) +#define dma_rx(di) ((di)->di_fn.rx(di)) +#define dma_rxfill(di) ((di)->di_fn.rxfill(di)) +#define dma_txreclaim(di, forceall) ((di)->di_fn.txreclaim(di, forceall)) +#define dma_rxreclaim(di) ((di)->di_fn.rxreclaim(di)) +#define dma_getvar(di, name) ((di)->di_fn.d_getvar(di, name)) +#define dma_getnexttxp(di, forceall) ((di)->di_fn.getnexttxp(di, forceall)) +#define dma_getnextrxp(di, forceall) ((di)->di_fn.getnextrxp(di, forceall)) +#define dma_peeknexttxp(di) ((di)->di_fn.peeknexttxp(di)) +#define dma_txblock(di) ((di)->di_fn.txblock(di)) +#define dma_txunblock(di) ((di)->di_fn.txunblock(di)) +#define dma_txactive(di) ((di)->di_fn.txactive(di)) +#define dma_txrotate(di) ((di)->di_fn.txrotate(di)) +#define dma_counterreset(di) ((di)->di_fn.counterreset(di)) + +#define DMA_DUMP_SIZE 2048 +/* return addresswidth allowed + * This needs to be done after SB attach but before dma attach. + * SB attach provides ability to probe backplane and dma core capabilities + * This info is needed by DMA_ALLOC_CONSISTENT in dma attach + */ +extern uint dma_addrwidth(sb_t *sbh, void *dmaregs); + +/* pio helpers */ +void dma_txpioloopback(osl_t *osh, dma32regs_t *); + +#endif /* _hnddma_h_ */ diff --git a/package/broadcom-wl/src/kmod/linux_osl.c b/package/broadcom-wl/src/kmod/linux_osl.c new file mode 100644 index 0000000000..d702961032 --- /dev/null +++ b/package/broadcom-wl/src/kmod/linux_osl.c @@ -0,0 +1,269 @@ +/* + * Linux OS Independent Layer + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: linux_osl.c,v 1.1.1.14 2006/04/08 06:13:39 honor Exp $ + */ + +#define LINUX_OSL + +#include +#include +#include +#include +#include +#include +#include "linux_osl.h" +#include +#include +#ifdef mips +#include +#endif /* mips */ +#include + +#define PCI_CFG_RETRY 10 + +#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */ +#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ + +typedef struct bcm_mem_link { + struct bcm_mem_link *prev; + struct bcm_mem_link *next; + uint size; + int line; + char file[BCM_MEM_FILENAME_LEN]; +} bcm_mem_link_t; + +static int16 linuxbcmerrormap[] = \ +{ 0, /* 0 */ + -EINVAL, /* BCME_ERROR */ + -EINVAL, /* BCME_BADARG */ + -EINVAL, /* BCME_BADOPTION */ + -EINVAL, /* BCME_NOTUP */ + -EINVAL, /* BCME_NOTDOWN */ + -EINVAL, /* BCME_NOTAP */ + -EINVAL, /* BCME_NOTSTA */ + -EINVAL, /* BCME_BADKEYIDX */ + -EINVAL, /* BCME_RADIOOFF */ + -EINVAL, /* BCME_NOTBANDLOCKED */ + -EINVAL, /* BCME_NOCLK */ + -EINVAL, /* BCME_BADRATESET */ + -EINVAL, /* BCME_BADBAND */ + -E2BIG, /* BCME_BUFTOOSHORT */ + -E2BIG, /* BCME_BUFTOOLONG */ + -EBUSY, /* BCME_BUSY */ + -EINVAL, /* BCME_NOTASSOCIATED */ + -EINVAL, /* BCME_BADSSIDLEN */ + -EINVAL, /* BCME_OUTOFRANGECHAN */ + -EINVAL, /* BCME_BADCHAN */ + -EFAULT, /* BCME_BADADDR */ + -ENOMEM, /* BCME_NORESOURCE */ + -EOPNOTSUPP, /* BCME_UNSUPPORTED */ + -EMSGSIZE, /* BCME_BADLENGTH */ + -EINVAL, /* BCME_NOTREADY */ + -EPERM, /* BCME_NOTPERMITTED */ + -ENOMEM, /* BCME_NOMEM */ + -EINVAL, /* BCME_ASSOCIATED */ + -ERANGE, /* BCME_RANGE */ + -EINVAL, /* BCME_NOTFOUND */ + -EINVAL, /* BCME_WME_NOT_ENABLED */ + -EINVAL, /* BCME_TSPEC_NOTFOUND */ + -EINVAL, /* BCME_ACM_NOTSUPPORTED */ + -EINVAL, /* BCME_NOT_WME_ASSOCIATION */ + -EIO, /* BCME_SDIO_ERROR */ + -ENODEV /* BCME_DONGLE_DOWN */ +}; + +/* translate bcmerrors into linux errors */ +int +osl_error(int bcmerror) +{ + int abs_bcmerror; + int array_size = ARRAYSIZE(linuxbcmerrormap); + + abs_bcmerror = ABS(bcmerror); + + if (bcmerror > 0) + abs_bcmerror = 0; + + else if (abs_bcmerror >= array_size) + abs_bcmerror = BCME_ERROR; + + return linuxbcmerrormap[abs_bcmerror]; +} + +osl_t * +osl_attach(void *pdev, bool pkttag) +{ + osl_t *osh; + + osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); + ASSERT(osh); + + bzero(osh, sizeof(osl_t)); + + /* + * check the cases where + * 1.Error code Added to bcmerror table, but forgot to add it to the OS + * dependent error code + * 2. Error code is added to the bcmerror table, but forgot to add the + * corresponding errorstring(dummy call to bcmerrorstr) + */ + bcmerrorstr(0); + ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); + + osh->magic = OS_HANDLE_MAGIC; + osh->malloced = 0; + osh->failed = 0; + osh->dbgmem_list = NULL; + osh->pdev = pdev; + osh->pub.pkttag = pkttag; + + return osh; +} + +void +osl_detach(osl_t *osh) +{ + if (osh == NULL) + return; + + ASSERT(osh->magic == OS_HANDLE_MAGIC); + kfree(osh); +} + +/* Return a new packet. zero out pkttag */ +void* +osl_pktget(osl_t *osh, uint len, bool send) +{ + struct sk_buff *skb; + + if ((skb = dev_alloc_skb(len))) { + skb_put(skb, len); + skb->priority = 0; + +#ifdef BCMDBG_PKT + pktlist_add(&(osh->pktlist), (void *) skb); +#endif /* BCMDBG_PKT */ + + osh->pub.pktalloced++; + } + + return ((void*) skb); +} + +/* Free the driver packet. Free the tag if present */ +void +osl_pktfree(osl_t *osh, void *p) +{ + struct sk_buff *skb, *nskb; + + skb = (struct sk_buff*) p; + + /* perversion: we use skb->next to chain multi-skb packets */ + while (skb) { + nskb = skb->next; + skb->next = NULL; + +#ifdef BCMDBG_PKT + pktlist_remove(&(osh->pktlist), (void *) skb); +#endif /* BCMDBG_PKT */ + + if (skb->destructor) { + /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists + */ + dev_kfree_skb_any(skb); + } else { + /* can free immediately (even in_irq()) if destructor does not exist */ + dev_kfree_skb(skb); + } + + osh->pub.pktalloced--; + + skb = nskb; + } +} + +void* +osl_malloc(osl_t *osh, uint size) +{ + void *addr; + + /* only ASSERT if osh is defined */ + if (osh) + ASSERT(osh->magic == OS_HANDLE_MAGIC); + + if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { + if (osh) + osh->failed++; + return (NULL); + } + if (osh) + osh->malloced += size; + + return (addr); +} + +void +osl_mfree(osl_t *osh, void *addr, uint size) +{ + if (osh) { + ASSERT(osh->magic == OS_HANDLE_MAGIC); + osh->malloced -= size; + } + kfree(addr); +} + +uint +osl_malloced(osl_t *osh) +{ + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); + return (osh->malloced); +} + +uint osl_malloc_failed(osl_t *osh) +{ + ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); + return (osh->failed); +} + +#undef osl_delay +void +osl_delay(uint usec) +{ + OSL_DELAY(usec); +} + +/* Clone a packet. + * The pkttag contents are NOT cloned. + */ +void * +osl_pktdup(osl_t *osh, void *skb) +{ + void * p; + + if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL) + return NULL; + + /* skb_clone copies skb->cb.. we don't want that */ + if (osh->pub.pkttag) + bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); + + /* Increment the packet counter */ + osh->pub.pktalloced++; + return (p); +} + +uint +osl_pktalloced(osl_t *osh) +{ + return (osh->pub.pktalloced); +} + diff --git a/package/broadcom-wl/src/kmod/linux_osl.h b/package/broadcom-wl/src/kmod/linux_osl.h new file mode 100644 index 0000000000..f6af6124c6 --- /dev/null +++ b/package/broadcom-wl/src/kmod/linux_osl.h @@ -0,0 +1,171 @@ +/* + * Linux OS Independent Layer + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: linux_osl.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $ + */ + +#ifndef _linux_osl_h_ +#define _linux_osl_h_ + +#include +#include +#include + +#define OSL_PKTTAG_SZ 32 /* Size of PktTag */ + +/* osl handle type forward declaration */ +typedef struct osl_dmainfo osldma_t; + +/* OSL initialization */ +extern osl_t *osl_attach(void *pdev, bool pkttag); +extern void osl_detach(osl_t *osh); + +/* host/bus architecture-specific byte swap */ +#define BUS_SWAP32(v) (v) +#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) + +extern void *osl_malloc(osl_t *osh, uint size); +extern void osl_mfree(osl_t *osh, void *addr, uint size); +extern uint osl_malloced(osl_t *osh); +extern uint osl_malloc_failed(osl_t *osh); + +/* API for DMA addressing capability */ +#define DMA_MAP(osh, va, size, direction, p) \ + osl_dma_map((osh), (va), (size), (direction)) +#define DMA_UNMAP(osh, pa, size, direction, p) \ + osl_dma_unmap((osh), (pa), (size), (direction)) +static inline uint +osl_dma_map(void *osh, void *va, uint size, int direction) +{ + int dir; + struct pci_dev *dev; + + dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev); + dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; + return (pci_map_single(dev, va, size, dir)); +} + +static inline void +osl_dma_unmap(void *osh, uint pa, uint size, int direction) +{ + int dir; + struct pci_dev *dev; + + dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev); + dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; + pci_unmap_single(dev, (uint32)pa, size, dir); +} + +#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) +#define DMA_CONSISTENT_ALIGN PAGE_SIZE +#define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah) \ + osl_dma_alloc_consistent((osh), (size), (pap)) +#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ + osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) +static inline void* +osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) +{ + return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); +} + +static inline void +osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) +{ + pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); +} + + +/* register access macros */ +#if defined(BCMJTAG) +#include +#define R_REG(osh, r) bcmjtag_read(NULL, (uint32)(r), sizeof(*(r))) +#define W_REG(osh, r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof(*(r))) +#endif /* defined(BCMSDIO) */ + +/* packet primitives */ +#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) +#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb)) +#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) +#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) +#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) +#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) +#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) +#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) +#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) +#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) +#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) +#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) +#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) +#define PKTALLOCED(osh) osl_pktalloced((osh)) +#define PKTLIST_DUMP(osh, buf) + +/* Convert a native(OS) packet to driver packet. + * In the process, native packet is destroyed, there is no copying + * Also, a packettag is zeroed out + */ +static INLINE void * +osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb) +{ + struct sk_buff *nskb; + + if (osh->pkttag) + bzero((void*)skb->cb, OSL_PKTTAG_SZ); + + /* Increment the packet counter */ + for (nskb = skb; nskb; nskb = nskb->next) { + osh->pktalloced++; + } + + return (void *)skb; +} +#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((struct osl_pubinfo *)osh), \ + (struct sk_buff*)(skb)) + +/* Convert a driver packet to native(OS) packet + * In the process, packettag is zeroed out before sending up + * IP code depends on skb->cb to be setup correctly with various options + * In our case, that means it should be 0 + */ +static INLINE struct sk_buff * +osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) +{ + struct sk_buff *nskb; + + if (osh->pkttag) + bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); + + /* Decrement the packet counter */ + for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { + osh->pktalloced--; + } + + return (struct sk_buff *)pkt; +} +#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt)) + +#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) +#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) +#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) +#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) +#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) + +extern void *osl_pktget(osl_t *osh, uint len, bool send); +extern void osl_pktfree(osl_t *osh, void *skb); +extern void *osl_pktdup(osl_t *osh, void *skb); +extern uint osl_pktalloced(osl_t *osh); + +#define OSL_ERROR(bcmerror) osl_error(bcmerror) +extern int osl_error(int bcmerror); + +/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ +#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ + +#endif /* _linux_osl_h_ */ diff --git a/package/broadcom-wl/src/kmod/patchtable.pl b/package/broadcom-wl/src/kmod/patchtable.pl new file mode 100644 index 0000000000..6144d8b925 --- /dev/null +++ b/package/broadcom-wl/src/kmod/patchtable.pl @@ -0,0 +1,54 @@ +#!/usr/bin/perl +use strict; + +my $TABLE = pack("V", 0xbadc0ded); +my $TABLE_SIZE = 512; +my $SLT1 = "\x01\x00\x00\x00"; +my $SLT2 = "\x02\x00\x00\x00"; +my $ACKW = "\x03\x00\x00\x00"; +my $PTABLE_END = "\xff\xff\xff\xff"; + +my $addr = ""; +my $opcode = ""; +my $function = ""; + +sub add_entry { + my $key = shift; + my $value = shift; + my $default = shift; + + $TABLE .= $key; + $TABLE .= pack("V", $value); + $TABLE .= pack("V", $default); +} + +while (<>) { + $addr = $opcode = ""; + /^\w{8}\s*<(.*)>:$/ and $function = $1; + /^\s*(\w+):\s*(\w{8})\s*/ and do { + $addr = $1; + $opcode = $2; + }; + + ($function eq 'wlc_update_slot_timing') and do { + # li a2,9 -- short slot time + ($opcode eq '24060009') and add_entry($SLT1, hex($addr), hex($opcode)); + # li v0,519 -- 510 + short slot time + ($opcode eq '24020207') and add_entry($SLT2, hex($addr), hex($opcode)); + + # li a2,20 -- long slot time + ($opcode eq '24060014') and add_entry($SLT1, hex($addr), hex($opcode)); + # li v0,530 -- 510 + long slot time + ($opcode eq '24020212') and add_entry($SLT2, hex($addr), hex($opcode)); + }; + ($function eq 'wlc_d11hdrs') and do { + # ori s6,s6,0x1 -- ack flag (new) + ($opcode eq '36d60001') and add_entry($ACKW, hex($addr), hex($opcode)); + # ori s3,s3,0x1 -- ack flag (old) + ($opcode eq '36730001') and add_entry($ACKW, hex($addr), hex($opcode)); + } +} + +$TABLE .= $PTABLE_END; +$TABLE .= ("\x00" x ($TABLE_SIZE - length($TABLE))); +print $TABLE; diff --git a/package/broadcom-wl/src/kmod/pktq.h b/package/broadcom-wl/src/kmod/pktq.h new file mode 100644 index 0000000000..7fe21815e8 --- /dev/null +++ b/package/broadcom-wl/src/kmod/pktq.h @@ -0,0 +1,97 @@ +/* + * Misc useful os-independent macros and functions. + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $ + */ + +#ifndef _pktq_h_ +#define _pktq_h_ +#include + +/* osl multi-precedence packet queue */ + +#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ +#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ + +struct pktq { + struct pktq_prec { + void *head; /* first packet to dequeue */ + void *tail; /* last packet to dequeue */ + uint16 len; /* number of queued packets */ + uint16 max; /* maximum number of queued packets */ + } q[PKTQ_MAX_PREC]; + uint16 num_prec; /* number of precedences in use */ + uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ + uint16 max; /* total max packets */ + uint16 len; /* total number of packets */ +}; + +#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) + +/* forward definition of ether_addr structure used by some function prototypes */ + +struct ether_addr; + +/* operations on a specific precedence in packet queue */ + +#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) +#define pktq_plen(pq, prec) ((pq)->q[prec].len) +#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) +#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) +#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) + +#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) +#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) + +extern void *pktq_penq(struct pktq *pq, int prec, void *p); +extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); +extern void *pktq_pdeq(struct pktq *pq, int prec); +extern void *pktq_pdeq_tail(struct pktq *pq, int prec); +/* Empty the queue at particular precedence level */ +extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir); +/* Remove a specified packet from its queue */ +extern bool pktq_pdel(struct pktq *pq, void *p, int prec); + +/* operations on a set of precedences in packet queue */ + +extern int pktq_mlen(struct pktq *pq, uint prec_bmp); +extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); + +/* operations on packet queue as a whole */ + +#define pktq_len(pq) ((int)(pq)->len) +#define pktq_max(pq) ((int)(pq)->max) +#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) +#define pktq_full(pq) ((pq)->len >= (pq)->max) +#define pktq_empty(pq) ((pq)->len == 0) + +/* operations for single precedence queues */ +#define pktenq(pq, p) pktq_penq((pq), 0, (p)) +#define pktenq_head(pq, p) pktq_penq_head((pq), 0, (p)) +#define pktdeq(pq) pktq_pdeq((pq), 0) +#define pktdeq_tail(pq) pktq_pdeq_tail((pq), 0) + +extern void pktq_init(struct pktq *pq, int num_prec, int max_len); +/* prec_out may be NULL if caller is not interested in return value */ +extern void *pktq_deq(struct pktq *pq, int *prec_out); +extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); +extern void *pktq_peek(struct pktq *pq, int *prec_out); +extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); +extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); /* Empty the entire queue */ + +/* externs */ +/* packet */ +extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); +extern uint pkttotlen(osl_t *osh, void *p); +extern void *pktlast(osl_t *osh, void *p); + +extern void pktsetprio(void *pkt, bool update_vtag); + +#endif /* _pktq_h_ */ diff --git a/package/broadcom-wl/src/kmod/sbhnddma.h b/package/broadcom-wl/src/kmod/sbhnddma.h new file mode 100644 index 0000000000..a26db7395e --- /dev/null +++ b/package/broadcom-wl/src/kmod/sbhnddma.h @@ -0,0 +1,284 @@ +/* + * Generic Broadcom Home Networking Division (HND) DMA engine HW interface + * This supports the following chips: BCM42xx, 44xx, 47xx . + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: sbhnddma.h,v 1.1.1.2 2006/02/27 03:43:16 honor Exp $ + */ + +#ifndef _sbhnddma_h_ +#define _sbhnddma_h_ + +/* DMA structure: + * support two DMA engines: 32 bits address or 64 bit addressing + * basic DMA register set is per channel(transmit or receive) + * a pair of channels is defined for convenience + */ + + +/* 32 bits addressing */ + +/* dma registers per channel(xmt or rcv) */ +typedef volatile struct { + uint32 control; /* enable, et al */ + uint32 addr; /* descriptor ring base address (4K aligned) */ + uint32 ptr; /* last descriptor posted to chip */ + uint32 status; /* current active descriptor, et al */ +} dma32regs_t; + +typedef volatile struct { + dma32regs_t xmt; /* dma tx channel */ + dma32regs_t rcv; /* dma rx channel */ +} dma32regp_t; + +typedef volatile struct { /* diag access */ + uint32 fifoaddr; /* diag address */ + uint32 fifodatalow; /* low 32bits of data */ + uint32 fifodatahigh; /* high 32bits of data */ + uint32 pad; /* reserved */ +} dma32diag_t; + +/* + * DMA Descriptor + * Descriptors are only read by the hardware, never written back. + */ +typedef volatile struct { + uint32 ctrl; /* misc control bits & bufcount */ + uint32 addr; /* data buffer address */ +} dma32dd_t; + +/* + * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. + */ +#define D32MAXRINGSZ 4096 +#define D32RINGALIGN 4096 +#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) + +/* transmit channel control */ +#define XC_XE ((uint32)1 << 0) /* transmit enable */ +#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ +#define XC_LE ((uint32)1 << 2) /* loopback enable */ +#define XC_FL ((uint32)1 << 4) /* flush request */ +#define XC_AE ((uint32)3 << 16) /* address extension bits */ +#define XC_AE_SHIFT 16 + +/* transmit descriptor table pointer */ +#define XP_LD_MASK 0xfff /* last valid descriptor */ + +/* transmit channel status */ +#define XS_CD_MASK 0x0fff /* current descriptor pointer */ +#define XS_XS_MASK 0xf000 /* transmit state */ +#define XS_XS_SHIFT 12 +#define XS_XS_DISABLED 0x0000 /* disabled */ +#define XS_XS_ACTIVE 0x1000 /* active */ +#define XS_XS_IDLE 0x2000 /* idle wait */ +#define XS_XS_STOPPED 0x3000 /* stopped */ +#define XS_XS_SUSP 0x4000 /* suspend pending */ +#define XS_XE_MASK 0xf0000 /* transmit errors */ +#define XS_XE_SHIFT 16 +#define XS_XE_NOERR 0x00000 /* no error */ +#define XS_XE_DPE 0x10000 /* descriptor protocol error */ +#define XS_XE_DFU 0x20000 /* data fifo underrun */ +#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ +#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ +#define XS_AD_MASK 0xfff00000 /* active descriptor */ +#define XS_AD_SHIFT 20 + +/* receive channel control */ +#define RC_RE ((uint32)1 << 0) /* receive enable */ +#define RC_RO_MASK 0xfe /* receive frame offset */ +#define RC_RO_SHIFT 1 +#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ +#define RC_AE ((uint32)3 << 16) /* address extension bits */ +#define RC_AE_SHIFT 16 + +/* receive descriptor table pointer */ +#define RP_LD_MASK 0xfff /* last valid descriptor */ + +/* receive channel status */ +#define RS_CD_MASK 0x0fff /* current descriptor pointer */ +#define RS_RS_MASK 0xf000 /* receive state */ +#define RS_RS_SHIFT 12 +#define RS_RS_DISABLED 0x0000 /* disabled */ +#define RS_RS_ACTIVE 0x1000 /* active */ +#define RS_RS_IDLE 0x2000 /* idle wait */ +#define RS_RS_STOPPED 0x3000 /* reserved */ +#define RS_RE_MASK 0xf0000 /* receive errors */ +#define RS_RE_SHIFT 16 +#define RS_RE_NOERR 0x00000 /* no error */ +#define RS_RE_DPE 0x10000 /* descriptor protocol error */ +#define RS_RE_DFO 0x20000 /* data fifo overflow */ +#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ +#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ +#define RS_AD_MASK 0xfff00000 /* active descriptor */ +#define RS_AD_SHIFT 20 + +/* fifoaddr */ +#define FA_OFF_MASK 0xffff /* offset */ +#define FA_SEL_MASK 0xf0000 /* select */ +#define FA_SEL_SHIFT 16 +#define FA_SEL_XDD 0x00000 /* transmit dma data */ +#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ +#define FA_SEL_RDD 0x40000 /* receive dma data */ +#define FA_SEL_RDP 0x50000 /* receive dma pointers */ +#define FA_SEL_XFD 0x80000 /* transmit fifo data */ +#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ +#define FA_SEL_RFD 0xc0000 /* receive fifo data */ +#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ +#define FA_SEL_RSD 0xe0000 /* receive frame status data */ +#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ + +/* descriptor control flags */ +#define CTRL_BC_MASK 0x1fff /* buffer byte count */ +#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ +#define CTRL_AE_SHIFT 16 +#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ +#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ +#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ +#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ + +/* control flags in the range [27:20] are core-specific and not defined here */ +#define CTRL_CORE_MASK 0x0ff00000 + +/* 64 bits addressing */ + +/* dma registers per channel(xmt or rcv) */ +typedef volatile struct { + uint32 control; /* enable, et al */ + uint32 ptr; /* last descriptor posted to chip */ + uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ + uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ + uint32 status0; /* current descriptor, xmt state */ + uint32 status1; /* active descriptor, xmt error */ +} dma64regs_t; + +typedef volatile struct { + dma64regs_t tx; /* dma64 tx channel */ + dma64regs_t rx; /* dma64 rx channel */ +} dma64regp_t; + +typedef volatile struct { /* diag access */ + uint32 fifoaddr; /* diag address */ + uint32 fifodatalow; /* low 32bits of data */ + uint32 fifodatahigh; /* high 32bits of data */ + uint32 pad; /* reserved */ +} dma64diag_t; + +/* + * DMA Descriptor + * Descriptors are only read by the hardware, never written back. + */ +typedef volatile struct { + uint32 ctrl1; /* misc control bits & bufcount */ + uint32 ctrl2; /* buffer count and address extension */ + uint32 addrlow; /* memory address of the date buffer, bits 31:0 */ + uint32 addrhigh; /* memory address of the date buffer, bits 63:32 */ +} dma64dd_t; + +/* + * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. + */ +#define D64MAXRINGSZ 8192 +#define D64RINGALIGN 8192 +#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) + +/* transmit channel control */ +#define D64_XC_XE 0x00000001 /* transmit enable */ +#define D64_XC_SE 0x00000002 /* transmit suspend request */ +#define D64_XC_LE 0x00000004 /* loopback enable */ +#define D64_XC_FL 0x00000010 /* flush request */ +#define D64_XC_AE 0x00030000 /* address extension bits */ +#define D64_XC_AE_SHIFT 16 + +/* transmit descriptor table pointer */ +#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ + +/* transmit channel status */ +#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ +#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ +#define D64_XS0_XS_SHIFT 28 +#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ +#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ +#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ +#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ +#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ + +#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ +#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ +#define D64_XS1_XE_SHIFT 28 +#define D64_XS1_XE_NOERR 0x00000000 /* no error */ +#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ +#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ +#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ +#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ +#define D64_XS1_XE_COREE 0x50000000 /* core error */ + +/* receive channel control */ +#define D64_RC_RE 0x00000001 /* receive enable */ +#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ +#define D64_RC_RO_SHIFT 1 +#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ +#define D64_RC_AE 0x00030000 /* address extension bits */ +#define D64_RC_AE_SHIFT 16 + +/* receive descriptor table pointer */ +#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ + +/* receive channel status */ +#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ +#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ +#define D64_RS0_RS_SHIFT 28 +#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ +#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ +#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ +#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ +#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ + +#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ +#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ +#define D64_RS1_RE_SHIFT 28 +#define D64_RS1_RE_NOERR 0x00000000 /* no error */ +#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ +#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ +#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ +#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ +#define D64_RS1_RE_COREE 0x50000000 /* core error */ + +/* fifoaddr */ +#define D64_FA_OFF_MASK 0xffff /* offset */ +#define D64_FA_SEL_MASK 0xf0000 /* select */ +#define D64_FA_SEL_SHIFT 16 +#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ +#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ +#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ +#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ +#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ +#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ +#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ +#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ +#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ +#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ + +/* descriptor control flags 1 */ +#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ +#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ +#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ +#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ + +/* descriptor control flags 2 */ +#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ +#define D64_CTRL2_AE 0x00030000 /* address extension bits */ +#define D64_CTRL2_AE_SHIFT 16 + +/* control flags in the range [27:20] are core-specific and not defined here */ +#define D64_CTRL_CORE_MASK 0x0ff00000 + + +#endif /* _sbhnddma_h_ */ diff --git a/package/broadcom-wl/src/wlc/Makefile b/package/broadcom-wl/src/wlc/Makefile new file mode 100644 index 0000000000..ffe1649515 --- /dev/null +++ b/package/broadcom-wl/src/wlc/Makefile @@ -0,0 +1,9 @@ +all: wlc +clean: + rm -f *.o wlc + +wlc: wlc.o ioctl.o +%.o: %.c + $(CC) $(CFLAGS) -Wall -c -o $@ $< + +.PHONY: all clean diff --git a/package/broadcom-wl/src/wlc/include/bcmdefs.h b/package/broadcom-wl/src/wlc/include/bcmdefs.h new file mode 100644 index 0000000000..8b5abe5d26 --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/bcmdefs.h @@ -0,0 +1,106 @@ +/* + * Misc system wide definitions + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * $Id: bcmdefs.h,v 1.1.1.3 2006/04/08 06:13:39 honor Exp $ + */ + +#ifndef _bcmdefs_h_ +#define _bcmdefs_h_ + +/* + * One doesn't need to include this file explicitly, gets included automatically if + * typedefs.h is included. + */ + +/* Reclaiming text and data : + * The following macros specify special linker sections that can be reclaimed + * after a system is considered 'up'. + */ +#if defined(__GNUC__) && defined(BCMRECLAIM) +extern bool bcmreclaimed; +#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data +#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn +#else /* #if defined(__GNUC__) && defined(BCMRECLAIM) */ +#define BCMINITDATA(_data) _data +#define BCMINITFN(_fn) _fn +#define bcmreclaimed 0 +#endif /* #if defined(__GNUC__) && defined(BCMRECLAIM) */ + +/* Reclaim uninit functions if BCMNODOWN is defined */ +/* and if they are not already removed by -gc-sections */ +#ifdef BCMNODOWN +#define BCMUNINITFN(_fn) BCMINITFN(_fn) +#else +#define BCMUNINITFN(_fn) _fn +#endif + +#ifdef BCMRECLAIM +#define CONST +#else +#define CONST const +#endif /* BCMRECLAIM */ + +/* Compatibility with old-style BCMRECLAIM */ +#define BCMINIT(_id) _id + + +/* Put some library data/code into ROM to reduce RAM requirements */ +#if defined(__GNUC__) && defined(BCMROMOFFLOAD) +#define BCMROMDATA(_data) __attribute__ ((__section__ (".datarom." #_data))) _data +#define BCMROMFN(_fn) __attribute__ ((__section__ (".textrom." #_fn))) _fn +#else +#define BCMROMDATA(_data) _data +#define BCMROMFN(_fn) _fn +#endif + +/* Bus types */ +#define SB_BUS 0 /* Silicon Backplane */ +#define PCI_BUS 1 /* PCI target */ +#define PCMCIA_BUS 2 /* PCMCIA target */ +#define SDIO_BUS 3 /* SDIO target */ +#define JTAG_BUS 4 /* JTAG */ +#define NO_BUS 0xFF /* Bus that does not support R/W REG */ + +/* Allows optimization for single-bus support */ +#ifdef BCMBUSTYPE +#define BUSTYPE(bus) (BCMBUSTYPE) +#else +#define BUSTYPE(bus) (bus) +#endif + +/* Defines for DMA Address Width - Shared between OSL and HNDDMA */ +#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */ +#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */ +#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */ + +#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ +#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ +#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ +#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ + +/* packet headroom necessary to accomodate the largest header in the system, (i.e TXOFF). + * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. + * There is a compile time check in wlc.c which ensure that this value is at least as big + * as TXOFF. This value is used in dma_rxfill (hnddma.c). + */ +#define BCMEXTRAHDROOM 160 + +/* Headroom required for dongle-to-host communication. Packets allocated + * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should + * leave this much room in front for low-level message headers which may + * be needed to get across the dongle bus to the host. (These messages + * don't go over the network, so room for the full WL header above would + * be a waste.) + */ +#define BCMDONGLEHDRSZ 8 + + + +#endif /* _bcmdefs_h_ */ diff --git a/package/broadcom-wl/src/wlc/include/bcmutils.h b/package/broadcom-wl/src/wlc/include/bcmutils.h new file mode 100644 index 0000000000..b6e7b0542b --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/bcmutils.h @@ -0,0 +1,258 @@ +/* + * Misc useful os-independent macros and functions. + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $ + */ + +#ifndef _bcmutils_h_ +#define _bcmutils_h_ + +/* ** driver/apps-shared section ** */ + +#define BCME_STRLEN 64 /* Max string length for BCM errors */ +#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) + + +/* + * error codes could be added but the defined ones shouldn't be changed/deleted + * these error codes are exposed to the user code + * when ever a new error code is added to this list + * please update errorstring table with the related error string and + * update osl files with os specific errorcode map +*/ + +#define BCME_OK 0 /* Success */ +#define BCME_ERROR -1 /* Error generic */ +#define BCME_BADARG -2 /* Bad Argument */ +#define BCME_BADOPTION -3 /* Bad option */ +#define BCME_NOTUP -4 /* Not up */ +#define BCME_NOTDOWN -5 /* Not down */ +#define BCME_NOTAP -6 /* Not AP */ +#define BCME_NOTSTA -7 /* Not STA */ +#define BCME_BADKEYIDX -8 /* BAD Key Index */ +#define BCME_RADIOOFF -9 /* Radio Off */ +#define BCME_NOTBANDLOCKED -10 /* Not band locked */ +#define BCME_NOCLK -11 /* No Clock */ +#define BCME_BADRATESET -12 /* BAD Rate valueset */ +#define BCME_BADBAND -13 /* BAD Band */ +#define BCME_BUFTOOSHORT -14 /* Buffer too short */ +#define BCME_BUFTOOLONG -15 /* Buffer too long */ +#define BCME_BUSY -16 /* Busy */ +#define BCME_NOTASSOCIATED -17 /* Not Associated */ +#define BCME_BADSSIDLEN -18 /* Bad SSID len */ +#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */ +#define BCME_BADCHAN -20 /* Bad Channel */ +#define BCME_BADADDR -21 /* Bad Address */ +#define BCME_NORESOURCE -22 /* Not Enough Resources */ +#define BCME_UNSUPPORTED -23 /* Unsupported */ +#define BCME_BADLEN -24 /* Bad length */ +#define BCME_NOTREADY -25 /* Not Ready */ +#define BCME_EPERM -26 /* Not Permitted */ +#define BCME_NOMEM -27 /* No Memory */ +#define BCME_ASSOCIATED -28 /* Associated */ +#define BCME_RANGE -29 /* Not In Range */ +#define BCME_NOTFOUND -30 /* Not Found */ +#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */ +#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */ +#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */ +#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */ +#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */ +#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */ +#define BCME_LAST BCME_DONGLE_DOWN + +/* These are collection of BCME Error strings */ +#define BCMERRSTRINGTABLE { \ + "OK", \ + "Undefined error", \ + "Bad Argument", \ + "Bad Option", \ + "Not up", \ + "Not down", \ + "Not AP", \ + "Not STA", \ + "Bad Key Index", \ + "Radio Off", \ + "Not band locked", \ + "No clock", \ + "Bad Rate valueset", \ + "Bad Band", \ + "Buffer too short", \ + "Buffer too long", \ + "Busy", \ + "Not Associated", \ + "Bad SSID len", \ + "Out of Range Channel", \ + "Bad Channel", \ + "Bad Address", \ + "Not Enough Resources", \ + "Unsupported", \ + "Bad length", \ + "Not Ready", \ + "Not Permitted", \ + "No Memory", \ + "Associated", \ + "Not In Range", \ + "Not Found", \ + "WME Not Enabled", \ + "TSPEC Not Found", \ + "ACM Not Supported", \ + "Not WME Association", \ + "SDIO Bus Error", \ + "Dongle Not Accessible" \ +} + +#ifndef ABS +#define ABS(a) (((a) < 0)?-(a):(a)) +#endif /* ABS */ + +#ifndef MIN +#define MIN(a, b) (((a) < (b))?(a):(b)) +#endif /* MIN */ + +#ifndef MAX +#define MAX(a, b) (((a) > (b))?(a):(b)) +#endif /* MAX */ + +#define CEIL(x, y) (((x) + ((y)-1)) / (y)) +#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) +#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) +#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) +#define VALID_MASK(mask) !((mask) & ((mask) + 1)) +#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) +#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) + +/* bit map related macros */ +#ifndef setbit +#ifndef NBBY /* the BSD family defines NBBY */ +#define NBBY 8 /* 8 bits per byte */ +#endif /* #ifndef NBBY */ +#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) +#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) +#define isset(a, i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) +#define isclr(a, i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) +#endif /* setbit */ + +#define NBITS(type) (sizeof(type) * 8) +#define NBITVAL(nbits) (1 << (nbits)) +#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) +#define NBITMASK(nbits) MAXBITVAL(nbits) +#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) + +/* basic mux operation - can be optimized on several architectures */ +#define MUX(pred, true, false) ((pred) ? (true) : (false)) + +/* modulo inc/dec - assumes x E [0, bound - 1] */ +#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) +#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) + +/* modulo inc/dec, bound = 2^k */ +#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) +#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) + +/* modulo add/sub - assumes x, y E [0, bound - 1] */ +#define MODADD(x, y, bound) \ + MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) +#define MODSUB(x, y, bound) \ + MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) + +/* module add/sub, bound = 2^k */ +#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) +#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) + +/* crc defines */ +#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ +#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ +#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ +#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ +#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ +#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ + +/* bcm_format_flags() bit description structure */ +typedef struct bcm_bit_desc { + uint32 bit; + char* name; +} bcm_bit_desc_t; + +/* tag_ID/length/value_buffer tuple */ +typedef struct bcm_tlv { + uint8 id; + uint8 len; + uint8 data[1]; +} bcm_tlv_t; + +/* Check that bcm_tlv_t fits into the given buflen */ +#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) + +/* buffer length for ethernet address from bcm_ether_ntoa() */ +#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ + +/* unaligned load and store macros */ +#ifdef IL_BIGENDIAN +static INLINE uint32 +load32_ua(uint8 *a) +{ + return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); +} + +static INLINE void +store32_ua(uint8 *a, uint32 v) +{ + a[0] = (v >> 24) & 0xff; + a[1] = (v >> 16) & 0xff; + a[2] = (v >> 8) & 0xff; + a[3] = v & 0xff; +} + +static INLINE uint16 +load16_ua(uint8 *a) +{ + return ((a[0] << 8) | a[1]); +} + +static INLINE void +store16_ua(uint8 *a, uint16 v) +{ + a[0] = (v >> 8) & 0xff; + a[1] = v & 0xff; +} + +#else + +static INLINE uint32 +load32_ua(uint8 *a) +{ + return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]); +} + +static INLINE void +store32_ua(uint8 *a, uint32 v) +{ + a[3] = (v >> 24) & 0xff; + a[2] = (v >> 16) & 0xff; + a[1] = (v >> 8) & 0xff; + a[0] = v & 0xff; +} + +static INLINE uint16 +load16_ua(uint8 *a) +{ + return ((a[1] << 8) | a[0]); +} + +static INLINE void +store16_ua(uint8 *a, uint16 v) +{ + a[1] = (v >> 8) & 0xff; + a[0] = v & 0xff; +} + +#endif /* IL_BIGENDIAN */ + +#endif /* _bcmutils_h_ */ diff --git a/package/broadcom-wl/src/wlc/include/proto/802.11.h b/package/broadcom-wl/src/wlc/include/proto/802.11.h new file mode 100644 index 0000000000..2b1c4ee111 --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/proto/802.11.h @@ -0,0 +1,1258 @@ +/* + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * Fundamental types and constants relating to 802.11 + * + * $Id: 802.11.h,v 1.1.1.17 2006/04/15 01:29:08 michael Exp $ + */ + +#ifndef _802_11_H_ +#define _802_11_H_ + +#ifndef _TYPEDEFS_H_ +#include +#endif + +#ifndef _NET_ETHERNET_H_ +#include +#endif + +#include + +/* enable structure packing */ +#if defined(__GNUC__) +#define PACKED __attribute__((packed)) +#else +#pragma pack(1) +#define PACKED +#endif + +#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */ + +/* Generic 802.11 frame constants */ +#define DOT11_A3_HDR_LEN 24 /* d11 header length with A3 */ +#define DOT11_A4_HDR_LEN 30 /* d11 header length with A4 */ +#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN /* MAC header length */ +#define DOT11_FCS_LEN 4 /* d11 FCS length */ +#define DOT11_ICV_LEN 4 /* d11 ICV length */ +#define DOT11_ICV_AES_LEN 8 /* d11 ICV/AES length */ +#define DOT11_QOS_LEN 2 /* d11 QoS length */ +#define DOT11_HTC_LEN 4 /* d11 HT Control field length */ + +#define DOT11_KEY_INDEX_SHIFT 6 /* d11 key index shift */ +#define DOT11_IV_LEN 4 /* d11 IV length */ +#define DOT11_IV_TKIP_LEN 8 /* d11 IV TKIP length */ +#define DOT11_IV_AES_OCB_LEN 4 /* d11 IV/AES/OCB length */ +#define DOT11_IV_AES_CCM_LEN 8 /* d11 IV/AES/CCM length */ +#define DOT11_IV_MAX_LEN 8 /* maximum iv len for any encryption */ + +/* Includes MIC */ +#define DOT11_MAX_MPDU_BODY_LEN 2304 /* max MPDU body length */ +/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */ +#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ + DOT11_QOS_LEN + \ + DOT11_IV_AES_CCM_LEN + \ + DOT11_MAX_MPDU_BODY_LEN + \ + DOT11_ICV_LEN + \ + DOT11_FCS_LEN) /* d11 max MPDU length */ + +#define DOT11_MAX_SSID_LEN 32 /* d11 max ssid length */ + +/* dot11RTSThreshold */ +#define DOT11_DEFAULT_RTS_LEN 2347 /* d11 default RTS length */ +#define DOT11_MAX_RTS_LEN 2347 /* d11 max RTS length */ + +/* dot11FragmentationThreshold */ +#define DOT11_MIN_FRAG_LEN 256 /* d11 min fragmentation length */ +#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength + * of the attached PHY + */ +#define DOT11_DEFAULT_FRAG_LEN 2346 /* d11 default fragmentation length */ + +/* dot11BeaconPeriod */ +#define DOT11_MIN_BEACON_PERIOD 1 /* d11 min beacon period */ +#define DOT11_MAX_BEACON_PERIOD 0xFFFF /* d11 max beacon period */ + +/* dot11DTIMPeriod */ +#define DOT11_MIN_DTIM_PERIOD 1 /* d11 min DTIM period */ +#define DOT11_MAX_DTIM_PERIOD 0xFF /* d11 max DTIM period */ + +/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */ +#define DOT11_LLC_SNAP_HDR_LEN 8 /* d11 LLC/SNAP header length */ +#define DOT11_OUI_LEN 3 /* d11 OUI length */ +struct dot11_llc_snap_header { + uint8 dsap; /* always 0xAA */ + uint8 ssap; /* always 0xAA */ + uint8 ctl; /* always 0x03 */ + uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00 + * Bridge-Tunnel: 0x00 0x00 0xF8 + */ + uint16 type; /* ethertype */ +} PACKED; + +/* RFC1042 header used by 802.11 per 802.1H */ +#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) /* RCF1042 header length */ + +/* Generic 802.11 MAC header */ +/* + * N.B.: This struct reflects the full 4 address 802.11 MAC header. + * The fields are defined such that the shorter 1, 2, and 3 + * address headers just use the first k fields. + */ +struct dot11_header { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr a1; /* address 1 */ + struct ether_addr a2; /* address 2 */ + struct ether_addr a3; /* address 3 */ + uint16 seq; /* sequence control */ + struct ether_addr a4; /* address 4 */ +} PACKED; + +/* Control frames */ + +struct dot11_rts_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ + struct ether_addr ta; /* transmitter address */ +} PACKED; +#define DOT11_RTS_LEN 16 /* d11 RTS frame length */ + +struct dot11_cts_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ +} PACKED; +#define DOT11_CTS_LEN 10 /* d11 CTS frame length */ + +struct dot11_ack_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ +} PACKED; +#define DOT11_ACK_LEN 10 /* d11 ACK frame length */ + +struct dot11_ps_poll_frame { + uint16 fc; /* frame control */ + uint16 durid; /* AID */ + struct ether_addr bssid; /* receiver address, STA in AP */ + struct ether_addr ta; /* transmitter address */ +} PACKED; +#define DOT11_PS_POLL_LEN 16 /* d11 PS poll frame length */ + +struct dot11_cf_end_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ + struct ether_addr bssid; /* transmitter address, STA in AP */ +} PACKED; +#define DOT11_CS_END_LEN 16 /* d11 CF-END frame length */ + +/* BA/BAR Control parameters */ +#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 /* normal ack */ +#define DOT11_BA_CTL_POLICY_NOACK 0x0001 /* no ack */ +#define DOT11_BA_CTL_POLICY_MASK 0x0001 /* ack policy mask */ + +#define DOT11_BA_CTL_MTID 0x0002 /* multi tid BA */ +#define DOT11_BA_CTL_COMPRESSED 0x0004 /* compressed bitmap */ + +#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 /* num msdu in bitmap mask */ +#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 /* num msdu in bitmap shift */ + +#define DOT11_BA_CTL_TID_MASK 0xF000 /* tid mask */ +#define DOT11_BA_CTL_TID_SHIFT 12 /* tid shift */ + +struct dot11_ba_req_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ + struct ether_addr ta; /* transmitter address */ + uint16 bar_control; /* BAR Control */ + uint16 seqnum; /* Starting Sequence control */ +} PACKED; +#define DOT11_BA_REQ_LEN 20 /* BAR frame length */ + +#define DOT11_BA_BITMAP_LEN 128 /* bitmap length */ +#define DOT11_BA_CMP_BITMAP_LEN 8 /* compressed bitmap length */ +struct dot11_ba_frame { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr ra; /* receiver address */ + struct ether_addr ta; /* transmitter address */ + uint16 ba_control; /* BA Control */ + uint16 seqnum; /* Starting Sequence control */ + uint8 bitmap[DOT11_BA_BITMAP_LEN]; /* Block Ack Bitmap */ +} PACKED; +#define DOT11_BA_LEN 20 /* BA frame length (without bitmap) */ + +/* Management frame header */ +struct dot11_management_header { + uint16 fc; /* frame control */ + uint16 durid; /* duration/ID */ + struct ether_addr da; /* receiver address */ + struct ether_addr sa; /* transmitter address */ + struct ether_addr bssid; /* BSS ID */ + uint16 seq; /* sequence control */ +} PACKED; +#define DOT11_MGMT_HDR_LEN 24 /* d11 management header length */ + +/* Management frame payloads */ + +struct dot11_bcn_prb { + uint32 timestamp[2]; + uint16 beacon_interval; + uint16 capability; +} PACKED; +#define DOT11_BCN_PRB_LEN 12 /* d11 beacon probe frame length */ + +struct dot11_auth { + uint16 alg; /* algorithm */ + uint16 seq; /* sequence control */ + uint16 status; /* status code */ +} PACKED; +#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge info + * elt + */ + +struct dot11_assoc_req { + uint16 capability; /* capability information */ + uint16 listen; /* listen interval */ +} PACKED; +#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */ + +struct dot11_reassoc_req { + uint16 capability; /* capability information */ + uint16 listen; /* listen interval */ + struct ether_addr ap; /* Current AP address */ +} PACKED; +#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */ + +struct dot11_assoc_resp { + uint16 capability; /* capability information */ + uint16 status; /* status code */ + uint16 aid; /* association ID */ +} PACKED; + +struct dot11_action_measure { + uint8 category; + uint8 action; + uint8 token; + uint8 data[1]; +} PACKED; +#define DOT11_ACTION_MEASURE_LEN 3 /* d11 action measurement header length */ + +struct dot11_action_switch_channel { + uint8 category; + uint8 action; + uint8 data[5]; /* for switch IE */ +} PACKED; + +struct dot11_action_ht_ch_width { + uint8 category; + uint8 action; + uint8 ch_width; +} PACKED; + +struct dot11_action_ht_mimops { + uint8 category; + uint8 action; + uint8 enable; + uint8 psmode; +} PACKED; + +/* ************* 802.11h related definitions. ************* */ +typedef struct { + uint8 id; + uint8 len; + uint8 power; +} dot11_power_cnst_t; + +typedef struct { + uint8 min; + uint8 max; +} dot11_power_cap_t; + +typedef struct { + uint8 id; + uint8 len; + uint8 tx_pwr; + uint8 margin; +} dot11_tpc_rep_t; +#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */ + +typedef struct { + uint8 id; + uint8 len; + uint8 first_channel; + uint8 num_channels; +} dot11_supp_channels_t; + +/* channel switch announcement (CSA) mode type - 802.11h-2003 $7.3.2.20 */ +#define DOT11_CSA_MODE_ADVISORY 0 /* no DOT11_CSA_MODE_NO_TX restriction imposed */ +#define DOT11_CSA_MODE_NO_TX 1 /* no transmission upon receiving CSA frame. */ + +/* CSA IE data structure */ +struct dot11_channel_switch { + uint8 id; + uint8 len; + uint8 mode; + uint8 channel; + uint8 count; +} PACKED; +typedef struct dot11_channel_switch dot11_channel_switch_t; + +#define DOT11_SWITCH_IE_LEN 3 /* length of IE data, not including 2 byte header */ + +/* 802.11h Measurement Request/Report IEs */ +/* Measurement Type field */ +#define DOT11_MEASURE_TYPE_BASIC 0 /* d11 measurement basic type */ +#define DOT11_MEASURE_TYPE_CCA 1 /* d11 measurement CCA type */ +#define DOT11_MEASURE_TYPE_RPI 2 /* d11 measurement PRI type */ + +/* Measurement Mode field */ + +/* Measurement Request Modes */ +#define DOT11_MEASURE_MODE_ENABLE (1<<1) /* d11 measurement enable */ +#define DOT11_MEASURE_MODE_REQUEST (1<<2) /* d11 measurement request */ +#define DOT11_MEASURE_MODE_REPORT (1<<3) /* d11 measurement report */ +/* Measurement Report Modes */ +#define DOT11_MEASURE_MODE_LATE (1<<0) /* d11 measurement late */ +#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) /* d11 measurement incapable */ +#define DOT11_MEASURE_MODE_REFUSED (1<<2) /* d11 measurement refuse */ +/* Basic Measurement Map bits */ +#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) /* d11 measurement basic map BSS */ +#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) /* d11 measurement map OFDM */ +#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) /* d11 measurement map unknown */ +#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) /* d11 measurement map radar */ +#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) /* d11 measurement map unmeasuremnt */ + +typedef struct { + uint8 id; + uint8 len; + uint8 token; + uint8 mode; + uint8 type; + uint8 channel; + uint8 start_time[8]; + uint16 duration; +} dot11_meas_req_t; +#define DOT11_MNG_IE_MREQ_LEN 14 /* d11 measurement request IE length */ +/* length of Measure Request IE data not including variable len */ +#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 /* d11 measurement request IE fixed length */ + +struct dot11_meas_rep { + uint8 id; + uint8 len; + uint8 token; + uint8 mode; + uint8 type; + union + { + struct { + uint8 channel; + uint8 start_time[8]; + uint16 duration; + uint8 map; + } PACKED basic; + uint8 data[1]; + } PACKED rep; +} PACKED; +typedef struct dot11_meas_rep dot11_meas_rep_t; + +/* length of Measure Report IE data not including variable len */ +#define DOT11_MNG_IE_MREP_FIXED_LEN 3 /* d11 measurement response IE fixed length */ + +struct dot11_meas_rep_basic { + uint8 channel; + uint8 start_time[8]; + uint16 duration; + uint8 map; +} PACKED; +typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; +#define DOT11_MEASURE_BASIC_REP_LEN 12 /* d11 measurement basic report length */ + +struct dot11_quiet { + uint8 id; + uint8 len; + uint8 count; /* TBTTs until beacon interval in quiet starts */ + uint8 period; /* Beacon intervals between periodic quiet periods ? */ + uint16 duration; /* Length of quiet period, in TU's */ + uint16 offset; /* TU's offset from TBTT in Count field */ +} PACKED; +typedef struct dot11_quiet dot11_quiet_t; + +typedef struct { + uint8 channel; + uint8 map; +} chan_map_tuple_t; + +typedef struct { + uint8 id; + uint8 len; + uint8 eaddr[ETHER_ADDR_LEN]; + uint8 interval; + chan_map_tuple_t map[1]; +} dot11_ibss_dfs_t; + +/* WME Elements */ +#define WME_OUI "\x00\x50\xf2" /* WME OUI */ +#define WME_VER 1 /* WME version */ +#define WME_TYPE 2 /* WME type */ +#define WME_SUBTYPE_IE 0 /* Information Element */ +#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */ +#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */ + +/* WME Access Category Indices (ACIs) */ +#define AC_BE 0 /* Best Effort */ +#define AC_BK 1 /* Background */ +#define AC_VI 2 /* Video */ +#define AC_VO 3 /* Voice */ +#define AC_COUNT 4 /* number of ACs */ + +typedef uint8 ac_bitmap_t; /* AC bitmap of (1 << AC_xx) */ + +#define AC_BITMAP_NONE 0x0 /* No ACs */ +#define AC_BITMAP_ALL 0xf /* All ACs */ +#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) + +/* WME Information Element (IE) */ +struct wme_ie { + uint8 oui[3]; + uint8 type; + uint8 subtype; + uint8 version; + uint8 qosinfo; +} PACKED; +typedef struct wme_ie wme_ie_t; +#define WME_IE_LEN 7 /* WME IE length */ + +struct edcf_acparam { + uint8 ACI; + uint8 ECW; + uint16 TXOP; /* stored in network order (ls octet first) */ +} PACKED; +typedef struct edcf_acparam edcf_acparam_t; + +/* WME Parameter Element (PE) */ +struct wme_param_ie { + uint8 oui[3]; + uint8 type; + uint8 subtype; + uint8 version; + uint8 qosinfo; + uint8 rsvd; + edcf_acparam_t acparam[AC_COUNT]; +} PACKED; +typedef struct wme_param_ie wme_param_ie_t; +#define WME_PARAM_IE_LEN 24 /* WME Parameter IE length */ + +/* QoS Info field for IE as sent from AP */ +#define WME_QI_AP_APSD_MASK 0x80 /* U-APSD Supported mask */ +#define WME_QI_AP_APSD_SHIFT 7 /* U-APSD Supported shift */ +#define WME_QI_AP_COUNT_MASK 0x0f /* Parameter set count mask */ +#define WME_QI_AP_COUNT_SHIFT 0 /* Parameter set count shift */ + +/* QoS Info field for IE as sent from STA */ +#define WME_QI_STA_MAXSPLEN_MASK 0x60 /* Max Service Period Length mask */ +#define WME_QI_STA_MAXSPLEN_SHIFT 5 /* Max Service Period Length shift */ +#define WME_QI_STA_APSD_ALL_MASK 0xf /* APSD all AC bits mask */ +#define WME_QI_STA_APSD_ALL_SHIFT 0 /* APSD all AC bits shift */ +#define WME_QI_STA_APSD_BE_MASK 0x8 /* APSD AC_BE mask */ +#define WME_QI_STA_APSD_BE_SHIFT 3 /* APSD AC_BE shift */ +#define WME_QI_STA_APSD_BK_MASK 0x4 /* APSD AC_BK mask */ +#define WME_QI_STA_APSD_BK_SHIFT 2 /* APSD AC_BK shift */ +#define WME_QI_STA_APSD_VI_MASK 0x2 /* APSD AC_VI mask */ +#define WME_QI_STA_APSD_VI_SHIFT 1 /* APSD AC_VI shift */ +#define WME_QI_STA_APSD_VO_MASK 0x1 /* APSD AC_VO mask */ +#define WME_QI_STA_APSD_VO_SHIFT 0 /* APSD AC_VO shift */ + +/* ACI */ +#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */ +#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */ +#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */ +#define EDCF_ACM_MASK 0x10 /* ACM mask */ +#define EDCF_ACI_MASK 0x60 /* ACI mask */ +#define EDCF_ACI_SHIFT 5 /* ACI shift */ + +/* ECW */ +#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */ +#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */ +#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) +#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */ +#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */ +#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */ + +/* TXOP */ +#define EDCF_TXOP_MIN 0 /* TXOP minimum value */ +#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */ +#define EDCF_TXOP2USEC(txop) ((txop) << 5) + +/* Default EDCF parameters that AP advertises for STA to use; WMM draft Table 12 */ +#define EDCF_AC_BE_ACI_STA 0x03 /* STA ACI value for best effort AC */ +#define EDCF_AC_BE_ECW_STA 0xA4 /* STA ECW value for best effort AC */ +#define EDCF_AC_BE_TXOP_STA 0x0000 /* STA TXOP value for best effort AC */ +#define EDCF_AC_BK_ACI_STA 0x27 /* STA ACI value for background AC */ +#define EDCF_AC_BK_ECW_STA 0xA4 /* STA ECW value for background AC */ +#define EDCF_AC_BK_TXOP_STA 0x0000 /* STA TXOP value for background AC */ +#define EDCF_AC_VI_ACI_STA 0x42 /* STA ACI value for video AC */ +#define EDCF_AC_VI_ECW_STA 0x43 /* STA ECW value for video AC */ +#define EDCF_AC_VI_TXOP_STA 0x005e /* STA TXOP value for video AC */ +#define EDCF_AC_VO_ACI_STA 0x62 /* STA ACI value for audio AC */ +#define EDCF_AC_VO_ECW_STA 0x32 /* STA ECW value for audio AC */ +#define EDCF_AC_VO_TXOP_STA 0x002f /* STA TXOP value for audio AC */ + +/* Default EDCF parameters that AP uses; WMM draft Table 14 */ +#define EDCF_AC_BE_ACI_AP 0x03 /* AP ACI value for best effort AC */ +#define EDCF_AC_BE_ECW_AP 0x64 /* AP ECW value for best effort AC */ +#define EDCF_AC_BE_TXOP_AP 0x0000 /* AP TXOP value for best effort AC */ +#define EDCF_AC_BK_ACI_AP 0x27 /* AP ACI value for background AC */ +#define EDCF_AC_BK_ECW_AP 0xA4 /* AP ECW value for background AC */ +#define EDCF_AC_BK_TXOP_AP 0x0000 /* AP TXOP value for background AC */ +#define EDCF_AC_VI_ACI_AP 0x41 /* AP ACI value for video AC */ +#define EDCF_AC_VI_ECW_AP 0x43 /* AP ECW value for video AC */ +#define EDCF_AC_VI_TXOP_AP 0x005e /* AP TXOP value for video AC */ +#define EDCF_AC_VO_ACI_AP 0x61 /* AP ACI value for audio AC */ +#define EDCF_AC_VO_ECW_AP 0x32 /* AP ECW value for audio AC */ +#define EDCF_AC_VO_TXOP_AP 0x002f /* AP TXOP value for audio AC */ + +struct dot11_qbss_load_ie { + uint8 id; /* 11, DOT11_MNG_QBSS_LOAD_ID */ + uint8 length; + uint16 station_count; /* total number of STAs associated */ + uint8 channel_utilization; /* % of time, normalized to 255, QAP sensed medium busy */ + uint16 aac; /* available admission capacity */ +} PACKED; +typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; + +/* nom_msdu_size */ +#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */ +#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */ + +/* surplus_bandwidth */ +/* Represented as 3 bits of integer, binary point, 13 bits fraction */ +#define INTEGER_SHIFT 13 /* integer shift */ +#define FRACTION_MASK 0x1FFF /* fraction mask */ + +/* Management Notification Frame */ +struct dot11_management_notification { + uint8 category; /* DOT11_ACTION_NOTIFICATION */ + uint8 action; + uint8 token; + uint8 status; + uint8 data[1]; /* Elements */ +} PACKED; +#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */ + +/* WME Action Codes */ +#define WME_ADDTS_REQUEST 0 /* WME ADDTS request */ +#define WME_ADDTS_RESPONSE 1 /* WME ADDTS response */ +#define WME_DELTS_REQUEST 2 /* WME DELTS request */ + +/* WME Setup Response Status Codes */ +#define WME_ADMISSION_ACCEPTED 0 /* WME admission accepted */ +#define WME_INVALID_PARAMETERS 1 /* WME invalide parameters */ +#define WME_ADMISSION_REFUSED 3 /* WME admission refused */ + +/* Macro to take a pointer to a beacon or probe response + * header and return the char* pointer to the SSID info element + */ +#define BCN_PRB_SSID(hdr) ((char*)(hdr) + DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_LEN) + +/* Authentication frame payload constants */ +#define DOT11_OPEN_SYSTEM 0 /* d11 open authentication */ +#define DOT11_SHARED_KEY 1 /* d11 shared authentication */ +#define DOT11_CHALLENGE_LEN 128 /* d11 chanllenge text length */ + +/* Frame control macros */ +#define FC_PVER_MASK 0x3 /* PVER mask */ +#define FC_PVER_SHIFT 0 /* PVER shift */ +#define FC_TYPE_MASK 0xC /* type mask */ +#define FC_TYPE_SHIFT 2 /* type shift */ +#define FC_SUBTYPE_MASK 0xF0 /* subtype mask */ +#define FC_SUBTYPE_SHIFT 4 /* subtype shift */ +#define FC_TODS 0x100 /* to DS */ +#define FC_TODS_SHIFT 8 /* to DS shift */ +#define FC_FROMDS 0x200 /* from DS */ +#define FC_FROMDS_SHIFT 9 /* from DS shift */ +#define FC_MOREFRAG 0x400 /* more frag. */ +#define FC_MOREFRAG_SHIFT 10 /* more frag. shift */ +#define FC_RETRY 0x800 /* retry */ +#define FC_RETRY_SHIFT 11 /* retry shift */ +#define FC_PM 0x1000 /* PM */ +#define FC_PM_SHIFT 12 /* PM shift */ +#define FC_MOREDATA 0x2000 /* more data */ +#define FC_MOREDATA_SHIFT 13 /* more data shift */ +#define FC_WEP 0x4000 /* WEP */ +#define FC_WEP_SHIFT 14 /* WEP shift */ +#define FC_ORDER 0x8000 /* order */ +#define FC_ORDER_SHIFT 15 /* order shift */ + +/* sequence control macros */ +#define SEQNUM_SHIFT 4 /* seq. number shift */ +#define SEQNUM_MAX 0x1000 /* max seqnum + 1 */ +#define FRAGNUM_MASK 0xF /* frag. number mask */ + +/* Frame Control type/subtype defs */ + +/* FC Types */ +#define FC_TYPE_MNG 0 /* management type */ +#define FC_TYPE_CTL 1 /* control type */ +#define FC_TYPE_DATA 2 /* data type */ + +/* Management Subtypes */ +#define FC_SUBTYPE_ASSOC_REQ 0 /* assoc. request */ +#define FC_SUBTYPE_ASSOC_RESP 1 /* assoc. response */ +#define FC_SUBTYPE_REASSOC_REQ 2 /* reassoc. request */ +#define FC_SUBTYPE_REASSOC_RESP 3 /* reassoc. response */ +#define FC_SUBTYPE_PROBE_REQ 4 /* probe request */ +#define FC_SUBTYPE_PROBE_RESP 5 /* probe response */ +#define FC_SUBTYPE_BEACON 8 /* beacon */ +#define FC_SUBTYPE_ATIM 9 /* ATIM */ +#define FC_SUBTYPE_DISASSOC 10 /* disassoc. */ +#define FC_SUBTYPE_AUTH 11 /* authentication */ +#define FC_SUBTYPE_DEAUTH 12 /* de-authentication */ +#define FC_SUBTYPE_ACTION 13 /* action */ + +/* Control Subtypes */ +#define FC_SUBTYPE_BLOCKACK_REQ 8 /* Block Ack Req */ +#define FC_SUBTYPE_BLOCKACK 9 /* Block Ack */ +#define FC_SUBTYPE_PS_POLL 10 /* PS poll */ +#define FC_SUBTYPE_RTS 11 /* RTS */ +#define FC_SUBTYPE_CTS 12 /* CTS */ +#define FC_SUBTYPE_ACK 13 /* ACK */ +#define FC_SUBTYPE_CF_END 14 /* CF-END */ +#define FC_SUBTYPE_CF_END_ACK 15 /* CF-END ACK */ + +/* Data Subtypes */ +#define FC_SUBTYPE_DATA 0 /* Data */ +#define FC_SUBTYPE_DATA_CF_ACK 1 /* Data + CF-ACK */ +#define FC_SUBTYPE_DATA_CF_POLL 2 /* Data + CF-Poll */ +#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 /* Data + CF-Ack + CF-Poll */ +#define FC_SUBTYPE_NULL 4 /* Null */ +#define FC_SUBTYPE_CF_ACK 5 /* CF-Ack */ +#define FC_SUBTYPE_CF_POLL 6 /* CF-Poll */ +#define FC_SUBTYPE_CF_ACK_POLL 7 /* CF-Ack + CF-Poll */ +#define FC_SUBTYPE_QOS_DATA 8 /* QoS Data */ +#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 /* QoS Data + CF-Ack */ +#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 /* QoS Data + CF-Poll */ +#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 /* QoS Data + CF-Ack + CF-Poll */ +#define FC_SUBTYPE_QOS_NULL 12 /* QoS Null */ +#define FC_SUBTYPE_QOS_CF_POLL 14 /* QoS CF-Poll */ +#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 /* QoS CF-Ack + CF-Poll */ + +/* Data Subtype Groups */ +#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) +#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) +#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) +#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) + +/* Type/Subtype Combos */ +#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) /* FC kind mask */ + +#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) /* FC kind */ + +#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) /* Subtype from FC */ +#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) /* Type from FC */ + +#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) /* assoc. request */ +#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) /* assoc. response */ +#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) /* reassoc. request */ +#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) /* reassoc. response */ +#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) /* probe request */ +#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) /* probe response */ +#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) /* beacon */ +#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) /* disassoc */ +#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) /* authentication */ +#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) /* deauthentication */ +#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) /* action */ + +#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) /* Block Ack Req */ +#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) /* Block Ack */ +#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) /* PS poll */ +#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) /* RTS */ +#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) /* CTS */ +#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) /* ACK */ +#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) /* CF-END */ +#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) /* CF-END ACK */ + +#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) /* data */ +#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) /* null data */ +#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) /* data CF ACK */ +#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) /* QoS data */ +#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) /* QoS null */ + +/* QoS Control Field */ + +/* 802.1D Priority */ +#define QOS_PRIO_SHIFT 0 /* QoS priority shift */ +#define QOS_PRIO_MASK 0x0007 /* QoS priority mask */ +#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) /* QoS priority */ + +/* Traffic Identifier */ +#define QOS_TID_SHIFT 0 /* QoS TID shift */ +#define QOS_TID_MASK 0x000f /* QoS TID mask */ +#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) /* QoS TID */ + +/* End of Service Period (U-APSD) */ +#define QOS_EOSP_SHIFT 4 /* QoS End of Service Period shift */ +#define QOS_EOSP_MASK 0x0010 /* QoS End of Service Period mask */ +#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) /* Qos EOSP */ + +/* Ack Policy */ +#define QOS_ACK_NORMAL_ACK 0 /* Normal Ack */ +#define QOS_ACK_NO_ACK 1 /* No Ack (eg mcast) */ +#define QOS_ACK_NO_EXP_ACK 2 /* No Explicit Ack */ +#define QOS_ACK_BLOCK_ACK 3 /* Block Ack */ +#define QOS_ACK_SHIFT 5 /* QoS ACK shift */ +#define QOS_ACK_MASK 0x0060 /* QoS ACK mask */ +#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) /* QoS ACK */ + +/* A-MSDU flag */ +#define QOS_AMSDU_SHIFT 7 /* AMSDU shift */ +#define QOS_AMSDU_MASK 0x0080 /* AMSDU mask */ + +/* Management Frames */ + +/* Management Frame Constants */ + +/* Fixed fields */ +#define DOT11_MNG_AUTH_ALGO_LEN 2 /* d11 management auth. algo. length */ +#define DOT11_MNG_AUTH_SEQ_LEN 2 /* d11 management auth. seq. length */ +#define DOT11_MNG_BEACON_INT_LEN 2 /* d11 management beacon interval length */ +#define DOT11_MNG_CAP_LEN 2 /* d11 management cap. length */ +#define DOT11_MNG_AP_ADDR_LEN 6 /* d11 management AP address length */ +#define DOT11_MNG_LISTEN_INT_LEN 2 /* d11 management listen interval length */ +#define DOT11_MNG_REASON_LEN 2 /* d11 management reason length */ +#define DOT11_MNG_AID_LEN 2 /* d11 management AID length */ +#define DOT11_MNG_STATUS_LEN 2 /* d11 management status length */ +#define DOT11_MNG_TIMESTAMP_LEN 8 /* d11 management timestamp length */ + +/* DUR/ID field in assoc resp is 0xc000 | AID */ +#define DOT11_AID_MASK 0x3fff /* d11 AID mask */ + +/* Reason Codes */ +#define DOT11_RC_RESERVED 0 /* d11 RC reserved */ +#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */ +#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer + * valid + */ +#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station + * is leaving (or has left) IBSS or ESS + */ +#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */ +#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable + * to handle all currently associated + * stations + */ +#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from + * nonauthenticated station + */ +#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from + * nonassociated station + */ +#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is + * leaving (or has left) BSS + */ +#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is + * not authenticated with responding + * station + */ +#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */ + +/* Status Codes */ +#define DOT11_STATUS_SUCCESS 0 /* Successful */ +#define DOT11_STATUS_FAILURE 1 /* Unspecified failure */ +#define DOT11_STATUS_CAP_MISMATCH 10 /* Cannot support all requested + * capabilities in the Capability + * Information field + */ +#define DOT11_STATUS_REASSOC_FAIL 11 /* Reassociation denied due to inability + * to confirm that association exists + */ +#define DOT11_STATUS_ASSOC_FAIL 12 /* Association denied due to reason + * outside the scope of this standard + */ +#define DOT11_STATUS_AUTH_MISMATCH 13 /* Responding station does not support + * the specified authentication + * algorithm + */ +#define DOT11_STATUS_AUTH_SEQ 14 /* Received an Authentication frame + * with authentication transaction + * sequence number out of expected + * sequence + */ +#define DOT11_STATUS_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of + * challenge failure + */ +#define DOT11_STATUS_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout + * waiting for next frame in sequence + */ +#define DOT11_STATUS_ASSOC_BUSY_FAIL 17 /* Association denied because AP is + * unable to handle additional + * associated stations + */ +#define DOT11_STATUS_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting + * station not supporting all of the + * data rates in the BSSBasicRateSet + * parameter + */ +#define DOT11_STATUS_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting + * station not supporting the Short + * Preamble option + */ +#define DOT11_STATUS_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting + * station not supporting the PBCC + * Modulation option + */ +#define DOT11_STATUS_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting + * station not supporting the Channel + * Agility option + */ +#define DOT11_STATUS_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum + * Management capability is required. + */ +#define DOT11_STATUS_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info + * in the Power Cap element is + * unacceptable. + */ +#define DOT11_STATUS_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info + * in the Supported Channel element is + * unacceptable + */ +#define DOT11_STATUS_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting + * station not supporting the Short Slot + * Time option + */ +#define DOT11_STATUS_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting + * station not supporting the ER-PBCC + * Modulation option + */ +#define DOT11_STATUS_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting + * station not supporting the DSS-OFDM + * option + */ + +/* Info Elts, length of INFORMATION portion of Info Elts */ +#define DOT11_MNG_DS_PARAM_LEN 1 /* d11 management DS parameter length */ +#define DOT11_MNG_IBSS_PARAM_LEN 2 /* d11 management IBSS parameter length */ + +/* TIM Info element has 3 bytes fixed info in INFORMATION field, + * followed by 1 to 251 bytes of Partial Virtual Bitmap + */ +#define DOT11_MNG_TIM_FIXED_LEN 3 /* d11 management TIM fixed length */ +#define DOT11_MNG_TIM_DTIM_COUNT 0 /* d11 management DTIM count */ +#define DOT11_MNG_TIM_DTIM_PERIOD 1 /* d11 management DTIM period */ +#define DOT11_MNG_TIM_BITMAP_CTL 2 /* d11 management TIM BITMAP control */ +#define DOT11_MNG_TIM_PVB 3 /* d11 management TIM PVB */ + +/* TLV defines */ +#define TLV_TAG_OFF 0 /* tag offset */ +#define TLV_LEN_OFF 1 /* length offset */ +#define TLV_HDR_LEN 2 /* header length */ +#define TLV_BODY_OFF 2 /* body offset */ + +/* Management Frame Information Element IDs */ +#define DOT11_MNG_SSID_ID 0 /* d11 management SSID id */ +#define DOT11_MNG_RATES_ID 1 /* d11 management rates id */ +#define DOT11_MNG_FH_PARMS_ID 2 /* d11 management FH parameter id */ +#define DOT11_MNG_DS_PARMS_ID 3 /* d11 management DS parameter id */ +#define DOT11_MNG_CF_PARMS_ID 4 /* d11 management CF parameter id */ +#define DOT11_MNG_TIM_ID 5 /* d11 management TIM id */ +#define DOT11_MNG_IBSS_PARMS_ID 6 /* d11 management IBSS parameter id */ +#define DOT11_MNG_COUNTRY_ID 7 /* d11 management country id */ +#define DOT11_MNG_HOPPING_PARMS_ID 8 /* d11 management hopping parameter id */ +#define DOT11_MNG_HOPPING_TABLE_ID 9 /* d11 management hopping table id */ +#define DOT11_MNG_REQUEST_ID 10 /* d11 management request id */ +#define DOT11_MNG_QBSS_LOAD_ID 11 /* d11 management QBSS Load id */ +#define DOT11_MNG_CHALLENGE_ID 16 /* d11 management chanllenge id */ +#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */ +#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */ +#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */ +#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */ +#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */ +#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement */ +#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */ +#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */ +#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */ +#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ +#define DOT11_MNG_ERP_ID 42 /* d11 management ERP id */ +#define DOT11_MNG_TS_DELAY_ID 43 /* d11 management TS Delay id */ +#define DOT11_MNG_NONERP_ID 47 /* d11 management NON-ERP id */ +#define DOT11_MNG_RSN_ID 48 /* d11 management RSN id */ +#define DOT11_MNG_EXT_RATES_ID 50 /* d11 management ext. rates id */ +#define DOT11_MNG_WPA_ID 221 /* d11 management WPA id */ +#define DOT11_MNG_PROPR_ID 221 /* d11 management proprietary id */ + +/* Rate element Basic flag and rate mask */ +#define DOT11_RATE_BASIC 0x80 /* flag for a Basic Rate */ +#define DOT11_RATE_MASK 0x7F /* mask for numeric part of rate */ + +/* ERP info element bit values */ +#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */ +#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present + *in the BSS + */ +#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for + *ERP-OFDM frames + */ +#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, + * 1 == not allowed + */ +/* TS Delay element offset & size */ +#define DOT11_MGN_TS_DELAY_LEN 4 /* length of TS DELAY IE */ +#define TS_DELAY_FIELD_SIZE 4 /* TS DELAY field size */ + +/* Capability Information Field */ +#define DOT11_CAP_ESS 0x0001 /* d11 cap. ESS */ +#define DOT11_CAP_IBSS 0x0002 /* d11 cap. IBSS */ +#define DOT11_CAP_POLLABLE 0x0004 /* d11 cap. pollable */ +#define DOT11_CAP_POLL_RQ 0x0008 /* d11 cap. poll request */ +#define DOT11_CAP_PRIVACY 0x0010 /* d11 cap. privacy */ +#define DOT11_CAP_SHORT 0x0020 /* d11 cap. short */ +#define DOT11_CAP_PBCC 0x0040 /* d11 cap. PBCC */ +#define DOT11_CAP_AGILITY 0x0080 /* d11 cap. agility */ +#define DOT11_CAP_SPECTRUM 0x0100 /* d11 cap. spectrum */ +#define DOT11_CAP_SHORTSLOT 0x0400 /* d11 cap. shortslot */ +#define DOT11_CAP_CCK_OFDM 0x2000 /* d11 cap. CCK/OFDM */ + +/* Action Frame Constants */ +#define DOT11_ACTION_CAT_ERR_MASK 0x80 /* d11 action category error mask */ +#define DOT11_ACTION_CAT_MASK 0x7F /* d11 action category mask */ +#define DOT11_ACTION_CAT_SPECT_MNG 0x00 /* d11 action category spectrum management */ +#define DOT11_ACTION_CAT_BLOCKACK 0x03 /* d11 action category block ack */ +#define DOT11_ACTION_NOTIFICATION 0x11 /* 17 */ + +#define DOT11_ACTION_ID_M_REQ 0 /* d11 action measurement request */ +#define DOT11_ACTION_ID_M_REP 1 /* d11 action measurement response */ +#define DOT11_ACTION_ID_TPC_REQ 2 /* d11 action TPC request */ +#define DOT11_ACTION_ID_TPC_REP 3 /* d11 action TPC response */ +#define DOT11_ACTION_ID_CHANNEL_SWITCH 4 /* d11 action channel switch */ + +/* HT (EWC) action ids */ +#define DOT11_ACTION_ID_HT_CH_WIDTH 0 /* mimo ps action frame id */ +#define DOT11_ACTION_ID_HT_MIMO_PS 1 /* mimo ps action frame id */ + +/* Block Ack action types */ +#define DOT11_BA_ACTION_ADDBA_REQ 0 /* ADDBA Req action frame type */ +#define DOT11_BA_ACTION_ADDBA_RESP 1 /* ADDBA Resp action frame type */ +#define DOT11_BA_ACTION_DELBA 2 /* DELBA action frame type */ + +/* ADDBA action parameters */ +#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 /* policy mask(ack vs delayed) */ +#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 /* policy shift */ +#define DOT11_ADDBA_PARAM_TID_MASK 0x003c /* tid mask */ +#define DOT11_ADDBA_PARAM_TID_SHIFT 2 /* tid shift */ +#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 /* buffer size mask */ +#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 /* buffer size shift */ + +#define DOT11_ADDBA_POLICY_DELAYED 0 /* delayed BA policy */ +#define DOT11_ADDBA_POLICY_IMMEDIATE 1 /* immediate BA policy */ + +struct dot11_addba_req { + uint8 category; /* category of action frame (3) */ + uint8 action; /* action: addba req */ + uint8 token; /* identifier */ + uint16 addba_param_set; /* parameter set */ + uint16 timeout; /* timeout in seconds */ + uint16 start_seqnum; /* starting sequence number */ +}PACKED; +typedef struct dot11_addba_req dot11_addba_req_t; +#define DOT11_ADDBA_REQ_LEN 9 /* length of addba req frame */ + +struct dot11_addba_resp { + uint8 category; /* category of action frame (3) */ + uint8 action; /* action: addba resp */ + uint8 token; /* identifier */ + uint16 status; /* status of add request */ + uint16 addba_param_set; /* negotiated parameter set */ + uint16 timeout; /* negotiated timeout in seconds */ +}PACKED; +typedef struct dot11_addba_resp dot11_addba_resp_t; +#define DOT11_ADDBA_RESP_LEN 9 /* length of addba resp frame */ + +/* DELBA action parameters */ +#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 /* initiator mask */ +#define DOT11_DELBA_PARAM_INIT_SHIFT 11 /* initiator shift */ +#define DOT11_DELBA_PARAM_TID_MASK 0xf000 /* tid mask */ +#define DOT11_DELBA_PARAM_TID_SHIFT 12 /* tid shift */ + +struct dot11_delba { + uint8 category; /* category of action frame (3) */ + uint8 action; /* action: addba req */ + uint16 delba_param_set; /* paarmeter set */ + uint16 reason; /* reason for dellba */ +}PACKED; +typedef struct dot11_delba dot11_delba_t; +#define DOT11_DELBA_LEN 6 /* length of delba frame */ + +/* MLME Enumerations */ +#define DOT11_BSSTYPE_INFRASTRUCTURE 0 /* d11 infrastructure */ +#define DOT11_BSSTYPE_INDEPENDENT 1 /* d11 independent */ +#define DOT11_BSSTYPE_ANY 2 /* d11 any BSS type */ +#define DOT11_SCANTYPE_ACTIVE 0 /* d11 scan active */ +#define DOT11_SCANTYPE_PASSIVE 1 /* d11 scan passive */ + +/* 802.11 BRCM "Compromise" Pre N constants */ +#define PREN_PREAMBLE 24 /* green field preamble time */ +#define PREN_MM_EXT 16 /* extra mixed mode preamble time */ +#define PREN_PREAMBLE_EXT 4 /* extra preamble (multiply by unique_streams-1) */ + +/* 802.11 A PHY constants */ +#define APHY_SLOT_TIME 9 /* APHY slot time */ +#define APHY_SIFS_TIME 16 /* APHY SIFS time */ +#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) /* APHY DIFS time */ +#define APHY_PREAMBLE_TIME 16 /* APHY preamble time */ +#define APHY_SIGNAL_TIME 4 /* APHY signal time */ +#define APHY_SYMBOL_TIME 4 /* APHY symbol time */ +#define APHY_SERVICE_NBITS 16 /* APHY service nbits */ +#define APHY_TAIL_NBITS 6 /* APHY tail nbits */ +#define APHY_CWMIN 15 /* APHY cwmin */ + +/* 802.11 B PHY constants */ +#define BPHY_SLOT_TIME 20 /* BPHY slot time */ +#define BPHY_SIFS_TIME 10 /* BPHY SIFS time */ +#define BPHY_DIFS_TIME 50 /* BPHY DIFS time */ +#define BPHY_PLCP_TIME 192 /* BPHY PLCP time */ +#define BPHY_PLCP_SHORT_TIME 96 /* BPHY PLCP short time */ +#define BPHY_CWMIN 31 /* BPHY cwmin */ + +/* 802.11 G constants */ +#define DOT11_OFDM_SIGNAL_EXTENSION 6 /* d11 OFDM signal extension */ + +#define PHY_CWMAX 1023 /* PHY cwmax */ + +#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */ + +/* dot11Counters Table - 802.11 spec., Annex D */ +typedef struct d11cnt { + uint32 txfrag; /* dot11TransmittedFragmentCount */ + uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ + uint32 txfail; /* dot11FailedCount */ + uint32 txretry; /* dot11RetryCount */ + uint32 txretrie; /* dot11MultipleRetryCount */ + uint32 rxdup; /* dot11FrameduplicateCount */ + uint32 txrts; /* dot11RTSSuccessCount */ + uint32 txnocts; /* dot11RTSFailureCount */ + uint32 txnoack; /* dot11ACKFailureCount */ + uint32 rxfrag; /* dot11ReceivedFragmentCount */ + uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ + uint32 rxcrc; /* dot11FCSErrorCount */ + uint32 txfrmsnt; /* dot11TransmittedFrameCount */ + uint32 rxundec; /* dot11WEPUndecryptableCount */ +} d11cnt_t; + +/* BRCM OUI */ +#define BRCM_OUI "\x00\x10\x18" /* Broadcom OUI */ + +/* OUI for BRCM proprietary IE */ +#define BRCM_PROP_OUI "\x00\x90\x4C" /* Broadcom proprietary OUI */ + +/* BRCM info element */ +struct brcm_ie { + uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ + uint8 len; /* IE length */ + uint8 oui[3]; /* Proprietary OUI, BRCM_OUI */ + uint8 ver; /* type/ver of this IE */ + uint8 assoc; /* # of assoc STAs */ + uint8 flags; /* misc flags */ + uint8 flags1; /* misc flags */ + uint16 amsdu_mtu_pref; /* preferred A-MSDU MTU */ +} PACKED; +typedef struct brcm_ie brcm_ie_t; +#define BRCM_IE_LEN 11 /* BRCM IE length */ +#define BRCM_IE_VER 2 /* BRCM IE version */ +#define BRCM_IE_LEGACY_AES_VER 1 /* BRCM IE legacy AES version */ + +/* brcm_ie flags */ +#define BRF_ABCAP 0x1 /* afterburner capable */ +#define BRF_ABRQRD 0x2 /* afterburner requested */ +#define BRF_LZWDS 0x4 /* lazy wds enabled */ +#define BRF_BLOCKACK 0x8 /* BlockACK capable */ +#define BRF_ABCOUNTER_MASK 0xf0 /* afterburner wds "state" counter */ +#define BRF_ABCOUNTER_SHIFT 4 /* offset of afterburner wds "state" counter */ + +/* brcm_ie flags1 */ +#define BRF1_AMSDU 0x1 /* A-MSDU capable */ + +#define AB_WDS_TIMEOUT_MAX 15 /* afterburner wds Max count indicating not + * locally capable + */ +#define AB_WDS_TIMEOUT_MIN 1 /* afterburner wds, use zero count as indicating + * "downrev" + */ + +/* EWC definitions */ +#define MCSSET_LEN 16 /* 16-bits per 8-bit set to give 128-bits bitmap of MCS Index */ + +struct ewc_cap { + uint16 cap; + uint8 params; + uint8 supp_mcs[MCSSET_LEN]; + uint16 ext_htcap; + uint32 txbf_cap; + uint8 as_cap; +} PACKED; +typedef struct ewc_cap ewc_cap_t; + +/* CAP IE: EWC 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ +/* the capability IE is primarily used to convey this nodes abilities */ +struct ewc_cap_ie { + uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ + uint8 len; /* IE length */ + uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ + uint8 type; /* type inidicates what follows */ + ewc_cap_t cap; +} PACKED; +typedef struct ewc_cap_ie ewc_cap_ie_t; + +#define EWC_CAP_IE_LEN (26+4) +#define EWC_CAP_IE_TYPE 51 + +#define EWC_CAP_ADC_CODING 0x0001 /* Advance coding support */ +#define EWC_CAP_40MHZ 0x0002 /* FALSE:20Mhz, TRUE: 20 and 40MHZ supported */ +#define EWC_CAP_MIMO_PS_MASK 0x000C /* Mimo PS mask */ +#define EWC_CAP_MIMO_PS_SHIFT 0x0002 /* Mimo PS shift */ +#define EWC_CAP_MIMO_PS_OFF 0x0003 /* Mimo PS, no restriction */ +#define EWC_CAP_MIMO_PS_RTS 0x0001 /* Mimo PS, send RTS/CTS around MIMO frames */ +#define EWC_CAP_MIMO_PS_ON 0x0000 /* Mimo PS, MIMO disallowed */ +#define EWC_CAP_GF 0x0010 /* Greenfield preamble support */ +#define EWC_CAP_SHORT_GI_20 0x0020 /* 20MHZ short guard interval support */ +#define EWC_CAP_SHORT_GI_40 0x0040 /* 40Mhz short guard interval support */ +#define EWC_CAP_TX_STBC 0x0080 /* Tx STBC support */ +#define EWC_CAP_RX_STBC_MASK 0x0300 /* Rx STBC mask */ +#define EWC_CAP_RX_STBC_SHIFT 8 /* Rx STBC shift */ +#define EWC_CAP_DELAYED_BA 0x0400 /* delayed BA support */ +#define EWC_CAP_MAX_AMSDU 0x0800 /* Max AMSDU size in bytes , 0=3839, 1=7935 */ +#define EWC_CAP_DSSS_CCK 0x1000 /* DSSS/CCK supported by the BSS */ +#define EWC_CAP_PSMP 0x2000 /* Power Save Multi Poll support */ +#define EWC_CAP_STBC_CTL 0x4000 /* STBC control frame support */ +#define EWC_CAP_LSIG_TXOP 0x8000 /* L-SIG TXOP protection support */ + +#define EWC_MAX_AMSDU 7935 /* max amsdu size (bytes) per the EWC spec */ +#define EWC_MIN_AMSDU 3835 /* min amsdu size (bytes) per the EWC spec */ + +#define EWC_PARAMS_RX_FACTOR_MASK 0x03 /* ampdu rcv factor mask */ +#define EWC_PARAMS_DENSITY_MASK 0x1C /* ampdu density mask */ +#define EWC_PARAMS_DENSITY_SHIFT 2 /* ampdu density shift */ + +/* EWC/AMPDU specific define */ +#define AMPDU_MAX_MPDU_DENSITY 7 /* max mpdu density; in 1/8 usec units */ +#define AMPDU_MAX_RX_FACTOR 3 /* max rcv ampdu len (64kb) */ +#define AMPDU_RX_FACTOR_BASE 8*1024 /* ampdu factor base for rx len */ +#define AMPDU_DELIMITER_LEN 4 /* length of ampdu delimiter */ + +struct ewc_add { + uint8 ctl_ch; /* control channel number */ + uint8 byte1; /* ext ch,rec. ch. width, RIFS support */ + uint16 opmode; /* operation mode */ + uint16 misc_bits; /* misc bits */ + uint8 basic_mcs[MCSSET_LEN]; /* required MCS set */ +} PACKED; +typedef struct ewc_add ewc_add_t; + +/* ADD IE: EWC 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ +/* the additional IE is primarily used to convey the current BSS configuration */ +struct ewc_add_ie { + uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ + uint8 len; /* IE length */ + uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ + uint8 type; /* indicates what follows */ + ewc_add_t add; +} PACKED; +typedef struct ewc_add_ie ewc_add_ie_t; + +#define EWC_ADD_IE_LEN (22+4) +#define EWC_ADD_IE_TYPE 52 + +/* byte1 defn's */ +#define EWC_EXT_CH_MASK 0x03 /* extension channel mask */ +#define EWC_EXT_CH_UPPER 0x01 /* ext. ch. on upper sb */ +#define EWC_EXT_CH_LOWER 0x03 /* ext. ch. on lower sb */ +#define EWC_EXT_CH_NONE 0x00 /* extension channel mask */ +#define EWC_BW_ANY 0x04 /* set, STA can use 20 or 40MHz */ +#define EWC_RIFS_PERMITTED 0x08 /* RIFS allowed */ + +/* opmode defn's */ +#define EWC_OPMODE_MASK 0x0003 /* protection mode mask */ +#define EWC_OPMODE_PURE 0x0000 /* protection mode PURE */ +#define EWC_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ +#define EWC_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ +#define EWC_NONGF_PRESENT 0x0004 /* protection mode non-GF */ + +/* misc_bites defn's */ +#define EWC_BASIC_STBC_MCS 0x007f /* basic STBC MCS */ +#define EWC_DUAL_STBC_PROT 0x0080 /* Dual STBC Protection */ +#define EWC_SECOND_BCN 0x0100 /* Secondary beacon support */ +#define EWC_LSIG_TXOP 0x0200 /* L-SIG TXOP Protection full support */ +#define EWC_PCO_ACTIVE 0x0400 /* PCO active */ +#define EWC_PCO_PHASE 0x0800 /* PCO phase */ + +/* Macros for opmode */ +#define EWC_MIXEDMODE_PRESENT(add) ((ltoh16_ua(&add.opmode) & EWC_OPMODE_MASK) \ + == EWC_OPMODE_MIXED) /* mixed mode present */ +#define EWC_HT20_PRESENT(add) ((ltoh16_ua(&add.opmode) & EWC_OPMODE_MASK) \ + == EWC_OPMODE_HT20IN40) /* 20MHz HT present */ +#define EWC_USE_PROTECTION(add) (EWC_HT20_PRESENT((add)) || \ + EWC_MIXEDMODE_PRESENT((add))) /* use protection */ + +/* Vendor IE structure */ +struct vndr_ie { + uchar id; + uchar len; + uchar oui [3]; + uchar data [1]; /* Variable size data */ +}PACKED; +typedef struct vndr_ie vndr_ie_t; + +#define VNDR_IE_HDR_LEN 2 /* id + len field */ +#define VNDR_IE_MIN_LEN 3 /* size of the oui field */ +#define VNDR_IE_MAX_LEN 256 /* verdor IE max length */ + +/* WPA definitions */ +#define WPA_VERSION 1 /* WPA version */ +#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ + +#define WPA2_VERSION 1 /* WPA2 version */ +#define WPA2_VERSION_LEN 2 /* WAP2 version length */ +#define WPA2_OUI "\x00\x0F\xAC" /* WPA2 OUI */ + +#define WPA_OUI_LEN 3 /* WPA OUI length */ + +/* RSN authenticated key managment suite */ +#define RSN_AKM_NONE 0 /* None (IBSS) */ +#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ +#define RSN_AKM_PSK 2 /* Pre-shared Key */ + +/* Key related defines */ +#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */ +#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */ +#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */ +#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */ + +#define WEP1_KEY_SIZE 5 /* max size of any WEP key */ +#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */ +#define WEP128_KEY_SIZE 13 /* max size of any WEP key */ +#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */ +#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */ +#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */ +#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */ +#define TKIP_KEY_SIZE 32 /* size of any TKIP key */ +#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */ +#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */ +#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX /* offset to Supplicant MIC RX key */ +#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX /* offset to Supplicant MIC TX key */ +#define AES_KEY_SIZE 16 /* size of AES key */ + +#undef PACKED +#if !defined(__GNUC__) +#pragma pack() +#endif + +#endif /* _802_11_H_ */ diff --git a/package/broadcom-wl/src/wlc/include/proto/bcmeth.h b/package/broadcom-wl/src/wlc/include/proto/bcmeth.h new file mode 100644 index 0000000000..7b3295389a --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/proto/bcmeth.h @@ -0,0 +1,101 @@ +/* + * Broadcom Ethernettype protocol definitions + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: bcmeth.h,v 1.1.1.4 2006/02/27 03:43:16 honor Exp $ + */ + +/* + * Broadcom Ethernet protocol defines + */ + +#ifndef _BCMETH_H_ +#define _BCMETH_H_ + +/* enable structure packing */ +#if defined(__GNUC__) +#define PACKED __attribute__((packed)) +#else +#pragma pack(1) +#define PACKED +#endif + +/* ETHER_TYPE_BRCM is defined in ethernet.h */ + +/* + * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field + * in one of two formats: (only subtypes 32768-65535 are in use now) + * + * subtypes 0-32767: + * 8 bit subtype (0-127) + * 8 bit length in bytes (0-255) + * + * subtypes 32768-65535: + * 16 bit big-endian subtype + * 16 bit big-endian length in bytes (0-65535) + * + * length is the number of additional bytes beyond the 4 or 6 byte header + * + * Reserved values: + * 0 reserved + * 5-15 reserved for iLine protocol assignments + * 17-126 reserved, assignable + * 127 reserved + * 32768 reserved + * 32769-65534 reserved, assignable + * 65535 reserved + */ + +/* + * While adding the subtypes and their specific processing code make sure + * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition + */ + +#define BCMILCP_SUBTYPE_RATE 1 +#define BCMILCP_SUBTYPE_LINK 2 +#define BCMILCP_SUBTYPE_CSA 3 +#define BCMILCP_SUBTYPE_LARQ 4 +#define BCMILCP_SUBTYPE_VENDOR 5 +#define BCMILCP_SUBTYPE_FLH 17 + +#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 +#define BCMILCP_SUBTYPE_CERT 32770 +#define BCMILCP_SUBTYPE_SES 32771 + + +#define BCMILCP_BCM_SUBTYPE_RESERVED 0 +#define BCMILCP_BCM_SUBTYPE_EVENT 1 +#define BCMILCP_BCM_SUBTYPE_SES 2 +/* + * The EAPOL type is not used anymore. Instead EAPOL messages are now embedded + * within BCMILCP_BCM_SUBTYPE_EVENT type messages + */ +/* #define BCMILCP_BCM_SUBTYPE_EAPOL 3 */ + +#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 +#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 + +/* These fields are stored in network order */ +typedef struct bcmeth_hdr +{ + uint16 subtype; /* Vendor specific..32769 */ + uint16 length; + uint8 version; /* Version is 0 */ + uint8 oui[3]; /* Broadcom OUI */ + /* user specific Data */ + uint16 usr_subtype; +} PACKED bcmeth_hdr_t; + +#undef PACKED +#if !defined(__GNUC__) +#pragma pack() +#endif + +#endif /* _BCMETH_H_ */ diff --git a/package/broadcom-wl/src/wlc/include/proto/bcmevent.h b/package/broadcom-wl/src/wlc/include/proto/bcmevent.h new file mode 100644 index 0000000000..d922a5d215 --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/proto/bcmevent.h @@ -0,0 +1,152 @@ +/* + * Broadcom Event protocol definitions + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * + * Dependencies: proto/bcmeth.h + * + * $Id: bcmevent.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $ + * + */ + +/* + * Broadcom Ethernet Events protocol defines + * + */ + +#ifndef _BCMEVENT_H_ +#define _BCMEVENT_H_ + +/* enable structure packing */ +#if defined(__GNUC__) +#define PACKED __attribute__((packed)) +#else +#pragma pack(1) +#define PACKED +#endif /* defined(__GNUC__) */ + +#define BCM_EVENT_MSG_VERSION 1 /* wl_event_msg_t struct version */ +#define BCM_MSG_IFNAME_MAX 16 /* max length of interface name */ + +/* flags */ +#define WLC_EVENT_MSG_LINK 0x01 /* link is up */ +#define WLC_EVENT_MSG_FLUSHTXQ 0x02 /* flush tx queue on MIC error */ +#define WLC_EVENT_MSG_GROUP 0x04 /* group MIC error */ + +/* theses fields are stored in network order */ +typedef struct +{ + uint16 version; + uint16 flags; /* see flags below */ + uint32 event_type; /* Message (see below) */ + uint32 status; /* Status code (see below) */ + uint32 reason; /* Reason code (if applicable) */ + uint32 auth_type; /* WLC_E_AUTH */ + uint32 datalen; /* data buf */ + struct ether_addr addr; /* Station address (if applicable) */ + char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ +} PACKED wl_event_msg_t; + +/* used by driver msgs */ +typedef struct bcm_event { + struct ether_header eth; + bcmeth_hdr_t bcm_hdr; + wl_event_msg_t event; + /* data portion follows */ +} PACKED bcm_event_t; + +#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header)) + +/* Event messages */ +#define WLC_E_SET_SSID 0 /* indicates status of set SSID */ +#define WLC_E_JOIN 1 /* differentiates join IBSS from found (WLC_E_START) IBSS */ +#define WLC_E_START 2 /* STA founded an IBSS or AP started a BSS */ +#define WLC_E_AUTH 3 /* 802.11 AUTH request */ +#define WLC_E_AUTH_IND 4 /* 802.11 AUTH indication */ +#define WLC_E_DEAUTH 5 /* 802.11 DEAUTH request */ +#define WLC_E_DEAUTH_IND 6 /* 802.11 DEAUTH indication */ +#define WLC_E_ASSOC 7 /* 802.11 ASSOC request */ +#define WLC_E_ASSOC_IND 8 /* 802.11 ASSOC indication */ +#define WLC_E_REASSOC 9 /* 802.11 REASSOC request */ +#define WLC_E_REASSOC_IND 10 /* 802.11 REASSOC indication */ +#define WLC_E_DISASSOC 11 /* 802.11 DISASSOC request */ +#define WLC_E_DISASSOC_IND 12 /* 802.11 DISASSOC indication */ +#define WLC_E_QUIET_START 13 /* 802.11h Quiet period started */ +#define WLC_E_QUIET_END 14 /* 802.11h Quiet period ended */ +#define WLC_E_BEACON_RX 15 /* BEACONS received/lost indication */ +#define WLC_E_LINK 16 /* generic link indication */ +#define WLC_E_MIC_ERROR 17 /* TKIP MIC error occurred */ +#define WLC_E_NDIS_LINK 18 /* NDIS style link indication */ +#define WLC_E_ROAM 19 /* roam attempt occurred: indicate status & reason */ +#define WLC_E_TXFAIL 20 /* change in dot11FailedCount (txfail) */ +#define WLC_E_PMKID_CACHE 21 /* WPA2 pmkid cache indication */ +#define WLC_E_RETROGRADE_TSF 22 /* current AP's TSF value went backward */ +#define WLC_E_PRUNE 23 /* AP was pruned from join list for reason */ +#define WLC_E_AUTOAUTH 24 /* report AutoAuth table entry match for join attempt */ +#define WLC_E_EAPOL_MSG 25 /* Event encapsulating an EAPOL message */ +#define WLC_E_SCAN_COMPLETE 26 /* Scan results are ready or scan was aborted */ +#define WLC_E_ADDTS_IND 27 /* indicate to host addts fail/success */ +#define WLC_E_DELTS_IND 28 /* indicate to host delts fail/success */ +#define WLC_E_BCNSENT_IND 29 /* indicate to host of beacon transmit */ +#define WLC_E_BCNRX_MSG 30 /* Send the received beacon up to the host */ +#define WLC_E_LAST 31 /* highest val + 1 for range checking */ + +/* Event status codes */ +#define WLC_E_STATUS_SUCCESS 0 /* operation was successful */ +#define WLC_E_STATUS_FAIL 1 /* operation failed */ +#define WLC_E_STATUS_TIMEOUT 2 /* operation timed out */ +#define WLC_E_STATUS_NO_NETWORKS 3 /* failed due to no matching network found */ +#define WLC_E_STATUS_ABORT 4 /* operation was aborted */ +#define WLC_E_STATUS_NO_ACK 5 /* protocol failure: packet not ack'd */ +#define WLC_E_STATUS_UNSOLICITED 6 /* AUTH or ASSOC packet was unsolicited */ +#define WLC_E_STATUS_ATTEMPT 7 /* attempt to assoc to an auto auth configuration */ + +/* roam reason codes */ +#define WLC_E_REASON_INITIAL_ASSOC 0 /* initial assoc */ +#define WLC_E_REASON_LOW_RSSI 1 /* roamed due to low RSSI */ +#define WLC_E_REASON_DEAUTH 2 /* roamed due to DEAUTH indication */ +#define WLC_E_REASON_DISASSOC 3 /* roamed due to DISASSOC indication */ +#define WLC_E_REASON_BCNS_LOST 4 /* roamed due to lost beacons */ +#define WLC_E_REASON_FAST_ROAM_FAILED 5 /* roamed due to fast roam failure */ +#define WLC_E_REASON_DIRECTED_ROAM 6 /* roamed due to request by AP */ +#define WLC_E_REASON_TSPEC_REJECTED 7 /* roamed due to TSPEC rejection */ +#define WLC_E_REASON_BETTER_AP 8 /* roamed due to finding better AP */ + +/* prune reason codes */ +#define WLC_E_PRUNE_ENCR_MISMATCH 1 /* ecryption mismatch */ +#define WLC_E_PRUNE_BCAST_BSSID 2 /* AP uses a broadcast BSSID */ +#define WLC_E_PRUNE_MAC_DENY 3 /* STA's MAC addr is in AP's MAC deny list */ +#define WLC_E_PRUNE_MAC_NA 4 /* STA's MAC addr is not in AP's MAC allow list */ +#define WLC_E_PRUNE_REG_PASSV 5 /* AP not allowed due to regulatory restriction */ +#define WLC_E_PRUNE_SPCT_MGMT 6 /* AP does not support STA locale spectrum mgmt */ +#define WLC_E_PRUNE_RADAR 7 /* AP is on a radar channel of STA locale */ +#define WLC_E_RSN_MISMATCH 8 /* STA does not support AP's RSN */ +#define WLC_E_PRUNE_NO_COMMON_RATES 9 /* No rates in common with AP */ +#define WLC_E_PRUNE_BASIC_RATES 10 /* STA does not support all basic rates of BSS */ +#define WLC_E_PRUNE_CCXFAST_PREVAP 11 /* CCX FAST ROAM: prune previous AP */ +#define WLC_E_PRUNE_CIPHER_NA 12 /* BSS's cipher not supported */ +#define WLC_E_PRUNE_KNOWN_STA 13 /* AP is already known to us as a STA */ +#define WLC_E_PRUNE_CCXFAST_DROAM 14 /* CCX FAST ROAM: prune unqulified AP */ +#define WLC_E_PRUNE_WDS_PEER 15 /* AP is already known to us as a WDS peer */ +#define WLC_E_PRUNE_QBSS_LOAD 16 /* QBSS LOAD - AAC is too low */ +#define WLC_E_PRUNE_HOME_AP 17 /* prune home AP */ + +/* WLC_SET_CALLBACK data type */ +typedef struct wlc_event_cb { + void (*fn)(void *, bcm_event_t *); /* Callback function */ + void *context; /* Passed to callback function */ +} wlc_event_cb_t; + +#undef PACKED +#if !defined(__GNUC__) +#pragma pack() +#endif /* PACKED */ + +#endif /* _BCMEVENT_H_ */ diff --git a/package/broadcom-wl/src/wlc/include/proto/ethernet.h b/package/broadcom-wl/src/wlc/include/proto/ethernet.h new file mode 100644 index 0000000000..03fd4f654c --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/proto/ethernet.h @@ -0,0 +1,165 @@ +/* + * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: ethernet.h,v 1.1.1.14 2006/02/27 03:43:16 honor Exp $ + */ + +#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ +#define _NET_ETHERNET_H_ + +#ifndef _TYPEDEFS_H_ +#include "typedefs.h" +#endif + +/* enable structure packing */ +#if defined(__GNUC__) +#define PACKED __attribute__((packed)) +#else +#pragma pack(1) +#define PACKED +#endif + +/* + * The number of bytes in an ethernet (MAC) address. + */ +#define ETHER_ADDR_LEN 6 + +/* + * The number of bytes in the type field. + */ +#define ETHER_TYPE_LEN 2 + +/* + * The number of bytes in the trailing CRC field. + */ +#define ETHER_CRC_LEN 4 + +/* + * The length of the combined header. + */ +#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) + +/* + * The minimum packet length. + */ +#define ETHER_MIN_LEN 64 + +/* + * The minimum packet user data length. + */ +#define ETHER_MIN_DATA 46 + +/* + * The maximum packet length. + */ +#define ETHER_MAX_LEN 1518 + +/* + * The maximum packet user data length. + */ +#define ETHER_MAX_DATA 1500 + +/* ether types */ +#define ETHER_TYPE_IP 0x0800 /* IP */ +#define ETHER_TYPE_ARP 0x0806 /* ARP */ +#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ +#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */ +#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ +#ifdef BCMWPA2 +#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */ +#endif + +/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */ +#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */ +#define ETHER_BRCM_CRAM 0x1 /* Broadcom subtype cram protocol */ + +/* ether header */ +#define ETHER_DEST_OFFSET 0 /* dest address offset */ +#define ETHER_SRC_OFFSET 6 /* src address offset */ +#define ETHER_TYPE_OFFSET 12 /* ether type offset */ + +/* + * A macro to validate a length with + */ +#define ETHER_IS_VALID_LEN(foo) \ + ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) + + +#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ +/* + * Structure of a 10Mb/s Ethernet header. + */ +struct ether_header { + uint8 ether_dhost[ETHER_ADDR_LEN]; + uint8 ether_shost[ETHER_ADDR_LEN]; + uint16 ether_type; +} PACKED; + +/* + * Structure of a 48-bit Ethernet address. + */ +struct ether_addr { + uint8 octet[ETHER_ADDR_LEN]; +} PACKED; +#endif /* !__INCif_etherh Quick and ugly hack for VxWorks */ + +/* + * Takes a pointer, sets locally admininistered + * address bit in the 48-bit Ethernet address. + */ +#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2)) + +/* + * Takes a pointer, returns true if a 48-bit multicast address + * (including broadcast, since it is all ones) + */ +#define ETHER_ISMULTI(ea) (((uint8 *)(ea))[0] & 1) + + +/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */ +#define ether_cmp(a, b) (!(((short*)a)[0] == ((short*)b)[0]) | \ + !(((short*)a)[1] == ((short*)b)[1]) | \ + !(((short*)a)[2] == ((short*)b)[2])) + +/* copy an ethernet address - assumes the pointers can be referenced as shorts */ +#define ether_copy(s, d) { \ + ((short*)d)[0] = ((short*)s)[0]; \ + ((short*)d)[1] = ((short*)s)[1]; \ + ((short*)d)[2] = ((short*)s)[2]; } + +/* + * Takes a pointer, returns true if a 48-bit broadcast (all ones) + */ +#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ + ((uint8 *)(ea))[1] & \ + ((uint8 *)(ea))[2] & \ + ((uint8 *)(ea))[3] & \ + ((uint8 *)(ea))[4] & \ + ((uint8 *)(ea))[5]) == 0xff) + +static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; + +/* + * Takes a pointer, returns true if a 48-bit null address (all zeros) + */ +#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ + ((uint8 *)(ea))[1] | \ + ((uint8 *)(ea))[2] | \ + ((uint8 *)(ea))[3] | \ + ((uint8 *)(ea))[4] | \ + ((uint8 *)(ea))[5]) == 0) + +#undef PACKED +#if !defined(__GNUC__) +#pragma pack() +#endif + +#endif /* _NET_ETHERNET_H_ */ diff --git a/package/broadcom-wl/src/wlc/include/proto/wpa.h b/package/broadcom-wl/src/wlc/include/proto/wpa.h new file mode 100644 index 0000000000..dd35dbef02 --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/proto/wpa.h @@ -0,0 +1,148 @@ +/* + * Fundamental types and constants relating to WPA + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: wpa.h,v 1.1.1.4 2006/02/27 03:43:16 honor Exp $ + */ + +#ifndef _proto_wpa_h_ +#define _proto_wpa_h_ + +#include +#include + +/* enable structure packing */ +#if defined(__GNUC__) +#define PACKED __attribute__((packed)) +#else +#pragma pack(1) +#define PACKED +#endif + +/* Reason Codes */ + +/* 10 and 11 are from TGh. */ +#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */ +#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */ +/* 12 is unused */ +/* 13 through 23 taken from P802.11i/D3.0, November 2002 */ +#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */ +#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */ +#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */ +#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */ +#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from + * (re-)assoc. request/probe response + */ +#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */ +#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */ +#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */ +#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */ +#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */ +#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */ + +#define WPA2_PMKID_LEN 16 + +/* WPA IE fixed portion */ +typedef struct +{ + uint8 tag; /* TAG */ + uint8 length; /* TAG length */ + uint8 oui[3]; /* IE OUI */ + uint8 oui_type; /* OUI type */ + struct { + uint8 low; + uint8 high; + } PACKED version; /* IE version */ +} PACKED wpa_ie_fixed_t; +#define WPA_IE_OUITYPE_LEN 4 +#define WPA_IE_FIXED_LEN 8 +#define WPA_IE_TAG_FIXED_LEN 6 + +#ifdef BCMWPA2 +typedef struct { + uint8 tag; /* TAG */ + uint8 length; /* TAG length */ + struct { + uint8 low; + uint8 high; + } PACKED version; /* IE version */ +} PACKED wpa_rsn_ie_fixed_t; +#define WPA_RSN_IE_FIXED_LEN 4 +#define WPA_RSN_IE_TAG_FIXED_LEN 2 +typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; +#endif + +/* WPA suite/multicast suite */ +typedef struct +{ + uint8 oui[3]; + uint8 type; +} PACKED wpa_suite_t, wpa_suite_mcast_t; +#define WPA_SUITE_LEN 4 + +/* WPA unicast suite list/key management suite list */ +typedef struct +{ + struct { + uint8 low; + uint8 high; + } PACKED count; + wpa_suite_t list[1]; +} PACKED wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; +#define WPA_IE_SUITE_COUNT_LEN 2 +#ifdef BCMWPA2 +typedef struct +{ + struct { + uint8 low; + uint8 high; + } PACKED count; + wpa_pmkid_t list[1]; +} PACKED wpa_pmkid_list_t; +#endif + +/* WPA cipher suites */ +#define WPA_CIPHER_NONE 0 /* None */ +#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */ +#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */ +#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */ +#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */ +#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ + +#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ + (cipher) == WPA_CIPHER_WEP_40 || \ + (cipher) == WPA_CIPHER_WEP_104 || \ + (cipher) == WPA_CIPHER_TKIP || \ + (cipher) == WPA_CIPHER_AES_OCB || \ + (cipher) == WPA_CIPHER_AES_CCM) + +/* WPA TKIP countermeasures parameters */ +#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ +#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ + +/* WPA capabilities defined in 802.11i */ +#define WPA_CAP_4_REPLAY_CNTRS 2 +#define WPA_CAP_16_REPLAY_CNTRS 3 +#define WPA_CAP_REPLAY_CNTR_SHIFT 2 +#define WPA_CAP_REPLAY_CNTR_MASK 0x000c + +/* WPA Specific defines */ +#define WPA_CAP_LEN 2 /* Length of RSN capabilities in RSN IE (2 octets) */ + +#ifdef BCMWPA2 +#define WPA_CAP_WPA2_PREAUTH 1 +#endif /* BCMWPA2 */ + +#undef PACKED +#if !defined(__GNUC__) +#pragma pack() +#endif + +#endif /* _proto_wpa_h_ */ diff --git a/package/broadcom-wl/src/wlc/include/typedefs.h b/package/broadcom-wl/src/wlc/include/typedefs.h new file mode 100644 index 0000000000..6c498bbcb2 --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/typedefs.h @@ -0,0 +1,230 @@ +/* + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * $Id: typedefs.h,v 1.1.1.12 2006/04/08 06:13:40 honor Exp $ + */ + +#ifndef _TYPEDEFS_H_ +#define _TYPEDEFS_H_ + +/* + * Inferred Typedefs + * + */ + +/* Infer the compile environment based on preprocessor symbols and pramas. + * Override type definitions as needed, and include configuration dependent + * header files to define types. + */ + +#ifdef __cplusplus + +#define TYPEDEF_BOOL +#ifndef FALSE +#define FALSE false +#endif +#ifndef TRUE +#define TRUE true +#endif + +#endif /* __cplusplus */ + +#if defined(_NEED_SIZE_T_) +typedef long unsigned int size_t; +#endif + +#define TYPEDEF_UINT +#define TYPEDEF_USHORT +#define TYPEDEF_ULONG + + +/* Do not support the (u)int64 types with strict ansi for GNU C */ +#if defined(__GNUC__) && defined(__STRICT_ANSI__) +#define TYPEDEF_INT64 +#define TYPEDEF_UINT64 +#endif + +/* pick up ushort & uint from standard types.h */ +#if defined(linux) && defined(__KERNEL__) +#include /* sys/types.h and linux/types.h are oil and water */ +#else +#include +#endif + +/* use the default typedefs in the next section of this file */ +#define USE_TYPEDEF_DEFAULTS + +/* + * Default Typedefs + * + */ + +#ifdef USE_TYPEDEF_DEFAULTS +#undef USE_TYPEDEF_DEFAULTS + +#ifndef TYPEDEF_BOOL +typedef /* @abstract@ */ unsigned char bool; +#endif + +/* define uchar, ushort, uint, ulong */ + +#ifndef TYPEDEF_UCHAR +typedef unsigned char uchar; +#endif + +#ifndef TYPEDEF_USHORT +typedef unsigned short ushort; +#endif + +#ifndef TYPEDEF_UINT +typedef unsigned int uint; +#endif + +#ifndef TYPEDEF_ULONG +typedef unsigned long ulong; +#endif + +/* define [u]int8/16/32/64, uintptr */ + +#ifndef TYPEDEF_UINT8 +typedef unsigned char uint8; +#endif + +#ifndef TYPEDEF_UINT16 +typedef unsigned short uint16; +#endif + +#ifndef TYPEDEF_UINT32 +typedef unsigned int uint32; +#endif + +#ifndef TYPEDEF_UINT64 +typedef unsigned long long uint64; +#endif + +#ifndef TYPEDEF_UINTPTR +typedef unsigned int uintptr; +#endif + +#ifndef TYPEDEF_INT8 +typedef signed char int8; +#endif + +#ifndef TYPEDEF_INT16 +typedef signed short int16; +#endif + +#ifndef TYPEDEF_INT32 +typedef signed int int32; +#endif + +#ifndef TYPEDEF_INT64 +typedef signed long long int64; +#endif + +/* define float32/64, float_t */ + +#ifndef TYPEDEF_FLOAT32 +typedef float float32; +#endif + +#ifndef TYPEDEF_FLOAT64 +typedef double float64; +#endif + +/* + * abstracted floating point type allows for compile time selection of + * single or double precision arithmetic. Compiling with -DFLOAT32 + * selects single precision; the default is double precision. + */ + +#ifndef TYPEDEF_FLOAT_T + +#if defined(FLOAT32) +typedef float32 float_t; +#else /* default to double precision floating point */ +typedef float64 float_t; +#endif + +#endif /* TYPEDEF_FLOAT_T */ + +/* define macro values */ + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 /* TRUE */ +#endif + +#ifndef NULL +#define NULL 0 +#endif + +#ifndef OFF +#define OFF 0 +#endif + +#ifndef ON +#define ON 1 /* ON = 1 */ +#endif + +#define AUTO (-1) /* Auto = -1 */ + +/* define PTRSZ, INLINE */ + +#ifndef PTRSZ +#define PTRSZ sizeof(char*) +#endif + +#ifndef INLINE + +#ifdef _MSC_VER + +#define INLINE __inline + +#elif __GNUC__ + +#define INLINE __inline__ + +#else + +#define INLINE + +#endif /* _MSC_VER */ + +#endif /* INLINE */ + +#undef TYPEDEF_BOOL +#undef TYPEDEF_UCHAR +#undef TYPEDEF_USHORT +#undef TYPEDEF_UINT +#undef TYPEDEF_ULONG +#undef TYPEDEF_UINT8 +#undef TYPEDEF_UINT16 +#undef TYPEDEF_UINT32 +#undef TYPEDEF_UINT64 +#undef TYPEDEF_UINTPTR +#undef TYPEDEF_INT8 +#undef TYPEDEF_INT16 +#undef TYPEDEF_INT32 +#undef TYPEDEF_INT64 +#undef TYPEDEF_FLOAT32 +#undef TYPEDEF_FLOAT64 +#undef TYPEDEF_FLOAT_T + +#endif /* USE_TYPEDEF_DEFAULTS */ + +/* + * Including the bcmdefs.h here, to make sure everyone including typedefs.h + * gets this automatically +*/ +#include + +#endif /* _TYPEDEFS_H_ */ diff --git a/package/broadcom-wl/src/wlc/include/wlioctl.h b/package/broadcom-wl/src/wlc/include/wlioctl.h new file mode 100644 index 0000000000..0558415d33 --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/wlioctl.h @@ -0,0 +1,1384 @@ +/* + * Custom OID/ioctl definitions for + * Broadcom 802.11abg Networking Device Driver + * + * Definitions subject to change without notice. + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: wlioctl.h,v 1.1.1.22 2006/04/15 01:29:08 michael Exp $ + */ + +#ifndef _wlioctl_h_ +#define _wlioctl_h_ + +#include +#include +#include +#include +#include + +#ifdef __NetBSD__ +/* NetBSD 2.0 does not have SIOCDEVPRIVATE. This is NetBSD 2.0 specific */ +#define SIOCDEVPRIVATE _IOWR('i', 139, struct ifreq) +#endif + +/* require default structure packing */ +#if !defined(__GNUC__) +#pragma pack(push, 8) +#endif + +/* A chanspec holds the channel number, band, bandwidth and control sideband */ +typedef uint16 chanspec_t; +#define WL_CHANSPEC_CHAN_MASK 0x00ff + +#define WL_CHANSPEC_CTL_SB_MASK 0x0300 +#define WL_CHANSPEC_CTL_SB_SHIFT 8 +#define WL_CHANSPEC_CTL_SB_LOWER 0x0100 +#define WL_CHANSPEC_CTL_SB_UPPER 0x0200 +#define WL_CHANSPEC_CTL_SB_NONE 0x0300 + +#define WL_CHANSPEC_BW_MASK 0x0C00 +#define WL_CHANSPEC_BW_SHIFT 10 +#define WL_CHANSPEC_BW_10 0x0400 +#define WL_CHANSPEC_BW_20 0x0800 +#define WL_CHANSPEC_BW_40 0x0C00 + +#define WL_CHANSPEC_BAND_MASK 0xf000 +#define WL_CHANSPEC_BAND_SHIFT 12 +#define WL_CHANSPEC_BAND_5G 0x1000 +#define WL_CHANSPEC_BAND_2G 0x2000 +#define INVCHANSPEC 255 + +/* Legacy structure to help keep backward compatible wl tool and tray app */ + +#define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */ + +typedef struct wl_bss_info_107 { + uint32 version; /* version field */ + uint32 length; /* byte length of data in this record, + * starting at version and including IEs + */ + struct ether_addr BSSID; + uint16 beacon_period; /* units are Kusec */ + uint16 capability; /* Capability information */ + uint8 SSID_len; + uint8 SSID[32]; + struct { + uint count; /* # rates in this set */ + uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ + } rateset; /* supported rates */ + uint8 channel; /* Channel no. */ + uint16 atim_window; /* units are Kusec */ + uint8 dtim_period; /* DTIM period */ + int16 RSSI; /* receive signal strength (in dBm) */ + int8 phy_noise; /* noise (in dBm) */ + uint32 ie_length; /* byte length of Information Elements */ + /* variable length Information Elements */ +} wl_bss_info_107_t; + +/* + * Per-bss information structure. + */ + +#define WL_BSS_INFO_VERSION 108 /* current version of wl_bss_info struct */ + +/* BSS info structure + * Applications MUST CHECK ie_offset field and length field to access IEs and + * next bss_info structure in a vector (in wl_scan_results_t) + */ +typedef struct wl_bss_info { + uint32 version; /* version field */ + uint32 length; /* byte length of data in this record, + * starting at version and including IEs + */ + struct ether_addr BSSID; + uint16 beacon_period; /* units are Kusec */ + uint16 capability; /* Capability information */ + uint8 SSID_len; + uint8 SSID[32]; + struct { + uint count; /* # rates in this set */ + uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ + } rateset; /* supported rates */ + chanspec_t chanspec; /* chanspec for bss */ + uint16 atim_window; /* units are Kusec */ + uint8 dtim_period; /* DTIM period */ + int16 RSSI; /* receive signal strength (in dBm) */ + int8 phy_noise; /* noise (in dBm) */ + + bool n_cap; /* BSS is 802.11N Capable */ + uint32 nbss_cap; /* 802.11N BSS Capabilities (based on EWC_CAP_*) */ + uint8 ctl_ch; /* 802.11N BSS control channel number */ + uint32 reserved[2]; /* Reserved for expansion of BSS properties */ + uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ + + uint16 ie_offset; /* offset at which IEs start, from beginning */ + uint32 ie_length; /* byte length of Information Elements */ + /* Add new fields here */ + /* variable length Information Elements */ +} wl_bss_info_t; + +typedef struct wlc_ssid { + uint32 SSID_len; + uchar SSID[32]; +} wlc_ssid_t; + +typedef struct wl_scan_params { + wlc_ssid_t ssid; /* default: {0, ""} */ + struct ether_addr bssid; /* default: bcast */ + int8 bss_type; /* default: any, + * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT + */ + int8 scan_type; /* -1 use default, DOT11_SCANTYPE_ACTIVE/PASSIVE */ + int32 nprobes; /* -1 use default, number of probes per channel */ + int32 active_time; /* -1 use default, dwell time per channel for + * active scanning + */ + int32 passive_time; /* -1 use default, dwell time per channel + * for passive scanning + */ + int32 home_time; /* -1 use default, dwell time for the home channel + * between channel scans + */ + int32 channel_num; /* 0 use default (all available channels), count of + * channels in channel_list + */ + uint16 channel_list[1]; /* list of chanspecs */ +} wl_scan_params_t; +/* size of wl_scan_params not including variable length array */ +#define WL_SCAN_PARAMS_FIXED_SIZE 64 + +typedef struct wl_scan_results { + uint32 buflen; + uint32 version; + uint32 count; + wl_bss_info_t bss_info[1]; +} wl_scan_results_t; +/* size of wl_scan_results not including variable length array */ +#define WL_SCAN_RESULTS_FIXED_SIZE 12 + + +#define WL_NUMRATES 255 /* max # of rates in a rateset */ +typedef struct wl_rateset { + uint32 count; /* # rates in this set */ + uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ +} wl_rateset_t; + +/* uint32 list */ +typedef struct wl_uint32_list { + /* in - # of elements, out - # of entries */ + uint32 count; + /* variable length uint32 list */ + uint32 element[1]; +} wl_uint32_list_t; + +#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NULL */ + +/* defines used by the nrate iovar */ +#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ +#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ +#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ +#define NRATE_STF_SHIFT 8 /* stf mode shift */ + +#define ANTENNA_NUM_1 1 /* total number of antennas to be used */ +#define ANTENNA_NUM_2 2 +#define ANTENNA_NUM_3 3 +#define ANTENNA_NUM_4 4 + +typedef struct wl_channels_in_country { + uint32 buflen; + uint32 band; + char country_abbrev[WLC_CNTRY_BUF_SZ]; + uint32 count; + uint32 channel[1]; +} wl_channels_in_country_t; + +typedef struct wl_country_list { + uint32 buflen; + uint32 band_set; + uint32 band; + uint32 count; + char country_abbrev[1]; +} wl_country_list_t; + +#define WL_RM_TYPE_BASIC 1 +#define WL_RM_TYPE_CCA 2 +#define WL_RM_TYPE_RPI 3 + +#define WL_RM_FLAG_PARALLEL (1<<0) + +#define WL_RM_FLAG_LATE (1<<1) +#define WL_RM_FLAG_INCAPABLE (1<<2) +#define WL_RM_FLAG_REFUSED (1<<3) + +typedef struct wl_rm_req_elt { + int8 type; + int8 flags; + chanspec_t chanspec; + uint32 token; /* token for this measurement */ + uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ + uint32 tsf_l; /* TSF low 32-bits */ + uint32 dur; /* TUs */ +} wl_rm_req_elt_t; + +typedef struct wl_rm_req { + uint32 token; /* overall measurement set token */ + uint32 count; /* number of measurement requests */ + wl_rm_req_elt_t req[1]; /* variable length block of requests */ +} wl_rm_req_t; +#define WL_RM_REQ_FIXED_LEN 8 + +typedef struct wl_rm_rep_elt { + int8 type; + int8 flags; + chanspec_t chanspec; + uint32 token; /* token for this measurement */ + uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ + uint32 tsf_l; /* TSF low 32-bits */ + uint32 dur; /* TUs */ + uint32 len; /* byte length of data block */ + uint8 data[1]; /* variable length data block */ +} wl_rm_rep_elt_t; +#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ + +#define WL_RPI_REP_BIN_NUM 8 +typedef struct wl_rm_rpi_rep { + uint8 rpi[WL_RPI_REP_BIN_NUM]; + int8 rpi_max[WL_RPI_REP_BIN_NUM]; +} wl_rm_rpi_rep_t; + +typedef struct wl_rm_rep { + uint32 token; /* overall measurement set token */ + uint32 len; /* length of measurement report block */ + wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ +} wl_rm_rep_t; +#define WL_RM_REP_FIXED_LEN 8 + + +#if defined(BCMSUP_PSK) +typedef enum sup_auth_status { + WLC_SUP_DISCONNECTED = 0, + WLC_SUP_CONNECTING, + WLC_SUP_IDREQUIRED, + WLC_SUP_AUTHENTICATING, + WLC_SUP_AUTHENTICATED, + WLC_SUP_KEYXCHANGE, + WLC_SUP_KEYED, + WLC_SUP_TIMEOUT +} sup_auth_status_t; +#endif /* BCMCCX | BCMSUP_PSK */ + +/* Enumerate crypto algorithms */ +#define CRYPTO_ALGO_OFF 0 +#define CRYPTO_ALGO_WEP1 1 +#define CRYPTO_ALGO_TKIP 2 +#define CRYPTO_ALGO_WEP128 3 +#define CRYPTO_ALGO_AES_CCM 4 +#define CRYPTO_ALGO_AES_OCB_MSDU 5 +#define CRYPTO_ALGO_AES_OCB_MPDU 6 +#define CRYPTO_ALGO_NALG 7 + +#define WSEC_GEN_MIC_ERROR 0x0001 +#define WSEC_GEN_REPLAY 0x0002 + +#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ +#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ +#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ +#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ + +typedef struct wl_wsec_key { + uint32 index; /* key index */ + uint32 len; /* key length */ + uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */ + uint32 pad_1[18]; + uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + uint32 flags; /* misc flags */ + uint32 pad_2[2]; + int pad_3; + int iv_initialized; /* has IV been initialized already? */ + int pad_4; + /* Rx IV */ + struct { + uint32 hi; /* upper 32 bits of IV */ + uint16 lo; /* lower 16 bits of IV */ + } rxiv; + uint32 pad_5[2]; + struct ether_addr ea; /* per station */ +} wl_wsec_key_t; + +#define WSEC_MIN_PSK_LEN 8 +#define WSEC_MAX_PSK_LEN 64 + +/* Flag for key material needing passhash'ing */ +#define WSEC_PASSPHRASE (1<<0) + +/* receptacle for WLC_SET_WSEC_PMK parameter */ +typedef struct { + ushort key_len; /* octets in key material */ + ushort flags; /* key handling qualification */ + uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ +} wsec_pmk_t; + +/* wireless security bitvec */ +#define WEP_ENABLED 0x0001 +#define TKIP_ENABLED 0x0002 +#define AES_ENABLED 0x0004 +#define WSEC_SWFLAG 0x0008 +#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ +#define FIPS_ENABLED 0x0080 + +/* WPA authentication mode bitvec */ +#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ +#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ +#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ +#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ +/* #define WPA_AUTH_8021X 0x0020 */ /* 802.1x, reserved */ +#ifdef BCMWPA2 +#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ +#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ +#endif /* BCMWPA2 */ + +#ifdef BCMWPA2 +/* pmkid */ +#define MAXPMKID 16 + +typedef struct _pmkid +{ + struct ether_addr BSSID; + uint8 PMKID[WPA2_PMKID_LEN]; +} pmkid_t; + +typedef struct _pmkid_list +{ + uint32 npmkid; + pmkid_t pmkid[1]; +} pmkid_list_t; + +typedef struct _pmkid_cand { + struct ether_addr BSSID; + uint8 preauth; +} pmkid_cand_t; + +typedef struct _pmkid_cand_list { + uint32 npmkid_cand; + pmkid_cand_t pmkid_cand[1]; +} pmkid_cand_list_t; +#endif /* BCMWPA2 */ + +typedef struct wl_led_info { + uint32 index; /* led index */ + uint32 behavior; + bool activehi; +} wl_led_info_t; + +typedef struct wlc_assoc_info { + uint32 req_len; + uint32 resp_len; + uint32 flags; + struct dot11_assoc_req req; + struct ether_addr reassoc_bssid; /* used in reassoc's */ + struct dot11_assoc_resp resp; +} wl_assoc_info_t; +/* flags */ +#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ +/* srom read/write struct passed through ioctl */ +typedef struct { + uint byteoff; /* byte offset */ + uint nbytes; /* number of bytes */ + uint16 buf[1]; +} srom_rw_t; + +/* R_REG and W_REG struct passed through ioctl */ +typedef struct { + uint32 byteoff; /* byte offset of the field in d11regs_t */ + uint32 val; /* read/write value of the field */ + uint32 size; /* sizeof the field */ + uint band; /* band (optional) */ +} rw_reg_t; + +/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */ +/* PCL - Power Control Loop */ +/* current gain setting is replaced by user input */ +#define WL_ATTEN_APP_INPUT_PCL_OFF 0 /* turn off PCL, apply supplied input */ +#define WL_ATTEN_PCL_ON 1 /* turn on PCL */ +/* current gain setting is maintained */ +#define WL_ATTEN_PCL_OFF 2 /* turn off PCL. */ +typedef struct { + uint16 auto_ctrl; /* WL_ATTEN_XX */ + uint16 bb; /* Baseband attenuation */ + uint16 radio; /* Radio attenuation */ + uint16 txctl1; /* Radio TX_CTL1 value */ +} atten_t; + +/* defines used by poweridx iovar - it controls power in a-band */ +/* current gain setting is maintained */ +#define WL_PWRIDX_PCL_OFF -2 /* turn off PCL. */ +#define WL_PWRIDX_PCL_ON -1 /* turn on PCL */ +#define WL_PWRIDX_LOWER_LIMIT -2 /* lower limit */ +#define WL_PWRIDX_UPPER_LIMIT 63 /* upper limit */ +/* value >= 0 causes + * - input to be set to that value + * - PCL to be off + */ + +/* Used to get specific STA parameters */ +typedef struct { + uint32 val; + struct ether_addr ea; +} scb_val_t; + + +/* Event data type */ +typedef struct wlc_event { + wl_event_msg_t event; /* encapsulated event */ + struct ether_addr *addr; /* used to keep a trace of the potential present of + * an address in wlc_event_msg_t + */ + void *data; /* used to hang additional data on an event */ + struct wlc_event *next; /* enables ordered list of pending events */ +} wlc_event_t; + +#define BCM_MAC_STATUS_INDICATION (0x40010200L) + +/* Please update the following when modifying this structure: + * StaInfo Twiki page flags section - description of the sta_info_t struct + * src/wl/exe/wlu.c - print of sta_info_t + * Pay attention to version if structure changes. + */ +typedef struct { + uint16 ver; /* version of this struct */ + uint16 len; /* length in bytes of this structure */ + uint16 cap; /* sta's advertised capabilities */ + uint32 flags; /* flags defined below */ + uint32 idle; /* time since data pkt rx'd from sta */ + struct ether_addr ea; /* Station address */ + wl_rateset_t rateset; /* rateset in use */ + uint32 in; /* seconds elapsed since associated */ + uint32 listen_interval_inms; /* Min Listen interval in ms for this STA */ +} sta_info_t; + +#define WL_STA_VER 2 + +/* Flags for sta_info_t indicating properties of STA */ +#define WL_STA_BRCM 0x1 /* Running a Broadcom driver */ +#define WL_STA_WME 0x2 /* WMM association */ +#define WL_STA_ABCAP 0x4 /* Afterburner-capable */ +#define WL_STA_AUTHE 0x8 /* Authenticated */ +#define WL_STA_ASSOC 0x10 /* Associated */ +#define WL_STA_AUTHO 0x20 /* Authorized */ +#define WL_STA_WDS 0x40 /* Wireless Distribution System */ +#define WL_STA_WDS_LINKUP 0x80 /* WDS traffic/probes flowing properly */ +#define WL_STA_PS 0x100 /* STA is in power save mode from AP's viewpoint */ +#define WL_STA_APSD_BE 0x200 /* APSD delv/trigger for AC_BE is default enabled */ +#define WL_STA_APSD_BK 0x400 /* APSD delv/trigger for AC_BK is default enabled */ +#define WL_STA_APSD_VI 0x800 /* APSD delv/trigger for AC_VI is default enabled */ +#define WL_STA_APSD_VO 0x1000 /* APSD delv/trigger for AC_VO is default enabled */ +#define WL_STA_N_CAP 0x2000 /* STA 802.11n capable */ + +#define WL_WDS_LINKUP WL_STA_WDS_LINKUP /* deprecated */ + +/* + * Country locale determines which channels are available to us. + */ +typedef enum _wlc_locale { + WLC_WW = 0, /* Worldwide */ + WLC_THA, /* Thailand */ + WLC_ISR, /* Israel */ + WLC_JDN, /* Jordan */ + WLC_PRC, /* China */ + WLC_JPN, /* Japan */ + WLC_FCC, /* USA */ + WLC_EUR, /* Europe */ + WLC_USL, /* US Low Band only */ + WLC_JPH, /* Japan High Band only */ + WLC_ALL, /* All the channels in this band */ + WLC_11D, /* Represents locale received by 11d beacons */ + WLC_LAST_LOCALE, + WLC_UNDEFINED_LOCALE = 0xf +} wlc_locale_t; + +/* channel encoding */ +typedef struct channel_info { + int hw_channel; + int target_channel; + int scan_channel; +} channel_info_t; + +/* For ioctls that take a list of MAC addresses */ +struct maclist { + uint count; /* number of MAC addresses */ + struct ether_addr ea[1]; /* variable length array of MAC addresses */ +}; + +/* get pkt count struct passed through ioctl */ +typedef struct get_pktcnt { + uint rx_good_pkt; + uint rx_bad_pkt; + uint tx_good_pkt; + uint tx_bad_pkt; +} get_pktcnt_t; + +/* Linux network driver ioctl encoding */ +typedef struct wl_ioctl { + uint cmd; /* common ioctl definition */ + void *buf; /* pointer to user buffer */ + uint len; /* length of user buffer */ + bool set; /* get or set request (optional) */ + uint used; /* bytes read or written (optional) */ + uint needed; /* bytes needed (optional) */ +} wl_ioctl_t; + +/* + * Structure for passing hardware and software + * revision info up from the driver. + */ +typedef struct wlc_rev_info { + uint vendorid; /* PCI vendor id */ + uint deviceid; /* device id of chip */ + uint radiorev; /* radio revision */ + uint chiprev; /* chip revision */ + uint corerev; /* core revision */ + uint boardid; /* board identifier (usu. PCI sub-device id) */ + uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ + uint boardrev; /* board revision */ + uint driverrev; /* driver version */ + uint ucoderev; /* microcode version */ + uint bus; /* bus type */ + uint chipnum; /* chip number */ +} wlc_rev_info_t; + +#define WL_BRAND_MAX 10 +typedef struct wl_instance_info { + uint instance; + char brand[WL_BRAND_MAX]; +} wl_instance_info_t; + +/* check this magic number */ +#define WLC_IOCTL_MAGIC 0x14e46c77 + +/* bump this number if you change the ioctl interface */ +#define WLC_IOCTL_VERSION 1 + +#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ +#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ + +/* common ioctl definitions */ +#define WLC_GET_MAGIC 0 +#define WLC_GET_VERSION 1 +#define WLC_UP 2 +#define WLC_DOWN 3 +#define WLC_DUMP 6 +#define WLC_GET_MSGLEVEL 7 +#define WLC_SET_MSGLEVEL 8 +#define WLC_GET_PROMISC 9 +#define WLC_SET_PROMISC 10 +#define WLC_GET_RATE 12 +/* #define WLC_SET_RATE 13 */ /* no longer supported */ +#define WLC_GET_INSTANCE 14 +/* #define WLC_GET_FRAG 15 */ /* no longer supported */ +/* #define WLC_SET_FRAG 16 */ /* no longer supported */ +/* #define WLC_GET_RTS 17 */ /* no longer supported */ +/* #define WLC_SET_RTS 18 */ /* no longer supported */ +#define WLC_GET_INFRA 19 +#define WLC_SET_INFRA 20 +#define WLC_GET_AUTH 21 +#define WLC_SET_AUTH 22 +#define WLC_GET_BSSID 23 +#define WLC_SET_BSSID 24 +#define WLC_GET_SSID 25 +#define WLC_SET_SSID 26 +#define WLC_RESTART 27 +#define WLC_GET_CHANNEL 29 +#define WLC_SET_CHANNEL 30 +#define WLC_GET_SRL 31 +#define WLC_SET_SRL 32 +#define WLC_GET_LRL 33 +#define WLC_SET_LRL 34 +#define WLC_GET_PLCPHDR 35 +#define WLC_SET_PLCPHDR 36 +#define WLC_GET_RADIO 37 +#define WLC_SET_RADIO 38 +#define WLC_GET_PHYTYPE 39 +/* #define WLC_GET_WEP 42 */ /* no longer supported */ +/* #define WLC_SET_WEP 43 */ /* no longer supported */ +#define WLC_GET_KEY 44 +#define WLC_SET_KEY 45 +#define WLC_GET_REGULATORY 46 +#define WLC_SET_REGULATORY 47 +#define WLC_GET_PASSIVE 48 +#define WLC_SET_PASSIVE 49 +#define WLC_SCAN 50 +#define WLC_SCAN_RESULTS 51 +#define WLC_DISASSOC 52 +#define WLC_REASSOC 53 +#define WLC_GET_ROAM_TRIGGER 54 +#define WLC_SET_ROAM_TRIGGER 55 +#define WLC_GET_TXANT 61 +#define WLC_SET_TXANT 62 +#define WLC_GET_ANTDIV 63 +#define WLC_SET_ANTDIV 64 +/* #define WLC_GET_TXPWR 65 */ /* no longer supported */ +/* #define WLC_SET_TXPWR 66 */ /* no longer supported */ +#define WLC_GET_CLOSED 67 +#define WLC_SET_CLOSED 68 +#define WLC_GET_MACLIST 69 +#define WLC_SET_MACLIST 70 +#define WLC_GET_RATESET 71 +#define WLC_SET_RATESET 72 +#define WLC_GET_LOCALE 73 +#define WLC_LONGTRAIN 74 +#define WLC_GET_BCNPRD 75 +#define WLC_SET_BCNPRD 76 +#define WLC_GET_DTIMPRD 77 +#define WLC_SET_DTIMPRD 78 +#define WLC_GET_SROM 79 +#define WLC_SET_SROM 80 +#define WLC_GET_WEP_RESTRICT 81 +#define WLC_SET_WEP_RESTRICT 82 +#define WLC_GET_COUNTRY 83 +#define WLC_SET_COUNTRY 84 +#define WLC_GET_PM 85 +#define WLC_SET_PM 86 +#define WLC_GET_WAKE 87 +#define WLC_SET_WAKE 88 +#define WLC_GET_D11CNTS 89 +#define WLC_GET_FORCELINK 90 /* ndis only */ +#define WLC_SET_FORCELINK 91 /* ndis only */ +#define WLC_FREQ_ACCURACY 92 +#define WLC_CARRIER_SUPPRESS 93 +#define WLC_GET_PHYREG 94 +#define WLC_SET_PHYREG 95 +#define WLC_GET_RADIOREG 96 +#define WLC_SET_RADIOREG 97 +#define WLC_GET_REVINFO 98 +#define WLC_GET_UCANTDIV 99 +#define WLC_SET_UCANTDIV 100 +#define WLC_R_REG 101 +#define WLC_W_REG 102 +#define WLC_DIAG_LOOPBACK 103 +#define WLC_RESET_D11CNTS 104 +#define WLC_GET_MACMODE 105 +#define WLC_SET_MACMODE 106 +#define WLC_GET_MONITOR 107 +#define WLC_SET_MONITOR 108 +#define WLC_GET_GMODE 109 +#define WLC_SET_GMODE 110 +#define WLC_GET_LEGACY_ERP 111 +#define WLC_SET_LEGACY_ERP 112 +#define WLC_GET_RX_ANT 113 +#define WLC_GET_CURR_RATESET 114 /* current rateset */ +#define WLC_GET_SCANSUPPRESS 115 +#define WLC_SET_SCANSUPPRESS 116 +#define WLC_GET_AP 117 +#define WLC_SET_AP 118 +#define WLC_GET_EAP_RESTRICT 119 +#define WLC_SET_EAP_RESTRICT 120 +#define WLC_SCB_AUTHORIZE 121 +#define WLC_SCB_DEAUTHORIZE 122 +#define WLC_GET_WDSLIST 123 +#define WLC_SET_WDSLIST 124 +#define WLC_GET_ATIM 125 +#define WLC_SET_ATIM 126 +#define WLC_GET_RSSI 127 +#define WLC_GET_PHYANTDIV 128 +#define WLC_SET_PHYANTDIV 129 +#define WLC_AP_RX_ONLY 130 +#define WLC_GET_TX_PATH_PWR 131 +#define WLC_SET_TX_PATH_PWR 132 +#define WLC_GET_WSEC 133 +#define WLC_SET_WSEC 134 +#define WLC_GET_PHY_NOISE 135 +#define WLC_GET_BSS_INFO 136 +#define WLC_GET_PKTCNTS 137 +#define WLC_GET_LAZYWDS 138 +#define WLC_SET_LAZYWDS 139 +#define WLC_GET_BANDLIST 140 +#define WLC_GET_BAND 141 +#define WLC_SET_BAND 142 +#define WLC_SCB_DEAUTHENTICATE 143 +#define WLC_GET_SHORTSLOT 144 +#define WLC_GET_SHORTSLOT_OVERRIDE 145 +#define WLC_SET_SHORTSLOT_OVERRIDE 146 +#define WLC_GET_SHORTSLOT_RESTRICT 147 +#define WLC_SET_SHORTSLOT_RESTRICT 148 +#define WLC_GET_GMODE_PROTECTION 149 +#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 +#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 +#define WLC_UPGRADE 152 +/* #define WLC_GET_MRATE 153 */ /* no longer supported */ +/* #define WLC_SET_MRATE 154 */ /* no longer supported */ +#define WLC_GET_ASSOCLIST 159 +#define WLC_GET_CLK 160 +#define WLC_SET_CLK 161 +#define WLC_GET_UP 162 +#define WLC_OUT 163 +#define WLC_GET_WPA_AUTH 164 +#define WLC_SET_WPA_AUTH 165 +#define WLC_GET_PROTECTION_CONTROL 178 +#define WLC_SET_PROTECTION_CONTROL 179 +#define WLC_GET_PHYLIST 180 +#define WLC_GET_KEY_SEQ 183 +/* #define WLC_GET_GMODE_PROTECTION_CTS 198 */ /* no longer supported */ +/* #define WLC_SET_GMODE_PROTECTION_CTS 199 */ /* no longer supported */ +#define WLC_GET_PIOMODE 203 +#define WLC_SET_PIOMODE 204 +#define WLC_SET_LED 209 +#define WLC_GET_LED 210 +#define WLC_GET_CHANNEL_SEL 215 +#define WLC_START_CHANNEL_SEL 216 +#define WLC_GET_VALID_CHANNELS 217 +#define WLC_GET_FAKEFRAG 218 +#define WLC_SET_FAKEFRAG 219 +#define WLC_GET_WET 230 +#define WLC_SET_WET 231 +#define WLC_GET_KEY_PRIMARY 235 +#define WLC_SET_KEY_PRIMARY 236 +#define WLC_GET_RADAR 242 +#define WLC_SET_RADAR 243 +#define WLC_SET_SPECT_MANAGMENT 244 +#define WLC_GET_SPECT_MANAGMENT 245 +#define WLC_WDS_GET_REMOTE_HWADDR 246 /* handled in wl_linux.c/wl_vx.c */ +#define WLC_SET_CS_SCAN_TIMER 248 +#define WLC_GET_CS_SCAN_TIMER 249 +#define WLC_SEND_PWR_CONSTRAINT 254 +#define WLC_CURRENT_PWR 256 +#define WLC_GET_CHANNELS_IN_COUNTRY 260 +#define WLC_GET_COUNTRY_LIST 261 +#define WLC_GET_VAR 262 /* get value of named variable */ +#define WLC_SET_VAR 263 /* set named variable to value */ +#define WLC_NVRAM_GET 264 /* deprecated */ +#define WLC_NVRAM_SET 265 +#define WLC_SET_WSEC_PMK 268 +#define WLC_GET_AUTH_MODE 269 +#define WLC_SET_AUTH_MODE 270 +#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ +#define WLC_NVOTPW 274 +#define WLC_OTPW 275 +#define WLC_SET_LOCALE 278 +#define WLC_LAST 279 /* do not change - use get_var/set_var */ + +/* + * Minor kludge alert: + * Duplicate a few definitions that irelay requires from epiioctl.h here + * so caller doesn't have to include this file and epiioctl.h . + * If this grows any more, it would be time to move these irelay-specific + * definitions out of the epiioctl.h and into a separate driver common file. + */ +#ifndef EPICTRL_COOKIE +#define EPICTRL_COOKIE 0xABADCEDE +#endif + +/* vx wlc ioctl's offset */ +#define CMN_IOCTL_OFF 0x180 + +/* + * custom OID support + * + * 0xFF - implementation specific OID + * 0xE4 - first byte of Broadcom PCI vendor ID + * 0x14 - second byte of Broadcom PCI vendor ID + * 0xXX - the custom OID number + */ + +/* begin 0x1f values beyond the start of the ET driver range. */ +#define WL_OID_BASE 0xFFE41420 + +/* NDIS overrides */ +#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) +#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) + +#define WL_DECRYPT_STATUS_SUCCESS 1 +#define WL_DECRYPT_STATUS_FAILURE 2 +#define WL_DECRYPT_STATUS_UNKNOWN 3 + +/* allows user-mode app to poll the status of USB image upgrade */ +#define WLC_UPGRADE_SUCCESS 0 +#define WLC_UPGRADE_PENDING 1 + +#ifdef CONFIG_USBRNDIS_RETAIL +/* struct passed in for WLC_NDCONFIG_ITEM */ +typedef struct { + char *name; + void *param; +} ndconfig_item_t; +#endif + +/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ +#define WL_RADIO_SW_DISABLE (1<<0) +#define WL_RADIO_HW_DISABLE (1<<1) +#define WL_RADIO_MPC_DISABLE (1<<2) +#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */ + +/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ +#define WL_TXPWR_OVERRIDE (1<<31) + +/* "diag" iovar argument and error code */ +#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ +#define WL_DIAG_MEMORY 3 /* d11 memory test */ +#define WL_DIAG_LED 4 /* LED test */ +#define WL_DIAG_REG 5 /* d11/phy register test */ +#define WL_DIAG_SROM 6 /* srom read/crc test */ +#define WL_DIAG_DMA 7 /* DMA test */ + +#define WL_DIAGERR_SUCCESS 0 +#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ +#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ +#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ +#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ +#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ +#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ +#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ +#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ +#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ +#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ + +/* band types */ +#define WLC_BAND_AUTO 0 /* auto-select */ +#define WLC_BAND_5G 1 /* 5 Ghz */ +#define WLC_BAND_2G 2 /* 2.4 Ghz */ +#define WLC_BAND_ALL 3 /* all bands */ + +/* phy types (returned by WLC_GET_PHYTPE) */ +#define WLC_PHY_TYPE_A 0 +#define WLC_PHY_TYPE_B 1 +#define WLC_PHY_TYPE_G 2 +#define WLC_PHY_TYPE_N 4 +#define WLC_PHY_TYPE_NULL 0xf + +/* MAC list modes */ +#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ +#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ +#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ + +/* + * + */ +#define GMODE_LEGACY_B 0 +#define GMODE_AUTO 1 +#define GMODE_ONLY 2 +#define GMODE_B_DEFERRED 3 +#define GMODE_PERFORMANCE 4 +#define GMODE_LRS 5 +#define GMODE_MAX 6 + +/* values for PLCPHdr_override */ +#define WLC_PLCP_AUTO -1 +#define WLC_PLCP_SHORT 0 +#define WLC_PLCP_LONG 1 + +/* values for g_protection_override and n_protection_override */ +#define WLC_PROTECTION_AUTO -1 +#define WLC_PROTECTION_OFF 0 +#define WLC_PROTECTION_ON 1 + +/* values for g_protection_control and n_protection_control */ +#define WLC_PROTECTION_CTL_OFF 0 +#define WLC_PROTECTION_CTL_LOCAL 1 +#define WLC_PROTECTION_CTL_OVERLAP 2 + +/* deprecated const names for g_protection_override */ +#define WLC_G_PROTECTION_AUTO WLC_PROTECTION_AUTO +#define WLC_G_PROTECTION_OFF WLC_PROTECTION_OFF +#define WLC_G_PROTECTION_ON WLC_PROTECTION_ON + +/* deprecated const names for g_protection_control */ +#define WLC_G_PROTECTION_CTL_OFF WLC_PROTECTION_CTL_OFF +#define WLC_G_PROTECTION_CTL_LOCAL WLC_PROTECTION_CTL_LOCAL +#define WLC_G_PROTECTION_CTL_OVERLAP WLC_PROTECTION_CTL_OVERLAP + +/* deprecated const names for get/set g_protection_control */ +#define WLC_GET_GMODE_PROTECTION_CONTROL WLC_GET_PROTECTION_CONTROL +#define WLC_SET_GMODE_PROTECTION_CONTROL WLC_SET_PROTECTION_CONTROL + +/* values for n_protection */ +#define WLC_N_PROTECTION_OFF 0 +#define WLC_N_PROTECTION_MIXEDMODE 1 +#define WLC_N_PROTECTION_CTS 2 + +/* values for n_preamble_type */ +#define WLC_N_PREAMBLE_MIXEDMODE 0 +#define WLC_N_PREAMBLE_GF 1 + +/* Values for PM */ +#define PM_OFF 0 +#define PM_MAX 1 +#define PM_FAST 2 + + + +typedef struct { + int npulses; /* required number of pulses at n * t_int */ + int ncontig; /* required number of pulses at t_int */ + int min_pw; /* minimum pulse width (20 MHz clocks) */ + int max_pw; /* maximum pulse width (20 MHz clocks) */ + uint16 thresh0; /* Radar detection, thresh 0 */ + uint16 thresh1; /* Radar detection, thresh 1 */ + int npulses_lp; /* Radar detection, minimum long pulses */ + int min_pw_lp; /* Minimum pulsewidth for long pulses */ + int max_pw_lp; /* Maximum pulsewidth for long pulses */ + int min_fm_lp; /* Minimum fm for long pulses */ + int max_deltat_lp; /* Maximum deltat for long pulses */ + int min_deltat; /* Minimum spacing between pulses */ +} wl_radar_args_t; + +/* radar iovar SET defines */ +#define WL_RADAR_DETECTOR_OFF 0 /* radar detector off */ +#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */ +#define WL_RADAR_SIMULATED 2 /* force radar detector to declare + * detection once + */ + +/* dfs_status iovar-related defines */ + +/* cac - channel availability check, + * ism - in-service monitoring + * csa - channel switching announcement + */ + +/* cac state values */ +#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */ +#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */ +#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */ +#define WL_DFS_CACSTATE_CSA 3 /* csa */ +#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */ +#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */ +#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */ +#define WL_DFS_CACSTATES 7 /* this many states exist */ + +/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */ +typedef struct { + uint state; /* noted by WL_DFS_CACSTATE_XX. */ + uint duration; /* time spent in ms in state. */ + /* as dfs enters ISM state, it removes the operational channel from quiet channel + * list and notes the channel in channel_cleared. set to 0 if no channel is cleared + */ + chanspec_t chanspec_cleared; + /* chanspec cleared used to be a uint, add another to uint16 to maintain size */ + uint16 pad; +} wl_dfs_status_t; + +#define NUM_PWRCTRL_RATES 12 + +typedef struct tx_inst_power { +} tx_inst_power_t; + + +/* regulatory enforcement levels */ +#define SPECT_MNGMT_OFF 0 /* both 11h and 11d disabled */ +#define SPECT_MNGMT_LOOSE_11H 1 /* allow non-11h APs in scan lists */ +#define SPECT_MNGMT_STRICT_11H 2 /* prune out non-11h APs from scan list */ +#define SPECT_MNGMT_STRICT_11D 3 /* switch to 802.11D mode */ +/* SPECT_MNGMT_LOOSE_11H_D - same as SPECT_MNGMT_LOOSE with the exception that Country IE + * adoption is done irregardless of capability-spectrum_management + */ +#define SPECT_MNGMT_LOOSE_11H_D 4 /* operation defined above */ + +#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ +#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */ +#define WL_CHAN_BAND_5G (1 << 2) /* 5GHz-band channel */ +#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ +#define WL_CHAN_INACTIVE (1 << 4) /* temporarily inactive due to radar */ +#define WL_CHAN_PASSIVE (1 << 5) /* channel is in passive mode */ +#define WL_CHAN_RESTRICTED (1 << 6) /* restricted use channel */ + +/* BTC mode used by "btc_mode" iovar */ +#define WL_BTC_DISABLE 0 /* disable BT coexistance */ +#define WL_BTC_ENABLE 1 /* enable BT coexistance */ +#define WL_BTC_PREMPT 2 /* enable BT coexistance and BT pre-emption */ + +#define WL_MPC_VAL 0x00400000 +#define WL_APSTA_VAL 0x00800000 +#define WL_DFS_VAL 0x01000000 +#define WL_BA_VAL 0x02000000 +#define WL_NITRO_VAL 0x04000000 +#define WL_CAC_VAL 0x08000000 +#define WL_AMSDU_VAL 0x10000000 +#define WL_AMPDU_VAL 0x20000000 + +/* max # of leds supported by GPIO (gpio pin# == led index#) */ +#define WL_LED_NUMGPIO 16 /* gpio 0-15 */ + +/* led per-pin behaviors */ +#define WL_LED_OFF 0 /* always off */ +#define WL_LED_ON 1 /* always on */ +#define WL_LED_ACTIVITY 2 /* activity */ +#define WL_LED_RADIO 3 /* radio enabled */ +#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */ +#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */ +#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */ +#define WL_LED_WI1 7 +#define WL_LED_WI2 8 +#define WL_LED_WI3 9 +#define WL_LED_ASSOC 10 /* associated state indicator */ +#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */ +#define WL_LED_NUMBEHAVIOR 12 + +/* led behavior numeric value format */ +#define WL_LED_BEH_MASK 0x7f /* behavior mask */ +#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */ + +/* max # of channels returnd by the get valid channels iovar */ +#define WL_NUMCHANSPECS 100 + +/* WDS link local endpoint WPA role */ +#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */ +#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */ +#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */ + +/* number of bytes needed to define a 128-bit mask for MAC event reporting */ +#define WL_EVENTING_MASK_LEN 16 + +/* Structures and constants used for "vndr_ie" IOVar interface */ +#define VNDR_IE_CMD_LEN 4 /* length of the set command string: + * "add", "del" (+ NULL) + */ + +/* 802.11 Mgmt Packet flags */ +#define VNDR_IE_BEACON_FLAG 0x1 +#define VNDR_IE_PRBRSP_FLAG 0x2 +#define VNDR_IE_ASSOCRSP_FLAG 0x4 +#define VNDR_IE_AUTHRSP_FLAG 0x8 + +#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) + +typedef struct { + uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ + vndr_ie_t vndr_ie_data; /* vendor IE data */ +} vndr_ie_info_t; + +typedef struct { + int iecount; /* number of entries in the vndr_ie_list[] array */ + vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */ +} vndr_ie_buf_t; + +typedef struct { + char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NULL */ + vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */ +} vndr_ie_setbuf_t; + +/* join target preference types */ +#define WL_JOIN_PREF_RSSI 1 /* by RSSI, mandatory */ +#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers, optional, RSN and WPA as values */ +#define WL_JOIN_PREF_BAND 3 /* by 802.11 band, optional, WLC_BAND_XXXX as values */ + +/* band preference */ +#define WLJP_BAND_ASSOC_PREF 255 /* use assoc preference settings */ + /* others use WLC_BAND_XXXX as values */ + +/* any multicast cipher suite */ +#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" + +struct tsinfo_arg { + uint8 octets[3]; +}; + +#if !defined(__GNUC__) +#pragma pack(pop) +#endif + +#define NFIFO 6 /* # tx/rx fifopairs */ + +#define WL_CNT_T_VERSION 1 /* current version of wl_cnt_t struct */ + +typedef struct { + uint16 version; /* see definition of WL_CNT_T_VERSION */ + uint16 length; /* length of entire structure */ + + /* transmit stat counters */ + uint32 txframe; /* tx data frames */ + uint32 txbyte; /* tx data bytes */ + uint32 txretrans; /* tx mac retransmits */ + uint32 txerror; /* tx data errors (derived: sum of others) */ + uint32 txctl; /* tx management frames */ + uint32 txprshort; /* tx short preamble frames */ + uint32 txserr; /* tx status errors */ + uint32 txnobuf; /* tx out of buffers errors */ + uint32 txnoassoc; /* tx discard because we're not associated */ + uint32 txrunt; /* tx runt frames */ + uint32 txchit; /* tx header cache hit (fastpath) */ + uint32 txcmiss; /* tx header cache miss (slowpath) */ + + /* transmit chip error counters */ + uint32 txuflo; /* tx fifo underflows */ + uint32 txphyerr; /* tx phy errors (indicated in tx status) */ + uint32 txphycrs; + + /* receive stat counters */ + uint32 rxframe; /* rx data frames */ + uint32 rxbyte; /* rx data bytes */ + uint32 rxerror; /* rx data errors (derived: sum of others) */ + uint32 rxctl; /* rx management frames */ + uint32 rxnobuf; /* rx out of buffers errors */ + uint32 rxnondata; /* rx non data frames in the data channel errors */ + uint32 rxbadds; /* rx bad DS errors */ + uint32 rxbadcm; /* rx bad control or management frames */ + uint32 rxfragerr; /* rx fragmentation errors */ + uint32 rxrunt; /* rx runt frames */ + uint32 rxgiant; /* rx giant frames */ + uint32 rxnoscb; /* rx no scb error */ + uint32 rxbadproto; /* rx invalid frames */ + uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ + uint32 rxbadda; /* rx frames tossed for invalid da */ + uint32 rxfilter; /* rx frames filtered out */ + + /* receive chip error counters */ + uint32 rxoflo; /* rx fifo overflow errors */ + uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ + + uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ + uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ + uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ + + /* misc counters */ + uint32 dmade; /* tx/rx dma descriptor errors */ + uint32 dmada; /* tx/rx dma data errors */ + uint32 dmape; /* tx/rx dma descriptor protocol errors */ + uint32 reset; /* reset count */ + uint32 tbtt; /* cnts the TBTT int's */ + uint32 txdmawar; + uint32 pkt_callback_reg_fail; /* callbacks register failure */ + + /* MAC counters: 32-bit version of d11.h's macstat_t */ + uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, + * Control Management (includes retransmissions) + */ + uint32 txrtsfrm; /* number of RTS sent out by the MAC */ + uint32 txctsfrm; /* number of CTS sent out by the MAC */ + uint32 txackfrm; /* number of ACK frames sent out */ + uint32 txdnlfrm; /* Not used */ + uint32 txbcnfrm; /* beacons transmitted */ + uint32 txfunfl[8]; /* per-fifo tx underflows */ + uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS + * or BCN) + */ + uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for + * driver enqueued frames + */ + uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ + uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ + uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not + * data/control/management + */ + uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ + uint32 rxbadplcp; /* parity check of the PLCP header failed */ + uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ + uint32 rxstrt; /* Number of received frames with a good PLCP + * (i.e. passing parity check) + */ + uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ + uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ + uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ + uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ + uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ + uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ + uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ + uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ + uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ + uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ + uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ + uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ + uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ + uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC + * (unlikely to see these) + */ + uint32 rxbeaconmbss; /* beacons received from member of BSS */ + uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from + * other BSS (WDS FRAME) + */ + uint32 rxbeaconobss; /* beacons received from other BSS */ + uint32 rxrsptmout; /* Number of response timeouts for transmitted frames + * expecting a response + */ + uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ + uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ + uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ + uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ + uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ + uint32 pmqovfl; /* Number of PMQ overflows */ + uint32 rxcgprqfrm; /* Number of received Probe requests that made it into + * the PRQ fifo + */ + uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ + uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did + * not get ACK + */ + uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ + uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ + * fifo because a probe response could not be sent out within + * the time limit defined in M_PRS_MAXTIME + */ + uint32 rxnack; /* Number of NACKS received (Afterburner) */ + uint32 frmscons; /* Number of frames completed without transmission because of an + * Afterburner re-queue + */ + uint32 txnack; /* Number of NACKs transmitted (Afterburner) */ + uint32 txglitch_nack; /* obsolete */ + uint32 txburst; /* obsolete */ + + /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ + uint32 txfrag; /* dot11TransmittedFragmentCount */ + uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ + uint32 txfail; /* dot11FailedCount */ + uint32 txretry; /* dot11RetryCount */ + uint32 txretrie; /* dot11MultipleRetryCount */ + uint32 rxdup; /* dot11FrameduplicateCount */ + uint32 txrts; /* dot11RTSSuccessCount */ + uint32 txnocts; /* dot11RTSFailureCount */ + uint32 txnoack; /* dot11ACKFailureCount */ + uint32 rxfrag; /* dot11ReceivedFragmentCount */ + uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ + uint32 rxcrc; /* dot11FCSErrorCount */ + uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ + uint32 rxundec; /* dot11WEPUndecryptableCount */ + + /* WPA2 counters (see rxundec for DecryptFailureCount) */ + uint32 tkipmicfaill; /* TKIPLocalMICFailures */ + uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ + uint32 tkipreplay; /* TKIPReplays */ + uint32 ccmpfmterr; /* CCMPFormatErrors */ + uint32 ccmpreplay; /* CCMPReplays */ + uint32 ccmpundec; /* CCMPDecryptErrors */ + uint32 fourwayfail; /* FourWayHandshakeFailures */ + uint32 wepundec; /* dot11WEPUndecryptableCount */ + uint32 wepicverr; /* dot11WEPICVErrorCount */ + uint32 decsuccess; /* DecryptSuccessCount */ + uint32 tkipicverr; /* TKIPICVErrorCount */ + uint32 wepexcluded; /* dot11WEPExcludedCount */ + + uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ + uint32 psmwds; /* Count PSM watchdogs */ + uint32 phywatchdog; /* Count Phy lockups */ +} wl_cnt_t; + +#define WL_WME_CNT_VERSION 1 /* current version of wl_wme_cnt_t */ + +typedef struct { + uint32 packets; + uint32 bytes; +} wl_traffic_stats_t; + +typedef struct { + uint16 version; /* see definition of WL_CNT_T_VERSION */ + uint16 length; /* length of entire structure */ + + wl_traffic_stats_t tx[AC_COUNT]; /* Packets transmitted */ + wl_traffic_stats_t tx_failed[AC_COUNT]; /* Packets dropped or failed to transmit */ + wl_traffic_stats_t rx[AC_COUNT]; /* Packets received */ + wl_traffic_stats_t rx_failed[AC_COUNT]; /* Packets failed to receive */ + + wl_traffic_stats_t forward[AC_COUNT]; /* Packets forwarded by AP */ + + wl_traffic_stats_t tx_expired[AC_COUNT]; /* packets dropped due to lifetime expiry */ + +} wl_wme_cnt_t; + +#ifdef WLBA + +#define WLC_BA_CNT_VERSION 1 /* current version of wlc_ba_cnt_t */ + +/* block ack related stats */ +typedef struct wlc_ba_cnt { + uint16 version; /* WLC_BA_CNT_VERSION */ + uint16 length; /* length of entire structure */ + + /* transmit stat counters */ + uint32 txpdu; /* pdus sent */ + uint32 txsdu; /* sdus sent */ + uint32 txfc; /* tx side flow controlled packets */ + uint32 txfci; /* tx side flow control initiated */ + uint32 txretrans; /* retransmitted pdus */ + uint32 txbatimer; /* ba resend due to timer */ + uint32 txdrop; /* dropped packets */ + uint32 txaddbareq; /* addba req sent */ + uint32 txaddbaresp; /* addba resp sent */ + uint32 txdelba; /* delba sent */ + uint32 txba; /* ba sent */ + uint32 txbar; /* bar sent */ + uint32 txpad[4]; /* future */ + + /* receive side counters */ + uint32 rxpdu; /* pdus recd */ + uint32 rxqed; /* pdus buffered before sending up */ + uint32 rxdup; /* duplicate pdus */ + uint32 rxnobuf; /* pdus discarded due to no buf */ + uint32 rxaddbareq; /* addba req recd */ + uint32 rxaddbaresp; /* addba resp recd */ + uint32 rxdelba; /* delba recd */ + uint32 rxba; /* ba recd */ + uint32 rxbar; /* bar recd */ + uint32 rxinvba; /* invalid ba recd */ + uint32 rxbaholes; /* ba recd with holes */ + uint32 rxunexp; /* unexpected packets */ + uint32 rxpad[4]; /* future */ +} wlc_ba_cnt_t; +#endif /* WLBA */ + +/* structure for per-tid ampdu control */ +struct ampdu_tid_control { + uint8 tid; /* tid */ + uint8 enable; /* enable/disable */ +}; + +/* structure for addts arguments */ +/* For ioctls that take a list of TSPEC */ +struct tslist { + int count; /* number of tspecs */ + struct tsinfo_arg tsinfo[1]; /* variable length array of tsinfo */ +}; + +/* structure for addts/delts arguments */ +typedef struct tspec_arg { + uint16 version; /* see definition of TSPEC_ARG_VERSION */ + uint16 length; /* length of entire structure */ + uint flag; /* bit field */ + /* TSPEC Arguments */ + struct tsinfo_arg tsinfo; /* TS Info bit field */ + uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ + uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ + uint min_srv_interval; /* Minimum Service Interval (us) */ + uint max_srv_interval; /* Maximum Service Interval (us) */ + uint inactivity_interval; /* Inactivity Interval (us) */ + uint suspension_interval; /* Suspension Interval (us) */ + uint srv_start_time; /* Service Start Time (us) */ + uint min_data_rate; /* Minimum Data Rate (bps) */ + uint mean_data_rate; /* Mean Data Rate (bps) */ + uint peak_data_rate; /* Peak Data Rate (bps) */ + uint max_burst_size; /* Maximum Burst Size (bytes) */ + uint delay_bound; /* Delay Bound (us) */ + uint min_phy_rate; /* Minimum PHY Rate (bps) */ + uint16 surplus_bw; /* Surplus Bandwidth Allowance Factor */ + uint16 medium_time; /* Medium Time (32 us/s periods) */ +} tspec_arg_t; + +/* current version of wl_tspec_arg_t struct */ +#define TSPEC_ARG_VERSION 1 /* current version of wl_tspec_arg_t struct */ +#define TSPEC_ARG_LENGTH 55 /* argment length from tsinfo to medium_time */ + +/* define for flag */ +#define TSPEC_PENDING 0 /* TSPEC pending */ +#define TSPEC_ACCEPTED 1 /* TSPEC accepted */ +#define TSPEC_REJECTED 2 /* TSPEC rejected */ +#define TSPEC_UNKNOWN 3 /* TSPEC unknown */ +#define TSPEC_STATUS_MASK 7 /* TSPEC status mask */ + + +/* Software feature flag defines used by wlfeatureflag */ +#define WL_SWFL_ABBFL 0x0001 /* Allow Afterburner on systems w/o hardware BFL */ +#define WL_SWFL_ABENCORE 0x0002 /* Allow AB on non-4318E chips */ + +#define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */ + +/* Packet lifetime configuration per ac */ +typedef struct wl_lifetime { + uint32 ac; /* access class */ + uint32 lifetime; /* Packet lifetime value in ms */ +} wl_lifetime_t; + +#endif /* _wlioctl_h_ */ diff --git a/package/broadcom-wl/src/wlc/include/wlutils.h b/package/broadcom-wl/src/wlc/include/wlutils.h new file mode 100644 index 0000000000..a5aa1fd663 --- /dev/null +++ b/package/broadcom-wl/src/wlc/include/wlutils.h @@ -0,0 +1,102 @@ +/* + * Broadcom wireless network adapter utility functions + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: wlutils.h,v 1.1.1.12 2006/02/27 03:43:20 honor Exp $ + */ + +#ifndef _wlutils_h_ +#define _wlutils_h_ + +#include +#include + +/* + * Pass a wlioctl request to the specified interface. + * @param name interface name + * @param cmd WLC_GET_MAGIC <= cmd < WLC_LAST + * @param buf buffer for passing in and/or receiving data + * @param len length of buf + * @return >= 0 if successful or < 0 otherwise + */ +extern int wl_ioctl(char *name, int cmd, void *buf, int len); + +/* + * Probe the specified interface. + * @param name interface name + * @return >= 0 if a Broadcom wireless device or < 0 otherwise + */ +extern int wl_probe(char *name); + +extern int wl_iovar_set(char *ifname, char *iovar, void *param, int paramlen); +extern int wl_iovar_get(char *ifname, char *iovar, void *bufptr, int buflen); +/* + * Set/Get named variable. + * @param ifname interface name + * @param iovar variable name + * @param param input param value/buffer + * @param paramlen input param value/buffer length + * @param bufptr io buffer + * @param buflen io buffer length + * @param val val or val pointer for int routines + * @return success == 0, failure != 0 + */ +/* + * set named driver variable to int value + * calling example: wl_iovar_setint(ifname, "arate", rate) +*/ +static inline int +wl_iovar_setint(char *ifname, char *iovar, int val) +{ + return wl_iovar_set(ifname, iovar, &val, sizeof(val)); +} + +/* + * get named driver variable to int value and return error indication + * calling example: wl_iovar_getint(ifname, "arate", &rate) + */ +static inline int +wl_iovar_getint(char *ifname, char *iovar, int *val) +{ + return wl_iovar_get(ifname, iovar, val, sizeof(int)); +} + +/* + * Set/Get named variable indexed by BSS Configuration + * @param ifname interface name + * @param iovar variable name + * @param bssidx bsscfg index + * @param param input param value/buffer + * @param paramlen input param value/buffer length + * @param bufptr io buffer + * @param buflen io buffer length + * @param val val or val pointer for int routines + * @return success == 0, failure != 0 + */ +extern int wl_bssiovar_get(char *ifname, char *iovar, int bssidx, void *outbuf, int len); +extern int wl_bssiovar_set(char *ifname, char *iovar, int bssidx, void *param, int paramlen); +/* + * set named & bss indexed driver variable to int value + */ +static inline int +wl_bssiovar_setint(char *ifname, char *iovar, int bssidx, int val) +{ + return wl_bssiovar_set(ifname, iovar, bssidx, &val, sizeof(int)); +} + +static inline int +wl_bssiovar_getint(char *ifname, char *iovar, int bssidx, int *val) +{ + return wl_bssiovar_get(ifname, iovar, bssidx, val, sizeof(int)); +} + +extern int wl_bssiovar_setint(char *ifname, char *iovar, int bssidx, int val); + +#endif /* _wlutils_h_ */ diff --git a/package/broadcom-wl/src/wlc/ioctl.c b/package/broadcom-wl/src/wlc/ioctl.c new file mode 100644 index 0000000000..6c676c7c9b --- /dev/null +++ b/package/broadcom-wl/src/wlc/ioctl.c @@ -0,0 +1,298 @@ +/* + * Wireless network adapter utilities + * + * Copyright 2006, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY + * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * + * $Id: wl.c,v 1.1.1.11 2006/02/27 03:43:20 honor Exp $ + */ +#include +#include +#include +#include +#include +#include +#include + +typedef u_int64_t u64; +typedef u_int32_t u32; +typedef u_int16_t u16; +typedef u_int8_t u8; +#include +#include + +#include +#include +#include +#include + +int +wl_ioctl(char *name, int cmd, void *buf, int len) +{ + struct ifreq ifr; + wl_ioctl_t ioc; + int ret = 0; + int s; + + /* open socket to kernel */ + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket"); + return errno; + } + + /* do it */ + ioc.cmd = cmd; + ioc.buf = buf; + ioc.len = len; + strncpy(ifr.ifr_name, name, IFNAMSIZ); + ifr.ifr_data = (caddr_t) &ioc; + if ((ret = ioctl(s, SIOCDEVPRIVATE, &ifr)) < 0) + + /* cleanup */ + close(s); + return ret; +} + +static inline int +wl_get_dev_type(char *name, void *buf, int len) +{ + int s; + int ret; + struct ifreq ifr; + struct ethtool_drvinfo info; + + /* open socket to kernel */ + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("socket"); + return -1; + } + + /* get device type */ + memset(&info, 0, sizeof(info)); + info.cmd = ETHTOOL_GDRVINFO; + ifr.ifr_data = (caddr_t)&info; + strncpy(ifr.ifr_name, name, IFNAMSIZ); + if ((ret = ioctl(s, SIOCETHTOOL, &ifr)) < 0) { + *(char *)buf = '\0'; + } else + strncpy(buf, info.driver, len); + + close(s); + return ret; +} + +int +wl_probe(char *name) +{ + int ret, val; + char buf[3]; + if ((ret = wl_get_dev_type(name, buf, 3)) < 0) + return ret; + /* Check interface */ + if (strncmp(buf, "wl", 2)) + return -1; + if ((ret = wl_ioctl(name, WLC_GET_VERSION, &val, sizeof(val)))) + return ret; + if (val > WLC_IOCTL_VERSION) + return -1; + + return ret; +} + +static int +wl_iovar_getbuf(char *ifname, char *iovar, void *param, int paramlen, void *bufptr, int buflen) +{ + int err; + uint namelen; + uint iolen; + + namelen = strlen(iovar) + 1; /* length of iovar name plus null */ + iolen = namelen + paramlen; + + /* check for overflow */ + if (iolen > buflen) + return (BCME_BUFTOOSHORT); + + memcpy(bufptr, iovar, namelen); /* copy iovar name including null */ + memcpy((int8*)bufptr + namelen, param, paramlen); + + err = wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen); + + return (err); +} + +static int +wl_iovar_setbuf(char *ifname, char *iovar, void *param, int paramlen, void *bufptr, int buflen) +{ + uint namelen; + uint iolen; + + namelen = strlen(iovar) + 1; /* length of iovar name plus null */ + iolen = namelen + paramlen; + + /* check for overflow */ + if (iolen > buflen) + return (BCME_BUFTOOSHORT); + + memcpy(bufptr, iovar, namelen); /* copy iovar name including null */ + memcpy((int8*)bufptr + namelen, param, paramlen); + + return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen); +} + +int +wl_iovar_set(char *ifname, char *iovar, void *param, int paramlen) +{ + char smbuf[WLC_IOCTL_SMLEN]; + + return wl_iovar_setbuf(ifname, iovar, param, paramlen, smbuf, sizeof(smbuf)); +} + +int +wl_iovar_get(char *ifname, char *iovar, void *bufptr, int buflen) +{ + char smbuf[WLC_IOCTL_SMLEN]; + int ret; + + /* use the return buffer if it is bigger than what we have on the stack */ + if (buflen > sizeof(smbuf)) { + ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, bufptr, buflen); + } else { + ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, smbuf, sizeof(smbuf)); + if (ret == 0) + memcpy(bufptr, smbuf, buflen); + } + + return ret; +} + + +/* + * format a bsscfg indexed iovar buffer + */ +static int +wl_bssiovar_mkbuf(char *iovar, int bssidx, void *param, int paramlen, void *bufptr, int buflen, + int *plen) +{ + char *prefix = "bsscfg:"; + int8* p; + uint prefixlen; + uint namelen; + uint iolen; + + prefixlen = strlen(prefix); /* length of bsscfg prefix */ + namelen = strlen(iovar) + 1; /* length of iovar name + null */ + iolen = prefixlen + namelen + sizeof(int) + paramlen; + + /* check for overflow */ + if (buflen < 0 || iolen > (uint)buflen) { + *plen = 0; + return BCME_BUFTOOSHORT; + } + + p = (int8*)bufptr; + + /* copy prefix, no null */ + memcpy(p, prefix, prefixlen); + p += prefixlen; + + /* copy iovar name including null */ + memcpy(p, iovar, namelen); + p += namelen; + + /* bss config index as first param */ + memcpy(p, &bssidx, sizeof(int32)); + p += sizeof(int32); + + /* parameter buffer follows */ + if (paramlen) + memcpy(p, param, paramlen); + + *plen = iolen; + return 0; +} + +/* + * set named & bss indexed driver variable to buffer value + */ +static int +wl_bssiovar_setbuf(char *ifname, char *iovar, int bssidx, void *param, int paramlen, void *bufptr, + int buflen) +{ + int err; + int iolen; + + err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen); + if (err) + return err; + + return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen); +} + +/* + * get named & bss indexed driver variable buffer value + */ +static int +wl_bssiovar_getbuf(char *ifname, char *iovar, int bssidx, void *param, int paramlen, void *bufptr, + int buflen) +{ + int err; + int iolen; + + err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen); + if (err) + return err; + + return wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen); +} + +/* + * set named & bss indexed driver variable to buffer value + */ +int +wl_bssiovar_set(char *ifname, char *iovar, int bssidx, void *param, int paramlen) +{ + char smbuf[WLC_IOCTL_SMLEN]; + + return wl_bssiovar_setbuf(ifname, iovar, bssidx, param, paramlen, smbuf, sizeof(smbuf)); +} + +/* + * get named & bss indexed driver variable buffer value + */ +int +wl_bssiovar_get(char *ifname, char *iovar, int bssidx, void *outbuf, int len) +{ + char smbuf[WLC_IOCTL_SMLEN]; + int err; + + /* use the return buffer if it is bigger than what we have on the stack */ + if (len > (int)sizeof(smbuf)) { + err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, outbuf, len); + } else { + memset(smbuf, 0, sizeof(smbuf)); + err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, smbuf, sizeof(smbuf)); + if (err == 0) + memcpy(outbuf, smbuf, len); + } + + return err; +} + +void +wl_printlasterror(char *name) +{ + char err_buf[WLC_IOCTL_SMLEN]; + strcpy(err_buf, "bcmerrstr"); + + fprintf(stderr, "Error: "); + if ( wl_ioctl(name, WLC_GET_VAR, err_buf, sizeof (err_buf)) != 0) + fprintf(stderr, "Error getting the Errorstring from driver\n"); + else + fprintf(stderr, err_buf); +} diff --git a/package/broadcom-wl/src/wlc/wlc.c b/package/broadcom-wl/src/wlc/wlc.c new file mode 100644 index 0000000000..99237c095a --- /dev/null +++ b/package/broadcom-wl/src/wlc/wlc.c @@ -0,0 +1,1138 @@ +/* + * wlc - Broadcom Wireless Driver Control Utility + * + * Copyright (C) 2006 Felix Fietkau + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define VERSION "0.1" +#define BUFSIZE 8192 +#define PTABLE_MAGIC 0xbadc0ded +#define PTABLE_SLT1 1 +#define PTABLE_SLT2 2 +#define PTABLE_ACKW 3 +#define PTABLE_ADHM 4 +#define PTABLE_END 0xffffffff + +/* + * Copy each token in wordlist delimited by space into word + * Taken from Broadcom shutils.h + */ +#define foreach(word, wordlist, next) \ + for (next = &wordlist[strspn(wordlist, " ")], \ + strncpy(word, next, sizeof(word)), \ + word[strcspn(word, " ")] = '\0', \ + word[sizeof(word) - 1] = '\0', \ + next = strchr(next, ' '); \ + strlen(word); \ + next = next ? &next[strspn(next, " ")] : "", \ + strncpy(word, next, sizeof(word)), \ + word[strcspn(word, " ")] = '\0', \ + word[sizeof(word) - 1] = '\0', \ + next = strchr(next, ' ')) + +static char wlbuf[8192]; +static char interface[16] = "wl0"; +static unsigned long ptable[128]; +static unsigned long kmem_offset = 0; +static int vif = 0, debug = 1, fromstdin = 0; + +typedef enum { + NONE = 0x00, + + /* types */ + PARAM_TYPE = 0x00f, + INT = 0x001, + STRING = 0x002, + + /* options */ + PARAM_OPTIONS = 0x0f0, + NOARG = 0x010, + + /* modes */ + PARAM_MODE = 0xf00, + GET = 0x100, + SET = 0x200, +} wlc_param; + +struct wlc_call { + const char *name; + wlc_param param; + int (*handler)(wlc_param param, void *data, void *value); + union { + int num; + char *str; + void *ptr; + } data; + const char *desc; +}; + +/* can't use the system include because of the stupid broadcom header files */ +extern struct ether_addr *ether_aton(const char *asc); +extern char *ether_ntoa(const struct ether_addr *addr); + +/* + * find the starting point of wl.o in memory + * by reading /proc/ksyms + */ +static inline void wlc_get_mem_offset(void) +{ + FILE *f; + char s[64]; + + /* yes, i'm lazy ;) */ + f = popen("grep '\\[wl]' /proc/ksyms | sort", "r"); + if (fgets(s, 64, f) == 0) + return; + + pclose(f); + + s[8] = 0; + kmem_offset = strtoul(s, NULL, 16); + + /* sanity check */ + if (kmem_offset < 0xc0000000) + kmem_offset = 0; +} + + +static int ptable_init(void) +{ + glob_t globbuf; + struct stat statbuf; + int fd; + + if (ptable[0] == PTABLE_MAGIC) + return 0; + + glob("/lib/modules/2.4.*/wl.o", 0, NULL, &globbuf); + + if (globbuf.gl_pathv[0] == NULL) + return -1; + + if ((fd = open(globbuf.gl_pathv[0], O_RDONLY)) < 0) + return -1; + + if (fstat(fd, &statbuf) < 0) + goto failed; + + if (statbuf.st_size <= 512) + goto failed; + + if (lseek(fd, statbuf.st_size - 512, SEEK_SET) < 0) { + perror("lseek"); + goto failed; + } + + if (read(fd, ptable, 512) < 512) + goto failed; + + if (ptable[0] != PTABLE_MAGIC) + goto failed; + + close(fd); + + wlc_get_mem_offset(); + if (kmem_offset == 0) + return -1; + + return 0; + +failed: + close(fd); + + return -1; +} + +static inline unsigned long wlc_kmem_read(unsigned long offset) +{ + int fd; + unsigned long ret; + + if ((fd = open("/dev/kmem", O_RDONLY )) < 0) + return -1; + + lseek(fd, 0x70000000, SEEK_SET); + lseek(fd, (kmem_offset - 0x70000000) + offset, SEEK_CUR); + read(fd, &ret, 4); + close(fd); + + return ret; +} + +static inline void wlc_kmem_write(unsigned long offset, unsigned long value) +{ + int fd; + + if ((fd = open("/dev/kmem", O_WRONLY )) < 0) + return; + + lseek(fd, 0x70000000, SEEK_SET); + lseek(fd, (kmem_offset - 0x70000000) + offset, SEEK_CUR); + write(fd, &value, 4); + close(fd); +} + +static int wlc_patcher_getval(unsigned long key, unsigned long *val) +{ + unsigned long *pt = &ptable[1]; + unsigned long tmp; + + if (ptable_init() < 0) { + fprintf(stderr, "Could not load the ptable\n"); + return -1; + } + + while (*pt != PTABLE_END) { + if (*pt == key) { + tmp = wlc_kmem_read(pt[1]); + + if (tmp == pt[2]) + *val = 0xffffffff; + else + *val = tmp; + + return 0; + } + pt += 3; + } + + return -1; +} + +static int wlc_patcher_setval(unsigned long key, unsigned long val) +{ + unsigned long *pt = &ptable[1]; + + if (ptable_init() < 0) { + fprintf(stderr, "Could not load the ptable\n"); + return -1; + } + + if (val != 0xffffffff) + val = (pt[2] & ~(0xffff)) | (val & 0xffff); + + while (*pt != PTABLE_END) { + if (*pt == key) { + if (val == 0xffffffff) /* default */ + val = pt[2]; + + wlc_kmem_write(pt[1], val); + } + pt += 3; + } + + return 0; +} + +static int wlc_slottime(wlc_param param, void *data, void *value) +{ + int *val = (int *) value; + int ret = 0; + + if ((param & PARAM_MODE) == SET) { + wlc_patcher_setval(PTABLE_SLT1, *val); + wlc_patcher_setval(PTABLE_SLT2, ((*val == -1) ? *val : *val + 510)); + } else if ((param & PARAM_MODE) == GET) { + ret = wlc_patcher_getval(PTABLE_SLT1, (unsigned long *) val); + if (*val != 0xffffffff) + *val &= 0xffff; + } + + return ret; +} + +static int wlc_noack(wlc_param param, void *data, void *value) +{ + int *val = (int *) value; + int ret = 0; + + if ((param & PARAM_MODE) == SET) { + wlc_patcher_setval(PTABLE_ACKW, ((*val) ? 1 : 0)); + } else if ((param & PARAM_MODE) == GET) { + ret = wlc_patcher_getval(PTABLE_ACKW, (unsigned long *) val); + *val &= 0xffff; + *val = (*val ? 1 : 0); + } + + return ret; +} + +static int wlc_ibss_merge(wlc_param param, void *data, void *value) +{ + int *val = (int *) value; + int ret = 0; + + if ((param & PARAM_MODE) == SET) { + /* overwrite the instruction with 'lui v0,0x0' - fake a return + * status of 0 for wlc_bcn_tsf_later */ + wlc_patcher_setval(PTABLE_ACKW, ((*val) ? -1 : 0x3c020000)); + } else if ((param & PARAM_MODE) == GET) { + ret = wlc_patcher_getval(PTABLE_ACKW, (unsigned long *) val); + *val = ((*val == -1) ? 1 : 0); + } + + return ret; +} + +static int wlc_ioctl(wlc_param param, void *data, void *value) +{ + unsigned int *var = ((unsigned int *) data); + unsigned int ioc = *var; + + if (param & NOARG) { + return wl_ioctl(interface, ioc, NULL, 0); + } + switch(param & PARAM_TYPE) { + case INT: + return wl_ioctl(interface, ((param & SET) ? (ioc) : (ioc >> 16)) & 0xffff, value, sizeof(int)); + case STRING: + return wl_ioctl(interface, ((param & SET) ? (ioc) : (ioc >> 16)) & 0xffff, value, BUFSIZE); + } + return 0; +} + +static int wlc_iovar(wlc_param param, void *data, void *value) +{ + int *val = (int *) value; + char *iov = *((char **) data); + int ret = 0; + + if (param & SET) { + switch(param & PARAM_TYPE) { + case INT: + ret = wl_iovar_setint(interface, iov, *val); + } + } + if (param & GET) { + switch(param & PARAM_TYPE) { + case INT: + ret = wl_iovar_getint(interface, iov, val); + } + } + + return ret; +} + +static int wlc_bssiovar(wlc_param param, void *data, void *value) +{ + int *val = (int *) value; + char *iov = *((char **) data); + int ret = 0; + + if (param & SET) { + switch(param & PARAM_TYPE) { + case INT: + ret = wl_bssiovar_setint(interface, iov, vif, *val); + } + } + if (param & GET) { + switch(param & PARAM_TYPE) { + case INT: + ret = wl_bssiovar_getint(interface, iov, vif, val); + } + } + + return ret; +} + +static int wlc_vif_enabled(wlc_param param, void *data, void *value) +{ + int *val = (int *) value; + int buf[3]; + int ret = 0; + + sprintf((char *) buf, "bss"); + buf[1] = vif; + if (param & SET) { + buf[2] = (*val ? 1 : 0); + ret = wl_ioctl(interface, WLC_SET_VAR, buf, sizeof(buf)); + } else if (param & GET) { + ret = wl_ioctl(interface, WLC_GET_VAR, buf, sizeof(buf)); + *val = buf[0]; + } + + return ret; +} + +static int wlc_ssid(wlc_param param, void *data, void *value) +{ + int ret = -1, ret2 = -1; + char *dest = (char *) value; + wlc_ssid_t ssid; + + if ((param & PARAM_MODE) == GET) { + ret = wl_bssiovar_get(interface, "ssid", vif, &ssid, sizeof(ssid)); + + if (ret) + /* if we can't get the ssid through the bssiovar, try WLC_GET_SSID */ + ret = wl_ioctl(interface, WLC_GET_SSID, &ssid, sizeof(ssid)); + + if (!ret) { + memcpy(dest, ssid.SSID, ssid.SSID_len); + dest[ssid.SSID_len] = 0; + } + } else if ((param & PARAM_MODE) == SET) { + strncpy(ssid.SSID, value, 32); + ssid.SSID_len = strlen(value); + + if (ssid.SSID_len > 32) + ssid.SSID_len = 32; + + if (vif == 0) { + /* for the main interface, also try the WLC_SET_SSID call */ + ret2 = wl_ioctl(interface, WLC_SET_SSID, &ssid, sizeof(ssid)); + } + + ret = wl_bssiovar_set(interface, "ssid", vif, &ssid, sizeof(ssid)); + ret = (!ret2 ? 0 : ret); + } + + return ret; +} + +static int wlc_int(wlc_param param, void *data, void *value) +{ + int *var = *((int **) data); + int *val = (int *) value; + + if ((param & PARAM_MODE) == SET) { + *var = *val; + } else if ((param & PARAM_MODE) == GET) { + *val = *var; + } + + return 0; +} + +static int wlc_flag(wlc_param param, void *data, void *value) +{ + int *var = *((int **) data); + + *var = 1; + + return 0; +} + +static int wlc_string(wlc_param param, void *data, void *value) +{ + char *var = *((char **) data); + + if ((param & PARAM_MODE) == GET) { + strcpy(value, var); + } + + return 0; +} + +static int wlc_afterburner(wlc_param param, void *data, void *value) +{ + int *val = (int *) value; + int ret = 0; + + if ((param & PARAM_MODE) == GET) { + ret = wl_iovar_getint(interface, "afterburner", val); + } else { + wl_iovar_setint(interface, "wlfeatureflag", (*val ? 3 : 0)); + ret = wl_iovar_setint(interface, "afterburner", (*val ? 1 : 0)); + wl_iovar_setint(interface, "afterburner_override", *val); + } + + return ret; +} + +static int wlc_maclist(wlc_param param, void *data, void *value) +{ + unsigned int *var = ((unsigned int *) data); + unsigned int ioc = *var; + int limit = (sizeof(wlbuf) - 4) / sizeof(struct ether_addr); + struct maclist *list = (struct maclist *) wlbuf; + char *str = (char *) value; + char astr[30], *p; + struct ether_addr *addr; + int isset = 0; + int ret; + + if ((param & PARAM_MODE) == GET) { + list->count = limit; + ret = wl_ioctl(interface, (ioc >> 16) & 0xffff, wlbuf, sizeof(wlbuf)); + + if (!ret) + while (list->count) + str += sprintf(str, "%s%s", ((((char *) value) == str) ? "" : " "), ether_ntoa(&list->ea[list->count-- - 1])); + + return ret; + } else { + while (*str && isspace(*str)) + *str++; + + if (*str == '+') { + str++; + + list->count = limit; + if (wl_ioctl(interface, (ioc >> 16) & 0xffff, wlbuf, sizeof(wlbuf)) == 0) + isset = 1; + + while (*str && isspace(*str)) + str++; + } + + if (!isset) + memset(wlbuf, 0, sizeof(wlbuf)); + + foreach(astr, str, p) { + if (list->count >= limit) + break; + + if ((addr = ether_aton(astr)) != NULL) + memcpy(&list->ea[list->count++], addr, sizeof(struct ether_addr)); + } + + return wl_ioctl(interface, ioc & 0xffff, wlbuf, sizeof(wlbuf)); + } +} + +static int wlc_radio(wlc_param param, void *data, void *value) +{ + int *val = (int *) value; + int ret; + + if ((param & PARAM_MODE) == GET) { + ret = wl_ioctl(interface, WLC_GET_RADIO, val, sizeof(int)); + *val = ((*val & 1) ? 0 : 1); + } else { + *val = (1 << 16) | (*val ? 0 : 1); + ret = wl_ioctl(interface, WLC_SET_RADIO, val, sizeof(int)); + } + + return ret; +} + +static int wlc_wsec_key(wlc_param param, void *null, void *value) +{ + wl_wsec_key_t wsec_key; + unsigned char *index = value; + unsigned char *key; + unsigned char *data; + unsigned char hex[3]; + + if ((param & PARAM_MODE) != SET) + return 0; + + memset(&wsec_key, 0, sizeof(wsec_key)); + if (index[0] == '=') { + wsec_key.flags = WL_PRIMARY_KEY; + index++; + } + + if ((index[0] < '1') || (index[0] > '4') || (index[1] != ',')) + return -1; + + key = index + 2; + if (strncmp(key, "d:", 2) == 0) { /* delete key */ + } else if (strncmp(key, "s:", 2) == 0) { /* ascii key */ + key += 2; + wsec_key.len = strlen(key); + + if ((wsec_key.len != 5) && (wsec_key.len != 13)) + return -1; + + strcpy(wsec_key.data, key); + } else { /* hex key */ + wsec_key.len = strlen(key); + if ((wsec_key.len != 10) && (wsec_key.len != 26)) + return -1; + + wsec_key.len /= 2; + data = wsec_key.data; + hex[2] = 0; + do { + hex[0] = *(key++); + hex[1] = *(key++); + *(data++) = (unsigned char) strtoul(hex, NULL, 16); + } while (*key != 0); + } + + return wl_bssiovar_set(interface, "wsec_key", vif, &wsec_key, sizeof(wsec_key)); +} + +static inline int cw2ecw(int cw) +{ + int i; + for (cw++, i = 0; cw; i++) cw >>=1; + return i - 1; +} + +static int wlc_wme_ac(wlc_param param, void *data, void *value) +{ + char *type = *((char **) data); + char *settings = (char *) value; + char cmd[100], *p, *val; + edcf_acparam_t params[AC_COUNT]; + int ret; + int intval; + int cur = -1; + char *buf = wlbuf; + + if ((param & PARAM_MODE) != SET) + return -1; + + memset(params, 0, sizeof(params)); + ret = wl_iovar_get(interface, type, params, sizeof(params)); + memset(buf, 0, BUFSIZE); + strcpy(buf, type); + buf += strlen(buf) + 1; + + foreach(cmd, settings, p) { + val = strchr(cmd, '='); + if (val == NULL) { + if (strcmp(cmd, "be") == 0) + cur = AC_BE; + else if (strcmp(cmd, "bk") == 0) + cur = AC_BK; + else if (strcmp(cmd, "vi") == 0) + cur = AC_VI; + else if (strcmp(cmd, "vo") == 0) + cur = AC_VO; + else + return -1; + + /* just in case */ + params[cur].ACI = (params[cur].ACI & (0x3 << 5)) | (cur << 5); + } else { + *(val++) = 0; + + intval = strtoul(val, NULL, 10); + if (strcmp(cmd, "cwmin") == 0) + params[cur].ECW = (params[cur].ECW & ~(0xf)) | cw2ecw(intval); + else if (strcmp(cmd, "ecwmin") == 0) + params[cur].ECW = (params[cur].ECW & ~(0xf)) | (intval & 0xf); + else if (strcmp(cmd, "cwmax") == 0) + params[cur].ECW = (params[cur].ECW & ~(0xf << 4)) | (cw2ecw(intval) << 4); + else if (strcmp(cmd, "ecwmax") == 0) + params[cur].ECW = (params[cur].ECW & ~(0xf << 4)) | ((intval & 0xf) << 4); + else if (strcmp(cmd, "aifsn") == 0) + params[cur].ACI = (params[cur].ACI & ~(0xf)) | (intval & 0xf); + else if (strcmp(cmd, "txop") == 0) + params[cur].TXOP = intval >> 5; + else if (strcmp(cmd, "force") == 0) + params[cur].ACI = (params[cur].ACI & ~(1 << 4)) | ((intval) ? (1 << 4) : 0); + else return -1; + + memcpy(buf, ¶ms[cur], sizeof(edcf_acparam_t)); + wl_ioctl(interface, WLC_SET_VAR, wlbuf, BUFSIZE); + } + } + return ret; +} + +static const struct wlc_call wlc_calls[] = { + { + .name = "version", + .param = STRING|NOARG, + .handler = wlc_string, + .data.str = VERSION, + .desc = "Version of this program" + }, + { + .name = "debug", + .param = INT, + .handler = wlc_int, + .data.ptr = &debug, + .desc = "wlc debug level" + }, + { + .name = "stdin", + .param = NOARG, + .handler = wlc_flag, + .data.ptr = &fromstdin, + .desc = "Accept input from stdin" + }, + { + .name = "up", + .param = NOARG, + .handler = wlc_ioctl, + .data.num = WLC_UP, + .desc = "Bring the interface up" + }, + { + .name = "down", + .param = NOARG, + .handler = wlc_ioctl, + .data.num = WLC_DOWN, + .desc = "Bring the interface down" + }, + { + .name = "radio", + .param = INT, + .handler = wlc_radio, + .desc = "Radio enabled flag" + }, + { + .name = "ap", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_AP << 16) | WLC_SET_AP), + .desc = "Access Point mode" + }, + { + .name = "mssid", + .param = INT, + .handler = wlc_iovar, + .data.str = "mssid", + .desc = "Multi-ssid mode" + }, + { + .name = "apsta", + .param = INT, + .handler = wlc_iovar, + .data.str = "apsta", + .desc = "AP+STA mode" + }, + { + .name = "infra", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_INFRA << 16) | WLC_SET_INFRA), + .desc = "Infrastructure mode" + }, + { + .name = "wet", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_WET << 16) | WLC_SET_WET), + .desc = "Wireless repeater mode", + }, + { + .name = "statimeout", + .param = INT, + .handler = wlc_iovar, + .data.str = "sta_retry_time", + .desc = "STA connection timeout" + }, + { + .name = "country", + .param = STRING, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_COUNTRY << 16) | WLC_SET_COUNTRY), + .desc = "Country code" + }, + { + .name = "channel", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_CHANNEL << 16) | WLC_SET_CHANNEL), + .desc = "Channel", + }, + { + .name = "vif", + .param = INT, + .handler = wlc_int, + .data.ptr = &vif, + .desc = "Current vif index" + }, + { + .name = "enabled", + .param = INT, + .handler = wlc_vif_enabled, + .desc = "vif enabled flag" + }, + { + .name = "ssid", + .param = STRING, + .handler = wlc_ssid, + .desc = "Interface ESSID" + }, + { + .name = "closed", + .param = INT, + .handler = wlc_bssiovar, + .data.str = "closednet", + .desc = "Hidden ESSID flag" + }, + { + .name = "wsec", + .param = INT, + .handler = wlc_bssiovar, + .data.str = "wsec", + .desc = "Security mode flags" + }, + { + .name = "wepkey", + .param = STRING, + .handler = wlc_wsec_key, + .desc = "Set/Remove WEP keys" + }, + { + .name = "wsec_restrict", + .param = INT, + .handler = wlc_bssiovar, + .data.str = "wsec_restrict", + .desc = "Drop unencrypted traffic" + }, + { + .name = "eap_restrict", + .param = INT, + .handler = wlc_bssiovar, + .data.str = "eap_restrict", + .desc = "Only allow 802.1X traffic until 802.1X authorized" + }, + { + .name = "wpa_auth", + .param = INT, + .handler = wlc_bssiovar, + .data.str = "wpa_auth", + .desc = "WPA authentication modes" + }, + { + .name = "ap_isolate", + .param = INT, + .handler = wlc_bssiovar, + .data.str = "ap_isolate", + .desc = "Isolate connected clients" + }, + { + .name = "supplicant", + .param = INT, + .handler = wlc_iovar, + .data.str = "sup_wpa", + .desc = "Built-in WPA supplicant" + }, + { + .name = "maxassoc", + .param = INT, + .handler = wlc_iovar, + .data.str = "maxassoc", + .desc = "Max. number of associated clients", + }, + { + .name = "wme", + .param = INT, + .handler = wlc_iovar, + .data.str = "wme", + .desc = "WME enabled" + }, + { + .name = "wme_ac_ap", + .param = STRING, + .handler = wlc_wme_ac, + .data.str = "wme_ac_ap", + .desc = "Set WME AC options for AP mode", + }, + { + .name = "wme_ac_sta", + .param = STRING, + .handler = wlc_wme_ac, + .data.str = "wme_ac_sta", + .desc = "Set WME AC options for STA mode", + }, + { + .name = "wme_noack", + .param = INT, + .handler = wlc_iovar, + .data.str = "wme_noack", + .desc = "WME ACK disable request", + }, + { + .name = "fragthresh", + .param = INT, + .handler = wlc_iovar, + .data.str = "fragthresh", + .desc = "Fragmentation threshold", + }, + { + .name = "rtsthresh", + .param = INT, + .handler = wlc_iovar, + .data.str = "rtsthresh", + .desc = "RTS threshold" + }, + { + .name = "rxant", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_ANTDIV << 16) | WLC_SET_ANTDIV), + .desc = "Rx antenna selection" + }, + { + .name = "txant", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_TXANT << 16) | WLC_SET_TXANT), + .desc = "Tx antenna selection" + }, + { + .name = "dtim", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_DTIMPRD << 16) | WLC_SET_DTIMPRD), + .desc = "DTIM period", + }, + { + .name = "bcn", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_BCNPRD << 16) | WLC_SET_BCNPRD), + .desc = "Beacon interval" + }, + { + .name = "frameburst", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_FAKEFRAG << 16) | WLC_SET_FAKEFRAG), + .desc = "Framebursting" + }, + { + .name = "monitor", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_MONITOR << 16) | WLC_SET_MONITOR), + .desc = "Monitor mode" + }, + { + .name = "passive", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_PASSIVE << 16) | WLC_SET_PASSIVE), + .desc = "Passive mode" + }, + { + .name = "macfilter", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_MACMODE << 16) | WLC_SET_MACMODE), + .desc = "MAC filter mode (0:disabled, 1:deny, 2:allow)" + }, + { + .name = "maclist", + .param = STRING, + .data.num = ((WLC_GET_MACLIST << 16) | WLC_SET_MACLIST), + .handler = wlc_maclist, + .desc = "MAC filter list" + }, + { + .name = "autowds", + .param = INT, + .handler = wlc_ioctl, + .data.num = ((WLC_GET_LAZYWDS << 16) | WLC_SET_LAZYWDS), + .desc = "Automatic WDS" + }, + { + .name = "wds", + .param = STRING, + .data.num = ((WLC_GET_WDSLIST << 16) | WLC_SET_WDSLIST), + .handler = wlc_maclist, + .desc = "WDS connection list" + }, + { + .name = "wdstimeout", + .param = INT, + .handler = wlc_iovar, + .data.str = "wdstimeout", + .desc = "WDS link detection timeout" + }, + { + .name = "afterburner", + .param = INT, + .handler = wlc_afterburner, + .desc = "Broadcom Afterburner" + }, + { + .name = "slottime", + .param = INT, + .handler = wlc_slottime, + .desc = "Slot time (-1 = auto)" + }, + { + .name = "txack", + .param = INT, + .handler = wlc_noack, + .desc = "Tx ACK enabled flag" + }, + { + .name = "ibss_merge", + .param = INT, + .handler = wlc_ibss_merge, + .desc = "Allow IBSS merge in Ad-Hoc mode" + } +}; +#define wlc_calls_size (sizeof(wlc_calls) / sizeof(struct wlc_call)) + +static void usage(char *cmd) +{ + int i; + fprintf(stderr, "Usage: %s [ ...]\n" + "\n" + "Available commands:\n", cmd); + for (i = 0; i < wlc_calls_size; i++) { + fprintf(stderr, "\t%-16s\t%s\n", wlc_calls[i].name ?: "", wlc_calls[i].desc ?: ""); + } + fprintf(stderr, "\n"); + exit(1); +} + +static int do_command(const struct wlc_call *cmd, char *arg) +{ + static char buf[BUFSIZE]; + int set; + int ret = 0; + char *format, *end; + int intval; + + if (debug >= 10) { + fprintf(stderr, "do_command %-16s\t'%s'\n", cmd->name, arg); + } + + if ((arg == NULL) && ((cmd->param & PARAM_TYPE) != NONE)) { + set = 0; + ret = cmd->handler(cmd->param | GET, (void *) &cmd->data, (void *) buf); + if (ret == 0) { + switch(cmd->param & PARAM_TYPE) { + case INT: + intval = *((int *) buf); + + if (intval > 65535) + format = "0x%08x\n"; + else if (intval > 255) + format = "0x%04x\n"; + else + format = "%d\n"; + + fprintf(stdout, format, intval); + break; + case STRING: + fprintf(stdout, "%s\n", buf); + } + } + } else { /* SET */ + set = 1; + switch(cmd->param & PARAM_TYPE) { + case INT: + intval = strtoul(arg, &end, 10); + if (end && !(*end)) { + memcpy(buf, &intval, sizeof(intval)); + } else { + fprintf(stderr, "%s: Invalid argument\n", cmd->name); + return -1; + } + break; + case STRING: + strncpy(buf, arg, BUFSIZE); + buf[BUFSIZE - 1] = 0; + } + + ret = cmd->handler(cmd->param | SET, (void *) &cmd->data, (void *) buf); + } + + if ((debug > 0) && (ret != 0)) + fprintf(stderr, "Command '%s %s' failed: %d\n", (set == 1 ? "set" : "get"), cmd->name, ret); + + return ret; +} + +static struct wlc_call *find_cmd(char *name) +{ + int found = 0, i = 0; + + while (!found && (i < wlc_calls_size)) { + if (strcmp(name, wlc_calls[i].name) == 0) + found = 1; + else + i++; + } + + return (struct wlc_call *) (found ? &wlc_calls[i] : NULL); +} + +int main(int argc, char **argv) +{ + static char buf[BUFSIZE]; + char *s, *s2; + char *cmd = argv[0]; + struct wlc_call *call; + int ret = 0; + + if (argc < 2) + usage(argv[0]); + + for(interface[2] = '0'; (interface[2] < '3') && (wl_probe(interface) != 0); interface[2]++); + if (interface[2] == '3') { + fprintf(stderr, "No Broadcom wl interface found!\n"); + return -1; + } + + argv++; + argc--; + while ((argc > 0) && (argv[0] != NULL)) { + if ((call = find_cmd(argv[0])) == NULL) { + fprintf(stderr, "Invalid command: %s\n\n", argv[0]); + usage(cmd); + } + if ((argc > 1) && (!(call->param & NOARG))) { + ret = do_command(call, argv[1]); + argv += 2; + argc -= 2; + } else { + ret = do_command(call, NULL); + argv++; + argc--; + } + } + + while (fromstdin && !feof(stdin)) { + *buf = 0; + fgets(buf, BUFSIZE - 1, stdin); + + if (*buf == 0) + continue; + + if ((s = strchr(buf, '\r')) != NULL) + *s = 0; + if ((s = strchr(buf, '\n')) != NULL) + *s = 0; + + s = buf; + while (isspace(*s)) + s++; + + if (!*s) + continue; + + if ((s2 = strchr(buf, ' ')) != NULL) + *(s2++) = 0; + + while (s2 && isspace(*s2)) + s2++; + + if ((call = find_cmd(buf)) == NULL) { + fprintf(stderr, "Invalid command: %s\n", buf); + ret = -1; + } else + ret = do_command(call, ((call->param & NOARG) ? NULL : s2)); + } + + return ret; +} diff --git a/package/wlc/Makefile b/package/wlc/Makefile deleted file mode 100644 index e40fcd8d15..0000000000 --- a/package/wlc/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -# $Id: Makefile 2480 2005-11-14 02:07:33Z nbd $ - -include $(TOPDIR)/rules.mk - -PKG_NAME:=wlc -PKG_RELEASE:=1 - -PKG_BUILD_DIR:=$(BUILD_DIR)/wlc - -include $(TOPDIR)/package/rules.mk - -define Package/wlc -SECTION:=base -CATEGORY:=Base system -DEPENDS:=@PACKAGE_KMOD_BRCM_WL -DEFAULT:=y -TITLE:=Utility for configuring the Broadcom wl driver -DESCRIPTION:=Utility for configuring the Broadcom wl driver -endef - - -define Build/Prepare - mkdir -p $(PKG_BUILD_DIR) - $(CP) src/* $(PKG_BUILD_DIR)/ -endef - -define Build/Compile - $(MAKE) -C $(PKG_BUILD_DIR)\ - $(TARGET_CONFIGURE_OPTS) \ - CC="$(TARGET_CC)" \ - CFLAGS="-I$(PKG_BUILD_DIR)/include $(TARGET_CFLAGS)" \ - all -endef - -define Package/wlc/install - install -d -m0755 $(1)/sbin - install -m0755 $(PKG_BUILD_DIR)/wlc $(1)/sbin/ -endef - -$(eval $(call BuildPackage,wlc)) diff --git a/package/wlc/src/Makefile b/package/wlc/src/Makefile deleted file mode 100644 index ffe1649515..0000000000 --- a/package/wlc/src/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -all: wlc -clean: - rm -f *.o wlc - -wlc: wlc.o ioctl.o -%.o: %.c - $(CC) $(CFLAGS) -Wall -c -o $@ $< - -.PHONY: all clean diff --git a/package/wlc/src/include/bcmdefs.h b/package/wlc/src/include/bcmdefs.h deleted file mode 100644 index 8b5abe5d26..0000000000 --- a/package/wlc/src/include/bcmdefs.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Misc system wide definitions - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * $Id: bcmdefs.h,v 1.1.1.3 2006/04/08 06:13:39 honor Exp $ - */ - -#ifndef _bcmdefs_h_ -#define _bcmdefs_h_ - -/* - * One doesn't need to include this file explicitly, gets included automatically if - * typedefs.h is included. - */ - -/* Reclaiming text and data : - * The following macros specify special linker sections that can be reclaimed - * after a system is considered 'up'. - */ -#if defined(__GNUC__) && defined(BCMRECLAIM) -extern bool bcmreclaimed; -#define BCMINITDATA(_data) __attribute__ ((__section__ (".dataini." #_data))) _data -#define BCMINITFN(_fn) __attribute__ ((__section__ (".textini." #_fn))) _fn -#else /* #if defined(__GNUC__) && defined(BCMRECLAIM) */ -#define BCMINITDATA(_data) _data -#define BCMINITFN(_fn) _fn -#define bcmreclaimed 0 -#endif /* #if defined(__GNUC__) && defined(BCMRECLAIM) */ - -/* Reclaim uninit functions if BCMNODOWN is defined */ -/* and if they are not already removed by -gc-sections */ -#ifdef BCMNODOWN -#define BCMUNINITFN(_fn) BCMINITFN(_fn) -#else -#define BCMUNINITFN(_fn) _fn -#endif - -#ifdef BCMRECLAIM -#define CONST -#else -#define CONST const -#endif /* BCMRECLAIM */ - -/* Compatibility with old-style BCMRECLAIM */ -#define BCMINIT(_id) _id - - -/* Put some library data/code into ROM to reduce RAM requirements */ -#if defined(__GNUC__) && defined(BCMROMOFFLOAD) -#define BCMROMDATA(_data) __attribute__ ((__section__ (".datarom." #_data))) _data -#define BCMROMFN(_fn) __attribute__ ((__section__ (".textrom." #_fn))) _fn -#else -#define BCMROMDATA(_data) _data -#define BCMROMFN(_fn) _fn -#endif - -/* Bus types */ -#define SB_BUS 0 /* Silicon Backplane */ -#define PCI_BUS 1 /* PCI target */ -#define PCMCIA_BUS 2 /* PCMCIA target */ -#define SDIO_BUS 3 /* SDIO target */ -#define JTAG_BUS 4 /* JTAG */ -#define NO_BUS 0xFF /* Bus that does not support R/W REG */ - -/* Allows optimization for single-bus support */ -#ifdef BCMBUSTYPE -#define BUSTYPE(bus) (BCMBUSTYPE) -#else -#define BUSTYPE(bus) (bus) -#endif - -/* Defines for DMA Address Width - Shared between OSL and HNDDMA */ -#define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */ -#define DMADDR_MASK_30 0xc0000000 /* Address mask for 30-bits */ -#define DMADDR_MASK_0 0xffffffff /* Address mask for 0-bits (hi-part) */ - -#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ -#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ -#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ -#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ - -/* packet headroom necessary to accomodate the largest header in the system, (i.e TXOFF). - * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. - * There is a compile time check in wlc.c which ensure that this value is at least as big - * as TXOFF. This value is used in dma_rxfill (hnddma.c). - */ -#define BCMEXTRAHDROOM 160 - -/* Headroom required for dongle-to-host communication. Packets allocated - * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should - * leave this much room in front for low-level message headers which may - * be needed to get across the dongle bus to the host. (These messages - * don't go over the network, so room for the full WL header above would - * be a waste.) - */ -#define BCMDONGLEHDRSZ 8 - - - -#endif /* _bcmdefs_h_ */ diff --git a/package/wlc/src/include/bcmutils.h b/package/wlc/src/include/bcmutils.h deleted file mode 100644 index b6e7b0542b..0000000000 --- a/package/wlc/src/include/bcmutils.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Misc useful os-independent macros and functions. - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $ - */ - -#ifndef _bcmutils_h_ -#define _bcmutils_h_ - -/* ** driver/apps-shared section ** */ - -#define BCME_STRLEN 64 /* Max string length for BCM errors */ -#define VALID_BCMERROR(e) ((e <= 0) && (e >= BCME_LAST)) - - -/* - * error codes could be added but the defined ones shouldn't be changed/deleted - * these error codes are exposed to the user code - * when ever a new error code is added to this list - * please update errorstring table with the related error string and - * update osl files with os specific errorcode map -*/ - -#define BCME_OK 0 /* Success */ -#define BCME_ERROR -1 /* Error generic */ -#define BCME_BADARG -2 /* Bad Argument */ -#define BCME_BADOPTION -3 /* Bad option */ -#define BCME_NOTUP -4 /* Not up */ -#define BCME_NOTDOWN -5 /* Not down */ -#define BCME_NOTAP -6 /* Not AP */ -#define BCME_NOTSTA -7 /* Not STA */ -#define BCME_BADKEYIDX -8 /* BAD Key Index */ -#define BCME_RADIOOFF -9 /* Radio Off */ -#define BCME_NOTBANDLOCKED -10 /* Not band locked */ -#define BCME_NOCLK -11 /* No Clock */ -#define BCME_BADRATESET -12 /* BAD Rate valueset */ -#define BCME_BADBAND -13 /* BAD Band */ -#define BCME_BUFTOOSHORT -14 /* Buffer too short */ -#define BCME_BUFTOOLONG -15 /* Buffer too long */ -#define BCME_BUSY -16 /* Busy */ -#define BCME_NOTASSOCIATED -17 /* Not Associated */ -#define BCME_BADSSIDLEN -18 /* Bad SSID len */ -#define BCME_OUTOFRANGECHAN -19 /* Out of Range Channel */ -#define BCME_BADCHAN -20 /* Bad Channel */ -#define BCME_BADADDR -21 /* Bad Address */ -#define BCME_NORESOURCE -22 /* Not Enough Resources */ -#define BCME_UNSUPPORTED -23 /* Unsupported */ -#define BCME_BADLEN -24 /* Bad length */ -#define BCME_NOTREADY -25 /* Not Ready */ -#define BCME_EPERM -26 /* Not Permitted */ -#define BCME_NOMEM -27 /* No Memory */ -#define BCME_ASSOCIATED -28 /* Associated */ -#define BCME_RANGE -29 /* Not In Range */ -#define BCME_NOTFOUND -30 /* Not Found */ -#define BCME_WME_NOT_ENABLED -31 /* WME Not Enabled */ -#define BCME_TSPEC_NOTFOUND -32 /* TSPEC Not Found */ -#define BCME_ACM_NOTSUPPORTED -33 /* ACM Not Supported */ -#define BCME_NOT_WME_ASSOCIATION -34 /* Not WME Association */ -#define BCME_SDIO_ERROR -35 /* SDIO Bus Error */ -#define BCME_DONGLE_DOWN -36 /* Dongle Not Accessible */ -#define BCME_LAST BCME_DONGLE_DOWN - -/* These are collection of BCME Error strings */ -#define BCMERRSTRINGTABLE { \ - "OK", \ - "Undefined error", \ - "Bad Argument", \ - "Bad Option", \ - "Not up", \ - "Not down", \ - "Not AP", \ - "Not STA", \ - "Bad Key Index", \ - "Radio Off", \ - "Not band locked", \ - "No clock", \ - "Bad Rate valueset", \ - "Bad Band", \ - "Buffer too short", \ - "Buffer too long", \ - "Busy", \ - "Not Associated", \ - "Bad SSID len", \ - "Out of Range Channel", \ - "Bad Channel", \ - "Bad Address", \ - "Not Enough Resources", \ - "Unsupported", \ - "Bad length", \ - "Not Ready", \ - "Not Permitted", \ - "No Memory", \ - "Associated", \ - "Not In Range", \ - "Not Found", \ - "WME Not Enabled", \ - "TSPEC Not Found", \ - "ACM Not Supported", \ - "Not WME Association", \ - "SDIO Bus Error", \ - "Dongle Not Accessible" \ -} - -#ifndef ABS -#define ABS(a) (((a) < 0)?-(a):(a)) -#endif /* ABS */ - -#ifndef MIN -#define MIN(a, b) (((a) < (b))?(a):(b)) -#endif /* MIN */ - -#ifndef MAX -#define MAX(a, b) (((a) > (b))?(a):(b)) -#endif /* MAX */ - -#define CEIL(x, y) (((x) + ((y)-1)) / (y)) -#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y)) -#define ISALIGNED(a, x) (((a) & ((x)-1)) == 0) -#define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) -#define VALID_MASK(mask) !((mask) & ((mask) + 1)) -#define OFFSETOF(type, member) ((uint)(uintptr)&((type *)0)->member) -#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0])) - -/* bit map related macros */ -#ifndef setbit -#ifndef NBBY /* the BSD family defines NBBY */ -#define NBBY 8 /* 8 bits per byte */ -#endif /* #ifndef NBBY */ -#define setbit(a, i) (((uint8 *)a)[(i)/NBBY] |= 1<<((i)%NBBY)) -#define clrbit(a, i) (((uint8 *)a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) -#define isset(a, i) (((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) -#define isclr(a, i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) -#endif /* setbit */ - -#define NBITS(type) (sizeof(type) * 8) -#define NBITVAL(nbits) (1 << (nbits)) -#define MAXBITVAL(nbits) ((1 << (nbits)) - 1) -#define NBITMASK(nbits) MAXBITVAL(nbits) -#define MAXNBVAL(nbyte) MAXBITVAL((nbyte) * 8) - -/* basic mux operation - can be optimized on several architectures */ -#define MUX(pred, true, false) ((pred) ? (true) : (false)) - -/* modulo inc/dec - assumes x E [0, bound - 1] */ -#define MODDEC(x, bound) MUX((x) == 0, (bound) - 1, (x) - 1) -#define MODINC(x, bound) MUX((x) == (bound) - 1, 0, (x) + 1) - -/* modulo inc/dec, bound = 2^k */ -#define MODDEC_POW2(x, bound) (((x) - 1) & ((bound) - 1)) -#define MODINC_POW2(x, bound) (((x) + 1) & ((bound) - 1)) - -/* modulo add/sub - assumes x, y E [0, bound - 1] */ -#define MODADD(x, y, bound) \ - MUX((x) + (y) >= (bound), (x) + (y) - (bound), (x) + (y)) -#define MODSUB(x, y, bound) \ - MUX(((int)(x)) - ((int)(y)) < 0, (x) - (y) + (bound), (x) - (y)) - -/* module add/sub, bound = 2^k */ -#define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1)) -#define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) - -/* crc defines */ -#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ -#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ -#define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ -#define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ -#define CRC32_INIT_VALUE 0xffffffff /* Initial CRC32 checksum value */ -#define CRC32_GOOD_VALUE 0xdebb20e3 /* Good final CRC32 checksum value */ - -/* bcm_format_flags() bit description structure */ -typedef struct bcm_bit_desc { - uint32 bit; - char* name; -} bcm_bit_desc_t; - -/* tag_ID/length/value_buffer tuple */ -typedef struct bcm_tlv { - uint8 id; - uint8 len; - uint8 data[1]; -} bcm_tlv_t; - -/* Check that bcm_tlv_t fits into the given buflen */ -#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (int)(buflen) >= (int)(2 + (elt)->len)) - -/* buffer length for ethernet address from bcm_ether_ntoa() */ -#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ - -/* unaligned load and store macros */ -#ifdef IL_BIGENDIAN -static INLINE uint32 -load32_ua(uint8 *a) -{ - return ((a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3]); -} - -static INLINE void -store32_ua(uint8 *a, uint32 v) -{ - a[0] = (v >> 24) & 0xff; - a[1] = (v >> 16) & 0xff; - a[2] = (v >> 8) & 0xff; - a[3] = v & 0xff; -} - -static INLINE uint16 -load16_ua(uint8 *a) -{ - return ((a[0] << 8) | a[1]); -} - -static INLINE void -store16_ua(uint8 *a, uint16 v) -{ - a[0] = (v >> 8) & 0xff; - a[1] = v & 0xff; -} - -#else - -static INLINE uint32 -load32_ua(uint8 *a) -{ - return ((a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0]); -} - -static INLINE void -store32_ua(uint8 *a, uint32 v) -{ - a[3] = (v >> 24) & 0xff; - a[2] = (v >> 16) & 0xff; - a[1] = (v >> 8) & 0xff; - a[0] = v & 0xff; -} - -static INLINE uint16 -load16_ua(uint8 *a) -{ - return ((a[1] << 8) | a[0]); -} - -static INLINE void -store16_ua(uint8 *a, uint16 v) -{ - a[1] = (v >> 8) & 0xff; - a[0] = v & 0xff; -} - -#endif /* IL_BIGENDIAN */ - -#endif /* _bcmutils_h_ */ diff --git a/package/wlc/src/include/proto/802.11.h b/package/wlc/src/include/proto/802.11.h deleted file mode 100644 index 2b1c4ee111..0000000000 --- a/package/wlc/src/include/proto/802.11.h +++ /dev/null @@ -1,1258 +0,0 @@ -/* - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * Fundamental types and constants relating to 802.11 - * - * $Id: 802.11.h,v 1.1.1.17 2006/04/15 01:29:08 michael Exp $ - */ - -#ifndef _802_11_H_ -#define _802_11_H_ - -#ifndef _TYPEDEFS_H_ -#include -#endif - -#ifndef _NET_ETHERNET_H_ -#include -#endif - -#include - -/* enable structure packing */ -#if defined(__GNUC__) -#define PACKED __attribute__((packed)) -#else -#pragma pack(1) -#define PACKED -#endif - -#define DOT11_TU_TO_US 1024 /* 802.11 Time Unit is 1024 microseconds */ - -/* Generic 802.11 frame constants */ -#define DOT11_A3_HDR_LEN 24 /* d11 header length with A3 */ -#define DOT11_A4_HDR_LEN 30 /* d11 header length with A4 */ -#define DOT11_MAC_HDR_LEN DOT11_A3_HDR_LEN /* MAC header length */ -#define DOT11_FCS_LEN 4 /* d11 FCS length */ -#define DOT11_ICV_LEN 4 /* d11 ICV length */ -#define DOT11_ICV_AES_LEN 8 /* d11 ICV/AES length */ -#define DOT11_QOS_LEN 2 /* d11 QoS length */ -#define DOT11_HTC_LEN 4 /* d11 HT Control field length */ - -#define DOT11_KEY_INDEX_SHIFT 6 /* d11 key index shift */ -#define DOT11_IV_LEN 4 /* d11 IV length */ -#define DOT11_IV_TKIP_LEN 8 /* d11 IV TKIP length */ -#define DOT11_IV_AES_OCB_LEN 4 /* d11 IV/AES/OCB length */ -#define DOT11_IV_AES_CCM_LEN 8 /* d11 IV/AES/CCM length */ -#define DOT11_IV_MAX_LEN 8 /* maximum iv len for any encryption */ - -/* Includes MIC */ -#define DOT11_MAX_MPDU_BODY_LEN 2304 /* max MPDU body length */ -/* A4 header + QoS + CCMP + PDU + ICV + FCS = 2352 */ -#define DOT11_MAX_MPDU_LEN (DOT11_A4_HDR_LEN + \ - DOT11_QOS_LEN + \ - DOT11_IV_AES_CCM_LEN + \ - DOT11_MAX_MPDU_BODY_LEN + \ - DOT11_ICV_LEN + \ - DOT11_FCS_LEN) /* d11 max MPDU length */ - -#define DOT11_MAX_SSID_LEN 32 /* d11 max ssid length */ - -/* dot11RTSThreshold */ -#define DOT11_DEFAULT_RTS_LEN 2347 /* d11 default RTS length */ -#define DOT11_MAX_RTS_LEN 2347 /* d11 max RTS length */ - -/* dot11FragmentationThreshold */ -#define DOT11_MIN_FRAG_LEN 256 /* d11 min fragmentation length */ -#define DOT11_MAX_FRAG_LEN 2346 /* Max frag is also limited by aMPDUMaxLength - * of the attached PHY - */ -#define DOT11_DEFAULT_FRAG_LEN 2346 /* d11 default fragmentation length */ - -/* dot11BeaconPeriod */ -#define DOT11_MIN_BEACON_PERIOD 1 /* d11 min beacon period */ -#define DOT11_MAX_BEACON_PERIOD 0xFFFF /* d11 max beacon period */ - -/* dot11DTIMPeriod */ -#define DOT11_MIN_DTIM_PERIOD 1 /* d11 min DTIM period */ -#define DOT11_MAX_DTIM_PERIOD 0xFF /* d11 max DTIM period */ - -/* 802.2 LLC/SNAP header used by 802.11 per 802.1H */ -#define DOT11_LLC_SNAP_HDR_LEN 8 /* d11 LLC/SNAP header length */ -#define DOT11_OUI_LEN 3 /* d11 OUI length */ -struct dot11_llc_snap_header { - uint8 dsap; /* always 0xAA */ - uint8 ssap; /* always 0xAA */ - uint8 ctl; /* always 0x03 */ - uint8 oui[DOT11_OUI_LEN]; /* RFC1042: 0x00 0x00 0x00 - * Bridge-Tunnel: 0x00 0x00 0xF8 - */ - uint16 type; /* ethertype */ -} PACKED; - -/* RFC1042 header used by 802.11 per 802.1H */ -#define RFC1042_HDR_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN) /* RCF1042 header length */ - -/* Generic 802.11 MAC header */ -/* - * N.B.: This struct reflects the full 4 address 802.11 MAC header. - * The fields are defined such that the shorter 1, 2, and 3 - * address headers just use the first k fields. - */ -struct dot11_header { - uint16 fc; /* frame control */ - uint16 durid; /* duration/ID */ - struct ether_addr a1; /* address 1 */ - struct ether_addr a2; /* address 2 */ - struct ether_addr a3; /* address 3 */ - uint16 seq; /* sequence control */ - struct ether_addr a4; /* address 4 */ -} PACKED; - -/* Control frames */ - -struct dot11_rts_frame { - uint16 fc; /* frame control */ - uint16 durid; /* duration/ID */ - struct ether_addr ra; /* receiver address */ - struct ether_addr ta; /* transmitter address */ -} PACKED; -#define DOT11_RTS_LEN 16 /* d11 RTS frame length */ - -struct dot11_cts_frame { - uint16 fc; /* frame control */ - uint16 durid; /* duration/ID */ - struct ether_addr ra; /* receiver address */ -} PACKED; -#define DOT11_CTS_LEN 10 /* d11 CTS frame length */ - -struct dot11_ack_frame { - uint16 fc; /* frame control */ - uint16 durid; /* duration/ID */ - struct ether_addr ra; /* receiver address */ -} PACKED; -#define DOT11_ACK_LEN 10 /* d11 ACK frame length */ - -struct dot11_ps_poll_frame { - uint16 fc; /* frame control */ - uint16 durid; /* AID */ - struct ether_addr bssid; /* receiver address, STA in AP */ - struct ether_addr ta; /* transmitter address */ -} PACKED; -#define DOT11_PS_POLL_LEN 16 /* d11 PS poll frame length */ - -struct dot11_cf_end_frame { - uint16 fc; /* frame control */ - uint16 durid; /* duration/ID */ - struct ether_addr ra; /* receiver address */ - struct ether_addr bssid; /* transmitter address, STA in AP */ -} PACKED; -#define DOT11_CS_END_LEN 16 /* d11 CF-END frame length */ - -/* BA/BAR Control parameters */ -#define DOT11_BA_CTL_POLICY_NORMAL 0x0000 /* normal ack */ -#define DOT11_BA_CTL_POLICY_NOACK 0x0001 /* no ack */ -#define DOT11_BA_CTL_POLICY_MASK 0x0001 /* ack policy mask */ - -#define DOT11_BA_CTL_MTID 0x0002 /* multi tid BA */ -#define DOT11_BA_CTL_COMPRESSED 0x0004 /* compressed bitmap */ - -#define DOT11_BA_CTL_NUMMSDU_MASK 0x0FC0 /* num msdu in bitmap mask */ -#define DOT11_BA_CTL_NUMMSDU_SHIFT 6 /* num msdu in bitmap shift */ - -#define DOT11_BA_CTL_TID_MASK 0xF000 /* tid mask */ -#define DOT11_BA_CTL_TID_SHIFT 12 /* tid shift */ - -struct dot11_ba_req_frame { - uint16 fc; /* frame control */ - uint16 durid; /* duration/ID */ - struct ether_addr ra; /* receiver address */ - struct ether_addr ta; /* transmitter address */ - uint16 bar_control; /* BAR Control */ - uint16 seqnum; /* Starting Sequence control */ -} PACKED; -#define DOT11_BA_REQ_LEN 20 /* BAR frame length */ - -#define DOT11_BA_BITMAP_LEN 128 /* bitmap length */ -#define DOT11_BA_CMP_BITMAP_LEN 8 /* compressed bitmap length */ -struct dot11_ba_frame { - uint16 fc; /* frame control */ - uint16 durid; /* duration/ID */ - struct ether_addr ra; /* receiver address */ - struct ether_addr ta; /* transmitter address */ - uint16 ba_control; /* BA Control */ - uint16 seqnum; /* Starting Sequence control */ - uint8 bitmap[DOT11_BA_BITMAP_LEN]; /* Block Ack Bitmap */ -} PACKED; -#define DOT11_BA_LEN 20 /* BA frame length (without bitmap) */ - -/* Management frame header */ -struct dot11_management_header { - uint16 fc; /* frame control */ - uint16 durid; /* duration/ID */ - struct ether_addr da; /* receiver address */ - struct ether_addr sa; /* transmitter address */ - struct ether_addr bssid; /* BSS ID */ - uint16 seq; /* sequence control */ -} PACKED; -#define DOT11_MGMT_HDR_LEN 24 /* d11 management header length */ - -/* Management frame payloads */ - -struct dot11_bcn_prb { - uint32 timestamp[2]; - uint16 beacon_interval; - uint16 capability; -} PACKED; -#define DOT11_BCN_PRB_LEN 12 /* d11 beacon probe frame length */ - -struct dot11_auth { - uint16 alg; /* algorithm */ - uint16 seq; /* sequence control */ - uint16 status; /* status code */ -} PACKED; -#define DOT11_AUTH_FIXED_LEN 6 /* length of auth frame without challenge info - * elt - */ - -struct dot11_assoc_req { - uint16 capability; /* capability information */ - uint16 listen; /* listen interval */ -} PACKED; -#define DOT11_ASSOC_REQ_FIXED_LEN 4 /* length of assoc frame without info elts */ - -struct dot11_reassoc_req { - uint16 capability; /* capability information */ - uint16 listen; /* listen interval */ - struct ether_addr ap; /* Current AP address */ -} PACKED; -#define DOT11_REASSOC_REQ_FIXED_LEN 10 /* length of assoc frame without info elts */ - -struct dot11_assoc_resp { - uint16 capability; /* capability information */ - uint16 status; /* status code */ - uint16 aid; /* association ID */ -} PACKED; - -struct dot11_action_measure { - uint8 category; - uint8 action; - uint8 token; - uint8 data[1]; -} PACKED; -#define DOT11_ACTION_MEASURE_LEN 3 /* d11 action measurement header length */ - -struct dot11_action_switch_channel { - uint8 category; - uint8 action; - uint8 data[5]; /* for switch IE */ -} PACKED; - -struct dot11_action_ht_ch_width { - uint8 category; - uint8 action; - uint8 ch_width; -} PACKED; - -struct dot11_action_ht_mimops { - uint8 category; - uint8 action; - uint8 enable; - uint8 psmode; -} PACKED; - -/* ************* 802.11h related definitions. ************* */ -typedef struct { - uint8 id; - uint8 len; - uint8 power; -} dot11_power_cnst_t; - -typedef struct { - uint8 min; - uint8 max; -} dot11_power_cap_t; - -typedef struct { - uint8 id; - uint8 len; - uint8 tx_pwr; - uint8 margin; -} dot11_tpc_rep_t; -#define DOT11_MNG_IE_TPC_REPORT_LEN 2 /* length of IE data, not including 2 byte header */ - -typedef struct { - uint8 id; - uint8 len; - uint8 first_channel; - uint8 num_channels; -} dot11_supp_channels_t; - -/* channel switch announcement (CSA) mode type - 802.11h-2003 $7.3.2.20 */ -#define DOT11_CSA_MODE_ADVISORY 0 /* no DOT11_CSA_MODE_NO_TX restriction imposed */ -#define DOT11_CSA_MODE_NO_TX 1 /* no transmission upon receiving CSA frame. */ - -/* CSA IE data structure */ -struct dot11_channel_switch { - uint8 id; - uint8 len; - uint8 mode; - uint8 channel; - uint8 count; -} PACKED; -typedef struct dot11_channel_switch dot11_channel_switch_t; - -#define DOT11_SWITCH_IE_LEN 3 /* length of IE data, not including 2 byte header */ - -/* 802.11h Measurement Request/Report IEs */ -/* Measurement Type field */ -#define DOT11_MEASURE_TYPE_BASIC 0 /* d11 measurement basic type */ -#define DOT11_MEASURE_TYPE_CCA 1 /* d11 measurement CCA type */ -#define DOT11_MEASURE_TYPE_RPI 2 /* d11 measurement PRI type */ - -/* Measurement Mode field */ - -/* Measurement Request Modes */ -#define DOT11_MEASURE_MODE_ENABLE (1<<1) /* d11 measurement enable */ -#define DOT11_MEASURE_MODE_REQUEST (1<<2) /* d11 measurement request */ -#define DOT11_MEASURE_MODE_REPORT (1<<3) /* d11 measurement report */ -/* Measurement Report Modes */ -#define DOT11_MEASURE_MODE_LATE (1<<0) /* d11 measurement late */ -#define DOT11_MEASURE_MODE_INCAPABLE (1<<1) /* d11 measurement incapable */ -#define DOT11_MEASURE_MODE_REFUSED (1<<2) /* d11 measurement refuse */ -/* Basic Measurement Map bits */ -#define DOT11_MEASURE_BASIC_MAP_BSS ((uint8)(1<<0)) /* d11 measurement basic map BSS */ -#define DOT11_MEASURE_BASIC_MAP_OFDM ((uint8)(1<<1)) /* d11 measurement map OFDM */ -#define DOT11_MEASURE_BASIC_MAP_UKNOWN ((uint8)(1<<2)) /* d11 measurement map unknown */ -#define DOT11_MEASURE_BASIC_MAP_RADAR ((uint8)(1<<3)) /* d11 measurement map radar */ -#define DOT11_MEASURE_BASIC_MAP_UNMEAS ((uint8)(1<<4)) /* d11 measurement map unmeasuremnt */ - -typedef struct { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; - uint8 channel; - uint8 start_time[8]; - uint16 duration; -} dot11_meas_req_t; -#define DOT11_MNG_IE_MREQ_LEN 14 /* d11 measurement request IE length */ -/* length of Measure Request IE data not including variable len */ -#define DOT11_MNG_IE_MREQ_FIXED_LEN 3 /* d11 measurement request IE fixed length */ - -struct dot11_meas_rep { - uint8 id; - uint8 len; - uint8 token; - uint8 mode; - uint8 type; - union - { - struct { - uint8 channel; - uint8 start_time[8]; - uint16 duration; - uint8 map; - } PACKED basic; - uint8 data[1]; - } PACKED rep; -} PACKED; -typedef struct dot11_meas_rep dot11_meas_rep_t; - -/* length of Measure Report IE data not including variable len */ -#define DOT11_MNG_IE_MREP_FIXED_LEN 3 /* d11 measurement response IE fixed length */ - -struct dot11_meas_rep_basic { - uint8 channel; - uint8 start_time[8]; - uint16 duration; - uint8 map; -} PACKED; -typedef struct dot11_meas_rep_basic dot11_meas_rep_basic_t; -#define DOT11_MEASURE_BASIC_REP_LEN 12 /* d11 measurement basic report length */ - -struct dot11_quiet { - uint8 id; - uint8 len; - uint8 count; /* TBTTs until beacon interval in quiet starts */ - uint8 period; /* Beacon intervals between periodic quiet periods ? */ - uint16 duration; /* Length of quiet period, in TU's */ - uint16 offset; /* TU's offset from TBTT in Count field */ -} PACKED; -typedef struct dot11_quiet dot11_quiet_t; - -typedef struct { - uint8 channel; - uint8 map; -} chan_map_tuple_t; - -typedef struct { - uint8 id; - uint8 len; - uint8 eaddr[ETHER_ADDR_LEN]; - uint8 interval; - chan_map_tuple_t map[1]; -} dot11_ibss_dfs_t; - -/* WME Elements */ -#define WME_OUI "\x00\x50\xf2" /* WME OUI */ -#define WME_VER 1 /* WME version */ -#define WME_TYPE 2 /* WME type */ -#define WME_SUBTYPE_IE 0 /* Information Element */ -#define WME_SUBTYPE_PARAM_IE 1 /* Parameter Element */ -#define WME_SUBTYPE_TSPEC 2 /* Traffic Specification */ - -/* WME Access Category Indices (ACIs) */ -#define AC_BE 0 /* Best Effort */ -#define AC_BK 1 /* Background */ -#define AC_VI 2 /* Video */ -#define AC_VO 3 /* Voice */ -#define AC_COUNT 4 /* number of ACs */ - -typedef uint8 ac_bitmap_t; /* AC bitmap of (1 << AC_xx) */ - -#define AC_BITMAP_NONE 0x0 /* No ACs */ -#define AC_BITMAP_ALL 0xf /* All ACs */ -#define AC_BITMAP_TST(ab, ac) (((ab) & (1 << (ac))) != 0) - -/* WME Information Element (IE) */ -struct wme_ie { - uint8 oui[3]; - uint8 type; - uint8 subtype; - uint8 version; - uint8 qosinfo; -} PACKED; -typedef struct wme_ie wme_ie_t; -#define WME_IE_LEN 7 /* WME IE length */ - -struct edcf_acparam { - uint8 ACI; - uint8 ECW; - uint16 TXOP; /* stored in network order (ls octet first) */ -} PACKED; -typedef struct edcf_acparam edcf_acparam_t; - -/* WME Parameter Element (PE) */ -struct wme_param_ie { - uint8 oui[3]; - uint8 type; - uint8 subtype; - uint8 version; - uint8 qosinfo; - uint8 rsvd; - edcf_acparam_t acparam[AC_COUNT]; -} PACKED; -typedef struct wme_param_ie wme_param_ie_t; -#define WME_PARAM_IE_LEN 24 /* WME Parameter IE length */ - -/* QoS Info field for IE as sent from AP */ -#define WME_QI_AP_APSD_MASK 0x80 /* U-APSD Supported mask */ -#define WME_QI_AP_APSD_SHIFT 7 /* U-APSD Supported shift */ -#define WME_QI_AP_COUNT_MASK 0x0f /* Parameter set count mask */ -#define WME_QI_AP_COUNT_SHIFT 0 /* Parameter set count shift */ - -/* QoS Info field for IE as sent from STA */ -#define WME_QI_STA_MAXSPLEN_MASK 0x60 /* Max Service Period Length mask */ -#define WME_QI_STA_MAXSPLEN_SHIFT 5 /* Max Service Period Length shift */ -#define WME_QI_STA_APSD_ALL_MASK 0xf /* APSD all AC bits mask */ -#define WME_QI_STA_APSD_ALL_SHIFT 0 /* APSD all AC bits shift */ -#define WME_QI_STA_APSD_BE_MASK 0x8 /* APSD AC_BE mask */ -#define WME_QI_STA_APSD_BE_SHIFT 3 /* APSD AC_BE shift */ -#define WME_QI_STA_APSD_BK_MASK 0x4 /* APSD AC_BK mask */ -#define WME_QI_STA_APSD_BK_SHIFT 2 /* APSD AC_BK shift */ -#define WME_QI_STA_APSD_VI_MASK 0x2 /* APSD AC_VI mask */ -#define WME_QI_STA_APSD_VI_SHIFT 1 /* APSD AC_VI shift */ -#define WME_QI_STA_APSD_VO_MASK 0x1 /* APSD AC_VO mask */ -#define WME_QI_STA_APSD_VO_SHIFT 0 /* APSD AC_VO shift */ - -/* ACI */ -#define EDCF_AIFSN_MIN 1 /* AIFSN minimum value */ -#define EDCF_AIFSN_MAX 15 /* AIFSN maximum value */ -#define EDCF_AIFSN_MASK 0x0f /* AIFSN mask */ -#define EDCF_ACM_MASK 0x10 /* ACM mask */ -#define EDCF_ACI_MASK 0x60 /* ACI mask */ -#define EDCF_ACI_SHIFT 5 /* ACI shift */ - -/* ECW */ -#define EDCF_ECW_MIN 0 /* cwmin/cwmax exponent minimum value */ -#define EDCF_ECW_MAX 15 /* cwmin/cwmax exponent maximum value */ -#define EDCF_ECW2CW(exp) ((1 << (exp)) - 1) -#define EDCF_ECWMIN_MASK 0x0f /* cwmin exponent form mask */ -#define EDCF_ECWMAX_MASK 0xf0 /* cwmax exponent form mask */ -#define EDCF_ECWMAX_SHIFT 4 /* cwmax exponent form shift */ - -/* TXOP */ -#define EDCF_TXOP_MIN 0 /* TXOP minimum value */ -#define EDCF_TXOP_MAX 65535 /* TXOP maximum value */ -#define EDCF_TXOP2USEC(txop) ((txop) << 5) - -/* Default EDCF parameters that AP advertises for STA to use; WMM draft Table 12 */ -#define EDCF_AC_BE_ACI_STA 0x03 /* STA ACI value for best effort AC */ -#define EDCF_AC_BE_ECW_STA 0xA4 /* STA ECW value for best effort AC */ -#define EDCF_AC_BE_TXOP_STA 0x0000 /* STA TXOP value for best effort AC */ -#define EDCF_AC_BK_ACI_STA 0x27 /* STA ACI value for background AC */ -#define EDCF_AC_BK_ECW_STA 0xA4 /* STA ECW value for background AC */ -#define EDCF_AC_BK_TXOP_STA 0x0000 /* STA TXOP value for background AC */ -#define EDCF_AC_VI_ACI_STA 0x42 /* STA ACI value for video AC */ -#define EDCF_AC_VI_ECW_STA 0x43 /* STA ECW value for video AC */ -#define EDCF_AC_VI_TXOP_STA 0x005e /* STA TXOP value for video AC */ -#define EDCF_AC_VO_ACI_STA 0x62 /* STA ACI value for audio AC */ -#define EDCF_AC_VO_ECW_STA 0x32 /* STA ECW value for audio AC */ -#define EDCF_AC_VO_TXOP_STA 0x002f /* STA TXOP value for audio AC */ - -/* Default EDCF parameters that AP uses; WMM draft Table 14 */ -#define EDCF_AC_BE_ACI_AP 0x03 /* AP ACI value for best effort AC */ -#define EDCF_AC_BE_ECW_AP 0x64 /* AP ECW value for best effort AC */ -#define EDCF_AC_BE_TXOP_AP 0x0000 /* AP TXOP value for best effort AC */ -#define EDCF_AC_BK_ACI_AP 0x27 /* AP ACI value for background AC */ -#define EDCF_AC_BK_ECW_AP 0xA4 /* AP ECW value for background AC */ -#define EDCF_AC_BK_TXOP_AP 0x0000 /* AP TXOP value for background AC */ -#define EDCF_AC_VI_ACI_AP 0x41 /* AP ACI value for video AC */ -#define EDCF_AC_VI_ECW_AP 0x43 /* AP ECW value for video AC */ -#define EDCF_AC_VI_TXOP_AP 0x005e /* AP TXOP value for video AC */ -#define EDCF_AC_VO_ACI_AP 0x61 /* AP ACI value for audio AC */ -#define EDCF_AC_VO_ECW_AP 0x32 /* AP ECW value for audio AC */ -#define EDCF_AC_VO_TXOP_AP 0x002f /* AP TXOP value for audio AC */ - -struct dot11_qbss_load_ie { - uint8 id; /* 11, DOT11_MNG_QBSS_LOAD_ID */ - uint8 length; - uint16 station_count; /* total number of STAs associated */ - uint8 channel_utilization; /* % of time, normalized to 255, QAP sensed medium busy */ - uint16 aac; /* available admission capacity */ -} PACKED; -typedef struct dot11_qbss_load_ie dot11_qbss_load_ie_t; - -/* nom_msdu_size */ -#define FIXED_MSDU_SIZE 0x8000 /* MSDU size is fixed */ -#define MSDU_SIZE_MASK 0x7fff /* (Nominal or fixed) MSDU size */ - -/* surplus_bandwidth */ -/* Represented as 3 bits of integer, binary point, 13 bits fraction */ -#define INTEGER_SHIFT 13 /* integer shift */ -#define FRACTION_MASK 0x1FFF /* fraction mask */ - -/* Management Notification Frame */ -struct dot11_management_notification { - uint8 category; /* DOT11_ACTION_NOTIFICATION */ - uint8 action; - uint8 token; - uint8 status; - uint8 data[1]; /* Elements */ -} PACKED; -#define DOT11_MGMT_NOTIFICATION_LEN 4 /* Fixed length */ - -/* WME Action Codes */ -#define WME_ADDTS_REQUEST 0 /* WME ADDTS request */ -#define WME_ADDTS_RESPONSE 1 /* WME ADDTS response */ -#define WME_DELTS_REQUEST 2 /* WME DELTS request */ - -/* WME Setup Response Status Codes */ -#define WME_ADMISSION_ACCEPTED 0 /* WME admission accepted */ -#define WME_INVALID_PARAMETERS 1 /* WME invalide parameters */ -#define WME_ADMISSION_REFUSED 3 /* WME admission refused */ - -/* Macro to take a pointer to a beacon or probe response - * header and return the char* pointer to the SSID info element - */ -#define BCN_PRB_SSID(hdr) ((char*)(hdr) + DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_LEN) - -/* Authentication frame payload constants */ -#define DOT11_OPEN_SYSTEM 0 /* d11 open authentication */ -#define DOT11_SHARED_KEY 1 /* d11 shared authentication */ -#define DOT11_CHALLENGE_LEN 128 /* d11 chanllenge text length */ - -/* Frame control macros */ -#define FC_PVER_MASK 0x3 /* PVER mask */ -#define FC_PVER_SHIFT 0 /* PVER shift */ -#define FC_TYPE_MASK 0xC /* type mask */ -#define FC_TYPE_SHIFT 2 /* type shift */ -#define FC_SUBTYPE_MASK 0xF0 /* subtype mask */ -#define FC_SUBTYPE_SHIFT 4 /* subtype shift */ -#define FC_TODS 0x100 /* to DS */ -#define FC_TODS_SHIFT 8 /* to DS shift */ -#define FC_FROMDS 0x200 /* from DS */ -#define FC_FROMDS_SHIFT 9 /* from DS shift */ -#define FC_MOREFRAG 0x400 /* more frag. */ -#define FC_MOREFRAG_SHIFT 10 /* more frag. shift */ -#define FC_RETRY 0x800 /* retry */ -#define FC_RETRY_SHIFT 11 /* retry shift */ -#define FC_PM 0x1000 /* PM */ -#define FC_PM_SHIFT 12 /* PM shift */ -#define FC_MOREDATA 0x2000 /* more data */ -#define FC_MOREDATA_SHIFT 13 /* more data shift */ -#define FC_WEP 0x4000 /* WEP */ -#define FC_WEP_SHIFT 14 /* WEP shift */ -#define FC_ORDER 0x8000 /* order */ -#define FC_ORDER_SHIFT 15 /* order shift */ - -/* sequence control macros */ -#define SEQNUM_SHIFT 4 /* seq. number shift */ -#define SEQNUM_MAX 0x1000 /* max seqnum + 1 */ -#define FRAGNUM_MASK 0xF /* frag. number mask */ - -/* Frame Control type/subtype defs */ - -/* FC Types */ -#define FC_TYPE_MNG 0 /* management type */ -#define FC_TYPE_CTL 1 /* control type */ -#define FC_TYPE_DATA 2 /* data type */ - -/* Management Subtypes */ -#define FC_SUBTYPE_ASSOC_REQ 0 /* assoc. request */ -#define FC_SUBTYPE_ASSOC_RESP 1 /* assoc. response */ -#define FC_SUBTYPE_REASSOC_REQ 2 /* reassoc. request */ -#define FC_SUBTYPE_REASSOC_RESP 3 /* reassoc. response */ -#define FC_SUBTYPE_PROBE_REQ 4 /* probe request */ -#define FC_SUBTYPE_PROBE_RESP 5 /* probe response */ -#define FC_SUBTYPE_BEACON 8 /* beacon */ -#define FC_SUBTYPE_ATIM 9 /* ATIM */ -#define FC_SUBTYPE_DISASSOC 10 /* disassoc. */ -#define FC_SUBTYPE_AUTH 11 /* authentication */ -#define FC_SUBTYPE_DEAUTH 12 /* de-authentication */ -#define FC_SUBTYPE_ACTION 13 /* action */ - -/* Control Subtypes */ -#define FC_SUBTYPE_BLOCKACK_REQ 8 /* Block Ack Req */ -#define FC_SUBTYPE_BLOCKACK 9 /* Block Ack */ -#define FC_SUBTYPE_PS_POLL 10 /* PS poll */ -#define FC_SUBTYPE_RTS 11 /* RTS */ -#define FC_SUBTYPE_CTS 12 /* CTS */ -#define FC_SUBTYPE_ACK 13 /* ACK */ -#define FC_SUBTYPE_CF_END 14 /* CF-END */ -#define FC_SUBTYPE_CF_END_ACK 15 /* CF-END ACK */ - -/* Data Subtypes */ -#define FC_SUBTYPE_DATA 0 /* Data */ -#define FC_SUBTYPE_DATA_CF_ACK 1 /* Data + CF-ACK */ -#define FC_SUBTYPE_DATA_CF_POLL 2 /* Data + CF-Poll */ -#define FC_SUBTYPE_DATA_CF_ACK_POLL 3 /* Data + CF-Ack + CF-Poll */ -#define FC_SUBTYPE_NULL 4 /* Null */ -#define FC_SUBTYPE_CF_ACK 5 /* CF-Ack */ -#define FC_SUBTYPE_CF_POLL 6 /* CF-Poll */ -#define FC_SUBTYPE_CF_ACK_POLL 7 /* CF-Ack + CF-Poll */ -#define FC_SUBTYPE_QOS_DATA 8 /* QoS Data */ -#define FC_SUBTYPE_QOS_DATA_CF_ACK 9 /* QoS Data + CF-Ack */ -#define FC_SUBTYPE_QOS_DATA_CF_POLL 10 /* QoS Data + CF-Poll */ -#define FC_SUBTYPE_QOS_DATA_CF_ACK_POLL 11 /* QoS Data + CF-Ack + CF-Poll */ -#define FC_SUBTYPE_QOS_NULL 12 /* QoS Null */ -#define FC_SUBTYPE_QOS_CF_POLL 14 /* QoS CF-Poll */ -#define FC_SUBTYPE_QOS_CF_ACK_POLL 15 /* QoS CF-Ack + CF-Poll */ - -/* Data Subtype Groups */ -#define FC_SUBTYPE_ANY_QOS(s) (((s) & 8) != 0) -#define FC_SUBTYPE_ANY_NULL(s) (((s) & 4) != 0) -#define FC_SUBTYPE_ANY_CF_POLL(s) (((s) & 2) != 0) -#define FC_SUBTYPE_ANY_CF_ACK(s) (((s) & 1) != 0) - -/* Type/Subtype Combos */ -#define FC_KIND_MASK (FC_TYPE_MASK | FC_SUBTYPE_MASK) /* FC kind mask */ - -#define FC_KIND(t, s) (((t) << FC_TYPE_SHIFT) | ((s) << FC_SUBTYPE_SHIFT)) /* FC kind */ - -#define FC_SUBTYPE(fc) (((fc) & FC_SUBTYPE_MASK) >> FC_SUBTYPE_SHIFT) /* Subtype from FC */ -#define FC_TYPE(fc) (((fc) & FC_TYPE_MASK) >> FC_TYPE_SHIFT) /* Type from FC */ - -#define FC_ASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_REQ) /* assoc. request */ -#define FC_ASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ASSOC_RESP) /* assoc. response */ -#define FC_REASSOC_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_REQ) /* reassoc. request */ -#define FC_REASSOC_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_REASSOC_RESP) /* reassoc. response */ -#define FC_PROBE_REQ FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_REQ) /* probe request */ -#define FC_PROBE_RESP FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_PROBE_RESP) /* probe response */ -#define FC_BEACON FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_BEACON) /* beacon */ -#define FC_DISASSOC FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DISASSOC) /* disassoc */ -#define FC_AUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_AUTH) /* authentication */ -#define FC_DEAUTH FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_DEAUTH) /* deauthentication */ -#define FC_ACTION FC_KIND(FC_TYPE_MNG, FC_SUBTYPE_ACTION) /* action */ - -#define FC_BLOCKACK_REQ FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK_REQ) /* Block Ack Req */ -#define FC_BLOCKACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_BLOCKACK) /* Block Ack */ -#define FC_PS_POLL FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_PS_POLL) /* PS poll */ -#define FC_RTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_RTS) /* RTS */ -#define FC_CTS FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CTS) /* CTS */ -#define FC_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_ACK) /* ACK */ -#define FC_CF_END FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END) /* CF-END */ -#define FC_CF_END_ACK FC_KIND(FC_TYPE_CTL, FC_SUBTYPE_CF_END_ACK) /* CF-END ACK */ - -#define FC_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA) /* data */ -#define FC_NULL_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_NULL) /* null data */ -#define FC_DATA_CF_ACK FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_DATA_CF_ACK) /* data CF ACK */ -#define FC_QOS_DATA FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_DATA) /* QoS data */ -#define FC_QOS_NULL FC_KIND(FC_TYPE_DATA, FC_SUBTYPE_QOS_NULL) /* QoS null */ - -/* QoS Control Field */ - -/* 802.1D Priority */ -#define QOS_PRIO_SHIFT 0 /* QoS priority shift */ -#define QOS_PRIO_MASK 0x0007 /* QoS priority mask */ -#define QOS_PRIO(qos) (((qos) & QOS_PRIO_MASK) >> QOS_PRIO_SHIFT) /* QoS priority */ - -/* Traffic Identifier */ -#define QOS_TID_SHIFT 0 /* QoS TID shift */ -#define QOS_TID_MASK 0x000f /* QoS TID mask */ -#define QOS_TID(qos) (((qos) & QOS_TID_MASK) >> QOS_TID_SHIFT) /* QoS TID */ - -/* End of Service Period (U-APSD) */ -#define QOS_EOSP_SHIFT 4 /* QoS End of Service Period shift */ -#define QOS_EOSP_MASK 0x0010 /* QoS End of Service Period mask */ -#define QOS_EOSP(qos) (((qos) & QOS_EOSP_MASK) >> QOS_EOSP_SHIFT) /* Qos EOSP */ - -/* Ack Policy */ -#define QOS_ACK_NORMAL_ACK 0 /* Normal Ack */ -#define QOS_ACK_NO_ACK 1 /* No Ack (eg mcast) */ -#define QOS_ACK_NO_EXP_ACK 2 /* No Explicit Ack */ -#define QOS_ACK_BLOCK_ACK 3 /* Block Ack */ -#define QOS_ACK_SHIFT 5 /* QoS ACK shift */ -#define QOS_ACK_MASK 0x0060 /* QoS ACK mask */ -#define QOS_ACK(qos) (((qos) & QOS_ACK_MASK) >> QOS_ACK_SHIFT) /* QoS ACK */ - -/* A-MSDU flag */ -#define QOS_AMSDU_SHIFT 7 /* AMSDU shift */ -#define QOS_AMSDU_MASK 0x0080 /* AMSDU mask */ - -/* Management Frames */ - -/* Management Frame Constants */ - -/* Fixed fields */ -#define DOT11_MNG_AUTH_ALGO_LEN 2 /* d11 management auth. algo. length */ -#define DOT11_MNG_AUTH_SEQ_LEN 2 /* d11 management auth. seq. length */ -#define DOT11_MNG_BEACON_INT_LEN 2 /* d11 management beacon interval length */ -#define DOT11_MNG_CAP_LEN 2 /* d11 management cap. length */ -#define DOT11_MNG_AP_ADDR_LEN 6 /* d11 management AP address length */ -#define DOT11_MNG_LISTEN_INT_LEN 2 /* d11 management listen interval length */ -#define DOT11_MNG_REASON_LEN 2 /* d11 management reason length */ -#define DOT11_MNG_AID_LEN 2 /* d11 management AID length */ -#define DOT11_MNG_STATUS_LEN 2 /* d11 management status length */ -#define DOT11_MNG_TIMESTAMP_LEN 8 /* d11 management timestamp length */ - -/* DUR/ID field in assoc resp is 0xc000 | AID */ -#define DOT11_AID_MASK 0x3fff /* d11 AID mask */ - -/* Reason Codes */ -#define DOT11_RC_RESERVED 0 /* d11 RC reserved */ -#define DOT11_RC_UNSPECIFIED 1 /* Unspecified reason */ -#define DOT11_RC_AUTH_INVAL 2 /* Previous authentication no longer - * valid - */ -#define DOT11_RC_DEAUTH_LEAVING 3 /* Deauthenticated because sending station - * is leaving (or has left) IBSS or ESS - */ -#define DOT11_RC_INACTIVITY 4 /* Disassociated due to inactivity */ -#define DOT11_RC_BUSY 5 /* Disassociated because AP is unable - * to handle all currently associated - * stations - */ -#define DOT11_RC_INVAL_CLASS_2 6 /* Class 2 frame received from - * nonauthenticated station - */ -#define DOT11_RC_INVAL_CLASS_3 7 /* Class 3 frame received from - * nonassociated station - */ -#define DOT11_RC_DISASSOC_LEAVING 8 /* Disassociated because sending station is - * leaving (or has left) BSS - */ -#define DOT11_RC_NOT_AUTH 9 /* Station requesting (re)association is - * not authenticated with responding - * station - */ -#define DOT11_RC_MAX 23 /* Reason codes > 23 are reserved */ - -/* Status Codes */ -#define DOT11_STATUS_SUCCESS 0 /* Successful */ -#define DOT11_STATUS_FAILURE 1 /* Unspecified failure */ -#define DOT11_STATUS_CAP_MISMATCH 10 /* Cannot support all requested - * capabilities in the Capability - * Information field - */ -#define DOT11_STATUS_REASSOC_FAIL 11 /* Reassociation denied due to inability - * to confirm that association exists - */ -#define DOT11_STATUS_ASSOC_FAIL 12 /* Association denied due to reason - * outside the scope of this standard - */ -#define DOT11_STATUS_AUTH_MISMATCH 13 /* Responding station does not support - * the specified authentication - * algorithm - */ -#define DOT11_STATUS_AUTH_SEQ 14 /* Received an Authentication frame - * with authentication transaction - * sequence number out of expected - * sequence - */ -#define DOT11_STATUS_AUTH_CHALLENGE_FAIL 15 /* Authentication rejected because of - * challenge failure - */ -#define DOT11_STATUS_AUTH_TIMEOUT 16 /* Authentication rejected due to timeout - * waiting for next frame in sequence - */ -#define DOT11_STATUS_ASSOC_BUSY_FAIL 17 /* Association denied because AP is - * unable to handle additional - * associated stations - */ -#define DOT11_STATUS_ASSOC_RATE_MISMATCH 18 /* Association denied due to requesting - * station not supporting all of the - * data rates in the BSSBasicRateSet - * parameter - */ -#define DOT11_STATUS_ASSOC_SHORT_REQUIRED 19 /* Association denied due to requesting - * station not supporting the Short - * Preamble option - */ -#define DOT11_STATUS_ASSOC_PBCC_REQUIRED 20 /* Association denied due to requesting - * station not supporting the PBCC - * Modulation option - */ -#define DOT11_STATUS_ASSOC_AGILITY_REQUIRED 21 /* Association denied due to requesting - * station not supporting the Channel - * Agility option - */ -#define DOT11_STATUS_ASSOC_SPECTRUM_REQUIRED 22 /* Association denied because Spectrum - * Management capability is required. - */ -#define DOT11_STATUS_ASSOC_BAD_POWER_CAP 23 /* Association denied because the info - * in the Power Cap element is - * unacceptable. - */ -#define DOT11_STATUS_ASSOC_BAD_SUP_CHANNELS 24 /* Association denied because the info - * in the Supported Channel element is - * unacceptable - */ -#define DOT11_STATUS_ASSOC_SHORTSLOT_REQUIRED 25 /* Association denied due to requesting - * station not supporting the Short Slot - * Time option - */ -#define DOT11_STATUS_ASSOC_ERPBCC_REQUIRED 26 /* Association denied due to requesting - * station not supporting the ER-PBCC - * Modulation option - */ -#define DOT11_STATUS_ASSOC_DSSOFDM_REQUIRED 27 /* Association denied due to requesting - * station not supporting the DSS-OFDM - * option - */ - -/* Info Elts, length of INFORMATION portion of Info Elts */ -#define DOT11_MNG_DS_PARAM_LEN 1 /* d11 management DS parameter length */ -#define DOT11_MNG_IBSS_PARAM_LEN 2 /* d11 management IBSS parameter length */ - -/* TIM Info element has 3 bytes fixed info in INFORMATION field, - * followed by 1 to 251 bytes of Partial Virtual Bitmap - */ -#define DOT11_MNG_TIM_FIXED_LEN 3 /* d11 management TIM fixed length */ -#define DOT11_MNG_TIM_DTIM_COUNT 0 /* d11 management DTIM count */ -#define DOT11_MNG_TIM_DTIM_PERIOD 1 /* d11 management DTIM period */ -#define DOT11_MNG_TIM_BITMAP_CTL 2 /* d11 management TIM BITMAP control */ -#define DOT11_MNG_TIM_PVB 3 /* d11 management TIM PVB */ - -/* TLV defines */ -#define TLV_TAG_OFF 0 /* tag offset */ -#define TLV_LEN_OFF 1 /* length offset */ -#define TLV_HDR_LEN 2 /* header length */ -#define TLV_BODY_OFF 2 /* body offset */ - -/* Management Frame Information Element IDs */ -#define DOT11_MNG_SSID_ID 0 /* d11 management SSID id */ -#define DOT11_MNG_RATES_ID 1 /* d11 management rates id */ -#define DOT11_MNG_FH_PARMS_ID 2 /* d11 management FH parameter id */ -#define DOT11_MNG_DS_PARMS_ID 3 /* d11 management DS parameter id */ -#define DOT11_MNG_CF_PARMS_ID 4 /* d11 management CF parameter id */ -#define DOT11_MNG_TIM_ID 5 /* d11 management TIM id */ -#define DOT11_MNG_IBSS_PARMS_ID 6 /* d11 management IBSS parameter id */ -#define DOT11_MNG_COUNTRY_ID 7 /* d11 management country id */ -#define DOT11_MNG_HOPPING_PARMS_ID 8 /* d11 management hopping parameter id */ -#define DOT11_MNG_HOPPING_TABLE_ID 9 /* d11 management hopping table id */ -#define DOT11_MNG_REQUEST_ID 10 /* d11 management request id */ -#define DOT11_MNG_QBSS_LOAD_ID 11 /* d11 management QBSS Load id */ -#define DOT11_MNG_CHALLENGE_ID 16 /* d11 management chanllenge id */ -#define DOT11_MNG_PWR_CONSTRAINT_ID 32 /* 11H PowerConstraint */ -#define DOT11_MNG_PWR_CAP_ID 33 /* 11H PowerCapability */ -#define DOT11_MNG_TPC_REQUEST_ID 34 /* 11H TPC Request */ -#define DOT11_MNG_TPC_REPORT_ID 35 /* 11H TPC Report */ -#define DOT11_MNG_SUPP_CHANNELS_ID 36 /* 11H Supported Channels */ -#define DOT11_MNG_CHANNEL_SWITCH_ID 37 /* 11H ChannelSwitch Announcement */ -#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */ -#define DOT11_MNG_MEASURE_REPORT_ID 39 /* 11H MeasurementReport */ -#define DOT11_MNG_QUIET_ID 40 /* 11H Quiet */ -#define DOT11_MNG_IBSS_DFS_ID 41 /* 11H IBSS_DFS */ -#define DOT11_MNG_ERP_ID 42 /* d11 management ERP id */ -#define DOT11_MNG_TS_DELAY_ID 43 /* d11 management TS Delay id */ -#define DOT11_MNG_NONERP_ID 47 /* d11 management NON-ERP id */ -#define DOT11_MNG_RSN_ID 48 /* d11 management RSN id */ -#define DOT11_MNG_EXT_RATES_ID 50 /* d11 management ext. rates id */ -#define DOT11_MNG_WPA_ID 221 /* d11 management WPA id */ -#define DOT11_MNG_PROPR_ID 221 /* d11 management proprietary id */ - -/* Rate element Basic flag and rate mask */ -#define DOT11_RATE_BASIC 0x80 /* flag for a Basic Rate */ -#define DOT11_RATE_MASK 0x7F /* mask for numeric part of rate */ - -/* ERP info element bit values */ -#define DOT11_MNG_ERP_LEN 1 /* ERP is currently 1 byte long */ -#define DOT11_MNG_NONERP_PRESENT 0x01 /* NonERP (802.11b) STAs are present - *in the BSS - */ -#define DOT11_MNG_USE_PROTECTION 0x02 /* Use protection mechanisms for - *ERP-OFDM frames - */ -#define DOT11_MNG_BARKER_PREAMBLE 0x04 /* Short Preambles: 0 == allowed, - * 1 == not allowed - */ -/* TS Delay element offset & size */ -#define DOT11_MGN_TS_DELAY_LEN 4 /* length of TS DELAY IE */ -#define TS_DELAY_FIELD_SIZE 4 /* TS DELAY field size */ - -/* Capability Information Field */ -#define DOT11_CAP_ESS 0x0001 /* d11 cap. ESS */ -#define DOT11_CAP_IBSS 0x0002 /* d11 cap. IBSS */ -#define DOT11_CAP_POLLABLE 0x0004 /* d11 cap. pollable */ -#define DOT11_CAP_POLL_RQ 0x0008 /* d11 cap. poll request */ -#define DOT11_CAP_PRIVACY 0x0010 /* d11 cap. privacy */ -#define DOT11_CAP_SHORT 0x0020 /* d11 cap. short */ -#define DOT11_CAP_PBCC 0x0040 /* d11 cap. PBCC */ -#define DOT11_CAP_AGILITY 0x0080 /* d11 cap. agility */ -#define DOT11_CAP_SPECTRUM 0x0100 /* d11 cap. spectrum */ -#define DOT11_CAP_SHORTSLOT 0x0400 /* d11 cap. shortslot */ -#define DOT11_CAP_CCK_OFDM 0x2000 /* d11 cap. CCK/OFDM */ - -/* Action Frame Constants */ -#define DOT11_ACTION_CAT_ERR_MASK 0x80 /* d11 action category error mask */ -#define DOT11_ACTION_CAT_MASK 0x7F /* d11 action category mask */ -#define DOT11_ACTION_CAT_SPECT_MNG 0x00 /* d11 action category spectrum management */ -#define DOT11_ACTION_CAT_BLOCKACK 0x03 /* d11 action category block ack */ -#define DOT11_ACTION_NOTIFICATION 0x11 /* 17 */ - -#define DOT11_ACTION_ID_M_REQ 0 /* d11 action measurement request */ -#define DOT11_ACTION_ID_M_REP 1 /* d11 action measurement response */ -#define DOT11_ACTION_ID_TPC_REQ 2 /* d11 action TPC request */ -#define DOT11_ACTION_ID_TPC_REP 3 /* d11 action TPC response */ -#define DOT11_ACTION_ID_CHANNEL_SWITCH 4 /* d11 action channel switch */ - -/* HT (EWC) action ids */ -#define DOT11_ACTION_ID_HT_CH_WIDTH 0 /* mimo ps action frame id */ -#define DOT11_ACTION_ID_HT_MIMO_PS 1 /* mimo ps action frame id */ - -/* Block Ack action types */ -#define DOT11_BA_ACTION_ADDBA_REQ 0 /* ADDBA Req action frame type */ -#define DOT11_BA_ACTION_ADDBA_RESP 1 /* ADDBA Resp action frame type */ -#define DOT11_BA_ACTION_DELBA 2 /* DELBA action frame type */ - -/* ADDBA action parameters */ -#define DOT11_ADDBA_PARAM_POLICY_MASK 0x0002 /* policy mask(ack vs delayed) */ -#define DOT11_ADDBA_PARAM_POLICY_SHIFT 1 /* policy shift */ -#define DOT11_ADDBA_PARAM_TID_MASK 0x003c /* tid mask */ -#define DOT11_ADDBA_PARAM_TID_SHIFT 2 /* tid shift */ -#define DOT11_ADDBA_PARAM_BSIZE_MASK 0xffc0 /* buffer size mask */ -#define DOT11_ADDBA_PARAM_BSIZE_SHIFT 6 /* buffer size shift */ - -#define DOT11_ADDBA_POLICY_DELAYED 0 /* delayed BA policy */ -#define DOT11_ADDBA_POLICY_IMMEDIATE 1 /* immediate BA policy */ - -struct dot11_addba_req { - uint8 category; /* category of action frame (3) */ - uint8 action; /* action: addba req */ - uint8 token; /* identifier */ - uint16 addba_param_set; /* parameter set */ - uint16 timeout; /* timeout in seconds */ - uint16 start_seqnum; /* starting sequence number */ -}PACKED; -typedef struct dot11_addba_req dot11_addba_req_t; -#define DOT11_ADDBA_REQ_LEN 9 /* length of addba req frame */ - -struct dot11_addba_resp { - uint8 category; /* category of action frame (3) */ - uint8 action; /* action: addba resp */ - uint8 token; /* identifier */ - uint16 status; /* status of add request */ - uint16 addba_param_set; /* negotiated parameter set */ - uint16 timeout; /* negotiated timeout in seconds */ -}PACKED; -typedef struct dot11_addba_resp dot11_addba_resp_t; -#define DOT11_ADDBA_RESP_LEN 9 /* length of addba resp frame */ - -/* DELBA action parameters */ -#define DOT11_DELBA_PARAM_INIT_MASK 0x0800 /* initiator mask */ -#define DOT11_DELBA_PARAM_INIT_SHIFT 11 /* initiator shift */ -#define DOT11_DELBA_PARAM_TID_MASK 0xf000 /* tid mask */ -#define DOT11_DELBA_PARAM_TID_SHIFT 12 /* tid shift */ - -struct dot11_delba { - uint8 category; /* category of action frame (3) */ - uint8 action; /* action: addba req */ - uint16 delba_param_set; /* paarmeter set */ - uint16 reason; /* reason for dellba */ -}PACKED; -typedef struct dot11_delba dot11_delba_t; -#define DOT11_DELBA_LEN 6 /* length of delba frame */ - -/* MLME Enumerations */ -#define DOT11_BSSTYPE_INFRASTRUCTURE 0 /* d11 infrastructure */ -#define DOT11_BSSTYPE_INDEPENDENT 1 /* d11 independent */ -#define DOT11_BSSTYPE_ANY 2 /* d11 any BSS type */ -#define DOT11_SCANTYPE_ACTIVE 0 /* d11 scan active */ -#define DOT11_SCANTYPE_PASSIVE 1 /* d11 scan passive */ - -/* 802.11 BRCM "Compromise" Pre N constants */ -#define PREN_PREAMBLE 24 /* green field preamble time */ -#define PREN_MM_EXT 16 /* extra mixed mode preamble time */ -#define PREN_PREAMBLE_EXT 4 /* extra preamble (multiply by unique_streams-1) */ - -/* 802.11 A PHY constants */ -#define APHY_SLOT_TIME 9 /* APHY slot time */ -#define APHY_SIFS_TIME 16 /* APHY SIFS time */ -#define APHY_DIFS_TIME (APHY_SIFS_TIME + (2 * APHY_SLOT_TIME)) /* APHY DIFS time */ -#define APHY_PREAMBLE_TIME 16 /* APHY preamble time */ -#define APHY_SIGNAL_TIME 4 /* APHY signal time */ -#define APHY_SYMBOL_TIME 4 /* APHY symbol time */ -#define APHY_SERVICE_NBITS 16 /* APHY service nbits */ -#define APHY_TAIL_NBITS 6 /* APHY tail nbits */ -#define APHY_CWMIN 15 /* APHY cwmin */ - -/* 802.11 B PHY constants */ -#define BPHY_SLOT_TIME 20 /* BPHY slot time */ -#define BPHY_SIFS_TIME 10 /* BPHY SIFS time */ -#define BPHY_DIFS_TIME 50 /* BPHY DIFS time */ -#define BPHY_PLCP_TIME 192 /* BPHY PLCP time */ -#define BPHY_PLCP_SHORT_TIME 96 /* BPHY PLCP short time */ -#define BPHY_CWMIN 31 /* BPHY cwmin */ - -/* 802.11 G constants */ -#define DOT11_OFDM_SIGNAL_EXTENSION 6 /* d11 OFDM signal extension */ - -#define PHY_CWMAX 1023 /* PHY cwmax */ - -#define DOT11_MAXNUMFRAGS 16 /* max # fragments per MSDU */ - -/* dot11Counters Table - 802.11 spec., Annex D */ -typedef struct d11cnt { - uint32 txfrag; /* dot11TransmittedFragmentCount */ - uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ - uint32 txfail; /* dot11FailedCount */ - uint32 txretry; /* dot11RetryCount */ - uint32 txretrie; /* dot11MultipleRetryCount */ - uint32 rxdup; /* dot11FrameduplicateCount */ - uint32 txrts; /* dot11RTSSuccessCount */ - uint32 txnocts; /* dot11RTSFailureCount */ - uint32 txnoack; /* dot11ACKFailureCount */ - uint32 rxfrag; /* dot11ReceivedFragmentCount */ - uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ - uint32 rxcrc; /* dot11FCSErrorCount */ - uint32 txfrmsnt; /* dot11TransmittedFrameCount */ - uint32 rxundec; /* dot11WEPUndecryptableCount */ -} d11cnt_t; - -/* BRCM OUI */ -#define BRCM_OUI "\x00\x10\x18" /* Broadcom OUI */ - -/* OUI for BRCM proprietary IE */ -#define BRCM_PROP_OUI "\x00\x90\x4C" /* Broadcom proprietary OUI */ - -/* BRCM info element */ -struct brcm_ie { - uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ - uint8 len; /* IE length */ - uint8 oui[3]; /* Proprietary OUI, BRCM_OUI */ - uint8 ver; /* type/ver of this IE */ - uint8 assoc; /* # of assoc STAs */ - uint8 flags; /* misc flags */ - uint8 flags1; /* misc flags */ - uint16 amsdu_mtu_pref; /* preferred A-MSDU MTU */ -} PACKED; -typedef struct brcm_ie brcm_ie_t; -#define BRCM_IE_LEN 11 /* BRCM IE length */ -#define BRCM_IE_VER 2 /* BRCM IE version */ -#define BRCM_IE_LEGACY_AES_VER 1 /* BRCM IE legacy AES version */ - -/* brcm_ie flags */ -#define BRF_ABCAP 0x1 /* afterburner capable */ -#define BRF_ABRQRD 0x2 /* afterburner requested */ -#define BRF_LZWDS 0x4 /* lazy wds enabled */ -#define BRF_BLOCKACK 0x8 /* BlockACK capable */ -#define BRF_ABCOUNTER_MASK 0xf0 /* afterburner wds "state" counter */ -#define BRF_ABCOUNTER_SHIFT 4 /* offset of afterburner wds "state" counter */ - -/* brcm_ie flags1 */ -#define BRF1_AMSDU 0x1 /* A-MSDU capable */ - -#define AB_WDS_TIMEOUT_MAX 15 /* afterburner wds Max count indicating not - * locally capable - */ -#define AB_WDS_TIMEOUT_MIN 1 /* afterburner wds, use zero count as indicating - * "downrev" - */ - -/* EWC definitions */ -#define MCSSET_LEN 16 /* 16-bits per 8-bit set to give 128-bits bitmap of MCS Index */ - -struct ewc_cap { - uint16 cap; - uint8 params; - uint8 supp_mcs[MCSSET_LEN]; - uint16 ext_htcap; - uint32 txbf_cap; - uint8 as_cap; -} PACKED; -typedef struct ewc_cap ewc_cap_t; - -/* CAP IE: EWC 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ -/* the capability IE is primarily used to convey this nodes abilities */ -struct ewc_cap_ie { - uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ - uint8 len; /* IE length */ - uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ - uint8 type; /* type inidicates what follows */ - ewc_cap_t cap; -} PACKED; -typedef struct ewc_cap_ie ewc_cap_ie_t; - -#define EWC_CAP_IE_LEN (26+4) -#define EWC_CAP_IE_TYPE 51 - -#define EWC_CAP_ADC_CODING 0x0001 /* Advance coding support */ -#define EWC_CAP_40MHZ 0x0002 /* FALSE:20Mhz, TRUE: 20 and 40MHZ supported */ -#define EWC_CAP_MIMO_PS_MASK 0x000C /* Mimo PS mask */ -#define EWC_CAP_MIMO_PS_SHIFT 0x0002 /* Mimo PS shift */ -#define EWC_CAP_MIMO_PS_OFF 0x0003 /* Mimo PS, no restriction */ -#define EWC_CAP_MIMO_PS_RTS 0x0001 /* Mimo PS, send RTS/CTS around MIMO frames */ -#define EWC_CAP_MIMO_PS_ON 0x0000 /* Mimo PS, MIMO disallowed */ -#define EWC_CAP_GF 0x0010 /* Greenfield preamble support */ -#define EWC_CAP_SHORT_GI_20 0x0020 /* 20MHZ short guard interval support */ -#define EWC_CAP_SHORT_GI_40 0x0040 /* 40Mhz short guard interval support */ -#define EWC_CAP_TX_STBC 0x0080 /* Tx STBC support */ -#define EWC_CAP_RX_STBC_MASK 0x0300 /* Rx STBC mask */ -#define EWC_CAP_RX_STBC_SHIFT 8 /* Rx STBC shift */ -#define EWC_CAP_DELAYED_BA 0x0400 /* delayed BA support */ -#define EWC_CAP_MAX_AMSDU 0x0800 /* Max AMSDU size in bytes , 0=3839, 1=7935 */ -#define EWC_CAP_DSSS_CCK 0x1000 /* DSSS/CCK supported by the BSS */ -#define EWC_CAP_PSMP 0x2000 /* Power Save Multi Poll support */ -#define EWC_CAP_STBC_CTL 0x4000 /* STBC control frame support */ -#define EWC_CAP_LSIG_TXOP 0x8000 /* L-SIG TXOP protection support */ - -#define EWC_MAX_AMSDU 7935 /* max amsdu size (bytes) per the EWC spec */ -#define EWC_MIN_AMSDU 3835 /* min amsdu size (bytes) per the EWC spec */ - -#define EWC_PARAMS_RX_FACTOR_MASK 0x03 /* ampdu rcv factor mask */ -#define EWC_PARAMS_DENSITY_MASK 0x1C /* ampdu density mask */ -#define EWC_PARAMS_DENSITY_SHIFT 2 /* ampdu density shift */ - -/* EWC/AMPDU specific define */ -#define AMPDU_MAX_MPDU_DENSITY 7 /* max mpdu density; in 1/8 usec units */ -#define AMPDU_MAX_RX_FACTOR 3 /* max rcv ampdu len (64kb) */ -#define AMPDU_RX_FACTOR_BASE 8*1024 /* ampdu factor base for rx len */ -#define AMPDU_DELIMITER_LEN 4 /* length of ampdu delimiter */ - -struct ewc_add { - uint8 ctl_ch; /* control channel number */ - uint8 byte1; /* ext ch,rec. ch. width, RIFS support */ - uint16 opmode; /* operation mode */ - uint16 misc_bits; /* misc bits */ - uint8 basic_mcs[MCSSET_LEN]; /* required MCS set */ -} PACKED; -typedef struct ewc_add ewc_add_t; - -/* ADD IE: EWC 1.0 spec. simply stole a 802.11 IE, we use our prop. IE until this is resolved */ -/* the additional IE is primarily used to convey the current BSS configuration */ -struct ewc_add_ie { - uint8 id; /* IE ID, 221, DOT11_MNG_PROPR_ID */ - uint8 len; /* IE length */ - uint8 oui[3]; /* Proprietary OUI, BRCM_PROP_OUI */ - uint8 type; /* indicates what follows */ - ewc_add_t add; -} PACKED; -typedef struct ewc_add_ie ewc_add_ie_t; - -#define EWC_ADD_IE_LEN (22+4) -#define EWC_ADD_IE_TYPE 52 - -/* byte1 defn's */ -#define EWC_EXT_CH_MASK 0x03 /* extension channel mask */ -#define EWC_EXT_CH_UPPER 0x01 /* ext. ch. on upper sb */ -#define EWC_EXT_CH_LOWER 0x03 /* ext. ch. on lower sb */ -#define EWC_EXT_CH_NONE 0x00 /* extension channel mask */ -#define EWC_BW_ANY 0x04 /* set, STA can use 20 or 40MHz */ -#define EWC_RIFS_PERMITTED 0x08 /* RIFS allowed */ - -/* opmode defn's */ -#define EWC_OPMODE_MASK 0x0003 /* protection mode mask */ -#define EWC_OPMODE_PURE 0x0000 /* protection mode PURE */ -#define EWC_OPMODE_HT20IN40 0x0002 /* protection mode 20MHz HT in 40MHz BSS */ -#define EWC_OPMODE_MIXED 0x0003 /* protection mode Mixed Mode */ -#define EWC_NONGF_PRESENT 0x0004 /* protection mode non-GF */ - -/* misc_bites defn's */ -#define EWC_BASIC_STBC_MCS 0x007f /* basic STBC MCS */ -#define EWC_DUAL_STBC_PROT 0x0080 /* Dual STBC Protection */ -#define EWC_SECOND_BCN 0x0100 /* Secondary beacon support */ -#define EWC_LSIG_TXOP 0x0200 /* L-SIG TXOP Protection full support */ -#define EWC_PCO_ACTIVE 0x0400 /* PCO active */ -#define EWC_PCO_PHASE 0x0800 /* PCO phase */ - -/* Macros for opmode */ -#define EWC_MIXEDMODE_PRESENT(add) ((ltoh16_ua(&add.opmode) & EWC_OPMODE_MASK) \ - == EWC_OPMODE_MIXED) /* mixed mode present */ -#define EWC_HT20_PRESENT(add) ((ltoh16_ua(&add.opmode) & EWC_OPMODE_MASK) \ - == EWC_OPMODE_HT20IN40) /* 20MHz HT present */ -#define EWC_USE_PROTECTION(add) (EWC_HT20_PRESENT((add)) || \ - EWC_MIXEDMODE_PRESENT((add))) /* use protection */ - -/* Vendor IE structure */ -struct vndr_ie { - uchar id; - uchar len; - uchar oui [3]; - uchar data [1]; /* Variable size data */ -}PACKED; -typedef struct vndr_ie vndr_ie_t; - -#define VNDR_IE_HDR_LEN 2 /* id + len field */ -#define VNDR_IE_MIN_LEN 3 /* size of the oui field */ -#define VNDR_IE_MAX_LEN 256 /* verdor IE max length */ - -/* WPA definitions */ -#define WPA_VERSION 1 /* WPA version */ -#define WPA_OUI "\x00\x50\xF2" /* WPA OUI */ - -#define WPA2_VERSION 1 /* WPA2 version */ -#define WPA2_VERSION_LEN 2 /* WAP2 version length */ -#define WPA2_OUI "\x00\x0F\xAC" /* WPA2 OUI */ - -#define WPA_OUI_LEN 3 /* WPA OUI length */ - -/* RSN authenticated key managment suite */ -#define RSN_AKM_NONE 0 /* None (IBSS) */ -#define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */ -#define RSN_AKM_PSK 2 /* Pre-shared Key */ - -/* Key related defines */ -#define DOT11_MAX_DEFAULT_KEYS 4 /* number of default keys */ -#define DOT11_MAX_KEY_SIZE 32 /* max size of any key */ -#define DOT11_MAX_IV_SIZE 16 /* max size of any IV */ -#define DOT11_EXT_IV_FLAG (1<<5) /* flag to indicate IV is > 4 bytes */ - -#define WEP1_KEY_SIZE 5 /* max size of any WEP key */ -#define WEP1_KEY_HEX_SIZE 10 /* size of WEP key in hex. */ -#define WEP128_KEY_SIZE 13 /* max size of any WEP key */ -#define WEP128_KEY_HEX_SIZE 26 /* size of WEP key in hex. */ -#define TKIP_MIC_SIZE 8 /* size of TKIP MIC */ -#define TKIP_EOM_SIZE 7 /* max size of TKIP EOM */ -#define TKIP_EOM_FLAG 0x5a /* TKIP EOM flag byte */ -#define TKIP_KEY_SIZE 32 /* size of any TKIP key */ -#define TKIP_MIC_AUTH_TX 16 /* offset to Authenticator MIC TX key */ -#define TKIP_MIC_AUTH_RX 24 /* offset to Authenticator MIC RX key */ -#define TKIP_MIC_SUP_RX TKIP_MIC_AUTH_TX /* offset to Supplicant MIC RX key */ -#define TKIP_MIC_SUP_TX TKIP_MIC_AUTH_RX /* offset to Supplicant MIC TX key */ -#define AES_KEY_SIZE 16 /* size of AES key */ - -#undef PACKED -#if !defined(__GNUC__) -#pragma pack() -#endif - -#endif /* _802_11_H_ */ diff --git a/package/wlc/src/include/proto/bcmeth.h b/package/wlc/src/include/proto/bcmeth.h deleted file mode 100644 index 7b3295389a..0000000000 --- a/package/wlc/src/include/proto/bcmeth.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Broadcom Ethernettype protocol definitions - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * $Id: bcmeth.h,v 1.1.1.4 2006/02/27 03:43:16 honor Exp $ - */ - -/* - * Broadcom Ethernet protocol defines - */ - -#ifndef _BCMETH_H_ -#define _BCMETH_H_ - -/* enable structure packing */ -#if defined(__GNUC__) -#define PACKED __attribute__((packed)) -#else -#pragma pack(1) -#define PACKED -#endif - -/* ETHER_TYPE_BRCM is defined in ethernet.h */ - -/* - * Following the 2byte BRCM ether_type is a 16bit BRCM subtype field - * in one of two formats: (only subtypes 32768-65535 are in use now) - * - * subtypes 0-32767: - * 8 bit subtype (0-127) - * 8 bit length in bytes (0-255) - * - * subtypes 32768-65535: - * 16 bit big-endian subtype - * 16 bit big-endian length in bytes (0-65535) - * - * length is the number of additional bytes beyond the 4 or 6 byte header - * - * Reserved values: - * 0 reserved - * 5-15 reserved for iLine protocol assignments - * 17-126 reserved, assignable - * 127 reserved - * 32768 reserved - * 32769-65534 reserved, assignable - * 65535 reserved - */ - -/* - * While adding the subtypes and their specific processing code make sure - * bcmeth_bcm_hdr_t is the first data structure in the user specific data structure definition - */ - -#define BCMILCP_SUBTYPE_RATE 1 -#define BCMILCP_SUBTYPE_LINK 2 -#define BCMILCP_SUBTYPE_CSA 3 -#define BCMILCP_SUBTYPE_LARQ 4 -#define BCMILCP_SUBTYPE_VENDOR 5 -#define BCMILCP_SUBTYPE_FLH 17 - -#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 -#define BCMILCP_SUBTYPE_CERT 32770 -#define BCMILCP_SUBTYPE_SES 32771 - - -#define BCMILCP_BCM_SUBTYPE_RESERVED 0 -#define BCMILCP_BCM_SUBTYPE_EVENT 1 -#define BCMILCP_BCM_SUBTYPE_SES 2 -/* - * The EAPOL type is not used anymore. Instead EAPOL messages are now embedded - * within BCMILCP_BCM_SUBTYPE_EVENT type messages - */ -/* #define BCMILCP_BCM_SUBTYPE_EAPOL 3 */ - -#define BCMILCP_BCM_SUBTYPEHDR_MINLENGTH 8 -#define BCMILCP_BCM_SUBTYPEHDR_VERSION 0 - -/* These fields are stored in network order */ -typedef struct bcmeth_hdr -{ - uint16 subtype; /* Vendor specific..32769 */ - uint16 length; - uint8 version; /* Version is 0 */ - uint8 oui[3]; /* Broadcom OUI */ - /* user specific Data */ - uint16 usr_subtype; -} PACKED bcmeth_hdr_t; - -#undef PACKED -#if !defined(__GNUC__) -#pragma pack() -#endif - -#endif /* _BCMETH_H_ */ diff --git a/package/wlc/src/include/proto/bcmevent.h b/package/wlc/src/include/proto/bcmevent.h deleted file mode 100644 index d922a5d215..0000000000 --- a/package/wlc/src/include/proto/bcmevent.h +++ /dev/null @@ -1,152 +0,0 @@ -/* - * Broadcom Event protocol definitions - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * - * Dependencies: proto/bcmeth.h - * - * $Id: bcmevent.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $ - * - */ - -/* - * Broadcom Ethernet Events protocol defines - * - */ - -#ifndef _BCMEVENT_H_ -#define _BCMEVENT_H_ - -/* enable structure packing */ -#if defined(__GNUC__) -#define PACKED __attribute__((packed)) -#else -#pragma pack(1) -#define PACKED -#endif /* defined(__GNUC__) */ - -#define BCM_EVENT_MSG_VERSION 1 /* wl_event_msg_t struct version */ -#define BCM_MSG_IFNAME_MAX 16 /* max length of interface name */ - -/* flags */ -#define WLC_EVENT_MSG_LINK 0x01 /* link is up */ -#define WLC_EVENT_MSG_FLUSHTXQ 0x02 /* flush tx queue on MIC error */ -#define WLC_EVENT_MSG_GROUP 0x04 /* group MIC error */ - -/* theses fields are stored in network order */ -typedef struct -{ - uint16 version; - uint16 flags; /* see flags below */ - uint32 event_type; /* Message (see below) */ - uint32 status; /* Status code (see below) */ - uint32 reason; /* Reason code (if applicable) */ - uint32 auth_type; /* WLC_E_AUTH */ - uint32 datalen; /* data buf */ - struct ether_addr addr; /* Station address (if applicable) */ - char ifname[BCM_MSG_IFNAME_MAX]; /* name of the packet incoming interface */ -} PACKED wl_event_msg_t; - -/* used by driver msgs */ -typedef struct bcm_event { - struct ether_header eth; - bcmeth_hdr_t bcm_hdr; - wl_event_msg_t event; - /* data portion follows */ -} PACKED bcm_event_t; - -#define BCM_MSG_LEN (sizeof(bcm_event_t) - sizeof(bcmeth_hdr_t) - sizeof(struct ether_header)) - -/* Event messages */ -#define WLC_E_SET_SSID 0 /* indicates status of set SSID */ -#define WLC_E_JOIN 1 /* differentiates join IBSS from found (WLC_E_START) IBSS */ -#define WLC_E_START 2 /* STA founded an IBSS or AP started a BSS */ -#define WLC_E_AUTH 3 /* 802.11 AUTH request */ -#define WLC_E_AUTH_IND 4 /* 802.11 AUTH indication */ -#define WLC_E_DEAUTH 5 /* 802.11 DEAUTH request */ -#define WLC_E_DEAUTH_IND 6 /* 802.11 DEAUTH indication */ -#define WLC_E_ASSOC 7 /* 802.11 ASSOC request */ -#define WLC_E_ASSOC_IND 8 /* 802.11 ASSOC indication */ -#define WLC_E_REASSOC 9 /* 802.11 REASSOC request */ -#define WLC_E_REASSOC_IND 10 /* 802.11 REASSOC indication */ -#define WLC_E_DISASSOC 11 /* 802.11 DISASSOC request */ -#define WLC_E_DISASSOC_IND 12 /* 802.11 DISASSOC indication */ -#define WLC_E_QUIET_START 13 /* 802.11h Quiet period started */ -#define WLC_E_QUIET_END 14 /* 802.11h Quiet period ended */ -#define WLC_E_BEACON_RX 15 /* BEACONS received/lost indication */ -#define WLC_E_LINK 16 /* generic link indication */ -#define WLC_E_MIC_ERROR 17 /* TKIP MIC error occurred */ -#define WLC_E_NDIS_LINK 18 /* NDIS style link indication */ -#define WLC_E_ROAM 19 /* roam attempt occurred: indicate status & reason */ -#define WLC_E_TXFAIL 20 /* change in dot11FailedCount (txfail) */ -#define WLC_E_PMKID_CACHE 21 /* WPA2 pmkid cache indication */ -#define WLC_E_RETROGRADE_TSF 22 /* current AP's TSF value went backward */ -#define WLC_E_PRUNE 23 /* AP was pruned from join list for reason */ -#define WLC_E_AUTOAUTH 24 /* report AutoAuth table entry match for join attempt */ -#define WLC_E_EAPOL_MSG 25 /* Event encapsulating an EAPOL message */ -#define WLC_E_SCAN_COMPLETE 26 /* Scan results are ready or scan was aborted */ -#define WLC_E_ADDTS_IND 27 /* indicate to host addts fail/success */ -#define WLC_E_DELTS_IND 28 /* indicate to host delts fail/success */ -#define WLC_E_BCNSENT_IND 29 /* indicate to host of beacon transmit */ -#define WLC_E_BCNRX_MSG 30 /* Send the received beacon up to the host */ -#define WLC_E_LAST 31 /* highest val + 1 for range checking */ - -/* Event status codes */ -#define WLC_E_STATUS_SUCCESS 0 /* operation was successful */ -#define WLC_E_STATUS_FAIL 1 /* operation failed */ -#define WLC_E_STATUS_TIMEOUT 2 /* operation timed out */ -#define WLC_E_STATUS_NO_NETWORKS 3 /* failed due to no matching network found */ -#define WLC_E_STATUS_ABORT 4 /* operation was aborted */ -#define WLC_E_STATUS_NO_ACK 5 /* protocol failure: packet not ack'd */ -#define WLC_E_STATUS_UNSOLICITED 6 /* AUTH or ASSOC packet was unsolicited */ -#define WLC_E_STATUS_ATTEMPT 7 /* attempt to assoc to an auto auth configuration */ - -/* roam reason codes */ -#define WLC_E_REASON_INITIAL_ASSOC 0 /* initial assoc */ -#define WLC_E_REASON_LOW_RSSI 1 /* roamed due to low RSSI */ -#define WLC_E_REASON_DEAUTH 2 /* roamed due to DEAUTH indication */ -#define WLC_E_REASON_DISASSOC 3 /* roamed due to DISASSOC indication */ -#define WLC_E_REASON_BCNS_LOST 4 /* roamed due to lost beacons */ -#define WLC_E_REASON_FAST_ROAM_FAILED 5 /* roamed due to fast roam failure */ -#define WLC_E_REASON_DIRECTED_ROAM 6 /* roamed due to request by AP */ -#define WLC_E_REASON_TSPEC_REJECTED 7 /* roamed due to TSPEC rejection */ -#define WLC_E_REASON_BETTER_AP 8 /* roamed due to finding better AP */ - -/* prune reason codes */ -#define WLC_E_PRUNE_ENCR_MISMATCH 1 /* ecryption mismatch */ -#define WLC_E_PRUNE_BCAST_BSSID 2 /* AP uses a broadcast BSSID */ -#define WLC_E_PRUNE_MAC_DENY 3 /* STA's MAC addr is in AP's MAC deny list */ -#define WLC_E_PRUNE_MAC_NA 4 /* STA's MAC addr is not in AP's MAC allow list */ -#define WLC_E_PRUNE_REG_PASSV 5 /* AP not allowed due to regulatory restriction */ -#define WLC_E_PRUNE_SPCT_MGMT 6 /* AP does not support STA locale spectrum mgmt */ -#define WLC_E_PRUNE_RADAR 7 /* AP is on a radar channel of STA locale */ -#define WLC_E_RSN_MISMATCH 8 /* STA does not support AP's RSN */ -#define WLC_E_PRUNE_NO_COMMON_RATES 9 /* No rates in common with AP */ -#define WLC_E_PRUNE_BASIC_RATES 10 /* STA does not support all basic rates of BSS */ -#define WLC_E_PRUNE_CCXFAST_PREVAP 11 /* CCX FAST ROAM: prune previous AP */ -#define WLC_E_PRUNE_CIPHER_NA 12 /* BSS's cipher not supported */ -#define WLC_E_PRUNE_KNOWN_STA 13 /* AP is already known to us as a STA */ -#define WLC_E_PRUNE_CCXFAST_DROAM 14 /* CCX FAST ROAM: prune unqulified AP */ -#define WLC_E_PRUNE_WDS_PEER 15 /* AP is already known to us as a WDS peer */ -#define WLC_E_PRUNE_QBSS_LOAD 16 /* QBSS LOAD - AAC is too low */ -#define WLC_E_PRUNE_HOME_AP 17 /* prune home AP */ - -/* WLC_SET_CALLBACK data type */ -typedef struct wlc_event_cb { - void (*fn)(void *, bcm_event_t *); /* Callback function */ - void *context; /* Passed to callback function */ -} wlc_event_cb_t; - -#undef PACKED -#if !defined(__GNUC__) -#pragma pack() -#endif /* PACKED */ - -#endif /* _BCMEVENT_H_ */ diff --git a/package/wlc/src/include/proto/ethernet.h b/package/wlc/src/include/proto/ethernet.h deleted file mode 100644 index 03fd4f654c..0000000000 --- a/package/wlc/src/include/proto/ethernet.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * From FreeBSD 2.2.7: Fundamental constants relating to ethernet. - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * $Id: ethernet.h,v 1.1.1.14 2006/02/27 03:43:16 honor Exp $ - */ - -#ifndef _NET_ETHERNET_H_ /* use native BSD ethernet.h when available */ -#define _NET_ETHERNET_H_ - -#ifndef _TYPEDEFS_H_ -#include "typedefs.h" -#endif - -/* enable structure packing */ -#if defined(__GNUC__) -#define PACKED __attribute__((packed)) -#else -#pragma pack(1) -#define PACKED -#endif - -/* - * The number of bytes in an ethernet (MAC) address. - */ -#define ETHER_ADDR_LEN 6 - -/* - * The number of bytes in the type field. - */ -#define ETHER_TYPE_LEN 2 - -/* - * The number of bytes in the trailing CRC field. - */ -#define ETHER_CRC_LEN 4 - -/* - * The length of the combined header. - */ -#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN) - -/* - * The minimum packet length. - */ -#define ETHER_MIN_LEN 64 - -/* - * The minimum packet user data length. - */ -#define ETHER_MIN_DATA 46 - -/* - * The maximum packet length. - */ -#define ETHER_MAX_LEN 1518 - -/* - * The maximum packet user data length. - */ -#define ETHER_MAX_DATA 1500 - -/* ether types */ -#define ETHER_TYPE_IP 0x0800 /* IP */ -#define ETHER_TYPE_ARP 0x0806 /* ARP */ -#define ETHER_TYPE_8021Q 0x8100 /* 802.1Q */ -#define ETHER_TYPE_BRCM 0x886c /* Broadcom Corp. */ -#define ETHER_TYPE_802_1X 0x888e /* 802.1x */ -#ifdef BCMWPA2 -#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 /* 802.1x preauthentication */ -#endif - -/* Broadcom subtype follows ethertype; First 2 bytes are reserved; Next 2 are subtype; */ -#define ETHER_BRCM_SUBTYPE_LEN 4 /* Broadcom 4 byte subtype */ -#define ETHER_BRCM_CRAM 0x1 /* Broadcom subtype cram protocol */ - -/* ether header */ -#define ETHER_DEST_OFFSET 0 /* dest address offset */ -#define ETHER_SRC_OFFSET 6 /* src address offset */ -#define ETHER_TYPE_OFFSET 12 /* ether type offset */ - -/* - * A macro to validate a length with - */ -#define ETHER_IS_VALID_LEN(foo) \ - ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) - - -#ifndef __INCif_etherh /* Quick and ugly hack for VxWorks */ -/* - * Structure of a 10Mb/s Ethernet header. - */ -struct ether_header { - uint8 ether_dhost[ETHER_ADDR_LEN]; - uint8 ether_shost[ETHER_ADDR_LEN]; - uint16 ether_type; -} PACKED; - -/* - * Structure of a 48-bit Ethernet address. - */ -struct ether_addr { - uint8 octet[ETHER_ADDR_LEN]; -} PACKED; -#endif /* !__INCif_etherh Quick and ugly hack for VxWorks */ - -/* - * Takes a pointer, sets locally admininistered - * address bit in the 48-bit Ethernet address. - */ -#define ETHER_SET_LOCALADDR(ea) (((uint8 *)(ea))[0] = (((uint8 *)(ea))[0] | 2)) - -/* - * Takes a pointer, returns true if a 48-bit multicast address - * (including broadcast, since it is all ones) - */ -#define ETHER_ISMULTI(ea) (((uint8 *)(ea))[0] & 1) - - -/* compare two ethernet addresses - assumes the pointers can be referenced as shorts */ -#define ether_cmp(a, b) (!(((short*)a)[0] == ((short*)b)[0]) | \ - !(((short*)a)[1] == ((short*)b)[1]) | \ - !(((short*)a)[2] == ((short*)b)[2])) - -/* copy an ethernet address - assumes the pointers can be referenced as shorts */ -#define ether_copy(s, d) { \ - ((short*)d)[0] = ((short*)s)[0]; \ - ((short*)d)[1] = ((short*)s)[1]; \ - ((short*)d)[2] = ((short*)s)[2]; } - -/* - * Takes a pointer, returns true if a 48-bit broadcast (all ones) - */ -#define ETHER_ISBCAST(ea) ((((uint8 *)(ea))[0] & \ - ((uint8 *)(ea))[1] & \ - ((uint8 *)(ea))[2] & \ - ((uint8 *)(ea))[3] & \ - ((uint8 *)(ea))[4] & \ - ((uint8 *)(ea))[5]) == 0xff) - -static const struct ether_addr ether_bcast = {{255, 255, 255, 255, 255, 255}}; - -/* - * Takes a pointer, returns true if a 48-bit null address (all zeros) - */ -#define ETHER_ISNULLADDR(ea) ((((uint8 *)(ea))[0] | \ - ((uint8 *)(ea))[1] | \ - ((uint8 *)(ea))[2] | \ - ((uint8 *)(ea))[3] | \ - ((uint8 *)(ea))[4] | \ - ((uint8 *)(ea))[5]) == 0) - -#undef PACKED -#if !defined(__GNUC__) -#pragma pack() -#endif - -#endif /* _NET_ETHERNET_H_ */ diff --git a/package/wlc/src/include/proto/wpa.h b/package/wlc/src/include/proto/wpa.h deleted file mode 100644 index dd35dbef02..0000000000 --- a/package/wlc/src/include/proto/wpa.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Fundamental types and constants relating to WPA - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * $Id: wpa.h,v 1.1.1.4 2006/02/27 03:43:16 honor Exp $ - */ - -#ifndef _proto_wpa_h_ -#define _proto_wpa_h_ - -#include -#include - -/* enable structure packing */ -#if defined(__GNUC__) -#define PACKED __attribute__((packed)) -#else -#pragma pack(1) -#define PACKED -#endif - -/* Reason Codes */ - -/* 10 and 11 are from TGh. */ -#define DOT11_RC_BAD_PC 10 /* Unacceptable power capability element */ -#define DOT11_RC_BAD_CHANNELS 11 /* Unacceptable supported channels element */ -/* 12 is unused */ -/* 13 through 23 taken from P802.11i/D3.0, November 2002 */ -#define DOT11_RC_INVALID_WPA_IE 13 /* Invalid info. element */ -#define DOT11_RC_MIC_FAILURE 14 /* Michael failure */ -#define DOT11_RC_4WH_TIMEOUT 15 /* 4-way handshake timeout */ -#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 /* Group key update timeout */ -#define DOT11_RC_WPA_IE_MISMATCH 17 /* WPA IE in 4-way handshake differs from - * (re-)assoc. request/probe response - */ -#define DOT11_RC_INVALID_MC_CIPHER 18 /* Invalid multicast cipher */ -#define DOT11_RC_INVALID_UC_CIPHER 19 /* Invalid unicast cipher */ -#define DOT11_RC_INVALID_AKMP 20 /* Invalid authenticated key management protocol */ -#define DOT11_RC_BAD_WPA_VERSION 21 /* Unsupported WPA version */ -#define DOT11_RC_INVALID_WPA_CAP 22 /* Invalid WPA IE capabilities */ -#define DOT11_RC_8021X_AUTH_FAIL 23 /* 802.1X authentication failure */ - -#define WPA2_PMKID_LEN 16 - -/* WPA IE fixed portion */ -typedef struct -{ - uint8 tag; /* TAG */ - uint8 length; /* TAG length */ - uint8 oui[3]; /* IE OUI */ - uint8 oui_type; /* OUI type */ - struct { - uint8 low; - uint8 high; - } PACKED version; /* IE version */ -} PACKED wpa_ie_fixed_t; -#define WPA_IE_OUITYPE_LEN 4 -#define WPA_IE_FIXED_LEN 8 -#define WPA_IE_TAG_FIXED_LEN 6 - -#ifdef BCMWPA2 -typedef struct { - uint8 tag; /* TAG */ - uint8 length; /* TAG length */ - struct { - uint8 low; - uint8 high; - } PACKED version; /* IE version */ -} PACKED wpa_rsn_ie_fixed_t; -#define WPA_RSN_IE_FIXED_LEN 4 -#define WPA_RSN_IE_TAG_FIXED_LEN 2 -typedef uint8 wpa_pmkid_t[WPA2_PMKID_LEN]; -#endif - -/* WPA suite/multicast suite */ -typedef struct -{ - uint8 oui[3]; - uint8 type; -} PACKED wpa_suite_t, wpa_suite_mcast_t; -#define WPA_SUITE_LEN 4 - -/* WPA unicast suite list/key management suite list */ -typedef struct -{ - struct { - uint8 low; - uint8 high; - } PACKED count; - wpa_suite_t list[1]; -} PACKED wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; -#define WPA_IE_SUITE_COUNT_LEN 2 -#ifdef BCMWPA2 -typedef struct -{ - struct { - uint8 low; - uint8 high; - } PACKED count; - wpa_pmkid_t list[1]; -} PACKED wpa_pmkid_list_t; -#endif - -/* WPA cipher suites */ -#define WPA_CIPHER_NONE 0 /* None */ -#define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */ -#define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */ -#define WPA_CIPHER_AES_OCB 3 /* AES (OCB) */ -#define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */ -#define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */ - -#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ - (cipher) == WPA_CIPHER_WEP_40 || \ - (cipher) == WPA_CIPHER_WEP_104 || \ - (cipher) == WPA_CIPHER_TKIP || \ - (cipher) == WPA_CIPHER_AES_OCB || \ - (cipher) == WPA_CIPHER_AES_CCM) - -/* WPA TKIP countermeasures parameters */ -#define WPA_TKIP_CM_DETECT 60 /* multiple MIC failure window (seconds) */ -#define WPA_TKIP_CM_BLOCK 60 /* countermeasures active window (seconds) */ - -/* WPA capabilities defined in 802.11i */ -#define WPA_CAP_4_REPLAY_CNTRS 2 -#define WPA_CAP_16_REPLAY_CNTRS 3 -#define WPA_CAP_REPLAY_CNTR_SHIFT 2 -#define WPA_CAP_REPLAY_CNTR_MASK 0x000c - -/* WPA Specific defines */ -#define WPA_CAP_LEN 2 /* Length of RSN capabilities in RSN IE (2 octets) */ - -#ifdef BCMWPA2 -#define WPA_CAP_WPA2_PREAUTH 1 -#endif /* BCMWPA2 */ - -#undef PACKED -#if !defined(__GNUC__) -#pragma pack() -#endif - -#endif /* _proto_wpa_h_ */ diff --git a/package/wlc/src/include/typedefs.h b/package/wlc/src/include/typedefs.h deleted file mode 100644 index 6c498bbcb2..0000000000 --- a/package/wlc/src/include/typedefs.h +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * $Id: typedefs.h,v 1.1.1.12 2006/04/08 06:13:40 honor Exp $ - */ - -#ifndef _TYPEDEFS_H_ -#define _TYPEDEFS_H_ - -/* - * Inferred Typedefs - * - */ - -/* Infer the compile environment based on preprocessor symbols and pramas. - * Override type definitions as needed, and include configuration dependent - * header files to define types. - */ - -#ifdef __cplusplus - -#define TYPEDEF_BOOL -#ifndef FALSE -#define FALSE false -#endif -#ifndef TRUE -#define TRUE true -#endif - -#endif /* __cplusplus */ - -#if defined(_NEED_SIZE_T_) -typedef long unsigned int size_t; -#endif - -#define TYPEDEF_UINT -#define TYPEDEF_USHORT -#define TYPEDEF_ULONG - - -/* Do not support the (u)int64 types with strict ansi for GNU C */ -#if defined(__GNUC__) && defined(__STRICT_ANSI__) -#define TYPEDEF_INT64 -#define TYPEDEF_UINT64 -#endif - -/* pick up ushort & uint from standard types.h */ -#if defined(linux) && defined(__KERNEL__) -#include /* sys/types.h and linux/types.h are oil and water */ -#else -#include -#endif - -/* use the default typedefs in the next section of this file */ -#define USE_TYPEDEF_DEFAULTS - -/* - * Default Typedefs - * - */ - -#ifdef USE_TYPEDEF_DEFAULTS -#undef USE_TYPEDEF_DEFAULTS - -#ifndef TYPEDEF_BOOL -typedef /* @abstract@ */ unsigned char bool; -#endif - -/* define uchar, ushort, uint, ulong */ - -#ifndef TYPEDEF_UCHAR -typedef unsigned char uchar; -#endif - -#ifndef TYPEDEF_USHORT -typedef unsigned short ushort; -#endif - -#ifndef TYPEDEF_UINT -typedef unsigned int uint; -#endif - -#ifndef TYPEDEF_ULONG -typedef unsigned long ulong; -#endif - -/* define [u]int8/16/32/64, uintptr */ - -#ifndef TYPEDEF_UINT8 -typedef unsigned char uint8; -#endif - -#ifndef TYPEDEF_UINT16 -typedef unsigned short uint16; -#endif - -#ifndef TYPEDEF_UINT32 -typedef unsigned int uint32; -#endif - -#ifndef TYPEDEF_UINT64 -typedef unsigned long long uint64; -#endif - -#ifndef TYPEDEF_UINTPTR -typedef unsigned int uintptr; -#endif - -#ifndef TYPEDEF_INT8 -typedef signed char int8; -#endif - -#ifndef TYPEDEF_INT16 -typedef signed short int16; -#endif - -#ifndef TYPEDEF_INT32 -typedef signed int int32; -#endif - -#ifndef TYPEDEF_INT64 -typedef signed long long int64; -#endif - -/* define float32/64, float_t */ - -#ifndef TYPEDEF_FLOAT32 -typedef float float32; -#endif - -#ifndef TYPEDEF_FLOAT64 -typedef double float64; -#endif - -/* - * abstracted floating point type allows for compile time selection of - * single or double precision arithmetic. Compiling with -DFLOAT32 - * selects single precision; the default is double precision. - */ - -#ifndef TYPEDEF_FLOAT_T - -#if defined(FLOAT32) -typedef float32 float_t; -#else /* default to double precision floating point */ -typedef float64 float_t; -#endif - -#endif /* TYPEDEF_FLOAT_T */ - -/* define macro values */ - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 /* TRUE */ -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#ifndef OFF -#define OFF 0 -#endif - -#ifndef ON -#define ON 1 /* ON = 1 */ -#endif - -#define AUTO (-1) /* Auto = -1 */ - -/* define PTRSZ, INLINE */ - -#ifndef PTRSZ -#define PTRSZ sizeof(char*) -#endif - -#ifndef INLINE - -#ifdef _MSC_VER - -#define INLINE __inline - -#elif __GNUC__ - -#define INLINE __inline__ - -#else - -#define INLINE - -#endif /* _MSC_VER */ - -#endif /* INLINE */ - -#undef TYPEDEF_BOOL -#undef TYPEDEF_UCHAR -#undef TYPEDEF_USHORT -#undef TYPEDEF_UINT -#undef TYPEDEF_ULONG -#undef TYPEDEF_UINT8 -#undef TYPEDEF_UINT16 -#undef TYPEDEF_UINT32 -#undef TYPEDEF_UINT64 -#undef TYPEDEF_UINTPTR -#undef TYPEDEF_INT8 -#undef TYPEDEF_INT16 -#undef TYPEDEF_INT32 -#undef TYPEDEF_INT64 -#undef TYPEDEF_FLOAT32 -#undef TYPEDEF_FLOAT64 -#undef TYPEDEF_FLOAT_T - -#endif /* USE_TYPEDEF_DEFAULTS */ - -/* - * Including the bcmdefs.h here, to make sure everyone including typedefs.h - * gets this automatically -*/ -#include - -#endif /* _TYPEDEFS_H_ */ diff --git a/package/wlc/src/include/wlioctl.h b/package/wlc/src/include/wlioctl.h deleted file mode 100644 index 0558415d33..0000000000 --- a/package/wlc/src/include/wlioctl.h +++ /dev/null @@ -1,1384 +0,0 @@ -/* - * Custom OID/ioctl definitions for - * Broadcom 802.11abg Networking Device Driver - * - * Definitions subject to change without notice. - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * $Id: wlioctl.h,v 1.1.1.22 2006/04/15 01:29:08 michael Exp $ - */ - -#ifndef _wlioctl_h_ -#define _wlioctl_h_ - -#include -#include -#include -#include -#include - -#ifdef __NetBSD__ -/* NetBSD 2.0 does not have SIOCDEVPRIVATE. This is NetBSD 2.0 specific */ -#define SIOCDEVPRIVATE _IOWR('i', 139, struct ifreq) -#endif - -/* require default structure packing */ -#if !defined(__GNUC__) -#pragma pack(push, 8) -#endif - -/* A chanspec holds the channel number, band, bandwidth and control sideband */ -typedef uint16 chanspec_t; -#define WL_CHANSPEC_CHAN_MASK 0x00ff - -#define WL_CHANSPEC_CTL_SB_MASK 0x0300 -#define WL_CHANSPEC_CTL_SB_SHIFT 8 -#define WL_CHANSPEC_CTL_SB_LOWER 0x0100 -#define WL_CHANSPEC_CTL_SB_UPPER 0x0200 -#define WL_CHANSPEC_CTL_SB_NONE 0x0300 - -#define WL_CHANSPEC_BW_MASK 0x0C00 -#define WL_CHANSPEC_BW_SHIFT 10 -#define WL_CHANSPEC_BW_10 0x0400 -#define WL_CHANSPEC_BW_20 0x0800 -#define WL_CHANSPEC_BW_40 0x0C00 - -#define WL_CHANSPEC_BAND_MASK 0xf000 -#define WL_CHANSPEC_BAND_SHIFT 12 -#define WL_CHANSPEC_BAND_5G 0x1000 -#define WL_CHANSPEC_BAND_2G 0x2000 -#define INVCHANSPEC 255 - -/* Legacy structure to help keep backward compatible wl tool and tray app */ - -#define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */ - -typedef struct wl_bss_info_107 { - uint32 version; /* version field */ - uint32 length; /* byte length of data in this record, - * starting at version and including IEs - */ - struct ether_addr BSSID; - uint16 beacon_period; /* units are Kusec */ - uint16 capability; /* Capability information */ - uint8 SSID_len; - uint8 SSID[32]; - struct { - uint count; /* # rates in this set */ - uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ - } rateset; /* supported rates */ - uint8 channel; /* Channel no. */ - uint16 atim_window; /* units are Kusec */ - uint8 dtim_period; /* DTIM period */ - int16 RSSI; /* receive signal strength (in dBm) */ - int8 phy_noise; /* noise (in dBm) */ - uint32 ie_length; /* byte length of Information Elements */ - /* variable length Information Elements */ -} wl_bss_info_107_t; - -/* - * Per-bss information structure. - */ - -#define WL_BSS_INFO_VERSION 108 /* current version of wl_bss_info struct */ - -/* BSS info structure - * Applications MUST CHECK ie_offset field and length field to access IEs and - * next bss_info structure in a vector (in wl_scan_results_t) - */ -typedef struct wl_bss_info { - uint32 version; /* version field */ - uint32 length; /* byte length of data in this record, - * starting at version and including IEs - */ - struct ether_addr BSSID; - uint16 beacon_period; /* units are Kusec */ - uint16 capability; /* Capability information */ - uint8 SSID_len; - uint8 SSID[32]; - struct { - uint count; /* # rates in this set */ - uint8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ - } rateset; /* supported rates */ - chanspec_t chanspec; /* chanspec for bss */ - uint16 atim_window; /* units are Kusec */ - uint8 dtim_period; /* DTIM period */ - int16 RSSI; /* receive signal strength (in dBm) */ - int8 phy_noise; /* noise (in dBm) */ - - bool n_cap; /* BSS is 802.11N Capable */ - uint32 nbss_cap; /* 802.11N BSS Capabilities (based on EWC_CAP_*) */ - uint8 ctl_ch; /* 802.11N BSS control channel number */ - uint32 reserved[2]; /* Reserved for expansion of BSS properties */ - uint8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ - - uint16 ie_offset; /* offset at which IEs start, from beginning */ - uint32 ie_length; /* byte length of Information Elements */ - /* Add new fields here */ - /* variable length Information Elements */ -} wl_bss_info_t; - -typedef struct wlc_ssid { - uint32 SSID_len; - uchar SSID[32]; -} wlc_ssid_t; - -typedef struct wl_scan_params { - wlc_ssid_t ssid; /* default: {0, ""} */ - struct ether_addr bssid; /* default: bcast */ - int8 bss_type; /* default: any, - * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT - */ - int8 scan_type; /* -1 use default, DOT11_SCANTYPE_ACTIVE/PASSIVE */ - int32 nprobes; /* -1 use default, number of probes per channel */ - int32 active_time; /* -1 use default, dwell time per channel for - * active scanning - */ - int32 passive_time; /* -1 use default, dwell time per channel - * for passive scanning - */ - int32 home_time; /* -1 use default, dwell time for the home channel - * between channel scans - */ - int32 channel_num; /* 0 use default (all available channels), count of - * channels in channel_list - */ - uint16 channel_list[1]; /* list of chanspecs */ -} wl_scan_params_t; -/* size of wl_scan_params not including variable length array */ -#define WL_SCAN_PARAMS_FIXED_SIZE 64 - -typedef struct wl_scan_results { - uint32 buflen; - uint32 version; - uint32 count; - wl_bss_info_t bss_info[1]; -} wl_scan_results_t; -/* size of wl_scan_results not including variable length array */ -#define WL_SCAN_RESULTS_FIXED_SIZE 12 - - -#define WL_NUMRATES 255 /* max # of rates in a rateset */ -typedef struct wl_rateset { - uint32 count; /* # rates in this set */ - uint8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ -} wl_rateset_t; - -/* uint32 list */ -typedef struct wl_uint32_list { - /* in - # of elements, out - # of entries */ - uint32 count; - /* variable length uint32 list */ - uint32 element[1]; -} wl_uint32_list_t; - -#define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NULL */ - -/* defines used by the nrate iovar */ -#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ -#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ -#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ -#define NRATE_STF_SHIFT 8 /* stf mode shift */ - -#define ANTENNA_NUM_1 1 /* total number of antennas to be used */ -#define ANTENNA_NUM_2 2 -#define ANTENNA_NUM_3 3 -#define ANTENNA_NUM_4 4 - -typedef struct wl_channels_in_country { - uint32 buflen; - uint32 band; - char country_abbrev[WLC_CNTRY_BUF_SZ]; - uint32 count; - uint32 channel[1]; -} wl_channels_in_country_t; - -typedef struct wl_country_list { - uint32 buflen; - uint32 band_set; - uint32 band; - uint32 count; - char country_abbrev[1]; -} wl_country_list_t; - -#define WL_RM_TYPE_BASIC 1 -#define WL_RM_TYPE_CCA 2 -#define WL_RM_TYPE_RPI 3 - -#define WL_RM_FLAG_PARALLEL (1<<0) - -#define WL_RM_FLAG_LATE (1<<1) -#define WL_RM_FLAG_INCAPABLE (1<<2) -#define WL_RM_FLAG_REFUSED (1<<3) - -typedef struct wl_rm_req_elt { - int8 type; - int8 flags; - chanspec_t chanspec; - uint32 token; /* token for this measurement */ - uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ - uint32 tsf_l; /* TSF low 32-bits */ - uint32 dur; /* TUs */ -} wl_rm_req_elt_t; - -typedef struct wl_rm_req { - uint32 token; /* overall measurement set token */ - uint32 count; /* number of measurement requests */ - wl_rm_req_elt_t req[1]; /* variable length block of requests */ -} wl_rm_req_t; -#define WL_RM_REQ_FIXED_LEN 8 - -typedef struct wl_rm_rep_elt { - int8 type; - int8 flags; - chanspec_t chanspec; - uint32 token; /* token for this measurement */ - uint32 tsf_h; /* TSF high 32-bits of Measurement start time */ - uint32 tsf_l; /* TSF low 32-bits */ - uint32 dur; /* TUs */ - uint32 len; /* byte length of data block */ - uint8 data[1]; /* variable length data block */ -} wl_rm_rep_elt_t; -#define WL_RM_REP_ELT_FIXED_LEN 24 /* length excluding data block */ - -#define WL_RPI_REP_BIN_NUM 8 -typedef struct wl_rm_rpi_rep { - uint8 rpi[WL_RPI_REP_BIN_NUM]; - int8 rpi_max[WL_RPI_REP_BIN_NUM]; -} wl_rm_rpi_rep_t; - -typedef struct wl_rm_rep { - uint32 token; /* overall measurement set token */ - uint32 len; /* length of measurement report block */ - wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ -} wl_rm_rep_t; -#define WL_RM_REP_FIXED_LEN 8 - - -#if defined(BCMSUP_PSK) -typedef enum sup_auth_status { - WLC_SUP_DISCONNECTED = 0, - WLC_SUP_CONNECTING, - WLC_SUP_IDREQUIRED, - WLC_SUP_AUTHENTICATING, - WLC_SUP_AUTHENTICATED, - WLC_SUP_KEYXCHANGE, - WLC_SUP_KEYED, - WLC_SUP_TIMEOUT -} sup_auth_status_t; -#endif /* BCMCCX | BCMSUP_PSK */ - -/* Enumerate crypto algorithms */ -#define CRYPTO_ALGO_OFF 0 -#define CRYPTO_ALGO_WEP1 1 -#define CRYPTO_ALGO_TKIP 2 -#define CRYPTO_ALGO_WEP128 3 -#define CRYPTO_ALGO_AES_CCM 4 -#define CRYPTO_ALGO_AES_OCB_MSDU 5 -#define CRYPTO_ALGO_AES_OCB_MPDU 6 -#define CRYPTO_ALGO_NALG 7 - -#define WSEC_GEN_MIC_ERROR 0x0001 -#define WSEC_GEN_REPLAY 0x0002 - -#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ -#define WL_PRIMARY_KEY (1 << 1) /* Indicates this key is the primary (ie tx) key */ -#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ -#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ - -typedef struct wl_wsec_key { - uint32 index; /* key index */ - uint32 len; /* key length */ - uint8 data[DOT11_MAX_KEY_SIZE]; /* key data */ - uint32 pad_1[18]; - uint32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - uint32 flags; /* misc flags */ - uint32 pad_2[2]; - int pad_3; - int iv_initialized; /* has IV been initialized already? */ - int pad_4; - /* Rx IV */ - struct { - uint32 hi; /* upper 32 bits of IV */ - uint16 lo; /* lower 16 bits of IV */ - } rxiv; - uint32 pad_5[2]; - struct ether_addr ea; /* per station */ -} wl_wsec_key_t; - -#define WSEC_MIN_PSK_LEN 8 -#define WSEC_MAX_PSK_LEN 64 - -/* Flag for key material needing passhash'ing */ -#define WSEC_PASSPHRASE (1<<0) - -/* receptacle for WLC_SET_WSEC_PMK parameter */ -typedef struct { - ushort key_len; /* octets in key material */ - ushort flags; /* key handling qualification */ - uint8 key[WSEC_MAX_PSK_LEN]; /* PMK material */ -} wsec_pmk_t; - -/* wireless security bitvec */ -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 -#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ -#define FIPS_ENABLED 0x0080 - -/* WPA authentication mode bitvec */ -#define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ -#define WPA_AUTH_NONE 0x0001 /* none (IBSS) */ -#define WPA_AUTH_UNSPECIFIED 0x0002 /* over 802.1x */ -#define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ -/* #define WPA_AUTH_8021X 0x0020 */ /* 802.1x, reserved */ -#ifdef BCMWPA2 -#define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ -#define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ -#endif /* BCMWPA2 */ - -#ifdef BCMWPA2 -/* pmkid */ -#define MAXPMKID 16 - -typedef struct _pmkid -{ - struct ether_addr BSSID; - uint8 PMKID[WPA2_PMKID_LEN]; -} pmkid_t; - -typedef struct _pmkid_list -{ - uint32 npmkid; - pmkid_t pmkid[1]; -} pmkid_list_t; - -typedef struct _pmkid_cand { - struct ether_addr BSSID; - uint8 preauth; -} pmkid_cand_t; - -typedef struct _pmkid_cand_list { - uint32 npmkid_cand; - pmkid_cand_t pmkid_cand[1]; -} pmkid_cand_list_t; -#endif /* BCMWPA2 */ - -typedef struct wl_led_info { - uint32 index; /* led index */ - uint32 behavior; - bool activehi; -} wl_led_info_t; - -typedef struct wlc_assoc_info { - uint32 req_len; - uint32 resp_len; - uint32 flags; - struct dot11_assoc_req req; - struct ether_addr reassoc_bssid; /* used in reassoc's */ - struct dot11_assoc_resp resp; -} wl_assoc_info_t; -/* flags */ -#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ -/* srom read/write struct passed through ioctl */ -typedef struct { - uint byteoff; /* byte offset */ - uint nbytes; /* number of bytes */ - uint16 buf[1]; -} srom_rw_t; - -/* R_REG and W_REG struct passed through ioctl */ -typedef struct { - uint32 byteoff; /* byte offset of the field in d11regs_t */ - uint32 val; /* read/write value of the field */ - uint32 size; /* sizeof the field */ - uint band; /* band (optional) */ -} rw_reg_t; - -/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */ -/* PCL - Power Control Loop */ -/* current gain setting is replaced by user input */ -#define WL_ATTEN_APP_INPUT_PCL_OFF 0 /* turn off PCL, apply supplied input */ -#define WL_ATTEN_PCL_ON 1 /* turn on PCL */ -/* current gain setting is maintained */ -#define WL_ATTEN_PCL_OFF 2 /* turn off PCL. */ -typedef struct { - uint16 auto_ctrl; /* WL_ATTEN_XX */ - uint16 bb; /* Baseband attenuation */ - uint16 radio; /* Radio attenuation */ - uint16 txctl1; /* Radio TX_CTL1 value */ -} atten_t; - -/* defines used by poweridx iovar - it controls power in a-band */ -/* current gain setting is maintained */ -#define WL_PWRIDX_PCL_OFF -2 /* turn off PCL. */ -#define WL_PWRIDX_PCL_ON -1 /* turn on PCL */ -#define WL_PWRIDX_LOWER_LIMIT -2 /* lower limit */ -#define WL_PWRIDX_UPPER_LIMIT 63 /* upper limit */ -/* value >= 0 causes - * - input to be set to that value - * - PCL to be off - */ - -/* Used to get specific STA parameters */ -typedef struct { - uint32 val; - struct ether_addr ea; -} scb_val_t; - - -/* Event data type */ -typedef struct wlc_event { - wl_event_msg_t event; /* encapsulated event */ - struct ether_addr *addr; /* used to keep a trace of the potential present of - * an address in wlc_event_msg_t - */ - void *data; /* used to hang additional data on an event */ - struct wlc_event *next; /* enables ordered list of pending events */ -} wlc_event_t; - -#define BCM_MAC_STATUS_INDICATION (0x40010200L) - -/* Please update the following when modifying this structure: - * StaInfo Twiki page flags section - description of the sta_info_t struct - * src/wl/exe/wlu.c - print of sta_info_t - * Pay attention to version if structure changes. - */ -typedef struct { - uint16 ver; /* version of this struct */ - uint16 len; /* length in bytes of this structure */ - uint16 cap; /* sta's advertised capabilities */ - uint32 flags; /* flags defined below */ - uint32 idle; /* time since data pkt rx'd from sta */ - struct ether_addr ea; /* Station address */ - wl_rateset_t rateset; /* rateset in use */ - uint32 in; /* seconds elapsed since associated */ - uint32 listen_interval_inms; /* Min Listen interval in ms for this STA */ -} sta_info_t; - -#define WL_STA_VER 2 - -/* Flags for sta_info_t indicating properties of STA */ -#define WL_STA_BRCM 0x1 /* Running a Broadcom driver */ -#define WL_STA_WME 0x2 /* WMM association */ -#define WL_STA_ABCAP 0x4 /* Afterburner-capable */ -#define WL_STA_AUTHE 0x8 /* Authenticated */ -#define WL_STA_ASSOC 0x10 /* Associated */ -#define WL_STA_AUTHO 0x20 /* Authorized */ -#define WL_STA_WDS 0x40 /* Wireless Distribution System */ -#define WL_STA_WDS_LINKUP 0x80 /* WDS traffic/probes flowing properly */ -#define WL_STA_PS 0x100 /* STA is in power save mode from AP's viewpoint */ -#define WL_STA_APSD_BE 0x200 /* APSD delv/trigger for AC_BE is default enabled */ -#define WL_STA_APSD_BK 0x400 /* APSD delv/trigger for AC_BK is default enabled */ -#define WL_STA_APSD_VI 0x800 /* APSD delv/trigger for AC_VI is default enabled */ -#define WL_STA_APSD_VO 0x1000 /* APSD delv/trigger for AC_VO is default enabled */ -#define WL_STA_N_CAP 0x2000 /* STA 802.11n capable */ - -#define WL_WDS_LINKUP WL_STA_WDS_LINKUP /* deprecated */ - -/* - * Country locale determines which channels are available to us. - */ -typedef enum _wlc_locale { - WLC_WW = 0, /* Worldwide */ - WLC_THA, /* Thailand */ - WLC_ISR, /* Israel */ - WLC_JDN, /* Jordan */ - WLC_PRC, /* China */ - WLC_JPN, /* Japan */ - WLC_FCC, /* USA */ - WLC_EUR, /* Europe */ - WLC_USL, /* US Low Band only */ - WLC_JPH, /* Japan High Band only */ - WLC_ALL, /* All the channels in this band */ - WLC_11D, /* Represents locale received by 11d beacons */ - WLC_LAST_LOCALE, - WLC_UNDEFINED_LOCALE = 0xf -} wlc_locale_t; - -/* channel encoding */ -typedef struct channel_info { - int hw_channel; - int target_channel; - int scan_channel; -} channel_info_t; - -/* For ioctls that take a list of MAC addresses */ -struct maclist { - uint count; /* number of MAC addresses */ - struct ether_addr ea[1]; /* variable length array of MAC addresses */ -}; - -/* get pkt count struct passed through ioctl */ -typedef struct get_pktcnt { - uint rx_good_pkt; - uint rx_bad_pkt; - uint tx_good_pkt; - uint tx_bad_pkt; -} get_pktcnt_t; - -/* Linux network driver ioctl encoding */ -typedef struct wl_ioctl { - uint cmd; /* common ioctl definition */ - void *buf; /* pointer to user buffer */ - uint len; /* length of user buffer */ - bool set; /* get or set request (optional) */ - uint used; /* bytes read or written (optional) */ - uint needed; /* bytes needed (optional) */ -} wl_ioctl_t; - -/* - * Structure for passing hardware and software - * revision info up from the driver. - */ -typedef struct wlc_rev_info { - uint vendorid; /* PCI vendor id */ - uint deviceid; /* device id of chip */ - uint radiorev; /* radio revision */ - uint chiprev; /* chip revision */ - uint corerev; /* core revision */ - uint boardid; /* board identifier (usu. PCI sub-device id) */ - uint boardvendor; /* board vendor (usu. PCI sub-vendor id) */ - uint boardrev; /* board revision */ - uint driverrev; /* driver version */ - uint ucoderev; /* microcode version */ - uint bus; /* bus type */ - uint chipnum; /* chip number */ -} wlc_rev_info_t; - -#define WL_BRAND_MAX 10 -typedef struct wl_instance_info { - uint instance; - char brand[WL_BRAND_MAX]; -} wl_instance_info_t; - -/* check this magic number */ -#define WLC_IOCTL_MAGIC 0x14e46c77 - -/* bump this number if you change the ioctl interface */ -#define WLC_IOCTL_VERSION 1 - -#define WLC_IOCTL_MAXLEN 8192 /* max length ioctl buffer required */ -#define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ - -/* common ioctl definitions */ -#define WLC_GET_MAGIC 0 -#define WLC_GET_VERSION 1 -#define WLC_UP 2 -#define WLC_DOWN 3 -#define WLC_DUMP 6 -#define WLC_GET_MSGLEVEL 7 -#define WLC_SET_MSGLEVEL 8 -#define WLC_GET_PROMISC 9 -#define WLC_SET_PROMISC 10 -#define WLC_GET_RATE 12 -/* #define WLC_SET_RATE 13 */ /* no longer supported */ -#define WLC_GET_INSTANCE 14 -/* #define WLC_GET_FRAG 15 */ /* no longer supported */ -/* #define WLC_SET_FRAG 16 */ /* no longer supported */ -/* #define WLC_GET_RTS 17 */ /* no longer supported */ -/* #define WLC_SET_RTS 18 */ /* no longer supported */ -#define WLC_GET_INFRA 19 -#define WLC_SET_INFRA 20 -#define WLC_GET_AUTH 21 -#define WLC_SET_AUTH 22 -#define WLC_GET_BSSID 23 -#define WLC_SET_BSSID 24 -#define WLC_GET_SSID 25 -#define WLC_SET_SSID 26 -#define WLC_RESTART 27 -#define WLC_GET_CHANNEL 29 -#define WLC_SET_CHANNEL 30 -#define WLC_GET_SRL 31 -#define WLC_SET_SRL 32 -#define WLC_GET_LRL 33 -#define WLC_SET_LRL 34 -#define WLC_GET_PLCPHDR 35 -#define WLC_SET_PLCPHDR 36 -#define WLC_GET_RADIO 37 -#define WLC_SET_RADIO 38 -#define WLC_GET_PHYTYPE 39 -/* #define WLC_GET_WEP 42 */ /* no longer supported */ -/* #define WLC_SET_WEP 43 */ /* no longer supported */ -#define WLC_GET_KEY 44 -#define WLC_SET_KEY 45 -#define WLC_GET_REGULATORY 46 -#define WLC_SET_REGULATORY 47 -#define WLC_GET_PASSIVE 48 -#define WLC_SET_PASSIVE 49 -#define WLC_SCAN 50 -#define WLC_SCAN_RESULTS 51 -#define WLC_DISASSOC 52 -#define WLC_REASSOC 53 -#define WLC_GET_ROAM_TRIGGER 54 -#define WLC_SET_ROAM_TRIGGER 55 -#define WLC_GET_TXANT 61 -#define WLC_SET_TXANT 62 -#define WLC_GET_ANTDIV 63 -#define WLC_SET_ANTDIV 64 -/* #define WLC_GET_TXPWR 65 */ /* no longer supported */ -/* #define WLC_SET_TXPWR 66 */ /* no longer supported */ -#define WLC_GET_CLOSED 67 -#define WLC_SET_CLOSED 68 -#define WLC_GET_MACLIST 69 -#define WLC_SET_MACLIST 70 -#define WLC_GET_RATESET 71 -#define WLC_SET_RATESET 72 -#define WLC_GET_LOCALE 73 -#define WLC_LONGTRAIN 74 -#define WLC_GET_BCNPRD 75 -#define WLC_SET_BCNPRD 76 -#define WLC_GET_DTIMPRD 77 -#define WLC_SET_DTIMPRD 78 -#define WLC_GET_SROM 79 -#define WLC_SET_SROM 80 -#define WLC_GET_WEP_RESTRICT 81 -#define WLC_SET_WEP_RESTRICT 82 -#define WLC_GET_COUNTRY 83 -#define WLC_SET_COUNTRY 84 -#define WLC_GET_PM 85 -#define WLC_SET_PM 86 -#define WLC_GET_WAKE 87 -#define WLC_SET_WAKE 88 -#define WLC_GET_D11CNTS 89 -#define WLC_GET_FORCELINK 90 /* ndis only */ -#define WLC_SET_FORCELINK 91 /* ndis only */ -#define WLC_FREQ_ACCURACY 92 -#define WLC_CARRIER_SUPPRESS 93 -#define WLC_GET_PHYREG 94 -#define WLC_SET_PHYREG 95 -#define WLC_GET_RADIOREG 96 -#define WLC_SET_RADIOREG 97 -#define WLC_GET_REVINFO 98 -#define WLC_GET_UCANTDIV 99 -#define WLC_SET_UCANTDIV 100 -#define WLC_R_REG 101 -#define WLC_W_REG 102 -#define WLC_DIAG_LOOPBACK 103 -#define WLC_RESET_D11CNTS 104 -#define WLC_GET_MACMODE 105 -#define WLC_SET_MACMODE 106 -#define WLC_GET_MONITOR 107 -#define WLC_SET_MONITOR 108 -#define WLC_GET_GMODE 109 -#define WLC_SET_GMODE 110 -#define WLC_GET_LEGACY_ERP 111 -#define WLC_SET_LEGACY_ERP 112 -#define WLC_GET_RX_ANT 113 -#define WLC_GET_CURR_RATESET 114 /* current rateset */ -#define WLC_GET_SCANSUPPRESS 115 -#define WLC_SET_SCANSUPPRESS 116 -#define WLC_GET_AP 117 -#define WLC_SET_AP 118 -#define WLC_GET_EAP_RESTRICT 119 -#define WLC_SET_EAP_RESTRICT 120 -#define WLC_SCB_AUTHORIZE 121 -#define WLC_SCB_DEAUTHORIZE 122 -#define WLC_GET_WDSLIST 123 -#define WLC_SET_WDSLIST 124 -#define WLC_GET_ATIM 125 -#define WLC_SET_ATIM 126 -#define WLC_GET_RSSI 127 -#define WLC_GET_PHYANTDIV 128 -#define WLC_SET_PHYANTDIV 129 -#define WLC_AP_RX_ONLY 130 -#define WLC_GET_TX_PATH_PWR 131 -#define WLC_SET_TX_PATH_PWR 132 -#define WLC_GET_WSEC 133 -#define WLC_SET_WSEC 134 -#define WLC_GET_PHY_NOISE 135 -#define WLC_GET_BSS_INFO 136 -#define WLC_GET_PKTCNTS 137 -#define WLC_GET_LAZYWDS 138 -#define WLC_SET_LAZYWDS 139 -#define WLC_GET_BANDLIST 140 -#define WLC_GET_BAND 141 -#define WLC_SET_BAND 142 -#define WLC_SCB_DEAUTHENTICATE 143 -#define WLC_GET_SHORTSLOT 144 -#define WLC_GET_SHORTSLOT_OVERRIDE 145 -#define WLC_SET_SHORTSLOT_OVERRIDE 146 -#define WLC_GET_SHORTSLOT_RESTRICT 147 -#define WLC_SET_SHORTSLOT_RESTRICT 148 -#define WLC_GET_GMODE_PROTECTION 149 -#define WLC_GET_GMODE_PROTECTION_OVERRIDE 150 -#define WLC_SET_GMODE_PROTECTION_OVERRIDE 151 -#define WLC_UPGRADE 152 -/* #define WLC_GET_MRATE 153 */ /* no longer supported */ -/* #define WLC_SET_MRATE 154 */ /* no longer supported */ -#define WLC_GET_ASSOCLIST 159 -#define WLC_GET_CLK 160 -#define WLC_SET_CLK 161 -#define WLC_GET_UP 162 -#define WLC_OUT 163 -#define WLC_GET_WPA_AUTH 164 -#define WLC_SET_WPA_AUTH 165 -#define WLC_GET_PROTECTION_CONTROL 178 -#define WLC_SET_PROTECTION_CONTROL 179 -#define WLC_GET_PHYLIST 180 -#define WLC_GET_KEY_SEQ 183 -/* #define WLC_GET_GMODE_PROTECTION_CTS 198 */ /* no longer supported */ -/* #define WLC_SET_GMODE_PROTECTION_CTS 199 */ /* no longer supported */ -#define WLC_GET_PIOMODE 203 -#define WLC_SET_PIOMODE 204 -#define WLC_SET_LED 209 -#define WLC_GET_LED 210 -#define WLC_GET_CHANNEL_SEL 215 -#define WLC_START_CHANNEL_SEL 216 -#define WLC_GET_VALID_CHANNELS 217 -#define WLC_GET_FAKEFRAG 218 -#define WLC_SET_FAKEFRAG 219 -#define WLC_GET_WET 230 -#define WLC_SET_WET 231 -#define WLC_GET_KEY_PRIMARY 235 -#define WLC_SET_KEY_PRIMARY 236 -#define WLC_GET_RADAR 242 -#define WLC_SET_RADAR 243 -#define WLC_SET_SPECT_MANAGMENT 244 -#define WLC_GET_SPECT_MANAGMENT 245 -#define WLC_WDS_GET_REMOTE_HWADDR 246 /* handled in wl_linux.c/wl_vx.c */ -#define WLC_SET_CS_SCAN_TIMER 248 -#define WLC_GET_CS_SCAN_TIMER 249 -#define WLC_SEND_PWR_CONSTRAINT 254 -#define WLC_CURRENT_PWR 256 -#define WLC_GET_CHANNELS_IN_COUNTRY 260 -#define WLC_GET_COUNTRY_LIST 261 -#define WLC_GET_VAR 262 /* get value of named variable */ -#define WLC_SET_VAR 263 /* set named variable to value */ -#define WLC_NVRAM_GET 264 /* deprecated */ -#define WLC_NVRAM_SET 265 -#define WLC_SET_WSEC_PMK 268 -#define WLC_GET_AUTH_MODE 269 -#define WLC_SET_AUTH_MODE 270 -#define WLC_NDCONFIG_ITEM 273 /* currently handled in wl_oid.c */ -#define WLC_NVOTPW 274 -#define WLC_OTPW 275 -#define WLC_SET_LOCALE 278 -#define WLC_LAST 279 /* do not change - use get_var/set_var */ - -/* - * Minor kludge alert: - * Duplicate a few definitions that irelay requires from epiioctl.h here - * so caller doesn't have to include this file and epiioctl.h . - * If this grows any more, it would be time to move these irelay-specific - * definitions out of the epiioctl.h and into a separate driver common file. - */ -#ifndef EPICTRL_COOKIE -#define EPICTRL_COOKIE 0xABADCEDE -#endif - -/* vx wlc ioctl's offset */ -#define CMN_IOCTL_OFF 0x180 - -/* - * custom OID support - * - * 0xFF - implementation specific OID - * 0xE4 - first byte of Broadcom PCI vendor ID - * 0x14 - second byte of Broadcom PCI vendor ID - * 0xXX - the custom OID number - */ - -/* begin 0x1f values beyond the start of the ET driver range. */ -#define WL_OID_BASE 0xFFE41420 - -/* NDIS overrides */ -#define OID_WL_GETINSTANCE (WL_OID_BASE + WLC_GET_INSTANCE) -#define OID_WL_NDCONFIG_ITEM (WL_OID_BASE + WLC_NDCONFIG_ITEM) - -#define WL_DECRYPT_STATUS_SUCCESS 1 -#define WL_DECRYPT_STATUS_FAILURE 2 -#define WL_DECRYPT_STATUS_UNKNOWN 3 - -/* allows user-mode app to poll the status of USB image upgrade */ -#define WLC_UPGRADE_SUCCESS 0 -#define WLC_UPGRADE_PENDING 1 - -#ifdef CONFIG_USBRNDIS_RETAIL -/* struct passed in for WLC_NDCONFIG_ITEM */ -typedef struct { - char *name; - void *param; -} ndconfig_item_t; -#endif - -/* Bit masks for radio disabled status - returned by WL_GET_RADIO */ -#define WL_RADIO_SW_DISABLE (1<<0) -#define WL_RADIO_HW_DISABLE (1<<1) -#define WL_RADIO_MPC_DISABLE (1<<2) -#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */ - -/* Override bit for WLC_SET_TXPWR. if set, ignore other level limits */ -#define WL_TXPWR_OVERRIDE (1<<31) - -/* "diag" iovar argument and error code */ -#define WL_DIAG_INTERRUPT 1 /* d11 loopback interrupt test */ -#define WL_DIAG_MEMORY 3 /* d11 memory test */ -#define WL_DIAG_LED 4 /* LED test */ -#define WL_DIAG_REG 5 /* d11/phy register test */ -#define WL_DIAG_SROM 6 /* srom read/crc test */ -#define WL_DIAG_DMA 7 /* DMA test */ - -#define WL_DIAGERR_SUCCESS 0 -#define WL_DIAGERR_FAIL_TO_RUN 1 /* unable to run requested diag */ -#define WL_DIAGERR_NOT_SUPPORTED 2 /* diag requested is not supported */ -#define WL_DIAGERR_INTERRUPT_FAIL 3 /* loopback interrupt test failed */ -#define WL_DIAGERR_LOOPBACK_FAIL 4 /* loopback data test failed */ -#define WL_DIAGERR_SROM_FAIL 5 /* srom read failed */ -#define WL_DIAGERR_SROM_BADCRC 6 /* srom crc failed */ -#define WL_DIAGERR_REG_FAIL 7 /* d11/phy register test failed */ -#define WL_DIAGERR_MEMORY_FAIL 8 /* d11 memory test failed */ -#define WL_DIAGERR_NOMEM 9 /* diag test failed due to no memory */ -#define WL_DIAGERR_DMA_FAIL 10 /* DMA test failed */ - -/* band types */ -#define WLC_BAND_AUTO 0 /* auto-select */ -#define WLC_BAND_5G 1 /* 5 Ghz */ -#define WLC_BAND_2G 2 /* 2.4 Ghz */ -#define WLC_BAND_ALL 3 /* all bands */ - -/* phy types (returned by WLC_GET_PHYTPE) */ -#define WLC_PHY_TYPE_A 0 -#define WLC_PHY_TYPE_B 1 -#define WLC_PHY_TYPE_G 2 -#define WLC_PHY_TYPE_N 4 -#define WLC_PHY_TYPE_NULL 0xf - -/* MAC list modes */ -#define WLC_MACMODE_DISABLED 0 /* MAC list disabled */ -#define WLC_MACMODE_DENY 1 /* Deny specified (i.e. allow unspecified) */ -#define WLC_MACMODE_ALLOW 2 /* Allow specified (i.e. deny unspecified) */ - -/* - * - */ -#define GMODE_LEGACY_B 0 -#define GMODE_AUTO 1 -#define GMODE_ONLY 2 -#define GMODE_B_DEFERRED 3 -#define GMODE_PERFORMANCE 4 -#define GMODE_LRS 5 -#define GMODE_MAX 6 - -/* values for PLCPHdr_override */ -#define WLC_PLCP_AUTO -1 -#define WLC_PLCP_SHORT 0 -#define WLC_PLCP_LONG 1 - -/* values for g_protection_override and n_protection_override */ -#define WLC_PROTECTION_AUTO -1 -#define WLC_PROTECTION_OFF 0 -#define WLC_PROTECTION_ON 1 - -/* values for g_protection_control and n_protection_control */ -#define WLC_PROTECTION_CTL_OFF 0 -#define WLC_PROTECTION_CTL_LOCAL 1 -#define WLC_PROTECTION_CTL_OVERLAP 2 - -/* deprecated const names for g_protection_override */ -#define WLC_G_PROTECTION_AUTO WLC_PROTECTION_AUTO -#define WLC_G_PROTECTION_OFF WLC_PROTECTION_OFF -#define WLC_G_PROTECTION_ON WLC_PROTECTION_ON - -/* deprecated const names for g_protection_control */ -#define WLC_G_PROTECTION_CTL_OFF WLC_PROTECTION_CTL_OFF -#define WLC_G_PROTECTION_CTL_LOCAL WLC_PROTECTION_CTL_LOCAL -#define WLC_G_PROTECTION_CTL_OVERLAP WLC_PROTECTION_CTL_OVERLAP - -/* deprecated const names for get/set g_protection_control */ -#define WLC_GET_GMODE_PROTECTION_CONTROL WLC_GET_PROTECTION_CONTROL -#define WLC_SET_GMODE_PROTECTION_CONTROL WLC_SET_PROTECTION_CONTROL - -/* values for n_protection */ -#define WLC_N_PROTECTION_OFF 0 -#define WLC_N_PROTECTION_MIXEDMODE 1 -#define WLC_N_PROTECTION_CTS 2 - -/* values for n_preamble_type */ -#define WLC_N_PREAMBLE_MIXEDMODE 0 -#define WLC_N_PREAMBLE_GF 1 - -/* Values for PM */ -#define PM_OFF 0 -#define PM_MAX 1 -#define PM_FAST 2 - - - -typedef struct { - int npulses; /* required number of pulses at n * t_int */ - int ncontig; /* required number of pulses at t_int */ - int min_pw; /* minimum pulse width (20 MHz clocks) */ - int max_pw; /* maximum pulse width (20 MHz clocks) */ - uint16 thresh0; /* Radar detection, thresh 0 */ - uint16 thresh1; /* Radar detection, thresh 1 */ - int npulses_lp; /* Radar detection, minimum long pulses */ - int min_pw_lp; /* Minimum pulsewidth for long pulses */ - int max_pw_lp; /* Maximum pulsewidth for long pulses */ - int min_fm_lp; /* Minimum fm for long pulses */ - int max_deltat_lp; /* Maximum deltat for long pulses */ - int min_deltat; /* Minimum spacing between pulses */ -} wl_radar_args_t; - -/* radar iovar SET defines */ -#define WL_RADAR_DETECTOR_OFF 0 /* radar detector off */ -#define WL_RADAR_DETECTOR_ON 1 /* radar detector on */ -#define WL_RADAR_SIMULATED 2 /* force radar detector to declare - * detection once - */ - -/* dfs_status iovar-related defines */ - -/* cac - channel availability check, - * ism - in-service monitoring - * csa - channel switching announcement - */ - -/* cac state values */ -#define WL_DFS_CACSTATE_IDLE 0 /* state for operating in non-radar channel */ -#define WL_DFS_CACSTATE_PREISM_CAC 1 /* CAC in progress */ -#define WL_DFS_CACSTATE_ISM 2 /* ISM in progress */ -#define WL_DFS_CACSTATE_CSA 3 /* csa */ -#define WL_DFS_CACSTATE_POSTISM_CAC 4 /* ISM CAC */ -#define WL_DFS_CACSTATE_PREISM_OOC 5 /* PREISM OOC */ -#define WL_DFS_CACSTATE_POSTISM_OOC 6 /* POSTISM OOC */ -#define WL_DFS_CACSTATES 7 /* this many states exist */ - -/* data structure used in 'dfs_status' wl interface, which is used to query dfs status */ -typedef struct { - uint state; /* noted by WL_DFS_CACSTATE_XX. */ - uint duration; /* time spent in ms in state. */ - /* as dfs enters ISM state, it removes the operational channel from quiet channel - * list and notes the channel in channel_cleared. set to 0 if no channel is cleared - */ - chanspec_t chanspec_cleared; - /* chanspec cleared used to be a uint, add another to uint16 to maintain size */ - uint16 pad; -} wl_dfs_status_t; - -#define NUM_PWRCTRL_RATES 12 - -typedef struct tx_inst_power { -} tx_inst_power_t; - - -/* regulatory enforcement levels */ -#define SPECT_MNGMT_OFF 0 /* both 11h and 11d disabled */ -#define SPECT_MNGMT_LOOSE_11H 1 /* allow non-11h APs in scan lists */ -#define SPECT_MNGMT_STRICT_11H 2 /* prune out non-11h APs from scan list */ -#define SPECT_MNGMT_STRICT_11D 3 /* switch to 802.11D mode */ -/* SPECT_MNGMT_LOOSE_11H_D - same as SPECT_MNGMT_LOOSE with the exception that Country IE - * adoption is done irregardless of capability-spectrum_management - */ -#define SPECT_MNGMT_LOOSE_11H_D 4 /* operation defined above */ - -#define WL_CHAN_VALID_HW (1 << 0) /* valid with current HW */ -#define WL_CHAN_VALID_SW (1 << 1) /* valid with current country setting */ -#define WL_CHAN_BAND_5G (1 << 2) /* 5GHz-band channel */ -#define WL_CHAN_RADAR (1 << 3) /* radar sensitive channel */ -#define WL_CHAN_INACTIVE (1 << 4) /* temporarily inactive due to radar */ -#define WL_CHAN_PASSIVE (1 << 5) /* channel is in passive mode */ -#define WL_CHAN_RESTRICTED (1 << 6) /* restricted use channel */ - -/* BTC mode used by "btc_mode" iovar */ -#define WL_BTC_DISABLE 0 /* disable BT coexistance */ -#define WL_BTC_ENABLE 1 /* enable BT coexistance */ -#define WL_BTC_PREMPT 2 /* enable BT coexistance and BT pre-emption */ - -#define WL_MPC_VAL 0x00400000 -#define WL_APSTA_VAL 0x00800000 -#define WL_DFS_VAL 0x01000000 -#define WL_BA_VAL 0x02000000 -#define WL_NITRO_VAL 0x04000000 -#define WL_CAC_VAL 0x08000000 -#define WL_AMSDU_VAL 0x10000000 -#define WL_AMPDU_VAL 0x20000000 - -/* max # of leds supported by GPIO (gpio pin# == led index#) */ -#define WL_LED_NUMGPIO 16 /* gpio 0-15 */ - -/* led per-pin behaviors */ -#define WL_LED_OFF 0 /* always off */ -#define WL_LED_ON 1 /* always on */ -#define WL_LED_ACTIVITY 2 /* activity */ -#define WL_LED_RADIO 3 /* radio enabled */ -#define WL_LED_ARADIO 4 /* 5 Ghz radio enabled */ -#define WL_LED_BRADIO 5 /* 2.4Ghz radio enabled */ -#define WL_LED_BGMODE 6 /* on if gmode, off if bmode */ -#define WL_LED_WI1 7 -#define WL_LED_WI2 8 -#define WL_LED_WI3 9 -#define WL_LED_ASSOC 10 /* associated state indicator */ -#define WL_LED_INACTIVE 11 /* null behavior (clears default behavior) */ -#define WL_LED_NUMBEHAVIOR 12 - -/* led behavior numeric value format */ -#define WL_LED_BEH_MASK 0x7f /* behavior mask */ -#define WL_LED_AL_MASK 0x80 /* activelow (polarity) bit */ - -/* max # of channels returnd by the get valid channels iovar */ -#define WL_NUMCHANSPECS 100 - -/* WDS link local endpoint WPA role */ -#define WL_WDS_WPA_ROLE_AUTH 0 /* authenticator */ -#define WL_WDS_WPA_ROLE_SUP 1 /* supplicant */ -#define WL_WDS_WPA_ROLE_AUTO 255 /* auto, based on mac addr value */ - -/* number of bytes needed to define a 128-bit mask for MAC event reporting */ -#define WL_EVENTING_MASK_LEN 16 - -/* Structures and constants used for "vndr_ie" IOVar interface */ -#define VNDR_IE_CMD_LEN 4 /* length of the set command string: - * "add", "del" (+ NULL) - */ - -/* 802.11 Mgmt Packet flags */ -#define VNDR_IE_BEACON_FLAG 0x1 -#define VNDR_IE_PRBRSP_FLAG 0x2 -#define VNDR_IE_ASSOCRSP_FLAG 0x4 -#define VNDR_IE_AUTHRSP_FLAG 0x8 - -#define VNDR_IE_INFO_HDR_LEN (sizeof(uint32)) - -typedef struct { - uint32 pktflag; /* bitmask indicating which packet(s) contain this IE */ - vndr_ie_t vndr_ie_data; /* vendor IE data */ -} vndr_ie_info_t; - -typedef struct { - int iecount; /* number of entries in the vndr_ie_list[] array */ - vndr_ie_info_t vndr_ie_list[1]; /* variable size list of vndr_ie_info_t structs */ -} vndr_ie_buf_t; - -typedef struct { - char cmd[VNDR_IE_CMD_LEN]; /* vndr_ie IOVar set command : "add", "del" + NULL */ - vndr_ie_buf_t vndr_ie_buffer; /* buffer containing Vendor IE list information */ -} vndr_ie_setbuf_t; - -/* join target preference types */ -#define WL_JOIN_PREF_RSSI 1 /* by RSSI, mandatory */ -#define WL_JOIN_PREF_WPA 2 /* by akm and ciphers, optional, RSN and WPA as values */ -#define WL_JOIN_PREF_BAND 3 /* by 802.11 band, optional, WLC_BAND_XXXX as values */ - -/* band preference */ -#define WLJP_BAND_ASSOC_PREF 255 /* use assoc preference settings */ - /* others use WLC_BAND_XXXX as values */ - -/* any multicast cipher suite */ -#define WL_WPA_ACP_MCS_ANY "\x00\x00\x00\x00" - -struct tsinfo_arg { - uint8 octets[3]; -}; - -#if !defined(__GNUC__) -#pragma pack(pop) -#endif - -#define NFIFO 6 /* # tx/rx fifopairs */ - -#define WL_CNT_T_VERSION 1 /* current version of wl_cnt_t struct */ - -typedef struct { - uint16 version; /* see definition of WL_CNT_T_VERSION */ - uint16 length; /* length of entire structure */ - - /* transmit stat counters */ - uint32 txframe; /* tx data frames */ - uint32 txbyte; /* tx data bytes */ - uint32 txretrans; /* tx mac retransmits */ - uint32 txerror; /* tx data errors (derived: sum of others) */ - uint32 txctl; /* tx management frames */ - uint32 txprshort; /* tx short preamble frames */ - uint32 txserr; /* tx status errors */ - uint32 txnobuf; /* tx out of buffers errors */ - uint32 txnoassoc; /* tx discard because we're not associated */ - uint32 txrunt; /* tx runt frames */ - uint32 txchit; /* tx header cache hit (fastpath) */ - uint32 txcmiss; /* tx header cache miss (slowpath) */ - - /* transmit chip error counters */ - uint32 txuflo; /* tx fifo underflows */ - uint32 txphyerr; /* tx phy errors (indicated in tx status) */ - uint32 txphycrs; - - /* receive stat counters */ - uint32 rxframe; /* rx data frames */ - uint32 rxbyte; /* rx data bytes */ - uint32 rxerror; /* rx data errors (derived: sum of others) */ - uint32 rxctl; /* rx management frames */ - uint32 rxnobuf; /* rx out of buffers errors */ - uint32 rxnondata; /* rx non data frames in the data channel errors */ - uint32 rxbadds; /* rx bad DS errors */ - uint32 rxbadcm; /* rx bad control or management frames */ - uint32 rxfragerr; /* rx fragmentation errors */ - uint32 rxrunt; /* rx runt frames */ - uint32 rxgiant; /* rx giant frames */ - uint32 rxnoscb; /* rx no scb error */ - uint32 rxbadproto; /* rx invalid frames */ - uint32 rxbadsrcmac; /* rx frames with Invalid Src Mac */ - uint32 rxbadda; /* rx frames tossed for invalid da */ - uint32 rxfilter; /* rx frames filtered out */ - - /* receive chip error counters */ - uint32 rxoflo; /* rx fifo overflow errors */ - uint32 rxuflo[NFIFO]; /* rx dma descriptor underflow errors */ - - uint32 d11cnt_txrts_off; /* d11cnt txrts value when reset d11cnt */ - uint32 d11cnt_rxcrc_off; /* d11cnt rxcrc value when reset d11cnt */ - uint32 d11cnt_txnocts_off; /* d11cnt txnocts value when reset d11cnt */ - - /* misc counters */ - uint32 dmade; /* tx/rx dma descriptor errors */ - uint32 dmada; /* tx/rx dma data errors */ - uint32 dmape; /* tx/rx dma descriptor protocol errors */ - uint32 reset; /* reset count */ - uint32 tbtt; /* cnts the TBTT int's */ - uint32 txdmawar; - uint32 pkt_callback_reg_fail; /* callbacks register failure */ - - /* MAC counters: 32-bit version of d11.h's macstat_t */ - uint32 txallfrm; /* total number of frames sent, incl. Data, ACK, RTS, CTS, - * Control Management (includes retransmissions) - */ - uint32 txrtsfrm; /* number of RTS sent out by the MAC */ - uint32 txctsfrm; /* number of CTS sent out by the MAC */ - uint32 txackfrm; /* number of ACK frames sent out */ - uint32 txdnlfrm; /* Not used */ - uint32 txbcnfrm; /* beacons transmitted */ - uint32 txfunfl[8]; /* per-fifo tx underflows */ - uint32 txtplunfl; /* Template underflows (mac was too slow to transmit ACK/CTS - * or BCN) - */ - uint32 txphyerror; /* Transmit phy error, type of error is reported in tx-status for - * driver enqueued frames - */ - uint32 rxfrmtoolong; /* Received frame longer than legal limit (2346 bytes) */ - uint32 rxfrmtooshrt; /* Received frame did not contain enough bytes for its frame type */ - uint32 rxinvmachdr; /* Either the protocol version != 0 or frame type not - * data/control/management - */ - uint32 rxbadfcs; /* number of frames for which the CRC check failed in the MAC */ - uint32 rxbadplcp; /* parity check of the PLCP header failed */ - uint32 rxcrsglitch; /* PHY was able to correlate the preamble but not the header */ - uint32 rxstrt; /* Number of received frames with a good PLCP - * (i.e. passing parity check) - */ - uint32 rxdfrmucastmbss; /* Number of received DATA frames with good FCS and matching RA */ - uint32 rxmfrmucastmbss; /* number of received mgmt frames with good FCS and matching RA */ - uint32 rxcfrmucast; /* number of received CNTRL frames with good FCS and matching RA */ - uint32 rxrtsucast; /* number of unicast RTS addressed to the MAC (good FCS) */ - uint32 rxctsucast; /* number of unicast CTS addressed to the MAC (good FCS) */ - uint32 rxackucast; /* number of ucast ACKS received (good FCS) */ - uint32 rxdfrmocast; /* number of received DATA frames (good FCS and not matching RA) */ - uint32 rxmfrmocast; /* number of received MGMT frames (good FCS and not matching RA) */ - uint32 rxcfrmocast; /* number of received CNTRL frame (good FCS and not matching RA) */ - uint32 rxrtsocast; /* number of received RTS not addressed to the MAC */ - uint32 rxctsocast; /* number of received CTS not addressed to the MAC */ - uint32 rxdfrmmcast; /* number of RX Data multicast frames received by the MAC */ - uint32 rxmfrmmcast; /* number of RX Management multicast frames received by the MAC */ - uint32 rxcfrmmcast; /* number of RX Control multicast frames received by the MAC - * (unlikely to see these) - */ - uint32 rxbeaconmbss; /* beacons received from member of BSS */ - uint32 rxdfrmucastobss; /* number of unicast frames addressed to the MAC from - * other BSS (WDS FRAME) - */ - uint32 rxbeaconobss; /* beacons received from other BSS */ - uint32 rxrsptmout; /* Number of response timeouts for transmitted frames - * expecting a response - */ - uint32 bcntxcancl; /* transmit beacons canceled due to receipt of beacon (IBSS) */ - uint32 rxf0ovfl; /* Number of receive fifo 0 overflows */ - uint32 rxf1ovfl; /* Number of receive fifo 1 overflows (obsolete) */ - uint32 rxf2ovfl; /* Number of receive fifo 2 overflows (obsolete) */ - uint32 txsfovfl; /* Number of transmit status fifo overflows (obsolete) */ - uint32 pmqovfl; /* Number of PMQ overflows */ - uint32 rxcgprqfrm; /* Number of received Probe requests that made it into - * the PRQ fifo - */ - uint32 rxcgprsqovfl; /* Rx Probe Request Que overflow in the AP */ - uint32 txcgprsfail; /* Tx Probe Response Fail. AP sent probe response but did - * not get ACK - */ - uint32 txcgprssuc; /* Tx Probe Response Success (ACK was received) */ - uint32 prs_timeout; /* Number of probe requests that were dropped from the PRQ - * fifo because a probe response could not be sent out within - * the time limit defined in M_PRS_MAXTIME - */ - uint32 rxnack; /* Number of NACKS received (Afterburner) */ - uint32 frmscons; /* Number of frames completed without transmission because of an - * Afterburner re-queue - */ - uint32 txnack; /* Number of NACKs transmitted (Afterburner) */ - uint32 txglitch_nack; /* obsolete */ - uint32 txburst; /* obsolete */ - - /* 802.11 MIB counters, pp. 614 of 802.11 reaff doc. */ - uint32 txfrag; /* dot11TransmittedFragmentCount */ - uint32 txmulti; /* dot11MulticastTransmittedFrameCount */ - uint32 txfail; /* dot11FailedCount */ - uint32 txretry; /* dot11RetryCount */ - uint32 txretrie; /* dot11MultipleRetryCount */ - uint32 rxdup; /* dot11FrameduplicateCount */ - uint32 txrts; /* dot11RTSSuccessCount */ - uint32 txnocts; /* dot11RTSFailureCount */ - uint32 txnoack; /* dot11ACKFailureCount */ - uint32 rxfrag; /* dot11ReceivedFragmentCount */ - uint32 rxmulti; /* dot11MulticastReceivedFrameCount */ - uint32 rxcrc; /* dot11FCSErrorCount */ - uint32 txfrmsnt; /* dot11TransmittedFrameCount (bogus MIB?) */ - uint32 rxundec; /* dot11WEPUndecryptableCount */ - - /* WPA2 counters (see rxundec for DecryptFailureCount) */ - uint32 tkipmicfaill; /* TKIPLocalMICFailures */ - uint32 tkipcntrmsr; /* TKIPCounterMeasuresInvoked */ - uint32 tkipreplay; /* TKIPReplays */ - uint32 ccmpfmterr; /* CCMPFormatErrors */ - uint32 ccmpreplay; /* CCMPReplays */ - uint32 ccmpundec; /* CCMPDecryptErrors */ - uint32 fourwayfail; /* FourWayHandshakeFailures */ - uint32 wepundec; /* dot11WEPUndecryptableCount */ - uint32 wepicverr; /* dot11WEPICVErrorCount */ - uint32 decsuccess; /* DecryptSuccessCount */ - uint32 tkipicverr; /* TKIPICVErrorCount */ - uint32 wepexcluded; /* dot11WEPExcludedCount */ - - uint32 txchanrej; /* Tx frames suppressed due to channel rejection */ - uint32 psmwds; /* Count PSM watchdogs */ - uint32 phywatchdog; /* Count Phy lockups */ -} wl_cnt_t; - -#define WL_WME_CNT_VERSION 1 /* current version of wl_wme_cnt_t */ - -typedef struct { - uint32 packets; - uint32 bytes; -} wl_traffic_stats_t; - -typedef struct { - uint16 version; /* see definition of WL_CNT_T_VERSION */ - uint16 length; /* length of entire structure */ - - wl_traffic_stats_t tx[AC_COUNT]; /* Packets transmitted */ - wl_traffic_stats_t tx_failed[AC_COUNT]; /* Packets dropped or failed to transmit */ - wl_traffic_stats_t rx[AC_COUNT]; /* Packets received */ - wl_traffic_stats_t rx_failed[AC_COUNT]; /* Packets failed to receive */ - - wl_traffic_stats_t forward[AC_COUNT]; /* Packets forwarded by AP */ - - wl_traffic_stats_t tx_expired[AC_COUNT]; /* packets dropped due to lifetime expiry */ - -} wl_wme_cnt_t; - -#ifdef WLBA - -#define WLC_BA_CNT_VERSION 1 /* current version of wlc_ba_cnt_t */ - -/* block ack related stats */ -typedef struct wlc_ba_cnt { - uint16 version; /* WLC_BA_CNT_VERSION */ - uint16 length; /* length of entire structure */ - - /* transmit stat counters */ - uint32 txpdu; /* pdus sent */ - uint32 txsdu; /* sdus sent */ - uint32 txfc; /* tx side flow controlled packets */ - uint32 txfci; /* tx side flow control initiated */ - uint32 txretrans; /* retransmitted pdus */ - uint32 txbatimer; /* ba resend due to timer */ - uint32 txdrop; /* dropped packets */ - uint32 txaddbareq; /* addba req sent */ - uint32 txaddbaresp; /* addba resp sent */ - uint32 txdelba; /* delba sent */ - uint32 txba; /* ba sent */ - uint32 txbar; /* bar sent */ - uint32 txpad[4]; /* future */ - - /* receive side counters */ - uint32 rxpdu; /* pdus recd */ - uint32 rxqed; /* pdus buffered before sending up */ - uint32 rxdup; /* duplicate pdus */ - uint32 rxnobuf; /* pdus discarded due to no buf */ - uint32 rxaddbareq; /* addba req recd */ - uint32 rxaddbaresp; /* addba resp recd */ - uint32 rxdelba; /* delba recd */ - uint32 rxba; /* ba recd */ - uint32 rxbar; /* bar recd */ - uint32 rxinvba; /* invalid ba recd */ - uint32 rxbaholes; /* ba recd with holes */ - uint32 rxunexp; /* unexpected packets */ - uint32 rxpad[4]; /* future */ -} wlc_ba_cnt_t; -#endif /* WLBA */ - -/* structure for per-tid ampdu control */ -struct ampdu_tid_control { - uint8 tid; /* tid */ - uint8 enable; /* enable/disable */ -}; - -/* structure for addts arguments */ -/* For ioctls that take a list of TSPEC */ -struct tslist { - int count; /* number of tspecs */ - struct tsinfo_arg tsinfo[1]; /* variable length array of tsinfo */ -}; - -/* structure for addts/delts arguments */ -typedef struct tspec_arg { - uint16 version; /* see definition of TSPEC_ARG_VERSION */ - uint16 length; /* length of entire structure */ - uint flag; /* bit field */ - /* TSPEC Arguments */ - struct tsinfo_arg tsinfo; /* TS Info bit field */ - uint16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ - uint16 max_msdu_size; /* Maximum MSDU Size (bytes) */ - uint min_srv_interval; /* Minimum Service Interval (us) */ - uint max_srv_interval; /* Maximum Service Interval (us) */ - uint inactivity_interval; /* Inactivity Interval (us) */ - uint suspension_interval; /* Suspension Interval (us) */ - uint srv_start_time; /* Service Start Time (us) */ - uint min_data_rate; /* Minimum Data Rate (bps) */ - uint mean_data_rate; /* Mean Data Rate (bps) */ - uint peak_data_rate; /* Peak Data Rate (bps) */ - uint max_burst_size; /* Maximum Burst Size (bytes) */ - uint delay_bound; /* Delay Bound (us) */ - uint min_phy_rate; /* Minimum PHY Rate (bps) */ - uint16 surplus_bw; /* Surplus Bandwidth Allowance Factor */ - uint16 medium_time; /* Medium Time (32 us/s periods) */ -} tspec_arg_t; - -/* current version of wl_tspec_arg_t struct */ -#define TSPEC_ARG_VERSION 1 /* current version of wl_tspec_arg_t struct */ -#define TSPEC_ARG_LENGTH 55 /* argment length from tsinfo to medium_time */ - -/* define for flag */ -#define TSPEC_PENDING 0 /* TSPEC pending */ -#define TSPEC_ACCEPTED 1 /* TSPEC accepted */ -#define TSPEC_REJECTED 2 /* TSPEC rejected */ -#define TSPEC_UNKNOWN 3 /* TSPEC unknown */ -#define TSPEC_STATUS_MASK 7 /* TSPEC status mask */ - - -/* Software feature flag defines used by wlfeatureflag */ -#define WL_SWFL_ABBFL 0x0001 /* Allow Afterburner on systems w/o hardware BFL */ -#define WL_SWFL_ABENCORE 0x0002 /* Allow AB on non-4318E chips */ - -#define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */ - -/* Packet lifetime configuration per ac */ -typedef struct wl_lifetime { - uint32 ac; /* access class */ - uint32 lifetime; /* Packet lifetime value in ms */ -} wl_lifetime_t; - -#endif /* _wlioctl_h_ */ diff --git a/package/wlc/src/include/wlutils.h b/package/wlc/src/include/wlutils.h deleted file mode 100644 index a5aa1fd663..0000000000 --- a/package/wlc/src/include/wlutils.h +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Broadcom wireless network adapter utility functions - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * $Id: wlutils.h,v 1.1.1.12 2006/02/27 03:43:20 honor Exp $ - */ - -#ifndef _wlutils_h_ -#define _wlutils_h_ - -#include -#include - -/* - * Pass a wlioctl request to the specified interface. - * @param name interface name - * @param cmd WLC_GET_MAGIC <= cmd < WLC_LAST - * @param buf buffer for passing in and/or receiving data - * @param len length of buf - * @return >= 0 if successful or < 0 otherwise - */ -extern int wl_ioctl(char *name, int cmd, void *buf, int len); - -/* - * Probe the specified interface. - * @param name interface name - * @return >= 0 if a Broadcom wireless device or < 0 otherwise - */ -extern int wl_probe(char *name); - -extern int wl_iovar_set(char *ifname, char *iovar, void *param, int paramlen); -extern int wl_iovar_get(char *ifname, char *iovar, void *bufptr, int buflen); -/* - * Set/Get named variable. - * @param ifname interface name - * @param iovar variable name - * @param param input param value/buffer - * @param paramlen input param value/buffer length - * @param bufptr io buffer - * @param buflen io buffer length - * @param val val or val pointer for int routines - * @return success == 0, failure != 0 - */ -/* - * set named driver variable to int value - * calling example: wl_iovar_setint(ifname, "arate", rate) -*/ -static inline int -wl_iovar_setint(char *ifname, char *iovar, int val) -{ - return wl_iovar_set(ifname, iovar, &val, sizeof(val)); -} - -/* - * get named driver variable to int value and return error indication - * calling example: wl_iovar_getint(ifname, "arate", &rate) - */ -static inline int -wl_iovar_getint(char *ifname, char *iovar, int *val) -{ - return wl_iovar_get(ifname, iovar, val, sizeof(int)); -} - -/* - * Set/Get named variable indexed by BSS Configuration - * @param ifname interface name - * @param iovar variable name - * @param bssidx bsscfg index - * @param param input param value/buffer - * @param paramlen input param value/buffer length - * @param bufptr io buffer - * @param buflen io buffer length - * @param val val or val pointer for int routines - * @return success == 0, failure != 0 - */ -extern int wl_bssiovar_get(char *ifname, char *iovar, int bssidx, void *outbuf, int len); -extern int wl_bssiovar_set(char *ifname, char *iovar, int bssidx, void *param, int paramlen); -/* - * set named & bss indexed driver variable to int value - */ -static inline int -wl_bssiovar_setint(char *ifname, char *iovar, int bssidx, int val) -{ - return wl_bssiovar_set(ifname, iovar, bssidx, &val, sizeof(int)); -} - -static inline int -wl_bssiovar_getint(char *ifname, char *iovar, int bssidx, int *val) -{ - return wl_bssiovar_get(ifname, iovar, bssidx, val, sizeof(int)); -} - -extern int wl_bssiovar_setint(char *ifname, char *iovar, int bssidx, int val); - -#endif /* _wlutils_h_ */ diff --git a/package/wlc/src/ioctl.c b/package/wlc/src/ioctl.c deleted file mode 100644 index 6c676c7c9b..0000000000 --- a/package/wlc/src/ioctl.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * Wireless network adapter utilities - * - * Copyright 2006, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * - * $Id: wl.c,v 1.1.1.11 2006/02/27 03:43:20 honor Exp $ - */ -#include -#include -#include -#include -#include -#include -#include - -typedef u_int64_t u64; -typedef u_int32_t u32; -typedef u_int16_t u16; -typedef u_int8_t u8; -#include -#include - -#include -#include -#include -#include - -int -wl_ioctl(char *name, int cmd, void *buf, int len) -{ - struct ifreq ifr; - wl_ioctl_t ioc; - int ret = 0; - int s; - - /* open socket to kernel */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket"); - return errno; - } - - /* do it */ - ioc.cmd = cmd; - ioc.buf = buf; - ioc.len = len; - strncpy(ifr.ifr_name, name, IFNAMSIZ); - ifr.ifr_data = (caddr_t) &ioc; - if ((ret = ioctl(s, SIOCDEVPRIVATE, &ifr)) < 0) - - /* cleanup */ - close(s); - return ret; -} - -static inline int -wl_get_dev_type(char *name, void *buf, int len) -{ - int s; - int ret; - struct ifreq ifr; - struct ethtool_drvinfo info; - - /* open socket to kernel */ - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("socket"); - return -1; - } - - /* get device type */ - memset(&info, 0, sizeof(info)); - info.cmd = ETHTOOL_GDRVINFO; - ifr.ifr_data = (caddr_t)&info; - strncpy(ifr.ifr_name, name, IFNAMSIZ); - if ((ret = ioctl(s, SIOCETHTOOL, &ifr)) < 0) { - *(char *)buf = '\0'; - } else - strncpy(buf, info.driver, len); - - close(s); - return ret; -} - -int -wl_probe(char *name) -{ - int ret, val; - char buf[3]; - if ((ret = wl_get_dev_type(name, buf, 3)) < 0) - return ret; - /* Check interface */ - if (strncmp(buf, "wl", 2)) - return -1; - if ((ret = wl_ioctl(name, WLC_GET_VERSION, &val, sizeof(val)))) - return ret; - if (val > WLC_IOCTL_VERSION) - return -1; - - return ret; -} - -static int -wl_iovar_getbuf(char *ifname, char *iovar, void *param, int paramlen, void *bufptr, int buflen) -{ - int err; - uint namelen; - uint iolen; - - namelen = strlen(iovar) + 1; /* length of iovar name plus null */ - iolen = namelen + paramlen; - - /* check for overflow */ - if (iolen > buflen) - return (BCME_BUFTOOSHORT); - - memcpy(bufptr, iovar, namelen); /* copy iovar name including null */ - memcpy((int8*)bufptr + namelen, param, paramlen); - - err = wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen); - - return (err); -} - -static int -wl_iovar_setbuf(char *ifname, char *iovar, void *param, int paramlen, void *bufptr, int buflen) -{ - uint namelen; - uint iolen; - - namelen = strlen(iovar) + 1; /* length of iovar name plus null */ - iolen = namelen + paramlen; - - /* check for overflow */ - if (iolen > buflen) - return (BCME_BUFTOOSHORT); - - memcpy(bufptr, iovar, namelen); /* copy iovar name including null */ - memcpy((int8*)bufptr + namelen, param, paramlen); - - return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen); -} - -int -wl_iovar_set(char *ifname, char *iovar, void *param, int paramlen) -{ - char smbuf[WLC_IOCTL_SMLEN]; - - return wl_iovar_setbuf(ifname, iovar, param, paramlen, smbuf, sizeof(smbuf)); -} - -int -wl_iovar_get(char *ifname, char *iovar, void *bufptr, int buflen) -{ - char smbuf[WLC_IOCTL_SMLEN]; - int ret; - - /* use the return buffer if it is bigger than what we have on the stack */ - if (buflen > sizeof(smbuf)) { - ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, bufptr, buflen); - } else { - ret = wl_iovar_getbuf(ifname, iovar, NULL, 0, smbuf, sizeof(smbuf)); - if (ret == 0) - memcpy(bufptr, smbuf, buflen); - } - - return ret; -} - - -/* - * format a bsscfg indexed iovar buffer - */ -static int -wl_bssiovar_mkbuf(char *iovar, int bssidx, void *param, int paramlen, void *bufptr, int buflen, - int *plen) -{ - char *prefix = "bsscfg:"; - int8* p; - uint prefixlen; - uint namelen; - uint iolen; - - prefixlen = strlen(prefix); /* length of bsscfg prefix */ - namelen = strlen(iovar) + 1; /* length of iovar name + null */ - iolen = prefixlen + namelen + sizeof(int) + paramlen; - - /* check for overflow */ - if (buflen < 0 || iolen > (uint)buflen) { - *plen = 0; - return BCME_BUFTOOSHORT; - } - - p = (int8*)bufptr; - - /* copy prefix, no null */ - memcpy(p, prefix, prefixlen); - p += prefixlen; - - /* copy iovar name including null */ - memcpy(p, iovar, namelen); - p += namelen; - - /* bss config index as first param */ - memcpy(p, &bssidx, sizeof(int32)); - p += sizeof(int32); - - /* parameter buffer follows */ - if (paramlen) - memcpy(p, param, paramlen); - - *plen = iolen; - return 0; -} - -/* - * set named & bss indexed driver variable to buffer value - */ -static int -wl_bssiovar_setbuf(char *ifname, char *iovar, int bssidx, void *param, int paramlen, void *bufptr, - int buflen) -{ - int err; - int iolen; - - err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen); - if (err) - return err; - - return wl_ioctl(ifname, WLC_SET_VAR, bufptr, iolen); -} - -/* - * get named & bss indexed driver variable buffer value - */ -static int -wl_bssiovar_getbuf(char *ifname, char *iovar, int bssidx, void *param, int paramlen, void *bufptr, - int buflen) -{ - int err; - int iolen; - - err = wl_bssiovar_mkbuf(iovar, bssidx, param, paramlen, bufptr, buflen, &iolen); - if (err) - return err; - - return wl_ioctl(ifname, WLC_GET_VAR, bufptr, buflen); -} - -/* - * set named & bss indexed driver variable to buffer value - */ -int -wl_bssiovar_set(char *ifname, char *iovar, int bssidx, void *param, int paramlen) -{ - char smbuf[WLC_IOCTL_SMLEN]; - - return wl_bssiovar_setbuf(ifname, iovar, bssidx, param, paramlen, smbuf, sizeof(smbuf)); -} - -/* - * get named & bss indexed driver variable buffer value - */ -int -wl_bssiovar_get(char *ifname, char *iovar, int bssidx, void *outbuf, int len) -{ - char smbuf[WLC_IOCTL_SMLEN]; - int err; - - /* use the return buffer if it is bigger than what we have on the stack */ - if (len > (int)sizeof(smbuf)) { - err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, outbuf, len); - } else { - memset(smbuf, 0, sizeof(smbuf)); - err = wl_bssiovar_getbuf(ifname, iovar, bssidx, NULL, 0, smbuf, sizeof(smbuf)); - if (err == 0) - memcpy(outbuf, smbuf, len); - } - - return err; -} - -void -wl_printlasterror(char *name) -{ - char err_buf[WLC_IOCTL_SMLEN]; - strcpy(err_buf, "bcmerrstr"); - - fprintf(stderr, "Error: "); - if ( wl_ioctl(name, WLC_GET_VAR, err_buf, sizeof (err_buf)) != 0) - fprintf(stderr, "Error getting the Errorstring from driver\n"); - else - fprintf(stderr, err_buf); -} diff --git a/package/wlc/src/wlc.c b/package/wlc/src/wlc.c deleted file mode 100644 index 99237c095a..0000000000 --- a/package/wlc/src/wlc.c +++ /dev/null @@ -1,1138 +0,0 @@ -/* - * wlc - Broadcom Wireless Driver Control Utility - * - * Copyright (C) 2006 Felix Fietkau - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define VERSION "0.1" -#define BUFSIZE 8192 -#define PTABLE_MAGIC 0xbadc0ded -#define PTABLE_SLT1 1 -#define PTABLE_SLT2 2 -#define PTABLE_ACKW 3 -#define PTABLE_ADHM 4 -#define PTABLE_END 0xffffffff - -/* - * Copy each token in wordlist delimited by space into word - * Taken from Broadcom shutils.h - */ -#define foreach(word, wordlist, next) \ - for (next = &wordlist[strspn(wordlist, " ")], \ - strncpy(word, next, sizeof(word)), \ - word[strcspn(word, " ")] = '\0', \ - word[sizeof(word) - 1] = '\0', \ - next = strchr(next, ' '); \ - strlen(word); \ - next = next ? &next[strspn(next, " ")] : "", \ - strncpy(word, next, sizeof(word)), \ - word[strcspn(word, " ")] = '\0', \ - word[sizeof(word) - 1] = '\0', \ - next = strchr(next, ' ')) - -static char wlbuf[8192]; -static char interface[16] = "wl0"; -static unsigned long ptable[128]; -static unsigned long kmem_offset = 0; -static int vif = 0, debug = 1, fromstdin = 0; - -typedef enum { - NONE = 0x00, - - /* types */ - PARAM_TYPE = 0x00f, - INT = 0x001, - STRING = 0x002, - - /* options */ - PARAM_OPTIONS = 0x0f0, - NOARG = 0x010, - - /* modes */ - PARAM_MODE = 0xf00, - GET = 0x100, - SET = 0x200, -} wlc_param; - -struct wlc_call { - const char *name; - wlc_param param; - int (*handler)(wlc_param param, void *data, void *value); - union { - int num; - char *str; - void *ptr; - } data; - const char *desc; -}; - -/* can't use the system include because of the stupid broadcom header files */ -extern struct ether_addr *ether_aton(const char *asc); -extern char *ether_ntoa(const struct ether_addr *addr); - -/* - * find the starting point of wl.o in memory - * by reading /proc/ksyms - */ -static inline void wlc_get_mem_offset(void) -{ - FILE *f; - char s[64]; - - /* yes, i'm lazy ;) */ - f = popen("grep '\\[wl]' /proc/ksyms | sort", "r"); - if (fgets(s, 64, f) == 0) - return; - - pclose(f); - - s[8] = 0; - kmem_offset = strtoul(s, NULL, 16); - - /* sanity check */ - if (kmem_offset < 0xc0000000) - kmem_offset = 0; -} - - -static int ptable_init(void) -{ - glob_t globbuf; - struct stat statbuf; - int fd; - - if (ptable[0] == PTABLE_MAGIC) - return 0; - - glob("/lib/modules/2.4.*/wl.o", 0, NULL, &globbuf); - - if (globbuf.gl_pathv[0] == NULL) - return -1; - - if ((fd = open(globbuf.gl_pathv[0], O_RDONLY)) < 0) - return -1; - - if (fstat(fd, &statbuf) < 0) - goto failed; - - if (statbuf.st_size <= 512) - goto failed; - - if (lseek(fd, statbuf.st_size - 512, SEEK_SET) < 0) { - perror("lseek"); - goto failed; - } - - if (read(fd, ptable, 512) < 512) - goto failed; - - if (ptable[0] != PTABLE_MAGIC) - goto failed; - - close(fd); - - wlc_get_mem_offset(); - if (kmem_offset == 0) - return -1; - - return 0; - -failed: - close(fd); - - return -1; -} - -static inline unsigned long wlc_kmem_read(unsigned long offset) -{ - int fd; - unsigned long ret; - - if ((fd = open("/dev/kmem", O_RDONLY )) < 0) - return -1; - - lseek(fd, 0x70000000, SEEK_SET); - lseek(fd, (kmem_offset - 0x70000000) + offset, SEEK_CUR); - read(fd, &ret, 4); - close(fd); - - return ret; -} - -static inline void wlc_kmem_write(unsigned long offset, unsigned long value) -{ - int fd; - - if ((fd = open("/dev/kmem", O_WRONLY )) < 0) - return; - - lseek(fd, 0x70000000, SEEK_SET); - lseek(fd, (kmem_offset - 0x70000000) + offset, SEEK_CUR); - write(fd, &value, 4); - close(fd); -} - -static int wlc_patcher_getval(unsigned long key, unsigned long *val) -{ - unsigned long *pt = &ptable[1]; - unsigned long tmp; - - if (ptable_init() < 0) { - fprintf(stderr, "Could not load the ptable\n"); - return -1; - } - - while (*pt != PTABLE_END) { - if (*pt == key) { - tmp = wlc_kmem_read(pt[1]); - - if (tmp == pt[2]) - *val = 0xffffffff; - else - *val = tmp; - - return 0; - } - pt += 3; - } - - return -1; -} - -static int wlc_patcher_setval(unsigned long key, unsigned long val) -{ - unsigned long *pt = &ptable[1]; - - if (ptable_init() < 0) { - fprintf(stderr, "Could not load the ptable\n"); - return -1; - } - - if (val != 0xffffffff) - val = (pt[2] & ~(0xffff)) | (val & 0xffff); - - while (*pt != PTABLE_END) { - if (*pt == key) { - if (val == 0xffffffff) /* default */ - val = pt[2]; - - wlc_kmem_write(pt[1], val); - } - pt += 3; - } - - return 0; -} - -static int wlc_slottime(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - int ret = 0; - - if ((param & PARAM_MODE) == SET) { - wlc_patcher_setval(PTABLE_SLT1, *val); - wlc_patcher_setval(PTABLE_SLT2, ((*val == -1) ? *val : *val + 510)); - } else if ((param & PARAM_MODE) == GET) { - ret = wlc_patcher_getval(PTABLE_SLT1, (unsigned long *) val); - if (*val != 0xffffffff) - *val &= 0xffff; - } - - return ret; -} - -static int wlc_noack(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - int ret = 0; - - if ((param & PARAM_MODE) == SET) { - wlc_patcher_setval(PTABLE_ACKW, ((*val) ? 1 : 0)); - } else if ((param & PARAM_MODE) == GET) { - ret = wlc_patcher_getval(PTABLE_ACKW, (unsigned long *) val); - *val &= 0xffff; - *val = (*val ? 1 : 0); - } - - return ret; -} - -static int wlc_ibss_merge(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - int ret = 0; - - if ((param & PARAM_MODE) == SET) { - /* overwrite the instruction with 'lui v0,0x0' - fake a return - * status of 0 for wlc_bcn_tsf_later */ - wlc_patcher_setval(PTABLE_ACKW, ((*val) ? -1 : 0x3c020000)); - } else if ((param & PARAM_MODE) == GET) { - ret = wlc_patcher_getval(PTABLE_ACKW, (unsigned long *) val); - *val = ((*val == -1) ? 1 : 0); - } - - return ret; -} - -static int wlc_ioctl(wlc_param param, void *data, void *value) -{ - unsigned int *var = ((unsigned int *) data); - unsigned int ioc = *var; - - if (param & NOARG) { - return wl_ioctl(interface, ioc, NULL, 0); - } - switch(param & PARAM_TYPE) { - case INT: - return wl_ioctl(interface, ((param & SET) ? (ioc) : (ioc >> 16)) & 0xffff, value, sizeof(int)); - case STRING: - return wl_ioctl(interface, ((param & SET) ? (ioc) : (ioc >> 16)) & 0xffff, value, BUFSIZE); - } - return 0; -} - -static int wlc_iovar(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - char *iov = *((char **) data); - int ret = 0; - - if (param & SET) { - switch(param & PARAM_TYPE) { - case INT: - ret = wl_iovar_setint(interface, iov, *val); - } - } - if (param & GET) { - switch(param & PARAM_TYPE) { - case INT: - ret = wl_iovar_getint(interface, iov, val); - } - } - - return ret; -} - -static int wlc_bssiovar(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - char *iov = *((char **) data); - int ret = 0; - - if (param & SET) { - switch(param & PARAM_TYPE) { - case INT: - ret = wl_bssiovar_setint(interface, iov, vif, *val); - } - } - if (param & GET) { - switch(param & PARAM_TYPE) { - case INT: - ret = wl_bssiovar_getint(interface, iov, vif, val); - } - } - - return ret; -} - -static int wlc_vif_enabled(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - int buf[3]; - int ret = 0; - - sprintf((char *) buf, "bss"); - buf[1] = vif; - if (param & SET) { - buf[2] = (*val ? 1 : 0); - ret = wl_ioctl(interface, WLC_SET_VAR, buf, sizeof(buf)); - } else if (param & GET) { - ret = wl_ioctl(interface, WLC_GET_VAR, buf, sizeof(buf)); - *val = buf[0]; - } - - return ret; -} - -static int wlc_ssid(wlc_param param, void *data, void *value) -{ - int ret = -1, ret2 = -1; - char *dest = (char *) value; - wlc_ssid_t ssid; - - if ((param & PARAM_MODE) == GET) { - ret = wl_bssiovar_get(interface, "ssid", vif, &ssid, sizeof(ssid)); - - if (ret) - /* if we can't get the ssid through the bssiovar, try WLC_GET_SSID */ - ret = wl_ioctl(interface, WLC_GET_SSID, &ssid, sizeof(ssid)); - - if (!ret) { - memcpy(dest, ssid.SSID, ssid.SSID_len); - dest[ssid.SSID_len] = 0; - } - } else if ((param & PARAM_MODE) == SET) { - strncpy(ssid.SSID, value, 32); - ssid.SSID_len = strlen(value); - - if (ssid.SSID_len > 32) - ssid.SSID_len = 32; - - if (vif == 0) { - /* for the main interface, also try the WLC_SET_SSID call */ - ret2 = wl_ioctl(interface, WLC_SET_SSID, &ssid, sizeof(ssid)); - } - - ret = wl_bssiovar_set(interface, "ssid", vif, &ssid, sizeof(ssid)); - ret = (!ret2 ? 0 : ret); - } - - return ret; -} - -static int wlc_int(wlc_param param, void *data, void *value) -{ - int *var = *((int **) data); - int *val = (int *) value; - - if ((param & PARAM_MODE) == SET) { - *var = *val; - } else if ((param & PARAM_MODE) == GET) { - *val = *var; - } - - return 0; -} - -static int wlc_flag(wlc_param param, void *data, void *value) -{ - int *var = *((int **) data); - - *var = 1; - - return 0; -} - -static int wlc_string(wlc_param param, void *data, void *value) -{ - char *var = *((char **) data); - - if ((param & PARAM_MODE) == GET) { - strcpy(value, var); - } - - return 0; -} - -static int wlc_afterburner(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - int ret = 0; - - if ((param & PARAM_MODE) == GET) { - ret = wl_iovar_getint(interface, "afterburner", val); - } else { - wl_iovar_setint(interface, "wlfeatureflag", (*val ? 3 : 0)); - ret = wl_iovar_setint(interface, "afterburner", (*val ? 1 : 0)); - wl_iovar_setint(interface, "afterburner_override", *val); - } - - return ret; -} - -static int wlc_maclist(wlc_param param, void *data, void *value) -{ - unsigned int *var = ((unsigned int *) data); - unsigned int ioc = *var; - int limit = (sizeof(wlbuf) - 4) / sizeof(struct ether_addr); - struct maclist *list = (struct maclist *) wlbuf; - char *str = (char *) value; - char astr[30], *p; - struct ether_addr *addr; - int isset = 0; - int ret; - - if ((param & PARAM_MODE) == GET) { - list->count = limit; - ret = wl_ioctl(interface, (ioc >> 16) & 0xffff, wlbuf, sizeof(wlbuf)); - - if (!ret) - while (list->count) - str += sprintf(str, "%s%s", ((((char *) value) == str) ? "" : " "), ether_ntoa(&list->ea[list->count-- - 1])); - - return ret; - } else { - while (*str && isspace(*str)) - *str++; - - if (*str == '+') { - str++; - - list->count = limit; - if (wl_ioctl(interface, (ioc >> 16) & 0xffff, wlbuf, sizeof(wlbuf)) == 0) - isset = 1; - - while (*str && isspace(*str)) - str++; - } - - if (!isset) - memset(wlbuf, 0, sizeof(wlbuf)); - - foreach(astr, str, p) { - if (list->count >= limit) - break; - - if ((addr = ether_aton(astr)) != NULL) - memcpy(&list->ea[list->count++], addr, sizeof(struct ether_addr)); - } - - return wl_ioctl(interface, ioc & 0xffff, wlbuf, sizeof(wlbuf)); - } -} - -static int wlc_radio(wlc_param param, void *data, void *value) -{ - int *val = (int *) value; - int ret; - - if ((param & PARAM_MODE) == GET) { - ret = wl_ioctl(interface, WLC_GET_RADIO, val, sizeof(int)); - *val = ((*val & 1) ? 0 : 1); - } else { - *val = (1 << 16) | (*val ? 0 : 1); - ret = wl_ioctl(interface, WLC_SET_RADIO, val, sizeof(int)); - } - - return ret; -} - -static int wlc_wsec_key(wlc_param param, void *null, void *value) -{ - wl_wsec_key_t wsec_key; - unsigned char *index = value; - unsigned char *key; - unsigned char *data; - unsigned char hex[3]; - - if ((param & PARAM_MODE) != SET) - return 0; - - memset(&wsec_key, 0, sizeof(wsec_key)); - if (index[0] == '=') { - wsec_key.flags = WL_PRIMARY_KEY; - index++; - } - - if ((index[0] < '1') || (index[0] > '4') || (index[1] != ',')) - return -1; - - key = index + 2; - if (strncmp(key, "d:", 2) == 0) { /* delete key */ - } else if (strncmp(key, "s:", 2) == 0) { /* ascii key */ - key += 2; - wsec_key.len = strlen(key); - - if ((wsec_key.len != 5) && (wsec_key.len != 13)) - return -1; - - strcpy(wsec_key.data, key); - } else { /* hex key */ - wsec_key.len = strlen(key); - if ((wsec_key.len != 10) && (wsec_key.len != 26)) - return -1; - - wsec_key.len /= 2; - data = wsec_key.data; - hex[2] = 0; - do { - hex[0] = *(key++); - hex[1] = *(key++); - *(data++) = (unsigned char) strtoul(hex, NULL, 16); - } while (*key != 0); - } - - return wl_bssiovar_set(interface, "wsec_key", vif, &wsec_key, sizeof(wsec_key)); -} - -static inline int cw2ecw(int cw) -{ - int i; - for (cw++, i = 0; cw; i++) cw >>=1; - return i - 1; -} - -static int wlc_wme_ac(wlc_param param, void *data, void *value) -{ - char *type = *((char **) data); - char *settings = (char *) value; - char cmd[100], *p, *val; - edcf_acparam_t params[AC_COUNT]; - int ret; - int intval; - int cur = -1; - char *buf = wlbuf; - - if ((param & PARAM_MODE) != SET) - return -1; - - memset(params, 0, sizeof(params)); - ret = wl_iovar_get(interface, type, params, sizeof(params)); - memset(buf, 0, BUFSIZE); - strcpy(buf, type); - buf += strlen(buf) + 1; - - foreach(cmd, settings, p) { - val = strchr(cmd, '='); - if (val == NULL) { - if (strcmp(cmd, "be") == 0) - cur = AC_BE; - else if (strcmp(cmd, "bk") == 0) - cur = AC_BK; - else if (strcmp(cmd, "vi") == 0) - cur = AC_VI; - else if (strcmp(cmd, "vo") == 0) - cur = AC_VO; - else - return -1; - - /* just in case */ - params[cur].ACI = (params[cur].ACI & (0x3 << 5)) | (cur << 5); - } else { - *(val++) = 0; - - intval = strtoul(val, NULL, 10); - if (strcmp(cmd, "cwmin") == 0) - params[cur].ECW = (params[cur].ECW & ~(0xf)) | cw2ecw(intval); - else if (strcmp(cmd, "ecwmin") == 0) - params[cur].ECW = (params[cur].ECW & ~(0xf)) | (intval & 0xf); - else if (strcmp(cmd, "cwmax") == 0) - params[cur].ECW = (params[cur].ECW & ~(0xf << 4)) | (cw2ecw(intval) << 4); - else if (strcmp(cmd, "ecwmax") == 0) - params[cur].ECW = (params[cur].ECW & ~(0xf << 4)) | ((intval & 0xf) << 4); - else if (strcmp(cmd, "aifsn") == 0) - params[cur].ACI = (params[cur].ACI & ~(0xf)) | (intval & 0xf); - else if (strcmp(cmd, "txop") == 0) - params[cur].TXOP = intval >> 5; - else if (strcmp(cmd, "force") == 0) - params[cur].ACI = (params[cur].ACI & ~(1 << 4)) | ((intval) ? (1 << 4) : 0); - else return -1; - - memcpy(buf, ¶ms[cur], sizeof(edcf_acparam_t)); - wl_ioctl(interface, WLC_SET_VAR, wlbuf, BUFSIZE); - } - } - return ret; -} - -static const struct wlc_call wlc_calls[] = { - { - .name = "version", - .param = STRING|NOARG, - .handler = wlc_string, - .data.str = VERSION, - .desc = "Version of this program" - }, - { - .name = "debug", - .param = INT, - .handler = wlc_int, - .data.ptr = &debug, - .desc = "wlc debug level" - }, - { - .name = "stdin", - .param = NOARG, - .handler = wlc_flag, - .data.ptr = &fromstdin, - .desc = "Accept input from stdin" - }, - { - .name = "up", - .param = NOARG, - .handler = wlc_ioctl, - .data.num = WLC_UP, - .desc = "Bring the interface up" - }, - { - .name = "down", - .param = NOARG, - .handler = wlc_ioctl, - .data.num = WLC_DOWN, - .desc = "Bring the interface down" - }, - { - .name = "radio", - .param = INT, - .handler = wlc_radio, - .desc = "Radio enabled flag" - }, - { - .name = "ap", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_AP << 16) | WLC_SET_AP), - .desc = "Access Point mode" - }, - { - .name = "mssid", - .param = INT, - .handler = wlc_iovar, - .data.str = "mssid", - .desc = "Multi-ssid mode" - }, - { - .name = "apsta", - .param = INT, - .handler = wlc_iovar, - .data.str = "apsta", - .desc = "AP+STA mode" - }, - { - .name = "infra", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_INFRA << 16) | WLC_SET_INFRA), - .desc = "Infrastructure mode" - }, - { - .name = "wet", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_WET << 16) | WLC_SET_WET), - .desc = "Wireless repeater mode", - }, - { - .name = "statimeout", - .param = INT, - .handler = wlc_iovar, - .data.str = "sta_retry_time", - .desc = "STA connection timeout" - }, - { - .name = "country", - .param = STRING, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_COUNTRY << 16) | WLC_SET_COUNTRY), - .desc = "Country code" - }, - { - .name = "channel", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_CHANNEL << 16) | WLC_SET_CHANNEL), - .desc = "Channel", - }, - { - .name = "vif", - .param = INT, - .handler = wlc_int, - .data.ptr = &vif, - .desc = "Current vif index" - }, - { - .name = "enabled", - .param = INT, - .handler = wlc_vif_enabled, - .desc = "vif enabled flag" - }, - { - .name = "ssid", - .param = STRING, - .handler = wlc_ssid, - .desc = "Interface ESSID" - }, - { - .name = "closed", - .param = INT, - .handler = wlc_bssiovar, - .data.str = "closednet", - .desc = "Hidden ESSID flag" - }, - { - .name = "wsec", - .param = INT, - .handler = wlc_bssiovar, - .data.str = "wsec", - .desc = "Security mode flags" - }, - { - .name = "wepkey", - .param = STRING, - .handler = wlc_wsec_key, - .desc = "Set/Remove WEP keys" - }, - { - .name = "wsec_restrict", - .param = INT, - .handler = wlc_bssiovar, - .data.str = "wsec_restrict", - .desc = "Drop unencrypted traffic" - }, - { - .name = "eap_restrict", - .param = INT, - .handler = wlc_bssiovar, - .data.str = "eap_restrict", - .desc = "Only allow 802.1X traffic until 802.1X authorized" - }, - { - .name = "wpa_auth", - .param = INT, - .handler = wlc_bssiovar, - .data.str = "wpa_auth", - .desc = "WPA authentication modes" - }, - { - .name = "ap_isolate", - .param = INT, - .handler = wlc_bssiovar, - .data.str = "ap_isolate", - .desc = "Isolate connected clients" - }, - { - .name = "supplicant", - .param = INT, - .handler = wlc_iovar, - .data.str = "sup_wpa", - .desc = "Built-in WPA supplicant" - }, - { - .name = "maxassoc", - .param = INT, - .handler = wlc_iovar, - .data.str = "maxassoc", - .desc = "Max. number of associated clients", - }, - { - .name = "wme", - .param = INT, - .handler = wlc_iovar, - .data.str = "wme", - .desc = "WME enabled" - }, - { - .name = "wme_ac_ap", - .param = STRING, - .handler = wlc_wme_ac, - .data.str = "wme_ac_ap", - .desc = "Set WME AC options for AP mode", - }, - { - .name = "wme_ac_sta", - .param = STRING, - .handler = wlc_wme_ac, - .data.str = "wme_ac_sta", - .desc = "Set WME AC options for STA mode", - }, - { - .name = "wme_noack", - .param = INT, - .handler = wlc_iovar, - .data.str = "wme_noack", - .desc = "WME ACK disable request", - }, - { - .name = "fragthresh", - .param = INT, - .handler = wlc_iovar, - .data.str = "fragthresh", - .desc = "Fragmentation threshold", - }, - { - .name = "rtsthresh", - .param = INT, - .handler = wlc_iovar, - .data.str = "rtsthresh", - .desc = "RTS threshold" - }, - { - .name = "rxant", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_ANTDIV << 16) | WLC_SET_ANTDIV), - .desc = "Rx antenna selection" - }, - { - .name = "txant", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_TXANT << 16) | WLC_SET_TXANT), - .desc = "Tx antenna selection" - }, - { - .name = "dtim", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_DTIMPRD << 16) | WLC_SET_DTIMPRD), - .desc = "DTIM period", - }, - { - .name = "bcn", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_BCNPRD << 16) | WLC_SET_BCNPRD), - .desc = "Beacon interval" - }, - { - .name = "frameburst", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_FAKEFRAG << 16) | WLC_SET_FAKEFRAG), - .desc = "Framebursting" - }, - { - .name = "monitor", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_MONITOR << 16) | WLC_SET_MONITOR), - .desc = "Monitor mode" - }, - { - .name = "passive", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_PASSIVE << 16) | WLC_SET_PASSIVE), - .desc = "Passive mode" - }, - { - .name = "macfilter", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_MACMODE << 16) | WLC_SET_MACMODE), - .desc = "MAC filter mode (0:disabled, 1:deny, 2:allow)" - }, - { - .name = "maclist", - .param = STRING, - .data.num = ((WLC_GET_MACLIST << 16) | WLC_SET_MACLIST), - .handler = wlc_maclist, - .desc = "MAC filter list" - }, - { - .name = "autowds", - .param = INT, - .handler = wlc_ioctl, - .data.num = ((WLC_GET_LAZYWDS << 16) | WLC_SET_LAZYWDS), - .desc = "Automatic WDS" - }, - { - .name = "wds", - .param = STRING, - .data.num = ((WLC_GET_WDSLIST << 16) | WLC_SET_WDSLIST), - .handler = wlc_maclist, - .desc = "WDS connection list" - }, - { - .name = "wdstimeout", - .param = INT, - .handler = wlc_iovar, - .data.str = "wdstimeout", - .desc = "WDS link detection timeout" - }, - { - .name = "afterburner", - .param = INT, - .handler = wlc_afterburner, - .desc = "Broadcom Afterburner" - }, - { - .name = "slottime", - .param = INT, - .handler = wlc_slottime, - .desc = "Slot time (-1 = auto)" - }, - { - .name = "txack", - .param = INT, - .handler = wlc_noack, - .desc = "Tx ACK enabled flag" - }, - { - .name = "ibss_merge", - .param = INT, - .handler = wlc_ibss_merge, - .desc = "Allow IBSS merge in Ad-Hoc mode" - } -}; -#define wlc_calls_size (sizeof(wlc_calls) / sizeof(struct wlc_call)) - -static void usage(char *cmd) -{ - int i; - fprintf(stderr, "Usage: %s [ ...]\n" - "\n" - "Available commands:\n", cmd); - for (i = 0; i < wlc_calls_size; i++) { - fprintf(stderr, "\t%-16s\t%s\n", wlc_calls[i].name ?: "", wlc_calls[i].desc ?: ""); - } - fprintf(stderr, "\n"); - exit(1); -} - -static int do_command(const struct wlc_call *cmd, char *arg) -{ - static char buf[BUFSIZE]; - int set; - int ret = 0; - char *format, *end; - int intval; - - if (debug >= 10) { - fprintf(stderr, "do_command %-16s\t'%s'\n", cmd->name, arg); - } - - if ((arg == NULL) && ((cmd->param & PARAM_TYPE) != NONE)) { - set = 0; - ret = cmd->handler(cmd->param | GET, (void *) &cmd->data, (void *) buf); - if (ret == 0) { - switch(cmd->param & PARAM_TYPE) { - case INT: - intval = *((int *) buf); - - if (intval > 65535) - format = "0x%08x\n"; - else if (intval > 255) - format = "0x%04x\n"; - else - format = "%d\n"; - - fprintf(stdout, format, intval); - break; - case STRING: - fprintf(stdout, "%s\n", buf); - } - } - } else { /* SET */ - set = 1; - switch(cmd->param & PARAM_TYPE) { - case INT: - intval = strtoul(arg, &end, 10); - if (end && !(*end)) { - memcpy(buf, &intval, sizeof(intval)); - } else { - fprintf(stderr, "%s: Invalid argument\n", cmd->name); - return -1; - } - break; - case STRING: - strncpy(buf, arg, BUFSIZE); - buf[BUFSIZE - 1] = 0; - } - - ret = cmd->handler(cmd->param | SET, (void *) &cmd->data, (void *) buf); - } - - if ((debug > 0) && (ret != 0)) - fprintf(stderr, "Command '%s %s' failed: %d\n", (set == 1 ? "set" : "get"), cmd->name, ret); - - return ret; -} - -static struct wlc_call *find_cmd(char *name) -{ - int found = 0, i = 0; - - while (!found && (i < wlc_calls_size)) { - if (strcmp(name, wlc_calls[i].name) == 0) - found = 1; - else - i++; - } - - return (struct wlc_call *) (found ? &wlc_calls[i] : NULL); -} - -int main(int argc, char **argv) -{ - static char buf[BUFSIZE]; - char *s, *s2; - char *cmd = argv[0]; - struct wlc_call *call; - int ret = 0; - - if (argc < 2) - usage(argv[0]); - - for(interface[2] = '0'; (interface[2] < '3') && (wl_probe(interface) != 0); interface[2]++); - if (interface[2] == '3') { - fprintf(stderr, "No Broadcom wl interface found!\n"); - return -1; - } - - argv++; - argc--; - while ((argc > 0) && (argv[0] != NULL)) { - if ((call = find_cmd(argv[0])) == NULL) { - fprintf(stderr, "Invalid command: %s\n\n", argv[0]); - usage(cmd); - } - if ((argc > 1) && (!(call->param & NOARG))) { - ret = do_command(call, argv[1]); - argv += 2; - argc -= 2; - } else { - ret = do_command(call, NULL); - argv++; - argc--; - } - } - - while (fromstdin && !feof(stdin)) { - *buf = 0; - fgets(buf, BUFSIZE - 1, stdin); - - if (*buf == 0) - continue; - - if ((s = strchr(buf, '\r')) != NULL) - *s = 0; - if ((s = strchr(buf, '\n')) != NULL) - *s = 0; - - s = buf; - while (isspace(*s)) - s++; - - if (!*s) - continue; - - if ((s2 = strchr(buf, ' ')) != NULL) - *(s2++) = 0; - - while (s2 && isspace(*s2)) - s2++; - - if ((call = find_cmd(buf)) == NULL) { - fprintf(stderr, "Invalid command: %s\n", buf); - ret = -1; - } else - ret = do_command(call, ((call->param & NOARG) ? NULL : s2)); - } - - return ret; -} diff --git a/target/linux/brcm-2.4/Config.in b/target/linux/brcm-2.4/Config.in deleted file mode 100644 index c766a45c3d..0000000000 --- a/target/linux/brcm-2.4/Config.in +++ /dev/null @@ -1,8 +0,0 @@ -config PACKAGE_KMOD_BRCM_WL - prompt "kmod-brcm-wl...................... Broadcom Wireless Network Driver" - tristate - depends LINUX_2_4_BRCM - default y - help - Proprietary driver for Broadcom Wireless chipsets - diff --git a/target/linux/brcm-2.4/Makefile b/target/linux/brcm-2.4/Makefile index 384a1ea918..022f3352c5 100644 --- a/target/linux/brcm-2.4/Makefile +++ b/target/linux/brcm-2.4/Makefile @@ -8,10 +8,6 @@ include ../rules.mk include ./config # broadcom specific kmod packages -$(eval $(call KMOD_template,BRCM_WL,brcm-wl,\ - $(MODULES_DIR)/kernel/drivers/net/wl/wl.o \ -,CONFIG_WL,,20,wl)) - $(eval $(call KMOD_template,LP,lp,\ $(MODULES_DIR)/kernel/drivers/parport/parport.o \ $(MODULES_DIR)/kernel/drivers/parport/parport_splink.o \ @@ -29,38 +25,3 @@ $(LINUX_DIR)/.patched: $(LINUX_DIR)/.unpacked @$(CP) config $(LINUX_DIR)/.config touch $@ - -############################################### -# Proprietary driver for BCM43xx -############################################### - -LINUX_BINARY_DRIVER_SITE=http://downloads.openwrt.org/sources -# proprietary driver, extracted from Linksys GPL sourcetree WRT54GS 4.70.6 -LINUX_BINARY_WL_DRIVER=kernel-binary-wl-0.7.tar.gz -LINUX_BINARY_WL_MD5SUM=ff50130914790cbae9b73a13513da5ee - -$(DL_DIR)/$(LINUX_BINARY_WL_DRIVER): - $(SCRIPT_DIR)/download.pl $(DL_DIR) $(LINUX_BINARY_WL_DRIVER) $(LINUX_BINARY_WL_MD5SUM) $(LINUX_BINARY_DRIVER_SITE) - -$(LINUX_DIR)/.unpacked: $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER) -$(LINUX_DIR)/.depend_done: $(LINUX_DIR)/.drivers-unpacked -$(LINUX_DIR)/.modules_done: $(LINUX_DIR)/.drivers-unpacked -$(STAMP_DIR)/.linux-compile: $(LINUX_DIR)/.drivers-installed - -$(LINUX_DIR)/.drivers-unpacked: $(LINUX_DIR)/.unpacked - -mkdir -p $(BUILD_DIR) - zcat $(DL_DIR)/$(LINUX_BINARY_WL_DRIVER) | tar -C $(BUILD_DIR) $(TAR_OPTIONS) - - # copy binary wlan driver - mkdir -p $(LINUX_DIR)/drivers/net/wl - $(CP) $(BUILD_DIR)/kernel-binary-wl/*.o $(LINUX_DIR)/drivers/net/wl - touch $@ - -$(LINUX_DIR)/.drivers-installed: $(LINUX_DIR)/.modules_done - mkdir -p $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl - @-[ -f $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/wl.o ] || $(CP) $(LINUX_DIR)/drivers/net/wl/wl.o $(LINUX_BUILD_DIR)/modules/lib/modules/2.4.32/kernel/drivers/net/wl/ - touch $@ - -linux-dirclean: drivers-clean - -drivers-clean: FORCE - rm -rf $(BUILD_DIR)/kernel-binary-wl diff --git a/target/linux/brcm-2.4/config b/target/linux/brcm-2.4/config index c4cf5340ea..7185e9f399 100644 --- a/target/linux/brcm-2.4/config +++ b/target/linux/brcm-2.4/config @@ -91,7 +91,6 @@ CONFIG_PCI=y CONFIG_NONCOHERENT_IO=y CONFIG_NEW_TIME_C=y CONFIG_NEW_IRQ=y -CONFIG_HND=y # CONFIG_MIPS_AU1000 is not set # @@ -726,7 +725,6 @@ CONFIG_SCSI_MULTI_LUN=y # Network device support # CONFIG_NETDEVICES=y -CONFIG_HND=y # # ARCnet devices @@ -832,7 +830,6 @@ CONFIG_NET_RADIO=y # CONFIG_AIRONET4500_PROC is not set # CONFIG_AIRO is not set # CONFIG_HERMES is not set -CONFIG_WL=m # CONFIG_PLX_HERMES is not set # CONFIG_TMD_HERMES is not set # CONFIG_PCI_HERMES is not set diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch index e1bd00bae2..dc0805e599 100644 --- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch +++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -15886,7 +15886,7 @@ diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared # Select some configuration options automatically based on user selections. # if [ "$CONFIG_ACER_PICA_61" = "y" ]; then -@@ -554,6 +567,13 @@ +@@ -554,6 +567,12 @@ define_bool CONFIG_SWAP_IO_SPACE_L y define_bool CONFIG_BOOT_ELF32 y fi @@ -15895,7 +15895,6 @@ diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared + define_bool CONFIG_NONCOHERENT_IO y + define_bool CONFIG_NEW_TIME_C y + define_bool CONFIG_NEW_IRQ y -+ define_bool CONFIG_HND y +fi if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then define_bool CONFIG_ARC32 y @@ -16265,18 +16264,6 @@ diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c cval = cflag & (CSIZE | CSTOPB); #if defined(__powerpc__) || defined(__alpha__) cval >>= 8; -diff -urN linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in ---- linux.old/drivers/net/Config.in 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/drivers/net/Config.in 2006-04-27 19:24:19.000000000 +0200 -@@ -2,6 +2,8 @@ - # Network device configuration - # - -+tristate 'Broadcom Home Network Division' CONFIG_HND $CONFIG_PCI -+ - source drivers/net/arcnet/Config.in - - tristate 'Dummy net driver support' CONFIG_DUMMY diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile --- linux.old/drivers/net/Makefile 2006-04-27 18:04:38.000000000 +0200 +++ linux.dev/drivers/net/Makefile 2006-05-04 01:41:03.000000000 +0200 @@ -16289,3243 +16276,6 @@ diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile obj-y := obj-m := obj-n := -@@ -39,6 +41,7 @@ - obj-$(CONFIG_ISDN) += slhc.o - endif - -+subdir-$(CONFIG_WL) += wl - subdir-$(CONFIG_NET_PCMCIA) += pcmcia - subdir-$(CONFIG_NET_WIRELESS) += wireless - subdir-$(CONFIG_TULIP) += tulip -diff -urN linux.old/drivers/net/wireless/Config.in linux.dev/drivers/net/wireless/Config.in ---- linux.old/drivers/net/wireless/Config.in 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/drivers/net/wireless/Config.in 2006-05-04 01:42:48.000000000 +0200 -@@ -13,6 +13,7 @@ - fi - - if [ "$CONFIG_PCI" = "y" ]; then -+ dep_tristate ' Proprietary Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL - dep_tristate ' Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)' CONFIG_PLX_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL - dep_tristate ' Hermes in TMD7160/NCP130 based PCI adaptor support (Pheecom WL-PCI etc.) (EXPERIMENTAL)' CONFIG_TMD_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL - dep_tristate ' Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)' CONFIG_PCI_HERMES $CONFIG_HERMES $CONFIG_EXPERIMENTAL -diff -urN linux.old/drivers/net/wl/patchtable.pl linux.dev/drivers/net/wl/patchtable.pl ---- linux.old/drivers/net/wl/patchtable.pl 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/patchtable.pl 2006-04-28 01:33:52.000000000 +0200 -@@ -0,0 +1,54 @@ -+#!/usr/bin/perl -+use strict; -+ -+my $TABLE = pack("V", 0xbadc0ded); -+my $TABLE_SIZE = 512; -+my $SLT1 = "\x01\x00\x00\x00"; -+my $SLT2 = "\x02\x00\x00\x00"; -+my $ACKW = "\x03\x00\x00\x00"; -+my $PTABLE_END = "\xff\xff\xff\xff"; -+ -+my $addr = ""; -+my $opcode = ""; -+my $function = ""; -+ -+sub add_entry { -+ my $key = shift; -+ my $value = shift; -+ my $default = shift; -+ -+ $TABLE .= $key; -+ $TABLE .= pack("V", $value); -+ $TABLE .= pack("V", $default); -+} -+ -+while (<>) { -+ $addr = $opcode = ""; -+ /^\w{8}\s*<(.*)>:$/ and $function = $1; -+ /^\s*(\w+):\s*(\w{8})\s*/ and do { -+ $addr = $1; -+ $opcode = $2; -+ }; -+ -+ ($function eq 'wlc_update_slot_timing') and do { -+ # li a2,9 -- short slot time -+ ($opcode eq '24060009') and add_entry($SLT1, hex($addr), hex($opcode)); -+ # li v0,519 -- 510 + short slot time -+ ($opcode eq '24020207') and add_entry($SLT2, hex($addr), hex($opcode)); -+ -+ # li a2,20 -- long slot time -+ ($opcode eq '24060014') and add_entry($SLT1, hex($addr), hex($opcode)); -+ # li v0,530 -- 510 + long slot time -+ ($opcode eq '24020212') and add_entry($SLT2, hex($addr), hex($opcode)); -+ }; -+ ($function eq 'wlc_d11hdrs') and do { -+ # ori s6,s6,0x1 -- ack flag (new) -+ ($opcode eq '36d60001') and add_entry($ACKW, hex($addr), hex($opcode)); -+ # ori s3,s3,0x1 -- ack flag (old) -+ ($opcode eq '36730001') and add_entry($ACKW, hex($addr), hex($opcode)); -+ } -+} -+ -+$TABLE .= $PTABLE_END; -+$TABLE .= ("\x00" x ($TABLE_SIZE - length($TABLE))); -+print $TABLE; -diff -urN linux.old/drivers/net/wl/Makefile linux.dev/drivers/net/wl/Makefile ---- linux.old/drivers/net/wl/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/Makefile 2006-04-28 01:33:52.000000000 +0200 -@@ -0,0 +1,32 @@ -+# -+# Makefile for the Broadcom wl driver -+# -+# Copyright 2004, Broadcom Corporation -+# All Rights Reserved. -+# -+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+# -+# $Id: Makefile,v 1.2 2005/03/29 03:32:18 mbm Exp $ -+ -+EXTRA_CFLAGS += -I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER -+ -+O_TARGET := wl_link.o -+ -+obj-y := wl_mod.o -+obj-y += bcmutils.o hnddma.o linux_osl.o -+ -+obj-m := $(O_TARGET) -+ -+wl_mod.o: wl_apsta.o -+ sed -e 's,eth%d,wl%d\x00,g' < $< > $@ -+ -+wl.o: wl_link.o -+ $(OBJDUMP) -d $< | perl patchtable.pl > patchtable.bin -+ cat wl_link.o patchtable.bin > $@ -+ -+modules: wl.o -+ -+include $(TOPDIR)/Rules.make -diff -urN linux.old/drivers/net/wl/bcmip.h linux.dev/drivers/net/wl/bcmip.h ---- linux.old/drivers/net/wl/bcmip.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/bcmip.h 2006-04-28 02:11:28.000000000 +0200 -@@ -0,0 +1,101 @@ -+/* -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * Fundamental constants relating to IP Protocol -+ * -+ * $Id: bcmip.h,v 1.1.1.3 2006/02/27 03:43:16 honor Exp $ -+ */ -+ -+#ifndef _bcmip_h_ -+#define _bcmip_h_ -+ -+/* IPV4 and IPV6 common */ -+#define IP_VER_OFFSET 0x0 /* offset to version field */ -+#define IP_VER_MASK 0xf0 /* version mask */ -+#define IP_VER_SHIFT 4 /* version shift */ -+#define IP_VER_4 4 /* version number for IPV4 */ -+#define IP_VER_6 6 /* version number for IPV6 */ -+ -+#define IP_VER(ip_body) \ -+ ((((uint8 *)(ip_body))[IP_VER_OFFSET] & IP_VER_MASK) >> IP_VER_SHIFT) -+ -+#define IP_PROT_ICMP 0x1 /* ICMP protocol */ -+#define IP_PROT_TCP 0x6 /* TCP protocol */ -+#define IP_PROT_UDP 0x11 /* UDP protocol type */ -+ -+/* IPV4 field offsets */ -+#define IPV4_VER_HL_OFFSET 0 /* version and ihl byte offset */ -+#define IPV4_TOS_OFFSET 1 /* type of service offset */ -+#define IPV4_PROT_OFFSET 9 /* protocol type offset */ -+#define IPV4_CHKSUM_OFFSET 10 /* IP header checksum offset */ -+#define IPV4_SRC_IP_OFFSET 12 /* src IP addr offset */ -+#define IPV4_DEST_IP_OFFSET 16 /* dest IP addr offset */ -+ -+/* IPV4 field decodes */ -+#define IPV4_VER_MASK 0xf0 /* IPV4 version mask */ -+#define IPV4_VER_SHIFT 4 /* IPV4 version shift */ -+ -+#define IPV4_HLEN_MASK 0x0f /* IPV4 header length mask */ -+#define IPV4_HLEN(ipv4_body) (4 * (((uint8 *)(ipv4_body))[IPV4_VER_HL_OFFSET] & IPV4_HLEN_MASK)) -+ -+#define IPV4_ADDR_LEN 4 /* IPV4 address length */ -+ -+#define IPV4_ADDR_NULL(a) ((((uint8 *)(a))[0] | ((uint8 *)(a))[1] | \ -+ ((uint8 *)(a))[2] | ((uint8 *)(a))[3]) == 0) -+ -+#define IPV4_TOS_DSCP_MASK 0xfc /* DiffServ codepoint mask */ -+#define IPV4_TOS_DSCP_SHIFT 2 /* DiffServ codepoint shift */ -+ -+#define IPV4_TOS(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_TOS_OFFSET]) -+ -+#define IPV4_TOS_PREC_MASK 0xe0 /* Historical precedence mask */ -+#define IPV4_TOS_PREC_SHIFT 5 /* Historical precedence shift */ -+ -+#define IPV4_TOS_LOWDELAY 0x10 /* Lowest delay requested */ -+#define IPV4_TOS_THROUGHPUT 0x8 /* Best throughput requested */ -+#define IPV4_TOS_RELIABILITY 0x4 /* Most reliable delivery requested */ -+ -+#define IPV4_PROT(ipv4_body) (((uint8 *)(ipv4_body))[IPV4_PROT_OFFSET]) -+ -+#define IPV4_ADDR_STR_LEN 16 /* Max IP address length in string format */ -+ -+/* IPV6 field offsets */ -+#define IPV6_PAYLOAD_LEN_OFFSET 4 /* payload length offset */ -+#define IPV6_NEXT_HDR_OFFSET 6 /* next header/protocol offset */ -+#define IPV6_HOP_LIMIT_OFFSET 7 /* hop limit offset */ -+#define IPV6_SRC_IP_OFFSET 8 /* src IP addr offset */ -+#define IPV6_DEST_IP_OFFSET 24 /* dst IP addr offset */ -+ -+/* IPV6 field decodes */ -+#define IPV6_TRAFFIC_CLASS(ipv6_body) \ -+ (((((uint8 *)(ipv6_body))[0] & 0x0f) << 4) | \ -+ ((((uint8 *)(ipv6_body))[1] & 0xf0) >> 4)) -+ -+#define IPV6_FLOW_LABEL(ipv6_body) \ -+ (((((uint8 *)(ipv6_body))[1] & 0x0f) << 16) | \ -+ (((uint8 *)(ipv6_body))[2] << 8) | \ -+ (((uint8 *)(ipv6_body))[3])) -+ -+#define IPV6_PAYLOAD_LEN(ipv6_body) \ -+ ((((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 0] << 8) | \ -+ ((uint8 *)(ipv6_body))[IPV6_PAYLOAD_LEN_OFFSET + 1]) -+ -+#define IPV6_NEXT_HDR(ipv6_body) \ -+ (((uint8 *)(ipv6_body))[IPV6_NEXT_HDR_OFFSET]) -+ -+#define IPV6_PROT(ipv6_body) IPV6_NEXT_HDR(ipv6_body) -+ -+#define IPV6_ADDR_LEN 16 /* IPV6 address length */ -+ -+/* IPV4 TOS or IPV6 Traffic Classifier or 0 */ -+#define IP_TOS(ip_body) \ -+ (IP_VER(ip_body) == IP_VER_4 ? IPV4_TOS(ip_body) : \ -+ IP_VER(ip_body) == IP_VER_6 ? IPV6_TRAFFIC_CLASS(ip_body) : 0) -+ -+#endif /* _bcmip_h_ */ -diff -urN linux.old/drivers/net/wl/bcmutils.c linux.dev/drivers/net/wl/bcmutils.c ---- linux.old/drivers/net/wl/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/bcmutils.c 2006-04-28 02:27:20.000000000 +0200 -@@ -0,0 +1,857 @@ -+/* -+ * Misc useful OS-independent routines. -+ * -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id: bcmutils.c,v 1.1.1.12 2006/02/27 03:43:16 honor Exp $ -+ */ -+ -+#include -+#include -+#include -+#include -+#include "linux_osl.h" -+#include "pktq.h" -+#include -+#include -+#include -+#include -+#include -+#include "bcmip.h" -+ -+#define ETHER_TYPE_8021Q 0x8100 -+#define ETHER_TYPE_IP 0x0800 -+#define VLAN_PRI_SHIFT 13 -+#define VLAN_PRI_MASK 7 -+ -+ -+struct ether_header { -+ uint8 ether_dhost[6]; -+ uint8 ether_shost[6]; -+ uint16 ether_type; -+} __attribute__((packed)); -+ -+ -+struct ethervlan_header { -+ uint8 ether_dhost[6]; -+ uint8 ether_shost[6]; -+ uint16 vlan_type; /* 0x8100 */ -+ uint16 vlan_tag; /* priority, cfi and vid */ -+ uint16 ether_type; -+}; -+ -+/* copy a pkt buffer chain into a buffer */ -+uint -+pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) -+{ -+ uint n, ret = 0; -+ -+ if (len < 0) -+ len = 4096; /* "infinite" */ -+ -+ /* skip 'offset' bytes */ -+ for (; p && offset; p = PKTNEXT(osh, p)) { -+ if (offset < (uint)PKTLEN(osh, p)) -+ break; -+ offset -= PKTLEN(osh, p); -+ } -+ -+ if (!p) -+ return 0; -+ -+ /* copy the data */ -+ for (; p && len; p = PKTNEXT(osh, p)) { -+ n = MIN((uint)PKTLEN(osh, p) - offset, (uint)len); -+ bcopy(PKTDATA(osh, p) + offset, buf, n); -+ buf += n; -+ len -= n; -+ ret += n; -+ offset = 0; -+ } -+ -+ return ret; -+} -+ -+/* return total length of buffer chain */ -+uint -+pkttotlen(osl_t *osh, void *p) -+{ -+ uint total; -+ -+ total = 0; -+ for (; p; p = PKTNEXT(osh, p)) -+ total += PKTLEN(osh, p); -+ return (total); -+} -+ -+/* return the last buffer of chained pkt */ -+void * -+pktlast(osl_t *osh, void *p) -+{ -+ for (; PKTNEXT(osh, p); p = PKTNEXT(osh, p)) -+ ; -+ -+ return (p); -+} -+ -+ -+/* -+ * osl multiple-precedence packet queue -+ * hi_prec is always >= the number of the highest non-empty queue -+ */ -+void * -+pktq_penq(struct pktq *pq, int prec, void *p) -+{ -+ struct pktq_prec *q; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ -+ -+ ASSERT(!pktq_full(pq)); -+ ASSERT(!pktq_pfull(pq, prec)); -+ -+ q = &pq->q[prec]; -+ -+ if (q->head) -+ PKTSETLINK(q->tail, p); -+ else -+ q->head = p; -+ -+ q->tail = p; -+ q->len++; -+ -+ pq->len++; -+ -+ if (pq->hi_prec < prec) -+ pq->hi_prec = (uint8)prec; -+ -+ return p; -+} -+ -+void * -+pktq_penq_head(struct pktq *pq, int prec, void *p) -+{ -+ struct pktq_prec *q; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ -+ -+ ASSERT(!pktq_full(pq)); -+ ASSERT(!pktq_pfull(pq, prec)); -+ -+ q = &pq->q[prec]; -+ -+ if (q->head == NULL) -+ q->tail = p; -+ -+ PKTSETLINK(p, q->head); -+ q->head = p; -+ q->len++; -+ -+ pq->len++; -+ -+ if (pq->hi_prec < prec) -+ pq->hi_prec = (uint8)prec; -+ -+ return p; -+} -+ -+void * -+pktq_pdeq(struct pktq *pq, int prec) -+{ -+ struct pktq_prec *q; -+ void *p; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ if ((q->head = PKTLINK(p)) == NULL) -+ q->tail = NULL; -+ -+ q->len--; -+ -+ pq->len--; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * -+pktq_pdeq_tail(struct pktq *pq, int prec) -+{ -+ struct pktq_prec *q; -+ void *p, *prev; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ for (prev = NULL; p != q->tail; p = PKTLINK(p)) -+ prev = p; -+ -+ if (prev) -+ PKTSETLINK(prev, NULL); -+ else -+ q->head = NULL; -+ -+ q->tail = prev; -+ q->len--; -+ -+ pq->len--; -+ -+ return p; -+} -+ -+void -+pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir) -+{ -+ struct pktq_prec *q; -+ void *p; -+ -+ q = &pq->q[prec]; -+ p = q->head; -+ while (p) { -+ q->head = PKTLINK(p); -+ PKTSETLINK(p, NULL); -+ PKTFREE(osh, p, dir); -+ q->len--; -+ pq->len--; -+ p = q->head; -+ } -+ ASSERT(q->len == 0); -+ q->tail = NULL; -+} -+ -+bool -+pktq_pdel(struct pktq *pq, void *pktbuf, int prec) -+{ -+ struct pktq_prec *q; -+ void *p; -+ -+ ASSERT(prec >= 0 && prec < pq->num_prec); -+ -+ if (!pktbuf) -+ return FALSE; -+ -+ q = &pq->q[prec]; -+ -+ if (q->head == pktbuf) { -+ if ((q->head = PKTLINK(pktbuf)) == NULL) -+ q->tail = NULL; -+ } else { -+ for (p = q->head; p && PKTLINK(p) != pktbuf; p = PKTLINK(p)) -+ ; -+ if (p == NULL) -+ return FALSE; -+ -+ PKTSETLINK(p, PKTLINK(pktbuf)); -+ if (q->tail == pktbuf) -+ q->tail = p; -+ } -+ -+ q->len--; -+ pq->len--; -+ PKTSETLINK(pktbuf, NULL); -+ return TRUE; -+} -+ -+void -+pktq_init(struct pktq *pq, int num_prec, int max_len) -+{ -+ int prec; -+ -+ ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); -+ -+ bzero(pq, sizeof(*pq)); -+ -+ pq->num_prec = (uint16)num_prec; -+ -+ pq->max = (uint16)max_len; -+ -+ for (prec = 0; prec < num_prec; prec++) -+ pq->q[prec].max = pq->max; -+} -+ -+void * -+pktq_deq(struct pktq *pq, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ if ((q->head = PKTLINK(p)) == NULL) -+ q->tail = NULL; -+ -+ q->len--; -+ -+ pq->len--; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * -+pktq_deq_tail(struct pktq *pq, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p, *prev; -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ for (prec = 0; prec < pq->hi_prec; prec++) -+ if (pq->q[prec].head) -+ break; -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ for (prev = NULL; p != q->tail; p = PKTLINK(p)) -+ prev = p; -+ -+ if (prev) -+ PKTSETLINK(prev, NULL); -+ else -+ q->head = NULL; -+ -+ q->tail = prev; -+ q->len--; -+ -+ pq->len--; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+void * -+pktq_peek(struct pktq *pq, int *prec_out) -+{ -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ return (pq->q[prec].head); -+} -+ -+void * -+pktq_peek_tail(struct pktq *pq, int *prec_out) -+{ -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ for (prec = 0; prec < pq->hi_prec; prec++) -+ if (pq->q[prec].head) -+ break; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ return (pq->q[prec].tail); -+} -+ -+void -+pktq_flush(osl_t *osh, struct pktq *pq, bool dir) -+{ -+ int prec; -+ for (prec = 0; prec < pq->num_prec; prec++) -+ pktq_pflush(osh, pq, prec, dir); -+ ASSERT(pq->len == 0); -+} -+ -+/* Return sum of lengths of a specific set of precedences */ -+int -+pktq_mlen(struct pktq *pq, uint prec_bmp) -+{ -+ int prec, len; -+ -+ len = 0; -+ -+ for (prec = 0; prec <= pq->hi_prec; prec++) -+ if (prec_bmp & (1 << prec)) -+ len += pq->q[prec].len; -+ -+ return len; -+} -+ -+/* Priority dequeue from a specific set of precedences */ -+void * -+pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) -+{ -+ struct pktq_prec *q; -+ void *p; -+ int prec; -+ -+ if (pq->len == 0) -+ return NULL; -+ -+ while ((prec = pq->hi_prec) > 0 && pq->q[prec].head == NULL) -+ pq->hi_prec--; -+ -+ while ((prec_bmp & (1 << prec)) == 0 || pq->q[prec].head == NULL) -+ if (prec-- == 0) -+ return NULL; -+ -+ q = &pq->q[prec]; -+ -+ if ((p = q->head) == NULL) -+ return NULL; -+ -+ if ((q->head = PKTLINK(p)) == NULL) -+ q->tail = NULL; -+ -+ q->len--; -+ -+ if (prec_out) -+ *prec_out = prec; -+ -+ pq->len--; -+ -+ PKTSETLINK(p, NULL); -+ -+ return p; -+} -+ -+char* -+bcmstrcat(char *dest, const char *src) -+{ -+ strcpy(&dest[strlen(dest)], src); -+ return (dest); -+} -+ -+char* -+bcm_ether_ntoa(struct ether_addr *ea, char *buf) -+{ -+ sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x", -+ ea->octet[0]&0xff, ea->octet[1]&0xff, ea->octet[2]&0xff, -+ ea->octet[3]&0xff, ea->octet[4]&0xff, ea->octet[5]&0xff); -+ return (buf); -+} -+ -+/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -+int -+bcm_ether_atoe(char *p, struct ether_addr *ea) -+{ -+ int i = 0; -+ -+ for (;;) { -+ ea->octet[i++] = (char) bcm_strtoul(p, &p, 16); -+ if (!*p++ || i == 6) -+ break; -+ } -+ -+ return (i == 6); -+} -+ -+/* Takes an Ethernet frame and sets out-of-bound PKTPRIO -+ * Also updates the inplace vlan tag if requested -+ */ -+void -+pktsetprio(void *pkt, bool update_vtag) -+{ -+ struct ether_header *eh; -+ struct ethervlan_header *evh; -+ uint8 *pktdata; -+ int priority = 0; -+ -+ pktdata = (uint8 *) PKTDATA(NULL, pkt); -+ ASSERT(ISALIGNED((uintptr)pktdata, sizeof(uint16))); -+ -+ eh = (struct ether_header *) pktdata; -+ -+ if (ntoh16(eh->ether_type) == ETHER_TYPE_8021Q) { -+ uint16 vlan_tag; -+ int vlan_prio, dscp_prio = 0; -+ -+ evh = (struct ethervlan_header *)eh; -+ -+ vlan_tag = ntoh16(evh->vlan_tag); -+ vlan_prio = (int) (vlan_tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK; -+ -+ if (ntoh16(evh->ether_type) == ETHER_TYPE_IP) { -+ uint8 *ip_body = pktdata + sizeof(struct ethervlan_header); -+ uint8 tos_tc = IP_TOS(ip_body); -+ dscp_prio = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); -+ } -+ -+ /* DSCP priority gets precedence over 802.1P (vlan tag) */ -+ priority = (dscp_prio != 0) ? dscp_prio : vlan_prio; -+ -+ /* -+ * If the DSCP priority is not the same as the VLAN priority, -+ * then overwrite the priority field in the vlan tag, with the -+ * DSCP priority value. This is required for Linux APs because -+ * the VLAN driver on Linux, overwrites the skb->priority field -+ * with the priority value in the vlan tag -+ */ -+ if (update_vtag && (priority != vlan_prio)) { -+ vlan_tag &= ~(VLAN_PRI_MASK << VLAN_PRI_SHIFT); -+ vlan_tag |= (uint16)priority << VLAN_PRI_SHIFT; -+ evh->vlan_tag = hton16(vlan_tag); -+ } -+ } else if (ntoh16(eh->ether_type) == ETHER_TYPE_IP) { -+ uint8 *ip_body = pktdata + sizeof(struct ether_header); -+ uint8 tos_tc = IP_TOS(ip_body); -+ priority = (int)(tos_tc >> IPV4_TOS_PREC_SHIFT); -+ } -+ -+ ASSERT(priority >= 0 && priority <= MAXPRIO); -+ PKTSETPRIO(pkt, priority); -+} -+ -+static char bcm_undeferrstr[BCME_STRLEN]; -+ -+static const char *bcmerrorstrtable[] = BCMERRSTRINGTABLE; -+ -+/* Convert the Error codes into related Error strings */ -+const char * -+bcmerrorstr(int bcmerror) -+{ -+ int abs_bcmerror; -+ -+ abs_bcmerror = ABS(bcmerror); -+ -+ /* check if someone added a bcmerror code but forgot to add errorstring */ -+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(bcmerrorstrtable) - 1)); -+ if ((bcmerror > 0) || (abs_bcmerror > ABS(BCME_LAST))) { -+ sprintf(bcm_undeferrstr, "undefined Error %d", bcmerror); -+ return bcm_undeferrstr; -+ } -+ -+ ASSERT((strlen((char*)bcmerrorstrtable[abs_bcmerror])) < BCME_STRLEN); -+ -+ return bcmerrorstrtable[abs_bcmerror]; -+} -+ -+ -+int -+bcm_iovar_lencheck(const bcm_iovar_t *vi, void *arg, int len, bool set) -+{ -+ int bcmerror = 0; -+ -+ /* length check on io buf */ -+ switch (vi->type) { -+ case IOVT_BOOL: -+ case IOVT_INT8: -+ case IOVT_INT16: -+ case IOVT_INT32: -+ case IOVT_UINT8: -+ case IOVT_UINT16: -+ case IOVT_UINT32: -+ /* all integers are int32 sized args at the ioctl interface */ -+ if (len < (int)sizeof(int)) { -+ bcmerror = BCME_BUFTOOSHORT; -+ } -+ break; -+ -+ case IOVT_BUFFER: -+ /* buffer must meet minimum length requirement */ -+ if (len < vi->minlen) { -+ bcmerror = BCME_BUFTOOSHORT; -+ } -+ break; -+ -+ case IOVT_VOID: -+ if (!set) { -+ /* Cannot return nil... */ -+ bcmerror = BCME_UNSUPPORTED; -+ } else if (len) { -+ /* Set is an action w/o parameters */ -+ bcmerror = BCME_BUFTOOLONG; -+ } -+ break; -+ -+ default: -+ /* unknown type for length check in iovar info */ -+ ASSERT(0); -+ bcmerror = BCME_UNSUPPORTED; -+ } -+ -+ return bcmerror; -+} -+ -+#define CRC_INNER_LOOP(n, c, x) \ -+ (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] -+ -+static uint32 crc32_table[256] = { -+ 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, -+ 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, -+ 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, -+ 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, -+ 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, -+ 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, -+ 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, -+ 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, -+ 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, -+ 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, -+ 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, -+ 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, -+ 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, -+ 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, -+ 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, -+ 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, -+ 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, -+ 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, -+ 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, -+ 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, -+ 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, -+ 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, -+ 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, -+ 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, -+ 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, -+ 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, -+ 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, -+ 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, -+ 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, -+ 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, -+ 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, -+ 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, -+ 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, -+ 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, -+ 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, -+ 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, -+ 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, -+ 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, -+ 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, -+ 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, -+ 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, -+ 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, -+ 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, -+ 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, -+ 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, -+ 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, -+ 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, -+ 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, -+ 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, -+ 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, -+ 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, -+ 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, -+ 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, -+ 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, -+ 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, -+ 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, -+ 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, -+ 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, -+ 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, -+ 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, -+ 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, -+ 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, -+ 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, -+ 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -+}; -+ -+uint32 -+hndcrc32( -+ uint8 *pdata, /* pointer to array of data to process */ -+ uint nbytes, /* number of input data bytes to process */ -+ uint32 crc /* either CRC32_INIT_VALUE or previous return value */ -+) -+{ -+ uint8 *pend; -+#ifdef __mips__ -+ uint8 tmp[4]; -+ ulong *tptr = (ulong *)tmp; -+ -+ /* in case the beginning of the buffer isn't aligned */ -+ pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); -+ nbytes -= (pend - pdata); -+ while (pdata < pend) -+ CRC_INNER_LOOP(32, crc, *pdata++); -+ -+ /* handle bulk of data as 32-bit words */ -+ pend = pdata + (nbytes & 0xfffffffc); -+ while (pdata < pend) { -+ *tptr = *(ulong *)pdata; -+ pdata += sizeof(ulong *); -+ CRC_INNER_LOOP(32, crc, tmp[0]); -+ CRC_INNER_LOOP(32, crc, tmp[1]); -+ CRC_INNER_LOOP(32, crc, tmp[2]); -+ CRC_INNER_LOOP(32, crc, tmp[3]); -+ } -+ -+ /* 1-3 bytes at end of buffer */ -+ pend = pdata + (nbytes & 0x03); -+ while (pdata < pend) -+ CRC_INNER_LOOP(32, crc, *pdata++); -+#else -+ pend = pdata + nbytes; -+ while (pdata < pend) -+ CRC_INNER_LOOP(32, crc, *pdata++); -+#endif /* __mips__ */ -+ -+ return crc; -+} -+ -+ -+/* -+ * Advance from the current 1-byte tag/1-byte length/variable-length value -+ * triple, to the next, returning a pointer to the next. -+ * If the current or next TLV is invalid (does not fit in given buffer length), -+ * NULL is returned. -+ * *buflen is not modified if the TLV elt parameter is invalid, or is decremented -+ * by the TLV paramter's length if it is valid. -+ */ -+bcm_tlv_t * -+bcm_next_tlv(bcm_tlv_t *elt, int *buflen) -+{ -+ int len; -+ -+ /* validate current elt */ -+ if (!bcm_valid_tlv(elt, *buflen)) -+ return NULL; -+ -+ /* advance to next elt */ -+ len = elt->len; -+ elt = (bcm_tlv_t*)(elt->data + len); -+ *buflen -= (2 + len); -+ -+ /* validate next elt */ -+ if (!bcm_valid_tlv(elt, *buflen)) -+ return NULL; -+ -+ return elt; -+} -+ -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag -+ */ -+bcm_tlv_t * -+bcm_parse_tlvs(void *buf, int buflen, uint key) -+{ -+ bcm_tlv_t *elt; -+ int totlen; -+ -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; -+ -+ /* find tagged parameter */ -+ while (totlen >= 2) { -+ int len = elt->len; -+ -+ /* validate remaining totlen */ -+ if ((elt->id == key) && (totlen >= (len + 2))) -+ return (elt); -+ -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); -+ totlen -= (len + 2); -+ } -+ -+ return NULL; -+} -+ -+/* -+ * Traverse a string of 1-byte tag/1-byte length/variable-length value -+ * triples, returning a pointer to the substring whose first element -+ * matches tag. Stop parsing when we see an element whose ID is greater -+ * than the target key. -+ */ -+bcm_tlv_t * -+bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) -+{ -+ bcm_tlv_t *elt; -+ int totlen; -+ -+ elt = (bcm_tlv_t*)buf; -+ totlen = buflen; -+ -+ /* find tagged parameter */ -+ while (totlen >= 2) { -+ uint id = elt->id; -+ int len = elt->len; -+ -+ /* Punt if we start seeing IDs > than target key */ -+ if (id > key) -+ return (NULL); -+ -+ /* validate remaining totlen */ -+ if ((id == key) && (totlen >= (len + 2))) -+ return (elt); -+ -+ elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); -+ totlen -= (len + 2); -+ } -+ return NULL; -+} -+ -+ -+/* Initialization of bcmstrbuf structure */ -+void -+bcm_binit(struct bcmstrbuf *b, char *buf, uint size) -+{ -+ b->origsize = b->size = size; -+ b->origbuf = b->buf = buf; -+} -+ -+/* Buffer sprintf wrapper to guard against buffer overflow */ -+int -+bcm_bprintf(struct bcmstrbuf *b, const char *fmt, ...) -+{ -+ va_list ap; -+ int r; -+ -+ va_start(ap, fmt); -+ r = vsnprintf(b->buf, b->size, fmt, ap); -+ -+ /* Non Ansi C99 compliant returns -1, -+ * Ansi compliant return r >= b->size, -+ * bcmstdlib returns 0, handle all -+ */ -+ if ((r == -1) || (r >= (int)b->size) || (r == 0)) -+ { -+ b->size = 0; -+ } -+ else -+ { -+ b->size -= r; -+ b->buf += r; -+ } -+ -+ va_end(ap); -+ -+ return r; -+} -diff -urN linux.old/drivers/net/wl/hnddma.c linux.dev/drivers/net/wl/hnddma.c ---- linux.old/drivers/net/wl/hnddma.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/hnddma.c 2006-05-02 17:42:13.000000000 +0200 -@@ -0,0 +1,1157 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA module. -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id: hnddma.c,v 1.11 2006/04/08 07:12:42 honor Exp $ -+ */ -+ -+#include -+#include -+#include -+#include "linux_osl.h" -+#include -+#include -+#include -+#include -+#include -+ -+#include "sbhnddma.h" -+#include "hnddma.h" -+ -+/* debug/trace */ -+#define DMA_ERROR(args) -+#define DMA_TRACE(args) -+ -+/* default dma message level (if input msg_level pointer is null in dma_attach()) */ -+static uint dma_msg_level = -+ 0; -+ -+#define MAXNAMEL 8 /* 8 char names */ -+ -+#define DI_INFO(dmah) (dma_info_t *)dmah -+ -+/* dma engine software state */ -+typedef struct dma_info { -+ struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t, -+ * which could be const -+ */ -+ uint *msg_level; /* message level pointer */ -+ char name[MAXNAMEL]; /* callers name for diag msgs */ -+ -+ void *osh; /* os handle */ -+ sb_t *sbh; /* sb handle */ -+ -+ bool dma64; /* dma64 enabled */ -+ bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ -+ -+ dma32regs_t *d32txregs; /* 32 bits dma tx engine registers */ -+ dma32regs_t *d32rxregs; /* 32 bits dma rx engine registers */ -+ dma64regs_t *d64txregs; /* 64 bits dma tx engine registers */ -+ dma64regs_t *d64rxregs; /* 64 bits dma rx engine registers */ -+ -+ uint32 dma64align; /* either 8k or 4k depends on number of dd */ -+ dma32dd_t *txd32; /* pointer to dma32 tx descriptor ring */ -+ dma64dd_t *txd64; /* pointer to dma64 tx descriptor ring */ -+ uint ntxd; /* # tx descriptors tunable */ -+ uint txin; /* index of next descriptor to reclaim */ -+ uint txout; /* index of next descriptor to post */ -+ void **txp; /* pointer to parallel array of pointers to packets */ -+ osldma_t *tx_dmah; /* DMA TX descriptor ring handle */ -+ osldma_t **txp_dmah; /* DMA TX packet data handle */ -+ ulong txdpa; /* physical address of descriptor ring */ -+ uint txdalign; /* #bytes added to alloc'd mem to align txd */ -+ uint txdalloc; /* #bytes allocated for the ring */ -+ -+ dma32dd_t *rxd32; /* pointer to dma32 rx descriptor ring */ -+ dma64dd_t *rxd64; /* pointer to dma64 rx descriptor ring */ -+ uint nrxd; /* # rx descriptors tunable */ -+ uint rxin; /* index of next descriptor to reclaim */ -+ uint rxout; /* index of next descriptor to post */ -+ void **rxp; /* pointer to parallel array of pointers to packets */ -+ osldma_t *rx_dmah; /* DMA RX descriptor ring handle */ -+ osldma_t **rxp_dmah; /* DMA RX packet data handle */ -+ ulong rxdpa; /* physical address of descriptor ring */ -+ uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ -+ uint rxdalloc; /* #bytes allocated for the ring */ -+ -+ /* tunables */ -+ uint rxbufsize; /* rx buffer size in bytes, -+ not including the extra headroom -+ */ -+ uint nrxpost; /* # rx buffers to keep posted */ -+ uint rxoffset; /* rxcontrol offset */ -+ uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ -+ uint ddoffsethigh; /* high 32 bits */ -+ uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ -+ uint dataoffsethigh; /* high 32 bits */ -+} dma_info_t; -+ -+/* descriptor bumping macros */ -+#define XXD(x, n) ((x) & ((n) - 1)) /* faster than %, but n must be power of 2 */ -+#define TXD(x) XXD((x), di->ntxd) -+#define RXD(x) XXD((x), di->nrxd) -+#define NEXTTXD(i) TXD(i + 1) -+#define PREVTXD(i) TXD(i - 1) -+#define NEXTRXD(i) RXD(i + 1) -+#define NTXDACTIVE(h, t) TXD(t - h) -+#define NRXDACTIVE(h, t) RXD(t - h) -+ -+/* macros to convert between byte offsets and indexes */ -+#define B2I(bytes, type) ((bytes) / sizeof(type)) -+#define I2B(index, type) ((index) * sizeof(type)) -+ -+#define PCI32ADDR_HIGH 0xc0000000 /* address[31:30] */ -+#define PCI32ADDR_HIGH_SHIFT 30 /* address[31:30] */ -+ -+ -+/* common prototypes */ -+static bool _dma_isaddrext(dma_info_t *di); -+static bool dma32_alloc(dma_info_t *di, uint direction); -+static void _dma_detach(dma_info_t *di); -+static void _dma_ddtable_init(dma_info_t *di, uint direction, ulong pa); -+static void _dma_rxinit(dma_info_t *di); -+static void *_dma_rx(dma_info_t *di); -+static void _dma_rxfill(dma_info_t *di); -+static void _dma_rxreclaim(dma_info_t *di); -+static void _dma_rxenable(dma_info_t *di); -+static void * _dma_getnextrxp(dma_info_t *di, bool forceall); -+ -+static void _dma_txblock(dma_info_t *di); -+static void _dma_txunblock(dma_info_t *di); -+static uint _dma_txactive(dma_info_t *di); -+ -+static void* _dma_peeknexttxp(dma_info_t *di); -+static uintptr _dma_getvar(dma_info_t *di, char *name); -+static void _dma_counterreset(dma_info_t *di); -+static void _dma_fifoloopbackenable(dma_info_t *di); -+ -+/* ** 32 bit DMA prototypes */ -+static bool dma32_alloc(dma_info_t *di, uint direction); -+static bool dma32_txreset(dma_info_t *di); -+static bool dma32_rxreset(dma_info_t *di); -+static bool dma32_txsuspendedidle(dma_info_t *di); -+static int dma32_txfast(dma_info_t *di, void *p0, bool commit); -+static void *dma32_getnexttxp(dma_info_t *di, bool forceall); -+static void *dma32_getnextrxp(dma_info_t *di, bool forceall); -+static void dma32_txrotate(dma_info_t *di); -+static bool dma32_rxidle(dma_info_t *di); -+static void dma32_txinit(dma_info_t *di); -+static bool dma32_txenabled(dma_info_t *di); -+static void dma32_txsuspend(dma_info_t *di); -+static void dma32_txresume(dma_info_t *di); -+static bool dma32_txsuspended(dma_info_t *di); -+static void dma32_txreclaim(dma_info_t *di, bool forceall); -+static bool dma32_txstopped(dma_info_t *di); -+static bool dma32_rxstopped(dma_info_t *di); -+static bool dma32_rxenabled(dma_info_t *di); -+static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs); -+ -+ -+static di_fcn_t dma32proc = { -+ (di_detach_t)_dma_detach, -+ (di_txinit_t)dma32_txinit, -+ (di_txreset_t)dma32_txreset, -+ (di_txenabled_t)dma32_txenabled, -+ (di_txsuspend_t)dma32_txsuspend, -+ (di_txresume_t)dma32_txresume, -+ (di_txsuspended_t)dma32_txsuspended, -+ (di_txsuspendedidle_t)dma32_txsuspendedidle, -+ (di_txfast_t)dma32_txfast, -+ (di_txstopped_t)dma32_txstopped, -+ (di_txreclaim_t)dma32_txreclaim, -+ (di_getnexttxp_t)dma32_getnexttxp, -+ (di_peeknexttxp_t)_dma_peeknexttxp, -+ (di_txblock_t)_dma_txblock, -+ (di_txunblock_t)_dma_txunblock, -+ (di_txactive_t)_dma_txactive, -+ (di_txrotate_t)dma32_txrotate, -+ -+ (di_rxinit_t)_dma_rxinit, -+ (di_rxreset_t)dma32_rxreset, -+ (di_rxidle_t)dma32_rxidle, -+ (di_rxstopped_t)dma32_rxstopped, -+ (di_rxenable_t)_dma_rxenable, -+ (di_rxenabled_t)dma32_rxenabled, -+ (di_rx_t)_dma_rx, -+ (di_rxfill_t)_dma_rxfill, -+ (di_rxreclaim_t)_dma_rxreclaim, -+ (di_getnextrxp_t)_dma_getnextrxp, -+ -+ (di_fifoloopbackenable_t)_dma_fifoloopbackenable, -+ (di_getvar_t)_dma_getvar, -+ (di_counterreset_t)_dma_counterreset, -+ -+ NULL, -+ NULL, -+ NULL, -+ 34 -+}; -+ -+hnddma_t * -+dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, -+ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, uint *msg_level) -+{ -+ dma_info_t *di; -+ uint size; -+ -+ /* allocate private info structure */ -+ if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { -+ return (NULL); -+ } -+ bzero((char *)di, sizeof(dma_info_t)); -+ -+ di->msg_level = msg_level ? msg_level : &dma_msg_level; -+ -+ /* old chips w/o sb is no longer supported */ -+ ASSERT(sbh != NULL); -+ -+ /* check arguments */ -+ ASSERT(ISPOWEROF2(ntxd)); -+ ASSERT(ISPOWEROF2(nrxd)); -+ if (nrxd == 0) -+ ASSERT(dmaregsrx == NULL); -+ if (ntxd == 0) -+ ASSERT(dmaregstx == NULL); -+ -+ -+ /* init dma reg pointer */ -+ ASSERT(ntxd <= D32MAXDD); -+ ASSERT(nrxd <= D32MAXDD); -+ di->d32txregs = (dma32regs_t *)dmaregstx; -+ di->d32rxregs = (dma32regs_t *)dmaregsrx; -+ -+ DMA_TRACE(("%s: dma_attach: %s osh %p ntxd %d nrxd %d rxbufsize %d nrxpost %d " -+ "rxoffset %d dmaregstx %p dmaregsrx %p\n", -+ name, "DMA32", osh, ntxd, nrxd, rxbufsize, -+ nrxpost, rxoffset, dmaregstx, dmaregsrx)); -+ -+ /* make a private copy of our callers name */ -+ strncpy(di->name, name, MAXNAMEL); -+ di->name[MAXNAMEL-1] = '\0'; -+ -+ di->osh = osh; -+ di->sbh = sbh; -+ -+ /* save tunables */ -+ di->ntxd = ntxd; -+ di->nrxd = nrxd; -+ -+ /* the actual dma size doesn't include the extra headroom */ -+ if (rxbufsize > BCMEXTRAHDROOM) -+ di->rxbufsize = rxbufsize - BCMEXTRAHDROOM; -+ else -+ di->rxbufsize = rxbufsize; -+ -+ di->nrxpost = nrxpost; -+ di->rxoffset = rxoffset; -+ -+ /* -+ * figure out the DMA physical address offset for dd and data -+ * for old chips w/o sb, use zero -+ * for new chips w sb, -+ * PCI/PCIE: they map silicon backplace address to zero based memory, need offset -+ * Other bus: use zero -+ * SB_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor -+ */ -+ di->ddoffsetlow = 0; -+ di->dataoffsetlow = 0; -+ /* for pci bus, add offset */ -+ if (sbh->bustype == PCI_BUS) { -+ di->ddoffsetlow = SB_PCI_DMA; -+ di->ddoffsethigh = 0; -+ di->dataoffsetlow = di->ddoffsetlow; -+ di->dataoffsethigh = di->ddoffsethigh; -+ } -+ -+#if defined(__mips__) && defined(IL_BIGENDIAN) -+ di->dataoffsetlow = di->dataoffsetlow + SB_SDRAM_SWAPPED; -+#endif -+ -+ di->addrext = _dma_isaddrext(di); -+ -+ /* allocate tx packet pointer vector */ -+ if (ntxd) { -+ size = ntxd * sizeof(void *); -+ if ((di->txp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: out of tx memory, malloced %d bytes\n", -+ di->name, MALLOCED(osh))); -+ goto fail; -+ } -+ bzero((char *)di->txp, size); -+ } -+ -+ /* allocate rx packet pointer vector */ -+ if (nrxd) { -+ size = nrxd * sizeof(void *); -+ if ((di->rxp = MALLOC(osh, size)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: out of rx memory, malloced %d bytes\n", -+ di->name, MALLOCED(osh))); -+ goto fail; -+ } -+ bzero((char *)di->rxp, size); -+ } -+ -+ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ -+ if (ntxd) { -+ if (!dma32_alloc(di, DMA_TX)) -+ goto fail; -+ } -+ -+ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ -+ if (nrxd) { -+ if (!dma32_alloc(di, DMA_RX)) -+ goto fail; -+ } -+ -+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->txdpa > SB_PCI_DMA_SZ) && !di->addrext) { -+ DMA_ERROR(("%s: dma_attach: txdpa 0x%lx: addrext not supported\n", -+ di->name, di->txdpa)); -+ goto fail; -+ } -+ if ((di->ddoffsetlow == SB_PCI_DMA) && (di->rxdpa > SB_PCI_DMA_SZ) && !di->addrext) { -+ DMA_ERROR(("%s: dma_attach: rxdpa 0x%lx: addrext not supported\n", -+ di->name, di->rxdpa)); -+ goto fail; -+ } -+ -+ DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " -+ "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, -+ di->dataoffsethigh, di->addrext)); -+ -+ /* allocate tx packet pointer vector and DMA mapping vectors */ -+ if (ntxd) { -+ -+ size = ntxd * sizeof(osldma_t **); -+ if ((di->txp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) -+ goto fail; -+ bzero((char*)di->txp_dmah, size); -+ }else -+ di->txp_dmah = NULL; -+ -+ /* allocate rx packet pointer vector and DMA mapping vectors */ -+ if (nrxd) { -+ -+ size = nrxd * sizeof(osldma_t **); -+ if ((di->rxp_dmah = (osldma_t **)MALLOC(osh, size)) == NULL) -+ goto fail; -+ bzero((char*)di->rxp_dmah, size); -+ -+ } else -+ di->rxp_dmah = NULL; -+ -+ /* initialize opsvec of function pointers */ -+ di->hnddma.di_fn = dma32proc; -+ -+ return ((hnddma_t *)di); -+ -+fail: -+ _dma_detach(di); -+ return (NULL); -+} -+ -+/* init the tx or rx descriptor */ -+static INLINE void -+dma32_dd_upd(dma_info_t *di, dma32dd_t *ddring, ulong pa, uint outidx, uint32 *flags, -+ uint32 bufcount) -+{ -+ /* dma32 uses 32 bits control to fit both flags and bufcounter */ -+ *flags = *flags | (bufcount & CTRL_BC_MASK); -+ -+ if ((di->dataoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { -+ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); -+ } else { -+ /* address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; -+ pa &= ~PCI32ADDR_HIGH; -+ -+ *flags |= (ae << CTRL_AE_SHIFT); -+ W_SM(&ddring[outidx].addr, BUS_SWAP32(pa + di->dataoffsetlow)); -+ W_SM(&ddring[outidx].ctrl, BUS_SWAP32(*flags)); -+ } -+} -+ -+static bool -+_dma32_addrext(osl_t *osh, dma32regs_t *dma32regs) -+{ -+ uint32 w; -+ -+ OR_REG(osh, &dma32regs->control, XC_AE); -+ w = R_REG(osh, &dma32regs->control); -+ AND_REG(osh, &dma32regs->control, ~XC_AE); -+ return ((w & XC_AE) == XC_AE); -+} -+ -+/* !! may be called with core in reset */ -+static void -+_dma_detach(dma_info_t *di) -+{ -+ if (di == NULL) -+ return; -+ -+ DMA_TRACE(("%s: dma_detach\n", di->name)); -+ -+ /* shouldn't be here if descriptors are unreclaimed */ -+ ASSERT(di->txin == di->txout); -+ ASSERT(di->rxin == di->rxout); -+ -+ /* free dma descriptor rings */ -+ if (di->txd32) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd32 - di->txdalign), -+ di->txdalloc, (di->txdpa - di->txdalign), &di->tx_dmah); -+ if (di->rxd32) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd32 - di->rxdalign), -+ di->rxdalloc, (di->rxdpa - di->rxdalign), &di->rx_dmah); -+ -+ /* free packet pointer vectors */ -+ if (di->txp) -+ MFREE(di->osh, (void *)di->txp, (di->ntxd * sizeof(void *))); -+ if (di->rxp) -+ MFREE(di->osh, (void *)di->rxp, (di->nrxd * sizeof(void *))); -+ -+ /* free tx packet DMA handles */ -+ if (di->txp_dmah) -+ MFREE(di->osh, (void *)di->txp_dmah, di->ntxd * sizeof(osldma_t **)); -+ -+ /* free rx packet DMA handles */ -+ if (di->rxp_dmah) -+ MFREE(di->osh, (void *)di->rxp_dmah, di->nrxd * sizeof(osldma_t **)); -+ -+ /* free our private info structure */ -+ MFREE(di->osh, (void *)di, sizeof(dma_info_t)); -+ -+} -+ -+/* return TRUE if this dma engine supports DmaExtendedAddrChanges, otherwise FALSE */ -+static bool -+_dma_isaddrext(dma_info_t *di) -+{ -+ if (di->d32txregs) -+ return (_dma32_addrext(di->osh, di->d32txregs)); -+ else if (di->d32rxregs) -+ return (_dma32_addrext(di->osh, di->d32rxregs)); -+ return FALSE; -+} -+ -+/* initialize descriptor table base address */ -+static void -+_dma_ddtable_init(dma_info_t *di, uint direction, ulong pa) -+{ -+ if ((di->ddoffsetlow != SB_PCI_DMA) || !(pa & PCI32ADDR_HIGH)) { -+ if (direction == DMA_TX) -+ W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); -+ else -+ W_REG(di->osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); -+ } else { -+ /* dma32 address extension */ -+ uint32 ae; -+ ASSERT(di->addrext); -+ -+ /* shift the high bit(s) from pa to ae */ -+ ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; -+ pa &= ~PCI32ADDR_HIGH; -+ -+ if (direction == DMA_TX) { -+ W_REG(di->osh, &di->d32txregs->addr, (pa + di->ddoffsetlow)); -+ SET_REG(di->osh, &di->d32txregs->control, XC_AE, ae <osh, &di->d32rxregs->addr, (pa + di->ddoffsetlow)); -+ SET_REG(di->osh, &di->d32rxregs->control, RC_AE, ae <name)); -+ OR_REG(di->osh, &di->d32txregs->control, XC_LE); -+} -+ -+static void -+_dma_rxinit(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxinit\n", di->name)); -+ -+ if (di->nrxd == 0) -+ return; -+ -+ di->rxin = di->rxout = 0; -+ -+ /* clear rx descriptor ring */ -+ BZERO_SM((void *)di->rxd32, (di->nrxd * sizeof(dma32dd_t))); -+ _dma_rxenable(di); -+ _dma_ddtable_init(di, DMA_RX, di->rxdpa); -+} -+ -+static void -+_dma_rxenable(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxenable\n", di->name)); -+ -+ W_REG(di->osh, &di->d32rxregs->control, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); -+} -+ -+/* !! rx entry routine, returns a pointer to the next frame received, -+ * or NULL if there are no more -+ */ -+static void * -+_dma_rx(dma_info_t *di) -+{ -+ void *p; -+ uint len; -+ int skiplen = 0; -+ -+ while ((p = _dma_getnextrxp(di, FALSE))) { -+ /* skip giant packets which span multiple rx descriptors */ -+ if (skiplen > 0) { -+ skiplen -= di->rxbufsize; -+ if (skiplen < 0) -+ skiplen = 0; -+ PKTFREE(di->osh, p, FALSE); -+ continue; -+ } -+ -+ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); -+ DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); -+ -+ /* bad frame length check */ -+ if (len > (di->rxbufsize - di->rxoffset)) { -+ DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); -+ if (len > 0) -+ skiplen = len - (di->rxbufsize - di->rxoffset); -+ PKTFREE(di->osh, p, FALSE); -+ di->hnddma.rxgiants++; -+ continue; -+ } -+ -+ /* set actual length */ -+ PKTSETLEN(di->osh, p, (di->rxoffset + len)); -+ -+ break; -+ } -+ -+ return (p); -+} -+ -+/* post receive buffers */ -+static void -+_dma_rxfill(dma_info_t *di) -+{ -+ void *p; -+ uint rxin, rxout; -+ uint32 flags = 0; -+ uint n; -+ uint i; -+ uint32 pa; -+ uint extra_offset = 0; -+ -+ /* -+ * Determine how many receive buffers we're lacking -+ * from the full complement, allocate, initialize, -+ * and post them, then update the chip rx lastdscr. -+ */ -+ -+ rxin = di->rxin; -+ rxout = di->rxout; -+ -+ n = di->nrxpost - NRXDACTIVE(rxin, rxout); -+ -+ DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); -+ -+ if (di->rxbufsize > BCMEXTRAHDROOM) -+ extra_offset = BCMEXTRAHDROOM; -+ -+ for (i = 0; i < n; i++) { -+ /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the -+ size to be allocated -+ */ -+ if ((p = PKTGET(di->osh, di->rxbufsize + extra_offset, -+ FALSE)) == NULL) { -+ DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); -+ di->hnddma.rxnobuf++; -+ break; -+ } -+ /* reserve an extra headroom, if applicable */ -+ if (extra_offset) -+ PKTPULL(di->osh, p, extra_offset); -+ -+ /* Do a cached write instead of uncached write since DMA_MAP -+ * will flush the cache. -+ */ -+ *(uint32*)(PKTDATA(di->osh, p)) = 0; -+ -+ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), -+ di->rxbufsize, DMA_RX, p); -+ -+ ASSERT(ISALIGNED(pa, 4)); -+ -+ /* save the free packet pointer */ -+ ASSERT(di->rxp[rxout] == NULL); -+ di->rxp[rxout] = p; -+ -+ /* reset flags for each descriptor */ -+ flags = 0; -+ if (rxout == (di->nrxd - 1)) -+ flags = CTRL_EOT; -+ dma32_dd_upd(di, di->rxd32, pa, rxout, &flags, di->rxbufsize); -+ rxout = NEXTRXD(rxout); -+ } -+ -+ di->rxout = rxout; -+ -+ /* update the chip lastdscr pointer */ -+ W_REG(di->osh, &di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); -+} -+ -+/* like getnexttxp but no reclaim */ -+static void * -+_dma_peeknexttxp(dma_info_t *di) -+{ -+ uint end, i; -+ -+ if (di->ntxd == 0) -+ return (NULL); -+ -+ end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); -+ -+ for (i = di->txin; i != end; i = NEXTTXD(i)) -+ if (di->txp[i]) -+ return (di->txp[i]); -+ -+ return (NULL); -+} -+ -+static void -+_dma_rxreclaim(dma_info_t *di) -+{ -+ void *p; -+ -+ /* "unused local" warning suppression for OSLs that -+ * define PKTFREE() without using the di->osh arg -+ */ -+ di = di; -+ -+ DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); -+ -+ while ((p = _dma_getnextrxp(di, TRUE))) -+ PKTFREE(di->osh, p, FALSE); -+} -+ -+static void * -+_dma_getnextrxp(dma_info_t *di, bool forceall) -+{ -+ if (di->nrxd == 0) -+ return (NULL); -+ -+ return dma32_getnextrxp(di, forceall); -+} -+ -+static void -+_dma_txblock(dma_info_t *di) -+{ -+ di->hnddma.txavail = 0; -+} -+ -+static void -+_dma_txunblock(dma_info_t *di) -+{ -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+} -+ -+static uint -+_dma_txactive(dma_info_t *di) -+{ -+ return (NTXDACTIVE(di->txin, di->txout)); -+} -+ -+static void -+_dma_counterreset(dma_info_t *di) -+{ -+ /* reset all software counter */ -+ di->hnddma.rxgiants = 0; -+ di->hnddma.rxnobuf = 0; -+ di->hnddma.txnobuf = 0; -+} -+ -+/* get the address of the var in order to change later */ -+static uintptr -+_dma_getvar(dma_info_t *di, char *name) -+{ -+ if (!strcmp(name, "&txavail")) -+ return ((uintptr) &(di->hnddma.txavail)); -+ else { -+ ASSERT(0); -+ } -+ return (0); -+} -+ -+void -+dma_txpioloopback(osl_t *osh, dma32regs_t *regs) -+{ -+ OR_REG(osh, ®s->control, XC_LE); -+} -+ -+ -+ -+/* 32 bits DMA functions */ -+static void -+dma32_txinit(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txinit\n", di->name)); -+ -+ if (di->ntxd == 0) -+ return; -+ -+ di->txin = di->txout = 0; -+ di->hnddma.txavail = di->ntxd - 1; -+ -+ /* clear tx descriptor ring */ -+ BZERO_SM((void *)di->txd32, (di->ntxd * sizeof(dma32dd_t))); -+ W_REG(di->osh, &di->d32txregs->control, XC_XE); -+ _dma_ddtable_init(di, DMA_TX, di->txdpa); -+} -+ -+static bool -+dma32_txenabled(dma_info_t *di) -+{ -+ uint32 xc; -+ -+ /* If the chip is dead, it is not enabled :-) */ -+ xc = R_REG(di->osh, &di->d32txregs->control); -+ return ((xc != 0xffffffff) && (xc & XC_XE)); -+} -+ -+static void -+dma32_txsuspend(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); -+ -+ if (di->ntxd == 0) -+ return; -+ -+ OR_REG(di->osh, &di->d32txregs->control, XC_SE); -+} -+ -+static void -+dma32_txresume(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_txresume\n", di->name)); -+ -+ if (di->ntxd == 0) -+ return; -+ -+ AND_REG(di->osh, &di->d32txregs->control, ~XC_SE); -+} -+ -+static bool -+dma32_txsuspended(dma_info_t *di) -+{ -+ return (di->ntxd == 0) || ((R_REG(di->osh, &di->d32txregs->control) & XC_SE) == XC_SE); -+} -+ -+static void -+dma32_txreclaim(dma_info_t *di, bool forceall) -+{ -+ void *p; -+ -+ DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); -+ -+ while ((p = dma32_getnexttxp(di, forceall))) -+ PKTFREE(di->osh, p, TRUE); -+} -+ -+static bool -+dma32_txstopped(dma_info_t *di) -+{ -+ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_STOPPED); -+} -+ -+static bool -+dma32_rxstopped(dma_info_t *di) -+{ -+ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_RS_MASK) == RS_RS_STOPPED); -+} -+ -+static bool -+dma32_alloc(dma_info_t *di, uint direction) -+{ -+ uint size; -+ uint ddlen; -+ void *va; -+ -+ ddlen = sizeof(dma32dd_t); -+ -+ size = (direction == DMA_TX) ? (di->ntxd * ddlen) : (di->nrxd * ddlen); -+ -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, D32RINGALIGN)) -+ size += D32RINGALIGN; -+ -+ -+ if (direction == DMA_TX) { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->txdpa, &di->tx_dmah)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(ntxd) failed\n", -+ di->name)); -+ return FALSE; -+ } -+ -+ di->txd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); -+ di->txdalign = (uint)((int8*)di->txd32 - (int8*)va); -+ di->txdpa += di->txdalign; -+ di->txdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->txd32, D32RINGALIGN)); -+ } else { -+ if ((va = DMA_ALLOC_CONSISTENT(di->osh, size, &di->rxdpa, &di->rx_dmah)) == NULL) { -+ DMA_ERROR(("%s: dma_attach: DMA_ALLOC_CONSISTENT(nrxd) failed\n", -+ di->name)); -+ return FALSE; -+ } -+ di->rxd32 = (dma32dd_t *) ROUNDUP((uintptr)va, D32RINGALIGN); -+ di->rxdalign = (uint)((int8*)di->rxd32 - (int8*)va); -+ di->rxdpa += di->rxdalign; -+ di->rxdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->rxd32, D32RINGALIGN)); -+ } -+ -+ return TRUE; -+} -+ -+static bool -+dma32_txreset(dma_info_t *di) -+{ -+ uint32 status; -+ -+ if (di->ntxd == 0) -+ return TRUE; -+ -+ /* suspend tx DMA first */ -+ W_REG(di->osh, &di->d32txregs->control, XC_SE); -+ SPINWAIT(((status = (R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK)) -+ != XS_XS_DISABLED) && -+ (status != XS_XS_IDLE) && -+ (status != XS_XS_STOPPED), -+ (10000)); -+ -+ W_REG(di->osh, &di->d32txregs->control, 0); -+ SPINWAIT(((status = (R_REG(di->osh, -+ &di->d32txregs->status) & XS_XS_MASK)) != XS_XS_DISABLED), -+ 10000); -+ -+ /* wait for the last transaction to complete */ -+ OSL_DELAY(300); -+ -+ return (status == XS_XS_DISABLED); -+} -+ -+static bool -+dma32_rxidle(dma_info_t *di) -+{ -+ DMA_TRACE(("%s: dma_rxidle\n", di->name)); -+ -+ if (di->nrxd == 0) -+ return TRUE; -+ -+ return ((R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK) == -+ R_REG(di->osh, &di->d32rxregs->ptr)); -+} -+ -+static bool -+dma32_rxreset(dma_info_t *di) -+{ -+ uint32 status; -+ -+ if (di->nrxd == 0) -+ return TRUE; -+ -+ W_REG(di->osh, &di->d32rxregs->control, 0); -+ SPINWAIT(((status = (R_REG(di->osh, -+ &di->d32rxregs->status) & RS_RS_MASK)) != RS_RS_DISABLED), -+ 10000); -+ -+ return (status == RS_RS_DISABLED); -+} -+ -+static bool -+dma32_rxenabled(dma_info_t *di) -+{ -+ uint32 rc; -+ -+ rc = R_REG(di->osh, &di->d32rxregs->control); -+ return ((rc != 0xffffffff) && (rc & RC_RE)); -+} -+ -+static bool -+dma32_txsuspendedidle(dma_info_t *di) -+{ -+ if (di->ntxd == 0) -+ return TRUE; -+ -+ if (!(R_REG(di->osh, &di->d32txregs->control) & XC_SE)) -+ return 0; -+ -+ if ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) != XS_XS_IDLE) -+ return 0; -+ -+ OSL_DELAY(2); -+ return ((R_REG(di->osh, &di->d32txregs->status) & XS_XS_MASK) == XS_XS_IDLE); -+} -+ -+/* !! tx entry routine -+ * supports full 32bit dma engine buffer addressing so -+ * dma buffers can cross 4 Kbyte page boundaries. -+ */ -+static int -+dma32_txfast(dma_info_t *di, void *p0, bool commit) -+{ -+ void *p, *next; -+ uchar *data; -+ uint len; -+ uint txout; -+ uint32 flags = 0; -+ uint32 pa; -+ -+ DMA_TRACE(("%s: dma_txfast\n", di->name)); -+ -+ txout = di->txout; -+ -+ /* -+ * Walk the chain of packet buffers -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ data = PKTDATA(di->osh, p); -+ len = PKTLEN(di->osh, p); -+ next = PKTNEXT(di->osh, p); -+ -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) -+ goto outoftxd; -+ -+ if (len == 0) -+ continue; -+ -+ /* get physical address of buffer start */ -+ pa = (uint32) DMA_MAP(di->osh, data, len, DMA_TX, p); -+ -+ flags = 0; -+ if (p == p0) -+ flags |= CTRL_SOF; -+ if (next == NULL) -+ flags |= (CTRL_IOC | CTRL_EOF); -+ if (txout == (di->ntxd - 1)) -+ flags |= CTRL_EOT; -+ -+ dma32_dd_upd(di, di->txd32, pa, txout, &flags, len); -+ ASSERT(di->txp[txout] == NULL); -+ -+ txout = NEXTTXD(txout); -+ } -+ -+ /* if last txd eof not set, fix it */ -+ if (!(flags & CTRL_EOF)) -+ W_SM(&di->txd32[PREVTXD(txout)].ctrl, BUS_SWAP32(flags | CTRL_IOC | CTRL_EOF)); -+ -+ /* save the packet */ -+ di->txp[PREVTXD(txout)] = p0; -+ -+ /* bump the tx descriptor index */ -+ di->txout = txout; -+ -+ /* kick the chip */ -+ if (commit) -+ W_REG(di->osh, &di->d32txregs->ptr, I2B(txout, dma32dd_t)); -+ -+ /* tx flow control */ -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (0); -+ -+outoftxd: -+ DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); -+ PKTFREE(di->osh, p0, TRUE); -+ di->hnddma.txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); -+} -+ -+/* -+ * Reclaim next completed txd (txds if using chained buffers) and -+ * return associated packet. -+ * If 'force' is true, reclaim txd(s) and return associated packet -+ * regardless of the value of the hardware "curr" pointer. -+ */ -+static void * -+dma32_getnexttxp(dma_info_t *di, bool forceall) -+{ -+ uint start, end, i; -+ void *txp; -+ -+ DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, forceall ? "all" : "")); -+ -+ if (di->ntxd == 0) -+ return (NULL); -+ -+ txp = NULL; -+ -+ start = di->txin; -+ if (forceall) -+ end = di->txout; -+ else -+ end = B2I(R_REG(di->osh, &di->d32txregs->status) & XS_CD_MASK, dma32dd_t); -+ -+ if ((start == 0) && (end > di->txout)) -+ goto bogus; -+ -+ for (i = start; i != end && !txp; i = NEXTTXD(i)) { -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->txd32[i].addr)) - di->dataoffsetlow), -+ (BUS_SWAP32(R_SM(&di->txd32[i].ctrl)) & CTRL_BC_MASK), -+ DMA_TX, di->txp[i]); -+ -+ W_SM(&di->txd32[i].addr, 0xdeadbeef); -+ txp = di->txp[i]; -+ di->txp[i] = NULL; -+ } -+ -+ di->txin = i; -+ -+ /* tx flow control */ -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (txp); -+ -+bogus: -+/* -+ DMA_ERROR(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", -+ start, end, di->txout, forceall)); -+*/ -+ return (NULL); -+} -+ -+static void * -+dma32_getnextrxp(dma_info_t *di, bool forceall) -+{ -+ uint i; -+ void *rxp; -+ -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma32_rxenabled(di)); -+ -+ i = di->rxin; -+ -+ /* return if no packets posted */ -+ if (i == di->rxout) -+ return (NULL); -+ -+ /* ignore curr if forceall */ -+ if (!forceall && (i == B2I(R_REG(di->osh, &di->d32rxregs->status) & RS_CD_MASK, dma32dd_t))) -+ return (NULL); -+ -+ /* get the packet pointer that corresponds to the rx descriptor */ -+ rxp = di->rxp[i]; -+ ASSERT(rxp); -+ di->rxp[i] = NULL; -+ -+ /* clear this packet from the descriptor ring */ -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), -+ di->rxbufsize, DMA_RX, rxp); -+ -+ W_SM(&di->rxd32[i].addr, 0xdeadbeef); -+ -+ di->rxin = NEXTRXD(i); -+ -+ return (rxp); -+} -+ -+/* -+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). -+ */ -+static void -+dma32_txrotate(dma_info_t *di) -+{ -+ uint ad; -+ uint nactive; -+ uint rot; -+ uint old, new; -+ uint32 w; -+ uint first, last; -+ -+ ASSERT(dma32_txsuspendedidle(di)); -+ -+ nactive = _dma_txactive(di); -+ ad = B2I(((R_REG(di->osh, &di->d32txregs->status) & XS_AD_MASK) >> XS_AD_SHIFT), dma32dd_t); -+ rot = TXD(ad - di->txin); -+ -+ ASSERT(rot < di->ntxd); -+ -+ /* full-ring case is a lot harder - don't worry about this */ -+ if (rot >= (di->ntxd - nactive)) { -+ DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); -+ return; -+ } -+ -+ first = di->txin; -+ last = PREVTXD(di->txout); -+ -+ /* move entries starting at last and moving backwards to first */ -+ for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { -+ new = TXD(old + rot); -+ -+ /* -+ * Move the tx dma descriptor. -+ * EOT is set only in the last entry in the ring. -+ */ -+ w = BUS_SWAP32(R_SM(&di->txd32[old].ctrl)) & ~CTRL_EOT; -+ if (new == (di->ntxd - 1)) -+ w |= CTRL_EOT; -+ W_SM(&di->txd32[new].ctrl, BUS_SWAP32(w)); -+ W_SM(&di->txd32[new].addr, R_SM(&di->txd32[old].addr)); -+ -+ /* zap the old tx dma descriptor address field */ -+ W_SM(&di->txd32[old].addr, BUS_SWAP32(0xdeadbeef)); -+ -+ /* move the corresponding txp[] entry */ -+ ASSERT(di->txp[new] == NULL); -+ di->txp[new] = di->txp[old]; -+ di->txp[old] = NULL; -+ } -+ -+ /* update txin and txout */ -+ di->txin = ad; -+ di->txout = TXD(di->txout + rot); -+ di->hnddma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ /* kick the chip */ -+ W_REG(di->osh, &di->d32txregs->ptr, I2B(di->txout, dma32dd_t)); -+} -+ -+ -+uint -+dma_addrwidth(sb_t *sbh, void *dmaregs) -+{ -+ dma32regs_t *dma32regs; -+ osl_t *osh; -+ -+ osh = sb_osh(sbh); -+ -+ /* Start checking for 32-bit / 30-bit addressing */ -+ dma32regs = (dma32regs_t *)dmaregs; -+ -+ /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */ -+ if ((BUSTYPE(sbh->bustype) == SB_BUS) || -+ ((BUSTYPE(sbh->bustype) == PCI_BUS) && sbh->buscoretype == SB_PCIE) || -+ (_dma32_addrext(osh, dma32regs))) -+ return (DMADDRWIDTH_32); -+ -+ /* Fallthru */ -+ return (DMADDRWIDTH_30); -+} -diff -urN linux.old/drivers/net/wl/hnddma.h linux.dev/drivers/net/wl/hnddma.h ---- linux.old/drivers/net/wl/hnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/hnddma.h 2006-04-28 02:20:44.000000000 +0200 -@@ -0,0 +1,156 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id: hnddma.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $ -+ */ -+ -+#ifndef _hnddma_h_ -+#define _hnddma_h_ -+ -+typedef const struct hnddma_pub hnddma_t; -+ -+/* dma function type */ -+typedef void (*di_detach_t)(hnddma_t *dmah); -+typedef bool (*di_txreset_t)(hnddma_t *dmah); -+typedef bool (*di_rxreset_t)(hnddma_t *dmah); -+typedef bool (*di_rxidle_t)(hnddma_t *dmah); -+typedef void (*di_txinit_t)(hnddma_t *dmah); -+typedef bool (*di_txenabled_t)(hnddma_t *dmah); -+typedef void (*di_rxinit_t)(hnddma_t *dmah); -+typedef void (*di_txsuspend_t)(hnddma_t *dmah); -+typedef void (*di_txresume_t)(hnddma_t *dmah); -+typedef bool (*di_txsuspended_t)(hnddma_t *dmah); -+typedef bool (*di_txsuspendedidle_t)(hnddma_t *dmah); -+typedef int (*di_txfast_t)(hnddma_t *dmah, void *p, bool commit); -+typedef void (*di_fifoloopbackenable_t)(hnddma_t *dmah); -+typedef bool (*di_txstopped_t)(hnddma_t *dmah); -+typedef bool (*di_rxstopped_t)(hnddma_t *dmah); -+typedef bool (*di_rxenable_t)(hnddma_t *dmah); -+typedef bool (*di_rxenabled_t)(hnddma_t *dmah); -+typedef void* (*di_rx_t)(hnddma_t *dmah); -+typedef void (*di_rxfill_t)(hnddma_t *dmah); -+typedef void (*di_txreclaim_t)(hnddma_t *dmah, bool forceall); -+typedef void (*di_rxreclaim_t)(hnddma_t *dmah); -+typedef uintptr (*di_getvar_t)(hnddma_t *dmah, char *name); -+typedef void* (*di_getnexttxp_t)(hnddma_t *dmah, bool forceall); -+typedef void* (*di_getnextrxp_t)(hnddma_t *dmah, bool forceall); -+typedef void* (*di_peeknexttxp_t)(hnddma_t *dmah); -+typedef void (*di_txblock_t)(hnddma_t *dmah); -+typedef void (*di_txunblock_t)(hnddma_t *dmah); -+typedef uint (*di_txactive_t)(hnddma_t *dmah); -+typedef void (*di_txrotate_t)(hnddma_t *dmah); -+typedef void (*di_counterreset_t)(hnddma_t *dmah); -+typedef char* (*di_dump_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); -+typedef char* (*di_dumptx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); -+typedef char* (*di_dumprx_t)(hnddma_t *dmah, struct bcmstrbuf *b, bool dumpring); -+ -+/* dma opsvec */ -+typedef struct di_fcn_s { -+ di_detach_t detach; -+ di_txinit_t txinit; -+ di_txreset_t txreset; -+ di_txenabled_t txenabled; -+ di_txsuspend_t txsuspend; -+ di_txresume_t txresume; -+ di_txsuspended_t txsuspended; -+ di_txsuspendedidle_t txsuspendedidle; -+ di_txfast_t txfast; -+ di_txstopped_t txstopped; -+ di_txreclaim_t txreclaim; -+ di_getnexttxp_t getnexttxp; -+ di_peeknexttxp_t peeknexttxp; -+ di_txblock_t txblock; -+ di_txunblock_t txunblock; -+ di_txactive_t txactive; -+ di_txrotate_t txrotate; -+ -+ di_rxinit_t rxinit; -+ di_rxreset_t rxreset; -+ di_rxidle_t rxidle; -+ di_rxstopped_t rxstopped; -+ di_rxenable_t rxenable; -+ di_rxenabled_t rxenabled; -+ di_rx_t rx; -+ di_rxfill_t rxfill; -+ di_rxreclaim_t rxreclaim; -+ di_getnextrxp_t getnextrxp; -+ -+ di_fifoloopbackenable_t fifoloopbackenable; -+ di_getvar_t d_getvar; -+ di_counterreset_t counterreset; -+ di_dump_t dump; -+ di_dumptx_t dumptx; -+ di_dumprx_t dumprx; -+ uint endnum; -+} di_fcn_t; -+ -+/* -+ * Exported data structure (read-only) -+ */ -+/* export structure */ -+struct hnddma_pub { -+ di_fcn_t di_fn; /* DMA function pointers */ -+ uint txavail; /* # free tx descriptors */ -+ -+ /* rx error counters */ -+ uint rxgiants; /* rx giant frames */ -+ uint rxnobuf; /* rx out of dma descriptors */ -+ /* tx error counters */ -+ uint txnobuf; /* tx out of dma descriptors */ -+}; -+ -+ -+extern hnddma_t * dma_attach(osl_t *osh, char *name, sb_t *sbh, void *dmaregstx, void *dmaregsrx, -+ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, -+ uint *msg_level); -+#define dma_detach(di) ((di)->di_fn.detach(di)) -+#define dma_txreset(di) ((di)->di_fn.txreset(di)) -+#define dma_rxreset(di) ((di)->di_fn.rxreset(di)) -+#define dma_rxidle(di) ((di)->di_fn.rxidle(di)) -+#define dma_txinit(di) ((di)->di_fn.txinit(di)) -+#define dma_txenabled(di) ((di)->di_fn.txenabled(di)) -+#define dma_rxinit(di) ((di)->di_fn.rxinit(di)) -+#define dma_txsuspend(di) ((di)->di_fn.txsuspend(di)) -+#define dma_txresume(di) ((di)->di_fn.txresume(di)) -+#define dma_txsuspended(di) ((di)->di_fn.txsuspended(di)) -+#define dma_txsuspendedidle(di) ((di)->di_fn.txsuspendedidle(di)) -+#define dma_txfast(di, p, commit) ((di)->di_fn.txfast(di, p, commit)) -+#define dma_fifoloopbackenable(di) ((di)->di_fn.fifoloopbackenable(di)) -+#define dma_txstopped(di) ((di)->di_fn.txstopped(di)) -+#define dma_rxstopped(di) ((di)->di_fn.rxstopped(di)) -+#define dma_rxenable(di) ((di)->di_fn.rxenable(di)) -+#define dma_rxenabled(di) ((di)->di_fn.rxenabled(di)) -+#define dma_rx(di) ((di)->di_fn.rx(di)) -+#define dma_rxfill(di) ((di)->di_fn.rxfill(di)) -+#define dma_txreclaim(di, forceall) ((di)->di_fn.txreclaim(di, forceall)) -+#define dma_rxreclaim(di) ((di)->di_fn.rxreclaim(di)) -+#define dma_getvar(di, name) ((di)->di_fn.d_getvar(di, name)) -+#define dma_getnexttxp(di, forceall) ((di)->di_fn.getnexttxp(di, forceall)) -+#define dma_getnextrxp(di, forceall) ((di)->di_fn.getnextrxp(di, forceall)) -+#define dma_peeknexttxp(di) ((di)->di_fn.peeknexttxp(di)) -+#define dma_txblock(di) ((di)->di_fn.txblock(di)) -+#define dma_txunblock(di) ((di)->di_fn.txunblock(di)) -+#define dma_txactive(di) ((di)->di_fn.txactive(di)) -+#define dma_txrotate(di) ((di)->di_fn.txrotate(di)) -+#define dma_counterreset(di) ((di)->di_fn.counterreset(di)) -+ -+#define DMA_DUMP_SIZE 2048 -+/* return addresswidth allowed -+ * This needs to be done after SB attach but before dma attach. -+ * SB attach provides ability to probe backplane and dma core capabilities -+ * This info is needed by DMA_ALLOC_CONSISTENT in dma attach -+ */ -+extern uint dma_addrwidth(sb_t *sbh, void *dmaregs); -+ -+/* pio helpers */ -+void dma_txpioloopback(osl_t *osh, dma32regs_t *); -+ -+#endif /* _hnddma_h_ */ -diff -urN linux.old/drivers/net/wl/linux_osl.c linux.dev/drivers/net/wl/linux_osl.c ---- linux.old/drivers/net/wl/linux_osl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/linux_osl.c 2006-04-28 02:29:46.000000000 +0200 -@@ -0,0 +1,269 @@ -+/* -+ * Linux OS Independent Layer -+ * -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id: linux_osl.c,v 1.1.1.14 2006/04/08 06:13:39 honor Exp $ -+ */ -+ -+#define LINUX_OSL -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "linux_osl.h" -+#include -+#include -+#ifdef mips -+#include -+#endif /* mips */ -+#include -+ -+#define PCI_CFG_RETRY 10 -+ -+#define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */ -+#define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ -+ -+typedef struct bcm_mem_link { -+ struct bcm_mem_link *prev; -+ struct bcm_mem_link *next; -+ uint size; -+ int line; -+ char file[BCM_MEM_FILENAME_LEN]; -+} bcm_mem_link_t; -+ -+static int16 linuxbcmerrormap[] = \ -+{ 0, /* 0 */ -+ -EINVAL, /* BCME_ERROR */ -+ -EINVAL, /* BCME_BADARG */ -+ -EINVAL, /* BCME_BADOPTION */ -+ -EINVAL, /* BCME_NOTUP */ -+ -EINVAL, /* BCME_NOTDOWN */ -+ -EINVAL, /* BCME_NOTAP */ -+ -EINVAL, /* BCME_NOTSTA */ -+ -EINVAL, /* BCME_BADKEYIDX */ -+ -EINVAL, /* BCME_RADIOOFF */ -+ -EINVAL, /* BCME_NOTBANDLOCKED */ -+ -EINVAL, /* BCME_NOCLK */ -+ -EINVAL, /* BCME_BADRATESET */ -+ -EINVAL, /* BCME_BADBAND */ -+ -E2BIG, /* BCME_BUFTOOSHORT */ -+ -E2BIG, /* BCME_BUFTOOLONG */ -+ -EBUSY, /* BCME_BUSY */ -+ -EINVAL, /* BCME_NOTASSOCIATED */ -+ -EINVAL, /* BCME_BADSSIDLEN */ -+ -EINVAL, /* BCME_OUTOFRANGECHAN */ -+ -EINVAL, /* BCME_BADCHAN */ -+ -EFAULT, /* BCME_BADADDR */ -+ -ENOMEM, /* BCME_NORESOURCE */ -+ -EOPNOTSUPP, /* BCME_UNSUPPORTED */ -+ -EMSGSIZE, /* BCME_BADLENGTH */ -+ -EINVAL, /* BCME_NOTREADY */ -+ -EPERM, /* BCME_NOTPERMITTED */ -+ -ENOMEM, /* BCME_NOMEM */ -+ -EINVAL, /* BCME_ASSOCIATED */ -+ -ERANGE, /* BCME_RANGE */ -+ -EINVAL, /* BCME_NOTFOUND */ -+ -EINVAL, /* BCME_WME_NOT_ENABLED */ -+ -EINVAL, /* BCME_TSPEC_NOTFOUND */ -+ -EINVAL, /* BCME_ACM_NOTSUPPORTED */ -+ -EINVAL, /* BCME_NOT_WME_ASSOCIATION */ -+ -EIO, /* BCME_SDIO_ERROR */ -+ -ENODEV /* BCME_DONGLE_DOWN */ -+}; -+ -+/* translate bcmerrors into linux errors */ -+int -+osl_error(int bcmerror) -+{ -+ int abs_bcmerror; -+ int array_size = ARRAYSIZE(linuxbcmerrormap); -+ -+ abs_bcmerror = ABS(bcmerror); -+ -+ if (bcmerror > 0) -+ abs_bcmerror = 0; -+ -+ else if (abs_bcmerror >= array_size) -+ abs_bcmerror = BCME_ERROR; -+ -+ return linuxbcmerrormap[abs_bcmerror]; -+} -+ -+osl_t * -+osl_attach(void *pdev, bool pkttag) -+{ -+ osl_t *osh; -+ -+ osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); -+ ASSERT(osh); -+ -+ bzero(osh, sizeof(osl_t)); -+ -+ /* -+ * check the cases where -+ * 1.Error code Added to bcmerror table, but forgot to add it to the OS -+ * dependent error code -+ * 2. Error code is added to the bcmerror table, but forgot to add the -+ * corresponding errorstring(dummy call to bcmerrorstr) -+ */ -+ bcmerrorstr(0); -+ ASSERT(ABS(BCME_LAST) == (ARRAYSIZE(linuxbcmerrormap) - 1)); -+ -+ osh->magic = OS_HANDLE_MAGIC; -+ osh->malloced = 0; -+ osh->failed = 0; -+ osh->dbgmem_list = NULL; -+ osh->pdev = pdev; -+ osh->pub.pkttag = pkttag; -+ -+ return osh; -+} -+ -+void -+osl_detach(osl_t *osh) -+{ -+ if (osh == NULL) -+ return; -+ -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ kfree(osh); -+} -+ -+/* Return a new packet. zero out pkttag */ -+void* -+osl_pktget(osl_t *osh, uint len, bool send) -+{ -+ struct sk_buff *skb; -+ -+ if ((skb = dev_alloc_skb(len))) { -+ skb_put(skb, len); -+ skb->priority = 0; -+ -+#ifdef BCMDBG_PKT -+ pktlist_add(&(osh->pktlist), (void *) skb); -+#endif /* BCMDBG_PKT */ -+ -+ osh->pub.pktalloced++; -+ } -+ -+ return ((void*) skb); -+} -+ -+/* Free the driver packet. Free the tag if present */ -+void -+osl_pktfree(osl_t *osh, void *p) -+{ -+ struct sk_buff *skb, *nskb; -+ -+ skb = (struct sk_buff*) p; -+ -+ /* perversion: we use skb->next to chain multi-skb packets */ -+ while (skb) { -+ nskb = skb->next; -+ skb->next = NULL; -+ -+#ifdef BCMDBG_PKT -+ pktlist_remove(&(osh->pktlist), (void *) skb); -+#endif /* BCMDBG_PKT */ -+ -+ if (skb->destructor) { -+ /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists -+ */ -+ dev_kfree_skb_any(skb); -+ } else { -+ /* can free immediately (even in_irq()) if destructor does not exist */ -+ dev_kfree_skb(skb); -+ } -+ -+ osh->pub.pktalloced--; -+ -+ skb = nskb; -+ } -+} -+ -+void* -+osl_malloc(osl_t *osh, uint size) -+{ -+ void *addr; -+ -+ /* only ASSERT if osh is defined */ -+ if (osh) -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ -+ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { -+ if (osh) -+ osh->failed++; -+ return (NULL); -+ } -+ if (osh) -+ osh->malloced += size; -+ -+ return (addr); -+} -+ -+void -+osl_mfree(osl_t *osh, void *addr, uint size) -+{ -+ if (osh) { -+ ASSERT(osh->magic == OS_HANDLE_MAGIC); -+ osh->malloced -= size; -+ } -+ kfree(addr); -+} -+ -+uint -+osl_malloced(osl_t *osh) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (osh->malloced); -+} -+ -+uint osl_malloc_failed(osl_t *osh) -+{ -+ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); -+ return (osh->failed); -+} -+ -+#undef osl_delay -+void -+osl_delay(uint usec) -+{ -+ OSL_DELAY(usec); -+} -+ -+/* Clone a packet. -+ * The pkttag contents are NOT cloned. -+ */ -+void * -+osl_pktdup(osl_t *osh, void *skb) -+{ -+ void * p; -+ -+ if ((p = skb_clone((struct sk_buff*)skb, GFP_ATOMIC)) == NULL) -+ return NULL; -+ -+ /* skb_clone copies skb->cb.. we don't want that */ -+ if (osh->pub.pkttag) -+ bzero((void*)((struct sk_buff *)p)->cb, OSL_PKTTAG_SZ); -+ -+ /* Increment the packet counter */ -+ osh->pub.pktalloced++; -+ return (p); -+} -+ -+uint -+osl_pktalloced(osl_t *osh) -+{ -+ return (osh->pub.pktalloced); -+} -+ -diff -urN linux.old/drivers/net/wl/linux_osl.h linux.dev/drivers/net/wl/linux_osl.h ---- linux.old/drivers/net/wl/linux_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/linux_osl.h 2006-05-02 17:44:29.000000000 +0200 -@@ -0,0 +1,171 @@ -+/* -+ * Linux OS Independent Layer -+ * -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id: linux_osl.h,v 1.1.1.13 2006/04/08 06:13:39 honor Exp $ -+ */ -+ -+#ifndef _linux_osl_h_ -+#define _linux_osl_h_ -+ -+#include -+#include -+#include -+ -+#define OSL_PKTTAG_SZ 32 /* Size of PktTag */ -+ -+/* osl handle type forward declaration */ -+typedef struct osl_dmainfo osldma_t; -+ -+/* OSL initialization */ -+extern osl_t *osl_attach(void *pdev, bool pkttag); -+extern void osl_detach(osl_t *osh); -+ -+/* host/bus architecture-specific byte swap */ -+#define BUS_SWAP32(v) (v) -+#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) -+ -+extern void *osl_malloc(osl_t *osh, uint size); -+extern void osl_mfree(osl_t *osh, void *addr, uint size); -+extern uint osl_malloced(osl_t *osh); -+extern uint osl_malloc_failed(osl_t *osh); -+ -+/* API for DMA addressing capability */ -+#define DMA_MAP(osh, va, size, direction, p) \ -+ osl_dma_map((osh), (va), (size), (direction)) -+#define DMA_UNMAP(osh, pa, size, direction, p) \ -+ osl_dma_unmap((osh), (pa), (size), (direction)) -+static inline uint -+osl_dma_map(void *osh, void *va, uint size, int direction) -+{ -+ int dir; -+ struct pci_dev *dev; -+ -+ dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev); -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ return (pci_map_single(dev, va, size, dir)); -+} -+ -+static inline void -+osl_dma_unmap(void *osh, uint pa, uint size, int direction) -+{ -+ int dir; -+ struct pci_dev *dev; -+ -+ dev = (osh == NULL ? NULL : ((osl_t *)osh)->pdev); -+ dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ pci_unmap_single(dev, (uint32)pa, size, dir); -+} -+ -+#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) -+#define DMA_CONSISTENT_ALIGN PAGE_SIZE -+#define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah) \ -+ osl_dma_alloc_consistent((osh), (size), (pap)) -+#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ -+ osl_dma_free_consistent((osh), (void*)(va), (size), (pa)) -+static inline void* -+osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) -+{ -+ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); -+} -+ -+static inline void -+osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) -+{ -+ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); -+} -+ -+ -+/* register access macros */ -+#if defined(BCMJTAG) -+#include -+#define R_REG(osh, r) bcmjtag_read(NULL, (uint32)(r), sizeof(*(r))) -+#define W_REG(osh, r, v) bcmjtag_write(NULL, (uint32)(r), (uint32)(v), sizeof(*(r))) -+#endif /* defined(BCMSDIO) */ -+ -+/* packet primitives */ -+#define PKTGET(osh, len, send) osl_pktget((osh), (len), (send)) -+#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb)) -+#define PKTDATA(osh, skb) (((struct sk_buff*)(skb))->data) -+#define PKTLEN(osh, skb) (((struct sk_buff*)(skb))->len) -+#define PKTHEADROOM(osh, skb) (PKTDATA(osh, skb)-(((struct sk_buff*)(skb))->head)) -+#define PKTTAILROOM(osh, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) -+#define PKTNEXT(osh, skb) (((struct sk_buff*)(skb))->next) -+#define PKTSETNEXT(osh, skb, x) (((struct sk_buff*)(skb))->next = (struct sk_buff*)(x)) -+#define PKTSETLEN(osh, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) -+#define PKTPUSH(osh, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) -+#define PKTPULL(osh, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) -+#define PKTDUP(osh, skb) osl_pktdup((osh), (skb)) -+#define PKTTAG(skb) ((void*)(((struct sk_buff*)(skb))->cb)) -+#define PKTALLOCED(osh) osl_pktalloced((osh)) -+#define PKTLIST_DUMP(osh, buf) -+ -+/* Convert a native(OS) packet to driver packet. -+ * In the process, native packet is destroyed, there is no copying -+ * Also, a packettag is zeroed out -+ */ -+static INLINE void * -+osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb) -+{ -+ struct sk_buff *nskb; -+ -+ if (osh->pkttag) -+ bzero((void*)skb->cb, OSL_PKTTAG_SZ); -+ -+ /* Increment the packet counter */ -+ for (nskb = skb; nskb; nskb = nskb->next) { -+ osh->pktalloced++; -+ } -+ -+ return (void *)skb; -+} -+#define PKTFRMNATIVE(osh, skb) osl_pkt_frmnative(((struct osl_pubinfo *)osh), \ -+ (struct sk_buff*)(skb)) -+ -+/* Convert a driver packet to native(OS) packet -+ * In the process, packettag is zeroed out before sending up -+ * IP code depends on skb->cb to be setup correctly with various options -+ * In our case, that means it should be 0 -+ */ -+static INLINE struct sk_buff * -+osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) -+{ -+ struct sk_buff *nskb; -+ -+ if (osh->pkttag) -+ bzero(((struct sk_buff*)pkt)->cb, OSL_PKTTAG_SZ); -+ -+ /* Decrement the packet counter */ -+ for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) { -+ osh->pktalloced--; -+ } -+ -+ return (struct sk_buff *)pkt; -+} -+#define PKTTONATIVE(osh, pkt) osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt)) -+ -+#define PKTLINK(skb) (((struct sk_buff*)(skb))->prev) -+#define PKTSETLINK(skb, x) (((struct sk_buff*)(skb))->prev = (struct sk_buff*)(x)) -+#define PKTPRIO(skb) (((struct sk_buff*)(skb))->priority) -+#define PKTSETPRIO(skb, x) (((struct sk_buff*)(skb))->priority = (x)) -+#define PKTSHARED(skb) (((struct sk_buff*)(skb))->cloned) -+ -+extern void *osl_pktget(osl_t *osh, uint len, bool send); -+extern void osl_pktfree(osl_t *osh, void *skb); -+extern void *osl_pktdup(osl_t *osh, void *skb); -+extern uint osl_pktalloced(osl_t *osh); -+ -+#define OSL_ERROR(bcmerror) osl_error(bcmerror) -+extern int osl_error(int bcmerror); -+ -+/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -+#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ -+ -+#endif /* _linux_osl_h_ */ -diff -urN linux.old/drivers/net/wl/pktq.h linux.dev/drivers/net/wl/pktq.h ---- linux.old/drivers/net/wl/pktq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/pktq.h 2006-04-28 02:11:49.000000000 +0200 -@@ -0,0 +1,97 @@ -+/* -+ * Misc useful os-independent macros and functions. -+ * -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id: bcmutils.h,v 1.1.1.16 2006/04/08 06:13:39 honor Exp $ -+ */ -+ -+#ifndef _pktq_h_ -+#define _pktq_h_ -+#include -+ -+/* osl multi-precedence packet queue */ -+ -+#define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ -+#define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ -+ -+struct pktq { -+ struct pktq_prec { -+ void *head; /* first packet to dequeue */ -+ void *tail; /* last packet to dequeue */ -+ uint16 len; /* number of queued packets */ -+ uint16 max; /* maximum number of queued packets */ -+ } q[PKTQ_MAX_PREC]; -+ uint16 num_prec; /* number of precedences in use */ -+ uint16 hi_prec; /* rapid dequeue hint (>= highest non-empty prec) */ -+ uint16 max; /* total max packets */ -+ uint16 len; /* total number of packets */ -+}; -+ -+#define PKTQ_PREC_ITER(pq, prec) for (prec = (pq)->num_prec - 1; prec >= 0; prec--) -+ -+/* forward definition of ether_addr structure used by some function prototypes */ -+ -+struct ether_addr; -+ -+/* operations on a specific precedence in packet queue */ -+ -+#define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) -+#define pktq_plen(pq, prec) ((pq)->q[prec].len) -+#define pktq_pavail(pq, prec) ((pq)->q[prec].max - (pq)->q[prec].len) -+#define pktq_pfull(pq, prec) ((pq)->q[prec].len >= (pq)->q[prec].max) -+#define pktq_pempty(pq, prec) ((pq)->q[prec].len == 0) -+ -+#define pktq_ppeek(pq, prec) ((pq)->q[prec].head) -+#define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) -+ -+extern void *pktq_penq(struct pktq *pq, int prec, void *p); -+extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); -+extern void *pktq_pdeq(struct pktq *pq, int prec); -+extern void *pktq_pdeq_tail(struct pktq *pq, int prec); -+/* Empty the queue at particular precedence level */ -+extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir); -+/* Remove a specified packet from its queue */ -+extern bool pktq_pdel(struct pktq *pq, void *p, int prec); -+ -+/* operations on a set of precedences in packet queue */ -+ -+extern int pktq_mlen(struct pktq *pq, uint prec_bmp); -+extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); -+ -+/* operations on packet queue as a whole */ -+ -+#define pktq_len(pq) ((int)(pq)->len) -+#define pktq_max(pq) ((int)(pq)->max) -+#define pktq_avail(pq) ((int)((pq)->max - (pq)->len)) -+#define pktq_full(pq) ((pq)->len >= (pq)->max) -+#define pktq_empty(pq) ((pq)->len == 0) -+ -+/* operations for single precedence queues */ -+#define pktenq(pq, p) pktq_penq((pq), 0, (p)) -+#define pktenq_head(pq, p) pktq_penq_head((pq), 0, (p)) -+#define pktdeq(pq) pktq_pdeq((pq), 0) -+#define pktdeq_tail(pq) pktq_pdeq_tail((pq), 0) -+ -+extern void pktq_init(struct pktq *pq, int num_prec, int max_len); -+/* prec_out may be NULL if caller is not interested in return value */ -+extern void *pktq_deq(struct pktq *pq, int *prec_out); -+extern void *pktq_deq_tail(struct pktq *pq, int *prec_out); -+extern void *pktq_peek(struct pktq *pq, int *prec_out); -+extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); -+extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); /* Empty the entire queue */ -+ -+/* externs */ -+/* packet */ -+extern uint pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf); -+extern uint pkttotlen(osl_t *osh, void *p); -+extern void *pktlast(osl_t *osh, void *p); -+ -+extern void pktsetprio(void *pkt, bool update_vtag); -+ -+#endif /* _pktq_h_ */ -diff -urN linux.old/drivers/net/wl/sbhnddma.h linux.dev/drivers/net/wl/sbhnddma.h ---- linux.old/drivers/net/wl/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/wl/sbhnddma.h 2006-04-28 02:20:47.000000000 +0200 -@@ -0,0 +1,284 @@ -+/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine HW interface -+ * This supports the following chips: BCM42xx, 44xx, 47xx . -+ * -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id: sbhnddma.h,v 1.1.1.2 2006/02/27 03:43:16 honor Exp $ -+ */ -+ -+#ifndef _sbhnddma_h_ -+#define _sbhnddma_h_ -+ -+/* DMA structure: -+ * support two DMA engines: 32 bits address or 64 bit addressing -+ * basic DMA register set is per channel(transmit or receive) -+ * a pair of channels is defined for convenience -+ */ -+ -+ -+/* 32 bits addressing */ -+ -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 addr; /* descriptor ring base address (4K aligned) */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 status; /* current active descriptor, et al */ -+} dma32regs_t; -+ -+typedef volatile struct { -+ dma32regs_t xmt; /* dma tx channel */ -+ dma32regs_t rcv; /* dma rx channel */ -+} dma32regp_t; -+ -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma32diag_t; -+ -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl; /* misc control bits & bufcount */ -+ uint32 addr; /* data buffer address */ -+} dma32dd_t; -+ -+/* -+ * Each descriptor ring must be 4096byte aligned, and fit within a single 4096byte page. -+ */ -+#define D32MAXRINGSZ 4096 -+#define D32RINGALIGN 4096 -+#define D32MAXDD (D32MAXRINGSZ / sizeof (dma32dd_t)) -+ -+/* transmit channel control */ -+#define XC_XE ((uint32)1 << 0) /* transmit enable */ -+#define XC_SE ((uint32)1 << 1) /* transmit suspend request */ -+#define XC_LE ((uint32)1 << 2) /* loopback enable */ -+#define XC_FL ((uint32)1 << 4) /* flush request */ -+#define XC_AE ((uint32)3 << 16) /* address extension bits */ -+#define XC_AE_SHIFT 16 -+ -+/* transmit descriptor table pointer */ -+#define XP_LD_MASK 0xfff /* last valid descriptor */ -+ -+/* transmit channel status */ -+#define XS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define XS_XS_MASK 0xf000 /* transmit state */ -+#define XS_XS_SHIFT 12 -+#define XS_XS_DISABLED 0x0000 /* disabled */ -+#define XS_XS_ACTIVE 0x1000 /* active */ -+#define XS_XS_IDLE 0x2000 /* idle wait */ -+#define XS_XS_STOPPED 0x3000 /* stopped */ -+#define XS_XS_SUSP 0x4000 /* suspend pending */ -+#define XS_XE_MASK 0xf0000 /* transmit errors */ -+#define XS_XE_SHIFT 16 -+#define XS_XE_NOERR 0x00000 /* no error */ -+#define XS_XE_DPE 0x10000 /* descriptor protocol error */ -+#define XS_XE_DFU 0x20000 /* data fifo underrun */ -+#define XS_XE_BEBR 0x30000 /* bus error on buffer read */ -+#define XS_XE_BEDA 0x40000 /* bus error on descriptor access */ -+#define XS_AD_MASK 0xfff00000 /* active descriptor */ -+#define XS_AD_SHIFT 20 -+ -+/* receive channel control */ -+#define RC_RE ((uint32)1 << 0) /* receive enable */ -+#define RC_RO_MASK 0xfe /* receive frame offset */ -+#define RC_RO_SHIFT 1 -+#define RC_FM ((uint32)1 << 8) /* direct fifo receive (pio) mode */ -+#define RC_AE ((uint32)3 << 16) /* address extension bits */ -+#define RC_AE_SHIFT 16 -+ -+/* receive descriptor table pointer */ -+#define RP_LD_MASK 0xfff /* last valid descriptor */ -+ -+/* receive channel status */ -+#define RS_CD_MASK 0x0fff /* current descriptor pointer */ -+#define RS_RS_MASK 0xf000 /* receive state */ -+#define RS_RS_SHIFT 12 -+#define RS_RS_DISABLED 0x0000 /* disabled */ -+#define RS_RS_ACTIVE 0x1000 /* active */ -+#define RS_RS_IDLE 0x2000 /* idle wait */ -+#define RS_RS_STOPPED 0x3000 /* reserved */ -+#define RS_RE_MASK 0xf0000 /* receive errors */ -+#define RS_RE_SHIFT 16 -+#define RS_RE_NOERR 0x00000 /* no error */ -+#define RS_RE_DPE 0x10000 /* descriptor protocol error */ -+#define RS_RE_DFO 0x20000 /* data fifo overflow */ -+#define RS_RE_BEBW 0x30000 /* bus error on buffer write */ -+#define RS_RE_BEDA 0x40000 /* bus error on descriptor access */ -+#define RS_AD_MASK 0xfff00000 /* active descriptor */ -+#define RS_AD_SHIFT 20 -+ -+/* fifoaddr */ -+#define FA_OFF_MASK 0xffff /* offset */ -+#define FA_SEL_MASK 0xf0000 /* select */ -+#define FA_SEL_SHIFT 16 -+#define FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define FA_SEL_RDD 0x40000 /* receive dma data */ -+#define FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define FA_SEL_RSP 0xf0000 /* receive frame status pointers */ -+ -+/* descriptor control flags */ -+#define CTRL_BC_MASK 0x1fff /* buffer byte count */ -+#define CTRL_AE ((uint32)3 << 16) /* address extension bits */ -+#define CTRL_AE_SHIFT 16 -+#define CTRL_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define CTRL_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define CTRL_EOF ((uint32)1 << 30) /* end of frame */ -+#define CTRL_SOF ((uint32)1 << 31) /* start of frame */ -+ -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define CTRL_CORE_MASK 0x0ff00000 -+ -+/* 64 bits addressing */ -+ -+/* dma registers per channel(xmt or rcv) */ -+typedef volatile struct { -+ uint32 control; /* enable, et al */ -+ uint32 ptr; /* last descriptor posted to chip */ -+ uint32 addrlow; /* descriptor ring base address low 32-bits (8K aligned) */ -+ uint32 addrhigh; /* descriptor ring base address bits 63:32 (8K aligned) */ -+ uint32 status0; /* current descriptor, xmt state */ -+ uint32 status1; /* active descriptor, xmt error */ -+} dma64regs_t; -+ -+typedef volatile struct { -+ dma64regs_t tx; /* dma64 tx channel */ -+ dma64regs_t rx; /* dma64 rx channel */ -+} dma64regp_t; -+ -+typedef volatile struct { /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dma64diag_t; -+ -+/* -+ * DMA Descriptor -+ * Descriptors are only read by the hardware, never written back. -+ */ -+typedef volatile struct { -+ uint32 ctrl1; /* misc control bits & bufcount */ -+ uint32 ctrl2; /* buffer count and address extension */ -+ uint32 addrlow; /* memory address of the date buffer, bits 31:0 */ -+ uint32 addrhigh; /* memory address of the date buffer, bits 63:32 */ -+} dma64dd_t; -+ -+/* -+ * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical addresss. -+ */ -+#define D64MAXRINGSZ 8192 -+#define D64RINGALIGN 8192 -+#define D64MAXDD (D64MAXRINGSZ / sizeof (dma64dd_t)) -+ -+/* transmit channel control */ -+#define D64_XC_XE 0x00000001 /* transmit enable */ -+#define D64_XC_SE 0x00000002 /* transmit suspend request */ -+#define D64_XC_LE 0x00000004 /* loopback enable */ -+#define D64_XC_FL 0x00000010 /* flush request */ -+#define D64_XC_AE 0x00030000 /* address extension bits */ -+#define D64_XC_AE_SHIFT 16 -+ -+/* transmit descriptor table pointer */ -+#define D64_XP_LD_MASK 0x00000fff /* last valid descriptor */ -+ -+/* transmit channel status */ -+#define D64_XS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_XS0_XS_MASK 0xf0000000 /* transmit state */ -+#define D64_XS0_XS_SHIFT 28 -+#define D64_XS0_XS_DISABLED 0x00000000 /* disabled */ -+#define D64_XS0_XS_ACTIVE 0x10000000 /* active */ -+#define D64_XS0_XS_IDLE 0x20000000 /* idle wait */ -+#define D64_XS0_XS_STOPPED 0x30000000 /* stopped */ -+#define D64_XS0_XS_SUSP 0x40000000 /* suspend pending */ -+ -+#define D64_XS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_XS1_XE_MASK 0xf0000000 /* transmit errors */ -+#define D64_XS1_XE_SHIFT 28 -+#define D64_XS1_XE_NOERR 0x00000000 /* no error */ -+#define D64_XS1_XE_DPE 0x10000000 /* descriptor protocol error */ -+#define D64_XS1_XE_DFU 0x20000000 /* data fifo underrun */ -+#define D64_XS1_XE_DTE 0x30000000 /* data transfer error */ -+#define D64_XS1_XE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_XS1_XE_COREE 0x50000000 /* core error */ -+ -+/* receive channel control */ -+#define D64_RC_RE 0x00000001 /* receive enable */ -+#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ -+#define D64_RC_RO_SHIFT 1 -+#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ -+#define D64_RC_AE 0x00030000 /* address extension bits */ -+#define D64_RC_AE_SHIFT 16 -+ -+/* receive descriptor table pointer */ -+#define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ -+ -+/* receive channel status */ -+#define D64_RS0_CD_MASK 0x00001fff /* current descriptor pointer */ -+#define D64_RS0_RS_MASK 0xf0000000 /* receive state */ -+#define D64_RS0_RS_SHIFT 28 -+#define D64_RS0_RS_DISABLED 0x00000000 /* disabled */ -+#define D64_RS0_RS_ACTIVE 0x10000000 /* active */ -+#define D64_RS0_RS_IDLE 0x20000000 /* idle wait */ -+#define D64_RS0_RS_STOPPED 0x30000000 /* stopped */ -+#define D64_RS0_RS_SUSP 0x40000000 /* suspend pending */ -+ -+#define D64_RS1_AD_MASK 0x0001ffff /* active descriptor */ -+#define D64_RS1_RE_MASK 0xf0000000 /* receive errors */ -+#define D64_RS1_RE_SHIFT 28 -+#define D64_RS1_RE_NOERR 0x00000000 /* no error */ -+#define D64_RS1_RE_DPO 0x10000000 /* descriptor protocol error */ -+#define D64_RS1_RE_DFU 0x20000000 /* data fifo overflow */ -+#define D64_RS1_RE_DTE 0x30000000 /* data transfer error */ -+#define D64_RS1_RE_DESRE 0x40000000 /* descriptor read error */ -+#define D64_RS1_RE_COREE 0x50000000 /* core error */ -+ -+/* fifoaddr */ -+#define D64_FA_OFF_MASK 0xffff /* offset */ -+#define D64_FA_SEL_MASK 0xf0000 /* select */ -+#define D64_FA_SEL_SHIFT 16 -+#define D64_FA_SEL_XDD 0x00000 /* transmit dma data */ -+#define D64_FA_SEL_XDP 0x10000 /* transmit dma pointers */ -+#define D64_FA_SEL_RDD 0x40000 /* receive dma data */ -+#define D64_FA_SEL_RDP 0x50000 /* receive dma pointers */ -+#define D64_FA_SEL_XFD 0x80000 /* transmit fifo data */ -+#define D64_FA_SEL_XFP 0x90000 /* transmit fifo pointers */ -+#define D64_FA_SEL_RFD 0xc0000 /* receive fifo data */ -+#define D64_FA_SEL_RFP 0xd0000 /* receive fifo pointers */ -+#define D64_FA_SEL_RSD 0xe0000 /* receive frame status data */ -+#define D64_FA_SEL_RSP 0xf0000 /* receive frame status pointers */ -+ -+/* descriptor control flags 1 */ -+#define D64_CTRL1_EOT ((uint32)1 << 28) /* end of descriptor table */ -+#define D64_CTRL1_IOC ((uint32)1 << 29) /* interrupt on completion */ -+#define D64_CTRL1_EOF ((uint32)1 << 30) /* end of frame */ -+#define D64_CTRL1_SOF ((uint32)1 << 31) /* start of frame */ -+ -+/* descriptor control flags 2 */ -+#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count mask */ -+#define D64_CTRL2_AE 0x00030000 /* address extension bits */ -+#define D64_CTRL2_AE_SHIFT 16 -+ -+/* control flags in the range [27:20] are core-specific and not defined here */ -+#define D64_CTRL_CORE_MASK 0x0ff00000 -+ -+ -+#endif /* _sbhnddma_h_ */ diff -urN linux.old/drivers/parport/Config.in linux.dev/drivers/parport/Config.in --- linux.old/drivers/parport/Config.in 2006-04-27 18:04:38.000000000 +0200 +++ linux.dev/drivers/parport/Config.in 2006-04-27 19:24:19.000000000 +0200 -- cgit v1.2.3 From da030183afb2b6def6cfe87af7cf2796c4a4fb9c Mon Sep 17 00:00:00 2001 From: nbd Date: Mon, 26 Jun 2006 23:52:57 +0000 Subject: add missing exports git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@4089 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- target/linux/brcm-2.4/patches/001-bcm47xx.patch | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'target/linux/brcm-2.4/patches/001-bcm47xx.patch') diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch index dc0805e599..557d24ff3f 100644 --- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch +++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -1795,7 +1795,7 @@ diff -urN linux.old/arch/mips/bcm947xx/compressed/Makefile linux.dev/arch/mips/b diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/export.c --- linux.old/arch/mips/bcm947xx/export.c 1970-01-01 01:00:00.000000000 +0100 +++ linux.dev/arch/mips/bcm947xx/export.c 2006-04-28 02:57:34.000000000 +0200 -@@ -0,0 +1,62 @@ +@@ -0,0 +1,65 @@ +#include + +#define _export(n) \ @@ -1805,6 +1805,7 @@ diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/exp +_export(bcm947xx_sbh) + +_export(sb_attach) ++_export(sb_kattach) +_export(sb_boardtype) +_export(sb_boardvendor) +_export(sb_btcgpiowar) @@ -1827,6 +1828,7 @@ diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/exp +_export(sb_coreunit) +_export(sb_detach) +_export(sb_deviceremoved) ++_export(sb_gpiosetcore) +_export(sb_gpiocontrol) +_export(sb_gpioled) +_export(sb_gpioin) @@ -1858,6 +1860,7 @@ diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/exp + +_export(srom_read) +_export(srom_write) ++ diff -urN linux.old/arch/mips/bcm947xx/generic/Makefile linux.dev/arch/mips/bcm947xx/generic/Makefile --- linux.old/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ linux.dev/arch/mips/bcm947xx/generic/Makefile 2006-04-27 19:24:19.000000000 +0200 -- cgit v1.2.3 From cf123d2a166d297712ab7b7221af999a62643f98 Mon Sep 17 00:00:00 2001 From: nbd Date: Wed, 4 Oct 2006 20:05:48 +0000 Subject: add new rc.common for standardized init scripts, convert existing init scripts git-svn-id: svn://svn.openwrt.org/openwrt/branches/buildroot-ng/openwrt@4915 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- package/base-files/ar7-2.4/etc/init.d/S00adam2 | 16 +- .../base-files/brcm-2.4/etc/init.d/S05netconfig | 157 +-- .../base-files/brcm-2.6/etc/init.d/S05netconfig | 161 +-- package/base-files/default/etc/init.d/S10boot | 46 +- package/base-files/default/etc/init.d/S40network | 14 +- package/base-files/default/etc/init.d/S50httpd | 10 +- package/base-files/default/etc/init.d/S50telnet | 10 +- package/base-files/default/etc/init.d/S60cron | 14 +- package/base-files/default/etc/init.d/S98done | 11 - package/base-files/default/etc/init.d/rcS | 17 +- package/base-files/default/etc/rc.common | 77 ++ package/dnsmasq/files/dnsmasq.init | 107 +- package/dropbear/files/dropbear.init | 33 +- package/iptables/files/firewall.init | 206 ++-- package/madwifi/files/madwifi.init | 6 +- target/linux/brcm-2.4/patches/001-bcm47xx.patch | 1117 ++++++++++---------- 16 files changed, 1065 insertions(+), 937 deletions(-) delete mode 100755 package/base-files/default/etc/init.d/S98done create mode 100755 package/base-files/default/etc/rc.common (limited to 'target/linux/brcm-2.4/patches/001-bcm47xx.patch') diff --git a/package/base-files/ar7-2.4/etc/init.d/S00adam2 b/package/base-files/ar7-2.4/etc/init.d/S00adam2 index 0ca4c01453..5f5b3504c2 100755 --- a/package/base-files/ar7-2.4/etc/init.d/S00adam2 +++ b/package/base-files/ar7-2.4/etc/init.d/S00adam2 @@ -1,8 +1,12 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common # ADAM2 patcher for Netgear DG834 and compatible -MD5="$(md5sum /dev/mtdblock/0 | awk '{print $1}')" -[ "$MD5" = "0530bfdf00ec155f4182afd70da028c1" ] && { - mtd unlock adam2 - /sbin/adam2patcher /dev/mtdblock/0 +# Copyright (C) 2006 OpenWrt.org + +start() { + MD5="$(md5sum /dev/mtdblock/0 | awk '{print $1}')" + [ "$MD5" = "0530bfdf00ec155f4182afd70da028c1" ] && { + mtd unlock adam2 + /sbin/adam2patcher /dev/mtdblock/0 + } + rm -f /etc/init.d/S00adam2 /sbin/adam2patcher >&- 2>&- } -rm -f /etc/init.d/S00adam2 /sbin/adam2patcher >&- 2>&- diff --git a/package/base-files/brcm-2.4/etc/init.d/S05netconfig b/package/base-files/brcm-2.4/etc/init.d/S05netconfig index 175b9a9836..71092da559 100755 --- a/package/base-files/brcm-2.4/etc/init.d/S05netconfig +++ b/package/base-files/brcm-2.4/etc/init.d/S05netconfig @@ -1,86 +1,87 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org -[ -e /etc/config/network ] && exit 0 +start() { + [ -e /etc/config/network ] && exit 0 -mkdir -p /etc/config + mkdir -p /etc/config -( - if grep -E 'mtd0: 000(6|a)0000' /proc/mtd 2>&- >&-; then - # WGT634u - echo boardtype=wgt634u - else - strings /dev/mtdblock/3 - fi -) | awk ' -function p(cfgname, name) { - if (c[name] != "") print " option " cfgname " \"" c[name] "\"" -} - -BEGIN { - FS="=" - c["lan_ifname"]="eth0.0 wl0" - c["wan_ifname"]="eth0.1" - c["vlan0ports"]="1 2 3 4 5*" - c["vlan1ports"]="0 5" -} - -($1 == "boardnum") || ($1 == "boardtype") || ($1 == "boardflags") { - nvram[$1] = $2 -} - -END { - # v1 hardware - if (nvram["boardtype"] == "bcm94710dev") { - # Asus WL-500g - if (nvram["boardnum"] == "asusX") { - c["lan_ifname"]="eth0 eth1 wl0" # FIXME - c["wan_ifname"]="" - } + ( + if grep -E 'mtd0: 000(6|a)0000' /proc/mtd 2>&- >&-; then + # WGT634u + echo boardtype=wgt634u + else + strings /dev/mtdblock/3 + fi + ) | awk ' + function p(cfgname, name) { + if (c[name] != "") print " option " cfgname " \"" c[name] "\"" } - if (nvram["boardtype"] == "wgt634u") { - c["vlan0ports"] = "0 1 2 3 5*" - c["vlan1ports"] = "4 5" - c["lan_ifname"] = "eth0.0 ath0" + + BEGIN { + FS="=" + c["lan_ifname"]="eth0.0 wl0" + c["wan_ifname"]="eth0.1" + c["vlan0ports"]="1 2 3 4 5*" + c["vlan1ports"]="0 5" } - if ((nvram["boardtype"] == "0x0467") || (nvram["boardtype"] == "0x042f")) { - c["vlan0ports"] = "0 1 2 3 5*" - c["vlan1ports"] = "4 5" + + ($1 == "boardnum") || ($1 == "boardtype") || ($1 == "boardflags") { + nvram[$1] = $2 } - - # WAP54G - if ((nvram["boardnum"] == "2") || \ - (nvram["boardnum"] == "1024")) { - c["lan_ifname"]="eth0 wl0" - c["wan_ifname"]="" - } - - print "#### VLAN configuration " - print "config switch eth0" - p("vlan0", "vlan0ports") - p("vlan1", "vlan1ports") - print "" - print "" - print "#### Loopback configuration" - print "config interface loopback" - print " option ifname \"lo\"" - print " option proto static" - print " option ipaddr 127.0.0.1" - print " option netmask 255.0.0.0" - print "" - print "" - print "#### LAN configuration" - print "config interface lan" - print " option type bridge" - p("ifname", "lan_ifname") - print " option proto static" - print " option ipaddr 192.168.1.1" - print " option netmask 255.255.255.0" - print "" - print "" - print "#### WAN configuration" - print "config interface wan" - p("ifname", "wan_ifname") - print " option proto dhcp" + + END { + # v1 hardware + if (nvram["boardtype"] == "bcm94710dev") { + # Asus WL-500g + if (nvram["boardnum"] == "asusX") { + c["lan_ifname"]="eth0 eth1 wl0" # FIXME + c["wan_ifname"]="" + } + } + if (nvram["boardtype"] == "wgt634u") { + c["vlan0ports"] = "0 1 2 3 5*" + c["vlan1ports"] = "4 5" + c["lan_ifname"] = "eth0.0 ath0" + } + if ((nvram["boardtype"] == "0x0467") || (nvram["boardtype"] == "0x042f")) { + c["vlan0ports"] = "0 1 2 3 5*" + c["vlan1ports"] = "4 5" + } + + # WAP54G + if ((nvram["boardnum"] == "2") || \ + (nvram["boardnum"] == "1024")) { + c["lan_ifname"]="eth0 wl0" + c["wan_ifname"]="" + } + + print "#### VLAN configuration " + print "config switch eth0" + p("vlan0", "vlan0ports") + p("vlan1", "vlan1ports") + print "" + print "" + print "#### Loopback configuration" + print "config interface loopback" + print " option ifname \"lo\"" + print " option proto static" + print " option ipaddr 127.0.0.1" + print " option netmask 255.0.0.0" + print "" + print "" + print "#### LAN configuration" + print "config interface lan" + print " option type bridge" + p("ifname", "lan_ifname") + print " option proto static" + print " option ipaddr 192.168.1.1" + print " option netmask 255.255.255.0" + print "" + print "" + print "#### WAN configuration" + print "config interface wan" + p("ifname", "wan_ifname") + print " option proto dhcp" + }' > /etc/config/network } -' > /etc/config/network diff --git a/package/base-files/brcm-2.6/etc/init.d/S05netconfig b/package/base-files/brcm-2.6/etc/init.d/S05netconfig index 175b9a9836..e37633e18f 100755 --- a/package/base-files/brcm-2.6/etc/init.d/S05netconfig +++ b/package/base-files/brcm-2.6/etc/init.d/S05netconfig @@ -1,86 +1,87 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org -[ -e /etc/config/network ] && exit 0 - -mkdir -p /etc/config - -( - if grep -E 'mtd0: 000(6|a)0000' /proc/mtd 2>&- >&-; then - # WGT634u - echo boardtype=wgt634u - else - strings /dev/mtdblock/3 - fi -) | awk ' -function p(cfgname, name) { - if (c[name] != "") print " option " cfgname " \"" c[name] "\"" -} - -BEGIN { - FS="=" - c["lan_ifname"]="eth0.0 wl0" - c["wan_ifname"]="eth0.1" - c["vlan0ports"]="1 2 3 4 5*" - c["vlan1ports"]="0 5" -} - -($1 == "boardnum") || ($1 == "boardtype") || ($1 == "boardflags") { - nvram[$1] = $2 -} - -END { - # v1 hardware - if (nvram["boardtype"] == "bcm94710dev") { - # Asus WL-500g - if (nvram["boardnum"] == "asusX") { - c["lan_ifname"]="eth0 eth1 wl0" # FIXME - c["wan_ifname"]="" - } - } - if (nvram["boardtype"] == "wgt634u") { - c["vlan0ports"] = "0 1 2 3 5*" - c["vlan1ports"] = "4 5" - c["lan_ifname"] = "eth0.0 ath0" +start() { + [ -e /etc/config/network ] && exit 0 + + mkdir -p /etc/config + + ( + if grep -E 'mtd0: 000(6|a)0000' /proc/mtd 2>&- >&-; then + # WGT634u + echo boardtype=wgt634u + else + strings /dev/mtdblock/3 + fi + ) | awk ' + function p(cfgname, name) { + if (c[name] != "") print " option " cfgname " \"" c[name] "\"" } - if ((nvram["boardtype"] == "0x0467") || (nvram["boardtype"] == "0x042f")) { - c["vlan0ports"] = "0 1 2 3 5*" - c["vlan1ports"] = "4 5" + + BEGIN { + FS="=" + c["lan_ifname"]="eth0.0 wl0" + c["wan_ifname"]="eth0.1" + c["vlan0ports"]="1 2 3 4 5*" + c["vlan1ports"]="0 5" } - - # WAP54G - if ((nvram["boardnum"] == "2") || \ - (nvram["boardnum"] == "1024")) { - c["lan_ifname"]="eth0 wl0" - c["wan_ifname"]="" + + ($1 == "boardnum") || ($1 == "boardtype") || ($1 == "boardflags") { + nvram[$1] = $2 } - - print "#### VLAN configuration " - print "config switch eth0" - p("vlan0", "vlan0ports") - p("vlan1", "vlan1ports") - print "" - print "" - print "#### Loopback configuration" - print "config interface loopback" - print " option ifname \"lo\"" - print " option proto static" - print " option ipaddr 127.0.0.1" - print " option netmask 255.0.0.0" - print "" - print "" - print "#### LAN configuration" - print "config interface lan" - print " option type bridge" - p("ifname", "lan_ifname") - print " option proto static" - print " option ipaddr 192.168.1.1" - print " option netmask 255.255.255.0" - print "" - print "" - print "#### WAN configuration" - print "config interface wan" - p("ifname", "wan_ifname") - print " option proto dhcp" + + END { + # v1 hardware + if (nvram["boardtype"] == "bcm94710dev") { + # Asus WL-500g + if (nvram["boardnum"] == "asusX") { + c["lan_ifname"]="eth0 eth1 wl0" # FIXME + c["wan_ifname"]="" + } + } + if (nvram["boardtype"] == "wgt634u") { + c["vlan0ports"] = "0 1 2 3 5*" + c["vlan1ports"] = "4 5" + c["lan_ifname"] = "eth0.0 ath0" + } + if ((nvram["boardtype"] == "0x0467") || (nvram["boardtype"] == "0x042f")) { + c["vlan0ports"] = "0 1 2 3 5*" + c["vlan1ports"] = "4 5" + } + + # WAP54G + if ((nvram["boardnum"] == "2") || \ + (nvram["boardnum"] == "1024")) { + c["lan_ifname"]="eth0 wl0" + c["wan_ifname"]="" + } + + print "#### VLAN configuration " + print "config switch eth0" + p("vlan0", "vlan0ports") + p("vlan1", "vlan1ports") + print "" + print "" + print "#### Loopback configuration" + print "config interface loopback" + print " option ifname \"lo\"" + print " option proto static" + print " option ipaddr 127.0.0.1" + print " option netmask 255.0.0.0" + print "" + print "" + print "#### LAN configuration" + print "config interface lan" + print " option type bridge" + p("ifname", "lan_ifname") + print " option proto static" + print " option ipaddr 192.168.1.1" + print " option netmask 255.255.255.0" + print "" + print "" + print "#### WAN configuration" + print "config interface wan" + p("ifname", "wan_ifname") + print " option proto dhcp" + }' > /etc/config/network } -' > /etc/config/network diff --git a/package/base-files/default/etc/init.d/S10boot b/package/base-files/default/etc/init.d/S10boot index b361e156fe..77b5ca72d5 100755 --- a/package/base-files/default/etc/init.d/S10boot +++ b/package/base-files/default/etc/init.d/S10boot @@ -1,25 +1,25 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org -. /etc/functions.sh - -[ -f /proc/mounts ] || /sbin/mount_root -[ -f /proc/jffs2_bbc ] && echo "S" > /proc/jffs2_bbc -vconfig set_name_type DEV_PLUS_VID_NO_PAD - -HOSTNAME=${wan_hostname%%.*} -echo ${HOSTNAME:=OpenWrt}>/proc/sys/kernel/hostname - -mkdir -p /var/run -mkdir -p /var/log -mkdir -p /var/lock -touch /var/log/wtmp -touch /var/log/lastlog -[ "$FAILSAFE" = "true" ] && touch /tmp/.failsafe - -# manually trigger hotplug before loading modules -for iface in $(awk -F: '/:/ {print $1}' /proc/net/dev); do - /usr/bin/env -i ACTION=add INTERFACE="$iface" /sbin/hotplug net -done - -load_modules /etc/modules /etc/modules.d/* +start() { + [ -f /proc/mounts ] || /sbin/mount_root + [ -f /proc/jffs2_bbc ] && echo "S" > /proc/jffs2_bbc + vconfig set_name_type DEV_PLUS_VID_NO_PAD + + HOSTNAME=${wan_hostname%%.*} + echo ${HOSTNAME:=OpenWrt}>/proc/sys/kernel/hostname + + mkdir -p /var/run + mkdir -p /var/log + mkdir -p /var/lock + touch /var/log/wtmp + touch /var/log/lastlog + [ "$FAILSAFE" = "true" ] && touch /tmp/.failsafe + + # manually trigger hotplug before loading modules + for iface in $(awk -F: '/:/ {print $1}' /proc/net/dev); do + /usr/bin/env -i ACTION=add INTERFACE="$iface" /sbin/hotplug net + done + + load_modules /etc/modules /etc/modules.d/* +} diff --git a/package/base-files/default/etc/init.d/S40network b/package/base-files/default/etc/init.d/S40network index f2c3e22859..be045045e7 100755 --- a/package/base-files/default/etc/init.d/S40network +++ b/package/base-files/default/etc/init.d/S40network @@ -1,9 +1,11 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org -setup_switch() { return 0; } +start() { + setup_switch() { return 0; } + + include /lib/network + setup_switch + /sbin/wifi +} -. /etc/functions.sh -include /lib/network -setup_switch -/sbin/wifi diff --git a/package/base-files/default/etc/init.d/S50httpd b/package/base-files/default/etc/init.d/S50httpd index d278519e98..a05b10c094 100755 --- a/package/base-files/default/etc/init.d/S50httpd +++ b/package/base-files/default/etc/init.d/S50httpd @@ -1,4 +1,10 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org -[ -d /www ] && httpd -p 80 -h /www -r OpenWrt +start() { + [ -d /www ] && httpd -p 80 -h /www -r OpenWrt +} + +stop() { + killall httpd +} diff --git a/package/base-files/default/etc/init.d/S50telnet b/package/base-files/default/etc/init.d/S50telnet index 25242bdef8..228eac2b62 100755 --- a/package/base-files/default/etc/init.d/S50telnet +++ b/package/base-files/default/etc/init.d/S50telnet @@ -1,4 +1,10 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org -if awk -F: '/^root:/ && $2 !~ /\!/ {exit 1}' /etc/passwd 2>/dev/null; then telnetd -l /bin/login; fi +start() { + if awk -F: '/^root:/ && $2 !~ /\!/ {exit 1}' /etc/passwd 2>/dev/null; then telnetd -l /bin/login; fi +} + +stop() { + killall telnetd +} diff --git a/package/base-files/default/etc/init.d/S60cron b/package/base-files/default/etc/init.d/S60cron index 6df9b7dee9..a450c36dd2 100755 --- a/package/base-files/default/etc/init.d/S60cron +++ b/package/base-files/default/etc/init.d/S60cron @@ -1,6 +1,12 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org -mkdir -p /var/spool/cron -ln -s /etc/crontabs /var/spool/cron/crontabs -crond -c /etc/crontabs +start () { + mkdir -p /var/spool/cron + ln -s /etc/crontabs /var/spool/cron/crontabs + crond -c /etc/crontabs +} + +stop() { + killall crond +} diff --git a/package/base-files/default/etc/init.d/S98done b/package/base-files/default/etc/init.d/S98done deleted file mode 100755 index a1ea5ad438..0000000000 --- a/package/base-files/default/etc/init.d/S98done +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -# Copyright (C) 2006 OpenWrt.org - -sysctl -p >&- - -# automagically run firstboot -{ mount|grep "on / type tmpfs" 1>&-; } && { - lock /tmp/.switch2jffs - firstboot switch2jffs - lock -u /tmp/.switch2jffs -} diff --git a/package/base-files/default/etc/init.d/rcS b/package/base-files/default/etc/init.d/rcS index 2aa70910c3..7fae7f5b05 100755 --- a/package/base-files/default/etc/init.d/rcS +++ b/package/base-files/default/etc/init.d/rcS @@ -10,6 +10,17 @@ ${FAILSAFE:+exit} syslogd -C 16 #${log_ipaddr:+-L -R $log_ipaddr} klogd -for i in /etc/init.d/S*; do - $i start 2>&1 -done | logger -s -p 6 -t '' & +( + for i in /etc/init.d/S*; do + $i start 2>&1 + done + + sysctl -p >&- + + # automagically run firstboot + { mount|grep "on / type tmpfs" 1>&-; } && { + lock /tmp/.switch2jffs + firstboot switch2jffs + lock -u /tmp/.switch2jffs + } +) | logger -s -p 6 -t '' & diff --git a/package/base-files/default/etc/rc.common b/package/base-files/default/etc/rc.common new file mode 100755 index 0000000000..4a90a25b18 --- /dev/null +++ b/package/base-files/default/etc/rc.common @@ -0,0 +1,77 @@ +#!/bin/sh +. /etc/functions.sh + +start() { + return 0 +} + +stop() { + return 0 +} + +reload() { + return 1 +} + +restart() { + stop + start +} + +boot() { + start +} + +shutdown() { + return 0 +} + +disable() { + rm -f /etc/rc.d/${initscript##*/} +} + +enable() { + disable + ln -s /etc/init.d/${initscript##*/} /etc/rc.d/${initscript##*/} +} + +depends() { + return 0 +} + +help() { + cat <&- && dhcp_enable="${dhcp_enable:-0}" - -# dhcp_enable=0 disables the dhcp server -( - [ -z "$dhcp_enable" -o "$dhcp_enable" -eq 1 ] && { - # no existing DHCP server? - - # calculate settings - config_get ipaddr "$iface" ipaddr - config_get netmask "$iface" netmask - eval $(ipcalc $ipaddr $netmask ${dhcp_start:-100} ${dhcp_num:-150}) - - # and pass the args via config parser defines - echo "${dhcp_enable:+@define dhcp_enable 1}" - echo "@define netmask $NETMASK" - echo "@define start $START" - echo "@define end $END" - echo "@define lease ${dhcp_lease:-12h}" - } - - # ignore requests from wan interface - config_get wan_proto wan proto - config_get wan_ifname wan ifname - [ -z "$wan_proto" -o "$wan_proto" = "none" ] || echo "@define wan_ifname $wan_ifname" - - cat /etc/dnsmasq.conf -) | awk -f /usr/lib/parse-config.awk | dnsmasq -C /proc/self/fd/0 +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org + +start() { + include /lib/network + scan_interfaces + + # The following is to automatically configure the DHCP settings + # based on config settings. Feel free to replace all this crap + # with a simple "dnsmasq" and manage everything via the + # /etc/dnsmasq.conf config file + + [ -f /etc/dnsmasq.conf ] || exit + + args="" + iface=lan + config_get ifname "$iface" ifname + config_get proto "$iface" proto + + [ "$proto" = static ] && dhcp_enable="${dhcp_enable:-1}" + dhcp_start="${dhcp_start:-100}" + dhcp_num="${dhcp_num:-50}" + dhcp_lease="${dhcp_lease:-12h}" + + # if dhcp_enable is unset and there is a dhcp server on the network already, default to dhcp_enable=0 + [ -z "$dhcp_enable" ] && udhcpc -n -q -R -s /bin/true -i $ifname >&- && dhcp_enable="${dhcp_enable:-0}" + + # dhcp_enable=0 disables the dhcp server + ( + [ -z "$dhcp_enable" -o "$dhcp_enable" -eq 1 ] && { + # no existing DHCP server? + + # calculate settings + config_get ipaddr "$iface" ipaddr + config_get netmask "$iface" netmask + eval $(ipcalc $ipaddr $netmask ${dhcp_start:-100} ${dhcp_num:-150}) + + # and pass the args via config parser defines + echo "${dhcp_enable:+@define dhcp_enable 1}" + echo "@define netmask $NETMASK" + echo "@define start $START" + echo "@define end $END" + echo "@define lease ${dhcp_lease:-12h}" + } + + # ignore requests from wan interface + config_get wan_proto wan proto + config_get wan_ifname wan ifname + [ -z "$wan_proto" -o "$wan_proto" = "none" ] || echo "@define wan_ifname $wan_ifname" + + cat /etc/dnsmasq.conf + ) | awk -f /usr/lib/parse-config.awk | dnsmasq -C /proc/self/fd/0 +} + +stop() { + killall dnsmasq +} diff --git a/package/dropbear/files/dropbear.init b/package/dropbear/files/dropbear.init index 88fc288491..e0a4481bf9 100755 --- a/package/dropbear/files/dropbear.init +++ b/package/dropbear/files/dropbear.init @@ -1,16 +1,19 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common +# Copyright (C) 2006 OpenWrt.org -for type in rsa dss; do { - # check for keys - key=/etc/dropbear/dropbear_${type}_host_key - [ ! -f $key ] && { - # generate missing keys - mkdir -p /etc/dropbear - [ -x /usr/bin/dropbearkey ] && { - /usr/bin/dropbearkey -t $type -f $key 2>&- >&- && exec $0 $* - } & - exit 0 - } -}; done - -/usr/sbin/dropbear +start() { + for type in rsa dss; do { + # check for keys + key=/etc/dropbear/dropbear_${type}_host_key + [ ! -f $key ] && { + # generate missing keys + mkdir -p /etc/dropbear + [ -x /usr/bin/dropbearkey ] && { + /usr/bin/dropbearkey -t $type -f $key 2>&- >&- && exec $0 $* + } & + exit 0 + } + }; done + + /usr/sbin/dropbear +} diff --git a/package/iptables/files/firewall.init b/package/iptables/files/firewall.init index 4acd325a99..731485bcdd 100755 --- a/package/iptables/files/firewall.init +++ b/package/iptables/files/firewall.init @@ -1,103 +1,115 @@ -#!/bin/sh +#!/bin/sh /etc/rc.common # Copyright (C) 2006 OpenWrt.org ## Please make changes in /etc/firewall.user -. /etc/functions.sh -include /lib/network - -scan_interfaces -config_get WAN wan ifname -config_get LAN lan ifname - -## CLEAR TABLES -for T in filter nat; do - iptables -t $T -F - iptables -t $T -X -done - -iptables -N input_rule -iptables -N output_rule -iptables -N forwarding_rule - -iptables -t nat -N prerouting_rule -iptables -t nat -N postrouting_rule - -iptables -N LAN_ACCEPT -[ -z "$WAN" ] || iptables -A LAN_ACCEPT -i "$WAN" -j RETURN -iptables -A LAN_ACCEPT -j ACCEPT - -### INPUT -### (connections with the router as destination) - - # base case - iptables -P INPUT DROP - iptables -A INPUT -m state --state INVALID -j DROP - iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT - iptables -A INPUT -p tcp --tcp-flags SYN SYN --tcp-option \! 2 -j DROP - - # - # insert accept rule or to jump to new accept-check table here - # - iptables -A INPUT -j input_rule - - # allow - iptables -A INPUT -j LAN_ACCEPT # allow from lan/wifi interfaces - iptables -A INPUT -p icmp -j ACCEPT # allow ICMP - iptables -A INPUT -p gre -j ACCEPT # allow GRE - - # reject (what to do with anything not allowed earlier) - iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset - iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable - -### OUTPUT -### (connections with the router as source) - - # base case - iptables -P OUTPUT DROP - iptables -A OUTPUT -m state --state INVALID -j DROP - iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT - - # - # insert accept rule or to jump to new accept-check table here - # - iptables -A OUTPUT -j output_rule - - # allow - iptables -A OUTPUT -j ACCEPT #allow everything out - - # reject (what to do with anything not allowed earlier) - iptables -A OUTPUT -p tcp -j REJECT --reject-with tcp-reset - iptables -A OUTPUT -j REJECT --reject-with icmp-port-unreachable - -### FORWARDING -### (connections routed through the router) - - # base case - iptables -P FORWARD DROP - iptables -A FORWARD -m state --state INVALID -j DROP - iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu - iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT - - # - # insert accept rule or to jump to new accept-check table here - # - iptables -A FORWARD -j forwarding_rule - - # allow - iptables -A FORWARD -i br0 -o br0 -j ACCEPT - [ -z "$WAN" ] || iptables -A FORWARD -i $LAN -o $WAN -j ACCEPT - - # reject (what to do with anything not allowed earlier) - # uses the default -P DROP - -### MASQ - iptables -t nat -A PREROUTING -j prerouting_rule - iptables -t nat -A POSTROUTING -j postrouting_rule - [ -z "$WAN" ] || iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE +start() { + include /lib/network + scan_interfaces + + config_get WAN wan ifname + config_get LAN lan ifname + + ## CLEAR TABLES + for T in filter nat; do + iptables -t $T -F + iptables -t $T -X + done + + iptables -N input_rule + iptables -N output_rule + iptables -N forwarding_rule + + iptables -t nat -N prerouting_rule + iptables -t nat -N postrouting_rule + + iptables -N LAN_ACCEPT + [ -z "$WAN" ] || iptables -A LAN_ACCEPT -i "$WAN" -j RETURN + iptables -A LAN_ACCEPT -j ACCEPT + + ### INPUT + ### (connections with the router as destination) + + # base case + iptables -P INPUT DROP + iptables -A INPUT -m state --state INVALID -j DROP + iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT + iptables -A INPUT -p tcp --tcp-flags SYN SYN --tcp-option \! 2 -j DROP + + # + # insert accept rule or to jump to new accept-check table here + # + iptables -A INPUT -j input_rule + + # allow + iptables -A INPUT -j LAN_ACCEPT # allow from lan/wifi interfaces + iptables -A INPUT -p icmp -j ACCEPT # allow ICMP + iptables -A INPUT -p gre -j ACCEPT # allow GRE + + # reject (what to do with anything not allowed earlier) + iptables -A INPUT -p tcp -j REJECT --reject-with tcp-reset + iptables -A INPUT -j REJECT --reject-with icmp-port-unreachable + + ### OUTPUT + ### (connections with the router as source) + + # base case + iptables -P OUTPUT DROP + iptables -A OUTPUT -m state --state INVALID -j DROP + iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT + + # + # insert accept rule or to jump to new accept-check table here + # + iptables -A OUTPUT -j output_rule + + # allow + iptables -A OUTPUT -j ACCEPT #allow everything out + + # reject (what to do with anything not allowed earlier) + iptables -A OUTPUT -p tcp -j REJECT --reject-with tcp-reset + iptables -A OUTPUT -j REJECT --reject-with icmp-port-unreachable + + ### FORWARDING + ### (connections routed through the router) + + # base case + iptables -P FORWARD DROP + iptables -A FORWARD -m state --state INVALID -j DROP + iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu + iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT + + # + # insert accept rule or to jump to new accept-check table here + # + iptables -A FORWARD -j forwarding_rule + + # allow + iptables -A FORWARD -i br0 -o br0 -j ACCEPT + [ -z "$WAN" ] || iptables -A FORWARD -i $LAN -o $WAN -j ACCEPT + + # reject (what to do with anything not allowed earlier) + # uses the default -P DROP + + ### MASQ + iptables -t nat -A PREROUTING -j prerouting_rule + iptables -t nat -A POSTROUTING -j postrouting_rule + [ -z "$WAN" ] || iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE + + ## USER RULES + [ -f /etc/firewall.user ] && . /etc/firewall.user + [ -n "$WAN" -a -e /etc/config/firewall ] && { + awk -f /usr/lib/common.awk -f /usr/lib/firewall.awk /etc/config/firewall | ash + } +} -## USER RULES -[ -f /etc/firewall.user ] && . /etc/firewall.user -[ -n "$WAN" -a -e /etc/config/firewall ] && { - awk -f /usr/lib/common.awk -f /usr/lib/firewall.awk /etc/config/firewall | ash +stop() { + iptables -P INPUT ACCEPT + iptables -P OUTPUT ACCEPT + iptables -P FORWARD ACCEPT + iptables -F + iptables -t nat -P PREROUTING ACCEPT + iptables -t nat -P POSTROUTING ACCEPT + iptables -t nat -P OUTPUT ACCEPT + iptables -t nat -F } diff --git a/package/madwifi/files/madwifi.init b/package/madwifi/files/madwifi.init index b1e78c0930..73eb11017e 100644 --- a/package/madwifi/files/madwifi.init +++ b/package/madwifi/files/madwifi.init @@ -1,2 +1,4 @@ -#!/bin/sh -iwpriv ath0 mode 3 +#!/bin/sh /etc/rc.common +start() { + iwpriv ath0 mode 3 +} diff --git a/target/linux/brcm-2.4/patches/001-bcm47xx.patch b/target/linux/brcm-2.4/patches/001-bcm47xx.patch index 557d24ff3f..726eba8061 100644 --- a/target/linux/brcm-2.4/patches/001-bcm47xx.patch +++ b/target/linux/brcm-2.4/patches/001-bcm47xx.patch @@ -1,58 +1,6 @@ -diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile ---- linux.old/arch/mips/Makefile 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/arch/mips/Makefile 2006-04-27 19:24:19.000000000 +0200 -@@ -726,6 +726,19 @@ - endif - - # -+# Broadcom BCM947XX variants -+# -+ifdef CONFIG_BCM947XX -+LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o -+SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx -+LOADADDR := 0x80001000 -+ -+zImage: vmlinux -+ $(MAKE) -C arch/$(ARCH)/bcm947xx/compressed -+export LOADADDR -+endif -+ -+# - # Choosing incompatible machines durings configuration will result in - # error messages during linking. Select a default linkscript if - # none has been choosen above. -@@ -778,6 +791,7 @@ - $(MAKE) -C arch/$(ARCH)/tools clean - $(MAKE) -C arch/mips/baget clean - $(MAKE) -C arch/mips/lasat clean -+ $(MAKE) -C arch/mips/bcm947xx/compressed clean - - archmrproper: - @$(MAKEBOOT) mrproper -diff -urN linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Makefile ---- linux.old/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/Makefile 2006-05-02 17:46:22.000000000 +0200 -@@ -0,0 +1,17 @@ -+# -+# Makefile for the BCM947xx specific kernel interface routines -+# under Linux. -+# -+ -+EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER -+ -+O_TARGET := bcm947xx.o -+ -+export-objs := export.o -+obj-y := prom.o setup.o time.o sbmips.o gpio.o -+obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o -+obj-y += sbutils.o bcmutils.o bcmsrom.o hndchipc.o -+obj-$(CONFIG_PCI) += sbpci.o pcibios.o -+obj-y += export.o -+ -+include $(TOPDIR)/Rules.make diff -urN linux.old/arch/mips/bcm947xx/bcmsrom.c linux.dev/arch/mips/bcm947xx/bcmsrom.c --- linux.old/arch/mips/bcm947xx/bcmsrom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/bcmsrom.c 2006-04-27 20:32:48.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/bcmsrom.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,1212 @@ +/* + * Misc useful routines to access NIC SROM/OTP . @@ -1268,7 +1216,7 @@ diff -urN linux.old/arch/mips/bcm947xx/bcmsrom.c linux.dev/arch/mips/bcm947xx/bc + diff -urN linux.old/arch/mips/bcm947xx/bcmutils.c linux.dev/arch/mips/bcm947xx/bcmutils.c --- linux.old/arch/mips/bcm947xx/bcmutils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/bcmutils.c 2006-04-28 00:34:02.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/bcmutils.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,247 @@ +/* + * Misc useful OS-independent routines. @@ -1519,7 +1467,7 @@ diff -urN linux.old/arch/mips/bcm947xx/bcmutils.c linux.dev/arch/mips/bcm947xx/b + diff -urN linux.old/arch/mips/bcm947xx/cfe_env.c linux.dev/arch/mips/bcm947xx/cfe_env.c --- linux.old/arch/mips/bcm947xx/cfe_env.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/cfe_env.c 2006-04-27 19:24:19.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/cfe_env.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,234 @@ +/* + * NVRAM variable manipulation (Linux kernel half) @@ -1757,7 +1705,7 @@ diff -urN linux.old/arch/mips/bcm947xx/cfe_env.c linux.dev/arch/mips/bcm947xx/cf + diff -urN linux.old/arch/mips/bcm947xx/compressed/Makefile linux.dev/arch/mips/bcm947xx/compressed/Makefile --- linux.old/arch/mips/bcm947xx/compressed/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/compressed/Makefile 2006-04-27 19:24:19.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/compressed/Makefile 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,33 @@ +# +# Makefile for Broadcom BCM947XX boards @@ -1794,7 +1742,7 @@ diff -urN linux.old/arch/mips/bcm947xx/compressed/Makefile linux.dev/arch/mips/b + rm -f vmlinuz piggy diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/export.c --- linux.old/arch/mips/bcm947xx/export.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/export.c 2006-04-28 02:57:34.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/export.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,65 @@ +#include + @@ -1861,28 +1809,9 @@ diff -urN linux.old/arch/mips/bcm947xx/export.c linux.dev/arch/mips/bcm947xx/exp +_export(srom_read) +_export(srom_write) + -diff -urN linux.old/arch/mips/bcm947xx/generic/Makefile linux.dev/arch/mips/bcm947xx/generic/Makefile ---- linux.old/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/generic/Makefile 2006-04-27 19:24:19.000000000 +0200 -@@ -0,0 +1,15 @@ -+# -+# Makefile for the BCM947xx specific kernel interface routines -+# under Linux. -+# -+ -+.S.s: -+ $(CPP) $(AFLAGS) $< -o $*.s -+.S.o: -+ $(CC) $(AFLAGS) -c $< -o $*.o -+ -+O_TARGET := brcm.o -+ -+obj-y := int-handler.o irq.o -+ -+include $(TOPDIR)/Rules.make diff -urN linux.old/arch/mips/bcm947xx/generic/int-handler.S linux.dev/arch/mips/bcm947xx/generic/int-handler.S --- linux.old/arch/mips/bcm947xx/generic/int-handler.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/generic/int-handler.S 2006-04-27 19:24:19.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/generic/int-handler.S 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,51 @@ +/* + * Generic interrupt handler for Broadcom MIPS boards @@ -1937,7 +1866,7 @@ diff -urN linux.old/arch/mips/bcm947xx/generic/int-handler.S linux.dev/arch/mips + END(brcmIRQ) diff -urN linux.old/arch/mips/bcm947xx/generic/irq.c linux.dev/arch/mips/bcm947xx/generic/irq.c --- linux.old/arch/mips/bcm947xx/generic/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/generic/irq.c 2006-04-27 19:24:19.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/generic/irq.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,130 @@ +/* + * Generic interrupt control functions for Broadcom MIPS boards @@ -2069,9 +1998,29 @@ diff -urN linux.old/arch/mips/bcm947xx/generic/irq.c linux.dev/arch/mips/bcm947x + breakpoint(); +#endif +} +diff -urN linux.old/arch/mips/bcm947xx/generic/Makefile linux.dev/arch/mips/bcm947xx/generic/Makefile +--- linux.old/arch/mips/bcm947xx/generic/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/generic/Makefile 2006-10-02 21:26:29.000000000 +0200 +@@ -0,0 +1,16 @@ ++# ++# Makefile for the BCM947xx specific kernel interface routines ++# under Linux. ++# ++EXTRA_CFLAGS += -fno-delayed-branch ++ ++.S.s: ++ $(CPP) $(AFLAGS) $< -o $*.s ++.S.o: ++ $(CC) $(AFLAGS) -c $< -o $*.o ++ ++O_TARGET := brcm.o ++ ++obj-y := int-handler.o irq.o ++ ++include $(TOPDIR)/Rules.make diff -urN linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio.c --- linux.old/arch/mips/bcm947xx/gpio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/gpio.c 2006-04-27 23:09:33.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/gpio.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,159 @@ +/* + * GPIO char driver @@ -2234,7 +2183,7 @@ diff -urN linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio. +module_exit(gpio_exit); diff -urN linux.old/arch/mips/bcm947xx/hndchipc.c linux.dev/arch/mips/bcm947xx/hndchipc.c --- linux.old/arch/mips/bcm947xx/hndchipc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/hndchipc.c 2006-04-28 00:33:05.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/hndchipc.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,158 @@ +/* + * BCM47XX support code for some chipcommon (old extif) facilities (uart) @@ -2396,7 +2345,7 @@ diff -urN linux.old/arch/mips/bcm947xx/hndchipc.c linux.dev/arch/mips/bcm947xx/h + diff -urN linux.old/arch/mips/bcm947xx/include/bcm4710.h linux.dev/arch/mips/bcm947xx/include/bcm4710.h --- linux.old/arch/mips/bcm947xx/include/bcm4710.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcm4710.h 2006-04-27 22:30:01.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcm4710.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,91 @@ +/* + * BCM4710 address space map and definitions @@ -2491,7 +2440,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcm4710.h linux.dev/arch/mips/bcm +#endif /* _bcm4710_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdefs.h linux.dev/arch/mips/bcm947xx/include/bcmdefs.h --- linux.old/arch/mips/bcm947xx/include/bcmdefs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmdefs.h 2006-04-27 20:12:21.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcmdefs.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,106 @@ +/* + * Misc system wide definitions @@ -2599,27 +2548,26 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdefs.h linux.dev/arch/mips/bcm + + +#endif /* _bcmdefs_h_ */ -diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm947xx/include/bcmdevs.h ---- linux.old/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h 2006-04-27 22:30:25.000000000 +0200 -@@ -0,0 +1,369 @@ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bcm947xx/include/bcmdevs1.h +--- linux.old/arch/mips/bcm947xx/include/bcmdevs1.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmdevs1.h 2006-10-02 21:19:59.000000000 +0200 +@@ -0,0 +1,391 @@ +/* + * Broadcom device-specific manifest constants. + * -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id: bcmdevs.h,v 1.1.1.17 2006/04/15 01:29:08 michael Exp $ ++ * Copyright 2005, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id$ + */ + +#ifndef _BCMDEVS_H +#define _BCMDEVS_H + -+#include "bcm4710.h" + +/* Known PCI vendor Id's */ +#define VENDOR_EPIGRAM 0xfeda @@ -2659,22 +2607,30 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ +#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ +#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ -+#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */ -+#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */ -+#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */ + -+#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */ -+#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */ -+ -+#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid returned by sb_chip() */ +#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ + -+#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */ ++#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */ ++#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */ ++#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */ ++#define BCM4610_ENET_ID 0x4613 /* 4610 enet */ ++#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */ ++#define BCM4610_USB_ID 0x4615 /* 4610 usb */ ++ ++#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */ +#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ +#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ +#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ + -+#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */ ++#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */ ++#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */ ++ ++#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */ ++#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */ ++#define BCM4307_ENET_ID 0x4306 /* 4307 enet */ ++#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */ ++ ++#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */ +#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ +#define BCM4306_D11G_ID2 0x4325 +#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ @@ -2684,63 +2640,77 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm + +#define BCM4309_PKG_ID 1 /* 4309 package id */ + -+#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */ -+#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */ -+#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */ -+#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */ -+ +#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ +#define BCM4303_PKG_ID 2 /* 4303 package id */ + ++#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */ ++#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */ ++#define BCM4310_UART_ID 0x4312 /* 4310 uart */ ++#define BCM4310_ENET_ID 0x4313 /* 4310 enet */ ++#define BCM4310_USB_ID 0x4315 /* 4310 usb */ ++ +#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ +#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ + -+#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */ ++ ++#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */ +#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ + -+#define BCM4318_CHIP_ID 0x4318 /* 4318 chip common chipid */ -+#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */ -+#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */ -+#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */ ++#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */ + -+#define BCM4321_CHIP_ID 0x4321 /* 4321 chip common chipid */ -+#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */ -+#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Hgz band id */ -+#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */ ++#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */ ++#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */ ++#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */ ++#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */ + -+#define BCM4331_CHIP_ID 0x4331 /* 4331 chip common chipid */ -+#define BCM4331_D11N2G_ID 0x4330 /* 4331 802.11n 2.4Ghz band id */ -+#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */ -+#define BCM4331_D11N5G_ID 0x4332 /* 4331 802.11n 5Ghz band id */ ++#define FPGA_JTAGM_ID 0x4330 /* ??? */ + -+#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */ -+#define HDLSIM_PKG_ID 14 /* HDL simulator package id */ -+#define HWSIM_PKG_ID 15 /* Hardware simulator package id */ ++/* Address map */ ++#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */ ++#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */ ++#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */ ++#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */ ++#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ ++#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */ + -+#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */ -+#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ -+#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ -+#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ -+#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ ++/* Core register space */ ++#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */ ++#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */ ++#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */ ++#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */ ++#define BCM4710_REG_USB 0x18004000 /* USB core registers */ ++#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */ ++#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */ ++#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */ ++#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */ + -+#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */ -+#define BCM5350_CHIP_ID 0x5350 /* bcm5350 chipcommon chipid */ -+#define BCM5352_CHIP_ID 0x5352 /* bcm5352 chipcommon chipid */ ++#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */ ++#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */ ++#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */ ++#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */ ++#define BCM4710_PROG 0x1f800000 /* Programable interface */ ++#define BCM4710_FLASH 0x1fc00000 /* Flash */ + -+#define BCM4320_CHIP_ID 0x4320 /* bcm4320 chipcommon chipid */ ++#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ + -+#define BCM4328_CHIP_ID 0x4328 /* bcm4328 chipcommon chipid */ ++#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300) + -+#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */ -+#define BCM43XX_JTAGM_ID 0x43f1 /* 43xx jtagm device id */ -+#define BCM43XXOLD_JTAGM_ID 0x4331 /* 43xx old jtagm device id */ ++#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000) ++#define BCM4710_LED (BCM4710_EXTIF + 0x00900000) + -+#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */ -+#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */ ++#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */ ++#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ ++#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ ++#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ ++#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ + -+#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */ ++#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */ + -+#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */ ++#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */ ++#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */ ++#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */ ++ ++#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */ + +/* PCMCIA vendor Id's */ + @@ -2766,12 +2736,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */ +#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */ + -+/* boardflags2 */ -+#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* This board has an external rxbb regulator */ -+#define BFL2_SSWITCH_AVAIL 0x00000002 /* This board has a superswitch for > 2 antennas */ -+#define BFL2_TXPWRCTRL_EN 0x00000004 /* This board permits TX Power Control to be enabled */ -+ +/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ ++#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */ +#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */ +#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */ +#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */ @@ -2782,6 +2748,20 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ +#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ + ++/* Bus types */ ++#define SB_BUS 0 /* Silicon Backplane */ ++#define PCI_BUS 1 /* PCI target */ ++#define PCMCIA_BUS 2 /* PCMCIA target */ ++#define SDIO_BUS 3 /* SDIO target */ ++#define JTAG_BUS 4 /* JTAG */ ++ ++/* Allows optimization for single-bus support */ ++#ifdef BCMBUSTYPE ++#define BUSTYPE(bus) (BCMBUSTYPE) ++#else ++#define BUSTYPE(bus) (bus) ++#endif ++ +/* power control defines */ +#define PLL_DELAY 150 /* us pll on delay */ +#define FREF_DELAY 200 /* us fref change delay */ @@ -2794,6 +2774,16 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +#define VSIM4710_BOARD 0x0401 +#define QT4710_BOARD 0x0402 + ++#define BU4610_BOARD 0x0403 ++#define VSIM4610_BOARD 0x0404 ++ ++#define BU4307_BOARD 0x0405 ++#define BCM94301CB_BOARD 0x0406 ++#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */ ++#define BCM94301MP_BOARD 0x0407 ++#define BCM94307MP_BOARD 0x0408 ++#define BCMAP4307_BOARD 0x0409 ++ +#define BU4309_BOARD 0x040a +#define BCM94309CB_BOARD 0x040b +#define BCM94309MP_BOARD 0x040c @@ -2801,6 +2791,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm + +#define BCM94302MP_BOARD 0x040e + ++#define VSIM4310_BOARD 0x040f ++#define BU4711_BOARD 0x0410 ++#define BCM94310U_BOARD 0x0411 ++#define BCM94310AP_BOARD 0x0412 ++#define BCM94310MP_BOARD 0x0414 ++ +#define BU4306_BOARD 0x0416 +#define BCM94306CB_BOARD 0x0417 +#define BCM94306MP_BOARD 0x0418 @@ -2810,16 +2806,21 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +#define BCM94710R4_BOARD 0x041c +#define BCM94710AP_BOARD 0x041d + ++ +#define BU2050_BOARD 0x041f + + +#define BCM94309G_BOARD 0x0421 + ++#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */ ++ +#define BU4704_BOARD 0x0423 +#define BU4702_BOARD 0x0424 + +#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ + ++#define BU4317_BOARD 0x0426 ++ + +#define BCM94702MN_BOARD 0x0428 + @@ -2832,6 +2833,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +/* cb4306 with SiGe PA */ +#define BCM94306CBSG_BOARD 0x042b + ++/* mp4301 with 2050 radio */ ++#define BCM94301MPL_BOARD 0x042c ++ +/* cb4306 with SiGe PA */ +#define PCSG94306_BOARD 0x042d + @@ -2846,6 +2850,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm + + + ++/* BCM94317 boards */ ++#define BCM94317CB_BOARD 0x0440 ++#define BCM94317MP_BOARD 0x0441 ++#define BCM94317PCMCIA_BOARD 0x0442 ++#define BCM94317SDIO_BOARD 0x0443 ++ +#define BU4712_BOARD 0x0444 +#define BU4712SD_BOARD 0x045d +#define BU4712L_BOARD 0x045f @@ -2863,11 +2873,15 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm + +/* BCM63XX boards */ +#define BCM96338_BOARD 0x6338 ++#define BCM96345_BOARD 0x6345 +#define BCM96348_BOARD 0x6348 + +/* Another mp4306 with SiGe */ +#define BCM94306P_BOARD 0x044c + ++/* CF-like 4317 modules */ ++#define BCM94317CF_BOARD 0x044d ++ +/* mp4303 */ +#define BCM94303MP_BOARD 0x044e + @@ -2881,6 +2895,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +/* 4712agr */ +#define BCM94712AGR_BOARD 0x0451 + ++/* The real CF 4317 board */ ++#define CFI4317_BOARD 0x0452 ++ +/* pcmcia 4303 */ +#define PC4303_BOARD 0x0454 + @@ -2916,82 +2933,37 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm + +#define BCM94318MPGH_BOARD 0x0463 + -+#define BU4311_BOARD 0x0464 -+#define BCM94311MC_BOARD 0x0465 -+#define BCM94311MCAG_BOARD 0x0466 + +#define BCM95352GR_BOARD 0x0467 + +/* bcm95351agr */ +#define BCM95351AGR_BOARD 0x0470 + -+/* bcm94704mpcb */ -+#define BCM94704MPCB_BOARD 0x0472 -+ -+/* 4785 boards */ -+#define BU4785_BOARD 0x0478 -+ -+/* 4321 boards */ -+#define BU4321_BOARD 0x046b -+#define BU4321E_BOARD 0x047c -+#define MP4321_BOARD 0x046c -+#define CB2_4321_BOARD 0x046d -+#define MC4321_BOARD 0x046e -+ +/* # of GPIO pins */ +#define GPIO_NUMPINS 16 + -+/* radio ID codes */ -+#define NORADIO_ID 0xe4f5 -+#define NORADIO_IDCODE 0x4e4f5246 -+ -+#define BCM2050_ID 0x2050 -+#define BCM2050_IDCODE 0x02050000 -+#define BCM2050A0_IDCODE 0x1205017f -+#define BCM2050A1_IDCODE 0x2205017f -+#define BCM2050R8_IDCODE 0x8205017f -+ -+#define BCM2055_ID 0x2055 -+#define BCM2055_IDCODE 0x02055000 -+#define BCM2055A0_IDCODE 0x1205517f -+ -+#define BCM2060_ID 0x2060 -+#define BCM2060_IDCODE 0x02060000 -+#define BCM2060WW_IDCODE 0x1206017f -+ -+#define BCM2062_ID 0x2062 -+#define BCM2062_IDCODE 0x02062000 -+#define BCM2062A0_IDCODE 0x0206217f -+ -+/* parts of an idcode: */ -+#define IDCODE_MFG_MASK 0x00000fff -+#define IDCODE_MFG_SHIFT 0 -+#define IDCODE_ID_MASK 0x0ffff000 -+#define IDCODE_ID_SHIFT 12 -+#define IDCODE_REV_MASK 0xf0000000 -+#define IDCODE_REV_SHIFT 28 -+ +#endif /* _BCMDEVS_H */ -diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bcm947xx/include/bcmdevs1.h ---- linux.old/arch/mips/bcm947xx/include/bcmdevs1.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmdevs1.h 2006-05-02 04:32:03.000000000 +0200 -@@ -0,0 +1,391 @@ +diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm947xx/include/bcmdevs.h +--- linux.old/arch/mips/bcm947xx/include/bcmdevs.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h 2006-10-02 21:19:59.000000000 +0200 +@@ -0,0 +1,369 @@ +/* + * Broadcom device-specific manifest constants. + * -+ * Copyright 2005, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * $Id$ ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * $Id: bcmdevs.h,v 1.1.1.17 2006/04/15 01:29:08 michael Exp $ + */ + +#ifndef _BCMDEVS_H +#define _BCMDEVS_H + ++#include "bcm4710.h" + +/* Known PCI vendor Id's */ +#define VENDOR_EPIGRAM 0xfeda @@ -3031,30 +3003,22 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc +#define BCM47XX_ROBO_ID 0x4719 /* 47xx/53xx roboswitch core */ +#define BCM47XX_USB20H_ID 0x471a /* 47xx usb 2.0 host */ +#define BCM47XX_USB20D_ID 0x471b /* 47xx usb 2.0 device */ ++#define BCM47XX_ATA100_ID 0x471d /* 47xx parallel ATA */ ++#define BCM47XX_SATAXOR_ID 0x471e /* 47xx serial ATA & XOR DMA */ ++#define BCM47XX_GIGETH_ID 0x471f /* 47xx GbE (5700) */ + -+#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ ++#define BCM47XX_SMBUS_EMU_ID 0x47fe /* 47xx emulated SMBus device */ ++#define BCM47XX_XOR_EMU_ID 0x47ff /* 47xx emulated XOR engine */ + -+#define BCM4610_DEVICE_ID 0x4610 /* 4610 primary function 0 */ -+#define BCM4610_ILINE_ID 0x4611 /* 4610 iline100 */ -+#define BCM4610_V90_ID 0x4612 /* 4610 v90 codec */ -+#define BCM4610_ENET_ID 0x4613 /* 4610 enet */ -+#define BCM4610_EXT_ID 0x4614 /* 4610 external i/f */ -+#define BCM4610_USB_ID 0x4615 /* 4610 usb */ ++#define BCM4710_CHIP_ID 0x4710 /* 4710 chipid returned by sb_chip() */ ++#define BCM4710_DEVICE_ID 0x4710 /* 4710 primary function 0 */ + -+#define BCM4402_DEVICE_ID 0x4402 /* 4402 primary function 0 */ ++#define BCM4402_CHIP_ID 0x4402 /* 4402 chipid */ +#define BCM4402_ENET_ID 0x4402 /* 4402 enet */ +#define BCM4402_V90_ID 0x4403 /* 4402 v90 codec */ +#define BCM4401_ENET_ID 0x170c /* 4401b0 production enet cards */ + -+#define BCM4301_DEVICE_ID 0x4301 /* 4301 primary function 0 */ -+#define BCM4301_D11B_ID 0x4301 /* 4301 802.11b */ -+ -+#define BCM4307_DEVICE_ID 0x4307 /* 4307 primary function 0 */ -+#define BCM4307_V90_ID 0x4305 /* 4307 v90 codec */ -+#define BCM4307_ENET_ID 0x4306 /* 4307 enet */ -+#define BCM4307_D11B_ID 0x4307 /* 4307 802.11b */ -+ -+#define BCM4306_DEVICE_ID 0x4306 /* 4306 chipcommon chipid */ ++#define BCM4306_CHIP_ID 0x4306 /* 4306 chipcommon chipid */ +#define BCM4306_D11G_ID 0x4320 /* 4306 802.11g */ +#define BCM4306_D11G_ID2 0x4325 +#define BCM4306_D11A_ID 0x4321 /* 4306 802.11a */ @@ -3064,77 +3028,63 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc + +#define BCM4309_PKG_ID 1 /* 4309 package id */ + ++#define BCM4311_CHIP_ID 0x4311 /* 4311 PCIe 802.11a/b/g */ ++#define BCM4311_D11G_ID 0x4311 /* 4311 802.11b/g id */ ++#define BCM4311_D11DUAL_ID 0x4312 /* 4311 802.11a/b/g id */ ++#define BCM4311_D11A_ID 0x4313 /* 4311 802.11a id */ ++ +#define BCM4303_D11B_ID 0x4303 /* 4303 802.11b */ +#define BCM4303_PKG_ID 2 /* 4303 package id */ + -+#define BCM4310_DEVICE_ID 0x4310 /* 4310 chipcommon chipid */ -+#define BCM4310_D11B_ID 0x4311 /* 4310 802.11b */ -+#define BCM4310_UART_ID 0x4312 /* 4310 uart */ -+#define BCM4310_ENET_ID 0x4313 /* 4310 enet */ -+#define BCM4310_USB_ID 0x4315 /* 4310 usb */ -+ +#define BCMGPRS_UART_ID 0x4333 /* Uart id used by 4306/gprs card */ +#define BCMGPRS2_UART_ID 0x4344 /* Uart id used by 4306/gprs card */ + -+ -+#define BCM4704_DEVICE_ID 0x4704 /* 4704 chipcommon chipid */ ++#define BCM4704_CHIP_ID 0x4704 /* 4704 chipcommon chipid */ +#define BCM4704_ENET_ID 0x4706 /* 4704 enet (Use 47XX_ENET_ID instead!) */ + -+#define BCM4317_DEVICE_ID 0x4317 /* 4317 chip common chipid */ -+ -+#define BCM4318_DEVICE_ID 0x4318 /* 4318 chip common chipid */ -+#define BCM4318_D11G_ID 0x4318 /* 4318 801.11b/g id */ -+#define BCM4318_D11DUAL_ID 0x4319 /* 4318 801.11a/b/g id */ -+#define BCM4318_JTAGM_ID 0x4331 /* 4318 jtagm device id */ -+ -+#define FPGA_JTAGM_ID 0x4330 /* ??? */ -+ -+/* Address map */ -+#define BCM4710_SDRAM 0x00000000 /* Physical SDRAM */ -+#define BCM4710_PCI_MEM 0x08000000 /* Host Mode PCI memory access space (64 MB) */ -+#define BCM4710_PCI_CFG 0x0c000000 /* Host Mode PCI configuration space (64 MB) */ -+#define BCM4710_PCI_DMA 0x40000000 /* Client Mode PCI memory access space (1 GB) */ -+#define BCM4710_SDRAM_SWAPPED 0x10000000 /* Byteswapped Physical SDRAM */ -+#define BCM4710_ENUM 0x18000000 /* Beginning of core enumeration space */ -+ -+/* Core register space */ -+#define BCM4710_REG_SDRAM 0x18000000 /* SDRAM core registers */ -+#define BCM4710_REG_ILINE20 0x18001000 /* InsideLine20 core registers */ -+#define BCM4710_REG_EMAC0 0x18002000 /* Ethernet MAC 0 core registers */ -+#define BCM4710_REG_CODEC 0x18003000 /* Codec core registers */ -+#define BCM4710_REG_USB 0x18004000 /* USB core registers */ -+#define BCM4710_REG_PCI 0x18005000 /* PCI core registers */ -+#define BCM4710_REG_MIPS 0x18006000 /* MIPS core registers */ -+#define BCM4710_REG_EXTIF 0x18007000 /* External Interface core registers */ -+#define BCM4710_REG_EMAC1 0x18008000 /* Ethernet MAC 1 core registers */ -+ -+#define BCM4710_EXTIF 0x1f000000 /* External Interface base address */ -+#define BCM4710_PCMCIA_MEM 0x1f000000 /* External Interface PCMCIA memory access */ -+#define BCM4710_PCMCIA_IO 0x1f100000 /* PCMCIA I/O access */ -+#define BCM4710_PCMCIA_CONF 0x1f200000 /* PCMCIA configuration */ -+#define BCM4710_PROG 0x1f800000 /* Programable interface */ -+#define BCM4710_FLASH 0x1fc00000 /* Flash */ ++#define BCM4318_CHIP_ID 0x4318 /* 4318 chip common chipid */ ++#define BCM4318_D11G_ID 0x4318 /* 4318 802.11b/g id */ ++#define BCM4318_D11DUAL_ID 0x4319 /* 4318 802.11a/b/g id */ ++#define BCM4318_D11A_ID 0x431a /* 4318 802.11a id */ + -+#define BCM4710_EJTAG 0xff200000 /* MIPS EJTAG space (2M) */ ++#define BCM4321_CHIP_ID 0x4321 /* 4321 chip common chipid */ ++#define BCM4321_D11N_ID 0x4328 /* 4321 802.11n dualband id */ ++#define BCM4321_D11N2G_ID 0x4329 /* 4321 802.11n 2.4Hgz band id */ ++#define BCM4321_D11N5G_ID 0x432a /* 4321 802.11n 5Ghz band id */ + -+#define BCM4710_UART (BCM4710_REG_EXTIF + 0x00000300) ++#define BCM4331_CHIP_ID 0x4331 /* 4331 chip common chipid */ ++#define BCM4331_D11N2G_ID 0x4330 /* 4331 802.11n 2.4Ghz band id */ ++#define BCM4331_D11N_ID 0x4331 /* 4331 802.11n dualband id */ ++#define BCM4331_D11N5G_ID 0x4332 /* 4331 802.11n 5Ghz band id */ + -+#define BCM4710_EUART (BCM4710_EXTIF + 0x00800000) -+#define BCM4710_LED (BCM4710_EXTIF + 0x00900000) ++#define HDLSIM5350_PKG_ID 1 /* HDL simulator package id for a 5350 */ ++#define HDLSIM_PKG_ID 14 /* HDL simulator package id */ ++#define HWSIM_PKG_ID 15 /* Hardware simulator package id */ + -+#define BCM4712_DEVICE_ID 0x4712 /* 4712 chipcommon chipid */ ++#define BCM4712_CHIP_ID 0x4712 /* 4712 chipcommon chipid */ +#define BCM4712_MIPS_ID 0x4720 /* 4712 base devid */ +#define BCM4712LARGE_PKG_ID 0 /* 340pin 4712 package id */ +#define BCM4712SMALL_PKG_ID 1 /* 200pin 4712 package id */ +#define BCM4712MID_PKG_ID 2 /* 225pin 4712 package id */ + -+#define SDIOH_FPGA_ID 0x4380 /* sdio host fpga */ ++#define BCM5365_CHIP_ID 0x5365 /* 5365 chipcommon chipid */ ++#define BCM5350_CHIP_ID 0x5350 /* bcm5350 chipcommon chipid */ ++#define BCM5352_CHIP_ID 0x5352 /* bcm5352 chipcommon chipid */ + -+#define BCM5365_DEVICE_ID 0x5365 /* 5365 chipcommon chipid */ -+#define BCM5350_DEVICE_ID 0x5350 /* bcm5350 chipcommon chipid */ -+#define BCM5352_DEVICE_ID 0x5352 /* bcm5352 chipcommon chipid */ ++#define BCM4320_CHIP_ID 0x4320 /* bcm4320 chipcommon chipid */ + -+#define BCM4320_DEVICE_ID 0x4320 /* bcm4320 chipcommon chipid */ ++#define BCM4328_CHIP_ID 0x4328 /* bcm4328 chipcommon chipid */ ++ ++#define FPGA_JTAGM_ID 0x43f0 /* FPGA jtagm device id */ ++#define BCM43XX_JTAGM_ID 0x43f1 /* 43xx jtagm device id */ ++#define BCM43XXOLD_JTAGM_ID 0x4331 /* 43xx old jtagm device id */ ++ ++#define SDIOH_FPGA_ID 0x43f2 /* sdio host fpga */ ++#define SDIOD_FPGA_ID 0x43f4 /* sdio device fpga */ ++ ++#define MIMO_FPGA_ID 0x43f8 /* FPGA mimo minimacphy device id */ ++ ++#define BCM4785_CHIP_ID 0x4785 /* 4785 chipcommon chipid */ + +/* PCMCIA vendor Id's */ + @@ -3160,8 +3110,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc +#define BFL_BTCMOD 0x4000 /* This board' BTCOEXIST is in the alternate gpios */ +#define BFL_ALTIQ 0x8000 /* Alternate I/Q settings */ + ++/* boardflags2 */ ++#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* This board has an external rxbb regulator */ ++#define BFL2_SSWITCH_AVAIL 0x00000002 /* This board has a superswitch for > 2 antennas */ ++#define BFL2_TXPWRCTRL_EN 0x00000004 /* This board permits TX Power Control to be enabled */ ++ +/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ -+#define BOARD_GPIO_HWRAD_B 0x010 /* bit 4 is HWRAD input on 4301 */ +#define BOARD_GPIO_BTCMOD_IN 0x010 /* bit 4 is the alternate BT Coexistance Input */ +#define BOARD_GPIO_BTCMOD_OUT 0x020 /* bit 5 is the alternate BT Coexistance Out */ +#define BOARD_GPIO_BTC_IN 0x080 /* bit 7 is BT Coexistance Input */ @@ -3172,20 +3126,6 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc +#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal powerup */ +#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL powerdown */ + -+/* Bus types */ -+#define SB_BUS 0 /* Silicon Backplane */ -+#define PCI_BUS 1 /* PCI target */ -+#define PCMCIA_BUS 2 /* PCMCIA target */ -+#define SDIO_BUS 3 /* SDIO target */ -+#define JTAG_BUS 4 /* JTAG */ -+ -+/* Allows optimization for single-bus support */ -+#ifdef BCMBUSTYPE -+#define BUSTYPE(bus) (BCMBUSTYPE) -+#else -+#define BUSTYPE(bus) (bus) -+#endif -+ +/* power control defines */ +#define PLL_DELAY 150 /* us pll on delay */ +#define FREF_DELAY 200 /* us fref change delay */ @@ -3198,16 +3138,6 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc +#define VSIM4710_BOARD 0x0401 +#define QT4710_BOARD 0x0402 + -+#define BU4610_BOARD 0x0403 -+#define VSIM4610_BOARD 0x0404 -+ -+#define BU4307_BOARD 0x0405 -+#define BCM94301CB_BOARD 0x0406 -+#define BCM94301PC_BOARD 0x0406 /* Pcmcia 5v card */ -+#define BCM94301MP_BOARD 0x0407 -+#define BCM94307MP_BOARD 0x0408 -+#define BCMAP4307_BOARD 0x0409 -+ +#define BU4309_BOARD 0x040a +#define BCM94309CB_BOARD 0x040b +#define BCM94309MP_BOARD 0x040c @@ -3215,12 +3145,6 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc + +#define BCM94302MP_BOARD 0x040e + -+#define VSIM4310_BOARD 0x040f -+#define BU4711_BOARD 0x0410 -+#define BCM94310U_BOARD 0x0411 -+#define BCM94310AP_BOARD 0x0412 -+#define BCM94310MP_BOARD 0x0414 -+ +#define BU4306_BOARD 0x0416 +#define BCM94306CB_BOARD 0x0417 +#define BCM94306MP_BOARD 0x0418 @@ -3230,21 +3154,16 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc +#define BCM94710R4_BOARD 0x041c +#define BCM94710AP_BOARD 0x041d + -+ +#define BU2050_BOARD 0x041f + + +#define BCM94309G_BOARD 0x0421 + -+#define BCM94301PC3_BOARD 0x0422 /* Pcmcia 3.3v card */ -+ +#define BU4704_BOARD 0x0423 +#define BU4702_BOARD 0x0424 + +#define BCM94306PC_BOARD 0x0425 /* pcmcia 3.3v 4306 card */ + -+#define BU4317_BOARD 0x0426 -+ + +#define BCM94702MN_BOARD 0x0428 + @@ -3257,9 +3176,6 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc +/* cb4306 with SiGe PA */ +#define BCM94306CBSG_BOARD 0x042b + -+/* mp4301 with 2050 radio */ -+#define BCM94301MPL_BOARD 0x042c -+ +/* cb4306 with SiGe PA */ +#define PCSG94306_BOARD 0x042d + @@ -3274,12 +3190,6 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc + + + -+/* BCM94317 boards */ -+#define BCM94317CB_BOARD 0x0440 -+#define BCM94317MP_BOARD 0x0441 -+#define BCM94317PCMCIA_BOARD 0x0442 -+#define BCM94317SDIO_BOARD 0x0443 -+ +#define BU4712_BOARD 0x0444 +#define BU4712SD_BOARD 0x045d +#define BU4712L_BOARD 0x045f @@ -3297,15 +3207,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc + +/* BCM63XX boards */ +#define BCM96338_BOARD 0x6338 -+#define BCM96345_BOARD 0x6345 +#define BCM96348_BOARD 0x6348 + +/* Another mp4306 with SiGe */ +#define BCM94306P_BOARD 0x044c + -+/* CF-like 4317 modules */ -+#define BCM94317CF_BOARD 0x044d -+ +/* mp4303 */ +#define BCM94303MP_BOARD 0x044e + @@ -3319,9 +3225,6 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc +/* 4712agr */ +#define BCM94712AGR_BOARD 0x0451 + -+/* The real CF 4317 board */ -+#define CFI4317_BOARD 0x0452 -+ +/* pcmcia 4303 */ +#define PC4303_BOARD 0x0454 + @@ -3357,19 +3260,65 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs1.h linux.dev/arch/mips/bc + +#define BCM94318MPGH_BOARD 0x0463 + ++#define BU4311_BOARD 0x0464 ++#define BCM94311MC_BOARD 0x0465 ++#define BCM94311MCAG_BOARD 0x0466 + +#define BCM95352GR_BOARD 0x0467 + +/* bcm95351agr */ +#define BCM95351AGR_BOARD 0x0470 + ++/* bcm94704mpcb */ ++#define BCM94704MPCB_BOARD 0x0472 ++ ++/* 4785 boards */ ++#define BU4785_BOARD 0x0478 ++ ++/* 4321 boards */ ++#define BU4321_BOARD 0x046b ++#define BU4321E_BOARD 0x047c ++#define MP4321_BOARD 0x046c ++#define CB2_4321_BOARD 0x046d ++#define MC4321_BOARD 0x046e ++ +/* # of GPIO pins */ +#define GPIO_NUMPINS 16 + ++/* radio ID codes */ ++#define NORADIO_ID 0xe4f5 ++#define NORADIO_IDCODE 0x4e4f5246 ++ ++#define BCM2050_ID 0x2050 ++#define BCM2050_IDCODE 0x02050000 ++#define BCM2050A0_IDCODE 0x1205017f ++#define BCM2050A1_IDCODE 0x2205017f ++#define BCM2050R8_IDCODE 0x8205017f ++ ++#define BCM2055_ID 0x2055 ++#define BCM2055_IDCODE 0x02055000 ++#define BCM2055A0_IDCODE 0x1205517f ++ ++#define BCM2060_ID 0x2060 ++#define BCM2060_IDCODE 0x02060000 ++#define BCM2060WW_IDCODE 0x1206017f ++ ++#define BCM2062_ID 0x2062 ++#define BCM2062_IDCODE 0x02062000 ++#define BCM2062A0_IDCODE 0x0206217f ++ ++/* parts of an idcode: */ ++#define IDCODE_MFG_MASK 0x00000fff ++#define IDCODE_MFG_SHIFT 0 ++#define IDCODE_ID_MASK 0x0ffff000 ++#define IDCODE_ID_SHIFT 12 ++#define IDCODE_REV_MASK 0xf0000000 ++#define IDCODE_REV_SHIFT 28 ++ +#endif /* _BCMDEVS_H */ diff -urN linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/bcm947xx/include/bcmendian.h --- linux.old/arch/mips/bcm947xx/include/bcmendian.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h 2006-04-27 20:08:35.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,198 @@ +/* + * local version of endian.h - byte order defines @@ -3571,7 +3520,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/b +#endif /* _BCMENDIAN_H_ */ diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bcm947xx/include/bcmnvram.h --- linux.old/arch/mips/bcm947xx/include/bcmnvram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h 2006-04-27 23:29:18.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,159 @@ +/* + * NVRAM variable manipulation @@ -3734,7 +3683,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bc +#endif /* _bcmnvram_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/bcmsrom.h linux.dev/arch/mips/bcm947xx/include/bcmsrom.h --- linux.old/arch/mips/bcm947xx/include/bcmsrom.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmsrom.h 2006-04-27 20:27:33.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcmsrom.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,108 @@ +/* + * Misc useful routines to access NIC local SROM/OTP . @@ -3846,7 +3795,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmsrom.h linux.dev/arch/mips/bcm +#endif /* _bcmsrom_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bcm947xx/include/bcmutils.h --- linux.old/arch/mips/bcm947xx/include/bcmutils.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmutils.h 2006-05-02 01:52:12.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcmutils.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,433 @@ +/* + * Misc useful os-independent macros and functions. @@ -4283,7 +4232,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bc +#endif /* _bcmutils_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/hndcpu.h linux.dev/arch/mips/bcm947xx/include/hndcpu.h --- linux.old/arch/mips/bcm947xx/include/hndcpu.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/hndcpu.h 2006-04-27 22:14:38.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/hndcpu.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,28 @@ +/* + * HND SiliconBackplane MIPS/ARM cores software interface. @@ -4315,7 +4264,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/hndcpu.h linux.dev/arch/mips/bcm9 +#endif /* _hndcpu_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/hndmips.h linux.dev/arch/mips/bcm947xx/include/hndmips.h --- linux.old/arch/mips/bcm947xx/include/hndmips.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/hndmips.h 2006-04-27 20:43:42.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/hndmips.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,45 @@ +/* + * HND SiliconBackplane MIPS core software interface. @@ -4364,7 +4313,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/hndmips.h linux.dev/arch/mips/bcm +#endif /* _hndmips_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/hndpci.h linux.dev/arch/mips/bcm947xx/include/hndpci.h --- linux.old/arch/mips/bcm947xx/include/hndpci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/hndpci.h 2006-04-27 20:36:48.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/hndpci.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,30 @@ +/* + * HND SiliconBackplane PCI core software interface. @@ -4398,7 +4347,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/hndpci.h linux.dev/arch/mips/bcm9 +#endif /* _hndpci_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bcm947xx/include/linuxver.h --- linux.old/arch/mips/bcm947xx/include/linuxver.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/linuxver.h 2006-04-27 20:10:08.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/linuxver.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,417 @@ +/* + * Linux-specific abstractions to gain some independence from linux kernel versions. @@ -4819,7 +4768,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bc +#endif /* _linuxver_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm947xx/include/mipsinc.h --- linux.old/arch/mips/bcm947xx/include/mipsinc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/mipsinc.h 2006-04-27 22:12:20.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/mipsinc.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,541 @@ +/* + * HND Run Time Environment for standalone MIPS programs. @@ -5364,7 +5313,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +#endif /* _MISPINC_H */ diff -urN linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947xx/include/osl.h --- linux.old/arch/mips/bcm947xx/include/osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/osl.h 2006-05-02 17:40:43.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/osl.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,179 @@ +#ifndef __osl_h +#define __osl_h @@ -5547,7 +5496,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947x +#endif diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm947xx/include/pcicfg.h --- linux.old/arch/mips/bcm947xx/include/pcicfg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/pcicfg.h 2006-04-27 20:31:41.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/pcicfg.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,495 @@ +/* + * pcicfg.h: PCI configuration constants and structures. @@ -6046,7 +5995,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm9 +#endif /* _h_pcicfg_ */ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm947xx/include/sbchipc.h --- linux.old/arch/mips/bcm947xx/include/sbchipc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbchipc.h 2006-04-27 22:11:01.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbchipc.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,516 @@ +/* + * SiliconBackplane Chipcommon core hardware definitions. @@ -6566,7 +6515,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm +#endif /* _SBCHIPC_H */ diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bcm947xx/include/sbconfig.h --- linux.old/arch/mips/bcm947xx/include/sbconfig.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbconfig.h 2006-04-27 22:14:11.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbconfig.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,369 @@ +/* + * Broadcom SiliconBackplane hardware register definitions. @@ -6939,7 +6888,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bc +#endif /* _SBCONFIG_H */ diff -urN linux.old/arch/mips/bcm947xx/include/sbextif.h linux.dev/arch/mips/bcm947xx/include/sbextif.h --- linux.old/arch/mips/bcm947xx/include/sbextif.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbextif.h 2006-04-27 22:13:03.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbextif.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,243 @@ +/* + * Hardware-specific External Interface I/O core definitions @@ -7186,7 +7135,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbextif.h linux.dev/arch/mips/bcm +#endif /* _SBEXTIF_H */ diff -urN linux.old/arch/mips/bcm947xx/include/sbhndmips.h linux.dev/arch/mips/bcm947xx/include/sbhndmips.h --- linux.old/arch/mips/bcm947xx/include/sbhndmips.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbhndmips.h 2006-04-27 20:43:56.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbhndmips.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,47 @@ +/* + * Broadcom SiliconBackplane MIPS definitions @@ -7237,7 +7186,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbhndmips.h linux.dev/arch/mips/b +#endif /* _sbhndmips_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm947xx/include/sbmemc.h --- linux.old/arch/mips/bcm947xx/include/sbmemc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbmemc.h 2006-04-27 22:12:41.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbmemc.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,147 @@ +/* + * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. @@ -7336,177 +7285,59 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm9 +#define MEMC_SDR_NCDL 0x00020032 +#define MEMC_SDR1_NCDL 0x0002020f /* For corerev 1 (4712) */ + -+/* For ddr: */ -+#define MEMC_CONFIG_INIT 0x00048000 -+#define MEMC_DRAMTIM2_INIT 0x000754d8 -+#define MEMC_DRAMTIM25_INIT 0x000754d9 -+#define MEMC_RDNCDLCOR_INIT 0x00000000 -+#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */ -+#define MEMC_WRNCDLCOR_INIT 0x49351200 -+#define MEMC_1_WRNCDLCOR_INIT 0x14500200 -+#define MEMC_DQSGATENCDL_INIT 0x00030000 -+#define MEMC_MISCDLYCTL_INIT 0x21061c1b -+#define MEMC_1_MISCDLYCTL_INIT 0x21021400 -+#define MEMC_NCDLCTL_INIT 0x00002001 -+#define MEMC_CONTROL_INIT0 0x00000002 -+#define MEMC_CONTROL_INIT1 0x00000008 -+#define MEMC_MODEBUF_INIT0 0x00004000 -+#define MEMC_CONTROL_INIT2 0x00000010 -+#define MEMC_MODEBUF_INIT1 0x00000100 -+#define MEMC_CONTROL_INIT3 0x00000010 -+#define MEMC_CONTROL_INIT4 0x00000008 -+#define MEMC_REFRESH_INIT 0x0000840f -+#define MEMC_CONTROL_INIT5 0x00000004 -+#define MEMC_MODEBUF_INIT2 0x00000000 -+#define MEMC_CONTROL_INIT6 0x00000010 -+#define MEMC_CONTROL_INIT7 0x00000001 -+ -+ -+/* This is for DDRM16X16X2 */ -+#define MEMC_DDR_INIT 0x0009 -+#define MEMC_DDR_MODE 0x62 -+#define MEMC_DDR_NCDL 0x0005050a -+#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */ -+ -+/* mask for sdr/ddr calibration registers */ -+#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff -+#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff -+#define MEMC_DQSGATENCDL_G_MASK 0x000000ff -+ -+/* masks for miscdlyctl registers */ -+#define MEMC_MISC_SM_MASK 0x30000000 -+#define MEMC_MISC_SM_SHIFT 28 -+#define MEMC_MISC_SD_MASK 0x0f000000 -+#define MEMC_MISC_SD_SHIFT 24 -+ -+/* hw threshhold for calculating wr/rd for sdr memc */ -+#define MEMC_CD_THRESHOLD 128 -+ -+/* Low bit of init register says if memc is ddr or sdr */ -+#define MEMC_CONFIG_DDR 0x00000001 -+ -+#endif /* _SBMEMC_H */ -diff -urN linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm947xx/include/sbpci.h ---- linux.old/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbpci.h 2006-05-02 17:20:14.000000000 +0200 -@@ -0,0 +1,114 @@ -+/* -+ * HND SiliconBackplane PCI core hardware definitions. -+ * -+ * Copyright 2006, Broadcom Corporation -+ * All Rights Reserved. -+ * -+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+ * -+ * $Id: sbpci.h,v 1.1.1.11 2006/02/27 03:43:16 honor Exp $ -+ */ -+ -+#ifndef _sbpci_h_ -+#define _sbpci_h_ -+ -+#ifndef _LANGUAGE_ASSEMBLY -+ -+/* cpp contortions to concatenate w/arg prescan */ -+#ifndef PAD -+#define _PADLINE(line) pad ## line -+#define _XSTR(line) _PADLINE(line) -+#define PAD _XSTR(__LINE__) -+#endif -+ -+/* Sonics side: PCI core and host control registers */ -+typedef struct sbpciregs { -+ uint32 control; /* PCI control */ -+ uint32 PAD[3]; -+ uint32 arbcontrol; /* PCI arbiter control */ -+ uint32 PAD[3]; -+ uint32 intstatus; /* Interrupt status */ -+ uint32 intmask; /* Interrupt mask */ -+ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */ -+ uint32 PAD[9]; -+ uint32 bcastaddr; /* Sonics broadcast address */ -+ uint32 bcastdata; /* Sonics broadcast data */ -+ uint32 PAD[2]; -+ uint32 gpioin; /* ro: gpio input (>=rev2) */ -+ uint32 gpioout; /* rw: gpio output (>=rev2) */ -+ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */ -+ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */ -+ uint32 PAD[36]; -+ uint32 sbtopci0; /* Sonics to PCI translation 0 */ -+ uint32 sbtopci1; /* Sonics to PCI translation 1 */ -+ uint32 sbtopci2; /* Sonics to PCI translation 2 */ -+ uint32 PAD[189]; -+ uint32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */ -+ uint16 sprom[36]; /* SPROM shadow Area */ -+ uint32 PAD[46]; -+} sbpciregs_t; -+ -+#endif /* _LANGUAGE_ASSEMBLY */ -+ -+/* PCI control */ -+#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ -+#define PCI_RST 0x02 /* Value driven out to pin */ -+#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ -+#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ -+ -+/* PCI arbiter control */ -+#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ -+#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ -+/* ParkID - for PCI corerev >= 8 */ -+#define PCI_PARKID_MASK 0x1c /* Selects which agent is parked on an idle bus */ -+#define PCI_PARKID_SHIFT 2 -+#define PCI_PARKID_EXT0 0 /* External master 0 */ -+#define PCI_PARKID_EXT1 1 /* External master 1 */ -+#define PCI_PARKID_EXT2 2 /* External master 2 */ -+#define PCI_PARKID_INT 3 /* Internal master */ -+#define PCI_PARKID_LAST 4 /* Last active master */ ++/* For ddr: */ ++#define MEMC_CONFIG_INIT 0x00048000 ++#define MEMC_DRAMTIM2_INIT 0x000754d8 ++#define MEMC_DRAMTIM25_INIT 0x000754d9 ++#define MEMC_RDNCDLCOR_INIT 0x00000000 ++#define MEMC_RDNCDLCOR_SIMINIT 0xf6f6f6f6 /* For hdl sim */ ++#define MEMC_WRNCDLCOR_INIT 0x49351200 ++#define MEMC_1_WRNCDLCOR_INIT 0x14500200 ++#define MEMC_DQSGATENCDL_INIT 0x00030000 ++#define MEMC_MISCDLYCTL_INIT 0x21061c1b ++#define MEMC_1_MISCDLYCTL_INIT 0x21021400 ++#define MEMC_NCDLCTL_INIT 0x00002001 ++#define MEMC_CONTROL_INIT0 0x00000002 ++#define MEMC_CONTROL_INIT1 0x00000008 ++#define MEMC_MODEBUF_INIT0 0x00004000 ++#define MEMC_CONTROL_INIT2 0x00000010 ++#define MEMC_MODEBUF_INIT1 0x00000100 ++#define MEMC_CONTROL_INIT3 0x00000010 ++#define MEMC_CONTROL_INIT4 0x00000008 ++#define MEMC_REFRESH_INIT 0x0000840f ++#define MEMC_CONTROL_INIT5 0x00000004 ++#define MEMC_MODEBUF_INIT2 0x00000000 ++#define MEMC_CONTROL_INIT6 0x00000010 ++#define MEMC_CONTROL_INIT7 0x00000001 + -+/* Interrupt status/mask */ -+#define PCI_INTA 0x01 /* PCI INTA# is asserted */ -+#define PCI_INTB 0x02 /* PCI INTB# is asserted */ -+#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ -+#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ -+#define PCI_PME 0x10 /* PCI PME# is asserted */ + -+/* (General) PCI/SB mailbox interrupts, two bits per pci function */ -+#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ -+#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ -+#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ -+#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ -+#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ -+#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ -+#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ -+#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ ++/* This is for DDRM16X16X2 */ ++#define MEMC_DDR_INIT 0x0009 ++#define MEMC_DDR_MODE 0x62 ++#define MEMC_DDR_NCDL 0x0005050a ++#define MEMC_DDR1_NCDL 0x00000a0a /* For corerev 1 (4712) */ + -+/* Sonics broadcast address */ -+#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ ++/* mask for sdr/ddr calibration registers */ ++#define MEMC_RDNCDLCOR_RD_MASK 0x000000ff ++#define MEMC_WRNCDLCOR_WR_MASK 0x000000ff ++#define MEMC_DQSGATENCDL_G_MASK 0x000000ff + -+/* Sonics to PCI translation types */ -+#define SBTOPCI0_MASK 0xfc000000 -+#define SBTOPCI1_MASK 0xfc000000 -+#define SBTOPCI2_MASK 0xc0000000 -+#define SBTOPCI_MEM 0 -+#define SBTOPCI_IO 1 -+#define SBTOPCI_CFG0 2 -+#define SBTOPCI_CFG1 3 -+#define SBTOPCI_PREF 0x4 /* prefetch enable */ -+#define SBTOPCI_BURST 0x8 /* burst enable */ -+#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ -+#define SBTOPCI_RC_READ 0x00 /* memory read */ -+#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ -+#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ ++/* masks for miscdlyctl registers */ ++#define MEMC_MISC_SM_MASK 0x30000000 ++#define MEMC_MISC_SM_SHIFT 28 ++#define MEMC_MISC_SD_MASK 0x0f000000 ++#define MEMC_MISC_SD_SHIFT 24 + -+/* PCI core index in SROM shadow area */ -+#define SRSH_PI_OFFSET 0 /* first word */ -+#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ -+#define SRSH_PI_SHIFT 12 /* bit 15:12 */ ++/* hw threshhold for calculating wr/rd for sdr memc */ ++#define MEMC_CD_THRESHOLD 128 + -+#endif /* _sbpci_h_ */ ++/* Low bit of init register says if memc is ddr or sdr */ ++#define MEMC_CONFIG_DDR 0x00000001 ++ ++#endif /* _SBMEMC_H */ diff -urN linux.old/arch/mips/bcm947xx/include/sbpcie.h linux.dev/arch/mips/bcm947xx/include/sbpcie.h --- linux.old/arch/mips/bcm947xx/include/sbpcie.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbpcie.h 2006-04-27 20:42:22.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbpcie.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,200 @@ +/* + * BCM43XX SiliconBackplane PCIE core hardware definitions. @@ -7708,9 +7539,127 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbpcie.h linux.dev/arch/mips/bcm9 +#define SERDES_RX_CDRBW 7 /* CDR BW */ + +#endif /* _SBPCIE_H */ +diff -urN linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm947xx/include/sbpci.h +--- linux.old/arch/mips/bcm947xx/include/sbpci.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbpci.h 2006-10-02 21:19:59.000000000 +0200 +@@ -0,0 +1,114 @@ ++/* ++ * HND SiliconBackplane PCI core hardware definitions. ++ * ++ * Copyright 2006, Broadcom Corporation ++ * All Rights Reserved. ++ * ++ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++ * ++ * $Id: sbpci.h,v 1.1.1.11 2006/02/27 03:43:16 honor Exp $ ++ */ ++ ++#ifndef _sbpci_h_ ++#define _sbpci_h_ ++ ++#ifndef _LANGUAGE_ASSEMBLY ++ ++/* cpp contortions to concatenate w/arg prescan */ ++#ifndef PAD ++#define _PADLINE(line) pad ## line ++#define _XSTR(line) _PADLINE(line) ++#define PAD _XSTR(__LINE__) ++#endif ++ ++/* Sonics side: PCI core and host control registers */ ++typedef struct sbpciregs { ++ uint32 control; /* PCI control */ ++ uint32 PAD[3]; ++ uint32 arbcontrol; /* PCI arbiter control */ ++ uint32 PAD[3]; ++ uint32 intstatus; /* Interrupt status */ ++ uint32 intmask; /* Interrupt mask */ ++ uint32 sbtopcimailbox; /* Sonics to PCI mailbox */ ++ uint32 PAD[9]; ++ uint32 bcastaddr; /* Sonics broadcast address */ ++ uint32 bcastdata; /* Sonics broadcast data */ ++ uint32 PAD[2]; ++ uint32 gpioin; /* ro: gpio input (>=rev2) */ ++ uint32 gpioout; /* rw: gpio output (>=rev2) */ ++ uint32 gpioouten; /* rw: gpio output enable (>= rev2) */ ++ uint32 gpiocontrol; /* rw: gpio control (>= rev2) */ ++ uint32 PAD[36]; ++ uint32 sbtopci0; /* Sonics to PCI translation 0 */ ++ uint32 sbtopci1; /* Sonics to PCI translation 1 */ ++ uint32 sbtopci2; /* Sonics to PCI translation 2 */ ++ uint32 PAD[189]; ++ uint32 pcicfg[4][64]; /* 0x400 - 0x7FF, PCI Cfg Space (>=rev8) */ ++ uint16 sprom[36]; /* SPROM shadow Area */ ++ uint32 PAD[46]; ++} sbpciregs_t; ++ ++#endif /* _LANGUAGE_ASSEMBLY */ ++ ++/* PCI control */ ++#define PCI_RST_OE 0x01 /* When set, drives PCI_RESET out to pin */ ++#define PCI_RST 0x02 /* Value driven out to pin */ ++#define PCI_CLK_OE 0x04 /* When set, drives clock as gated by PCI_CLK out to pin */ ++#define PCI_CLK 0x08 /* Gate for clock driven out to pin */ ++ ++/* PCI arbiter control */ ++#define PCI_INT_ARB 0x01 /* When set, use an internal arbiter */ ++#define PCI_EXT_ARB 0x02 /* When set, use an external arbiter */ ++/* ParkID - for PCI corerev >= 8 */ ++#define PCI_PARKID_MASK 0x1c /* Selects which agent is parked on an idle bus */ ++#define PCI_PARKID_SHIFT 2 ++#define PCI_PARKID_EXT0 0 /* External master 0 */ ++#define PCI_PARKID_EXT1 1 /* External master 1 */ ++#define PCI_PARKID_EXT2 2 /* External master 2 */ ++#define PCI_PARKID_INT 3 /* Internal master */ ++#define PCI_PARKID_LAST 4 /* Last active master */ ++ ++/* Interrupt status/mask */ ++#define PCI_INTA 0x01 /* PCI INTA# is asserted */ ++#define PCI_INTB 0x02 /* PCI INTB# is asserted */ ++#define PCI_SERR 0x04 /* PCI SERR# has been asserted (write one to clear) */ ++#define PCI_PERR 0x08 /* PCI PERR# has been asserted (write one to clear) */ ++#define PCI_PME 0x10 /* PCI PME# is asserted */ ++ ++/* (General) PCI/SB mailbox interrupts, two bits per pci function */ ++#define MAILBOX_F0_0 0x100 /* function 0, int 0 */ ++#define MAILBOX_F0_1 0x200 /* function 0, int 1 */ ++#define MAILBOX_F1_0 0x400 /* function 1, int 0 */ ++#define MAILBOX_F1_1 0x800 /* function 1, int 1 */ ++#define MAILBOX_F2_0 0x1000 /* function 2, int 0 */ ++#define MAILBOX_F2_1 0x2000 /* function 2, int 1 */ ++#define MAILBOX_F3_0 0x4000 /* function 3, int 0 */ ++#define MAILBOX_F3_1 0x8000 /* function 3, int 1 */ ++ ++/* Sonics broadcast address */ ++#define BCAST_ADDR_MASK 0xff /* Broadcast register address */ ++ ++/* Sonics to PCI translation types */ ++#define SBTOPCI0_MASK 0xfc000000 ++#define SBTOPCI1_MASK 0xfc000000 ++#define SBTOPCI2_MASK 0xc0000000 ++#define SBTOPCI_MEM 0 ++#define SBTOPCI_IO 1 ++#define SBTOPCI_CFG0 2 ++#define SBTOPCI_CFG1 3 ++#define SBTOPCI_PREF 0x4 /* prefetch enable */ ++#define SBTOPCI_BURST 0x8 /* burst enable */ ++#define SBTOPCI_RC_MASK 0x30 /* read command (>= rev11) */ ++#define SBTOPCI_RC_READ 0x00 /* memory read */ ++#define SBTOPCI_RC_READLINE 0x10 /* memory read line */ ++#define SBTOPCI_RC_READMULTI 0x20 /* memory read multiple */ ++ ++/* PCI core index in SROM shadow area */ ++#define SRSH_PI_OFFSET 0 /* first word */ ++#define SRSH_PI_MASK 0xf000 /* bit 15:12 */ ++#define SRSH_PI_SHIFT 12 /* bit 15:12 */ ++ ++#endif /* _sbpci_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/sbpcmcia.h linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h --- linux.old/arch/mips/bcm947xx/include/sbpcmcia.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h 2006-04-27 20:29:47.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,147 @@ +/* + * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. @@ -7861,7 +7810,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbpcmcia.h linux.dev/arch/mips/bc +#endif /* _SBPCMCIA_H */ diff -urN linux.old/arch/mips/bcm947xx/include/sbsdram.h linux.dev/arch/mips/bcm947xx/include/sbsdram.h --- linux.old/arch/mips/bcm947xx/include/sbsdram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbsdram.h 2006-04-27 20:36:08.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbsdram.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,85 @@ +/* + * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions. @@ -7950,7 +7899,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbsdram.h linux.dev/arch/mips/bcm +#endif /* _SBSDRAM_H */ diff -urN linux.old/arch/mips/bcm947xx/include/sbsocram.h linux.dev/arch/mips/bcm947xx/include/sbsocram.h --- linux.old/arch/mips/bcm947xx/include/sbsocram.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbsocram.h 2006-04-27 22:13:19.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbsocram.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,64 @@ +/* + * BCM47XX Sonics SiliconBackplane embedded ram core @@ -8018,7 +7967,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbsocram.h linux.dev/arch/mips/bc +#endif /* _SBSOCRAM_H */ diff -urN linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm947xx/include/sbutils.h --- linux.old/arch/mips/bcm947xx/include/sbutils.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sbutils.h 2006-04-27 23:09:25.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbutils.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,150 @@ +/* + * Misc utility routines for accessing chip-specific features @@ -8172,7 +8121,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm +#endif /* _sbutils_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/sflash.h linux.dev/arch/mips/bcm947xx/include/sflash.h --- linux.old/arch/mips/bcm947xx/include/sflash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/sflash.h 2006-04-27 22:13:51.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sflash.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,36 @@ +/* + * Broadcom SiliconBackplane chipcommon serial flash interface @@ -8212,7 +8161,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sflash.h linux.dev/arch/mips/bcm9 +#endif /* _sflash_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/trxhdr.h linux.dev/arch/mips/bcm947xx/include/trxhdr.h --- linux.old/arch/mips/bcm947xx/include/trxhdr.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/trxhdr.h 2006-04-27 19:24:19.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/trxhdr.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,33 @@ +/* + * TRX image file header format. @@ -8249,7 +8198,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/trxhdr.h linux.dev/arch/mips/bcm9 +typedef struct trx_header TRXHDR, *PTRXHDR; diff -urN linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bcm947xx/include/typedefs.h --- linux.old/arch/mips/bcm947xx/include/typedefs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/typedefs.h 2006-04-27 23:47:30.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/typedefs.h 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,361 @@ +/* + * Copyright 2006, Broadcom Corporation @@ -8612,9 +8561,30 @@ diff -urN linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bc +#include "bcmdefs.h" + +#endif /* _TYPEDEFS_H_ */ +diff -urN linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Makefile +--- linux.old/arch/mips/bcm947xx/Makefile 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/Makefile 2006-10-02 21:26:08.000000000 +0200 +@@ -0,0 +1,17 @@ ++# ++# Makefile for the BCM947xx specific kernel interface routines ++# under Linux. ++# ++ ++EXTRA_CFLAGS+=-I$(TOPDIR)/arch/mips/bcm947xx/include -DBCMDRIVER -fno-delayed-branch ++ ++O_TARGET := bcm947xx.o ++ ++export-objs := export.o ++obj-y := prom.o setup.o time.o sbmips.o gpio.o ++obj-y += nvram.o nvram_linux.o sflash.o cfe_env.o ++obj-y += sbutils.o bcmutils.o bcmsrom.o hndchipc.o ++obj-$(CONFIG_PCI) += sbpci.o pcibios.o ++obj-y += export.o ++ ++include $(TOPDIR)/Rules.make diff -urN linux.old/arch/mips/bcm947xx/nvram.c linux.dev/arch/mips/bcm947xx/nvram.c --- linux.old/arch/mips/bcm947xx/nvram.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/nvram.c 2006-04-27 23:11:58.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/nvram.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,315 @@ +/* + * NVRAM variable manipulation (common) @@ -8933,7 +8903,7 @@ diff -urN linux.old/arch/mips/bcm947xx/nvram.c linux.dev/arch/mips/bcm947xx/nvra +} diff -urN linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947xx/nvram_linux.c --- linux.old/arch/mips/bcm947xx/nvram_linux.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/nvram_linux.c 2006-04-27 23:30:07.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/nvram_linux.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,723 @@ +/* + * NVRAM variable manipulation (Linux kernel half) @@ -9660,7 +9630,7 @@ diff -urN linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947x +module_exit(dev_nvram_exit); diff -urN linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/pcibios.c --- linux.old/arch/mips/bcm947xx/pcibios.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/pcibios.c 2006-04-27 23:42:50.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/pcibios.c 2006-10-02 21:22:56.000000000 +0200 @@ -0,0 +1,380 @@ +/* + * Low-Level PCI and SB support for BCM47xx (Linux support code) @@ -10044,7 +10014,7 @@ diff -urN linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/pc + diff -urN linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom.c --- linux.old/arch/mips/bcm947xx/prom.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/prom.c 2006-04-27 19:24:19.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/prom.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,41 @@ +/* + * Early initialization code for BCM94710 boards @@ -10089,7 +10059,7 @@ diff -urN linux.old/arch/mips/bcm947xx/prom.c linux.dev/arch/mips/bcm947xx/prom. +} diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbmips.c --- linux.old/arch/mips/bcm947xx/sbmips.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/sbmips.c 2006-05-02 04:43:13.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/sbmips.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,1132 @@ +/* + * BCM47XX Sonics SiliconBackplane MIPS core routines @@ -11225,7 +11195,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm +#endif /* BCMINTERNAL | BCMPERFSTATS */ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpci.c --- linux.old/arch/mips/bcm947xx/sbpci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/sbpci.c 2006-05-02 17:37:13.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/sbpci.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,768 @@ +/* + * Low-Level PCI and SB support for BCM47xx @@ -11997,7 +11967,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc + diff -urN linux.old/arch/mips/bcm947xx/sbutils.c linux.dev/arch/mips/bcm947xx/sbutils.c --- linux.old/arch/mips/bcm947xx/sbutils.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/sbutils.c 2006-05-02 04:33:16.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/sbutils.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,3081 @@ +/* + * Misc utility routines for accessing chip-specific features @@ -15082,7 +15052,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbutils.c linux.dev/arch/mips/bcm947xx/sb + diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setup.c --- linux.old/arch/mips/bcm947xx/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/setup.c 2006-04-27 23:22:53.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/setup.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,241 @@ +/* + * Generic setup routines for Broadcom MIPS boards @@ -15327,7 +15297,7 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu + diff -urN linux.old/arch/mips/bcm947xx/sflash.c linux.dev/arch/mips/bcm947xx/sflash.c --- linux.old/arch/mips/bcm947xx/sflash.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/sflash.c 2006-04-27 22:11:27.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/sflash.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,422 @@ +/* + * Broadcom SiliconBackplane chipcommon serial flash interface @@ -15753,7 +15723,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sflash.c linux.dev/arch/mips/bcm947xx/sfl +} diff -urN linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time.c --- linux.old/arch/mips/bcm947xx/time.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/time.c 2006-04-28 00:45:40.000000000 +0200 ++++ linux.dev/arch/mips/bcm947xx/time.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,104 @@ +/* + * Copyright 2006, Broadcom Corporation @@ -15860,8 +15830,8 @@ diff -urN linux.old/arch/mips/bcm947xx/time.c linux.dev/arch/mips/bcm947xx/time. + setup_irq(7, &bcm947xx_timer_irqaction); +} diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared.in ---- linux.old/arch/mips/config-shared.in 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/arch/mips/config-shared.in 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/arch/mips/config-shared.in 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/arch/mips/config-shared.in 2006-10-02 21:19:59.000000000 +0200 @@ -208,6 +208,14 @@ fi define_bool CONFIG_MIPS_RTC y @@ -15902,7 +15872,7 @@ diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared if [ "$CONFIG_SNI_RM200_PCI" = "y" ]; then define_bool CONFIG_ARC32 y define_bool CONFIG_ARC_MEMORY y -@@ -1042,7 +1062,11 @@ +@@ -1042,7 +1061,11 @@ bool 'Are you using a crosscompiler' CONFIG_CROSSCOMPILE bool 'Enable run-time debugging' CONFIG_RUNTIME_DEBUG @@ -15916,8 +15886,8 @@ diff -urN linux.old/arch/mips/config-shared.in linux.dev/arch/mips/config-shared if [ "$CONFIG_KGDB" = "y" ]; then define_bool CONFIG_DEBUG_INFO y diff -urN linux.old/arch/mips/kernel/cpu-probe.c linux.dev/arch/mips/kernel/cpu-probe.c ---- linux.old/arch/mips/kernel/cpu-probe.c 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/arch/mips/kernel/cpu-probe.c 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/arch/mips/kernel/cpu-probe.c 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/arch/mips/kernel/cpu-probe.c 2006-10-02 21:19:59.000000000 +0200 @@ -162,7 +162,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) @@ -16038,8 +16008,8 @@ diff -urN linux.old/arch/mips/kernel/cpu-probe.c linux.dev/arch/mips/kernel/cpu- cpu_probe_sibyte(c); break; diff -urN linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S ---- linux.old/arch/mips/kernel/head.S 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/arch/mips/kernel/head.S 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/arch/mips/kernel/head.S 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/arch/mips/kernel/head.S 2006-10-02 21:19:59.000000000 +0200 @@ -28,12 +28,20 @@ #include #include @@ -16063,8 +16033,8 @@ diff -urN linux.old/arch/mips/kernel/head.S linux.dev/arch/mips/kernel/head.S /* The following two symbols are used for kernel profiling. */ EXPORT(stext) diff -urN linux.old/arch/mips/kernel/proc.c linux.dev/arch/mips/kernel/proc.c ---- linux.old/arch/mips/kernel/proc.c 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/arch/mips/kernel/proc.c 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/arch/mips/kernel/proc.c 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/arch/mips/kernel/proc.c 2006-10-02 21:19:59.000000000 +0200 @@ -78,9 +78,10 @@ [CPU_AU1550] "Au1550", [CPU_24K] "MIPS 24K", @@ -16078,8 +16048,8 @@ diff -urN linux.old/arch/mips/kernel/proc.c linux.dev/arch/mips/kernel/proc.c { unsigned int version = current_cpu_data.processor_id; diff -urN linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c ---- linux.old/arch/mips/kernel/setup.c 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/arch/mips/kernel/setup.c 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/arch/mips/kernel/setup.c 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/arch/mips/kernel/setup.c 2006-10-02 21:19:59.000000000 +0200 @@ -493,6 +493,7 @@ void swarm_setup(void); void hp_setup(void); @@ -16101,8 +16071,8 @@ diff -urN linux.old/arch/mips/kernel/setup.c linux.dev/arch/mips/kernel/setup.c panic("Unsupported architecture"); } diff -urN linux.old/arch/mips/kernel/traps.c linux.dev/arch/mips/kernel/traps.c ---- linux.old/arch/mips/kernel/traps.c 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/arch/mips/kernel/traps.c 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/arch/mips/kernel/traps.c 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/arch/mips/kernel/traps.c 2006-10-02 21:19:59.000000000 +0200 @@ -920,6 +920,7 @@ void __init trap_init(void) { @@ -16132,9 +16102,40 @@ diff -urN linux.old/arch/mips/kernel/traps.c linux.dev/arch/mips/kernel/traps.c if (cpu_has_fpu && !cpu_has_nofpuex) set_except_vector(15, handle_fpe); +diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile +--- linux.old/arch/mips/Makefile 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/arch/mips/Makefile 2006-10-02 21:19:59.000000000 +0200 +@@ -726,6 +726,19 @@ + endif + + # ++# Broadcom BCM947XX variants ++# ++ifdef CONFIG_BCM947XX ++LIBS += arch/mips/bcm947xx/generic/brcm.o arch/mips/bcm947xx/bcm947xx.o ++SUBDIRS += arch/mips/bcm947xx/generic arch/mips/bcm947xx ++LOADADDR := 0x80001000 ++ ++zImage: vmlinux ++ $(MAKE) -C arch/$(ARCH)/bcm947xx/compressed ++export LOADADDR ++endif ++ ++# + # Choosing incompatible machines durings configuration will result in + # error messages during linking. Select a default linkscript if + # none has been choosen above. +@@ -778,6 +791,7 @@ + $(MAKE) -C arch/$(ARCH)/tools clean + $(MAKE) -C arch/mips/baget clean + $(MAKE) -C arch/mips/lasat clean ++ $(MAKE) -C arch/mips/bcm947xx/compressed clean + + archmrproper: + @$(MAKEBOOT) mrproper diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c ---- linux.old/arch/mips/mm/c-r4k.c 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/arch/mips/mm/c-r4k.c 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/arch/mips/mm/c-r4k.c 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/arch/mips/mm/c-r4k.c 2006-10-02 21:19:59.000000000 +0200 @@ -1166,3 +1166,47 @@ build_clear_page(); build_copy_page(); @@ -16184,8 +16185,8 @@ diff -urN linux.old/arch/mips/mm/c-r4k.c linux.dev/arch/mips/mm/c-r4k.c + + diff -urN linux.old/arch/mips/pci/Makefile linux.dev/arch/mips/pci/Makefile ---- linux.old/arch/mips/pci/Makefile 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/arch/mips/pci/Makefile 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/arch/mips/pci/Makefile 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/arch/mips/pci/Makefile 2006-10-02 21:19:59.000000000 +0200 @@ -13,7 +13,9 @@ obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o @@ -16197,8 +16198,8 @@ diff -urN linux.old/arch/mips/pci/Makefile linux.dev/arch/mips/pci/Makefile include $(TOPDIR)/Rules.make diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c ---- linux.old/drivers/char/serial.c 2006-04-27 18:04:37.000000000 +0200 -+++ linux.dev/drivers/char/serial.c 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/drivers/char/serial.c 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/drivers/char/serial.c 2006-10-02 21:19:59.000000000 +0200 @@ -444,6 +444,10 @@ return inb(info->port+1); #endif @@ -16268,8 +16269,8 @@ diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c #if defined(__powerpc__) || defined(__alpha__) cval >>= 8; diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile ---- linux.old/drivers/net/Makefile 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/drivers/net/Makefile 2006-05-04 01:41:03.000000000 +0200 +--- linux.old/drivers/net/Makefile 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/drivers/net/Makefile 2006-10-02 21:19:59.000000000 +0200 @@ -3,6 +3,8 @@ # Makefile for the Linux network (ethercard) device drivers. # @@ -16280,8 +16281,8 @@ diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile obj-m := obj-n := diff -urN linux.old/drivers/parport/Config.in linux.dev/drivers/parport/Config.in ---- linux.old/drivers/parport/Config.in 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/drivers/parport/Config.in 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/drivers/parport/Config.in 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/drivers/parport/Config.in 2006-10-02 21:19:59.000000000 +0200 @@ -11,6 +11,7 @@ tristate 'Parallel port support' CONFIG_PARPORT if [ "$CONFIG_PARPORT" != "n" ]; then @@ -16291,8 +16292,8 @@ diff -urN linux.old/drivers/parport/Config.in linux.dev/drivers/parport/Config.i if [ "$CONFIG_SERIAL" = "m" ]; then define_tristate CONFIG_PARPORT_PC_CML1 m diff -urN linux.old/drivers/parport/Makefile linux.dev/drivers/parport/Makefile ---- linux.old/drivers/parport/Makefile 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/drivers/parport/Makefile 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/drivers/parport/Makefile 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/drivers/parport/Makefile 2006-10-02 21:19:59.000000000 +0200 @@ -22,6 +22,7 @@ obj-$(CONFIG_PARPORT) += parport.o @@ -16303,7 +16304,7 @@ diff -urN linux.old/drivers/parport/Makefile linux.dev/drivers/parport/Makefile obj-$(CONFIG_PARPORT_MFC3) += parport_mfc3.o diff -urN linux.old/drivers/parport/parport_splink.c linux.dev/drivers/parport/parport_splink.c --- linux.old/drivers/parport/parport_splink.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/parport/parport_splink.c 2006-04-27 19:24:19.000000000 +0200 ++++ linux.dev/drivers/parport/parport_splink.c 2006-10-02 21:19:59.000000000 +0200 @@ -0,0 +1,345 @@ +/* Low-level parallel port routines for the ASUS WL-500g built-in port + * @@ -16651,8 +16652,8 @@ diff -urN linux.old/drivers/parport/parport_splink.c linux.dev/drivers/parport/p +module_exit(parport_splink_cleanup) + diff -urN linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h ---- linux.old/include/asm-mips/bootinfo.h 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/include/asm-mips/bootinfo.h 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/include/asm-mips/bootinfo.h 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/include/asm-mips/bootinfo.h 2006-10-02 21:19:59.000000000 +0200 @@ -37,6 +37,7 @@ #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ #define MACH_GROUP_LASAT 21 @@ -16678,8 +16679,8 @@ diff -urN linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/booti */ #define MACH_TITAN_YOSEMITE 1 /* PMC-Sierra Yosemite */ diff -urN linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h ---- linux.old/include/asm-mips/cpu.h 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/include/asm-mips/cpu.h 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/include/asm-mips/cpu.h 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/include/asm-mips/cpu.h 2006-10-02 21:19:59.000000000 +0200 @@ -22,6 +22,11 @@ spec. */ @@ -16729,8 +16730,8 @@ diff -urN linux.old/include/asm-mips/cpu.h linux.dev/include/asm-mips/cpu.h /* * ISA Level encodings diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kcache.h ---- linux.old/include/asm-mips/r4kcache.h 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/include/asm-mips/r4kcache.h 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/include/asm-mips/r4kcache.h 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/include/asm-mips/r4kcache.h 2006-10-02 21:19:59.000000000 +0200 @@ -658,4 +658,17 @@ cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } @@ -16750,8 +16751,8 @@ diff -urN linux.old/include/asm-mips/r4kcache.h linux.dev/include/asm-mips/r4kca + #endif /* __ASM_R4KCACHE_H */ diff -urN linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial.h ---- linux.old/include/asm-mips/serial.h 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/include/asm-mips/serial.h 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/include/asm-mips/serial.h 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/include/asm-mips/serial.h 2006-10-02 21:19:59.000000000 +0200 @@ -223,6 +223,13 @@ #define TXX927_SERIAL_PORT_DEFNS #endif @@ -16775,8 +16776,8 @@ diff -urN linux.old/include/asm-mips/serial.h linux.dev/include/asm-mips/serial. DDB5477_SERIAL_PORT_DEFNS \ EV96100_SERIAL_PORT_DEFNS \ diff -urN linux.old/init/do_mounts.c linux.dev/init/do_mounts.c ---- linux.old/init/do_mounts.c 2006-04-27 18:04:38.000000000 +0200 -+++ linux.dev/init/do_mounts.c 2006-04-27 19:24:19.000000000 +0200 +--- linux.old/init/do_mounts.c 2006-10-02 21:23:10.000000000 +0200 ++++ linux.dev/init/do_mounts.c 2006-10-02 21:19:59.000000000 +0200 @@ -254,7 +254,13 @@ { "ftlb", 0x2c08 }, { "ftlc", 0x2c10 }, -- cgit v1.2.3