From 50af40000ac37ef921ebd46f6d641959503ee919 Mon Sep 17 00:00:00 2001 From: nbd Date: Sat, 28 May 2005 09:17:29 +0000 Subject: move package/linux into target/linux, use wbx' new kernel code. support building images with more than one kernel, split kernel module parts off of packages that use their own kernel modules (fuse, shfs, openswan). some cleanup in the image building process in target/. image builder is disabled for now, needs some fixing. git-svn-id: svn://svn.openwrt.org/openwrt/trunk@1085 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../linux/kernel-source/drivers/net/hnd/Config.in | 35 - .../linux/kernel-source/drivers/net/hnd/Makefile | 30 - .../linux/kernel-source/drivers/net/hnd/bcmsrom.c | 711 ------- .../linux/kernel-source/drivers/net/hnd/bcmutils.c | 803 -------- .../linux/kernel-source/drivers/net/hnd/hnddma.c | 841 -------- .../kernel-source/drivers/net/hnd/linux_osl.c | 465 ----- .../linux/kernel-source/drivers/net/hnd/sbutils.c | 2164 -------------------- .../kernel-source/drivers/net/hnd/shared_ksyms.sh | 21 - 8 files changed, 5070 deletions(-) delete mode 100644 openwrt/package/linux/kernel-source/drivers/net/hnd/Config.in delete mode 100644 openwrt/package/linux/kernel-source/drivers/net/hnd/Makefile delete mode 100644 openwrt/package/linux/kernel-source/drivers/net/hnd/bcmsrom.c delete mode 100644 openwrt/package/linux/kernel-source/drivers/net/hnd/bcmutils.c delete mode 100644 openwrt/package/linux/kernel-source/drivers/net/hnd/hnddma.c delete mode 100644 openwrt/package/linux/kernel-source/drivers/net/hnd/linux_osl.c delete mode 100644 openwrt/package/linux/kernel-source/drivers/net/hnd/sbutils.c delete mode 100644 openwrt/package/linux/kernel-source/drivers/net/hnd/shared_ksyms.sh (limited to 'openwrt/package/linux/kernel-source/drivers/net/hnd') diff --git a/openwrt/package/linux/kernel-source/drivers/net/hnd/Config.in b/openwrt/package/linux/kernel-source/drivers/net/hnd/Config.in deleted file mode 100644 index 5ced207f3..000000000 --- a/openwrt/package/linux/kernel-source/drivers/net/hnd/Config.in +++ /dev/null @@ -1,35 +0,0 @@ -# -# Broadcom Home Networking Division (HND) driver configuration -# -# 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. -# - -mainmenu_option next_comment -comment 'Broadcom HND network devices' - tristate 'Broadcom HND network device support' CONFIG_HND $CONFIG_PCI - if [ "$CONFIG_HND" != "n" ]; then - dep_tristate ' Broadcom InsideLine HPNA support' CONFIG_IL $CONFIG_HND - if [ "$CONFIG_IL" != "n" ]; then - bool ' Broadcom BCM42xx support' CONFIG_IL_42XX - bool ' Broadcom BCM47xx support' CONFIG_IL_47XX - int ' LARQ buffer allocation (0 = tiny, 2 = huge)' CONFIG_LARQ_BUF 0 - fi - dep_tristate ' Broadcom 10/100 Ethernet support' CONFIG_ET $CONFIG_HND - if [ "$CONFIG_ET" != "n" ]; then - bool ' Broadcom BCM4413 support' CONFIG_ET_4413 - bool ' Broadcom BCM47xx support' CONFIG_ET_47XX - fi - dep_tristate ' Broadcom BCM43xx 802.11 Wireless support' CONFIG_WL $CONFIG_HND - if [ "$CONFIG_WL" != "n" ]; then - bool ' Access Point Mode Supported' CONFIG_WL_AP - bool ' STA Mode Supported' CONFIG_WL_STA - bool ' OID Interface Supported' CONFIG_WL_OID - fi - fi -endmenu diff --git a/openwrt/package/linux/kernel-source/drivers/net/hnd/Makefile b/openwrt/package/linux/kernel-source/drivers/net/hnd/Makefile deleted file mode 100644 index 5adaa5abe..000000000 --- a/openwrt/package/linux/kernel-source/drivers/net/hnd/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# -# Makefile for Broadcom Home Networking Division (HND) shared driver code -# -# 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$ -# - -O_TARGET := hnd.o - -HND_OBJS := bcmutils.o hnddma.o linux_osl.o sbutils.o bcmsrom.o - -ifneq ($(CONFIG_BCM947XX),y) -HND_OBJS += nvramstubs.o -endif - -export-objs := shared_ksyms.o -obj-y := shared_ksyms.o $(HND_OBJS) -obj-m := $(O_TARGET) - -include $(TOPDIR)/Rules.make - -shared_ksyms.c: shared_ksyms.sh $(HND_OBJS) - sh -e $< $(HND_OBJS) > $@ diff --git a/openwrt/package/linux/kernel-source/drivers/net/hnd/bcmsrom.c b/openwrt/package/linux/kernel-source/drivers/net/hnd/bcmsrom.c deleted file mode 100644 index 8a0f05d95..000000000 --- a/openwrt/package/linux/kernel-source/drivers/net/hnd/bcmsrom.c +++ /dev/null @@ -1,711 +0,0 @@ -/* - * Misc useful routines to access NIC SROM - * - * Copyright 2004, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include /* for sprom content groking */ - -#define VARS_MAX 4096 /* should be reduced */ - -static int initvars_srom_pci(void *curmap, char **vars, int *count); -static int initvars_cis_pcmcia(void *sbh, void *curmap, void *osh, 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 sprom_read_pci(uint16 *sprom, uint byteoff, uint16 *buf, uint nbytes, bool check_crc); - -/* - * Initialize the vars from the right source for this platform. - * Return 0 on success, nonzero on error. - */ -int -srom_var_init(void *sbh, uint bus, void *curmap, void *osh, char **vars, int *count) -{ - if (vars == NULL) - return (0); - - switch (bus) { - case SB_BUS: - /* These two could be asserts ... */ - *vars = NULL; - *count = 0; - return(0); - - case PCI_BUS: - ASSERT(curmap); /* can not be NULL */ - return(initvars_srom_pci(curmap, vars, count)); - - case PCMCIA_BUS: - return(initvars_cis_pcmcia(sbh, curmap, osh, vars, count)); - - - default: - ASSERT(0); - } - return (-1); -} - - -/* support only 16-bit word read from srom */ -int -srom_read(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf) -{ - void *srom; - uint i, off, nw; - - /* check input - 16-bit access only */ - if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) - return 1; - - if (bus == PCI_BUS) { - if (!curmap) - return 1; - srom = (void *)((uint)curmap + PCI_BAR0_SPROM_OFFSET); - if (sprom_read_pci(srom, byteoff, buf, nbytes, FALSE)) - return 1; - } else if (bus == PCMCIA_BUS) { - off = byteoff / 2; - nw = nbytes / 2; - for (i = 0; i < nw; i++) { - if (sprom_read_pcmcia(osh, (uint16)(off + i), (uint16*)(buf + i))) - return 1; - } - } else { - return 1; - } - - return 0; -} - -/* support only 16-bit word write into srom */ -int -srom_write(uint bus, void *curmap, void *osh, uint byteoff, uint nbytes, uint16 *buf) -{ - uint16 *srom; - uint i, off, nw, crc_range; - uint16 image[SPROM_SIZE], *p; - uint8 crc; - volatile uint32 val32; - - /* check input - 16-bit access only */ - if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > (SPROM_SIZE * 2)) - return 1; - - crc_range = ((bus == PCMCIA_BUS) ? SPROM_SIZE : SPROM_CRC_RANGE) * 2; - - /* if changes made inside crc cover range */ - if (byteoff < crc_range) { - nw = (((byteoff + nbytes) > crc_range) ? byteoff + nbytes : crc_range) / 2; - /* read data including entire first 64 words from srom */ - if (srom_read(bus, curmap, osh, 0, nw * 2, image)) - return 1; - /* make changes */ - bcopy((void*)buf, (void*)&image[byteoff / 2], nbytes); - /* calculate crc */ - htol16_buf(image, crc_range); - crc = ~crc8((uint8 *)image, crc_range - 1, CRC8_INIT_VALUE); - ltoh16_buf(image, crc_range); - image[(crc_range / 2) - 1] = (crc << 8) | (image[(crc_range / 2) - 1] & 0xff); - p = image; - off = 0; - } else { - p = buf; - off = byteoff / 2; - nw = nbytes / 2; - } - - if (bus == PCI_BUS) { - srom = (uint16*)((uint)curmap + PCI_BAR0_SPROM_OFFSET); - /* enable writes to the SPROM */ - val32 = OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32)); - val32 |= SPROM_WRITEEN; - OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32); - bcm_mdelay(500); - /* write srom */ - for (i = 0; i < nw; i++) { - W_REG(&srom[off + i], p[i]); - bcm_mdelay(20); - } - /* disable writes to the SPROM */ - OSL_PCI_WRITE_CONFIG(osh, PCI_SPROM_CONTROL, sizeof(uint32), val32 & ~SPROM_WRITEEN); - } else if (bus == PCMCIA_BUS) { - /* enable writes to the SPROM */ - if (sprom_cmd_pcmcia(osh, SROM_WEN)) - return 1; - bcm_mdelay(500); - /* write srom */ - for (i = 0; i < nw; i++) { - sprom_write_pcmcia(osh, (uint16)(off + i), p[i]); - bcm_mdelay(20); - } - /* disable writes to the SPROM */ - if (sprom_cmd_pcmcia(osh, SROM_WDS)) - return 1; - } else { - return 1; - } - - bcm_mdelay(500); - return 0; -} - - -int -srom_parsecis(uint8 *cis, char **vars, int *count) -{ - char eabuf[32]; - char *vp, *base; - uint8 tup, tlen, sromrev = 1; - int i, j; - uint varsize; - bool ag_init = FALSE; - uint16 w; - - ASSERT(vars); - ASSERT(count); - - base = vp = MALLOC(VARS_MAX); - ASSERT(vp); - - i = 0; - do { - tup = cis[i++]; - tlen = cis[i++]; - if ((i + tlen) >= CIS_SIZE) - break; - - switch (tup) { - case CISTPL_MANFID: - vp += sprintf(vp, "manfid=%d", (cis[i + 1] << 8) + cis[i]); - vp++; - vp += sprintf(vp, "prodid=%d", (cis[i + 3] << 8) + cis[i + 2]); - vp++; - break; - - case CISTPL_FUNCE: - if (cis[i] == LAN_NID) { - ASSERT(cis[i + 1] == ETHER_ADDR_LEN); - bcm_ether_ntoa((uchar*)&cis[i + 2], eabuf); - vp += sprintf(vp, "il0macaddr=%s", eabuf); - vp++; - } - break; - - case CISTPL_CFTABLE: - vp += sprintf(vp, "regwindowsz=%d", (cis[i + 7] << 8) | cis[i + 6]); - vp++; - break; - - case CISTPL_BRCM_HNBU: - switch (cis[i]) { - case HNBU_CHIPID: - vp += sprintf(vp, "vendid=%d", (cis[i + 2] << 8) + cis[i + 1]); - vp++; - vp += sprintf(vp, "devid=%d", (cis[i + 4] << 8) + cis[i + 3]); - vp++; - if (tlen == 7) { - vp += sprintf(vp, "chiprev=%d", (cis[i + 6] << 8) + cis[i + 5]); - vp++; - } - break; - - case HNBU_BOARDREV: - vp += sprintf(vp, "boardrev=%d", cis[i + 1]); - vp++; - break; - - case HNBU_AA: - vp += sprintf(vp, "aa0=%d", cis[i + 1]); - vp++; - break; - - case HNBU_AG: - vp += sprintf(vp, "ag0=%d", cis[i + 1]); - vp++; - ag_init = TRUE; - break; - - case HNBU_CC: - 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 */ - for (j = 0; j < 3; j++) { - vp += sprintf(vp, "pa0b%d=%d", j, - (cis[i + (j * 2) + 2] << 8) + cis[i + (j * 2) + 1]); - vp++; - } - vp += sprintf(vp, "pa0itssit=%d", cis[i + 7]); - vp++; - } - break; - - case HNBU_OEM: - 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); - vp++; - break; - case HNBU_LED: - if (cis[i + 1] != 0xff) { - vp += sprintf(vp, "wl0gpio0=%d", cis[i + 1]); - vp++; - } - if (cis[i + 2] != 0xff) { - vp += sprintf(vp, "wl0gpio1=%d", cis[i + 2]); - vp++; - } - if (cis[i + 3] != 0xff) { - vp += sprintf(vp, "wl0gpio2=%d", cis[i + 3]); - vp++; - } - if (cis[i + 4] != 0xff) { - vp += sprintf(vp, "wl0gpio3=%d", cis[i + 4]); - vp++; - } - break; - } - break; - - } - i += tlen; - } while (tup != 0xff); - - /* Set the srom version */ - 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) { - vp += sprintf(vp, "ag0=%d", 0xff); - vp++; - } - - /* final nullbyte terminator */ - *vp++ = '\0'; - varsize = (uint)vp - (uint)base; - - ASSERT(varsize < VARS_MAX); - - if (varsize == VARS_MAX) { - *vars = base; - } else { - vp = MALLOC(varsize); - ASSERT(vp); - bcopy(base, vp, varsize); - MFREE(base, VARS_MAX); - *vars = vp; - } - *count = varsize; - - return (0); -} - - -/* set PCMCIA sprom command register */ -static int -sprom_cmd_pcmcia(void *osh, uint8 cmd) -{ - uint8 status; - uint wait_cnt = 1000; - - /* write sprom command register */ - OSL_PCMCIA_WRITE_ATTR(osh, SROM_CS, &cmd, 1); - - /* wait status */ - while (wait_cnt--) { - OSL_PCMCIA_READ_ATTR(osh, SROM_CS, &status, 1); - if (status & SROM_DONE) - return 0; - } - - return 1; -} - -/* read a word from the PCMCIA srom */ -static int -sprom_read_pcmcia(void *osh, uint16 addr, uint16 *data) -{ - uint8 addr_l, addr_h, data_l, data_h; - - addr_l = (uint8)((addr * 2) & 0xff); - addr_h = (uint8)(((addr * 2) >> 8) & 0xff); - - /* set address */ - OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); - OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); - - /* do read */ - if (sprom_cmd_pcmcia(osh, SROM_READ)) - return 1; - - /* read data */ - OSL_PCMCIA_READ_ATTR(osh, SROM_DATAH, &data_h, 1); - OSL_PCMCIA_READ_ATTR(osh, SROM_DATAL, &data_l, 1); - - *data = (data_h << 8) | data_l; - return 0; -} - -/* write a word to the PCMCIA srom */ -static int -sprom_write_pcmcia(void *osh, uint16 addr, uint16 data) -{ - uint8 addr_l, addr_h, data_l, data_h; - - addr_l = (uint8)((addr * 2) & 0xff); - addr_h = (uint8)(((addr * 2) >> 8) & 0xff); - data_l = (uint8)(data & 0xff); - data_h = (uint8)((data >> 8) & 0xff); - - /* set address */ - OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRH, &addr_h, 1); - OSL_PCMCIA_WRITE_ATTR(osh, SROM_ADDRL, &addr_l, 1); - - /* write data */ - OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAH, &data_h, 1); - OSL_PCMCIA_WRITE_ATTR(osh, SROM_DATAL, &data_l, 1); - - /* do write */ - return sprom_cmd_pcmcia(osh, SROM_WRITE); -} - -/* - * Read in and validate sprom. - * Return 0 on success, nonzero on error. - */ -static int -sprom_read_pci(uint16 *sprom, uint byteoff, uint16 *buf, uint nbytes, bool check_crc) -{ - int off, nw; - uint8 chk8; - int i; - - off = byteoff / 2; - nw = ROUNDUP(nbytes, 2) / 2; - - /* read the sprom */ - for (i = 0; i < nw; i++) - buf[i] = R_REG(&sprom[off + i]); - - if (check_crc) { - /* fixup the endianness so crc8 will pass */ - htol16_buf(buf, nw * 2); - if ((chk8 = crc8((uchar*)buf, nbytes, CRC8_INIT_VALUE)) != CRC8_GOOD_VALUE) - return (1); - /* now correct the endianness of the byte array */ - ltoh16_buf(buf, nw * 2); - } - - return (0); -} - -/* - * Initialize nonvolatile variable table from sprom. - * Return 0 on success, nonzero on error. - */ - -static int -initvars_srom_pci(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; - char *vp, *base; - - if (sprom_read_pci((void *)((uint)curmap + PCI_BAR0_SPROM_OFFSET), 0, b, sizeof (b), TRUE)) - return (-1); - - /* top word of sprom contains version and crc8 */ - sromrev = b[63] & 0xff; - if ((sromrev != 1) && (sromrev != 2)) { - return (-2); - } - - ASSERT(vars); - ASSERT(count); - - base = vp = MALLOC(VARS_MAX); - ASSERT(vp); - - vp += sprintf(vp, "sromrev=%d", sromrev); - vp++; - - if (sromrev >= 2) { - /* New section takes over the 4th hardware function space */ - - /* Word 29 is max power 11a high/low */ - w = b[29]; - vp += sprintf(vp, "pa1himaxpwr=%d", w & 0xff); - vp++; - vp += sprintf(vp, "pa1lomaxpwr=%d", (w >> 8) & 0xff); - vp++; - - /* Words 30-32 set the 11alow pa settings, - * 33-35 are the 11ahigh ones. - */ - for (i = 0; i < 3; i++) { - vp += sprintf(vp, "pa1lob%d=%d", i, b[30 + i]); - vp++; - vp += sprintf(vp, "pa1hib%d=%d", i, b[33 + i]); - vp++; - } - w = b[59]; - if (w == 0) - vp += sprintf(vp, "ccode="); - else - vp += sprintf(vp, "ccode=%c%c", (w >> 8), (w & 0xff)); - vp++; - - } - - /* parameter section of sprom starts at byte offset 72 */ - woff = 72/2; - - /* first 6 bytes are il0macaddr */ - ea.octet[0] = (b[woff] >> 8) & 0xff; - ea.octet[1] = b[woff] & 0xff; - ea.octet[2] = (b[woff+1] >> 8) & 0xff; - ea.octet[3] = b[woff+1] & 0xff; - ea.octet[4] = (b[woff+2] >> 8) & 0xff; - ea.octet[5] = b[woff+2] & 0xff; - woff += ETHER_ADDR_LEN/2 ; - bcm_ether_ntoa((uchar*)&ea, eabuf); - vp += sprintf(vp, "il0macaddr=%s", eabuf); - vp++; - - /* next 6 bytes are et0macaddr */ - ea.octet[0] = (b[woff] >> 8) & 0xff; - ea.octet[1] = b[woff] & 0xff; - ea.octet[2] = (b[woff+1] >> 8) & 0xff; - ea.octet[3] = b[woff+1] & 0xff; - ea.octet[4] = (b[woff+2] >> 8) & 0xff; - ea.octet[5] = b[woff+2] & 0xff; - woff += ETHER_ADDR_LEN/2 ; - bcm_ether_ntoa((uchar*)&ea, eabuf); - vp += sprintf(vp, "et0macaddr=%s", eabuf); - vp++; - - /* next 6 bytes are et1macaddr */ - ea.octet[0] = (b[woff] >> 8) & 0xff; - ea.octet[1] = b[woff] & 0xff; - ea.octet[2] = (b[woff+1] >> 8) & 0xff; - ea.octet[3] = b[woff+1] & 0xff; - ea.octet[4] = (b[woff+2] >> 8) & 0xff; - ea.octet[5] = b[woff+2] & 0xff; - woff += ETHER_ADDR_LEN/2 ; - bcm_ether_ntoa((uchar*)&ea, eabuf); - vp += sprintf(vp, "et1macaddr=%s", eabuf); - vp++; - - /* - * Enet phy settings one or two singles or a dual - * Bits 4-0 : MII address for enet0 (0x1f for not there) - * Bits 9-5 : MII address for enet1 (0x1f for not there) - * Bit 14 : Mdio for enet0 - * Bit 15 : Mdio for enet1 - */ - w = b[woff]; - vp += sprintf(vp, "et0phyaddr=%d", (w & 0x1f)); - vp++; - vp += sprintf(vp, "et1phyaddr=%d", ((w >> 5) & 0x1f)); - vp++; - vp += sprintf(vp, "et0mdcport=%d", ((w >> 14) & 0x1)); - vp++; - vp += sprintf(vp, "et1mdcport=%d", ((w >> 15) & 0x1)); - vp++; - - /* Word 46 has board rev, antennas 0/1 & Country code/control */ - w = b[46]; - vp += sprintf(vp, "boardrev=%d", w & 0xff); - vp++; - - if (sromrev > 1) - vp += sprintf(vp, "cctl=%d", (w >> 8) & 0xf); - else - vp += sprintf(vp, "cc=%d", (w >> 8) & 0xf); - vp++; - - vp += sprintf(vp, "aa0=%d", (w >> 12) & 0x3); - vp++; - - vp += sprintf(vp, "aa1=%d", (w >> 14) & 0x3); - vp++; - - /* Words 47-49 set the (wl) pa settings */ - woff = 47; - - for (i = 0; i < 3; i++) { - vp += sprintf(vp, "pa0b%d=%d", i, b[woff+i]); - vp++; - vp += sprintf(vp, "pa1b%d=%d", i, b[woff+i+6]); - vp++; - } - - /* - * Words 50-51 set the customer-configured wl led behavior. - * 8 bits/gpio pin. High bit: activehi=0, activelo=1; - * LED behavior values defined in wlioctl.h . - */ - w = b[50]; - if ((w != 0) && (w != 0xffff)) { - /* gpio0 */ - vp += sprintf(vp, "wl0gpio0=%d", (w & 0xff)); - vp++; - - /* gpio1 */ - vp += sprintf(vp, "wl0gpio1=%d", (w >> 8) & 0xff); - vp++; - } - w = b[51]; - if ((w != 0) && (w != 0xffff)) { - /* gpio2 */ - vp += sprintf(vp, "wl0gpio2=%d", w & 0xff); - vp++; - - /* gpio3 */ - vp += sprintf(vp, "wl0gpio3=%d", (w >> 8) & 0xff); - vp++; - } - - /* Word 52 is max power 0/1 */ - w = b[52]; - vp += sprintf(vp, "pa0maxpwr=%d", w & 0xff); - vp++; - vp += sprintf(vp, "pa1maxpwr=%d", (w >> 8) & 0xff); - vp++; - - /* Word 56 is idle tssi target 0/1 */ - w = b[56]; - vp += sprintf(vp, "pa0itssit=%d", w & 0xff); - vp++; - vp += sprintf(vp, "pa1itssit=%d", (w >> 8) & 0xff); - vp++; - - /* Word 57 is boardflags, if not programmed make it zero */ - bfl = (uint32)b[57]; - if (bfl == 0xffff) bfl = 0; - if (sromrev > 1) { - /* Word 28 is boardflags2 */ - bfl |= (uint32)b[28] << 16; - } - vp += sprintf(vp, "boardflags=%d", bfl); - vp++; - - /* Word 58 is antenna gain 0/1 */ - w = b[58]; - vp += sprintf(vp, "ag0=%d", w & 0xff); - vp++; - - vp += sprintf(vp, "ag1=%d", (w >> 8) & 0xff); - vp++; - - if (sromrev == 1) { - /* set the oem string */ - vp += sprintf(vp, "oem=%02x%02x%02x%02x%02x%02x%02x%02x", - ((b[59] >> 8) & 0xff), (b[59] & 0xff), - ((b[60] >> 8) & 0xff), (b[60] & 0xff), - ((b[61] >> 8) & 0xff), (b[61] & 0xff), - ((b[62] >> 8) & 0xff), (b[62] & 0xff)); - vp++; - } else { - if (sromrev >= 1){ - /* Word 60 OFDM tx power offset from CCK level */ - /* OFDM Power Offset - opo */ - w = b[60] & 0xff; - if (w == 0xff) - w = 16; - vp += sprintf(vp, "opo=%d", w); - vp++; - } - } - - /* final nullbyte terminator */ - *vp++ = '\0'; - - c = vp - base; - ASSERT(c <= VARS_MAX); - - if (c == VARS_MAX) { - *vars = base; - } else { - vp = MALLOC(c); - ASSERT(vp); - bcopy(base, vp, c); - MFREE(base, VARS_MAX); - *vars = vp; - } - *count = c; - - return (0); -} - -/* - * Read the cis and call parsecis to initialize the vars. - * Return 0 on success, nonzero on error. - */ -static int -initvars_cis_pcmcia(void *sbh, void *curmap, void *osh, char **vars, int *count) -{ - uint8 *cis = NULL; - int rc; - uint data_sz; - - data_sz = (sb_pcmciarev(sbh) == 1) ? (SPROM_SIZE * 2) : CIS_SIZE; - - if ((cis = MALLOC(data_sz)) == NULL) - return (-1); - - if (sb_pcmciarev(sbh) == 1) { - if (srom_read(PCMCIA_BUS, (void *)NULL, osh, 0, data_sz, (uint16 *)cis)) { - MFREE(cis, data_sz); - return (-1); - } - /* fix up endianess for 16-bit data vs 8-bit parsing */ - ltoh16_buf((uint16 *)cis, data_sz); - } else - OSL_PCMCIA_READ_ATTR(osh, 0, cis, data_sz); - - rc = srom_parsecis(cis, vars, count); - - MFREE(cis, data_sz); - - return (rc); -} - diff --git a/openwrt/package/linux/kernel-source/drivers/net/hnd/bcmutils.c b/openwrt/package/linux/kernel-source/drivers/net/hnd/bcmutils.c deleted file mode 100644 index 1b37c511e..000000000 --- a/openwrt/package/linux/kernel-source/drivers/net/hnd/bcmutils.c +++ /dev/null @@ -1,803 +0,0 @@ -/* - * Misc useful OS-independent routines. - * - * Copyright 2004, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * $Id$ - */ - -#include -#include -#include -#include -#include - -unsigned char bcm_ctype[] = { - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 0-7 */ - _BCM_C,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C|_BCM_S,_BCM_C,_BCM_C, /* 8-15 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 16-23 */ - _BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C,_BCM_C, /* 24-31 */ - _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 32-39 */ - _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 40-47 */ - _BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D,_BCM_D, /* 48-55 */ - _BCM_D,_BCM_D,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 56-63 */ - _BCM_P,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U|_BCM_X,_BCM_U, /* 64-71 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 72-79 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 80-87 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 88-95 */ - _BCM_P,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L|_BCM_X,_BCM_L, /* 96-103 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 104-111 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 112-119 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_C, /* 120-127 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ - _BCM_S|_BCM_SP,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 160-175 */ - _BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P,_BCM_P, /* 176-191 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U, /* 192-207 */ - _BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_P,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_U,_BCM_L, /* 208-223 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L, /* 224-239 */ - _BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_P,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L,_BCM_L /* 240-255 */ -}; - -uchar -bcm_toupper(uchar c) -{ - if (bcm_islower(c)) - c -= 'a'-'A'; - return (c); -} - -ulong -bcm_strtoul(char *cp, char **endp, uint base) -{ - ulong result, value; - bool minus; - - minus = FALSE; - - while (bcm_isspace(*cp)) - cp++; - - if (cp[0] == '+') - cp++; - else if (cp[0] == '-') { - minus = TRUE; - cp++; - } - - if (base == 0) { - if (cp[0] == '0') { - if ((cp[1] == 'x') || (cp[1] == 'X')) { - base = 16; - cp = &cp[2]; - } else { - base = 8; - cp = &cp[1]; - } - } else - base = 10; - } else if (base == 16 && (cp[0] == '0') && ((cp[1] == 'x') || (cp[1] == 'X'))) { - cp = &cp[2]; - } - - result = 0; - - while (bcm_isxdigit(*cp) && - (value = bcm_isdigit(*cp) ? *cp-'0' : bcm_toupper(*cp)-'A'+10) < base) { - result = result*base + value; - cp++; - } - - if (minus) - result = (ulong)(result * -1); - - if (endp) - *endp = (char *)cp; - - return (result); -} - -uint -bcm_atoi(char *s) -{ - uint n; - - n = 0; - - while (bcm_isdigit(*s)) - n = (n * 10) + *s++ - '0'; - return (n); -} - -void -deadbeef(char *p, uint len) -{ - static uchar meat[] = { 0xde, 0xad, 0xbe, 0xef }; - - while (len-- > 0) { - *p = meat[((uint)p) & 3]; - p++; - } -} - -/* pretty hex print a contiguous buffer */ -void -prhex(char *msg, uchar *buf, uint nbytes) -{ - char line[256]; - char* p; - uint i; - - if (msg && (msg[0] != '\0')) - printf("%s: ", msg); - - p = line; - for (i = 0; i < nbytes; i++) { - if (i % 16 == 0) { - p += sprintf(p, "%04d: ", i); /* line prefix */ - } - p += sprintf(p, "%02x ", buf[i]); - if (i % 16 == 15) { - printf("%s\n", line); /* flush line */ - p = line; - } - } - - /* flush last partial line */ - if (p != line) - printf("%s\n", line); -} - -/* pretty hex print a pkt buffer chain */ -void -prpkt(char *msg, void *drv, void *p0) -{ - void *p; - - if (msg && (msg[0] != '\0')) - printf("%s: ", msg); - - for (p = p0; p; p = PKTNEXT(drv, p)) - prhex(NULL, PKTDATA(drv, p), PKTLEN(drv, p)); -} - -/* copy a pkt buffer chain into a buffer */ -uint -pktcopy(void *drv, void *p, uint offset, int len, uchar *buf) -{ - uint n, ret = 0; - - if (len < 0) - len = 4096; /* "infinite" */ - - /* skip 'offset' bytes */ - for (; p && offset; p = PKTNEXT(drv, p)) { - if (offset < (uint)PKTLEN(drv, p)) - break; - offset -= PKTLEN(drv, 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); - buf += n; - len -= n; - ret += n; - offset = 0; - } - - return ret; -} - -/* return total length of buffer chain */ -uint -pkttotlen(void *drv, void *p) -{ - uint total; - - total = 0; - for (; p; p = PKTNEXT(drv, p)) - total += PKTLEN(drv, p); - return (total); -} - - -uchar* -bcm_ether_ntoa(char *ea, char *buf) -{ - sprintf(buf,"%02x:%02x:%02x:%02x:%02x:%02x", - (uchar)ea[0]&0xff, (uchar)ea[1]&0xff, (uchar)ea[2]&0xff, - (uchar)ea[3]&0xff, (uchar)ea[4]&0xff, (uchar)ea[5]&0xff); - return (buf); -} - -/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -int -bcm_ether_atoe(char *p, char *ea) -{ - int i = 0; - - for (;;) { - ea[i++] = (char) bcm_strtoul(p, &p, 16); - if (!*p++ || i == 6) - break; - } - - return (i == 6); -} - -/* - * Advance from the current 1-byte tag/1-byte length/variable-length value - * triple, to the next, returning a pointer to the next. - */ -bcm_tlv_t * -bcm_next_tlv(bcm_tlv_t *elt, int *buflen) -{ - int len; - - /* validate current elt */ - if (*buflen < 2) { - return NULL; - } - - len = elt->len; - - /* validate remaining buflen */ - if (*buflen >= (2 + len + 2)) { - elt = (bcm_tlv_t*)(elt->data + len); - *buflen -= (2 + len); - } else { - elt = NULL; - } - - return elt; -} - -/* - * Traverse a string of 1-byte tag/1-byte length/variable-length value - * triples, returning a pointer to the substring whose first element - * matches tag. Stop parsing when we see an element whose ID is greater - * than the target key. - */ -bcm_tlv_t * -bcm_parse_ordered_tlvs(void *buf, int buflen, uint key) -{ - bcm_tlv_t *elt; - int totlen; - - elt = (bcm_tlv_t*)buf; - totlen = buflen; - - /* find tagged parameter */ - while (totlen >= 2) { - uint id = elt->id; - int len = elt->len; - - /* Punt if we start seeing IDs > than target key */ - if (id > key) - return(NULL); - - /* validate remaining totlen */ - if ((id == key) && (totlen >= (len + 2))) - return (elt); - - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); - } - return NULL; -} - - -/* - * Traverse a string of 1-byte tag/1-byte length/variable-length value - * triples, returning a pointer to the substring whose first element - * matches tag - */ -bcm_tlv_t * -bcm_parse_tlvs(void *buf, int buflen, uint key) -{ - bcm_tlv_t *elt; - int totlen; - - elt = (bcm_tlv_t*)buf; - totlen = buflen; - - /* find tagged parameter */ - while (totlen >= 2) { - int len = elt->len; - - /* validate remaining totlen */ - if ((elt->id == key) && (totlen >= (len + 2))) - return (elt); - - elt = (bcm_tlv_t*)((uint8*)elt + (len + 2)); - totlen -= (len + 2); - } - - return NULL; -} - -void -pktq_init(struct pktq *q, uint maxlen, bool priority) -{ - q->head = q->tail = NULL; - q->priority = priority; - q->maxlen = maxlen; - q->len = 0; -} - -bool -pktenq(struct pktq *q, void *p, bool lifo) -{ - void *next, *prev; - - /* Queue is full */ - if (q->len >= q->maxlen) - return FALSE; - - /* Queueing chains not allowed */ - ASSERT(PKTLINK(p) == NULL); - - /* Queue is empty */ - if (q->tail == NULL) { - ASSERT(q->head == NULL); - q->head = q->tail = p; - } - - /* Insert at head or tail */ - else if (q->priority == FALSE) { - /* Insert at head (LIFO) */ - if (lifo) { - PKTSETLINK(p, q->head); - q->head = p; - } - /* Insert at tail (FIFO) */ - else { - ASSERT(PKTLINK(q->tail) == NULL); - PKTSETLINK(q->tail, p); - PKTSETLINK(p, NULL); - q->tail = p; - } - } - - /* Insert by priority */ - else { - ASSERT(q->head); - ASSERT(q->tail); - /* Shortcut to insertion at tail */ - if (PKTPRIO(p) < PKTPRIO(q->tail) || - (!lifo && PKTPRIO(p) <= PKTPRIO(q->tail))) { - prev = q->tail; - next = NULL; - } - /* Insert at head or in the middle */ - else { - prev = NULL; - next = q->head; - } - /* Walk the queue */ - for (; next; prev = next, next = PKTLINK(next)) { - /* Priority queue invariant */ - ASSERT(!prev || PKTPRIO(prev) >= PKTPRIO(next)); - /* Insert at head of string of packets of same priority (LIFO) */ - if (lifo) { - if (PKTPRIO(p) >= PKTPRIO(next)) - break; - } - /* Insert at tail of string of packets of same priority (FIFO) */ - else { - if (PKTPRIO(p) > PKTPRIO(next)) - break; - } - } - /* Insert at tail */ - if (next == NULL) { - ASSERT(PKTLINK(q->tail) == NULL); - PKTSETLINK(q->tail, p); - PKTSETLINK(p, NULL); - q->tail = p; - } - /* Insert in the middle */ - else if (prev) { - PKTSETLINK(prev, p); - PKTSETLINK(p, next); - } - /* Insert at head */ - else { - PKTSETLINK(p, q->head); - q->head = p; - } - } - - /* List invariants after insertion */ - ASSERT(q->head); - ASSERT(PKTLINK(q->tail) == NULL); - - q->len++; - return TRUE; -} - -void* -pktdeq(struct pktq *q) -{ - void *p; - - if ((p = q->head)) { - ASSERT(q->tail); - q->head = PKTLINK(p); - PKTSETLINK(p, NULL); - q->len--; - if (q->head == NULL) - q->tail = NULL; - } - else { - ASSERT(q->tail == NULL); - } - - return (p); -} - -/******************************************************************************* - * crc8 - * - * Computes a crc8 over the input data using the polynomial: - * - * x^8 + x^7 +x^6 + x^4 + x^2 + 1 - * - * The caller provides the initial value (either CRC8_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC8_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - ******************************************************************************/ - -static uint8 crc8_table[256] = { - 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, - 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, - 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, - 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, - 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, - 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, - 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, - 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, - 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, - 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, - 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, - 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, - 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, - 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, - 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, - 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, - 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, - 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, - 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, - 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, - 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, - 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, - 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, - 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, - 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, - 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, - 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, - 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, - 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, - 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, - 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, - 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F -}; - -/* - * Search the name=value vars for a specific one and return its value. - * Returns NULL if not found. - */ -char* -getvar(char *vars, char *name) -{ - char *s; - int len; - - len = strlen(name); - - /* first look in vars[] */ - for (s = vars; s && *s; ) { - if ((bcmp(s, name, len) == 0) && (s[len] == '=')) - return (&s[len+1]); - - while (*s++) - ; - } - - /* then query nvram */ - return (nvram_get(name)); -} - -/* - * Search the vars for a specific one and return its value as - * an integer. Returns 0 if not found. - */ -int -getintvar(char *vars, char *name) -{ - char *val; - - if ((val = getvar(vars, name)) == NULL) - return (0); - - return (bcm_strtoul(val, NULL, 0)); -} - -/* return pointer to location of substring 'needle' in 'haystack' */ -char* -bcmstrstr(char *haystack, char *needle) -{ - int len, nlen; - int i; - - if ((haystack == NULL) || (needle == NULL)) - return (haystack); - - nlen = strlen(needle); - len = strlen(haystack) - nlen + 1; - - for (i = 0; i < len; i++) - if (bcmp(needle, &haystack[i], nlen) == 0) - return (&haystack[i]); - return (NULL); -} - -void -bcm_mdelay(uint ms) -{ - uint i; - - for (i = 0; i < ms; i++) { - OSL_DELAY(1000); - } -} - -#define CRC_INNER_LOOP(n, c, x) \ - (c) = ((c) >> 8) ^ crc##n##_table[((c) ^ (x)) & 0xff] - -uint8 -crc8( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint8 crc /* either CRC8_INIT_VALUE or previous return value */ -) -{ - /* hard code the crc loop instead of using CRC_INNER_LOOP macro - * to avoid the undefined and unnecessary (uint8 >> 8) operation. */ - while (nbytes-- > 0) - crc = crc8_table[(crc ^ *pdata++) & 0xff]; - - return crc; -} - -/******************************************************************************* - * crc16 - * - * Computes a crc16 over the input data using the polynomial: - * - * x^16 + x^12 +x^5 + 1 - * - * The caller provides the initial value (either CRC16_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC16_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - ******************************************************************************/ - -static uint16 crc16_table[256] = { - 0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF, - 0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7, - 0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E, - 0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876, - 0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD, - 0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5, - 0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C, - 0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974, - 0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB, - 0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3, - 0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A, - 0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72, - 0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9, - 0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1, - 0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738, - 0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70, - 0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7, - 0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF, - 0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036, - 0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E, - 0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5, - 0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD, - 0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134, - 0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C, - 0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3, - 0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB, - 0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232, - 0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A, - 0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1, - 0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9, - 0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330, - 0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78 -}; - -uint16 -crc16( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint16 crc /* either CRC16_INIT_VALUE or previous return value */ -) -{ - while (nbytes-- > 0) - CRC_INNER_LOOP(16, crc, *pdata++); - return crc; -} - -static uint32 crc32_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; - -uint32 -crc32( - uint8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - uint32 crc /* either CRC32_INIT_VALUE or previous return value */ -) -{ - uint8 *pend; -#ifdef __mips__ - uint8 tmp[4]; - ulong *tptr = (ulong *)tmp; - - /* in case the beginning of the buffer isn't aligned */ - pend = (uint8 *)((uint)(pdata + 3) & 0xfffffffc); - nbytes -= (pend - pdata); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); - - /* handle bulk of data as 32-bit words */ - pend = pdata + (nbytes & 0xfffffffc); - while (pdata < pend) { - *tptr = (*((ulong *)pdata))++; - CRC_INNER_LOOP(32, crc, tmp[0]); - CRC_INNER_LOOP(32, crc, tmp[1]); - CRC_INNER_LOOP(32, crc, tmp[2]); - CRC_INNER_LOOP(32, crc, tmp[3]); - } - - /* 1-3 bytes at end of buffer */ - pend = pdata + (nbytes & 0x03); - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#else - pend = pdata + nbytes; - while (pdata < pend) - CRC_INNER_LOOP(32, crc, *pdata++); -#endif - - return crc; -} - -#ifdef notdef -#define CLEN 1499 -#define CBUFSIZ (CLEN+4) -#define CNBUFS 5 - -void testcrc32(void) -{ - uint j,k,l; - uint8 *buf; - uint len[CNBUFS]; - uint32 crcr; - uint32 crc32tv[CNBUFS] = - {0xd2cb1faa, 0xd385c8fa, 0xf5b4f3f3, 0x55789e20, 0x00343110}; - - ASSERT((buf = MALLOC(CBUFSIZ*CNBUFS)) != NULL); - - /* step through all possible alignments */ - for (l=0;l<=4;l++) { - for (j=0; j -#include -#include -#include - -struct dma_info; /* forward declaration */ -#define di_t struct dma_info -#include - -/* debug/trace */ -#define DMA_ERROR(args) -#define DMA_TRACE(args) - -/* default dma message level(if input msg_level pointer is null in dma_attach()) */ -static uint dma_msg_level = 0; - -#define MAXNAMEL 8 -#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 *dev; /* device handle */ - dmaregs_t *regs; /* dma engine registers */ - - dmadd_t *txd; /* pointer to chip-specific tx descriptor ring */ - uint txin; /* index of next descriptor to reclaim */ - uint txout; /* index of next descriptor to post */ - uint txavail; /* # free tx descriptors */ - void *txp[MAXDD]; /* parallel array of pointers to packets */ - ulong txdpa; /* physical address of descriptor ring */ - uint txdalign; /* #bytes added to alloc'd mem to align txd */ - - dmadd_t *rxd; /* pointer to chip-specific rx descriptor ring */ - uint rxin; /* index of next descriptor to reclaim */ - uint rxout; /* index of next descriptor to post */ - void *rxp[MAXDD]; /* parallel array of pointers to packets */ - ulong rxdpa; /* physical address of descriptor ring */ - uint rxdalign; /* #bytes added to alloc'd mem to align rxd */ - - /* 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 */ -} dma_info_t; - -/* descriptor bumping macros */ -#define TXD(x) ((x) & (di->ntxd - 1)) -#define RXD(x) ((x) & (di->nrxd - 1)) -#define NEXTTXD(i) TXD(i + 1) -#define PREVTXD(i) TXD(i - 1) -#define NEXTRXD(i) RXD(i + 1) -#define NTXDACTIVE(h, t) TXD(t - h) -#define NRXDACTIVE(h, t) RXD(t - h) - -/* macros to convert between byte offsets and indexes */ -#define B2I(bytes) ((bytes) / sizeof (dmadd_t)) -#define I2B(index) ((index) * sizeof (dmadd_t)) - -void* -dma_attach(void *drv, void *dev, char *name, dmaregs_t *regs, uint ntxd, uint nrxd, - uint rxbufsize, uint nrxpost, uint rxoffset, uint ddoffset, uint dataoffset, uint *msg_level) -{ - dma_info_t *di; - void *va; - - ASSERT(ntxd <= MAXDD); - ASSERT(nrxd <= MAXDD); - - /* allocate private info structure */ - if ((di = MALLOC(sizeof (dma_info_t))) == NULL) - return (NULL); - bzero((char*)di, sizeof (dma_info_t)); - - /* set message level */ - di->msg_level = msg_level ? msg_level : &dma_msg_level; - - DMA_TRACE(("%s: dma_attach: drv 0x%x dev 0x%x regs 0x%x ntxd %d nrxd %d rxbufsize %d nrxpost %d rxoffset %d ddoffset 0x%x dataoffset 0x%x\n", name, (uint)drv, (uint)dev, (uint)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->dev = dev; - di->regs = regs; - - /* allocate transmit descriptor ring */ - if (ntxd) { - if ((va = DMA_ALLOC_CONSISTENT(dev, (DMAMAXRINGSZ + DMARINGALIGN), &di->txdpa)) == NULL) - goto fail; - di->txd = (dmadd_t*) ROUNDUP(va, DMARINGALIGN); - di->txdalign = ((uint)di->txd - (uint)va); - di->txdpa = di->txdpa + di->txdalign; - ASSERT(ISALIGNED(di->txd, DMARINGALIGN)); - } - - /* allocate receive descriptor ring */ - if (nrxd) { - if ((va = DMA_ALLOC_CONSISTENT(dev, (DMAMAXRINGSZ + DMARINGALIGN), &di->rxdpa)) == NULL) - goto fail; - di->rxd = (dmadd_t*) ROUNDUP(va, DMARINGALIGN); - di->rxdalign = ((uint)di->rxd - (uint)va); - di->rxdpa = di->rxdpa + di->rxdalign; - ASSERT(ISALIGNED(di->rxd, DMARINGALIGN)); - } - - /* save tunables */ - di->ntxd = ntxd; - di->nrxd = nrxd; - di->rxbufsize = rxbufsize; - di->nrxpost = nrxpost; - di->rxoffset = rxoffset; - di->ddoffset = ddoffset; - di->dataoffset = dataoffset; - - return ((void*)di); - -fail: - dma_detach((void*)di); - return (NULL); -} - -/* may be called with core in reset */ -void -dma_detach(dma_info_t *di) -{ - if (di == NULL) - return; - - DMA_TRACE(("%s: dma_detach\n", di->name)); - - /* shouldn't be here if descriptors are unreclaimed */ - ASSERT(di->txin == di->txout); - ASSERT(di->rxin == di->rxout); - - /* free dma descriptor rings */ - if (di->txd) - DMA_FREE_CONSISTENT(di->dev, (void *)((uint)di->txd - di->txdalign), (DMAMAXRINGSZ + DMARINGALIGN), di->txdpa); - if (di->rxd) - DMA_FREE_CONSISTENT(di->dev, (void *)((uint)di->rxd - di->rxdalign), (DMAMAXRINGSZ + DMARINGALIGN), di->rxdpa); - - /* free our private info structure */ - MFREE((void*)di, sizeof (dma_info_t)); -} - - -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); -} - -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)); - } -} - -void -dma_txinit(dma_info_t *di) -{ - DMA_TRACE(("%s: dma_txinit\n", di->name)); - - di->txin = di->txout = 0; - di->txavail = di->ntxd - 1; - - /* clear tx descriptor ring */ - 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)); -} - -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)); -} - -void -dma_txsuspend(dma_info_t *di) -{ - DMA_TRACE(("%s: dma_txsuspend\n", di->name)); - OR_REG(&di->regs->xmtcontrol, XC_SE); -} - -void -dma_txresume(dma_info_t *di) -{ - DMA_TRACE(("%s: dma_txresume\n", di->name)); - AND_REG(&di->regs->xmtcontrol, ~XC_SE); -} - -bool -dma_txsuspended(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; - - OSL_DELAY(2); - return ((R_REG(&di->regs->xmtstatus) & XS_XS_MASK) == XS_XS_IDLE); -} - -bool -dma_txstopped(dma_info_t *di) -{ - return ((R_REG(&di->regs->xmtstatus) & 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); -} - -void -dma_fifoloopbackenable(dma_info_t *di) -{ - DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); - OR_REG(&di->regs->xmtcontrol, XC_LE); -} - -void -dma_rxinit(dma_info_t *di) -{ - DMA_TRACE(("%s: dma_rxinit\n", di->name)); - - di->rxin = di->rxout = 0; - - /* clear rx descriptor ring */ - BZERO_SM((void*)di->rxd, (di->nrxd * sizeof (dmadd_t))); - - dma_rxenable(di); - W_REG(&di->regs->rcvaddr, (di->rxdpa + di->ddoffset)); -} - -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)); -} - -bool -dma_rxenabled(dma_info_t *di) -{ - 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->dev, 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; - - /* 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 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) ((uint)(x) & ~4095) - -/* - * Just like above except go through the extra effort of splitting - * buffers that cross 4Kbyte boundaries into multiple tx descriptors. - */ -int -dma_tx(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 = 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->dev, start, len, DMA_TX, p); - - /* 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 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 */ -void* -dma_rx(dma_info_t *di) -{ - void *p; - uint len; - int skiplen = 0; - - while ((p = dma_getnextrxp(di, FALSE))) { - /* skip giant packets which span multiple rx descriptors */ - if (skiplen > 0) { - skiplen -= di->rxbufsize; - if (skiplen < 0) - skiplen = 0; - PKTFREE(di->drv, p, FALSE); - continue; - } - - len = ltoh16(*(uint16*)(PKTDATA(di->drv, p))); - DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); - - /* bad frame length check */ - if (len > (di->rxbufsize - di->rxoffset)) { - DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); - if (len > 0) - skiplen = len - (di->rxbufsize - di->rxoffset); - PKTFREE(di->drv, p, FALSE); - di->hnddma.rxgiants++; - continue; - } - - /* set actual length */ - PKTSETLEN(di->drv, p, (di->rxoffset + len)); - - break; - } - - return (p); -} - -/* post receive buffers */ -void -dma_rxfill(dma_info_t *di) -{ - void *p; - uint rxin, rxout; - uint ctrl; - uint n; - uint i; - uint32 pa; - uint rxbufsize; - - /* - * Determine how many receive buffers we're lacking - * from the full complement, allocate, initialize, - * and post them, then update the chip rx lastdscr. - */ - - rxin = di->rxin; - rxout = di->rxout; - rxbufsize = di->rxbufsize; - - n = di->nrxpost - NRXDACTIVE(rxin, rxout); - - DMA_TRACE(("%s: dma_rxfill: post %d\n", di->name, n)); - - for (i = 0; i < n; i++) { - if ((p = PKTGET(di->drv, 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; - - pa = (uint32) DMA_MAP(di->dev, PKTDATA(di->drv, p), rxbufsize, DMA_RX, p); - ASSERT(ISALIGNED(pa, 4)); - - /* 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; - - /* init the rx descriptor */ - W_SM(&di->rxd[rxout].ctrl, BUS_SWAP32(ctrl)); - W_SM(&di->rxd[rxout].addr, BUS_SWAP32(pa + di->dataoffset)); - - rxout = NEXTRXD(rxout); - } - - di->rxout = rxout; - - /* update the chip lastdscr pointer */ - W_REG(&di->regs->rcvptr, I2B(rxout)); -} - -void -dma_txreclaim(dma_info_t *di, bool forceall) -{ - void *p; - - DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, forceall ? "all" : "")); - - while ((p = dma_getnexttxp(di, forceall))) - PKTFREE(di->drv, p, TRUE); -} - -/* - * Reclaim next completed txd (txds if using chained buffers) and - * return associated packet. - * If 'force' is true, reclaim txd(s) and return associated packet - * regardless of the value of the hardware "curr" pointer. - */ -void* -dma_getnexttxp(dma_info_t *di, bool forceall) -{ - 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->dev, (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; - } - - 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); - - for (i = di->txin; i != end; i = NEXTTXD(i)) - if (di->txp[i]) - return (di->txp[i]); - - return (NULL); -} - -void -dma_rxreclaim(dma_info_t *di) -{ - void *p; - - DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); - - while ((p = dma_getnextrxp(di, TRUE))) - PKTFREE(di->drv, 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)); - - 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))) - 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->dev, (BUS_SWAP32(R_SM(&di->rxd[i].addr)) - di->dataoffset), - di->rxbufsize, DMA_RX, rxp); - W_SM(&di->rxd[i].addr, 0xdeadbeef); - - di->rxin = NEXTRXD(i); - - return (rxp); -} - -char* -dma_dumptx(dma_info_t *di, char *buf) -{ - buf += sprintf(buf, "txd 0x%lx txdpa 0x%lx txp 0x%lx txin %d txout %d txavail %d\n", - (ulong)di->txd, di->txdpa, (ulong)di->txp, di->txin, di->txout, di->txavail); - buf += sprintf(buf, "xmtcontrol 0x%x xmtaddr 0x%x xmtptr 0x%x xmtstatus 0x%x\n", - R_REG(&di->regs->xmtcontrol), - R_REG(&di->regs->xmtaddr), - R_REG(&di->regs->xmtptr), - R_REG(&di->regs->xmtstatus)); - return (buf); -} - -char* -dma_dumprx(dma_info_t *di, char *buf) -{ - buf += sprintf(buf, "rxd 0x%lx rxdpa 0x%lx rxp 0x%lx rxin %d rxout %d\n", - (ulong)di->rxd, di->rxdpa, (ulong)di->rxp, di->rxin, di->rxout); - buf += sprintf(buf, "rcvcontrol 0x%x rcvaddr 0x%x rcvptr 0x%x rcvstatus 0x%x\n", - R_REG(&di->regs->rcvcontrol), - R_REG(&di->regs->rcvaddr), - R_REG(&di->regs->rcvptr), - R_REG(&di->regs->rcvstatus)); - return (buf); -} - -char* -dma_dump(dma_info_t *di, char *buf) -{ - buf = dma_dumptx(di, buf); - buf = dma_dumprx(di, buf); - return (buf); -} - -uint -dma_getvar(dma_info_t *di, char *name) -{ - if (!strcmp(name, "&txavail")) - return ((uint) &di->txavail); - else { - ASSERT(0); - } - return (0); -} - -void -dma_txblock(dma_info_t *di) -{ - di->txavail = 0; -} - -void -dma_txunblock(dma_info_t *di) -{ - di->txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -} - -uint -dma_txactive(dma_info_t *di) -{ - return (NTXDACTIVE(di->txin, di->txout)); -} - -/* - * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). - */ -void -dma_txrotate(di_t *di) -{ - uint ad; - uint nactive; - uint rot; - uint old, new; - uint32 w; - uint first, last; - - ASSERT(dma_txsuspended(di)); - - nactive = dma_txactive(di); - ad = B2I((R_REG(&di->regs->xmtstatus) & XS_AD_MASK) >> XS_AD_SHIFT); - 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->txd[old].ctrl) & ~CTRL_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)); - - /* zap the old tx dma descriptor address field */ - W_SM(&di->txd[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->regs->xmtptr, I2B(di->txout)); -} diff --git a/openwrt/package/linux/kernel-source/drivers/net/hnd/linux_osl.c b/openwrt/package/linux/kernel-source/drivers/net/hnd/linux_osl.c deleted file mode 100644 index 575b046fb..000000000 --- a/openwrt/package/linux/kernel-source/drivers/net/hnd/linux_osl.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * Linux OS Independent Layer - * - * 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$ - */ - -#define LINUX_OSL - -#include -#include -#include -#include -#include -#include -#ifdef mips -#include -#endif -#include - -#define PCI_CFG_RETRY 10 - -void* -osl_pktget(void *drv, uint len, bool send) -{ - struct sk_buff *skb; - - if ((skb = dev_alloc_skb(len)) == NULL) - return (NULL); - - skb_put(skb, len); - - /* ensure the cookie field is cleared */ - PKTSETCOOKIE(skb, NULL); - - return ((void*) skb); -} - -void -osl_pktfree(void *p) -{ - struct sk_buff *skb, *nskb; - - skb = (struct sk_buff*) p; - - /* perversion: we use skb->next to chain multi-skb packets */ - while (skb) { - nskb = skb->next; - skb->next = NULL; - if (skb->destructor) { - /* cannot kfree_skb() on hard IRQ (net/core/skbuff.c) if destructor exists */ - dev_kfree_skb_any(skb); - } else { - /* can free immediately (even in_irq()) if destructor does not exist */ - dev_kfree_skb(skb); - } - skb = nskb; - } -} - -uint32 -osl_pci_read_config(void *loc, uint offset, uint size) -{ - struct pci_dev *pdev; - uint val; - uint retry=PCI_CFG_RETRY; - - /* only 4byte access supported */ - ASSERT(size == 4); - - pdev = (struct pci_dev*)loc; - do { - pci_read_config_dword(pdev, offset, &val); - if (val != 0xffffffff) - break; - } while (retry--); - - - return (val); -} - -void -osl_pci_write_config(void *loc, uint offset, uint size, uint val) -{ - struct pci_dev *pdev; - uint retry=PCI_CFG_RETRY; - - /* only 4byte access supported */ - ASSERT(size == 4); - - pdev = (struct pci_dev*)loc; - - do { - pci_write_config_dword(pdev, offset, val); - if (offset!=PCI_BAR0_WIN) - break; - if (osl_pci_read_config(loc,offset,size) == val) - break; - } while (retry--); - -} - -static void -osl_pcmcia_attr(void *osh, uint offset, char *buf, int size, bool write) -{ -} - -void -osl_pcmcia_read_attr(void *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_attr(osh, offset, (char *) buf, size, TRUE); -} - -#if defined(BINOSL) - -void -osl_assert(char *exp, char *file, int line) -{ - char tempbuf[255]; - - sprintf(tempbuf, "assertion \"%s\" failed: file \"%s\", line %d\n", exp, file, line); - panic(tempbuf); -} - - - -void* -osl_malloc(uint size) -{ - return (kmalloc(size, GFP_ATOMIC)); -} - -void -osl_mfree(void *addr, uint size) -{ - kfree(addr); -} - -uint -osl_malloced(void) -{ -#ifdef MODULE - return malloced; -#else - return 0; -#endif -} - -#endif /* defined(BCMDBG) || defined(BINOSL) */ - -/* - * BINOSL selects the slightly slower function-call-based binary compatible osl. - */ -#ifdef BINOSL - -int -osl_printf(const char *format, ...) -{ - va_list args; - char buf[1024]; - int len; - - /* sprintf into a local buffer because there *is* no "vprintk()".. */ - va_start(args, format); - len = vsprintf(buf, format, args); - va_end(args); - - if (len > sizeof (buf)) { - printk("osl_printf: buffer overrun\n"); - return (0); - } - - return (printk(buf)); -} - -int -osl_sprintf(char *buf, const char *format, ...) -{ - va_list args; - int rc; - - va_start(args, format); - rc = vsprintf(buf, format, args); - va_end(args); - return (rc); -} - -int -osl_strcmp(const char *s1, const char *s2) -{ - return (strcmp(s1, s2)); -} - -int -osl_strncmp(const char *s1, const char *s2, uint n) -{ - return (strncmp(s1, s2, n)); -} - -int -osl_strlen(char *s) -{ - return (strlen(s)); -} - -char* -osl_strcpy(char *d, const char *s) -{ - return (strcpy(d, s)); -} - -char* -osl_strncpy(char *d, const char *s, uint n) -{ - return (strncpy(d, s, n)); -} - -void -bcopy(const void *src, void *dst, int len) -{ - memcpy(dst, src, len); -} - -int -bcmp(const void *b1, const void *b2, int len) -{ - return (memcmp(b1, b2, len)); -} - -void -bzero(void *b, int len) -{ - memset(b, '\0', len); -} - -uint32 -osl_readl(volatile uint32 *r) -{ - return (readl(r)); -} - -uint16 -osl_readw(volatile uint16 *r) -{ - return (readw(r)); -} - -uint8 -osl_readb(volatile uint8 *r) -{ - return (readb(r)); -} - -void -osl_writel(uint32 v, volatile uint32 *r) -{ - writel(v, r); -} - -void -osl_writew(uint16 v, volatile uint16 *r) -{ - writew(v, r); -} - -void -osl_writeb(uint8 v, volatile uint8 *r) -{ - writeb(v, r); -} - -void * -osl_uncached(void *va) -{ -#ifdef mips - return ((void*)KSEG1ADDR(va)); -#else - return ((void*)va); -#endif -} - -uint -osl_getcycles(void) -{ - uint cycles; - -#if defined(mips) - cycles = read_c0_count() * 2; -#elif defined(__i386__) - rdtscl(cycles); -#else - cycles = 0; -#endif - return cycles; -} - -void * -osl_reg_map(uint32 pa, uint size) -{ - return (ioremap_nocache((unsigned long)pa, (unsigned long)size)); -} - -void -osl_reg_unmap(void *va) -{ - iounmap(va); -} - -int -osl_busprobe(uint32 *val, uint32 addr) -{ -#ifdef mips - return get_dbe(*val, (uint32*)addr); -#else - *val = readl(addr); - return 0; -#endif -} - -void* -osl_dma_alloc_consistent(void *dev, uint size, ulong *pap) -{ - return (pci_alloc_consistent((struct pci_dev*)dev, size, (dma_addr_t*)pap)); -} - -void -osl_dma_free_consistent(void *dev, void *va, uint size, ulong pa) -{ - pci_free_consistent((struct pci_dev*)dev, size, va, (dma_addr_t)pa); -} - -uint -osl_dma_map(void *dev, void *va, uint size, int direction) -{ - int dir; - - dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; - return (pci_map_single(dev, va, size, dir)); -} - -void -osl_dma_unmap(void *dev, uint pa, uint size, int direction) -{ - int dir; - - dir = (direction == DMA_TX)? PCI_DMA_TODEVICE: PCI_DMA_FROMDEVICE; - pci_unmap_single(dev, (uint32)pa, size, dir); -} - -void -osl_delay(uint usec) -{ - udelay(usec); -} - -uchar* -osl_pktdata(void *drv, void *skb) -{ - return (((struct sk_buff*)skb)->data); -} - -uint -osl_pktlen(void *drv, void *skb) -{ - return (((struct sk_buff*)skb)->len); -} - -uint -osl_pktheadroom(void *drv, void *skb) -{ - return (uint) skb_headroom((struct sk_buff *) skb); -} - -uint -osl_pkttailroom(void *drv, void *skb) -{ - return (uint) skb_tailroom((struct sk_buff *) skb); -} - -void* -osl_pktnext(void *drv, void *skb) -{ - return (((struct sk_buff*)skb)->next); -} - -void -osl_pktsetnext(void *skb, void *x) -{ - ((struct sk_buff*)skb)->next = (struct sk_buff*)x; -} - -void -osl_pktsetlen(void *drv, void *skb, uint len) -{ - __skb_trim((struct sk_buff*)skb, len); -} - -uchar* -osl_pktpush(void *drv, void *skb, int bytes) -{ - return (skb_push((struct sk_buff*)skb, bytes)); -} - -uchar* -osl_pktpull(void *drv, void *skb, int bytes) -{ - return (skb_pull((struct sk_buff*)skb, bytes)); -} - -void* -osl_pktdup(void *drv, void *skb) -{ - return (skb_clone((struct sk_buff*)skb, GFP_ATOMIC)); -} - -void* -osl_pktcookie(void *skb) -{ - return ((void*)((struct sk_buff*)skb)->csum); -} - -void -osl_pktsetcookie(void *skb, void *x) -{ - ((struct sk_buff*)skb)->csum = (uint)x; -} - -void* -osl_pktlink(void *skb) -{ - return (((struct sk_buff*)skb)->prev); -} - -void -osl_pktsetlink(void *skb, void *x) -{ - ((struct sk_buff*)skb)->prev = (struct sk_buff*)x; -} - -uint -osl_pktprio(void *skb) -{ - return (((struct sk_buff*)skb)->priority); -} - -void -osl_pktsetprio(void *skb, uint x) -{ - ((struct sk_buff*)skb)->priority = x; -} - -#endif /* BINOSL */ diff --git a/openwrt/package/linux/kernel-source/drivers/net/hnd/sbutils.c b/openwrt/package/linux/kernel-source/drivers/net/hnd/sbutils.c deleted file mode 100644 index 1b221e0b3..000000000 --- a/openwrt/package/linux/kernel-source/drivers/net/hnd/sbutils.c +++ /dev/null @@ -1,2164 +0,0 @@ -/* - * Misc utility routines for accessing chip-specific features - * of the SiliconBackplane-based Broadcom chips. - * - * Copyright 2004, Broadcom Corporation - * All Rights Reserved. - * - * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY - * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM - * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. - * $Id$ - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* debug/trace */ -#define SB_ERROR(args) - -typedef uint32 (*sb_intrsoff_t)(void *intr_arg); -typedef void (*sb_intrsrestore_t)(void *intr_arg, uint32 arg); -typedef bool (*sb_intrsenabled_t)(void *intr_arg); - -/* misc sb info needed by some of the routines */ -typedef struct sb_info { - uint chip; /* chip number */ - uint chiprev; /* chip revision */ - uint chippkg; /* chip package option */ - uint boardtype; /* board type */ - uint boardvendor; /* board vendor id */ - uint bus; /* what bus type we are going through */ - - void *osh; /* osl os handle */ - void *sdh; /* bcmsdh handle */ - - void *curmap; /* current regs va */ - void *regs[SB_MAXCORES]; /* other regs va */ - - uint curidx; /* current core index */ - uint dev_coreid; /* the core provides driver functions */ - 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 */ - - uint numcores; /* # discovered cores */ - uint coreid[SB_MAXCORES]; /* id of each core */ - - void *intr_arg; /* interrupt callback function arg */ - sb_intrsoff_t intrsoff_fn; /* function turns chip interrupts off */ - sb_intrsrestore_t intrsrestore_fn; /* function restore chip interrupts */ - sb_intrsenabled_t intrsenabled_fn; /* function to check if chip interrupts are enabled */ -} sb_info_t; - -/* local prototypes */ -static void* sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz); -static void 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_pcidev2chip(uint pcidev); -static uint sb_chip2numcores(uint chip); - -#define SB_INFO(sbh) (sb_info_t*)sbh -#define SET_SBREG(sbh, r, mask, val) W_SBREG((sbh), (r), ((R_SBREG((sbh), (r)) & ~(mask)) | (val))) -#define GOODCOREADDR(x) (((x) >= SB_ENUM_BASE) && ((x) <= SB_ENUM_LIM) && ISALIGNED((x), SB_CORE_SIZE)) -#define GOODREGS(regs) (regs && ISALIGNED(regs, SB_CORE_SIZE)) -#define REGS2SB(va) (sbconfig_t*) ((uint)(va) + SBCONFIGOFF) -#define GOODIDX(idx) (((uint)idx) < SB_MAXCORES) -#define BADIDX (SB_MAXCORES+1) - -#define R_SBREG(sbh, sbr) sb_read_sbreg((sbh), (sbr)) -#define W_SBREG(sbh, sbr, v) sb_write_sbreg((sbh), (sbr), (v)) -#define AND_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) & (v))) -#define OR_SBREG(sbh, sbr, v) W_SBREG((sbh), (sbr), (R_SBREG((sbh), (sbr)) | (v))) - -/* - * Macros to disable/restore function core(D11, ENET, ILINE20, etc) interrupts before/ - * after core switching to avoid invalid register accesss inside ISR. - */ -#define INTR_OFF(si, intr_val) \ - if ((si)->intrsoff_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ - intr_val = (*(si)->intrsoff_fn)((si)->intr_arg); } -#define INTR_RESTORE(si, intr_val) \ - if ((si)->intrsrestore_fn && (si)->coreid[(si)->curidx] == (si)->dev_coreid) { \ - (*(si)->intrsrestore_fn)((si)->intr_arg, intr_val); } - -/* power 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 XTAL_ON_DELAY 1000 /* Xtal power on delay in us */ - -#define SCC_LOW2FAST_LIMIT 5000 /* turn on fast clock time, in unit of ms */ - - -static uint32 -sb_read_sbreg(void *sbh, 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. - * MEM_SEG will be OR'd with other 11 bits address in hardware, - * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). - * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special - */ - if(si->memseg) { - INTR_OFF(si, intr_val); - tmp = 1; - OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); - sbr = (uint32 *) (((uint32) sbr) & ~(1 << 11)); /* mask out bit 11*/ - } - - val = R_REG(sbr); - - if(si->memseg) { - tmp = 0; - OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); - INTR_RESTORE(si, intr_val); - } - - return (val); -} - -static void -sb_write_sbreg(void *sbh, 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. - * MEM_SEG will be OR'd with other 11 bits address in hardware, - * so we program MEM_SEG with 12th bit when necessary(access sb regsiters). - * For normal PCMCIA bus(CFTable_regwinsz > 2k), do nothing special - */ - if(si->memseg) { - INTR_OFF(si, intr_val); - tmp = 1; - OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); - sbr = (uint32 *) (((uint32) sbr) & ~(1 << 11)); /* mask out bit 11*/ - } - - if (si->bus == PCMCIA_BUS) { -#ifdef IL_BIGENDIAN - dummy = R_REG(sbr); - W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff)); - dummy = R_REG(sbr); - W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); -#else - dummy = R_REG(sbr); - W_REG((volatile uint16 *)sbr, (uint16)(v & 0xffff)); - dummy = R_REG(sbr); - W_REG((volatile uint16 *)((uint32)sbr + 2), (uint16)((v >> 16) & 0xffff)); -#endif - } else - W_REG(sbr, v); - - if(si->memseg) { - tmp = 0; - OSL_PCMCIA_WRITE_ATTR(si->osh, MEM_SEG, &tmp, 1); - INTR_RESTORE(si, intr_val); - } -} - -/* - * Allocate a sb handle. - * devid - pci device id (used to determine chip#) - * osh - opaque OS handle - * regs - virtual address of initial core registers - * bustype - pci/pcmcia/sb/sdio/etc - * vars - pointer to a pointer area for "environment" variables - * varsz - pointer to int to return the size of the vars - */ -void* -sb_attach(uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz) -{ - sb_info_t *si; - - /* alloc sb_info_t */ - if ((si = MALLOC(sizeof (sb_info_t))) == NULL) { - SB_ERROR(("sb_attach: malloc failed!\n")); - return (NULL); - } - - return (sb_doattach(si, devid, osh, regs, bustype, sdh, vars, varsz)); -} - -/* global kernel resource */ -static sb_info_t ksi; - -/* generic kernel variant of sb_attach() */ -void* -sb_kattach() -{ - uint32 *regs; - char *unused; - int varsz; - - if (ksi.curmap == NULL) { - uint32 cid; - - regs = (uint32 *)REG_MAP(SB_ENUM_BASE, SB_CORE_SIZE); - cid = R_REG((uint32 *)regs); - if (((cid & (CID_ID_MASK | CID_PKG_MASK)) == 0x00104712) && - ((cid & CID_REV_MASK) <= 0x00020000)) { - uint32 *scc, val; - - scc = (uint32 *)((uint32)regs + OFFSETOF(chipcregs_t, slow_clk_ctl)); - val = R_REG(scc); - SB_ERROR((" initial scc = 0x%x\n", val)); - val |= SCC_SS_XTAL; - W_REG(scc, val); - } - - sb_doattach(&ksi, BCM4710_DEVICE_ID, NULL, (void*)regs, - SB_BUS, NULL, &unused, &varsz); - } - - return &ksi; -} - -static void* -sb_doattach(sb_info_t *si, uint devid, void *osh, void *regs, uint bustype, void *sdh, char **vars, int *varsz) -{ - uint origidx; - chipcregs_t *cc; - uint32 w; - - ASSERT(GOODREGS(regs)); - - bzero((uchar*)si, sizeof (sb_info_t)); - - si->pciidx = si->gpioidx = BADIDX; - - si->osh = osh; - si->curmap = regs; - si->sdh = sdh; - - /* check to see if we are a sb core mimic'ing a pci core */ - if (bustype == PCI_BUS) { - if (OSL_PCI_READ_CONFIG(osh, PCI_SPROM_CONTROL, sizeof (uint32)) == 0xffffffff) - bustype = SB_BUS; - else - bustype = PCI_BUS; - } - - si->bus = bustype; - - if (si->bus == PCMCIA_BUS) - /* need to set memseg flag for CF card first before any sb registers access, - * such as the access inside sb_scan. the card type is detected and memseg - * flag is reassigned later after srom_var_init. there should be no effect - * for PCMCIA cards even though the memseg flag is set - */ - si->memseg = TRUE; - - /* kludge to enable the clock on the 4306 which lacks a slowclock */ - if (si->bus == PCI_BUS) - sb_pwrctl_xtal((void*)si, XTAL|PLL, ON); - - /* initialize current core index value */ - si->curidx = _sb_coreidx((void*)si); - if (si->curidx == BADIDX) - goto bad; - - /* keep and reuse the initial register mapping */ - origidx = si->curidx; - if (si->bus == 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 = 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; - } else { - /* The only pcmcia chip without a chipcommon core is a 4301 */ - if (si->bus == PCMCIA_BUS) - devid = BCM4301_DEVICE_ID; - - /* no chip common core -- must convert device id to chip id */ - if ((si->chip = sb_pcidev2chip(devid)) == 0) { - SB_ERROR(("sb_attach: unrecognized device id 0x%04x\n", devid)); - goto bad; - } - } - - /* get chipcommon rev */ - si->ccrev = cc? sb_corerev((void*)si) : 0; - - /* determine numcores */ - if ((si->ccrev == 4) || (si->ccrev >= 6)) - si->numcores = (R_REG(&cc->chipid) & CID_CC_MASK) >> CID_CC_SHIFT; - else - si->numcores = sb_chip2numcores(si->chip); - - /* return to original core */ - sb_setcoreidx((void*)si, origidx); - - /* sanity checks */ - ASSERT(si->chip); - - /* scan for cores */ - sb_scan(si); - - /* initialize the vars after sb_scan so that the core rev. information - * collected by sb_scan is available for the srom_var_init. - */ - if (srom_var_init(si, si->bus, si->curmap, osh, vars, varsz)) { - SB_ERROR(("sb_attach: srom_var_init failed\n")); - goto bad; - } - - if (cc == NULL) { - /* - * The chip revision number is hardwired into all - * of the pci function config rev fields and is - * independent from the individual core revision numbers. - * For example, the "A0" silicon of each chip is chip rev 0. - * For PCMCIA we get it from the CIS instead. - */ - if (si->bus == PCMCIA_BUS) { - ASSERT(vars); - si->chiprev = getintvar(*vars, "chiprev"); - } else if (si->bus == PCI_BUS) { - w = OSL_PCI_READ_CONFIG(osh, PCI_CFG_REV, sizeof (uint32)); - si->chiprev = w & 0xff; - } else - si->chiprev = 0; - } - - if (si->bus == PCMCIA_BUS) { - w = getintvar(*vars, "regwindowsz"); - si->memseg = (w <= CFTABLE_REGWIN_2K) ? TRUE : FALSE; - } - - /* pci core is required */ - if (!GOODIDX(si->pciidx)) { - SB_ERROR(("sb_attach: pci core not found\n")); - goto bad; - } - - /* gpio control core is required */ - if (!GOODIDX(si->gpioidx)) { - SB_ERROR(("sb_attach: gpio control core not found\n")); - goto bad; - } - - /* get boardtype and boardrev */ - switch (si->bus) { - 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; - break; - - case PCMCIA_BUS: - case SDIO_BUS: - si->boardvendor = getintvar(*vars, "manfid"); - si->boardtype = getintvar(*vars, "prodid"); - break; - - case SB_BUS: - si->boardvendor = VENDOR_BROADCOM; - si->boardtype = 0xffff; - break; - } - - if (si->boardtype == 0) { - SB_ERROR(("sb_attach: unknown board type\n")); - ASSERT(si->boardtype); - } - - /* clear any previous epidiag-induced target abort */ - sb_taclear((void*)si); - - return ((void*)si); - -bad: - MFREE(si, sizeof (sb_info_t)); - return (NULL); -} - -uint -sb_coreid(void *sbh) -{ - sb_info_t *si; - sbconfig_t *sb; - - si = SB_INFO(sbh); - sb = REGS2SB(si->curmap); - - return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT); -} - -uint -sb_coreidx(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - return (si->curidx); -} - -/* return current index of core */ -static uint -_sb_coreidx(void *sbh) -{ - sb_info_t *si; - sbconfig_t *sb; - uint32 sbaddr = 0; - - si = SB_INFO(sbh); - ASSERT(si); - - switch (si->bus) { - case SB_BUS: - sb = REGS2SB(si->curmap); - sbaddr = sb_base(R_SBREG(sbh, &sb->sbadmatch0)); - break; - - case PCI_BUS: - sbaddr = OSL_PCI_READ_CONFIG(si->osh, PCI_BAR0_WIN, sizeof (uint32)); - break; - - case PCMCIA_BUS: { - uint8 tmp; - - OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); - sbaddr = (uint)tmp << 12; - OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); - sbaddr |= (uint)tmp << 16; - OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); - sbaddr |= (uint)tmp << 24; - break; - } - default: - ASSERT(0); - } - - if (!GOODCOREADDR(sbaddr)) - return BADIDX; - - return ((sbaddr - SB_ENUM_BASE) / SB_CORE_SIZE); -} - -uint -sb_corevendor(void *sbh) -{ - sb_info_t *si; - sbconfig_t *sb; - - si = SB_INFO(sbh); - sb = REGS2SB(si->curmap); - - return ((R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_VC_MASK) >> SBIDH_VC_SHIFT); -} - -uint -sb_corerev(void *sbh) -{ - sb_info_t *si; - sbconfig_t *sb; - - si = SB_INFO(sbh); - sb = REGS2SB(si->curmap); - - return (R_SBREG(sbh, &(sb)->sbidhigh) & SBIDH_RC_MASK); -} - -#define SBTML_ALLOW (SBTML_PE | SBTML_FGC | SBTML_FL_MASK) - -/* set/clear sbtmstatelow core-specific flags */ -uint32 -sb_coreflags(void *sbh, uint32 mask, uint32 val) -{ - sb_info_t *si; - sbconfig_t *sb; - uint32 w; - - si = SB_INFO(sbh); - sb = REGS2SB(si->curmap); - - ASSERT((val & ~mask) == 0); - ASSERT((mask & ~SBTML_ALLOW) == 0); - - /* mask and set */ - if (mask || val) { - w = (R_SBREG(sbh, &sb->sbtmstatelow) & ~mask) | val; - W_SBREG(sbh, &sb->sbtmstatelow, w); - } - - /* return the new value */ - return (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_ALLOW); -} - -/* set/clear sbtmstatehigh core-specific flags */ -uint32 -sb_coreflagshi(void *sbh, uint32 mask, uint32 val) -{ - sb_info_t *si; - sbconfig_t *sb; - uint32 w; - - si = SB_INFO(sbh); - sb = REGS2SB(si->curmap); - - ASSERT((val & ~mask) == 0); - ASSERT((mask & ~SBTMH_FL_MASK) == 0); - - /* mask and set */ - if (mask || val) { - w = (R_SBREG(sbh, &sb->sbtmstatehigh) & ~mask) | val; - W_SBREG(sbh, &sb->sbtmstatehigh, w); - } - - /* return the new value */ - return (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_FL_MASK); -} - -bool -sb_iscoreup(void *sbh) -{ - sb_info_t *si; - sbconfig_t *sb; - - si = SB_INFO(sbh); - sb = REGS2SB(si->curmap); - - return ((R_SBREG(sbh, &(sb)->sbtmstatelow) & (SBTML_RESET | SBTML_REJ | SBTML_CLK)) == SBTML_CLK); -} - -/* - * Switch to 'coreidx', issue a single arbitrary 32bit register mask&set operation, - * switch back to the original core, and return the new value. - */ -static uint -sb_corereg(void *sbh, uint coreidx, uint regoff, uint mask, uint val) -{ - sb_info_t *si; - uint origidx; - uint32 *r; - uint w; - uint intr_val = 0; - - ASSERT(GOODIDX(coreidx)); - 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); - - /* switch core */ - r = (uint32*) ((uint) sb_setcoreidx(sbh, coreidx) + regoff); - - /* mask and set */ - if (mask || val) { - if (regoff >= SBCONFIGOFF) { - w = (R_SBREG(sbh, r) & ~mask) | val; - W_SBREG(sbh, r, w); - } else { - w = (R_REG(r) & ~mask) | val; - W_REG(r, w); - } - } - - /* readback */ - if (regoff >= SBCONFIGOFF) - w = R_SBREG(sbh, r); - else - w = R_REG(r); - - /* restore core index */ - if (origidx != coreidx) - sb_setcoreidx(sbh, origidx); - - INTR_RESTORE(si, intr_val); - return (w); -} - -/* scan the sb enumerated space to identify all cores */ -static void -sb_scan(sb_info_t *si) -{ - void *sbh; - uint origidx; - uint i; - - sbh = (void*) si; - - /* numcores should already be set */ - ASSERT((si->numcores > 0) && (si->numcores <= SB_MAXCORES)); - - /* save current core index */ - origidx = sb_coreidx(sbh); - - si->pciidx = si->gpioidx = BADIDX; - - for (i = 0; i < si->numcores; i++) { - sb_setcoreidx(sbh, i); - si->coreid[i] = sb_coreid(sbh); - - if (si->coreid[i] == SB_PCI) { - si->pciidx = i; - si->pcirev = sb_corerev(sbh); - - } else if (si->coreid[i] == SB_PCMCIA) { - si->pcmciaidx = i; - si->pcmciarev = sb_corerev(sbh); - } - } - - /* - * Find the gpio "controlling core" type and index. - * Precedence: - * - if there's a chip common core - use that - * - else if there's a pci core (rev >= 2) - use that - * - else there had better be an extif core (4710 only) - */ - if (GOODIDX(sb_findcoreidx(sbh, SB_CC, 0))) { - si->gpioidx = sb_findcoreidx(sbh, SB_CC, 0); - si->gpioid = SB_CC; - } else if (GOODIDX(si->pciidx) && (si->pcirev >= 2)) { - si->gpioidx = si->pciidx; - si->gpioid = SB_PCI; - } else if (sb_findcoreidx(sbh, SB_EXTIF, 0)) { - si->gpioidx = sb_findcoreidx(sbh, SB_EXTIF, 0); - si->gpioid = SB_EXTIF; - } - - /* return to original core index */ - sb_setcoreidx(sbh, origidx); -} - -/* may be called with core in reset */ -void -sb_detach(void *sbh) -{ - sb_info_t *si; - uint idx; - - si = SB_INFO(sbh); - - if (si == NULL) - return; - - if (si->bus == SB_BUS) - for (idx = 0; idx < SB_MAXCORES; idx++) - if (si->regs[idx]) { - REG_UNMAP(si->regs[idx]); - si->regs[idx] = NULL; - } - - MFREE(si, sizeof (sb_info_t)); -} - -/* use pci dev id to determine chip id for chips not having a chipcommon core */ -static uint -sb_pcidev2chip(uint pcidev) -{ - 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 >= BCM4307_V90_ID) && (pcidev <= BCM4307_D11B_ID)) - return (BCM4307_DEVICE_ID); - if (pcidev == BCM4301_DEVICE_ID) - return (BCM4301_DEVICE_ID); - - return (0); -} - -/* convert chip number to number of i/o cores */ -static uint -sb_chip2numcores(uint chip) -{ - if (chip == 0x4710) - return (9); - if (chip == 0x4610) - return (9); - if (chip == 0x4402) - return (3); - if ((chip == 0x4307) || (chip == 0x4301)) - return (5); - if (chip == 0x4310) - return (8); - if (chip == 0x4306) /* < 4306c0 */ - return (6); - if (chip == 0x4704) - return (9); - if (chip == 0x5365) - return (7); - - SB_ERROR(("sb_chip2numcores: unsupported chip 0x%x\n", chip)); - ASSERT(0); - return (1); -} - -/* return index of coreid or BADIDX if not found */ -static uint -sb_findcoreidx(void *sbh, 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++) - if (si->coreid[i] == coreid) { - if (found == coreunit) - return (i); - found++; - } - - return (BADIDX); -} - -/* - * this function changes logical "focus" to the indiciated core, - * must be called with interrupt off. - * Moreover, callers should keep interrupts off during switching out of and back to d11 core - */ -void* -sb_setcoreidx(void *sbh, uint coreidx) -{ - sb_info_t *si; - uint32 sbaddr; - uint8 tmp; - - si = SB_INFO(sbh); - - if (coreidx >= si->numcores) - return (NULL); - - /* - * If the user has provided an interrupt mask enabled function, - * then assert interrupts are disabled before switching the core. - */ - ASSERT((si->intrsenabled_fn == NULL) || !(*(si)->intrsenabled_fn)((si)->intr_arg)); - - sbaddr = SB_ENUM_BASE + (coreidx * SB_CORE_SIZE); - - switch (si->bus) { - case SB_BUS: - /* map new one */ - if (!si->regs[coreidx]) { - si->regs[coreidx] = (void*)REG_MAP(sbaddr, SB_CORE_SIZE); - ASSERT(GOODREGS(si->regs[coreidx])); - } - si->curmap = si->regs[coreidx]; - break; - - case PCI_BUS: - /* point bar0 window */ - OSL_PCI_WRITE_CONFIG(si->osh, PCI_BAR0_WIN, 4, sbaddr); - break; - - case PCMCIA_BUS: - tmp = (sbaddr >> 12) & 0x0f; - OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR0, &tmp, 1); - tmp = (sbaddr >> 16) & 0xff; - OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR1, &tmp, 1); - tmp = (sbaddr >> 24) & 0xff; - OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_ADDR2, &tmp, 1); - break; - } - - si->curidx = coreidx; - - return (si->curmap); -} - -/* - * this function changes logical "focus" to the indiciated core, - * must be called with interrupt off. - * Moreover, callers should keep interrupts off during switching out of and back to d11 core - */ -void* -sb_setcore(void *sbh, uint coreid, uint coreunit) -{ - sb_info_t *si; - uint idx; - - si = SB_INFO(sbh); - - idx = sb_findcoreidx(sbh, coreid, coreunit); - if (!GOODIDX(idx)) - return (NULL); - - return (sb_setcoreidx(sbh, idx)); -} - -/* return chip number */ -uint -sb_chip(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - return (si->chip); -} - -/* return chip revision number */ -uint -sb_chiprev(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - return (si->chiprev); -} - -/* return chip common revision number */ -uint -sb_chipcrev(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - return (si->ccrev); -} - -/* return chip package option */ -uint -sb_chippkg(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - return (si->chippkg); -} - -/* return PCI core rev. */ -uint -sb_pcirev(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - return (si->pcirev); -} - -/* return PCMCIA core rev. */ -uint -sb_pcmciarev(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - return (si->pcmciarev); -} - -/* return board vendor id */ -uint -sb_boardvendor(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - return (si->boardvendor); -} - -/* return boardtype */ -uint -sb_boardtype(void *sbh) -{ - sb_info_t *si; - char *var; - - si = SB_INFO(sbh); - - if (si->bus == SB_BUS && si->boardtype == 0xffff) { - /* boardtype format is a hex string */ - si->boardtype = getintvar(NULL, "boardtype"); - - /* backward compatibility for older boardtype string format */ - if ((si->boardtype == 0) && (var = getvar(NULL, "boardtype"))) { - if (!strcmp(var, "bcm94710dev")) - si->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; - else if (!strcmp(var, "bu4710")) - si->boardtype = BU4710_BOARD; - else if (!strcmp(var, "bcm94702mn")) - si->boardtype = BCM94702MN_BOARD; - else if (!strcmp(var, "bcm94710r1")) - si->boardtype = BCM94710R1_BOARD; - else if (!strcmp(var, "bcm94710r4")) - si->boardtype = BCM94710R4_BOARD; - else if (!strcmp(var, "bcm94702cpci")) - si->boardtype = BCM94702CPCI_BOARD; - else if (!strcmp(var, "bcm95380_rr")) - si->boardtype = BCM95380RR_BOARD; - } - } - - return (si->boardtype); -} - -/* return board bus style */ -uint -sb_boardstyle(void *sbh) -{ - sb_info_t *si; - uint16 w; - - si = SB_INFO(sbh); - - if (si->bus == PCMCIA_BUS) - return (BOARDSTYLE_PCMCIA); - - if (si->bus == SB_BUS) - return (BOARDSTYLE_SOC); - - /* bus is PCI */ - - if (OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CIS, sizeof (uint32)) != 0) - return (BOARDSTYLE_CARDBUS); - - if ((srom_read(si->bus, si->curmap, si->osh, (SPROM_SIZE - 1) * 2, 2, &w) == 0) && - (w == 0x0313)) - return (BOARDSTYLE_CARDBUS); - - return (BOARDSTYLE_PCI); -} - -/* return boolean if sbh device is in pci hostmode or client mode */ -uint -sb_bus(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - return (si->bus); -} - -/* return list of found cores */ -uint -sb_corelist(void *sbh, uint coreid[]) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - - bcopy((uchar*)si->coreid, (uchar*)coreid, (si->numcores * sizeof (uint))); - return (si->numcores); -} - -/* return current register mapping */ -void * -sb_coreregs(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - ASSERT(GOODREGS(si->curmap)); - - return (si->curmap); -} - -/* traverse all cores to find and clear source of serror */ -static void -sb_serr_clear(void *sbh) -{ - sb_info_t *si; - sbconfig_t *sb; - uint origidx; - uint i, intr_val = 0; - void * corereg = NULL; - - si = SB_INFO(sbh); - - INTR_OFF(si, intr_val); - origidx = sb_coreidx(sbh); - - for (i = 0; i < si->numcores; i++) { - corereg = sb_setcoreidx(sbh, i); - if (NULL != corereg) { - sb = REGS2SB(corereg); - if ((si->chip == BCM4317_DEVICE_ID) && (si->chiprev == 0)) { - W_SBREG(sbh, &sb->sbtmstatehigh, 0); - } else { - if ((R_SBREG(sbh, &sb->sbtmstatehigh)) & SBTMH_SERR) { - AND_SBREG(sbh, &sb->sbtmstatehigh, ~SBTMH_SERR); - SB_ERROR(("sb_serr_clear: SError at core 0x%x\n", sb_coreid(sbh))); - } - } - } - } - - sb_setcoreidx(sbh, origidx); - INTR_RESTORE(si, intr_val); -} - -/* check if any inband, outband or timeout errors has happened and clear them */ -/* !! must be called with chip clk on */ -bool -sb_taclear(void *sbh) -{ - sb_info_t *si; - sbconfig_t *sb; - uint origidx; - uint intr_val = 0; - bool rc = FALSE; - uint32 inband = 0, serror = 0, timeout = 0; - void *corereg = NULL; - volatile uint32 imstate, tmstate; - - si = SB_INFO(sbh); - - if (si->bus == PCI_BUS) { - volatile uint32 stcmd; - - /* inband error is Target abort for PCI */ - stcmd = OSL_PCI_READ_CONFIG(si->osh, PCI_CFG_CMD, sizeof(uint32)); - inband = stcmd & PCI_CFG_CMD_STAT_TA; - if (inband) - OSL_PCI_WRITE_CONFIG(si->osh, PCI_CFG_CMD, sizeof(uint32), stcmd); - - /* serror */ - stcmd = OSL_PCI_READ_CONFIG(si->osh, PCI_INT_STATUS, sizeof(uint32)); - serror = stcmd & PCI_SBIM_STATUS_SERR; - if (serror) { - sb_serr_clear(sbh); - OSL_PCI_WRITE_CONFIG(si->osh, PCI_INT_STATUS, sizeof(uint32), stcmd); - } - - /* timeout */ - imstate = sb_corereg(sbh, si->pciidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbimstate), 0, 0); - if ((imstate != 0xffffffff) && (imstate & (SBIM_IBE | SBIM_TO))) { - sb_corereg(sbh, si->pciidx, SBCONFIGOFF + OFFSETOF(sbconfig_t, sbimstate), ~0, - (imstate & ~(SBIM_IBE | SBIM_TO))); - /* inband = imstate & SBIM_IBE; same as TA above */ - timeout = imstate & SBIM_TO; - } - - } else if (si->bus == PCMCIA_BUS) { - - INTR_OFF(si, intr_val); - origidx = sb_coreidx(sbh); - - corereg = sb_setcore(sbh, SB_PCMCIA, 0); - if (NULL != corereg) { - sb = REGS2SB(corereg); - - imstate = R_SBREG(sbh, &sb->sbimstate); - /* handle surprise removal */ - if ((imstate != 0xffffffff) && (imstate & (SBIM_IBE | SBIM_TO))) { - AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); - inband = imstate & SBIM_IBE; - timeout = imstate & SBIM_TO; - } - tmstate = R_SBREG(sbh, &sb->sbtmstatehigh); - if ((tmstate != 0xffffffff) && (tmstate & SBTMH_INT_STATUS)) { - if (!inband) { - serror = 1; - sb_serr_clear(sbh); - } - OR_SBREG(sbh, &sb->sbtmstatelow, SBTML_INT_ACK); - AND_SBREG(sbh, &sb->sbtmstatelow, ~SBTML_INT_ACK); - } - } - sb_setcoreidx(sbh, origidx); - INTR_RESTORE(si, intr_val); - - } else if (si->bus == SDIO_BUS) { - - INTR_OFF(si, intr_val); - origidx = sb_coreidx(sbh); - - corereg = sb_setcore(sbh, SB_PCMCIA, 0); - if (NULL != corereg) { - sb = REGS2SB(corereg); - - imstate = R_SBREG(sbh, &sb->sbimstate); - if ((imstate != 0xffffffff) && (imstate & (SBIM_IBE | SBIM_TO))) { - AND_SBREG(sbh, &sb->sbimstate, ~(SBIM_IBE | SBIM_TO)); - /* inband = imstate & SBIM_IBE; cmd error */ - timeout = imstate & SBIM_TO; - } - tmstate = R_SBREG(sbh, &sb->sbtmstatehigh); - if ((tmstate != 0xffffffff) && (tmstate & SBTMH_INT_STATUS)) { - sb_serr_clear(sbh); - serror = 1; - OR_SBREG(sbh, &sb->sbtmstatelow, SBTML_INT_ACK); - AND_SBREG(sbh, &sb->sbtmstatelow, ~SBTML_INT_ACK); - } - } - - sb_setcoreidx(sbh, origidx); - INTR_RESTORE(si, intr_val); - } - - if ((inband | timeout | serror) != 0) { - rc = TRUE; - SB_ERROR(("sb_taclear: inband 0x%x, serror 0x%x, timeout 0x%x!\n", inband, serror, timeout)); - } - - return (rc); -} - -/* do buffered registers update */ -void -sb_commit(void *sbh) -{ - sb_info_t *si; - sbpciregs_t *pciregs; - uint origidx; - uint intr_val = 0; - - si = SB_INFO(sbh); - - origidx = si->curidx; - ASSERT(GOODIDX(origidx)); - - INTR_OFF(si, intr_val); - /* switch over to pci core */ - 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); - - /* restore core index */ - sb_setcoreidx(sbh, origidx); - INTR_RESTORE(si, intr_val); -} - -/* reset and re-enable a core */ -void -sb_core_reset(void *sbh, uint32 bits) -{ - sb_info_t *si; - sbconfig_t *sb; - volatile uint32 dummy; - - si = SB_INFO(sbh); - ASSERT(GOODREGS(si->curmap)); - sb = REGS2SB(si->curmap); - - /* - * Must do the disable sequence first to work for arbitrary current core state. - */ - sb_core_disable(sbh, bits); - - /* - * Now do the initialization sequence. - */ - - /* set reset while enabling the clock and forcing them on throughout the core */ - W_SBREG(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); - } - - if (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_SERR) { - W_SBREG(sbh, &sb->sbtmstatehigh, 0); - } - if ((dummy = R_SBREG(sbh, &sb->sbimstate)) & (SBIM_IBE | SBIM_TO)) { - AND_SBREG(sbh, &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); - OSL_DELAY(1); - - /* leave clock enabled */ - W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | bits)); - dummy = R_SBREG(sbh, &sb->sbtmstatelow); - OSL_DELAY(1); -} - -void -sb_core_tofixup(void *sbh) -{ - sb_info_t *si; - sbconfig_t *sb; - - si = SB_INFO(sbh); - - if (si->pcirev >= 5) - return; - - ASSERT(GOODREGS(si->curmap)); - sb = REGS2SB(si->curmap); - - if (si->bus == SB_BUS) { - SET_SBREG(sbh, &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, - SBIMCL_RTO_MASK | SBIMCL_STO_MASK, - (0x3 << SBIMCL_RTO_SHIFT) | 0x2); - } else { - SET_SBREG(sbh, &sb->sbimconfiglow, (SBIMCL_RTO_MASK | SBIMCL_STO_MASK), 0); - } - } - - sb_commit(sbh); -} - -void -sb_core_disable(void *sbh, uint32 bits) -{ - sb_info_t *si; - volatile uint32 dummy; - sbconfig_t *sb; - - si = SB_INFO(sbh); - - ASSERT(GOODREGS(si->curmap)); - sb = REGS2SB(si->curmap); - - /* must return if core is already in reset */ - if (R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_RESET) - return; - - /* put into reset and return if clocks are not enabled */ - if ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_CLK) == 0) - goto disable; - - /* set the reject bit */ - W_SBREG(sbh, &sb->sbtmstatelow, (SBTML_CLK | SBTML_REJ)); - - /* spin until reject is set */ - while ((R_SBREG(sbh, &sb->sbtmstatelow) & SBTML_REJ) == 0) - OSL_DELAY(1); - - /* spin until sbtmstatehigh.busy is clear */ - while (R_SBREG(sbh, &sb->sbtmstatehigh) & SBTMH_BUSY) - OSL_DELAY(1); - - /* 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); - OSL_DELAY(10); - - disable: - /* leave reset and reject asserted */ - W_SBREG(sbh, &sb->sbtmstatelow, (bits | SBTML_REJ | SBTML_RESET)); - OSL_DELAY(1); -} - -void -sb_watchdog(void *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); - break; - case SB_EXTIF: - sb_corereg(sbh, si->gpioidx, OFFSETOF(extifregs_t, watchdog), ~0, ticks); - break; - } -} - -/* initialize the pcmcia core */ -void -sb_pcmcia_init(void *sbh) -{ - sb_info_t *si; - uint8 cor; - - si = SB_INFO(sbh); - - /* enable d11 mac interrupts */ - if (si->chip == BCM4301_DEVICE_ID) { - /* Have to use FCR2 in 4301 */ - OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); - cor |= COR_IRQEN | COR_FUNEN; - OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR2 + PCMCIA_COR, &cor, 1); - } else { - OSL_PCMCIA_READ_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); - cor |= COR_IRQEN | COR_FUNEN; - OSL_PCMCIA_WRITE_ATTR(si->osh, PCMCIA_FCR0 + PCMCIA_COR, &cor, 1); - } - -} - - -/* - * Configure the pci core for pci client (NIC) action - * 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_info_t *si; - sbconfig_t *sb; - sbpciregs_t *pciregs; - uint32 sbflag; - uint32 w; - uint idx; - - si = SB_INFO(sbh); - - if (dmaoffset) - *dmaoffset = 0; - - /* if not pci bus, we're done */ - if (si->bus != PCI_BUS) - return; - - ASSERT(si->pciidx); - - /* get current core index */ - idx = si->curidx; - - /* we interrupt on this backplane flag number */ - ASSERT(GOODREGS(si->curmap)); - sb = REGS2SB(si->curmap); - sbflag = R_SBREG(sbh, &sb->sbtpsflag) & SBTPS_NUM0_MASK; - - /* switch over to pci core */ - pciregs = (sbpciregs_t*) sb_setcoreidx(sbh, si->pciidx); - 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 { - /* 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); - } - - /* enable prefetch and bursts for sonics-to-pci translation 2 */ - OR_REG(&pciregs->sbtopci2, (SBTOPCI_PREF|SBTOPCI_BURST)); - - if (si->pcirev < 5) { - SET_SBREG(sbh, &sb->sbimconfiglow, SBIMCL_RTO_MASK | SBIMCL_STO_MASK, - (0x3 << SBIMCL_RTO_SHIFT) | 0x2); - sb_commit(sbh); - } - - /* switch back to previous core */ - sb_setcoreidx(sbh, idx); - - /* use large sb pci dma window */ - if (dmaoffset) - *dmaoffset = SB_PCI_DMA; -} - -uint32 -sb_base(uint32 admatch) -{ - uint32 base; - uint type; - - type = admatch & SBAM_TYPE_MASK; - ASSERT(type < 3); - - base = 0; - - if (type == 0) { - base = admatch & SBAM_BASE0_MASK; - } else if (type == 1) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE1_MASK; - } else if (type == 2) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - base = admatch & SBAM_BASE2_MASK; - } - - return (base); -} - -uint32 -sb_size(uint32 admatch) -{ - uint32 size; - uint type; - - type = admatch & SBAM_TYPE_MASK; - ASSERT(type < 3); - - size = 0; - - if (type == 0) { - size = 1 << (((admatch & SBAM_ADINT0_MASK) >> SBAM_ADINT0_SHIFT) + 1); - } else if (type == 1) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - size = 1 << (((admatch & SBAM_ADINT1_MASK) >> SBAM_ADINT1_SHIFT) + 1); - } else if (type == 2) { - ASSERT(!(admatch & SBAM_ADNEG)); /* neg not supported */ - size = 1 << (((admatch & SBAM_ADINT2_MASK) >> SBAM_ADINT2_SHIFT) + 1); - } - - return (size); -} - -/* return the core-type instantiation # of the current core */ -uint -sb_coreunit(void *sbh) -{ - sb_info_t *si; - uint idx; - uint coreid; - uint coreunit; - uint i; - - si = SB_INFO(sbh); - coreunit = 0; - - idx = si->curidx; - - ASSERT(GOODREGS(si->curmap)); - coreid = sb_coreid(sbh); - - /* count the cores of our type */ - for (i = 0; i < idx; i++) - if (si->coreid[i] == coreid) - coreunit++; - - return (coreunit); -} - -static INLINE uint32 -factor6(uint32 x) -{ - switch (x) { - case CC_F6_2: return 2; - case CC_F6_3: return 3; - case CC_F6_4: return 4; - case CC_F6_5: return 5; - case CC_F6_6: return 6; - case CC_F6_7: return 7; - default: return 0; - } -} - -/* calculate the speed the SB would run at given a set of clockcontrol values */ -uint32 -sb_clock_rate(uint32 pll_type, uint32 n, uint32 m) -{ - uint32 n1, n2, clock, m1, m2, m3, mc; - - n1 = n & CN_N1_MASK; - n2 = (n & CN_N2_MASK) >> CN_N2_SHIFT; - - if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) { - n1 = factor6(n1); - n2 += CC_F5_BIAS; - } else if (pll_type == PLL_TYPE2) { - n1 += CC_T2_BIAS; - n2 += CC_T2_BIAS; - ASSERT((n1 >= 2) && (n1 <= 7)); - ASSERT((n2 >= 5) && (n2 <= 23)); - } else if (pll_type == PLL_TYPE3) { - return (100000000); - } else - ASSERT((pll_type >= PLL_TYPE1) && (pll_type <= PLL_TYPE4)); - - clock = CC_CLOCK_BASE * n1 * n2; - - if (clock == 0) - return 0; - - m1 = m & CC_M1_MASK; - m2 = (m & CC_M2_MASK) >> CC_M2_SHIFT; - m3 = (m & CC_M3_MASK) >> CC_M3_SHIFT; - mc = (m & CC_MC_MASK) >> CC_MC_SHIFT; - - if ((pll_type == PLL_TYPE1) || (pll_type == PLL_TYPE4)) { - m1 = factor6(m1); - if (pll_type == PLL_TYPE1) - m2 += CC_F5_BIAS; - else - m2 = factor6(m2); - m3 = factor6(m3); - - switch (mc) { - case CC_MC_BYPASS: return (clock); - case CC_MC_M1: return (clock / m1); - case CC_MC_M1M2: return (clock / (m1 * m2)); - case CC_MC_M1M2M3: return (clock / (m1 * m2 * m3)); - case CC_MC_M1M3: return (clock / (m1 * m3)); - default: return (0); - } - } else { - ASSERT(pll_type == PLL_TYPE2); - - m1 += CC_T2_BIAS; - m2 += CC_T2M2_BIAS; - m3 += CC_T2_BIAS; - ASSERT((m1 >= 2) && (m1 <= 7)); - ASSERT((m2 >= 3) && (m2 <= 10)); - ASSERT((m3 >= 2) && (m3 <= 7)); - - if ((mc & CC_T2MC_M1BYP) == 0) - clock /= m1; - if ((mc & CC_T2MC_M2BYP) == 0) - clock /= m2; - if ((mc & CC_T2MC_M3BYP) == 0) - clock /= m3; - - return(clock); - } -} - -/* returns the current speed the SB is running at */ -uint32 -sb_clock(void *sbh) -{ - sb_info_t *si; - extifregs_t *eir; - chipcregs_t *cc; - uint32 n, m; - uint idx; - uint32 pll_type, rate; - uint intr_val = 0; - - si = SB_INFO(sbh); - idx = si->curidx; - pll_type = PLL_TYPE1; - - INTR_OFF(si, intr_val); - - /* switch to extif or chipc core */ - if ((eir = (extifregs_t *) sb_setcore(sbh, SB_EXTIF, 0))) { - n = R_REG(&eir->clockcontrol_n); - m = R_REG(&eir->clockcontrol_sb); - } else if ((cc = (chipcregs_t *) sb_setcore(sbh, SB_CC, 0))) { - pll_type = R_REG(&cc->capabilities) & CAP_PLL_MASK; - n = R_REG(&cc->clockcontrol_n); - m = R_REG(&cc->clockcontrol_sb); - } else { - INTR_RESTORE(si, intr_val); - return 0; - } - - /* calculate rate */ - rate = sb_clock_rate(pll_type, n, m); - - /* switch back to previous core */ - sb_setcoreidx(sbh, idx); - - INTR_RESTORE(si, intr_val); - - return rate; -} - -/* change logical "focus" to the gpio core for optimized access */ -void* -sb_gpiosetcore(void *sbh) -{ - sb_info_t *si; - - si = SB_INFO(sbh); - - return (sb_setcoreidx(sbh, si->gpioidx)); -} - -/* mask&set gpiocontrol bits */ -uint32 -sb_gpiocontrol(void *sbh, uint32 mask, uint32 val) -{ - sb_info_t *si; - uint regoff; - - si = SB_INFO(sbh); - regoff = 0; - - switch (si->gpioid) { - case SB_CC: - regoff = OFFSETOF(chipcregs_t, gpiocontrol); - break; - - case SB_PCI: - regoff = OFFSETOF(sbpciregs_t, gpiocontrol); - break; - - case SB_EXTIF: - return (0); - } - - return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -} - -/* mask&set gpio output enable bits */ -uint32 -sb_gpioouten(void *sbh, uint32 mask, uint32 val) -{ - sb_info_t *si; - uint regoff; - - si = SB_INFO(sbh); - regoff = 0; - - switch (si->gpioid) { - case SB_CC: - regoff = OFFSETOF(chipcregs_t, gpioouten); - break; - - case SB_PCI: - regoff = OFFSETOF(sbpciregs_t, gpioouten); - break; - - case SB_EXTIF: - regoff = OFFSETOF(extifregs_t, gpio[0].outen); - break; - } - - return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -} - -/* mask&set gpio output bits */ -uint32 -sb_gpioout(void *sbh, uint32 mask, uint32 val) -{ - sb_info_t *si; - uint regoff; - - si = SB_INFO(sbh); - regoff = 0; - - switch (si->gpioid) { - case SB_CC: - regoff = OFFSETOF(chipcregs_t, gpioout); - break; - - case SB_PCI: - regoff = OFFSETOF(sbpciregs_t, gpioout); - break; - - case SB_EXTIF: - regoff = OFFSETOF(extifregs_t, gpio[0].out); - break; - } - - return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -} - -/* return the current gpioin register value */ -uint32 -sb_gpioin(void *sbh) -{ - sb_info_t *si; - uint regoff; - - si = SB_INFO(sbh); - regoff = 0; - - switch (si->gpioid) { - case SB_CC: - regoff = OFFSETOF(chipcregs_t, gpioin); - break; - - case SB_PCI: - regoff = OFFSETOF(sbpciregs_t, gpioin); - break; - - case SB_EXTIF: - regoff = OFFSETOF(extifregs_t, gpioin); - break; - } - - return (sb_corereg(sbh, si->gpioidx, regoff, 0, 0)); -} - -/* mask&set gpio interrupt polarity bits */ -uint32 -sb_gpiointpolarity(void *sbh, uint32 mask, uint32 val) -{ - sb_info_t *si; - uint regoff; - - si = SB_INFO(sbh); - regoff = 0; - - switch (si->gpioid) { - case SB_CC: - regoff = OFFSETOF(chipcregs_t, gpiointpolarity); - break; - - case SB_PCI: - /* pci gpio implementation does not support interrupt polarity */ - ASSERT(0); - break; - - case SB_EXTIF: - regoff = OFFSETOF(extifregs_t, gpiointpolarity); - break; - } - - return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -} - -/* mask&set gpio interrupt mask bits */ -uint32 -sb_gpiointmask(void *sbh, uint32 mask, uint32 val) -{ - sb_info_t *si; - uint regoff; - - si = SB_INFO(sbh); - regoff = 0; - - switch (si->gpioid) { - case SB_CC: - regoff = OFFSETOF(chipcregs_t, gpiointmask); - break; - - case SB_PCI: - /* pci gpio implementation does not support interrupt mask */ - ASSERT(0); - break; - - case SB_EXTIF: - regoff = OFFSETOF(extifregs_t, gpiointmask); - break; - } - - return (sb_corereg(sbh, si->gpioidx, regoff, mask, val)); -} - - -/* - * Return the slow clock source. - * Three sources of SLOW CLOCK: LPO, Xtal, PCI - */ -static uint -sb_slowclk_src(void *sbh) -{ - sb_info_t *si; - chipcregs_t *cc; - uint32 v; - - si = SB_INFO(sbh); - - ASSERT(sb_coreid(sbh) == SB_CC); - - if (si->ccrev < 6) { - switch (si->bus) { - 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 { - 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) - */ -static uint -sb_slowclk_freq(void *sbh, bool max) -{ - sb_info_t *si; - chipcregs_t *cc; - uint32 slowclk; - uint div; - - si = SB_INFO(sbh); - - ASSERT(sb_coreid(sbh) == SB_CC); - - cc = (chipcregs_t*) sb_setcoreidx(sbh, si->curidx); - - /* shouldn't be here unless we've established the chip has dynamic power control */ - ASSERT(R_REG(&cc->capabilities) & CAP_PWR_CTL); - - slowclk = sb_slowclk_src(sbh); - if (si->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); - if (slowclk == SCC_SS_LPO) - return (max? LPOMAXFREQ : LPOMINFREQ); - else if (slowclk == SCC_SS_XTAL) - return (max? (XTALMAXFREQ/div) : (XTALMINFREQ/div)); - else if (slowclk == SCC_SS_PCI) - return (max? (PCIMAXFREQ/div) : (PCIMINFREQ/div)); - else - ASSERT(0); - } else { - /* Chipc rev 10 is InstaClock */ - div = R_REG(&cc->system_clk_ctl) >> SYCC_CD_SHF; - div = 4 * (div + 1); - return (max ? XTALMAXFREQ : (XTALMINFREQ/div)); - } - return (0); -} - -static void -sb_pwrctl_setdelay(void *sbh, void *chipcregs) -{ - chipcregs_t * cc; - uint slowmaxfreq, pll_delay, slowclk; - uint pll_on_delay, fref_sel_delay; - - pll_delay = PLL_DELAY; - - /* If the slow clock is not sourced by the xtal then add the xtal_on_delay - * since the xtal will also be powered down by dynamic power control logic. - */ - slowclk = sb_slowclk_src(sbh); - if (slowclk != SCC_SS_XTAL) - pll_delay += XTAL_ON_DELAY; - - slowmaxfreq = sb_slowclk_freq(sbh, TRUE); - - pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; - fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; - - cc = (chipcregs_t *)chipcregs; - W_REG(&cc->pll_on_delay, pll_on_delay); - W_REG(&cc->fref_sel_delay, fref_sel_delay); -} - -/* set or get slow clock divider */ -int -sb_pwrctl_slowclk(void *sbh, bool set, uint *div) -{ - sb_info_t *si; - uint origidx; - chipcregs_t *cc; - uint intr_val = 0; - uint err = 0; - - si = SB_INFO(sbh); - - /* chipcommon cores prior to rev6 don't support slowclkcontrol */ - if (si->ccrev < 6) - return 1; - - /* chipcommon cores rev10 are a whole new ball game */ - if (si->ccrev >= 10) - return 1; - - if (set && ((*div % 4) || (*div < 4))) - return 2; - - INTR_OFF(si, intr_val); - origidx = si->curidx; - cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); - ASSERT(cc != NULL); - - if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) { - err = 3; - goto done; - } - - if (set) { - SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, ((*div / 4 - 1) << SCC_CD_SHF)); - sb_pwrctl_setdelay(sbh, (void *)cc); - } else - *div = 4 * (((R_REG(&cc->slow_clk_ctl) & SCC_CD_MASK) >> SCC_CD_SHF) + 1); - -done: - sb_setcoreidx(sbh, origidx); - INTR_RESTORE(si, intr_val); - return err; -} - -/* initialize power control delay registers */ -void -sb_pwrctl_init(void *sbh) -{ - sb_info_t *si; - uint origidx; - chipcregs_t *cc; - - si = SB_INFO(sbh); - - if (si->bus == SB_BUS) - return; - - origidx = si->curidx; - - if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) - return; - - if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) - goto done; - - /* 4317pc does not work with SlowClock less than 5Mhz */ - if (si->bus == PCMCIA_BUS) { - if ((si->ccrev >= 6) && (si->ccrev < 10)) - SET_REG(&cc->slow_clk_ctl, SCC_CD_MASK, (SCC_DEF_DIV << SCC_CD_SHF)); - } - - sb_pwrctl_setdelay(sbh, (void *)cc); - -done: - sb_setcoreidx(sbh, origidx); -} - -/* return the value suitable for writing to the dot11 core FAST_PWRUP_DELAY register */ -uint16 -sb_pwrctl_fast_pwrup_delay(void *sbh) -{ - sb_info_t *si; - uint origidx; - chipcregs_t *cc; - uint slowminfreq; - uint16 fpdelay; - uint intr_val = 0; - - si = SB_INFO(sbh); - fpdelay = 0; - origidx = si->curidx; - - if (si->bus == SB_BUS) - goto done; - - INTR_OFF(si, intr_val); - - if ((cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0)) == NULL) - goto done; - - if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) - goto done; - - slowminfreq = sb_slowclk_freq(sbh, FALSE); - fpdelay = (((R_REG(&cc->pll_on_delay) + 2) * 1000000) + (slowminfreq - 1)) / slowminfreq; - -done: - sb_setcoreidx(sbh, origidx); - INTR_RESTORE(si, intr_val); - return (fpdelay); -} - -/* turn primary xtal and/or pll off/on */ -int -sb_pwrctl_xtal(void *sbh, uint what, bool on) -{ - sb_info_t *si; - uint32 in, out, outen; - - si = SB_INFO(sbh); - - switch (si->bus) { - - - case PCMCIA_BUS: - return (0); - - - case PCI_BUS: - - 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)); - - /* - * We can't actually read the state of the PLLPD so we infer it - * by the value of XTAL_PU which *is* readable via gpioin. - */ - if (on && (in & PCI_CFG_GPIO_XTAL)) - return (0); - - if (what & XTAL) - outen |= PCI_CFG_GPIO_XTAL; - if (what & PLL) - outen |= PCI_CFG_GPIO_PLL; - - if (on) { - /* turn primary xtal on */ - if (what & XTAL) { - out |= PCI_CFG_GPIO_XTAL; - if (what & PLL) - out |= PCI_CFG_GPIO_PLL; - OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); - OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); - OSL_DELAY(XTAL_ON_DELAY); - } - - /* turn pll on */ - if (what & PLL) { - out &= ~PCI_CFG_GPIO_PLL; - OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); - OSL_DELAY(2000); - } - } else { - if (what & XTAL) - out &= ~PCI_CFG_GPIO_XTAL; - if (what & PLL) - out |= PCI_CFG_GPIO_PLL; - OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUT, sizeof (uint32), out); - OSL_PCI_WRITE_CONFIG(si->osh, PCI_GPIO_OUTEN, sizeof (uint32), outen); - } - - default: - return (-1); - } - - return (0); -} - -/* set dynamic power 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_info_t *si; - uint origidx; - chipcregs_t *cc; - uint32 scc; - bool forcefastclk=FALSE; - uint intr_val = 0; - - si = SB_INFO(sbh); - - /* chipcommon cores prior to rev6 don't support slowclkcontrol */ - if (si->ccrev < 6) - return (FALSE); - - /* chipcommon cores rev10 are a whole new ball game */ - if (si->ccrev >= 10) - return (FALSE); - - INTR_OFF(si, intr_val); - - origidx = si->curidx; - - cc = (chipcregs_t*) sb_setcore(sbh, SB_CC, 0); - ASSERT(cc != NULL); - - if (!(R_REG(&cc->capabilities) & CAP_PWR_CTL)) - goto done; - - switch (mode) { - case CLK_FAST: /* force fast (pll) clock */ - /* don't forget to force xtal back on before we clear SCC_DYN_XTAL.. */ - sb_pwrctl_xtal(sbh, XTAL, ON); - - SET_REG(&cc->slow_clk_ctl, (SCC_XC | SCC_FS | SCC_IP), SCC_IP); - break; - - case CLK_SLOW: /* force slow clock */ - if ((si->bus == SDIO_BUS) || (si->bus == PCMCIA_BUS)) - return (-1); - - if (si->ccrev >= 6) - OR_REG(&cc->slow_clk_ctl, SCC_FS); - break; - - case CLK_DYNAMIC: /* enable dynamic power control */ - scc = R_REG(&cc->slow_clk_ctl); - scc &= ~(SCC_FS | SCC_IP | SCC_XC); - if ((scc & SCC_SS_MASK) != SCC_SS_XTAL) - scc |= SCC_XC; - W_REG(&cc->slow_clk_ctl, scc); - - /* for dynamic control, we have to release our xtal_pu "force on" */ - if (scc & SCC_XC) - sb_pwrctl_xtal(sbh, XTAL, OFF); - break; - } - - /* Is the h/w forcing the use of the fast clk */ - forcefastclk = (bool)((R_REG(&cc->slow_clk_ctl) & SCC_IP) == SCC_IP); - -done: - sb_setcoreidx(sbh, origidx); - INTR_RESTORE(si, intr_val); - return (forcefastclk); -} - -/* 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_info_t *si; - - si = SB_INFO(sbh); - si->intr_arg = intr_arg; - si->intrsoff_fn = (sb_intrsoff_t)intrsoff_fn; - si->intrsrestore_fn = (sb_intrsrestore_t)intrsrestore_fn; - si->intrsenabled_fn = (sb_intrsenabled_t)intrsenabled_fn; - /* save current core id. when this function called, the current core - * must be the core which provides driver functions(il, et, wl, etc.) - */ - si->dev_coreid = si->coreid[si->curidx]; -} - - diff --git a/openwrt/package/linux/kernel-source/drivers/net/hnd/shared_ksyms.sh b/openwrt/package/linux/kernel-source/drivers/net/hnd/shared_ksyms.sh deleted file mode 100644 index 0187d47ea..000000000 --- a/openwrt/package/linux/kernel-source/drivers/net/hnd/shared_ksyms.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# -# Copyright 2004, Broadcom Corporation -# All Rights Reserved. -# -# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -# -# $Id$ -# - -cat < -#include -EOF - -for file in $* ; do - ${NM} $file | sed -ne 's/[0-9A-Fa-f]* [DT] \([^ ]*\)/extern void \1; EXPORT_SYMBOL(\1);/p' -done -- cgit v1.2.3