Merge commit 'origin/HEAD' into test-merge
[sfrench/cifs-2.6.git] / drivers / net / ibm_newemac / core.c
index babc79ad490b6ada422a3ce96f9fefd510050b65..61af02b4c9d88b88365e1917d47193c23a61d475 100644 (file)
@@ -363,25 +363,31 @@ static int emac_reset(struct emac_instance *dev)
 
 static void emac_hash_mc(struct emac_instance *dev)
 {
-       struct emac_regs __iomem *p = dev->emacp;
-       u16 gaht[4] = { 0 };
+       const int regs = EMAC_XAHT_REGS(dev);
+       u32 *gaht_base = emac_gaht_base(dev);
+       u32 gaht_temp[regs];
        struct dev_mc_list *dmi;
+       int i;
 
        DBG(dev, "hash_mc %d" NL, dev->ndev->mc_count);
 
+       memset(gaht_temp, 0, sizeof (gaht_temp));
+
        for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
-               int bit;
+               int slot, reg, mask;
                DBG2(dev, "mc %02x:%02x:%02x:%02x:%02x:%02x" NL,
                     dmi->dmi_addr[0], dmi->dmi_addr[1], dmi->dmi_addr[2],
                     dmi->dmi_addr[3], dmi->dmi_addr[4], dmi->dmi_addr[5]);
 
-               bit = 63 - (ether_crc(ETH_ALEN, dmi->dmi_addr) >> 26);
-               gaht[bit >> 4] |= 0x8000 >> (bit & 0x0f);
+               slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr));
+               reg = EMAC_XAHT_SLOT_TO_REG(dev, slot);
+               mask = EMAC_XAHT_SLOT_TO_MASK(dev, slot);
+
+               gaht_temp[reg] |= mask;
        }
-       out_be32(&p->gaht1, gaht[0]);
-       out_be32(&p->gaht2, gaht[1]);
-       out_be32(&p->gaht3, gaht[2]);
-       out_be32(&p->gaht4, gaht[3]);
+
+       for (i = 0; i < regs; i++)
+               out_be32(gaht_base + i, gaht_temp[i]);
 }
 
 static inline u32 emac_iff2rmr(struct net_device *ndev)
@@ -398,7 +404,8 @@ static inline u32 emac_iff2rmr(struct net_device *ndev)
 
        if (ndev->flags & IFF_PROMISC)
                r |= EMAC_RMR_PME;
-       else if (ndev->flags & IFF_ALLMULTI || ndev->mc_count > 32)
+       else if (ndev->flags & IFF_ALLMULTI ||
+                        (ndev->mc_count > EMAC_XAHT_SLOTS(dev)))
                r |= EMAC_RMR_PMME;
        else if (ndev->mc_count > 0)
                r |= EMAC_RMR_MAE;
@@ -542,7 +549,7 @@ static int emac_configure(struct emac_instance *dev)
                        /* Put some arbitrary OUI, Manuf & Rev IDs so we can
                         * identify this GPCS PHY later.
                         */
-                       out_be32(&p->ipcr, 0xdeadbeef);
+                       out_be32(&p->u1.emac4.ipcr, 0xdeadbeef);
                } else
                        mr1 |= EMAC_MR1_MF_1000;
 
@@ -2021,10 +2028,10 @@ static int emac_get_regs_len(struct emac_instance *dev)
 {
        if (emac_has_feature(dev, EMAC_FTR_EMAC4))
                return sizeof(struct emac_ethtool_regs_subhdr) +
-                       EMAC4_ETHTOOL_REGS_SIZE;
+                       EMAC4_ETHTOOL_REGS_SIZE(dev);
        else
                return sizeof(struct emac_ethtool_regs_subhdr) +
-                       EMAC_ETHTOOL_REGS_SIZE;
+                       EMAC_ETHTOOL_REGS_SIZE(dev);
 }
 
 static int emac_ethtool_get_regs_len(struct net_device *ndev)
@@ -2051,12 +2058,12 @@ static void *emac_dump_regs(struct emac_instance *dev, void *buf)
        hdr->index = dev->cell_index;
        if (emac_has_feature(dev, EMAC_FTR_EMAC4)) {
                hdr->version = EMAC4_ETHTOOL_REGS_VER;
-               memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE);
-               return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE);
+               memcpy_fromio(hdr + 1, dev->emacp, EMAC4_ETHTOOL_REGS_SIZE(dev));
+               return ((void *)(hdr + 1) + EMAC4_ETHTOOL_REGS_SIZE(dev));
        } else {
                hdr->version = EMAC_ETHTOOL_REGS_VER;
-               memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE);
-               return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE);
+               memcpy_fromio(hdr + 1, dev->emacp, EMAC_ETHTOOL_REGS_SIZE(dev));
+               return ((void *)(hdr + 1) + EMAC_ETHTOOL_REGS_SIZE(dev));
        }
 }
 
@@ -2546,7 +2553,9 @@ static int __devinit emac_init_config(struct emac_instance *dev)
        }
 
        /* Check EMAC version */
-       if (of_device_is_compatible(np, "ibm,emac4")) {
+       if (of_device_is_compatible(np, "ibm,emac4sync")) {
+               dev->features |= (EMAC_FTR_EMAC4 | EMAC_FTR_EMAC4SYNC);
+       } else if (of_device_is_compatible(np, "ibm,emac4")) {
                dev->features |= EMAC_FTR_EMAC4;
                if (of_device_is_compatible(np, "ibm,emac-440gx"))
                        dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX;
@@ -2607,6 +2616,15 @@ static int __devinit emac_init_config(struct emac_instance *dev)
        }
        memcpy(dev->ndev->dev_addr, p, 6);
 
+       /* IAHT and GAHT filter parameterization */
+       if (emac_has_feature(dev, EMAC_FTR_EMAC4SYNC)) {
+               dev->xaht_slots_shift = EMAC4SYNC_XAHT_SLOTS_SHIFT;
+               dev->xaht_width_shift = EMAC4SYNC_XAHT_WIDTH_SHIFT;
+       } else {
+               dev->xaht_slots_shift = EMAC4_XAHT_SLOTS_SHIFT;
+               dev->xaht_width_shift = EMAC4_XAHT_WIDTH_SHIFT;
+       }
+
        DBG(dev, "features     : 0x%08x / 0x%08x\n", dev->features, EMAC_FTRS_POSSIBLE);
        DBG(dev, "tx_fifo_size : %d (%d gige)\n", dev->tx_fifo_size, dev->tx_fifo_size_gige);
        DBG(dev, "rx_fifo_size : %d (%d gige)\n", dev->rx_fifo_size, dev->rx_fifo_size_gige);
@@ -2678,7 +2696,8 @@ static int __devinit emac_probe(struct of_device *ofdev,
                goto err_irq_unmap;
        }
        // TODO : request_mem_region
-       dev->emacp = ioremap(dev->rsrc_regs.start, sizeof(struct emac_regs));
+       dev->emacp = ioremap(dev->rsrc_regs.start,
+                            dev->rsrc_regs.end - dev->rsrc_regs.start + 1);
        if (dev->emacp == NULL) {
                printk(KERN_ERR "%s: Can't map device registers!\n",
                       np->full_name);
@@ -2892,6 +2911,10 @@ static struct of_device_id emac_match[] =
                .type           = "network",
                .compatible     = "ibm,emac4",
        },
+       {
+               .type           = "network",
+               .compatible     = "ibm,emac4sync",
+       },
        {},
 };