-/* $Id: ethernet.c,v 1.31 2004/10/18 14:49:03 starvik Exp $
+/* $Id: ethernet.c,v 1.22 2004/05/14 07:58:03 starvik Exp $
*
* e100net.c: A network driver for the ETRAX 100LX network controller.
*
* The outline of this driver comes from skeleton.c.
*
* $Log: ethernet.c,v $
- * Revision 1.31 2004/10/18 14:49:03 starvik
- * Use RX interrupt as random source
- *
- * Revision 1.30 2004/09/29 10:44:04 starvik
- * Enabed MAC-address output again
- *
- * Revision 1.29 2004/08/24 07:14:05 starvik
- * Make use of generic MDIO interface and constants.
- *
- * Revision 1.28 2004/08/20 09:37:11 starvik
- * Added support for Intel LXT972A. Creds to Randy Scarborough.
- *
- * Revision 1.27 2004/08/16 12:37:22 starvik
- * Merge of Linux 2.6.8
- *
- * Revision 1.25 2004/06/21 10:29:57 starvik
- * Merge of Linux 2.6.7
- *
- * Revision 1.23 2004/06/09 05:29:22 starvik
- * Avoid any race where R_DMA_CH1_FIRST is NULL (may trigger cache bug).
- *
* Revision 1.22 2004/05/14 07:58:03 starvik
* Merge of changes from 2.4
*
/* Information that need to be kept for each board. */
struct net_local {
struct net_device_stats stats;
- struct mii_if_info mii_if;
/* Tx control lock. This protects the transmit buffer ring
* state along with the "tx full" state of the driver. This
struct transceiver_ops
{
unsigned int oui;
- void (*check_speed)(struct net_device* dev);
- void (*check_duplex)(struct net_device* dev);
+ void (*check_speed)(void);
+ void (*check_duplex)(void);
};
struct transceiver_ops* transceiver;
#define MIN_PACKET_LEN 46
#define ETHER_HEAD_LEN 14
-/*
+/*
** MDIO constants.
*/
+#define MDIO_BASE_STATUS_REG 0x1
+#define MDIO_BASE_CONTROL_REG 0x0
+#define MDIO_PHY_ID_HIGH_REG 0x2
+#define MDIO_PHY_ID_LOW_REG 0x3
+#define MDIO_BC_NEGOTIATE 0x0200
+#define MDIO_BC_FULL_DUPLEX_MASK 0x0100
+#define MDIO_BC_AUTO_NEG_MASK 0x1000
+#define MDIO_BC_SPEED_SELECT_MASK 0x2000
+#define MDIO_STATUS_100_FD 0x4000
+#define MDIO_STATUS_100_HD 0x2000
+#define MDIO_STATUS_10_FD 0x1000
+#define MDIO_STATUS_10_HD 0x0800
+#define MDIO_STATUS_SPEED_DUPLEX_MASK 0x7800
+#define MDIO_ADVERTISMENT_REG 0x4
+#define MDIO_ADVERT_100_FD 0x100
+#define MDIO_ADVERT_100_HD 0x080
+#define MDIO_ADVERT_10_FD 0x040
+#define MDIO_ADVERT_10_HD 0x020
+#define MDIO_LINK_UP_MASK 0x4
#define MDIO_START 0x1
#define MDIO_READ 0x2
#define MDIO_WRITE 0x1
#define MDIO_TDK_DIAGNOSTIC_RATE 0x400
#define MDIO_TDK_DIAGNOSTIC_DPLX 0x800
-/*Intel LXT972A specific*/
-#define MDIO_INT_STATUS_REG_2 0x0011
-#define MDIO_INT_FULL_DUPLEX_IND ( 1 << 9 )
-#define MDIO_INT_SPEED ( 1 << 14 )
-
/* Network flash constants */
#define NET_FLASH_TIME (HZ/50) /* 20 ms */
#define NET_FLASH_PAUSE (HZ/100) /* 10 ms */
static void e100_hardware_send_packet(char *buf, int length);
static void update_rx_stats(struct net_device_stats *);
static void update_tx_stats(struct net_device_stats *);
-static int e100_probe_transceiver(struct net_device* dev);
+static int e100_probe_transceiver(void);
-static void e100_check_speed(unsigned long priv);
-static void e100_set_speed(struct net_device* dev, unsigned long speed);
-static void e100_check_duplex(unsigned long priv);
-static void e100_set_duplex(struct net_device* dev, enum duplex);
-static void e100_negotiate(struct net_device* dev);
-
-static int e100_get_mdio_reg(struct net_device *dev, int phy_id, int location);
-static void e100_set_mdio_reg(struct net_device *dev, int phy_id, int location, int value);
+static void e100_check_speed(unsigned long dummy);
+static void e100_set_speed(unsigned long speed);
+static void e100_check_duplex(unsigned long dummy);
+static void e100_set_duplex(enum duplex);
+static void e100_negotiate(void);
+static unsigned short e100_get_mdio_reg(unsigned char reg_num);
+static void e100_set_mdio_reg(unsigned char reg, unsigned short data);
static void e100_send_mdio_cmd(unsigned short cmd, int write_cmd);
static void e100_send_mdio_bit(unsigned char bit);
static unsigned char e100_receive_mdio_bit(void);
-static void e100_reset_transceiver(struct net_device* net);
+static void e100_reset_transceiver(void);
static void e100_clear_network_leds(unsigned long dummy);
static void e100_set_network_leds(int active);
-static void broadcom_check_speed(struct net_device* dev);
-static void broadcom_check_duplex(struct net_device* dev);
-static void tdk_check_speed(struct net_device* dev);
-static void tdk_check_duplex(struct net_device* dev);
-static void intel_check_speed(struct net_device* dev);
-static void intel_check_duplex(struct net_device* dev);
-static void generic_check_speed(struct net_device* dev);
-static void generic_check_duplex(struct net_device* dev);
+static void broadcom_check_speed(void);
+static void broadcom_check_duplex(void);
+static void tdk_check_speed(void);
+static void tdk_check_duplex(void);
+static void generic_check_speed(void);
+static void generic_check_duplex(void);
struct transceiver_ops transceivers[] =
{
{0x1018, broadcom_check_speed, broadcom_check_duplex}, /* Broadcom */
{0xC039, tdk_check_speed, tdk_check_duplex}, /* TDK 2120 */
{0x039C, tdk_check_speed, tdk_check_duplex}, /* TDK 2120C */
- {0x04de, intel_check_speed, intel_check_duplex}, /* Intel LXT972A*/
{0x0000, generic_check_speed, generic_check_duplex} /* Generic, must be last */
};
etrax_ethernet_init(void)
{
struct net_device *dev;
- struct net_local* np;
int i, err;
printk(KERN_INFO
"ETRAX 100LX 10/100MBit ethernet v2.0 (c) 2000-2003 Axis Communications AB\n");
dev = alloc_etherdev(sizeof(struct net_local));
- np = dev->priv;
-
if (!dev)
return -ENOMEM;
- dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */
+ dev->base_addr = (unsigned int)R_NETWORK_SA_0; /* just to have something to show */
/* now setup our etrax specific stuff */
RxDescList[i].descr.next = virt_to_phys(&RxDescList[i + 1]);
RxDescList[i].descr.buf = L1_CACHE_ALIGN(virt_to_phys(RxDescList[i].skb->data));
RxDescList[i].descr.status = 0;
- RxDescList[i].descr.hw_len = 0;
+ RxDescList[i].descr.hw_len = 0;
prepare_rx_descriptor(&RxDescList[i].descr);
}
TxDescList[NBR_OF_TX_DESC - 1].descr.ctrl = d_eol;
TxDescList[NBR_OF_TX_DESC - 1].descr.next = virt_to_phys(&TxDescList[0].descr);
-
+
/* Initialise initial pointers */
myNextRxDesc = &RxDescList[0];
current_speed = 10;
current_speed_selection = 0; /* Auto */
speed_timer.expires = jiffies + NET_LINK_UP_CHECK_INTERVAL;
- duplex_timer.data = (unsigned long)dev;
speed_timer.function = e100_check_speed;
-
+
clear_led_timer.function = e100_clear_network_leds;
-
+
full_duplex = 0;
current_duplex = autoneg;
- duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL;
- duplex_timer.data = (unsigned long)dev;
+ duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL;
duplex_timer.function = e100_check_duplex;
- /* Initialize mii interface */
- np->mii_if.phy_id = mdio_phy_addr;
- np->mii_if.phy_id_mask = 0x1f;
- np->mii_if.reg_num_mask = 0x1f;
- np->mii_if.dev = dev;
- np->mii_if.mdio_read = e100_get_mdio_reg;
- np->mii_if.mdio_write = e100_set_mdio_reg;
-
/* Initialize group address registers to make sure that no */
/* unwanted addresses are matched */
*R_NETWORK_GA_0 = 0x00000000;
* *R_NETWORK_SA_0 = a0_0 | (a0_1 << 8) | (a0_2 << 16) | (a0_3 << 24);
* *R_NETWORK_SA_1 = a0_4 | (a0_5 << 8);
*/
-
+
*R_NETWORK_SA_0 = dev->dev_addr[0] | (dev->dev_addr[1] << 8) |
(dev->dev_addr[2] << 16) | (dev->dev_addr[3] << 24);
*R_NETWORK_SA_1 = dev->dev_addr[4] | (dev->dev_addr[5] << 8);
IO_STATE(R_IRQ_MASK0_CLR, overrun, clr) |
IO_STATE(R_IRQ_MASK0_CLR, underrun, clr) |
IO_STATE(R_IRQ_MASK0_CLR, excessive_col, clr);
-
+
/* clear dma0 and 1 eop and descr irq masks */
*R_IRQ_MASK2_CLR =
IO_STATE(R_IRQ_MASK2_CLR, dma0_descr, clr) |
/* allocate the irq corresponding to the receiving DMA */
- if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt,
- SA_SAMPLE_RANDOM, cardname, (void *)dev)) {
+ if (request_irq(NETWORK_DMA_RX_IRQ_NBR, e100rxtx_interrupt, 0,
+ cardname, (void *)dev)) {
goto grace_exit0;
}
*R_DMA_CH1_CMD = IO_STATE(R_DMA_CH1_CMD, cmd, start);
/* Set up transmit DMA channel so it can be restarted later */
-
+
*R_DMA_CH0_FIRST = 0;
*R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc);
restore_flags(flags);
-
+
/* Probe for transceiver */
- if (e100_probe_transceiver(dev))
+ if (e100_probe_transceiver())
goto grace_exit3;
/* Start duplex/speed timers */
static void
-generic_check_speed(struct net_device* dev)
+generic_check_speed(void)
{
unsigned long data;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE);
- if ((data & ADVERTISE_100FULL) ||
- (data & ADVERTISE_100HALF))
+ data = e100_get_mdio_reg(MDIO_ADVERTISMENT_REG);
+ if ((data & MDIO_ADVERT_100_FD) ||
+ (data & MDIO_ADVERT_100_HD))
current_speed = 100;
else
current_speed = 10;
}
static void
-tdk_check_speed(struct net_device* dev)
+tdk_check_speed(void)
{
unsigned long data;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_TDK_DIAGNOSTIC_REG);
+ data = e100_get_mdio_reg(MDIO_TDK_DIAGNOSTIC_REG);
current_speed = (data & MDIO_TDK_DIAGNOSTIC_RATE ? 100 : 10);
}
static void
-broadcom_check_speed(struct net_device* dev)
+broadcom_check_speed(void)
{
unsigned long data;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_AUX_CTRL_STATUS_REG);
+ data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG);
current_speed = (data & MDIO_BC_SPEED ? 100 : 10);
}
static void
-intel_check_speed(struct net_device* dev)
-{
- unsigned long data;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_INT_STATUS_REG_2);
- current_speed = (data & MDIO_INT_SPEED ? 100 : 10);
-}
-
-static void
-e100_check_speed(unsigned long priv)
+e100_check_speed(unsigned long dummy)
{
- struct net_device* dev = (struct net_device*)priv;
static int led_initiated = 0;
unsigned long data;
int old_speed = current_speed;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMSR);
- if (!(data & BMSR_LSTATUS)) {
+ data = e100_get_mdio_reg(MDIO_BASE_STATUS_REG);
+ if (!(data & MDIO_LINK_UP_MASK)) {
current_speed = 0;
} else {
- transceiver->check_speed(dev);
+ transceiver->check_speed();
}
-
+
if ((old_speed != current_speed) || !led_initiated) {
led_initiated = 1;
e100_set_network_leds(NO_NETWORK_ACTIVITY);
}
static void
-e100_negotiate(struct net_device* dev)
+e100_negotiate(void)
{
- unsigned short data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE);
+ unsigned short data = e100_get_mdio_reg(MDIO_ADVERTISMENT_REG);
/* Discard old speed and duplex settings */
- data &= ~(ADVERTISE_100HALF | ADVERTISE_100FULL |
- ADVERTISE_10HALF | ADVERTISE_10FULL);
-
+ data &= ~(MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD |
+ MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD);
+
switch (current_speed_selection) {
case 10 :
if (current_duplex == full)
- data |= ADVERTISE_10FULL;
+ data |= MDIO_ADVERT_10_FD;
else if (current_duplex == half)
- data |= ADVERTISE_10HALF;
+ data |= MDIO_ADVERT_10_HD;
else
- data |= ADVERTISE_10HALF | ADVERTISE_10FULL;
+ data |= MDIO_ADVERT_10_HD | MDIO_ADVERT_10_FD;
break;
case 100 :
if (current_duplex == full)
- data |= ADVERTISE_100FULL;
+ data |= MDIO_ADVERT_100_FD;
else if (current_duplex == half)
- data |= ADVERTISE_100HALF;
+ data |= MDIO_ADVERT_100_HD;
else
- data |= ADVERTISE_100HALF | ADVERTISE_100FULL;
+ data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD;
break;
case 0 : /* Auto */
if (current_duplex == full)
- data |= ADVERTISE_100FULL | ADVERTISE_10FULL;
+ data |= MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD;
else if (current_duplex == half)
- data |= ADVERTISE_100HALF | ADVERTISE_10HALF;
+ data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_10_HD;
else
- data |= ADVERTISE_10HALF | ADVERTISE_10FULL |
- ADVERTISE_100HALF | ADVERTISE_100FULL;
+ data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD | MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD;
break;
default : /* assume autoneg speed and duplex */
- data |= ADVERTISE_10HALF | ADVERTISE_10FULL |
- ADVERTISE_100HALF | ADVERTISE_100FULL;
+ data |= MDIO_ADVERT_100_HD | MDIO_ADVERT_100_FD |
+ MDIO_ADVERT_10_FD | MDIO_ADVERT_10_HD;
}
- e100_set_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE, data);
+ e100_set_mdio_reg(MDIO_ADVERTISMENT_REG, data);
/* Renegotiate with link partner */
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMCR);
- data |= BMCR_ANENABLE | BMCR_ANRESTART;
+ data = e100_get_mdio_reg(MDIO_BASE_CONTROL_REG);
+ data |= MDIO_BC_NEGOTIATE;
- e100_set_mdio_reg(dev, mdio_phy_addr, MII_BMCR, data);
+ e100_set_mdio_reg(MDIO_BASE_CONTROL_REG, data);
}
static void
-e100_set_speed(struct net_device* dev, unsigned long speed)
+e100_set_speed(unsigned long speed)
{
if (speed != current_speed_selection) {
current_speed_selection = speed;
- e100_negotiate(dev);
+ e100_negotiate();
}
}
static void
-e100_check_duplex(unsigned long priv)
+e100_check_duplex(unsigned long dummy)
{
- struct net_device *dev = (struct net_device *)priv;
- struct net_local *np = (struct net_local *)dev->priv;
int old_duplex = full_duplex;
- transceiver->check_duplex(dev);
+ transceiver->check_duplex();
if (old_duplex != full_duplex) {
/* Duplex changed */
SETF(network_rec_config_shadow, R_NETWORK_REC_CONFIG, duplex, full_duplex);
/* Reinitialize the timer. */
duplex_timer.expires = jiffies + NET_DUPLEX_CHECK_INTERVAL;
add_timer(&duplex_timer);
- np->mii_if.full_duplex = full_duplex;
}
static void
-generic_check_duplex(struct net_device* dev)
+generic_check_duplex(void)
{
unsigned long data;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_ADVERTISE);
- if ((data & ADVERTISE_10FULL) ||
- (data & ADVERTISE_100FULL))
+ data = e100_get_mdio_reg(MDIO_ADVERTISMENT_REG);
+ if ((data & MDIO_ADVERT_100_FD) ||
+ (data & MDIO_ADVERT_10_FD))
full_duplex = 1;
else
full_duplex = 0;
}
static void
-tdk_check_duplex(struct net_device* dev)
+tdk_check_duplex(void)
{
unsigned long data;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_TDK_DIAGNOSTIC_REG);
+ data = e100_get_mdio_reg(MDIO_TDK_DIAGNOSTIC_REG);
full_duplex = (data & MDIO_TDK_DIAGNOSTIC_DPLX) ? 1 : 0;
}
static void
-broadcom_check_duplex(struct net_device* dev)
+broadcom_check_duplex(void)
{
unsigned long data;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_AUX_CTRL_STATUS_REG);
+ data = e100_get_mdio_reg(MDIO_AUX_CTRL_STATUS_REG);
full_duplex = (data & MDIO_BC_FULL_DUPLEX_IND) ? 1 : 0;
}
-static void
-intel_check_duplex(struct net_device* dev)
-{
- unsigned long data;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MDIO_INT_STATUS_REG_2);
- full_duplex = (data & MDIO_INT_FULL_DUPLEX_IND) ? 1 : 0;
-}
-
-static void
-e100_set_duplex(struct net_device* dev, enum duplex new_duplex)
+static void
+e100_set_duplex(enum duplex new_duplex)
{
if (new_duplex != current_duplex) {
current_duplex = new_duplex;
- e100_negotiate(dev);
+ e100_negotiate();
}
}
static int
-e100_probe_transceiver(struct net_device* dev)
+e100_probe_transceiver(void)
{
unsigned int phyid_high;
unsigned int phyid_low;
/* Probe MDIO physical address */
for (mdio_phy_addr = 0; mdio_phy_addr <= 31; mdio_phy_addr++) {
- if (e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMSR) != 0xffff)
+ if (e100_get_mdio_reg(MDIO_BASE_STATUS_REG) != 0xffff)
break;
}
if (mdio_phy_addr == 32)
return -ENODEV;
/* Get manufacturer */
- phyid_high = e100_get_mdio_reg(dev, mdio_phy_addr, MII_PHYSID1);
- phyid_low = e100_get_mdio_reg(dev, mdio_phy_addr, MII_PHYSID2);
+ phyid_high = e100_get_mdio_reg(MDIO_PHY_ID_HIGH_REG);
+ phyid_low = e100_get_mdio_reg(MDIO_PHY_ID_LOW_REG);
oui = (phyid_high << 6) | (phyid_low >> 10);
for (ops = &transceivers[0]; ops->oui; ops++) {
return 0;
}
-static int
-e100_get_mdio_reg(struct net_device *dev, int phy_id, int location)
+static unsigned short
+e100_get_mdio_reg(unsigned char reg_num)
{
unsigned short cmd; /* Data to be sent on MDIO port */
- int data; /* Data read from MDIO */
+ unsigned short data; /* Data read from MDIO */
int bitCounter;
-
+
/* Start of frame, OP Code, Physical Address, Register Address */
- cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (phy_id << 7) |
- (location << 2);
-
+ cmd = (MDIO_START << 14) | (MDIO_READ << 12) | (mdio_phy_addr << 7) |
+ (reg_num << 2);
+
e100_send_mdio_cmd(cmd, 0);
-
+
data = 0;
-
+
/* Data... */
for (bitCounter=15; bitCounter>=0 ; bitCounter--) {
data |= (e100_receive_mdio_bit() << bitCounter);
}
static void
-e100_set_mdio_reg(struct net_device *dev, int phy_id, int location, int value)
+e100_set_mdio_reg(unsigned char reg, unsigned short data)
{
int bitCounter;
unsigned short cmd;
- cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (phy_id << 7) |
- (location << 2);
+ cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) |
+ (reg << 2);
e100_send_mdio_cmd(cmd, 1);
/* Data... */
for (bitCounter=15; bitCounter>=0 ; bitCounter--) {
- e100_send_mdio_bit(GET_BIT(bitCounter, value));
+ e100_send_mdio_bit(GET_BIT(bitCounter, data));
}
}
{
int bitCounter;
unsigned char data = 0x2;
-
+
/* Preamble */
for (bitCounter = 31; bitCounter>= 0; bitCounter--)
e100_send_mdio_bit(GET_BIT(bitCounter, MDIO_PREAMBLE));
return bit;
}
-static void
-e100_reset_transceiver(struct net_device* dev)
+static void
+e100_reset_transceiver(void)
{
unsigned short cmd;
unsigned short data;
int bitCounter;
- data = e100_get_mdio_reg(dev, mdio_phy_addr, MII_BMCR);
+ data = e100_get_mdio_reg(MDIO_BASE_CONTROL_REG);
- cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (MII_BMCR << 2);
+ cmd = (MDIO_START << 14) | (MDIO_WRITE << 12) | (mdio_phy_addr << 7) | (MDIO_BASE_CONTROL_REG << 2);
e100_send_mdio_cmd(cmd, 1);
-
+
data |= 0x8000;
-
+
for (bitCounter = 15; bitCounter >= 0 ; bitCounter--) {
e100_send_mdio_bit(GET_BIT(bitCounter, data));
}
printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
tx_done(dev) ? "IRQ problem" : "network cable problem");
-
+
/* remember we got an error */
-
- np->stats.tx_errors++;
-
+
+ np->stats.tx_errors++;
+
/* reset the TX DMA in case it has hung on something */
-
+
RESET_DMA(NETWORK_TX_DMA_NBR);
WAIT_DMA(NETWORK_TX_DMA_NBR);
-
+
/* Reset the transceiver. */
-
- e100_reset_transceiver(dev);
-
+
+ e100_reset_transceiver();
+
/* and get rid of the packets that never got an interrupt */
while (myFirstTxDesc != myNextTxDesc)
{
/* Set up transmit DMA channel so it can be restarted later */
*R_DMA_CH0_FIRST = 0;
- *R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc);
+ *R_DMA_CH0_DESCR = virt_to_phys(myLastTxDesc);
/* tell the upper layers we're ok again */
-
+
netif_wake_queue(dev);
spin_unlock_irqrestore(&np->lock, flags);
}
struct net_local *np = (struct net_local *)dev->priv;
unsigned char *buf = skb->data;
unsigned long flags;
-
+
#ifdef ETHDEBUG
printk("send packet len %d\n", length);
#endif
myNextTxDesc->skb = skb;
dev->trans_start = jiffies;
-
+
e100_hardware_send_packet(buf, skb->len);
myNextTxDesc = phys_to_virt(myNextTxDesc->descr.next);
struct net_device *dev = (struct net_device *)dev_id;
struct net_local *np = (struct net_local *)dev->priv;
unsigned long irqbits = *R_IRQ_MASK2_RD;
-
+
/* Disable RX/TX IRQs to avoid reentrancy */
*R_IRQ_MASK2_CLR =
IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) |
/* check if one or more complete packets were indeed received */
- while ((*R_DMA_CH1_FIRST != virt_to_phys(myNextRxDesc)) &&
- (myNextRxDesc != myLastRxDesc)) {
+ while (*R_DMA_CH1_FIRST != virt_to_phys(myNextRxDesc)) {
/* Take out the buffer and give it to the OS, then
* allocate a new buffer to put a packet in.
*/
*R_DMA_CH1_CLR_INTR =
IO_STATE(R_DMA_CH1_CLR_INTR, clr_eop, do) |
IO_STATE(R_DMA_CH1_CLR_INTR, clr_descr, do);
-
+
/* now, we might have gotten another packet
so we have to loop back and check if so */
}
unsigned long irqbits = *R_IRQ_MASK0_RD;
/* check for underrun irq */
- if (irqbits & IO_STATE(R_IRQ_MASK0_RD, underrun, active)) {
+ if (irqbits & IO_STATE(R_IRQ_MASK0_RD, underrun, active)) {
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr);
*R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop);
}
/* check for overrun irq */
- if (irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) {
+ if (irqbits & IO_STATE(R_IRQ_MASK0_RD, overrun, active)) {
update_rx_stats(&np->stats); /* this will ack the irq */
D(printk("ethernet receiver overrun!\n"));
}
/* check for excessive collision irq */
- if (irqbits & IO_STATE(R_IRQ_MASK0_RD, excessive_col, active)) {
+ if (irqbits & IO_STATE(R_IRQ_MASK0_RD, excessive_col, active)) {
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, clr);
*R_NETWORK_TR_CTRL = network_tr_ctrl_shadow;
SETS(network_tr_ctrl_shadow, R_NETWORK_TR_CTRL, clr_error, nop);
skb->head, skb->data, skb->tail, skb->end);
printk("copying packet to 0x%x.\n", skb_data_ptr);
#endif
-
+
memcpy(skb_data_ptr, phys_to_virt(myNextRxDesc->descr.buf), length);
}
else {
- /* Large packet, send directly to upper layers and allocate new
+ /* Large packet, send directly to upper layers and allocate new
* memory (aligned to cache line boundary to avoid bug).
- * Before sending the skb to upper layers we must make sure that
- * skb->data points to the aligned start of the packet.
+ * Before sending the skb to upper layers we must make sure that
+ * skb->data points to the aligned start of the packet.
*/
- int align;
+ int align;
struct sk_buff *new_skb = dev_alloc_skb(MAX_MEDIA_DATA_SIZE + 2 * L1_CACHE_BYTES);
if (!new_skb) {
np->stats.rx_errors++;
return;
}
skb = myNextRxDesc->skb;
- align = (int)phys_to_virt(myNextRxDesc->descr.buf) - (int)skb->data;
- skb_put(skb, length + align);
+ align = (int)phys_to_virt(myNextRxDesc->descr.buf) - (int)skb->data;
+ skb_put(skb, length + align);
skb_pull(skb, align); /* Remove alignment bytes */
myNextRxDesc->skb = new_skb;
myNextRxDesc->descr.buf = L1_CACHE_ALIGN(virt_to_phys(myNextRxDesc->skb->data));
IO_STATE(R_IRQ_MASK0_CLR, overrun, clr) |
IO_STATE(R_IRQ_MASK0_CLR, underrun, clr) |
IO_STATE(R_IRQ_MASK0_CLR, excessive_col, clr);
-
+
*R_IRQ_MASK2_CLR =
IO_STATE(R_IRQ_MASK2_CLR, dma0_descr, clr) |
IO_STATE(R_IRQ_MASK2_CLR, dma0_eop, clr) |
data->phy_id = mdio_phy_addr;
break;
case SIOCGMIIREG: /* Read MII register */
- data->val_out = e100_get_mdio_reg(dev, mdio_phy_addr, data->reg_num);
+ data->val_out = e100_get_mdio_reg(data->reg_num);
break;
case SIOCSMIIREG: /* Write MII register */
- e100_set_mdio_reg(dev, mdio_phy_addr, data->reg_num, data->val_in);
+ e100_set_mdio_reg(data->reg_num, data->val_in);
break;
/* The ioctls below should be considered obsolete but are */
- /* still present for compatability with old scripts/apps */
+ /* still present for compatability with old scripts/apps */
case SET_ETH_SPEED_10: /* 10 Mbps */
- e100_set_speed(dev, 10);
+ e100_set_speed(10);
break;
case SET_ETH_SPEED_100: /* 100 Mbps */
- e100_set_speed(dev, 100);
+ e100_set_speed(100);
break;
case SET_ETH_SPEED_AUTO: /* Auto negotiate speed */
- e100_set_speed(dev, 0);
+ e100_set_speed(0);
break;
case SET_ETH_DUPLEX_HALF: /* Half duplex. */
- e100_set_duplex(dev, half);
+ e100_set_duplex(half);
break;
case SET_ETH_DUPLEX_FULL: /* Full duplex. */
- e100_set_duplex(dev, full);
+ e100_set_duplex(full);
break;
case SET_ETH_DUPLEX_AUTO: /* Autonegotiate duplex*/
- e100_set_duplex(dev, autoneg);
+ e100_set_duplex(autoneg);
break;
default:
return -EINVAL;
case ETHTOOL_GSET:
{
memset((void *) &ecmd, 0, sizeof (ecmd));
- ecmd.supported =
+ ecmd.supported =
SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |
- SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+ SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full;
ecmd.port = PORT_TP;
ecmd.transceiver = XCVR_EXTERNAL;
if (current_duplex == autoneg && current_speed_selection == 0)
ecmd.advertising |= ADVERTISED_Autoneg;
else {
- ecmd.advertising |=
+ ecmd.advertising |=
ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full |
ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full;
if (current_speed_selection == 10)
return -EPERM;
}
if (ecmd.autoneg == AUTONEG_ENABLE) {
- e100_set_duplex(dev, autoneg);
- e100_set_speed(dev, 0);
+ e100_set_duplex(autoneg);
+ e100_set_speed(0);
} else {
- e100_set_duplex(dev, ecmd.duplex == DUPLEX_HALF ? half : full);
- e100_set_speed(dev, ecmd.speed == SPEED_10 ? 10: 100);
+ e100_set_duplex(ecmd.duplex == DUPLEX_HALF ? half : full);
+ e100_set_speed(ecmd.speed == SPEED_10 ? 10: 100);
}
}
break;
struct ethtool_drvinfo info;
memset((void *) &info, 0, sizeof (info));
strncpy(info.driver, "ETRAX 100LX", sizeof(info.driver) - 1);
- strncpy(info.version, "$Revision: 1.31 $", sizeof(info.version) - 1);
+ strncpy(info.version, "$Revision: 1.22 $", sizeof(info.version) - 1);
strncpy(info.fw_version, "N/A", sizeof(info.fw_version) - 1);
strncpy(info.bus_info, "N/A", sizeof(info.bus_info) - 1);
info.regdump_len = 0;
break;
case ETHTOOL_NWAY_RST:
if (current_duplex == autoneg && current_speed_selection == 0)
- e100_negotiate(dev);
+ e100_negotiate();
break;
default:
return -EOPNOTSUPP;
{
struct net_local *np = (struct net_local *)dev->priv;
spin_lock(&np->lock); /* Preempt protection */
-
+
switch(map->port) {
case IF_PORT_UNKNOWN:
/* Use autoneg */
- e100_set_speed(dev, 0);
- e100_set_duplex(dev, autoneg);
+ e100_set_speed(0);
+ e100_set_duplex(autoneg);
break;
case IF_PORT_10BASET:
- e100_set_speed(dev, 10);
- e100_set_duplex(dev, autoneg);
+ e100_set_speed(10);
+ e100_set_duplex(autoneg);
break;
case IF_PORT_100BASET:
case IF_PORT_100BASETX:
- e100_set_speed(dev, 100);
- e100_set_duplex(dev, autoneg);
+ e100_set_speed(100);
+ e100_set_duplex(autoneg);
break;
case IF_PORT_100BASEFX:
case IF_PORT_10BASE2:
update_rx_stats(&lp->stats);
update_tx_stats(&lp->stats);
-
+
spin_unlock_irqrestore(&lp->lock, flags);
return &lp->stats;
}
hi_bits = 0x00000000ul;
for (i=0; i<num_addr; i++) {
/* Calculate the hash index for the GA registers */
-
+
hash_ix = 0;
baddr = dmi->dmi_addr;
hash_ix ^= (*baddr) & 0x3f;
++baddr;
hash_ix ^= ((*baddr) << 4) & 0x30;
hash_ix ^= ((*baddr) >> 2) & 0x3f;
-
+
hash_ix &= 0x3f;
-
+
if (hash_ix >= 32) {
hi_bits |= (1 << (hash_ix-32));
}