linux/drivers/staging/netlogic/platform_net.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2003-2012 Broadcom Corporation
   3 * All Rights Reserved
   4 *
   5 * This software is available to you under a choice of one of two
   6 * licenses.  You may choose to be licensed under the terms of the GNU
   7 * 1. Redistributions of source code must retain the above copyright
   8 * General Public License (GPL) Version 2, available from the file
   9 * COPYING in the main directory of this source tree, or the Broadcom
  10 * license below:
  11 *
  12 * Redistribution and use in source and binary forms, with or without
  13 * modification, are permitted provided that the following conditions
  14 * are met:
  15 *
  16 * 1. Redistributions of source code must retain the above copyright
  17 *    notice, this list of conditions and the following disclaimer.
  18 * 2. Redistributions in binary form must reproduce the above copyright
  19 *    notice, this list of conditions and the following disclaimer in
  20 *    the documentation and/or other materials provided with the
  21 *    distribution.
  22 *
  23 * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
  24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  26 * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
  27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
  32 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  33 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34 */
  35
  36#include <linux/device.h>
  37#include <linux/platform_device.h>
  38#include <linux/kernel.h>
  39#include <linux/init.h>
  40#include <linux/io.h>
  41#include <linux/delay.h>
  42#include <linux/ioport.h>
  43#include <linux/resource.h>
  44#include <linux/phy.h>
  45
  46#include <asm/netlogic/haldefs.h>
  47#include <asm/netlogic/common.h>
  48#include <asm/netlogic/xlr/fmn.h>
  49#include <asm/netlogic/xlr/xlr.h>
  50#include <asm/netlogic/psb-bootinfo.h>
  51#include <asm/netlogic/xlr/pic.h>
  52#include <asm/netlogic/xlr/iomap.h>
  53
  54#include "platform_net.h"
  55
  56/* Linux Net */
  57#define MAX_NUM_GMAC            8
  58#define MAX_NUM_XLS_GMAC        8
  59#define MAX_NUM_XLR_GMAC        4
  60
  61
  62static u32 xlr_gmac_offsets[] = {
  63        NETLOGIC_IO_GMAC_0_OFFSET, NETLOGIC_IO_GMAC_1_OFFSET,
  64        NETLOGIC_IO_GMAC_2_OFFSET, NETLOGIC_IO_GMAC_3_OFFSET,
  65        NETLOGIC_IO_GMAC_4_OFFSET, NETLOGIC_IO_GMAC_5_OFFSET,
  66        NETLOGIC_IO_GMAC_6_OFFSET, NETLOGIC_IO_GMAC_7_OFFSET
  67};
  68
  69static u32 xlr_gmac_irqs[] = { PIC_GMAC_0_IRQ, PIC_GMAC_1_IRQ,
  70        PIC_GMAC_2_IRQ, PIC_GMAC_3_IRQ,
  71        PIC_GMAC_4_IRQ, PIC_GMAC_5_IRQ,
  72        PIC_GMAC_6_IRQ, PIC_GMAC_7_IRQ
  73};
  74
  75static struct xlr_net_data ndata[MAX_NUM_GMAC];
  76static struct resource xlr_net_res[8][2];
  77static struct platform_device xlr_net_dev[8];
  78static u32 __iomem *gmac0_addr;
  79static u32 __iomem *gmac4_addr;
  80static u32 __iomem *gpio_addr;
  81
  82static void config_mac(struct xlr_net_data *nd, int phy, u32 __iomem *serdes,
  83                u32 __iomem *pcs, int rfr, int tx, int *bkt_size,
  84                struct xlr_fmn_info *gmac_fmn_info, int phy_addr)
  85{
  86        nd->cpu_mask = nlm_current_node()->coremask;
  87        nd->phy_interface = phy;
  88        nd->rfr_station = rfr;
  89        nd->tx_stnid = tx;
  90        nd->mii_addr = gmac0_addr;
  91        nd->serdes_addr = serdes;
  92        nd->pcs_addr = pcs;
  93        nd->gpio_addr = gpio_addr;
  94
  95        nd->bucket_size = bkt_size;
  96        nd->gmac_fmn_info = gmac_fmn_info;
  97        nd->phy_addr = phy_addr;
  98}
  99
 100static void net_device_init(int id, struct resource *res, int offset, int irq)
 101{
 102        res[0].name = "gmac";
 103        res[0].start = CPHYSADDR(nlm_mmio_base(offset));
 104        res[0].end = res[0].start + 0xfff;
 105        res[0].flags = IORESOURCE_MEM;
 106
 107        res[1].name = "gmac";
 108        res[1].start = irq;
 109        res[1].end = irq;
 110        res[1].flags = IORESOURCE_IRQ;
 111
 112        xlr_net_dev[id].name = "xlr-net";
 113        xlr_net_dev[id].id = id;
 114        xlr_net_dev[id].num_resources = 2;
 115        xlr_net_dev[id].resource = res;
 116        xlr_net_dev[id].dev.platform_data = &ndata[id];
 117}
 118
 119static void xls_gmac_init(void)
 120{
 121        int mac;
 122
 123        gmac4_addr = ioremap(CPHYSADDR(
 124                nlm_mmio_base(NETLOGIC_IO_GMAC_4_OFFSET)), 0xfff);
 125        /* Passing GPIO base for serdes init. Only needed on sgmii ports*/
 126        gpio_addr = ioremap(CPHYSADDR(
 127                nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET)), 0xfff);
 128
 129        switch (nlm_prom_info.board_major_version) {
 130        case 12:
 131                /* first block RGMII or XAUI, use RGMII */
 132                config_mac(&ndata[0],
 133                        PHY_INTERFACE_MODE_RGMII,
 134                        gmac0_addr,     /* serdes */
 135                        gmac0_addr,     /* pcs */
 136                        FMN_STNID_GMACRFR_0,
 137                        FMN_STNID_GMAC0_TX0,
 138                        xlr_board_fmn_config.bucket_size,
 139                        &xlr_board_fmn_config.gmac[0],
 140                        0);
 141
 142                net_device_init(0, xlr_net_res[0], xlr_gmac_offsets[0],
 143                                xlr_gmac_irqs[0]);
 144                platform_device_register(&xlr_net_dev[0]);
 145
 146                /* second block is XAUI, not supported yet */
 147                break;
 148        default:
 149                /* default XLS config, all ports SGMII */
 150                for (mac = 0; mac < 4; mac++) {
 151                        config_mac(&ndata[mac],
 152                                PHY_INTERFACE_MODE_SGMII,
 153                                gmac0_addr,     /* serdes */
 154                                gmac0_addr,     /* pcs */
 155                                FMN_STNID_GMACRFR_0,
 156                                FMN_STNID_GMAC0_TX0 + mac,
 157                                xlr_board_fmn_config.bucket_size,
 158                                &xlr_board_fmn_config.gmac[0],
 159                                /* PHY address according to chip/board */
 160                                mac + 0x10);
 161
 162                        net_device_init(mac, xlr_net_res[mac],
 163                                        xlr_gmac_offsets[mac],
 164                                        xlr_gmac_irqs[mac]);
 165                        platform_device_register(&xlr_net_dev[mac]);
 166                }
 167
 168                for (mac = 4; mac < MAX_NUM_XLS_GMAC; mac++) {
 169                        config_mac(&ndata[mac],
 170                                PHY_INTERFACE_MODE_SGMII,
 171                                gmac4_addr,     /* serdes */
 172                                gmac4_addr,     /* pcs */
 173                                FMN_STNID_GMAC1_FR_0,
 174                                FMN_STNID_GMAC1_TX0 + mac - 4,
 175                                xlr_board_fmn_config.bucket_size,
 176                                &xlr_board_fmn_config.gmac[1],
 177                                /* PHY address according to chip/board */
 178                                mac + 0x10);
 179
 180                        net_device_init(mac, xlr_net_res[mac],
 181                                        xlr_gmac_offsets[mac],
 182                                        xlr_gmac_irqs[mac]);
 183                        platform_device_register(&xlr_net_dev[mac]);
 184                }
 185        }
 186}
 187
 188static void xlr_gmac_init(void)
 189{
 190        int mac;
 191
 192        /* assume all GMACs for now */
 193        for (mac = 0; mac < MAX_NUM_XLR_GMAC; mac++) {
 194                config_mac(&ndata[mac],
 195                        PHY_INTERFACE_MODE_RGMII,
 196                        0,
 197                        0,
 198                        FMN_STNID_GMACRFR_0,
 199                        FMN_STNID_GMAC0_TX0,
 200                        xlr_board_fmn_config.bucket_size,
 201                        &xlr_board_fmn_config.gmac[0],
 202                        mac);
 203
 204                net_device_init(mac, xlr_net_res[mac], xlr_gmac_offsets[mac],
 205                                xlr_gmac_irqs[mac]);
 206                platform_device_register(&xlr_net_dev[mac]);
 207        }
 208}
 209
 210static int __init xlr_net_init(void)
 211{
 212        gmac0_addr = ioremap(CPHYSADDR(
 213                nlm_mmio_base(NETLOGIC_IO_GMAC_0_OFFSET)), 0xfff);
 214
 215        if (nlm_chip_is_xls())
 216                xls_gmac_init();
 217        else
 218                xlr_gmac_init();
 219
 220        return 0;
 221}
 222
 223arch_initcall(xlr_net_init);
 224