SPIDER_NET_DMA_RX_VALUE);
}
+/**
+ * spider_net_disable_rxdmac - disables the receive DMA controller
+ * @card: card structure
+ *
+ * spider_net_disable_rxdmac terminates processing on the DMA controller
+ * by turing off the DMA controller, with the force-end flag set.
+ */
+static inline void
+spider_net_disable_rxdmac(struct spider_net_card *card)
+{
+ spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR,
+ SPIDER_NET_DMA_RX_FEND_VALUE);
+}
+
/**
* spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains
* @card: card structure
}
}
-/**
- * spider_net_disable_rxdmac - disables the receive DMA controller
- * @card: card structure
- *
- * spider_net_disable_rxdmac terminates processing on the DMA controller by
- * turing off DMA and issueing a force end
- */
-static void
-spider_net_disable_rxdmac(struct spider_net_card *card)
-{
- spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR,
- SPIDER_NET_DMA_RX_FEND_VALUE);
-}
-
/**
* spider_net_prepare_tx_descr - fill tx descriptor with skb data
* @card: card structure
hwdescr->data_status = 0;
hwdescr->dmac_cmd_status =
- SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_NOCS;
+ SPIDER_NET_DESCR_CARDOWNED | SPIDER_NET_DMAC_TXFRMTL;
spin_unlock_irqrestore(&chain->lock, flags);
if (skb->ip_summed == CHECKSUM_PARTIAL)
static int
spider_net_release_tx_chain(struct spider_net_card *card, int brutal)
{
+ struct net_device *dev = card->netdev;
struct spider_net_descr_chain *chain = &card->tx_chain;
struct spider_net_descr *descr;
struct spider_net_hw_descr *hwdescr;
status = spider_net_get_descr_status(hwdescr);
switch (status) {
case SPIDER_NET_DESCR_COMPLETE:
- card->netdev_stats.tx_packets++;
- card->netdev_stats.tx_bytes += descr->skb->len;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += descr->skb->len;
break;
case SPIDER_NET_DESCR_CARDOWNED:
if (netif_msg_tx_err(card))
dev_err(&card->netdev->dev, "forcing end of tx descriptor "
"with status x%02x\n", status);
- card->netdev_stats.tx_errors++;
+ dev->stats.tx_errors++;
break;
default:
- card->netdev_stats.tx_dropped++;
+ dev->stats.tx_dropped++;
if (!brutal) {
spin_unlock_irqrestore(&chain->lock, flags);
return 1;
spider_net_release_tx_chain(card, 0);
if (spider_net_prepare_tx_descr(card, skb) != 0) {
- card->netdev_stats.tx_dropped++;
+ netdev->stats.tx_dropped++;
netif_stop_queue(netdev);
return NETDEV_TX_BUSY;
}
spider_net_pass_skb_up(struct spider_net_descr *descr,
struct spider_net_card *card)
{
- struct spider_net_hw_descr *hwdescr= descr->hwdescr;
- struct sk_buff *skb;
- struct net_device *netdev;
- u32 data_status, data_error;
-
- data_status = hwdescr->data_status;
- data_error = hwdescr->data_error;
- netdev = card->netdev;
+ struct spider_net_hw_descr *hwdescr = descr->hwdescr;
+ struct sk_buff *skb = descr->skb;
+ struct net_device *netdev = card->netdev;
+ u32 data_status = hwdescr->data_status;
+ u32 data_error = hwdescr->data_error;
- skb = descr->skb;
skb_put(skb, hwdescr->valid_size);
/* the card seems to add 2 bytes of junk in front
}
/* update netdevice statistics */
- card->netdev_stats.rx_packets++;
- card->netdev_stats.rx_bytes += skb->len;
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += skb->len;
/* pass skb up to stack */
netif_receive_skb(skb);
static int
spider_net_decode_one_descr(struct spider_net_card *card)
{
+ struct net_device *dev = card->netdev;
struct spider_net_descr_chain *chain = &card->rx_chain;
struct spider_net_descr *descr = chain->tail;
struct spider_net_hw_descr *hwdescr = descr->hwdescr;
(status == SPIDER_NET_DESCR_PROTECTION_ERROR) ||
(status == SPIDER_NET_DESCR_FORCE_END) ) {
if (netif_msg_rx_err(card))
- dev_err(&card->netdev->dev,
+ dev_err(&dev->dev,
"dropping RX descriptor with state %d\n", status);
- card->netdev_stats.rx_dropped++;
+ dev->stats.rx_dropped++;
goto bad_desc;
}
goto bad_desc;
}
- if (hwdescr->dmac_cmd_status & 0xfcf4) {
+ if (hwdescr->dmac_cmd_status & SPIDER_NET_DESCR_BAD_STATUS) {
dev_err(&card->netdev->dev, "bad status, cmd_status=x%08x\n",
hwdescr->dmac_cmd_status);
pr_err("buf_addr=x%08x\n", hw_buf_addr);
* (using netif_receive_skb). If all/enough packets are up, the driver
* reenables interrupts and returns 0. If not, 1 is returned.
*/
-static int
-spider_net_poll(struct net_device *netdev, int *budget)
+static int spider_net_poll(struct napi_struct *napi, int budget)
{
- struct spider_net_card *card = netdev_priv(netdev);
- int packets_to_do, packets_done = 0;
- int no_more_packets = 0;
-
- packets_to_do = min(*budget, netdev->quota);
-
- while (packets_to_do) {
- if (spider_net_decode_one_descr(card)) {
- packets_done++;
- packets_to_do--;
- } else {
- /* no more packets for the stack */
- no_more_packets = 1;
+ struct spider_net_card *card = container_of(napi, struct spider_net_card, napi);
+ struct net_device *netdev = card->netdev;
+ int packets_done = 0;
+
+ while (packets_done < budget) {
+ if (!spider_net_decode_one_descr(card))
break;
- }
+
+ packets_done++;
}
if ((packets_done == 0) && (card->num_rx_ints != 0)) {
- no_more_packets = spider_net_resync_tail_ptr(card);
+ if (!spider_net_resync_tail_ptr(card))
+ packets_done = budget;
spider_net_resync_head_ptr(card);
}
card->num_rx_ints = 0;
- netdev->quota -= packets_done;
- *budget -= packets_done;
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
/* if all packets are in the stack, enable interrupts and return 0 */
/* if not, return 1 */
- if (no_more_packets) {
- netif_rx_complete(netdev);
+ if (packets_done < budget) {
+ netif_rx_complete(netdev, napi);
spider_net_rx_irq_on(card);
card->ignore_rx_ramfull = 0;
- return 0;
}
- return 1;
-}
-
-/**
- * spider_net_get_stats - get interface statistics
- * @netdev: interface device structure
- *
- * returns the interface statistics residing in the spider_net_card struct
- */
-static struct net_device_stats *
-spider_net_get_stats(struct net_device *netdev)
-{
- struct spider_net_card *card = netdev_priv(netdev);
- struct net_device_stats *stats = &card->netdev_stats;
- return stats;
+ return packets_done;
}
/**
error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
+ error_reg1 &= SPIDER_NET_INT1_MASK_VALUE;
+ error_reg2 &= SPIDER_NET_INT2_MASK_VALUE;
+
/* check GHIINT0STS ************************************/
if (status_reg)
for (i = 0; i < 32; i++)
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
card->num_rx_ints ++;
- netif_rx_schedule(card->netdev);
+ netif_rx_schedule(card->netdev,
+ &card->napi);
}
show_error = 0;
break;
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
card->num_rx_ints ++;
- netif_rx_schedule(card->netdev);
+ netif_rx_schedule(card->netdev,
+ &card->napi);
show_error = 0;
break;
spider_net_refill_rx_chain(card);
spider_net_enable_rxdmac(card);
card->num_rx_ints ++;
- netif_rx_schedule(card->netdev);
+ netif_rx_schedule(card->netdev,
+ &card->napi);
show_error = 0;
break;
u32 status_reg;
status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS);
+ status_reg &= SPIDER_NET_INT0_MASK_VALUE;
if (!status_reg)
return IRQ_NONE;
if (status_reg & SPIDER_NET_RXINT ) {
spider_net_rx_irq_off(card);
- netif_rx_schedule(netdev);
+ netif_rx_schedule(netdev, &card->napi);
card->num_rx_ints ++;
}
if (status_reg & SPIDER_NET_TXINT)
- netif_rx_schedule(netdev);
+ netif_rx_schedule(netdev, &card->napi);
if (status_reg & SPIDER_NET_LINKINT)
spider_net_link_reset(netdev);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
+/**
+ * spider_net_enable_interrupts - enable interrupts
+ * @card: card structure
+ *
+ * spider_net_enable_interrupt enables several interrupts
+ */
+static void
+spider_net_enable_interrupts(struct spider_net_card *card)
+{
+ spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
+ SPIDER_NET_INT0_MASK_VALUE);
+ spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
+ SPIDER_NET_INT1_MASK_VALUE);
+ spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
+ SPIDER_NET_INT2_MASK_VALUE);
+}
+
+/**
+ * spider_net_disable_interrupts - disable interrupts
+ * @card: card structure
+ *
+ * spider_net_disable_interrupts disables all the interrupts
+ */
+static void
+spider_net_disable_interrupts(struct spider_net_card *card)
+{
+ spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
+ spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
+ spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
+ spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+}
+
/**
* spider_net_init_card - initializes the card
* @card: card structure
spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4);
+ spider_net_disable_interrupts(card);
}
/**
spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
SPIDER_NET_OPMODE_VALUE);
- /* set interrupt mask registers */
- spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
- SPIDER_NET_INT0_MASK_VALUE);
- spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
- SPIDER_NET_INT1_MASK_VALUE);
- spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
- SPIDER_NET_INT2_MASK_VALUE);
-
spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
SPIDER_NET_GDTBSTA);
}
netif_start_queue(netdev);
netif_carrier_on(netdev);
- netif_poll_enable(netdev);
+ napi_enable(&card->napi);
+
+ spider_net_enable_interrupts(card);
return 0;
{
struct spider_net_card *card = netdev_priv(netdev);
- netif_poll_disable(netdev);
+ napi_disable(&card->napi);
netif_carrier_off(netdev);
netif_stop_queue(netdev);
del_timer_sync(&card->tx_timer);
del_timer_sync(&card->aneg_timer);
- /* disable/mask all interrupts */
- spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
- spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
- spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
- spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+ spider_net_disable_interrupts(card);
free_irq(netdev->irq, netdev);
netdev->open = &spider_net_open;
netdev->stop = &spider_net_stop;
netdev->hard_start_xmit = &spider_net_xmit;
- netdev->get_stats = &spider_net_get_stats;
netdev->set_multicast_list = &spider_net_set_multi;
netdev->set_mac_address = &spider_net_set_mac;
netdev->change_mtu = &spider_net_change_mtu;
/* tx watchdog */
netdev->tx_timeout = &spider_net_tx_timeout;
netdev->watchdog_timeo = SPIDER_NET_WATCHDOG_TIMEOUT;
- /* NAPI */
- netdev->poll = &spider_net_poll;
- netdev->weight = SPIDER_NET_NAPI_WEIGHT;
/* HW VLAN */
#ifdef CONFIG_NET_POLL_CONTROLLER
/* poll controller */
struct sockaddr addr;
const u8 *mac;
- SET_MODULE_OWNER(netdev);
SET_NETDEV_DEV(netdev, &card->pdev->dev);
pci_set_drvdata(card->pdev, netdev);
card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT;
+ netif_napi_add(netdev, &card->napi,
+ spider_net_poll, SPIDER_NET_NAPI_WEIGHT);
+
spider_net_setup_netdev_ops(netdev);
netdev->features = NETIF_F_IP_CSUM | NETIF_F_LLTX;