예제 #1
0
파일: robocfg.c 프로젝트: hajuuk/asuswrt
/* checks that attached switch is 5325/5352/5354/5356/5357/53115/5301x */
static int robo_vlan535x(robo_t *robo, u32 phyid)
{
#ifdef BCM5301X
	if ((robo_read32(robo, ROBO_MGMT_PAGE, ROBO_DEVICE_ID) & 0xfffffff0) == 0x53010)
		return 5;
#else
	/* set vlan access id to 15 and read it back */
	u16 val16 = 15;
	robo_write16(robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350, val16);
	
	/* 5365 will refuse this as it does not have this reg */
	if (robo_read16(robo, ROBO_VLAN_PAGE, ROBO_VLAN_TABLE_ACCESS_5350) != val16)
		return 0;
	/* gigabit ? */
	if (robo->et != 1 && (mdio_read(robo, 0, ROBO_MII_STAT) & 0x0100))
		robo->gmii = ((mdio_read(robo, 0, 0x0f) & 0xf000) != 0);
	/* 53115 ? */
	if (robo->gmii && robo_read32(robo, ROBO_STAT_PAGE, ROBO_LSA_IM_PORT) != 0) {
		robo_write16(robo, ROBO_ARLIO_PAGE, ROBO_VTBL_INDX_5395, val16);
		robo_write16(robo, ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395,
					 (1 << 7) /* start */ | 1 /* read */);
		if (robo_read16(robo, ROBO_ARLIO_PAGE, ROBO_VTBL_ACCESS_5395) == 1
		    && robo_read16(robo, ROBO_ARLIO_PAGE, ROBO_VTBL_INDX_5395) == val16)
			return 4;
	}
	/* dirty trick for 5356/5357 */
	if ((phyid & 0xfff0ffff ) == 0x5da00362 ||
	    (phyid & 0xfff0ffff ) == 0x5e000362)
		return 3;
	/* 5325/5352/5354*/
	return 1;
#endif
}
예제 #2
0
파일: meth.c 프로젝트: CSCLOG/beaglebone
static int mdio_probe(struct meth_private *priv)
{
	int i;
	unsigned long p2, p3, flags;
	/* check if phy is detected already */
	if(priv->phy_addr>=0&&priv->phy_addr<32)
		return 0;
	spin_lock_irqsave(&priv->meth_lock, flags);
	for (i=0;i<32;++i){
		priv->phy_addr=i;
		p2=mdio_read(priv,2);
		p3=mdio_read(priv,3);
#if MFE_DEBUG>=2
		switch ((p2<<12)|(p3>>4)){
		case PHY_QS6612X:
			DPRINTK("PHY is QS6612X\n");
			break;
		case PHY_ICS1889:
			DPRINTK("PHY is ICS1889\n");
			break;
		case PHY_ICS1890:
			DPRINTK("PHY is ICS1890\n");
			break;
		case PHY_DP83840:
			DPRINTK("PHY is DP83840\n");
			break;
		}
#endif
		if(p2!=0xffff&&p2!=0x0000){
			DPRINTK("PHY code: %x\n",(p2<<12)|(p3>>4));
			break;
		}
	}
예제 #3
0
static __u32 robo_read32(__u8 page, __u8 reg)
{
	robo_reg(page, reg, REG_MII_ADDR_READ);

	return mdio_read(robo.phy_addr, REG_MII_DATA0) +
		(mdio_read(robo.phy_addr, REG_MII_DATA0 + 1) << 16);
}
예제 #4
0
static __u32 robo_read32(__u8 page, __u8 reg)
{
	robo_reg(page, reg, REG_MII_ADDR_READ);
	
	return mdio_read(ROBO_PHY_ADDR, REG_MII_DATA0) +
		(mdio_read(ROBO_PHY_ADDR, REG_MII_DATA0 + 1) << 16);
}
예제 #5
0
int am79c874_init(struct net_device *dev, int phy_addr)
{
	s16 data;

	/* 79c874 has quit resembled bit assignments to BCM5201 */
	if (au1000_debug > 4)
		printk("am79c847_init\n");

	/* Stop auto-negotiation */
	data = mdio_read(dev, phy_addr, MII_CONTROL);
	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);

	/* Set advertisement to 10/100 and Half/Full duplex
	 * (full capabilities) */
	data = mdio_read(dev, phy_addr, MII_ANADV);
	data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T;
	mdio_write(dev, phy_addr, MII_ANADV, data);
	
	/* Restart auto-negotiation */
	data = mdio_read(dev, phy_addr, MII_CONTROL);
	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;

	mdio_write(dev, phy_addr, MII_CONTROL, data);

	if (au1000_debug > 4) dump_mii(dev, phy_addr);
	return 0;
}
예제 #6
0
int bcm_5201_init(struct net_device *dev, int phy_addr)
{
	s16 data;
	
	/* Stop auto-negotiation */
	//printk("bcm_5201_init\n");
	data = mdio_read(dev, phy_addr, MII_CONTROL);
	mdio_write(dev, phy_addr, MII_CONTROL, data & ~MII_CNTL_AUTO);

	/* Set advertisement to 10/100 and Half/Full duplex
	 * (full capabilities) */
	data = mdio_read(dev, phy_addr, MII_ANADV);
	data |= MII_NWAY_TX | MII_NWAY_TX_FDX | MII_NWAY_T_FDX | MII_NWAY_T;
	mdio_write(dev, phy_addr, MII_ANADV, data);
	
	/* Restart auto-negotiation */
	data = mdio_read(dev, phy_addr, MII_CONTROL);
	data |= MII_CNTL_RST_AUTO | MII_CNTL_AUTO;
	mdio_write(dev, phy_addr, MII_CONTROL, data);

	/* Enable TX LED instead of FDX */
	data = mdio_read(dev, phy_addr, MII_INT);
	data &= ~MII_FDX_LED;
	mdio_write(dev, phy_addr, MII_INT, data);

	if (au1000_debug > 4) dump_mii(dev, phy_addr);
	return 0;
}
예제 #7
0
int show_basic_mii(int sock, int phy_id)
{
    char buf[100];
    int i, mii_val[32];
    unsigned bmcr, bmsr, advert, lkpar, bmcr2, lpa2;

    /* Some bits in the BMSR are latched, but we can't rely on being
       the only reader, so only the current values are meaningful */
    mdio_read(sock, MII_BMSR);
    for (i = 0; i < ((verbose > 1) ? 32 : MII_BASIC_MAX); i++)
	mii_val[i] = mdio_read(sock, i);

    if (mii_val[MII_BMCR] == 0xffff  || mii_val[MII_BMSR] == 0x0000) {
	fprintf(stderr, "  No MII transceiver present!.\n");
	return -1;
    }

    /* Descriptive rename. */
    bmcr = mii_val[MII_BMCR]; bmsr = mii_val[MII_BMSR];
    advert = mii_val[MII_ANAR]; lkpar = mii_val[MII_ANLPAR];
    bmcr2 = mii_val[MII_CTRL1000]; lpa2 = mii_val[MII_STAT1000];

    sprintf(buf, "%s: ", ifr.ifr_name);
    if (bmcr & MII_BMCR_AN_ENA) {
	if (bmsr & MII_BMSR_AN_COMPLETE) {
	    if (advert & lkpar) {
		strcat(buf, (lkpar & MII_AN_ACK) ?
		       "negotiated" : "no autonegotiation,");
		strcat(buf, media_list(advert & lkpar, bmcr2 & lpa2>>2, 1));
		strcat(buf, ", ");
	    } else {
		strcat(buf, "autonegotiation failed, ");
	    }
	} else if (bmcr & MII_BMCR_RESTART) {
예제 #8
0
static int aq100x_intr_clear(struct cphy *phy)
{
	unsigned int v;

	mdio_read(phy, MDIO_DEV_VEND1, AQ_IFLAG_GLOBAL, &v);
	mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &v);

	return 0;
}
// Enables loopback on the Ethernet PHY.
// NOTE: Software reset will disable loopback.
void eth_enable_loopback (void)
{
	// Set to 100Mbps
	int x = mdio_read (ETH_PHY_ADR, 20) & ~(7 << 4);
	mdio_write (ETH_PHY_ADR, 20,  x | (5 << 4));
	eth_soft_reset ();

	// Loopback
	mdio_write (ETH_PHY_ADR, 0, mdio_read (ETH_PHY_ADR, 0) | (1 << 14));
}
예제 #10
0
static void netdev_error(struct net_device *dev, int intr_status)
{
	long ioaddr = dev->base_addr;
	struct netdev_private *np = dev->priv;
	u16 mii_reg0, mii_reg4, mii_reg5;
	int speed;

	if (intr_status & IntrDrvRqst) {
		/* Stop the down counter and turn interrupts back on. */
		if (debug > 1)
			printk("%s: Turning interrupts back on.\n", dev->name);
		writew(0, ioaddr + IntrEnable);
		writew(0, ioaddr + DownCounter);
		writew(IntrRxDone | IntrRxDMADone | IntrPCIErr | IntrDrvRqst |
			   IntrTxDone | StatsMax | LinkChange, ioaddr + IntrEnable);
		/* Ack buggy InRequest */
		writew (IntrDrvRqst, ioaddr + IntrStatus);
	}
	if (intr_status & LinkChange) {
		if (np->an_enable) {
			mii_reg4 = mdio_read (dev, np->phys[0], 4);
			mii_reg5= mdio_read (dev, np->phys[0], 5);
			mii_reg4 &= mii_reg5;
			printk (KERN_INFO "%s: Link changed: ", dev->name);
			if (mii_reg4 & 0x0100)
				printk ("100Mbps, full duplex\n");
			else if (mii_reg4 & 0x0080)
				printk ("100Mbps, half duplex\n");
			else if (mii_reg4 & 0x0040)
				printk ("10Mbps, full duplex\n");
			else if (mii_reg4 & 0x0020)
				printk ("10Mbps, half duplex\n");
			else
				printk ("\n");

		} else {
			mii_reg0 = mdio_read (dev, np->phys[0], 0);
			speed = (mii_reg0 & 0x2000) ? 100 : 10;
			printk (KERN_INFO "%s: Link changed: %dMbps ,",
				dev->name, speed);
			printk ("%s duplex.\n", (mii_reg0 & 0x0100) ?
				"full" : "half");
		}
		check_duplex (dev);
	}
	if (intr_status & StatsMax) {
		get_stats(dev);
	}
	if (intr_status & IntrPCIErr) {
		printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
			   dev->name, intr_status);
		/* We must do a global reset of DMA to continue. */
	}
}
예제 #11
0
static void dump_mii(struct net_device *dev, int phy_id)
{
	int i, val;

	for (i = 0; i < 7; i++) {
		if ((val = mdio_read(dev, phy_id, i)) >= 0)
			printk("%s: MII Reg %d=%x\n", dev->name, i, val);
	}
	for (i = 16; i < 25; i++) {
		if ((val = mdio_read(dev, phy_id, i)) >= 0)
			printk("%s: MII Reg %d=%x\n", dev->name, i, val);
	}
}
예제 #12
0
static int aq100x_intr_handler(struct cphy *phy)
{
	int err;
	unsigned int cause, v;

	err = mdio_read(phy, MDIO_DEV_VEND1, AQ_IFLAG_GLOBAL, &cause);
	if (err)
		return err;

	/* Read (and reset) the latching version of the status */
	mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &v);

	return cphy_cause_link_change;
}
예제 #13
0
파일: robocfg.c 프로젝트: hajuuk/asuswrt
static u32 robo_read32(robo_t *robo, u8 page, u8 reg)
{
#ifdef BCM5301X
	u32 val32;

	robo_read(robo, page, reg, (u16 *) &val32, 2);
	return val32;
#else
	robo_reg(robo, page, reg, REG_MII_ADDR_READ);
	
	return ((u32 )mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0)) |
		((u32 )mdio_read(robo, ROBO_PHY_ADDR, REG_MII_DATA0 + 1) << 16);
#endif
}
예제 #14
0
static int mv88x201x_interrupt_clear(struct cphy *cphy)
{
	u32 elmer;
	u32 val;

#ifdef MV88x2010_LINK_STATUS_BUGS
	/* Required to read twice before clear takes affect. */
	mdio_read(cphy, 0x1, 0x9003, &val);
	mdio_read(cphy, 0x1, 0x9004, &val);
	mdio_read(cphy, 0x1, 0x9005, &val);

	/* Read this register after the others above it else
	 * the register doesn't clear correctly.
	 */
	mdio_read(cphy, 0x1, 0x1, &val);
#endif

	/* Clear link status. */
	mdio_read(cphy, 0x1, 0x1, &val);
	/* Clear PHY LASI interrupts. */
	mdio_read(cphy, 0x1, 0x9005, &val);

#ifdef MV88x2010_LINK_STATUS_BUGS
	/* Do it again. */
	mdio_read(cphy, 0x1, 0x9003, &val);
	mdio_read(cphy, 0x1, 0x9004, &val);
#endif

	/* Clear Marvell interrupts through Elmer0. */
	t1_tpi_read(cphy->adapter, A_ELMER0_INT_CAUSE, &elmer);
	elmer |= ELMER0_GP_BIT6;
	t1_tpi_write(cphy->adapter, A_ELMER0_INT_CAUSE, elmer);
	return 0;
}
예제 #15
0
/* on each timer ticks we check two things, Link Status (ON/OFF) and 
   Link Mode (10/100/Full/Half)
 */
static void sis900_timer(unsigned long data)
{
        struct device *net_dev = (struct device *)data;
        struct sis900_private *sis_priv = (struct sis900_private *)net_dev->priv;
	struct mii_phy *mii_phy = sis_priv->mii;
        static int next_tick = 5*HZ;
        u16 status;

	status = mdio_read(net_dev, sis_priv->cur_phy, MII_STATUS);

	/* current mii phy is failed to link, try another one */
	while (!(status & MII_STAT_LINK)) {		
		if (mii_phy->next == NULL) { 
			if (sis_priv->LinkOn) {
				/* link stat change from ON to OFF */
				next_tick = HZ;
				sis_priv->LinkOn = FALSE;
				printk(KERN_INFO "%s: Media Link Off\n",
				       net_dev->name);
			}
			sis_priv->timer.expires = jiffies + next_tick;
			add_timer(&sis_priv->timer);
			return;
		}
		mii_phy = mii_phy->next;
		status = mdio_read(net_dev, mii_phy->phy_addr, MII_STATUS);
	}

	if (!sis_priv->LinkOn) {
		/* link stat change forn OFF to ON, read and report link mode */
		sis_priv->LinkOn = TRUE;
		next_tick = 5*HZ;
		/* change what cur_phy means */
		if (mii_phy->phy_addr != sis_priv->cur_phy) {
			printk(KERN_INFO "%s: Changing transceiver to %s\n", net_dev->name,
			       mii_phy->chip_info->name);
			status = mdio_read(net_dev, sis_priv->cur_phy, MII_CONTROL);
			mdio_write(net_dev, sis_priv->cur_phy, 
				   MII_CONTROL, status | MII_CNTL_ISOLATE);
			status = mdio_read(net_dev, mii_phy->phy_addr, MII_CONTROL);
			mdio_write(net_dev, mii_phy->phy_addr, 
				   MII_CONTROL, status & ~MII_CNTL_ISOLATE);
			sis_priv->cur_phy = mii_phy->phy_addr;
		}
		sis900_check_mode(net_dev, mii_phy);
	}

	sis_priv->timer.expires = jiffies + next_tick;
	add_timer(&sis_priv->timer);
}
예제 #16
0
파일: r8169.c 프로젝트: wxlong/Test
static void rtl8169_phy_timer(unsigned long __opaque)
{
    struct net_device *dev = (struct net_device *)__opaque;
    struct rtl8169_private *tp = dev->priv;
    struct timer_list *timer = &tp->timer;
    void *ioaddr = tp->mmio_addr;

    assert(tp->mac_version > RTL_GIGA_MAC_VER_B);
    assert(tp->phy_version < RTL_GIGA_PHY_VER_G);

    if (RTL_R8(PHYstatus) & LinkStatus)
        tp->phy_link_down_cnt = 0;
    else {
        tp->phy_link_down_cnt++;
        if (tp->phy_link_down_cnt >= 12) {
            int reg;

            // If link on 1000, perform phy reset.
            reg = mdio_read(ioaddr, PHY_1000_CTRL_REG);
            if (reg & PHY_Cap_1000_Full)
                rtl8169_hw_phy_reset(dev);

            tp->phy_link_down_cnt = 0;
        }
    }

    mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT);
}
예제 #17
0
파일: rtl8139.c 프로젝트: HarryR/sanos
static void rtl_hw_start(struct dev *dev) {
  struct nic *tp = (struct nic *) dev->privdata;
  long ioaddr = tp->iobase;
  int i;

  // Soft reset the chip
  outp(ioaddr + ChipCmd, CmdReset);

  // Check that the chip has finished the reset
  for (i = 1000; i > 0; i--) {
    if ((inp(ioaddr + ChipCmd) & CmdReset) == 0) break;
  }

  // Restore our idea of the MAC address
  outp(ioaddr + Cfg9346, 0xC0);
  outpd(ioaddr + MAC0 + 0, *(unsigned long *)(tp->hwaddr.addr + 0));
  outpd(ioaddr + MAC0 + 4, *(unsigned long *)(tp->hwaddr.addr + 4));

  // Hmmm, do these belong here?
  tp->cur_rx = 0;

  // Must enable Tx/Rx before setting transfer thresholds!
  outp(ioaddr + ChipCmd, CmdRxEnb | CmdTxEnb);
  outpd(ioaddr + RxConfig, tp->rx_config);

  // Check this value: the documentation contradicts ifself.  Is the
  // IFG correct with bit 28:27 zero, or with |0x03000000 ?
  outpd(ioaddr + TxConfig, (TX_DMA_BURST << 8));

  // This is check_duplex()
  if (tp->phys[0] >= 0 || (tp->flags & HAS_MII_XCVR)) {
    unsigned short mii_reg5 = mdio_read(dev, tp->phys[0], 5);
    if (mii_reg5 != 0xffff) {
      if ((mii_reg5 & 0x0100) == 0x0100 || (mii_reg5 & 0x00C0) == 0x0040) {
        tp->full_duplex = 1;
      }
    }

    kprintf(KERN_INFO "%s: Setting %s%s-duplex based on auto-negotiated partner ability %4.4x\n", 
      dev->name, 
      mii_reg5 == 0 ? "" : (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
      tp->full_duplex ? "full" : "half", mii_reg5);
  }

  if (tp->flags & HAS_MII_XCVR) {
    // RTL8129 chip
    outp(ioaddr + Config1, tp->full_duplex ? 0x60 : 0x20);
  }
  outp(ioaddr + Cfg9346, 0x00);

  outpd(ioaddr + RxBuf, virt2phys(tp->rx_ring));

  // Start the chip's Tx and Rx process
  outpd(ioaddr + RxMissed, 0);
  rtl8139_set_rx_mode(dev);
  outp(ioaddr + ChipCmd, CmdRxEnb | CmdTxEnb);
  
  // Enable all known interrupts by setting the interrupt mask
  outpw(ioaddr + IntrMask, PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK);
}
예제 #18
0
static int mv88e1xxx_intr_clear(struct cphy *cphy)
{
	u32 val;

	/* Clear PHY interrupts by reading the register. */
	return mdio_read(cphy, 0, MV88E1XXX_INTR_STATUS, &val);
}
예제 #19
0
파일: sundance.c 프로젝트: 42wim/ipxe
static void check_duplex(struct nic *nic)
{
	int mii_lpa = mdio_read(nic, sdc->phys[0], MII_LPA);
	int negotiated = mii_lpa & sdc->mii_if.advertising;
	int duplex;

	/* Force media */
	if (!sdc->an_enable || mii_lpa == 0xffff) {
		if (sdc->mii_if.full_duplex)
			outw(inw(BASE + MACCtrl0) | EnbFullDuplex,
			     BASE + MACCtrl0);
		return;
	}

	/* Autonegotiation */
	duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
	if (sdc->mii_if.full_duplex != duplex) {
		sdc->mii_if.full_duplex = duplex;
		DBG ("%s: Setting %s-duplex based on MII #%d "
			 "negotiated capability %4.4x.\n", sdc->nic_name,
			 duplex ? "full" : "half", sdc->phys[0],
			 negotiated );
		outw(inw(BASE + MACCtrl0) | duplex ? 0x20 : 0,
		     BASE + MACCtrl0);
	}
}
예제 #20
0
static int mv88e1xxx_get_link_status(struct cphy *cphy, int *link_ok,
				     int *speed, int *duplex, int *fc)
{
	u32 status;
	int sp = -1, dplx = -1, pause = 0;

	mdio_read(cphy, 0, MV88E1XXX_SPECIFIC_STATUS, &status);
	if ((status & V_PSSR_STATUS_RESOLVED) != 0) {
		if (status & V_PSSR_RX_PAUSE)
			pause |= PAUSE_RX;
		if (status & V_PSSR_TX_PAUSE)
			pause |= PAUSE_TX;
		dplx = (status & V_PSSR_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF;
		sp = G_PSSR_SPEED(status);
		if (sp == 0)
			sp = SPEED_10;
		else if (sp == 1)
			sp = SPEED_100;
		else
			sp = SPEED_1000;
	}
	if (link_ok)
		*link_ok = (status & V_PSSR_LINK) != 0;
	if (speed)
		*speed = sp;
	if (duplex)
		*duplex = dplx;
	if (fc)
		*fc = pause;
	return 0;
}
예제 #21
0
int t3_vsc8211_fifo_depth(adapter_t *adap, unsigned int mtu, int port)
{
	/* TX FIFO Depth set bits 9:7 to 100 (IEEE mode) */
	unsigned int val = 4;
	unsigned int currentregval;
	unsigned int regval;
	int err;

	/* Retrieve the port info structure from adater_t */
	struct port_info *portinfo = adap2pinfo(adap, port);

	/* What phy is this */
	struct cphy *phy = &portinfo->phy;

	/* Read the current value of the PHY control Register */
	err = mdio_read(phy, 0, VSC8211_PHY_CTRL, &currentregval);

	if (err)
		return err;

	/* IEEE mode supports up to 1518 bytes */
	/* mtu does not contain the header + FCS (18 bytes) */
	if (mtu > 1500)
		/* 
		 * If using a packet size > 1500  set TX FIFO Depth bits 
		 * 9:7 to 011 (Jumbo packet mode) 
		 */
		val = 3;

	regval = V_VSC8211_TXFIFODEPTH(val) | V_VSC8211_RXFIFODEPTH(val) | 
		(currentregval & ~V_VSC8211_TXFIFODEPTH(M_VSC8211_TXFIFODEPTH) &
		~V_VSC8211_RXFIFODEPTH(M_VSC8211_RXFIFODEPTH));

	return  mdio_write(phy, 0, VSC8211_PHY_CTRL, regval);
}
예제 #22
0
static int vsc8211_intr_clear(struct cphy *cphy)
{
	u32 val;

	/* Clear PHY interrupts by reading the register. */
	return mdio_read(cphy, 0, VSC8211_INTR_STATUS, &val);
}
예제 #23
0
static void sis900_read_mode(struct device *net_dev, int phy_addr, int *speed, int *duplex)
{
	int i = 0;
	u32 status;
	
	/* STSOUT register is Latched on Transition, read operation updates it */
	while (i++ < 2)
		status = mdio_read(net_dev, phy_addr, MII_STSOUT);

	if (status & MII_STSOUT_SPD)
		*speed = HW_SPEED_100_MBPS;
	else
		*speed = HW_SPEED_10_MBPS;

	if (status & MII_STSOUT_DPLX)
		*duplex = FDX_CAPABLE_FULL_SELECTED;
	else
		*duplex = FDX_CAPABLE_HALF_SELECTED;

	if (status & MII_STSOUT_LINK_FAIL)
		printk(KERN_INFO "%s: Media Link Off\n", net_dev->name);
	else
		printk(KERN_INFO "%s: Media Link On %s %s-duplex \n", 
		       net_dev->name,
		       *speed == HW_SPEED_100_MBPS ? 
		       "100mbps" : "10mbps",
		       *duplex == FDX_CAPABLE_FULL_SELECTED ?
		       "full" : "half");
}
예제 #24
0
파일: eepro100.c 프로젝트: HarryR/sanos
static void speedo_show_state(struct dev *dev) {
  struct nic *sp = (struct nic *) dev->privdata;
  long ioaddr = sp->iobase;
  int phy_num = sp->phy[0] & 0x1f;
  unsigned int i;

  // Print a few items for debugging
  kprintf("%s: Tx ring dump,  Tx queue %d / %d:\n", dev->name, sp->cur_tx, sp->dirty_tx);
  for (i = 0; i < TX_RING_SIZE; i++) {
    kprintf("%s: %c%c%d %8.8x\n", dev->name,
          i == sp->dirty_tx % TX_RING_SIZE ? '*' : ' ',
          i == sp->cur_tx % TX_RING_SIZE ? '=' : ' ',
          i, sp->tx_ring[i].status);
  }

  kprintf("%s: Rx ring dump (next to receive into %d)\n", dev->name, sp->cur_rx);

  for (i = 0; i < RX_RING_SIZE; i++) {
    kprintf("  Rx ring entry %d  %8.8x\n",  i, sp->rx_ringp[i]->status);
  }

  for (i = 0; i < 16; i++) {
    if (i == 6) i = 21;
    kprintf("  PHY index %d register %d is %4.4x.\n", phy_num, i, mdio_read(ioaddr, phy_num, i));
  }
}
예제 #25
0
static void check_duplex(struct net_device *dev)
{
	struct netdev_private *np = dev->priv;
	long ioaddr = dev->base_addr;
	int mii_reg5 = mdio_read(dev, np->phys[0], 5);
	int negotiated = mii_reg5 & np->advertising;
	int duplex;
	
	/* Force media */
	if (!np->an_enable || mii_reg5 == 0xffff) {
		if (np->full_duplex)
			writew (readw (ioaddr + MACCtrl0) | EnbFullDuplex,
				ioaddr + MACCtrl0);
		return;
	}
	/* Autonegotiation */
	duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
	if (np->full_duplex != duplex) {
		np->full_duplex = duplex;
		if (debug)
			printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d "
				   "negotiated capability %4.4x.\n", dev->name,
				   duplex ? "full" : "half", np->phys[0], negotiated);
		writew(duplex ? 0x20 : 0, ioaddr + MACCtrl0);
	}
}
예제 #26
0
static void netdev_timer(unsigned long data)
{
	struct net_device *dev = (struct net_device *)data;
	struct am_net_private *np = netdev_priv(dev);
	unsigned long ioaddr = np->base_addr;
	static int error_num = 0;
	int val;

	if (debug > 2)
		printk(KERN_INFO "%s: Media selection timer tick, mac status %8.8x \n", 
				dev->name,
		       ioread32(ioaddr + ETH_DMA_5_Status));
	if (!phy_linked(np)) {	//unlink .....
		error_num++;
		if (error_num > 30) {
			error_num = 0;
			spin_lock_irq(&np->lock);
			val = (1 << 14) | (7 << 5) | np->phys[0];
			mdio_write(dev, np->phys[0], 18, val);
			// Auto negotiation restart 
			val = mdio_read(dev, np->phys[0], MII_BMCR);
			
			#ifdef PHY_LOOPBACK_TEST	
			val = 1<<14 | 1<<8 | 1<<13;//100M,full,seting it as 
			#else
			val |= BMCR_ANENABLE | BMCR_ANRESTART;
			#endif	
			mdio_write(dev, np->phys[0], MII_BMCR, val);
			spin_unlock_irq(&np->lock);
		}
		np->timer.expires = jiffies + 1 * HZ;
		netif_stop_queue(dev);
		netif_carrier_off(dev);
		np->phy_set[0] = 0;
	} else {		//linked 
		val = mdio_read(dev, np->phys[0], 1);
		if (np->phy_set[0] != val) {
			np->phy_set[0] =val;
			phy_auto_negotiation_set(np);
		}
		error_num = 0;
		netif_carrier_on(dev);
		netif_start_queue(dev);
		np->timer.expires = jiffies + 1 * HZ;
	}
	add_timer(&np->timer);
}
예제 #27
0
static void rtl8129_timer(unsigned long data)
{
	struct device *dev = (struct device *)data;
	struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
	long ioaddr = dev->base_addr;
	int next_tick = 60*HZ;
	int mii_reg5 = mdio_read(dev, tp->phys[0], 5);

	if (! tp->duplex_lock  &&  mii_reg5 != 0xffff) {
		int duplex = (mii_reg5&0x0100) || (mii_reg5 & 0x01C0) == 0x0040;
		if (tp->full_duplex != duplex) {
			tp->full_duplex = duplex;
			printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d link"
				   " partner ability of %4.4x.\n", dev->name,
				   tp->full_duplex ? "full" : "half", tp->phys[0], mii_reg5);
			outb(0xC0, ioaddr + Cfg9346);
			outb(tp->full_duplex ? 0x60 : 0x20, ioaddr + Config1);
			outb(0x00, ioaddr + Cfg9346);
		}
	}
	/* Check for bogusness. */
	if (inw(ioaddr + IntrStatus) & (TxOK | RxOK)) {
		int status = inw(ioaddr + IntrStatus);
		if (status & (TxOK | RxOK)) {	/* Double check */
			printk(KERN_ERR "%s: RTL8139 Interrupt line blocked, status %x.\n",
				   dev->name, status);
			rtl8129_interrupt(dev->irq, dev, 0);
		}
	}
	if (dev->tbusy  &&  jiffies - dev->trans_start >= 2*TX_TIMEOUT)
		rtl8129_tx_timeout(dev);

#if 0
	if (tp->twistie) {
		unsigned int CSCRval = inw(ioaddr + CSCR);		/* Read link status. */
		if (tp->twistie == 1) {
			if (CSCRval & CSCR_LinkOKBit) {
				outw(CSCR_LinkDownOffCmd, ioaddr + CSCR);
				tp->twistie = 2;
				next_tick = HZ/10;
			} else {
				outw(CSCR_LinkDownCmd, ioaddr + CSCR);
				outl(FIFOTMS_default,ioaddr + FIFOTMS);
				outl(PARA78_default ,ioaddr + PARA78);
				outl(PARA7c_default ,ioaddr + PARA7c);
				tp->twistie = 0;
			}
		} else if (tp->twistie == 2) {
			int linkcase = (CSCRval & CSCR_LinkStatusBits) >> 12;
			int row;
			if (linkcase >= 0x7000) row = 3;
			else if (linkcase >= 0x3000) row = 2;
			else if (linkcase >= 0x1000) row = 1;
			else row = 0;
			tp->twistie == row + 3;
			outw(0,ioaddr+FIFOTMS);
			outl(param[row][0], ioaddr+PARA7c);
			tp->twist_cnt = 1;
		} else {
예제 #28
0
static int my3126_interrupt_handler(struct cphy *cphy)
{
	u32 val;
	u16 val16;
	u16 status;
	u32 act_count;
	adapter_t *adapter;
	adapter = cphy->adapter;

	if (cphy->count == 50) {
		mdio_read(cphy, 0x1, 0x1, &val);
		val16 = (u16) val;
		status = cphy->bmsr ^ val16;

		if (status & BMSR_LSTATUS)
			t1_link_changed(adapter, 0);
		cphy->bmsr = val16;

		/* We have only enabled link change interrupts so it
		   must be that
		 */
		cphy->count = 0;
	}

	t1_tpi_write(adapter, OFFSET(SUNI1x10GEXP_REG_MSTAT_CONTROL),
		SUNI1x10GEXP_BITMSK_MSTAT_SNAP);
	t1_tpi_read(adapter,
		OFFSET(SUNI1x10GEXP_REG_MSTAT_COUNTER_1_LOW), &act_count);
	t1_tpi_read(adapter,
		OFFSET(SUNI1x10GEXP_REG_MSTAT_COUNTER_33_LOW), &val);
	act_count += val;

	/* Populate elmer_gpo with the register value */
	t1_tpi_read(adapter, A_ELMER0_GPO, &val);
	cphy->elmer_gpo = val;

	if ( (val & (1 << 8)) || (val & (1 << 19)) ||
	     (cphy->act_count == act_count) || cphy->act_on ) {
		if (is_T2(adapter))
			val |= (1 << 9);
		else if (t1_is_T1B(adapter))
			val |= (1 << 20);
		cphy->act_on = 0;
	} else {
		if (is_T2(adapter))
			val &= ~(1 << 9);
		else if (t1_is_T1B(adapter))
			val &= ~(1 << 20);
		cphy->act_on = 1;
	}

	t1_tpi_write(adapter, A_ELMER0_GPO, val);

	cphy->elmer_gpo = val;
	cphy->act_count = act_count;
	cphy->count++;

	return cphy_cause_link_change;
}
예제 #29
0
static void monitor_status(long ioaddr, int phy_id)
{
	unsigned int baseline_1 = 0x55555555; 	/* Always show initial status. */

	while (1) {
		unsigned int new_1 = mdio_read(ioaddr, phy_id, 1);
		if (new_1 != baseline_1) {
			printf("%-12s 0x%4.4x 0x%4.4x\n",
				   new_1 & 0x04 ? (new_1==0xffff ? "unknown" : "up") :
				   new_1 & 0x20 ? "negotiating" : "down",
				   new_1, mdio_read(ioaddr, phy_id, 5));
			fflush(stdout);
			baseline_1 = new_1;
		}
		sleep(1);
	}
}
예제 #30
0
static int robo_probe(char *devname)
{
	struct ethtool_drvinfo info;
	int i;
	__u32 phyid;

	printk("Probing device %s: ", devname);
	strcpy(ifr.ifr_name, devname);

	if ((dev = dev_get_by_name(devname)) == NULL) {
		printk("No such device\n");
		return 1;
	}

	info.cmd = ETHTOOL_GDRVINFO;
	if (do_ioctl(SIOCETHTOOL, (void *) &info) < 0) {
		printk("SIOCETHTOOL: not supported\n");
		return 1;
	}
	
	/* try access using MII ioctls - get phy address */
	if (do_ioctl(SIOCGMIIPHY, NULL) < 0) {
		use_et = 1;
	} else {
		/* got phy address check for robo address */
		struct mii_ioctl_data *mii = (struct mii_ioctl_data *) &ifr.ifr_data;
		if (mii->phy_id != ROBO_PHY_ADDR) {
			printk("Invalid phy address (%d)\n", mii->phy_id);
			return 1;
		}
	}

	phyid = mdio_read(ROBO_PHY_ADDR, 0x2) | 
		(mdio_read(ROBO_PHY_ADDR, 0x3) << 16);

	if (phyid == 0xffffffff || phyid == 0x55210022) {
		printk("No Robo switch in managed mode found\n");
		return 1;
	}
	
	is_5350 = robo_vlan5350();
	
	printk("found!\n");
	return 0;
}