usb: ASIX AX88179 Gigabit-Ethernet Adapter support

This commit is contained in:
Sebastian Sumpf 2013-05-16 16:46:49 +02:00 committed by Norman Feske
parent 6928821f52
commit 6d07fff07c
7 changed files with 167 additions and 101 deletions

View File

@ -75,7 +75,7 @@ CONTENT_NET = usbnet.c
# Panda board
CONTENT_NET += smsc95xx.c smsc95xx.h
# Arndale board
CONTENT_NET += asix_devices.c asix_common.c ax88172a.c asix.h
CONTENT_NET += asix_devices.c asix_common.c ax88172a.c ax88179_178a.c asix.h
CONTENT += $(addprefix drivers/net/usb/,$(CONTENT_NET))
CONTENT += include/linux/usb/usbnet.h include/linux/netdev_features.h

View File

@ -1,10 +1,10 @@
SRC_C += usbnet.c asix_devices.c asix_common.c ax88172a.c
SRC_C += usbnet.c asix_devices.c asix_common.c ax88172a.c ax88179_178a.c
include $(REP_DIR)/lib/mk/usb.inc
include $(REP_DIR)/lib/mk/arm/usb.inc
CC_OPT += -DCONFIG_USB_EHCI_S5P -DCONFIG_USB_EHCI_TT_NEWSCHED -DCONFIG_OF -DCONFIG_USB_DWC3_HOST \
-DCONFIG_USB_OTG_UTILS -DCONFIG_USB_XHCI_PLATFORM
-DCONFIG_USB_OTG_UTILS -DCONFIG_USB_XHCI_PLATFORM -DDWC3_QUIRK
INC_DIR += $(CONTRIB_DIR)/arch/arm/plat-samsung/include
SRC_CC += platform.cc

View File

@ -0,0 +1,20 @@
diff -r 6978f825431c drivers/usb/host/xhci-plat.c
--- a/drivers/usb/host/xhci-plat.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/host/xhci-plat.c Thu May 16 16:41:46 2013 +0200
@@ -25,6 +25,16 @@
* dev struct in order to setup MSI
*/
xhci->quirks |= XHCI_BROKEN_MSI;
+
+#ifdef DWC3_QUIRK
+ /*
+ * DWC3 controller
+ * One will see 'dev_error: ERROR Transfer event TRB DMA ptr not part of
+ * current TD' and last message was short (ep_ring->last_td_was_short, in
+ * xhci-ring.c
+ */
+ xhci->quirks |= XHCI_SPURIOUS_SUCCESS;
+#endif
}
/* called during probe() after chip reset completes */

View File

@ -1,6 +1,6 @@
diff -r a1568b909999 drivers/hid/usbhid/hid-core.c
--- a/drivers/hid/usbhid/hid-core.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/hid/usbhid/hid-core.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/hid/usbhid/hid-core.c
--- a/drivers/hid/usbhid/hid-core.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/hid/usbhid/hid-core.c Thu May 16 16:04:34 2013 +0200
@@ -895,7 +895,7 @@
&usbhid->inbuf_dma);
usbhid->outbuf = usb_alloc_coherent(dev, usbhid->bufsize, GFP_KERNEL,
@ -19,9 +19,9 @@ diff -r a1568b909999 drivers/hid/usbhid/hid-core.c
dbg_hid("couldn't allocate rdesc memory\n");
return -ENOMEM;
}
diff -r a1568b909999 drivers/net/usb/usbnet.c
--- a/drivers/net/usb/usbnet.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/net/usb/usbnet.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/net/usb/usbnet.c
--- a/drivers/net/usb/usbnet.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/net/usb/usbnet.c Thu May 16 16:04:34 2013 +0200
@@ -234,7 +234,7 @@
period = max ((int) dev->status->desc.bInterval,
(dev->udev->speed == USB_SPEED_HIGH) ? 7 : 3);
@ -85,9 +85,9 @@ diff -r a1568b909999 drivers/net/usb/usbnet.c
if (!req)
goto fail_free_buf;
diff -r a1568b909999 drivers/usb/core/config.c
--- a/drivers/usb/core/config.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/core/config.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/core/config.c
--- a/drivers/usb/core/config.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/core/config.c Thu May 16 16:04:34 2013 +0200
@@ -689,7 +689,7 @@
if (!dev->rawdescriptors)
goto err2;
@ -106,9 +106,27 @@ diff -r a1568b909999 drivers/usb/core/config.c
if (!bigbuffer) {
result = -ENOMEM;
goto err;
diff -r a1568b909999 drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/core/devices.c Mon Apr 29 17:30:30 2013 +0200
@@ -777,7 +777,7 @@
int length, total_len, num, i;
int ret;
- bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_KERNEL);
+ bos = kzalloc(sizeof(struct usb_bos_descriptor), GFP_NOIO);
if (!bos)
return -ENOMEM;
@@ -803,7 +803,7 @@
return -ENOMEM;
/* Now let's get the whole BOS descriptor set */
- buffer = kzalloc(total_len, GFP_KERNEL);
+ buffer = kzalloc(total_len, GFP_NOIO);
if (!buffer) {
ret = -ENOMEM;
goto err;
diff -r 6978f825431c drivers/usb/core/devices.c
--- a/drivers/usb/core/devices.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/core/devices.c Thu May 16 16:04:34 2013 +0200
@@ -513,7 +513,7 @@
return 0;
/* allocate 2^1 pages = 8K (on i386);
@ -118,9 +136,9 @@ diff -r a1568b909999 drivers/usb/core/devices.c
if (!pages_start)
return -ENOMEM;
diff -r a1568b909999 drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/core/hub.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/core/hub.c Thu May 16 16:04:34 2013 +0200
@@ -1049,7 +1049,7 @@
hcd = bus_to_hcd(hdev->bus);
if (hcd->driver->update_hub_device) {
@ -184,9 +202,9 @@ diff -r a1568b909999 drivers/usb/core/hub.c
if (buf == NULL) {
dev_err(&udev->dev, "no mem to re-read configs after reset\n");
/* assume the worst */
diff -r a1568b909999 drivers/usb/core/message.c
--- a/drivers/usb/core/message.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/core/message.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/core/message.c
--- a/drivers/usb/core/message.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/core/message.c Thu May 16 16:04:34 2013 +0200
@@ -50,7 +50,7 @@
init_completion(&ctx.done);
urb->context = &ctx;
@ -246,9 +264,9 @@ diff -r a1568b909999 drivers/usb/core/message.c
if (!new_interfaces[n]) {
dev_err(&dev->dev, "Out of memory\n");
ret = -ENOMEM;
diff -r a1568b909999 drivers/usb/host/xhci-hub.c
--- a/drivers/usb/host/xhci-hub.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/host/xhci-hub.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/host/xhci-hub.c
--- a/drivers/usb/host/xhci-hub.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/host/xhci-hub.c Thu May 16 16:04:34 2013 +0200
@@ -275,7 +275,7 @@
ret = 0;
@ -258,9 +276,18 @@ diff -r a1568b909999 drivers/usb/host/xhci-hub.c
if (!cmd) {
xhci_dbg(xhci, "Couldn't allocate command structure.\n");
return -ENOMEM;
diff -r a1568b909999 drivers/usb/host/xhci.c
--- a/drivers/usb/host/xhci.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/host/xhci.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/host/xhci.c
--- a/drivers/usb/host/xhci.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/host/xhci.c Thu May 16 16:04:34 2013 +0200
@@ -1277,7 +1277,7 @@
size = 1;
urb_priv = kzalloc(sizeof(struct urb_priv) +
- size * sizeof(struct xhci_td *), mem_flags);
+ size * sizeof(struct xhci_td *), GFP_NOIO);
if (!urb_priv)
return -ENOMEM;
@@ -1706,7 +1706,7 @@
* process context, not interrupt context (or so documenation
* for usb_set_interface() and usb_set_configuration() claim).
@ -297,9 +324,9 @@ diff -r a1568b909999 drivers/usb/host/xhci.c
xhci_warn(xhci, "Could not allocate xHCI USB device data structures\n");
goto disable_slot;
}
diff -r a1568b909999 drivers/usb/storage/alauda.c
--- a/drivers/usb/storage/alauda.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/alauda.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/alauda.c
--- a/drivers/usb/storage/alauda.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/alauda.c Thu May 16 16:04:34 2013 +0200
@@ -448,8 +448,8 @@
num_zones = MEDIA_INFO(us).capacity >> (MEDIA_INFO(us).zoneshift
@ -358,9 +385,9 @@ diff -r a1568b909999 drivers/usb/storage/alauda.c
if (!us->extra) {
US_DEBUGP("init_alauda: Gah! Can't allocate storage for"
"alauda info struct!\n");
diff -r a1568b909999 drivers/usb/storage/datafab.c
--- a/drivers/usb/storage/datafab.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/datafab.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/datafab.c
--- a/drivers/usb/storage/datafab.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/datafab.c Thu May 16 16:04:34 2013 +0200
@@ -174,7 +174,7 @@
// bounce buffer and the actual transfer buffer.
@ -406,9 +433,9 @@ diff -r a1568b909999 drivers/usb/storage/datafab.c
if (!us->extra) {
US_DEBUGP("datafab_transport: Gah! "
"Can't allocate storage for Datafab info struct!\n");
diff -r a1568b909999 drivers/usb/storage/jumpshot.c
--- a/drivers/usb/storage/jumpshot.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/jumpshot.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/jumpshot.c
--- a/drivers/usb/storage/jumpshot.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/jumpshot.c Thu May 16 16:04:34 2013 +0200
@@ -188,7 +188,7 @@
// bounce buffer and the actual transfer buffer.
@ -445,9 +472,9 @@ diff -r a1568b909999 drivers/usb/storage/jumpshot.c
if (!us->extra) {
US_DEBUGP("jumpshot_transport: Gah! Can't allocate storage for jumpshot info struct!\n");
return USB_STOR_TRANSPORT_ERROR;
diff -r a1568b909999 drivers/usb/storage/karma.c
--- a/drivers/usb/storage/karma.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/karma.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/karma.c
--- a/drivers/usb/storage/karma.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/karma.c Thu May 16 16:04:34 2013 +0200
@@ -182,11 +182,11 @@
static int rio_karma_init(struct us_data *us)
{
@ -462,9 +489,9 @@ diff -r a1568b909999 drivers/usb/storage/karma.c
if (!data->recv) {
kfree(data);
goto out;
diff -r a1568b909999 drivers/usb/storage/onetouch.c
--- a/drivers/usb/storage/onetouch.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/onetouch.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/onetouch.c
--- a/drivers/usb/storage/onetouch.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/onetouch.c Thu May 16 16:04:34 2013 +0200
@@ -163,7 +163,7 @@
usb_kill_urb(onetouch->irq);
break;
@ -474,9 +501,9 @@ diff -r a1568b909999 drivers/usb/storage/onetouch.c
dev_err(&onetouch->irq->dev->dev,
"usb_submit_urb failed\n");
break;
diff -r a1568b909999 drivers/usb/storage/realtek_cr.c
--- a/drivers/usb/storage/realtek_cr.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/realtek_cr.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/realtek_cr.c
--- a/drivers/usb/storage/realtek_cr.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/realtek_cr.c Thu May 16 16:04:34 2013 +0200
@@ -367,7 +367,7 @@
u8 cmnd[12] = { 0 };
u8 *buf;
@ -513,9 +540,9 @@ diff -r a1568b909999 drivers/usb/storage/realtek_cr.c
if (!buf)
return USB_STOR_TRANSPORT_ERROR;
diff -r a1568b909999 drivers/usb/storage/sddr09.c
--- a/drivers/usb/storage/sddr09.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/sddr09.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/sddr09.c
--- a/drivers/usb/storage/sddr09.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/sddr09.c Thu May 16 16:04:34 2013 +0200
@@ -692,7 +692,7 @@
return result;
}
@ -581,9 +608,9 @@ diff -r a1568b909999 drivers/usb/storage/sddr09.c
if (!us->extra)
return -ENOMEM;
us->extra_destructor = sddr09_card_info_destructor;
diff -r a1568b909999 drivers/usb/storage/sddr55.c
--- a/drivers/usb/storage/sddr55.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/sddr55.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/sddr55.c
--- a/drivers/usb/storage/sddr55.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/sddr55.c Thu May 16 16:04:34 2013 +0200
@@ -216,7 +216,7 @@
len = min((unsigned int) sectors, (unsigned int) info->blocksize >>
@ -631,9 +658,9 @@ diff -r a1568b909999 drivers/usb/storage/sddr55.c
if (!us->extra)
return USB_STOR_TRANSPORT_ERROR;
us->extra_destructor = sddr55_card_info_destructor;
diff -r a1568b909999 drivers/usb/storage/shuttle_usbat.c
--- a/drivers/usb/storage/shuttle_usbat.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/shuttle_usbat.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/shuttle_usbat.c
--- a/drivers/usb/storage/shuttle_usbat.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/shuttle_usbat.c Thu May 16 16:04:34 2013 +0200
@@ -1068,7 +1068,7 @@
if (!us || !info)
return USB_STOR_TRANSPORT_ERROR;
@ -679,9 +706,9 @@ diff -r a1568b909999 drivers/usb/storage/shuttle_usbat.c
if (!us->extra) {
US_DEBUGP("init_usbat: Gah! Can't allocate storage for usbat info struct!\n");
return 1;
diff -r a1568b909999 drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/transport.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/transport.c Thu May 16 16:04:34 2013 +0200
@@ -151,7 +151,7 @@
us->current_urb->transfer_dma = us->iobuf_dma;
@ -700,9 +727,9 @@ diff -r a1568b909999 drivers/usb/storage/transport.c
if (result) {
US_DEBUGP("usb_sg_init returned %d\n", result);
return USB_STOR_XFER_ERROR;
diff -r a1568b909999 drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c Mon Apr 29 17:08:12 2013 +0200
+++ b/drivers/usb/storage/usb.c Mon Apr 29 17:30:30 2013 +0200
diff -r 6978f825431c drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c Thu May 16 15:54:34 2013 +0200
+++ b/drivers/usb/storage/usb.c Thu May 16 16:04:34 2013 +0200
@@ -453,7 +453,7 @@
usb_set_intfdata(intf, us);

View File

@ -149,40 +149,6 @@ static void arndale_ehci_init()
}
extern "C" void module_ehci_hcd_init();
extern "C" void module_usbnet_init();
extern "C" void module_asix_driver_init();
extern "C" void module_dwc3_exynos_driver_init();
extern "C" void module_dwc3_driver_init();
extern "C" void module_xhci_hcd_init();
void ehci_setup(Services *services)
{
if (services->nic)
module_asix_driver_init();
/* register EHCI controller */
module_ehci_hcd_init();
/* setup controller */
arndale_ehci_init();
/* setup EHCI-controller platform device */
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
pdev->name = (char *)"s5p-ehci";
pdev->id = 0;
pdev->num_resources = 2;
pdev->resource = _ehci;
pdev->dev.platform_data = &_ehci_data;
/*needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c' */
static u64 dma_mask = ~(u64)0;
pdev->dev.dma_mask = &dma_mask;
pdev->dev.coherent_dma_mask = ~0;
platform_device_register(pdev);
}
struct Power : Genode::Mmio
{
struct Usbdrd_phy_control : Register<0x704, 32> { };
@ -195,6 +161,7 @@ struct Power : Genode::Mmio
}
};
struct Phy_usb3 : Genode::Mmio
{
struct Link_system : Register<0x4, 32>
@ -305,6 +272,7 @@ struct Phy_usb3 : Genode::Mmio
}
};
static void arndale_xhci_init()
{
/* enable power of USB3 */
@ -316,14 +284,55 @@ static void arndale_xhci_init()
Phy_usb3 phy((addr_t)io_phy.local_addr<addr_t>());
}
void xhci_setup()
extern "C" void module_ehci_hcd_init();
extern "C" void module_usbnet_init();
extern "C" void module_asix_driver_init();
extern "C" void module_ax88179_178a_driver_init();
extern "C" void module_dwc3_exynos_driver_init();
extern "C" void module_dwc3_driver_init();
extern "C" void module_xhci_hcd_init();
void ehci_setup(Services *services)
{
arndale_xhci_init();
if (services->nic)
module_asix_driver_init();
/* register EHCI controller */
module_ehci_hcd_init();
/* setup controller */
arndale_ehci_init();
/* setup EHCI-controller platform device */
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
pdev->name = (char *)"s5p-ehci";
pdev->id = 0;
pdev->num_resources = 2;
pdev->resource = _ehci;
pdev->dev.platform_data = &_ehci_data;
/*needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c' */
static u64 dma_mask = ~(u64)0;
pdev->dev.dma_mask = &dma_mask;
pdev->dev.coherent_dma_mask = ~0;
platform_device_register(pdev);
}
void xhci_setup(Services *services)
{
if (services->nic)
module_ax88179_178a_driver_init();
module_dwc3_exynos_driver_init();
module_dwc3_driver_init();
module_xhci_hcd_init();
arndale_xhci_init();
/* setup DWC3-controller platform device */
platform_device *pdev = (platform_device *)kzalloc(sizeof(platform_device), 0);
pdev->name = (char *)"exynos-dwc3";
@ -340,12 +349,13 @@ void xhci_setup()
platform_device_register(pdev);
}
void platform_hcd_init(Services *services)
{
/* register network */
if (services->nic)
module_usbnet_init();
ehci_setup(services);
xhci_setup();
//ehci_setup(services);
xhci_setup(services);
}

View File

@ -869,6 +869,8 @@ void skb_queue_purge(struct sk_buff_head *list) { TRACE; }
void skb_tx_timestamp(struct sk_buff *skb) { TRACE; }
bool skb_defer_rx_timestamp(struct sk_buff *skb) { TRACE; return 0; }
int skb_linearize(struct sk_buff *skb) { TRACE; return 0; }
/*********************
** linux/ethtool.h **

View File

@ -322,6 +322,7 @@ __u64 __swab64p(const __u64 *);
#define cpu_to_le16p __cpu_to_le16p
#define cpu_to_be16p __cpu_to_be16p
#define cpu_to_le16 __cpu_to_le16
#define cpu_to_le16s __cpu_to_le16s
#define cpu_to_be16 __cpu_to_be16
#define cpu_to_le32 __cpu_to_le32
#define cpu_to_be32 __cpu_to_be32
@ -2892,14 +2893,18 @@ int net_ratelimit(void);
struct net_device;
enum {
NET_IP_ALIGN = 2,
CHECKSUM_COMPLETE = 2,
CHECKSUM_PARTIAL = 3,
CHECKSUM_NONE = 0,
CHECKSUM_UNNECESSARY = 1,
CHECKSUM_COMPLETE = 2,
CHECKSUM_PARTIAL = 3,
NET_IP_ALIGN = 2,
};
struct skb_shared_info
{
unsigned short nr_frags;
unsigned short gso_size;
};
struct sk_buff
@ -2976,6 +2981,7 @@ void skb_set_tail_pointer(struct sk_buff *, const int);
struct sk_buff *skb_clone(struct sk_buff *, gfp_t);
void skb_reserve(struct sk_buff *, int);
int skb_header_cloned(const struct sk_buff *);
int skb_linearize(struct sk_buff *);
struct sk_buff *netdev_alloc_skb_ip_align(struct net_device *dev, unsigned int length);
@ -3210,6 +3216,7 @@ struct net_device
unsigned int mtu;
unsigned short needed_headroom;
unsigned short needed_tailroom;
unsigned char perm_addr[MAX_ADDR_LEN];
unsigned char *dev_addr;
unsigned char _dev_addr[ETH_ALEN];
unsigned long trans_start; /* Time (in jiffies) of last Tx */