Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[safe/jmp/linux-2.6] / drivers / net / ibm_newemac / core.c
index 58dfd32..89c82c5 100644 (file)
@@ -134,7 +134,7 @@ static inline void emac_report_timeout_error(struct emac_instance *dev,
                                  EMAC_FTR_440EP_PHY_CLK_FIX))
                DBG(dev, "%s" NL, error);
        else if (net_ratelimit())
-               printk(KERN_ERR "%s: %s\n", dev->ndev->name, error);
+               printk(KERN_ERR "%s: %s\n", dev->ofdev->node->full_name, error);
 }
 
 /* EMAC PHY clock workaround:
@@ -202,13 +202,15 @@ static inline int emac_phy_supports_gige(int phy_mode)
 {
        return  phy_mode == PHY_MODE_GMII ||
                phy_mode == PHY_MODE_RGMII ||
+               phy_mode == PHY_MODE_SGMII ||
                phy_mode == PHY_MODE_TBI ||
                phy_mode == PHY_MODE_RTBI;
 }
 
 static inline int emac_phy_gpcs(int phy_mode)
 {
-       return  phy_mode == PHY_MODE_TBI ||
+       return  phy_mode == PHY_MODE_SGMII ||
+               phy_mode == PHY_MODE_TBI ||
                phy_mode == PHY_MODE_RTBI;
 }
 
@@ -394,9 +396,7 @@ static void emac_hash_mc(struct emac_instance *dev)
 
        for (dmi = dev->ndev->mc_list; dmi; dmi = dmi->next) {
                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]);
+               DBG2(dev, "mc %pM" NL, dmi->dmi_addr);
 
                slot = EMAC_XAHT_CRC_TO_SLOT(dev, ether_crc(ETH_ALEN, dmi->dmi_addr));
                reg = EMAC_XAHT_SLOT_TO_REG(dev, slot);
@@ -562,8 +562,9 @@ static int emac_configure(struct emac_instance *dev)
        switch (dev->phy.speed) {
        case SPEED_1000:
                if (emac_phy_gpcs(dev->phy.mode)) {
-                       mr1 |= EMAC_MR1_MF_1000GPCS |
-                               EMAC_MR1_MF_IPPA(dev->phy.address);
+                       mr1 |= EMAC_MR1_MF_1000GPCS | EMAC_MR1_MF_IPPA(
+                               (dev->phy.gpcs_address != 0xffffffff) ?
+                                dev->phy.gpcs_address : dev->phy.address);
 
                        /* Put some arbitrary OUI, Manuf & Rev IDs so we can
                         * identify this GPCS PHY later.
@@ -675,8 +676,12 @@ static int emac_configure(struct emac_instance *dev)
        out_be32(&p->iser,  r);
 
        /* We need to take GPCS PHY out of isolate mode after EMAC reset */
-       if (emac_phy_gpcs(dev->phy.mode))
-               emac_mii_reset_phy(&dev->phy);
+       if (emac_phy_gpcs(dev->phy.mode)) {
+               if (dev->phy.gpcs_address != 0xffffffff)
+                       emac_mii_reset_gpcs(&dev->phy);
+               else
+                       emac_mii_reset_phy(&dev->phy);
+       }
 
        return 0;
 }
@@ -881,7 +886,9 @@ static int emac_mdio_read(struct net_device *ndev, int id, int reg)
        struct emac_instance *dev = netdev_priv(ndev);
        int res;
 
-       res = __emac_mdio_read(dev->mdio_instance ? dev->mdio_instance : dev,
+       res = __emac_mdio_read((dev->mdio_instance &&
+                               dev->phy.gpcs_address != id) ?
+                               dev->mdio_instance : dev,
                               (u8) id, (u8) reg);
        return res;
 }
@@ -890,7 +897,9 @@ static void emac_mdio_write(struct net_device *ndev, int id, int reg, int val)
 {
        struct emac_instance *dev = netdev_priv(ndev);
 
-       __emac_mdio_write(dev->mdio_instance ? dev->mdio_instance : dev,
+       __emac_mdio_write((dev->mdio_instance &&
+                          dev->phy.gpcs_address != id) ?
+                          dev->mdio_instance : dev,
                          (u8) id, (u8) reg, (u16) val);
 }
 
@@ -1220,7 +1229,7 @@ static int emac_link_differs(struct emac_instance *dev)
 static void emac_link_timer(struct work_struct *work)
 {
        struct emac_instance *dev =
-               container_of((struct delayed_work *)work,
+               container_of(to_delayed_work(work),
                             struct emac_instance, link_work);
        int link_poll_interval;
 
@@ -1296,6 +1305,8 @@ static int emac_close(struct net_device *ndev)
 
        free_irq(dev->emac_irq, dev);
 
+       netif_carrier_off(ndev);
+
        return 0;
 }
 
@@ -1333,7 +1344,7 @@ static inline int emac_xmit_finish(struct emac_instance *dev, int len)
        ++dev->stats.tx_packets;
        dev->stats.tx_bytes += len;
 
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 /* Tx lock BH */
@@ -1475,7 +1486,7 @@ static int emac_start_xmit_sg(struct sk_buff *skb, struct net_device *ndev)
  stop_queue:
        netif_stop_queue(ndev);
        DBG2(dev, "stopped TX queue" NL);
-       return 1;
+       return NETDEV_TX_BUSY;
 }
 
 /* Tx lock BHs */
@@ -2198,7 +2209,7 @@ static const struct ethtool_ops emac_ethtool_ops = {
 static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 {
        struct emac_instance *dev = netdev_priv(ndev);
-       uint16_t *data = (uint16_t *) & rq->ifr_ifru;
+       struct mii_ioctl_data *data = if_mii(rq);
 
        DBG(dev, "ioctl %08x" NL, cmd);
 
@@ -2207,19 +2218,16 @@ static int emac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
 
        switch (cmd) {
        case SIOCGMIIPHY:
-       case SIOCDEVPRIVATE:
-               data[0] = dev->phy.address;
+               data->phy_id = dev->phy.address;
                /* Fall through */
        case SIOCGMIIREG:
-       case SIOCDEVPRIVATE + 1:
-               data[3] = emac_mdio_read(ndev, dev->phy.address, data[1]);
+               data->val_out = emac_mdio_read(ndev, dev->phy.address,
+                                              data->reg_num);
                return 0;
 
        case SIOCSMIIREG:
-       case SIOCDEVPRIVATE + 2:
-               if (!capable(CAP_NET_ADMIN))
-                       return -EPERM;
-               emac_mdio_write(ndev, dev->phy.address, data[1], data[2]);
+               emac_mdio_write(ndev, dev->phy.address, data->reg_num,
+                               data->val_in);
                return 0;
        default:
                return -EOPNOTSUPP;
@@ -2382,7 +2390,11 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
                 * XXX I probably should move these settings to the dev tree
                 */
                dev->phy.address = -1;
-               dev->phy.features = SUPPORTED_100baseT_Full | SUPPORTED_MII;
+               dev->phy.features = SUPPORTED_MII;
+               if (emac_phy_supports_gige(dev->phy_mode))
+                       dev->phy.features |= SUPPORTED_1000baseT_Full;
+               else
+                       dev->phy.features |= SUPPORTED_100baseT_Full;
                dev->phy.pause = 1;
 
                return 0;
@@ -2421,7 +2433,9 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
                 * Note that the busy_phy_map is currently global
                 * while it should probably be per-ASIC...
                 */
-               dev->phy.address = dev->cell_index;
+               dev->phy.gpcs_address = dev->gpcs_address;
+               if (dev->phy.gpcs_address == 0xffffffff)
+                       dev->phy.address = dev->cell_index;
        }
 
        emac_configure(dev);
@@ -2531,6 +2545,8 @@ static int __devinit emac_init_config(struct emac_instance *dev)
                dev->phy_address = 0xffffffff;
        if (emac_read_uint_prop(np, "phy-map", &dev->phy_map, 0))
                dev->phy_map = 0xffffffff;
+       if (emac_read_uint_prop(np, "gpcs-address", &dev->gpcs_address, 0))
+               dev->gpcs_address = 0xffffffff;
        if (emac_read_uint_prop(np->parent, "clock-frequency", &dev->opb_bus_freq, 1))
                return -ENXIO;
        if (emac_read_uint_prop(np, "tah-device", &dev->tah_ph, 0))
@@ -2540,13 +2556,13 @@ static int __devinit emac_init_config(struct emac_instance *dev)
        if (emac_read_uint_prop(np, "mdio-device", &dev->mdio_ph, 0))
                dev->mdio_ph = 0;
        if (emac_read_uint_prop(np, "zmii-device", &dev->zmii_ph, 0))
-               dev->zmii_ph = 0;;
+               dev->zmii_ph = 0;
        if (emac_read_uint_prop(np, "zmii-channel", &dev->zmii_port, 0))
-               dev->zmii_port = 0xffffffff;;
+               dev->zmii_port = 0xffffffff;
        if (emac_read_uint_prop(np, "rgmii-device", &dev->rgmii_ph, 0))
-               dev->rgmii_ph = 0;;
+               dev->rgmii_ph = 0;
        if (emac_read_uint_prop(np, "rgmii-channel", &dev->rgmii_port, 0))
-               dev->rgmii_port = 0xffffffff;;
+               dev->rgmii_port = 0xffffffff;
        if (emac_read_uint_prop(np, "fifo-entry-size", &dev->fifo_entry_size, 0))
                dev->fifo_entry_size = 16;
        if (emac_read_uint_prop(np, "mal-burst-size", &dev->mal_burst_size, 0))
@@ -2577,6 +2593,9 @@ static int __devinit emac_init_config(struct emac_instance *dev)
                if (of_device_is_compatible(np, "ibm,emac-460ex") ||
                    of_device_is_compatible(np, "ibm,emac-460gt"))
                        dev->features |= EMAC_FTR_460EX_PHY_CLK_FIX;
+               if (of_device_is_compatible(np, "ibm,emac-405ex") ||
+                   of_device_is_compatible(np, "ibm,emac-405exr"))
+                       dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX;
        } else if (of_device_is_compatible(np, "ibm,emac4")) {
                dev->features |= EMAC_FTR_EMAC4;
                if (of_device_is_compatible(np, "ibm,emac-440gx"))
@@ -2585,6 +2604,16 @@ static int __devinit emac_init_config(struct emac_instance *dev)
                if (of_device_is_compatible(np, "ibm,emac-440ep") ||
                    of_device_is_compatible(np, "ibm,emac-440gr"))
                        dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX;
+               if (of_device_is_compatible(np, "ibm,emac-405ez")) {
+#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL
+                       dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x;
+#else
+                       printk(KERN_ERR "%s: Flow control not disabled!\n",
+                                       np->full_name);
+                       return -ENXIO;
+#endif
+               }
+
        }
 
        /* Fixup some feature bits based on the device tree */
@@ -2656,6 +2685,32 @@ static int __devinit emac_init_config(struct emac_instance *dev)
        return 0;
 }
 
+static const struct net_device_ops emac_netdev_ops = {
+       .ndo_open               = emac_open,
+       .ndo_stop               = emac_close,
+       .ndo_get_stats          = emac_stats,
+       .ndo_set_multicast_list = emac_set_multicast_list,
+       .ndo_do_ioctl           = emac_ioctl,
+       .ndo_tx_timeout         = emac_tx_timeout,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_start_xmit         = emac_start_xmit,
+       .ndo_change_mtu         = eth_change_mtu,
+};
+
+static const struct net_device_ops emac_gige_netdev_ops = {
+       .ndo_open               = emac_open,
+       .ndo_stop               = emac_close,
+       .ndo_get_stats          = emac_stats,
+       .ndo_set_multicast_list = emac_set_multicast_list,
+       .ndo_do_ioctl           = emac_ioctl,
+       .ndo_tx_timeout         = emac_tx_timeout,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_start_xmit         = emac_start_xmit_sg,
+       .ndo_change_mtu         = emac_change_mtu,
+};
+
 static int __devinit emac_probe(struct of_device *ofdev,
                                const struct of_device_id *match)
 {
@@ -2797,23 +2852,14 @@ static int __devinit emac_probe(struct of_device *ofdev,
        if (err != 0)
                goto err_detach_tah;
 
-       /* Fill in the driver function table */
-       ndev->open = &emac_open;
        if (dev->tah_dev)
                ndev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-       ndev->tx_timeout = &emac_tx_timeout;
        ndev->watchdog_timeo = 5 * HZ;
-       ndev->stop = &emac_close;
-       ndev->get_stats = &emac_stats;
-       ndev->set_multicast_list = &emac_set_multicast_list;
-       ndev->do_ioctl = &emac_ioctl;
        if (emac_phy_supports_gige(dev->phy_mode)) {
-               ndev->hard_start_xmit = &emac_start_xmit_sg;
-               ndev->change_mtu = &emac_change_mtu;
+               ndev->netdev_ops = &emac_gige_netdev_ops;
                dev->commac.ops = &emac_commac_sg_ops;
-       } else {
-               ndev->hard_start_xmit = &emac_start_xmit;
-       }
+       } else
+               ndev->netdev_ops = &emac_netdev_ops;
        SET_ETHTOOL_OPS(ndev, &emac_ethtool_ops);
 
        netif_carrier_off(ndev);
@@ -2836,11 +2882,11 @@ static int __devinit emac_probe(struct of_device *ofdev,
        wake_up_all(&emac_probe_wait);
 
 
-       printk(KERN_INFO
-              "%s: EMAC-%d %s, MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
-              ndev->name, dev->cell_index, np->full_name,
-              ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
-              ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+       printk(KERN_INFO "%s: EMAC-%d %s, MAC %pM\n",
+              ndev->name, dev->cell_index, np->full_name, ndev->dev_addr);
+
+       if (dev->phy_mode == PHY_MODE_SGMII)
+               printk(KERN_NOTICE "%s: in SGMII mode\n", ndev->name);
 
        if (dev->phy.address >= 0)
                printk("%s: found %s PHY (0x%02x)\n", ndev->name,