*/
struct net_device *sbm_dev; /* pointer to linux device */
+ struct napi_struct napi;
spinlock_t sbm_lock; /* spin lock */
struct timer_list sbm_timer; /* for monitoring MII */
- struct net_device_stats sbm_stats;
int sbm_devflags; /* current device flags */
int sbm_phy_oldbmsr;
static int sbmac_open(struct net_device *dev);
static void sbmac_timer(unsigned long data);
static void sbmac_tx_timeout (struct net_device *dev);
-static struct net_device_stats *sbmac_get_stats(struct net_device *dev);
static void sbmac_set_rx_mode(struct net_device *dev);
static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
static int sbmac_close(struct net_device *dev);
-static int sbmac_poll(struct net_device *poll_dev, int *budget);
+static int sbmac_poll(struct napi_struct *napi, int budget);
static int sbmac_mii_poll(struct sbmac_softc *s,int noisy);
static int sbmac_mii_probe(struct net_device *dev);
* And context table
*/
- d->sbdma_ctxtable = (struct sk_buff **)
- kmalloc(d->sbdma_maxdescr*sizeof(struct sk_buff *), GFP_KERNEL);
-
- memset(d->sbdma_ctxtable,0,d->sbdma_maxdescr*sizeof(struct sk_buff *));
+ d->sbdma_ctxtable = kcalloc(d->sbdma_maxdescr,
+ sizeof(struct sk_buff *), GFP_KERNEL);
#ifdef CONFIG_SBMAC_COALESCE
/*
__raw_writeq(0, sc->sbm_imr);
- sbmac_intr(irq, netdev, NULL);
+ sbmac_intr(irq, netdev);
#ifdef CONFIG_SBMAC_COALESCE
__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
static int sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d,
int work_to_do, int poll)
{
+ struct net_device *dev = sc->sbm_dev;
int curidx;
int hwidx;
sbdmadscr_t *dsc;
again:
/* Check if the HW dropped any frames */
- sc->sbm_stats.rx_fifo_errors
+ dev->stats.rx_fifo_errors
+= __raw_readq(sc->sbm_rxdma.sbdma_oodpktlost) & 0xffff;
__raw_writeq(0, sc->sbm_rxdma.sbdma_oodpktlost);
if (unlikely (sbdma_add_rcvbuffer(d,NULL) ==
-ENOBUFS)) {
- sc->sbm_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
sbdma_add_rcvbuffer(d,sb); /* re-add old buffer */
/* No point in continuing at the moment */
printk(KERN_ERR "dropped packet (1)\n");
dropped = netif_rx(sb);
if (dropped == NET_RX_DROP) {
- sc->sbm_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr);
goto done;
}
else {
- sc->sbm_stats.rx_bytes += len;
- sc->sbm_stats.rx_packets++;
+ dev->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
}
}
} else {
* Packet was mangled somehow. Just drop it and
* put it back on the receive ring.
*/
- sc->sbm_stats.rx_errors++;
+ dev->stats.rx_errors++;
sbdma_add_rcvbuffer(d,sb);
}
static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll)
{
+ struct net_device *dev = sc->sbm_dev;
int curidx;
int hwidx;
sbdmadscr_t *dsc;
* Stats
*/
- sc->sbm_stats.tx_bytes += sb->len;
- sc->sbm_stats.tx_packets++;
+ dev->stats.tx_bytes += sb->len;
+ dev->stats.tx_packets++;
/*
* for transmits, we just free buffers.
* Transmits on channel 0
*/
- if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) {
+ if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0))
sbdma_tx_process(sc,&(sc->sbm_txdma), 0);
-#ifdef CONFIG_NETPOLL_TRAP
- if (netpoll_trap()) {
- if (test_and_clear_bit(__LINK_STATE_XOFF, &dev->state))
- __netif_schedule(dev);
- }
-#endif
- }
if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) {
- if (netif_rx_schedule_prep(dev)) {
+ if (netif_rx_schedule_prep(dev, &sc->napi)) {
__raw_writeq(0, sc->sbm_imr);
- __netif_rx_schedule(dev);
+ __netif_rx_schedule(dev, &sc->napi);
/* Depend on the exit from poll to reenable intr */
}
else {
uint64_t ea_reg;
int i;
int err;
+ DECLARE_MAC_BUF(mac);
sc = netdev_priv(dev);
dev->open = sbmac_open;
dev->hard_start_xmit = sbmac_start_tx;
dev->stop = sbmac_close;
- dev->get_stats = sbmac_get_stats;
dev->set_multicast_list = sbmac_set_rx_mode;
dev->do_ioctl = sbmac_mii_ioctl;
dev->tx_timeout = sbmac_tx_timeout;
dev->watchdog_timeo = TX_TIMEOUT;
- dev->poll = sbmac_poll;
- dev->weight = 16;
+
+ netif_napi_add(dev, &sc->napi, sbmac_poll, 16);
dev->change_mtu = sb1250_change_mtu;
#ifdef CONFIG_NET_POLL_CONTROLLER
* was being displayed)
*/
printk(KERN_INFO
- "%s: SiByte Ethernet at 0x%08lX, address: %02X:%02X:%02X:%02X:%02X:%02X\n",
- dev->name, dev->base_addr,
- eaddr[0],eaddr[1],eaddr[2],eaddr[3],eaddr[4],eaddr[5]);
-
+ "%s: SiByte Ethernet at 0x%08lX, address: %s\n",
+ dev->name, dev->base_addr, print_mac(mac, eaddr));
return 0;
return -EINVAL;
}
+ napi_enable(&sc->napi);
+
/*
* Configure default speed
*/
dev->trans_start = jiffies;
- sc->sbm_stats.tx_errors++;
+ dev->stats.tx_errors++;
spin_unlock_irq (&sc->sbm_lock);
-static struct net_device_stats *sbmac_get_stats(struct net_device *dev)
-{
- struct sbmac_softc *sc = netdev_priv(dev);
- unsigned long flags;
-
- spin_lock_irqsave(&sc->sbm_lock, flags);
-
- /* XXX update other stats here */
-
- spin_unlock_irqrestore(&sc->sbm_lock, flags);
-
- return &sc->sbm_stats;
-}
-
-
-
static void sbmac_set_rx_mode(struct net_device *dev)
{
unsigned long flags;
unsigned long flags;
int irq;
+ napi_disable(&sc->napi);
+
sbmac_set_channel_state(sc,sbmac_state_off);
del_timer_sync(&sc->sbm_timer);
return 0;
}
-static int sbmac_poll(struct net_device *dev, int *budget)
+static int sbmac_poll(struct napi_struct *napi, int budget)
{
- int work_to_do;
+ struct sbmac_softc *sc = container_of(napi, struct sbmac_softc, napi);
+ struct net_device *dev = sc->sbm_dev;
int work_done;
- struct sbmac_softc *sc = netdev_priv(dev);
-
- work_to_do = min(*budget, dev->quota);
- work_done = sbdma_rx_process(sc, &(sc->sbm_rxdma), work_to_do, 1);
-
- if (work_done > work_to_do)
- printk(KERN_ERR "%s exceeded work_to_do budget=%d quota=%d work-done=%d\n",
- sc->sbm_dev->name, *budget, dev->quota, work_done);
+ work_done = sbdma_rx_process(sc, &(sc->sbm_rxdma), budget, 1);
sbdma_tx_process(sc, &(sc->sbm_txdma), 1);
- *budget -= work_done;
- dev->quota -= work_done;
-
- if (work_done < work_to_do) {
- netif_rx_complete(dev);
+ if (work_done < budget) {
+ netif_rx_complete(dev, napi);
#ifdef CONFIG_SBMAC_COALESCE
__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
#endif
}
- return (work_done >= work_to_do);
+ return work_done;
}
#if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR)