uboot/drivers/net/kirkwood_egiga.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2009
   3 * Marvell Semiconductor <www.marvell.com>
   4 * Written-by: Prafulla Wadaskar <prafulla@marvell.com>
   5 *
   6 * (C) Copyright 2003
   7 * Ingo Assmus <ingo.assmus@keymile.com>
   8 *
   9 * based on - Driver for MV64360X ethernet ports
  10 * Copyright (C) 2002 rabeeh@galileo.co.il
  11 *
  12 * See file CREDITS for list of people who contributed to this
  13 * project.
  14 *
  15 * This program is free software; you can redistribute it and/or
  16 * modify it under the terms of the GNU General Public License as
  17 * published by the Free Software Foundation; either version 2 of
  18 * the License, or (at your option) any later version.
  19 *
  20 * This program is distributed in the hope that it will be useful,
  21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  23 * GNU General Public License for more details.
  24 *
  25 * You should have received a copy of the GNU General Public License
  26 * along with this program; if not, write to the Free Software
  27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  28 * MA 02110-1301 USA
  29 */
  30
  31#include <common.h>
  32#include <net.h>
  33#include <malloc.h>
  34#include <miiphy.h>
  35#include <asm/errno.h>
  36#include <asm/types.h>
  37#include <asm/byteorder.h>
  38#include <asm/arch/kirkwood.h>
  39#include "kirkwood_egiga.h"
  40
  41#define KIRKWOOD_PHY_ADR_REQUEST 0xee
  42
  43/*
  44 * smi_reg_read - miiphy_read callback function.
  45 *
  46 * Returns 16bit phy register value, or 0xffff on error
  47 */
  48static int smi_reg_read(char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
  49{
  50        struct eth_device *dev = eth_get_dev_by_name(devname);
  51        struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
  52        struct kwgbe_registers *regs = dkwgbe->regs;
  53        u32 smi_reg;
  54        u32 timeout;
  55
  56        /* Phyadr read request */
  57        if (phy_adr == KIRKWOOD_PHY_ADR_REQUEST &&
  58                        reg_ofs == KIRKWOOD_PHY_ADR_REQUEST) {
  59                /* */
  60                *data = (u16) (KWGBEREG_RD(regs->phyadr) & PHYADR_MASK);
  61                return 0;
  62        }
  63        /* check parameters */
  64        if (phy_adr > PHYADR_MASK) {
  65                printf("Err..(%s) Invalid PHY address %d\n",
  66                        __FUNCTION__, phy_adr);
  67                return -EFAULT;
  68        }
  69        if (reg_ofs > PHYREG_MASK) {
  70                printf("Err..(%s) Invalid register offset %d\n",
  71                        __FUNCTION__, reg_ofs);
  72                return -EFAULT;
  73        }
  74
  75        timeout = KWGBE_PHY_SMI_TIMEOUT;
  76        /* wait till the SMI is not busy */
  77        do {
  78                /* read smi register */
  79                smi_reg = KWGBEREG_RD(regs->smi);
  80                if (timeout-- == 0) {
  81                        printf("Err..(%s) SMI busy timeout\n", __FUNCTION__);
  82                        return -EFAULT;
  83                }
  84        } while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK);
  85
  86        /* fill the phy address and regiser offset and read opcode */
  87        smi_reg = (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS)
  88                | (reg_ofs << KWGBE_SMI_REG_ADDR_OFFS)
  89                | KWGBE_PHY_SMI_OPCODE_READ;
  90
  91        /* write the smi register */
  92        KWGBEREG_WR(regs->smi, smi_reg);
  93
  94        /*wait till read value is ready */
  95        timeout = KWGBE_PHY_SMI_TIMEOUT;
  96
  97        do {
  98                /* read smi register */
  99                smi_reg = KWGBEREG_RD(regs->smi);
 100                if (timeout-- == 0) {
 101                        printf("Err..(%s) SMI read ready timeout\n",
 102                                __FUNCTION__);
 103                        return -EFAULT;
 104                }
 105        } while (!(smi_reg & KWGBE_PHY_SMI_READ_VALID_MASK));
 106
 107        /* Wait for the data to update in the SMI register */
 108        for (timeout = 0; timeout < KWGBE_PHY_SMI_TIMEOUT; timeout++) ;
 109
 110        *data = (u16) (KWGBEREG_RD(regs->smi) & KWGBE_PHY_SMI_DATA_MASK);
 111
 112        debug("%s:(adr %d, off %d) value= %04x\n", __FUNCTION__, phy_adr,
 113                reg_ofs, *data);
 114
 115        return 0;
 116}
 117
 118/*
 119 * smi_reg_write - imiiphy_write callback function.
 120 *
 121 * Returns 0 if write succeed, -EINVAL on bad parameters
 122 * -ETIME on timeout
 123 */
 124static int smi_reg_write(char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
 125{
 126        struct eth_device *dev = eth_get_dev_by_name(devname);
 127        struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
 128        struct kwgbe_registers *regs = dkwgbe->regs;
 129        u32 smi_reg;
 130        u32 timeout;
 131
 132        /* Phyadr write request*/
 133        if (phy_adr == KIRKWOOD_PHY_ADR_REQUEST &&
 134                        reg_ofs == KIRKWOOD_PHY_ADR_REQUEST) {
 135                KWGBEREG_WR(regs->phyadr, data);
 136                return 0;
 137        }
 138
 139        /* check parameters */
 140        if (phy_adr > PHYADR_MASK) {
 141                printf("Err..(%s) Invalid phy address\n", __FUNCTION__);
 142                return -EINVAL;
 143        }
 144        if (reg_ofs > PHYREG_MASK) {
 145                printf("Err..(%s) Invalid register offset\n", __FUNCTION__);
 146                return -EINVAL;
 147        }
 148
 149        /* wait till the SMI is not busy */
 150        timeout = KWGBE_PHY_SMI_TIMEOUT;
 151        do {
 152                /* read smi register */
 153                smi_reg = KWGBEREG_RD(regs->smi);
 154                if (timeout-- == 0) {
 155                        printf("Err..(%s) SMI busy timeout\n", __FUNCTION__);
 156                        return -ETIME;
 157                }
 158        } while (smi_reg & KWGBE_PHY_SMI_BUSY_MASK);
 159
 160        /* fill the phy addr and reg offset and write opcode and data */
 161        smi_reg = (data << KWGBE_PHY_SMI_DATA_OFFS);
 162        smi_reg |= (phy_adr << KWGBE_PHY_SMI_DEV_ADDR_OFFS)
 163                | (reg_ofs << KWGBE_SMI_REG_ADDR_OFFS);
 164        smi_reg &= ~KWGBE_PHY_SMI_OPCODE_READ;
 165
 166        /* write the smi register */
 167        KWGBEREG_WR(regs->smi, smi_reg);
 168
 169        return 0;
 170}
 171
 172/* Stop and checks all queues */
 173static void stop_queue(u32 * qreg)
 174{
 175        u32 reg_data;
 176
 177        reg_data = readl(qreg);
 178
 179        if (reg_data & 0xFF) {
 180                /* Issue stop command for active channels only */
 181                writel((reg_data << 8), qreg);
 182
 183                /* Wait for all queue activity to terminate. */
 184                do {
 185                        /*
 186                         * Check port cause register that all queues
 187                         * are stopped
 188                         */
 189                        reg_data = readl(qreg);
 190                }
 191                while (reg_data & 0xFF);
 192        }
 193}
 194
 195/*
 196 * set_access_control - Config address decode parameters for Ethernet unit
 197 *
 198 * This function configures the address decode parameters for the Gigabit
 199 * Ethernet Controller according the given parameters struct.
 200 *
 201 * @regs        Register struct pointer.
 202 * @param       Address decode parameter struct.
 203 */
 204static void set_access_control(struct kwgbe_registers *regs,
 205                                struct kwgbe_winparam *param)
 206{
 207        u32 access_prot_reg;
 208
 209        /* Set access control register */
 210        access_prot_reg = KWGBEREG_RD(regs->epap);
 211        /* clear window permission */
 212        access_prot_reg &= (~(3 << (param->win * 2)));
 213        access_prot_reg |= (param->access_ctrl << (param->win * 2));
 214        KWGBEREG_WR(regs->epap, access_prot_reg);
 215
 216        /* Set window Size reg (SR) */
 217        KWGBEREG_WR(regs->barsz[param->win].size,
 218                        (((param->size / 0x10000) - 1) << 16));
 219
 220        /* Set window Base address reg (BA) */
 221        KWGBEREG_WR(regs->barsz[param->win].bar,
 222                        (param->target | param->attrib | param->base_addr));
 223        /* High address remap reg (HARR) */
 224        if (param->win < 4)
 225                KWGBEREG_WR(regs->ha_remap[param->win], param->high_addr);
 226
 227        /* Base address enable reg (BARER) */
 228        if (param->enable == 1)
 229                KWGBEREG_BITS_RESET(regs->bare, (1 << param->win));
 230        else
 231                KWGBEREG_BITS_SET(regs->bare, (1 << param->win));
 232}
 233
 234static void set_dram_access(struct kwgbe_registers *regs)
 235{
 236        struct kwgbe_winparam win_param;
 237        int i;
 238
 239        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 240                /* Set access parameters for DRAM bank i */
 241                win_param.win = i;      /* Use Ethernet window i */
 242                /* Window target - DDR */
 243                win_param.target = KWGBE_TARGET_DRAM;
 244                /* Enable full access */
 245                win_param.access_ctrl = EWIN_ACCESS_FULL;
 246                win_param.high_addr = 0;
 247                /* Get bank base */
 248                win_param.base_addr = kw_sdram_bar(i);
 249                win_param.size = kw_sdram_bs(i);        /* Get bank size */
 250                if (win_param.size == 0)
 251                        win_param.enable = 0;
 252                else
 253                        win_param.enable = 1;   /* Enable the access */
 254
 255                /* Enable DRAM bank */
 256                switch (i) {
 257                case 0:
 258                        win_param.attrib = EBAR_DRAM_CS0;
 259                        break;
 260                case 1:
 261                        win_param.attrib = EBAR_DRAM_CS1;
 262                        break;
 263                case 2:
 264                        win_param.attrib = EBAR_DRAM_CS2;
 265                        break;
 266                case 3:
 267                        win_param.attrib = EBAR_DRAM_CS3;
 268                        break;
 269                default:
 270                        /* invalide bank, disable access */
 271                        win_param.enable = 0;
 272                        win_param.attrib = 0;
 273                        break;
 274                }
 275                /* Set the access control for address window(EPAPR) RD/WR */
 276                set_access_control(regs, &win_param);
 277        }
 278}
 279
 280/*
 281 * port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables
 282 *
 283 * Go through all the DA filter tables (Unicast, Special Multicast & Other
 284 * Multicast) and set each entry to 0.
 285 */
 286static void port_init_mac_tables(struct kwgbe_registers *regs)
 287{
 288        int table_index;
 289
 290        /* Clear DA filter unicast table (Ex_dFUT) */
 291        for (table_index = 0; table_index < 4; ++table_index)
 292                KWGBEREG_WR(regs->dfut[table_index], 0);
 293
 294        for (table_index = 0; table_index < 64; ++table_index) {
 295                /* Clear DA filter special multicast table (Ex_dFSMT) */
 296                KWGBEREG_WR(regs->dfsmt[table_index], 0);
 297                /* Clear DA filter other multicast table (Ex_dFOMT) */
 298                KWGBEREG_WR(regs->dfomt[table_index], 0);
 299        }
 300}
 301
 302/*
 303 * port_uc_addr - This function Set the port unicast address table
 304 *
 305 * This function locates the proper entry in the Unicast table for the
 306 * specified MAC nibble and sets its properties according to function
 307 * parameters.
 308 * This function add/removes MAC addresses from the port unicast address
 309 * table.
 310 *
 311 * @uc_nibble   Unicast MAC Address last nibble.
 312 * @option      0 = Add, 1 = remove address.
 313 *
 314 * RETURN: 1 if output succeeded. 0 if option parameter is invalid.
 315 */
 316static int port_uc_addr(struct kwgbe_registers *regs, u8 uc_nibble,
 317                        int option)
 318{
 319        u32 unicast_reg;
 320        u32 tbl_offset;
 321        u32 reg_offset;
 322
 323        /* Locate the Unicast table entry */
 324        uc_nibble = (0xf & uc_nibble);
 325        /* Register offset from unicast table base */
 326        tbl_offset = (uc_nibble / 4);
 327        /* Entry offset within the above register */
 328        reg_offset = uc_nibble % 4;
 329
 330        switch (option) {
 331        case REJECT_MAC_ADDR:
 332                /*
 333                 * Clear accepts frame bit at specified unicast
 334                 * DA table entry
 335                 */
 336                unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]);
 337                unicast_reg &= (0xFF << (8 * reg_offset));
 338                KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg);
 339                break;
 340        case ACCEPT_MAC_ADDR:
 341                /* Set accepts frame bit at unicast DA filter table entry */
 342                unicast_reg = KWGBEREG_RD(regs->dfut[tbl_offset]);
 343                unicast_reg &= (0xFF << (8 * reg_offset));
 344                unicast_reg |= ((0x01 | (RXUQ << 1)) << (8 * reg_offset));
 345                KWGBEREG_WR(regs->dfut[tbl_offset], unicast_reg);
 346                break;
 347        default:
 348                return 0;
 349        }
 350        return 1;
 351}
 352
 353/*
 354 * port_uc_addr_set - This function Set the port Unicast address.
 355 */
 356static void port_uc_addr_set(struct kwgbe_registers *regs, u8 * p_addr)
 357{
 358        u32 mac_h;
 359        u32 mac_l;
 360
 361        mac_l = (p_addr[4] << 8) | (p_addr[5]);
 362        mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
 363                (p_addr[3] << 0);
 364
 365        KWGBEREG_WR(regs->macal, mac_l);
 366        KWGBEREG_WR(regs->macah, mac_h);
 367
 368        /* Accept frames of this address */
 369        port_uc_addr(regs, p_addr[5], ACCEPT_MAC_ADDR);
 370}
 371
 372/*
 373 * kwgbe_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory.
 374 */
 375static void kwgbe_init_rx_desc_ring(struct kwgbe_device *dkwgbe)
 376{
 377        struct kwgbe_rxdesc *p_rx_desc;
 378        int i;
 379
 380        /* initialize the Rx descriptors ring */
 381        p_rx_desc = dkwgbe->p_rxdesc;
 382        for (i = 0; i < RINGSZ; i++) {
 383                p_rx_desc->cmd_sts =
 384                        KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT;
 385                p_rx_desc->buf_size = PKTSIZE_ALIGN;
 386                p_rx_desc->byte_cnt = 0;
 387                p_rx_desc->buf_ptr = dkwgbe->p_rxbuf + i * PKTSIZE_ALIGN;
 388                if (i == (RINGSZ - 1))
 389                        p_rx_desc->nxtdesc_p = dkwgbe->p_rxdesc;
 390                else {
 391                        p_rx_desc->nxtdesc_p = (struct kwgbe_rxdesc *)
 392                                ((u32) p_rx_desc + KW_RXQ_DESC_ALIGNED_SIZE);
 393                        p_rx_desc = p_rx_desc->nxtdesc_p;
 394                }
 395        }
 396        dkwgbe->p_rxdesc_curr = dkwgbe->p_rxdesc;
 397}
 398
 399static int kwgbe_init(struct eth_device *dev)
 400{
 401        struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
 402        struct kwgbe_registers *regs = dkwgbe->regs;
 403        int i;
 404
 405        /* setup RX rings */
 406        kwgbe_init_rx_desc_ring(dkwgbe);
 407
 408        /* Clear the ethernet port interrupts */
 409        KWGBEREG_WR(regs->ic, 0);
 410        KWGBEREG_WR(regs->ice, 0);
 411        /* Unmask RX buffer and TX end interrupt */
 412        KWGBEREG_WR(regs->pim, INT_CAUSE_UNMASK_ALL);
 413        /* Unmask phy and link status changes interrupts */
 414        KWGBEREG_WR(regs->peim, INT_CAUSE_UNMASK_ALL_EXT);
 415
 416        set_dram_access(regs);
 417        port_init_mac_tables(regs);
 418        port_uc_addr_set(regs, dkwgbe->dev.enetaddr);
 419
 420        /* Assign port configuration and command. */
 421        KWGBEREG_WR(regs->pxc, PRT_CFG_VAL);
 422        KWGBEREG_WR(regs->pxcx, PORT_CFG_EXTEND_VALUE);
 423        KWGBEREG_WR(regs->psc0, PORT_SERIAL_CONTROL_VALUE);
 424        /* Disable port initially */
 425        KWGBEREG_BITS_SET(regs->psc0, KWGBE_SERIAL_PORT_EN);
 426
 427        /* Assign port SDMA configuration */
 428        KWGBEREG_WR(regs->sdc, PORT_SDMA_CFG_VALUE);
 429        KWGBEREG_WR(regs->tqx[0].qxttbc, QTKNBKT_DEF_VAL);
 430        KWGBEREG_WR(regs->tqx[0].tqxtbc, (QMTBS_DEF_VAL << 16) | QTKNRT_DEF_VAL);
 431        /* Turn off the port/RXUQ bandwidth limitation */
 432        KWGBEREG_WR(regs->pmtu, 0);
 433
 434        /* Set maximum receive buffer to 9700 bytes */
 435        KWGBEREG_WR(regs->psc0, KWGBE_MAX_RX_PACKET_9700BYTE
 436                        | (KWGBEREG_RD(regs->psc0) & MRU_MASK));
 437
 438        /*
 439         * Set ethernet MTU for leaky bucket mechanism to 0 - this will
 440         * disable the leaky bucket mechanism .
 441         */
 442        KWGBEREG_WR(regs->pmtu, 0);
 443
 444        /* Assignment of Rx CRDB of given RXUQ */
 445        KWGBEREG_WR(regs->rxcdp[RXUQ].rxcdp, (u32) dkwgbe->p_rxdesc_curr);
 446        /* Enable port Rx. */
 447        KWGBEREG_WR(regs->rqc, (1 << RXUQ));
 448
 449#if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \
 450         && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
 451        /* Wait up to 5s for the link status */
 452        for (i = 0; i < 5; i++) {
 453                u16 phyadr;
 454
 455                miiphy_read(dev->name, KIRKWOOD_PHY_ADR_REQUEST,
 456                                KIRKWOOD_PHY_ADR_REQUEST, &phyadr);
 457                /* Return if we get link up */
 458                if (miiphy_link(dev->name, phyadr))
 459                        return 0;
 460                udelay(1000000);
 461        }
 462
 463        printf("No link on %s\n", dev->name);
 464        return -1;
 465#endif
 466        return 0;
 467}
 468
 469static int kwgbe_halt(struct eth_device *dev)
 470{
 471        struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
 472        struct kwgbe_registers *regs = dkwgbe->regs;
 473
 474        /* Disable all gigE address decoder */
 475        KWGBEREG_WR(regs->bare, 0x3f);
 476
 477        stop_queue(&regs->tqc);
 478        stop_queue(&regs->rqc);
 479
 480        /* Enable port */
 481        KWGBEREG_BITS_RESET(regs->psc0, KWGBE_SERIAL_PORT_EN);
 482        /* Set port is not reset */
 483        KWGBEREG_BITS_RESET(regs->psc1, 1 << 4);
 484#ifdef CONFIG_SYS_MII_MODE
 485        /* Set MMI interface up */
 486        KWGBEREG_BITS_RESET(regs->psc1, 1 << 3);
 487#endif
 488        /* Disable & mask ethernet port interrupts */
 489        KWGBEREG_WR(regs->ic, 0);
 490        KWGBEREG_WR(regs->ice, 0);
 491        KWGBEREG_WR(regs->pim, 0);
 492        KWGBEREG_WR(regs->peim, 0);
 493
 494        return 0;
 495}
 496
 497static int kwgbe_send(struct eth_device *dev, volatile void *dataptr,
 498                      int datasize)
 499{
 500        struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
 501        struct kwgbe_registers *regs = dkwgbe->regs;
 502        struct kwgbe_txdesc *p_txdesc = dkwgbe->p_txdesc;
 503        void *p = (void *)dataptr;
 504        u32 cmd_sts;
 505
 506        /* Copy buffer if it's misaligned */
 507        if ((u32) dataptr & 0x07) {
 508                if (datasize > PKTSIZE_ALIGN) {
 509                        printf("Non-aligned data too large (%d)\n",
 510                                        datasize);
 511                        return -1;
 512                }
 513
 514                memcpy(dkwgbe->p_aligned_txbuf, p, datasize);
 515                p = dkwgbe->p_aligned_txbuf;
 516        }
 517
 518        p_txdesc->cmd_sts = KWGBE_ZERO_PADDING | KWGBE_GEN_CRC;
 519        p_txdesc->cmd_sts |= KWGBE_TX_FIRST_DESC | KWGBE_TX_LAST_DESC;
 520        p_txdesc->cmd_sts |= KWGBE_BUFFER_OWNED_BY_DMA;
 521        p_txdesc->cmd_sts |= KWGBE_TX_EN_INTERRUPT;
 522        p_txdesc->buf_ptr = (u8 *) p;
 523        p_txdesc->byte_cnt = datasize;
 524
 525        /* Apply send command using zeroth RXUQ */
 526        KWGBEREG_WR(regs->tcqdp[TXUQ], (u32) p_txdesc);
 527        KWGBEREG_WR(regs->tqc, (1 << TXUQ));
 528
 529        /*
 530         * wait for packet xmit completion
 531         */
 532        cmd_sts = readl(&p_txdesc->cmd_sts);
 533        while (cmd_sts & KWGBE_BUFFER_OWNED_BY_DMA) {
 534                /* return fail if error is detected */
 535                if ((cmd_sts & (KWGBE_ERROR_SUMMARY | KWGBE_TX_LAST_FRAME)) ==
 536                                (KWGBE_ERROR_SUMMARY | KWGBE_TX_LAST_FRAME) &&
 537                                cmd_sts & (KWGBE_UR_ERROR | KWGBE_RL_ERROR)) {
 538                        printf("Err..(%s) in xmit packet\n", __FUNCTION__);
 539                        return -1;
 540                }
 541                cmd_sts = readl(&p_txdesc->cmd_sts);
 542        };
 543        return 0;
 544}
 545
 546static int kwgbe_recv(struct eth_device *dev)
 547{
 548        struct kwgbe_device *dkwgbe = to_dkwgbe(dev);
 549        struct kwgbe_rxdesc *p_rxdesc_curr = dkwgbe->p_rxdesc_curr;
 550        u32 cmd_sts;
 551        u32 timeout = 0;
 552
 553        /* wait untill rx packet available or timeout */
 554        do {
 555                if (timeout < KWGBE_PHY_SMI_TIMEOUT)
 556                        timeout++;
 557                else {
 558                        debug("%s time out...\n", __FUNCTION__);
 559                        return -1;
 560                }
 561        } while (readl(&p_rxdesc_curr->cmd_sts) & KWGBE_BUFFER_OWNED_BY_DMA);
 562
 563        if (p_rxdesc_curr->byte_cnt != 0) {
 564                debug("%s: Received %d byte Packet @ 0x%x (cmd_sts= %08x)\n",
 565                        __FUNCTION__, (u32) p_rxdesc_curr->byte_cnt,
 566                        (u32) p_rxdesc_curr->buf_ptr,
 567                        (u32) p_rxdesc_curr->cmd_sts);
 568        }
 569
 570        /*
 571         * In case received a packet without first/last bits on
 572         * OR the error summary bit is on,
 573         * the packets needs to be dropeed.
 574         */
 575        cmd_sts = readl(&p_rxdesc_curr->cmd_sts);
 576
 577        if ((cmd_sts &
 578                (KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC))
 579                != (KWGBE_RX_FIRST_DESC | KWGBE_RX_LAST_DESC)) {
 580
 581                printf("Err..(%s) Dropping packet spread on"
 582                        " multiple descriptors\n", __FUNCTION__);
 583
 584        } else if (cmd_sts & KWGBE_ERROR_SUMMARY) {
 585
 586                printf("Err..(%s) Dropping packet with errors\n",
 587                        __FUNCTION__);
 588
 589        } else {
 590                /* !!! call higher layer processing */
 591                debug("%s: Sending Received packet to"
 592                        " upper layer (NetReceive)\n", __FUNCTION__);
 593
 594                /* let the upper layer handle the packet */
 595                NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET),
 596                        (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET));
 597        }
 598        /*
 599         * free these descriptors and point next in the ring
 600         */
 601        p_rxdesc_curr->cmd_sts =
 602                KWGBE_BUFFER_OWNED_BY_DMA | KWGBE_RX_EN_INTERRUPT;
 603        p_rxdesc_curr->buf_size = PKTSIZE_ALIGN;
 604        p_rxdesc_curr->byte_cnt = 0;
 605
 606        writel((unsigned)p_rxdesc_curr->nxtdesc_p, &dkwgbe->p_rxdesc_curr);
 607
 608        return 0;
 609}
 610
 611int kirkwood_egiga_initialize(bd_t * bis)
 612{
 613        struct kwgbe_device *dkwgbe;
 614        struct eth_device *dev;
 615        int devnum;
 616        char *s;
 617        u8 used_ports[MAX_KWGBE_DEVS] = CONFIG_KIRKWOOD_EGIGA_PORTS;
 618
 619        for (devnum = 0; devnum < MAX_KWGBE_DEVS; devnum++) {
 620                /*skip if port is configured not to use */
 621                if (used_ports[devnum] == 0)
 622                        continue;
 623
 624                if (!(dkwgbe = malloc(sizeof(struct kwgbe_device))))
 625                        goto error1;
 626
 627                memset(dkwgbe, 0, sizeof(struct kwgbe_device));
 628
 629                if (!(dkwgbe->p_rxdesc =
 630                      (struct kwgbe_rxdesc *)memalign(PKTALIGN,
 631                                                KW_RXQ_DESC_ALIGNED_SIZE
 632                                                * RINGSZ + 1)))
 633                        goto error2;
 634
 635                if (!(dkwgbe->p_rxbuf = (u8 *) memalign(PKTALIGN, RINGSZ
 636                                                        * PKTSIZE_ALIGN + 1)))
 637                        goto error3;
 638
 639                if (!(dkwgbe->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN)))
 640                        goto error4;
 641
 642                if (!(dkwgbe->p_txdesc = (struct kwgbe_txdesc *)
 643                      memalign(PKTALIGN, sizeof(struct kwgbe_txdesc) + 1))) {
 644                        free(dkwgbe->p_aligned_txbuf);
 645                      error4:
 646                        free(dkwgbe->p_rxbuf);
 647                      error3:
 648                        free(dkwgbe->p_rxdesc);
 649                      error2:
 650                        free(dkwgbe);
 651                      error1:
 652                        printf("Err.. %s Failed to allocate memory\n",
 653                                __FUNCTION__);
 654                        return -1;
 655                }
 656
 657                dev = &dkwgbe->dev;
 658
 659                /* must be less than NAMESIZE (16) */
 660                sprintf(dev->name, "egiga%d", devnum);
 661
 662                /* Extract the MAC address from the environment */
 663                switch (devnum) {
 664                case 0:
 665                        dkwgbe->regs = (void *)KW_EGIGA0_BASE;
 666                        s = "ethaddr";
 667                        break;
 668                case 1:
 669                        dkwgbe->regs = (void *)KW_EGIGA1_BASE;
 670                        s = "eth1addr";
 671                        break;
 672                default:        /* this should never happen */
 673                        printf("Err..(%s) Invalid device number %d\n",
 674                                __FUNCTION__, devnum);
 675                        return -1;
 676                }
 677
 678                while (!eth_getenv_enetaddr(s, dev->enetaddr)) {
 679                        /* Generate Random Private MAC addr if not set */
 680                        dev->enetaddr[0] = 0x02;
 681                        dev->enetaddr[1] = 0x50;
 682                        dev->enetaddr[2] = 0x43;
 683                        dev->enetaddr[3] = get_random_hex();
 684                        dev->enetaddr[4] = get_random_hex();
 685                        dev->enetaddr[5] = get_random_hex();
 686                        eth_setenv_enetaddr(s, dev->enetaddr);
 687                }
 688
 689                dev->init = (void *)kwgbe_init;
 690                dev->halt = (void *)kwgbe_halt;
 691                dev->send = (void *)kwgbe_send;
 692                dev->recv = (void *)kwgbe_recv;
 693
 694                eth_register(dev);
 695
 696#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
 697                miiphy_register(dev->name, smi_reg_read, smi_reg_write);
 698                /* Set phy address of the port */
 699                miiphy_write(dev->name, KIRKWOOD_PHY_ADR_REQUEST,
 700                                KIRKWOOD_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum);
 701#endif
 702        }
 703        return 0;
 704}
 705