netdev
[Top] [All Lists]

Re: [7/9][PATCH 2.6] Media mode rewrite

To: Roger Luethi <rl@xxxxxxxxxxx>
Subject: Re: [7/9][PATCH 2.6] Media mode rewrite
From: Jeff Garzik <jgarzik@xxxxxxxxx>
Date: Sat, 19 Jun 2004 17:24:32 -0400
Cc: Andrew Morton <akpm@xxxxxxxx>, netdev@xxxxxxxxxxx
In-reply-to: <20040615174942.GA11319@xxxxxxxxxxxxxx>
References: <20040615174942.GA11319@xxxxxxxxxxxxxx>
Sender: netdev-bounce@xxxxxxxxxxx
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040510
Roger Luethi wrote:
Remove rhine_check_duplex, rhine_timer and related data structures

Add rhine_check_media: wrapper for generic mii_check_media, sets duplex
bit in MAC

Add rhine_enable_linkmon, rhine_disable_linkmon to enable hardware link
status monitoring

Update mdio_read, mdio_write accordingly

Remove get_intr_status check in rhine_start_tx because we are not racing
anymore

Signed-off-by: Roger Luethi <rl@xxxxxxxxxxx>

--- orig/drivers/net/via-rhine.c
+++ mod/drivers/net/via-rhine.c
@@ -485,7 +485,6 @@
struct pci_dev *pdev;
        struct net_device_stats stats;
-       struct timer_list timer;        /* Media monitoring timer. */
        spinlock_t lock;
/* Frequently used values: keep some adjacent for cache effect. */
@@ -498,16 +497,12 @@
        /* These values are keep track of the transceiver/media in use. */
        u8 tx_thresh, rx_thresh;
- /* MII transceiver section. */
-       u16 mii_status;                 /* last read MII status */
        struct mii_if_info mii_if;
 };
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  rhine_open(struct net_device *dev);
-static void rhine_check_duplex(struct net_device *dev);
-static void rhine_timer(unsigned long data);
 static void rhine_tx_timeout(struct net_device *dev);
 static int  rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs 
*regs);
@@ -1032,6 +1027,21 @@
        }
 }
+static void rhine_check_media(struct net_device *dev, unsigned int init_media)
+{
+       struct rhine_private *rp = netdev_priv(dev);
+       long ioaddr = dev->base_addr;
+
+       mii_check_media(&rp->mii_if, debug, init_media);
+
+       if (rp->mii_if.full_duplex)
+           writeb(readb(ioaddr + ChipCmd1) | Cmd1FDuplex,
+                  ioaddr + ChipCmd1);
+       else
+           writeb(readb(ioaddr + ChipCmd1) & ~Cmd1FDuplex,
+                  ioaddr + ChipCmd1);
+}
+
 static void init_registers(struct net_device *dev)
 {
        struct rhine_private *rp = netdev_priv(dev);
@@ -1047,7 +1057,6 @@
        writeb(0x20, ioaddr + TxConfig);
        rp->tx_thresh = 0x20;
        rp->rx_thresh = 0x60;                /* Written in rhine_set_rx_mode(). 
*/
-       rp->mii_if.full_duplex = 0;
writel(rp->rx_ring_dma, ioaddr + RxRingPtr);
        writel(rp->tx_ring_dma, ioaddr + TxRingPtr);
@@ -1063,14 +1072,42 @@
writew(CmdStart|CmdTxOn|CmdRxOn|(Cmd1NoTxPoll << 8),
               ioaddr + ChipCmd);
-       if (rp->mii_if.force_media)
-               writeb(readb(ioaddr + ChipCmd1) | Cmd1FDuplex,
-                      ioaddr + ChipCmd1);
-       else
-               writeb(readb(ioaddr + ChipCmd1) & ~Cmd1FDuplex,
-                      ioaddr + ChipCmd1);
+       rhine_check_media(dev, 1);
+}
+
+/* Enable MII link status auto-polling (required for IntrLinkChange) */
+static void rhine_enable_linkmon(long ioaddr)
+{
+       writeb(0, ioaddr + MIICmd);
+       writeb(MII_BMSR, ioaddr + MIIRegAddr);
+       writeb(0x80, ioaddr + MIICmd);
- rhine_check_duplex(dev);
+       RHINE_WAIT_FOR((readb(ioaddr + MIIRegAddr) & 0x20));
+
+       writeb(MII_BMSR | 0x40, ioaddr + MIIRegAddr);
+}
+
+/* Disable MII link status auto-polling (required for MDIO access) */
+static void rhine_disable_linkmon(long ioaddr, u32 quirks)
+{
+       writeb(0, ioaddr + MIICmd);
+
+       if (quirks & rqRhineI) {
+               writeb(0x01, ioaddr + MIIRegAddr);      // MII_BMSR
+
+               /* Can be called from ISR. Evil. */
+               mdelay(1);


Net drivers are slowly moving towards schedule_work()/queue_work() for doing "slow path" stuff like chip reset or MII phy stuff.

        Jeff



<Prev in Thread] Current Thread [Next in Thread>