unsigned nsr = dm9000_read_locked(db, DM9000_NSR);
unsigned old_carrier = netif_carrier_ok(ndev) ? 1 : 0;
unsigned new_carrier;
new_carrier = (nsr & NSR_LINKST) ? 1 : 0;
if (old_carrier != new_carrier) {
if (netif_msg_link(db))
dm9000_show_carrier(db, new_carrier, nsr);
if (!new_carrier)
netif_carrier_off(ndev);
else
netif_carrier_on(ndev);
}
} else
mii_check_media(&db->mii, netif_msg_link(db), 0);
if (netif_running(ndev))
dm9000_schedule_poll(db);
}
static void
dm9000_release_board(struct platform_device *pdev, struct board_info *db)
{
iounmap(db->io_addr);
iounmap(db->io_data);
release_resource(db->data_req);
kfree(db->data_req);
release_resource(db->addr_req);
kfree(db->addr_req);
}
static unsigned char dm9000_type_to_char(enum dm9000_type type)
{
switch (type) {
case TYPE_DM9000E: return e;
case TYPE_DM9000A: return a;
case TYPE_DM9000B: return b;
}
return ?;
}
static void
dm9000_hash_table_unlocked(struct net_device *dev)
{
board_info_t *db = netdev_priv(dev);
struct netdev_hw_addr *ha;
int i, oft;
u32 hash_val;
u16 hash_table[4];
u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;
dm9000_dbg(db, 1, "entering %s\n", __func__);
for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
iow(db, oft, dev->dev_addr[i]);
for (i = 0; i < 4; i++)
hash_table[i] = 0x0;
hash_table[3] = 0x8000;
if (dev->flags & IFF_PROMISC)
rcr |= RCR_PRMSC;
if (dev->flags & IFF_ALLMULTI)
rcr |= RCR_ALL;
netdev_for_each_mc_addr(ha, dev) {
hash_val = ether_crc_le(6, ha->addr) & 0x3f;
hash_table[hash_val / 16] |= (u16) 1 < (hash_val % 16);
}
for (i = 0, oft = DM9000_MAR; i < 4; i++) {
iow(db, oft++, hash_table[i]);
iow(db, oft++, hash_table[i] >> 8);
}
iow(db, DM9000_RCR, rcr);
}
static void
dm9000_hash_table(struct net_device *dev)
{
board_info_t *db = netdev_priv(dev);
unsigned long flags;
spin_lock_irqsave(&db->lock, flags);
dm9000_hash_table_unlocked(dev);
spin_unlock_irqrestore(&db->lock, flags);
}
static void
dm9000_init_dm9000(struct net_device *dev)
{
board_info_t *db = netdev_priv(dev);
unsigned int imr;
unsigned int ncr;
dm9000_dbg(db, 1, "entering %s\n", __func__);
db->io_mode = ior(db, DM9000_ISR) >> 6;
dm9000_set_rx_csum_unlocked(dev, db->rx_csum);
iow(db, DM9000_GPR, 0);
iow(db, DM9000_GPCR, GPCR_GEP_CNTL);
iow(db, DM9000_GPR, 0);
ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
if (db->wake_supported)
ncr |= NCR_WAKEEN;
iow(db, DM9000_NCR, ncr);
iow(db, DM9000_TCR, 0);
iow(db, DM9000_BPTR, 0x3f);
iow(db, DM9000_FCR, 0xff);
iow(db, DM9000_SMCR, 0);
iow(db, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
iow(db, DM9000_ISR, ISR_CLR_STATUS);
dm9000_hash_table_unlocked(dev);
imr = IMR_PAR | IMR_PTM | IMR_PRM;
if (db->type != TYPE_DM9000E)
imr |= IMR_LNKCHNG;
db->imr_all = imr;
iow(db, DM9000_IMR, imr);
db->tx_pkt_cnt = 0;
db->queue_pkt_len = 0;
dev->trans_start = jiffies;
}
static void dm9000_timeout(struct net_device *dev)
{
board_info_t *db = netdev_priv(dev);
u8 reg_save;
unsigned long flags;
reg_save = readb(db->io_addr);
spin_lock_irqsave(&db->lock, flags);
netif_stop_queue(dev);
dm9000_reset(db);
dm9000_init_dm9000(dev);
dev->trans_start = jiffies;
netif_wake_queue(dev);
writeb(reg_save, db->io_addr);
spin_unlock_irqrestore(&db->lock, flags);
}
static void dm9000_send_packet(struct net_device *dev,
int ip_summed,
u16 pkt_len)