static int xgbe_one_poll(struct napi_struct *, int);
static int xgbe_all_poll(struct napi_struct *, int);
-static void xgbe_set_rx_mode(struct net_device *);
static int xgbe_alloc_channels(struct xgbe_prv_data *pdata)
{
return IRQ_HANDLED;
}
-static enum hrtimer_restart xgbe_tx_timer(struct hrtimer *timer)
+static void xgbe_tx_timer(unsigned long data)
{
- struct xgbe_channel *channel = container_of(timer,
- struct xgbe_channel,
- tx_timer);
+ struct xgbe_channel *channel = (struct xgbe_channel *)data;
struct xgbe_prv_data *pdata = channel->pdata;
struct napi_struct *napi;
if (napi_schedule_prep(napi)) {
/* Disable Tx and Rx interrupts */
if (pdata->per_channel_irq)
- disable_irq(channel->dma_irq);
+ disable_irq_nosync(channel->dma_irq);
else
xgbe_disable_rx_tx_ints(pdata);
channel->tx_timer_active = 0;
DBGPR("<--xgbe_tx_timer\n");
-
- return HRTIMER_NORESTART;
}
static void xgbe_init_tx_timers(struct xgbe_prv_data *pdata)
break;
DBGPR(" %s adding tx timer\n", channel->name);
- hrtimer_init(&channel->tx_timer, CLOCK_MONOTONIC,
- HRTIMER_MODE_REL);
- channel->tx_timer.function = xgbe_tx_timer;
+ setup_timer(&channel->tx_timer, xgbe_tx_timer,
+ (unsigned long)channel);
}
DBGPR("<--xgbe_init_tx_timers\n");
break;
DBGPR(" %s deleting tx timer\n", channel->name);
- channel->tx_timer_active = 0;
- hrtimer_cancel(&channel->tx_timer);
+ del_timer_sync(&channel->tx_timer);
}
DBGPR("<--xgbe_stop_tx_timers\n");
RXFIFOSIZE);
hw_feat->tx_fifo_size = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R,
TXFIFOSIZE);
+ hw_feat->dma_width = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, ADDR64);
hw_feat->dcb = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, DCBEN);
hw_feat->sph = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, SPHEN);
hw_feat->tso = XGMAC_GET_BITS(mac_hfr1, MAC_HWF1R, TSOEN);
break;
}
+ /* Translate the address width setting into actual number */
+ switch (hw_feat->dma_width) {
+ case 0:
+ hw_feat->dma_width = 32;
+ break;
+ case 1:
+ hw_feat->dma_width = 40;
+ break;
+ case 2:
+ hw_feat->dma_width = 48;
+ break;
+ default:
+ hw_feat->dma_width = 32;
+ }
+
/* The Queue, Channel and TC counts are zero based so increment them
* to get the actual number
*/
DBGPR("-->xgbe_init_rx_coalesce\n");
pdata->rx_riwt = hw_if->usec_to_riwt(pdata, XGMAC_INIT_DMA_RX_USECS);
+ pdata->rx_usecs = XGMAC_INIT_DMA_RX_USECS;
pdata->rx_frames = XGMAC_INIT_DMA_RX_FRAMES;
hw_if->config_rx_coalesce(pdata);
DBGPR("-->xgbe_start\n");
- xgbe_set_rx_mode(netdev);
-
hw_if->init(pdata);
phy_start(pdata->phydev);
{
struct xgbe_prv_data *pdata = netdev_priv(netdev);
struct xgbe_hw_if *hw_if = &pdata->hw_if;
- unsigned int pr_mode, am_mode;
DBGPR("-->xgbe_set_rx_mode\n");
- pr_mode = ((netdev->flags & IFF_PROMISC) != 0);
- am_mode = ((netdev->flags & IFF_ALLMULTI) != 0);
-
- hw_if->set_promiscuous_mode(pdata, pr_mode);
- hw_if->set_all_multicast_mode(pdata, am_mode);
-
- hw_if->add_mac_addresses(pdata);
+ hw_if->config_rx_mode(pdata);
DBGPR("<--xgbe_set_rx_mode\n");
}
return 0;
}
+static void xgbe_tx_timeout(struct net_device *netdev)
+{
+ struct xgbe_prv_data *pdata = netdev_priv(netdev);
+
+ netdev_warn(netdev, "tx timeout, device restarting\n");
+ schedule_work(&pdata->restart_work);
+}
+
static struct rtnl_link_stats64 *xgbe_get_stats64(struct net_device *netdev,
struct rtnl_link_stats64 *s)
{
.ndo_validate_addr = eth_validate_addr,
.ndo_do_ioctl = xgbe_ioctl,
.ndo_change_mtu = xgbe_change_mtu,
+ .ndo_tx_timeout = xgbe_tx_timeout,
.ndo_get_stats64 = xgbe_get_stats64,
.ndo_vlan_rx_add_vid = xgbe_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = xgbe_vlan_rx_kill_vid,
if (desc_if->map_rx_buffer(pdata, ring, rdata))
break;
- hw_if->rx_desc_reset(rdata);
+ hw_if->rx_desc_reset(pdata, rdata, ring->dirty);
ring->dirty++;
}
+ /* Make sure everything is written before the register write */
+ wmb();
+
/* Update the Rx Tail Pointer Register with address of
* the last cleaned entry */
rdata = XGBE_GET_DESC_DATA(ring, ring->dirty - 1);
lower_32_bits(rdata->rdesc_dma));
}
-static struct sk_buff *xgbe_create_skb(struct xgbe_prv_data *pdata,
+static struct sk_buff *xgbe_create_skb(struct napi_struct *napi,
struct xgbe_ring_data *rdata,
unsigned int *len)
{
- struct net_device *netdev = pdata->netdev;
struct sk_buff *skb;
u8 *packet;
unsigned int copy_len;
- skb = netdev_alloc_skb_ip_align(netdev, rdata->rx.hdr.dma_len);
+ skb = napi_alloc_skb(napi, rdata->rx.hdr.dma_len);
if (!skb)
return NULL;
/* Make sure descriptor fields are read after reading the OWN
* bit */
- rmb();
+ dma_rmb();
#ifdef XGMAC_ENABLE_TX_DESC_DUMP
xgbe_dump_tx_desc(ring, ring->dirty, 1, 0);
rdata->rx.hdr.dma_len,
DMA_FROM_DEVICE);
- skb = xgbe_create_skb(pdata, rdata, &put_len);
+ skb = xgbe_create_skb(napi, rdata, &put_len);
if (!skb) {
error = 1;
goto skip_data;