Newer
Older
if (skb == NULL) {
DPRINTK( 1, ( "%s: Memory squeeze, deferring packet.\n",
dev->name ));
for( i = 0; i < RX_RING_SIZE; i++ )
if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag &
RMD1_OWN_CHIP)
break;
if (i > RX_RING_SIZE - 2) {
dev->stats.rx_dropped++;
head->flag |= RMD1_OWN_CHIP;
lp->cur_rx++;
}
break;
}
if (lance_debug >= 3) {
u_char *data = PKTBUF_ADDR(head);
printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %pM to %pM "
"data %02x %02x %02x %02x %02x %02x %02x %02x "
dev->name, ((u_short *)data)[6],
data[15], data[16], data[17], data[18],
data[19], data[20], data[21], data[22],
}
skb_reserve( skb, 2 ); /* 16 byte align */
skb_put( skb, pkt_len ); /* Make room */
lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len );
skb->protocol = eth_type_trans( skb, dev );
netif_rx( skb );
dev->stats.rx_packets++;
dev->stats.rx_bytes += pkt_len;
}
}
head->flag |= RMD1_OWN_CHIP;
entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
}
lp->cur_rx &= RX_RING_MOD_MASK;
/* From lance.c (Donald Becker): */
/* We should check that at least two ring entries are free. If not,
we should free one and mark stats->rx_dropped++. */
return 0;
}
static int lance_close( struct net_device *dev )
{
struct lance_private *lp = netdev_priv(dev);
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
struct lance_ioreg *IO = lp->iobase;
netif_stop_queue (dev);
AREG = CSR0;
DPRINTK( 2, ( "%s: Shutting down ethercard, status was %2.2x.\n",
dev->name, DREG ));
/* We stop the LANCE here -- it occasionally polls
memory if we don't. */
DREG = CSR0_STOP;
return 0;
}
/* Set or clear the multicast filter for this adaptor.
num_addrs == -1 Promiscuous mode, receive all packets
num_addrs == 0 Normal mode, clear multicast list
num_addrs > 0 Multicast mode, receive normal and MC packets, and do
best-effort filtering.
*/
static void set_multicast_list( struct net_device *dev )
{
struct lance_private *lp = netdev_priv(dev);
struct lance_ioreg *IO = lp->iobase;
if (netif_running(dev))
/* Only possible if board is already started */
return;
/* We take the simple way out and always enable promiscuous mode. */
DREG = CSR0_STOP; /* Temporarily stop the lance. */
if (dev->flags & IFF_PROMISC) {
/* Log any net taps. */
DPRINTK( 2, ( "%s: Promiscuous mode enabled.\n", dev->name ));
REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
} else {
short multicast_table[4];
int num_addrs = netdev_mc_count(dev);
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
int i;
/* We don't use the multicast table, but rely on upper-layer
* filtering. */
memset( multicast_table, (num_addrs == 0) ? 0 : -1,
sizeof(multicast_table) );
for( i = 0; i < 4; i++ )
REGA( CSR8+i ) = multicast_table[i];
REGA( CSR15 ) = 0; /* Unset promiscuous mode */
}
/*
* Always set BSWP after a STOP as STOP puts it back into
* little endian mode.
*/
REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0);
/* Resume normal operation and reset AREG to CSR0 */
REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT;
}
/* This is needed for old RieblCards and possible for new RieblCards */
static int lance_set_mac_address( struct net_device *dev, void *addr )
{
struct lance_private *lp = netdev_priv(dev);
struct sockaddr *saddr = addr;
int i;
if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL)
if (netif_running(dev)) {
/* Only possible while card isn't started */
DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n",
dev->name ));
}
memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len );
for( i = 0; i < 6; i++ )
MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */
lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 );
/* set also the magic for future sessions */
*RIEBL_MAGIC_ADDR = RIEBL_MAGIC;
#ifdef MODULE
static struct net_device *atarilance_dev;
Jon Schindler
committed
static int __init atarilance_module_init(void)
{
atarilance_dev = atarilance_probe(-1);
if (IS_ERR(atarilance_dev))
return PTR_ERR(atarilance_dev);
return 0;
}
Jon Schindler
committed
static void __exit atarilance_module_exit(void)
{
unregister_netdev(atarilance_dev);
free_irq(atarilance_dev->irq, atarilance_dev);
free_netdev(atarilance_dev);
}
Jon Schindler
committed
module_init(atarilance_module_init);
module_exit(atarilance_module_exit);
/*
* Local variables:
* c-indent-level: 4
* tab-width: 4
* End:
*/