X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fsvn-archive%2Farchive.git;a=blobdiff_plain;f=openwrt%2Ftarget%2Flinux%2Flinux-2.4%2Fpatches%2Fbrcm%2F001-bcm47xx.patch;h=7a61637022849b0b4874fced1289ff709077b573;hp=973487846e9eabf1b63f6c34e92168ad9ee7c5d0;hb=1cbb4fcad627b69e13455a673be4e638d48375cc;hpb=382687ad4428bb03c4c26892c3d2a2e94f4636e9 diff --git a/openwrt/target/linux/linux-2.4/patches/brcm/001-bcm47xx.patch b/openwrt/target/linux/linux-2.4/patches/brcm/001-bcm47xx.patch index 973487846e..7a61637022 100644 --- a/openwrt/target/linux/linux-2.4/patches/brcm/001-bcm47xx.patch +++ b/openwrt/target/linux/linux-2.4/patches/brcm/001-bcm47xx.patch @@ -44,8 +44,8 @@ diff -urN linux.old/Makefile linux.dev/Makefile ifdef CONFIG_MODVERSIONS diff -urN linux.old/Rules.make linux.dev/Rules.make ---- linux.old/Rules.make 2004-02-18 14:36:30.000000000 +0100 -+++ linux.dev/Rules.make 2005-08-26 13:44:34.252400640 +0200 +--- linux.old/Rules.make 2005-11-07 23:12:50.538884250 +0100 ++++ linux.dev/Rules.make 2005-11-07 21:57:07.837585250 +0100 @@ -176,7 +176,14 @@ _modinst__: dummy ifneq "$(strip $(ALL_MOBJS))" "" @@ -63,8 +63,8 @@ diff -urN linux.old/Rules.make linux.dev/Rules.make .PHONY: modules_install diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile ---- linux.old/arch/mips/Makefile 2005-08-26 13:41:41.690634016 +0200 -+++ linux.dev/arch/mips/Makefile 2005-08-26 13:44:34.253400488 +0200 +--- linux.old/arch/mips/Makefile 2005-11-07 23:12:50.582887000 +0100 ++++ linux.dev/arch/mips/Makefile 2005-11-07 21:57:08.537629000 +0100 @@ -46,10 +46,10 @@ GCCFLAGS := -I $(TOPDIR)/include/asm/gcc GCCFLAGS += -G 0 -mno-abicalls -fno-pic -pipe @@ -142,7 +142,7 @@ diff -urN linux.old/arch/mips/Makefile linux.dev/arch/mips/Makefile @$(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 2005-08-26 13:44:34.262399120 +0200 ++++ linux.dev/arch/mips/bcm947xx/Makefile 2005-11-08 00:55:04.392074500 +0100 @@ -0,0 +1,15 @@ +# +# Makefile for the BCM947xx specific kernel interface routines @@ -155,13 +155,13 @@ diff -urN linux.old/arch/mips/bcm947xx/Makefile linux.dev/arch/mips/bcm947xx/Mak + +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 ++obj-y += nvram.o nvram_linux.o sflash.o +obj-$(CONFIG_PCI) += sbpci.o pcibios.o + +include $(TOPDIR)/Rules.make 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 2005-08-26 13:44:34.262399120 +0200 ++++ linux.dev/arch/mips/bcm947xx/compressed/Makefile 2005-11-07 21:57:07.841585500 +0100 @@ -0,0 +1,33 @@ +# +# Makefile for Broadcom BCM947XX boards @@ -198,7 +198,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/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 2005-08-26 13:44:34.263398968 +0200 ++++ linux.dev/arch/mips/bcm947xx/generic/Makefile 2005-11-07 21:57:07.841585500 +0100 @@ -0,0 +1,15 @@ +# +# Makefile for the BCM947xx specific kernel interface routines @@ -217,7 +217,7 @@ diff -urN linux.old/arch/mips/bcm947xx/generic/Makefile linux.dev/arch/mips/bcm9 +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 2005-08-26 13:44:34.263398968 +0200 ++++ linux.dev/arch/mips/bcm947xx/generic/int-handler.S 2005-11-07 21:57:07.841585500 +0100 @@ -0,0 +1,51 @@ +/* + * Generic interrupt handler for Broadcom MIPS boards @@ -272,7 +272,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 2005-08-26 13:44:34.263398968 +0200 ++++ linux.dev/arch/mips/bcm947xx/generic/irq.c 2005-11-07 21:57:07.841585500 +0100 @@ -0,0 +1,130 @@ +/* + * Generic interrupt control functions for Broadcom MIPS boards @@ -406,12 +406,12 @@ diff -urN linux.old/arch/mips/bcm947xx/generic/irq.c linux.dev/arch/mips/bcm947x +} 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 2005-08-26 13:44:34.264398816 +0200 ++++ linux.dev/arch/mips/bcm947xx/gpio.c 2005-11-07 23:58:34.968754500 +0100 @@ -0,0 +1,158 @@ +/* + * GPIO char driver + * -+ * Copyright 2004, Broadcom Corporation ++ * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -419,7 +419,7 @@ diff -urN linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio. + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id: gpio.c,v 1.1 2005/03/16 13:49:59 wbx Exp $ ++ * $Id$ + */ + +#include @@ -433,7 +433,7 @@ diff -urN linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio. +#include +#include + -+static void *gpio_sbh; ++static sb_t *gpio_sbh; +static int gpio_major; +static devfs_handle_t gpio_dir; +static struct { @@ -473,13 +473,13 @@ diff -urN linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio. + val = sb_gpioin(gpio_sbh); + break; + case 1: -+ val = sb_gpioout(gpio_sbh, 0, 0); ++ val = sb_gpioout(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); + break; + case 2: -+ val = sb_gpioouten(gpio_sbh, 0, 0); ++ val = sb_gpioouten(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); + break; + case 3: -+ val = sb_gpiocontrol(gpio_sbh, 0, 0); ++ val = sb_gpiocontrol(gpio_sbh, 0, 0, GPIO_DRV_PRIORITY); + break; + default: + return -ENODEV; @@ -503,13 +503,13 @@ diff -urN linux.old/arch/mips/bcm947xx/gpio.c linux.dev/arch/mips/bcm947xx/gpio. + case 0: + return -EACCES; + case 1: -+ sb_gpioout(gpio_sbh, ~0, val); ++ sb_gpioout(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); + break; + case 2: -+ sb_gpioouten(gpio_sbh, ~0, val); ++ sb_gpioouten(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); + break; + case 3: -+ sb_gpiocontrol(gpio_sbh, ~0, val); ++ sb_gpiocontrol(gpio_sbh, ~0, val, GPIO_DRV_PRIORITY); + break; + default: + return -ENODEV; @@ -568,8 +568,8 @@ 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/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 2005-08-26 13:44:34.265398664 +0200 -@@ -0,0 +1,369 @@ ++++ linux.dev/arch/mips/bcm947xx/include/bcmdevs.h 2005-11-07 22:51:38.772725750 +0100 +@@ -0,0 +1,391 @@ +/* + * Broadcom device-specific manifest constants. + * @@ -668,6 +668,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +#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!) */ @@ -750,6 +752,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +#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 */ @@ -778,9 +781,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +#endif + +/* power control defines */ -+#define PLL_DELAY 150 /* 150us pll on delay */ -+#define FREF_DELAY 200 /* 200us fref change delay */ -+#define MIN_SLOW_CLK 32 /* 32us Slow clock period */ ++#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 */ + @@ -885,6 +889,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +#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 + @@ -919,6 +928,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm +/* 4306mplna */ +#define BCM94306MPLNA_BOARD 0x0457 + ++/* 4320 boards */ ++#define BU4320_BOARD 0x0458 ++#define BU4320S_BOARD 0x0459 ++#define BCM94320PH_BOARD 0x045a + +/* 4306mph */ +#define BCM94306MPH_BOARD 0x045b @@ -928,21 +941,30 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmdevs.h linux.dev/arch/mips/bcm + +#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 -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 2005-08-26 13:44:34.269398056 +0200 -@@ -0,0 +1,168 @@ ++++ linux.dev/arch/mips/bcm947xx/include/bcmendian.h 2005-11-07 22:51:38.772725750 +0100 +@@ -0,0 +1,152 @@ +/* + * local version of endian.h - byte order defines + * @@ -975,6 +997,13 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/b + (((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) @@ -988,6 +1017,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/b + 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 @@ -1069,51 +1104,22 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmendian.h linux.dev/arch/mips/b + return (bytes[0]<<24)+(bytes[1]<<16)+(bytes[2]<<8)+bytes[3]; +} + -+/* get_ua adapted from Linux asm-mips/unaligned.h */ -+#ifdef IL_BIGENDIAN -+#define get_ua(ptr) \ -+({ \ -+ __typeof__(*(ptr)) __val; \ -+ \ -+ switch (sizeof(*(ptr))) { \ -+ case 1: \ -+ __val = *(uint8 *)ptr; \ -+ break; \ -+ case 2: \ -+ __val = ntoh16_ua((uint8 *)ptr); \ -+ break; \ -+ case 4: \ -+ __val = ntoh32_ua((uint8 *)ptr); \ -+ break; \ -+ } \ -+ \ -+ __val; \ -+}) -+#else -+#define get_ua(ptr) \ -+({ \ -+ __typeof__(*(ptr)) __val; \ -+ \ -+ switch (sizeof(*(ptr))) { \ -+ case 1: \ -+ __val = *(uint8 *)ptr; \ -+ break; \ -+ case 2: \ -+ __val = ltoh16_ua((uint8 *)ptr); \ -+ break; \ -+ case 4: \ -+ __val = ltoh32_ua((uint8 *)ptr); \ -+ break; \ -+ } \ -+ \ -+ __val; \ -+}) -+#endif ++#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/bcmenet47xx.h linux.dev/arch/mips/bcm947xx/include/bcmenet47xx.h --- linux.old/arch/mips/bcm947xx/include/bcmenet47xx.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmenet47xx.h 2005-08-26 13:44:34.270397904 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcmenet47xx.h 2005-11-07 22:51:38.772725750 +0100 @@ -0,0 +1,229 @@ +/* + * Hardware-specific definitions for @@ -1191,8 +1197,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmenet47xx.h linux.dev/arch/mips + uint32 PAD[63]; + + /* DMA engine */ -+ dmaregs_t dmaregs; -+ dmafifo_t dmafifo; ++ dma32regp_t dmaregs; ++ dma32diag_t dmafifo; + uint32 PAD[116]; + + /* EMAC Registers */ @@ -1346,7 +1352,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmenet47xx.h linux.dev/arch/mips +#endif /* _bcmenet_47xx_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/bcmenetmib.h linux.dev/arch/mips/bcm947xx/include/bcmenetmib.h --- linux.old/arch/mips/bcm947xx/include/bcmenetmib.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmenetmib.h 2005-08-26 13:44:34.278396688 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcmenetmib.h 2005-11-07 21:57:07.845585750 +0100 @@ -0,0 +1,81 @@ +/* + * Hardware-specific MIB definition for @@ -1431,7 +1437,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmenetmib.h linux.dev/arch/mips/ +#endif /* _bcmenetmib_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/bcmenetphy.h linux.dev/arch/mips/bcm947xx/include/bcmenetphy.h --- linux.old/arch/mips/bcm947xx/include/bcmenetphy.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmenetphy.h 2005-08-26 13:44:34.278396688 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcmenetphy.h 2005-11-07 21:57:07.845585750 +0100 @@ -0,0 +1,58 @@ +/* + * Misc Broadcom BCM47XX MDC/MDIO enet phy definitions. @@ -1493,7 +1499,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmenetphy.h linux.dev/arch/mips/ +#endif /* _bcmenetphy_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/bcmenetrxh.h linux.dev/arch/mips/bcm947xx/include/bcmenetrxh.h --- linux.old/arch/mips/bcm947xx/include/bcmenetrxh.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmenetrxh.h 2005-08-26 13:44:34.278396688 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bcmenetrxh.h 2005-11-07 21:57:07.845585750 +0100 @@ -0,0 +1,43 @@ +/* + * Hardware-specific Receive Data Header for the @@ -1540,8 +1546,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmenetrxh.h linux.dev/arch/mips/ +#endif /* _bcmenetrxh_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 2005-08-26 13:44:34.279396536 +0200 -@@ -0,0 +1,132 @@ ++++ linux.dev/arch/mips/bcm947xx/include/bcmnvram.h 2005-11-07 22:51:38.772725750 +0100 +@@ -0,0 +1,141 @@ +/* + * NVRAM variable manipulation + * @@ -1566,8 +1572,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bc +struct nvram_header { + uint32 magic; + uint32 len; -+ uint32 crc_ver_init; /* 0:7 crc, 8:15 ver, 16:27 init, mem. test 28, 29-31 reserved */ -+ uint32 config_refresh; /* 0:15 config, 16:31 refresh */ ++ 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 */ +}; + @@ -1587,7 +1593,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bc + * Disable NVRAM access. May be unnecessary or undefined on certain + * platforms. + */ -+extern void BCMINIT(nvram_exit)(void); ++extern void BCMINIT(nvram_exit)(void *sbh); + +/* + * Get the value of an NVRAM variable. The pointer returned may be @@ -1598,6 +1604,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bc +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 @@ -1673,11 +1685,14 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmnvram.h linux.dev/arch/mips/bc +#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 -urN linux.old/arch/mips/bcm947xx/include/bcmparams.h linux.dev/arch/mips/bcm947xx/include/bcmparams.h --- linux.old/arch/mips/bcm947xx/include/bcmparams.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bcmparams.h 2005-08-26 13:44:34.279396536 +0200 -@@ -0,0 +1,23 @@ ++++ linux.dev/arch/mips/bcm947xx/include/bcmparams.h 2005-11-07 22:51:38.776726000 +0100 +@@ -0,0 +1,25 @@ +/* + * Misc system wide parameters. + * @@ -1700,11 +1715,13 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmparams.h linux.dev/arch/mips/b + +#define DEV_NUMIFS 16 /* Max. # of devices/interfaces supported */ + ++#define WL_MAXBSSCFG 16 /* maximum number of BSS Configs we can configure */ ++ +#endif 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 2005-08-26 13:44:34.280396384 +0200 -@@ -0,0 +1,22 @@ ++++ linux.dev/arch/mips/bcm947xx/include/bcmsrom.h 2005-11-07 22:51:38.776726000 +0100 +@@ -0,0 +1,23 @@ +/* + * Misc useful routines to access NIC local SROM/OTP . + * @@ -1722,15 +1739,16 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmsrom.h linux.dev/arch/mips/bcm +#ifndef _bcmsrom_h_ +#define _bcmsrom_h_ + -+extern int srom_var_init(void *sbh, uint bus, void *curmap, void *osh, char **vars, int *count); -+extern int srom_read(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf); -+extern int srom_write(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf); -+ ++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 -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 2005-08-26 13:44:34.280396384 +0200 -@@ -0,0 +1,239 @@ ++++ linux.dev/arch/mips/bcm947xx/include/bcmutils.h 2005-11-07 22:51:38.776726000 +0100 +@@ -0,0 +1,313 @@ +/* + * Misc useful os-independent macros and functions. + * @@ -1760,6 +1778,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bc +#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)]) + @@ -1808,8 +1828,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bc + +/* externs */ +/* packet */ -+extern uint pktcopy(void *drv, void *p, uint offset, int len, uchar *buf); -+extern uint pkttotlen(void *drv, void *); ++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); @@ -1833,9 +1853,59 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bc +#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 @@ -1848,6 +1918,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bc +#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])) + @@ -1860,7 +1931,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bc +#define isclr(a,i) ((((uint8 *)a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) +#endif + -+#define NBITS(type) (sizeof (type) * 8) ++#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 */ @@ -1884,7 +1957,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bc +} bcm_tlv_t; + +/* Check that bcm_tlv_t fits into the given buflen */ -+#define bcm_valid_tlv(elt, buflen) ((buflen) >= 2 && (buflen) >= 2 + (elt)->len) ++#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 @@ -1962,6 +2035,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bc +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 */ @@ -1969,10 +2045,26 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bcmutils.h linux.dev/arch/mips/bc +#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 -urN linux.old/arch/mips/bcm947xx/include/bitfuncs.h linux.dev/arch/mips/bcm947xx/include/bitfuncs.h --- linux.old/arch/mips/bcm947xx/include/bitfuncs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/bitfuncs.h 2005-08-26 13:44:34.281396232 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/bitfuncs.h 2005-11-07 21:57:07.849586000 +0100 @@ -0,0 +1,85 @@ +/* + * bit manipulation utility functions @@ -2061,8 +2153,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/bitfuncs.h linux.dev/arch/mips/bc +#endif /* _BITFUNCS_H */ diff -urN linux.old/arch/mips/bcm947xx/include/cfe_osl.h linux.dev/arch/mips/bcm947xx/include/cfe_osl.h --- linux.old/arch/mips/bcm947xx/include/cfe_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/cfe_osl.h 2005-08-26 13:44:34.281396232 +0200 -@@ -0,0 +1,184 @@ ++++ linux.dev/arch/mips/bcm947xx/include/cfe_osl.h 2005-11-07 22:51:38.776726000 +0100 +@@ -0,0 +1,191 @@ +/* + * CFE boot loader OS Abstraction Layer. + * @@ -2111,6 +2203,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/cfe_osl.h linux.dev/arch/mips/bcm +#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)) @@ -2147,7 +2243,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/cfe_osl.h linux.dev/arch/mips/bcm +/* bcopy, bcmp, and bzero */ +#define bcmp(b1, b2, len) lib_memcmp((b1), (b2), (len)) + -+#define osl_attach(pdev) (pdev) ++#define osl_attach(pdev) ((osl_t*)pdev) +#define osl_detach(osh) + +/* general purpose memory allocation */ @@ -2169,6 +2265,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/cfe_osl.h linux.dev/arch/mips/bcm +/* 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) @@ -2221,18 +2319,18 @@ diff -urN linux.old/arch/mips/bcm947xx/include/cfe_osl.h linux.dev/arch/mips/bcm +#define PKTBUFSZ 2048 + +/* packet primitives */ -+#define PKTGET(drv, len, send) ((void*)osl_pktget((len))) -+#define PKTFREE(drv, lb, send) osl_pktfree((struct lbuf*)(lb)) -+#define PKTDATA(drv, lb) (((struct lbuf*)(lb))->data) -+#define PKTLEN(drv, lb) (((struct lbuf*)(lb))->len) -+#define PKTHEADROOM(drv, lb) (PKTDATA(drv,lb)-(((struct lbuf*)(lb))->head)) -+#define PKTTAILROOM(drv, lb) ((((struct lbuf*)(lb))->end)-(((struct lbuf*)(lb))->tail)) -+#define PKTNEXT(drv, lb) (((struct lbuf*)(lb))->next) ++#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(drv, lb, len) osl_pktsetlen((struct lbuf*)(lb), (len)) -+#define PKTPUSH(drv, lb, bytes) osl_pktpush((struct lbuf*)(lb), (bytes)) -+#define PKTPULL(drv, lb, bytes) osl_pktpull((struct lbuf*)(lb), (bytes)) -+#define PKTDUP(drv, lb) osl_pktdup((struct lbuf*)(lb)) ++#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) @@ -2245,11 +2343,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/cfe_osl.h linux.dev/arch/mips/bcm +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 -urN linux.old/arch/mips/bcm947xx/include/epivers.h linux.dev/arch/mips/bcm947xx/include/epivers.h --- linux.old/arch/mips/bcm947xx/include/epivers.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/epivers.h 2005-08-26 13:44:34.282396080 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/epivers.h 2005-11-07 22:51:38.776726000 +0100 @@ -0,0 +1,69 @@ +/* + * Copyright 2005, Broadcom Corporation @@ -2303,26 +2402,26 @@ diff -urN linux.old/arch/mips/bcm947xx/include/epivers.h linux.dev/arch/mips/bcm + +#define EPI_MAJOR_VERSION 3 + -+#define EPI_MINOR_VERSION 90 ++#define EPI_MINOR_VERSION 130 + -+#define EPI_RC_NUMBER 23 ++#define EPI_RC_NUMBER 20 + +#define EPI_INCREMENTAL_NUMBER 0 + +#define EPI_BUILD_NUMBER 0 + -+#define EPI_VERSION 3,90,23,0 ++#define EPI_VERSION 3,130,20,0 + -+#define EPI_VERSION_NUM 0x035a1700 ++#define EPI_VERSION_NUM 0x03821400 + +/* Driver Version String, ASCII, 32 chars max */ -+#define EPI_VERSION_STR "3.90.23.0" -+#define EPI_ROUTER_VERSION_STR "3.91.23.0" ++#define EPI_VERSION_STR "3.130.20.0" ++#define EPI_ROUTER_VERSION_STR "3.131.20.0" + +#endif /* _epivers_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/epivers.h.in linux.dev/arch/mips/bcm947xx/include/epivers.h.in --- linux.old/arch/mips/bcm947xx/include/epivers.h.in 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/epivers.h.in 2005-08-26 13:44:34.282396080 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/epivers.h.in 2005-11-07 21:57:07.849586000 +0100 @@ -0,0 +1,69 @@ +/* + * Copyright 2005, Broadcom Corporation @@ -2395,7 +2494,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/epivers.h.in linux.dev/arch/mips/ +#endif /* _epivers_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/etsockio.h linux.dev/arch/mips/bcm947xx/include/etsockio.h --- linux.old/arch/mips/bcm947xx/include/etsockio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/etsockio.h 2005-08-26 13:44:34.283395928 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/etsockio.h 2005-11-07 21:57:07.861586750 +0100 @@ -0,0 +1,59 @@ +/* + * Driver-specific socket ioctls @@ -2458,7 +2557,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/etsockio.h linux.dev/arch/mips/bc +#endif diff -urN linux.old/arch/mips/bcm947xx/include/flash.h linux.dev/arch/mips/bcm947xx/include/flash.h --- linux.old/arch/mips/bcm947xx/include/flash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/flash.h 2005-08-27 02:56:56.458670688 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/flash.h 2005-11-07 21:57:07.861586750 +0100 @@ -0,0 +1,188 @@ +/* + * flash.h: Common definitions for flash access. @@ -2650,7 +2749,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/flash.h linux.dev/arch/mips/bcm94 +#endif diff -urN linux.old/arch/mips/bcm947xx/include/flashutl.h linux.dev/arch/mips/bcm947xx/include/flashutl.h --- linux.old/arch/mips/bcm947xx/include/flashutl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/flashutl.h 2005-08-26 13:44:34.284395776 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/flashutl.h 2005-11-07 21:57:07.861586750 +0100 @@ -0,0 +1,27 @@ +/* + * BCM47XX FLASH driver interface @@ -2681,10 +2780,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/flashutl.h linux.dev/arch/mips/bc +#endif /* _flashutl_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/hnddma.h linux.dev/arch/mips/bcm947xx/include/hnddma.h --- linux.old/arch/mips/bcm947xx/include/hnddma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/hnddma.h 2005-08-26 13:44:34.284395776 +0200 -@@ -0,0 +1,184 @@ ++++ linux.dev/arch/mips/bcm947xx/include/hnddma.h 2005-11-07 22:51:38.776726000 +0100 +@@ -0,0 +1,71 @@ +/* -+ * Generic Broadcom Home Networking Division (HND) DMA engine definitions. ++ * Generic Broadcom Home Networking Division (HND) DMA engine SW interface + * This supports the following chips: BCM42xx, 44xx, 47xx . + * + * Copyright 2005, Broadcom Corporation @@ -2700,125 +2799,6 @@ diff -urN linux.old/arch/mips/bcm947xx/include/hnddma.h linux.dev/arch/mips/bcm9 +#ifndef _hnddma_h_ +#define _hnddma_h_ + -+/* -+ * Each DMA processor consists of a transmit channel and a receive channel. -+ */ -+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 volatile struct { -+ /* diag access */ -+ uint32 fifoaddr; /* diag address */ -+ uint32 fifodatalow; /* low 32bits of data */ -+ uint32 fifodatahigh; /* high 32bits of data */ -+ uint32 pad; /* reserved */ -+} dmafifo_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 */ -+ -+/* 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 */ -+ -+/* 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 */ -+ -+/* -+ * 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 */ -+} dmadd_t; -+ -+/* -+ * Each descriptor ring must be 4096byte aligned -+ * and fit within a single 4096byte page. -+ */ -+#define DMAMAXRINGSZ 4096 -+#define DMARINGALIGN 4096 -+ -+/* control flags */ -+#define CTRL_BC_MASK 0x1fff /* buffer byte count */ -+#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 -+ +/* export structure */ +typedef volatile struct { + /* rx error counters */ @@ -2832,10 +2812,13 @@ diff -urN linux.old/arch/mips/bcm947xx/include/hnddma.h linux.dev/arch/mips/bcm9 +#define di_t void +#endif + ++#ifndef osl_t ++#define osl_t void ++#endif ++ +/* externs */ -+extern void * dma_attach(void *drv, void *dev, char *name, dmaregs_t *dmaregs, -+ uint ntxd, uint nrxd, uint rxbufsize, uint nrxpost, uint rxoffset, -+ uint ddoffset, uint dataoffset, uint *msg_level); ++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); @@ -2847,10 +2830,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/hnddma.h linux.dev/arch/mips/bcm9 +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 int dma_tx(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); @@ -2865,11 +2848,14 @@ diff -urN linux.old/arch/mips/bcm947xx/include/hnddma.h linux.dev/arch/mips/bcm9 +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 -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 2005-08-26 13:44:34.285395624 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/hndmips.h 2005-11-07 21:57:07.861586750 +0100 @@ -0,0 +1,16 @@ +/* + * Alternate include file for HND sbmips.h since CFE also ships with @@ -2889,8 +2875,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/hndmips.h linux.dev/arch/mips/bcm +#include "sbmips.h" diff -urN 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 2005-08-26 13:44:34.286395472 +0200 -@@ -0,0 +1,341 @@ ++++ linux.dev/arch/mips/bcm947xx/include/linux_osl.h 2005-11-07 22:51:38.776726000 +0100 +@@ -0,0 +1,371 @@ +/* + * Linux OS Independent Layer + * @@ -2914,7 +2900,19 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b +#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) @@ -2930,20 +2928,26 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b + 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(void *osh, uint offset, void *buf, int size); -+extern void osl_pcmcia_write_attr(void *osh, uint offset, void *buf, int 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(void *osh, uint size, uint offset); -+extern void osl_pci_write_config(void *osh, uint offset, uint size, uint 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 void *osl_attach(void *pdev); -+extern void osl_detach(void *osh); ++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) @@ -2956,9 +2960,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b +#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(void *osh, uint size, int line, char* file); -+extern void osl_debug_mfree(void *osh, void *addr, uint size, int line, char* file); -+extern char *osl_debug_memdump(void *osh, char *buf, uint 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 + @@ -2970,10 +2974,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b + +#define MALLOC_FAILED(osh) osl_malloc_failed((osh)) + -+extern void *osl_malloc(void *osh, uint size); -+extern void osl_mfree(void *osh, void *addr, uint size); -+extern uint osl_malloced(void *osh); -+extern uint osl_malloc_failed(void *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 @@ -2981,8 +2985,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b + 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(void *osh, uint size, ulong *pap); -+extern void osl_dma_free_consistent(void *osh, void *va, uint size, ulong 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 @@ -2993,14 +2997,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b + 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(void *osh, void *va, uint size, int direction); -+extern void osl_dma_unmap(void *osh, uint pa, uint size, int 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) -+struct bcmjtag_info; -+extern uint32 bcmjtag_read(struct bcmjtag_info *ejh, uint32 addr, uint size); -+extern void bcmjtag_write(struct bcmjtag_info *ejh, uint32 addr, uint32 val, uint size); ++#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 @@ -3018,6 +3020,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b + +/* 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)) : \ @@ -3030,6 +3033,24 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b + 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)) @@ -3073,35 +3094,31 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b +#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) +#define REG_UNMAP(va) iounmap((void *)(va)) + -+/* microsecond delay */ -+#define OSL_DELAY(usec) udelay(usec) -+#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)) + +/* packet primitives */ -+#define PKTGET(drv, len, send) osl_pktget((drv), (len), (send)) -+#define PKTFREE(drv, skb, send) osl_pktfree((skb)) -+#define PKTDATA(drv, skb) (((struct sk_buff*)(skb))->data) -+#define PKTLEN(drv, skb) (((struct sk_buff*)(skb))->len) -+#define PKTHEADROOM(drv, skb) (PKTDATA(drv,skb)-(((struct sk_buff*)(skb))->head)) -+#define PKTTAILROOM(drv, skb) ((((struct sk_buff*)(skb))->end)-(((struct sk_buff*)(skb))->tail)) -+#define PKTNEXT(drv, skb) (((struct sk_buff*)(skb))->next) ++#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(drv, skb, len) __skb_trim((struct sk_buff*)(skb), (len)) -+#define PKTPUSH(drv, skb, bytes) skb_push((struct sk_buff*)(skb), (bytes)) -+#define PKTPULL(drv, skb, bytes) skb_pull((struct sk_buff*)(skb), (bytes)) -+#define PKTDUP(drv, skb) skb_clone((struct sk_buff*)(skb), GFP_ATOMIC) ++#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(void *drv, uint len, bool send); ++extern void *osl_pktget(osl_t *osh, uint len, bool send); +extern void osl_pktfree(void *skb); + +#else /* BINOSL */ @@ -3127,7 +3144,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b +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(char *s); ++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); + @@ -3179,46 +3196,42 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b +extern void *osl_reg_map(uint32 pa, uint size); +extern void osl_reg_unmap(void *va); + -+/* microsecond delay */ -+#define OSL_DELAY(usec) osl_delay((usec)) -+extern void osl_delay(uint usec); -+ +/* 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(drv, len, send) osl_pktget((drv), (len), (send)) -+#define PKTFREE(drv, skb, send) osl_pktfree((skb)) -+#define PKTDATA(drv, skb) osl_pktdata((drv), (skb)) -+#define PKTLEN(drv, skb) osl_pktlen((drv), (skb)) -+#define PKTHEADROOM(drv, skb) osl_pktheadroom((drv), (skb)) -+#define PKTTAILROOM(drv, skb) osl_pkttailroom((drv), (skb)) -+#define PKTNEXT(drv, skb) osl_pktnext((drv), (skb)) ++#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(drv, skb, len) osl_pktsetlen((drv), (skb), (len)) -+#define PKTPUSH(drv, skb, bytes) osl_pktpush((drv), (skb), (bytes)) -+#define PKTPULL(drv, skb, bytes) osl_pktpull((drv), (skb), (bytes)) -+#define PKTDUP(drv, skb) osl_pktdup((drv), (skb)) ++#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(void *drv, uint len, bool send); ++extern void *osl_pktget(osl_t *osh, uint len, bool send); +extern void osl_pktfree(void *skb); -+extern uchar *osl_pktdata(void *drv, void *skb); -+extern uint osl_pktlen(void *drv, void *skb); -+extern uint osl_pktheadroom(void *drv, void *skb); -+extern uint osl_pkttailroom(void *drv, void *skb); -+extern void *osl_pktnext(void *drv, 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(void *drv, void *skb, uint len); -+extern uchar *osl_pktpush(void *drv, void *skb, int bytes); -+extern uchar *osl_pktpull(void *drv, void *skb, int bytes); -+extern void *osl_pktdup(void *drv, void *skb); ++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); @@ -3228,14 +3241,17 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linux_osl.h linux.dev/arch/mips/b + +#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 -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 2005-08-26 13:44:34.287395320 +0200 -@@ -0,0 +1,399 @@ ++++ linux.dev/arch/mips/bcm947xx/include/linuxver.h 2005-11-07 22:51:38.780726250 +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. @@ -3270,6 +3286,16 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bc +#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 @@ -3312,6 +3338,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/linuxver.h linux.dev/arch/mips/bc +#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) @@ -3637,8 +3665,8 @@ 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/min_osl.h linux.dev/arch/mips/bcm947xx/include/min_osl.h --- linux.old/arch/mips/bcm947xx/include/min_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/min_osl.h 2005-08-26 13:44:34.287395320 +0200 -@@ -0,0 +1,120 @@ ++++ linux.dev/arch/mips/bcm947xx/include/min_osl.h 2005-11-07 22:51:38.780726250 +0100 +@@ -0,0 +1,126 @@ +/* + * HND Minimal OS Abstraction Layer. + * @@ -3658,6 +3686,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/min_osl.h linux.dev/arch/mips/bcm + +#include +#include ++#include + +/* Cache support */ +extern void caches_on(void); @@ -3700,6 +3729,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/min_osl.h linux.dev/arch/mips/bcm +#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)) @@ -3753,16 +3786,17 @@ diff -urN linux.old/arch/mips/bcm947xx/include/min_osl.h linux.dev/arch/mips/bcm +#define BUSPROBE(val, addr) (uint32 *)(addr) = (val) + +/* Misc stubs */ -+#define osl_attach(pdev) (pdev) ++#define osl_attach(pdev) ((osl_t*)pdev) +#define osl_detach(osh) +extern void *osl_init(void); -+extern int getintvar(char *vars, char *name); ++#define OSL_ERROR(bcmerror) osl_error(bcmerror) ++extern int osl_error(int); + +#endif /* _min_osl_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 2005-08-26 13:44:34.288395168 +0200 -@@ -0,0 +1,524 @@ ++++ linux.dev/arch/mips/bcm947xx/include/mipsinc.h 2005-11-07 22:51:38.780726250 +0100 +@@ -0,0 +1,552 @@ +/* + * HND Run Time Environment for standalone MIPS programs. + * @@ -3778,7 +3812,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm + */ + +#ifndef _MISPINC_H -+#define _MISPINC_H ++#define _MISPINC_H + + +/* MIPS defines */ @@ -3824,9 +3858,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +#define ra $31 /* return address */ + + -+/* ********************************************************************* -+ * CP0 Registers -+ ********************************************************************* */ ++/* ++ * CP0 Registers ++ */ + +#define C0_INX $0 +#define C0_RAND $1 @@ -3852,6 +3886,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +#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 @@ -3862,7 +3897,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +/* + * LEAF - declare leaf routine + */ -+#define LEAF(symbol) \ ++#define LEAF(symbol) \ + .globl symbol; \ + .align 2; \ + .type symbol,@function; \ @@ -3872,11 +3907,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +/* + * END - mark end of function + */ -+#define END(function) \ ++#define END(function) \ + .end function; \ + .size function,.-function + -+#define _ULCAST_ ++#define _ULCAST_ + +#else + @@ -3891,12 +3926,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +#define STR(x) __STR(x) +#endif + -+#define _ULCAST_ (unsigned long) ++#define _ULCAST_ (unsigned long) + + -+/* ********************************************************************* -+ * CP0 Registers -+ ********************************************************************* */ ++/* ++ * CP0 Registers ++ */ + +#define C0_INX 0 /* CP0: TLB Index */ +#define C0_RAND 1 /* CP0: TLB Random */ @@ -3922,6 +3957,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +#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 */ @@ -3966,10 +4002,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +/* + * 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_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 @@ -3999,144 +4035,48 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +#define Hit_Set_Virtual_SD 0x1f +#endif + -+#ifndef _LANGUAGE_ASSEMBLY + +/* -+ * Macros to access the system control coprocessor ++ * R4x00 interrupt enable / cause bits + */ -+ -+#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 >> 19) & 7))) -+ lsz = 2 << lsz; -+ sets = 64 << ((config1 >> 22) & 7); -+ ways = 1 + ((config1 >> 16) & 7); -+ *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 >> 10) & 7))) -+ lsz = 2 << lsz; -+ sets = 64 << ((config1 >> 13) & 7); -+ ways = 1 + ((config1 >> 7) & 7); -+ *size = lsz * sets * ways; -+ *lsize = lsz; -+} -+ -+#define cache_unroll(base,op) \ -+ __asm__ __volatile__(" \ -+ .set noreorder; \ -+ .set mips3; \ -+ cache %1, (%0); \ -+ .set mips0; \ -+ .set reorder" \ -+ : \ -+ : "r" (base), \ -+ "i" (op)); -+ -+#endif /* !_LANGUAGE_ASSEMBLY */ -+ -+ -+/* -+ * R4x00 interrupt enable / cause bits -+ */ -+#undef IE_SW0 -+#undef IE_SW1 -+#undef IE_IRQ0 -+#undef IE_IRQ1 -+#undef IE_IRQ2 -+#undef IE_IRQ3 -+#undef IE_IRQ4 -+#undef IE_IRQ5 -+#define IE_SW0 (1<< 8) -+#define IE_SW1 (1<< 9) -+#define IE_IRQ0 (1<<10) -+#define IE_IRQ1 (1<<11) -+#define IE_IRQ2 (1<<12) -+#define IE_IRQ3 (1<<13) -+#define IE_IRQ4 (1<<14) -+#define IE_IRQ5 (1<<15) -+ -+/* -+ * Bitfields in the mips32 cp0 status register -+ */ -+#define ST0_IE 0x00000001 -+#define ST0_EXL 0x00000002 -+#define ST0_ERL 0x00000004 -+/* already defined -+#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 ++#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 + + +/* @@ -4146,16 +4086,14 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +#define C_EXC_SHIFT 2 +#define C_INT 0x0000ff00 +#define C_INT_SHIFT 8 -+/* already defined -+#define C_SW0 0x00000100 -+#define C_SW1 0x00000200 -+#define C_IRQ0 0x00000400 -+#define C_IRQ1 0x00000800 -+#define C_IRQ2 0x00001000 -+#define C_IRQ3 0x00002000 -+#define C_IRQ4 0x00004000 -+#define C_IRQ5 0x00008000 -+*/ ++#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 @@ -4205,31 +4143,31 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +/* + * 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 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 @@ -4245,24 +4183,46 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +#define PRID_IMP_BCM4710 0x4000 +#define PRID_IMP_BCM3302 0x9000 +#define PRID_IMP_BCM3303 0x9100 -+#define PRID_IMP_BCM3303 0x9100 + +#define PRID_IMP_UNKNOWN 0xff00 + -+#define BCM330X(id) \ ++#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) */ ++#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 */ ++#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 @@ -4280,16 +4240,118 @@ diff -urN linux.old/arch/mips/bcm947xx/include/mipsinc.h linux.dev/arch/mips/bcm +#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_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 -urN linux.old/arch/mips/bcm947xx/include/nvports.h linux.dev/arch/mips/bcm947xx/include/nvports.h --- linux.old/arch/mips/bcm947xx/include/nvports.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/nvports.h 2005-08-26 13:44:34.291394712 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/nvports.h 2005-11-07 21:57:07.865587000 +0100 @@ -0,0 +1,55 @@ +/* + * BCM53xx RoboSwitch utility functions @@ -4348,10 +4410,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/nvports.h linux.dev/arch/mips/bcm + 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 2005-08-26 13:44:34.291394712 +0200 -@@ -0,0 +1,39 @@ ++++ linux.dev/arch/mips/bcm947xx/include/osl.h 2005-11-07 22:51:38.780726250 +0100 +@@ -0,0 +1,42 @@ +/* -+ * OS Independent Layer ++ * OS Abstraction Layer + * + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. @@ -4366,6 +4428,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947x +#ifndef _osl_h_ +#define _osl_h_ + ++/* osl handle type forward declaration */ ++typedef struct os_handle osl_t; ++ +#if defined(linux) +#include +#elif defined(NDIS) @@ -4391,8 +4456,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/osl.h linux.dev/arch/mips/bcm947x +#endif /* _osl_h_ */ 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 2005-08-26 13:44:34.292394560 +0200 -@@ -0,0 +1,369 @@ ++++ linux.dev/arch/mips/bcm947xx/include/pcicfg.h 2005-11-07 22:51:38.780726250 +0100 +@@ -0,0 +1,451 @@ +/* + * pcicfg.h: PCI configuration constants and structures. + * @@ -4434,7 +4499,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm9 +#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 /* Bus shift */ ++#define PCICFG_OFF_SHIFT 0 /* Register shift */ + +#define PCICFG_BUS_MASK 0xff /* Bus mask */ +#define PCICFG_SLOT_MASK 0x1f /* Slot mask */ @@ -4452,7 +4517,30 @@ diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm9 +#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 @@ -4461,6 +4549,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm9 + +#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; @@ -4516,6 +4608,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm9 +#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 @@ -4724,7 +4817,61 @@ diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm9 + unsigned char dev_dep[192]; +} ppb_config_regs; + -+/* Eveything below is BRCM HND proprietary */ ++ ++/* 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 */ @@ -4764,7 +4911,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/pcicfg.h linux.dev/arch/mips/bcm9 +#endif diff -urN linux.old/arch/mips/bcm947xx/include/pmon_osl.h linux.dev/arch/mips/bcm947xx/include/pmon_osl.h --- linux.old/arch/mips/bcm947xx/include/pmon_osl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/pmon_osl.h 2005-08-26 13:44:34.293394408 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/pmon_osl.h 2005-11-07 21:57:07.869587250 +0100 @@ -0,0 +1,126 @@ +/* + * MIPS PMON boot loader OS Abstraction Layer. @@ -4894,8 +5041,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/pmon_osl.h linux.dev/arch/mips/bc +#endif /* _pmon_osl_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mips/bcm947xx/include/proto/802.11.h --- linux.old/arch/mips/bcm947xx/include/proto/802.11.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/proto/802.11.h 2005-08-26 13:44:34.295394104 +0200 -@@ -0,0 +1,897 @@ ++++ linux.dev/arch/mips/bcm947xx/include/proto/802.11.h 2005-11-07 22:51:38.784726500 +0100 +@@ -0,0 +1,930 @@ +/* + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. @@ -5080,6 +5227,14 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mip + 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 */ @@ -5095,6 +5250,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mip +} 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. +**************/ @@ -5124,6 +5285,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mip + 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; @@ -5133,6 +5297,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mip +} 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 @@ -5499,6 +5666,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mip +#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 @@ -5626,7 +5797,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mip +#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 @@ -5733,6 +5906,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mip +#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 */ @@ -5755,9 +5933,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mip +#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 + @@ -5795,8 +5975,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/802.11.h linux.dev/arch/mip +#endif /* _802_11_H_ */ diff -urN linux.old/arch/mips/bcm947xx/include/proto/bcmeth.h linux.dev/arch/mips/bcm947xx/include/proto/bcmeth.h --- linux.old/arch/mips/bcm947xx/include/proto/bcmeth.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/proto/bcmeth.h 2005-08-26 13:44:34.295394104 +0200 -@@ -0,0 +1,97 @@ ++++ linux.dev/arch/mips/bcm947xx/include/proto/bcmeth.h 2005-11-07 22:51:38.784726500 +0100 +@@ -0,0 +1,103 @@ +/* + * Broadcom Ethernettype protocol definitions + * @@ -5870,14 +6050,19 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/bcmeth.h linux.dev/arch/mip + + +#define BCMILCP_BCM_SUBTYPE_RESERVED 0 -+#define BCMILCP_BCM_SUBTYPE_WPA 1 -+#define BCMILCP_BCM_SUBTYPE_EAPOL 2 -+#define BCMILCP_BCM_SUBTYPE_SES 3 ++#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 + -+typedef struct bcmeth_bcm_hdr ++/* These fields are stored in network order */ ++typedef struct bcmeth_hdr +{ + uint16 subtype; /* Vendor specific..32769*/ + uint16 length; @@ -5885,7 +6070,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/bcmeth.h linux.dev/arch/mip + uint8 oui[3]; /* Broadcom OUI*/ + /* user specific Data */ + uint16 usr_subtype; -+} PACKED bcmeth_bcm_hdr_t; ++} PACKED bcmeth_hdr_t; ++ + + +#undef PACKED @@ -5894,10 +6080,56 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/bcmeth.h linux.dev/arch/mip +#endif + +#endif +diff -urN linux.old/arch/mips/bcm947xx/include/proto/bcmip.h linux.dev/arch/mips/bcm947xx/include/proto/bcmip.h +--- linux.old/arch/mips/bcm947xx/include/proto/bcmip.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/proto/bcmip.h 2005-11-08 00:15:47.881307500 +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 -urN linux.old/arch/mips/bcm947xx/include/proto/ethernet.h linux.dev/arch/mips/bcm947xx/include/proto/ethernet.h --- linux.old/arch/mips/bcm947xx/include/proto/ethernet.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/proto/ethernet.h 2005-08-26 13:44:34.296393952 +0200 -@@ -0,0 +1,161 @@ ++++ linux.dev/arch/mips/bcm947xx/include/proto/ethernet.h 2005-11-07 22:51:38.784726500 +0100 +@@ -0,0 +1,169 @@ +/******************************************************************************* + * $Id$ + * Copyright 2005, Broadcom Corporation @@ -6008,11 +6240,19 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/ethernet.h linux.dev/arch/m +#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]) | \ @@ -6061,7 +6301,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/ethernet.h linux.dev/arch/m +#endif /* _NET_ETHERNET_H_ */ diff -urN linux.old/arch/mips/bcm947xx/include/proto/vlan.h linux.dev/arch/mips/bcm947xx/include/proto/vlan.h --- linux.old/arch/mips/bcm947xx/include/proto/vlan.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/proto/vlan.h 2005-08-26 13:44:34.296393952 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/proto/vlan.h 2005-11-07 21:57:07.873587500 +0100 @@ -0,0 +1,50 @@ +/* + * 802.1Q VLAN protocol definitions @@ -6115,7 +6355,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/vlan.h linux.dev/arch/mips/ +#endif /* _vlan_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/proto/wpa.h linux.dev/arch/mips/bcm947xx/include/proto/wpa.h --- linux.old/arch/mips/bcm947xx/include/proto/wpa.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/proto/wpa.h 2005-08-26 13:44:34.297393800 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/proto/wpa.h 2005-11-07 21:57:07.873587500 +0100 @@ -0,0 +1,140 @@ +/* + * Fundamental types and constants relating to WPA @@ -6259,7 +6499,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/proto/wpa.h linux.dev/arch/mips/b +#endif /* _proto_wpa_h_ */ diff -urN linux.old/arch/mips/bcm947xx/include/rts/crc.h linux.dev/arch/mips/bcm947xx/include/rts/crc.h --- linux.old/arch/mips/bcm947xx/include/rts/crc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/rts/crc.h 2005-08-26 13:44:34.297393800 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/rts/crc.h 2005-11-07 21:57:07.873587500 +0100 @@ -0,0 +1,69 @@ +/******************************************************************************* + * $Id$ @@ -6332,8 +6572,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/rts/crc.h linux.dev/arch/mips/bcm +#endif /* _RTS_CRC_H_ */ 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 2005-08-26 13:44:34.298393648 +0200 -@@ -0,0 +1,394 @@ ++++ linux.dev/arch/mips/bcm947xx/include/sbchipc.h 2005-11-07 22:51:38.784726500 +0100 +@@ -0,0 +1,440 @@ +/* + * SiliconBackplane Chipcommon core hardware definitions. + * @@ -6411,7 +6651,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm + + /* Watchdog timer */ + uint32 watchdog; /* 0x80 */ -+ uint32 PAD[3]; ++ uint32 PAD[1]; ++ ++ /*GPIO based LED powersave registers corerev >= 16*/ ++ uint32 gpiotimerval; /*0x88 */ ++ uint32 gpiotimeroutmask; + + /* clock control */ + uint32 clockcontrol_n; /* 0x90 */ @@ -6477,7 +6721,14 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm +#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 */ @@ -6501,6 +6752,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm +#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 */ + @@ -6518,6 +6770,32 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm +#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 @@ -6548,7 +6826,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm + +/* Fields in clkdiv */ +#define CLKD_SFLASH 0x0f000000 -+#define CLKD_SFLASH_SHIFT 24 ++#define CLKD_SFLASH_SHIFT 24 +#define CLKD_OTP 0x000f0000 +#define CLKD_OTP_SHIFT 16 +#define CLKD_JTAG 0x00000f00 @@ -6571,17 +6849,20 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm +#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 mask, SlowClk = 1/(4+divisor) * crystal/PCI clock */ -+#define SCC_CD_SHF 16 /* CLockDivider shift */ ++#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ ++#define SCC_CD_SHIFT 16 + -+/* sys_clk_ctl */ ++/* 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 /* ClockDivider mask, SlowClk = 1/(4+divisor) * crystal/PCI clock */ -+#define SYCC_CD_SHF 16 /* CLockDivider shift */ ++#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 */ @@ -6599,12 +6880,6 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm +#define CC_MC_MASK 0x1f000000 /* mux control */ +#define CC_MC_SHIFT 24 + -+/* N3M Clock control values for 125Mhz */ -+#define CC_125_N 0x0802 /* Default values for bcm4310 */ -+#define CC_125_M 0x04020009 -+#define CC_125_M25 0x11090009 -+#define CC_125_M33 0x11090005 -+ +/* 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 */ @@ -6639,6 +6914,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm +#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 */ @@ -6709,20 +6988,27 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbchipc.h linux.dev/arch/mips/bcm +#define SFLASH_AT_ID_MASK 0x38 +#define SFLASH_AT_ID_SHIFT 3 + -+/* OTP conventions */ -+#define OTP_HWBASE 0 -+#define OTP_SWLIM 256 -+#define OTP_CIDBASE 256 -+#define OTP_CIDLIM 260 ++/* 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 + -+#define OTP_BOUNDARY 252 -+#define OTP_HWSIGN 253 -+#define OTP_SWSIGN 254 -+#define OTP_CIDSIGN 255 ++/* 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 256 -+#define OTP_PKG 257 -+#define OTP_FID 258 ++#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 @@ -6730,8 +7016,8 @@ 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 2005-08-26 13:44:34.299393496 +0200 -@@ -0,0 +1,324 @@ ++++ linux.dev/arch/mips/bcm947xx/include/sbconfig.h 2005-11-07 22:51:38.784726500 +0100 +@@ -0,0 +1,342 @@ +/* + * Broadcom SiliconBackplane hardware register definitions. + * @@ -6775,9 +7061,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bc + +#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) @@ -6892,7 +7181,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bc + +/* sbtmstatelow */ +#define SBTML_RESET 0x1 /* reset */ -+#define SBTML_REJ 0x2 /* reject */ ++#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 */ @@ -6905,10 +7195,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bc +#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 */ @@ -6996,10 +7288,16 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bc +#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 0xf /* revision code*/ -+#define SBIDH_CC_MASK 0xfff0 /* core code */ ++#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 @@ -7036,6 +7334,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bc +#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: @@ -7054,11 +7357,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbconfig.h linux.dev/arch/mips/bc +#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 2005-08-26 13:44:34.300393344 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbextif.h 2005-11-07 21:57:07.877587750 +0100 @@ -0,0 +1,242 @@ +/* + * Hardware-specific External Interface I/O core definitions @@ -7302,12 +7606,13 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbextif.h linux.dev/arch/mips/bcm +#define CC_CLOCK_BASE 24000000 /* Half the clock freq. in the 4710 */ + +#endif /* _SBEXTIF_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 2005-08-26 13:44:34.300393344 +0200 -@@ -0,0 +1,147 @@ +diff -urN linux.old/arch/mips/bcm947xx/include/sbhnddma.h linux.dev/arch/mips/bcm947xx/include/sbhnddma.h +--- linux.old/arch/mips/bcm947xx/include/sbhnddma.h 1970-01-01 01:00:00.000000000 +0100 ++++ linux.dev/arch/mips/bcm947xx/include/sbhnddma.h 2005-11-07 23:37:03.453685750 +0100 +@@ -0,0 +1,312 @@ +/* -+ * BCM47XX Sonics SiliconBackplane DDR/SDRAM controller core hardware definitions. ++ * 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. @@ -7316,44 +7621,359 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm9 + * 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 _sbhnddma_h_ ++#define _sbhnddma_h_ + -+#ifdef _LANGUAGE_ASSEMBLY ++ ++/* 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; + -+#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 ++/* 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; + -+#else ++/* a pair of pio channels(tx and rx) */ ++typedef volatile struct { ++ pio4regs_t tx; ++ pio4regs_t rx; ++} pio4regp_t; + -+/* Sonics side: MEMC core registers */ -+typedef volatile struct sbmemcregs { -+ uint32 control; -+ uint32 config; ++ ++ ++/* 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 -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 2005-11-07 22:51:38.784726500 +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; @@ -7409,6 +8029,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm9 +#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 @@ -7455,8 +8076,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbmemc.h linux.dev/arch/mips/bcm9 +#endif /* _SBMEMC_H */ diff -urN 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 2005-08-26 13:44:34.301393192 +0200 -@@ -0,0 +1,60 @@ ++++ linux.dev/arch/mips/bcm947xx/include/sbmips.h 2005-11-07 22:51:38.784726500 +0100 +@@ -0,0 +1,62 @@ +/* + * Broadcom SiliconBackplane MIPS definitions + * @@ -7480,6 +8101,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbmips.h linux.dev/arch/mips/bcm9 +#ifndef _SBMIPS_H +#define _SBMIPS_H + ++#include ++ +#ifndef _LANGUAGE_ASSEMBLY + +/* cpp contortions to concatenate w/arg prescan */ @@ -7499,28 +8122,28 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbmips.h linux.dev/arch/mips/bcm9 + uint32 timer; +} mipsregs_t; + -+extern uint32 sb_flag(void *sbh); -+extern uint sb_irq(void *sbh); ++extern uint32 sb_flag(sb_t *sbh); ++extern uint sb_irq(sb_t *sbh); + -+extern void BCMINIT(sb_serial_init)(void *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)); ++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(void *sbh, uint clkd, bool exttap); ++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)(void *sbh); -+extern uint32 BCMINIT(sb_mips_clock)(void *sbh); -+extern bool BCMINIT(sb_mips_setclock)(void *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock); ++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); + -+extern uint32 BCMINIT(sb_memc_get_ncdl)(void *sbh); -+extern uint32 BCMINIT(sb_mips_get_pfc)(void *sbh); + +#endif /* _LANGUAGE_ASSEMBLY */ + +#endif /* _SBMIPS_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 2005-08-26 13:44:34.301393192 +0200 -@@ -0,0 +1,117 @@ ++++ linux.dev/arch/mips/bcm947xx/include/sbpci.h 2005-11-07 22:51:38.788726750 +0100 +@@ -0,0 +1,122 @@ +/* + * BCM47XX Sonics SiliconBackplane PCI core hardware definitions. + * @@ -7621,6 +8244,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm94 +#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] @@ -7629,19 +8257,222 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbpci.h linux.dev/arch/mips/bcm94 + +#ifndef _LANGUAGE_ASSEMBLY + -+extern int sbpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); -+extern int sbpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len); ++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(void *sbh); -+extern void sbpci_check(void *sbh); ++extern int sbpci_init(sb_t *sbh); ++extern void sbpci_check(sb_t *sbh); + +#endif /* !_LANGUAGE_ASSEMBLY */ + +#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 2005-11-07 23:39:41.403557000 +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 -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 2005-08-26 13:44:34.302393040 +0200 -@@ -0,0 +1,139 @@ ++++ linux.dev/arch/mips/bcm947xx/include/sbpcmcia.h 2005-11-07 22:51:38.788726750 +0100 +@@ -0,0 +1,146 @@ +/* + * BCM43XX Sonics SiliconBackplane PCMCIA core hardware definitions. + * @@ -7760,17 +8591,24 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbpcmcia.h linux.dev/arch/mips/bc + +/* Subtypes of BRCM_HNBU: */ + -+#define HNBU_CHIPID 0x01 /* Six bytes with PCI vendor & ++#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 /* Eleven bytes PA parameters */ -+#define HNBU_OEM 0x04 /* Eight bytes OEM data */ -+#define HNBU_CC 0x05 /* Default country code */ ++#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 */ -+#define HNBU_LED 0x09 /* LED set */ ++#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 */ @@ -7783,7 +8621,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 2005-08-26 13:44:34.302393040 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbsdram.h 2005-11-07 21:57:07.877587750 +0100 @@ -0,0 +1,75 @@ +/* + * BCM47XX Sonics SiliconBackplane SDRAM controller core hardware definitions. @@ -7862,7 +8700,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 2005-08-26 13:44:34.303392888 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sbsocram.h 2005-11-07 21:57:07.877587750 +0100 @@ -0,0 +1,37 @@ +/* + * BCM47XX Sonics SiliconBackplane embedded ram core @@ -7903,8 +8741,8 @@ 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 2005-08-26 13:44:34.303392888 +0200 -@@ -0,0 +1,87 @@ ++++ linux.dev/arch/mips/bcm947xx/include/sbutils.h 2005-11-07 22:51:38.788726750 +0100 +@@ -0,0 +1,140 @@ +/* + * Misc utility routines for accessing chip-specific features + * of Broadcom HNBU SiliconBackplane-based chips. @@ -7923,6 +8761,29 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm +#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(). @@ -7932,69 +8793,99 @@ diff -urN linux.old/arch/mips/bcm947xx/include/sbutils.h linux.dev/arch/mips/bcm + */ + +/* exported externs */ -+extern void * BCMINIT(sb_attach)(uint pcidev, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz); -+extern void * BCMINIT(sb_kattach)(void); -+extern void sb_detach(void *sbh); -+extern uint BCMINIT(sb_chip)(void *sbh); -+extern uint BCMINIT(sb_chiprev)(void *sbh); -+extern uint BCMINIT(sb_chipcrev)(void *sbh); -+extern uint BCMINIT(sb_chippkg)(void *sbh); -+extern uint BCMINIT(sb_pcirev)(void *sbh); -+extern uint BCMINIT(sb_pcmciarev)(void *sbh); -+extern uint BCMINIT(sb_boardvendor)(void *sbh); -+extern uint BCMINIT(sb_boardtype)(void *sbh); -+extern uint sb_bus(void *sbh); -+extern uint sb_corelist(void *sbh, uint coreid[]); -+extern uint sb_coreid(void *sbh); -+extern uint sb_coreidx(void *sbh); -+extern uint sb_coreunit(void *sbh); -+extern uint sb_corevendor(void *sbh); -+extern uint sb_corerev(void *sbh); -+extern void *sb_osh(void *sbh); -+extern void *sb_coreregs(void *sbh); -+extern uint32 sb_coreflags(void *sbh, uint32 mask, uint32 val); -+extern uint32 sb_coreflagshi(void *sbh, uint32 mask, uint32 val); -+extern bool sb_iscoreup(void *sbh); -+extern void *sb_setcoreidx(void *sbh, uint coreidx); -+extern void *sb_setcore(void *sbh, uint coreid, uint coreunit); -+extern void sb_commit(void *sbh); ++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(void *sbh, uint32 bits); -+extern void sb_core_tofixup(void *sbh); -+extern void sb_core_disable(void *sbh, uint32 bits); ++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(void *sbh); -+extern void sb_pci_setup(void *sbh, uint32 *dmaoffset, uint coremask); -+extern void sb_pcmcia_init(void *sbh); -+extern void sb_watchdog(void *sbh, uint ticks); -+extern void *sb_gpiosetcore(void *sbh); -+extern uint32 sb_gpiocontrol(void *sbh, uint32 mask, uint32 val); -+extern uint32 sb_gpioouten(void *sbh, uint32 mask, uint32 val); -+extern uint32 sb_gpioout(void *sbh, uint32 mask, uint32 val); -+extern uint32 sb_gpioin(void *sbh); -+extern uint32 sb_gpiointpolarity(void *sbh, uint32 mask, uint32 val); -+extern uint32 sb_gpiointmask(void *sbh, uint32 mask, uint32 val); -+extern void sb_pwrctl_init(void *sbh); -+extern uint16 sb_pwrctl_fast_pwrup_delay(void *sbh); -+extern bool sb_pwrctl_clk(void *sbh, uint mode); -+extern int sb_pwrctl_xtal(void *sbh, uint what, bool on); -+extern int sb_pwrctl_slowclk(void *sbh, bool set, uint *div); -+extern void sb_register_intr_callback(void *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg); -+ -+/* pwrctl xtal what flags */ ++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 */ + -+/* pwrctl clk mode */ ++/* clkctl clk mode */ +#define CLK_FAST 0 /* force fast (pll) clock */ -+#define CLK_SLOW 1 /* force slow clock */ -+#define CLK_DYNAMIC 2 /* enable dynamic power control */ ++#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 -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 2005-08-26 13:44:34.304392736 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/sflash.h 2005-11-07 21:57:07.881588000 +0100 @@ -0,0 +1,36 @@ +/* + * Broadcom SiliconBackplane chipcommon serial flash interface @@ -8034,7 +8925,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 2005-08-26 13:44:34.304392736 +0200 ++++ linux.dev/arch/mips/bcm947xx/include/trxhdr.h 2005-11-07 21:57:07.881588000 +0100 @@ -0,0 +1,33 @@ +/* + * TRX image file header format. @@ -8071,8 +8962,8 @@ 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 2005-08-26 13:44:34.305392584 +0200 -@@ -0,0 +1,322 @@ ++++ linux.dev/arch/mips/bcm947xx/include/typedefs.h 2005-11-07 22:51:38.788726750 +0100 +@@ -0,0 +1,326 @@ +/* + * Copyright 2005, Broadcom Corporation + * All Rights Reserved. @@ -8148,6 +9039,10 @@ diff -urN linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bc +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 @@ -8397,8 +9292,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/typedefs.h linux.dev/arch/mips/bc +#endif /* _TYPEDEFS_H_ */ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm947xx/include/wlioctl.h --- linux.old/arch/mips/bcm947xx/include/wlioctl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/arch/mips/bcm947xx/include/wlioctl.h 2005-08-26 13:44:34.307392280 +0200 -@@ -0,0 +1,825 @@ ++++ linux.dev/arch/mips/bcm947xx/include/wlioctl.h 2005-11-07 22:51:38.792727000 +0100 +@@ -0,0 +1,1030 @@ +/* + * Custom OID/ioctl definitions for + * Broadcom 802.11abg Networking Device Driver @@ -8421,6 +9316,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm + +#include +#include ++#include ++#include +#include + +/* require default structure packing */ @@ -8585,7 +9482,8 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm + WLC_SUP_AUTHENTICATING, + WLC_SUP_AUTHENTICATED, + WLC_SUP_KEYXCHANGE, -+ WLC_SUP_KEYED ++ WLC_SUP_KEYED, ++ WLC_SUP_TIMEOUT +} sup_auth_status_t; +#endif /* BCMCCX | BCMSUP_PSK */ + @@ -8642,10 +9540,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +} wsec_pmk_t; + +/* wireless security bitvec */ -+#define WEP_ENABLED 1 -+#define TKIP_ENABLED 2 -+#define AES_ENABLED 4 -+#define WSEC_SWFLAG 8 ++#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) */ @@ -8653,83 +9552,54 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#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 */ + -+typedef struct wl_led_info { -+ uint32 index; /* led index */ -+ uint32 behavior; -+ bool activehi; -+} wl_led_info_t; -+ -+/* -+ * definitions for driver messages passed from WL to NAS. -+ */ -+/* Use this to recognize wpa and 802.1x driver messages. */ -+static const uint8 wl_wpa_snap_template[] = -+ { 0xaa, 0xaa, 0x03, 0x00, 0x90, 0x4c }; + -+#define WL_WPA_MSG_IFNAME_MAX 16 + -+/* WPA driver message */ -+typedef struct wl_wpa_header { -+ struct ether_header eth; -+ struct dot11_llc_snap_header snap; -+ uint8 version; -+ uint8 type; -+ /* version 2 additions */ -+ char ifname[WL_WPA_MSG_IFNAME_MAX]; -+ /* version specific data */ -+ /* uint8 data[1]; */ -+} wl_wpa_header_t; -+ -+#define WL_WPA_HEADER_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN + 2 + WL_WPA_MSG_IFNAME_MAX) -+ -+/* WPA driver message ethertype - private between wlc and nas */ -+#define WL_WPA_ETHER_TYPE 0x9999 -+ -+/* WPA driver message current version */ -+#define WL_WPA_MSG_VERSION 2 -+ -+/* Type field values for the 802.2 driver messages for WPA. */ -+#define WLC_ASSOC_MSG 1 -+#define WLC_DISASSOC_MSG 2 -+#define WLC_PTK_MIC_MSG 3 -+#define WLC_GTK_MIC_MSG 4 -+ -+/* 802.1x driver message */ -+typedef struct wl_eapol_header { -+ struct ether_header eth; -+ struct dot11_llc_snap_header snap; -+ uint8 version; -+ uint8 reserved; -+ char ifname[WL_WPA_MSG_IFNAME_MAX]; -+ /* version specific data */ -+ /* uint8 802_1x_msg[1]; */ -+} wl_eapol_header_t; ++/* pmkid */ ++#define MAXPMKID 16 + -+#define WL_EAPOL_HEADER_LEN (ETHER_HDR_LEN + DOT11_LLC_SNAP_HDR_LEN + 2 + WL_WPA_MSG_IFNAME_MAX) ++typedef struct _pmkid ++{ ++ struct ether_addr BSSID; ++ uint8 PMKID[WPA2_PMKID_LEN]; ++} pmkid_t; + -+/* 802.1x driver message ethertype - private between wlc and nas */ -+#define WL_EAPOL_ETHER_TYPE 0x999A ++typedef struct _pmkid_list ++{ ++ uint32 npmkid; ++ pmkid_t pmkid[1]; ++} pmkid_list_t; + -+/* 802.1x driver message current version */ -+#define WL_EAPOL_MSG_VERSION 1 ++typedef struct _pmkid_cand { ++ struct ether_addr BSSID; ++ uint8 preauth; ++} pmkid_cand_t; + -+#define WL_SECPVT_DATA_LEN (ETHER_HDR_LEN + 4 + WL_WPA_MSG_IFNAME_MAX) ++typedef struct _pmkid_cand_list { ++ uint32 npmkid_cand; ++ pmkid_cand_t pmkid_cand[1]; ++} pmkid_cand_list_t; + -+/* message header for the private data exchange between nas and wl*/ -+typedef struct wl_secpvt_data { -+ struct ether_header eth; /* use the Type field in the eth header with the private type*/ -+ uint8 version; -+ uint8 sub_type; -+ uint16 data_len; -+ char ifname[WL_WPA_MSG_IFNAME_MAX]; -+ /* version specific data */ -+ /* uint8 802_1x_msg[1]; */ -+}wl_secpvt_data_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 */ @@ -8742,6 +9612,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm + 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 */ @@ -8758,18 +9629,18 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm + struct ether_addr ea; +} scb_val_t; + ++ +/* Event data type */ -+typedef struct { -+ uint msg; /* Message (see below) */ -+ struct ether_addr *addr; /* Station address (if applicable) */ -+ uint status; /* Status code (see below) */ -+ uint reason; /* Reason code (if applicable) */ -+ uint auth_type; /* WLC_E_AUTH */ -+ bool link; /* WLC_E_LINK */ -+ bool group; /* WLC_E_MIC_ERROR */ -+ bool flush_txq; /* WLC_E_MIC_ERROR */ ++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 */ @@ -8794,43 +9665,6 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#define WL_STA_WDS 0x40 +#define WL_WDS_LINKUP 0x80 + -+/* Event messages */ -+#define WLC_E_SET_SSID 1 -+#define WLC_E_JOIN 2 -+#define WLC_E_START 3 -+#define WLC_E_AUTH 4 -+#define WLC_E_AUTH_IND 5 -+#define WLC_E_DEAUTH 6 -+#define WLC_E_DEAUTH_IND 7 -+#define WLC_E_ASSOC 8 -+#define WLC_E_ASSOC_IND 9 -+#define WLC_E_REASSOC 10 -+#define WLC_E_REASSOC_IND 11 -+#define WLC_E_DISASSOC 12 -+#define WLC_E_DISASSOC_IND 13 -+#define WLC_E_QUIET_START 14 /* 802.11h Quiet period started */ -+#define WLC_E_QUIET_END 15 /* 802.11h Quiet period ended */ -+#define WLC_E_GOT_BEACONS 16 -+#define WLC_E_LINK 17 /* Link indication */ -+#define WLC_E_MIC_ERROR 18 /* TKIP MIC error occurred */ -+#define WLC_E_NDIS_LINK 19 /* NDIS style link indication */ -+#define WLC_E_ROAM 20 -+#define WLC_E_TXFAIL 21 /* dot11FailedCount (txfail) */ -+#define WLC_E_LAST 22 -+ -+/* Event status codes */ -+#define WLC_E_STATUS_SUCCESS 0 -+#define WLC_E_STATUS_FAIL 1 -+#define WLC_E_STATUS_TIMEOUT 2 -+#define WLC_E_STATUS_NO_NETWORKS 3 -+#define WLC_E_STATUS_ABORT 4 -+ -+typedef struct wlc_event_cb { -+ uint msg; /* Event message or 0 for all */ -+ void (*fn)(void *, wlc_event_t *); /* Callback function */ -+ void *context; /* Passed to callback function */ -+ struct wlc_event_cb *next; /* Next in the chain */ -+} wlc_event_cb_t; + +/* + * Country locale determines which channels are available to us. @@ -8902,6 +9736,12 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm + 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 + @@ -8914,20 +9754,20 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +/* 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_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 ++/* #define WLC_SET_RATE 13 */ /* no longer supported */ +#define WLC_GET_INSTANCE 14 -+#define WLC_GET_FRAG 15 -+#define WLC_SET_FRAG 16 -+#define WLC_GET_RTS 17 -+#define WLC_SET_RTS 18 ++/* #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 @@ -8948,22 +9788,24 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#define WLC_GET_RADIO 37 +#define WLC_SET_RADIO 38 +#define WLC_GET_PHYTYPE 39 -+#define WLC_GET_WEP 42 -+#define WLC_SET_WEP 43 -+#define WLC_GET_KEY 44 -+#define WLC_SET_KEY 45 -+#define WLC_SCAN 50 ++/* #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_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 -+#define WLC_SET_TXPWR 66 ++/* #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 @@ -8971,7 +9813,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#define WLC_GET_RATESET 71 +#define WLC_SET_RATESET 72 +#define WLC_GET_LOCALE 73 -+#define WLC_SET_LOCALE 74 ++#define WLC_LONGTRAIN 74 +#define WLC_GET_BCNPRD 75 +#define WLC_SET_BCNPRD 76 +#define WLC_GET_DTIMPRD 77 @@ -9013,15 +9855,15 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#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 -+#define WLC_SET_MRATE 154 -+#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_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 @@ -9042,9 +9884,14 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#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 @@ -9055,7 +9902,11 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#define WLC_SET_WSEC_PMK 268 +#define WLC_GET_AUTH_MODE 269 +#define WLC_SET_AUTH_MODE 270 -+#define WLC_LAST 273 /* do not change - use get_var/set_var */ ++#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: @@ -9085,6 +9936,7 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm + +/* 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 @@ -9094,14 +9946,42 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#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_UNASSOC_DISABLE (1<<2) ++#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 */ @@ -9112,6 +9992,13 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#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 */ @@ -9151,13 +10038,55 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm + + + ++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 /* qllow scan lists to contain non-11h AP */ ++#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 */ @@ -9166,6 +10095,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#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 */ @@ -9195,6 +10127,9 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#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) */ + @@ -9204,29 +10139,194 @@ diff -urN linux.old/arch/mips/bcm947xx/include/wlioctl.h linux.dev/arch/mips/bcm +#define VNDR_IE_ASSOCRSP_FLAG 0x4 +#define VNDR_IE_AUTHRSP_FLAG 0x8 + -+typedef struct vndr_ie_info { ++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 vndr_ie_buf { ++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 vndr_ie_setbuf { ++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 -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 2005-08-26 13:44:34.307392280 +0200 ++++ linux.dev/arch/mips/bcm947xx/nvram.c 2005-11-07 21:57:07.881588000 +0100 @@ -0,0 +1,321 @@ +/* + * NVRAM variable manipulation (common) @@ -9551,12 +10651,12 @@ 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 2005-08-26 13:44:34.308392128 +0200 -@@ -0,0 +1,617 @@ ++++ linux.dev/arch/mips/bcm947xx/nvram_linux.c 2005-11-08 00:54:56.755597250 +0100 +@@ -0,0 +1,633 @@ +/* + * NVRAM variable manipulation (Linux kernel half) + * -+ * Copyright 2004, Broadcom Corporation ++ * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -9592,6 +10692,7 @@ diff -urN linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947x +#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))); @@ -9618,8 +10719,10 @@ diff -urN linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947x +{ + 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); @@ -9630,6 +10733,11 @@ diff -urN linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947x + + case SFLASH_ST: + case SFLASH_AT: ++ if ((info = sflash_init(cc)) == NULL) ++ return; ++ lim = info->size; ++ break; ++ + case FLASH_NONE: + default: + return; @@ -9644,26 +10752,30 @@ diff -urN linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947x + while (off <= lim) { + /* Windowed flash access */ + header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE); -+ if (header->magic == NVRAM_MAGIC) { -+ u32 *src = (u32 *) header; -+ u32 *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++); -+ return; -+ } -+ -+ /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */ -+ if (off == 1 KB) -+ break; -+ else if (off == 4 KB) -+ off = 1 KB; -+ else if (off == lim) -+ off = 4 KB; -+ else -+ off <<= 1; ++ 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 */ @@ -9675,6 +10787,10 @@ diff -urN linux.old/arch/mips/bcm947xx/nvram_linux.c linux.dev/arch/mips/bcm947x + if (!name) + return NULL; + ++ /* Too early? */ ++ if (sbh == NULL) ++ return NULL; ++ + if (!nvram_buf[0]) + early_nvram_init(); + @@ -10172,12 +11288,12 @@ 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 2005-08-26 13:44:34.309391976 +0200 ++++ linux.dev/arch/mips/bcm947xx/pcibios.c 2005-11-07 23:59:38.908750500 +0100 @@ -0,0 +1,355 @@ +/* + * Low-Level PCI and SB support for BCM47xx (Linux support code) + * -+ * Copyright 2004, Broadcom Corporation ++ * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -10202,14 +11318,14 @@ diff -urN linux.old/arch/mips/bcm947xx/pcibios.c linux.dev/arch/mips/bcm947xx/pc +#include +#include +#include ++#include +#include +#include -+#include +#include +#include + +/* Global SB handle */ -+extern void *bcm947xx_sbh; ++extern sb_t *bcm947xx_sbh; +extern spinlock_t bcm947xx_sbh_lock; + +/* Convenience */ @@ -10531,7 +11647,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 2005-08-26 13:44:34.310391824 +0200 ++++ linux.dev/arch/mips/bcm947xx/prom.c 2005-11-07 21:57:07.885588250 +0100 @@ -0,0 +1,41 @@ +/* + * Early initialization code for BCM94710 boards @@ -10576,8 +11692,8 @@ 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 2005-09-01 01:30:26.074176728 +0200 -@@ -0,0 +1,1033 @@ ++++ linux.dev/arch/mips/bcm947xx/sbmips.c 2005-11-07 23:55:45.682174750 +0100 +@@ -0,0 +1,1038 @@ +/* + * BCM47XX Sonics SiliconBackplane MIPS core routines + * @@ -10589,7 +11705,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id: sbmips.c,v 1.3 2005/03/07 08:35:32 kanki Exp $ ++ * $Id$ + */ + +#include @@ -10604,12 +11720,13 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm +#include +#include +#include ++#include + -+/* ++/* + * Returns TRUE if an external UART exists at the given base + * register. + */ -+static bool ++static bool +BCMINITFN(serial_exists)(uint8 *regs) +{ + uint8 save_mcr, status1; @@ -10622,12 +11739,12 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + return (status1 == 0x90); +} + -+/* ++/* + * Initializes UART access. The callback function will be called once + * per found UART. + */ -+void -+BCMINITFN(sb_serial_init)(void *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)) ++void ++BCMINITFN(sb_serial_init)(sb_t *sbh, void (*add)(void *regs, uint irq, uint baud_base, uint reg_shift)) +{ + void *regs; + ulong base; @@ -10694,7 +11811,8 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + /* Internal backplane clock */ + baud_base = sb_clock(sbh); + div = 2; /* Minimum divisor */ -+ W_REG(&cc->clkdiv, ((R_REG(&cc->clkdiv) & ~CLKD_UART) | div)); ++ W_REG(&cc->clkdiv, ++ ((R_REG(&cc->clkdiv) & ~CLKD_UART) | div)); + } else { + /* Fixed internal backplane clock */ + baud_base = 88000000; @@ -10734,7 +11852,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + * jtag_rwreg. Returns NULL on failure. + */ +void * -+sb_jtagm_init(void *sbh, uint clkd, bool exttap) ++sb_jtagm_init(sb_t *sbh, uint clkd, bool exttap) +{ + void *regs; + @@ -10812,7 +11930,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + +/* Returns the SB interrupt flag of the current core. */ +uint32 -+sb_flag(void *sbh) ++sb_flag(sb_t *sbh) +{ + void *regs; + sbconfig_t *sb; @@ -10839,12 +11957,12 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + SBIPS_INT4_SHIFT +}; + -+/* ++/* + * Returns the MIPS IRQ assignment of the current core. If unassigned, + * 0 is returned. + */ +uint -+sb_irq(void *sbh) ++sb_irq(sb_t *sbh) +{ + uint idx; + void *regs; @@ -10876,8 +11994,8 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm +} + +/* Clears the specified MIPS IRQ. */ -+static void -+BCMINITFN(sb_clearirq)(void *sbh, uint irq) ++static void ++BCMINITFN(sb_clearirq)(sb_t *sbh, uint irq) +{ + void *regs; + sbconfig_t *sb; @@ -10893,12 +12011,12 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + 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)(void *sbh, uint irq, uint coreid, uint coreunit) ++static void ++BCMINITFN(sb_setirq)(sb_t *sbh, uint irq, uint coreid, uint coreunit) +{ + void *regs; + sbconfig_t *sb; @@ -10921,14 +12039,14 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + 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)(void *sbh) ++void ++BCMINITFN(sb_mips_init)(sb_t *sbh) +{ + ulong hz, ns, tmp; + extifregs_t *eir; @@ -10959,19 +12077,11 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + 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))) { -+//==================================tallest=============================================== -+ /* set register for external IO to control LED. */ -+ W_REG(&cc->prog_config, 0x11); -+ tmp = CEIL(10, ns) << FW_W3_SHIFT; /* W3 = 10nS */ -+ tmp = tmp | (CEIL(40, ns) << FW_W1_SHIFT); /* W1 = 40nS */ -+ tmp = tmp | CEIL(240, ns); /* W0 = 120nS */ -+ W_REG(&cc->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ -+//======================================================================================== + /* 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) + { @@ -10980,29 +12090,14 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + } + else + { -+ if (sb_corerev(sbh) < 9) ++ 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) ) { ++ ++ if ((sb_corerev(sbh) < 9) || ++ ((BCMINIT(sb_chip)(sbh) == BCM5350_DEVICE_ID) && BCMINIT(sb_chiprev)(sbh) == 0)) { + W_REG(&cc->pcmcia_memwait, tmp); + } + } -+ -+ // Added by Chen-I & Yen for enabling 5350 EXTIF -+ if (BCMINIT(sb_chip)(sbh) == BCM5350_DEVICE_ID) -+ { -+ /* 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(&cc->prog_waitcount, tmp); /* 0x01020a0c for a 100Mhz clock */ -+ //printf("===========config_REG=%d\n", R_REG(&cc->prog_config)); -+ //printf("-----------config_REG_addr=%x\n", &cc->prog_config); -+ //printf("===========waitcount_REG=%d\n", R_REG(&cc->prog_waitcount)); -+ //printf("-----------waitcount_REG=%x\n", &cc->prog_waitcount); -+ } + } + + /* Chip specific initialization */ @@ -11031,24 +12126,21 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + BCMINIT(sb_setirq)(sbh, 0, SB_USB, 0); + } + break; -+ case BCM4310_DEVICE_ID: -+ MTC0(C0_BROADCOM, 0, MFC0(C0_BROADCOM, 0) & ~(1 << 22)); -+ 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_IPSEC, 0); -+ BCMINIT(sb_setirq)(sbh, 4, SB_USB, 0); ++ 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)(void *sbh) ++BCMINITFN(sb_mips_clock)(sb_t *sbh) +{ + extifregs_t *eir; + chipcregs_t *cc; @@ -11106,7 +12198,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + +#define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) + -+static void ++static void +BCMINITFN(handler)(void) +{ + /* Step 11 */ @@ -11129,7 +12221,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm +} + +/* The following MUST come right after handler() */ -+static void ++static void +BCMINITFN(afterhandler)(void) +{ +} @@ -11137,8 +12229,8 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm +/* + * Set the MIPS, backplane and PCI clocks as closely as possible. + */ -+bool -+BCMINITFN(sb_mips_setclock)(void *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock) ++bool ++BCMINITFN(sb_mips_setclock)(sb_t *sbh, uint32 mipsclock, uint32 sbclock, uint32 pciclock) +{ + extifregs_t *eir = NULL; + chipcregs_t *cc = NULL; @@ -11183,8 +12275,8 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + 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 }, ++ { 150000000, 0x311, 0x4020005 }, ++ { 200000000, 0x311, 0x4020003 }, + }; + typedef struct { + uint32 mipsclock; @@ -11260,7 +12352,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + + ulong start, end, dst; + bool ret = FALSE; -+ ++ + /* get index of the current core */ + idx = sb_coreidx(sbh); + clockcontrol_m2 = NULL; @@ -11282,7 +12374,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + clockcontrol_n = &cc->clockcontrol_n; + clockcontrol_sb = &cc->clockcontrol_sb; + clockcontrol_pci = &cc->clockcontrol_pci; -+ clockcontrol_m2 = &cc->clockcontrol_m2; ++ clockcontrol_m2 = &cc->clockcontrol_m2; + } + } else + goto done; @@ -11359,10 +12451,10 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + /* No PLL change */ + orig_m2 = R_REG(&cc->clockcontrol_m2); + if ((orig_n == type3_table[i].n) && -+ (orig_m2 == type3_table[i].m2)) { ++ (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); @@ -11405,7 +12497,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + table = BCMINIT(type7_table); + tabsz = ARRAYSIZE(BCMINIT(type7_table)); + } else -+ ASSERT((char *)"No table for plltype" == NULL); ++ ASSERT("No table for plltype" == NULL); + + /* Store the current clock register values */ + orig_m2 = R_REG(&cc->clockcontrol_m2); @@ -11472,7 +12564,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + start = ((ulong) &&start_fill) & ~(ic_lsize - 1); + end = ((ulong) &&end_fill + (ic_lsize - 1)) & ~(ic_lsize - 1); + while (start < end) { -+ cache_unroll(start, Fill_I); ++ cache_op(start, Fill_I); + start += ic_lsize; + } + @@ -11482,10 +12574,10 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + 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_unroll(dst + i, Fill_I); ++ cache_op(dst + i, Fill_I); + + /* Clear BEV bit */ + MTC0(C0_STATUS, 0, MFC0(C0_STATUS, 0) & ~ST0_BEV); @@ -11516,7 +12608,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + MTC0(C0_BROADCOM, 2, 0x9); + + -+ /* steps 5 & 6 */ ++ /* steps 5 & 6 */ + __asm__ __volatile__ ( + ".set\tmips3\n\t" + "wait\n\t" @@ -11525,7 +12617,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + + /* step 7, clear cfg_active */ + MTC0(C0_BROADCOM, 2, 0); -+ ++ + /* Additional Step: set back to orig sync mode */ + MTC0(C0_BROADCOM, 4, sync_mode); + @@ -11554,10 +12646,49 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + 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)(void *sbh) ++BCMINITFN(sb_memc_get_ncdl)(sb_t *sbh) +{ + sbmemcregs_t *memc; + uint32 ret = 0; @@ -11579,13 +12710,13 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + dqsg = R_REG(&memc->dqsgatencdl); + + rd &= MEMC_RDNCDLCOR_RD_MASK; -+ wr &= MEMC_WRNCDLCOR_WR_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) || (sb_chip(sbh) == BCM5365_DEVICE_ID)) ++ if (rev > 0) + cd = rd; + else + cd = (rd == MEMC_CD_THRESHOLD) ? rd : (wr + MEMC_CD_THRESHOLD); @@ -11601,19 +12732,9 @@ diff -urN linux.old/arch/mips/bcm947xx/sbmips.c linux.dev/arch/mips/bcm947xx/sbm + return ret; +} + -+/* returns the PFC values to be used based on the chip ID*/ -+ -+uint32 -+BCMINITFN(sb_mips_get_pfc)(void *sbh) -+{ -+ if (BCMINIT(sb_chip)(sbh) == BCM5350_DEVICE_ID) -+ return 0x11; -+ else -+ return 0x15; -+} 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 2005-08-26 13:44:34.313391368 +0200 ++++ linux.dev/arch/mips/bcm947xx/sbpci.c 2005-11-07 23:53:20.981131500 +0100 @@ -0,0 +1,588 @@ +/* + * Low-Level PCI and SB support for BCM47xx @@ -11626,18 +12747,18 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id: sbpci.c,v 1.7 2005/03/07 08:35:32 kanki Exp $ ++ * $Id$ + */ + +#include +#include +#include +#include -+#include +#include ++#include ++#include +#include +#include -+#include +#include +#include + @@ -11667,7 +12788,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +#define PCI_SLOT_MAX 16 + +static uint32 -+config_cmd(void *sbh, uint bus, uint dev, uint func, uint off) ++config_cmd(sb_t *sbh, uint bus, uint dev, uint func, uint off) +{ + uint coreidx; + sbpciregs_t *regs; @@ -11703,7 +12824,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +} + +static int -+extpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++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; @@ -11731,7 +12852,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +} + +static int -+extpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++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; @@ -11767,7 +12888,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc + */ + +static int -+sb_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++sb_read_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) +{ + pci_config_regs *cfg; + @@ -11791,7 +12912,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +} + +static int -+sb_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++sb_write_config(sb_t *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) +{ + uint coreidx, n; + void *regs; @@ -11839,7 +12960,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +} + +int -+sbpci_read_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++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); @@ -11848,7 +12969,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +} + +int -+sbpci_write_config(void *sbh, uint bus, uint dev, uint func, uint off, void *buf, int len) ++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); @@ -11864,13 +12985,12 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +} + +static int -+sbpci_init_pci(void *sbh) ++sbpci_init_pci(sb_t *sbh) +{ + uint chip, chiprev, chippkg, host; + uint32 boardflags; + sbpciregs_t *pci; + sbconfig_t *sb; -+ int CT4712_WR; + uint32 val; + + chip = sb_chip(sbh); @@ -11933,8 +13053,8 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc + if (cardbus) { + printf("PCI: Enabling CardBus\n"); + /* GPIO 1 resets the CardBus device on bcm94710ap */ -+ sb_gpioout(sbh, 1, 1); -+ sb_gpioouten(sbh, 1, 1); ++ 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); + } + @@ -11957,7 +13077,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +} + +static int -+sbpci_init_cores(void *sbh) ++sbpci_init_cores(sb_t *sbh) +{ + uint chip, chiprev, chippkg, coreidx, i; + sbconfig_t *sb; @@ -12138,7 +13258,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +} + +int __init -+sbpci_init(void *sbh) ++sbpci_init(sb_t *sbh) +{ + sbpci_init_pci(sbh); + sbpci_init_cores(sbh); @@ -12146,7 +13266,7 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc +} + +void -+sbpci_check(void *sbh) ++sbpci_check(sb_t *sbh) +{ + uint coreidx; + sbpciregs_t *pci; @@ -12203,14 +13323,15 @@ diff -urN linux.old/arch/mips/bcm947xx/sbpci.c linux.dev/arch/mips/bcm947xx/sbpc + + sb_setcoreidx(sbh, coreidx); +} ++ 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 2005-08-26 13:44:34.313391368 +0200 -@@ -0,0 +1,261 @@ ++++ linux.dev/arch/mips/bcm947xx/setup.c 2005-11-08 00:11:55.346775000 +0100 +@@ -0,0 +1,272 @@ +/* + * Generic setup routines for Broadcom MIPS boards + * -+ * Copyright 2004, Broadcom Corporation ++ * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -12218,7 +13339,7 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu + * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. + * -+ * $Id: setup.c,v 1.2 2005/04/02 12:12:57 wbx Exp $ ++ * $Id$ + */ + +#include @@ -12227,6 +13348,7 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu +#include +#include +#include ++#include +#include +#include + @@ -12236,15 +13358,15 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu +#endif + +#include ++#include ++#include +#include +#include +#include -+#include +#include + +extern void bcm947xx_time_init(void); +extern void bcm947xx_timer_setup(struct irqaction *irq); -+extern void check_enable_mips_pfc(int val); + +#ifdef CONFIG_REMOTE_DEBUG +extern void set_debug_traps(void); @@ -12257,7 +13379,7 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu +#endif + +/* Global SB handle */ -+void *bcm947xx_sbh = NULL; ++sb_t *bcm947xx_sbh = NULL; +spinlock_t bcm947xx_sbh_lock = SPIN_LOCK_UNLOCKED; +EXPORT_SYMBOL(bcm947xx_sbh); +EXPORT_SYMBOL(bcm947xx_sbh_lock); @@ -12313,7 +13435,7 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu +} + +static void __init -+serial_setup(void *sbh) ++serial_setup(sb_t *sbh) +{ + sb_serial_init(sbh, serial_add); + @@ -12330,7 +13452,6 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu +brcm_setup(void) +{ + char *value; -+ uint pfc_val; + + /* Get global SB handle */ + sbh = sb_kattach(); @@ -12338,12 +13459,15 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu + /* Initialize clocks and interrupts */ + sb_mips_init(sbh); + -+ /* -+ * Now that the sbh is inited set the proper PFC value -+ */ -+ pfc_val = sb_mips_get_pfc(sbh); -+ printk("Setting the PFC value as 0x%x\n", pfc_val); -+ check_enable_mips_pfc(pfc_val); ++ 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 + /* Initialize UARTs */ @@ -12372,7 +13496,15 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu +const char * +get_system_type(void) +{ -+ return "Broadcom BCM947XX"; ++ 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 @@ -12468,95 +13600,518 @@ diff -urN linux.old/arch/mips/bcm947xx/setup.c linux.dev/arch/mips/bcm947xx/setu +EXPORT_SYMBOL(init_mtd_partitions); + +#endif -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 2005-08-26 13:44:34.314391216 +0200 -@@ -0,0 +1,117 @@ +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 2005-11-08 00:54:43.022739000 +0100 +@@ -0,0 +1,418 @@ +/* -+ * 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. ++ * Broadcom SiliconBackplane chipcommon serial flash interface + * -+ * $Id: time.c,v 1.1 2005/03/16 13:49:59 wbx 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$ + */ -+#include -+#include -+#include -+#include -+#include -+#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; ++/* Private global state */ ++static struct sflash sflash; + -+/* Convenience */ -+#define sbh bcm947xx_sbh -+#define sbh_lock bcm947xx_sbh_lock ++/* 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 int panic_timeout; -+static int watchdog = 0; -+static u8 *mcr = NULL; ++/* Initialize serial flash access */ ++struct sflash * ++sflash_init(chipcregs_t *cc) ++{ ++ uint32 id, id2; + -+void __init -+bcm947xx_time_init(void) ++ 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) +{ -+ unsigned int hz; -+ extifregs_t *eir; ++ int cnt; ++ uint32 *from, *to; + -+ /* -+ * 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 (!len) ++ return 0; + -+ if (!(hz = sb_mips_clock(sbh))) -+ hz = 100000000; ++ if ((offset + len) > sflash.size) ++ return -22; + -+ printk("CPU: BCM%04x rev %d at %d MHz\n", sb_chip(sbh), sb_chiprev(sbh), -+ (hz + 500000) / 1000000); ++ if ((len >= 4) && (offset & 3)) ++ cnt = 4 - (offset & 3); ++ else if ((len >= 4) && ((uint32)buf & 3)) ++ cnt = 4 - ((uint32)buf & 3); ++ else ++ cnt = len; + -+ /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ -+ mips_hpt_frequency = hz / 2; ++ from = (uint32 *)KSEG1ADDR(SB_FLASH2 + offset); ++ to = (uint32 *)buf; + -+ /* 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; ++ if (cnt < 4) { ++ bcopy(from, to, cnt); ++ return cnt; + } + ++ while (cnt >= 4) { ++ *to++ = *from++; ++ cnt -= 4; ++ } + -+ /* Set panic timeout in seconds */ -+ panic_timeout = watchdog / 1000; ++ return (len - cnt); ++} + -+ /* 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); ++/* 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; +} + -+static void -+bcm947xx_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) ++/* 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 -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 2005-11-07 23:47:27.528101500 +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); @@ -12590,8 +14145,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 2005-08-26 13:41:43.371378504 +0200 -+++ linux.dev/arch/mips/config-shared.in 2005-08-26 13:44:34.315391064 +0200 +--- linux.old/arch/mips/config-shared.in 2005-11-07 23:12:50.850903750 +0100 ++++ linux.dev/arch/mips/config-shared.in 2005-11-07 21:57:07.889588500 +0100 @@ -208,6 +208,14 @@ fi define_bool CONFIG_MIPS_RTC y @@ -12647,8 +14202,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 2005-08-26 13:41:41.803616840 +0200 -+++ linux.dev/arch/mips/kernel/cpu-probe.c 2005-08-26 13:44:34.316390912 +0200 +--- linux.old/arch/mips/kernel/cpu-probe.c 2005-11-07 23:12:50.890906250 +0100 ++++ linux.dev/arch/mips/kernel/cpu-probe.c 2005-11-07 21:57:07.893588750 +0100 @@ -163,7 +163,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c) @@ -12769,8 +14324,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 2005-08-26 13:41:41.804616688 +0200 -+++ linux.dev/arch/mips/kernel/head.S 2005-08-26 13:44:34.317390760 +0200 +--- linux.old/arch/mips/kernel/head.S 2005-11-07 23:12:50.898906750 +0100 ++++ linux.dev/arch/mips/kernel/head.S 2005-11-07 21:57:07.893588750 +0100 @@ -28,12 +28,20 @@ #include #include @@ -12794,8 +14349,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 2005-01-19 15:09:29.000000000 +0100 -+++ linux.dev/arch/mips/kernel/proc.c 2005-08-26 13:44:34.318390608 +0200 +--- linux.old/arch/mips/kernel/proc.c 2005-11-07 23:12:50.906907250 +0100 ++++ linux.dev/arch/mips/kernel/proc.c 2005-11-07 21:57:07.893588750 +0100 @@ -78,9 +78,10 @@ [CPU_AU1550] "Au1550", [CPU_24K] "MIPS 24K", @@ -12809,8 +14364,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 2005-08-26 13:41:41.805616536 +0200 -+++ linux.dev/arch/mips/kernel/setup.c 2005-08-26 13:44:34.318390608 +0200 +--- linux.old/arch/mips/kernel/setup.c 2005-11-07 23:12:50.906907250 +0100 ++++ linux.dev/arch/mips/kernel/setup.c 2005-11-07 21:57:07.893588750 +0100 @@ -493,6 +493,7 @@ void swarm_setup(void); void hp_setup(void); @@ -12832,8 +14387,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 2005-08-26 13:41:41.806616384 +0200 -+++ linux.dev/arch/mips/kernel/traps.c 2005-08-26 13:44:34.321390152 +0200 +--- linux.old/arch/mips/kernel/traps.c 2005-11-07 23:12:50.922908250 +0100 ++++ linux.dev/arch/mips/kernel/traps.c 2005-11-07 21:57:07.893588750 +0100 @@ -920,6 +920,7 @@ void __init trap_init(void) { @@ -12864,9 +14419,9 @@ diff -urN linux.old/arch/mips/kernel/traps.c linux.dev/arch/mips/kernel/traps.c 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 2005-08-26 13:41:41.825613496 +0200 -+++ linux.dev/arch/mips/mm/c-r4k.c 2005-08-26 13:44:34.322390000 +0200 -@@ -1118,3 +1118,47 @@ +--- linux.old/arch/mips/mm/c-r4k.c 2005-11-07 23:12:50.954910250 +0100 ++++ linux.dev/arch/mips/mm/c-r4k.c 2005-11-07 21:57:08.157605250 +0100 +@@ -1166,3 +1166,47 @@ build_clear_page(); build_copy_page(); } @@ -12915,8 +14470,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 2005-01-19 15:09:29.000000000 +0100 -+++ linux.dev/arch/mips/pci/Makefile 2005-08-26 13:44:34.323389848 +0200 +--- linux.old/arch/mips/pci/Makefile 2005-11-07 23:12:50.978911750 +0100 ++++ linux.dev/arch/mips/pci/Makefile 2005-11-07 21:57:07.897589000 +0100 @@ -13,7 +13,9 @@ obj-$(CONFIG_MIPS_MSC) += ops-msc.o obj-$(CONFIG_MIPS_NILE4) += ops-nile4.o @@ -12928,8 +14483,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 2005-08-26 13:41:41.952594192 +0200 -+++ linux.dev/drivers/char/serial.c 2005-09-01 02:33:38.312794792 +0200 +--- linux.old/drivers/char/serial.c 2005-11-07 23:12:51.038915500 +0100 ++++ linux.dev/drivers/char/serial.c 2005-11-07 21:57:07.901589250 +0100 @@ -444,6 +444,10 @@ return inb(info->port+1); #endif @@ -12975,7 +14530,7 @@ diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c /* * Work around a bug in the Oxford Semiconductor 952 rev B * chip which causes it to seriously miscalculate baud rates -@@ -5996,6 +6003,13 @@ +@@ -5984,6 +5991,13 @@ * Divisor, bytesize and parity */ state = rs_table + co->index; @@ -12989,7 +14544,7 @@ diff -urN linux.old/drivers/char/serial.c linux.dev/drivers/char/serial.c if (doflow) state->flags |= ASYNC_CONS_FLOW; info = &async_sercons; -@@ -6009,7 +6023,7 @@ +@@ -5997,7 +6011,7 @@ info->io_type = state->io_type; info->iomem_base = state->iomem_base; info->iomem_reg_shift = state->iomem_reg_shift; @@ -12999,8 +14554,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/mtd/maps/Config.in linux.dev/drivers/mtd/maps/Config.in ---- linux.old/drivers/mtd/maps/Config.in 2005-08-26 13:41:41.963592520 +0200 -+++ linux.dev/drivers/mtd/maps/Config.in 2005-08-26 13:44:34.345386504 +0200 +--- linux.old/drivers/mtd/maps/Config.in 2005-11-07 23:12:51.086918500 +0100 ++++ linux.dev/drivers/mtd/maps/Config.in 2005-11-07 21:57:07.901589250 +0100 @@ -48,6 +48,7 @@ fi @@ -13010,8 +14565,8 @@ diff -urN linux.old/drivers/mtd/maps/Config.in linux.dev/drivers/mtd/maps/Config dep_tristate ' Pb1500 MTD support' CONFIG_MTD_PB1500 $CONFIG_MIPS_PB1500 dep_tristate ' Pb1100 MTD support' CONFIG_MTD_PB1100 $CONFIG_MIPS_PB1100 diff -urN linux.old/drivers/mtd/maps/Makefile linux.dev/drivers/mtd/maps/Makefile ---- linux.old/drivers/mtd/maps/Makefile 2005-08-26 13:41:41.963592520 +0200 -+++ linux.dev/drivers/mtd/maps/Makefile 2005-08-26 13:44:34.346386352 +0200 +--- linux.old/drivers/mtd/maps/Makefile 2005-11-07 23:12:51.086918500 +0100 ++++ linux.dev/drivers/mtd/maps/Makefile 2005-11-07 21:57:07.905589500 +0100 @@ -3,6 +3,8 @@ # # $Id: Makefile,v 1.37 2003/01/24 14:26:38 dwmw2 Exp $ @@ -13031,8 +14586,8 @@ diff -urN linux.old/drivers/mtd/maps/Makefile linux.dev/drivers/mtd/maps/Makefil obj-$(CONFIG_MTD_CFI_FLAGADM) += cfi_flagadm.o diff -urN linux.old/drivers/mtd/maps/bcm947xx-flash.c linux.dev/drivers/mtd/maps/bcm947xx-flash.c --- linux.old/drivers/mtd/maps/bcm947xx-flash.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/mtd/maps/bcm947xx-flash.c 2005-08-26 13:44:34.346386352 +0200 -@@ -0,0 +1,236 @@ ++++ linux.dev/drivers/mtd/maps/bcm947xx-flash.c 2005-11-07 23:33:20.715765500 +0100 +@@ -0,0 +1,237 @@ +/* + * Flash mapping for BCM947XX boards + * @@ -13056,6 +14611,7 @@ diff -urN linux.old/drivers/mtd/maps/bcm947xx-flash.c linux.dev/drivers/mtd/maps +#include +#include + ++#include +#include +#include +#include @@ -13270,8 +14826,8 @@ diff -urN linux.old/drivers/mtd/maps/bcm947xx-flash.c linux.dev/drivers/mtd/maps +module_init(init_bcm947xx_map); +module_exit(cleanup_bcm947xx_map); diff -urN linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in ---- linux.old/drivers/net/Config.in 2005-08-26 13:41:43.481361784 +0200 -+++ linux.dev/drivers/net/Config.in 2005-08-26 13:44:34.358384528 +0200 +--- linux.old/drivers/net/Config.in 2005-11-07 23:12:51.110920000 +0100 ++++ linux.dev/drivers/net/Config.in 2005-11-07 21:57:07.905589500 +0100 @@ -2,6 +2,8 @@ # Network device configuration # @@ -13290,8 +14846,8 @@ diff -urN linux.old/drivers/net/Config.in linux.dev/drivers/net/Config.in dep_tristate ' DECchip Tulip (dc21x4x) PCI support' CONFIG_TULIP $CONFIG_PCI if [ "$CONFIG_TULIP" = "y" -o "$CONFIG_TULIP" = "m" ]; then diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile ---- linux.old/drivers/net/Makefile 2005-08-26 13:41:43.082422432 +0200 -+++ linux.dev/drivers/net/Makefile 2005-08-26 13:44:34.370382704 +0200 +--- linux.old/drivers/net/Makefile 2005-11-07 23:12:51.110920000 +0100 ++++ linux.dev/drivers/net/Makefile 2005-11-07 21:57:07.905589500 +0100 @@ -3,6 +3,8 @@ # Makefile for the Linux network (ethercard) device drivers. # @@ -13338,7 +14894,7 @@ diff -urN linux.old/drivers/net/Makefile linux.dev/drivers/net/Makefile clean: diff -urN linux.old/drivers/net/et/Makefile linux.dev/drivers/net/et/Makefile --- linux.old/drivers/net/et/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/et/Makefile 2005-08-26 13:44:34.371382552 +0200 ++++ linux.dev/drivers/net/et/Makefile 2005-11-07 21:57:07.905589500 +0100 @@ -0,0 +1,21 @@ +# +# Makefile for the Broadcom et driver @@ -13363,7 +14919,7 @@ diff -urN linux.old/drivers/net/et/Makefile linux.dev/drivers/net/et/Makefile +include $(TOPDIR)/Rules.make diff -urN 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 2005-08-26 13:44:34.371382552 +0200 ++++ linux.dev/drivers/net/hnd/Makefile 2005-11-07 21:57:07.905589500 +0100 @@ -0,0 +1,19 @@ +# +# Makefile for the BCM47xx specific kernel interface routines @@ -13386,12 +14942,12 @@ diff -urN linux.old/drivers/net/hnd/Makefile linux.dev/drivers/net/hnd/Makefile + sh -e $< $(HND_OBJS) > $@ diff -urN 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 2005-08-26 13:44:34.372382400 +0200 -@@ -0,0 +1,714 @@ ++++ linux.dev/drivers/net/hnd/bcmsrom.c 2005-11-07 22:28:05.077337250 +0100 +@@ -0,0 +1,936 @@ +/* + * Misc useful routines to access NIC SROM/OTP . + * -+ * Copyright 2004, Broadcom Corporation ++ * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -13410,6 +14966,7 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. +#include +#include +#include ++#include + +#include /* for sprom content groking */ + @@ -13418,38 +14975,40 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. +#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 *osh, void *curmap, char **vars, int *count); -+static int initvars_cis_pcmcia(void *sbh, void *curmap, void *osh, char **vars, int *count); -+static int srom_parsecis(void *osh, uint8 *cis, char **vars, int *count); -+static int sprom_cmd_pcmcia(void *osh, uint8 cmd); -+static int sprom_read_pcmcia(void *osh, uint16 addr, uint16 *data); -+static int sprom_write_pcmcia(void *osh, uint16 addr, uint16 data); ++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, void *osh, char **vars, int *count) ++srom_var_init(void *sbh, uint bustype, void *curmap, osl_t *osh, char **vars, int *count) +{ + ASSERT(bustype == BUSTYPE(bustype)); -+ if (vars == NULL) ++ if (vars == NULL || count == NULL) + return (0); + + switch (BUSTYPE(bustype)) { + case SB_BUS: -+ /* These two could be asserts ... */ -+ *vars = NULL; -+ *count = 0; -+ return(0); ++ case JTAG_BUS: ++ return initvars_flash_sb(sbh, vars, count); + + case PCI_BUS: + ASSERT(curmap); /* can not be NULL */ -+ return(initvars_srom_pci(osh, curmap, vars, count)); ++ return initvars_srom_pci(sbh, curmap, vars, count); + + case PCMCIA_BUS: -+ return(initvars_cis_pcmcia(sbh, curmap, osh, vars, count)); ++ return initvars_cis_pcmcia(sbh, osh, vars, count); + + + default: @@ -13460,7 +15019,7 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + +/* support only 16-bit word read from srom */ +int -+srom_read(uint bustype, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf) ++srom_read(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) +{ + void *srom; + uint i, off, nw; @@ -13494,7 +15053,7 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + +/* support only 16-bit word write into srom */ +int -+srom_write(uint bustype, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf) ++srom_write(uint bustype, void *curmap, osl_t *osh, uint byteoff, uint nbytes, uint16 *buf) +{ + uint16 *srom; + uint i, off, nw, crc_range; @@ -13568,7 +15127,7 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + + +static int -+srom_parsecis(void *osh, uint8 *cis, char **vars, int *count) ++srom_parsecis(osl_t *osh, uint8 *cis, char **vars, int *count) +{ + char eabuf[32]; + char *vp, *base; @@ -13576,13 +15135,15 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + int i, j; + uint varsize; + bool ag_init = FALSE; -+ uint16 w; ++ uint32 w32; + + ASSERT(vars); + ASSERT(count); + + base = vp = MALLOC(osh, VARS_MAX); + ASSERT(vp); ++ if (!vp) ++ return -2; + + i = 0; + do { @@ -13615,6 +15176,10 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + + 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++; @@ -13643,15 +15208,24 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + break; + + case HNBU_CC: ++ ASSERT(sromrev > 1); + vp += sprintf(vp, "cc=%d", cis[i + 1]); + vp++; + break; + + case HNBU_PAPARMS: -+ vp += sprintf(vp, "pa0maxpwr=%d", cis[i + tlen - 1]); -+ vp++; -+ if (tlen == 9) { -+ /* New version */ ++ 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]); @@ -13659,22 +15233,29 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + } + 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: -+ w = (cis[i + 2] << 8) + cis[i + 1]; -+ if (w == 0xffff) w = 0; -+ vp += sprintf(vp, "boardflags=%d", w); ++ 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_LED: ++ ++ case HNBU_LEDS: + if (cis[i + 1] != 0xff) { + vp += sprintf(vp, "wl0gpio0=%d", cis[i + 1]); + vp++; @@ -13692,6 +15273,27 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + 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; + @@ -13703,12 +15305,9 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + vp += sprintf(vp, "sromrev=%d", sromrev); + vp++; + -+ /* For now just set boardflags2 to zero */ -+ vp += sprintf(vp, "boardflags2=0"); -+ vp++; -+ + /* if there is no antenna gain field, set default */ + if (ag_init == FALSE) { ++ ASSERT(sromrev == 1); + vp += sprintf(vp, "ag0=%d", 0xff); + vp++; + } @@ -13724,9 +15323,14 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + } else { + vp = MALLOC(osh, varsize); + ASSERT(vp); -+ bcopy(base, vp, varsize); ++ if (vp) ++ bcopy(base, vp, varsize); + MFREE(osh, base, VARS_MAX); + *vars = vp; ++ if (!vp) { ++ *count = 0; ++ return -2; ++ } + } + *count = varsize; + @@ -13736,7 +15340,7 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + +/* set PCMCIA sprom command register */ +static int -+sprom_cmd_pcmcia(void *osh, uint8 cmd) ++sprom_cmd_pcmcia(osl_t *osh, uint8 cmd) +{ + uint8 status = 0; + uint wait_cnt = 1000; @@ -13756,7 +15360,7 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + +/* read a word from the PCMCIA srom */ +static int -+sprom_read_pcmcia(void *osh, uint16 addr, uint16 *data) ++sprom_read_pcmcia(osl_t *osh, uint16 addr, uint16 *data) +{ + uint8 addr_l, addr_h, data_l, data_h; + @@ -13782,7 +15386,7 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + +/* write a word to the PCMCIA srom */ +static int -+sprom_write_pcmcia(void *osh, uint16 addr, uint16 data) ++sprom_write_pcmcia(osl_t *osh, uint16 addr, uint16 data) +{ + uint8 addr_l, addr_h, data_l, data_h; + @@ -13810,7 +15414,7 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. +static int +sprom_read_pci(uint16 *sprom, uint wordoff, uint16 *buf, uint nwords, bool check_crc) +{ -+ uint8 chk8; ++ int err = 0; + uint i; + + /* read the sprom */ @@ -13820,40 +15424,175 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + if (check_crc) { + /* fixup the endianness so crc8 will pass */ + htol16_buf(buf, nwords * 2); -+ if ((chk8 = hndcrc8((uchar*)buf, nwords * 2, CRC8_INIT_VALUE)) != CRC8_GOOD_VALUE) -+ return (1); ++ 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; ++} + -+ return (0); ++/* ++* 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; +} + +/* -+ * Initialize nonvolatile variable table from sprom. ++* 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 *osh, void *curmap, char **vars, int *count) ++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 bfl; -+ int c, woff, i; ++ 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; + -+ if (sprom_read_pci((void*)((int8*)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof(b)/sizeof(b[0]), TRUE)) -+ return (-1); -+ -+ /* top word of sprom contains version and crc8 */ -+ sromrev = b[63] & 0xff; -+ /* bcm4401 sroms misprogrammed */ -+ if (sromrev == 0x10) -+ sromrev = 1; -+ if ((sromrev != 1) && (sromrev != 2)) ++ /* ++ * 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); @@ -13861,18 +15600,57 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + + 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 >= 2) { -+ /* New section takes over the 4th hardware function space */ ++ if (sromrev >= 3) { ++ /* New section takes over the 3th hardware function space */ + -+ /* Word 29 is max power 11a high/low */ -+ w = b[29]; -+ vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff); ++ /* Words 22+23 are 11a (mid) ofdm power offsets */ ++ w32 = ((uint32)b[23] << 16) | b[22]; ++ vp += sprintf(vp, "ofdmapo=%d", w32); + vp++; -+ vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff); ++ ++ /* 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, @@ -14017,13 +15795,13 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + vp++; + + /* Word 57 is boardflags, if not programmed make it zero */ -+ bfl = (uint32)b[57]; -+ if (bfl == 0xffff) bfl = 0; ++ w32 = (uint32)b[57]; ++ if (w32 == 0xffff) w32 = 0; + if (sromrev > 1) { -+ /* Word 28 is boardflags2 */ -+ bfl |= (uint32)b[28] << 16; ++ /* Word 28 is the high bits of boardflags */ ++ w32 |= (uint32)b[28] << 16; + } -+ vp += sprintf(vp, "boardflags=%d", bfl); ++ vp += sprintf(vp, "boardflags=%d", w32); + vp++; + + /* Word 58 is antenna gain 0/1 */ @@ -14042,31 +15820,31 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + ((b[61] >> 8) & 0xff), (b[61] & 0xff), + ((b[62] >> 8) & 0xff), (b[62] & 0xff)); + vp++; -+ } else { ++ } 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'; + -+ c = (int)(vp - base); + ASSERT((vp - base) <= VARS_MAX); -+ -+ if (c == VARS_MAX) { -+ *vars = base; -+ } else { -+ vp = MALLOC(osh, c); -+ ASSERT(vp); -+ bcopy(base, vp, c); -+ MFREE(osh, base, VARS_MAX); -+ *vars = vp; -+ } -+ *count = c; -+ -+ return (0); ++ ++done: err = initvars_table(osh, base, vp, vars, count); ++ ++err: MFREE(osh, base, VARS_MAX); ++ return err; +} + +/* @@ -14074,7 +15852,7 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + * Return 0 on success, nonzero on error. + */ +static int -+initvars_cis_pcmcia(void *sbh, void *curmap, void *osh, char **vars, int *count) ++initvars_cis_pcmcia(void *sbh, osl_t *osh, char **vars, int *count) +{ + uint8 *cis = NULL; + int rc; @@ -14104,12 +15882,12 @@ diff -urN linux.old/drivers/net/hnd/bcmsrom.c linux.dev/drivers/net/hnd/bcmsrom. + diff -urN 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 2005-08-26 13:44:34.374382096 +0200 -@@ -0,0 +1,862 @@ ++++ linux.dev/drivers/net/hnd/bcmutils.c 2005-11-08 12:52:21.836276500 +0100 +@@ -0,0 +1,1081 @@ +/* + * Misc useful OS-independent routines. + * -+ * Copyright 2004, Broadcom Corporation ++ * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -14120,8 +15898,14 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil + */ + +#include ++#ifdef BCMDRIVER +#include ++#include +#include ++#else ++#include ++#include ++#endif +#include +#include +#include @@ -14129,7 +15913,7 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil +#ifdef BCMDRIVER +/* copy a pkt buffer chain into a buffer */ +uint -+pktcopy(void *drv, void *p, uint offset, int len, uchar *buf) ++pktcopy(osl_t *osh, void *p, uint offset, int len, uchar *buf) +{ + uint n, ret = 0; + @@ -14137,19 +15921,19 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil + len = 4096; /* "infinite" */ + + /* skip 'offset' bytes */ -+ for (; p && offset; p = PKTNEXT(drv, p)) { -+ if (offset < (uint)PKTLEN(drv, p)) ++ for (; p && offset; p = PKTNEXT(osh, p)) { ++ if (offset < (uint)PKTLEN(osh, p)) + break; -+ offset -= PKTLEN(drv, p); ++ offset -= PKTLEN(osh, p); + } + + if (!p) + return 0; + + /* copy the data */ -+ for (; p && len; p = PKTNEXT(drv, p)) { -+ n = MIN((uint)PKTLEN(drv, p) - offset, (uint)len); -+ bcopy(PKTDATA(drv, p) + offset, buf, n); ++ 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; @@ -14161,18 +15945,18 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil + +/* return total length of buffer chain */ +uint -+pkttotlen(void *drv, void *p) ++pkttotlen(osl_t *osh, void *p) +{ + uint total; + + total = 0; -+ for (; p; p = PKTNEXT(drv, p)) -+ total += PKTLEN(drv, p); ++ for (; p; p = PKTNEXT(osh, p)) ++ total += PKTLEN(osh, p); + return (total); +} + +void -+pktq_init(struct pktq *q, uint maxlen, const bool prio_map[]) ++pktq_init(struct pktq *q, uint maxlen, const uint8 prio_map[]) +{ + q->head = q->tail = NULL; + q->maxlen = maxlen; @@ -14564,13 +16348,35 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil + 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 ++* gpio=pin_name,pin_name ++* ++* This format allows multiple features to share the gpio with mutual ++* understanding. +* -+* 'def_pin' is returned if there is no such variable found. ++* '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) @@ -14583,14 +16389,80 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil + for (pin = 0; pin < GPIO_NUMPINS; pin ++) { + sprintf(name, "gpio%d", pin); + val = getvar(vars, name); -+ if (val && !strcmp(val, pin_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 + * @@ -14821,7 +16693,8 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil + /* handle bulk of data as 32-bit words */ + pend = pdata + (nbytes & 0xfffffffc); + while (pdata < pend) { -+ *tptr = *((ulong *)pdata)++; ++ 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]); @@ -14880,6 +16753,10 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil +/* + * 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) @@ -14887,19 +16764,17 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil + int len; + + /* validate current elt */ -+ if (*buflen < 2) { ++ if (!bcm_valid_tlv(elt, *buflen)) + return NULL; -+ } + ++ /* advance to next elt */ + len = elt->len; -+ -+ /* validate remaining buflen */ -+ if (*buflen >= (2 + len + 2)) { -+ elt = (bcm_tlv_t*)(elt->data + len); -+ *buflen -= (2 + len); -+ } else { -+ elt = NULL; -+ } ++ elt = (bcm_tlv_t*)(elt->data + len); ++ *buflen -= (2 + len); ++ ++ /* validate next elt */ ++ if (!bcm_valid_tlv(elt, *buflen)) ++ return NULL; + + return elt; +} @@ -14966,17 +16841,139 @@ diff -urN linux.old/drivers/net/hnd/bcmutils.c linux.dev/drivers/net/hnd/bcmutil + } + 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 -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c --- linux.old/drivers/net/hnd/hnddma.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux.dev/drivers/net/hnd/hnddma.c 2005-08-26 13:44:34.375381944 +0200 -@@ -0,0 +1,865 @@ ++++ linux.dev/drivers/net/hnd/hnddma.c 2005-11-08 16:07:38.846817500 +0100 +@@ -0,0 +1,1527 @@ +/* + * Generic Broadcom Home Networking Division (HND) DMA module. + * This supports the following chips: BCM42xx, 44xx, 47xx . + * -+ * Copyright 2004, Broadcom Corporation ++ * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -14992,32 +16989,46 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c +#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_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; ++/* default dma message level (if input msg_level pointer is null in dma_attach()) */ ++static uint dma_msg_level = ++ 0; + +#define MAXNAMEL 8 -+#define MAXDD (DMAMAXRINGSZ / sizeof (dmadd_t)) + +/* 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 *drv; /* driver handle */ ++ + void *osh; /* os handle */ -+ dmaregs_t *regs; /* dma engine registers */ -+ -+ dmadd_t *txd; /* pointer to chip-specific tx descriptor ring */ ++ 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 */ @@ -15026,7 +17037,9 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + uint txdalign; /* #bytes added to alloc'd mem to align txd */ + uint txdalloc; /* #bytes allocated for the ring */ + -+ dmadd_t *rxd; /* pointer to chip-specific rx descriptor 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 */ @@ -15035,15 +17048,21 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + uint rxdalloc; /* #bytes allocated for the ring */ + + /* tunables */ -+ uint ntxd; /* # tx descriptors */ -+ uint nrxd; /* # rx descriptors */ + uint rxbufsize; /* rx buffer size in bytes */ + uint nrxpost; /* # rx buffers to keep posted */ + uint rxoffset; /* rxcontrol offset */ -+ uint ddoffset; /* add to get dma address of descriptor ring */ -+ uint dataoffset; /* add to get dma address of data buffer */ ++ 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) @@ -15055,31 +17074,90 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c +#define NRXDACTIVE(h, t) RXD(t - h) + +/* macros to convert between byte offsets and indexes */ -+#define B2I(bytes) ((bytes) / sizeof (dmadd_t)) -+#define I2B(index) ((index) * sizeof (dmadd_t)) ++#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 + -+/* -+ * This assume the largest i/o address is, in fact, the pci big window -+ * and that the pci core sb2pcitranslation2 register has been left with -+ * the default 0x0 pci base address. -+ */ -+#define MAXDMAADDR SB_PCI_DMA_SZ -+#define DMA_ADDRESSABLE(x) !((x) & ~(MAXDMAADDR - 1)) + +/* 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(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) ++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; -+ void *va; -+ -+ ASSERT(ntxd <= MAXDD); -+ ASSERT(ISPOWEROF2(ntxd)); -+ ASSERT(nrxd <= MAXDD); -+ ASSERT(ISPOWEROF2(nrxd)); + + /* allocate private info structure */ + if ((di = MALLOC(osh, sizeof (dma_info_t))) == NULL) { @@ -15087,75 +17165,139 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + } + 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) ++ 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) ++ 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); -+ } -+ -+ /* set message level */ -+ di->msg_level = msg_level ? msg_level : &dma_msg_level; -+ -+ DMA_TRACE(("%s: dma_attach: drv %p osh %p regs %p ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", name, drv, osh, regs, ntxd, nrxd, rxbufsize, nrxpost, rxoffset, ddoffset, dataoffset)); -+ -+ /* make a private copy of our callers name */ -+ strncpy(di->name, name, MAXNAMEL); -+ di->name[MAXNAMEL-1] = '\0'; -+ -+ di->drv = drv; -+ di->osh = osh; -+ di->regs = regs; ++ } + -+ /* allocate transmit descriptor ring */ ++ /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ + if (ntxd) { -+ /* only need ntxd descriptors but it must be DMARINGALIGNed */ -+ size = ntxd * sizeof (dmadd_t); -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, DMARINGALIGN)) -+ size += DMARINGALIGN; -+ if ((va = DMA_ALLOC_CONSISTENT(osh, size, &di->txdpa)) == NULL) ++ if (!dma_alloc(di, DMA_TX)) + goto fail; -+ di->txd = (dmadd_t*) ROUNDUP((uintptr)va, DMARINGALIGN); -+ di->txdalign = (uint)((int8*)di->txd - (int8*)va); -+ di->txdpa += di->txdalign; -+ di->txdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->txd, DMARINGALIGN)); -+ ASSERT(DMA_ADDRESSABLE(di->txdpa)); + } + -+ /* allocate receive descriptor ring */ ++ /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ + if (nrxd) { -+ /* only need nrxd descriptors but it must be DMARINGALIGNed */ -+ size = nrxd * sizeof (dmadd_t); -+ if (!ISALIGNED(DMA_CONSISTENT_ALIGN, DMARINGALIGN)) -+ size += DMARINGALIGN; -+ if ((va = DMA_ALLOC_CONSISTENT(osh, size, &di->rxdpa)) == NULL) ++ if (!dma_alloc(di, DMA_RX)) + goto fail; -+ di->rxd = (dmadd_t*) ROUNDUP((uintptr)va, DMARINGALIGN); -+ di->rxdalign = (uint)((int8*)di->rxd - (int8*)va); -+ di->rxdpa += di->rxdalign; -+ di->rxdalloc = size; -+ ASSERT(ISALIGNED((uintptr)di->rxd, DMARINGALIGN)); -+ ASSERT(DMA_ADDRESSABLE(di->rxdpa)); + } + -+ /* save tunables */ -+ di->ntxd = ntxd; -+ di->nrxd = nrxd; -+ di->rxbufsize = rxbufsize; -+ di->nrxpost = nrxpost; -+ di->rxoffset = rxoffset; -+ di->ddoffset = ddoffset; -+ di->dataoffset = dataoffset; ++ 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); + @@ -15164,6 +17306,16 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + 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) @@ -15178,12 +17330,10 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + ASSERT(di->rxin == di->rxout); + + /* free dma descriptor rings */ -+ if (di->txd) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->txd - di->txdalign), -+ di->txdalloc, (di->txdpa - di->txdalign)); -+ if (di->rxd) -+ DMA_FREE_CONSISTENT(di->osh, ((int8*)di->rxd - di->rxdalign), -+ di->rxdalloc, (di->rxdpa - di->rxdalign)); ++ 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) @@ -15195,51 +17345,121 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + 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) +{ -+ uint32 status; -+ + DMA_TRACE(("%s: dma_txreset\n", di->name)); + -+ /* suspend tx DMA first */ -+ W_REG(&di->regs->xmtcontrol, XC_SE); -+ SPINWAIT((status = (R_REG(&di->regs->xmtstatus) & XS_XS_MASK)) != XS_XS_DISABLED && -+ status != XS_XS_IDLE && -+ status != XS_XS_STOPPED, -+ 10000); -+ -+ W_REG(&di->regs->xmtcontrol, 0); -+ SPINWAIT((status = (R_REG(&di->regs->xmtstatus) & 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); ++ if (DMA64_ENAB(di)) ++ dma64_txreset(di); ++ else ++ dma32_txreset(di); +} + +void +dma_rxreset(dma_info_t *di) +{ -+ uint32 status; -+ + DMA_TRACE(("%s: dma_rxreset\n", di->name)); + -+ W_REG(&di->regs->rcvcontrol, 0); -+ SPINWAIT((status = (R_REG(&di->regs->rcvstatus) & RS_RS_MASK)) != RS_RS_DISABLED, -+ 10000); -+ -+ if (status != RS_RS_DISABLED) { -+ DMA_ERROR(("%s: dma_rxreset: dma cannot be stopped\n", di->name)); -+ } ++ if (DMA64_ENAB(di)) ++ dma64_rxreset(di); ++ else ++ dma32_rxreset(di); +} + -+void -+dma_txinit(dma_info_t *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)); + @@ -15247,66 +17467,96 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + di->txavail = di->ntxd - 1; + + /* clear tx descriptor ring */ -+ BZERO_SM((void*)di->txd, (di->ntxd * sizeof (dmadd_t))); -+ -+ W_REG(&di->regs->xmtcontrol, XC_XE); -+ W_REG(&di->regs->xmtaddr, (di->txdpa + di->ddoffset)); ++ 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 :-) */ -+ xc = R_REG(&di->regs->xmtcontrol); -+ return ((xc != 0xffffffff) && (xc & XC_XE)); ++ 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)); -+ OR_REG(&di->regs->xmtcontrol, XC_SE); ++ 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)); -+ AND_REG(&di->regs->xmtcontrol, ~XC_SE); ++ if (DMA64_ENAB(di)) ++ AND_REG(&di->d64txregs->control, ~D64_XC_SE); ++ else ++ AND_REG(&di->d32txregs->control, ~XC_SE); +} + +bool -+dma_txsuspended(dma_info_t *di) ++dma_txsuspendedidle(dma_info_t *di) +{ -+ if (!(R_REG(&di->regs->xmtcontrol) & XC_SE)) -+ return 0; -+ -+ if ((R_REG(&di->regs->xmtstatus) & XS_XS_MASK) != XS_XS_IDLE) -+ return 0; ++ if (DMA64_ENAB(di)) ++ return dma64_txsuspendedidle(di); ++ else ++ return dma32_txsuspendedidle(di); ++} + -+ OSL_DELAY(2); -+ return ((R_REG(&di->regs->xmtstatus) & XS_XS_MASK) == XS_XS_IDLE); ++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) +{ -+ return ((R_REG(&di->regs->xmtstatus) & XS_XS_MASK) == XS_XS_STOPPED); ++ 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) +{ -+ return ((R_REG(&di->regs->rcvstatus) & RS_RS_MASK) == RS_RS_STOPPED); ++ 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)); -+ OR_REG(&di->regs->xmtcontrol, XC_LE); ++ if (DMA64_ENAB(di)) ++ OR_REG(&di->d64txregs->control, D64_XC_LE); ++ else ++ OR_REG(&di->d32txregs->control, XC_LE); +} + +void @@ -15317,17 +17567,25 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + di->rxin = di->rxout = 0; + + /* clear rx descriptor ring */ -+ BZERO_SM((void*)di->rxd, (di->nrxd * sizeof (dmadd_t))); -+ -+ dma_rxenable(di); -+ W_REG(&di->regs->rcvaddr, (di->rxdpa + di->ddoffset)); ++ 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)); -+ W_REG(&di->regs->rcvcontrol, ((di->rxoffset << RC_RO_SHIFT) | RC_RE)); ++ 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 @@ -15335,198 +17593,28 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c +{ + uint32 rc; + -+ rc = R_REG(&di->regs->rcvcontrol); -+ return ((rc != 0xffffffff) && (rc & RC_RE)); -+} -+ -+/* -+ * The BCM47XX family supports full 32bit dma engine buffer addressing so -+ * dma buffers can cross 4 Kbyte page boundaries. -+ */ -+int -+dma_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->drv, p); -+ len = PKTLEN(di->drv, p); -+ next = PKTNEXT(di->drv, 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); -+ ASSERT(DMA_ADDRESSABLE(pa)); -+ -+ /* 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; -+ -+ /* init the tx descriptor */ -+ W_SM(&di->txd[txout].ctrl, BUS_SWAP32(ctrl)); -+ W_SM(&di->txd[txout].addr, BUS_SWAP32(pa + di->dataoffset)); -+ -+ ASSERT(di->txp[txout] == NULL); -+ -+ 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 (!(ctrl & CTRL_EOF)) -+ W_SM(&di->txd[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 */ -+ W_REG(&di->regs->xmtptr, I2B(txout)); -+ -+ /* 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->drv, p0, TRUE); -+ di->txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); +} + -+#define PAGESZ 4096 -+#define PAGEBASE(x) ((uintptr)(x) & ~4095) + -+/* -+ * Just like above except go through the extra effort of splitting -+ * buffers that cross 4Kbyte boundaries into multiple tx descriptors. -+ */ ++/* !! tx entry routine */ +int -+dma_tx(dma_info_t *di, void *p0, uint32 coreflags) ++dma_txfast(dma_info_t *di, void *p0, uint32 coreflags) +{ -+ void *p, *next; -+ uchar *data; -+ uint plen, len; -+ uchar *page, *start, *end; -+ uint txout; -+ uint32 ctrl; -+ uint32 pa; -+ -+ DMA_TRACE(("%s: dma_tx\n", di->name)); -+ -+ txout = di->txout; -+ ctrl = 0; -+ -+ /* -+ * Walk the chain of packet buffers -+ * splitting those that cross 4 Kbyte boundaries -+ * allocating and initializing transmit descriptor entries. -+ */ -+ for (p = p0; p; p = next) { -+ data = PKTDATA(di->drv, p); -+ plen = PKTLEN(di->drv, p); -+ next = PKTNEXT(di->drv, p); -+ -+ if (plen == 0) -+ continue; -+ -+ for (page = (uchar*)PAGEBASE(data); -+ page <= (uchar*)PAGEBASE(data + plen - 1); -+ page += PAGESZ) { -+ -+ /* return nonzero if out of tx descriptors */ -+ if (NEXTTXD(txout) == di->txin) -+ goto outoftxd; -+ -+ start = (page == (uchar*)PAGEBASE(data))? data: page; -+ end = (page == (uchar*)PAGEBASE(data + plen))? -+ (data + plen): (page + PAGESZ); -+ len = (uint)(end - start); -+ -+ /* build the descriptor control value */ -+ ctrl = len & CTRL_BC_MASK; -+ -+ ctrl |= coreflags; -+ -+ if ((p == p0) && (start == data)) -+ ctrl |= CTRL_SOF; -+ if ((next == NULL) && (end == (data + plen))) -+ ctrl |= (CTRL_IOC | CTRL_EOF); -+ if (txout == (di->ntxd - 1)) -+ ctrl |= CTRL_EOT; -+ -+ /* get physical address of buffer start */ -+ pa = (uint32) DMA_MAP(di->osh, start, len, DMA_TX, p); -+ ASSERT(DMA_ADDRESSABLE(pa)); -+ -+ /* init the tx descriptor */ -+ W_SM(&di->txd[txout].ctrl, BUS_SWAP32(ctrl)); -+ W_SM(&di->txd[txout].addr, BUS_SWAP32(pa + di->dataoffset)); -+ -+ ASSERT(di->txp[txout] == NULL); -+ -+ txout = NEXTTXD(txout); -+ } ++ if (DMA64_ENAB(di)) { ++ return dma64_txfast(di, p0, coreflags); ++ } else { ++ return dma32_txfast(di, p0, coreflags); + } -+ -+ /* if last txd eof not set, fix it */ -+ if (!(ctrl & CTRL_EOF)) -+ W_SM(&di->txd[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 */ -+ W_REG(&di->regs->xmtptr, I2B(txout)); -+ -+ /* tx flow control */ -+ di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -+ -+ return (0); -+ -+outoftxd: -+ DMA_ERROR(("%s: dma_tx: out of txds\n", di->name)); -+ PKTFREE(di->drv, p0, TRUE); -+ di->txavail = 0; -+ di->hnddma.txnobuf++; -+ return (-1); +} + -+/* returns a pointer to the next frame received, or NULL if there are no more */ ++/* !! 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) +{ @@ -15540,11 +17628,11 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + skiplen -= di->rxbufsize; + if (skiplen < 0) + skiplen = 0; -+ PKTFREE(di->drv, p, FALSE); ++ PKTFREE(di->osh, p, FALSE); + continue; + } + -+ len = ltoh16(*(uint16*)(PKTDATA(di->drv, p))); ++ len = ltoh16(*(uint16*)(PKTDATA(di->osh, p))); + DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); + + /* bad frame length check */ @@ -15552,13 +17640,13 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); + if (len > 0) + skiplen = len - (di->rxbufsize - di->rxoffset); -+ PKTFREE(di->drv, p, FALSE); ++ PKTFREE(di->osh, p, FALSE); + di->hnddma.rxgiants++; + continue; + } + + /* set actual length */ -+ PKTSETLEN(di->drv, p, (di->rxoffset + len)); ++ PKTSETLEN(di->osh, p, (di->rxoffset + len)); + + break; + } @@ -15572,7 +17660,7 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c +{ + void *p; + uint rxin, rxout; -+ uint ctrl; ++ uint32 ctrl; + uint n; + uint i; + uint32 pa; @@ -15593,30 +17681,36 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); + + for (i = 0; i < n; i++) { -+ if ((p = PKTGET(di->drv, rxbufsize, FALSE)) == NULL) { ++ if ((p = PKTGET(di->osh, rxbufsize, FALSE)) == NULL) { + DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", di->name)); + di->hnddma.rxnobuf++; + break; + } + -+ *(uint32*)(OSL_UNCACHED(PKTDATA(di->drv, p))) = 0; ++ /* 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->drv, p), rxbufsize, DMA_RX, p); ++ pa = (uint32) DMA_MAP(di->osh, PKTDATA(di->osh, p), rxbufsize, DMA_RX, p); + ASSERT(ISALIGNED(pa, 4)); -+ ASSERT(DMA_ADDRESSABLE(pa)); + + /* save the free packet pointer */ + ASSERT(di->rxp[rxout] == NULL); + di->rxp[rxout] = p; + -+ /* prep the descriptor control value */ -+ ctrl = rxbufsize; -+ if (rxout == (di->nrxd - 1)) -+ ctrl |= CTRL_EOT; ++ if (DMA64_ENAB(di)) { ++ /* prep the descriptor control value */ ++ if (rxout == (di->nrxd - 1)) ++ ctrl = CTRL_EOT; + -+ /* init the rx descriptor */ -+ W_SM(&di->rxd[rxout].ctrl, BUS_SWAP32(ctrl)); -+ W_SM(&di->rxd[rxout].addr, BUS_SWAP32(pa + di->dataoffset)); ++ 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); + } @@ -15624,7 +17718,11 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + di->rxout = rxout; + + /* update the chip lastdscr pointer */ -+ W_REG(&di->regs->rcvptr, I2B(rxout)); ++ if (DMA64_ENAB(di)) { ++ W_REG(&di->d64rxregs->ptr, I2B(rxout, dma64dd_t)); ++ } else { ++ W_REG(&di->d32rxregs->ptr, I2B(rxout, dma32dd_t)); ++ } +} + +void @@ -15635,7 +17733,7 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); + + while ((p = dma_getnexttxp(di, forceall))) -+ PKTFREE(di->drv, p, TRUE); ++ PKTFREE(di->osh, p, TRUE); +} + +/* @@ -15647,52 +17745,24 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c +void* +dma_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->regs->xmtstatus) & XS_CD_MASK); -+ -+ 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->txd[i].addr)) - di->dataoffset), -+ (BUS_SWAP32(R_SM(&di->txd[i].ctrl)) & CTRL_BC_MASK), DMA_TX, di->txp[i]); -+ W_SM(&di->txd[i].addr, 0xdeadbeef); -+ txp = di->txp[i]; -+ di->txp[i] = NULL; ++ if (DMA64_ENAB(di)) { ++ return dma64_getnexttxp(di, forceall); ++ } else { ++ return dma32_getnexttxp(di, forceall); + } -+ -+ 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); +} -+ ++ +/* like getnexttxp but no reclaim */ +void* +dma_peeknexttxp(dma_info_t *di) +{ + uint end, i; + -+ end = B2I(R_REG(&di->regs->xmtstatus) & XS_CD_MASK); ++ 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]) @@ -15701,6 +17771,19 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + 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) +{ @@ -15709,26 +17792,307 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); + + while ((p = dma_getnextrxp(di, TRUE))) -+ PKTFREE(di->drv, p, FALSE); ++ PKTFREE(di->osh, p, FALSE); +} + +void * +dma_getnextrxp(dma_info_t *di, bool forceall) +{ -+ uint i; -+ void *rxp; -+ -+ /* if forcing, dma engine must be disabled */ -+ ASSERT(!forceall || !dma_rxenabled(di)); ++ if (DMA64_ENAB(di)) { ++ return dma64_getnextrxp(di, forceall); ++ } else { ++ return dma32_getnextrxp(di, forceall); ++ } ++} + -+ i = di->rxin; ++uintptr ++dma_getvar(dma_info_t *di, char *name) ++{ ++ if (!strcmp(name, "&txavail")) ++ return ((uintptr) &di->txavail); ++ else { ++ ASSERT(0); ++ } ++ return (0); ++} + -+ /* return if no packets posted */ -+ if (i == di->rxout) ++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->regs->rcvstatus) & RS_CD_MASK))) ++ 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 */ @@ -15737,50 +18101,336 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + di->rxp[i] = NULL; + + /* clear this packet from the descriptor ring */ -+ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd[i].addr)) - di->dataoffset), ++ DMA_UNMAP(di->osh, (BUS_SWAP32(R_SM(&di->rxd32[i].addr)) - di->dataoffsetlow), + di->rxbufsize, DMA_RX, rxp); -+ W_SM(&di->rxd[i].addr, 0xdeadbeef); ++ 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; + -+uintptr -+dma_getvar(dma_info_t *di, char *name) ++ 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) +{ -+ if (!strcmp(name, "&txavail")) -+ return ((uintptr) &di->txavail); -+ else { -+ ASSERT(0); ++ 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 (0); ++ ++ return TRUE; +} + -+void -+dma_txblock(dma_info_t *di) ++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); +} + -+void -+dma_txunblock(dma_info_t *di) ++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); +} + -+uint -+dma_txactive(dma_info_t *di) -+{ -+ return (NTXDACTIVE(di->txin, di->txout)); ++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); +} + -+/* -+ * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). -+ */ -+void -+dma_txrotate(di_t *di) ++static void ++dma64_txrotate(di_t *di) +{ + uint ad; + uint nactive; @@ -15789,10 +18439,10 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + uint32 w; + uint first, last; + -+ ASSERT(dma_txsuspended(di)); ++ ASSERT(dma_txsuspendedidle(di)); + + nactive = dma_txactive(di); -+ ad = B2I((R_REG(&di->regs->xmtstatus) & XS_AD_MASK) >> XS_AD_SHIFT); ++ ad = B2I((R_REG(&di->d64txregs->status1) & D64_XS1_AD_MASK), dma64dd_t); + rot = TXD(ad - di->txin); + + ASSERT(rot < di->ntxd); @@ -15814,14 +18464,20 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + * Move the tx dma descriptor. + * EOT is set only in the last entry in the ring. + */ -+ w = R_SM(&di->txd[old].ctrl) & ~CTRL_EOT; ++ w = R_SM(&di->txd64[old].ctrl1) & ~D64_CTRL1_EOT; + if (new == (di->ntxd - 1)) -+ w |= CTRL_EOT; -+ W_SM(&di->txd[new].ctrl, w); -+ W_SM(&di->txd[new].addr, R_SM(&di->txd[old].addr)); ++ 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->txd[old].addr, 0xdeadbeef); ++ W_SM(&di->txd64[old].addrlow, 0xdeadbeef); ++ W_SM(&di->txd64[old].addrhigh, 0xdeadbeef); + + /* move the corresponding txp[] entry */ + ASSERT(di->txp[new] == NULL); @@ -15835,16 +18491,19 @@ diff -urN linux.old/drivers/net/hnd/hnddma.c linux.dev/drivers/net/hnd/hnddma.c + di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; + + /* kick the chip */ -+ W_REG(&di->regs->xmtptr, I2B(di->txout)); ++ W_REG(&di->d64txregs->ptr, I2B(di->txout, dma64dd_t)); +} ++ ++#endif ++ diff -urN 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 2005-08-26 13:44:34.376381792 +0200 -@@ -0,0 +1,640 @@ ++++ linux.dev/drivers/net/hnd/linux_osl.c 2005-11-07 23:38:26.782893500 +0100 +@@ -0,0 +1,708 @@ +/* + * Linux OS Independent Layer + * -+ * Copyright 2004, Broadcom Corporation ++ * Copyright 2005, Broadcom Corporation + * All Rights Reserved. + * + * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY @@ -15861,7 +18520,7 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +#include +#include +#include -+#include ++#include +#include +#include +#ifdef mips @@ -15882,22 +18541,84 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ + char file[BCM_MEM_FILENAME_LEN]; +} bcm_mem_link_t; + -+typedef struct os_handle { ++struct os_handle { + uint magic; + void *pdev; + uint malloced; + uint failed; + bcm_mem_link_t *dbgmem_list; -+} os_handle_t; ++}; + -+void * ++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) +{ -+ os_handle_t *osh; ++ osl_t *osh; + -+ osh = kmalloc(sizeof(os_handle_t), GFP_ATOMIC); ++ 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; @@ -15908,14 +18629,14 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +} + +void -+osl_detach(void *osh) ++osl_detach(osl_t *osh) +{ -+ ASSERT((osh && (((os_handle_t *)osh)->magic == OS_HANDLE_MAGIC))); ++ ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC)); + kfree(osh); +} + +void* -+osl_pktget(void *drv, uint len, bool send) ++osl_pktget(osl_t *osh, uint len, bool send) +{ + struct sk_buff *skb; + @@ -15953,20 +18674,18 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +} + +uint32 -+osl_pci_read_config(void *osh, uint offset, uint size) ++osl_pci_read_config(osl_t *osh, uint offset, uint size) +{ -+ struct pci_dev *pdev; + uint val; + uint retry=PCI_CFG_RETRY; + -+ ASSERT((osh && (((os_handle_t *)osh)->magic == OS_HANDLE_MAGIC))); ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); + + /* only 4byte access supported */ + ASSERT(size == 4); + -+ pdev = ((os_handle_t *)osh)->pdev; + do { -+ pci_read_config_dword(pdev, offset, &val); ++ pci_read_config_dword(osh->pdev, offset, &val); + if (val != 0xffffffff) + break; + } while (retry--); @@ -15976,20 +18695,17 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +} + +void -+osl_pci_write_config(void *osh, uint offset, uint size, uint val) ++osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) +{ -+ struct pci_dev *pdev; + uint retry=PCI_CFG_RETRY; + -+ ASSERT((osh && (((os_handle_t *)osh)->magic == OS_HANDLE_MAGIC))); ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); + + /* only 4byte access supported */ + ASSERT(size == 4); + -+ pdev = ((os_handle_t *)osh)->pdev; -+ + do { -+ pci_write_config_dword(pdev, offset, val); ++ pci_write_config_dword(osh->pdev, offset, val); + if (offset!=PCI_BAR0_WIN) + break; + if (osl_pci_read_config(osh,offset,size) == val) @@ -15998,19 +18714,37 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ + +} + ++/* 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(void *osh, uint offset, char *buf, int size, bool write) ++osl_pcmcia_attr(osl_t *osh, uint offset, char *buf, int size, bool write) +{ +} + +void -+osl_pcmcia_read_attr(void *osh, uint offset, void *buf, int size) ++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(void *osh, uint offset, void *buf, int size) ++osl_pcmcia_write_attr(osl_t *osh, uint offset, void *buf, int size) +{ + osl_pcmcia_attr(osh, offset, (char *) buf, size, TRUE); +} @@ -16019,19 +18753,15 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +#ifdef BCMDBG_MEM + +void* -+osl_debug_malloc(void *osh, uint size, int line, char* file) ++osl_debug_malloc(osl_t *osh, uint size, int line, char* file) +{ + bcm_mem_link_t *p; + char* basename; -+ os_handle_t *h = (os_handle_t *)osh; -+ -+ if (size == 0) { -+ return NULL; -+ } ++ ++ ASSERT(size); + -+ p = (bcm_mem_link_t*)osl_malloc(osh, sizeof(bcm_mem_link_t) + size); -+ if (p == NULL) -+ return p; ++ if ((p = (bcm_mem_link_t*)osl_malloc(osh, sizeof(bcm_mem_link_t) + size)) == NULL) ++ return (NULL); + + p->size = size; + p->line = line; @@ -16049,31 +18779,32 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ + + /* link this block */ + p->prev = NULL; -+ p->next = h->dbgmem_list; ++ p->next = osh->dbgmem_list; + if (p->next) + p->next->prev = p; -+ h->dbgmem_list = p; ++ osh->dbgmem_list = p; + + return p + 1; +} + +void -+osl_debug_mfree(void *osh, void *addr, uint size, int line, char* file) ++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)); -+ os_handle_t *h = (os_handle_t *)osh; + -+ ASSERT((h && (h->magic == OS_HANDLE_MAGIC))); ++ 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; + } + @@ -16082,25 +18813,24 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ + p->prev->next = p->next; + if (p->next) + p->next->prev = p->prev; -+ if (h->dbgmem_list == p) -+ h->dbgmem_list = p->next; ++ 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(void *osh, char *buf, uint sz) ++osl_debug_memdump(osl_t *osh, char *buf, uint sz) +{ + bcm_mem_link_t *p; + char *obuf; -+ os_handle_t *h = (os_handle_t *)osh; -+ -+ ASSERT((h && (h->magic == OS_HANDLE_MAGIC))); ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); + obuf = buf; + + buf += sprintf(buf, " Address\tSize\tFile:line\n"); -+ for (p = h->dbgmem_list; p && ((buf - obuf) < (sz - 128)); p = p->next) ++ 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); + @@ -16110,92 +18840,82 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +#endif /* BCMDBG_MEM */ + +void* -+osl_malloc(void *osh, uint size) ++osl_malloc(osl_t *osh, uint size) +{ -+ os_handle_t *h = (os_handle_t *)osh; + void *addr; ++ ++ /* only ASSERT if osh is defined */ ++ if (osh) ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); + -+ ASSERT((h && (h->magic == OS_HANDLE_MAGIC))); -+ h->malloced += size; -+ addr = kmalloc(size, GFP_ATOMIC); -+ if (!addr) -+ h->failed++; ++ if ((addr = kmalloc(size, GFP_ATOMIC)) == NULL) { ++ if(osh) ++ osh->failed++; ++ return (NULL); ++ } ++ if (osh) ++ osh->malloced += size; ++ + return (addr); +} + +void -+osl_mfree(void *osh, void *addr, uint size) ++osl_mfree(osl_t *osh, void *addr, uint size) +{ -+ os_handle_t *h = (os_handle_t *)osh; -+ -+ ASSERT((h && (h->magic == OS_HANDLE_MAGIC))); -+ h->malloced -= size; ++ if (osh) { ++ ASSERT(osh->magic == OS_HANDLE_MAGIC); ++ osh->malloced -= size; ++ } + kfree(addr); +} + +uint -+osl_malloced(void *osh) ++osl_malloced(osl_t *osh) +{ -+ os_handle_t *h = (os_handle_t *)osh; -+ -+ ASSERT((h && (h->magic == OS_HANDLE_MAGIC))); -+ return (h->malloced); ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->malloced); +} + -+uint osl_malloc_failed(void *osh) ++uint osl_malloc_failed(osl_t *osh) +{ -+ os_handle_t *h = (os_handle_t *)osh; -+ -+ ASSERT((h && (h->magic == OS_HANDLE_MAGIC))); -+ return (h->failed); ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); ++ return (osh->failed); +} + +void* -+osl_dma_alloc_consistent(void *osh, uint size, ulong *pap) ++osl_dma_alloc_consistent(osl_t *osh, uint size, ulong *pap) +{ -+ struct pci_dev *dev; ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); + -+ ASSERT((osh && (((os_handle_t *)osh)->magic == OS_HANDLE_MAGIC))); -+ -+ dev = ((os_handle_t *)osh)->pdev; -+ return (pci_alloc_consistent(dev, size, (dma_addr_t*)pap)); ++ return (pci_alloc_consistent(osh->pdev, size, (dma_addr_t*)pap)); +} + +void -+osl_dma_free_consistent(void *osh, void *va, uint size, ulong pa) ++osl_dma_free_consistent(osl_t *osh, void *va, uint size, ulong pa) +{ -+ struct pci_dev *dev; -+ -+ ASSERT((osh && (((os_handle_t *)osh)->magic == OS_HANDLE_MAGIC))); ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); + -+ dev = ((os_handle_t *)osh)->pdev; -+ pci_free_consistent(dev, size, va, (dma_addr_t)pa); ++ pci_free_consistent(osh->pdev, size, va, (dma_addr_t)pa); +} + +uint -+osl_dma_map(void *osh, void *va, uint size, int direction) ++osl_dma_map(osl_t *osh, void *va, uint size, int direction) +{ + int dir; -+ struct pci_dev *dev; -+ -+ ASSERT((osh && (((os_handle_t *)osh)->magic == OS_HANDLE_MAGIC))); -+ -+ dev = ((os_handle_t *)osh)->pdev; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); + dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ return (pci_map_single(dev, va, size, dir)); ++ return (pci_map_single(osh->pdev, va, size, dir)); +} + +void -+osl_dma_unmap(void *osh, uint pa, uint size, int direction) ++osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) +{ + int dir; -+ struct pci_dev *dev; -+ -+ ASSERT((osh && (((os_handle_t *)osh)->magic == OS_HANDLE_MAGIC))); -+ -+ dev = ((os_handle_t *)osh)->pdev; ++ ++ ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); + dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; -+ pci_unmap_single(dev, (uint32)pa, size, dir); ++ pci_unmap_single(osh->pdev, (uint32)pa, size, dir); +} + +#if defined(BINOSL) @@ -16209,6 +18929,18 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +} +#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. + */ @@ -16259,7 +18991,7 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +} + +int -+osl_strlen(char *s) ++osl_strlen(const char *s) +{ + return (strlen(s)); +} @@ -16378,38 +19110,32 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +#endif +} + -+void -+osl_delay(uint usec) -+{ -+ udelay(usec); -+} -+ +uchar* -+osl_pktdata(void *drv, void *skb) ++osl_pktdata(osl_t *osh, void *skb) +{ + return (((struct sk_buff*)skb)->data); +} + +uint -+osl_pktlen(void *drv, void *skb) ++osl_pktlen(osl_t *osh, void *skb) +{ + return (((struct sk_buff*)skb)->len); +} + +uint -+osl_pktheadroom(void *drv, void *skb) ++osl_pktheadroom(osl_t *osh, void *skb) +{ + return (uint) skb_headroom((struct sk_buff *) skb); +} + +uint -+osl_pkttailroom(void *drv, void *skb) ++osl_pkttailroom(osl_t *osh, void *skb) +{ + return (uint) skb_tailroom((struct sk_buff *) skb); +} + +void* -+osl_pktnext(void *drv, void *skb) ++osl_pktnext(osl_t *osh, void *skb) +{ + return (((struct sk_buff*)skb)->next); +} @@ -16421,25 +19147,25 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ +} + +void -+osl_pktsetlen(void *drv, void *skb, uint len) ++osl_pktsetlen(osl_t *osh, void *skb, uint len) +{ + __skb_trim((struct sk_buff*)skb, len); +} + +uchar* -+osl_pktpush(void *drv, void *skb, int bytes) ++osl_pktpush(osl_t *osh, void *skb, int bytes) +{ + return (skb_push((struct sk_buff*)skb, bytes)); +} + +uchar* -+osl_pktpull(void *drv, void *skb, int bytes) ++osl_pktpull(osl_t *osh, void *skb, int bytes) +{ + return (skb_pull((struct sk_buff*)skb, bytes)); +} + +void* -+osl_pktdup(void *drv, void *skb) ++osl_pktdup(osl_t *osh, void *skb) +{ + return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC)); +} @@ -16480,11 +19206,12 @@ diff -urN linux.old/drivers/net/hnd/linux_osl.c linux.dev/drivers/net/hnd/linux_ + ((struct sk_buff*)skb)->priority = x; +} + ++ +#endif /* BINOSL */ diff -urN 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 2005-09-01 01:33:48.212447040 +0200 -@@ -0,0 +1,2061 @@ ++++ linux.dev/drivers/net/hnd/sbutils.c 2005-11-08 12:54:06.123274250 +0100 +@@ -0,0 +1,2823 @@ +/* + * Misc utility routines for accessing chip-specific features + * of the SiliconBackplane-based Broadcom chips. @@ -16496,20 +19223,21 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + * 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.6 2005/03/07 08:35:32 kanki Exp $ ++ * $Id$ + */ + +#include +#include ++#include +#include +#include +#include +#include +#include ++#include +#include +#include +#include -+#include +#include + +/* debug/trace */ @@ -16522,12 +19250,8 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* misc sb info needed by some of the routines */ +typedef struct sb_info { -+ uint chip; /* chip number */ -+ uint chiprev; /* chip revision */ -+ uint chippkg; /* chip package option */ -+ uint boardtype; /* board type */ -+ uint boardvendor; /* board vendor id */ -+ uint bustype; /* what bus type we are going through */ ++ ++ struct sb_pub sb; /* back plane public state(must be first field of sb_info */ + + void *osh; /* osl os handle */ + void *sdh; /* bcmsdh handle */ @@ -16537,15 +19261,9 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + + uint curidx; /* current core index */ + uint dev_coreid; /* the core provides driver functions */ -+ uint pciidx; /* pci core index */ -+ uint pcirev; /* pci core rev */ + -+ uint pcmciaidx; /* pcmcia core index */ -+ uint pcmciarev; /* pcmcia core rev */ + bool memseg; /* flag to toggle MEM_SEG register */ + -+ uint ccrev; /* chipc core rev */ -+ + uint gpioidx; /* gpio control core index */ + uint gpioid; /* gpio control coretype */ + @@ -16556,16 +19274,32 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + 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 void* BCMINIT(sb_doattach)(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz); ++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(void *sbh, uint coreidx, uint regoff, uint mask, uint val); -+static uint _sb_coreidx(void *sbh); -+static uint sb_findcoreidx(void *sbh, uint coreid, uint coreunit); ++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))) @@ -16574,7 +19308,14 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. +#define REGS2SB(va) (sbconfig_t*) ((int8*)(va) + SBCONFIGOFF) +#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) +#define BADIDX (SB_MAXCORES+1) -+#define NOREV (SBIDH_RC_MASK + 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)) @@ -16592,27 +19333,35 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ + (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } + -+/* power control defines */ ++/* dynamic clock control defines */ +#define LPOMINFREQ 25000 /* low power oscillator min */ +#define LPOMAXFREQ 43000 /* low power oscillator max */ -+#define XTALMINFREQ 19800000 /* 20mhz - 1% */ -+#define XTALMAXFREQ 20200000 /* 20mhz + 1% */ -+#define PCIMINFREQ 25000000 /* 25mhz */ -+#define PCIMAXFREQ 34000000 /* 33mhz + fudge */ -+#define SCC_DEF_DIV 0 /* default slow clock divider */ ++#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 */ + -+#define XTAL_ON_DELAY 1000 /* Xtal power on delay in us */ ++/* different register spaces to access thr'u pcie indirect access*/ ++#define PCIE_CONFIGREGS 1 ++#define PCIE_PCIEREGS 2 + -+#define SCC_LOW2FAST_LIMIT 5000 /* turn on fast clock time, in unit of ms */ ++/* 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(void *sbh, volatile uint32 *sbr) ++sb_read_sbreg(sb_info_t *si, volatile uint32 *sbr) +{ -+ sb_info_t *si; + uint8 tmp; + uint32 val, intr_val = 0; + -+ si = SB_INFO(sbh); + + /* + * compact flash only has 11 bits address, while we needs 12 bits address. @@ -16624,7 +19373,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + INTR_OFF(si, intr_val); + tmp = 1; + OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ (uintptr)sbr &= ~(1 << 11); /* mask out bit 11*/ ++ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ + } + + val = R_REG(sbr); @@ -16639,14 +19388,12 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. +} + +static void -+sb_write_sbreg(void *sbh, volatile uint32 *sbr, uint32 v) ++sb_write_sbreg(sb_info_t *si, volatile uint32 *sbr, uint32 v) +{ -+ sb_info_t *si; + uint8 tmp; + volatile uint32 dummy; + uint32 intr_val = 0; + -+ si = SB_INFO(sbh); + + /* + * compact flash only has 11 bits address, while we needs 12 bits address. @@ -16658,10 +19405,10 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + INTR_OFF(si, intr_val); + tmp = 1; + OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); -+ (uintptr)sbr &= ~(1 << 11); /* mask out bit 11 */ ++ sbr = (uint32) ((uintptr) sbr & ~(1 << 11)); /* mask out bit 11*/ + } + -+ if (BUSTYPE(si->bustype) == PCMCIA_BUS) { ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { +#ifdef IL_BIGENDIAN + dummy = R_REG(sbr); + W_REG(((volatile uint16 *)sbr + 1), (uint16)((v >> 16) & 0xffff)); @@ -16692,8 +19439,9 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + * vars - pointer to a pointer area for "environment" variables + * varsz - pointer to int to return the size of the vars + */ -+void* -+BCMINITFN(sb_attach)(uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz) ++sb_t * ++BCMINITFN(sb_attach)(uint devid, osl_t *osh, void *regs, ++ uint bustype, void *sdh, char **vars, int *varsz) +{ + sb_info_t *si; + @@ -16707,7 +19455,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + MFREE(osh, si, sizeof (sb_info_t)); + return (NULL); + } -+ return si; ++ return (sb_t *)si; +} + +/* Using sb_kattach depends on SB_BUS support, either implicit */ @@ -16718,12 +19466,10 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. +static sb_info_t ksi; + +/* generic kernel variant of sb_attach() */ -+void* ++sb_t * +BCMINITFN(sb_kattach)() +{ + uint32 *regs; -+ char *unused; -+ int varsz; + + if (ksi.curmap == NULL) { + uint32 cid; @@ -16743,28 +19489,29 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + } + + if (BCMINIT(sb_doattach)(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, -+ SB_BUS, NULL, &unused, &varsz) == NULL) { ++ SB_BUS, NULL, NULL, NULL) == NULL) { + return NULL; + } + } + -+ return &ksi; ++ return (sb_t *)&ksi; +} +#endif + -+static void* -+BCMINITFN(sb_doattach)(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz) ++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; -+ int res; + + ASSERT(GOODREGS(regs)); + + bzero((uchar*)si, sizeof (sb_info_t)); + -+ si->pciidx = si->gpioidx = BADIDX; ++ si->sb.buscoreidx = si->gpioidx = BADIDX; + + si->osh = osh; + si->curmap = regs; @@ -16778,77 +19525,98 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + bustype = PCI_BUS; + } + -+ si->bustype = bustype; -+ if (si->bustype != BUSTYPE(si->bustype)) { ++ 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->bustype, BUSTYPE(si->bustype))); ++ 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->bustype) == PCMCIA_BUS) ++ 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->bustype) == PCI_BUS) -+ sb_pwrctl_xtal((void*)si, XTAL|PLL, ON); ++ 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((void*)si); ++ 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->bustype) == SB_BUS) ++ 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((void*)si, 0); -+ if (sb_coreid((void*)si) != SB_CC) ++ 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->chip = R_REG(&cc->chipid) & CID_ID_MASK; -+ si->chiprev = (R_REG(&cc->chipid) & CID_REV_MASK) >> CID_REV_SHIFT; -+ si->chippkg = (R_REG(&cc->chipid) & CID_PKG_MASK) >> CID_PKG_SHIFT; ++ 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->bustype) == PCMCIA_BUS) ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) + devid = BCM4301_DEVICE_ID; + + /* no chip common core -- must convert device id to chip id */ -+ if ((si->chip = BCMINIT(sb_pcidev2chip)(devid)) == 0) { -+ SB_ERROR(("sb_attach: unrecognized device id 0x%04x\n", devid)); ++ 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->ccrev = cc ? sb_corerev((void*)si) : NOREV; ++ si->sb.ccrev = cc ? (int)sb_corerev(&si->sb) : NOREV; + + /* determine numcores */ -+ if (cc && ((si->ccrev == 4) || (si->ccrev >= 6))) ++ 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->chip); ++ si->numcores = BCMINIT(sb_chip2numcores)(si->sb.chip); + + /* return to original core */ -+ sb_setcoreidx((void*)si, origidx); ++ sb_setcoreidx(&si->sb, origidx); + + /* sanity checks */ -+ ASSERT(si->chip); ++ 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 ((res = srom_var_init(si, si->bustype, si->curmap, osh, vars, varsz))) { -+ SB_ERROR(("sb_attach: srom_var_init failed: bad srom\n")); ++ 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); + } + @@ -16860,59 +19628,69 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + * For example, the "A0" silicon of each chip is chip rev 0. + * For PCMCIA we get it from the CIS instead. + */ -+ if (BUSTYPE(si->bustype) == PCMCIA_BUS) { ++ if (BUSTYPE(si->sb.bustype) == PCMCIA_BUS) { + ASSERT(vars); -+ si->chiprev = getintvar(*vars, "chiprev"); -+ } else if (BUSTYPE(si->bustype) == PCI_BUS) { ++ 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->chiprev = w & 0xff; ++ si->sb.chiprev = w & 0xff; + } else -+ si->chiprev = 0; ++ si->sb.chiprev = 0; + } + -+ if (BUSTYPE(si->bustype) == PCMCIA_BUS) { ++ 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_attach: gpio control core not found\n")); ++ SB_ERROR(("sb_doattach: gpio control core not found\n")); + return NULL; + } + + /* get boardtype and boardrev */ -+ switch (BUSTYPE(si->bustype)) { ++ 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->boardvendor = w & 0xffff; -+ si->boardtype = (w >> 16) & 0xffff; ++ si->sb.boardvendor = w & 0xffff; ++ si->sb.boardtype = (w >> 16) & 0xffff; + break; + + case PCMCIA_BUS: + case SDIO_BUS: -+ si->boardvendor = getintvar(*vars, "manfid"); -+ si->boardtype = getintvar(*vars, "prodid"); ++ si->sb.boardvendor = getintvar(*vars, "manfid"); ++ si->sb.boardtype = getintvar(*vars, "prodid"); + break; + + case SB_BUS: -+ si->boardvendor = VENDOR_BROADCOM; -+ si->boardtype = 0xffff; ++ case JTAG_BUS: ++ si->sb.boardvendor = VENDOR_BROADCOM; ++ if ((si->sb.boardtype = getintvar(NULL, "boardtype")) == 0) ++ si->sb.boardtype = 0xffff; + break; + } + -+ if (si->boardtype == 0) { -+ SB_ERROR(("sb_attach: unknown board type\n")); -+ ASSERT(si->boardtype); ++ 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 ((void*)si); ++ return (si); +} + +uint -+sb_coreid(void *sbh) ++sb_coreid(sb_t *sbh) +{ + sb_info_t *si; + sbconfig_t *sb; @@ -16920,11 +19698,11 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + sb = REGS2SB(si->curmap); + -+ return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); +} + +uint -+sb_coreidx(void *sbh) ++sb_coreidx(sb_t *sbh) +{ + sb_info_t *si; + @@ -16934,19 +19712,17 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* return current index of core */ +static uint -+_sb_coreidx(void *sbh) ++_sb_coreidx(sb_info_t *si) +{ -+ sb_info_t *si; + sbconfig_t *sb; + uint32 sbaddr = 0; + -+ si = SB_INFO(sbh); + ASSERT(si); + -+ switch (BUSTYPE(si->bustype)) { ++ switch (BUSTYPE(si->sb.bustype)) { + case SB_BUS: + sb = REGS2SB(si->curmap); -+ sbaddr = sb_base(R_SBREG(sbh, &sb->sbadmatch0)); ++ sbaddr = sb_base(R_SBREG(si, &sb->sbadmatch0)); + break; + + case PCI_BUS: @@ -16964,6 +19740,13 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + sbaddr |= (uint)tmp << 24; + break; + } ++ ++#ifdef BCMJTAG ++ case JTAG_BUS: ++ sbaddr = (uint32)si->curmap; ++ break; ++#endif /* BCMJTAG */ ++ + default: + ASSERT(0); + } @@ -16975,7 +19758,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. +} + +uint -+sb_corevendor(void *sbh) ++sb_corevendor(sb_t *sbh) +{ + sb_info_t *si; + sbconfig_t *sb; @@ -16983,23 +19766,25 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + sb = REGS2SB(si->curmap); + -+ return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); ++ return ((R_SBREG(si, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); +} + +uint -+sb_corerev(void *sbh) ++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 (R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_RC_MASK); ++ return (SBCOREREV(sbidh)); +} + +void * -+sb_osh(void *sbh) ++sb_osh(sb_t *sbh) +{ + sb_info_t *si; + @@ -17011,7 +19796,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* set/clear sbtmstatelow core-specific flags */ +uint32 -+sb_coreflags(void *sbh, uint32 mask, uint32 val) ++sb_coreflags(sb_t *sbh, uint32 mask, uint32 val) +{ + sb_info_t *si; + sbconfig_t *sb; @@ -17025,17 +19810,17 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + + /* mask and set */ + if (mask || val) { -+ w = (R_SBREG(sbh, &sb->sbtmstatelow) & ~mask) | val; -+ W_SBREG(sbh, &sb->sbtmstatelow, w); ++ w = (R_SBREG(si, &sb->sbtmstatelow) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatelow, w); + } + + /* return the new value */ -+ return (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_ALLOW); ++ return (R_SBREG(si, &sb->sbtmstatelow) & SBTML_ALLOW); +} + +/* set/clear sbtmstatehigh core-specific flags */ +uint32 -+sb_coreflagshi(void *sbh, uint32 mask, uint32 val) ++sb_coreflagshi(sb_t *sbh, uint32 mask, uint32 val) +{ + sb_info_t *si; + sbconfig_t *sb; @@ -17049,16 +19834,45 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + + /* mask and set */ + if (mask || val) { -+ w = (R_SBREG(sbh, &sb->sbtmstatehigh) & ~mask) | val; -+ W_SBREG(sbh, &sb->sbtmstatehigh, w); ++ w = (R_SBREG(si, &sb->sbtmstatehigh) & ~mask) | val; ++ W_SBREG(si, &sb->sbtmstatehigh, w); + } + + /* return the new value */ -+ return (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_FL_MASK); ++ 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(void *sbh) ++sb_iscoreup(sb_t *sbh) +{ + sb_info_t *si; + sbconfig_t *sb; @@ -17066,7 +19880,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + sb = REGS2SB(si->curmap); + -+ return ((R_SBREG(sbh, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ | SBTML_CLK)) == SBTML_CLK); ++ return ((R_SBREG(si, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ_MASK | SBTML_CLK)) == SBTML_CLK); +} + +/* @@ -17074,9 +19888,8 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + * switch back to the original core, and return the new value. + */ +static uint -+sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val) ++sb_corereg(sb_info_t *si, uint coreidx, uint regoff, uint mask, uint val) +{ -+ sb_info_t *si; + uint origidx; + uint32 *r; + uint w; @@ -17086,21 +19899,19 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + ASSERT(regoff < SB_CORE_SIZE); + ASSERT((val & ~mask) == 0); + -+ si = SB_INFO(sbh); -+ + INTR_OFF(si, intr_val); + + /* save current core index */ -+ origidx = sb_coreidx(sbh); ++ origidx = sb_coreidx(&si->sb); + + /* switch core */ -+ r = (uint32*) ((uchar*) sb_setcoreidx(sbh, coreidx) + regoff); ++ r = (uint32*) ((uchar*) sb_setcoreidx(&si->sb, coreidx) + regoff); + + /* mask and set */ + if (mask || val) { + if (regoff >= SBCONFIGOFF) { -+ w = (R_SBREG(sbh, r) & ~mask) | val; -+ W_SBREG(sbh, r, w); ++ w = (R_SBREG(si, r) & ~mask) | val; ++ W_SBREG(si, r, w); + } else { + w = (R_REG(r) & ~mask) | val; + W_REG(r, w); @@ -17109,50 +19920,166 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + + /* readback */ + if (regoff >= SBCONFIGOFF) -+ w = R_SBREG(sbh, r); ++ w = R_SBREG(si, r); + else + w = R_REG(r); + + /* restore core index */ + if (origidx != coreidx) -+ sb_setcoreidx(sbh, origidx); ++ 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) +{ -+ void *sbh; + uint origidx; + uint i; ++ bool pci; ++ bool pcie; ++ uint pciidx; ++ uint pcieidx; ++ uint pcirev; ++ uint pcierev; ++ + -+ sbh = (void*) si; + + /* numcores should already be set */ + ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); + + /* save current core index */ -+ origidx = sb_coreidx(sbh); ++ origidx = sb_coreidx(&si->sb); + -+ si->pciidx = si->pcmciaidx = si->gpioidx = BADIDX; -+ si->pcirev = si->pcmciarev = NOREV; ++ si->sb.buscorerev = NOREV; ++ si->sb.buscoreidx = BADIDX; + -+ for (i = 0; i < si->numcores; i++) { -+ sb_setcoreidx(sbh, i); -+ si->coreid[i] = sb_coreid(sbh); ++ si->gpioidx = BADIDX; + -+ if (si->coreid[i] == SB_PCI) { -+ si->pciidx = i; -+ si->pcirev = sb_corerev(sbh); ++ 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->pcmciaidx = i; -+ si->pcmciarev = sb_corerev(sbh); ++ 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. @@ -17161,25 +20088,25 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + * - 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(sbh, SB_CC, 0))) { -+ si->gpioidx = sb_findcoreidx(sbh, SB_CC, 0); ++ if (GOODIDX(sb_findcoreidx(si, SB_CC, 0))) { ++ si->gpioidx = sb_findcoreidx(si, SB_CC, 0); + si->gpioid = SB_CC; -+ } else if (GOODIDX(si->pciidx) && (si->pcirev >= 2)) { -+ si->gpioidx = si->pciidx; ++ } else if (PCI(si) && (si->sb.buscorerev >= 2)) { ++ si->gpioidx = si->sb.buscoreidx; + si->gpioid = SB_PCI; -+ } else if (sb_findcoreidx(sbh, SB_EXTIF, 0)) { -+ si->gpioidx = sb_findcoreidx(sbh, SB_EXTIF, 0); ++ } 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(sbh, origidx); ++ sb_setcoreidx(&si->sb, origidx); +} + +/* may be called with core in reset */ +void -+sb_detach(void *sbh) ++sb_detach(sb_t *sbh) +{ + sb_info_t *si; + uint idx; @@ -17189,14 +20116,15 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + if (si == NULL) + return; + -+ if (BUSTYPE(si->bustype) == SB_BUS) ++ 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; + } + -+ MFREE(si->osh, si, sizeof (sb_info_t)); ++ 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 */ @@ -17205,8 +20133,6 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. +{ + if ((pcidev >= BCM4710_DEVICE_ID) && (pcidev <= BCM47XX_USB_ID)) + return (BCM4710_DEVICE_ID); -+ if ((pcidev >= BCM4610_DEVICE_ID) && (pcidev <= BCM4610_USB_ID)) -+ return (BCM4610_DEVICE_ID); + if ((pcidev >= BCM4402_DEVICE_ID) && (pcidev <= BCM4402_V90_ID)) + return (BCM4402_DEVICE_ID); + if (pcidev == BCM4401_ENET_ID) @@ -17223,21 +20149,17 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. +static uint +BCMINITFN(sb_chip2numcores)(uint chip) +{ -+ if (chip == 0x4710) ++ if (chip == BCM4710_DEVICE_ID) + return (9); -+ if (chip == 0x4610) -+ return (9); -+ if (chip == 0x4402) ++ if (chip == BCM4402_DEVICE_ID) + return (3); -+ if ((chip == 0x4307) || (chip == 0x4301)) ++ if ((chip == BCM4301_DEVICE_ID) || (chip == BCM4307_DEVICE_ID)) + return (5); -+ if (chip == 0x4310) -+ return (8); -+ if (chip == 0x4306) /* < 4306c0 */ ++ if (chip == BCM4306_DEVICE_ID) /* < 4306c0 */ + return (6); -+ if (chip == 0x4704) ++ if (chip == BCM4704_DEVICE_ID) + return (9); -+ if (chip == 0x5365) ++ if (chip == BCM5365_DEVICE_ID) + return (7); + + SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); @@ -17247,13 +20169,11 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* return index of coreid or BADIDX if not found */ +static uint -+sb_findcoreidx(void *sbh, uint coreid, uint coreunit) ++sb_findcoreidx( sb_info_t *si, uint coreid, uint coreunit) +{ -+ sb_info_t *si; + uint found; + uint i; + -+ si = SB_INFO(sbh); + found = 0; + + for (i = 0; i < si->numcores; i++) @@ -17272,7 +20192,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + * Moreover, callers should keep interrupts off during switching out of and back to d11 core + */ +void* -+sb_setcoreidx(void *sbh, uint coreidx) ++sb_setcoreidx(sb_t *sbh, uint coreidx) +{ + sb_info_t *si; + uint32 sbaddr; @@ -17291,7 +20211,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + + sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); + -+ switch (BUSTYPE(si->bustype)) { ++ switch (BUSTYPE(si->sb.bustype)) { + case SB_BUS: + /* map new one */ + if (!si->regs[coreidx]) { @@ -17314,6 +20234,16 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + 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; @@ -17327,14 +20257,13 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + * Moreover, callers should keep interrupts off during switching out of and back to d11 core + */ +void* -+sb_setcore(void *sbh, uint coreid, uint coreunit) ++sb_setcore(sb_t *sbh, uint coreid, uint coreunit) +{ + sb_info_t *si; + uint idx; + + si = SB_INFO(sbh); -+ -+ idx = sb_findcoreidx(sbh, coreid, coreunit); ++ idx = sb_findcoreidx(si, coreid, coreunit); + if (!GOODIDX(idx)) + return (NULL); + @@ -17343,128 +20272,163 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* return chip number */ +uint -+BCMINITFN(sb_chip)(void *sbh) ++BCMINITFN(sb_chip)(sb_t *sbh) +{ + sb_info_t *si; + + si = SB_INFO(sbh); -+ return (si->chip); ++ return (si->sb.chip); +} + +/* return chip revision number */ +uint -+BCMINITFN(sb_chiprev)(void *sbh) ++BCMINITFN(sb_chiprev)(sb_t *sbh) +{ + sb_info_t *si; + + si = SB_INFO(sbh); -+ return (si->chiprev); ++ return (si->sb.chiprev); +} + +/* return chip common revision number */ +uint -+BCMINITFN(sb_chipcrev)(void *sbh) ++BCMINITFN(sb_chipcrev)(sb_t *sbh) +{ + sb_info_t *si; + + si = SB_INFO(sbh); -+ return (si->ccrev); ++ return (si->sb.ccrev); +} + +/* return chip package option */ +uint -+BCMINITFN(sb_chippkg)(void *sbh) ++BCMINITFN(sb_chippkg)(sb_t *sbh) +{ + sb_info_t *si; + + si = SB_INFO(sbh); -+ return (si->chippkg); ++ return (si->sb.chippkg); +} + +/* return PCI core rev. */ +uint -+BCMINITFN(sb_pcirev)(void *sbh) ++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 (si->pcirev); ++ ++ 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)(void *sbh) ++BCMINITFN(sb_pcmciarev)(sb_t *sbh) +{ + sb_info_t *si; + + si = SB_INFO(sbh); -+ return (si->pcmciarev); ++ return (si->sb.buscorerev); +} + +/* return board vendor id */ +uint -+BCMINITFN(sb_boardvendor)(void *sbh) ++BCMINITFN(sb_boardvendor)(sb_t *sbh) +{ + sb_info_t *si; + + si = SB_INFO(sbh); -+ return (si->boardvendor); ++ return (si->sb.boardvendor); +} + +/* return boardtype */ +uint -+BCMINITFN(sb_boardtype)(void *sbh) ++BCMINITFN(sb_boardtype)(sb_t *sbh) +{ + sb_info_t *si; + char *var; + + si = SB_INFO(sbh); + -+ if (BUSTYPE(si->bustype) == SB_BUS && si->boardtype == 0xffff) { ++ if (BUSTYPE(si->sb.bustype) == SB_BUS && si->sb.boardtype == 0xffff) { + /* boardtype format is a hex string */ -+ si->boardtype = getintvar(NULL, "boardtype"); ++ si->sb.boardtype = getintvar(NULL, "boardtype"); + + /* backward compatibility for older boardtype string format */ -+ if ((si->boardtype == 0) && (var = getvar(NULL, "boardtype"))) { ++ if ((si->sb.boardtype == 0) && (var = getvar(NULL, "boardtype"))) { + if (!strcmp(var, "bcm94710dev")) -+ si->boardtype = BCM94710D_BOARD; ++ si->sb.boardtype = BCM94710D_BOARD; + else if (!strcmp(var, "bcm94710ap")) -+ si->boardtype = BCM94710AP_BOARD; -+ else if (!strcmp(var, "bcm94310u")) -+ si->boardtype = BCM94310U_BOARD; -+ else if (!strcmp(var, "bu4711")) -+ si->boardtype = BU4711_BOARD; ++ si->sb.boardtype = BCM94710AP_BOARD; + else if (!strcmp(var, "bu4710")) -+ si->boardtype = BU4710_BOARD; ++ si->sb.boardtype = BU4710_BOARD; + else if (!strcmp(var, "bcm94702mn")) -+ si->boardtype = BCM94702MN_BOARD; ++ si->sb.boardtype = BCM94702MN_BOARD; + else if (!strcmp(var, "bcm94710r1")) -+ si->boardtype = BCM94710R1_BOARD; ++ si->sb.boardtype = BCM94710R1_BOARD; + else if (!strcmp(var, "bcm94710r4")) -+ si->boardtype = BCM94710R4_BOARD; ++ si->sb.boardtype = BCM94710R4_BOARD; + else if (!strcmp(var, "bcm94702cpci")) -+ si->boardtype = BCM94702CPCI_BOARD; ++ si->sb.boardtype = BCM94702CPCI_BOARD; + else if (!strcmp(var, "bcm95380_rr")) -+ si->boardtype = BCM95380RR_BOARD; ++ si->sb.boardtype = BCM95380RR_BOARD; + } + } + -+ return (si->boardtype); ++ 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 type of sdh device */ ++/* return bus core type */ +uint -+sb_bus(void *sbh) ++sb_buscoretype(sb_t *sbh) +{ + sb_info_t *si; + + si = SB_INFO(sbh); -+ return (si->bustype); ++ ++ 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(void *sbh, uint coreid[]) ++sb_corelist(sb_t *sbh, uint coreid[]) +{ + sb_info_t *si; + @@ -17476,7 +20440,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* return current register mapping */ +void * -+sb_coreregs(void *sbh) ++sb_coreregs(sb_t *sbh) +{ + sb_info_t *si; + @@ -17489,7 +20453,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* do buffered registers update */ +void -+sb_commit(void *sbh) ++sb_commit(sb_t *sbh) +{ + sb_info_t *si; + uint origidx; @@ -17503,21 +20467,20 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + INTR_OFF(si, intr_val); + + /* switch over to chipcommon core if there is one, else use pci */ -+ if (si->ccrev != NOREV) { ++ 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 (si->pciidx != BADIDX) { ++ } 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((si->ccrev != NOREV) && (si->pciidx != BADIDX)); -+ } ++ } else ++ ASSERT(0); + + /* restore core index */ + sb_setcoreidx(sbh, origidx); @@ -17526,7 +20489,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* reset and re-enable a core */ +void -+sb_core_reset(void *sbh, uint32 bits) ++sb_core_reset(sb_t *sbh, uint32 bits) +{ + sb_info_t *si; + sbconfig_t *sb; @@ -17546,69 +20509,141 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + */ + + /* set reset while enabling the clock and forcing them on throughout the core */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); -+ dummy = R_SBREG(sbh, &sb->sbtmstatelow); -+ -+ if (sb_coreid(sbh) == SB_ILINE100) { -+ bcm_mdelay(50); -+ } else { -+ OSL_DELAY(1); -+ } ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | SBTML_RESET | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); ++ OSL_DELAY(1); + -+ if (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_SERR) { -+ W_SBREG(sbh, &sb->sbtmstatehigh, 0); ++ if (R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_SERR) { ++ W_SBREG(si, &sb->sbtmstatehigh, 0); + } -+ if ((dummy = R_SBREG(sbh, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { -+ AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); ++ 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(sbh, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); -+ dummy = R_SBREG(sbh, &sb->sbtmstatelow); ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_FGC | SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); + OSL_DELAY(1); + + /* leave clock enabled */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | bits)); -+ dummy = R_SBREG(sbh, &sb->sbtmstatelow); ++ W_SBREG(si, &sb->sbtmstatelow, (SBTML_CLK | bits)); ++ dummy = R_SBREG(si, &sb->sbtmstatelow); + OSL_DELAY(1); +} + +void -+sb_core_tofixup(void *sbh) ++sb_core_tofixup(sb_t *sbh) +{ + sb_info_t *si; + sbconfig_t *sb; + + si = SB_INFO(sbh); + -+ if ((si->pciidx == BADIDX) || (si->pcirev >= 5)) ++ 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->bustype) == SB_BUS) { -+ SET_SBREG(sbh, &sb->sbimconfiglow, ++ 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(sbh, &sb->sbimconfiglow, ++ SET_SBREG(si, &sb->sbimconfiglow, + SBIMCL_RTO_MASK | SBIMCL_STO_MASK, + (0x3 << SBIMCL_RTO_SHIFT) | 0x2); + } else { -+ SET_SBREG(sbh, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); ++ 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(void *sbh, uint32 bits) ++sb_core_disable(sb_t *sbh, uint32 bits) +{ + sb_info_t *si; + volatile uint32 dummy; ++ uint32 rej; + sbconfig_t *sb; + + si = SB_INFO(sbh); @@ -17617,60 +20652,67 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + sb = REGS2SB(si->curmap); + + /* if core is already in reset, just return */ -+ if (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_RESET) ++ 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(sbh, &sb->sbtmstatelow) & SBTML_CLK) == 0) ++ if ((R_SBREG(si, &sb->sbtmstatelow) & SBTML_CLK) == 0) + goto disable; + -+ /* set the target reject bit and spin until busy is clear */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | SBTML_REJ)); -+ dummy = R_SBREG(sbh, &sb->sbtmstatelow); ++ /* 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(sbh, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); ++ SPINWAIT((R_SBREG(si, &sb->sbtmstatehigh) & SBTMH_BUSY), 100000); + -+ if (R_SBREG(sbh, &sb->sbidlow) & SBIDL_INIT) { -+ OR_SBREG(sbh, &sb->sbimstate, SBIM_RJ); -+ dummy = R_SBREG(sbh, &sb->sbimstate); ++ 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(sbh, &sb->sbimstate) & SBIM_BY), 100000); ++ SPINWAIT((R_SBREG(si, &sb->sbimstate) & SBIM_BY), 100000); + } + + /* set reset and reject while enabling the clocks */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_FGC | SBTML_CLK | SBTML_REJ | SBTML_RESET)); -+ dummy = R_SBREG(sbh, &sb->sbtmstatelow); ++ 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(sbh, &sb->sbidlow) & SBIDL_INIT) -+ AND_SBREG(sbh, &sb->sbimstate, ~SBIM_RJ); ++ if (R_SBREG(si, &sb->sbidlow) & SBIDL_INIT) ++ AND_SBREG(si, &sb->sbimstate, ~SBIM_RJ); + +disable: + /* leave reset and reject asserted */ -+ W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_REJ | SBTML_RESET)); ++ 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(void *sbh, uint ticks) ++sb_watchdog(sb_t *sbh, uint ticks) +{ + sb_info_t *si = SB_INFO(sbh); + + /* instant NMI */ + switch (si->gpioid) { + case SB_CC: -+ sb_corereg(sbh, si->gpioidx, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); ++ sb_corereg(si, 0, OFFSETOF(chipcregs_t, watchdog), ~0, ticks); + break; + case SB_EXTIF: -+ sb_corereg(sbh, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); ++ sb_corereg(si, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); + break; + } +} + +/* initialize the pcmcia core */ +void -+sb_pcmcia_init(void *sbh) ++sb_pcmcia_init(sb_t *sbh) +{ + sb_info_t *si; + uint8 cor; @@ -17678,7 +20720,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + + /* enable d11 mac interrupts */ -+ if (si->chip == BCM4301_DEVICE_ID) { ++ 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; @@ -17694,11 +20736,10 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* + * Configure the pci core for pci client (NIC) action -+ * and get appropriate dma offset value. + * coremask is the bitvec of cores by index to be enabled. + */ +void -+sb_pci_setup(void *sbh, uint32 *dmaoffset, uint coremask) ++sb_pci_setup(sb_t *sbh, uint coremask) +{ + sb_info_t *si; + sbconfig_t *sb; @@ -17706,17 +20747,16 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + uint32 sbflag; + uint32 w; + uint idx; ++ int reg_val; + + si = SB_INFO(sbh); + -+ if (dmaoffset) -+ *dmaoffset = 0; -+ + /* if not pci bus, we're done */ -+ if (BUSTYPE(si->bustype) != PCI_BUS) ++ if (BUSTYPE(si->sb.bustype) != PCI_BUS) + return; + -+ ASSERT(si->pciidx != BADIDX); ++ ASSERT(PCI(si) || PCIE(si)); ++ ASSERT(si->sb.buscoreidx != BADIDX); + + /* get current core index */ + idx = si->curidx; @@ -17724,45 +20764,51 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + /* we interrupt on this backplane flag number */ + ASSERT(GOODREGS(si->curmap)); + sb = REGS2SB(si->curmap); -+ sbflag = R_SBREG(sbh, &sb->sbtpsflag) & SBTPS_NUM0_MASK; ++ sbflag = R_SBREG(si, &sb->sbtpsflag) & SBTPS_NUM0_MASK; + + /* switch over to pci core */ -+ pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->pciidx); ++ 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 (si->pcirev < 6) { -+ /* set sbintvec bit for our flag number */ -+ OR_SBREG(sbh, &sb->sbintvec, (1 << sbflag)); -+ } else { ++ 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)); + } + -+ /* enable prefetch and bursts for dma big window */ -+ OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); ++ 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); ++ } ++ } + -+ /* enable read multiple for dma big window */ -+ if (si->pcirev >= 11) -+ OR_REG(&pciregs->sbtopci2, SBTOPCI_RC_READMULTI); ++ 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 (si->pcirev < 5) { -+ SET_SBREG(sbh, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, -+ (0x3 << SBIMCL_RTO_SHIFT) | 0x2); -+ sb_commit(sbh); ++ 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); -+ -+ /* use large sb pci dma window */ -+ if (dmaoffset) -+ *dmaoffset = SB_PCI_DMA; +} + +uint32 @@ -17815,7 +20861,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* return the core-type instantiation # of the current core */ +uint -+sb_coreunit(void *sbh) ++sb_coreunit(sb_t *sbh) +{ + sb_info_t *si; + uint idx; @@ -17881,7 +20927,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + } else if (pll_type == PLL_TYPE5) { + return (100000000); + } else -+ ASSERT((pll_type >= PLL_TYPE1) && (pll_type <= PLL_TYPE4)); ++ ASSERT(0); + /* PLL types 3 and 7 use BASE2 (25Mhz) */ + if ((pll_type == PLL_TYPE3) || + (pll_type == PLL_TYPE7)) { @@ -17940,7 +20986,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* returns the current speed the SB is running at */ +uint32 -+sb_clock(void *sbh) ++sb_clock(sb_t *sbh) +{ + sb_info_t *si; + extifregs_t *eir; @@ -17965,8 +21011,14 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + n = R_REG(&cc->clockcontrol_n); + if (pll_type == PLL_TYPE6) + m = R_REG(&cc->clockcontrol_mips); -+ else if ((pll_type == PLL_TYPE3) && (BCMINIT(sb_chip)(sbh) != BCM5365_DEVICE_ID)) -+ m = R_REG(&cc->clockcontrol_m2); ++ 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 { @@ -17974,16 +21026,19 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + return 0; + } + -+ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) { ++ // Added by Chen-I for 5365 ++ if (BCMINIT(sb_chip)(sbh) == BCM5365_DEVICE_ID) ++ { + rate = 100000000; -+ } else { ++ } ++ 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); + @@ -17994,7 +21049,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* change logical "focus" to the gpio core for optimized access */ +void* -+sb_gpiosetcore(void *sbh) ++sb_gpiosetcore(sb_t *sbh) +{ + sb_info_t *si; + @@ -18005,7 +21060,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + +/* mask&set gpiocontrol bits */ +uint32 -+sb_gpiocontrol(void *sbh, uint32 mask, uint32 val) ++sb_gpiocontrol(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ + sb_info_t *si; + uint regoff; @@ -18013,6 +21068,13 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + regoff = 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; ++ } ++ + switch (si->gpioid) { + case SB_CC: + regoff = OFFSETOF(chipcregs_t, gpiocontrol); @@ -18026,12 +21088,12 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + return (0); + } + -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); +} + +/* mask&set gpio output enable bits */ +uint32 -+sb_gpioouten(void *sbh, uint32 mask, uint32 val) ++sb_gpioouten(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ + sb_info_t *si; + uint regoff; @@ -18039,6 +21101,13 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + regoff = 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; ++ } ++ + switch (si->gpioid) { + case SB_CC: + regoff = OFFSETOF(chipcregs_t, gpioouten); @@ -18053,12 +21122,12 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + break; + } + -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); +} + +/* mask&set gpio output bits */ +uint32 -+sb_gpioout(void *sbh, uint32 mask, uint32 val) ++sb_gpioout(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ + sb_info_t *si; + uint regoff; @@ -18066,6 +21135,13 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + regoff = 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; ++ } ++ + switch (si->gpioid) { + case SB_CC: + regoff = OFFSETOF(chipcregs_t, gpioout); @@ -18080,12 +21156,74 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + break; + } + -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++ 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); ++ ++ /* 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); ++ ++ /* 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(void *sbh) ++sb_gpioin(sb_t *sbh) +{ + sb_info_t *si; + uint regoff; @@ -18107,12 +21245,12 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + break; + } + -+ return (sb_corereg(sbh, si->gpioidx, regoff, 0, 0)); ++ return (sb_corereg(si, si->gpioidx, regoff, 0, 0)); +} + +/* mask&set gpio interrupt polarity bits */ +uint32 -+sb_gpiointpolarity(void *sbh, uint32 mask, uint32 val) ++sb_gpiointpolarity(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ + sb_info_t *si; + uint regoff; @@ -18120,6 +21258,13 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + regoff = 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; ++ } ++ + switch (si->gpioid) { + case SB_CC: + regoff = OFFSETOF(chipcregs_t, gpiointpolarity); @@ -18135,12 +21280,12 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + break; + } + -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++ return (sb_corereg(si, si->gpioidx, regoff, mask, val)); +} + +/* mask&set gpio interrupt mask bits */ +uint32 -+sb_gpiointmask(void *sbh, uint32 mask, uint32 val) ++sb_gpiointmask(sb_t *sbh, uint32 mask, uint32 val, uint8 priority) +{ + sb_info_t *si; + uint regoff; @@ -18148,6 +21293,13 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + regoff = 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; ++ } ++ + switch (si->gpioid) { + case SB_CC: + regoff = OFFSETOF(chipcregs_t, gpiointmask); @@ -18163,77 +21315,83 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + break; + } + -+ return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); ++ 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; + -+/* -+ * Return the slow clock source. -+ * Three sources of SLOW CLOCK: LPO, Xtal, PCI -+ */ -+static uint -+sb_slowclk_src(void *sbh) ++ 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; -+ uint32 v; + -+ si = SB_INFO(sbh); + -+ ASSERT(sb_coreid(sbh) == SB_CC); ++ ASSERT(sb_coreid(&si->sb) == SB_CC); + -+ if (si->ccrev < 6) { -+ switch (BUSTYPE(si->bustype)) { -+ case PCMCIA_BUS: return (SCC_SS_XTAL); -+ case PCI_BUS: -+ v = OSL_PCI_READ_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32)); -+ if (v & PCI_CFG_GPIO_SCS) -+ return (SCC_SS_PCI); -+ else -+ return (SCC_SS_XTAL); -+ default: return (SCC_SS_XTAL); -+ } -+ } else if (si->ccrev < 10) { -+ cc = (chipcregs_t*) sb_setcoreidx(sbh, si->curidx); -+ v = R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK; -+ return (v); -+ } else { ++ 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 slowclock min or max frequency. -+ * Three sources of SLOW CLOCK: -+ * 1. On Chip LPO - 32khz or 160khz -+ * 2. On Chip Xtal OSC - 20mhz/4*(divider+1) -+ * 3. External PCI clock - 66mhz/4*(divider+1) -+ */ ++/* return the ILP (slowclock) min or max frequency */ +static uint -+sb_slowclk_freq(void *sbh, bool max) ++sb_slowclk_freq(sb_info_t *si, bool max) +{ -+ sb_info_t *si; + chipcregs_t *cc; + uint32 slowclk; + uint div; + -+ si = SB_INFO(sbh); + -+ ASSERT(sb_coreid(sbh) == SB_CC); ++ ASSERT(sb_coreid(&si->sb) == SB_CC); + -+ cc = (chipcregs_t*) sb_setcoreidx(sbh, si->curidx); ++ cc = (chipcregs_t*) sb_setcoreidx(&si->sb, si->curidx); + -+ /* shouldn't be here unless we've established the chip has dynamic power control */ ++ /* 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(sbh); -+ if (si->ccrev < 6) { ++ 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->ccrev < 10) { -+ div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHF) + 1); ++ } 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) @@ -18244,7 +21402,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + ASSERT(0); + } else { + /* Chipc rev 10 is InstaClock */ -+ div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHF; ++ div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHIFT; + div = 4 * (div + 1); + return (max ? XTALMAXFREQ : (XTALMINFREQ/div)); + } @@ -18252,25 +21410,23 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. +} + +static void -+sb_pwrctl_setdelay(void *sbh, void *chipcregs) ++sb_clkctl_setdelay(sb_info_t *si, void *chipcregs) +{ -+ sb_info_t *si; + chipcregs_t * cc; + uint slowmaxfreq, pll_delay, slowclk; + uint pll_on_delay, fref_sel_delay; + -+ si = SB_INFO(sbh); + 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 power control logic. ++ * since the xtal will also be powered down by dynamic clk control logic. + */ -+ slowclk = sb_slowclk_src(sbh); ++ 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(sbh, (si->ccrev >= 10) ? FALSE : TRUE); ++ 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; @@ -18280,7 +21436,6 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + W_REG(&cc->fref_sel_delay, fref_sel_delay); +} + -+/* set or get slow clock divider */ +int +sb_pwrctl_slowclk(void *sbh, bool set, uint *div) +{ @@ -18293,11 +21448,11 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + si = SB_INFO(sbh); + + /* chipcommon cores prior to rev6 don't support slowclkcontrol */ -+ if (si->ccrev < 6) ++ if (si->sb.ccrev < 6) + return 1; + + /* chipcommon cores rev10 are a whole new ball game */ -+ if (si->ccrev >= 10) ++ if (si->sb.ccrev >= 10) + return 1; + + if (set && ((*div % 4) || (*div < 4))) @@ -18314,10 +21469,10 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + } + + if (set) { -+ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHF)); -+ sb_pwrctl_setdelay(sbh, (void *)cc); ++ 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_SHF) + 1); ++ *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHIFT) + 1); + +done: + sb_setcoreidx(sbh, origidx); @@ -18326,8 +21481,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. +} + +/* initialize power control delay registers */ -+void -+sb_pwrctl_init(void *sbh) ++void sb_clkctl_init(sb_t *sbh) +{ + sb_info_t *si; + uint origidx; @@ -18343,21 +21497,26 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) + goto done; + -+ /* 4317pc does not work with SlowClock less than 5Mhz */ -+ if (BUSTYPE(si->bustype) == PCMCIA_BUS) { -+ if ((si->ccrev >= 6) && (si->ccrev < 10)) -+ SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (SCC_DEF_DIV << SCC_CD_SHF)); -+ } ++ /* 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_pwrctl_setdelay(sbh, (void *)cc); ++ 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_pwrctl_fast_pwrup_delay(void *sbh) ++sb_clkctl_fast_pwrup_delay(sb_t *sbh) +{ + sb_info_t *si; + uint origidx; @@ -18370,9 +21529,6 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + fpdelay = 0; + origidx = si->curidx; + -+ if (BUSTYPE(si->bustype) == SB_BUS) -+ goto done; -+ + INTR_OFF(si, intr_val); + + if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) @@ -18381,7 +21537,7 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) + goto done; + -+ slowminfreq = sb_slowclk_freq(sbh, FALSE); ++ slowminfreq = sb_slowclk_freq(si, FALSE); + fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; + +done: @@ -18389,17 +21545,20 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + 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_pwrctl_xtal(void *sbh, uint what, bool on) ++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->bustype)) { ++ switch (BUSTYPE(si->sb.bustype)) { + + + case PCMCIA_BUS: @@ -18408,6 +21567,10 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + + 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)); @@ -18458,10 +21621,15 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + return (0); +} + -+/* set dynamic power control mode (forceslow, forcefast, dynamic) */ ++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_pwrctl_clk(void *sbh, uint mode) ++sb_clkctl_clk(sb_t *sbh, uint mode) +{ + sb_info_t *si; + uint origidx; @@ -18472,12 +21640,12 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + + si = SB_INFO(sbh); + -+ /* chipcommon cores prior to rev6 don't support slowclkcontrol */ -+ if (si->ccrev < 6) ++ /* 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->ccrev >= 10) ++ if (si->sb.ccrev >= 10) + return (FALSE); + + INTR_OFF(si, intr_val); @@ -18493,20 +21661,12 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + switch (mode) { + case CLK_FAST: /* force fast (pll) clock */ + /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ -+ sb_pwrctl_xtal(sbh, XTAL, ON); ++ sb_clkctl_xtal(&si->sb, XTAL, ON); + + SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); + break; + -+ case CLK_SLOW: /* force slow clock */ -+ if ((BUSTYPE(si->bustype) == SDIO_BUS) || (BUSTYPE(si->bustype) == PCMCIA_BUS)) -+ return (-1); -+ -+ if (si->ccrev >= 6) -+ OR_REG(&cc->slow_clk_ctl, SCC_FS); -+ break; -+ -+ case CLK_DYNAMIC: /* enable dynamic power control */ ++ 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) @@ -18515,8 +21675,11 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + + /* for dynamic control, we have to release our xtal_pu "force on" */ + if (scc & SCC_XC) -+ sb_pwrctl_xtal(sbh, XTAL, OFF); ++ sb_clkctl_xtal(&si->sb, XTAL, OFF); + break; ++ ++ default: ++ ASSERT(0); + } + + /* Is the h/w forcing the use of the fast clk */ @@ -18528,9 +21691,13 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. + 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(void *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) ++sb_register_intr_callback(sb_t *sbh, void *intrsoff_fn, void *intrsrestore_fn, void *intrsenabled_fn, void *intr_arg) +{ + sb_info_t *si; + @@ -18546,9 +21713,331 @@ diff -urN linux.old/drivers/net/hnd/sbutils.c linux.dev/drivers/net/hnd/sbutils. +} + + ++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 -urN 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 2005-08-26 13:44:34.406377232 +0200 ++++ linux.dev/drivers/net/hnd/shared_ksyms.sh 2005-11-07 21:57:07.917590250 +0100 @@ -0,0 +1,21 @@ +#!/bin/sh +# @@ -18572,8 +22061,8 @@ diff -urN linux.old/drivers/net/hnd/shared_ksyms.sh linux.dev/drivers/net/hnd/sh + ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p' +done diff -urN linux.old/drivers/net/wireless/Config.in linux.dev/drivers/net/wireless/Config.in ---- linux.old/drivers/net/wireless/Config.in 2004-11-17 12:54:21.000000000 +0100 -+++ linux.dev/drivers/net/wireless/Config.in 2005-08-26 13:44:34.427374040 +0200 +--- linux.old/drivers/net/wireless/Config.in 2005-11-07 23:12:51.258929250 +0100 ++++ linux.dev/drivers/net/wireless/Config.in 2005-11-07 21:57:07.941591750 +0100 @@ -13,6 +13,7 @@ fi @@ -18584,7 +22073,7 @@ diff -urN linux.old/drivers/net/wireless/Config.in linux.dev/drivers/net/wireles 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/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 2005-08-26 13:44:34.427374040 +0200 ++++ linux.dev/drivers/net/wl/Makefile 2005-11-07 21:57:07.941591750 +0100 @@ -0,0 +1,26 @@ +# +# Makefile for the Broadcom wl driver @@ -18613,8 +22102,8 @@ diff -urN linux.old/drivers/net/wl/Makefile linux.dev/drivers/net/wl/Makefile + +include $(TOPDIR)/Rules.make diff -urN linux.old/drivers/parport/Config.in linux.dev/drivers/parport/Config.in ---- linux.old/drivers/parport/Config.in 2004-02-18 14:36:31.000000000 +0100 -+++ linux.dev/drivers/parport/Config.in 2005-08-26 13:44:34.428373888 +0200 +--- linux.old/drivers/parport/Config.in 2005-11-07 23:12:51.306932250 +0100 ++++ linux.dev/drivers/parport/Config.in 2005-11-07 21:57:07.941591750 +0100 @@ -11,6 +11,7 @@ tristate 'Parallel port support' CONFIG_PARPORT if [ "$CONFIG_PARPORT" != "n" ]; then @@ -18624,8 +22113,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 2004-08-08 01:26:05.000000000 +0200 -+++ linux.dev/drivers/parport/Makefile 2005-08-26 13:44:34.428373888 +0200 +--- linux.old/drivers/parport/Makefile 2005-11-07 23:12:51.318933000 +0100 ++++ linux.dev/drivers/parport/Makefile 2005-11-07 21:57:07.941591750 +0100 @@ -22,6 +22,7 @@ obj-$(CONFIG_PARPORT) += parport.o @@ -18636,7 +22125,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 2005-08-26 13:44:34.429373736 +0200 ++++ linux.dev/drivers/parport/parport_splink.c 2005-11-07 21:57:07.941591750 +0100 @@ -0,0 +1,345 @@ +/* Low-level parallel port routines for the ASUS WL-500g built-in port + * @@ -18984,8 +22473,8 @@ diff -urN linux.old/drivers/parport/parport_splink.c linux.dev/drivers/parport/p +module_exit(parport_splink_cleanup) + diff -urN linux.old/drivers/pcmcia/Makefile linux.dev/drivers/pcmcia/Makefile ---- linux.old/drivers/pcmcia/Makefile 2005-08-26 13:41:42.048579600 +0200 -+++ linux.dev/drivers/pcmcia/Makefile 2005-08-26 13:44:34.430373584 +0200 +--- linux.old/drivers/pcmcia/Makefile 2005-11-07 23:12:51.350935000 +0100 ++++ linux.dev/drivers/pcmcia/Makefile 2005-11-07 21:57:07.941591750 +0100 @@ -74,6 +74,10 @@ au1000_ss-objs-$(CONFIG_MIPS_HYDROGEN3) += au1000_hydrogen3.o au1000_ss-objs-$(CONFIG_MIPS_XXS1500) += au1000_xxs1500.o @@ -19008,7 +22497,7 @@ diff -urN linux.old/drivers/pcmcia/Makefile linux.dev/drivers/pcmcia/Makefile $(LD) $(LD_RFLAG) -r -o $@ $(yenta_socket-objs) diff -urN 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 2005-08-26 13:44:34.432373280 +0200 ++++ linux.dev/drivers/pcmcia/bcm4710_generic.c 2005-11-07 21:57:07.945592000 +0100 @@ -0,0 +1,912 @@ +/* + * @@ -19924,7 +23413,7 @@ diff -urN linux.old/drivers/pcmcia/bcm4710_generic.c linux.dev/drivers/pcmcia/bc +#endif /* defined(CONFIG_PROC_FS) */ diff -urN 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 2005-08-26 13:44:34.433373128 +0200 ++++ linux.dev/drivers/pcmcia/bcm4710_pcmcia.c 2005-11-07 21:57:07.945592000 +0100 @@ -0,0 +1,266 @@ +/* + * BCM4710 specific pcmcia routines. @@ -20194,7 +23683,7 @@ diff -urN linux.old/drivers/pcmcia/bcm4710_pcmcia.c linux.dev/drivers/pcmcia/bcm + diff -urN 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 2005-08-26 13:44:34.433373128 +0200 ++++ linux.dev/drivers/pcmcia/bcm4710pcmcia.h 2005-11-07 21:57:07.945592000 +0100 @@ -0,0 +1,118 @@ +/* + * @@ -20315,8 +23804,8 @@ diff -urN linux.old/drivers/pcmcia/bcm4710pcmcia.h linux.dev/drivers/pcmcia/bcm4 + +#endif /* !defined(_BCM4710PCMCIA_H) */ diff -urN linux.old/include/asm-mips/bootinfo.h linux.dev/include/asm-mips/bootinfo.h ---- linux.old/include/asm-mips/bootinfo.h 2005-08-26 13:41:42.329536888 +0200 -+++ linux.dev/include/asm-mips/bootinfo.h 2005-08-26 13:44:34.447371000 +0200 +--- linux.old/include/asm-mips/bootinfo.h 2005-11-07 23:12:51.434940250 +0100 ++++ linux.dev/include/asm-mips/bootinfo.h 2005-11-07 21:57:07.945592000 +0100 @@ -37,6 +37,7 @@ #define MACH_GROUP_HP_LJ 20 /* Hewlett Packard LaserJet */ #define MACH_GROUP_LASAT 21 @@ -20342,8 +23831,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 2005-01-19 15:10:11.000000000 +0100 -+++ linux.dev/include/asm-mips/cpu.h 2005-08-26 13:44:34.455369784 +0200 +--- linux.old/include/asm-mips/cpu.h 2005-11-07 23:12:51.434940250 +0100 ++++ linux.dev/include/asm-mips/cpu.h 2005-11-07 21:57:07.965593250 +0100 @@ -22,6 +22,11 @@ spec. */ @@ -20393,9 +23882,9 @@ 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 2004-02-18 14:36:32.000000000 +0100 -+++ linux.dev/include/asm-mips/r4kcache.h 2005-08-26 13:44:34.457369480 +0200 -@@ -567,4 +567,17 @@ +--- linux.old/include/asm-mips/r4kcache.h 2005-11-07 23:12:51.438940500 +0100 ++++ linux.dev/include/asm-mips/r4kcache.h 2005-11-07 21:57:08.161605500 +0100 +@@ -658,4 +658,17 @@ cache128_unroll32(addr|ws,Index_Writeback_Inv_SD); } @@ -20414,8 +23903,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 2005-01-19 15:10:12.000000000 +0100 -+++ linux.dev/include/asm-mips/serial.h 2005-08-26 13:44:34.459369176 +0200 +--- linux.old/include/asm-mips/serial.h 2005-11-07 23:12:51.442940750 +0100 ++++ linux.dev/include/asm-mips/serial.h 2005-11-07 21:57:07.993595000 +0100 @@ -223,6 +223,13 @@ #define TXX927_SERIAL_PORT_DEFNS #endif @@ -20439,8 +23928,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 2005-08-26 13:41:42.608494480 +0200 -+++ linux.dev/init/do_mounts.c 2005-08-26 13:44:34.481365832 +0200 +--- linux.old/init/do_mounts.c 2005-11-07 23:12:51.458941750 +0100 ++++ linux.dev/init/do_mounts.c 2005-11-07 21:57:07.993595000 +0100 @@ -254,7 +254,13 @@ { "ftlb", 0x2c08 }, { "ftlc", 0x2c10 },