Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
[safe/jmp/linux-2.6] / drivers / net / ucc_geth.c
index 12cd7b5..e2f2e91 100644 (file)
@@ -1,15 +1,12 @@
 /*
- * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
+ * Copyright (C) 2006-2009 Freescale Semicondutor, Inc. All rights reserved.
  *
  * Author: Shlomi Gridish <gridish@freescale.com>
+ *        Li Yang <leoli@freescale.com>
  *
  * Description:
  * QE UCC Gigabit Ethernet Driver
  *
- * Changelog:
- * Jul 6, 2006 Li Yang <LeoLi@freescale.com>
- * - Rearrange code and style fixes
- *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
  * Free Software Foundation;  either version 2 of the  License, or (at your
 #include <linux/skbuff.h>
 #include <linux/spinlock.h>
 #include <linux/mm.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
 #include <linux/dma-mapping.h>
-#include <linux/fsl_devices.h>
-#include <linux/ethtool.h>
-#include <linux/platform_device.h>
 #include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/workqueue.h>
+#include <linux/of_mdio.h>
+#include <linux/of_platform.h>
 
 #include <asm/uaccess.h>
 #include <asm/irq.h>
 #include <asm/ucc_fast.h>
 
 #include "ucc_geth.h"
-#include "ucc_geth_phy.h"
+#include "fsl_pq_mdio.h"
 
 #undef DEBUG
 
-#define DRV_DESC "QE UCC Gigabit Ethernet Controller version:Sept 11, 2006"
-#define DRV_NAME "ucc_geth"
-
 #define ugeth_printk(level, format, arg...)  \
         printk(level format "\n", ## arg)
 
 #else
 #define ugeth_vdbg(fmt, args...) do { } while (0)
 #endif                         /* UGETH_VERBOSE_DEBUG */
+#define UGETH_MSG_DEFAULT      (NETIF_MSG_IFUP << 1 ) - 1
+
 
 static DEFINE_SPINLOCK(ugeth_lock);
 
-static ucc_geth_info_t ugeth_primary_info = {
+static void uec_configure_serdes(struct net_device *dev);
+
+static struct {
+       u32 msg_enable;
+} debug = { -1 };
+
+module_param_named(debug, debug.msg_enable, int, 0);
+MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 0xffff=all)");
+
+static struct ucc_geth_info ugeth_primary_info = {
        .uf_info = {
                    .bd_mem_part = MEM_PART_SYSTEM,
                    .rtsm = UCC_FAST_SEND_IDLES_BETWEEN_FRAMES,
                    .max_rx_buf_length = 1536,
-/* FIXME: should be changed in run time for 1G and 100M */
-#ifdef CONFIG_UGETH_HAS_GIGA
-                   .urfs = UCC_GETH_URFS_GIGA_INIT,
-                   .urfet = UCC_GETH_URFET_GIGA_INIT,
-                   .urfset = UCC_GETH_URFSET_GIGA_INIT,
-                   .utfs = UCC_GETH_UTFS_GIGA_INIT,
-                   .utfet = UCC_GETH_UTFET_GIGA_INIT,
-                   .utftt = UCC_GETH_UTFTT_GIGA_INIT,
-#else
+                   /* adjusted at startup if max-speed 1000 */
                    .urfs = UCC_GETH_URFS_INIT,
                    .urfet = UCC_GETH_URFET_INIT,
                    .urfset = UCC_GETH_URFSET_INIT,
                    .utfs = UCC_GETH_UTFS_INIT,
                    .utfet = UCC_GETH_UTFET_INIT,
                    .utftt = UCC_GETH_UTFTT_INIT,
-#endif
                    .ufpt = 256,
                    .mode = UCC_FAST_PROTOCOL_MODE_ETHERNET,
                    .ttx_trx = UCC_FAST_GUMR_TRANSPARENT_TTX_TRX_NORMAL,
@@ -116,6 +111,7 @@ static ucc_geth_info_t ugeth_primary_info = {
        .maxRetransmission = 0xf,
        .collisionWindow = 0x37,
        .receiveFlowControl = 1,
+       .transmitFlowControl = 1,
        .maxGroupAddrInHash = 4,
        .maxIndAddrInHash = 4,
        .prel = 7,
@@ -151,19 +147,21 @@ static ucc_geth_info_t ugeth_primary_info = {
        .numStationAddresses = UCC_GETH_NUM_OF_STATION_ADDRESSES_1,
        .largestexternallookupkeysize =
            QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE,
-       .statisticsMode = UCC_GETH_STATISTICS_GATHERING_MODE_NONE,
+       .statisticsMode = UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE |
+               UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX |
+               UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX,
        .vlanOperationTagged = UCC_GETH_VLAN_OPERATION_TAGGED_NOP,
        .vlanOperationNonTagged = UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP,
        .rxQoSMode = UCC_GETH_QOS_MODE_DEFAULT,
        .aufc = UPSMR_AUTOMATIC_FLOW_CONTROL_MODE_NONE,
        .padAndCrc = MACCFG2_PAD_AND_CRC_MODE_PAD_AND_CRC,
-       .numThreadsTx = UCC_GETH_NUM_OF_THREADS_4,
-       .numThreadsRx = UCC_GETH_NUM_OF_THREADS_4,
+       .numThreadsTx = UCC_GETH_NUM_OF_THREADS_1,
+       .numThreadsRx = UCC_GETH_NUM_OF_THREADS_1,
        .riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
        .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
 };
 
-static ucc_geth_info_t ugeth_info[8];
+static struct ucc_geth_info ugeth_info[8];
 
 #ifdef DEBUG
 static void mem_disp(u8 *addr, int size)
@@ -192,98 +190,24 @@ static void mem_disp(u8 *addr, int size)
 }
 #endif /* DEBUG */
 
-#ifdef CONFIG_UGETH_FILTERING
-static void enqueue(struct list_head *node, struct list_head *lh)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(ugeth_lock, flags);
-       list_add_tail(node, lh);
-       spin_unlock_irqrestore(ugeth_lock, flags);
-}
-#endif /* CONFIG_UGETH_FILTERING */
-
 static struct list_head *dequeue(struct list_head *lh)
 {
        unsigned long flags;
 
-       spin_lock_irqsave(ugeth_lock, flags);
+       spin_lock_irqsave(&ugeth_lock, flags);
        if (!list_empty(lh)) {
                struct list_head *node = lh->next;
                list_del(node);
-               spin_unlock_irqrestore(ugeth_lock, flags);
+               spin_unlock_irqrestore(&ugeth_lock, flags);
                return node;
        } else {
-               spin_unlock_irqrestore(ugeth_lock, flags);
+               spin_unlock_irqrestore(&ugeth_lock, flags);
                return NULL;
        }
 }
 
-static int get_interface_details(enet_interface_e enet_interface,
-                                enet_speed_e *speed,
-                                int *r10m,
-                                int *rmm,
-                                int *rpm,
-                                int *tbi, int *limited_to_full_duplex)
-{
-       /* Analyze enet_interface according to Interface Mode
-       Configuration table */
-       switch (enet_interface) {
-       case ENET_10_MII:
-               *speed = ENET_SPEED_10BT;
-               break;
-       case ENET_10_RMII:
-               *speed = ENET_SPEED_10BT;
-               *r10m = 1;
-               *rmm = 1;
-               break;
-       case ENET_10_RGMII:
-               *speed = ENET_SPEED_10BT;
-               *rpm = 1;
-               *r10m = 1;
-               *limited_to_full_duplex = 1;
-               break;
-       case ENET_100_MII:
-               *speed = ENET_SPEED_100BT;
-               break;
-       case ENET_100_RMII:
-               *speed = ENET_SPEED_100BT;
-               *rmm = 1;
-               break;
-       case ENET_100_RGMII:
-               *speed = ENET_SPEED_100BT;
-               *rpm = 1;
-               *limited_to_full_duplex = 1;
-               break;
-       case ENET_1000_GMII:
-               *speed = ENET_SPEED_1000BT;
-               *limited_to_full_duplex = 1;
-               break;
-       case ENET_1000_RGMII:
-               *speed = ENET_SPEED_1000BT;
-               *rpm = 1;
-               *limited_to_full_duplex = 1;
-               break;
-       case ENET_1000_TBI:
-               *speed = ENET_SPEED_1000BT;
-               *tbi = 1;
-               *limited_to_full_duplex = 1;
-               break;
-       case ENET_1000_RTBI:
-               *speed = ENET_SPEED_1000BT;
-               *rpm = 1;
-               *tbi = 1;
-               *limited_to_full_duplex = 1;
-               break;
-       default:
-               return -EINVAL;
-               break;
-       }
-
-       return 0;
-}
-
-static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd)
+static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
+               u8 __iomem *bd)
 {
        struct sk_buff *skb = NULL;
 
@@ -301,25 +225,24 @@ static struct sk_buff *get_new_skb(ucc_geth_private_t *ugeth, u8 *bd)
                    (((unsigned)skb->data) & (UCC_GETH_RX_DATA_BUF_ALIGNMENT -
                                              1)));
 
-       skb->dev = ugeth->dev;
+       skb->dev = ugeth->ndev;
 
-       BD_BUFFER_SET(bd,
-                     dma_map_single(NULL,
+       out_be32(&((struct qe_bd __iomem *)bd)->buf,
+                     dma_map_single(ugeth->dev,
                                     skb->data,
                                     ugeth->ug_info->uf_info.max_rx_buf_length +
                                     UCC_GETH_RX_DATA_BUF_ALIGNMENT,
                                     DMA_FROM_DEVICE));
 
-       BD_STATUS_AND_LENGTH_SET(bd,
-                                (R_E | R_I |
-                                 (BD_STATUS_AND_LENGTH(bd) & R_W)));
+       out_be32((u32 __iomem *)bd,
+                       (R_E | R_I | (in_be32((u32 __iomem*)bd) & R_W)));
 
        return skb;
 }
 
-static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ)
+static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ)
 {
-       u8 *bd;
+       u8 __iomem *bd;
        u32 bd_status;
        struct sk_buff *skb;
        int i;
@@ -328,7 +251,7 @@ static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ)
        i = 0;
 
        do {
-               bd_status = BD_STATUS_AND_LENGTH(bd);
+               bd_status = in_be32((u32 __iomem *)bd);
                skb = get_new_skb(ugeth, bd);
 
                if (!skb)       /* If can not allocate data buffer,
@@ -338,19 +261,19 @@ static int rx_bd_buffer_set(ucc_geth_private_t *ugeth, u8 rxQ)
                ugeth->rx_skbuff[rxQ][i] = skb;
 
                /* advance the BD pointer */
-               bd += UCC_GETH_SIZE_OF_BD;
+               bd += sizeof(struct qe_bd);
                i++;
        } while (!(bd_status & R_W));
 
        return 0;
 }
 
-static int fill_init_enet_entries(ucc_geth_private_t *ugeth,
-                                 volatile u32 *p_start,
+static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
+                                 u32 *p_start,
                                  u8 num_entries,
                                  u32 thread_size,
                                  u32 thread_alignment,
-                                 qe_risc_allocation_e risc,
+                                 unsigned int risc,
                                  int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -359,7 +282,8 @@ static int fill_init_enet_entries(ucc_geth_private_t *ugeth,
 
        for (i = 0; i < num_entries; i++) {
                if ((snum = qe_get_snum()) < 0) {
-                       ugeth_err("fill_init_enet_entries: Can not get SNUM.");
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err("fill_init_enet_entries: Can not get SNUM.");
                        return snum;
                }
                if ((i == 0) && skip_page_for_first_entry)
@@ -368,9 +292,9 @@ static int fill_init_enet_entries(ucc_geth_private_t *ugeth,
                else {
                        init_enet_offset =
                            qe_muram_alloc(thread_size, thread_alignment);
-                       if (IS_MURAM_ERR(init_enet_offset)) {
-                               ugeth_err
-               ("fill_init_enet_entries: Can not allocate DPRAM memory.");
+                       if (IS_ERR_VALUE(init_enet_offset)) {
+                               if (netif_msg_ifup(ugeth))
+                                       ugeth_err("fill_init_enet_entries: Can not allocate DPRAM memory.");
                                qe_put_snum((u8) snum);
                                return -ENOMEM;
                        }
@@ -383,10 +307,10 @@ static int fill_init_enet_entries(ucc_geth_private_t *ugeth,
        return 0;
 }
 
-static int return_init_enet_entries(ucc_geth_private_t *ugeth,
-                                   volatile u32 *p_start,
+static int return_init_enet_entries(struct ucc_geth_private *ugeth,
+                                   u32 *p_start,
                                    u8 num_entries,
-                                   qe_risc_allocation_e risc,
+                                   unsigned int risc,
                                    int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -394,21 +318,22 @@ static int return_init_enet_entries(ucc_geth_private_t *ugeth,
        int snum;
 
        for (i = 0; i < num_entries; i++) {
+               u32 val = *p_start;
+
                /* Check that this entry was actually valid --
                needed in case failed in allocations */
-               if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) {
+               if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) {
                        snum =
-                           (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >>
+                           (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >>
                            ENET_INIT_PARAM_SNUM_SHIFT;
                        qe_put_snum((u8) snum);
                        if (!((i == 0) && skip_page_for_first_entry)) {
                        /* First entry of Rx does not have page */
                                init_enet_offset =
-                                   (in_be32(p_start) &
-                                    ENET_INIT_PARAM_PTR_MASK);
+                                   (val & ENET_INIT_PARAM_PTR_MASK);
                                qe_muram_free(init_enet_offset);
                        }
-                       *(p_start++) = 0;       /* Just for cosmetics */
+                       *p_start++ = 0;
                }
        }
 
@@ -416,11 +341,11 @@ static int return_init_enet_entries(ucc_geth_private_t *ugeth,
 }
 
 #ifdef DEBUG
-static int dump_init_enet_entries(ucc_geth_private_t *ugeth,
-                                 volatile u32 *p_start,
+static int dump_init_enet_entries(struct ucc_geth_private *ugeth,
+                                 u32 __iomem *p_start,
                                  u8 num_entries,
                                  u32 thread_size,
-                                 qe_risc_allocation_e risc,
+                                 unsigned int risc,
                                  int skip_page_for_first_entry)
 {
        u32 init_enet_offset;
@@ -428,11 +353,13 @@ static int dump_init_enet_entries(ucc_geth_private_t *ugeth,
        int snum;
 
        for (i = 0; i < num_entries; i++) {
+               u32 val = in_be32(p_start);
+
                /* Check that this entry was actually valid --
                needed in case failed in allocations */
-               if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) {
+               if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) {
                        snum =
-                           (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >>
+                           (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >>
                            ENET_INIT_PARAM_SNUM_SHIFT;
                        qe_put_snum((u8) snum);
                        if (!((i == 0) && skip_page_for_first_entry)) {
@@ -455,70 +382,29 @@ static int dump_init_enet_entries(ucc_geth_private_t *ugeth,
 }
 #endif
 
-#ifdef CONFIG_UGETH_FILTERING
-static enet_addr_container_t *get_enet_addr_container(void)
-{
-       enet_addr_container_t *enet_addr_cont;
-
-       /* allocate memory */
-       enet_addr_cont = kmalloc(sizeof(enet_addr_container_t), GFP_KERNEL);
-       if (!enet_addr_cont) {
-               ugeth_err("%s: No memory for enet_addr_container_t object.",
-                         __FUNCTION__);
-               return NULL;
-       }
-
-       return enet_addr_cont;
-}
-#endif /* CONFIG_UGETH_FILTERING */
-
-static void put_enet_addr_container(enet_addr_container_t *enet_addr_cont)
+static void put_enet_addr_container(struct enet_addr_container *enet_addr_cont)
 {
        kfree(enet_addr_cont);
 }
 
-#ifdef CONFIG_UGETH_FILTERING
-static int hw_add_addr_in_paddr(ucc_geth_private_t *ugeth,
-                               enet_addr_t *p_enet_addr, u8 paddr_num)
+static void set_mac_addr(__be16 __iomem *reg, u8 *mac)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-
-       if (!(paddr_num < NUM_OF_PADDRS)) {
-               ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
-               return -EINVAL;
-       }
-
-       p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
-           addressfiltering;
-
-       /* Ethernet frames are defined in Little Endian mode,    */
-       /* therefore to insert the address we reverse the bytes. */
-       out_be16(&p_82xx_addr_filt->paddr[paddr_num].h,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) |
-                       (u16) (*p_enet_addr)[4]));
-       out_be16(&p_82xx_addr_filt->paddr[paddr_num].m,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) |
-                       (u16) (*p_enet_addr)[2]));
-       out_be16(&p_82xx_addr_filt->paddr[paddr_num].l,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) |
-                       (u16) (*p_enet_addr)[0]));
-
-       return 0;
+       out_be16(&reg[0], ((u16)mac[5] << 8) | mac[4]);
+       out_be16(&reg[1], ((u16)mac[3] << 8) | mac[2]);
+       out_be16(&reg[2], ((u16)mac[1] << 8) | mac[0]);
 }
-#endif /* CONFIG_UGETH_FILTERING */
 
-static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num)
+static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+       struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
 
        if (!(paddr_num < NUM_OF_PADDRS)) {
-               ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
+               ugeth_warn("%s: Illagel paddr_num.", __func__);
                return -EINVAL;
        }
 
        p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+           (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram->
            addressfiltering;
 
        /* Writing address ff.ff.ff.ff.ff.ff disables address
@@ -530,14 +416,14 @@ static int hw_clear_addr_in_paddr(ucc_geth_private_t *ugeth, u8 paddr_num)
        return 0;
 }
 
-static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth,
-                               enet_addr_t *p_enet_addr)
+static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth,
+                                u8 *p_enet_addr)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
+       struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
        u32 cecr_subblock;
 
        p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
+           (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram->
            addressfiltering;
 
        cecr_subblock =
@@ -546,82 +432,65 @@ static void hw_add_addr_in_hash(ucc_geth_private_t *ugeth,
        /* Ethernet frames are defined in Little Endian mode,
        therefor to insert */
        /* the address to the hash (Big Endian mode), we reverse the bytes.*/
-       out_be16(&p_82xx_addr_filt->taddr.h,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[5])) << 8)) |
-                       (u16) (*p_enet_addr)[4]));
-       out_be16(&p_82xx_addr_filt->taddr.m,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[3])) << 8)) |
-                       (u16) (*p_enet_addr)[2]));
-       out_be16(&p_82xx_addr_filt->taddr.l,
-                (u16) (((u16) (((u16) ((*p_enet_addr)[1])) << 8)) |
-                       (u16) (*p_enet_addr)[0]));
+
+       set_mac_addr(&p_82xx_addr_filt->taddr.h, p_enet_addr);
 
        qe_issue_cmd(QE_SET_GROUP_ADDRESS, cecr_subblock,
-                    (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+                    QE_CR_PROTOCOL_ETHERNET, 0);
 }
 
 #ifdef CONFIG_UGETH_MAGIC_PACKET
-static void magic_packet_detection_enable(ucc_geth_private_t *ugeth)
+static void magic_packet_detection_enable(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
-       ucc_geth_t *ug_regs;
-       u32 maccfg2, uccm;
+       struct ucc_fast_private *uccf;
+       struct ucc_geth __iomem *ug_regs;
 
        uccf = ugeth->uccf;
        ug_regs = ugeth->ug_regs;
 
        /* Enable interrupts for magic packet detection */
-       uccm = in_be32(uccf->p_uccm);
-       uccm |= UCCE_MPD;
-       out_be32(uccf->p_uccm, uccm);
+       setbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD);
 
        /* Enable magic packet detection */
-       maccfg2 = in_be32(&ug_regs->maccfg2);
-       maccfg2 |= MACCFG2_MPE;
-       out_be32(&ug_regs->maccfg2, maccfg2);
+       setbits32(&ug_regs->maccfg2, MACCFG2_MPE);
 }
 
-static void magic_packet_detection_disable(ucc_geth_private_t *ugeth)
+static void magic_packet_detection_disable(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
-       ucc_geth_t *ug_regs;
-       u32 maccfg2, uccm;
+       struct ucc_fast_private *uccf;
+       struct ucc_geth __iomem *ug_regs;
 
        uccf = ugeth->uccf;
        ug_regs = ugeth->ug_regs;
 
        /* Disable interrupts for magic packet detection */
-       uccm = in_be32(uccf->p_uccm);
-       uccm &= ~UCCE_MPD;
-       out_be32(uccf->p_uccm, uccm);
+       clrbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD);
 
        /* Disable magic packet detection */
-       maccfg2 = in_be32(&ug_regs->maccfg2);
-       maccfg2 &= ~MACCFG2_MPE;
-       out_be32(&ug_regs->maccfg2, maccfg2);
+       clrbits32(&ug_regs->maccfg2, MACCFG2_MPE);
 }
 #endif /* MAGIC_PACKET */
 
-static inline int compare_addr(enet_addr_t *addr1, enet_addr_t *addr2)
+static inline int compare_addr(u8 **addr1, u8 **addr2)
 {
        return memcmp(addr1, addr2, ENET_NUM_OCTETS_PER_ADDRESS);
 }
 
 #ifdef DEBUG
-static void get_statistics(ucc_geth_private_t *ugeth,
-                          ucc_geth_tx_firmware_statistics_t *
+static void get_statistics(struct ucc_geth_private *ugeth,
+                          struct ucc_geth_tx_firmware_statistics *
                           tx_firmware_statistics,
-                          ucc_geth_rx_firmware_statistics_t *
+                          struct ucc_geth_rx_firmware_statistics *
                           rx_firmware_statistics,
-                          ucc_geth_hardware_statistics_t *hardware_statistics)
+                          struct ucc_geth_hardware_statistics *hardware_statistics)
 {
-       ucc_fast_t *uf_regs;
-       ucc_geth_t *ug_regs;
-       ucc_geth_tx_firmware_statistics_pram_t *p_tx_fw_statistics_pram;
-       ucc_geth_rx_firmware_statistics_pram_t *p_rx_fw_statistics_pram;
+       struct ucc_fast __iomem *uf_regs;
+       struct ucc_geth __iomem *ug_regs;
+       struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram;
+       struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram;
 
        ug_regs = ugeth->ug_regs;
-       uf_regs = (ucc_fast_t *) ug_regs;
+       uf_regs = (struct ucc_fast __iomem *) ug_regs;
        p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram;
        p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram;
 
@@ -708,7 +577,8 @@ static void get_statistics(ucc_geth_private_t *ugeth,
 
        /* Hardware only if user handed pointer and driver actually
        gathers hardware statistics */
-       if (hardware_statistics && (in_be32(&uf_regs->upsmr) & UPSMR_HSE)) {
+       if (hardware_statistics &&
+           (in_be32(&uf_regs->upsmr) & UCC_GETH_UPSMR_HSE)) {
                hardware_statistics->tx64 = in_be32(&ug_regs->tx64);
                hardware_statistics->tx127 = in_be32(&ug_regs->tx127);
                hardware_statistics->tx255 = in_be32(&ug_regs->tx255);
@@ -727,7 +597,7 @@ static void get_statistics(ucc_geth_private_t *ugeth,
        }
 }
 
-static void dump_bds(ucc_geth_private_t *ugeth)
+static void dump_bds(struct ucc_geth_private *ugeth)
 {
        int i;
        int length;
@@ -736,7 +606,7 @@ static void dump_bds(ucc_geth_private_t *ugeth)
                if (ugeth->p_tx_bd_ring[i]) {
                        length =
                            (ugeth->ug_info->bdRingLenTx[i] *
-                            UCC_GETH_SIZE_OF_BD);
+                            sizeof(struct qe_bd));
                        ugeth_info("TX BDs[%d]", i);
                        mem_disp(ugeth->p_tx_bd_ring[i], length);
                }
@@ -745,14 +615,14 @@ static void dump_bds(ucc_geth_private_t *ugeth)
                if (ugeth->p_rx_bd_ring[i]) {
                        length =
                            (ugeth->ug_info->bdRingLenRx[i] *
-                            UCC_GETH_SIZE_OF_BD);
+                            sizeof(struct qe_bd));
                        ugeth_info("RX BDs[%d]", i);
                        mem_disp(ugeth->p_rx_bd_ring[i], length);
                }
        }
 }
 
-static void dump_regs(ucc_geth_private_t *ugeth)
+static void dump_regs(struct ucc_geth_private *ugeth)
 {
        int i;
 
@@ -771,24 +641,6 @@ static void dump_regs(ucc_geth_private_t *ugeth)
        ugeth_info("hafdup     : addr - 0x%08x, val - 0x%08x",
                   (u32) & ugeth->ug_regs->hafdup,
                   in_be32(&ugeth->ug_regs->hafdup));
-       ugeth_info("miimcfg    : addr - 0x%08x, val - 0x%08x",
-                  (u32) & ugeth->ug_regs->miimng.miimcfg,
-                  in_be32(&ugeth->ug_regs->miimng.miimcfg));
-       ugeth_info("miimcom    : addr - 0x%08x, val - 0x%08x",
-                  (u32) & ugeth->ug_regs->miimng.miimcom,
-                  in_be32(&ugeth->ug_regs->miimng.miimcom));
-       ugeth_info("miimadd    : addr - 0x%08x, val - 0x%08x",
-                  (u32) & ugeth->ug_regs->miimng.miimadd,
-                  in_be32(&ugeth->ug_regs->miimng.miimadd));
-       ugeth_info("miimcon    : addr - 0x%08x, val - 0x%08x",
-                  (u32) & ugeth->ug_regs->miimng.miimcon,
-                  in_be32(&ugeth->ug_regs->miimng.miimcon));
-       ugeth_info("miimstat   : addr - 0x%08x, val - 0x%08x",
-                  (u32) & ugeth->ug_regs->miimng.miimstat,
-                  in_be32(&ugeth->ug_regs->miimng.miimstat));
-       ugeth_info("miimmind   : addr - 0x%08x, val - 0x%08x",
-                  (u32) & ugeth->ug_regs->miimng.miimind,
-                  in_be32(&ugeth->ug_regs->miimng.miimind));
        ugeth_info("ifctl      : addr - 0x%08x, val - 0x%08x",
                   (u32) & ugeth->ug_regs->ifctl,
                   in_be32(&ugeth->ug_regs->ifctl));
@@ -893,7 +745,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                        ugeth_info("Base address: 0x%08x",
                                   (u32) & ugeth->p_thread_data_tx[i]);
                        mem_disp((u8 *) & ugeth->p_thread_data_tx[i],
-                                sizeof(ucc_geth_thread_data_tx_t));
+                                sizeof(struct ucc_geth_thread_data_tx));
                }
        }
        if (ugeth->p_thread_data_rx) {
@@ -927,7 +779,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                        ugeth_info("Base address: 0x%08x",
                                   (u32) & ugeth->p_thread_data_rx[i]);
                        mem_disp((u8 *) & ugeth->p_thread_data_rx[i],
-                                sizeof(ucc_geth_thread_data_rx_t));
+                                sizeof(struct ucc_geth_thread_data_rx));
                }
        }
        if (ugeth->p_exf_glbl_param) {
@@ -1105,7 +957,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                        ugeth_info("Base address: 0x%08x",
                                   (u32) & ugeth->p_send_q_mem_reg->sqqd[i]);
                        mem_disp((u8 *) & ugeth->p_send_q_mem_reg->sqqd[i],
-                                sizeof(ucc_geth_send_queue_qd_t));
+                                sizeof(struct ucc_geth_send_queue_qd));
                }
        }
        if (ugeth->p_scheduler) {
@@ -1187,7 +1039,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                                 qe_muram_addr(in_be32
                                               (&ugeth->p_rx_bd_qs_tbl[i].
                                                bdbaseptr)),
-                                sizeof(ucc_geth_rx_prefetched_bds_t));
+                                sizeof(struct ucc_geth_rx_prefetched_bds));
                }
        }
        if (ugeth->p_init_enet_param_shadow) {
@@ -1198,7 +1050,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                mem_disp((u8 *) ugeth->p_init_enet_param_shadow,
                         sizeof(*ugeth->p_init_enet_param_shadow));
 
-               size = sizeof(ucc_geth_thread_rx_pram_t);
+               size = sizeof(struct ucc_geth_thread_rx_pram);
                if (ugeth->ug_info->rxExtendedFiltering) {
                        size +=
                            THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
@@ -1216,7 +1068,7 @@ static void dump_regs(ucc_geth_private_t *ugeth)
                                       &(ugeth->p_init_enet_param_shadow->
                                         txthread[0]),
                                       ENET_INIT_PARAM_MAX_ENTRIES_TX,
-                                      sizeof(ucc_geth_thread_tx_pram_t),
+                                      sizeof(struct ucc_geth_thread_tx_pram),
                                       ugeth->ug_info->riscTx, 0);
                dump_init_enet_entries(ugeth,
                                       &(ugeth->p_init_enet_param_shadow->
@@ -1227,9 +1079,9 @@ static void dump_regs(ucc_geth_private_t *ugeth)
 }
 #endif /* DEBUG */
 
-static void init_default_reg_vals(volatile u32 *upsmr_register,
-                                 volatile u32 *maccfg1_register,
-                                 volatile u32 *maccfg2_register)
+static void init_default_reg_vals(u32 __iomem *upsmr_register,
+                                 u32 __iomem *maccfg1_register,
+                                 u32 __iomem *maccfg2_register)
 {
        out_be32(upsmr_register, UCC_GETH_UPSMR_INIT);
        out_be32(maccfg1_register, UCC_GETH_MACCFG1_INIT);
@@ -1243,7 +1095,7 @@ static int init_half_duplex_params(int alt_beb,
                                   u8 alt_beb_truncation,
                                   u8 max_retransmissions,
                                   u8 collision_window,
-                                  volatile u32 *hafdup_register)
+                                  u32 __iomem *hafdup_register)
 {
        u32 value = 0;
 
@@ -1275,7 +1127,7 @@ static int init_inter_frame_gap_params(u8 non_btb_cs_ipg,
                                       u8 non_btb_ipg,
                                       u8 min_ifg,
                                       u8 btb_ipg,
-                                      volatile u32 *ipgifg_register)
+                                      u32 __iomem *ipgifg_register)
 {
        u32 value = 0;
 
@@ -1305,14 +1157,14 @@ static int init_inter_frame_gap_params(u8 non_btb_cs_ipg,
        return 0;
 }
 
-static int init_flow_control_params(u32 automatic_flow_control_mode,
+int init_flow_control_params(u32 automatic_flow_control_mode,
                                    int rx_flow_control_enable,
                                    int tx_flow_control_enable,
                                    u16 pause_period,
                                    u16 extension_field,
-                                   volatile u32 *upsmr_register,
-                                   volatile u32 *uempr_register,
-                                   volatile u32 *maccfg1_register)
+                                   u32 __iomem *upsmr_register,
+                                   u32 __iomem *uempr_register,
+                                   u32 __iomem *maccfg1_register)
 {
        u32 value = 0;
 
@@ -1322,9 +1174,7 @@ static int init_flow_control_params(u32 automatic_flow_control_mode,
        out_be32(uempr_register, value);
 
        /* Set UPSMR register */
-       value = in_be32(upsmr_register);
-       value |= automatic_flow_control_mode;
-       out_be32(upsmr_register, value);
+       setbits32(upsmr_register, automatic_flow_control_mode);
 
        value = in_be32(maccfg1_register);
        if (rx_flow_control_enable)
@@ -1338,17 +1188,14 @@ static int init_flow_control_params(u32 automatic_flow_control_mode,
 
 static int init_hw_statistics_gathering_mode(int enable_hardware_statistics,
                                             int auto_zero_hardware_statistics,
-                                            volatile u32 *upsmr_register,
-                                            volatile u16 *uescr_register)
+                                            u32 __iomem *upsmr_register,
+                                            u16 __iomem *uescr_register)
 {
-       u32 upsmr_value = 0;
        u16 uescr_value = 0;
+
        /* Enable hardware statistics gathering if requested */
-       if (enable_hardware_statistics) {
-               upsmr_value = in_be32(upsmr_register);
-               upsmr_value |= UPSMR_HSE;
-               out_be32(upsmr_register, upsmr_value);
-       }
+       if (enable_hardware_statistics)
+               setbits32(upsmr_register, UCC_GETH_UPSMR_HSE);
 
        /* Clear hardware statistics counters */
        uescr_value = in_be16(uescr_register);
@@ -1365,32 +1212,26 @@ static int init_hw_statistics_gathering_mode(int enable_hardware_statistics,
 static int init_firmware_statistics_gathering_mode(int
                enable_tx_firmware_statistics,
                int enable_rx_firmware_statistics,
-               volatile u32 *tx_rmon_base_ptr,
+               u32 __iomem *tx_rmon_base_ptr,
                u32 tx_firmware_statistics_structure_address,
-               volatile u32 *rx_rmon_base_ptr,
+               u32 __iomem *rx_rmon_base_ptr,
                u32 rx_firmware_statistics_structure_address,
-               volatile u16 *temoder_register,
-               volatile u32 *remoder_register)
+               u16 __iomem *temoder_register,
+               u32 __iomem *remoder_register)
 {
        /* Note: this function does not check if */
        /* the parameters it receives are NULL   */
-       u16 temoder_value;
-       u32 remoder_value;
 
        if (enable_tx_firmware_statistics) {
                out_be32(tx_rmon_base_ptr,
                         tx_firmware_statistics_structure_address);
-               temoder_value = in_be16(temoder_register);
-               temoder_value |= TEMODER_TX_RMON_STATISTICS_ENABLE;
-               out_be16(temoder_register, temoder_value);
+               setbits16(temoder_register, TEMODER_TX_RMON_STATISTICS_ENABLE);
        }
 
        if (enable_rx_firmware_statistics) {
                out_be32(rx_rmon_base_ptr,
                         rx_firmware_statistics_structure_address);
-               remoder_value = in_be32(remoder_register);
-               remoder_value |= REMODER_RX_RMON_STATISTICS_ENABLE;
-               out_be32(remoder_register, remoder_value);
+               setbits32(remoder_register, REMODER_RX_RMON_STATISTICS_ENABLE);
        }
 
        return 0;
@@ -1402,8 +1243,8 @@ static int init_mac_station_addr_regs(u8 address_byte_0,
                                      u8 address_byte_3,
                                      u8 address_byte_4,
                                      u8 address_byte_5,
-                                     volatile u32 *macstnaddr1_register,
-                                     volatile u32 *macstnaddr2_register)
+                                     u32 __iomem *macstnaddr1_register,
+                                     u32 __iomem *macstnaddr2_register)
 {
        u32 value = 0;
 
@@ -1438,29 +1279,8 @@ static int init_mac_station_addr_regs(u8 address_byte_0,
        return 0;
 }
 
-static int init_mac_duplex_mode(int full_duplex,
-                               int limited_to_full_duplex,
-                               volatile u32 *maccfg2_register)
-{
-       u32 value = 0;
-
-       /* some interfaces must work in full duplex mode */
-       if ((full_duplex == 0) && (limited_to_full_duplex == 1))
-               return -EINVAL;
-
-       value = in_be32(maccfg2_register);
-
-       if (full_duplex)
-               value |= MACCFG2_FDX;
-       else
-               value &= ~MACCFG2_FDX;
-
-       out_be32(maccfg2_register, value);
-       return 0;
-}
-
 static int init_check_frame_length_mode(int length_check,
-                                       volatile u32 *maccfg2_register)
+                                       u32 __iomem *maccfg2_register)
 {
        u32 value = 0;
 
@@ -1476,76 +1296,39 @@ static int init_check_frame_length_mode(int length_check,
 }
 
 static int init_preamble_length(u8 preamble_length,
-                               volatile u32 *maccfg2_register)
+                               u32 __iomem *maccfg2_register)
 {
-       u32 value = 0;
-
        if ((preamble_length < 3) || (preamble_length > 7))
                return -EINVAL;
 
-       value = in_be32(maccfg2_register);
-       value &= ~MACCFG2_PREL_MASK;
-       value |= (preamble_length << MACCFG2_PREL_SHIFT);
-       out_be32(maccfg2_register, value);
-       return 0;
-}
-
-static int init_mii_management_configuration(int reset_mgmt,
-                                            int preamble_supress,
-                                            volatile u32 *miimcfg_register,
-                                            volatile u32 *miimind_register)
-{
-       unsigned int timeout = PHY_INIT_TIMEOUT;
-       u32 value = 0;
-
-       value = in_be32(miimcfg_register);
-       if (reset_mgmt) {
-               value |= MIIMCFG_RESET_MANAGEMENT;
-               out_be32(miimcfg_register, value);
-       }
-
-       value = 0;
-
-       if (preamble_supress)
-               value |= MIIMCFG_NO_PREAMBLE;
-
-       value |= UCC_GETH_MIIMCFG_MNGMNT_CLC_DIV_INIT;
-       out_be32(miimcfg_register, value);
-
-       /* Wait until the bus is free */
-       while ((in_be32(miimind_register) & MIIMIND_BUSY) && timeout--)
-               cpu_relax();
-
-       if (timeout <= 0) {
-               ugeth_err("%s: The MII Bus is stuck!", __FUNCTION__);
-               return -ETIMEDOUT;
-       }
+       clrsetbits_be32(maccfg2_register, MACCFG2_PREL_MASK,
+                       preamble_length << MACCFG2_PREL_SHIFT);
 
        return 0;
 }
 
 static int init_rx_parameters(int reject_broadcast,
                              int receive_short_frames,
-                             int promiscuous, volatile u32 *upsmr_register)
+                             int promiscuous, u32 __iomem *upsmr_register)
 {
        u32 value = 0;
 
        value = in_be32(upsmr_register);
 
        if (reject_broadcast)
-               value |= UPSMR_BRO;
+               value |= UCC_GETH_UPSMR_BRO;
        else
-               value &= ~UPSMR_BRO;
+               value &= ~UCC_GETH_UPSMR_BRO;
 
        if (receive_short_frames)
-               value |= UPSMR_RSH;
+               value |= UCC_GETH_UPSMR_RSH;
        else
-               value &= ~UPSMR_RSH;
+               value &= ~UCC_GETH_UPSMR_RSH;
 
        if (promiscuous)
-               value |= UPSMR_PRO;
+               value |= UCC_GETH_UPSMR_PRO;
        else
-               value &= ~UPSMR_PRO;
+               value &= ~UCC_GETH_UPSMR_PRO;
 
        out_be32(upsmr_register, value);
 
@@ -1553,7 +1336,7 @@ static int init_rx_parameters(int reject_broadcast,
 }
 
 static int init_max_rx_buff_len(u16 max_rx_buf_len,
-                               volatile u16 *mrblr_register)
+                               u16 __iomem *mrblr_register)
 {
        /* max_rx_buf_len value must be a multiple of 128 */
        if ((max_rx_buf_len == 0)
@@ -1565,8 +1348,8 @@ static int init_max_rx_buff_len(u16 max_rx_buf_len,
 }
 
 static int init_min_frame_len(u16 min_frame_length,
-                             volatile u16 *minflr_register,
-                             volatile u16 *mrblr_register)
+                             u16 __iomem *minflr_register,
+                             u16 __iomem *mrblr_register)
 {
        u16 mrblr_value = 0;
 
@@ -1578,105 +1361,84 @@ static int init_min_frame_len(u16 min_frame_length,
        return 0;
 }
 
-static int adjust_enet_interface(ucc_geth_private_t *ugeth)
+static int adjust_enet_interface(struct ucc_geth_private *ugeth)
 {
-       ucc_geth_info_t *ug_info;
-       ucc_geth_t *ug_regs;
-       ucc_fast_t *uf_regs;
-       enet_speed_e speed;
-       int ret_val, rpm = 0, tbi = 0, r10m = 0, rmm =
-           0, limited_to_full_duplex = 0;
-       u32 upsmr, maccfg2, utbipar, tbiBaseAddress;
+       struct ucc_geth_info *ug_info;
+       struct ucc_geth __iomem *ug_regs;
+       struct ucc_fast __iomem *uf_regs;
+       int ret_val;
+       u32 upsmr, maccfg2, tbiBaseAddress;
        u16 value;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        ug_info = ugeth->ug_info;
        ug_regs = ugeth->ug_regs;
        uf_regs = ugeth->uccf->uf_regs;
 
-       /* Analyze enet_interface according to Interface Mode Configuration
-       table */
-       ret_val =
-           get_interface_details(ug_info->enet_interface, &speed, &r10m, &rmm,
-                                 &rpm, &tbi, &limited_to_full_duplex);
-       if (ret_val != 0) {
-               ugeth_err
-                 ("%s: half duplex not supported in requested configuration.",
-                    __FUNCTION__);
-               return ret_val;
-       }
-
        /*                    Set MACCFG2                    */
        maccfg2 = in_be32(&ug_regs->maccfg2);
        maccfg2 &= ~MACCFG2_INTERFACE_MODE_MASK;
-       if ((speed == ENET_SPEED_10BT) || (speed == ENET_SPEED_100BT))
+       if ((ugeth->max_speed == SPEED_10) ||
+           (ugeth->max_speed == SPEED_100))
                maccfg2 |= MACCFG2_INTERFACE_MODE_NIBBLE;
-       else if (speed == ENET_SPEED_1000BT)
+       else if (ugeth->max_speed == SPEED_1000)
                maccfg2 |= MACCFG2_INTERFACE_MODE_BYTE;
        maccfg2 |= ug_info->padAndCrc;
        out_be32(&ug_regs->maccfg2, maccfg2);
 
        /*                    Set UPSMR                      */
        upsmr = in_be32(&uf_regs->upsmr);
-       upsmr &= ~(UPSMR_RPM | UPSMR_R10M | UPSMR_TBIM | UPSMR_RMM);
-       if (rpm)
-               upsmr |= UPSMR_RPM;
-       if (r10m)
-               upsmr |= UPSMR_R10M;
-       if (tbi)
-               upsmr |= UPSMR_TBIM;
-       if (rmm)
-               upsmr |= UPSMR_RMM;
-       out_be32(&uf_regs->upsmr, upsmr);
+       upsmr &= ~(UCC_GETH_UPSMR_RPM | UCC_GETH_UPSMR_R10M |
+                  UCC_GETH_UPSMR_TBIM | UCC_GETH_UPSMR_RMM);
+       if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
+           (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
+           (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+           (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
+           (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
+           (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
+               if (ugeth->phy_interface != PHY_INTERFACE_MODE_RMII)
+                       upsmr |= UCC_GETH_UPSMR_RPM;
+               switch (ugeth->max_speed) {
+               case SPEED_10:
+                       upsmr |= UCC_GETH_UPSMR_R10M;
+                       /* FALLTHROUGH */
+               case SPEED_100:
+                       if (ugeth->phy_interface != PHY_INTERFACE_MODE_RTBI)
+                               upsmr |= UCC_GETH_UPSMR_RMM;
+               }
+       }
+       if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
+           (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
+               upsmr |= UCC_GETH_UPSMR_TBIM;
+       }
+       if ((ugeth->phy_interface == PHY_INTERFACE_MODE_SGMII))
+               upsmr |= UCC_GETH_UPSMR_SGMM;
 
-       /*                    Set UTBIPAR                    */
-       utbipar = in_be32(&ug_regs->utbipar);
-       utbipar &= ~UTBIPAR_PHY_ADDRESS_MASK;
-       if (tbi)
-               utbipar |=
-                   (ug_info->phy_address +
-                    ugeth->ug_info->uf_info.
-                    ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT;
-       else
-               utbipar |=
-                   (0x10 +
-                    ugeth->ug_info->uf_info.
-                    ucc_num) << UTBIPAR_PHY_ADDRESS_SHIFT;
-       out_be32(&ug_regs->utbipar, utbipar);
+       out_be32(&uf_regs->upsmr, upsmr);
 
        /* Disable autonegotiation in tbi mode, because by default it
        comes up in autonegotiation mode. */
        /* Note that this depends on proper setting in utbipar register. */
-       if (tbi) {
+       if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
+           (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
                tbiBaseAddress = in_be32(&ug_regs->utbipar);
                tbiBaseAddress &= UTBIPAR_PHY_ADDRESS_MASK;
                tbiBaseAddress >>= UTBIPAR_PHY_ADDRESS_SHIFT;
-               value =
-                   ugeth->mii_info->mdio_read(ugeth->dev, (u8) tbiBaseAddress,
-                                              ENET_TBI_MII_CR);
+               value = ugeth->phydev->bus->read(ugeth->phydev->bus,
+                               (u8) tbiBaseAddress, ENET_TBI_MII_CR);
                value &= ~0x1000;       /* Turn off autonegotiation */
-               ugeth->mii_info->mdio_write(ugeth->dev, (u8) tbiBaseAddress,
-                                           ENET_TBI_MII_CR, value);
-       }
-
-       ret_val = init_mac_duplex_mode(1,
-                                      limited_to_full_duplex,
-                                      &ug_regs->maccfg2);
-       if (ret_val != 0) {
-               ugeth_err
-               ("%s: half duplex not supported in requested configuration.",
-                    __FUNCTION__);
-               return ret_val;
+               ugeth->phydev->bus->write(ugeth->phydev->bus,
+                               (u8) tbiBaseAddress, ENET_TBI_MII_CR, value);
        }
 
        init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2);
 
        ret_val = init_preamble_length(ug_info->prel, &ug_regs->maccfg2);
        if (ret_val != 0) {
-               ugeth_err
-                   ("%s: Preamble length must be between 3 and 7 inclusive.",
-                    __FUNCTION__);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: Preamble length must be between 3 and 7 inclusive.",
+                            __func__);
                return ret_val;
        }
 
@@ -1689,137 +1451,89 @@ static int adjust_enet_interface(ucc_geth_private_t *ugeth)
  * function converts those variables into the appropriate
  * register values, and can bring down the device if needed.
  */
+
 static void adjust_link(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       ucc_geth_t *ug_regs;
-       u32 tempval;
-       struct ugeth_mii_info *mii_info = ugeth->mii_info;
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct ucc_geth __iomem *ug_regs;
+       struct ucc_fast __iomem *uf_regs;
+       struct phy_device *phydev = ugeth->phydev;
+       unsigned long flags;
+       int new_state = 0;
 
        ug_regs = ugeth->ug_regs;
+       uf_regs = ugeth->uccf->uf_regs;
+
+       spin_lock_irqsave(&ugeth->lock, flags);
 
-       if (mii_info->link) {
+       if (phydev->link) {
+               u32 tempval = in_be32(&ug_regs->maccfg2);
+               u32 upsmr = in_be32(&uf_regs->upsmr);
                /* Now we make sure that we can be in full duplex mode.
                 * If not, we operate in half-duplex mode. */
-               if (mii_info->duplex != ugeth->oldduplex) {
-                       if (!(mii_info->duplex)) {
-                               tempval = in_be32(&ug_regs->maccfg2);
+               if (phydev->duplex != ugeth->oldduplex) {
+                       new_state = 1;
+                       if (!(phydev->duplex))
                                tempval &= ~(MACCFG2_FDX);
-                               out_be32(&ug_regs->maccfg2, tempval);
-
-                               ugeth_info("%s: Half Duplex", dev->name);
-                       } else {
-                               tempval = in_be32(&ug_regs->maccfg2);
+                       else
                                tempval |= MACCFG2_FDX;
-                               out_be32(&ug_regs->maccfg2, tempval);
-
-                               ugeth_info("%s: Full Duplex", dev->name);
-                       }
-
-                       ugeth->oldduplex = mii_info->duplex;
+                       ugeth->oldduplex = phydev->duplex;
                }
 
-               if (mii_info->speed != ugeth->oldspeed) {
-                       switch (mii_info->speed) {
-                       case 1000:
-#ifdef CONFIG_MPC836x
-/* FIXME: This code is for 100Mbs BUG fixing,
-remove this when it is fixed!!! */
-                               if (ugeth->ug_info->enet_interface ==
-                                   ENET_1000_GMII)
-                               /* Run the commands which initialize the PHY */
-                               {
-                                       tempval =
-                                           (u32) mii_info->mdio_read(ugeth->
-                                               dev, mii_info->mii_id, 0x1b);
-                                       tempval |= 0x000f;
-                                       mii_info->mdio_write(ugeth->dev,
-                                               mii_info->mii_id, 0x1b,
-                                               (u16) tempval);
-                                       tempval =
-                                           (u32) mii_info->mdio_read(ugeth->
-                                               dev, mii_info->mii_id,
-                                               MII_BMCR);
-                                       mii_info->mdio_write(ugeth->dev,
-                                               mii_info->mii_id, MII_BMCR,
-                                               (u16) (tempval | BMCR_RESET));
-                               } else if (ugeth->ug_info->enet_interface ==
-                                          ENET_1000_RGMII)
-                               /* Run the commands which initialize the PHY */
-                               {
-                                       tempval =
-                                           (u32) mii_info->mdio_read(ugeth->
-                                               dev, mii_info->mii_id, 0x1b);
-                                       tempval = (tempval & ~0x000f) | 0x000b;
-                                       mii_info->mdio_write(ugeth->dev,
-                                               mii_info->mii_id, 0x1b,
-                                               (u16) tempval);
-                                       tempval =
-                                           (u32) mii_info->mdio_read(ugeth->
-                                               dev, mii_info->mii_id,
-                                               MII_BMCR);
-                                       mii_info->mdio_write(ugeth->dev,
-                                               mii_info->mii_id, MII_BMCR,
-                                               (u16) (tempval | BMCR_RESET));
-                               }
-                               msleep(4000);
-#endif                         /* CONFIG_MPC8360 */
-                               adjust_enet_interface(ugeth);
+               if (phydev->speed != ugeth->oldspeed) {
+                       new_state = 1;
+                       switch (phydev->speed) {
+                       case SPEED_1000:
+                               tempval = ((tempval &
+                                           ~(MACCFG2_INTERFACE_MODE_MASK)) |
+                                           MACCFG2_INTERFACE_MODE_BYTE);
                                break;
-                       case 100:
-                       case 10:
-#ifdef CONFIG_MPC836x
-/* FIXME: This code is for 100Mbs BUG fixing,
-remove this lines when it will be fixed!!! */
-                               ugeth->ug_info->enet_interface = ENET_100_RGMII;
-                               tempval =
-                                   (u32) mii_info->mdio_read(ugeth->dev,
-                                                             mii_info->mii_id,
-                                                             0x1b);
-                               tempval = (tempval & ~0x000f) | 0x000b;
-                               mii_info->mdio_write(ugeth->dev,
-                                                    mii_info->mii_id, 0x1b,
-                                                    (u16) tempval);
-                               tempval =
-                                   (u32) mii_info->mdio_read(ugeth->dev,
-                                                             mii_info->mii_id,
-                                                             MII_BMCR);
-                               mii_info->mdio_write(ugeth->dev,
-                                                    mii_info->mii_id, MII_BMCR,
-                                                    (u16) (tempval |
-                                                           BMCR_RESET));
-                               msleep(4000);
-#endif                         /* CONFIG_MPC8360 */
-                               adjust_enet_interface(ugeth);
+                       case SPEED_100:
+                       case SPEED_10:
+                               tempval = ((tempval &
+                                           ~(MACCFG2_INTERFACE_MODE_MASK)) |
+                                           MACCFG2_INTERFACE_MODE_NIBBLE);
+                               /* if reduced mode, re-set UPSMR.R10M */
+                               if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
+                                   (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
+                                   (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+                                   (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
+                                   (ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
+                                   (ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
+                                       if (phydev->speed == SPEED_10)
+                                               upsmr |= UCC_GETH_UPSMR_R10M;
+                                       else
+                                               upsmr &= ~UCC_GETH_UPSMR_R10M;
+                               }
                                break;
                        default:
-                               ugeth_warn
-                                   ("%s: Ack!  Speed (%d) is not 10/100/1000!",
-                                    dev->name, mii_info->speed);
+                               if (netif_msg_link(ugeth))
+                                       ugeth_warn(
+                                               "%s: Ack!  Speed (%d) is not 10/100/1000!",
+                                               dev->name, phydev->speed);
                                break;
                        }
-
-                       ugeth_info("%s: Speed %dBT", dev->name,
-                                  mii_info->speed);
-
-                       ugeth->oldspeed = mii_info->speed;
+                       ugeth->oldspeed = phydev->speed;
                }
 
+               out_be32(&ug_regs->maccfg2, tempval);
+               out_be32(&uf_regs->upsmr, upsmr);
+
                if (!ugeth->oldlink) {
-                       ugeth_info("%s: Link is up", dev->name);
+                       new_state = 1;
                        ugeth->oldlink = 1;
-                       netif_carrier_on(dev);
-                       netif_schedule(dev);
                }
-       } else {
-               if (ugeth->oldlink) {
-                       ugeth_info("%s: Link is down", dev->name);
+       } else if (ugeth->oldlink) {
+                       new_state = 1;
                        ugeth->oldlink = 0;
                        ugeth->oldspeed = 0;
                        ugeth->oldduplex = -1;
-                       netif_carrier_off(dev);
-               }
        }
+
+       if (new_state && netif_msg_link(ugeth))
+               phy_print_status(phydev);
+
+       spin_unlock_irqrestore(&ugeth->lock, flags);
 }
 
 /* Configure the PHY for dev.
@@ -1827,143 +1541,121 @@ remove this lines when it will be fixed!!! */
  */
 static int init_phy(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       struct phy_info *curphy;
-       ucc_mii_mng_t *mii_regs;
-       struct ugeth_mii_info *mii_info;
-       int err;
+       struct ucc_geth_private *priv = netdev_priv(dev);
+       struct ucc_geth_info *ug_info = priv->ug_info;
+       struct phy_device *phydev;
 
-       mii_regs = &ugeth->ug_regs->miimng;
+       priv->oldlink = 0;
+       priv->oldspeed = 0;
+       priv->oldduplex = -1;
 
-       ugeth->oldlink = 0;
-       ugeth->oldspeed = 0;
-       ugeth->oldduplex = -1;
-
-       mii_info = kmalloc(sizeof(struct ugeth_mii_info), GFP_KERNEL);
+       if (!ug_info->phy_node)
+               return 0;
 
-       if (NULL == mii_info) {
-               ugeth_err("%s: Could not allocate mii_info", dev->name);
-               return -ENOMEM;
+       phydev = of_phy_connect(dev, ug_info->phy_node, &adjust_link, 0,
+                               priv->phy_interface);
+       if (!phydev) {
+               printk("%s: Could not attach to PHY\n", dev->name);
+               return -ENODEV;
        }
 
-       mii_info->mii_regs = mii_regs;
-       mii_info->speed = SPEED_1000;
-       mii_info->duplex = DUPLEX_FULL;
-       mii_info->pause = 0;
-       mii_info->link = 0;
+       if (priv->phy_interface == PHY_INTERFACE_MODE_SGMII)
+               uec_configure_serdes(dev);
 
-       mii_info->advertising = (ADVERTISED_10baseT_Half |
+       phydev->supported &= (ADVERTISED_10baseT_Half |
                                 ADVERTISED_10baseT_Full |
                                 ADVERTISED_100baseT_Half |
-                                ADVERTISED_100baseT_Full |
-                                ADVERTISED_1000baseT_Full);
-       mii_info->autoneg = 1;
-
-       mii_info->mii_id = ugeth->ug_info->phy_address;
-
-       mii_info->dev = dev;
-
-       mii_info->mdio_read = &read_phy_reg;
-       mii_info->mdio_write = &write_phy_reg;
-
-       ugeth->mii_info = mii_info;
+                                ADVERTISED_100baseT_Full);
 
-       spin_lock_irq(&ugeth->lock);
-
-       /* Set this UCC to be the master of the MII managment */
-       ucc_set_qe_mux_mii_mng(ugeth->ug_info->uf_info.ucc_num);
-
-       if (init_mii_management_configuration(1,
-                                             ugeth->ug_info->
-                                             miiPreambleSupress,
-                                             &mii_regs->miimcfg,
-                                             &mii_regs->miimind)) {
-               ugeth_err("%s: The MII Bus is stuck!", dev->name);
-               err = -1;
-               goto bus_fail;
-       }
+       if (priv->max_speed == SPEED_1000)
+               phydev->supported |= ADVERTISED_1000baseT_Full;
 
-       spin_unlock_irq(&ugeth->lock);
+       phydev->advertising = phydev->supported;
 
-       /* get info for this PHY */
-       curphy = get_phy_info(ugeth->mii_info);
+       priv->phydev = phydev;
 
-       if (curphy == NULL) {
-               ugeth_err("%s: No PHY found", dev->name);
-               err = -1;
-               goto no_phy;
-       }
+       return 0;
+}
 
-       mii_info->phyinfo = curphy;
+/* Initialize TBI PHY interface for communicating with the
+ * SERDES lynx PHY on the chip.  We communicate with this PHY
+ * through the MDIO bus on each controller, treating it as a
+ * "normal" PHY at the address found in the UTBIPA register.  We assume
+ * that the UTBIPA register is valid.  Either the MDIO bus code will set
+ * it to a value that doesn't conflict with other PHYs on the bus, or the
+ * value doesn't matter, as there are no other PHYs on the bus.
+ */
+static void uec_configure_serdes(struct net_device *dev)
+{
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
 
-       /* Run the commands which initialize the PHY */
-       if (curphy->init) {
-               err = curphy->init(ugeth->mii_info);
-               if (err)
-                       goto phy_init_fail;
+       if (!ugeth->tbiphy) {
+               printk(KERN_WARNING "SGMII mode requires that the device "
+                       "tree specify a tbi-handle\n");
+       return;
        }
 
-       return 0;
+       /*
+        * If the link is already up, we must already be ok, and don't need to
+        * configure and reset the TBI<->SerDes link.  Maybe U-Boot configured
+        * everything for us?  Resetting it takes the link down and requires
+        * several seconds for it to come back.
+        */
+       if (phy_read(ugeth->tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS)
+               return;
 
-      phy_init_fail:
-      no_phy:
-      bus_fail:
-       kfree(mii_info);
+       /* Single clk mode, mii mode off(for serdes communication) */
+       phy_write(ugeth->tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS);
 
-       return err;
-}
+       phy_write(ugeth->tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);
 
-#ifdef CONFIG_UGETH_TX_ON_DEMOND
-static int ugeth_transmit_on_demand(ucc_geth_private_t *ugeth)
-{
-       ucc_fast_transmit_on_demand(ugeth->uccf);
+       phy_write(ugeth->tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS);
 
-       return 0;
 }
-#endif
 
-static int ugeth_graceful_stop_tx(ucc_geth_private_t *ugeth)
+static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        u32 cecr_subblock;
        u32 temp;
+       int i = 10;
 
        uccf = ugeth->uccf;
 
        /* Mask GRACEFUL STOP TX interrupt bit and clear it */
-       temp = in_be32(uccf->p_uccm);
-       temp &= ~UCCE_GRA;
-       out_be32(uccf->p_uccm, temp);
-       out_be32(uccf->p_ucce, UCCE_GRA);       /* clear by writing 1 */
+       clrbits32(uccf->p_uccm, UCC_GETH_UCCE_GRA);
+       out_be32(uccf->p_ucce, UCC_GETH_UCCE_GRA);  /* clear by writing 1 */
 
        /* Issue host command */
        cecr_subblock =
            ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
        qe_issue_cmd(QE_GRACEFUL_STOP_TX, cecr_subblock,
-                    (u8) QE_CR_PROTOCOL_ETHERNET, 0);
+                    QE_CR_PROTOCOL_ETHERNET, 0);
 
        /* Wait for command to complete */
        do {
+               msleep(10);
                temp = in_be32(uccf->p_ucce);
-       } while (!(temp & UCCE_GRA));
+       } while (!(temp & UCC_GETH_UCCE_GRA) && --i);
 
        uccf->stopped_tx = 1;
 
        return 0;
 }
 
-static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth)
+static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        u32 cecr_subblock;
        u8 temp;
+       int i = 10;
 
        uccf = ugeth->uccf;
 
        /* Clear acknowledge bit */
-       temp = ugeth->p_rx_glbl_pram->rxgstpack;
+       temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
        temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX;
-       ugeth->p_rx_glbl_pram->rxgstpack = temp;
+       out_8(&ugeth->p_rx_glbl_pram->rxgstpack, temp);
 
        /* Keep issuing command and checking acknowledge bit until
        it is asserted, according to spec */
@@ -1973,58 +1665,58 @@ static int ugeth_graceful_stop_rx(ucc_geth_private_t * ugeth)
                    ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.
                                                ucc_num);
                qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
-                            (u8) QE_CR_PROTOCOL_ETHERNET, 0);
-
-               temp = ugeth->p_rx_glbl_pram->rxgstpack;
-       } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX));
+                            QE_CR_PROTOCOL_ETHERNET, 0);
+               msleep(10);
+               temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
+       } while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX) && --i);
 
        uccf->stopped_rx = 1;
 
        return 0;
 }
 
-static int ugeth_restart_tx(ucc_geth_private_t *ugeth)
+static int ugeth_restart_tx(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        u32 cecr_subblock;
 
        uccf = ugeth->uccf;
 
        cecr_subblock =
            ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-       qe_issue_cmd(QE_RESTART_TX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
-                    0);
+       qe_issue_cmd(QE_RESTART_TX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET, 0);
        uccf->stopped_tx = 0;
 
        return 0;
 }
 
-static int ugeth_restart_rx(ucc_geth_private_t *ugeth)
+static int ugeth_restart_rx(struct ucc_geth_private *ugeth)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        u32 cecr_subblock;
 
        uccf = ugeth->uccf;
 
        cecr_subblock =
            ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-       qe_issue_cmd(QE_RESTART_RX, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
+       qe_issue_cmd(QE_RESTART_RX, cecr_subblock, QE_CR_PROTOCOL_ETHERNET,
                     0);
        uccf->stopped_rx = 0;
 
        return 0;
 }
 
-static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode)
+static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
        int enabled_tx, enabled_rx;
 
        uccf = ugeth->uccf;
 
        /* check if the UCC number is in range. */
        if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
-               ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: ucc_num out of range.", __func__);
                return -EINVAL;
        }
 
@@ -2044,15 +1736,16 @@ static int ugeth_enable(ucc_geth_private_t *ugeth, comm_dir_e mode)
 
 }
 
-static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode)
+static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode)
 {
-       ucc_fast_private_t *uccf;
+       struct ucc_fast_private *uccf;
 
        uccf = ugeth->uccf;
 
        /* check if the UCC number is in range. */
        if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
-               ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: ucc_num out of range.", __func__);
                return -EINVAL;
        }
 
@@ -2069,7 +1762,7 @@ static int ugeth_disable(ucc_geth_private_t * ugeth, comm_dir_e mode)
        return 0;
 }
 
-static void ugeth_dump_regs(ucc_geth_private_t *ugeth)
+static void ugeth_dump_regs(struct ucc_geth_private *ugeth)
 {
 #ifdef DEBUG
        ucc_fast_dump_regs(ugeth->uccf);
@@ -2078,215 +1771,25 @@ static void ugeth_dump_regs(ucc_geth_private_t *ugeth)
 #endif
 }
 
-#ifdef CONFIG_UGETH_FILTERING
-static int ugeth_ext_filtering_serialize_tad(ucc_geth_tad_params_t *
-                                            p_UccGethTadParams,
-                                            qe_fltr_tad_t *qe_fltr_tad)
-{
-       u16 temp;
-
-       /* Zero serialized TAD */
-       memset(qe_fltr_tad, 0, QE_FLTR_TAD_SIZE);
-
-       qe_fltr_tad->serialized[0] |= UCC_GETH_TAD_V;   /* Must have this */
-       if (p_UccGethTadParams->rx_non_dynamic_extended_features_mode ||
-           (p_UccGethTadParams->vtag_op != UCC_GETH_VLAN_OPERATION_TAGGED_NOP)
-           || (p_UccGethTadParams->vnontag_op !=
-               UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP)
-           )
-               qe_fltr_tad->serialized[0] |= UCC_GETH_TAD_EF;
-       if (p_UccGethTadParams->reject_frame)
-               qe_fltr_tad->serialized[0] |= UCC_GETH_TAD_REJ;
-       temp =
-           (u16) (((u16) p_UccGethTadParams->
-                   vtag_op) << UCC_GETH_TAD_VTAG_OP_SHIFT);
-       qe_fltr_tad->serialized[0] |= (u8) (temp >> 8); /* upper bits */
-
-       qe_fltr_tad->serialized[1] |= (u8) (temp & 0x00ff);     /* lower bits */
-       if (p_UccGethTadParams->vnontag_op ==
-           UCC_GETH_VLAN_OPERATION_NON_TAGGED_Q_TAG_INSERT)
-               qe_fltr_tad->serialized[1] |= UCC_GETH_TAD_V_NON_VTAG_OP;
-       qe_fltr_tad->serialized[1] |=
-           p_UccGethTadParams->rqos << UCC_GETH_TAD_RQOS_SHIFT;
-
-       qe_fltr_tad->serialized[2] |=
-           p_UccGethTadParams->vpri << UCC_GETH_TAD_V_PRIORITY_SHIFT;
-       /* upper bits */
-       qe_fltr_tad->serialized[2] |= (u8) (p_UccGethTadParams->vid >> 8);
-       /* lower bits */
-       qe_fltr_tad->serialized[3] |= (u8) (p_UccGethTadParams->vid & 0x00ff);
-
-       return 0;
-}
-
-static enet_addr_container_t
-    *ugeth_82xx_filtering_get_match_addr_in_hash(ucc_geth_private_t *ugeth,
-                                                enet_addr_t *p_enet_addr)
-{
-       enet_addr_container_t *enet_addr_cont;
-       struct list_head *p_lh;
-       u16 i, num;
-       int32_t j;
-       u8 *p_counter;
-
-       if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) {
-               p_lh = &ugeth->group_hash_q;
-               p_counter = &(ugeth->numGroupAddrInHash);
-       } else {
-               p_lh = &ugeth->ind_hash_q;
-               p_counter = &(ugeth->numIndAddrInHash);
-       }
-
-       if (!p_lh)
-               return NULL;
-
-       num = *p_counter;
-
-       for (i = 0; i < num; i++) {
-               enet_addr_cont =
-                   (enet_addr_container_t *)
-                   ENET_ADDR_CONT_ENTRY(dequeue(p_lh));
-               for (j = ENET_NUM_OCTETS_PER_ADDRESS - 1; j >= 0; j--) {
-                       if ((*p_enet_addr)[j] != (enet_addr_cont->address)[j])
-                               break;
-                       if (j == 0)
-                               return enet_addr_cont;  /* Found */
-               }
-               enqueue(p_lh, &enet_addr_cont->node);   /* Put it back */
-       }
-       return NULL;
-}
-
-static int ugeth_82xx_filtering_add_addr_in_hash(ucc_geth_private_t *ugeth,
-                                                enet_addr_t *p_enet_addr)
-{
-       ucc_geth_enet_address_recognition_location_e location;
-       enet_addr_container_t *enet_addr_cont;
-       struct list_head *p_lh;
-       u8 i;
-       u32 limit;
-       u8 *p_counter;
-
-       if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) {
-               p_lh = &ugeth->group_hash_q;
-               limit = ugeth->ug_info->maxGroupAddrInHash;
-               location =
-                   UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_GROUP_HASH;
-               p_counter = &(ugeth->numGroupAddrInHash);
-       } else {
-               p_lh = &ugeth->ind_hash_q;
-               limit = ugeth->ug_info->maxIndAddrInHash;
-               location =
-                   UCC_GETH_ENET_ADDRESS_RECOGNITION_LOCATION_INDIVIDUAL_HASH;
-               p_counter = &(ugeth->numIndAddrInHash);
-       }
-
-       if ((enet_addr_cont =
-            ugeth_82xx_filtering_get_match_addr_in_hash(ugeth, p_enet_addr))) {
-               list_add(p_lh, &enet_addr_cont->node);  /* Put it back */
-               return 0;
-       }
-       if ((!p_lh) || (!(*p_counter < limit)))
-               return -EBUSY;
-       if (!(enet_addr_cont = get_enet_addr_container()))
-               return -ENOMEM;
-       for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++)
-               (enet_addr_cont->address)[i] = (*p_enet_addr)[i];
-       enet_addr_cont->location = location;
-       enqueue(p_lh, &enet_addr_cont->node);   /* Put it back */
-       ++(*p_counter);
-
-       hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address));
-
-       return 0;
-}
-
-static int ugeth_82xx_filtering_clear_addr_in_hash(ucc_geth_private_t *ugeth,
-                                                  enet_addr_t *p_enet_addr)
-{
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-       enet_addr_container_t *enet_addr_cont;
-       ucc_fast_private_t *uccf;
-       comm_dir_e comm_dir;
-       u16 i, num;
-       struct list_head *p_lh;
-       u32 *addr_h, *addr_l;
-       u8 *p_counter;
-
-       uccf = ugeth->uccf;
-
-       p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
-           addressfiltering;
-
-       if (!
-           (enet_addr_cont =
-            ugeth_82xx_filtering_get_match_addr_in_hash(ugeth, p_enet_addr)))
-               return -ENOENT;
-
-       /* It's been found and removed from the CQ. */
-       /* Now destroy its container */
-       put_enet_addr_container(enet_addr_cont);
-
-       if ((*p_enet_addr)[0] & ENET_GROUP_ADDR) {
-               addr_h = &(p_82xx_addr_filt->gaddr_h);
-               addr_l = &(p_82xx_addr_filt->gaddr_l);
-               p_lh = &ugeth->group_hash_q;
-               p_counter = &(ugeth->numGroupAddrInHash);
-       } else {
-               addr_h = &(p_82xx_addr_filt->iaddr_h);
-               addr_l = &(p_82xx_addr_filt->iaddr_l);
-               p_lh = &ugeth->ind_hash_q;
-               p_counter = &(ugeth->numIndAddrInHash);
-       }
-
-       comm_dir = 0;
-       if (uccf->enabled_tx)
-               comm_dir |= COMM_DIR_TX;
-       if (uccf->enabled_rx)
-               comm_dir |= COMM_DIR_RX;
-       if (comm_dir)
-               ugeth_disable(ugeth, comm_dir);
-
-       /* Clear the hash table. */
-       out_be32(addr_h, 0x00000000);
-       out_be32(addr_l, 0x00000000);
-
-       /* Add all remaining CQ elements back into hash */
-       num = --(*p_counter);
-       for (i = 0; i < num; i++) {
-               enet_addr_cont =
-                   (enet_addr_container_t *)
-                   ENET_ADDR_CONT_ENTRY(dequeue(p_lh));
-               hw_add_addr_in_hash(ugeth, &(enet_addr_cont->address));
-               enqueue(p_lh, &enet_addr_cont->node);   /* Put it back */
-       }
-
-       if (comm_dir)
-               ugeth_enable(ugeth, comm_dir);
-
-       return 0;
-}
-#endif /* CONFIG_UGETH_FILTERING */
-
-static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t *
+static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private *
                                                       ugeth,
-                                                      enet_addr_type_e
+                                                      enum enet_addr_type
                                                       enet_addr_type)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-       ucc_fast_private_t *uccf;
-       comm_dir_e comm_dir;
+       struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
+       struct ucc_fast_private *uccf;
+       enum comm_dir comm_dir;
        struct list_head *p_lh;
        u16 i, num;
-       u32 *addr_h, *addr_l;
+       u32 __iomem *addr_h;
+       u32 __iomem *addr_l;
        u8 *p_counter;
 
        uccf = ugeth->uccf;
 
        p_82xx_addr_filt =
-           (ucc_geth_82xx_address_filtering_pram_t *) ugeth->p_rx_glbl_pram->
-           addressfiltering;
+           (struct ucc_geth_82xx_address_filtering_pram __iomem *)
+           ugeth->p_rx_glbl_pram->addressfiltering;
 
        if (enet_addr_type == ENET_ADDR_TYPE_GROUP) {
                addr_h = &(p_82xx_addr_filt->gaddr_h);
@@ -2330,45 +1833,25 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(ucc_geth_private_t *
        return 0;
 }
 
-#ifdef CONFIG_UGETH_FILTERING
-static int ugeth_82xx_filtering_add_addr_in_paddr(ucc_geth_private_t *ugeth,
-                                                 enet_addr_t *p_enet_addr,
-                                                 u8 paddr_num)
-{
-       int i;
-
-       if ((*p_enet_addr)[0] & ENET_GROUP_ADDR)
-               ugeth_warn
-                   ("%s: multicast address added to paddr will have no "
-                    "effect - is this what you wanted?",
-                    __FUNCTION__);
-
-       ugeth->indAddrRegUsed[paddr_num] = 1;   /* mark this paddr as used */
-       /* store address in our database */
-       for (i = 0; i < ENET_NUM_OCTETS_PER_ADDRESS; i++)
-               ugeth->paddr[paddr_num][i] = (*p_enet_addr)[i];
-       /* put in hardware */
-       return hw_add_addr_in_paddr(ugeth, p_enet_addr, paddr_num);
-}
-#endif /* CONFIG_UGETH_FILTERING */
-
-static int ugeth_82xx_filtering_clear_addr_in_paddr(ucc_geth_private_t *ugeth,
+static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *ugeth,
                                                    u8 paddr_num)
 {
        ugeth->indAddrRegUsed[paddr_num] = 0; /* mark this paddr as not used */
        return hw_clear_addr_in_paddr(ugeth, paddr_num);/* clear in hardware */
 }
 
-static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
+static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
 {
        u16 i, j;
-       u8 *bd;
+       u8 __iomem *bd;
 
        if (!ugeth)
                return;
 
-       if (ugeth->uccf)
+       if (ugeth->uccf) {
                ucc_fast_free(ugeth->uccf);
+               ugeth->uccf = NULL;
+       }
 
        if (ugeth->p_thread_data_tx) {
                qe_muram_free(ugeth->thread_dat_tx_offset);
@@ -2430,11 +1913,13 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
        }
        for (i = 0; i < ugeth->ug_info->numQueuesTx; i++) {
                bd = ugeth->p_tx_bd_ring[i];
+               if (!bd)
+                       continue;
                for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
                        if (ugeth->tx_skbuff[i][j]) {
-                               dma_unmap_single(NULL,
-                                                BD_BUFFER_ARG(bd),
-                                                (BD_STATUS_AND_LENGTH(bd) &
+                               dma_unmap_single(ugeth->dev,
+                                                in_be32(&((struct qe_bd __iomem *)bd)->buf),
+                                                (in_be32((u32 __iomem *)bd) &
                                                  BD_LENGTH_MASK),
                                                 DMA_TO_DEVICE);
                                dev_kfree_skb_any(ugeth->tx_skbuff[i][j]);
@@ -2460,18 +1945,17 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
                        bd = ugeth->p_rx_bd_ring[i];
                        for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) {
                                if (ugeth->rx_skbuff[i][j]) {
-                                       dma_unmap_single(NULL, BD_BUFFER(bd),
-                                                ugeth->ug_info->
-                                                uf_info.
-                                                max_rx_buf_length +
-                                                UCC_GETH_RX_DATA_BUF_ALIGNMENT,
-                                                DMA_FROM_DEVICE);
-
-                                       dev_kfree_skb_any(ugeth->
-                                                         rx_skbuff[i][j]);
+                                       dma_unmap_single(ugeth->dev,
+                                               in_be32(&((struct qe_bd __iomem *)bd)->buf),
+                                               ugeth->ug_info->
+                                               uf_info.max_rx_buf_length +
+                                               UCC_GETH_RX_DATA_BUF_ALIGNMENT,
+                                               DMA_FROM_DEVICE);
+                                       dev_kfree_skb_any(
+                                               ugeth->rx_skbuff[i][j]);
                                        ugeth->rx_skbuff[i][j] = NULL;
                                }
-                               bd += UCC_GETH_SIZE_OF_BD;
+                               bd += sizeof(struct qe_bd);
                        }
 
                        kfree(ugeth->rx_skbuff[i]);
@@ -2491,33 +1975,31 @@ static void ucc_geth_memclean(ucc_geth_private_t *ugeth)
        while (!list_empty(&ugeth->ind_hash_q))
                put_enet_addr_container(ENET_ADDR_CONT_ENTRY
                                        (dequeue(&ugeth->ind_hash_q)));
-
+       if (ugeth->ug_regs) {
+               iounmap(ugeth->ug_regs);
+               ugeth->ug_regs = NULL;
+       }
 }
 
 static void ucc_geth_set_multi(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth;
+       struct ucc_geth_private *ugeth;
        struct dev_mc_list *dmi;
-       ucc_fast_t *uf_regs;
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-       enet_addr_t tempaddr;
-       u8 *mcptr, *tdptr;
-       int i, j;
+       struct ucc_fast __iomem *uf_regs;
+       struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
+       int i;
 
        ugeth = netdev_priv(dev);
 
        uf_regs = ugeth->uccf->uf_regs;
 
        if (dev->flags & IFF_PROMISC) {
-
-               uf_regs->upsmr |= UPSMR_PRO;
-
+               setbits32(&uf_regs->upsmr, UCC_GETH_UPSMR_PRO);
        } else {
-
-               uf_regs->upsmr &= ~UPSMR_PRO;
+               clrbits32(&uf_regs->upsmr, UCC_GETH_UPSMR_PRO);
 
                p_82xx_addr_filt =
-                   (ucc_geth_82xx_address_filtering_pram_t *) ugeth->
+                   (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->
                    p_rx_glbl_pram->addressfiltering;
 
                if (dev->flags & IFF_ALLMULTI) {
@@ -2541,97 +2023,57 @@ static void ucc_geth_set_multi(struct net_device *dev)
                                if (!(dmi->dmi_addr[0] & 1))
                                        continue;
 
-                               /* The address in dmi_addr is LSB first,
-                                * and taddr is MSB first.  We have to
-                                * copy bytes MSB first from dmi_addr.
-                                */
-                               mcptr = (u8 *) dmi->dmi_addr + 5;
-                               tdptr = (u8 *) & tempaddr;
-                               for (j = 0; j < 6; j++)
-                                       *tdptr++ = *mcptr--;
-
                                /* Ask CPM to run CRC and set bit in
                                 * filter mask.
                                 */
-                               hw_add_addr_in_hash(ugeth, &tempaddr);
-
+                               hw_add_addr_in_hash(ugeth, dmi->dmi_addr);
                        }
                }
        }
 }
 
-static void ucc_geth_stop(ucc_geth_private_t *ugeth)
+static void ucc_geth_stop(struct ucc_geth_private *ugeth)
 {
-       ucc_geth_t *ug_regs = ugeth->ug_regs;
-       u32 tempval;
+       struct ucc_geth __iomem *ug_regs = ugeth->ug_regs;
+       struct phy_device *phydev = ugeth->phydev;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        /* Disable the controller */
        ugeth_disable(ugeth, COMM_DIR_RX_AND_TX);
 
        /* Tell the kernel the link is down */
-       ugeth->mii_info->link = 0;
-       adjust_link(ugeth->dev);
+       phy_stop(phydev);
 
        /* Mask all interrupts */
-       out_be32(ugeth->uccf->p_ucce, 0x00000000);
+       out_be32(ugeth->uccf->p_uccm, 0x00000000);
 
        /* Clear all interrupts */
        out_be32(ugeth->uccf->p_ucce, 0xffffffff);
 
        /* Disable Rx and Tx */
-       tempval = in_be32(&ug_regs->maccfg1);
-       tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
-       out_be32(&ug_regs->maccfg1, tempval);
-
-       if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
-               /* Clear any pending interrupts */
-               mii_clear_phy_interrupt(ugeth->mii_info);
-
-               /* Disable PHY Interrupts */
-               mii_configure_phy_interrupt(ugeth->mii_info,
-                                           MII_INTERRUPT_DISABLED);
-       }
+       clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
 
-       free_irq(ugeth->ug_info->uf_info.irq, ugeth->dev);
-
-       if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
-               free_irq(ugeth->ug_info->phy_interrupt, ugeth->dev);
-       } else {
-               del_timer_sync(&ugeth->phy_info_timer);
-       }
+       phy_disconnect(ugeth->phydev);
+       ugeth->phydev = NULL;
 
        ucc_geth_memclean(ugeth);
 }
 
-static int ucc_geth_startup(ucc_geth_private_t *ugeth)
+static int ucc_struct_init(struct ucc_geth_private *ugeth)
 {
-       ucc_geth_82xx_address_filtering_pram_t *p_82xx_addr_filt;
-       ucc_geth_init_pram_t *p_init_enet_pram;
-       ucc_fast_private_t *uccf;
-       ucc_geth_info_t *ug_info;
-       ucc_fast_info_t *uf_info;
-       ucc_fast_t *uf_regs;
-       ucc_geth_t *ug_regs;
-       int ret_val = -EINVAL;
-       u32 remoder = UCC_GETH_REMODER_INIT;
-       u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
-       u32 ifstat, i, j, size, l2qt, l3qt, length;
-       u16 temoder = UCC_GETH_TEMODER_INIT;
-       u16 test;
-       u8 function_code = 0;
-       u8 *bd, *endOfRing;
-       u8 numThreadsRxNumerical, numThreadsTxNumerical;
-
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       struct ucc_geth_info *ug_info;
+       struct ucc_fast_info *uf_info;
+       int i;
 
        ug_info = ugeth->ug_info;
        uf_info = &ug_info->uf_info;
 
        if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
              (uf_info->bd_mem_part == MEM_PART_MURAM))) {
-               ugeth_err("%s: Bad memory partition value.", __FUNCTION__);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: Bad memory partition value.",
+                                       __func__);
                return -EINVAL;
        }
 
@@ -2640,9 +2082,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                if ((ug_info->bdRingLenRx[i] < UCC_GETH_RX_BD_RING_SIZE_MIN) ||
                    (ug_info->bdRingLenRx[i] %
                     UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT)) {
-                       ugeth_err
-                           ("%s: Rx BD ring length must be multiple of 4,"
-                               " no smaller than 8.", __FUNCTION__);
+                       if (netif_msg_probe(ugeth))
+                               ugeth_err
+                                   ("%s: Rx BD ring length must be multiple of 4, no smaller than 8.",
+                                       __func__);
                        return -EINVAL;
                }
        }
@@ -2650,9 +2093,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Tx BD lengths */
        for (i = 0; i < ug_info->numQueuesTx; i++) {
                if (ug_info->bdRingLenTx[i] < UCC_GETH_TX_BD_RING_SIZE_MIN) {
-                       ugeth_err
-                           ("%s: Tx BD ring length must be no smaller than 2.",
-                            __FUNCTION__);
+                       if (netif_msg_probe(ugeth))
+                               ugeth_err
+                                   ("%s: Tx BD ring length must be no smaller than 2.",
+                                    __func__);
                        return -EINVAL;
                }
        }
@@ -2660,31 +2104,35 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* mrblr */
        if ((uf_info->max_rx_buf_length == 0) ||
            (uf_info->max_rx_buf_length % UCC_GETH_MRBLR_ALIGNMENT)) {
-               ugeth_err
-                   ("%s: max_rx_buf_length must be non-zero multiple of 128.",
-                    __FUNCTION__);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err
+                           ("%s: max_rx_buf_length must be non-zero multiple of 128.",
+                            __func__);
                return -EINVAL;
        }
 
        /* num Tx queues */
        if (ug_info->numQueuesTx > NUM_TX_QUEUES) {
-               ugeth_err("%s: number of tx queues too large.", __FUNCTION__);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: number of tx queues too large.", __func__);
                return -EINVAL;
        }
 
        /* num Rx queues */
        if (ug_info->numQueuesRx > NUM_RX_QUEUES) {
-               ugeth_err("%s: number of rx queues too large.", __FUNCTION__);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: number of rx queues too large.", __func__);
                return -EINVAL;
        }
 
        /* l2qt */
        for (i = 0; i < UCC_GETH_VLAN_PRIORITY_MAX; i++) {
                if (ug_info->l2qt[i] >= ug_info->numQueuesRx) {
-                       ugeth_err
-                           ("%s: VLAN priority table entry must not be"
-                               " larger than number of Rx queues.",
-                            __FUNCTION__);
+                       if (netif_msg_probe(ugeth))
+                               ugeth_err
+                                   ("%s: VLAN priority table entry must not be"
+                                       " larger than number of Rx queues.",
+                                    __func__);
                        return -EINVAL;
                }
        }
@@ -2692,43 +2140,90 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* l3qt */
        for (i = 0; i < UCC_GETH_IP_PRIORITY_MAX; i++) {
                if (ug_info->l3qt[i] >= ug_info->numQueuesRx) {
-                       ugeth_err
-                           ("%s: IP priority table entry must not be"
-                               " larger than number of Rx queues.",
-                            __FUNCTION__);
+                       if (netif_msg_probe(ugeth))
+                               ugeth_err
+                                   ("%s: IP priority table entry must not be"
+                                       " larger than number of Rx queues.",
+                                    __func__);
                        return -EINVAL;
                }
        }
 
        if (ug_info->cam && !ug_info->ecamptr) {
-               ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
-                         __FUNCTION__);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
+                                 __func__);
                return -EINVAL;
        }
 
        if ((ug_info->numStationAddresses !=
             UCC_GETH_NUM_OF_STATION_ADDRESSES_1)
            && ug_info->rxExtendedFiltering) {
-               ugeth_err("%s: Number of station addresses greater than 1 "
-                         "not allowed in extended parsing mode.",
-                         __FUNCTION__);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: Number of station addresses greater than 1 "
+                                 "not allowed in extended parsing mode.",
+                                 __func__);
                return -EINVAL;
        }
 
        /* Generate uccm_mask for receive */
        uf_info->uccm_mask = ug_info->eventRegMask & UCCE_OTHER;/* Errors */
        for (i = 0; i < ug_info->numQueuesRx; i++)
-               uf_info->uccm_mask |= (UCCE_RXBF_SINGLE_MASK << i);
+               uf_info->uccm_mask |= (UCC_GETH_UCCE_RXF0 << i);
 
        for (i = 0; i < ug_info->numQueuesTx; i++)
-               uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i);
+               uf_info->uccm_mask |= (UCC_GETH_UCCE_TXB0 << i);
        /* Initialize the general fast UCC block. */
-       if (ucc_fast_init(uf_info, &uccf)) {
-               ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+       if (ucc_fast_init(uf_info, &ugeth->uccf)) {
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: Failed to init uccf.", __func__);
+               return -ENOMEM;
+       }
+
+       /* read the number of risc engines, update the riscTx and riscRx
+        * if there are 4 riscs in QE
+        */
+       if (qe_get_num_of_risc() == 4) {
+               ug_info->riscTx = QE_RISC_ALLOCATION_FOUR_RISCS;
+               ug_info->riscRx = QE_RISC_ALLOCATION_FOUR_RISCS;
+       }
+
+       ugeth->ug_regs = ioremap(uf_info->regs, sizeof(*ugeth->ug_regs));
+       if (!ugeth->ug_regs) {
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: Failed to ioremap regs.", __func__);
                return -ENOMEM;
        }
-       ugeth->uccf = uccf;
+
+       return 0;
+}
+
+static int ucc_geth_startup(struct ucc_geth_private *ugeth)
+{
+       struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
+       struct ucc_geth_init_pram __iomem *p_init_enet_pram;
+       struct ucc_fast_private *uccf;
+       struct ucc_geth_info *ug_info;
+       struct ucc_fast_info *uf_info;
+       struct ucc_fast __iomem *uf_regs;
+       struct ucc_geth __iomem *ug_regs;
+       int ret_val = -EINVAL;
+       u32 remoder = UCC_GETH_REMODER_INIT;
+       u32 init_enet_pram_offset, cecr_subblock, command;
+       u32 ifstat, i, j, size, l2qt, l3qt, length;
+       u16 temoder = UCC_GETH_TEMODER_INIT;
+       u16 test;
+       u8 function_code = 0;
+       u8 __iomem *bd;
+       u8 __iomem *endOfRing;
+       u8 numThreadsRxNumerical, numThreadsTxNumerical;
+
+       ugeth_vdbg("%s: IN", __func__);
+       uccf = ugeth->uccf;
+       ug_info = ugeth->ug_info;
+       uf_info = &ug_info->uf_info;
+       uf_regs = uccf->uf_regs;
+       ug_regs = ugeth->ug_regs;
 
        switch (ug_info->numThreadsRx) {
        case UCC_GETH_NUM_OF_THREADS_1:
@@ -2747,8 +2242,9 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                numThreadsRxNumerical = 8;
                break;
        default:
-               ugeth_err("%s: Bad number of Rx threads value.", __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Bad number of Rx threads value.",
+                                       __func__);
                return -EINVAL;
                break;
        }
@@ -2770,8 +2266,9 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                numThreadsTxNumerical = 8;
                break;
        default:
-               ugeth_err("%s: Bad number of Tx threads value.", __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Bad number of Tx threads value.",
+                                       __func__);
                return -EINVAL;
                break;
        }
@@ -2787,10 +2284,6 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
            || (ug_info->vlanOperationNonTagged !=
                UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP);
 
-       uf_regs = uccf->uf_regs;
-       ug_regs = (ucc_geth_t *) (uccf->uf_regs);
-       ugeth->ug_regs = ug_regs;
-
        init_default_reg_vals(&uf_regs->upsmr,
                              &ug_regs->maccfg1, &ug_regs->maccfg2);
 
@@ -2806,16 +2299,13 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* For more details see the hardware spec.           */
        init_flow_control_params(ug_info->aufc,
                                 ug_info->receiveFlowControl,
-                                1,
+                                ug_info->transmitFlowControl,
                                 ug_info->pausePeriod,
                                 ug_info->extensionField,
                                 &uf_regs->upsmr,
                                 &ug_regs->uempr, &ug_regs->maccfg1);
 
-       maccfg1 = in_be32(&ug_regs->maccfg1);
-       maccfg1 |= MACCFG1_ENABLE_RX;
-       maccfg1 |= MACCFG1_ENABLE_TX;
-       out_be32(&ug_regs->maccfg1, maccfg1);
+       setbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
 
        /*                    Set IPGIFG                     */
        /* For more details see the hardware spec.           */
@@ -2826,9 +2316,9 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                                              ug_info->backToBackInterFrameGap,
                                              &ug_regs->ipgifg);
        if (ret_val != 0) {
-               ugeth_err("%s: IPGIFG initialization parameter too large.",
-                         __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: IPGIFG initialization parameter too large.",
+                                 __func__);
                return ret_val;
        }
 
@@ -2843,9 +2333,9 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                                          ug_info->collisionWindow,
                                          &ug_regs->hafdup);
        if (ret_val != 0) {
-               ugeth_err("%s: Half Duplex initialization parameter too large.",
-                         __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Half Duplex initialization parameter too large.",
+                         __func__);
                return ret_val;
        }
 
@@ -2869,10 +2359,10 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                /* Allocate in multiple of
                   UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT,
                   according to spec */
-               length = ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD)
+               length = ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd))
                          / UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
                    * UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
-               if ((ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD) %
+               if ((ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)) %
                    UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT)
                        length += UCC_GETH_TX_BD_RING_SIZE_MEMORY_ALIGNMENT;
                if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
@@ -2880,61 +2370,61 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                        if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4)
                                align = UCC_GETH_TX_BD_RING_ALIGNMENT;
                        ugeth->tx_bd_ring_offset[j] =
-                               (u32) (kmalloc((u32) (length + align),
-                               GFP_KERNEL));
+                               (u32) kmalloc((u32) (length + align), GFP_KERNEL);
+
                        if (ugeth->tx_bd_ring_offset[j] != 0)
                                ugeth->p_tx_bd_ring[j] =
-                                       (void*)((ugeth->tx_bd_ring_offset[j] +
+                                       (u8 __iomem *)((ugeth->tx_bd_ring_offset[j] +
                                        align) & ~(align - 1));
                } else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
                        ugeth->tx_bd_ring_offset[j] =
                            qe_muram_alloc(length,
                                           UCC_GETH_TX_BD_RING_ALIGNMENT);
-                       if (!IS_MURAM_ERR(ugeth->tx_bd_ring_offset[j]))
+                       if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j]))
                                ugeth->p_tx_bd_ring[j] =
-                                   (u8 *) qe_muram_addr(ugeth->
+                                   (u8 __iomem *) qe_muram_addr(ugeth->
                                                         tx_bd_ring_offset[j]);
                }
                if (!ugeth->p_tx_bd_ring[j]) {
-                       ugeth_err
-                           ("%s: Can not allocate memory for Tx bd rings.",
-                            __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err
+                                   ("%s: Can not allocate memory for Tx bd rings.",
+                                    __func__);
                        return -ENOMEM;
                }
                /* Zero unused end of bd ring, according to spec */
-               memset(ugeth->p_tx_bd_ring[j] +
-                      ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD, 0,
-                      length - ug_info->bdRingLenTx[j] * UCC_GETH_SIZE_OF_BD);
+               memset_io((void __iomem *)(ugeth->p_tx_bd_ring[j] +
+                      ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)), 0,
+                      length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd));
        }
 
        /* Allocate Rx bds */
        for (j = 0; j < ug_info->numQueuesRx; j++) {
-               length = ug_info->bdRingLenRx[j] * UCC_GETH_SIZE_OF_BD;
+               length = ug_info->bdRingLenRx[j] * sizeof(struct qe_bd);
                if (uf_info->bd_mem_part == MEM_PART_SYSTEM) {
                        u32 align = 4;
                        if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4)
                                align = UCC_GETH_RX_BD_RING_ALIGNMENT;
                        ugeth->rx_bd_ring_offset[j] =
-                           (u32) (kmalloc((u32) (length + align), GFP_KERNEL));
+                               (u32) kmalloc((u32) (length + align), GFP_KERNEL);
                        if (ugeth->rx_bd_ring_offset[j] != 0)
                                ugeth->p_rx_bd_ring[j] =
-                                       (void*)((ugeth->rx_bd_ring_offset[j] +
+                                       (u8 __iomem *)((ugeth->rx_bd_ring_offset[j] +
                                        align) & ~(align - 1));
                } else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
                        ugeth->rx_bd_ring_offset[j] =
                            qe_muram_alloc(length,
                                           UCC_GETH_RX_BD_RING_ALIGNMENT);
-                       if (!IS_MURAM_ERR(ugeth->rx_bd_ring_offset[j]))
+                       if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j]))
                                ugeth->p_rx_bd_ring[j] =
-                                   (u8 *) qe_muram_addr(ugeth->
+                                   (u8 __iomem *) qe_muram_addr(ugeth->
                                                         rx_bd_ring_offset[j]);
                }
                if (!ugeth->p_rx_bd_ring[j]) {
-                       ugeth_err
-                           ("%s: Can not allocate memory for Rx bd rings.",
-                            __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err
+                                   ("%s: Can not allocate memory for Rx bd rings.",
+                                    __func__);
                        return -ENOMEM;
                }
        }
@@ -2942,15 +2432,14 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Init Tx bds */
        for (j = 0; j < ug_info->numQueuesTx; j++) {
                /* Setup the skbuff rings */
-               ugeth->tx_skbuff[j] =
-                   (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) *
-                                              ugeth->ug_info->bdRingLenTx[j],
-                                              GFP_KERNEL);
+               ugeth->tx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) *
+                                             ugeth->ug_info->bdRingLenTx[j],
+                                             GFP_KERNEL);
 
                if (ugeth->tx_skbuff[j] == NULL) {
-                       ugeth_err("%s: Could not allocate tx_skbuff",
-                                 __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err("%s: Could not allocate tx_skbuff",
+                                         __func__);
                        return -ENOMEM;
                }
 
@@ -2960,26 +2449,28 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                ugeth->skb_curtx[j] = ugeth->skb_dirtytx[j] = 0;
                bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j];
                for (i = 0; i < ug_info->bdRingLenTx[j]; i++) {
-                       BD_BUFFER_CLEAR(bd);
-                       BD_STATUS_AND_LENGTH_SET(bd, 0);
-                       bd += UCC_GETH_SIZE_OF_BD;
+                       /* clear bd buffer */
+                       out_be32(&((struct qe_bd __iomem *)bd)->buf, 0);
+                       /* set bd status and length */
+                       out_be32((u32 __iomem *)bd, 0);
+                       bd += sizeof(struct qe_bd);
                }
-               bd -= UCC_GETH_SIZE_OF_BD;
-               BD_STATUS_AND_LENGTH_SET(bd, T_W);/* for last BD set Wrap bit */
+               bd -= sizeof(struct qe_bd);
+               /* set bd status and length */
+               out_be32((u32 __iomem *)bd, T_W); /* for last BD set Wrap bit */
        }
 
        /* Init Rx bds */
        for (j = 0; j < ug_info->numQueuesRx; j++) {
                /* Setup the skbuff rings */
-               ugeth->rx_skbuff[j] =
-                   (struct sk_buff **)kmalloc(sizeof(struct sk_buff *) *
-                                              ugeth->ug_info->bdRingLenRx[j],
-                                              GFP_KERNEL);
+               ugeth->rx_skbuff[j] = kmalloc(sizeof(struct sk_buff *) *
+                                             ugeth->ug_info->bdRingLenRx[j],
+                                             GFP_KERNEL);
 
                if (ugeth->rx_skbuff[j] == NULL) {
-                       ugeth_err("%s: Could not allocate rx_skbuff",
-                                 __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err("%s: Could not allocate rx_skbuff",
+                                         __func__);
                        return -ENOMEM;
                }
 
@@ -2989,12 +2480,15 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                ugeth->skb_currx[j] = 0;
                bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j];
                for (i = 0; i < ug_info->bdRingLenRx[j]; i++) {
-                       BD_STATUS_AND_LENGTH_SET(bd, R_I);
-                       BD_BUFFER_CLEAR(bd);
-                       bd += UCC_GETH_SIZE_OF_BD;
+                       /* set bd status and length */
+                       out_be32((u32 __iomem *)bd, R_I);
+                       /* clear bd buffer */
+                       out_be32(&((struct qe_bd __iomem *)bd)->buf, 0);
+                       bd += sizeof(struct qe_bd);
                }
-               bd -= UCC_GETH_SIZE_OF_BD;
-               BD_STATUS_AND_LENGTH_SET(bd, R_W);/* for last BD set Wrap bit */
+               bd -= sizeof(struct qe_bd);
+               /* set bd status and length */
+               out_be32((u32 __iomem *)bd, R_W); /* for last BD set Wrap bit */
        }
 
        /*
@@ -3003,20 +2497,20 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Tx global PRAM */
        /* Allocate global tx parameter RAM page */
        ugeth->tx_glbl_pram_offset =
-           qe_muram_alloc(sizeof(ucc_geth_tx_global_pram_t),
+           qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram),
                           UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT);
-       if (IS_MURAM_ERR(ugeth->tx_glbl_pram_offset)) {
-               ugeth_err
-                   ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
-                    __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+       if (IS_ERR_VALUE(ugeth->tx_glbl_pram_offset)) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err
+                           ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
+                            __func__);
                return -ENOMEM;
        }
        ugeth->p_tx_glbl_pram =
-           (ucc_geth_tx_global_pram_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_tx_global_pram __iomem *) qe_muram_addr(ugeth->
                                                        tx_glbl_pram_offset);
        /* Zero out p_tx_glbl_pram */
-       memset(ugeth->p_tx_glbl_pram, 0, sizeof(ucc_geth_tx_global_pram_t));
+       memset_io((void __iomem *)ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram));
 
        /* Fill global PRAM */
 
@@ -3024,19 +2518,19 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Size varies with number of Tx threads */
        ugeth->thread_dat_tx_offset =
            qe_muram_alloc(numThreadsTxNumerical *
-                          sizeof(ucc_geth_thread_data_tx_t) +
+                          sizeof(struct ucc_geth_thread_data_tx) +
                           32 * (numThreadsTxNumerical == 1),
                           UCC_GETH_THREAD_DATA_ALIGNMENT);
-       if (IS_MURAM_ERR(ugeth->thread_dat_tx_offset)) {
-               ugeth_err
-                   ("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
-                    __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+       if (IS_ERR_VALUE(ugeth->thread_dat_tx_offset)) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err
+                           ("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
+                            __func__);
                return -ENOMEM;
        }
 
        ugeth->p_thread_data_tx =
-           (ucc_geth_thread_data_tx_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_thread_data_tx __iomem *) qe_muram_addr(ugeth->
                                                        thread_dat_tx_offset);
        out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset);
 
@@ -3047,24 +2541,25 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
 
        /* iphoffset */
        for (i = 0; i < TX_IP_OFFSET_ENTRY_MAX; i++)
-               ugeth->p_tx_glbl_pram->iphoffset[i] = ug_info->iphoffset[i];
+               out_8(&ugeth->p_tx_glbl_pram->iphoffset[i],
+                               ug_info->iphoffset[i]);
 
        /* SQPTR */
        /* Size varies with number of Tx queues */
        ugeth->send_q_mem_reg_offset =
            qe_muram_alloc(ug_info->numQueuesTx *
-                          sizeof(ucc_geth_send_queue_qd_t),
+                          sizeof(struct ucc_geth_send_queue_qd),
                           UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT);
-       if (IS_MURAM_ERR(ugeth->send_q_mem_reg_offset)) {
-               ugeth_err
-                   ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
-                    __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+       if (IS_ERR_VALUE(ugeth->send_q_mem_reg_offset)) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err
+                           ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
+                            __func__);
                return -ENOMEM;
        }
 
        ugeth->p_send_q_mem_reg =
-           (ucc_geth_send_queue_mem_region_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_send_queue_mem_region __iomem *) qe_muram_addr(ugeth->
                        send_q_mem_reg_offset);
        out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset);
 
@@ -3073,7 +2568,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        for (i = 0; i < ug_info->numQueuesTx; i++) {
                endOfRing =
                    ugeth->p_tx_bd_ring[i] + (ug_info->bdRingLenTx[i] -
-                                             1) * UCC_GETH_SIZE_OF_BD;
+                                             1) * sizeof(struct qe_bd);
                if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_SYSTEM) {
                        out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base,
                                 (u32) virt_to_phys(ugeth->p_tx_bd_ring[i]));
@@ -3096,36 +2591,37 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        if (ug_info->numQueuesTx > 1) {
        /* scheduler exists only if more than 1 tx queue */
                ugeth->scheduler_offset =
-                   qe_muram_alloc(sizeof(ucc_geth_scheduler_t),
+                   qe_muram_alloc(sizeof(struct ucc_geth_scheduler),
                                   UCC_GETH_SCHEDULER_ALIGNMENT);
-               if (IS_MURAM_ERR(ugeth->scheduler_offset)) {
-                       ugeth_err
-                        ("%s: Can not allocate DPRAM memory for p_scheduler.",
-                            __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+               if (IS_ERR_VALUE(ugeth->scheduler_offset)) {
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err
+                                ("%s: Can not allocate DPRAM memory for p_scheduler.",
+                                    __func__);
                        return -ENOMEM;
                }
 
                ugeth->p_scheduler =
-                   (ucc_geth_scheduler_t *) qe_muram_addr(ugeth->
+                   (struct ucc_geth_scheduler __iomem *) qe_muram_addr(ugeth->
                                                           scheduler_offset);
                out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer,
                         ugeth->scheduler_offset);
                /* Zero out p_scheduler */
-               memset(ugeth->p_scheduler, 0, sizeof(ucc_geth_scheduler_t));
+               memset_io((void __iomem *)ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler));
 
                /* Set values in scheduler */
                out_be32(&ugeth->p_scheduler->mblinterval,
                         ug_info->mblinterval);
                out_be16(&ugeth->p_scheduler->nortsrbytetime,
                         ug_info->nortsrbytetime);
-               ugeth->p_scheduler->fracsiz = ug_info->fracsiz;
-               ugeth->p_scheduler->strictpriorityq = ug_info->strictpriorityq;
-               ugeth->p_scheduler->txasap = ug_info->txasap;
-               ugeth->p_scheduler->extrabw = ug_info->extrabw;
+               out_8(&ugeth->p_scheduler->fracsiz, ug_info->fracsiz);
+               out_8(&ugeth->p_scheduler->strictpriorityq,
+                               ug_info->strictpriorityq);
+               out_8(&ugeth->p_scheduler->txasap, ug_info->txasap);
+               out_8(&ugeth->p_scheduler->extrabw, ug_info->extrabw);
                for (i = 0; i < NUM_TX_QUEUES; i++)
-                       ugeth->p_scheduler->weightfactor[i] =
-                           ug_info->weightfactor[i];
+                       out_8(&ugeth->p_scheduler->weightfactor[i],
+                           ug_info->weightfactor[i]);
 
                /* Set pointers to cpucount registers in scheduler */
                ugeth->p_cpucount[0] = &(ugeth->p_scheduler->cpucount0);
@@ -3144,21 +2640,22 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
            statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
                ugeth->tx_fw_statistics_pram_offset =
                    qe_muram_alloc(sizeof
-                                  (ucc_geth_tx_firmware_statistics_pram_t),
+                                  (struct ucc_geth_tx_firmware_statistics_pram),
                                   UCC_GETH_TX_STATISTICS_ALIGNMENT);
-               if (IS_MURAM_ERR(ugeth->tx_fw_statistics_pram_offset)) {
-                       ugeth_err
-                           ("%s: Can not allocate DPRAM memory for"
-                               " p_tx_fw_statistics_pram.", __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+               if (IS_ERR_VALUE(ugeth->tx_fw_statistics_pram_offset)) {
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err
+                                   ("%s: Can not allocate DPRAM memory for"
+                                       " p_tx_fw_statistics_pram.",
+                                       __func__);
                        return -ENOMEM;
                }
                ugeth->p_tx_fw_statistics_pram =
-                   (ucc_geth_tx_firmware_statistics_pram_t *)
+                   (struct ucc_geth_tx_firmware_statistics_pram __iomem *)
                    qe_muram_addr(ugeth->tx_fw_statistics_pram_offset);
                /* Zero out p_tx_fw_statistics_pram */
-               memset(ugeth->p_tx_fw_statistics_pram,
-                      0, sizeof(ucc_geth_tx_firmware_statistics_pram_t));
+               memset_io((void __iomem *)ugeth->p_tx_fw_statistics_pram,
+                      0, sizeof(struct ucc_geth_tx_firmware_statistics_pram));
        }
 
        /* temoder */
@@ -3174,7 +2671,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        test = in_be16(&ugeth->p_tx_glbl_pram->temoder);
 
        /* Function code register value to be used later */
-       function_code = QE_BMR_BYTE_ORDER_BO_MOT | UCC_FAST_FUNCTION_CODE_GBL;
+       function_code = UCC_BMR_BO_BE | UCC_BMR_GBL;
        /* Required for QE */
 
        /* function code register */
@@ -3183,20 +2680,20 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Rx global PRAM */
        /* Allocate global rx parameter RAM page */
        ugeth->rx_glbl_pram_offset =
-           qe_muram_alloc(sizeof(ucc_geth_rx_global_pram_t),
+           qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram),
                           UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT);
-       if (IS_MURAM_ERR(ugeth->rx_glbl_pram_offset)) {
-               ugeth_err
-                   ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
-                    __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+       if (IS_ERR_VALUE(ugeth->rx_glbl_pram_offset)) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err
+                           ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
+                            __func__);
                return -ENOMEM;
        }
        ugeth->p_rx_glbl_pram =
-           (ucc_geth_rx_global_pram_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_rx_global_pram __iomem *) qe_muram_addr(ugeth->
                                                        rx_glbl_pram_offset);
        /* Zero out p_rx_glbl_pram */
-       memset(ugeth->p_rx_glbl_pram, 0, sizeof(ucc_geth_rx_global_pram_t));
+       memset_io((void __iomem *)ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram));
 
        /* Fill global PRAM */
 
@@ -3204,18 +2701,18 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Size varies with number of Rx threads */
        ugeth->thread_dat_rx_offset =
            qe_muram_alloc(numThreadsRxNumerical *
-                          sizeof(ucc_geth_thread_data_rx_t),
+                          sizeof(struct ucc_geth_thread_data_rx),
                           UCC_GETH_THREAD_DATA_ALIGNMENT);
-       if (IS_MURAM_ERR(ugeth->thread_dat_rx_offset)) {
-               ugeth_err
-                   ("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
-                    __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+       if (IS_ERR_VALUE(ugeth->thread_dat_rx_offset)) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err
+                           ("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
+                            __func__);
                return -ENOMEM;
        }
 
        ugeth->p_thread_data_rx =
-           (ucc_geth_thread_data_rx_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_thread_data_rx __iomem *) qe_muram_addr(ugeth->
                                                        thread_dat_rx_offset);
        out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset);
 
@@ -3227,21 +2724,21 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
            statisticsMode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) {
                ugeth->rx_fw_statistics_pram_offset =
                    qe_muram_alloc(sizeof
-                                  (ucc_geth_rx_firmware_statistics_pram_t),
+                                  (struct ucc_geth_rx_firmware_statistics_pram),
                                   UCC_GETH_RX_STATISTICS_ALIGNMENT);
-               if (IS_MURAM_ERR(ugeth->rx_fw_statistics_pram_offset)) {
-                       ugeth_err
-                               ("%s: Can not allocate DPRAM memory for"
-                               " p_rx_fw_statistics_pram.", __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+               if (IS_ERR_VALUE(ugeth->rx_fw_statistics_pram_offset)) {
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err
+                                       ("%s: Can not allocate DPRAM memory for"
+                                       " p_rx_fw_statistics_pram.", __func__);
                        return -ENOMEM;
                }
                ugeth->p_rx_fw_statistics_pram =
-                   (ucc_geth_rx_firmware_statistics_pram_t *)
+                   (struct ucc_geth_rx_firmware_statistics_pram __iomem *)
                    qe_muram_addr(ugeth->rx_fw_statistics_pram_offset);
                /* Zero out p_rx_fw_statistics_pram */
-               memset(ugeth->p_rx_fw_statistics_pram, 0,
-                      sizeof(ucc_geth_rx_firmware_statistics_pram_t));
+               memset_io((void __iomem *)ugeth->p_rx_fw_statistics_pram, 0,
+                      sizeof(struct ucc_geth_rx_firmware_statistics_pram));
        }
 
        /* intCoalescingPtr */
@@ -3249,18 +2746,18 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Size varies with number of Rx queues */
        ugeth->rx_irq_coalescing_tbl_offset =
            qe_muram_alloc(ug_info->numQueuesRx *
-                          sizeof(ucc_geth_rx_interrupt_coalescing_entry_t),
-                          UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
-       if (IS_MURAM_ERR(ugeth->rx_irq_coalescing_tbl_offset)) {
-               ugeth_err
-                   ("%s: Can not allocate DPRAM memory for"
-                       " p_rx_irq_coalescing_tbl.", __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+                          sizeof(struct ucc_geth_rx_interrupt_coalescing_entry)
+                          + 4, UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
+       if (IS_ERR_VALUE(ugeth->rx_irq_coalescing_tbl_offset)) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err
+                           ("%s: Can not allocate DPRAM memory for"
+                               " p_rx_irq_coalescing_tbl.", __func__);
                return -ENOMEM;
        }
 
        ugeth->p_rx_irq_coalescing_tbl =
-           (ucc_geth_rx_interrupt_coalescing_table_t *)
+           (struct ucc_geth_rx_interrupt_coalescing_table __iomem *)
            qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset);
        out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr,
                 ugeth->rx_irq_coalescing_tbl_offset);
@@ -3300,7 +2797,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                l3qt = 0;
                for (i = 0; i < 8; i++)
                        l3qt |= (ug_info->l3qt[j + i] << (28 - 4 * i));
-               out_be32(&ugeth->p_rx_glbl_pram->l3qt[j], l3qt);
+               out_be32(&ugeth->p_rx_glbl_pram->l3qt[j/8], l3qt);
        }
 
        /* vlantype */
@@ -3316,26 +2813,26 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Size varies with number of Rx queues */
        ugeth->rx_bd_qs_tbl_offset =
            qe_muram_alloc(ug_info->numQueuesRx *
-                          (sizeof(ucc_geth_rx_bd_queues_entry_t) +
-                           sizeof(ucc_geth_rx_prefetched_bds_t)),
+                          (sizeof(struct ucc_geth_rx_bd_queues_entry) +
+                           sizeof(struct ucc_geth_rx_prefetched_bds)),
                           UCC_GETH_RX_BD_QUEUES_ALIGNMENT);
-       if (IS_MURAM_ERR(ugeth->rx_bd_qs_tbl_offset)) {
-               ugeth_err
-                   ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
-                    __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+       if (IS_ERR_VALUE(ugeth->rx_bd_qs_tbl_offset)) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err
+                           ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
+                            __func__);
                return -ENOMEM;
        }
 
        ugeth->p_rx_bd_qs_tbl =
-           (ucc_geth_rx_bd_queues_entry_t *) qe_muram_addr(ugeth->
+           (struct ucc_geth_rx_bd_queues_entry __iomem *) qe_muram_addr(ugeth->
                                    rx_bd_qs_tbl_offset);
        out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset);
        /* Zero out p_rx_bd_qs_tbl */
-       memset(ugeth->p_rx_bd_qs_tbl,
+       memset_io((void __iomem *)ugeth->p_rx_bd_qs_tbl,
               0,
-              ug_info->numQueuesRx * (sizeof(ucc_geth_rx_bd_queues_entry_t) +
-                                      sizeof(ucc_geth_rx_prefetched_bds_t)));
+              ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) +
+                                      sizeof(struct ucc_geth_rx_prefetched_bds)));
 
        /* Setup the table */
        /* Assume BD rings are already established */
@@ -3392,32 +2889,32 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                &ugeth->p_rx_glbl_pram->remoder);
 
        /* function code register */
-       ugeth->p_rx_glbl_pram->rstate = function_code;
+       out_8(&ugeth->p_rx_glbl_pram->rstate, function_code);
 
        /* initialize extended filtering */
        if (ug_info->rxExtendedFiltering) {
                if (!ug_info->extendedFilteringChainPointer) {
-                       ugeth_err("%s: Null Extended Filtering Chain Pointer.",
-                                 __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err("%s: Null Extended Filtering Chain Pointer.",
+                                         __func__);
                        return -EINVAL;
                }
 
                /* Allocate memory for extended filtering Mode Global
                Parameters */
                ugeth->exf_glbl_param_offset =
-                   qe_muram_alloc(sizeof(ucc_geth_exf_global_pram_t),
+                   qe_muram_alloc(sizeof(struct ucc_geth_exf_global_pram),
                UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT);
-               if (IS_MURAM_ERR(ugeth->exf_glbl_param_offset)) {
-                       ugeth_err
-                               ("%s: Can not allocate DPRAM memory for"
-                               " p_exf_glbl_param.", __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+               if (IS_ERR_VALUE(ugeth->exf_glbl_param_offset)) {
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err
+                                       ("%s: Can not allocate DPRAM memory for"
+                                       " p_exf_glbl_param.", __func__);
                        return -ENOMEM;
                }
 
                ugeth->p_exf_glbl_param =
-                   (ucc_geth_exf_global_pram_t *) qe_muram_addr(ugeth->
+                   (struct ucc_geth_exf_global_pram __iomem *) qe_muram_addr(ugeth->
                                 exf_glbl_param_offset);
                out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam,
                         ugeth->exf_glbl_param_offset);
@@ -3431,15 +2928,8 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                for (j = 0; j < NUM_OF_PADDRS; j++)
                        ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j);
 
-               /* Create CQs for hash tables */
-               if (ug_info->maxGroupAddrInHash > 0) {
-                       INIT_LIST_HEAD(&ugeth->group_hash_q);
-               }
-               if (ug_info->maxIndAddrInHash > 0) {
-                       INIT_LIST_HEAD(&ugeth->ind_hash_q);
-               }
                p_82xx_addr_filt =
-                   (ucc_geth_82xx_address_filtering_pram_t *) ugeth->
+                   (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->
                    p_rx_glbl_pram->addressfiltering;
 
                ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth,
@@ -3462,17 +2952,16 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
         * allocated resources can be released when the channel is freed.
         */
        if (!(ugeth->p_init_enet_param_shadow =
-            (ucc_geth_init_pram_t *) kmalloc(sizeof(ucc_geth_init_pram_t),
-                                             GFP_KERNEL))) {
-               ugeth_err
-                   ("%s: Can not allocate memory for"
-                       " p_UccInitEnetParamShadows.", __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+             kmalloc(sizeof(struct ucc_geth_init_pram), GFP_KERNEL))) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err
+                           ("%s: Can not allocate memory for"
+                               " p_UccInitEnetParamShadows.", __func__);
                return -ENOMEM;
        }
        /* Zero out *p_init_enet_param_shadow */
        memset((char *)ugeth->p_init_enet_param_shadow,
-              0, sizeof(ucc_geth_init_pram_t));
+              0, sizeof(struct ucc_geth_init_pram));
 
        /* Fill shadow InitEnet command parameter structure */
 
@@ -3499,14 +2988,14 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
            && (ug_info->largestexternallookupkeysize !=
                QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) {
-               ugeth_err("%s: Invalid largest External Lookup Key Size.",
-                         __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Invalid largest External Lookup Key Size.",
+                                 __func__);
                return -EINVAL;
        }
        ugeth->p_init_enet_param_shadow->largestexternallookupkeysize =
            ug_info->largestexternallookupkeysize;
-       size = sizeof(ucc_geth_thread_rx_pram_t);
+       size = sizeof(struct ucc_geth_thread_rx_pram);
        if (ug_info->rxExtendedFiltering) {
                size += THREAD_RX_PRAM_ADDITIONAL_FOR_EXTENDED_FILTERING;
                if (ug_info->largestexternallookupkeysize ==
@@ -3525,9 +3014,9 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
                /* Rx needs one extra for terminator */
                , size, UCC_GETH_THREAD_RX_PRAM_ALIGNMENT,
                ug_info->riscRx, 1)) != 0) {
-                       ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
-                               __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+               if (netif_msg_ifup(ugeth))
+                               ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
+                                       __func__);
                return ret_val;
        }
 
@@ -3537,46 +3026,50 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
             fill_init_enet_entries(ugeth,
                                    &(ugeth->p_init_enet_param_shadow->
                                      txthread[0]), numThreadsTxNumerical,
-                                   sizeof(ucc_geth_thread_tx_pram_t),
+                                   sizeof(struct ucc_geth_thread_tx_pram),
                                    UCC_GETH_THREAD_TX_PRAM_ALIGNMENT,
                                    ug_info->riscTx, 0)) != 0) {
-               ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
-                         __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
+                                 __func__);
                return ret_val;
        }
 
        /* Load Rx bds with buffers */
        for (i = 0; i < ug_info->numQueuesRx; i++) {
                if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) {
-                       ugeth_err("%s: Can not fill Rx bds with buffers.",
-                                 __FUNCTION__);
-                       ucc_geth_memclean(ugeth);
+                       if (netif_msg_ifup(ugeth))
+                               ugeth_err("%s: Can not fill Rx bds with buffers.",
+                                         __func__);
                        return ret_val;
                }
        }
 
        /* Allocate InitEnet command parameter structure */
-       init_enet_pram_offset = qe_muram_alloc(sizeof(ucc_geth_init_pram_t), 4);
-       if (IS_MURAM_ERR(init_enet_pram_offset)) {
-               ugeth_err
-                   ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
-                    __FUNCTION__);
-               ucc_geth_memclean(ugeth);
+       init_enet_pram_offset = qe_muram_alloc(sizeof(struct ucc_geth_init_pram), 4);
+       if (IS_ERR_VALUE(init_enet_pram_offset)) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err
+                           ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
+                            __func__);
                return -ENOMEM;
        }
        p_init_enet_pram =
-           (ucc_geth_init_pram_t *) qe_muram_addr(init_enet_pram_offset);
+           (struct ucc_geth_init_pram __iomem *) qe_muram_addr(init_enet_pram_offset);
 
        /* Copy shadow InitEnet command parameter structure into PRAM */
-       p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1;
-       p_init_enet_pram->resinit2 = ugeth->p_init_enet_param_shadow->resinit2;
-       p_init_enet_pram->resinit3 = ugeth->p_init_enet_param_shadow->resinit3;
-       p_init_enet_pram->resinit4 = ugeth->p_init_enet_param_shadow->resinit4;
+       out_8(&p_init_enet_pram->resinit1,
+                       ugeth->p_init_enet_param_shadow->resinit1);
+       out_8(&p_init_enet_pram->resinit2,
+                       ugeth->p_init_enet_param_shadow->resinit2);
+       out_8(&p_init_enet_pram->resinit3,
+                       ugeth->p_init_enet_param_shadow->resinit3);
+       out_8(&p_init_enet_pram->resinit4,
+                       ugeth->p_init_enet_param_shadow->resinit4);
        out_be16(&p_init_enet_pram->resinit5,
                 ugeth->p_init_enet_param_shadow->resinit5);
-       p_init_enet_pram->largestexternallookupkeysize =
-           ugeth->p_init_enet_param_shadow->largestexternallookupkeysize;
+       out_8(&p_init_enet_pram->largestexternallookupkeysize,
+           ugeth->p_init_enet_param_shadow->largestexternallookupkeysize);
        out_be32(&p_init_enet_pram->rgftgfrxglobal,
                 ugeth->p_init_enet_param_shadow->rgftgfrxglobal);
        for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_RX; i++)
@@ -3591,7 +3084,7 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        /* Issue QE command */
        cecr_subblock =
            ucc_fast_get_qe_cr_subblock(ugeth->ug_info->uf_info.ucc_num);
-       qe_issue_cmd(command, cecr_subblock, (u8) QE_CR_PROTOCOL_ETHERNET,
+       qe_issue_cmd(command, cecr_subblock, QE_CR_PROTOCOL_ETHERNET,
                     init_enet_pram_offset);
 
        /* Free InitEnet command parameter */
@@ -3600,54 +3093,27 @@ static int ucc_geth_startup(ucc_geth_private_t *ugeth)
        return 0;
 }
 
-/* returns a net_device_stats structure pointer */
-static struct net_device_stats *ucc_geth_get_stats(struct net_device *dev)
-{
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-
-       return &(ugeth->stats);
-}
-
-/* ucc_geth_timeout gets called when a packet has not been
- * transmitted after a set amount of time.
- * For now, assume that clearing out all the structures, and
- * starting over will fix the problem. */
-static void ucc_geth_timeout(struct net_device *dev)
-{
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-
-       ugeth_vdbg("%s: IN", __FUNCTION__);
-
-       ugeth->stats.tx_errors++;
-
-       ugeth_dump_regs(ugeth);
-
-       if (dev->flags & IFF_UP) {
-               ucc_geth_stop(ugeth);
-               ucc_geth_startup(ugeth);
-       }
-
-       netif_schedule(dev);
-}
-
 /* This is called by the kernel when a frame is ready for transmission. */
 /* It is pointed to by the dev->hard_start_xmit function pointer */
 static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       u8 *bd;                 /* BD pointer */
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+#ifdef CONFIG_UGETH_TX_ON_DEMAND
+       struct ucc_fast_private *uccf;
+#endif
+       u8 __iomem *bd;                 /* BD pointer */
        u32 bd_status;
        u8 txQ = 0;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        spin_lock_irq(&ugeth->lock);
 
-       ugeth->stats.tx_bytes += skb->len;
+       dev->stats.tx_bytes += skb->len;
 
        /* Start from the next BD that should be filled */
        bd = ugeth->txBd[txQ];
-       bd_status = BD_STATUS_AND_LENGTH(bd);
+       bd_status = in_be32((u32 __iomem *)bd);
        /* Save the skb pointer so we can free it later */
        ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb;
 
@@ -3657,22 +3123,24 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
             1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
 
        /* set up the buffer descriptor */
-       BD_BUFFER_SET(bd,
-                     dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE));
+       out_be32(&((struct qe_bd __iomem *)bd)->buf,
+                     dma_map_single(ugeth->dev, skb->data,
+                             skb->len, DMA_TO_DEVICE));
 
-       //printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data);
+       /* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */
 
        bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len;
 
-       BD_STATUS_AND_LENGTH_SET(bd, bd_status);
+       /* set bd status and length */
+       out_be32((u32 __iomem *)bd, bd_status);
 
        dev->trans_start = jiffies;
 
        /* Move to next BD in the ring */
        if (!(bd_status & T_W))
-               ugeth->txBd[txQ] = bd + UCC_GETH_SIZE_OF_BD;
+               bd += sizeof(struct qe_bd);
        else
-               ugeth->txBd[txQ] = ugeth->p_tx_bd_ring[txQ];
+               bd = ugeth->p_tx_bd_ring[txQ];
 
        /* If the next BD still needs to be cleaned up, then the bds
           are full.  We need to tell the kernel to stop sending us stuff. */
@@ -3681,6 +3149,8 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        netif_stop_queue(dev);
        }
 
+       ugeth->txBd[txQ] = bd;
+
        if (ugeth->p_scheduler) {
                ugeth->cpucount[txQ]++;
                /* Indicate to QE that there are more Tx bds ready for
@@ -3690,30 +3160,36 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
                out_be16(ugeth->p_cpucount[txQ], ugeth->cpucount[txQ]);
        }
 
+#ifdef CONFIG_UGETH_TX_ON_DEMAND
+       uccf = ugeth->uccf;
+       out_be16(uccf->p_utodr, UCC_FAST_TOD);
+#endif
        spin_unlock_irq(&ugeth->lock);
 
        return 0;
 }
 
-static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit)
+static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit)
 {
        struct sk_buff *skb;
-       u8 *bd;
+       u8 __iomem *bd;
        u16 length, howmany = 0;
        u32 bd_status;
        u8 *bdBuffer;
+       struct net_device *dev;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
+
+       dev = ugeth->ndev;
 
-       spin_lock(&ugeth->lock);
        /* collect received buffers */
        bd = ugeth->rxBd[rxQ];
 
-       bd_status = BD_STATUS_AND_LENGTH(bd);
+       bd_status = in_be32((u32 __iomem *)bd);
 
        /* while there are received buffers and BD is full (~R_E) */
        while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) {
-               bdBuffer = (u8 *) BD_BUFFER(bd);
+               bdBuffer = (u8 *) in_be32(&((struct qe_bd __iomem *)bd)->buf);
                length = (u16) ((bd_status & BD_LENGTH_MASK) - 4);
                skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]];
 
@@ -3722,39 +3198,34 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit)
                if (!skb ||
                    (!(bd_status & (R_F | R_L))) ||
                    (bd_status & R_ERRORS_FATAL)) {
-                       ugeth_vdbg("%s, %d: ERROR!!! skb - 0x%08x",
-                                  __FUNCTION__, __LINE__, (u32) skb);
+                       if (netif_msg_rx_err(ugeth))
+                               ugeth_err("%s, %d: ERROR!!! skb - 0x%08x",
+                                          __func__, __LINE__, (u32) skb);
                        if (skb)
                                dev_kfree_skb_any(skb);
 
                        ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]] = NULL;
-                       ugeth->stats.rx_dropped++;
+                       dev->stats.rx_dropped++;
                } else {
-                       ugeth->stats.rx_packets++;
+                       dev->stats.rx_packets++;
                        howmany++;
 
                        /* Prep the skb for the packet */
                        skb_put(skb, length);
 
                        /* Tell the skb what kind of packet this is */
-                       skb->protocol = eth_type_trans(skb, ugeth->dev);
+                       skb->protocol = eth_type_trans(skb, ugeth->ndev);
 
-                       ugeth->stats.rx_bytes += length;
+                       dev->stats.rx_bytes += length;
                        /* Send the packet up the stack */
-#ifdef CONFIG_UGETH_NAPI
                        netif_receive_skb(skb);
-#else
-                       netif_rx(skb);
-#endif                         /* CONFIG_UGETH_NAPI */
                }
 
-               ugeth->dev->last_rx = jiffies;
-
                skb = get_new_skb(ugeth, bd);
                if (!skb) {
-                       ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
-                       spin_unlock(&ugeth->lock);
-                       ugeth->stats.rx_dropped++;
+                       if (netif_msg_rx_err(ugeth))
+                               ugeth_warn("%s: No Rx Data Buffer", __func__);
+                       dev->stats.rx_dropped++;
                        break;
                }
 
@@ -3768,25 +3239,24 @@ static int ucc_geth_rx(ucc_geth_private_t *ugeth, u8 rxQ, int rx_work_limit)
                if (bd_status & R_W)
                        bd = ugeth->p_rx_bd_ring[rxQ];
                else
-                       bd += UCC_GETH_SIZE_OF_BD;
+                       bd += sizeof(struct qe_bd);
 
-               bd_status = BD_STATUS_AND_LENGTH(bd);
+               bd_status = in_be32((u32 __iomem *)bd);
        }
 
        ugeth->rxBd[rxQ] = bd;
-       spin_unlock(&ugeth->lock);
        return howmany;
 }
 
 static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 {
        /* Start from the next BD that should be filled */
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       u8 *bd;                 /* BD pointer */
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       u8 __iomem *bd;         /* BD pointer */
        u32 bd_status;
 
        bd = ugeth->confBd[txQ];
-       bd_status = BD_STATUS_AND_LENGTH(bd);
+       bd_status = in_be32((u32 __iomem *)bd);
 
        /* Normal processing. */
        while ((bd_status & T_R) == 0) {
@@ -3794,13 +3264,13 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
                /* Handle the transmitted buffer and release */
                /* the BD to be used with the current frame  */
 
-               if ((bd = ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0))
+               if ((bd == ugeth->txBd[txQ]) && (netif_queue_stopped(dev) == 0))
                        break;
 
-               ugeth->stats.tx_packets++;
+               dev->stats.tx_packets++;
 
                /* Free the sk buffer associated with this TxBD */
-               dev_kfree_skb_irq(ugeth->
+               dev_kfree_skb(ugeth->
                                  tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]]);
                ugeth->tx_skbuff[txQ][ugeth->skb_dirtytx[txQ]] = NULL;
                ugeth->skb_dirtytx[txQ] =
@@ -3813,251 +3283,177 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 
                /* Advance the confirmation BD pointer */
                if (!(bd_status & T_W))
-                       ugeth->confBd[txQ] += UCC_GETH_SIZE_OF_BD;
+                       bd += sizeof(struct qe_bd);
                else
-                       ugeth->confBd[txQ] = ugeth->p_tx_bd_ring[txQ];
+                       bd = ugeth->p_tx_bd_ring[txQ];
+               bd_status = in_be32((u32 __iomem *)bd);
        }
+       ugeth->confBd[txQ] = bd;
        return 0;
 }
 
-#ifdef CONFIG_UGETH_NAPI
-static int ucc_geth_poll(struct net_device *dev, int *budget)
+static int ucc_geth_poll(struct napi_struct *napi, int budget)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       int howmany;
-       int rx_work_limit = *budget;
-       u8 rxQ = 0;
+       struct ucc_geth_private *ugeth = container_of(napi, struct ucc_geth_private, napi);
+       struct ucc_geth_info *ug_info;
+       int howmany, i;
 
-       if (rx_work_limit > dev->quota)
-               rx_work_limit = dev->quota;
+       ug_info = ugeth->ug_info;
 
-       howmany = ucc_geth_rx(ugeth, rxQ, rx_work_limit);
+       howmany = 0;
+       for (i = 0; i < ug_info->numQueuesRx; i++)
+               howmany += ucc_geth_rx(ugeth, i, budget - howmany);
 
-       dev->quota -= howmany;
-       rx_work_limit -= howmany;
-       *budget -= howmany;
+       /* Tx event processing */
+       spin_lock(&ugeth->lock);
+       for (i = 0; i < ug_info->numQueuesTx; i++)
+               ucc_geth_tx(ugeth->ndev, i);
+       spin_unlock(&ugeth->lock);
 
-       if (rx_work_limit >= 0)
-               netif_rx_complete(dev);
+       if (howmany < budget) {
+               napi_complete(napi);
+               setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS | UCCE_TX_EVENTS);
+       }
 
-       return (rx_work_limit < 0) ? 1 : 0;
+       return howmany;
 }
-#endif                         /* CONFIG_UGETH_NAPI */
 
 static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
 {
-       struct net_device *dev = (struct net_device *)info;
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       ucc_fast_private_t *uccf;
-       ucc_geth_info_t *ug_info;
-       register u32 ucce = 0;
-       register u32 bit_mask = UCCE_RXBF_SINGLE_MASK;
-       register u32 tx_mask = UCCE_TXBF_SINGLE_MASK;
-       register u8 i;
+       struct net_device *dev = info;
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct ucc_fast_private *uccf;
+       struct ucc_geth_info *ug_info;
+       register u32 ucce;
+       register u32 uccm;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
-
-       if (!ugeth)
-               return IRQ_NONE;
+       ugeth_vdbg("%s: IN", __func__);
 
        uccf = ugeth->uccf;
        ug_info = ugeth->ug_info;
 
-       do {
-               ucce |= (u32) (in_be32(uccf->p_ucce) & in_be32(uccf->p_uccm));
-
-               /* clear event bits for next time */
-               /* Side effect here is to mask ucce variable
-               for future processing below. */
-               out_be32(uccf->p_ucce, ucce);   /* Clear with ones,
-                                               but only bits in UCCM */
-
-               /* We ignore Tx interrupts because Tx confirmation is
-               done inside Tx routine */
-
-               for (i = 0; i < ug_info->numQueuesRx; i++) {
-                       if (ucce & bit_mask)
-                               ucc_geth_rx(ugeth, i,
-                                           (int)ugeth->ug_info->
-                                           bdRingLenRx[i]);
-                       ucce &= ~bit_mask;
-                       bit_mask <<= 1;
-               }
-
-               for (i = 0; i < ug_info->numQueuesTx; i++) {
-                       if (ucce & tx_mask)
-                               ucc_geth_tx(dev, i);
-                       ucce &= ~tx_mask;
-                       tx_mask <<= 1;
-               }
-
-               /* Exceptions */
-               if (ucce & UCCE_BSY) {
-                       ugeth_vdbg("Got BUSY irq!!!!");
-                       ugeth->stats.rx_errors++;
-                       ucce &= ~UCCE_BSY;
-               }
-               if (ucce & UCCE_OTHER) {
-                       ugeth_vdbg("Got frame with error (ucce - 0x%08x)!!!!",
-                                  ucce);
-                       ugeth->stats.rx_errors++;
-                       ucce &= ~ucce;
+       /* read and clear events */
+       ucce = (u32) in_be32(uccf->p_ucce);
+       uccm = (u32) in_be32(uccf->p_uccm);
+       ucce &= uccm;
+       out_be32(uccf->p_ucce, ucce);
+
+       /* check for receive events that require processing */
+       if (ucce & (UCCE_RX_EVENTS | UCCE_TX_EVENTS)) {
+               if (napi_schedule_prep(&ugeth->napi)) {
+                       uccm &= ~(UCCE_RX_EVENTS | UCCE_TX_EVENTS);
+                       out_be32(uccf->p_uccm, uccm);
+                       __napi_schedule(&ugeth->napi);
                }
        }
-       while (ucce);
-
-       return IRQ_HANDLED;
-}
-
-static irqreturn_t phy_interrupt(int irq, void *dev_id)
-{
-       struct net_device *dev = (struct net_device *)dev_id;
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-
-       ugeth_vdbg("%s: IN", __FUNCTION__);
-
-       /* Clear the interrupt */
-       mii_clear_phy_interrupt(ugeth->mii_info);
 
-       /* Disable PHY interrupts */
-       mii_configure_phy_interrupt(ugeth->mii_info, MII_INTERRUPT_DISABLED);
-
-       /* Schedule the phy change */
-       schedule_work(&ugeth->tq);
+       /* Errors and other events */
+       if (ucce & UCCE_OTHER) {
+               if (ucce & UCC_GETH_UCCE_BSY)
+                       dev->stats.rx_errors++;
+               if (ucce & UCC_GETH_UCCE_TXE)
+                       dev->stats.tx_errors++;
+       }
 
        return IRQ_HANDLED;
 }
 
-/* Scheduled by the phy_interrupt/timer to handle PHY changes */
-static void ugeth_phy_change(void *data)
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * Polling 'interrupt' - used by things like netconsole to send skbs
+ * without having to re-enable interrupts. It's not called while
+ * the interrupt routine is executing.
+ */
+static void ucc_netpoll(struct net_device *dev)
 {
-       struct net_device *dev = (struct net_device *)data;
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
-       ucc_geth_t *ug_regs;
-       int result = 0;
-
-       ugeth_vdbg("%s: IN", __FUNCTION__);
-
-       ug_regs = ugeth->ug_regs;
-
-       /* Delay to give the PHY a chance to change the
-        * register state */
-       msleep(1);
-
-       /* Update the link, speed, duplex */
-       result = ugeth->mii_info->phyinfo->read_status(ugeth->mii_info);
-
-       /* Adjust the known status as long as the link
-        * isn't still coming up */
-       if ((0 == result) || (ugeth->mii_info->link == 0))
-               adjust_link(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       int irq = ugeth->ug_info->uf_info.irq;
 
-       /* Reenable interrupts, if needed */
-       if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR)
-               mii_configure_phy_interrupt(ugeth->mii_info,
-                                           MII_INTERRUPT_ENABLED);
+       disable_irq(irq);
+       ucc_geth_irq_handler(irq, dev);
+       enable_irq(irq);
 }
+#endif /* CONFIG_NET_POLL_CONTROLLER */
 
-/* Called every so often on systems that don't interrupt
- * the core for PHY changes */
-static void ugeth_phy_timer(unsigned long data)
+static int ucc_geth_set_mac_addr(struct net_device *dev, void *p)
 {
-       struct net_device *dev = (struct net_device *)data;
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+       struct sockaddr *addr = p;
 
-       schedule_work(&ugeth->tq);
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
 
-       mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ);
-}
+       memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
 
-/* Keep trying aneg for some time
- * If, after GFAR_AN_TIMEOUT seconds, it has not
- * finished, we switch to forced.
- * Either way, once the process has completed, we either
- * request the interrupt, or switch the timer over to
- * using ugeth_phy_timer to check status */
-static void ugeth_phy_startup_timer(unsigned long data)
-{
-       struct ugeth_mii_info *mii_info = (struct ugeth_mii_info *)data;
-       ucc_geth_private_t *ugeth = netdev_priv(mii_info->dev);
-       static int secondary = UGETH_AN_TIMEOUT;
-       int result;
-
-       /* Configure the Auto-negotiation */
-       result = mii_info->phyinfo->config_aneg(mii_info);
-
-       /* If autonegotiation failed to start, and
-        * we haven't timed out, reset the timer, and return */
-       if (result && secondary--) {
-               mod_timer(&ugeth->phy_info_timer, jiffies + HZ);
-               return;
-       } else if (result) {
-               /* Couldn't start autonegotiation.
-                * Try switching to forced */
-               mii_info->autoneg = 0;
-               result = mii_info->phyinfo->config_aneg(mii_info);
-
-               /* Forcing failed!  Give up */
-               if (result) {
-                       ugeth_err("%s: Forcing failed!", mii_info->dev->name);
-                       return;
-               }
-       }
+       /*
+        * If device is not running, we will set mac addr register
+        * when opening the device.
+        */
+       if (!netif_running(dev))
+               return 0;
 
-       /* Kill the timer so it can be restarted */
-       del_timer_sync(&ugeth->phy_info_timer);
-
-       /* Grab the PHY interrupt, if necessary/possible */
-       if (ugeth->ug_info->board_flags & FSL_UGETH_BRD_HAS_PHY_INTR) {
-               if (request_irq(ugeth->ug_info->phy_interrupt,
-                               phy_interrupt,
-                               SA_SHIRQ, "phy_interrupt", mii_info->dev) < 0) {
-                       ugeth_err("%s: Can't get IRQ %d (PHY)",
-                                 mii_info->dev->name,
-                                 ugeth->ug_info->phy_interrupt);
-               } else {
-                       mii_configure_phy_interrupt(ugeth->mii_info,
-                                                   MII_INTERRUPT_ENABLED);
-                       return;
-               }
-       }
+       spin_lock_irq(&ugeth->lock);
+       init_mac_station_addr_regs(dev->dev_addr[0],
+                                  dev->dev_addr[1],
+                                  dev->dev_addr[2],
+                                  dev->dev_addr[3],
+                                  dev->dev_addr[4],
+                                  dev->dev_addr[5],
+                                  &ugeth->ug_regs->macstnaddr1,
+                                  &ugeth->ug_regs->macstnaddr2);
+       spin_unlock_irq(&ugeth->lock);
 
-       /* Start the timer again, this time in order to
-        * handle a change in status */
-       init_timer(&ugeth->phy_info_timer);
-       ugeth->phy_info_timer.function = &ugeth_phy_timer;
-       ugeth->phy_info_timer.data = (unsigned long)mii_info->dev;
-       mod_timer(&ugeth->phy_info_timer, jiffies + PHY_CHANGE_TIME * HZ);
+       return 0;
 }
 
 /* Called when something needs to use the ethernet device */
 /* Returns 0 for success. */
 static int ucc_geth_open(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
        int err;
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
        /* Test station address */
        if (dev->dev_addr[0] & ENET_GROUP_ADDR) {
-               ugeth_err("%s: Multicast address used for station address"
-                         " - is this what you wanted?", __FUNCTION__);
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Multicast address used for station address"
+                                 " - is this what you wanted?", __func__);
                return -EINVAL;
        }
 
-       err = ucc_geth_startup(ugeth);
+       err = init_phy(dev);
        if (err) {
-               ugeth_err("%s: Cannot configure net device, aborting.",
-                         dev->name);
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Cannot initialize PHY, aborting.",
+                                 dev->name);
                return err;
        }
 
+       err = ucc_struct_init(ugeth);
+       if (err) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Cannot configure internal struct, aborting.", dev->name);
+               goto out_err_stop;
+       }
+
+       napi_enable(&ugeth->napi);
+
+       err = ucc_geth_startup(ugeth);
+       if (err) {
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Cannot configure net device, aborting.",
+                                 dev->name);
+               goto out_err;
+       }
+
        err = adjust_enet_interface(ugeth);
        if (err) {
-               ugeth_err("%s: Cannot configure net device, aborting.",
-                         dev->name);
-               return err;
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Cannot configure net device, aborting.",
+                                 dev->name);
+               goto out_err;
        }
 
        /*       Set MACSTNADDR1, MACSTNADDR2                */
@@ -4071,105 +3467,307 @@ static int ucc_geth_open(struct net_device *dev)
                                   &ugeth->ug_regs->macstnaddr1,
                                   &ugeth->ug_regs->macstnaddr2);
 
-       err = init_phy(dev);
-       if (err) {
-               ugeth_err("%s: Cannot initialzie PHY, aborting.", dev->name);
-               return err;
-       }
-#ifndef CONFIG_UGETH_NAPI
-       err =
-           request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0,
-                       "UCC Geth", dev);
+       phy_start(ugeth->phydev);
+
+       err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
        if (err) {
-               ugeth_err("%s: Cannot get IRQ for net device, aborting.",
-                         dev->name);
-               ucc_geth_stop(ugeth);
-               return err;
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
+               goto out_err;
        }
-#endif                         /* CONFIG_UGETH_NAPI */
 
-       /* Set up the PHY change work queue */
-       INIT_WORK(&ugeth->tq, ugeth_phy_change, dev);
-
-       init_timer(&ugeth->phy_info_timer);
-       ugeth->phy_info_timer.function = &ugeth_phy_startup_timer;
-       ugeth->phy_info_timer.data = (unsigned long)ugeth->mii_info;
-       mod_timer(&ugeth->phy_info_timer, jiffies + HZ);
-
-       err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
+       err = request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler,
+                         0, "UCC Geth", dev);
        if (err) {
-               ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
-               ucc_geth_stop(ugeth);
-               return err;
+               if (netif_msg_ifup(ugeth))
+                       ugeth_err("%s: Cannot get IRQ for net device, aborting.",
+                                 dev->name);
+               goto out_err;
        }
 
        netif_start_queue(dev);
 
        return err;
+
+out_err:
+       napi_disable(&ugeth->napi);
+out_err_stop:
+       ucc_geth_stop(ugeth);
+       return err;
 }
 
 /* Stops the kernel queue, and halts the controller */
 static int ucc_geth_close(struct net_device *dev)
 {
-       ucc_geth_private_t *ugeth = netdev_priv(dev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
 
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       ugeth_vdbg("%s: IN", __func__);
 
-       ucc_geth_stop(ugeth);
+       napi_disable(&ugeth->napi);
 
-       /* Shutdown the PHY */
-       if (ugeth->mii_info->phyinfo->close)
-               ugeth->mii_info->phyinfo->close(ugeth->mii_info);
+       ucc_geth_stop(ugeth);
 
-       kfree(ugeth->mii_info);
+       free_irq(ugeth->ug_info->uf_info.irq, ugeth->ndev);
 
        netif_stop_queue(dev);
 
        return 0;
 }
 
-const struct ethtool_ops ucc_geth_ethtool_ops = { };
+/* Reopen device. This will reset the MAC and PHY. */
+static void ucc_geth_timeout_work(struct work_struct *work)
+{
+       struct ucc_geth_private *ugeth;
+       struct net_device *dev;
+
+       ugeth = container_of(work, struct ucc_geth_private, timeout_work);
+       dev = ugeth->ndev;
+
+       ugeth_vdbg("%s: IN", __func__);
+
+       dev->stats.tx_errors++;
+
+       ugeth_dump_regs(ugeth);
+
+       if (dev->flags & IFF_UP) {
+               /*
+                * Must reset MAC *and* PHY. This is done by reopening
+                * the device.
+                */
+               ucc_geth_close(dev);
+               ucc_geth_open(dev);
+       }
+
+       netif_tx_schedule_all(dev);
+}
+
+/*
+ * ucc_geth_timeout gets called when a packet has not been
+ * transmitted after a set amount of time.
+ */
+static void ucc_geth_timeout(struct net_device *dev)
+{
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+
+       netif_carrier_off(dev);
+       schedule_work(&ugeth->timeout_work);
+}
+
+static phy_interface_t to_phy_interface(const char *phy_connection_type)
+{
+       if (strcasecmp(phy_connection_type, "mii") == 0)
+               return PHY_INTERFACE_MODE_MII;
+       if (strcasecmp(phy_connection_type, "gmii") == 0)
+               return PHY_INTERFACE_MODE_GMII;
+       if (strcasecmp(phy_connection_type, "tbi") == 0)
+               return PHY_INTERFACE_MODE_TBI;
+       if (strcasecmp(phy_connection_type, "rmii") == 0)
+               return PHY_INTERFACE_MODE_RMII;
+       if (strcasecmp(phy_connection_type, "rgmii") == 0)
+               return PHY_INTERFACE_MODE_RGMII;
+       if (strcasecmp(phy_connection_type, "rgmii-id") == 0)
+               return PHY_INTERFACE_MODE_RGMII_ID;
+       if (strcasecmp(phy_connection_type, "rgmii-txid") == 0)
+               return PHY_INTERFACE_MODE_RGMII_TXID;
+       if (strcasecmp(phy_connection_type, "rgmii-rxid") == 0)
+               return PHY_INTERFACE_MODE_RGMII_RXID;
+       if (strcasecmp(phy_connection_type, "rtbi") == 0)
+               return PHY_INTERFACE_MODE_RTBI;
+       if (strcasecmp(phy_connection_type, "sgmii") == 0)
+               return PHY_INTERFACE_MODE_SGMII;
+
+       return PHY_INTERFACE_MODE_MII;
+}
+
+static const struct net_device_ops ucc_geth_netdev_ops = {
+       .ndo_open               = ucc_geth_open,
+       .ndo_stop               = ucc_geth_close,
+       .ndo_start_xmit         = ucc_geth_start_xmit,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = ucc_geth_set_mac_addr,
+       .ndo_change_mtu         = eth_change_mtu,
+       .ndo_set_multicast_list = ucc_geth_set_multi,
+       .ndo_tx_timeout         = ucc_geth_timeout,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = ucc_netpoll,
+#endif
+};
 
-static int ucc_geth_probe(struct device *device)
+static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *match)
 {
-       struct platform_device *pdev = to_platform_device(device);
-       struct ucc_geth_platform_data *ugeth_pdata;
+       struct device *device = &ofdev->dev;
+       struct device_node *np = ofdev->node;
        struct net_device *dev = NULL;
        struct ucc_geth_private *ugeth = NULL;
        struct ucc_geth_info *ug_info;
-       int err;
-       static int mii_mng_configured = 0;
-
-       ugeth_vdbg("%s: IN", __FUNCTION__);
+       struct resource res;
+       struct device_node *phy;
+       int err, ucc_num, max_speed = 0;
+       const u32 *fixed_link;
+       const unsigned int *prop;
+       const char *sprop;
+       const void *mac_addr;
+       phy_interface_t phy_interface;
+       static const int enet_to_speed[] = {
+               SPEED_10, SPEED_10, SPEED_10,
+               SPEED_100, SPEED_100, SPEED_100,
+               SPEED_1000, SPEED_1000, SPEED_1000, SPEED_1000,
+       };
+       static const phy_interface_t enet_to_phy_interface[] = {
+               PHY_INTERFACE_MODE_MII, PHY_INTERFACE_MODE_RMII,
+               PHY_INTERFACE_MODE_RGMII, PHY_INTERFACE_MODE_MII,
+               PHY_INTERFACE_MODE_RMII, PHY_INTERFACE_MODE_RGMII,
+               PHY_INTERFACE_MODE_GMII, PHY_INTERFACE_MODE_RGMII,
+               PHY_INTERFACE_MODE_TBI, PHY_INTERFACE_MODE_RTBI,
+               PHY_INTERFACE_MODE_SGMII,
+       };
+
+       ugeth_vdbg("%s: IN", __func__);
+
+       prop = of_get_property(np, "cell-index", NULL);
+       if (!prop) {
+               prop = of_get_property(np, "device-id", NULL);
+               if (!prop)
+                       return -ENODEV;
+       }
+
+       ucc_num = *prop - 1;
+       if ((ucc_num < 0) || (ucc_num > 7))
+               return -ENODEV;
 
-       ugeth_pdata = (struct ucc_geth_platform_data *)pdev->dev.platform_data;
+       ug_info = &ugeth_info[ucc_num];
+       if (ug_info == NULL) {
+               if (netif_msg_probe(&debug))
+                       ugeth_err("%s: [%d] Missing additional data!",
+                                       __func__, ucc_num);
+               return -ENODEV;
+       }
 
-       ug_info = &ugeth_info[pdev->id];
-       ug_info->uf_info.ucc_num = pdev->id;
-       ug_info->uf_info.rx_clock = ugeth_pdata->rx_clock;
-       ug_info->uf_info.tx_clock = ugeth_pdata->tx_clock;
-       ug_info->uf_info.regs = ugeth_pdata->phy_reg_addr;
-       ug_info->uf_info.irq = platform_get_irq(pdev, 0);
-       ug_info->phy_address = ugeth_pdata->phy_id;
-       ug_info->enet_interface = ugeth_pdata->phy_interface;
-       ug_info->board_flags = ugeth_pdata->board_flags;
-       ug_info->phy_interrupt = ugeth_pdata->phy_interrupt;
+       ug_info->uf_info.ucc_num = ucc_num;
 
-       printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
-               ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
-               ug_info->uf_info.irq);
+       sprop = of_get_property(np, "rx-clock-name", NULL);
+       if (sprop) {
+               ug_info->uf_info.rx_clock = qe_clock_source(sprop);
+               if ((ug_info->uf_info.rx_clock < QE_CLK_NONE) ||
+                   (ug_info->uf_info.rx_clock > QE_CLK24)) {
+                       printk(KERN_ERR
+                               "ucc_geth: invalid rx-clock-name property\n");
+                       return -EINVAL;
+               }
+       } else {
+               prop = of_get_property(np, "rx-clock", NULL);
+               if (!prop) {
+                       /* If both rx-clock-name and rx-clock are missing,
+                          we want to tell people to use rx-clock-name. */
+                       printk(KERN_ERR
+                               "ucc_geth: missing rx-clock-name property\n");
+                       return -EINVAL;
+               }
+               if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
+                       printk(KERN_ERR
+                               "ucc_geth: invalid rx-clock propperty\n");
+                       return -EINVAL;
+               }
+               ug_info->uf_info.rx_clock = *prop;
+       }
 
-       if (ug_info == NULL) {
-               ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__,
-                         pdev->id);
-               return -ENODEV;
+       sprop = of_get_property(np, "tx-clock-name", NULL);
+       if (sprop) {
+               ug_info->uf_info.tx_clock = qe_clock_source(sprop);
+               if ((ug_info->uf_info.tx_clock < QE_CLK_NONE) ||
+                   (ug_info->uf_info.tx_clock > QE_CLK24)) {
+                       printk(KERN_ERR
+                               "ucc_geth: invalid tx-clock-name property\n");
+                       return -EINVAL;
+               }
+       } else {
+               prop = of_get_property(np, "tx-clock", NULL);
+               if (!prop) {
+                       printk(KERN_ERR
+                               "ucc_geth: mising tx-clock-name property\n");
+                       return -EINVAL;
+               }
+               if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
+                       printk(KERN_ERR
+                               "ucc_geth: invalid tx-clock property\n");
+                       return -EINVAL;
+               }
+               ug_info->uf_info.tx_clock = *prop;
        }
 
-       if (!mii_mng_configured) {
-               ucc_set_qe_mux_mii_mng(ug_info->uf_info.ucc_num);
-               mii_mng_configured = 1;
+       err = of_address_to_resource(np, 0, &res);
+       if (err)
+               return -EINVAL;
+
+       ug_info->uf_info.regs = res.start;
+       ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
+       fixed_link = of_get_property(np, "fixed-link", NULL);
+       if (fixed_link) {
+               phy = NULL;
+       } else {
+               phy = of_parse_phandle(np, "phy-handle", 0);
+               if (phy == NULL)
+                       return -ENODEV;
+       }
+       ug_info->phy_node = phy;
+
+       /* get the phy interface type, or default to MII */
+       prop = of_get_property(np, "phy-connection-type", NULL);
+       if (!prop) {
+               /* handle interface property present in old trees */
+               prop = of_get_property(phy, "interface", NULL);
+               if (prop != NULL) {
+                       phy_interface = enet_to_phy_interface[*prop];
+                       max_speed = enet_to_speed[*prop];
+               } else
+                       phy_interface = PHY_INTERFACE_MODE_MII;
+       } else {
+               phy_interface = to_phy_interface((const char *)prop);
+       }
+
+       /* get speed, or derive from PHY interface */
+       if (max_speed == 0)
+               switch (phy_interface) {
+               case PHY_INTERFACE_MODE_GMII:
+               case PHY_INTERFACE_MODE_RGMII:
+               case PHY_INTERFACE_MODE_RGMII_ID:
+               case PHY_INTERFACE_MODE_RGMII_RXID:
+               case PHY_INTERFACE_MODE_RGMII_TXID:
+               case PHY_INTERFACE_MODE_TBI:
+               case PHY_INTERFACE_MODE_RTBI:
+               case PHY_INTERFACE_MODE_SGMII:
+                       max_speed = SPEED_1000;
+                       break;
+               default:
+                       max_speed = SPEED_100;
+                       break;
+               }
+
+       if (max_speed == SPEED_1000) {
+               /* configure muram FIFOs for gigabit operation */
+               ug_info->uf_info.urfs = UCC_GETH_URFS_GIGA_INIT;
+               ug_info->uf_info.urfet = UCC_GETH_URFET_GIGA_INIT;
+               ug_info->uf_info.urfset = UCC_GETH_URFSET_GIGA_INIT;
+               ug_info->uf_info.utfs = UCC_GETH_UTFS_GIGA_INIT;
+               ug_info->uf_info.utfet = UCC_GETH_UTFET_GIGA_INIT;
+               ug_info->uf_info.utftt = UCC_GETH_UTFTT_GIGA_INIT;
+               ug_info->numThreadsTx = UCC_GETH_NUM_OF_THREADS_4;
+
+               /* If QE's snum number is 46 which means we need to support
+                * 4 UECs at 1000Base-T simultaneously, we need to allocate
+                * more Threads to Rx.
+                */
+               if (qe_get_num_of_snums() == 46)
+                       ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_6;
+               else
+                       ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
        }
 
+       if (netif_msg_probe(&debug))
+               printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
+                       ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
+                       ug_info->uf_info.irq);
+
        /* Create an ethernet device instance */
        dev = alloc_etherdev(sizeof(*ugeth));
 
@@ -4179,79 +3777,130 @@ static int ucc_geth_probe(struct device *device)
        ugeth = netdev_priv(dev);
        spin_lock_init(&ugeth->lock);
 
+       /* Create CQs for hash tables */
+       INIT_LIST_HEAD(&ugeth->group_hash_q);
+       INIT_LIST_HEAD(&ugeth->ind_hash_q);
+
        dev_set_drvdata(device, dev);
 
        /* Set the dev->base_addr to the gfar reg region */
        dev->base_addr = (unsigned long)(ug_info->uf_info.regs);
 
-       SET_MODULE_OWNER(dev);
        SET_NETDEV_DEV(dev, device);
 
        /* Fill in the dev structure */
-       dev->open = ucc_geth_open;
-       dev->hard_start_xmit = ucc_geth_start_xmit;
-       dev->tx_timeout = ucc_geth_timeout;
+       uec_set_ethtool_ops(dev);
+       dev->netdev_ops = &ucc_geth_netdev_ops;
        dev->watchdog_timeo = TX_TIMEOUT;
-#ifdef CONFIG_UGETH_NAPI
-       dev->poll = ucc_geth_poll;
-       dev->weight = UCC_GETH_DEV_WEIGHT;
-#endif                         /* CONFIG_UGETH_NAPI */
-       dev->stop = ucc_geth_close;
-       dev->get_stats = ucc_geth_get_stats;
-//    dev->change_mtu = ucc_geth_change_mtu;
+       INIT_WORK(&ugeth->timeout_work, ucc_geth_timeout_work);
+       netif_napi_add(dev, &ugeth->napi, ucc_geth_poll, 64);
        dev->mtu = 1500;
-       dev->set_multicast_list = ucc_geth_set_multi;
-       dev->ethtool_ops = &ucc_geth_ethtool_ops;
+
+       ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
+       ugeth->phy_interface = phy_interface;
+       ugeth->max_speed = max_speed;
 
        err = register_netdev(dev);
        if (err) {
-               ugeth_err("%s: Cannot register net device, aborting.",
-                         dev->name);
+               if (netif_msg_probe(ugeth))
+                       ugeth_err("%s: Cannot register net device, aborting.",
+                                 dev->name);
                free_netdev(dev);
                return err;
        }
 
+       mac_addr = of_get_mac_address(np);
+       if (mac_addr)
+               memcpy(dev->dev_addr, mac_addr, 6);
+
        ugeth->ug_info = ug_info;
-       ugeth->dev = dev;
-       memcpy(dev->dev_addr, ugeth_pdata->mac_addr, 6);
+       ugeth->dev = device;
+       ugeth->ndev = dev;
+       ugeth->node = np;
+
+       /* Find the TBI PHY.  If it's not there, we don't support SGMII */
+       ph = of_get_property(np, "tbi-handle", NULL);
+       if (ph) {
+               struct device_node *tbi = of_find_node_by_phandle(*ph);
+               struct of_device *ofdev;
+               struct mii_bus *bus;
+               const unsigned int *id;
+
+               if (!tbi)
+                       return 0;
+
+               mdio = of_get_parent(tbi);
+               if (!mdio)
+                       return 0;
+
+               ofdev = of_find_device_by_node(mdio);
+
+               of_node_put(mdio);
+
+               id = of_get_property(tbi, "reg", NULL);
+               if (!id)
+                       return 0;
+               of_node_put(tbi);
+
+               bus = dev_get_drvdata(&ofdev->dev);
+               if (!bus)
+                       return 0;
+
+               ugeth->tbiphy = bus->phy_map[*id];
+       }
 
        return 0;
 }
 
-static int ucc_geth_remove(struct device *device)
+static int ucc_geth_remove(struct of_device* ofdev)
 {
+       struct device *device = &ofdev->dev;
        struct net_device *dev = dev_get_drvdata(device);
        struct ucc_geth_private *ugeth = netdev_priv(dev);
 
-       dev_set_drvdata(device, NULL);
-       ucc_geth_memclean(ugeth);
+       unregister_netdev(dev);
        free_netdev(dev);
+       ucc_geth_memclean(ugeth);
+       dev_set_drvdata(device, NULL);
 
        return 0;
 }
 
-/* Structure for a device driver */
-static struct device_driver ucc_geth_driver = {
-       .name = DRV_NAME,
-       .bus = &platform_bus_type,
-       .probe = ucc_geth_probe,
-       .remove = ucc_geth_remove,
+static struct of_device_id ucc_geth_match[] = {
+       {
+               .type = "network",
+               .compatible = "ucc_geth",
+       },
+       {},
+};
+
+MODULE_DEVICE_TABLE(of, ucc_geth_match);
+
+static struct of_platform_driver ucc_geth_driver = {
+       .name           = DRV_NAME,
+       .match_table    = ucc_geth_match,
+       .probe          = ucc_geth_probe,
+       .remove         = ucc_geth_remove,
 };
 
 static int __init ucc_geth_init(void)
 {
-       int i;
-       printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
+       int i, ret;
+
+       if (netif_msg_drv(&debug))
+               printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
        for (i = 0; i < 8; i++)
                memcpy(&(ugeth_info[i]), &ugeth_primary_info,
                       sizeof(ugeth_primary_info));
 
-       return driver_register(&ucc_geth_driver);
+       ret = of_register_platform_driver(&ucc_geth_driver);
+
+       return ret;
 }
 
 static void __exit ucc_geth_exit(void)
 {
-       driver_unregister(&ucc_geth_driver);
+       of_unregister_platform_driver(&ucc_geth_driver);
 }
 
 module_init(ucc_geth_init);
@@ -4259,4 +3908,5 @@ module_exit(ucc_geth_exit);
 
 MODULE_AUTHOR("Freescale Semiconductor, Inc");
 MODULE_DESCRIPTION(DRV_DESC);
+MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE("GPL");