Merge git://git.kernel.org/pub/scm/linux/kernel/git/lethal/sh-2.6
[safe/jmp/linux-2.6] / drivers / net / ll_temac_main.c
index a8522bd..52dcc84 100644 (file)
@@ -20,9 +20,6 @@
  *   or rx, so this should be okay.
  *
  * TODO:
- * - Fix driver to work on more than just Virtex5.  Right now the driver
- *   assumes that the locallink DMA registers are accessed via DCR
- *   instructions.
  * - Factor out locallink DMA code into separate driver
  * - Fix multicast assignment.
  * - Fix support for hardware checksumming.
@@ -49,6 +46,7 @@
 #include <linux/in.h>
 #include <linux/io.h>
 #include <linux/ip.h>
+#include <linux/slab.h>
 
 #include "ll_temac.h"
 
@@ -115,17 +113,86 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
        temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
 }
 
+/**
+ * temac_dma_in32 - Memory mapped DMA read, this function expects a
+ * register input that is based on DCR word addresses which
+ * are then converted to memory mapped byte addresses
+ */
 static u32 temac_dma_in32(struct temac_local *lp, int reg)
 {
-       return dcr_read(lp->sdma_dcrs, reg);
+       return in_be32((u32 *)(lp->sdma_regs + (reg << 2)));
 }
 
+/**
+ * temac_dma_out32 - Memory mapped DMA read, this function expects a
+ * register input that is based on DCR word addresses which
+ * are then converted to memory mapped byte addresses
+ */
 static void temac_dma_out32(struct temac_local *lp, int reg, u32 value)
 {
+       out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value);
+}
+
+/* DMA register access functions can be DCR based or memory mapped.
+ * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both
+ * memory mapped.
+ */
+#ifdef CONFIG_PPC_DCR
+
+/**
+ * temac_dma_dcr_in32 - DCR based DMA read
+ */
+static u32 temac_dma_dcr_in(struct temac_local *lp, int reg)
+{
+       return dcr_read(lp->sdma_dcrs, reg);
+}
+
+/**
+ * temac_dma_dcr_out32 - DCR based DMA write
+ */
+static void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value)
+{
        dcr_write(lp->sdma_dcrs, reg, value);
 }
 
 /**
+ * temac_dcr_setup - If the DMA is DCR based, then setup the address and
+ * I/O  functions
+ */
+static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,
+                               struct device_node *np)
+{
+       unsigned int dcrs;
+
+       /* setup the dcr address mapping if it's in the device tree */
+
+       dcrs = dcr_resource_start(np, 0);
+       if (dcrs != 0) {
+               lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
+               lp->dma_in = temac_dma_dcr_in;
+               lp->dma_out = temac_dma_dcr_out;
+               dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
+               return 0;
+       }
+       /* no DCR in the device tree, indicate a failure */
+       return -1;
+}
+
+#else
+
+/*
+ * temac_dcr_setup - This is a stub for when DCR is not supported,
+ * such as with MicroBlaze
+ */
+static int temac_dcr_setup(struct temac_local *lp, struct of_device *op,
+                               struct device_node *np)
+{
+       return -1;
+}
+
+#endif
+
+/**
  * temac_dma_bd_init - Setup buffer descriptor rings
  */
 static int temac_dma_bd_init(struct net_device *ndev)
@@ -155,14 +222,14 @@ static int temac_dma_bd_init(struct net_device *ndev)
                lp->rx_bd_v[i].next = lp->rx_bd_p +
                                sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM);
 
-               skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE
-                               + XTE_ALIGN, GFP_ATOMIC);
+               skb = netdev_alloc_skb_ip_align(ndev,
+                                               XTE_MAX_JUMBO_FRAME_SIZE);
+
                if (skb == 0) {
                        dev_err(&ndev->dev, "alloc_skb error %d\n", i);
                        return -1;
                }
                lp->rx_skb[i] = skb;
-               skb_reserve(skb,  BUFFER_ALIGN(skb->data));
                /* returns physical address of skb->data */
                lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent,
                                                     skb->data,
@@ -172,23 +239,23 @@ static int temac_dma_bd_init(struct net_device *ndev)
                lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND;
        }
 
-       temac_dma_out32(lp, TX_CHNL_CTRL, 0x10220400 |
+       lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 |
                                          CHNL_CTRL_IRQ_EN |
                                          CHNL_CTRL_IRQ_DLY_EN |
                                          CHNL_CTRL_IRQ_COAL_EN);
        /* 0x10220483 */
        /* 0x00100483 */
-       temac_dma_out32(lp, RX_CHNL_CTRL, 0xff010000 |
+       lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 |
                                          CHNL_CTRL_IRQ_EN |
                                          CHNL_CTRL_IRQ_DLY_EN |
                                          CHNL_CTRL_IRQ_COAL_EN |
                                          CHNL_CTRL_IRQ_IOE);
        /* 0xff010283 */
 
-       temac_dma_out32(lp, RX_CURDESC_PTR,  lp->rx_bd_p);
-       temac_dma_out32(lp, RX_TAILDESC_PTR,
+       lp->dma_out(lp, RX_CURDESC_PTR,  lp->rx_bd_p);
+       lp->dma_out(lp, RX_TAILDESC_PTR,
                       lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1)));
-       temac_dma_out32(lp, TX_CURDESC_PTR, lp->tx_bd_p);
+       lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p);
 
        return 0;
 }
@@ -224,6 +291,13 @@ static int temac_set_mac_address(struct net_device *ndev, void *address)
        return 0;
 }
 
+static int netdev_set_mac_address(struct net_device *ndev, void *p)
+{
+       struct sockaddr *addr = p;
+
+       return temac_set_mac_address(ndev, addr->sa_data);
+}
+
 static void temac_set_multicast_list(struct net_device *ndev)
 {
        struct temac_local *lp = netdev_priv(ndev);
@@ -232,7 +306,7 @@ static void temac_set_multicast_list(struct net_device *ndev)
 
        mutex_lock(&lp->indirect_mutex);
        if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) ||
-           ndev->mc_count > MULTICAST_CAM_TABLE_NUM) {
+           netdev_mc_count(ndev) > MULTICAST_CAM_TABLE_NUM) {
                /*
                 *      We must make the kernel realise we had to move
                 *      into promisc mode or we start all out war on
@@ -242,23 +316,24 @@ static void temac_set_multicast_list(struct net_device *ndev)
                ndev->flags |= IFF_PROMISC;
                temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK);
                dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
-       } else if (ndev->mc_count) {
-               struct dev_mc_list *mclist = ndev->mc_list;
-               for (i = 0; mclist && i < ndev->mc_count; i++) {
+       } else if (!netdev_mc_empty(ndev)) {
+               struct netdev_hw_addr *ha;
 
+               i = 0;
+               netdev_for_each_mc_addr(ha, ndev) {
                        if (i >= MULTICAST_CAM_TABLE_NUM)
                                break;
-                       multi_addr_msw = ((mclist->dmi_addr[3] << 24) |
-                                         (mclist->dmi_addr[2] << 16) |
-                                         (mclist->dmi_addr[1] << 8) |
-                                         (mclist->dmi_addr[0]));
+                       multi_addr_msw = ((ha->addr[3] << 24) |
+                                         (ha->addr[2] << 16) |
+                                         (ha->addr[1] << 8) |
+                                         (ha->addr[0]));
                        temac_indirect_out32(lp, XTE_MAW0_OFFSET,
                                             multi_addr_msw);
-                       multi_addr_lsw = ((mclist->dmi_addr[5] << 8) |
-                                         (mclist->dmi_addr[4]) | (i << 16));
+                       multi_addr_lsw = ((ha->addr[5] << 8) |
+                                         (ha->addr[4]) | (i << 16));
                        temac_indirect_out32(lp, XTE_MAW1_OFFSET,
                                             multi_addr_lsw);
-                       mclist = mclist->next;
+                       i++;
                }
        } else {
                val = temac_indirect_in32(lp, XTE_AFM_OFFSET);
@@ -418,9 +493,9 @@ static void temac_device_reset(struct net_device *ndev)
        temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK);
 
        /* Reset Local Link (DMA) */
-       temac_dma_out32(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
+       lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
        timeout = 1000;
-       while (temac_dma_in32(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
+       while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
                udelay(1);
                if (--timeout == 0) {
                        dev_err(&ndev->dev,
@@ -428,7 +503,7 @@ static void temac_device_reset(struct net_device *ndev)
                        break;
                }
        }
-       temac_dma_out32(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
+       lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
 
        temac_dma_bd_init(ndev);
 
@@ -452,7 +527,7 @@ static void temac_device_reset(struct net_device *ndev)
                dev_err(&ndev->dev, "Error setting TEMAC options\n");
 
        /* Init Driver variable */
-       ndev->trans_start = 0;
+       ndev->trans_start = jiffies; /* prevent tx timeout */
 }
 
 void temac_adjust_link(struct net_device *ndev)
@@ -499,6 +574,10 @@ static void temac_start_xmit_done(struct net_device *ndev)
                if (cur_p->app4)
                        dev_kfree_skb_irq((struct sk_buff *)cur_p->app4);
                cur_p->app0 = 0;
+               cur_p->app1 = 0;
+               cur_p->app2 = 0;
+               cur_p->app3 = 0;
+               cur_p->app4 = 0;
 
                ndev->stats.tx_packets++;
                ndev->stats.tx_bytes += cur_p->len;
@@ -514,6 +593,29 @@ static void temac_start_xmit_done(struct net_device *ndev)
        netif_wake_queue(ndev);
 }
 
+static inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag)
+{
+       struct cdmac_bd *cur_p;
+       int tail;
+
+       tail = lp->tx_bd_tail;
+       cur_p = &lp->tx_bd_v[tail];
+
+       do {
+               if (cur_p->app0)
+                       return NETDEV_TX_BUSY;
+
+               tail++;
+               if (tail >= TX_BD_NUM)
+                       tail = 0;
+
+               cur_p = &lp->tx_bd_v[tail];
+               num_frag--;
+       } while (num_frag >= 0);
+
+       return 0;
+}
+
 static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 {
        struct temac_local *lp = netdev_priv(ndev);
@@ -528,7 +630,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
        start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
        cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
 
-       if (cur_p->app0 & STS_CTRL_APP0_CMPLT) {
+       if (temac_check_tx_bd_space(lp, num_frag)) {
                if (!netif_queue_stopped(ndev)) {
                        netif_stop_queue(ndev);
                        return NETDEV_TX_BUSY;
@@ -538,29 +640,14 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
        cur_p->app0 = 0;
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
-               const struct iphdr *ip = ip_hdr(skb);
-               int length = 0, start = 0, insert = 0;
-
-               switch (ip->protocol) {
-               case IPPROTO_TCP:
-                       start = sizeof(struct iphdr) + ETH_HLEN;
-                       insert = sizeof(struct iphdr) + ETH_HLEN + 16;
-                       length = ip->tot_len - sizeof(struct iphdr);
-                       break;
-               case IPPROTO_UDP:
-                       start = sizeof(struct iphdr) + ETH_HLEN;
-                       insert = sizeof(struct iphdr) + ETH_HLEN + 6;
-                       length = ip->tot_len - sizeof(struct iphdr);
-                       break;
-               default:
-                       break;
-               }
-               cur_p->app1 = ((start << 16) | insert);
-               cur_p->app2 = csum_tcpudp_magic(ip->saddr, ip->daddr,
-                                               length, ip->protocol, 0);
-               skb->data[insert] = 0;
-               skb->data[insert + 1] = 0;
+               unsigned int csum_start_off = skb_transport_offset(skb);
+               unsigned int csum_index_off = csum_start_off + skb->csum_offset;
+
+               cur_p->app0 |= 1; /* TX Checksum Enabled */
+               cur_p->app1 = (csum_start_off << 16) | csum_index_off;
+               cur_p->app2 = 0;  /* initial checksum seed */
        }
+
        cur_p->app0 |= STS_CTRL_APP0_SOP;
        cur_p->len = skb_headlen(skb);
        cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
@@ -589,7 +676,7 @@ static int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                lp->tx_bd_tail = 0;
 
        /* Kick off the transfer */
-       temac_dma_out32(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
+       lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
 
        return NETDEV_TX_OK;
 }
@@ -603,7 +690,6 @@ static void ll_temac_recv(struct net_device *ndev)
        struct cdmac_bd *cur_p;
        dma_addr_t tail_p;
        int length;
-       unsigned long skb_vaddr;
        unsigned long flags;
 
        spin_lock_irqsave(&lp->rx_lock, flags);
@@ -615,10 +701,9 @@ static void ll_temac_recv(struct net_device *ndev)
        while ((bdstat & STS_CTRL_APP0_CMPLT)) {
 
                skb = lp->rx_skb[lp->rx_bd_ci];
-               length = cur_p->app4;
+               length = cur_p->app4 & 0x3FFF;
 
-               skb_vaddr = virt_to_bus(skb->data);
-               dma_unmap_single(ndev->dev.parent, skb_vaddr, length,
+               dma_unmap_single(ndev->dev.parent, cur_p->phys, length,
                                 DMA_FROM_DEVICE);
 
                skb_put(skb, length);
@@ -626,21 +711,29 @@ static void ll_temac_recv(struct net_device *ndev)
                skb->protocol = eth_type_trans(skb, ndev);
                skb->ip_summed = CHECKSUM_NONE;
 
+               /* if we're doing rx csum offload, set it up */
+               if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) &&
+                       (skb->protocol == __constant_htons(ETH_P_IP)) &&
+                       (skb->len > 64)) {
+
+                       skb->csum = cur_p->app3 & 0xFFFF;
+                       skb->ip_summed = CHECKSUM_COMPLETE;
+               }
+
                netif_rx(skb);
 
                ndev->stats.rx_packets++;
                ndev->stats.rx_bytes += length;
 
-               new_skb = alloc_skb(XTE_MAX_JUMBO_FRAME_SIZE + XTE_ALIGN,
-                               GFP_ATOMIC);
+               new_skb = netdev_alloc_skb_ip_align(ndev,
+                                               XTE_MAX_JUMBO_FRAME_SIZE);
+
                if (new_skb == 0) {
                        dev_err(&ndev->dev, "no memory for new sk_buff\n");
                        spin_unlock_irqrestore(&lp->rx_lock, flags);
                        return;
                }
 
-               skb_reserve(new_skb, BUFFER_ALIGN(new_skb->data));
-
                cur_p->app0 = STS_CTRL_APP0_IRQONEND;
                cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data,
                                             XTE_MAX_JUMBO_FRAME_SIZE,
@@ -655,7 +748,7 @@ static void ll_temac_recv(struct net_device *ndev)
                cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
                bdstat = cur_p->app0;
        }
-       temac_dma_out32(lp, RX_TAILDESC_PTR, tail_p);
+       lp->dma_out(lp, RX_TAILDESC_PTR, tail_p);
 
        spin_unlock_irqrestore(&lp->rx_lock, flags);
 }
@@ -666,8 +759,8 @@ static irqreturn_t ll_temac_tx_irq(int irq, void *_ndev)
        struct temac_local *lp = netdev_priv(ndev);
        unsigned int status;
 
-       status = temac_dma_in32(lp, TX_IRQ_REG);
-       temac_dma_out32(lp, TX_IRQ_REG, status);
+       status = lp->dma_in(lp, TX_IRQ_REG);
+       lp->dma_out(lp, TX_IRQ_REG, status);
 
        if (status & (IRQ_COAL | IRQ_DLY))
                temac_start_xmit_done(lp->ndev);
@@ -684,8 +777,8 @@ static irqreturn_t ll_temac_rx_irq(int irq, void *_ndev)
        unsigned int status;
 
        /* Read and clear the status registers */
-       status = temac_dma_in32(lp, RX_IRQ_REG);
-       temac_dma_out32(lp, RX_IRQ_REG, status);
+       status = lp->dma_in(lp, RX_IRQ_REG);
+       lp->dma_out(lp, RX_IRQ_REG, status);
 
        if (status & (IRQ_COAL | IRQ_DLY))
                ll_temac_recv(lp->ndev);
@@ -768,7 +861,7 @@ static const struct net_device_ops temac_netdev_ops = {
        .ndo_open = temac_open,
        .ndo_stop = temac_stop,
        .ndo_start_xmit = temac_start_xmit,
-       .ndo_set_mac_address = temac_set_mac_address,
+       .ndo_set_mac_address = netdev_set_mac_address,
        //.ndo_set_multicast_list = temac_set_multicast_list,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller = temac_poll_controller,
@@ -786,7 +879,7 @@ static ssize_t temac_show_llink_regs(struct device *dev,
        int i, len = 0;
 
        for (i = 0; i < 0x11; i++)
-               len += sprintf(buf + len, "%.8x%s", temac_dma_in32(lp, i),
+               len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i),
                               (i % 8) == 7 ? "\n" : " ");
        len += sprintf(buf + len, "\n");
 
@@ -811,8 +904,8 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
        struct temac_local *lp;
        struct net_device *ndev;
        const void *addr;
+       __be32 *p;
        int size, rc = 0;
-       unsigned int dcrs;
 
        /* Init network device structure */
        ndev = alloc_etherdev(sizeof(*lp));
@@ -849,30 +942,49 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
        mutex_init(&lp->indirect_mutex);
 
        /* map device registers */
-       lp->regs = of_iomap(op->node, 0);
+       lp->regs = of_iomap(op->dev.of_node, 0);
        if (!lp->regs) {
                dev_err(&op->dev, "could not map temac regs.\n");
                goto nodev;
        }
 
+       /* Setup checksum offload, but default to off if not specified */
+       lp->temac_features = 0;
+       p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL);
+       if (p && be32_to_cpu(*p)) {
+               lp->temac_features |= TEMAC_FEATURE_TX_CSUM;
+               /* Can checksum TCP/UDP over IPv4. */
+               ndev->features |= NETIF_F_IP_CSUM;
+       }
+       p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL);
+       if (p && be32_to_cpu(*p))
+               lp->temac_features |= TEMAC_FEATURE_RX_CSUM;
+
        /* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
-       np = of_parse_phandle(op->node, "llink-connected", 0);
+       np = of_parse_phandle(op->dev.of_node, "llink-connected", 0);
        if (!np) {
                dev_err(&op->dev, "could not find DMA node\n");
                goto nodev;
        }
 
-       dcrs = dcr_resource_start(np, 0);
-       if (dcrs == 0) {
-               dev_err(&op->dev, "could not get DMA register address\n");
-               goto nodev;
+       /* Setup the DMA register accesses, could be DCR or memory mapped */
+       if (temac_dcr_setup(lp, op, np)) {
+
+               /* no DCR in the device tree, try non-DCR */
+               lp->sdma_regs = of_iomap(np, 0);
+               if (lp->sdma_regs) {
+                       lp->dma_in = temac_dma_in32;
+                       lp->dma_out = temac_dma_out32;
+                       dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs);
+               } else {
+                       dev_err(&op->dev, "unable to map DMA registers\n");
+                       goto nodev;
+               }
        }
-       lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
-       dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
 
        lp->rx_irq = irq_of_parse_and_map(np, 0);
        lp->tx_irq = irq_of_parse_and_map(np, 1);
-       if (!lp->rx_irq || !lp->tx_irq) {
+       if ((lp->rx_irq == NO_IRQ) || (lp->tx_irq == NO_IRQ)) {
                dev_err(&op->dev, "could not determine irqs\n");
                rc = -ENOMEM;
                goto nodev;
@@ -881,7 +993,7 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
        of_node_put(np); /* Finished with the DMA node; drop the reference */
 
        /* Retrieve the MAC address */
-       addr = of_get_property(op->node, "local-mac-address", &size);
+       addr = of_get_property(op->dev.of_node, "local-mac-address", &size);
        if ((!addr) || (size != 6)) {
                dev_err(&op->dev, "could not find MAC address\n");
                rc = -ENODEV;
@@ -889,11 +1001,11 @@ temac_of_probe(struct of_device *op, const struct of_device_id *match)
        }
        temac_set_mac_address(ndev, (void *)addr);
 
-       rc = temac_mdio_setup(lp, op->node);
+       rc = temac_mdio_setup(lp, op->dev.of_node);
        if (rc)
                dev_warn(&op->dev, "error registering MDIO bus\n");
 
-       lp->phy_node = of_parse_phandle(op->node, "phy-handle", 0);
+       lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0);
        if (lp->phy_node)
                dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np);
 
@@ -938,17 +1050,20 @@ static int __devexit temac_of_remove(struct of_device *op)
 
 static struct of_device_id temac_of_match[] __devinitdata = {
        { .compatible = "xlnx,xps-ll-temac-1.01.b", },
+       { .compatible = "xlnx,xps-ll-temac-2.00.a", },
+       { .compatible = "xlnx,xps-ll-temac-2.02.a", },
+       { .compatible = "xlnx,xps-ll-temac-2.03.a", },
        {},
 };
 MODULE_DEVICE_TABLE(of, temac_of_match);
 
 static struct of_platform_driver temac_of_driver = {
-       .match_table = temac_of_match,
        .probe = temac_of_probe,
        .remove = __devexit_p(temac_of_remove),
        .driver = {
                .owner = THIS_MODULE,
                .name = "xilinx_temac",
+               .of_match_table = temac_of_match,
        },
 };