167 lines
4.7 KiB
C
167 lines
4.7 KiB
C
/*
|
|
* Copyright 2007-2010 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* Compatibility file for Linux wireless for kernels 2.6.29.
|
|
*/
|
|
|
|
#include <linux/compat.h>
|
|
#include <linux/usb.h>
|
|
#include <linux/etherdevice.h>
|
|
|
|
/*
|
|
* If you don't see your net_device_ops implemented on
|
|
* netdev_attach_ops() then you are shit out of luck and
|
|
* you must do the nasty ifdef magic, unless you figure
|
|
* out a way to squeze your hacks into this routine :)
|
|
*/
|
|
void netdev_attach_ops(struct net_device *dev,
|
|
const struct net_device_ops *ops)
|
|
{
|
|
dev->open = ops->ndo_open;
|
|
dev->init = ops->ndo_init;
|
|
dev->stop = ops->ndo_stop;
|
|
dev->hard_start_xmit = ops->ndo_start_xmit;
|
|
dev->change_rx_flags = ops->ndo_change_rx_flags;
|
|
dev->set_multicast_list = ops->ndo_set_multicast_list;
|
|
dev->validate_addr = ops->ndo_validate_addr;
|
|
dev->do_ioctl = ops->ndo_do_ioctl;
|
|
dev->set_config = ops->ndo_set_config;
|
|
dev->change_mtu = ops->ndo_change_mtu;
|
|
dev->set_mac_address = ops->ndo_set_mac_address;
|
|
dev->tx_timeout = ops->ndo_tx_timeout;
|
|
if (ops->ndo_get_stats)
|
|
dev->get_stats = ops->ndo_get_stats;
|
|
dev->vlan_rx_register = ops->ndo_vlan_rx_register;
|
|
dev->vlan_rx_add_vid = ops->ndo_vlan_rx_add_vid;
|
|
dev->vlan_rx_kill_vid = ops->ndo_vlan_rx_kill_vid;
|
|
#ifdef CONFIG_NET_POLL_CONTROLLER
|
|
dev->poll_controller = ops->ndo_poll_controller;
|
|
#endif
|
|
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
|
|
dev->select_queue = ops->ndo_select_queue;
|
|
#endif
|
|
}
|
|
EXPORT_SYMBOL_GPL(netdev_attach_ops);
|
|
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,23))
|
|
#if defined(CONFIG_USB) || defined(CONFIG_USB_MODULE)
|
|
/**
|
|
* usb_unpoison_anchored_urbs - let an anchor be used successfully again
|
|
* @anchor: anchor the requests are bound to
|
|
*
|
|
* Reverses the effect of usb_poison_anchored_urbs
|
|
* the anchor can be used normally after it returns
|
|
*/
|
|
void usb_unpoison_anchored_urbs(struct usb_anchor *anchor)
|
|
{
|
|
unsigned long flags;
|
|
struct urb *lazarus;
|
|
|
|
spin_lock_irqsave(&anchor->lock, flags);
|
|
list_for_each_entry(lazarus, &anchor->urb_list, anchor_list) {
|
|
usb_unpoison_urb(lazarus);
|
|
}
|
|
//anchor->poisoned = 0; /* XXX: cannot backport */
|
|
spin_unlock_irqrestore(&anchor->lock, flags);
|
|
}
|
|
EXPORT_SYMBOL_GPL(usb_unpoison_anchored_urbs);
|
|
#endif /* CONFIG_USB */
|
|
#endif
|
|
|
|
/**
|
|
* eth_mac_addr - set new Ethernet hardware address
|
|
* @dev: network device
|
|
* @p: socket address
|
|
* Change hardware address of device.
|
|
*
|
|
* This doesn't change hardware matching, so needs to be overridden
|
|
* for most real devices.
|
|
*/
|
|
int eth_mac_addr(struct net_device *dev, void *p)
|
|
{
|
|
struct sockaddr *addr = p;
|
|
|
|
if (netif_running(dev))
|
|
return -EBUSY;
|
|
if (!is_valid_ether_addr(addr->sa_data))
|
|
return -EADDRNOTAVAIL;
|
|
memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(eth_mac_addr);
|
|
|
|
/**
|
|
* eth_change_mtu - set new MTU size
|
|
* @dev: network device
|
|
* @new_mtu: new Maximum Transfer Unit
|
|
*
|
|
* Allow changing MTU size. Needs to be overridden for devices
|
|
* supporting jumbo frames.
|
|
*/
|
|
int eth_change_mtu(struct net_device *dev, int new_mtu)
|
|
{
|
|
if (new_mtu < 68 || new_mtu > ETH_DATA_LEN)
|
|
return -EINVAL;
|
|
dev->mtu = new_mtu;
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(eth_change_mtu);
|
|
|
|
int eth_validate_addr(struct net_device *dev)
|
|
{
|
|
if (!is_valid_ether_addr(dev->dev_addr))
|
|
return -EADDRNOTAVAIL;
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(eth_validate_addr);
|
|
/* Source: net/ethernet/eth.c */
|
|
|
|
#define NETREG_DUMMY 5
|
|
/**
|
|
* init_dummy_netdev - init a dummy network device for NAPI
|
|
* @dev: device to init
|
|
*
|
|
* This takes a network device structure and initialize the minimum
|
|
* amount of fields so it can be used to schedule NAPI polls without
|
|
* registering a full blown interface. This is to be used by drivers
|
|
* that need to tie several hardware interfaces to a single NAPI
|
|
* poll scheduler due to HW limitations.
|
|
*/
|
|
int init_dummy_netdev(struct net_device *dev)
|
|
{
|
|
/* Clear everything. Note we don't initialize spinlocks
|
|
* are they aren't supposed to be taken by any of the
|
|
* NAPI code and this dummy netdev is supposed to be
|
|
* only ever used for NAPI polls
|
|
*/
|
|
memset(dev, 0, sizeof(struct net_device));
|
|
|
|
/* make sure we BUG if trying to hit standard
|
|
* register/unregister code path
|
|
*/
|
|
dev->reg_state = NETREG_DUMMY;
|
|
|
|
/* initialize the ref count */
|
|
atomic_set(&dev->refcnt, 1);
|
|
|
|
#ifdef CONFIG_NETPOLL
|
|
/* NAPI wants this */
|
|
INIT_LIST_HEAD(&dev->napi_list);
|
|
#endif
|
|
|
|
/* a dummy interface is started by default */
|
|
set_bit(__LINK_STATE_PRESENT, &dev->state);
|
|
set_bit(__LINK_STATE_START, &dev->state);
|
|
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL_GPL(init_dummy_netdev);
|
|
/* Source: net/core/dev.c */
|
|
|