Following are the changes.
-This patch enables auto-negotiation.
-Loading firmware is done when spidernet_open() is called.
-And this patch adds other several small changes for Celleb. 
-This patch is not tested on CellBlade.

Signed-off-by: Kou Ishizaki <kou.ishizaki at toshiba.co.jp>
---

Dear everyone,

This is the patch (besed on powerpc-git (2006-12-05)) for spidernet driver to
work on Toshiba Cell reference set(Celleb). 
The reference set consists of Cell, 512MB memory, Super Companion Chip(SCC) 
and some peripherals such as HDD, GbE, etc. You can see brief explanation
and picture of Cell reference set at following URLs.

    http://www.toshiba.co.jp/about/press/2005_09/pr2001.htm
    http://cell-industries.com/toshiba_announces.php

This patch set is intended to be merged to 2.6.20.
If you have any comment, please write to me.

---
Index: linux-2.6.19/drivers/net/Kconfig
diff -u linux-2.6.19/drivers/net/Kconfig:1.1.1.4 
linux-2.6.19/drivers/net/Kconfig:1.6
--- linux-2.6.19/drivers/net/Kconfig:1.1.1.4    Tue Nov 14 11:15:25 2006
+++ linux-2.6.19/drivers/net/Kconfig    Fri Dec  1 15:16:10 2006
@@ -2245,7 +2245,7 @@
 
 config SPIDER_NET
        tristate "Spider Gigabit Ethernet driver"
-       depends on PCI && PPC_IBM_CELL_BLADE
+       depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB)
        select FW_LOADER
        help
          This driver supports the Gigabit Ethernet chips present on the
Index: linux-2.6.19/drivers/net/spider_net.h
diff -u linux-2.6.19/drivers/net/spider_net.h:1.1.1.2 
linux-2.6.19/drivers/net/spider_net.h:1.5
--- linux-2.6.19/drivers/net/spider_net.h:1.1.1.2       Tue Oct 17 08:42:39 2006
+++ linux-2.6.19/drivers/net/spider_net.h       Tue Nov  7 12:36:35 2006
@@ -1,7 +1,8 @@
 /*
- * Network device driver for Cell Processor-Based Blade
+ * Network device driver for Cell Processor-Based Blade and Celleb platform
  *
  * (C) Copyright IBM Corp. 2005
+ * (C) Copyright 2006 TOSHIBA CORPORATION
  *
  * Authors : Utz Bacher <[EMAIL PROTECTED]>
  *           Jens Osterkamp <[EMAIL PROTECTED]>
@@ -50,6 +51,7 @@
 #define SPIDER_NET_TX_DESCRIPTORS_MAX          512
 
 #define SPIDER_NET_TX_TIMER                    (HZ/5)
+#define SPIDER_NET_ANEG_TIMER                  (HZ*2)
 
 #define SPIDER_NET_RX_CSUM_DEFAULT             1
 
@@ -104,6 +106,7 @@
 
 #define SPIDER_NET_GMACOPEMD           0x00000100
 #define SPIDER_NET_GMACLENLMT          0x00000108
+#define SPIDER_NET_GMACST              0x00000110
 #define SPIDER_NET_GMACINTEN           0x00000118
 #define SPIDER_NET_GMACPHYCTRL         0x00000120
 
@@ -180,8 +183,8 @@
 #define SPIDER_NET_IPSECINIT_VALUE     0x6f716f71
 
 /* pause frames: automatic, no upper retransmission count */
-/* outside loopback mode: ETOMOD signal dont matter, not connected */
-#define SPIDER_NET_OPMODE_VALUE                0x00000063
+/* ETOMOD signal is brought to PHY reset. bit2 must be 1 in Celleb */
+#define SPIDER_NET_OPMODE_VALUE                0x00000067
 /*#define SPIDER_NET_OPMODE_VALUE              0x001b0062*/
 #define SPIDER_NET_LENLMT_VALUE                0x00000908
 
@@ -333,9 +336,12 @@
 /* We rely on flagged descriptor interrupts */
 #define SPIDER_NET_RXINT       ( (1 << SPIDER_NET_GDAFDCINT) )
 
+#define SPIDER_NET_LINKINT     ( 1 << SPIDER_NET_GMAC2INT )
+
 #define SPIDER_NET_ERRINT      ( 0xffffffff & \
                                  (~SPIDER_NET_TXINT) & \
-                                 (~SPIDER_NET_RXINT) )
+                                 (~SPIDER_NET_RXINT) & \
+                                 (~SPIDER_NET_LINKINT) )
 
 #define SPIDER_NET_GPREXEC                     0x80000000
 #define SPIDER_NET_GPRDAT_MASK                 0x0000ffff
@@ -447,6 +453,8 @@
 
        spinlock_t intmask_lock;
        struct tasklet_struct rxram_full_tl;
+       int aneg_count;
+       struct timer_list aneg_timer;
        struct timer_list tx_timer;
 
        struct work_struct tx_timeout_task;
Index: linux-2.6.19/drivers/net/spider_net.c
diff -u linux-2.6.19/drivers/net/spider_net.c:1.1.1.2 
linux-2.6.19/drivers/net/spider_net.c:1.10
--- linux-2.6.19/drivers/net/spider_net.c:1.1.1.2       Tue Oct 17 08:42:39 2006
+++ linux-2.6.19/drivers/net/spider_net.c       Tue Dec  5 20:30:42 2006
@@ -1,7 +1,8 @@
 /*
- * Network device driver for Cell Processor-Based Blade
+ * Network device driver for Cell Processor-Based Blade and Celleb platform
  *
  * (C) Copyright IBM Corp. 2005
+ * (C) Copyright 2006 TOSHIBA CORPORATION
  *
  * Authors : Utz Bacher <[EMAIL PROTECTED]>
  *           Jens Osterkamp <[EMAIL PROTECTED]>
@@ -78,6 +79,8 @@
 
 MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl);
 
+static int is1000 = 1;
+
 /**
  * spider_net_read_reg - reads an SMMIO register of a card
  * @card: device structure
@@ -163,6 +166,53 @@
        return readvalue;
 }
 
+static void
+spider_net_setup_aneg(struct spider_net_card *card, int is1000)
+{
+       struct mii_phy *phy = &card->phy;
+       u32 advertise = 0;
+       u16 bmcr, bmsr, ctrl1000, stat1000, estat;
+
+       bmcr     = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMCR);
+       bmsr     = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
+       ctrl1000 = spider_net_read_phy(card->netdev, phy->mii_id, MII_CTRL1000);
+       stat1000 = spider_net_read_phy(card->netdev, phy->mii_id, MII_STAT1000);
+       estat    = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS);
+
+       if (bmsr & BMSR_10HALF)
+               advertise |= ADVERTISE_10HALF;
+       if (bmsr & BMSR_10FULL)
+               advertise |= ADVERTISE_10FULL;
+       if (bmsr & BMSR_100HALF)
+               advertise |= ADVERTISE_100HALF;
+       if (bmsr & BMSR_100FULL)
+               advertise |= ADVERTISE_100FULL;
+       if (bmsr & BMSR_100BASE4)
+               advertise |= ADVERTISE_100BASE4;
+
+       if (is1000) {
+               if ((bmsr & BMSR_ESTATEN) && (estat & ESTATUS_1000_TFULL)) {
+                       advertise |= ADVERTISE_1000XFULL;
+                       ctrl1000 |= ADVERTISE_1000FULL;
+               }
+               if ((bmsr & BMSR_ESTATEN) && (estat & ESTATUS_1000_THALF)) {
+                       advertise |= ADVERTISE_1000XHALF;
+                       ctrl1000 |= ADVERTISE_1000HALF;
+               }
+
+               spider_net_write_phy(card->netdev, phy->mii_id,
+                                    MII_CTRL1000, ctrl1000);
+               spider_net_write_reg(card, SPIDER_NET_GMACMODE, 0x00000001);
+
+               phy->def->ops->setup_aneg(phy, advertise);
+       } else {
+               spider_net_write_reg(card, SPIDER_NET_GMACMODE, 0);
+               bmcr |= (BMCR_ANRESTART | BMCR_ANENABLE);
+               spider_net_write_phy(card->netdev, phy->mii_id,
+                                    MII_BMCR, bmcr);
+       }
+}
+
 /**
  * spider_net_rx_irq_off - switch off rx irq on this spider card
  * @card: device structure
@@ -1233,6 +1283,31 @@
 }
 
 /**
+ * spider_net_link_reset
+ * @netdev: net device structure
+ *
+ */
+static void
+spider_net_link_reset(struct net_device *netdev)
+{
+
+       struct spider_net_card *card=netdev_priv(netdev);
+
+       del_timer_sync(&card->aneg_timer);
+
+       spider_net_write_reg(card, SPIDER_NET_GMACST,
+                            spider_net_read_reg(card, SPIDER_NET_GMACST));
+       spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+
+       mii_phy_probe(&card->phy, card->phy.mii_id);
+       spider_net_setup_aneg(card, is1000);
+       if (card->phy.def->phy_id)
+               mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+       else
+               pr_err("No phy is available\n");
+}
+
+/**
  * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt
  * @card: card structure
  *
@@ -1362,8 +1437,8 @@
                                switch (i)
        {
        case SPIDER_NET_GTMFLLINT:
-               if (netif_msg_intr(card) && net_ratelimit())
-                       pr_err("Spider TX RAM full\n");
+               /* if (netif_msg_intr(card) && net_ratelimit())
+                       pr_err("Spider TX RAM full\n"); */
                show_error = 0;
                break;
        case SPIDER_NET_GRFDFLLINT: /* fallthrough */
@@ -1503,6 +1578,9 @@
        if (status_reg & SPIDER_NET_TXINT)
                netif_rx_schedule(netdev);
 
+       if (status_reg & SPIDER_NET_LINKINT)
+               spider_net_link_reset(netdev);
+
        if (status_reg & SPIDER_NET_ERRINT )
                spider_net_handle_error_irq(card, status_reg);
 
@@ -1543,6 +1621,10 @@
 
        spider_net_write_reg(card, SPIDER_NET_CKRCTRL,
                             SPIDER_NET_CKRCTRL_RUN_VALUE);
+
+       spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
+                            spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 
0x4);
+
 }
 
 /**
@@ -1627,8 +1709,6 @@
 
        spider_net_write_reg(card, SPIDER_NET_GMACLENLMT,
                             SPIDER_NET_LENLMT_VALUE);
-       spider_net_write_reg(card, SPIDER_NET_GMACMODE,
-                            SPIDER_NET_MACMODE_VALUE);
        spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
                             SPIDER_NET_OPMODE_VALUE);
 
@@ -1644,6 +1724,7 @@
                             SPIDER_NET_GDTBSTA | SPIDER_NET_GDTDCEIDIS);
 }
 
+static int spider_net_init_firmware(struct spider_net_card *);
 /**
  * spider_net_open - called upon ifonfig up
  * @netdev: interface device structure
@@ -1661,6 +1742,16 @@
        int i, result;
 
        result = -ENOMEM;
+       if (spider_net_init_firmware(card))
+               goto init_firmware_failed;
+
+       spider_net_setup_aneg(card, is1000);
+       if (card->phy.def->phy_id)
+               mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+       else
+               pr_err("No phy is available\n");
+
+
        if (spider_net_init_chain(card, &card->tx_chain, card->descr,
                                  card->num_tx_desc))
                goto alloc_tx_failed;
@@ -1705,9 +1796,60 @@
 alloc_rx_failed:
        spider_net_free_chain(card, &card->tx_chain);
 alloc_tx_failed:
+init_firmware_failed:
        return result;
 }
 
+static void spider_net_init_card(struct spider_net_card *);
+/**
+ * spider_net_link_phy
+ * @data: used for pointer to card structure
+ *
+ */
+static void spider_net_link_phy(unsigned long data)
+{
+       struct spider_net_card *card = (struct spider_net_card *)data;
+       struct mii_phy *phy = &card->phy;
+
+       if (card->aneg_count > 10) {
+               /* timeout */
+               card->aneg_count = 0;
+               is1000 = !is1000;
+               goto re_setup;
+       }
+
+       if (!(phy->def->ops->poll_link(phy))) {
+               card->aneg_count++;
+               mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+               return;
+       }
+
+       phy->def->ops->read_link(phy);
+
+       if (phy->speed == 1000 && !is1000) {
+               is1000 = 1;
+               goto re_setup;
+       } else if(phy->speed != 1000 && is1000) {
+               is1000 = 0;
+               goto re_setup;
+       } 
+
+       spider_net_write_reg(card, SPIDER_NET_GMACST,
+                            spider_net_read_reg(card, SPIDER_NET_GMACST));
+       spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0x4);
+
+       pr_info("Found %s with %i Mbps, %s-duplex.\n",
+               phy->def->name, phy->speed, phy->duplex==1 ? "Full" : "Half");
+
+       return;
+
+re_setup:
+       mii_phy_probe(phy, phy->mii_id);
+       spider_net_setup_aneg(card, is1000);
+       card->aneg_count = 0;
+       mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
+}
+
 /**
  * spider_net_setup_phy - setup PHY
  * @card: card structure
@@ -1726,21 +1868,19 @@
                             SPIDER_NET_DMASEL_VALUE);
        spider_net_write_reg(card, SPIDER_NET_GPCCTRL,
                             SPIDER_NET_PHY_CTRL_VALUE);
-       phy->mii_id = 1;
+
        phy->dev = card->netdev;
        phy->mdio_read = spider_net_read_phy;
        phy->mdio_write = spider_net_write_phy;
 
-       mii_phy_probe(phy, phy->mii_id);
-
-       if (phy->def->ops->setup_forced)
-               phy->def->ops->setup_forced(phy, SPEED_1000, DUPLEX_FULL);
-
-       phy->def->ops->enable_fiber(phy);
-
-       phy->def->ops->read_link(phy);
-       pr_info("Found %s with %i Mbps, %s-duplex.\n", phy->def->name,
-               phy->speed, phy->duplex==1 ? "Full" : "Half");
+       for (phy->mii_id = 1; phy->mii_id <= 31; phy->mii_id++) {
+               unsigned short id;
+               id = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
+               if (id != 0x0000 && id != 0xffff) {
+                       mii_phy_probe(phy, phy->mii_id);
+                       break;
+               }
+       }
 
        return 0;
 }
@@ -1913,11 +2053,13 @@
        netif_carrier_off(netdev);
        netif_stop_queue(netdev);
        del_timer_sync(&card->tx_timer);
+       del_timer_sync(&card->aneg_timer);
 
        /* disable/mask all interrupts */
        spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
        spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
        spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
+       spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
 
        /* free_irq(netdev->irq, netdev);*/
        free_irq(to_pci_dev(netdev->class_dev.dev)->irq, netdev);
@@ -1961,8 +2103,6 @@
 
        if (spider_net_setup_phy(card))
                goto out;
-       if (spider_net_init_firmware(card))
-               goto out;
 
        spider_net_open(netdev);
        spider_net_kick_tx_dma(card);
@@ -2058,6 +2198,11 @@
        card->tx_timer.data = (unsigned long) card;
        netdev->irq = card->pdev->irq;
 
+       card->aneg_count = 0;
+       init_timer(&card->aneg_timer);
+       card->aneg_timer.function = spider_net_link_phy;
+       card->aneg_timer.data = (unsigned long) card;
+
        card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT;
 
        card->num_tx_desc = tx_descriptors;
@@ -2236,10 +2381,6 @@
        if (err)
                goto out_undo_pci;
 
-       err = spider_net_init_firmware(card);
-       if (err)
-               goto out_undo_pci;
-
        err = spider_net_setup_netdev(card);
        if (err)
                goto out_undo_pci;
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to