* Copyright (C) 2002 Red Hat, Inc.
*/
+#include <linux/moduleparam.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/string.h>
#include <net/tcp.h>
#include <net/udp.h>
#include <asm/unaligned.h>
+#include <trace/events/napi.h>
/*
* We maintain a small pool of fully-sized skbs, to make sure the
static void zap_completion_queue(void);
static void arp_reply(struct sk_buff *skb);
+static unsigned int carrier_timeout = 4;
+module_param(carrier_timeout, uint, 0644);
+
static void queue_process(struct work_struct *work)
{
struct netpoll_info *npinfo =
while ((skb = skb_dequeue(&npinfo->txq))) {
struct net_device *dev = skb->dev;
+ const struct net_device_ops *ops = dev->netdev_ops;
struct netdev_queue *txq;
if (!netif_device_present(dev) || !netif_running(dev)) {
__netif_tx_lock(txq, smp_processor_id());
if (netif_tx_queue_stopped(txq) ||
netif_tx_queue_frozen(txq) ||
- dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
+ ops->ndo_start_xmit(skb, dev) != NETDEV_TX_OK) {
skb_queue_head(&npinfo->txq, skb);
__netif_tx_unlock(txq);
local_irq_restore(flags);
npinfo->rx_flags |= NETPOLL_RX_DROP;
atomic_inc(&trapped);
+ set_bit(NAPI_STATE_NPSVC, &napi->state);
work = napi->poll(napi, budget);
+ trace_napi_poll(napi);
+ clear_bit(NAPI_STATE_NPSVC, &napi->state);
atomic_dec(&trapped);
npinfo->rx_flags &= ~NETPOLL_RX_DROP;
void netpoll_poll(struct netpoll *np)
{
struct net_device *dev = np->dev;
+ const struct net_device_ops *ops;
+
+ if (!dev || !netif_running(dev))
+ return;
- if (!dev || !netif_running(dev) || !dev->poll_controller)
+ ops = dev->netdev_ops;
+ if (!ops->ndo_poll_controller)
return;
/* Process pending work on NIC */
- dev->poll_controller(dev);
+ ops->ndo_poll_controller(dev);
poll_napi(dev);
int status = NETDEV_TX_BUSY;
unsigned long tries;
struct net_device *dev = np->dev;
+ const struct net_device_ops *ops = dev->netdev_ops;
struct netpoll_info *npinfo = np->dev->npinfo;
if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) {
for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
tries > 0; --tries) {
if (__netif_tx_trylock(txq)) {
- if (!netif_tx_queue_stopped(txq))
- status = dev->hard_start_xmit(skb, dev);
+ if (!netif_tx_queue_stopped(txq)) {
+ status = ops->ndo_start_xmit(skb, dev);
+ if (status == NETDEV_TX_OK)
+ txq_trans_update(txq);
+ }
__netif_tx_unlock(txq);
if (status == NETDEV_TX_OK)
udelay(USEC_PER_POLL);
}
+
+ WARN_ONCE(!irqs_disabled(),
+ "netpoll_send_skb(): %s enabled interrupts in poll (%pF)\n",
+ dev->name, ops->ndo_start_xmit);
+
local_irq_restore(flags);
}
udph->dest = htons(np->remote_port);
udph->len = htons(udp_len);
udph->check = 0;
- udph->check = csum_tcpudp_magic(htonl(np->local_ip),
- htonl(np->remote_ip),
+ udph->check = csum_tcpudp_magic(np->local_ip,
+ np->remote_ip,
udp_len, IPPROTO_UDP,
- csum_partial((unsigned char *)udph, udp_len, 0));
+ csum_partial(udph, udp_len, 0));
if (udph->check == 0)
udph->check = CSUM_MANGLED_0;
iph->ttl = 64;
iph->protocol = IPPROTO_UDP;
iph->check = 0;
- put_unaligned(htonl(np->local_ip), &(iph->saddr));
- put_unaligned(htonl(np->remote_ip), &(iph->daddr));
+ put_unaligned(np->local_ip, &(iph->saddr));
+ put_unaligned(np->remote_ip, &(iph->daddr));
iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
eth = (struct ethhdr *) skb_push(skb, ETH_HLEN);
memcpy(&tip, arp_ptr, 4);
/* Should we ignore arp? */
- if (tip != htonl(np->local_ip) ||
+ if (tip != np->local_ip ||
ipv4_is_loopback(tip) || ipv4_is_multicast(tip))
return;
goto out;
if (checksum_udp(skb, uh, ulen, iph->saddr, iph->daddr))
goto out;
- if (np->local_ip && np->local_ip != ntohl(iph->daddr))
+ if (np->local_ip && np->local_ip != iph->daddr)
goto out;
- if (np->remote_ip && np->remote_ip != ntohl(iph->saddr))
+ if (np->remote_ip && np->remote_ip != iph->saddr)
goto out;
if (np->local_port && np->local_port != ntohs(uh->dest))
goto out;
{
printk(KERN_INFO "%s: local port %d\n",
np->name, np->local_port);
- printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
- np->name, HIPQUAD(np->local_ip));
+ printk(KERN_INFO "%s: local IP %pI4\n",
+ np->name, &np->local_ip);
printk(KERN_INFO "%s: interface %s\n",
np->name, np->dev_name);
printk(KERN_INFO "%s: remote port %d\n",
np->name, np->remote_port);
- printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",
- np->name, HIPQUAD(np->remote_ip));
+ printk(KERN_INFO "%s: remote IP %pI4\n",
+ np->name, &np->remote_ip);
printk(KERN_INFO "%s: remote ethernet address %pM\n",
np->name, np->remote_mac);
}
if ((delim = strchr(cur, '/')) == NULL)
goto parse_failed;
*delim = 0;
- np->local_ip = ntohl(in_aton(cur));
+ np->local_ip = in_aton(cur);
cur = delim;
}
cur++;
if ((delim = strchr(cur, '/')) == NULL)
goto parse_failed;
*delim = 0;
- np->remote_ip = ntohl(in_aton(cur));
+ np->remote_ip = in_aton(cur);
cur = delim + 1;
if (*cur != 0) {
atomic_inc(&npinfo->refcnt);
}
- if (!ndev->poll_controller) {
+ if (!ndev->netdev_ops->ndo_poll_controller) {
printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
np->name, np->dev_name);
err = -ENOTSUPP;
}
atleast = jiffies + HZ/10;
- atmost = jiffies + 4*HZ;
+ atmost = jiffies + carrier_timeout * HZ;
while (!netif_carrier_ok(ndev)) {
if (time_after(jiffies, atmost)) {
printk(KERN_NOTICE
np->name);
break;
}
- cond_resched();
+ msleep(1);
}
/* If carrier appears to come up instantly, we don't
goto release;
}
- np->local_ip = ntohl(in_dev->ifa_list->ifa_local);
+ np->local_ip = in_dev->ifa_list->ifa_local;
rcu_read_unlock();
- printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
- np->name, HIPQUAD(np->local_ip));
+ printk(KERN_INFO "%s: local IP %pI4\n", np->name, &np->local_ip);
}
if (np->rx_hook) {