source: clfs-embedded/patches/linux-2.6.19.2-bcm947xx-2.patch@ 320a81a

Last change on this file since 320a81a was be76242, checked in by Jim Gifford <clfs@…>, 18 years ago

Updated to Linux 2.6.19.2
Fixes for uClibc
Changed > to &gt;
Updated all Linux Patches
Updated Linux Headers
Updated to Busybox 1.4.1
Added E2FSProgs since it was removed from Busybox
Fixed Typos

  • Property mode set to 100644
File size: 122.7 KB
  • arch/mips/Kconfig

    From da20def23769f672480f6d7bc472d1fa54e1bafa Mon Sep 17 00:00:00 2001
    From: Maarten Lankhorst <mlankhorst:cross-lfs.org>
    Date: Tue, 9 Jan 2007 22:42:47 +0000
    Subject: [PATCH] Add bcm947xx support
    
    ---
     arch/mips/Kconfig                                  |   20 +
     arch/mips/Makefile                                 |   12 +
     arch/mips/bcm947xx/Makefile                        |    8 +
     arch/mips/bcm947xx/cfe_env.c                       |  232 ++++++
     arch/mips/bcm947xx/include/nvram.h                 |   37 +
     arch/mips/bcm947xx/irq.c                           |   63 ++
     arch/mips/bcm947xx/nvram.c                         |  131 +++
     arch/mips/bcm947xx/pci.c                           |  227 +++++
     arch/mips/bcm947xx/prom.c                          |   59 ++
     arch/mips/bcm947xx/setup.c                         |  163 ++++
     arch/mips/bcm947xx/time.c                          |   62 ++
     arch/mips/cfe/Makefile                             |    5 +
     arch/mips/cfe/cfe.c                                |  533 ++++++++++++
     arch/mips/cfe/cfe_private.h                        |  176 ++++
     arch/mips/kernel/cpu-probe.c                       |   25 +
     arch/mips/kernel/head.S                            |    3 +
     arch/mips/kernel/proc.c                            |    2 +
     arch/mips/mm/tlbex.c                               |    2 +
     drivers/mtd/chips/cfi_cmdset_0002.c                |    3 -
     drivers/mtd/maps/Kconfig                           |    6 +
     drivers/mtd/maps/Makefile                          |    1 +
     drivers/mtd/maps/bcm47xx-flash.c                   |  477 +++++++++++
     drivers/net/Kconfig                                |    2 +-
     drivers/net/b44.c                                  |  873 +++++++++++---------
     drivers/net/b44.h                                  |   83 +--
     include/asm-mips/bootinfo.h                        |    6 +
     include/asm-mips/cfe.h                             |  189 +++++
     include/asm-mips/cpu.h                             |   11 +-
     include/asm-mips/mach-bcm947xx/kernel-entry-init.h |   26 +
     include/linux/pci_ids.h                            |    1 +
     30 files changed, 2988 insertions(+), 450 deletions(-)
    
    diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
    index 1443024..d845a8f 100644
    a b config MIPS  
    44        # Horrible source of confusion.  Die, die, die ...
    55        select EMBEDDED
    66
     7config CFE
     8        bool
     9        # Common Firmware Environment
     10
    711mainmenu "Linux/MIPS Kernel Configuration"
    812
    913menu "Machine selection"
    config MACH_JAZZ  
    222226         Members include the Acer PICA, MIPS Magnum 4000, MIPS Millenium and
    223227         Olivetti M700-10 workstations.
    224228
     229config BCM947XX
     230        bool "Support for BCM947xx based boards"
     231        select DMA_NONCOHERENT
     232        select HW_HAS_PCI
     233        select IRQ_CPU
     234        select SYS_HAS_CPU_MIPS32_R1
     235        select SYS_SUPPORTS_32BIT_KERNEL
     236        select SYS_SUPPORTS_LITTLE_ENDIAN
     237        select MIPS_CPU_SCACHE
     238        select SSB
     239        select SSB_DRIVER_MIPS
     240        select SSB_DRIVER_EXTIF
     241        select CFE
     242        help
     243         Support for BCM947xx based boards
     244
    225245config LASAT
    226246        bool "LASAT Networks platforms"
    227247        select DMA_NONCOHERENT
  • arch/mips/Makefile

    diff --git a/arch/mips/Makefile b/arch/mips/Makefile
    index d580d46..03429c5 100644
    a b libs-$(CONFIG_SIBYTE_BIGSUR) += arch/mip  
    571571load-$(CONFIG_SIBYTE_BIGSUR)    := 0xffffffff80100000
    572572
    573573#
     574# Broadcom BCM47XX boards
     575#
     576core-$(CONFIG_BCM947XX)         += arch/mips/bcm947xx/
     577cflags-$(CONFIG_BCM947XX)       += -Iarch/mips/bcm947xx/include -Iinclude/asm-mips/mach-bcm947xx
     578load-$(CONFIG_BCM947XX)         := 0xffffffff80001000
     579
     580#
     581# Common Firmware Environment
     582#
     583core-$(CONFIG_CFE)              += arch/mips/cfe/
     584
     585#
    574586# SNI RM200 PCI
    575587#
    576588core-$(CONFIG_SNI_RM200_PCI)    += arch/mips/sni/
  • new file arch/mips/bcm947xx/Makefile

    diff --git a/arch/mips/bcm947xx/Makefile b/arch/mips/bcm947xx/Makefile
    new file mode 100644
    index 0000000..b02e840
    - +  
     1#
     2# Makefile for the BCM47xx specific kernel interface routines
     3# under Linux.
     4#
     5
     6obj-y := irq.o prom.o setup.o time.o
     7obj-y += nvram.o cfe_env.o
     8#obj-y += pci.o
  • new file arch/mips/bcm947xx/cfe_env.c

    diff --git a/arch/mips/bcm947xx/cfe_env.c b/arch/mips/bcm947xx/cfe_env.c
    new file mode 100644
    index 0000000..6ef464f
    - +  
     1/*
     2 * CFE environment varialble access
     3 *
     4 * Copyright 2006, Felix Fietkau <nbd@openwrt.org>
     5 *
     6 * This program is free software; you can redistribute  it and/or modify it
     7 * under  the terms of  the GNU General  Public License as published by the
     8 * Free Software Foundation;  either version 2 of the  License, or (at your
     9 * option) any later version.
     10 *
     11 * Copyright 2001-2003, Broadcom Corporation
     12 *
     13 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
     14 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
     15 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
     16 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
     17 */
     18
     19#include <linux/init.h>
     20#include <linux/module.h>
     21#include <linux/kernel.h>
     22#include <linux/string.h>
     23#include <asm/io.h>
     24#include <asm/uaccess.h>
     25
     26#define NVRAM_SIZE       (0x1ff0)
     27static char _nvdata[NVRAM_SIZE] __initdata;
     28static char _valuestr[256] __initdata;
     29
     30/*
     31 * TLV types.  These codes are used in the "type-length-value"
     32 * encoding of the items stored in the NVRAM device (flash or EEPROM)
     33 *
     34 * The layout of the flash/nvram is as follows:
     35 *
     36 * <type> <length> <data ...> <type> <length> <data ...> <type_end>
     37 *
     38 * The type code of "ENV_TLV_TYPE_END" marks the end of the list.
     39 * The "length" field marks the length of the data section, not
     40 * including the type and length fields.
     41 *
     42 * Environment variables are stored as follows:
     43 *
     44 * <type_env> <length> <flags> <name> = <value>
     45 *
     46 * If bit 0 (low bit) is set, the length is an 8-bit value.
     47 * If bit 0 (low bit) is clear, the length is a 16-bit value
     48 *
     49 * Bit 7 set indicates "user" TLVs.  In this case, bit 0 still
     50 * indicates the size of the length field. 
     51 *
     52 * Flags are from the constants below:
     53 *
     54 */
     55#define ENV_LENGTH_16BITS       0x00    /* for low bit */
     56#define ENV_LENGTH_8BITS        0x01
     57
     58#define ENV_TYPE_USER           0x80
     59
     60#define ENV_CODE_SYS(n,l) (((n)<<1)|(l))
     61#define ENV_CODE_USER(n,l) ((((n)<<1)|(l)) | ENV_TYPE_USER)
     62
     63/*
     64 * The actual TLV types we support
     65 */
     66
     67#define ENV_TLV_TYPE_END        0x00   
     68#define ENV_TLV_TYPE_ENV        ENV_CODE_SYS(0,ENV_LENGTH_8BITS)
     69
     70/*
     71 * Environment variable flags
     72 */
     73
     74#define ENV_FLG_NORMAL          0x00    /* normal read/write */
     75#define ENV_FLG_BUILTIN         0x01    /* builtin - not stored in flash */
     76#define ENV_FLG_READONLY        0x02    /* read-only - cannot be changed */
     77
     78#define ENV_FLG_MASK            0xFF    /* mask of attributes we keep */
     79#define ENV_FLG_ADMIN           0x100   /* lets us internally override permissions */
     80
     81
     82/*  *********************************************************************
     83    *  _nvram_read(buffer,offset,length)
     84    * 
     85    *  Read data from the NVRAM device
     86    * 
     87    *  Input parameters:
     88    *      buffer - destination buffer
     89    *      offset - offset of data to read
     90    *      length - number of bytes to read
     91    *     
     92    *  Return value:
     93    *      number of bytes read, or <0 if error occured
     94    ********************************************************************* */
     95static int
     96_nvram_read(unsigned char *nv_buf, unsigned char *buffer, int offset, int length)
     97{
     98    int i;
     99    if (offset > NVRAM_SIZE)
     100        return -1;
     101
     102    for ( i = 0; i < length; i++) {
     103        buffer[i] = ((volatile unsigned char*)nv_buf)[offset + i];
     104    }
     105    return length;
     106}
     107
     108
     109static char*
     110_strnchr(const char *dest,int c,size_t cnt)
     111{
     112        while (*dest && (cnt > 0)) {
     113        if (*dest == c) return (char *) dest;
     114        dest++;
     115        cnt--;
     116        }
     117        return NULL;
     118}
     119
     120
     121
     122/*
     123 * Core support API: Externally visible.
     124 */
     125
     126/*
     127 * Get the value of an NVRAM variable
     128 * @param       name    name of variable to get
     129 * @return      value of variable or NULL if undefined
     130 */
     131
     132char*
     133cfe_env_get(unsigned char *nv_buf, char* name)
     134{
     135    int size;
     136    unsigned char *buffer;
     137    unsigned char *ptr;
     138    unsigned char *envval;
     139    unsigned int reclen;
     140    unsigned int rectype;
     141    int offset;
     142    int flg;
     143   
     144    size = NVRAM_SIZE;
     145    buffer = &_nvdata[0];
     146
     147    ptr = buffer;
     148    offset = 0;
     149
     150    /* Read the record type and length */
     151    if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
     152        goto error;
     153    }
     154   
     155    while ((*ptr != ENV_TLV_TYPE_END)  && (size > 1)) {
     156
     157        /* Adjust pointer for TLV type */
     158        rectype = *(ptr);
     159        offset++;
     160        size--;
     161
     162        /*
     163         * Read the length.  It can be either 1 or 2 bytes
     164         * depending on the code
     165         */
     166        if (rectype & ENV_LENGTH_8BITS) {
     167            /* Read the record type and length - 8 bits */
     168            if (_nvram_read(nv_buf, ptr,offset,1) != 1) {
     169                goto error;
     170            }
     171            reclen = *(ptr);
     172            size--;
     173            offset++;
     174        }
     175        else {
     176            /* Read the record type and length - 16 bits, MSB first */
     177            if (_nvram_read(nv_buf, ptr,offset,2) != 2) {
     178                goto error;
     179            }
     180            reclen = (((unsigned int) *(ptr)) << 8) + (unsigned int) *(ptr+1);
     181            size -= 2;
     182            offset += 2;
     183        }
     184
     185        if (reclen > size)
     186            break;      /* should not happen, bad NVRAM */
     187
     188        switch (rectype) {
     189            case ENV_TLV_TYPE_ENV:
     190                /* Read the TLV data */
     191                if (_nvram_read(nv_buf, ptr,offset,reclen) != reclen)
     192                    goto error;
     193                flg = *ptr++;
     194                envval = (unsigned char *) _strnchr(ptr,'=',(reclen-1));
     195                if (envval) {
     196                    *envval++ = '\0';
     197                    memcpy(_valuestr,envval,(reclen-1)-(envval-ptr));
     198                    _valuestr[(reclen-1)-(envval-ptr)] = '\0';
     199#if 0                   
     200                    printk(KERN_INFO "NVRAM:%s=%s\n", ptr, _valuestr);
     201#endif
     202                    if(!strcmp(ptr, name)){
     203                        return _valuestr;
     204                    }
     205                    if((strlen(ptr) > 1) && !strcmp(&ptr[1], name))
     206                        return _valuestr;
     207                }
     208                break;
     209               
     210            default:
     211                /* Unknown TLV type, skip it. */
     212                break;
     213            }
     214
     215        /*
     216         * Advance to next TLV
     217         */
     218               
     219        size -= (int)reclen;
     220        offset += reclen;
     221
     222        /* Read the next record type */
     223        ptr = buffer;
     224        if (_nvram_read(nv_buf, ptr,offset,1) != 1)
     225            goto error;
     226        }
     227
     228error:
     229    return NULL;
     230
     231}
     232
  • new file arch/mips/bcm947xx/include/nvram.h

    diff --git a/arch/mips/bcm947xx/include/nvram.h b/arch/mips/bcm947xx/include/nvram.h
    new file mode 100644
    index 0000000..6bb18e8
    - +  
     1/*
     2 *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
     3 *
     4 *  This program is free software; you can redistribute  it and/or modify it
     5 *  under  the terms of  the GNU General  Public License as published by the
     6 *  Free Software Foundation;  either version 2 of the  License, or (at your
     7 *  option) any later version.
     8 */
     9
     10#ifndef __NVRAM_H
     11#define __NVRAM_H
     12
     13struct nvram_header {
     14        u32 magic;
     15        u32 len;
     16        u32 crc_ver_init;       /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
     17        u32 config_refresh;     /* 0:15 sdram_config, 16:31 sdram_refresh */
     18        u32 config_ncdl;        /* ncdl values for memc */
     19};
     20
     21struct nvram_tuple {
     22        char *name;
     23        char *value;
     24        struct nvram_tuple *next;
     25};
     26
     27#define NVRAM_HEADER            0x48534C46      /* 'FLSH' */
     28#define NVRAM_VERSION           1
     29#define NVRAM_HEADER_SIZE       20
     30#define NVRAM_SPACE             0x8000
     31
     32#define NVRAM_MAX_VALUE_LEN 255
     33#define NVRAM_MAX_PARAM_LEN 64
     34
     35char *nvram_get(const char *name);
     36
     37#endif
  • new file arch/mips/bcm947xx/irq.c

    diff --git a/arch/mips/bcm947xx/irq.c b/arch/mips/bcm947xx/irq.c
    new file mode 100644
    index 0000000..8727a4f
    - +  
     1/*
     2 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     3 *
     4 *  This program is free software; you can redistribute  it and/or modify it
     5 *  under  the terms of  the GNU General  Public License as published by the
     6 *  Free Software Foundation;  either version 2 of the  License, or (at your
     7 *  option) any later version.
     8 *
     9 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     10 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     11 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     12 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     13 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     14 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     15 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     16 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     17 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     18 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     19 *
     20 *  You should have received a copy of the  GNU General Public License along
     21 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     22 *  675 Mass Ave, Cambridge, MA 02139, USA.
     23 */
     24
     25#include <linux/errno.h>
     26#include <linux/init.h>
     27#include <linux/interrupt.h>
     28#include <linux/irq.h>
     29#include <linux/module.h>
     30#include <linux/smp.h>
     31#include <linux/types.h>
     32
     33#include <asm/cpu.h>
     34#include <asm/io.h>
     35#include <asm/irq.h>
     36#include <asm/irq_cpu.h>
     37
     38void plat_irq_dispatch(void)
     39{
     40        u32 cause;
     41
     42        cause = read_c0_cause() & read_c0_status() & CAUSEF_IP;
     43
     44        clear_c0_status(cause);
     45
     46        if (cause & CAUSEF_IP7)
     47                do_IRQ(7);
     48        if (cause & CAUSEF_IP2)
     49                do_IRQ(2);
     50        if (cause & CAUSEF_IP3)
     51                do_IRQ(3);
     52        if (cause & CAUSEF_IP4)
     53                do_IRQ(4);
     54        if (cause & CAUSEF_IP5)
     55                do_IRQ(5);
     56        if (cause & CAUSEF_IP6)
     57                do_IRQ(6);
     58}
     59
     60void __init arch_init_irq(void)
     61{
     62        mips_cpu_irq_init(0);
     63}
  • new file arch/mips/bcm947xx/nvram.c

    diff --git a/arch/mips/bcm947xx/nvram.c b/arch/mips/bcm947xx/nvram.c
    new file mode 100644
    index 0000000..d147adb
    - +  
     1/*
     2 * BCM947xx nvram variable access
     3 *
     4 * Copyright 2006, Felix Fietkau <nbd@openwrt.org>
     5 *
     6 * This program is free software; you can redistribute  it and/or modify it
     7 * under  the terms of  the GNU General  Public License as published by the
     8 * Free Software Foundation;  either version 2 of the  License, or (at your
     9 * option) any later version.
     10 *
     11 *
     12 * Copyright 2005, Broadcom Corporation
     13 *
     14 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
     15 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
     16 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
     17 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
     18 *
     19 */
     20
     21#include <linux/init.h>
     22#include <linux/module.h>
     23#include <linux/ssb.h>
     24#include <linux/kernel.h>
     25#include <linux/string.h>
     26#include <linux/interrupt.h>
     27#include <linux/spinlock.h>
     28#include <linux/slab.h>
     29#include <asm/byteorder.h>
     30#include <asm/bootinfo.h>
     31#include <asm/addrspace.h>
     32#include <asm/io.h>
     33#include <asm/uaccess.h>
     34
     35#include <nvram.h>
     36
     37#define MB * 1048576
     38extern struct ssb_bus ssb;
     39
     40static char nvram_buf[NVRAM_SPACE];
     41static int cfe_env;
     42extern char *cfe_env_get(char *nv_buf, const char *name);
     43               
     44/* Probe for NVRAM header */
     45static void __init early_nvram_init(void)
     46{
     47        struct ssb_mipscore *mcore = &ssb.mipscore;
     48        struct nvram_header *header;
     49        int i;
     50        u32 base, lim, off;
     51        u32 *src, *dst;
     52       
     53        base = mcore->flash_window;
     54        lim = mcore->flash_window_size;
     55        cfe_env = 0;
     56
     57       
     58        /* XXX: hack for supporting the CFE environment stuff on WGT634U */
     59        if (lim >= 8 MB) {
     60                src = (u32 *) KSEG1ADDR(base + 8 MB - 0x2000);
     61                dst = (u32 *) nvram_buf;
     62
     63                if ((*src & 0xff00ff) == 0x000001) {
     64                        printk("early_nvram_init: WGT634U NVRAM found.\n");
     65
     66                        for (i = 0; i < 0x1ff0; i++) {
     67                                if (*src == 0xFFFFFFFF)
     68                                        break;
     69                                *dst++ = *src++;
     70                        }
     71                        cfe_env = 1;
     72                        return;
     73                }
     74        }
     75
     76        off = 0x20000;
     77        while (off <= lim) {
     78                /* Windowed flash access */
     79                header = (struct nvram_header *) KSEG1ADDR(base + off - NVRAM_SPACE);
     80                if (header->magic == NVRAM_HEADER)
     81                        goto found;
     82                off <<= 1;
     83        }
     84
     85        /* Try embedded NVRAM at 4 KB and 1 KB as last resorts */
     86        header = (struct nvram_header *) KSEG1ADDR(base + 4096);
     87        if (header->magic == NVRAM_HEADER)
     88                goto found;
     89       
     90        header = (struct nvram_header *) KSEG1ADDR(base + 1024);
     91        if (header->magic == NVRAM_HEADER)
     92                goto found;
     93       
     94        return;
     95
     96found:
     97        src = (u32 *) header;
     98        dst = (u32 *) nvram_buf;
     99        for (i = 0; i < sizeof(struct nvram_header); i += 4)
     100                *dst++ = *src++;
     101        for (; i < header->len && i < NVRAM_SPACE; i += 4)
     102                *dst++ = le32_to_cpu(*src++);
     103}
     104
     105char *nvram_get(const char *name)
     106{
     107        char *var, *value, *end, *eq;
     108
     109        if (!name)
     110                return NULL;
     111
     112        if (!nvram_buf[0])
     113                early_nvram_init();
     114
     115        if (cfe_env)
     116                return cfe_env_get(nvram_buf, name);
     117
     118        /* Look for name=value and return value */
     119        var = &nvram_buf[sizeof(struct nvram_header)];
     120        end = nvram_buf + sizeof(nvram_buf) - 2;
     121        end[0] = end[1] = '\0';
     122        for (; *var; var = value + strlen(value) + 1) {
     123                if (!(eq = strchr(var, '=')))
     124                        break;
     125                value = eq + 1;
     126                if ((eq - var) == strlen(name) && strncmp(var, name, (eq - var)) == 0)
     127                        return value;
     128        }
     129
     130        return NULL;
     131}
  • new file arch/mips/bcm947xx/pci.c

    diff --git a/arch/mips/bcm947xx/pci.c b/arch/mips/bcm947xx/pci.c
    new file mode 100644
    index 0000000..bdc3d96
    - +  
     1#include <linux/kernel.h>
     2#include <linux/init.h>
     3#include <linux/pci.h>
     4#include <linux/types.h>
     5
     6#include <asm/cpu.h>
     7#include <asm/io.h>
     8
     9#include <typedefs.h>
     10#include <osl.h>
     11#include <sbutils.h>
     12#include <sbmips.h>
     13#include <sbconfig.h>
     14#include <sbpci.h>
     15#include <bcmdevs.h>
     16#include <pcicfg.h>
     17
     18extern sb_t *sbh;
     19extern spinlock_t sbh_lock;
     20
     21
     22static int
     23sb_pci_read_config(struct pci_bus *bus, unsigned int devfn,
     24                                int reg, int size, u32 *val)
     25{
     26        int ret;
     27        unsigned long flags;
     28       
     29        spin_lock_irqsave(&sbh_lock, flags);
     30        ret = sbpci_read_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, val, size);
     31        spin_unlock_irqrestore(&sbh_lock, flags);
     32
     33        return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
     34}
     35
     36static int
     37sb_pci_write_config(struct pci_bus *bus, unsigned int devfn,
     38                                int reg, int size, u32 val)
     39{
     40        int ret;
     41        unsigned long flags;
     42       
     43        spin_lock_irqsave(&sbh_lock, flags);
     44        ret = sbpci_write_config(sbh, bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), reg, &val, size);
     45        spin_unlock_irqrestore(&sbh_lock, flags);
     46
     47        return ret ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
     48}
     49
     50
     51static struct pci_ops sb_pci_ops = {
     52        .read   = sb_pci_read_config,
     53        .write  = sb_pci_write_config,
     54};
     55
     56static struct resource sb_pci_mem_resource = {
     57        .name   = "SB PCI Memory resources",
     58        .start  = SB_ENUM_BASE,
     59        .end    = SB_ENUM_LIM - 1,
     60        .flags  = IORESOURCE_MEM,
     61};
     62
     63static struct resource sb_pci_io_resource = {
     64        .name   = "SB PCI I/O resources",
     65        .start  = 0x000,
     66        .end    = 0x0FF,
     67        .flags  = IORESOURCE_IO,
     68};
     69
     70static struct pci_controller bcm47xx_sb_pci_controller = {
     71        .pci_ops        = &sb_pci_ops,
     72        .mem_resource   = &sb_pci_mem_resource,
     73        .io_resource    = &sb_pci_io_resource,
     74};
     75
     76static struct resource ext_pci_mem_resource = {
     77        .name   = "Ext PCI Memory resources",
     78        .start  = 0x40000000,
     79        .end    = 0x7fffffff,
     80        .flags  = IORESOURCE_MEM,
     81};
     82
     83static struct resource ext_pci_io_resource = {
     84        .name   = "Ext PCI I/O resources",
     85        .start  = 0x100,
     86        .end    = 0x7FF,
     87        .flags  = IORESOURCE_IO,
     88};
     89
     90static struct pci_controller bcm47xx_ext_pci_controller = {
     91        .pci_ops        = &sb_pci_ops,
     92        .io_resource    = &ext_pci_io_resource,
     93        .mem_resource   = &ext_pci_mem_resource,
     94        .mem_offset             = 0x24000000,
     95};
     96
     97void bcm47xx_pci_init(void)
     98{
     99        unsigned long flags;
     100       
     101        spin_lock_irqsave(&sbh_lock, flags);
     102        sbpci_init(sbh);
     103        spin_unlock_irqrestore(&sbh_lock, flags);
     104
     105        set_io_port_base((unsigned long) ioremap_nocache(SB_PCI_MEM, 0x04000000));
     106
     107        register_pci_controller(&bcm47xx_sb_pci_controller);
     108        register_pci_controller(&bcm47xx_ext_pci_controller);
     109}
     110
     111int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
     112{
     113        unsigned long flags;
     114        u8 irq;
     115        uint idx;
     116       
     117        /* external: use the irq of the pci core */
     118        if (dev->bus->number >= 1) {
     119                spin_lock_irqsave(&sbh_lock, flags);
     120                idx = sb_coreidx(sbh);
     121                sb_setcore(sbh, SB_PCI, 0);
     122                irq = sb_irq(sbh);
     123                sb_setcoreidx(sbh, idx);
     124                spin_unlock_irqrestore(&sbh_lock, flags);
     125               
     126                return irq + 2;
     127        }
     128       
     129        /* internal */
     130        pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
     131        return irq + 2;
     132}
     133
     134u32 pci_iobase = 0x100;
     135u32 pci_membase = SB_PCI_DMA;
     136
     137static void bcm47xx_fixup_device(struct pci_dev *d)
     138{
     139        struct resource *res;
     140        int pos, size;
     141        u32 *base;
     142
     143        if (d->bus->number == 0)
     144                return;
     145       
     146        printk("PCI: Fixing up device %s\n", pci_name(d));
     147
     148        /* Fix up resource bases */
     149        for (pos = 0; pos < 6; pos++) {
     150                res = &d->resource[pos];
     151                base = ((res->flags & IORESOURCE_IO) ? &pci_iobase : &pci_membase);
     152                if (res->end) {
     153                        size = res->end - res->start + 1;
     154                        if (*base & (size - 1))
     155                                *base = (*base + size) & ~(size - 1);
     156                        res->start = *base;
     157                        res->end = res->start + size - 1;
     158                        *base += size;
     159                        pci_write_config_dword(d, PCI_BASE_ADDRESS_0 + (pos << 2), res->start);
     160                }
     161                /* Fix up PCI bridge BAR0 only */
     162                if (d->bus->number == 1 && PCI_SLOT(d->devfn) == 0)
     163                        break;
     164        }
     165        /* Fix up interrupt lines */
     166        if (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))
     167                d->irq = (pci_find_device(VENDOR_BROADCOM, SB_PCI, NULL))->irq;
     168        pci_write_config_byte(d, PCI_INTERRUPT_LINE, d->irq);
     169}
     170
     171
     172static void bcm47xx_fixup_bridge(struct pci_dev *dev)
     173{
     174        if (dev->bus->number != 1 || PCI_SLOT(dev->devfn) != 0)
     175                return;
     176       
     177        printk("PCI: fixing up bridge\n");
     178
     179        /* Enable PCI bridge bus mastering and memory space */
     180        pci_set_master(dev);
     181        pcibios_enable_device(dev, ~0);
     182       
     183        /* Enable PCI bridge BAR1 prefetch and burst */
     184        pci_write_config_dword(dev, PCI_BAR1_CONTROL, 3);
     185}
     186
     187/* Do platform specific device initialization at pci_enable_device() time */
     188int pcibios_plat_dev_init(struct pci_dev *dev)
     189{
     190        uint coreidx;
     191        unsigned long flags;
     192       
     193        bcm47xx_fixup_device(dev);
     194
     195        /* These cores come out of reset enabled */
     196        if ((dev->bus->number != 0) ||
     197                (dev->device == SB_MIPS) ||
     198                (dev->device == SB_MIPS33) ||
     199                (dev->device == SB_EXTIF) ||
     200                (dev->device == SB_CC))
     201                return 0;
     202
     203        /* Do a core reset */
     204        spin_lock_irqsave(&sbh_lock, flags);
     205        coreidx = sb_coreidx(sbh);
     206        if (sb_setcoreidx(sbh, PCI_SLOT(dev->devfn)) && (sb_coreid(sbh) == SB_USB)) {
     207                /*
     208                 * The USB core requires a special bit to be set during core
     209                 * reset to enable host (OHCI) mode. Resetting the SB core in
     210                 * pcibios_enable_device() is a hack for compatibility with
     211                 * vanilla usb-ohci so that it does not have to know about
     212                 * SB. A driver that wants to use the USB core in device mode
     213                 * should know about SB and should reset the bit back to 0
     214                 * after calling pcibios_enable_device().
     215                 */
     216                sb_core_disable(sbh, sb_coreflags(sbh, 0, 0));
     217                sb_core_reset(sbh, 1 << 29);
     218        } else {
     219                sb_core_reset(sbh, 0);
     220        }
     221        sb_setcoreidx(sbh, coreidx);
     222        spin_unlock_irqrestore(&sbh_lock, flags);
     223       
     224        return 0;
     225}
     226
     227DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, bcm47xx_fixup_bridge);
  • new file arch/mips/bcm947xx/prom.c

    diff --git a/arch/mips/bcm947xx/prom.c b/arch/mips/bcm947xx/prom.c
    new file mode 100644
    index 0000000..7a6981d
    - +  
     1/*
     2 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     3 *
     4 *  This program is free software; you can redistribute  it and/or modify it
     5 *  under  the terms of  the GNU General  Public License as published by the
     6 *  Free Software Foundation;  either version 2 of the  License, or (at your
     7 *  option) any later version.
     8 *
     9 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     10 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     11 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     12 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     13 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     14 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     15 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     16 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     17 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     18 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     19 *
     20 *  You should have received a copy of the  GNU General Public License along
     21 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     22 *  675 Mass Ave, Cambridge, MA 02139, USA.
     23 */
     24
     25#include <linux/init.h>
     26#include <linux/mm.h>
     27#include <linux/sched.h>
     28#include <linux/bootmem.h>
     29
     30#include <asm/addrspace.h>
     31#include <asm/bootinfo.h>
     32#include <asm/pmon.h>
     33
     34const char *get_system_type(void)
     35{
     36        return "Broadcom BCM47xx";
     37}
     38
     39void __init prom_init(void)
     40{
     41        unsigned long mem;
     42
     43        mips_machgroup = MACH_GROUP_BRCM;
     44        mips_machtype = MACH_BCM47XX;
     45
     46        /* Figure out memory size by finding aliases */
     47        for (mem = (1 << 20); mem < (128 << 20); mem += (1 << 20)) {
     48                if (*(unsigned long *)((unsigned long)(prom_init) + mem) ==
     49                    *(unsigned long *)(prom_init))
     50                        break;
     51        }
     52
     53        add_memory_region(0, mem, BOOT_MEM_RAM);
     54}
     55
     56unsigned long __init prom_free_prom_memory(void)
     57{
     58        return 0;
     59}
  • new file arch/mips/bcm947xx/setup.c

    diff --git a/arch/mips/bcm947xx/setup.c b/arch/mips/bcm947xx/setup.c
    new file mode 100644
    index 0000000..5ebbd02
    - +  
     1/*
     2 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     3 *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
     4 *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
     5 *  Copyright (C) 2006 Michael Buesch
     6 *
     7 *  This program is free software; you can redistribute  it and/or modify it
     8 *  under  the terms of  the GNU General  Public License as published by the
     9 *  Free Software Foundation;  either version 2 of the  License, or (at your
     10 *  option) any later version.
     11 *
     12 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     13 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     14 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     15 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     16 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     17 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     18 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     19 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     20 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     21 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     22 *
     23 *  You should have received a copy of the  GNU General Public License along
     24 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     25 *  675 Mass Ave, Cambridge, MA 02139, USA.
     26 */
     27
     28#include <linux/init.h>
     29#include <linux/types.h>
     30#include <linux/tty.h>
     31#include <linux/serial.h>
     32#include <linux/serial_core.h>
     33#include <linux/serial_reg.h>
     34#include <asm/bootinfo.h>
     35#include <asm/time.h>
     36#include <asm/reboot.h>
     37#include <asm/cfe.h>
     38#include <linux/pm.h>
     39#include <linux/ssb.h>
     40
     41#include <nvram.h>
     42
     43extern void bcm47xx_pci_init(void);
     44extern void bcm47xx_time_init(void);
     45
     46struct ssb_bus ssb;
     47
     48static void bcm47xx_machine_restart(char *command)
     49{
     50        printk(KERN_ALERT "Please stand by while rebooting the system...\n");
     51        local_irq_disable();
     52        /* CFE has a reboot callback, but that does not work.
     53         * Oopses with: Reserved instruction in kernel code.
     54         */
     55
     56        /* Set the watchdog timer to reset immediately */
     57//TODO  sb_watchdog(sbh, 1);
     58        while (1)
     59                cpu_relax();
     60}
     61
     62static void bcm47xx_machine_halt(void)
     63{
     64        /* Disable interrupts and watchdog and spin forever */
     65        local_irq_disable();
     66//TODO  sb_watchdog(sbh, 0);
     67        while (1)
     68                cpu_relax();
     69}
     70
     71static void e_aton(char *str, char *dest)
     72{
     73        int i = 0;
     74
     75        if (str == NULL) {
     76                memset(dest, 0, 6);
     77                return;
     78        }
     79       
     80        for (;;) {
     81                dest[i++] = (char) simple_strtoul(str, NULL, 16);
     82                str += 2;
     83                if (!*str++ || i == 6)
     84                        break;
     85        }
     86}
     87
     88static void bcm47xx_fill_sprom(struct ssb_sprom *sprom)
     89{
     90        // TODO
     91}
     92
     93static void bcm47xx_fill_sprom_nvram(struct ssb_sprom *sprom)
     94{
     95        char *s;
     96
     97        memset(sprom, 0, sizeof(struct ssb_sprom));
     98       
     99        sprom->revision = 3;
     100        if ((s = nvram_get("et0macaddr")))
     101                e_aton(s, sprom->r1.et0mac);
     102        if ((s = nvram_get("et1macaddr")))
     103                e_aton(s, sprom->r1.et1mac);
     104        if ((s = nvram_get("il0macaddr")))
     105                e_aton(s, sprom->r1.il0mac);
     106        if ((s = nvram_get("et0phyaddr")))
     107                sprom->r1.et0phyaddr = simple_strtoul(s, NULL, 10);
     108        if ((s = nvram_get("et1phyaddr")))
     109                sprom->r1.et1phyaddr = simple_strtoul(s, NULL, 10);
     110}
     111
     112void __init plat_mem_setup(void)
     113{
     114        int i, err;
     115        char *s;
     116        struct ssb_mipscore *mcore;
     117
     118        err = ssb_bus_ssbbus_register(&ssb, SSB_ENUM_BASE, bcm47xx_fill_sprom);
     119        if (err) {
     120                const char *msg = "Failed to initialize SSB bus (err %d)\n";
     121                cfe_printk(msg, err); /* Make sure the message gets out of the box. */
     122                panic(msg, err);
     123        }
     124        mcore = &ssb.mipscore;
     125
     126        /* FIXME: the nvram init depends on the ssb being fully initializes,
     127         * can't use the fill_sprom callback yet! */
     128        bcm47xx_fill_sprom_nvram(&ssb.sprom);
     129       
     130        s = nvram_get("kernel_args");
     131        if (s && !strncmp(s, "console=ttyS1", 13) && (mcore->nr_serial_ports >= 2)) {
     132                struct ssb_serial_port port;
     133
     134                /* swap serial ports */
     135                memcpy(&port, &mcore->serial_ports[0], sizeof(port));
     136                memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], sizeof(port));
     137                memcpy(&mcore->serial_ports[1], &port, sizeof(port));
     138        }
     139
     140        for (i = 0; i < mcore->nr_serial_ports; i++) {
     141                struct ssb_serial_port *port = &(mcore->serial_ports[i]);
     142                struct uart_port s;
     143       
     144                memset(&s, 0, sizeof(s));
     145                s.line = i;
     146                s.membase = port->regs;
     147                s.irq = port->irq + 2;//FIXME?
     148                s.uartclk = port->baud_base;
     149                s.flags = ASYNC_BOOT_AUTOCONF;
     150                s.iotype = SERIAL_IO_MEM;
     151                s.regshift = port->reg_shift;
     152
     153                early_serial_setup(&s);
     154        }
     155        cfe_printk("Serial init done.\n");
     156
     157        _machine_restart = bcm47xx_machine_restart;
     158        _machine_halt = bcm47xx_machine_halt;
     159        pm_power_off = bcm47xx_machine_halt;
     160
     161        board_time_init = bcm47xx_time_init;//FIXME move into ssb
     162}
     163
  • new file arch/mips/bcm947xx/time.c

    diff --git a/arch/mips/bcm947xx/time.c b/arch/mips/bcm947xx/time.c
    new file mode 100644
    index 0000000..0adf6af
    - +  
     1/*
     2 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     3 *
     4 *  This program is free software; you can redistribute  it and/or modify it
     5 *  under  the terms of  the GNU General  Public License as published by the
     6 *  Free Software Foundation;  either version 2 of the  License, or (at your
     7 *  option) any later version.
     8 *
     9 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     10 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     11 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     12 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     13 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     14 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     15 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     16 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     17 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     18 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     19 *
     20 *  You should have received a copy of the  GNU General Public License along
     21 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     22 *  675 Mass Ave, Cambridge, MA 02139, USA.
     23 */
     24
     25#include <linux/init.h>
     26#include <linux/kernel.h>
     27#include <linux/sched.h>
     28#include <linux/serial_reg.h>
     29#include <linux/interrupt.h>
     30#include <linux/ssb.h>
     31#include <asm/addrspace.h>
     32#include <asm/io.h>
     33#include <asm/time.h>
     34
     35extern struct ssb_bus ssb;
     36
     37void __init
     38bcm47xx_time_init(void)
     39{
     40        unsigned long hz;
     41
     42        /*
     43         * Use deterministic values for initial counter interrupt
     44         * so that calibrate delay avoids encountering a counter wrap.
     45         */
     46        write_c0_count(0);
     47        write_c0_compare(0xffff);
     48
     49        hz = ssb_clockspeed(&ssb);
     50        if (!hz)
     51                hz = 100000000;
     52
     53        /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */
     54        mips_hpt_frequency = hz;
     55}
     56
     57void __init
     58plat_timer_setup(struct irqaction *irq)
     59{
     60        /* Enable the timer interrupt */
     61        setup_irq(7, irq);
     62}
  • new file arch/mips/cfe/Makefile

    diff --git a/arch/mips/cfe/Makefile b/arch/mips/cfe/Makefile
    new file mode 100644
    index 0000000..d9f046a
    - +  
     1#
     2# Makefile for the Broadcom Common Firmware Environment support
     3#
     4
     5obj-y += cfe.o
  • new file arch/mips/cfe/cfe.c

    diff --git a/arch/mips/cfe/cfe.c b/arch/mips/cfe/cfe.c
    new file mode 100644
    index 0000000..6d16111
    - +  
     1/*
     2 * Broadcom Common Firmware Environment (CFE) support
     3 *
     4 * Copyright 2000, 2001, 2002
     5 * Broadcom Corporation. All rights reserved.
     6 *
     7 * Copyright (C) 2006 Michael Buesch
     8 *
     9 * Original Authors:  Mitch Lichtenberg, Chris Demetriou
     10 *
     11 * This software is furnished under license and may be used and copied only
     12 * in accordance with the following terms and conditions.  Subject to these
     13 * conditions, you may download, copy, install, use, modify and distribute
     14 * modified or unmodified copies of this software in source and/or binary
     15 * form. No title or ownership is transferred hereby.
     16 *
     17 * 1) Any source code used, modified or distributed must reproduce and
     18 *    retain this copyright notice and list of conditions as they appear in
     19 *    the source file.
     20 *
     21 * 2) No right is granted to use any trade name, trademark, or logo of
     22 *    Broadcom Corporation.  The "Broadcom Corporation" name may not be
     23 *    used to endorse or promote products derived from this software
     24 *    without the prior written permission of Broadcom Corporation.
     25 *
     26 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
     27 *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
     28 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
     29 *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
     30 *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
     31 *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     34 *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     35 *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     36 *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     37 */
     38
     39#include <linux/init.h>
     40#include <linux/string.h>
     41#include <linux/errno.h>
     42#include <linux/spinlock.h>
     43#include <asm/cfe.h>
     44
     45#include "cfe_private.h"
     46
     47
     48static cfe_uint_t cfe_handle;
     49static int (*cfe_trampoline)(long handle, long iocb);
     50
     51
     52#include <linux/kernel.h>
     53
     54void __init cfe_setup(unsigned long fwarg0, unsigned long fwarg1,
     55                      unsigned long fwarg2, unsigned long fwarg3)
     56{
     57        if (fwarg3 == 0x80300000) {
     58                /* WRT54G workaround */
     59                fwarg3 = CFE_EPTSEAL;
     60                fwarg2 = 0xBFC00500;
     61        }
     62        if (fwarg3 != CFE_EPTSEAL) {
     63                /* We are not booted from CFE */
     64                return;
     65        }
     66        if (fwarg1 == 0) {
     67                /* We are on the boot CPU */
     68                cfe_handle = (cfe_uint_t)fwarg0;
     69                cfe_trampoline = CFE_TO_PTR(fwarg2);
     70        }
     71}
     72
     73int cfe_vprintk(const char *fmt, va_list args)
     74{
     75        static char buffer[1024];
     76        static DEFINE_SPINLOCK(lock);
     77        static const char pfx[] = "CFE-console: ";
     78        static const size_t pfx_len = sizeof(pfx) - 1;
     79        unsigned long flags;
     80        int len, cnt, pos;
     81        int handle;
     82        int res;
     83
     84        if (!cfe_present())
     85                return -ENODEV;
     86
     87        spin_lock_irqsave(&lock, flags);
     88        handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
     89        if (CFE_ISERR(handle)) {
     90                len = -EIO;
     91                goto out;
     92        }
     93        strcpy(buffer, pfx);
     94        len = vscnprintf(buffer + pfx_len,
     95                         sizeof(buffer) - pfx_len - 2,
     96                         fmt, args);
     97        len += pfx_len;
     98        /* The CFE console requires CR-LF line-ends.
     99         * Add a CR, if we only terminate lines with a LF.
     100         * This does only fix CR-LF at the end of the string.
     101         * So for multiple lines, use multiple cfe_vprintk calls.
     102         */
     103        if (len > 1 &&
     104            buffer[len - 1] == '\n' && buffer[len - 2] != '\r') {
     105                buffer[len - 1] = '\r';
     106                buffer[len] = '\n';
     107                len += 1;
     108        }
     109        cnt = len;
     110        pos = 0;
     111        while (cnt > 0) {
     112                res = cfe_write(handle, buffer + pos, len - pos);
     113                if (CFE_ISERR(res)) {
     114                        len = -EIO;
     115                        goto out;
     116                }
     117                cnt -= res;
     118                pos += res;
     119        }
     120out:
     121        spin_unlock_irqrestore(&lock, flags);
     122
     123        return len;
     124}
     125
     126int cfe_printk(const char *fmt, ...)
     127{
     128        va_list args;
     129        int res;
     130
     131        va_start(args, fmt);
     132        res = cfe_vprintk(fmt, args);
     133        va_end(args);
     134
     135        return res;
     136}
     137
     138static int cfe_iocb_dispatch(struct cfe_iocb *iocb)
     139{
     140        if (!cfe_present())
     141                return CFE_ERR_UNSUPPORTED;
     142        return cfe_trampoline((long)cfe_handle, (long)iocb);
     143}
     144
     145int cfe_present(void)
     146{
     147        return (cfe_trampoline != NULL);
     148}
     149
     150int cfe_close(int handle)
     151{
     152        struct cfe_iocb iocb;
     153        int err;
     154
     155        memset(&iocb, 0, sizeof(iocb));
     156        iocb.fcode = CFE_CMD_DEV_CLOSE;
     157        iocb.handle = handle;
     158
     159        err = cfe_iocb_dispatch(&iocb);
     160
     161        return (CFE_ISERR(err)) ? err : iocb.status;
     162}
     163
     164int cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1)
     165{
     166        struct cfe_iocb iocb;
     167        int err;
     168
     169        memset(&iocb, 0, sizeof(iocb));
     170        iocb.fcode = CFE_CMD_FW_CPUCTL;
     171        iocb.psize = sizeof(struct cfe_iocb_cpuctl);
     172        iocb.cpuctl.number = cpu;
     173        iocb.cpuctl.command = CFE_CPU_CMD_START;
     174        iocb.cpuctl.gp = gp;
     175        iocb.cpuctl.sp = sp;
     176        iocb.cpuctl.a1 = a1;
     177        iocb.cpuctl.start_addr = (long)fn;
     178
     179        err = cfe_iocb_dispatch(&iocb);
     180
     181        return (CFE_ISERR(err)) ? err : iocb.status;
     182}
     183
     184int cfe_cpu_stop(int cpu)
     185{
     186        struct cfe_iocb iocb;
     187        int err;
     188
     189        memset(&iocb, 0, sizeof(iocb));
     190        iocb.fcode = CFE_CMD_FW_CPUCTL;
     191        iocb.psize = sizeof(struct cfe_iocb_cpuctl);
     192        iocb.cpuctl.number = cpu;
     193        iocb.cpuctl.command = CFE_CPU_CMD_STOP;
     194
     195        err = cfe_iocb_dispatch(&iocb);
     196
     197        return (CFE_ISERR(err)) ? err : iocb.status;
     198}
     199
     200int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen)
     201{
     202        struct cfe_iocb iocb;
     203        int err;
     204
     205        memset(&iocb, 0, sizeof(iocb));
     206        iocb.fcode = CFE_CMD_ENV_ENUM;
     207        iocb.psize = sizeof(struct cfe_iocb_envbuf);
     208        iocb.envbuf.index = idx;
     209        iocb.envbuf.name = PTR_TO_CFE(name);
     210        iocb.envbuf.name_len = namelen;
     211        iocb.envbuf.val = PTR_TO_CFE(val);
     212        iocb.envbuf.val_len = vallen;
     213
     214        err = cfe_iocb_dispatch(&iocb);
     215
     216        return (CFE_ISERR(err)) ? err : iocb.status;
     217}
     218
     219int cfe_enumdev(int idx, char *name, int namelen)
     220{
     221        struct cfe_iocb iocb;
     222        int err;
     223
     224        memset(&iocb, 0, sizeof(iocb));
     225
     226        iocb.fcode = CFE_CMD_DEV_ENUM;
     227        iocb.psize = sizeof(struct cfe_iocb_envbuf);
     228        iocb.envbuf.index = idx;
     229        iocb.envbuf.name = PTR_TO_CFE(name);
     230        iocb.envbuf.name_len = namelen;
     231
     232        err = cfe_iocb_dispatch(&iocb);
     233
     234        return (CFE_ISERR(err)) ? err : iocb.status;
     235}
     236
     237int cfe_enummem(int idx, int flags, u64 *start, u64 *length,
     238                u64 *type)
     239{
     240        struct cfe_iocb iocb;
     241        int err;
     242
     243        memset(&iocb, 0, sizeof(iocb));
     244
     245        iocb.fcode = CFE_CMD_FW_MEMENUM;
     246        iocb.flags = flags;
     247        iocb.psize = sizeof(struct cfe_iocb_meminfo);
     248        iocb.meminfo.index = idx;
     249
     250        err = cfe_iocb_dispatch(&iocb);
     251        if (CFE_ISERR(err))
     252                return err;
     253        if (!CFE_ISERR(iocb.status)) {
     254                *start = iocb.meminfo.addr;
     255                *length = iocb.meminfo.size;
     256                *type = iocb.meminfo.type;
     257        }
     258
     259        return iocb.status;
     260}
     261
     262int cfe_exit(int warm, int status)
     263{
     264        struct cfe_iocb iocb;
     265        int err;
     266
     267printk("CFE REBOOT\n");
     268        memset(&iocb, 0, sizeof(iocb));
     269        iocb.fcode = CFE_CMD_FW_RESTART;
     270        if (warm)
     271                iocb.flags = CFE_FLG_WARMSTART;
     272        iocb.psize = sizeof(struct cfe_iocb_exitstat);
     273        iocb.exitstat.status = status;
     274
     275printk("CALL\n");
     276        err = cfe_iocb_dispatch(&iocb);
     277printk("DONE\n");
     278
     279        return (CFE_ISERR(err)) ? err : iocb.status;
     280}
     281
     282int cfe_flushcache(int flags)
     283{
     284        struct cfe_iocb iocb;
     285        int err;
     286
     287        memset(&iocb, 0, sizeof(iocb));
     288        iocb.fcode = CFE_CMD_FW_FLUSHCACHE;
     289        iocb.flags = flags;
     290
     291        err = cfe_iocb_dispatch(&iocb);
     292
     293        return (CFE_ISERR(err)) ? err : iocb.status;
     294}
     295
     296int cfe_getdevinfo(char *name)
     297{
     298        struct cfe_iocb iocb;
     299        int err;
     300
     301        memset(&iocb, 0, sizeof(iocb));
     302        iocb.fcode = CFE_CMD_DEV_GETINFO;
     303        iocb.psize = sizeof(struct cfe_iocb_buf);
     304        iocb.buffer.ptr = PTR_TO_CFE(name);
     305        iocb.buffer.length = strlen(name);
     306
     307        err = cfe_iocb_dispatch(&iocb);
     308        if (CFE_ISERR(err))
     309                return err;
     310        if (CFE_ISERR(iocb.status))
     311                return iocb.status;
     312
     313        return iocb.buffer.devflags;
     314}
     315
     316int cfe_getenv(char *name, char *dest, int destlen)
     317{
     318        struct cfe_iocb iocb;
     319        int err;
     320
     321        dest[0] = '\0';
     322        memset(&iocb, 0, sizeof(iocb));
     323        iocb.fcode = CFE_CMD_ENV_GET;
     324        iocb.psize = sizeof(struct cfe_iocb_envbuf);
     325        iocb.envbuf.name = PTR_TO_CFE(name);
     326        iocb.envbuf.name_len = strlen(name);
     327        iocb.envbuf.val = PTR_TO_CFE(dest);
     328        iocb.envbuf.val_len = destlen;
     329
     330        err = cfe_iocb_dispatch(&iocb);
     331
     332        return (CFE_ISERR(err)) ? err : iocb.status;
     333}
     334
     335int cfe_getfwinfo(struct cfe_fwinfo *info)
     336{
     337        struct cfe_iocb iocb;
     338        int err;
     339
     340        memset(&iocb, 0, sizeof(iocb));
     341        iocb.fcode = CFE_CMD_FW_GETINFO;
     342        iocb.psize = sizeof(struct cfe_iocb_fwinfo);
     343
     344        err = cfe_iocb_dispatch(&iocb);
     345        if (CFE_ISERR(err))
     346                return err;
     347        if (CFE_ISERR(iocb.status))
     348                return err;
     349
     350        info->version = iocb.fwinfo.version;
     351        info->totalmem = iocb.fwinfo.totalmem;
     352        info->flags = iocb.fwinfo.flags;
     353        info->boardid = iocb.fwinfo.boardid;
     354        info->bootarea_va = iocb.fwinfo.bootarea_va;
     355        info->bootarea_pa = iocb.fwinfo.bootarea_pa;
     356        info->bootarea_size = iocb.fwinfo.bootarea_size;
     357
     358        return iocb.status;
     359}
     360
     361int cfe_getstdhandle(int handletype)
     362{
     363        struct cfe_iocb iocb;
     364        int err;
     365
     366        memset(&iocb, 0, sizeof(iocb));
     367        iocb.fcode = CFE_CMD_DEV_GETHANDLE;
     368        iocb.flags = handletype;
     369
     370        err = cfe_iocb_dispatch(&iocb);
     371        if (CFE_ISERR(err))
     372                return err;
     373        if (CFE_ISERR(iocb.status))
     374                return iocb.status;
     375
     376        return iocb.handle;
     377}
     378
     379int cfe_getticks(s64 *ticks)
     380{
     381        struct cfe_iocb iocb;
     382        int err;
     383
     384        memset(&iocb, 0, sizeof(iocb));
     385        iocb.fcode = CFE_CMD_FW_GETTIME;
     386        iocb.psize = sizeof(struct cfe_iocb_time);
     387
     388        err = cfe_iocb_dispatch(&iocb);
     389        if (CFE_ISERR(err))
     390                return err;
     391        if (!CFE_ISERR(iocb.status))
     392                *ticks = iocb.time.ticks;
     393
     394        return iocb.status;
     395}
     396
     397int cfe_inpstat(int handle)
     398{
     399        struct cfe_iocb iocb;
     400        int err;
     401
     402        memset(&iocb, 0, sizeof(iocb));
     403        iocb.fcode = CFE_CMD_DEV_INPSTAT;
     404        iocb.handle = handle;
     405        iocb.psize = sizeof(struct cfe_iocb_inpstat);
     406
     407        err = cfe_iocb_dispatch(&iocb);
     408        if (CFE_ISERR(err))
     409                return err;
     410        if (CFE_ISERR(iocb.status))
     411                return iocb.status;
     412
     413        return iocb.inpstat.status;
     414}
     415
     416int cfe_ioctl(int handle, unsigned int ioctlnum,
     417              unsigned char *buffer, int length,
     418              int *retlen, u64 offset)
     419{
     420        struct cfe_iocb iocb;
     421        int err;
     422
     423        memset(&iocb, 0, sizeof(iocb));
     424        iocb.fcode = CFE_CMD_DEV_IOCTL;
     425        iocb.handle = handle;
     426        iocb.psize = sizeof(struct cfe_iocb_buf);
     427        iocb.buffer.offset = offset;
     428        iocb.buffer.ioctlcmd = ioctlnum;
     429        iocb.buffer.ptr = PTR_TO_CFE(buffer);
     430        iocb.buffer.length = length;
     431
     432        err = cfe_iocb_dispatch(&iocb);
     433        if (CFE_ISERR(err))
     434                return err;
     435        if (CFE_ISERR(iocb.status))
     436                return iocb.status;
     437        if (retlen)
     438                *retlen = iocb.buffer.retlen;
     439
     440        return iocb.status;
     441}
     442
     443int cfe_open(char *name)
     444{
     445        struct cfe_iocb iocb;
     446        int err;
     447
     448        memset(&iocb, 0, sizeof(iocb));
     449        iocb.fcode = CFE_CMD_DEV_OPEN;
     450        iocb.psize = sizeof(struct cfe_iocb_buf);
     451        iocb.buffer.ptr = PTR_TO_CFE(name);
     452        iocb.buffer.length = strlen(name);
     453
     454        err = cfe_iocb_dispatch(&iocb);
     455        if (CFE_ISERR(err))
     456                return err;
     457        if (CFE_ISERR(iocb.status))
     458                return iocb.status;
     459
     460        return iocb.handle;
     461}
     462
     463int cfe_read(int handle, unsigned char *buffer, int length)
     464{
     465        return cfe_readblk(handle, 0, buffer, length);
     466}
     467
     468int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length)
     469{
     470        struct cfe_iocb iocb;
     471        int err;
     472
     473        memset(&iocb, 0, sizeof(iocb));
     474        iocb.fcode = CFE_CMD_DEV_READ;
     475        iocb.handle = handle;
     476        iocb.psize = sizeof(struct cfe_iocb_buf);
     477        iocb.buffer.offset = offset;
     478        iocb.buffer.ptr = PTR_TO_CFE(buffer);
     479        iocb.buffer.length = length;
     480
     481        err = cfe_iocb_dispatch(&iocb);
     482        if (CFE_ISERR(err))
     483                return err;
     484        if (CFE_ISERR(iocb.status))
     485                return iocb.status;
     486
     487        return iocb.buffer.retlen;
     488}
     489
     490int cfe_setenv(char *name, char *val)
     491{
     492        struct cfe_iocb iocb;
     493        int err;
     494
     495        memset(&iocb, 0, sizeof(iocb));
     496        iocb.fcode = CFE_CMD_ENV_SET;
     497        iocb.psize = sizeof(struct cfe_iocb_envbuf);
     498        iocb.envbuf.name = PTR_TO_CFE(name);
     499        iocb.envbuf.name_len = strlen(name);
     500        iocb.envbuf.val = PTR_TO_CFE(val);
     501        iocb.envbuf.val_len = strlen(val);
     502
     503        err = cfe_iocb_dispatch(&iocb);
     504
     505        return (CFE_ISERR(err)) ? err : iocb.status;
     506}
     507
     508int cfe_write(int handle, unsigned char *buffer, int length)
     509{
     510        return cfe_writeblk(handle, 0, buffer, length);
     511}
     512
     513int cfe_writeblk(int handle, s64 offset, unsigned char *buffer, int length)
     514{
     515        struct cfe_iocb iocb;
     516        int err;
     517
     518        memset(&iocb, 0, sizeof(iocb));
     519        iocb.fcode = CFE_CMD_DEV_WRITE;
     520        iocb.handle = handle;
     521        iocb.psize = sizeof(struct cfe_iocb_buf);
     522        iocb.buffer.offset = offset;
     523        iocb.buffer.ptr = PTR_TO_CFE(buffer);
     524        iocb.buffer.length = length;
     525
     526        err = cfe_iocb_dispatch(&iocb);
     527        if (CFE_ISERR(err))
     528                return err;
     529        if (CFE_ISERR(iocb.status))
     530                return iocb.status;
     531
     532        return iocb.buffer.retlen;
     533}
  • new file arch/mips/cfe/cfe_private.h

    diff --git a/arch/mips/cfe/cfe_private.h b/arch/mips/cfe/cfe_private.h
    new file mode 100644
    index 0000000..0a604d3
    - +  
     1/*
     2 * Broadcom Common Firmware Environment (CFE) support
     3 *
     4 * Copyright 2000, 2001, 2002
     5 * Broadcom Corporation. All rights reserved.
     6 *
     7 * Copyright (C) 2006 Michael Buesch
     8 *
     9 * Original Authors:  Mitch Lichtenberg, Chris Demetriou
     10 *
     11 * This software is furnished under license and may be used and copied only
     12 * in accordance with the following terms and conditions.  Subject to these
     13 * conditions, you may download, copy, install, use, modify and distribute
     14 * modified or unmodified copies of this software in source and/or binary
     15 * form. No title or ownership is transferred hereby.
     16 *
     17 * 1) Any source code used, modified or distributed must reproduce and
     18 *    retain this copyright notice and list of conditions as they appear in
     19 *    the source file.
     20 *
     21 * 2) No right is granted to use any trade name, trademark, or logo of
     22 *    Broadcom Corporation.  The "Broadcom Corporation" name may not be
     23 *    used to endorse or promote products derived from this software
     24 *    without the prior written permission of Broadcom Corporation.
     25 *
     26 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
     27 *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
     28 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
     29 *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
     30 *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
     31 *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     34 *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     35 *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     36 *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     37 */
     38
     39#ifndef LINUX_CFE_PRIVATE_H_
     40#define LINUX_CFE_PRIVATE_H_
     41
     42#ifndef __ASSEMBLY__
     43
     44/* Seal indicating CFE's presence, passed to the kernel. */
     45#define CFE_EPTSEAL             0x43464531
     46
     47#define CFE_CMD_FW_GETINFO      0
     48#define CFE_CMD_FW_RESTART      1
     49#define CFE_CMD_FW_BOOT         2
     50#define CFE_CMD_FW_CPUCTL       3
     51#define CFE_CMD_FW_GETTIME      4
     52#define CFE_CMD_FW_MEMENUM      5
     53#define CFE_CMD_FW_FLUSHCACHE   6
     54
     55#define CFE_CMD_DEV_GETHANDLE   9
     56#define CFE_CMD_DEV_ENUM        10
     57#define CFE_CMD_DEV_OPEN        11
     58#define CFE_CMD_DEV_INPSTAT     12
     59#define CFE_CMD_DEV_READ        13
     60#define CFE_CMD_DEV_WRITE       14
     61#define CFE_CMD_DEV_IOCTL       15
     62#define CFE_CMD_DEV_CLOSE       16
     63#define CFE_CMD_DEV_GETINFO     17
     64
     65#define CFE_CMD_ENV_ENUM        20
     66#define CFE_CMD_ENV_GET         22
     67#define CFE_CMD_ENV_SET         23
     68#define CFE_CMD_ENV_DEL         24
     69
     70#define CFE_CMD_MAX             32
     71
     72#define CFE_CMD_VENDOR_USE      0x8000  /* codes above this are for customer use */
     73
     74typedef u64 cfe_uint_t;
     75typedef s64 cfe_int_t;
     76typedef s64 cfe_ptr_t;
     77
     78/* Cast a pointer from native to CFE-API pointer and back */
     79#define CFE_TO_PTR(p)           ((void *)(unsigned long)(p))
     80#define PTR_TO_CFE(p)           ((cfe_ptr_t)(unsigned long)(p))
     81
     82struct cfe_iocb_buf {
     83        cfe_uint_t      offset;         /* offset on device (bytes) */
     84        cfe_ptr_t       ptr;            /* pointer to a buffer */
     85        cfe_uint_t      length;         /* length of this buffer */
     86        cfe_uint_t      retlen;         /* returned length (for read ops) */
     87        union {
     88                cfe_uint_t      ioctlcmd;       /* IOCTL command (used only for IOCTLs) */
     89                cfe_uint_t      devflags;       /* Returned device info flags */
     90        };
     91};
     92
     93struct cfe_iocb_inpstat {
     94        cfe_uint_t      status;         /* 1 means input available */
     95};
     96
     97struct cfe_iocb_envbuf {
     98        cfe_int_t       index;          /* 0-based enumeration index */
     99        cfe_ptr_t       name;           /* name string buffer */
     100        cfe_int_t       name_len;       /* size of name buffer */
     101        cfe_ptr_t       val;            /* value string buffer */
     102        cfe_int_t       val_len;        /* size of value string buffer */
     103};
     104
     105struct cfe_iocb_cpuctl {
     106        cfe_uint_t      number;         /* cpu number to control */
     107        cfe_uint_t      command;        /* command to issue to CPU */
     108        cfe_uint_t      start_addr;     /* CPU start address */
     109        cfe_uint_t      gp;             /* starting GP value */
     110        cfe_uint_t      sp;             /* starting SP value */
     111        cfe_uint_t      a1;             /* starting A1 value */
     112};
     113
     114struct cfe_iocb_time {
     115        cfe_int_t       ticks;          /* current time in ticks */
     116};
     117
     118struct cfe_iocb_exitstat {
     119        cfe_int_t       status;
     120};
     121
     122struct cfe_iocb_meminfo {
     123        cfe_int_t       index;          /* 0-based enumeration index */
     124        cfe_int_t       type;           /* type of memory block */
     125        cfe_uint_t      addr;           /* physical start address */
     126        cfe_uint_t      size;           /* block size */
     127};
     128
     129struct cfe_iocb_fwinfo {
     130        cfe_int_t       version;        /* major, minor, eco version */
     131        cfe_int_t       totalmem;       /* total installed mem */
     132        cfe_int_t       flags;          /* various flags */
     133        cfe_int_t       boardid;        /* board ID */
     134        cfe_int_t       bootarea_va;    /* VA of boot area */
     135        cfe_int_t       bootarea_pa;    /* PA of boot area */
     136        cfe_int_t       bootarea_size;  /* size of boot area */
     137        cfe_int_t       reserved1;
     138        cfe_int_t       reserved2;
     139        cfe_int_t       reserved3;
     140};
     141
     142/* CFE I/O Control Block */
     143struct cfe_iocb {
     144        cfe_uint_t      fcode;          /* IOCB function code */
     145        cfe_int_t       status;         /* return status */
     146        cfe_int_t       handle;         /* file/device handle */
     147        cfe_uint_t      flags;          /* flags for this IOCB */
     148        cfe_uint_t      psize;          /* size of parameter list */
     149        union {
     150                struct cfe_iocb_buf             buffer;         /* buffer parameters */
     151                struct cfe_iocb_inpstat         inpstat;        /* input status parameters */
     152                struct cfe_iocb_envbuf          envbuf;         /* environment function parameters */
     153                struct cfe_iocb_cpuctl          cpuctl;         /* CPU control parameters */
     154                struct cfe_iocb_time            time;           /* timer parameters */
     155                struct cfe_iocb_meminfo         meminfo;        /* memory arena info parameters */
     156                struct cfe_iocb_fwinfo          fwinfo;         /* firmware information */
     157                struct cfe_iocb_exitstat        exitstat;       /* Exit Status */
     158        };
     159};
     160
     161
     162#include <linux/init.h>
     163
     164void __init cfe_setup(unsigned long fwarg0, unsigned long fwarg1,
     165                      unsigned long fwarg2, unsigned long fwarg3);
     166
     167#else /* __ASSEMBLY__ */
     168
     169        .macro  cfe_early_init
     170#ifdef CONFIG_CFE
     171                jal     cfe_setup
     172#endif
     173        .endm
     174
     175#endif /* __ASSEMBLY__ */
     176#endif /* LINUX_CFE_PRIVATE_H_ */
  • arch/mips/kernel/cpu-probe.c

    diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
    index 8485af3..fb5e5aa 100644
    a b static inline void cpu_probe_philips(str  
    723723}
    724724
    725725
     726static inline void cpu_probe_broadcom(struct cpuinfo_mips *c)
     727{
     728        decode_config1(c);
     729        switch (c->processor_id & 0xff00) {
     730                case PRID_IMP_BCM3302:
     731                        c->cputype = CPU_BCM3302;
     732                        c->isa_level = MIPS_CPU_ISA_M32R1;
     733                        c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
     734                                        MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
     735                break;
     736                case PRID_IMP_BCM4710:
     737                        c->cputype = CPU_BCM4710;
     738                        c->isa_level = MIPS_CPU_ISA_M32R1;
     739                        c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX |
     740                                        MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER;
     741                break;
     742        default:
     743                c->cputype = CPU_UNKNOWN;
     744                break;
     745        }
     746}
     747
    726748__init void cpu_probe(void)
    727749{
    728750        struct cpuinfo_mips *c = &current_cpu_data;
    __init void cpu_probe(void)  
    745767        case PRID_COMP_SIBYTE:
    746768                cpu_probe_sibyte(c);
    747769                break;
     770        case PRID_COMP_BROADCOM:
     771                cpu_probe_broadcom(c);
     772                break;
    748773        case PRID_COMP_SANDCRAFT:
    749774                cpu_probe_sandcraft(c);
    750775                break;
  • arch/mips/kernel/head.S

    diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S
    index ddc1b71..252db66 100644
    a b  
    129129#endif
    130130        .endm
    131131
     132        j kernel_entry
     133        nop
     134
    132135        /*
    133136         * Reserved space for exception handlers.
    134137         * Necessary for machines which link their kernels at KSEG0.
  • arch/mips/kernel/proc.c

    diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
    index 4ed37ba..2acfa19 100644
    a b static const char *cpu_name[] = {  
    8383        [CPU_VR4181]    = "NEC VR4181",
    8484        [CPU_VR4181A]   = "NEC VR4181A",
    8585        [CPU_SR71000]   = "Sandcraft SR71000",
     86        [CPU_BCM3302]   = "Broadcom BCM3302",
     87        [CPU_BCM4710]   = "Broadcom BCM4710",
    8688        [CPU_PR4450]    = "Philips PR4450",
    8789};
    8890
  • arch/mips/mm/tlbex.c

    diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
    index fec318a..3045432 100644
    a b static __init void build_tlb_write_entry  
    880880        case CPU_4KSC:
    881881        case CPU_20KC:
    882882        case CPU_25KF:
     883        case CPU_BCM3302:
     884        case CPU_BCM4710:
    883885                tlbw(p);
    884886                break;
    885887
  • drivers/mtd/chips/cfi_cmdset_0002.c

    diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c
    index 702ae4c..35cd1c8 100644
    a b struct mtd_info *cfi_cmdset_0002(struct  
    296296                        printk(KERN_ERR "  Unknown Amd/Fujitsu Extended Query "
    297297                               "version %c.%c.\n",  extp->MajorVersion,
    298298                               extp->MinorVersion);
    299                         kfree(extp);
    300                         kfree(mtd);
    301                         return NULL;
    302299                }
    303300
    304301                /* Install our own private info structure */
  • drivers/mtd/maps/Kconfig

    diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig
    index 24747bd..fec2769 100644
    a b config MTD_CFI_FLAGADM  
    299299          Mapping for the Flaga digital module. If you don't have one, ignore
    300300          this setting.
    301301
     302config MTD_BCM47XX
     303        tristate "BCM47xx flash device"
     304        depends on MIPS && MTD_CFI && BCM947XX
     305        help
     306          Support for the flash chips on the BCM947xx board.
     307         
    302308config MTD_BEECH
    303309        tristate "CFI Flash device mapped on IBM 405LP Beech"
    304310        depends on MTD_CFI && BEECH
  • drivers/mtd/maps/Makefile

    diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile
    index 191c192..5881584 100644
    a b obj-$(CONFIG_MTD_PNC2000) += pnc2000.o  
    2929obj-$(CONFIG_MTD_PCMCIA)        += pcmciamtd.o
    3030obj-$(CONFIG_MTD_RPXLITE)       += rpxlite.o
    3131obj-$(CONFIG_MTD_TQM8XXL)       += tqm8xxl.o
     32obj-$(CONFIG_MTD_BCM47XX)       += bcm47xx-flash.o
    3233obj-$(CONFIG_MTD_SA1100)        += sa1100-flash.o
    3334obj-$(CONFIG_MTD_IPAQ)          += ipaq-flash.o
    3435obj-$(CONFIG_MTD_SBC_GXX)       += sbc_gxx.o
  • new file drivers/mtd/maps/bcm47xx-flash.c

    diff --git a/drivers/mtd/maps/bcm47xx-flash.c b/drivers/mtd/maps/bcm47xx-flash.c
    new file mode 100644
    index 0000000..334432d
    - +  
     1/*
     2 *  Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
     3 *  Copyright (C) 2005 Waldemar Brodkorb <wbx@openwrt.org>
     4 *  Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     5 *
     6 *  original functions for finding root filesystem from Mike Baker
     7 *
     8 *  This program is free software; you can redistribute  it and/or modify it
     9 *  under  the terms of  the GNU General  Public License as published by the
     10 *  Free Software Foundation;  either version 2 of the  License, or (at your
     11 *  option) any later version.
     12 *
     13 *  THIS  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
     14 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
     15 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
     16 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
     17 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     18 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
     19 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     20 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
     21 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     22 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23 *
     24 *  You should have received a copy of the  GNU General Public License along
     25 *  with this program; if not, write  to the Free Software Foundation, Inc.,
     26 *  675 Mass Ave, Cambridge, MA 02139, USA.
     27 *
     28 *  Copyright 2001-2003, Broadcom Corporation
     29 *  All Rights Reserved.
     30 *
     31 *  THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
     32 *  KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
     33 *  SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
     34 *  FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
     35 *
     36 *  Flash mapping for BCM947XX boards
     37 */
     38
     39#include <linux/init.h>
     40#include <linux/module.h>
     41#include <linux/types.h>
     42#include <linux/kernel.h>
     43#include <linux/wait.h>
     44#include <linux/mtd/mtd.h>
     45#include <linux/mtd/map.h>
     46#ifdef CONFIG_MTD_PARTITIONS
     47#include <linux/mtd/partitions.h>
     48#endif
     49#ifdef CONFIG_SQUASHFS
     50#include <linux/squashfs_fs.h>
     51#endif
     52#include <linux/jffs2.h>
     53#include <linux/crc32.h>
     54#include <linux/ssb.h>
     55#include <asm/io.h>
     56
     57
     58#define TRX_MAGIC       0x30524448      /* "HDR0" */
     59#define TRX_VERSION     1
     60#define TRX_MAX_LEN     0x3A0000
     61#define TRX_NO_HEADER   1               /* Do not write TRX header */   
     62#define TRX_GZ_FILES    0x2     /* Contains up to TRX_MAX_OFFSET individual gzip files */
     63#define TRX_MAX_OFFSET  3
     64
     65struct trx_header {
     66        u32 magic;              /* "HDR0" */
     67        u32 len;                /* Length of file including header */
     68        u32 crc32;              /* 32-bit CRC from flag_version to end of file */
     69        u32 flag_version;       /* 0:15 flags, 16:31 version */
     70        u32 offsets[TRX_MAX_OFFSET];    /* Offsets of partitions from start of header */
     71};
     72
     73#define ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
     74#define NVRAM_SPACE 0x8000
     75#define WINDOW_ADDR 0x1fc00000
     76#define WINDOW_SIZE 0x400000
     77#define BUSWIDTH 2
     78
     79extern struct ssb_bus ssb;
     80static struct mtd_info *bcm947xx_mtd;
     81
     82static void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
     83{
     84#define MIPS_MEMCPY_ALIGN 4
     85        map_word ret;
     86        ssize_t transfer;
     87        ssize_t done = 0;
     88        if ((len >= MIPS_MEMCPY_ALIGN) && (!(from & (MIPS_MEMCPY_ALIGN - 1))) && (!(((unsigned int)to & (MIPS_MEMCPY_ALIGN - 1))))) {
     89                done = len & ~(MIPS_MEMCPY_ALIGN - 1);
     90                memcpy_fromio(to, map->virt + from, done);
     91        }
     92        while (done < len) {
     93                ret = map->read(map, from + done);
     94                transfer = len - done;
     95                if (transfer > map->bankwidth)
     96                        transfer = map->bankwidth;
     97                memcpy((void *)((unsigned long)to + done), &ret.x[0], transfer);
     98                done += transfer;
     99        }
     100}
     101
     102static struct map_info bcm947xx_map = {
     103        name: "Physically mapped flash",
     104        size: WINDOW_SIZE,
     105        bankwidth: BUSWIDTH,
     106        phys: WINDOW_ADDR,
     107};
     108
     109#ifdef CONFIG_MTD_PARTITIONS
     110
     111static struct mtd_partition bcm947xx_parts[] = {
     112        { name: "cfe",  offset: 0, size: 0, mask_flags: MTD_WRITEABLE, },
     113        { name: "linux", offset: 0, size: 0, },
     114        { name: "rootfs", offset: 0, size: 0, },
     115        { name: "nvram", offset: 0, size: 0, },
     116        { name: "OpenWrt", offset: 0, size: 0, },
     117        { name: NULL, },
     118};
     119
     120static int __init
     121find_cfe_size(struct mtd_info *mtd, size_t size)
     122{
     123        struct trx_header *trx;
     124        unsigned char buf[512];
     125        int off;
     126        size_t len;
     127        int blocksize;
     128
     129        trx = (struct trx_header *) buf;
     130
     131        blocksize = mtd->erasesize;
     132        if (blocksize < 0x10000)
     133                blocksize = 0x10000;
     134
     135        for (off = (128*1024); off < size; off += blocksize) {
     136                memset(buf, 0xe5, sizeof(buf));
     137
     138                /*
     139                 * Read into buffer
     140                 */
     141                if (mtd->read(mtd, off, sizeof(buf), &len, buf) ||
     142                    len != sizeof(buf))
     143                        continue;
     144
     145                /* found a TRX header */
     146                if (le32_to_cpu(trx->magic) == TRX_MAGIC) {
     147                        goto found;
     148                }
     149        }
     150
     151        printk(KERN_NOTICE
     152               "%s: Couldn't find bootloader size\n",
     153               mtd->name);
     154        return -1;
     155
     156 found:
     157        printk(KERN_NOTICE "bootloader size: %d\n", off);
     158        return off;
     159
     160}
     161
     162/*
     163 * Copied from mtdblock.c
     164 *
     165 * Cache stuff...
     166 *
     167 * Since typical flash erasable sectors are much larger than what Linux's
     168 * buffer cache can handle, we must implement read-modify-write on flash
     169 * sectors for each block write requests.  To avoid over-erasing flash sectors
     170 * and to speed things up, we locally cache a whole flash sector while it is
     171 * being written to until a different sector is required.
     172 */
     173
     174static void erase_callback(struct erase_info *done)
     175{
     176        wait_queue_head_t *wait_q = (wait_queue_head_t *)done->priv;
     177        wake_up(wait_q);
     178}
     179
     180static int erase_write (struct mtd_info *mtd, unsigned long pos,
     181                        int len, const char *buf)
     182{
     183        struct erase_info erase;
     184        DECLARE_WAITQUEUE(wait, current);
     185        wait_queue_head_t wait_q;
     186        size_t retlen;
     187        int ret;
     188
     189        /*
     190         * First, let's erase the flash block.
     191         */
     192
     193        init_waitqueue_head(&wait_q);
     194        erase.mtd = mtd;
     195        erase.callback = erase_callback;
     196        erase.addr = pos;
     197        erase.len = len;
     198        erase.priv = (u_long)&wait_q;
     199
     200        set_current_state(TASK_INTERRUPTIBLE);
     201        add_wait_queue(&wait_q, &wait);
     202
     203        ret = mtd->erase(mtd, &erase);
     204        if (ret) {
     205                set_current_state(TASK_RUNNING);
     206                remove_wait_queue(&wait_q, &wait);
     207                printk (KERN_WARNING "erase of region [0x%lx, 0x%x] "
     208                                     "on \"%s\" failed\n",
     209                        pos, len, mtd->name);
     210                return ret;
     211        }
     212
     213        schedule();  /* Wait for erase to finish. */
     214        remove_wait_queue(&wait_q, &wait);
     215
     216        /*
     217         * Next, writhe data to flash.
     218         */
     219
     220        ret = mtd->write (mtd, pos, len, &retlen, buf);
     221        if (ret)
     222                return ret;
     223        if (retlen != len)
     224                return -EIO;
     225        return 0;
     226}
     227
     228
     229
     230
     231static int __init
     232find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part)
     233{
     234        struct trx_header trx, *trx2;
     235        unsigned char buf[512], *block;
     236        int off, blocksize;
     237        u32 i, crc = ~0;
     238        size_t len;
     239#ifdef CONFIG_SQUASHFS
     240        struct squashfs_super_block *sb = (struct squashfs_super_block *) buf;
     241#endif
     242
     243        blocksize = mtd->erasesize;
     244        if (blocksize < 0x10000)
     245                blocksize = 0x10000;
     246
     247        for (off = (128*1024); off < size; off += blocksize) {
     248                memset(&trx, 0xe5, sizeof(trx));
     249
     250                /*
     251                 * Read into buffer
     252                 */
     253                if (mtd->read(mtd, off, sizeof(trx), &len, (char *) &trx) ||
     254                    len != sizeof(trx))
     255                        continue;
     256
     257                /* found a TRX header */
     258                if (le32_to_cpu(trx.magic) == TRX_MAGIC) {
     259                        part->offset = le32_to_cpu(trx.offsets[2]) ? :
     260                                le32_to_cpu(trx.offsets[1]);
     261                        part->size = le32_to_cpu(trx.len);
     262
     263                        part->size -= part->offset;
     264                        part->offset += off;
     265
     266                        goto found;
     267                }
     268        }
     269
     270        printk(KERN_NOTICE
     271               "%s: Couldn't find root filesystem\n",
     272               mtd->name);
     273        return -1;
     274
     275 found:
     276        if (part->size == 0)
     277                return 0;
     278       
     279        if (mtd->read(mtd, part->offset, sizeof(buf), &len, buf) || len != sizeof(buf))
     280                return 0;
     281#ifdef CONFIG_SQUASHFS
     282        if (*((__u32 *) buf) == SQUASHFS_MAGIC) {
     283                printk(KERN_INFO "%s: Filesystem type: squashfs, size=0x%x\n", mtd->name, (u32) sb->bytes_used);
     284
     285                /* Update the squashfs partition size based on the superblock info */
     286                part->size = sb->bytes_used;
     287                len = part->offset + part->size;
     288                len +=  (mtd->erasesize - 1);
     289                len &= ~(mtd->erasesize - 1);
     290                part->size = len - part->offset;
     291        } else
     292#endif
     293        if (*((__u16 *) buf) == JFFS2_MAGIC_BITMASK) {
     294                printk(KERN_INFO "%s: Filesystem type: jffs2\n", mtd->name);
     295
     296                /* Move the squashfs outside of the trx */
     297                part->size = 0;
     298        } else {
     299                printk(KERN_INFO "%s: Filesystem type: unknown\n", mtd->name);
     300                return 0;
     301        }
     302
     303        if (trx.len != part->offset + part->size - off) {
     304                /* Update the trx offsets and length */
     305                trx.len = part->offset + part->size - off;
     306       
     307                /* Update the trx crc32 */
     308                for (i = (u32) &(((struct trx_header *)NULL)->flag_version); i <= trx.len; i += sizeof(buf)) {
     309                        if (mtd->read(mtd, off + i, sizeof(buf), &len, buf) || len != sizeof(buf))
     310                                return 0;
     311                        crc = crc32_le(crc, buf, min(sizeof(buf), trx.len - i));
     312                }
     313                trx.crc32 = crc;
     314
     315                /* read first eraseblock from the trx */
     316                block = kmalloc(mtd->erasesize, GFP_KERNEL);
     317                trx2 = (struct trx_header *) block;
     318                if (mtd->read(mtd, off, mtd->erasesize, &len, block) || len != mtd->erasesize) {
     319                        printk("Error accessing the first trx eraseblock\n");
     320                        return 0;
     321                }
     322               
     323                printk("Updating TRX offsets and length:\n");
     324                printk("old trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n", trx2->offsets[0], trx2->offsets[1], trx2->offsets[2], trx2->len, trx2->crc32);
     325                printk("new trx = [0x%08x, 0x%08x, 0x%08x], len=0x%08x crc32=0x%08x\n",   trx.offsets[0],   trx.offsets[1],   trx.offsets[2],   trx.len, trx.crc32);
     326
     327                /* Write updated trx header to the flash */
     328                memcpy(block, &trx, sizeof(trx));
     329                if (mtd->unlock)
     330                        mtd->unlock(mtd, off, mtd->erasesize);
     331                erase_write(mtd, off, mtd->erasesize, block);
     332                if (mtd->sync)
     333                        mtd->sync(mtd);
     334                kfree(block);
     335                printk("Done\n");
     336        }
     337       
     338        return part->size;
     339}
     340
     341struct mtd_partition * __init
     342init_mtd_partitions(struct mtd_info *mtd, size_t size)
     343{
     344        int cfe_size;
     345
     346        if ((cfe_size = find_cfe_size(mtd,size)) < 0)
     347                return NULL;
     348
     349        /* boot loader */
     350        bcm947xx_parts[0].offset = 0;
     351        bcm947xx_parts[0].size   = cfe_size;
     352
     353        /* nvram */
     354        if (cfe_size != 384 * 1024) {
     355                bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize);
     356                bcm947xx_parts[3].size   = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
     357        } else {
     358                /* nvram (old 128kb config partition on netgear wgt634u) */
     359                bcm947xx_parts[3].offset = bcm947xx_parts[0].size;
     360                bcm947xx_parts[3].size   = ROUNDUP(NVRAM_SPACE, mtd->erasesize);
     361        }
     362
     363        /* linux (kernel and rootfs) */
     364        if (cfe_size != 384 * 1024) {
     365                bcm947xx_parts[1].offset = bcm947xx_parts[0].size;
     366                bcm947xx_parts[1].size   = bcm947xx_parts[3].offset -
     367                        bcm947xx_parts[1].offset;
     368        } else {
     369                /* do not count the elf loader, which is on one block */
     370                bcm947xx_parts[1].offset = bcm947xx_parts[0].size +
     371                        bcm947xx_parts[3].size + mtd->erasesize;
     372                bcm947xx_parts[1].size   = size -
     373                        bcm947xx_parts[0].size -
     374                        (2*bcm947xx_parts[3].size) -
     375                        mtd->erasesize;
     376        }
     377
     378        /* find and size rootfs */
     379        if (find_root(mtd,size,&bcm947xx_parts[2])==0) {
     380                /* entirely jffs2 */
     381                bcm947xx_parts[4].name = NULL;
     382                bcm947xx_parts[2].size = size - bcm947xx_parts[2].offset -
     383                                bcm947xx_parts[3].size;
     384        } else {
     385                /* legacy setup */
     386                /* calculate leftover flash, and assign it to the jffs2 partition */
     387                if (cfe_size != 384 * 1024) {
     388                        bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +
     389                                bcm947xx_parts[2].size;
     390                        if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
     391                                bcm947xx_parts[4].offset += mtd->erasesize -
     392                                        (bcm947xx_parts[4].offset % mtd->erasesize);
     393                        }
     394                        bcm947xx_parts[4].size = bcm947xx_parts[3].offset -
     395                                bcm947xx_parts[4].offset;
     396                } else {
     397                        bcm947xx_parts[4].offset = bcm947xx_parts[2].offset +
     398                                bcm947xx_parts[2].size;
     399                        if ((bcm947xx_parts[4].offset % mtd->erasesize) > 0) {
     400                                bcm947xx_parts[4].offset += mtd->erasesize -
     401                                        (bcm947xx_parts[4].offset % mtd->erasesize);
     402                        }
     403                        bcm947xx_parts[4].size = size - bcm947xx_parts[3].size -
     404                                bcm947xx_parts[4].offset;
     405                }
     406        }
     407
     408        return bcm947xx_parts;
     409}
     410#endif
     411
     412int __init init_bcm947xx_map(void)
     413{
     414        struct ssb_mipscore *mcore = &ssb.mipscore;
     415        size_t size;
     416        int ret = 0;
     417#ifdef CONFIG_MTD_PARTITIONS
     418        struct mtd_partition *parts;
     419        int i;
     420#endif
     421        u32 window = mcore->flash_window;
     422        u32 window_size = mcore->flash_window_size;
     423
     424        printk("flash init: 0x%08x 0x%08x\n", window, window_size);
     425        bcm947xx_map.virt = ioremap(window, window_size);
     426
     427        if (!bcm947xx_map.virt) {
     428                printk("Failed to ioremap\n");
     429                return -EIO;
     430        }
     431        simple_map_init(&bcm947xx_map);
     432       
     433        bcm947xx_map.copy_from = bcm947xx_map_copy_from;
     434       
     435        if (!(bcm947xx_mtd = do_map_probe("cfi_probe", &bcm947xx_map))) {
     436                printk("Failed to do_map_probe\n");
     437                iounmap((void *)bcm947xx_map.virt);
     438                return -ENXIO;
     439        }
     440
     441        bcm947xx_mtd->owner = THIS_MODULE;
     442
     443        size = bcm947xx_mtd->size;
     444
     445        printk(KERN_NOTICE "Flash device: 0x%x at 0x%x\n", size, WINDOW_ADDR);
     446
     447#ifdef CONFIG_MTD_PARTITIONS
     448        parts = init_mtd_partitions(bcm947xx_mtd, size);
     449        for (i = 0; parts[i].name; i++);
     450        ret = add_mtd_partitions(bcm947xx_mtd, parts, i);
     451        if (ret) {
     452                printk(KERN_ERR "Flash: add_mtd_partitions failed\n");
     453                goto fail;
     454        }
     455#endif
     456        return 0;
     457
     458 fail:
     459        if (bcm947xx_mtd)
     460                map_destroy(bcm947xx_mtd);
     461        if (bcm947xx_map.virt)
     462                iounmap((void *)bcm947xx_map.virt);
     463        bcm947xx_map.virt = 0;
     464        return ret;
     465}
     466
     467void __exit cleanup_bcm947xx_map(void)
     468{
     469#ifdef CONFIG_MTD_PARTITIONS
     470        del_mtd_partitions(bcm947xx_mtd);
     471#endif
     472        map_destroy(bcm947xx_mtd);
     473        iounmap((void *)bcm947xx_map.virt);
     474}
     475
     476module_init(init_bcm947xx_map);
     477module_exit(cleanup_bcm947xx_map);
  • drivers/net/Kconfig

    diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
    index 6e863aa..a09a8e4 100644
    a b config APRICOT  
    14021402
    14031403config B44
    14041404        tristate "Broadcom 4400 ethernet support"
    1405         depends on NET_PCI && PCI
     1405        depends on SSB && EXPERIMENTAL
    14061406        select MII
    14071407        help
    14081408          If you have a network (Ethernet) controller of this type, say Y and
  • drivers/net/b44.c

    diff --git a/drivers/net/b44.c b/drivers/net/b44.c
    index 474a4e3..eb29c71 100644
    a b  
    1 /* b44.c: Broadcom 4400 device driver.
     1/* b44.c: Broadcom 4400/47xx device driver.
    22 *
    33 * Copyright (C) 2002 David S. Miller (davem@redhat.com)
    4  * Fixed by Pekka Pietikainen (pp@ee.oulu.fi)
     4 * Copyright (C) 2004 Pekka Pietikainen (pp@ee.oulu.fi)
     5 * Copyright (C) 2004 Florian Schirmer (jolt@tuxbox.org)
     6 * Copyright (C) 2006 Felix Fietkau (nbd@openwrt.org)
    57 * Copyright (C) 2006 Broadcom Corporation.
    68 *
    79 * Distribute under GPL.
     
    2022#include <linux/delay.h>
    2123#include <linux/init.h>
    2224#include <linux/dma-mapping.h>
     25#include <linux/ssb.h>
    2326
    2427#include <asm/uaccess.h>
    2528#include <asm/io.h>
    2629#include <asm/irq.h>
    2730
     31
    2832#include "b44.h"
    2933
    3034#define DRV_MODULE_NAME         "b44"
     
    8791static char version[] __devinitdata =
    8892        DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
    8993
    90 MODULE_AUTHOR("Florian Schirmer, Pekka Pietikainen, David S. Miller");
    91 MODULE_DESCRIPTION("Broadcom 4400 10/100 PCI ethernet driver");
     94MODULE_AUTHOR("Felix Fietkau, Florian Schirmer, Pekka Pietikainen, David S. Miller");
     95MODULE_DESCRIPTION("Broadcom 4400/47xx 10/100 PCI ethernet driver");
    9296MODULE_LICENSE("GPL");
    9397MODULE_VERSION(DRV_MODULE_VERSION);
    9498
    static int b44_debug = -1; /* -1 == use  
    96100module_param(b44_debug, int, 0);
    97101MODULE_PARM_DESC(b44_debug, "B44 bitmapped debugging message enable value");
    98102
    99 static struct pci_device_id b44_pci_tbl[] = {
    100         { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401,
    101           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
    102         { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B0,
    103           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
    104         { PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BCM4401B1,
    105           PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
    106         { }     /* terminate list with empty entry */
     103static struct ssb_device_id b44_ssb_tbl[] = {
     104        SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_ETHERNET, SSB_ANY_REV),
     105        SSB_DEVTABLE_END
    107106};
    108107
    109 MODULE_DEVICE_TABLE(pci, b44_pci_tbl);
    110 
    111108static void b44_halt(struct b44 *);
    112109static void b44_init_rings(struct b44 *);
    113110static void b44_init_hw(struct b44 *, int);
    114111
    115112static int dma_desc_align_mask;
    116113static int dma_desc_sync_size;
     114static int instance;
    117115
    118116static const char b44_gstrings[][ETH_GSTRING_LEN] = {
    119117#define _B44(x...)      # x,
    B44_STAT_REG_DECLARE  
    121119#undef _B44
    122120};
    123121
    124 static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
    125                                                 dma_addr_t dma_base,
    126                                                 unsigned long offset,
    127                                                 enum dma_data_direction dir)
    128 {
    129         dma_sync_single_range_for_device(&pdev->dev, dma_base,
    130                                          offset & dma_desc_align_mask,
    131                                          dma_desc_sync_size, dir);
    132 }
    133 
    134 static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
    135                                              dma_addr_t dma_base,
    136                                              unsigned long offset,
    137                                              enum dma_data_direction dir)
    138 {
    139         dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
    140                                       offset & dma_desc_align_mask,
    141                                       dma_desc_sync_size, dir);
    142 }
    143 
    144 static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
     122static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
     123                                               dma_addr_t dma_base,
     124                                               unsigned long offset,
     125                                               enum dma_data_direction dir)
    145126{
    146         return readl(bp->regs + reg);
     127        dma_sync_single_range_for_device(&sdev->dev, dma_base,
     128                                        offset & dma_desc_align_mask,
     129                                        dma_desc_sync_size, dir);
    147130}
    148131
    149 static inline void bw32(const struct b44 *bp,
    150                         unsigned long reg, unsigned long val)
     132static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
     133                                            dma_addr_t dma_base,
     134                                            unsigned long offset,
     135                                            enum dma_data_direction dir)
    151136{
    152         writel(val, bp->regs + reg);
     137        dma_sync_single_range_for_cpu(&sdev->dev, dma_base,
     138                                     offset & dma_desc_align_mask,
     139                                     dma_desc_sync_size, dir);
    153140}
    154141
    155142static int b44_wait_bit(struct b44 *bp, unsigned long reg,
    static int b44_wait_bit(struct b44 *bp,  
    177164        return 0;
    178165}
    179166
    180 /* Sonics SiliconBackplane support routines.  ROFL, you should see all the
    181  * buzz words used on this company's website :-)
    182  *
    183  * All of these routines must be invoked with bp->lock held and
    184  * interrupts disabled.
    185  */
    186 
    187 #define SB_PCI_DMA             0x40000000      /* Client Mode PCI memory access space (1 GB) */
    188 #define BCM4400_PCI_CORE_ADDR  0x18002000      /* Address of PCI core on BCM4400 cards */
    189 
    190 static u32 ssb_get_core_rev(struct b44 *bp)
    191 {
    192         return (br32(bp, B44_SBIDHIGH) & SBIDHIGH_RC_MASK);
    193 }
    194 
    195 static u32 ssb_pci_setup(struct b44 *bp, u32 cores)
    196 {
    197         u32 bar_orig, pci_rev, val;
    198 
    199         pci_read_config_dword(bp->pdev, SSB_BAR0_WIN, &bar_orig);
    200         pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, BCM4400_PCI_CORE_ADDR);
    201         pci_rev = ssb_get_core_rev(bp);
    202 
    203         val = br32(bp, B44_SBINTVEC);
    204         val |= cores;
    205         bw32(bp, B44_SBINTVEC, val);
    206 
    207         val = br32(bp, SSB_PCI_TRANS_2);
    208         val |= SSB_PCI_PREF | SSB_PCI_BURST;
    209         bw32(bp, SSB_PCI_TRANS_2, val);
    210 
    211         pci_write_config_dword(bp->pdev, SSB_BAR0_WIN, bar_orig);
    212 
    213         return pci_rev;
    214 }
    215 
    216 static void ssb_core_disable(struct b44 *bp)
    217 {
    218         if (br32(bp, B44_SBTMSLOW) & SBTMSLOW_RESET)
    219                 return;
    220 
    221         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_CLOCK));
    222         b44_wait_bit(bp, B44_SBTMSLOW, SBTMSLOW_REJECT, 100000, 0);
    223         b44_wait_bit(bp, B44_SBTMSHIGH, SBTMSHIGH_BUSY, 100000, 1);
    224         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_FGC | SBTMSLOW_CLOCK |
    225                             SBTMSLOW_REJECT | SBTMSLOW_RESET));
    226         br32(bp, B44_SBTMSLOW);
    227         udelay(1);
    228         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_REJECT | SBTMSLOW_RESET));
    229         br32(bp, B44_SBTMSLOW);
    230         udelay(1);
    231 }
    232 
    233 static void ssb_core_reset(struct b44 *bp)
     167static inline void __b44_cam_read(struct b44 *bp, unsigned char *data, int index)
    234168{
    235169        u32 val;
    236170
    237         ssb_core_disable(bp);
    238         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_RESET | SBTMSLOW_CLOCK | SBTMSLOW_FGC));
    239         br32(bp, B44_SBTMSLOW);
    240         udelay(1);
    241 
    242         /* Clear SERR if set, this is a hw bug workaround.  */
    243         if (br32(bp, B44_SBTMSHIGH) & SBTMSHIGH_SERR)
    244                 bw32(bp, B44_SBTMSHIGH, 0);
    245 
    246         val = br32(bp, B44_SBIMSTATE);
    247         if (val & (SBIMSTATE_IBE | SBIMSTATE_TO))
    248                 bw32(bp, B44_SBIMSTATE, val & ~(SBIMSTATE_IBE | SBIMSTATE_TO));
    249 
    250         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK | SBTMSLOW_FGC));
    251         br32(bp, B44_SBTMSLOW);
    252         udelay(1);
    253 
    254         bw32(bp, B44_SBTMSLOW, (SBTMSLOW_CLOCK));
    255         br32(bp, B44_SBTMSLOW);
    256         udelay(1);
    257 }
     171        bw32(bp, B44_CAM_CTRL, (CAM_CTRL_READ |
     172                            (index << CAM_CTRL_INDEX_SHIFT)));
    258173
    259 static int ssb_core_unit(struct b44 *bp)
    260 {
    261 #if 0
    262         u32 val = br32(bp, B44_SBADMATCH0);
    263         u32 base;
     174        b44_wait_bit(bp, B44_CAM_CTRL, CAM_CTRL_BUSY, 100, 1);
    264175
    265         type = val & SBADMATCH0_TYPE_MASK;
    266         switch (type) {
    267         case 0:
    268                 base = val & SBADMATCH0_BS0_MASK;
    269                 break;
     176        val = br32(bp, B44_CAM_DATA_LO);
    270177
    271         case 1:
    272                 base = val & SBADMATCH0_BS1_MASK;
    273                 break;
     178        data[2] = (val >> 24) & 0xFF;
     179        data[3] = (val >> 16) & 0xFF;
     180        data[4] = (val >> 8) & 0xFF;
     181        data[5] = (val >> 0) & 0xFF;
    274182
    275         case 2:
    276         default:
    277                 base = val & SBADMATCH0_BS2_MASK;
    278                 break;
    279         };
    280 #endif
    281         return 0;
    282 }
     183        val = br32(bp, B44_CAM_DATA_HI);
    283184
    284 static int ssb_is_core_up(struct b44 *bp)
    285 {
    286         return ((br32(bp, B44_SBTMSLOW) & (SBTMSLOW_RESET | SBTMSLOW_REJECT | SBTMSLOW_CLOCK))
    287                 == SBTMSLOW_CLOCK);
     185        data[0] = (val >> 8) & 0xFF;
     186        data[1] = (val >> 0) & 0xFF;
    288187}
    289188
    290 static void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
     189static inline void __b44_cam_write(struct b44 *bp, unsigned char *data, int index)
    291190{
    292191        u32 val;
    293192
    static void b44_enable_ints(struct b44 *  
    323222        bw32(bp, B44_IMASK, bp->imask);
    324223}
    325224
    326 static int b44_readphy(struct b44 *bp, int reg, u32 *val)
     225static int __b44_readphy(struct b44 *bp, int phy_addr, int reg, u32 *val)
    327226{
    328227        int err;
    329228
    330229        bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
    331230        bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
    332231                             (MDIO_OP_READ << MDIO_DATA_OP_SHIFT) |
    333                              (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
     232                             (phy_addr << MDIO_DATA_PMD_SHIFT) |
    334233                             (reg << MDIO_DATA_RA_SHIFT) |
    335234                             (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT)));
    336235        err = b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
    static int b44_readphy(struct b44 *bp, i  
    339238        return err;
    340239}
    341240
    342 static int b44_writephy(struct b44 *bp, int reg, u32 val)
     241static int __b44_writephy(struct b44 *bp, int phy_addr, int reg, u32 val)
    343242{
    344243        bw32(bp, B44_EMAC_ISTAT, EMAC_INT_MII);
    345244        bw32(bp, B44_MDIO_DATA, (MDIO_DATA_SB_START |
    346245                             (MDIO_OP_WRITE << MDIO_DATA_OP_SHIFT) |
    347                              (bp->phy_addr << MDIO_DATA_PMD_SHIFT) |
     246                             (phy_addr << MDIO_DATA_PMD_SHIFT) |
    348247                             (reg << MDIO_DATA_RA_SHIFT) |
    349248                             (MDIO_TA_VALID << MDIO_DATA_TA_SHIFT) |
    350249                             (val & MDIO_DATA_DATA)));
    351250        return b44_wait_bit(bp, B44_EMAC_ISTAT, EMAC_INT_MII, 100, 0);
    352251}
    353252
     253static inline int b44_readphy(struct b44 *bp, int reg, u32 *val)
     254{
     255        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
     256                return 0;
     257
     258        return __b44_readphy(bp, bp->phy_addr, reg, val);
     259}
     260
     261static inline int b44_writephy(struct b44 *bp, int reg, u32 val)
     262{
     263        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
     264                return 0;
     265               
     266        return __b44_writephy(bp, bp->phy_addr, reg, val);
     267}
     268
    354269/* miilib interface */
    355270/* FIXME FIXME: phy_id is ignored, bp->phy_addr use is unconditional
    356271 * due to code existing before miilib use was added to this driver.
    static int b44_phy_reset(struct b44 *bp)  
    379294        u32 val;
    380295        int err;
    381296
     297        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
     298                return 0;
    382299        err = b44_writephy(bp, MII_BMCR, BMCR_RESET);
    383300        if (err)
    384301                return err;
    static void b44_set_flow_ctrl(struct b44  
    437354        __b44_set_flow_ctrl(bp, pause_enab);
    438355}
    439356
     357
     358extern char *nvram_get(char *name); //FIXME: move elsewhere
    440359static int b44_setup_phy(struct b44 *bp)
    441360{
    442361        u32 val;
    443362        int err;
    444363
     364        /*
     365         * workaround for bad hardware design in Linksys WAP54G v1.0
     366         * see https://dev.openwrt.org/ticket/146
     367         * check and reset bit "isolate"
     368         */
     369        if ((atoi(nvram_get("boardnum")) == 2) &&
     370                        (__b44_readphy(bp, 0, MII_BMCR, &val) == 0) &&
     371                        (val & BMCR_ISOLATE) &&
     372                        (__b44_writephy(bp, 0, MII_BMCR, val & ~BMCR_ISOLATE) != 0)) {
     373                printk(KERN_WARNING PFX "PHY: cannot reset MII transceiver isolate bit.\n");
     374        }
     375
     376        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY)
     377                return 0;
    445378        if ((err = b44_readphy(bp, B44_MII_ALEDCTRL, &val)) != 0)
    446379                goto out;
    447380        if ((err = b44_writephy(bp, B44_MII_ALEDCTRL,
    static void b44_check_phy(struct b44 *bp  
    537470{
    538471        u32 bmsr, aux;
    539472
     473        if (bp->phy_addr == B44_PHY_ADDR_NO_PHY) {
     474                bp->flags |= B44_FLAG_100_BASE_T;
     475                bp->flags |= B44_FLAG_FULL_DUPLEX;
     476                if (!netif_carrier_ok(bp->dev)) {
     477                        u32 val = br32(bp, B44_TX_CTRL);
     478                        val |= TX_CTRL_DUPLEX;
     479                        bw32(bp, B44_TX_CTRL, val);
     480                        netif_carrier_on(bp->dev);
     481                        b44_link_report(bp);
     482                }
     483                return;
     484        }
     485
    540486        if (!b44_readphy(bp, MII_BMSR, &bmsr) &&
    541487            !b44_readphy(bp, B44_MII_AUXCTRL, &aux) &&
    542488            (bmsr != 0xffff)) {
    static void b44_tx(struct b44 *bp)  
    613559
    614560                BUG_ON(skb == NULL);
    615561
    616                 pci_unmap_single(bp->pdev,
     562                dma_unmap_single(&bp->sdev->dev,
    617563                                 pci_unmap_addr(rp, mapping),
    618564                                 skb->len,
    619                                  PCI_DMA_TODEVICE);
     565                                 DMA_TO_DEVICE);
    620566                rp->skb = NULL;
    621567                dev_kfree_skb_irq(skb);
    622568        }
    static int b44_alloc_rx_skb(struct b44 *  
    652598        skb = dev_alloc_skb(RX_PKT_BUF_SZ);
    653599        if (skb == NULL)
    654600                return -ENOMEM;
    655 
    656         mapping = pci_map_single(bp->pdev, skb->data,
     601       
     602        mapping = dma_map_single(&bp->sdev->dev, skb->data,
    657603                                 RX_PKT_BUF_SZ,
    658                                  PCI_DMA_FROMDEVICE);
     604                                 DMA_FROM_DEVICE);
    659605
    660606        /* Hardware bug work-around, the chip is unable to do PCI DMA
    661607           to/from anything above 1GB :-( */
    static int b44_alloc_rx_skb(struct b44 *  
    663609                mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
    664610                /* Sigh... */
    665611                if (!dma_mapping_error(mapping))
    666                         pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
     612                        dma_unmap_single(&bp->sdev->dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
    667613                dev_kfree_skb_any(skb);
    668614                skb = __dev_alloc_skb(RX_PKT_BUF_SZ,GFP_DMA);
    669615                if (skb == NULL)
    670616                        return -ENOMEM;
    671                 mapping = pci_map_single(bp->pdev, skb->data,
     617                mapping = dma_map_single(&bp->sdev->dev, skb->data,
    672618                                         RX_PKT_BUF_SZ,
    673                                          PCI_DMA_FROMDEVICE);
     619                                         DMA_FROM_DEVICE);
    674620                if (dma_mapping_error(mapping) ||
    675621                        mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
    676622                        if (!dma_mapping_error(mapping))
    677                                 pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
     623                                dma_unmap_single(&bp->sdev->dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
    678624                        dev_kfree_skb_any(skb);
    679625                        return -ENOMEM;
    680626                }
    static int b44_alloc_rx_skb(struct b44 *  
    703649        dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
    704650
    705651        if (bp->flags & B44_FLAG_RX_RING_HACK)
    706                 b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
    707                                              dest_idx * sizeof(dp),
    708                                              DMA_BIDIRECTIONAL);
     652                b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
     653                                            dest_idx * sizeof(dp),
     654                                            DMA_BIDIRECTIONAL);
    709655
    710656        return RX_PKT_BUF_SZ;
    711657}
    static void b44_recycle_rx(struct b44 *b  
    732678                           pci_unmap_addr(src_map, mapping));
    733679
    734680        if (bp->flags & B44_FLAG_RX_RING_HACK)
    735                 b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
    736                                           src_idx * sizeof(src_desc),
    737                                           DMA_BIDIRECTIONAL);
     681                b44_sync_dma_desc_for_cpu(bp->sdev, bp->rx_ring_dma,
     682                                         src_idx * sizeof(src_desc),
     683                                         DMA_BIDIRECTIONAL);
    738684
    739685        ctrl = src_desc->ctrl;
    740686        if (dest_idx == (B44_RX_RING_SIZE - 1))
    static void b44_recycle_rx(struct b44 *b  
    748694        src_map->skb = NULL;
    749695
    750696        if (bp->flags & B44_FLAG_RX_RING_HACK)
    751                 b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
    752                                              dest_idx * sizeof(dest_desc),
    753                                              DMA_BIDIRECTIONAL);
     697                b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
     698                                            dest_idx * sizeof(dest_desc),
     699                                            DMA_BIDIRECTIONAL);
    754700
    755         pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
     701        dma_sync_single_for_device(&bp->sdev->dev, src_desc->addr,
    756702                                       RX_PKT_BUF_SZ,
    757                                        PCI_DMA_FROMDEVICE);
     703                                       DMA_FROM_DEVICE);
    758704}
    759705
    760706static int b44_rx(struct b44 *bp, int budget)
    static int b44_rx(struct b44 *bp, int bu  
    774720                struct rx_header *rh;
    775721                u16 len;
    776722
    777                 pci_dma_sync_single_for_cpu(bp->pdev, map,
     723                dma_sync_single_for_cpu(&bp->sdev->dev, map,
    778724                                            RX_PKT_BUF_SZ,
    779                                             PCI_DMA_FROMDEVICE);
     725                                            DMA_FROM_DEVICE);
    780726                rh = (struct rx_header *) skb->data;
    781727                len = cpu_to_le16(rh->len);
    782728                if ((len > (RX_PKT_BUF_SZ - bp->rx_offset)) ||
    static int b44_rx(struct b44 *bp, int bu  
    808754                        skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
    809755                        if (skb_size < 0)
    810756                                goto drop_it;
    811                         pci_unmap_single(bp->pdev, map,
    812                                          skb_size, PCI_DMA_FROMDEVICE);
     757                        dma_unmap_single(&bp->sdev->dev, map,
     758                                         skb_size, DMA_FROM_DEVICE);
    813759                        /* Leave out rx_header */
    814                         skb_put(skb, len+bp->rx_offset);
    815                         skb_pull(skb,bp->rx_offset);
     760                skb_put(skb, len+bp->rx_offset);
     761                        skb_pull(skb,bp->rx_offset);
    816762                } else {
    817763                        struct sk_buff *copy_skb;
    818764
    static int b44_start_xmit(struct sk_buff  
    980926                goto err_out;
    981927        }
    982928
    983         mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
     929        mapping = dma_map_single(&bp->sdev->dev, skb->data, len, DMA_TO_DEVICE);
    984930        if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
    985931                /* Chip can't handle DMA to/from >1GB, use bounce buffer */
    986932                if (!dma_mapping_error(mapping))
    987                         pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
     933                        dma_unmap_single(&bp->sdev->dev, mapping, len, DMA_TO_DEVICE);
    988934
    989935                bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
    990936                                             GFP_ATOMIC|GFP_DMA);
    991937                if (!bounce_skb)
    992938                        goto err_out;
    993939
    994                 mapping = pci_map_single(bp->pdev, bounce_skb->data,
    995                                          len, PCI_DMA_TODEVICE);
     940                mapping = dma_map_single(&bp->sdev->dev, bounce_skb->data,
     941                                         len, DMA_TO_DEVICE);
    996942                if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
    997943                        if (!dma_mapping_error(mapping))
    998                                 pci_unmap_single(bp->pdev, mapping,
    999                                          len, PCI_DMA_TODEVICE);
     944                                dma_unmap_single(&bp->sdev->dev, mapping,
     945                                         len, DMA_TO_DEVICE);
    1000946                        dev_kfree_skb_any(bounce_skb);
    1001947                        goto err_out;
    1002948                }
    static int b44_start_xmit(struct sk_buff  
    1019965        bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
    1020966
    1021967        if (bp->flags & B44_FLAG_TX_RING_HACK)
    1022                 b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
    1023                                              entry * sizeof(bp->tx_ring[0]),
    1024                                              DMA_TO_DEVICE);
     968                b44_sync_dma_desc_for_device(bp->sdev, bp->tx_ring_dma,
     969                                            entry * sizeof(bp->tx_ring[0]),
     970                                            DMA_TO_DEVICE);
    1025971
    1026972        entry = NEXT_TX(entry);
    1027973
    static void b44_free_rings(struct b44 *b  
    10941040
    10951041                if (rp->skb == NULL)
    10961042                        continue;
    1097                 pci_unmap_single(bp->pdev,
     1043                dma_unmap_single(&bp->sdev->dev,
    10981044                                 pci_unmap_addr(rp, mapping),
    10991045                                 RX_PKT_BUF_SZ,
    1100                                  PCI_DMA_FROMDEVICE);
     1046                                 DMA_FROM_DEVICE);
    11011047                dev_kfree_skb_any(rp->skb);
    11021048                rp->skb = NULL;
    11031049        }
    static void b44_free_rings(struct b44 *b  
    11081054
    11091055                if (rp->skb == NULL)
    11101056                        continue;
    1111                 pci_unmap_single(bp->pdev,
     1057                dma_unmap_single(&bp->sdev->dev,
    11121058                                 pci_unmap_addr(rp, mapping),
    11131059                                 rp->skb->len,
    1114                                  PCI_DMA_TODEVICE);
     1060                                 DMA_TO_DEVICE);
    11151061                dev_kfree_skb_any(rp->skb);
    11161062                rp->skb = NULL;
    11171063        }
    static void b44_init_rings(struct b44 *b  
    11331079        memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
    11341080
    11351081        if (bp->flags & B44_FLAG_RX_RING_HACK)
    1136                 dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
    1137                                            DMA_TABLE_BYTES,
    1138                                            PCI_DMA_BIDIRECTIONAL);
     1082                dma_sync_single_for_device(&bp->sdev->dev, bp->rx_ring_dma,
     1083                                          DMA_TABLE_BYTES,
     1084                                          DMA_BIDIRECTIONAL);
    11391085
    11401086        if (bp->flags & B44_FLAG_TX_RING_HACK)
    1141                 dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
    1142                                            DMA_TABLE_BYTES,
    1143                                            PCI_DMA_TODEVICE);
     1087                dma_sync_single_for_device(&bp->sdev->dev, bp->tx_ring_dma,
     1088                                          DMA_TABLE_BYTES,
     1089                                          DMA_TO_DEVICE);
    11441090
    11451091        for (i = 0; i < bp->rx_pending; i++) {
    11461092                if (b44_alloc_rx_skb(bp, -1, i) < 0)
    static void b44_free_consistent(struct b  
    11601106        bp->tx_buffers = NULL;
    11611107        if (bp->rx_ring) {
    11621108                if (bp->flags & B44_FLAG_RX_RING_HACK) {
    1163                         dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
    1164                                          DMA_TABLE_BYTES,
    1165                                          DMA_BIDIRECTIONAL);
     1109                        dma_unmap_single(&bp->sdev->dev, bp->rx_ring_dma,
     1110                                        DMA_TABLE_BYTES,
     1111                                        DMA_BIDIRECTIONAL);
    11661112                        kfree(bp->rx_ring);
    11671113                } else
    1168                         pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
     1114                        dma_free_coherent(&bp->sdev->dev, DMA_TABLE_BYTES,
    11691115                                            bp->rx_ring, bp->rx_ring_dma);
    11701116                bp->rx_ring = NULL;
    11711117                bp->flags &= ~B44_FLAG_RX_RING_HACK;
    11721118        }
    11731119        if (bp->tx_ring) {
    11741120                if (bp->flags & B44_FLAG_TX_RING_HACK) {
    1175                         dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
    1176                                          DMA_TABLE_BYTES,
    1177                                          DMA_TO_DEVICE);
     1121                        dma_unmap_single(&bp->sdev->dev, bp->tx_ring_dma,
     1122                                        DMA_TABLE_BYTES,
     1123                                        DMA_TO_DEVICE);
    11781124                        kfree(bp->tx_ring);
    11791125                } else
    1180                         pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
     1126                        dma_free_coherent(&bp->sdev->dev, DMA_TABLE_BYTES,
    11811127                                            bp->tx_ring, bp->tx_ring_dma);
    11821128                bp->tx_ring = NULL;
    11831129                bp->flags &= ~B44_FLAG_TX_RING_HACK;
    static int b44_alloc_consistent(struct b  
    12031149                goto out_err;
    12041150
    12051151        size = DMA_TABLE_BYTES;
    1206         bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
     1152        bp->rx_ring = dma_alloc_coherent(&bp->sdev->dev, size, &bp->rx_ring_dma, GFP_ATOMIC);
    12071153        if (!bp->rx_ring) {
    12081154                /* Allocation may have failed due to pci_alloc_consistent
    12091155                   insisting on use of GFP_DMA, which is more restrictive
    static int b44_alloc_consistent(struct b  
    12151161                if (!rx_ring)
    12161162                        goto out_err;
    12171163
    1218                 rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
    1219                                              DMA_TABLE_BYTES,
    1220                                              DMA_BIDIRECTIONAL);
     1164                rx_ring_dma = dma_map_single(&bp->sdev->dev, rx_ring,
     1165                                            DMA_TABLE_BYTES,
     1166                                            DMA_BIDIRECTIONAL);
    12211167
    12221168                if (dma_mapping_error(rx_ring_dma) ||
    12231169                        rx_ring_dma + size > B44_DMA_MASK) {
    static int b44_alloc_consistent(struct b  
    12301176                bp->flags |= B44_FLAG_RX_RING_HACK;
    12311177        }
    12321178
    1233         bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
     1179        bp->tx_ring = dma_alloc_coherent(&bp->sdev->dev, size, &bp->tx_ring_dma, GFP_ATOMIC);
    12341180        if (!bp->tx_ring) {
    1235                 /* Allocation may have failed due to pci_alloc_consistent
     1181                /* Allocation may have failed due to dma_alloc_coherent
    12361182                   insisting on use of GFP_DMA, which is more restrictive
    12371183                   than necessary...  */
    12381184                struct dma_desc *tx_ring;
    static int b44_alloc_consistent(struct b  
    12421188                if (!tx_ring)
    12431189                        goto out_err;
    12441190
    1245                 tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
    1246                                              DMA_TABLE_BYTES,
    1247                                              DMA_TO_DEVICE);
     1191                tx_ring_dma = dma_map_single(&bp->sdev->dev, tx_ring,
     1192                                            DMA_TABLE_BYTES,
     1193                                            DMA_TO_DEVICE);
    12481194
    12491195                if (dma_mapping_error(tx_ring_dma) ||
    12501196                        tx_ring_dma + size > B44_DMA_MASK) {
    static void b44_clear_stats(struct b44 *  
    12791225/* bp->lock is held. */
    12801226static void b44_chip_reset(struct b44 *bp)
    12811227{
    1282         if (ssb_is_core_up(bp)) {
     1228        struct ssb_device *sdev = bp->sdev;
     1229
     1230        if (ssb_device_is_enabled(bp->sdev)) {
    12831231                bw32(bp, B44_RCV_LAZY, 0);
    12841232                bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
    12851233                b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 100, 1);
    static void b44_chip_reset(struct b44 *b  
    12911239                }
    12921240                bw32(bp, B44_DMARX_CTRL, 0);
    12931241                bp->rx_prod = bp->rx_cons = 0;
    1294         } else {
    1295                 ssb_pci_setup(bp, (bp->core_unit == 0 ?
    1296                                    SBINTVEC_ENET0 :
    1297                                    SBINTVEC_ENET1));
    12981242        }
    12991243
    1300         ssb_core_reset(bp);
    1301 
     1244        ssb_device_enable(bp->sdev, 0);
    13021245        b44_clear_stats(bp);
    13031246
    1304         /* Make PHY accessible. */
    1305         bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
     1247        switch (sdev->bus->bustype) {
     1248        case SSB_BUSTYPE_SSB:
     1249                        bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
     1250                             (((ssb_clockspeed(sdev->bus) + (B44_MDC_RATIO / 2)) / B44_MDC_RATIO)
     1251                             & MDIO_CTRL_MAXF_MASK)));
     1252                break;
     1253        case SSB_BUSTYPE_PCI:
     1254                bw32(bp, B44_MDIO_CTRL, (MDIO_CTRL_PREAMBLE |
    13061255                             (0x0d & MDIO_CTRL_MAXF_MASK)));
     1256                break;
     1257        }
     1258
    13071259        br32(bp, B44_MDIO_CTRL);
    13081260
    13091261        if (!(br32(bp, B44_DEVCTRL) & DEVCTRL_IPP)) {
    static int b44_set_mac_addr(struct net_d  
    13461298{
    13471299        struct b44 *bp = netdev_priv(dev);
    13481300        struct sockaddr *addr = p;
     1301        u32 val;
    13491302
    13501303        if (netif_running(dev))
    13511304                return -EBUSY;
    static int b44_set_mac_addr(struct net_d  
    13561309        memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
    13571310
    13581311        spin_lock_irq(&bp->lock);
    1359         __b44_set_mac_addr(bp);
     1312   
     1313        val = br32(bp, B44_RXCONFIG);
     1314        if (!(val & RXCONFIG_CAM_ABSENT))
     1315                __b44_set_mac_addr(bp);
     1316   
    13601317        spin_unlock_irq(&bp->lock);
    13611318
    13621319        return 0;
    out:  
    14421399        return err;
    14431400}
    14441401
    1445 #if 0
    1446 /*static*/ void b44_dump_state(struct b44 *bp)
    1447 {
    1448         u32 val32, val32_2, val32_3, val32_4, val32_5;
    1449         u16 val16;
    1450 
    1451         pci_read_config_word(bp->pdev, PCI_STATUS, &val16);
    1452         printk("DEBUG: PCI status [%04x] \n", val16);
    1453 
    1454 }
    1455 #endif
    1456 
    14571402#ifdef CONFIG_NET_POLL_CONTROLLER
    14581403/*
    14591404 * Polling receive - used by netconsole and other diagnostic tools
    static void b44_setup_pseudo_magicp(stru  
    15681513static void b44_setup_wol(struct b44 *bp)
    15691514{
    15701515        u32 val;
    1571         u16 pmval;
    15721516
    15731517        bw32(bp, B44_RXCONFIG, RXCONFIG_ALLMULTI);
    15741518
    static void b44_setup_wol(struct b44 *bp  
    15921536        } else {
    15931537                b44_setup_pseudo_magicp(bp);
    15941538        }
    1595 
    1596         val = br32(bp, B44_SBTMSLOW);
    1597         bw32(bp, B44_SBTMSLOW, val | SBTMSLOW_PE);
    1598 
    1599         pci_read_config_word(bp->pdev, SSB_PMCSR, &pmval);
    1600         pci_write_config_word(bp->pdev, SSB_PMCSR, pmval | SSB_PE);
    1601 
    16021539}
    16031540
    16041541static int b44_close(struct net_device *dev)
    static void __b44_set_rx_mode(struct net  
    16981635
    16991636        val = br32(bp, B44_RXCONFIG);
    17001637        val &= ~(RXCONFIG_PROMISC | RXCONFIG_ALLMULTI);
    1701         if (dev->flags & IFF_PROMISC) {
     1638        if ((dev->flags & IFF_PROMISC) || (val & RXCONFIG_CAM_ABSENT)) {
    17021639                val |= RXCONFIG_PROMISC;
    17031640                bw32(bp, B44_RXCONFIG, val);
    17041641        } else {
    static void b44_set_msglevel(struct net_  
    17451682
    17461683static void b44_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info)
    17471684{
    1748         struct b44 *bp = netdev_priv(dev);
    1749         struct pci_dev *pci_dev = bp->pdev;
    1750 
    17511685        strcpy (info->driver, DRV_MODULE_NAME);
    17521686        strcpy (info->version, DRV_MODULE_VERSION);
    1753         strcpy (info->bus_info, pci_name(pci_dev));
    17541687}
    17551688
    17561689static int b44_nway_reset(struct net_device *dev)
    static const struct ethtool_ops b44_etht  
    20341967        .get_perm_addr          = ethtool_op_get_perm_addr,
    20351968};
    20361969
     1970static int b44_ethtool_ioctl (struct net_device *dev, void __user *useraddr)
     1971{
     1972        struct b44 *bp = dev->priv;
     1973        u32 ethcmd;
     1974
     1975        if (copy_from_user (&ethcmd, useraddr, sizeof (ethcmd)))
     1976                return -EFAULT;
     1977
     1978        switch (ethcmd) {
     1979        case ETHTOOL_GDRVINFO: {
     1980                struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
     1981                strcpy (info.driver, DRV_MODULE_NAME);
     1982                strcpy (info.version, DRV_MODULE_VERSION);
     1983                memset(&info.fw_version, 0, sizeof(info.fw_version));
     1984                info.eedump_len = 0;
     1985                info.regdump_len = 0;
     1986                if (copy_to_user (useraddr, &info, sizeof (info)))
     1987                        return -EFAULT;
     1988                return 0;
     1989        }
     1990
     1991        case ETHTOOL_GSET: {
     1992                struct ethtool_cmd cmd = { ETHTOOL_GSET };
     1993
     1994                if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
     1995                        return -EAGAIN;
     1996                cmd.supported = (SUPPORTED_Autoneg);
     1997                cmd.supported |= (SUPPORTED_100baseT_Half |
     1998                                  SUPPORTED_100baseT_Full |
     1999                                  SUPPORTED_10baseT_Half |
     2000                                  SUPPORTED_10baseT_Full |
     2001                                  SUPPORTED_MII);
     2002
     2003                cmd.advertising = 0;
     2004                if (bp->flags & B44_FLAG_ADV_10HALF)
     2005                        cmd.advertising |= ADVERTISE_10HALF;
     2006                if (bp->flags & B44_FLAG_ADV_10FULL)
     2007                        cmd.advertising |= ADVERTISE_10FULL;
     2008                if (bp->flags & B44_FLAG_ADV_100HALF)
     2009                        cmd.advertising |= ADVERTISE_100HALF;
     2010                if (bp->flags & B44_FLAG_ADV_100FULL)
     2011                        cmd.advertising |= ADVERTISE_100FULL;
     2012                cmd.advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
     2013                cmd.speed = (bp->flags & B44_FLAG_100_BASE_T) ?
     2014                        SPEED_100 : SPEED_10;
     2015                cmd.duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
     2016                        DUPLEX_FULL : DUPLEX_HALF;
     2017                cmd.port = 0;
     2018                cmd.phy_address = bp->phy_addr;
     2019                cmd.transceiver = (bp->flags & B44_FLAG_INTERNAL_PHY) ?
     2020                        XCVR_INTERNAL : XCVR_EXTERNAL;
     2021                cmd.autoneg = (bp->flags & B44_FLAG_FORCE_LINK) ?
     2022                        AUTONEG_DISABLE : AUTONEG_ENABLE;
     2023                cmd.maxtxpkt = 0;
     2024                cmd.maxrxpkt = 0;
     2025                if (copy_to_user(useraddr, &cmd, sizeof(cmd)))
     2026                        return -EFAULT;
     2027                return 0;
     2028        }
     2029        case ETHTOOL_SSET: {
     2030                struct ethtool_cmd cmd;
     2031
     2032                if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
     2033                        return -EAGAIN;
     2034
     2035                if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
     2036                        return -EFAULT;
     2037
     2038                /* We do not support gigabit. */
     2039                if (cmd.autoneg == AUTONEG_ENABLE) {
     2040                        if (cmd.advertising &
     2041                            (ADVERTISED_1000baseT_Half |
     2042                             ADVERTISED_1000baseT_Full))
     2043                                return -EINVAL;
     2044                } else if ((cmd.speed != SPEED_100 &&
     2045                            cmd.speed != SPEED_10) ||
     2046                           (cmd.duplex != DUPLEX_HALF &&
     2047                            cmd.duplex != DUPLEX_FULL)) {
     2048                                return -EINVAL;
     2049                }
     2050
     2051                spin_lock_irq(&bp->lock);
     2052
     2053                if (cmd.autoneg == AUTONEG_ENABLE) {
     2054                        bp->flags &= ~B44_FLAG_FORCE_LINK;
     2055                        bp->flags &= ~(B44_FLAG_ADV_10HALF |
     2056                                       B44_FLAG_ADV_10FULL |
     2057                                       B44_FLAG_ADV_100HALF |
     2058                                       B44_FLAG_ADV_100FULL);
     2059                        if (cmd.advertising & ADVERTISE_10HALF)
     2060                                bp->flags |= B44_FLAG_ADV_10HALF;
     2061                        if (cmd.advertising & ADVERTISE_10FULL)
     2062                                bp->flags |= B44_FLAG_ADV_10FULL;
     2063                        if (cmd.advertising & ADVERTISE_100HALF)
     2064                                bp->flags |= B44_FLAG_ADV_100HALF;
     2065                        if (cmd.advertising & ADVERTISE_100FULL)
     2066                                bp->flags |= B44_FLAG_ADV_100FULL;
     2067                } else {
     2068                        bp->flags |= B44_FLAG_FORCE_LINK;
     2069                        if (cmd.speed == SPEED_100)
     2070                                bp->flags |= B44_FLAG_100_BASE_T;
     2071                        if (cmd.duplex == DUPLEX_FULL)
     2072                                bp->flags |= B44_FLAG_FULL_DUPLEX;
     2073                }
     2074
     2075                b44_setup_phy(bp);
     2076
     2077                spin_unlock_irq(&bp->lock);
     2078
     2079                return 0;
     2080        }
     2081
     2082        case ETHTOOL_GMSGLVL: {
     2083                struct ethtool_value edata = { ETHTOOL_GMSGLVL };
     2084                edata.data = bp->msg_enable;
     2085                if (copy_to_user(useraddr, &edata, sizeof(edata)))
     2086                        return -EFAULT;
     2087                return 0;
     2088        }
     2089        case ETHTOOL_SMSGLVL: {
     2090                struct ethtool_value edata;
     2091                if (copy_from_user(&edata, useraddr, sizeof(edata)))
     2092                        return -EFAULT;
     2093                bp->msg_enable = edata.data;
     2094                return 0;
     2095        }
     2096        case ETHTOOL_NWAY_RST: {
     2097                u32 bmcr;
     2098                int r;
     2099
     2100                spin_lock_irq(&bp->lock);
     2101                b44_readphy(bp, MII_BMCR, &bmcr);
     2102                b44_readphy(bp, MII_BMCR, &bmcr);
     2103                r = -EINVAL;
     2104                if (bmcr & BMCR_ANENABLE) {
     2105                        b44_writephy(bp, MII_BMCR,
     2106                                     bmcr | BMCR_ANRESTART);
     2107                        r = 0;
     2108                }
     2109                spin_unlock_irq(&bp->lock);
     2110
     2111                return r;
     2112        }
     2113        case ETHTOOL_GLINK: {
     2114                struct ethtool_value edata = { ETHTOOL_GLINK };
     2115                edata.data = netif_carrier_ok(bp->dev) ? 1 : 0;
     2116                if (copy_to_user(useraddr, &edata, sizeof(edata)))
     2117                        return -EFAULT;
     2118                return 0;
     2119        }
     2120        case ETHTOOL_GRINGPARAM: {
     2121                struct ethtool_ringparam ering = { ETHTOOL_GRINGPARAM };
     2122
     2123                ering.rx_max_pending = B44_RX_RING_SIZE - 1;
     2124                ering.rx_pending = bp->rx_pending;
     2125
     2126                /* XXX ethtool lacks a tx_max_pending, oops... */
     2127
     2128                if (copy_to_user(useraddr, &ering, sizeof(ering)))
     2129                        return -EFAULT;
     2130                return 0;
     2131        }
     2132        case ETHTOOL_SRINGPARAM: {
     2133                struct ethtool_ringparam ering;
     2134
     2135                if (copy_from_user(&ering, useraddr, sizeof(ering)))
     2136                        return -EFAULT;
     2137
     2138                if ((ering.rx_pending > B44_RX_RING_SIZE - 1) ||
     2139                    (ering.rx_mini_pending != 0) ||
     2140                    (ering.rx_jumbo_pending != 0) ||
     2141                    (ering.tx_pending > B44_TX_RING_SIZE - 1))
     2142                        return -EINVAL;
     2143
     2144                spin_lock_irq(&bp->lock);
     2145
     2146                bp->rx_pending = ering.rx_pending;
     2147                bp->tx_pending = ering.tx_pending;
     2148
     2149                b44_halt(bp);
     2150                b44_init_rings(bp);
     2151                b44_init_hw(bp, 1);
     2152                netif_wake_queue(bp->dev);
     2153                spin_unlock_irq(&bp->lock);
     2154
     2155                b44_enable_ints(bp);
     2156               
     2157                return 0;
     2158        }
     2159        case ETHTOOL_GPAUSEPARAM: {
     2160                struct ethtool_pauseparam epause = { ETHTOOL_GPAUSEPARAM };
     2161
     2162                epause.autoneg =
     2163                        (bp->flags & B44_FLAG_PAUSE_AUTO) != 0;
     2164                epause.rx_pause =
     2165                        (bp->flags & B44_FLAG_RX_PAUSE) != 0;
     2166                epause.tx_pause =
     2167                        (bp->flags & B44_FLAG_TX_PAUSE) != 0;
     2168                if (copy_to_user(useraddr, &epause, sizeof(epause)))
     2169                        return -EFAULT;
     2170                return 0;
     2171        }
     2172        case ETHTOOL_SPAUSEPARAM: {
     2173                struct ethtool_pauseparam epause;
     2174
     2175                if (copy_from_user(&epause, useraddr, sizeof(epause)))
     2176                        return -EFAULT;
     2177
     2178                spin_lock_irq(&bp->lock);
     2179                if (epause.autoneg)
     2180                        bp->flags |= B44_FLAG_PAUSE_AUTO;
     2181                else
     2182                        bp->flags &= ~B44_FLAG_PAUSE_AUTO;
     2183                if (epause.rx_pause)
     2184                        bp->flags |= B44_FLAG_RX_PAUSE;
     2185                else
     2186                        bp->flags &= ~B44_FLAG_RX_PAUSE;
     2187                if (epause.tx_pause)
     2188                        bp->flags |= B44_FLAG_TX_PAUSE;
     2189                else
     2190                        bp->flags &= ~B44_FLAG_TX_PAUSE;
     2191                if (bp->flags & B44_FLAG_PAUSE_AUTO) {
     2192                        b44_halt(bp);
     2193                        b44_init_rings(bp);
     2194                        b44_init_hw(bp, 1);
     2195                } else {
     2196                        __b44_set_flow_ctrl(bp, bp->flags);
     2197                }
     2198                spin_unlock_irq(&bp->lock);
     2199
     2200                b44_enable_ints(bp);
     2201               
     2202                return 0;
     2203        }
     2204        };
     2205
     2206        return -EOPNOTSUPP;
     2207}
     2208
    20372209static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
    20382210{
    20392211        struct mii_ioctl_data *data = if_mii(ifr);
    static int b44_ioctl(struct net_device *  
    20432215        if (!netif_running(dev))
    20442216                goto out;
    20452217
    2046         spin_lock_irq(&bp->lock);
    2047         err = generic_mii_ioctl(&bp->mii_if, data, cmd, NULL);
    2048         spin_unlock_irq(&bp->lock);
    2049 out:
    2050         return err;
    2051 }
     2218        switch (cmd) {
     2219        case SIOCETHTOOL:
     2220               return b44_ethtool_ioctl(dev, (void __user*) ifr->ifr_data);
    20522221
    2053 /* Read 128-bytes of EEPROM. */
    2054 static int b44_read_eeprom(struct b44 *bp, u8 *data)
    2055 {
    2056         long i;
    2057         u16 *ptr = (u16 *) data;
     2222        case SIOCGMIIPHY:
     2223               data->phy_id = bp->phy_addr;
    20582224
    2059         for (i = 0; i < 128; i += 2)
    2060                 ptr[i / 2] = cpu_to_le16(readw(bp->regs + 4096 + i));
     2225               /* fallthru */
     2226        case SIOCGMIIREG: {
     2227               u32 mii_regval;
     2228               spin_lock_irq(&bp->lock);
     2229               err = __b44_readphy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, &mii_regval);
     2230               spin_unlock_irq(&bp->lock);
    20612231
    2062         return 0;
     2232               data->val_out = mii_regval;
     2233
     2234               return err;
     2235        }
     2236
     2237        case SIOCSMIIREG:
     2238               if (!capable(CAP_NET_ADMIN))
     2239                      return -EPERM;
     2240
     2241               spin_lock_irq(&bp->lock);
     2242               err = __b44_writephy(bp, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
     2243               spin_unlock_irq(&bp->lock);
     2244
     2245               return err;
     2246
     2247        default:
     2248               break;
     2249        };
     2250        return -EOPNOTSUPP;
     2251
     2252out:
     2253        return err;
    20632254}
    20642255
    20652256static int __devinit b44_get_invariants(struct b44 *bp)
    20662257{
    2067         u8 eeprom[128];
    2068         int err;
     2258        struct ssb_device *sdev = bp->sdev;
     2259        int err = 0;
     2260        u8 *addr;
    20692261
    2070         err = b44_read_eeprom(bp, &eeprom[0]);
    2071         if (err)
    2072                 goto out;
     2262        bp->dma_offset = ssb_dma_offset(sdev);
    20732263
    2074         bp->dev->dev_addr[0] = eeprom[79];
    2075         bp->dev->dev_addr[1] = eeprom[78];
    2076         bp->dev->dev_addr[2] = eeprom[81];
    2077         bp->dev->dev_addr[3] = eeprom[80];
    2078         bp->dev->dev_addr[4] = eeprom[83];
    2079         bp->dev->dev_addr[5] = eeprom[82];
     2264        switch (instance) {
     2265        case 1:
     2266               addr = sdev->bus->sprom.r1.et0mac;
     2267               bp->phy_addr = sdev->bus->sprom.r1.et0phyaddr;
     2268               break;
     2269        default:
     2270               addr = sdev->bus->sprom.r1.et1mac;
     2271               bp->phy_addr = sdev->bus->sprom.r1.et1phyaddr;
     2272               break;
     2273        }
     2274
     2275        memcpy(bp->dev->dev_addr, addr, 6);
    20802276
    20812277        if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
    20822278                printk(KERN_ERR PFX "Invalid MAC address found in EEPROM\n");
    static int __devinit b44_get_invariants(  
    20852281
    20862282        memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
    20872283
    2088         bp->phy_addr = eeprom[90] & 0x1f;
    2089 
    20902284        /* With this, plus the rx_header prepended to the data by the
    20912285         * hardware, we'll land the ethernet header on a 2-byte boundary.
    20922286         */
    20932287        bp->rx_offset = 30;
    2094 
    20952288        bp->imask = IMASK_DEF;
    2096 
    2097         bp->core_unit = ssb_core_unit(bp);
    2098         bp->dma_offset = SB_PCI_DMA;
    2099 
    21002289        /* XXX - really required?
    21012290           bp->flags |= B44_FLAG_BUGGY_TXPTR;
    2102          */
     2291        */
    21032292
    2104         if (ssb_get_core_rev(bp) >= 7)
    2105                 bp->flags |= B44_FLAG_B0_ANDLATER;
    2106 
    2107 out:
    21082293        return err;
    21092294}
    21102295
    2111 static int __devinit b44_init_one(struct pci_dev *pdev,
    2112                                   const struct pci_device_id *ent)
     2296static int __devinit b44_init_one(struct ssb_device *sdev,
     2297                                  const struct ssb_device_id *ent)
    21132298{
    21142299        static int b44_version_printed = 0;
    2115         unsigned long b44reg_base, b44reg_len;
    21162300        struct net_device *dev;
    21172301        struct b44 *bp;
    21182302        int err, i;
    21192303
     2304        instance++;
     2305
    21202306        if (b44_version_printed++ == 0)
    21212307                printk(KERN_INFO "%s", version);
    21222308
    2123         err = pci_enable_device(pdev);
    2124         if (err) {
    2125                 dev_err(&pdev->dev, "Cannot enable PCI device, "
    2126                        "aborting.\n");
    2127                 return err;
    2128         }
    2129 
    2130         if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
    2131                 dev_err(&pdev->dev,
    2132                         "Cannot find proper PCI device "
    2133                        "base address, aborting.\n");
    2134                 err = -ENODEV;
    2135                 goto err_out_disable_pdev;
    2136         }
    2137 
    2138         err = pci_request_regions(pdev, DRV_MODULE_NAME);
    2139         if (err) {
    2140                 dev_err(&pdev->dev,
    2141                         "Cannot obtain PCI resources, aborting.\n");
    2142                 goto err_out_disable_pdev;
    2143         }
    2144 
    2145         pci_set_master(pdev);
    2146 
    2147         err = pci_set_dma_mask(pdev, (u64) B44_DMA_MASK);
    2148         if (err) {
    2149                 dev_err(&pdev->dev, "No usable DMA configuration, aborting.\n");
    2150                 goto err_out_free_res;
    2151         }
    2152 
    2153         err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
    2154         if (err) {
    2155                 dev_err(&pdev->dev, "No usable DMA configuration, aborting.\n");
    2156                 goto err_out_free_res;
    2157         }
    2158 
    2159         b44reg_base = pci_resource_start(pdev, 0);
    2160         b44reg_len = pci_resource_len(pdev, 0);
    2161 
    21622309        dev = alloc_etherdev(sizeof(*bp));
    21632310        if (!dev) {
    2164                 dev_err(&pdev->dev, "Etherdev alloc failed, aborting.\n");
     2311                dev_err(&sdev->dev, "Etherdev alloc failed, aborting.\n");
    21652312                err = -ENOMEM;
    2166                 goto err_out_free_res;
     2313                goto out;
    21672314        }
    21682315
    21692316        SET_MODULE_OWNER(dev);
    2170         SET_NETDEV_DEV(dev,&pdev->dev);
     2317        SET_NETDEV_DEV(dev,&sdev->dev);
    21712318
    21722319        /* No interesting netdevice features in this card... */
    21732320        dev->features |= 0;
    21742321
    21752322        bp = netdev_priv(dev);
    2176         bp->pdev = pdev;
     2323        bp->sdev = sdev;
    21772324        bp->dev = dev;
    21782325
    21792326        bp->msg_enable = netif_msg_init(b44_debug, B44_DEF_MSG_ENABLE);
    21802327
    21812328        spin_lock_init(&bp->lock);
    21822329
    2183         bp->regs = ioremap(b44reg_base, b44reg_len);
    2184         if (bp->regs == 0UL) {
    2185                 dev_err(&pdev->dev, "Cannot map device registers, aborting.\n");
    2186                 err = -ENOMEM;
    2187                 goto err_out_free_dev;
    2188         }
    2189 
    21902330        bp->rx_pending = B44_DEF_RX_RING_PENDING;
    21912331        bp->tx_pending = B44_DEF_TX_RING_PENDING;
    21922332
    static int __devinit b44_init_one(struct  
    22052345        dev->poll_controller = b44_poll_controller;
    22062346#endif
    22072347        dev->change_mtu = b44_change_mtu;
    2208         dev->irq = pdev->irq;
     2348        dev->irq = sdev->irq;
    22092349        SET_ETHTOOL_OPS(dev, &b44_ethtool_ops);
    22102350
    22112351        netif_carrier_off(dev);
    22122352
    22132353        err = b44_get_invariants(bp);
    22142354        if (err) {
    2215                 dev_err(&pdev->dev,
     2355                dev_err(&sdev->dev,
    22162356                        "Problem fetching invariants of chip, aborting.\n");
    2217                 goto err_out_iounmap;
     2357                goto err_out_free_dev;
    22182358        }
    22192359
    22202360        bp->mii_if.dev = dev;
    static int __devinit b44_init_one(struct  
    22332373
    22342374        err = register_netdev(dev);
    22352375        if (err) {
    2236                 dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
    2237                 goto err_out_iounmap;
     2376                dev_err(&sdev->dev, "Cannot register net device, aborting.\n");
     2377                goto out;
    22382378        }
    22392379
    2240         pci_set_drvdata(pdev, dev);
    2241 
    2242         pci_save_state(bp->pdev);
     2380        ssb_set_drvdata(sdev, dev);
    22432381
    22442382        /* Chip reset provides power to the b44 MAC & PCI cores, which
    22452383         * is necessary for MAC register access.
    22462384         */
    22472385        b44_chip_reset(bp);
    22482386
    2249         printk(KERN_INFO "%s: Broadcom 4400 10/100BaseT Ethernet ", dev->name);
     2387        printk(KERN_INFO "%s: Broadcom 10/100BaseT Ethernet ", dev->name);
    22502388        for (i = 0; i < 6; i++)
    22512389                printk("%2.2x%c", dev->dev_addr[i],
    22522390                       i == 5 ? '\n' : ':');
    22532391
    2254         return 0;
     2392        /* Initialize phy */
     2393        spin_lock_irq(&bp->lock);
     2394        b44_chip_reset(bp);
     2395        spin_unlock_irq(&bp->lock);
    22552396
    2256 err_out_iounmap:
    2257         iounmap(bp->regs);
     2397        return 0;
    22582398
    22592399err_out_free_dev:
    22602400        free_netdev(dev);
    22612401
    2262 err_out_free_res:
    2263         pci_release_regions(pdev);
    2264 
    2265 err_out_disable_pdev:
    2266         pci_disable_device(pdev);
    2267         pci_set_drvdata(pdev, NULL);
     2402out:
    22682403        return err;
    22692404}
    22702405
    2271 static void __devexit b44_remove_one(struct pci_dev *pdev)
     2406static void __devexit b44_remove_one(struct ssb_device *pdev)
    22722407{
    2273         struct net_device *dev = pci_get_drvdata(pdev);
    2274         struct b44 *bp = netdev_priv(dev);
     2408        struct net_device *dev = ssb_get_drvdata(pdev);
    22752409
    22762410        unregister_netdev(dev);
    2277         iounmap(bp->regs);
    22782411        free_netdev(dev);
    2279         pci_release_regions(pdev);
    2280         pci_disable_device(pdev);
    2281         pci_set_drvdata(pdev, NULL);
     2412        ssb_set_drvdata(pdev, NULL);
    22822413}
    22832414
    2284 static int b44_suspend(struct pci_dev *pdev, pm_message_t state)
     2415static int b44_suspend(struct ssb_device *pdev, pm_message_t state)
    22852416{
    2286         struct net_device *dev = pci_get_drvdata(pdev);
     2417        struct net_device *dev = ssb_get_drvdata(pdev);
    22872418        struct b44 *bp = netdev_priv(dev);
    22882419
    22892420        if (!netif_running(dev))
    2290                  return 0;
     2421                return 0;
    22912422
    22922423        del_timer_sync(&bp->timer);
    22932424
    static int b44_suspend(struct pci_dev *p  
    23052436                b44_init_hw(bp, 0);
    23062437                b44_setup_wol(bp);
    23072438        }
    2308         pci_disable_device(pdev);
     2439
    23092440        return 0;
    23102441}
    23112442
    2312 static int b44_resume(struct pci_dev *pdev)
     2443static int b44_resume(struct ssb_device *pdev)
    23132444{
    2314         struct net_device *dev = pci_get_drvdata(pdev);
     2445        struct net_device *dev = ssb_get_drvdata(pdev);
    23152446        struct b44 *bp = netdev_priv(dev);
    23162447
    2317         pci_restore_state(pdev);
    2318         pci_enable_device(pdev);
    2319         pci_set_master(pdev);
    2320 
    23212448        if (!netif_running(dev))
    23222449                return 0;
    23232450
    static int b44_resume(struct pci_dev *pd  
    23392466        return 0;
    23402467}
    23412468
    2342 static struct pci_driver b44_driver = {
     2469static struct ssb_driver b44_driver = {
    23432470        .name           = DRV_MODULE_NAME,
    2344         .id_table       = b44_pci_tbl,
     2471        .id_table       = b44_ssb_tbl,
    23452472        .probe          = b44_init_one,
    23462473        .remove         = __devexit_p(b44_remove_one),
    2347         .suspend        = b44_suspend,
    2348         .resume         = b44_resume,
     2474        .suspend        = b44_suspend,
     2475        .resume         = b44_resume,
    23492476};
    23502477
    23512478static int __init b44_init(void)
    23522479{
    23532480        unsigned int dma_desc_align_size = dma_get_cache_alignment();
    23542481
     2482        instance = 0;
     2483
    23552484        /* Setup paramaters for syncing RX/TX DMA descriptors */
    23562485        dma_desc_align_mask = ~(dma_desc_align_size - 1);
    23572486        dma_desc_sync_size = max_t(unsigned int, dma_desc_align_size, sizeof(struct dma_desc));
    23582487
    2359         return pci_register_driver(&b44_driver);
     2488        return ssb_driver_register(&b44_driver);
    23602489}
    23612490
    23622491static void __exit b44_cleanup(void)
    23632492{
    2364         pci_unregister_driver(&b44_driver);
     2493        ssb_driver_unregister(&b44_driver);
    23652494}
    23662495
    23672496module_init(b44_init);
  • drivers/net/b44.h

    diff --git a/drivers/net/b44.h b/drivers/net/b44.h
    index 4944507..7e3ea87 100644
    a b  
    129129#define  RXCONFIG_FLOW          0x00000020 /* Flow Control Enable */
    130130#define  RXCONFIG_FLOW_ACCEPT   0x00000040 /* Accept Unicast Flow Control Frame */
    131131#define  RXCONFIG_RFILT         0x00000080 /* Reject Filter */
     132#define  RXCONFIG_CAM_ABSENT    0x00000100 /* CAM Absent */
    132133#define B44_RXMAXLEN    0x0404UL /* EMAC RX Max Packet Length */
    133134#define B44_TXMAXLEN    0x0408UL /* EMAC TX Max Packet Length */
    134135#define B44_MDIO_CTRL   0x0410UL /* EMAC MDIO Control */
     
    227228#define B44_RX_PAUSE    0x05D4UL /* MIB RX Pause Packets */
    228229#define B44_RX_NPAUSE   0x05D8UL /* MIB RX Non-Pause Packets */
    229230
    230 /* Silicon backplane register definitions */
    231 #define B44_SBIMSTATE   0x0F90UL /* SB Initiator Agent State */
    232 #define  SBIMSTATE_PC           0x0000000f /* Pipe Count */
    233 #define  SBIMSTATE_AP_MASK      0x00000030 /* Arbitration Priority */
    234 #define  SBIMSTATE_AP_BOTH      0x00000000 /* Use both timeslices and token */
    235 #define  SBIMSTATE_AP_TS        0x00000010 /* Use timeslices only */
    236 #define  SBIMSTATE_AP_TK        0x00000020 /* Use token only */
    237 #define  SBIMSTATE_AP_RSV       0x00000030 /* Reserved */
    238 #define  SBIMSTATE_IBE          0x00020000 /* In Band Error */
    239 #define  SBIMSTATE_TO           0x00040000 /* Timeout */
    240 #define B44_SBINTVEC    0x0F94UL /* SB Interrupt Mask */
    241 #define  SBINTVEC_PCI           0x00000001 /* Enable interrupts for PCI */
    242 #define  SBINTVEC_ENET0         0x00000002 /* Enable interrupts for enet 0 */
    243 #define  SBINTVEC_ILINE20       0x00000004 /* Enable interrupts for iline20 */
    244 #define  SBINTVEC_CODEC         0x00000008 /* Enable interrupts for v90 codec */
    245 #define  SBINTVEC_USB           0x00000010 /* Enable interrupts for usb */
    246 #define  SBINTVEC_EXTIF         0x00000020 /* Enable interrupts for external i/f */
    247 #define  SBINTVEC_ENET1         0x00000040 /* Enable interrupts for enet 1 */
    248 #define B44_SBTMSLOW    0x0F98UL /* SB Target State Low */
    249 #define  SBTMSLOW_RESET         0x00000001 /* Reset */
    250 #define  SBTMSLOW_REJECT        0x00000002 /* Reject */
    251 #define  SBTMSLOW_CLOCK         0x00010000 /* Clock Enable */
    252 #define  SBTMSLOW_FGC           0x00020000 /* Force Gated Clocks On */
    253 #define  SBTMSLOW_PE            0x40000000 /* Power Management Enable */
    254 #define  SBTMSLOW_BE            0x80000000 /* BIST Enable */
    255 #define B44_SBTMSHIGH   0x0F9CUL /* SB Target State High */
    256 #define  SBTMSHIGH_SERR         0x00000001 /* S-error */
    257 #define  SBTMSHIGH_INT          0x00000002 /* Interrupt */
    258 #define  SBTMSHIGH_BUSY         0x00000004 /* Busy */
    259 #define  SBTMSHIGH_GCR          0x20000000 /* Gated Clock Request */
    260 #define  SBTMSHIGH_BISTF        0x40000000 /* BIST Failed */
    261 #define  SBTMSHIGH_BISTD        0x80000000 /* BIST Done */
    262 #define B44_SBIDHIGH    0x0FFCUL /* SB Identification High */
    263 #define  SBIDHIGH_RC_MASK       0x0000000f /* Revision Code */
    264 #define  SBIDHIGH_CC_MASK       0x0000fff0 /* Core Code */
    265 #define  SBIDHIGH_CC_SHIFT      4
    266 #define  SBIDHIGH_VC_MASK       0xffff0000 /* Vendor Code */
    267 #define  SBIDHIGH_VC_SHIFT      16
    268 
    269 /* SSB PCI config space registers.  */
    270 #define SSB_PMCSR               0x44
    271 #define  SSB_PE                 0x100
    272 #define SSB_BAR0_WIN            0x80
    273 #define SSB_BAR1_WIN            0x84
    274 #define SSB_SPROM_CONTROL       0x88
    275 #define SSB_BAR1_CONTROL        0x8c
    276 
    277 /* SSB core and host control registers.  */
    278 #define SSB_CONTROL             0x0000UL
    279 #define SSB_ARBCONTROL          0x0010UL
    280 #define SSB_ISTAT               0x0020UL
    281 #define SSB_IMASK               0x0024UL
    282 #define SSB_MBOX                0x0028UL
    283 #define SSB_BCAST_ADDR          0x0050UL
    284 #define SSB_BCAST_DATA          0x0054UL
    285 #define SSB_PCI_TRANS_0         0x0100UL
    286 #define SSB_PCI_TRANS_1         0x0104UL
    287 #define SSB_PCI_TRANS_2         0x0108UL
    288 #define SSB_SPROM               0x0800UL
    289 
    290 #define SSB_PCI_MEM             0x00000000
    291 #define SSB_PCI_IO              0x00000001
    292 #define SSB_PCI_CFG0            0x00000002
    293 #define SSB_PCI_CFG1            0x00000003
    294 #define SSB_PCI_PREF            0x00000004
    295 #define SSB_PCI_BURST           0x00000008
    296 #define SSB_PCI_MASK0           0xfc000000
    297 #define SSB_PCI_MASK1           0xfc000000
    298 #define SSB_PCI_MASK2           0xc0000000
     231#define br32(bp, REG)   ssb_read32((bp)->sdev, (REG))
     232#define bw32(bp, REG, VAL)      ssb_write32((bp)->sdev, (REG), (VAL))
     233#define atoi(str) simple_strtoul(((str != NULL) ? str : ""), NULL, 0)
    299234
    300235/* 4400 PHY registers */
    301236#define B44_MII_AUXCTRL         24      /* Auxiliary Control */
    struct rx_header {  
    346281
    347282struct ring_info {
    348283        struct sk_buff          *skb;
    349         DECLARE_PCI_UNMAP_ADDR(mapping);
     284        dma_addr_t      mapping;
    350285};
    351286
    352287#define B44_MCAST_TABLE_SIZE    32
     288#define B44_PHY_ADDR_NO_PHY     30
     289#define B44_MDC_RATIO           5000000
    353290
    354291#define B44_STAT_REG_DECLARE            \
    355292        _B44(tx_good_octets)            \
    struct b44 {  
    425362
    426363        u32                     dma_offset;
    427364        u32                     flags;
    428 #define B44_FLAG_B0_ANDLATER    0x00000001
     365#define B44_FLAG_INIT_COMPLETE  0x00000001
    429366#define B44_FLAG_BUGGY_TXPTR    0x00000002
    430367#define B44_FLAG_REORDER_BUG    0x00000004
     368#define B44_FLAG_B0_ANDLATER    0x00000008
    431369#define B44_FLAG_PAUSE_AUTO     0x00008000
    432370#define B44_FLAG_FULL_DUPLEX    0x00010000
    433371#define B44_FLAG_100_BASE_T     0x00020000
    struct b44 {  
    452390        struct net_device_stats stats;
    453391        struct b44_hw_stats     hw_stats;
    454392
    455         void __iomem            *regs;
    456         struct pci_dev          *pdev;
     393        struct ssb_device       *sdev;
    457394        struct net_device       *dev;
    458395
    459396        dma_addr_t              rx_ring_dma, tx_ring_dma;
  • include/asm-mips/bootinfo.h

    diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h
    index 1e5ccda..fd5cc13 100644
    a b  
    212212#define MACH_GROUP_NEC_EMMA2RH 25       /* NEC EMMA2RH (was 23)         */
    213213#define  MACH_NEC_MARKEINS      0       /* NEC EMMA2RH Mark-eins        */
    214214
     215/*
     216 * Valid machtype for group Broadcom
     217 */
     218#define MACH_GROUP_BRCM         23      /* Broadcom                     */
     219#define MACH_BCM47XX            1       /* Broadcom BCM47xx             */
     220
    215221#define CL_SIZE                 COMMAND_LINE_SIZE
    216222
    217223const char *get_system_type(void);
  • new file include/asm-mips/cfe.h

    diff --git a/include/asm-mips/cfe.h b/include/asm-mips/cfe.h
    new file mode 100644
    index 0000000..47c3f56
    - +  
     1/*
     2 * Broadcom Common Firmware Environment (CFE) support
     3 *
     4 * Copyright 2000, 2001, 2002
     5 * Broadcom Corporation. All rights reserved.
     6 *
     7 * Copyright (C) 2006 Michael Buesch
     8 *
     9 * Original Authors:  Mitch Lichtenberg, Chris Demetriou
     10 *
     11 * This software is furnished under license and may be used and copied only
     12 * in accordance with the following terms and conditions.  Subject to these
     13 * conditions, you may download, copy, install, use, modify and distribute
     14 * modified or unmodified copies of this software in source and/or binary
     15 * form. No title or ownership is transferred hereby.
     16 *
     17 * 1) Any source code used, modified or distributed must reproduce and
     18 *    retain this copyright notice and list of conditions as they appear in
     19 *    the source file.
     20 *
     21 * 2) No right is granted to use any trade name, trademark, or logo of
     22 *    Broadcom Corporation.  The "Broadcom Corporation" name may not be
     23 *    used to endorse or promote products derived from this software
     24 *    without the prior written permission of Broadcom Corporation.
     25 *
     26 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
     27 *    WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
     28 *    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
     29 *    NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
     30 *    FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
     31 *    LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32 *    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33 *    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     34 *    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     35 *    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     36 *    OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     37 */
     38
     39#ifndef LINUX_CFE_API_H_
     40#define LINUX_CFE_API_H_
     41
     42#include <linux/types.h>
     43
     44
     45#define CFE_MI_RESERVED         0               /* memory is reserved, do not use */
     46#define CFE_MI_AVAILABLE        1               /* memory is available */
     47
     48#define CFE_FLG_WARMSTART       0x00000001
     49#define CFE_FLG_FULL_ARENA      0x00000001
     50#define CFE_FLG_ENV_PERMANENT   0x00000001
     51
     52#define CFE_CPU_CMD_START       1
     53#define CFE_CPU_CMD_STOP        0
     54
     55#define CFE_STDHANDLE_CONSOLE   0
     56
     57#define CFE_DEV_NETWORK         1
     58#define CFE_DEV_DISK            2
     59#define CFE_DEV_FLASH           3
     60#define CFE_DEV_SERIAL          4
     61#define CFE_DEV_CPU             5
     62#define CFE_DEV_NVRAM           6
     63#define CFE_DEV_CLOCK           7
     64#define CFE_DEV_OTHER           8
     65#define CFE_DEV_MASK            0x0F
     66
     67#define CFE_CACHE_FLUSH_D       1
     68#define CFE_CACHE_INVAL_I       2
     69#define CFE_CACHE_INVAL_D       4
     70#define CFE_CACHE_INVAL_L2      8
     71
     72#define CFE_FWI_64BIT           0x00000001
     73#define CFE_FWI_32BIT           0x00000002
     74#define CFE_FWI_RELOC           0x00000004
     75#define CFE_FWI_UNCACHED        0x00000008
     76#define CFE_FWI_MULTICPU        0x00000010
     77#define CFE_FWI_FUNCSIM         0x00000020
     78#define CFE_FWI_RTLSIM          0x00000040
     79
     80struct cfe_fwinfo {
     81        s64 version;            /* major, minor, eco version */
     82        s64 totalmem;           /* total installed mem */
     83        s64 flags;              /* various flags */
     84        s64 boardid;            /* board ID */
     85        s64 bootarea_va;        /* VA of boot area */
     86        s64 bootarea_pa;        /* PA of boot area */
     87        s64 bootarea_size;      /* size of boot area */
     88};
     89
     90
     91/* The public CFE API */
     92
     93int cfe_present(void);  /* Check if we booted from CFE. Returns bool */
     94
     95int cfe_getticks(s64 *ticks);
     96int cfe_close(int handle);
     97int cfe_cpu_start(int cpu, void (*fn)(void), long sp, long gp, long a1);
     98int cfe_cpu_stop(int cpu);
     99int cfe_enumenv(int idx, char *name, int namelen, char *val, int vallen);
     100int cfe_enumdev(int idx, char *name, int namelen);
     101int cfe_enummem(int idx, int flags, u64 *start, u64 *length,
     102                u64 *type);
     103int cfe_exit(int warm, int status);
     104int cfe_flushcache(int flags);
     105int cfe_getdevinfo(char *name);
     106int cfe_getenv(char *name, char *dest, int destlen);
     107int cfe_getfwinfo(struct cfe_fwinfo *info);
     108int cfe_getstdhandle(int handletype);
     109int cfe_inpstat(int handle);
     110int cfe_ioctl(int handle, unsigned int ioctlnum, unsigned char *buffer,
     111              int length, int *retlen, u64 offset);
     112int cfe_open(char *name);
     113int cfe_read(int handle, unsigned char *buffer, int length);
     114int cfe_readblk(int handle, s64 offset, unsigned char *buffer, int length);
     115int cfe_setenv(char *name, char *val);
     116int cfe_write(int handle, unsigned char *buffer, int length);
     117int cfe_writeblk(int handle, s64 offset, unsigned char *buffer,
     118                 int length);
     119
     120
     121/* High level API */
     122
     123/* Print some information to CFE's console (most likely serial line) */
     124int cfe_printk(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
     125int cfe_vprintk(const char *fmt, va_list args);
     126
     127
     128
     129/* Error codes returned by the low API functions */
     130
     131#define CFE_ISERR(errcode)      (errcode < 0)
     132
     133#define CFE_OK                   0
     134#define CFE_ERR                 -1      /* generic error */
     135#define CFE_ERR_INV_COMMAND     -2
     136#define CFE_ERR_EOF             -3
     137#define CFE_ERR_IOERR           -4
     138#define CFE_ERR_NOMEM           -5
     139#define CFE_ERR_DEVNOTFOUND     -6
     140#define CFE_ERR_DEVOPEN         -7
     141#define CFE_ERR_INV_PARAM       -8
     142#define CFE_ERR_ENVNOTFOUND     -9
     143#define CFE_ERR_ENVREADONLY     -10
     144
     145#define CFE_ERR_NOTELF          -11
     146#define CFE_ERR_NOT32BIT        -12
     147#define CFE_ERR_WRONGENDIAN     -13
     148#define CFE_ERR_BADELFVERS      -14
     149#define CFE_ERR_NOTMIPS         -15
     150#define CFE_ERR_BADELFFMT       -16
     151#define CFE_ERR_BADADDR         -17
     152
     153#define CFE_ERR_FILENOTFOUND    -18
     154#define CFE_ERR_UNSUPPORTED     -19
     155
     156#define CFE_ERR_HOSTUNKNOWN     -20
     157
     158#define CFE_ERR_TIMEOUT         -21
     159
     160#define CFE_ERR_PROTOCOLERR     -22
     161
     162#define CFE_ERR_NETDOWN         -23
     163#define CFE_ERR_NONAMESERVER    -24
     164
     165#define CFE_ERR_NOHANDLES       -25
     166#define CFE_ERR_ALREADYBOUND    -26
     167
     168#define CFE_ERR_CANNOTSET       -27
     169#define CFE_ERR_NOMORE          -28
     170#define CFE_ERR_BADFILESYS      -29
     171#define CFE_ERR_FSNOTAVAIL      -30
     172
     173#define CFE_ERR_INVBOOTBLOCK    -31
     174#define CFE_ERR_WRONGDEVTYPE    -32
     175#define CFE_ERR_BBCHECKSUM      -33
     176#define CFE_ERR_BOOTPROGCHKSUM  -34
     177
     178#define CFE_ERR_LDRNOTAVAIL     -35
     179
     180#define CFE_ERR_NOTREADY        -36
     181
     182#define CFE_ERR_GETMEM          -37
     183#define CFE_ERR_SETMEM          -38
     184
     185#define CFE_ERR_NOTCONN         -39
     186#define CFE_ERR_ADDRINUSE       -40
     187
     188
     189#endif /* LINUX_CFE_API_H_ */
  • include/asm-mips/cpu.h

    diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h
    index d38fdbf..4621876 100644
    a b  
    104104#define PRID_IMP_SR71000        0x0400
    105105
    106106/*
     107 * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM
     108 */
     109
     110#define PRID_IMP_BCM4710        0x4000
     111#define PRID_IMP_BCM3302        0x9000
     112
     113/*
    107114 * Definitions for 7:0 on legacy processors
    108115 */
    109116
     
    200207#define CPU_SB1A                62
    201208#define CPU_74K                 63
    202209#define CPU_R14000              64
    203 #define CPU_LAST                64
     210#define CPU_BCM3302             65
     211#define CPU_BCM4710             66
     212#define CPU_LAST                66
    204213
    205214/*
    206215 * ISA Level encodings
  • new file include/asm-mips/mach-bcm947xx/kernel-entry-init.h

    diff --git a/include/asm-mips/mach-bcm947xx/kernel-entry-init.h b/include/asm-mips/mach-bcm947xx/kernel-entry-init.h
    new file mode 100644
    index 0000000..7df0dc2
    - +  
     1/*
     2 * This file is subject to the terms and conditions of the GNU General Public
     3 * License.  See the file "COPYING" in the main directory of this archive
     4 * for more details.
     5 *
     6 * Copyright (C) 2005 Embedded Alley Solutions, Inc
     7 * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
     8 * Copyright (C) 2006 Michael Buesch
     9 */
     10#ifndef __ASM_MACH_GENERIC_KERNEL_ENTRY_H
     11#define __ASM_MACH_GENERIC_KERNEL_ENTRY_H
     12
     13/* Intentionally empty macro, used in head.S. Override in
     14 * arch/mips/mach-xxx/kernel-entry-init.h when necessary.
     15 */
     16        .macro  kernel_entry_setup
     17        .endm
     18
     19/*
     20 * Do SMP slave processor setup necessary before we can savely execute C code.
     21 */
     22        .macro  smp_slave_setup
     23        .endm
     24
     25
     26#endif /* __ASM_MACH_GENERIC_KERNEL_ENTRY_H */
  • include/linux/pci_ids.h

    diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
    index fa4e1d7..cbc4de7 100644
    a b  
    19501950#define PCI_DEVICE_ID_TIGON3_5906M      0x1713
    19511951#define PCI_DEVICE_ID_BCM4401           0x4401
    19521952#define PCI_DEVICE_ID_BCM4401B0         0x4402
     1953#define PCI_DEVICE_ID_BCM4713           0x4713
    19531954
    19541955#define PCI_VENDOR_ID_TOPIC             0x151f
    19551956#define PCI_DEVICE_ID_TOPIC_TP560       0x0000
Note: See TracBrowser for help on using the repository browser.