patch-2.4.21 linux-2.4.21/drivers/net/hamachi.c
Next file: linux-2.4.21/drivers/net/hp100.c
Previous file: linux-2.4.21/drivers/net/fmv18x.c
Back to the patch index
Back to the overall index
- Lines: 347
- Date:
2003-06-13 07:51:34.000000000 -0700
- Orig file:
linux-2.4.20/drivers/net/hamachi.c
- Orig date:
2002-11-28 15:53:13.000000000 -0800
diff -urN linux-2.4.20/drivers/net/hamachi.c linux-2.4.21/drivers/net/hamachi.c
@@ -158,7 +158,6 @@
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/time.h>
-#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
@@ -508,13 +507,11 @@
unsigned int cur_tx, dirty_tx;
unsigned int rx_buf_sz; /* Based on MTU+slack. */
unsigned int tx_full:1; /* The Tx queue is full. */
- unsigned int full_duplex:1; /* Full-duplex operation requested. */
unsigned int duplex_lock:1;
- unsigned int medialock:1; /* Do not sense media. */
unsigned int default_port:4; /* Last dev->if_port value. */
/* MII transceiver section. */
int mii_cnt; /* MII device addresses. */
- u16 advertising; /* NWay media advertisement */
+ struct mii_if_info mii_if; /* MII lib hooks/info */
unsigned char phys[MII_CNT]; /* MII device addresses, only first one used. */
u32 rx_int_var, tx_int_var; /* interrupt control variables */
u32 option; /* Hold on to a copy of the options */
@@ -557,8 +554,8 @@
MODULE_PARM_DESC(force32, "GNIC-II: Bit 0: 32 bit PCI, bit 1: disable parity, bit 2: 64 bit PCI (all boards)");
static int read_eeprom(long ioaddr, int location);
-static int mdio_read(long ioaddr, int phy_id, int location);
-static void mdio_write(long ioaddr, int phy_id, int location, int value);
+static int mdio_read(struct net_device *dev, int phy_id, int location);
+static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
static int hamachi_open(struct net_device *dev);
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static void hamachi_timer(unsigned long data);
@@ -640,6 +637,12 @@
hmp = dev->priv;
spin_lock_init(&hmp->lock);
+ hmp->mii_if.dev = dev;
+ hmp->mii_if.mdio_read = mdio_read;
+ hmp->mii_if.mdio_write = mdio_write;
+ hmp->mii_if.phy_id_mask = 0x1f;
+ hmp->mii_if.reg_num_mask = 0x1f;
+
ring_space = pci_alloc_consistent(pdev, TX_TOTAL_SIZE, &ring_dma);
if (!ring_space)
goto err_out_cleardev;
@@ -688,18 +691,18 @@
if (option > 0) {
hmp->option = option;
if (option & 0x200)
- hmp->full_duplex = 1;
+ hmp->mii_if.full_duplex = 1;
else if (option & 0x080)
- hmp->full_duplex = 0;
+ hmp->mii_if.full_duplex = 0;
hmp->default_port = option & 15;
if (hmp->default_port)
- hmp->medialock = 1;
+ hmp->mii_if.force_media = 1;
}
if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
- hmp->full_duplex = 1;
+ hmp->mii_if.full_duplex = 1;
/* lock the duplex mode if someone specified a value */
- if (hmp->full_duplex || (option & 0x080))
+ if (hmp->mii_if.full_duplex || (option & 0x080))
hmp->duplex_lock = 1;
/* Set interrupt tuning parameters */
@@ -752,17 +755,21 @@
if (chip_tbl[hmp->chip_id].flags & CanHaveMII) {
int phy, phy_idx = 0;
for (phy = 0; phy < 32 && phy_idx < MII_CNT; phy++) {
- int mii_status = mdio_read(ioaddr, phy, 1);
+ int mii_status = mdio_read(dev, phy, MII_BMSR);
if (mii_status != 0xffff &&
mii_status != 0x0000) {
hmp->phys[phy_idx++] = phy;
- hmp->advertising = mdio_read(ioaddr, phy, 4);
+ hmp->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
printk(KERN_INFO "%s: MII PHY found at address %d, status "
"0x%4.4x advertising %4.4x.\n",
- dev->name, phy, mii_status, hmp->advertising);
+ dev->name, phy, mii_status, hmp->mii_if.advertising);
}
}
hmp->mii_cnt = phy_idx;
+ if (hmp->mii_cnt > 0)
+ hmp->mii_if.phy_id = hmp->phys[0];
+ else
+ memset(&hmp->mii_if, 0, sizeof(hmp->mii_if));
}
/* Configure gigabit autonegotiation. */
writew(0x0400, ioaddr + ANXchngCtrl); /* Enable legacy links. */
@@ -808,8 +815,9 @@
These routines assume the MDIO controller is idle, and do not exit until
the command is finished. */
-static int mdio_read(long ioaddr, int phy_id, int location)
+static int mdio_read(struct net_device *dev, int phy_id, int location)
{
+ long ioaddr = dev->base_addr;
int i;
/* We should check busy first - per docs -KDU */
@@ -824,8 +832,9 @@
return readw(ioaddr + MII_Rd_Data);
}
-static void mdio_write(long ioaddr, int phy_id, int location, int value)
+static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
{
+ long ioaddr = dev->base_addr;
int i;
/* We should check busy first - per docs -KDU */
@@ -915,7 +924,7 @@
/* Setting the Rx mode will start the Rx process. */
/* If someone didn't choose a duplex, default to full-duplex */
if (hmp->duplex_lock != 1)
- hmp->full_duplex = 1;
+ hmp->mii_if.full_duplex = 1;
/* always 1, takes no more time to do it */
writew(0x0001, ioaddr + RxChecksum);
@@ -1463,64 +1472,6 @@
spin_unlock(&hmp->lock);
}
-#ifdef TX_CHECKSUM
-/*
- * Copied from eth_type_trans(), with reduced header, since we don't
- * get it on RX, only on TX.
- */
-static unsigned short hamachi_eth_type_trans(struct sk_buff *skb,
- struct net_device *dev)
-{
- struct ethhdr *eth;
- unsigned char *rawp;
-
- skb->mac.raw=skb->data;
- skb_pull(skb,dev->hard_header_len-8); /* artificially enlarged on tx */
- eth= skb->mac.ethernet;
-
- if(*eth->h_dest&1)
- {
- if(memcmp(eth->h_dest,dev->broadcast, ETH_ALEN)==0)
- skb->pkt_type=PACKET_BROADCAST;
- else
- skb->pkt_type=PACKET_MULTICAST;
- }
-
- /*
- * This ALLMULTI check should be redundant by 1.4
- * so don't forget to remove it.
- *
- * Seems, you forgot to remove it. All silly devices
- * seems to set IFF_PROMISC.
- */
-
- else if(dev->flags&(IFF_PROMISC/*|IFF_ALLMULTI*/))
- {
- if(memcmp(eth->h_dest,dev->dev_addr, ETH_ALEN))
- skb->pkt_type=PACKET_OTHERHOST;
- }
-
- if (ntohs(eth->h_proto) >= 1536)
- return eth->h_proto;
-
- rawp = skb->data;
-
- /*
- * This is a magic hack to spot IPX packets. Older Novell breaks
- * the protocol design and runs IPX over 802.3 without an 802.2 LLC
- * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
- * won't work for fault tolerant netware but does for the rest.
- */
- if (*(unsigned short *)rawp == 0xFFFF)
- return htons(ETH_P_802_3);
-
- /*
- * Real 802.2 LLC
- */
- return htons(ETH_P_802_2);
-}
-#endif /* TX_CHECKSUM */
-
/* This routine is logically part of the interrupt handler, but seperated
for clarity and better register allocation. */
static int hamachi_rx(struct net_device *dev)
@@ -1625,12 +1576,7 @@
skb_put(skb = hmp->rx_skbuff[entry], pkt_len);
hmp->rx_skbuff[entry] = NULL;
}
-#ifdef TX_CHECKSUM
- /* account for extra TX hard_header bytes */
- skb->protocol = hamachi_eth_type_trans(skb, dev);
-#else
skb->protocol = eth_type_trans(skb, dev);
-#endif
#ifdef RX_CHECKSUM
@@ -1912,7 +1858,7 @@
static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
{
- struct hamachi_private *hmp = dev->priv;
+ struct hamachi_private *np = dev->priv;
u32 ethcmd;
if (copy_from_user(ðcmd, useraddr, sizeof(ethcmd)))
@@ -1923,12 +1869,53 @@
struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
strcpy(info.driver, DRV_NAME);
strcpy(info.version, DRV_VERSION);
- strcpy(info.bus_info, hmp->pci_dev->slot_name);
+ strcpy(info.bus_info, np->pci_dev->slot_name);
if (copy_to_user(useraddr, &info, sizeof(info)))
return -EFAULT;
return 0;
}
+ /* get settings */
+ case ETHTOOL_GSET: {
+ struct ethtool_cmd ecmd = { ETHTOOL_GSET };
+ if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
+ return -EINVAL;
+ spin_lock_irq(&np->lock);
+ mii_ethtool_gset(&np->mii_if, &ecmd);
+ spin_unlock_irq(&np->lock);
+ if (copy_to_user(useraddr, &ecmd, sizeof(ecmd)))
+ return -EFAULT;
+ return 0;
+ }
+ /* set settings */
+ case ETHTOOL_SSET: {
+ int r;
+ struct ethtool_cmd ecmd;
+ if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
+ return -EINVAL;
+ if (copy_from_user(&ecmd, useraddr, sizeof(ecmd)))
+ return -EFAULT;
+ spin_lock_irq(&np->lock);
+ r = mii_ethtool_sset(&np->mii_if, &ecmd);
+ spin_unlock_irq(&np->lock);
+ return r;
+ }
+ /* restart autonegotiation */
+ case ETHTOOL_NWAY_RST: {
+ if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
+ return -EINVAL;
+ return mii_nway_restart(&np->mii_if);
+ }
+ /* get link status */
+ case ETHTOOL_GLINK: {
+ struct ethtool_value edata = {ETHTOOL_GLINK};
+ if (!(chip_tbl[np->chip_id].flags & CanHaveMII))
+ return -EINVAL;
+ edata.data = mii_link_ok(&np->mii_if);
+ if (copy_to_user(useraddr, &edata, sizeof(edata)))
+ return -EFAULT;
+ return 0;
+ }
}
return -EOPNOTSUPP;
@@ -1936,32 +1923,17 @@
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
- long ioaddr = dev->base_addr;
- struct mii_ioctl_data *data = (struct mii_ioctl_data *)&rq->ifr_data;
+ struct hamachi_private *np = dev->priv;
+ struct mii_ioctl_data *data = (struct mii_ioctl_data *) & rq->ifr_data;
+ int rc;
- switch(cmd) {
- case SIOCETHTOOL:
- return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
- case SIOCGMIIPHY: /* Get address of MII PHY in use. */
- case SIOCDEVPRIVATE: /* for binary compat, remove in 2.5 */
- data->phy_id = ((struct hamachi_private *)dev->priv)->phys[0] & 0x1f;
- /* Fall Through */
-
- case SIOCGMIIREG: /* Read MII PHY register. */
- case SIOCDEVPRIVATE+1: /* for binary compat, remove in 2.5 */
- data->val_out = mdio_read(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f);
- return 0;
+ if (!netif_running(dev))
+ return -EINVAL;
- case SIOCSMIIREG: /* Write MII PHY register. */
- case SIOCDEVPRIVATE+2: /* for binary compat, remove in 2.5 */
- /* TODO: Check the sequencing of this. Might need to stop and
- * restart Rx and Tx engines. -KDU
- */
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
- mdio_write(ioaddr, data->phy_id & 0x1f, data->reg_num & 0x1f, data->val_in);
- return 0;
- case SIOCDEVPRIVATE+3: { /* set rx,tx intr params */
+ if (cmd == SIOCETHTOOL)
+ rc = netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+
+ else if (cmd == (SIOCDEVPRIVATE+3)) { /* set rx,tx intr params */
u32 *d = (u32 *)&rq->ifr_data;
/* Should add this check here or an ordinary user can do nasty
* things. -KDU
@@ -1975,11 +1947,16 @@
printk(KERN_NOTICE "%s: tx %08x, rx %08x intr\n", dev->name,
(u32) readl(dev->base_addr + TxIntrCtrl),
(u32) readl(dev->base_addr + RxIntrCtrl));
- return 0;
- }
- default:
- return -EOPNOTSUPP;
+ rc = 0;
+ }
+
+ else {
+ spin_lock_irq(&np->lock);
+ rc = generic_mii_ioctl(&np->mii_if, data, cmd, NULL);
+ spin_unlock_irq(&np->lock);
}
+
+ return rc;
}
@@ -2010,10 +1987,10 @@
MODULE_DEVICE_TABLE(pci, hamachi_pci_tbl);
static struct pci_driver hamachi_driver = {
- name: DRV_NAME,
- id_table: hamachi_pci_tbl,
- probe: hamachi_init_one,
- remove: __devexit_p(hamachi_remove_one),
+ .name = DRV_NAME,
+ .id_table = hamachi_pci_tbl,
+ .probe = hamachi_init_one,
+ .remove = __devexit_p(hamachi_remove_one),
};
static int __init hamachi_init (void)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)