"%s: forcing end of tx descriptor " \
"with status %x\n",
__func__, status);
- card->netdev_stats.tx_dropped++;
+ card->netdev->stats.tx_dropped++;
break;
case GELIC_NET_DESCR_COMPLETE:
if (tx_chain->tail->skb) {
- card->netdev_stats.tx_packets++;
- card->netdev_stats.tx_bytes +=
+ card->netdev->stats.tx_packets++;
+ card->netdev->stats.tx_bytes +=
tx_chain->tail->skb->len;
}
break;
{
struct gelic_net_card *card = netdev_priv(netdev);
- netif_poll_disable(netdev);
netif_stop_queue(netdev);
/* turn off DMA, force end */
* DMA map failed. As chanses are that failure
* would continue, just release skb and return
*/
- card->netdev_stats.tx_dropped++;
+ card->netdev->stats.tx_dropped++;
dev_kfree_skb_any(skb);
spin_unlock_irqrestore(&card->tx_dma_lock, flags);
return NETDEV_TX_OK;
* kick failed.
* release descriptors which were just prepared
*/
- card->netdev_stats.tx_dropped++;
+ card->netdev->stats.tx_dropped++;
gelic_net_release_tx_descr(card, descr);
gelic_net_release_tx_descr(card, descr->next);
card->tx_chain.tail = descr->next->next;
skb->ip_summed = CHECKSUM_NONE;
/* update netdevice statistics */
- card->netdev_stats.rx_packets++;
- card->netdev_stats.rx_bytes += skb->len;
+ card->netdev->stats.rx_packets++;
+ card->netdev->stats.rx_bytes += skb->len;
/* pass skb up to stack */
netif_receive_skb(skb);
(status == GELIC_NET_DESCR_FORCE_END)) {
dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
status);
- card->netdev_stats.rx_dropped++;
+ card->netdev->stats.rx_dropped++;
goto refill;
}
- if ((status != GELIC_NET_DESCR_COMPLETE) &&
- (status != GELIC_NET_DESCR_FRAME_END)) {
+ if (status == GELIC_NET_DESCR_BUFFER_FULL) {
+ /*
+ * Buffer full would occur if and only if
+ * the frame length was longer than the size of this
+ * descriptor's buffer. If the frame length was equal
+ * to or shorter than buffer'size, FRAME_END condition
+ * would occur.
+ * Anyway this frame was longer than the MTU,
+ * just drop it.
+ */
+ dev_info(ctodev(card), "overlength frame\n");
+ goto refill;
+ }
+ /*
+ * descriptoers any other than FRAME_END here should
+ * be treated as error.
+ */
+ if (status != GELIC_NET_DESCR_FRAME_END) {
dev_dbg(ctodev(card), "RX descriptor with state %x\n",
status);
goto refill;
}
/* ok, we've got a packet in descr */
- gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */
-
+ gelic_net_pass_skb_up(descr, card);
refill:
- descr->next_descr_addr = 0; /* unlink the descr */
+ /*
+ * So that always DMAC can see the end
+ * of the descriptor chain to avoid
+ * from unwanted DMAC overrun.
+ */
+ descr->next_descr_addr = 0;
/* change the descriptor state: */
gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
- /* refill one desc
- * FIXME: this can fail, but for now, just leave this
- * descriptor without skb
+ /*
+ * this call can fail, but for now, just leave this
+ * decriptor without skb
*/
gelic_net_prepare_rx_descr(card, descr);
+
chain->head = descr;
chain->tail = descr->next;
+
+ /*
+ * Set this descriptor the end of the chain.
+ */
descr->prev->next_descr_addr = descr->bus_addr;
+ /*
+ * If dmac chain was met, DMAC stopped.
+ * thus re-enable it
+ */
if (dmac_chain_ended) {
- gelic_net_enable_rxdmac(card);
- dev_dbg(ctodev(card), "reenable rx dma\n");
+ card->rx_dma_restart_required = 1;
+ dev_dbg(ctodev(card), "reenable rx dma scheduled\n");
}
return 1;
} else
return 1;
}
-
-/**
- * gelic_net_get_stats - get interface statistics
- * @netdev: interface device structure
- *
- * returns the interface statistics residing in the gelic_net_card struct
- */
-static struct net_device_stats *gelic_net_get_stats(struct net_device *netdev)
-{
- struct gelic_net_card *card = netdev_priv(netdev);
-
- return &card->netdev_stats;
-}
-
/**
* gelic_net_change_mtu - changes the MTU of an interface
* @netdev: interface device structure
if (!status)
return IRQ_NONE;
+ if (card->rx_dma_restart_required) {
+ card->rx_dma_restart_required = 0;
+ gelic_net_enable_rxdmac(card);
+ }
+
if (status & GELIC_NET_RXINT) {
gelic_net_rx_irq_off(card);
netif_rx_schedule(netdev);
}
result = request_irq(card->netdev->irq, gelic_net_interrupt,
- IRQF_DISABLED, "gelic network", card->netdev);
+ IRQF_DISABLED, card->netdev->name, card->netdev);
if (result) {
dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n",
netif_start_queue(netdev);
netif_carrier_on(netdev);
- netif_poll_enable(netdev);
return 0;
return -ENOMEM;
}
-#ifdef GELIC_NET_ETHTOOL
static void gelic_net_get_drvinfo (struct net_device *netdev,
struct ethtool_drvinfo *info)
{
.get_rx_csum = gelic_net_get_rx_csum,
.set_rx_csum = gelic_net_set_rx_csum,
};
-#endif
/**
* gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
netdev->open = &gelic_net_open;
netdev->stop = &gelic_net_stop;
netdev->hard_start_xmit = &gelic_net_xmit;
- netdev->get_stats = &gelic_net_get_stats;
netdev->set_multicast_list = &gelic_net_set_multi;
netdev->change_mtu = &gelic_net_change_mtu;
/* tx watchdog */
/* NAPI */
netdev->poll = &gelic_net_poll;
netdev->weight = GELIC_NET_NAPI_WEIGHT;
-#ifdef GELIC_NET_ETHTOOL
netdev->ethtool_ops = &gelic_net_ethtool_ops;
-#endif
}
/**