Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / drivers / net / dm9000.c
index 1d790a8..b09a53d 100644 (file)
@@ -142,6 +142,7 @@ static int dm9000_probe(struct platform_device *);
 static int dm9000_open(struct net_device *);
 static int dm9000_start_xmit(struct sk_buff *, struct net_device *);
 static int dm9000_stop(struct net_device *);
+static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd);
 
 static void dm9000_init_dm9000(struct net_device *);
 
@@ -332,6 +333,16 @@ static void dm9000_poll_controller(struct net_device *dev)
 }
 #endif
 
+static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+       board_info_t *dm = to_dm9000_board(dev);
+
+       if (!netif_running(dev))
+               return -EINVAL;
+
+       return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);
+}
+
 /* ethtool ops */
 
 static void dm9000_get_drvinfo(struct net_device *dev,
@@ -405,6 +416,9 @@ static int dm9000_get_eeprom(struct net_device *dev,
        if ((len & 1) != 0 || (offset & 1) != 0)
                return -EINVAL;
 
+       if (dm->flags & DM9000_PLATF_NO_EEPROM)
+               return -ENOENT;
+
        ee->magic = DM_EEPROM_MAGIC;
 
        for (i = 0; i < len; i += 2)
@@ -426,6 +440,9 @@ static int dm9000_set_eeprom(struct net_device *dev,
        if ((len & 1) != 0 || (offset & 1) != 0)
                return -EINVAL;
 
+       if (dm->flags & DM9000_PLATF_NO_EEPROM)
+               return -ENOENT;
+
        if (ee->magic != DM_EEPROM_MAGIC)
                return -EINVAL;
 
@@ -492,6 +509,7 @@ dm9000_probe(struct platform_device *pdev)
        struct dm9000_plat_data *pdata = pdev->dev.platform_data;
        struct board_info *db;  /* Point a board information structure */
        struct net_device *ndev;
+       const unsigned char *mac_src;
        unsigned long base;
        int ret = 0;
        int iosize;
@@ -626,7 +644,7 @@ dm9000_probe(struct platform_device *pdev)
        dm9000_reset(db);
 
        /* try two times, DM9000 sometimes gets the first read wrong */
-       for (i = 0; i < 2; i++) {
+       for (i = 0; i < 8; i++) {
                id_val  = ior(db, DM9000_VIDL);
                id_val |= (u32)ior(db, DM9000_VIDH) << 8;
                id_val |= (u32)ior(db, DM9000_PIDL) << 16;
@@ -655,6 +673,7 @@ dm9000_probe(struct platform_device *pdev)
        ndev->stop               = &dm9000_stop;
        ndev->set_multicast_list = &dm9000_hash_table;
        ndev->ethtool_ops        = &dm9000_ethtool_ops;
+       ndev->do_ioctl           = &dm9000_ioctl;
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
        ndev->poll_controller    = &dm9000_poll_controller;
@@ -669,13 +688,16 @@ dm9000_probe(struct platform_device *pdev)
        db->mii.mdio_read    = dm9000_phy_read;
        db->mii.mdio_write   = dm9000_phy_write;
 
+       mac_src = "eeprom";
+
        /* try reading the node address from the attached EEPROM */
        for (i = 0; i < 6; i += 2)
                dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
 
        if (!is_valid_ether_addr(ndev->dev_addr)) {
                /* try reading from mac */
-
+               
+               mac_src = "chip";
                for (i = 0; i < 6; i++)
                        ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
        }
@@ -689,9 +711,9 @@ dm9000_probe(struct platform_device *pdev)
 
        if (ret == 0) {
                DECLARE_MAC_BUF(mac);
-               printk("%s: dm9000 at %p,%p IRQ %d MAC: %s\n",
+               printk("%s: dm9000 at %p,%p IRQ %d MAC: %s (%s)\n",
                       ndev->name,  db->io_addr, db->io_data, ndev->irq,
-                      print_mac(mac, ndev->dev_addr));
+                      print_mac(mac, ndev->dev_addr), mac_src);
        }
        return 0;
 
@@ -776,8 +798,6 @@ dm9000_init_dm9000(struct net_device *dev)
        /* Set address filter table */
        dm9000_hash_table(dev);
 
-       /* Activate DM9000 */
-       iow(db, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
        /* Enable TX/RX interrupt mask */
        iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
 
@@ -814,8 +834,8 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
        /* TX control: First packet immediately send, second packet queue */
        if (db->tx_pkt_cnt == 1) {
                /* Set TX length to DM9000 */
-               iow(db, DM9000_TXPLL, skb->len & 0xff);
-               iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff);
+               iow(db, DM9000_TXPLL, skb->len);
+               iow(db, DM9000_TXPLH, skb->len >> 8);
 
                /* Issue TX polling command */
                iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
@@ -890,8 +910,8 @@ dm9000_tx_done(struct net_device *dev, board_info_t * db)
 
                /* Queue packet check & send */
                if (db->tx_pkt_cnt > 0) {
-                       iow(db, DM9000_TXPLL, db->queue_pkt_len & 0xff);
-                       iow(db, DM9000_TXPLH, (db->queue_pkt_len >> 8) & 0xff);
+                       iow(db, DM9000_TXPLL, db->queue_pkt_len);
+                       iow(db, DM9000_TXPLH, db->queue_pkt_len >> 8);
                        iow(db, DM9000_TCR, TCR_TXREQ);
                        dev->trans_start = jiffies;
                }
@@ -1100,6 +1120,12 @@ dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
 {
        unsigned long flags;
 
+       if (db->flags & DM9000_PLATF_NO_EEPROM) {
+               to[0] = 0xff;
+               to[1] = 0xff;
+               return;
+       }
+
        mutex_lock(&db->addr_lock);
 
        spin_lock_irqsave(&db->lock, flags);
@@ -1134,6 +1160,9 @@ dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
 {
        unsigned long flags;
 
+       if (db->flags & DM9000_PLATF_NO_EEPROM)
+               return;
+
        mutex_lock(&db->addr_lock);
 
        spin_lock_irqsave(&db->lock, flags);
@@ -1155,24 +1184,6 @@ dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
 }
 
 /*
- *  Calculate the CRC valude of the Rx packet
- *  flag = 1 : return the reverse CRC (for the received packet CRC)
- *         0 : return the normal CRC (for Hash Table index)
- */
-
-static unsigned long
-cal_CRC(unsigned char *Data, unsigned int Len, u8 flag)
-{
-
-       u32 crc = ether_crc_le(Len, Data);
-
-       if (flag)
-               return ~crc;
-
-       return crc;
-}
-
-/*
  *  Set DM9000 multicast address
  */
 static void
@@ -1181,15 +1192,17 @@ dm9000_hash_table(struct net_device *dev)
        board_info_t *db = (board_info_t *) dev->priv;
        struct dev_mc_list *mcptr = dev->mc_list;
        int mc_cnt = dev->mc_count;
+       int i, oft;
        u32 hash_val;
-       u16 i, oft, hash_table[4];
+       u16 hash_table[4];
+       u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;
        unsigned long flags;
 
        dm9000_dbg(db, 1, "entering %s\n", __func__);
 
-       spin_lock_irqsave(&db->lock,flags);
+       spin_lock_irqsave(&db->lock, flags);
 
-       for (i = 0, oft = 0x10; i < 6; i++, oft++)
+       for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
                iow(db, oft, dev->dev_addr[i]);
 
        /* Clear Hash Table */
@@ -1199,19 +1212,26 @@ dm9000_hash_table(struct net_device *dev)
        /* broadcast address */
        hash_table[3] = 0x8000;
 
+       if (dev->flags & IFF_PROMISC)
+               rcr |= RCR_PRMSC;
+
+       if (dev->flags & IFF_ALLMULTI)
+               rcr |= RCR_ALL;
+
        /* the multicast address in Hash Table : 64 bits */
        for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
-               hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f;
+               hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f;
                hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
        }
 
        /* Write the hash table to MAC MD table */
-       for (i = 0, oft = 0x16; i < 4; i++) {
-               iow(db, oft++, hash_table[i] & 0xff);
-               iow(db, oft++, (hash_table[i] >> 8) & 0xff);
+       for (i = 0, oft = DM9000_MAR; i < 4; i++) {
+               iow(db, oft++, hash_table[i]);
+               iow(db, oft++, hash_table[i] >> 8);
        }
 
-       spin_unlock_irqrestore(&db->lock,flags);
+       iow(db, DM9000_RCR, rcr);
+       spin_unlock_irqrestore(&db->lock, flags);
 }
 
 
@@ -1292,8 +1312,8 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
        iow(db, DM9000_EPAR, DM9000_PHY | reg);
 
        /* Fill the written data into REG_0D & REG_0E */
-       iow(db, DM9000_EPDRL, (value & 0xff));
-       iow(db, DM9000_EPDRH, ((value >> 8) & 0xff));
+       iow(db, DM9000_EPDRL, value);
+       iow(db, DM9000_EPDRH, value >> 8);
 
        iow(db, DM9000_EPCR, 0xa);      /* Issue phyxcer write command */