aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/android/Kconfig1
-rw-r--r--drivers/staging/android/ram_console.c14
-rw-r--r--drivers/staging/android/timed_gpio.c2
-rw-r--r--drivers/staging/at76_usb/Kconfig2
-rw-r--r--drivers/staging/at76_usb/at76_usb.c4620
-rw-r--r--drivers/staging/at76_usb/at76_usb.h227
-rw-r--r--drivers/staging/benet/Kconfig7
-rw-r--r--drivers/staging/benet/MAINTAINERS6
-rw-r--r--drivers/staging/benet/Makefile14
-rw-r--r--drivers/staging/benet/TODO6
-rw-r--r--drivers/staging/benet/asyncmesg.h82
-rw-r--r--drivers/staging/benet/be_cm.h134
-rw-r--r--drivers/staging/benet/be_common.h53
-rw-r--r--drivers/staging/benet/be_ethtool.c348
-rw-r--r--drivers/staging/benet/be_init.c1382
-rw-r--r--drivers/staging/benet/be_int.c863
-rw-r--r--drivers/staging/benet/be_netif.c705
-rw-r--r--drivers/staging/benet/benet.h429
-rw-r--r--drivers/staging/benet/bestatus.h103
-rw-r--r--drivers/staging/benet/cev.h243
-rw-r--r--drivers/staging/benet/cq.c211
-rw-r--r--drivers/staging/benet/descriptors.h71
-rw-r--r--drivers/staging/benet/doorbells.h179
-rw-r--r--drivers/staging/benet/ep.h66
-rw-r--r--drivers/staging/benet/eq.c299
-rw-r--r--drivers/staging/benet/eth.c1273
-rw-r--r--drivers/staging/benet/etx_context.h55
-rw-r--r--drivers/staging/benet/funcobj.c565
-rw-r--r--drivers/staging/benet/fwcmd_common.h222
-rw-r--r--drivers/staging/benet/fwcmd_common_bmap.h717
-rw-r--r--drivers/staging/benet/fwcmd_eth_bmap.h280
-rw-r--r--drivers/staging/benet/fwcmd_hdr_bmap.h54
-rw-r--r--drivers/staging/benet/fwcmd_mcc.h94
-rw-r--r--drivers/staging/benet/fwcmd_opcodes.h244
-rw-r--r--drivers/staging/benet/fwcmd_types_bmap.h29
-rw-r--r--drivers/staging/benet/host_struct.h182
-rw-r--r--drivers/staging/benet/hwlib.h830
-rw-r--r--drivers/staging/benet/mpu.c1364
-rw-r--r--drivers/staging/benet/mpu.h74
-rw-r--r--drivers/staging/benet/mpu_context.h46
-rw-r--r--drivers/staging/benet/pcicfg.h825
-rw-r--r--drivers/staging/benet/post_codes.h111
-rw-r--r--drivers/staging/benet/regmap.h68
-rw-r--r--drivers/staging/panel/panel.c33
-rw-r--r--drivers/staging/rtl8187se/Kconfig1
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c19
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c2
-rw-r--r--drivers/staging/winbond/wbusb.c20
50 files changed, 3940 insertions, 13238 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index ce6badded47a..211af86a6c55 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -73,8 +73,6 @@ source "drivers/staging/rt2860/Kconfig"
source "drivers/staging/rt2870/Kconfig"
-source "drivers/staging/benet/Kconfig"
-
source "drivers/staging/comedi/Kconfig"
source "drivers/staging/asus_oled/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 9ddcc2bb3365..47a56f5ffabc 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_AGNX) += agnx/
obj-$(CONFIG_OTUS) += otus/
obj-$(CONFIG_RT2860) += rt2860/
obj-$(CONFIG_RT2870) += rt2870/
-obj-$(CONFIG_BENET) += benet/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_ASUS_OLED) += asus_oled/
obj-$(CONFIG_PANEL) += panel/
diff --git a/drivers/staging/android/Kconfig b/drivers/staging/android/Kconfig
index 6b996db0dd6a..604bd1e0d546 100644
--- a/drivers/staging/android/Kconfig
+++ b/drivers/staging/android/Kconfig
@@ -27,6 +27,7 @@ menuconfig ANDROID_RAM_CONSOLE_ERROR_CORRECTION
bool "Android RAM Console Enable error correction"
default n
depends on ANDROID_RAM_CONSOLE
+ depends on !ANDROID_RAM_CONSOLE_EARLY_INIT
select REED_SOLOMON
select REED_SOLOMON_ENC8
select REED_SOLOMON_DEC8
diff --git a/drivers/staging/android/ram_console.c b/drivers/staging/android/ram_console.c
index bf006857a87a..643ac5ce381d 100644
--- a/drivers/staging/android/ram_console.c
+++ b/drivers/staging/android/ram_console.c
@@ -224,9 +224,23 @@ static int __init ram_console_init(struct ram_console_buffer *buffer,
ram_console_buffer_size =
buffer_size - sizeof(struct ram_console_buffer);
+ if (ram_console_buffer_size > buffer_size) {
+ pr_err("ram_console: buffer %p, invalid size %d, datasize %d\n",
+ buffer, buffer_size, ram_console_buffer_size);
+ return 0;
+ }
+
#ifdef CONFIG_ANDROID_RAM_CONSOLE_ERROR_CORRECTION
ram_console_buffer_size -= (DIV_ROUND_UP(ram_console_buffer_size,
ECC_BLOCK_SIZE) + 1) * ECC_SIZE;
+
+ if (ram_console_buffer_size > buffer_size) {
+ pr_err("ram_console: buffer %p, invalid size %d, "
+ "non-ecc datasize %d\n",
+ buffer, buffer_size, ram_console_buffer_size);
+ return 0;
+ }
+
ram_console_par_buffer = buffer->data + ram_console_buffer_size;
diff --git a/drivers/staging/android/timed_gpio.c b/drivers/staging/android/timed_gpio.c
index 903270cbbe02..33daff0481d2 100644
--- a/drivers/staging/android/timed_gpio.c
+++ b/drivers/staging/android/timed_gpio.c
@@ -50,7 +50,7 @@ static ssize_t gpio_enable_show(struct device *dev, struct device_attribute *att
if (hrtimer_active(&gpio_data->timer)) {
ktime_t r = hrtimer_get_remaining(&gpio_data->timer);
struct timeval t = ktime_to_timeval(r);
- remaining = t.tv_sec * 1000 + t.tv_usec;
+ remaining = t.tv_sec * 1000 + t.tv_usec / 1000;
} else
remaining = 0;
diff --git a/drivers/staging/at76_usb/Kconfig b/drivers/staging/at76_usb/Kconfig
index 4c0e55e15448..8606f9621624 100644
--- a/drivers/staging/at76_usb/Kconfig
+++ b/drivers/staging/at76_usb/Kconfig
@@ -1,6 +1,6 @@
config USB_ATMEL
tristate "Atmel at76c503/at76c505/at76c505a USB cards"
- depends on MAC80211 && WLAN_80211 && USB
+ depends on WLAN_80211 && USB
default N
select FW_LOADER
---help---
diff --git a/drivers/staging/at76_usb/at76_usb.c b/drivers/staging/at76_usb/at76_usb.c
index 185533e54769..c8e4d31c7df2 100644
--- a/drivers/staging/at76_usb/at76_usb.c
+++ b/drivers/staging/at76_usb/at76_usb.c
@@ -6,7 +6,6 @@
* Copyright (c) 2004 Nick Jones
* Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
* Copyright (c) 2007 Guido Guenther <agx@sigxcpu.org>
- * Copyright (c) 2007 Kalle Valo <kalle.valo@iki.fi>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -17,13 +16,6 @@
* Atmel AT76C503A/505/505A.
*
* Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
- *
- * TODO for the mac80211 port:
- * o adhoc support
- * o RTS/CTS support
- * o Power Save Mode support
- * o support for short/long preambles
- * o export variables through debugfs/sysfs
*/
#include <linux/init.h>
@@ -44,7 +36,7 @@
#include <net/ieee80211_radiotap.h>
#include <linux/firmware.h>
#include <linux/leds.h>
-#include <net/mac80211.h>
+#include <net/ieee80211.h>
#include "at76_usb.h"
@@ -84,43 +76,31 @@
#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */
#define DBG_FW 0x10000000 /* firmware download */
#define DBG_DFU 0x20000000 /* device firmware upgrade */
-#define DBG_CMD 0x40000000
-#define DBG_MAC80211 0x80000000
#define DBG_DEFAULTS 0
/* Use our own dbg macro */
#define at76_dbg(bits, format, arg...) \
-do { \
- if (at76_debug & (bits)) \
- printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
-} while (0)
-
-#define at76_dbg_dump(bits, buf, len, format, arg...) \
-do { \
- if (at76_debug & (bits)) { \
+ do { \
+ if (at76_debug & (bits)) \
printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , ## arg); \
- print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); \
- } \
-} while (0)
+ } while (0)
static int at76_debug = DBG_DEFAULTS;
-#define FIRMWARE_IS_WPA(ver) ((ver.major == 1) && (ver.minor == 103))
-
/* Protect against concurrent firmware loading and parsing */
static struct mutex fw_mutex;
static struct fwentry firmwares[] = {
- [0] = { "" },
- [BOARD_503_ISL3861] = { "atmel_at76c503-i3861.bin" },
- [BOARD_503_ISL3863] = { "atmel_at76c503-i3863.bin" },
- [BOARD_503] = { "atmel_at76c503-rfmd.bin" },
- [BOARD_503_ACC] = { "atmel_at76c503-rfmd-acc.bin" },
- [BOARD_505] = { "atmel_at76c505-rfmd.bin" },
- [BOARD_505_2958] = { "atmel_at76c505-rfmd2958.bin" },
- [BOARD_505A] = { "atmel_at76c505a-rfmd2958.bin" },
- [BOARD_505AMX] = { "atmel_at76c505amx-rfmd.bin" },
+ [0] = {""},
+ [BOARD_503_ISL3861] = {"atmel_at76c503-i3861.bin"},
+ [BOARD_503_ISL3863] = {"atmel_at76c503-i3863.bin"},
+ [BOARD_503] = {"atmel_at76c503-rfmd.bin"},
+ [BOARD_503_ACC] = {"atmel_at76c503-rfmd-acc.bin"},
+ [BOARD_505] = {"atmel_at76c505-rfmd.bin"},
+ [BOARD_505_2958] = {"atmel_at76c505-rfmd2958.bin"},
+ [BOARD_505A] = {"atmel_at76c505a-rfmd2958.bin"},
+ [BOARD_505AMX] = {"atmel_at76c505amx-rfmd.bin"},
};
#define USB_DEVICE_DATA(__ops) .driver_info = (kernel_ulong_t)(__ops)
@@ -130,133 +110,135 @@ static struct usb_device_id dev_table[] = {
* at76c503-i3861
*/
/* Generic AT76C503/3861 device */
- { USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x03eb, 0x7603), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Linksys WUSB11 v2.1/v2.6 */
- { USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x066b, 0x2211), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Netgear MA101 rev. A */
- { USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0864, 0x4100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Tekram U300C / Allnet ALL0193 */
- { USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0b3b, 0x1612), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* HP HN210W J7801A */
- { USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x03f0, 0x011c), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Sitecom/Z-Com/Zyxel M4Y-750 */
- { USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0cde, 0x0001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Dynalink/Askey WLL013 (intersil) */
- { USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x069a, 0x0320), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* EZ connect 11Mpbs Wireless USB Adapter SMC2662W v1 */
- { USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0d5c, 0xa001), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* BenQ AWL300 */
- { USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x04a5, 0x9000), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Addtron AWU-120, Compex WLU11 */
- { USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x05dd, 0xff31), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Intel AP310 AnyPoint II USB */
- { USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x8086, 0x0200), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Dynalink L11U */
- { USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0d8e, 0x7100), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* Arescom WL-210, FCC id 07J-GL2411USB */
- { USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x0d8e, 0x7110), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* I-O DATA WN-B11/USB */
- { USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x04bb, 0x0919), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/* BT Voyager 1010 */
- { USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861) },
+ {USB_DEVICE(0x069a, 0x0821), USB_DEVICE_DATA(BOARD_503_ISL3861)},
/*
* at76c503-i3863
*/
/* Generic AT76C503/3863 device */
- { USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ {USB_DEVICE(0x03eb, 0x7604), USB_DEVICE_DATA(BOARD_503_ISL3863)},
/* Samsung SWL-2100U */
- { USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863) },
+ {USB_DEVICE(0x055d, 0xa000), USB_DEVICE_DATA(BOARD_503_ISL3863)},
/*
* at76c503-rfmd
*/
/* Generic AT76C503/RFMD device */
- { USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x03eb, 0x7605), USB_DEVICE_DATA(BOARD_503)},
/* Dynalink/Askey WLL013 (rfmd) */
- { USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x069a, 0x0321), USB_DEVICE_DATA(BOARD_503)},
/* Linksys WUSB11 v2.6 */
- { USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x077b, 0x2219), USB_DEVICE_DATA(BOARD_503)},
/* Network Everywhere NWU11B */
- { USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x077b, 0x2227), USB_DEVICE_DATA(BOARD_503)},
/* Netgear MA101 rev. B */
- { USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x0864, 0x4102), USB_DEVICE_DATA(BOARD_503)},
/* D-Link DWL-120 rev. E */
- { USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x2001, 0x3200), USB_DEVICE_DATA(BOARD_503)},
/* Actiontec 802UAT1, HWU01150-01UK */
- { USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1668, 0x7605), USB_DEVICE_DATA(BOARD_503)},
/* AirVast W-Buddie WN210 */
- { USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x03eb, 0x4102), USB_DEVICE_DATA(BOARD_503)},
/* Dick Smith Electronics XH1153 802.11b USB adapter */
- { USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1371, 0x5743), USB_DEVICE_DATA(BOARD_503)},
/* CNet CNUSB611 */
- { USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1371, 0x0001), USB_DEVICE_DATA(BOARD_503)},
/* FiberLine FL-WL200U */
- { USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1371, 0x0002), USB_DEVICE_DATA(BOARD_503)},
/* BenQ AWL400 USB stick */
- { USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x04a5, 0x9001), USB_DEVICE_DATA(BOARD_503)},
/* 3Com 3CRSHEW696 */
- { USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x0506, 0x0a01), USB_DEVICE_DATA(BOARD_503)},
/* Siemens Santis ADSL WLAN USB adapter WLL 013 */
- { USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x0681, 0x001b), USB_DEVICE_DATA(BOARD_503)},
/* Belkin F5D6050, version 2 */
- { USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x050d, 0x0050), USB_DEVICE_DATA(BOARD_503)},
/* iBlitzz, BWU613 (not *B or *SB) */
- { USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x07b8, 0xb000), USB_DEVICE_DATA(BOARD_503)},
/* Gigabyte GN-WLBM101 */
- { USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x1044, 0x8003), USB_DEVICE_DATA(BOARD_503)},
/* Planex GW-US11S */
- { USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x2019, 0x3220), USB_DEVICE_DATA(BOARD_503)},
/* Internal WLAN adapter in h5[4,5]xx series iPAQs */
- { USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x049f, 0x0032), USB_DEVICE_DATA(BOARD_503)},
/* Corega Wireless LAN USB-11 mini */
- { USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x07aa, 0x0011), USB_DEVICE_DATA(BOARD_503)},
/* Corega Wireless LAN USB-11 mini2 */
- { USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x07aa, 0x0018), USB_DEVICE_DATA(BOARD_503)},
/* Uniden PCW100 */
- { USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503) },
+ {USB_DEVICE(0x05dd, 0xff35), USB_DEVICE_DATA(BOARD_503)},
/*
* at76c503-rfmd-acc
*/
/* SMC2664W */
- { USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC) },
+ {USB_DEVICE(0x083a, 0x3501), USB_DEVICE_DATA(BOARD_503_ACC)},
/* Belkin F5D6050, SMC2662W v2, SMC2662W-AR */
- { USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC) },
+ {USB_DEVICE(0x0d5c, 0xa002), USB_DEVICE_DATA(BOARD_503_ACC)},
/*
* at76c505-rfmd
*/
/* Generic AT76C505/RFMD */
- { USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505) },
+ {USB_DEVICE(0x03eb, 0x7606), USB_DEVICE_DATA(BOARD_505)},
/*
* at76c505-rfmd2958
*/
/* Generic AT76C505/RFMD, OvisLink WL-1130USB */
- { USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x03eb, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
/* Fiberline FL-WL240U */
- { USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x1371, 0x0014), USB_DEVICE_DATA(BOARD_505_2958)},
/* CNet CNUSB-611G */
- { USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x1371, 0x0013), USB_DEVICE_DATA(BOARD_505_2958)},
/* Linksys WUSB11 v2.8 */
- { USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x1915, 0x2233), USB_DEVICE_DATA(BOARD_505_2958)},
/* Xterasys XN-2122B, IBlitzz BWU613B/BWU613SB */
- { USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x12fd, 0x1001), USB_DEVICE_DATA(BOARD_505_2958)},
/* Corega WLAN USB Stick 11 */
- { USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x07aa, 0x7613), USB_DEVICE_DATA(BOARD_505_2958)},
/* Microstar MSI Box MS6978 */
- { USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958) },
+ {USB_DEVICE(0x0db0, 0x1020), USB_DEVICE_DATA(BOARD_505_2958)},
/*
* at76c505a-rfmd2958
*/
/* Generic AT76C505A device */
- { USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A) },
+ {USB_DEVICE(0x03eb, 0x7614), USB_DEVICE_DATA(BOARD_505A)},
/* Generic AT76C505AS device */
- { USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A) },
+ {USB_DEVICE(0x03eb, 0x7617), USB_DEVICE_DATA(BOARD_505A)},
/* Siemens Gigaset USB WLAN Adapter 11 */
- { USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A) },
+ {USB_DEVICE(0x1690, 0x0701), USB_DEVICE_DATA(BOARD_505A)},
+ /* OQO Model 01+ Internal Wi-Fi */
+ {USB_DEVICE(0x1557, 0x0002), USB_DEVICE_DATA(BOARD_505A)},
/*
* at76c505amx-rfmd
*/
/* Generic AT76C505AMX device */
- { USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX) },
- { }
+ {USB_DEVICE(0x03eb, 0x7615), USB_DEVICE_DATA(BOARD_505AMX)},
+ {}
};
MODULE_DEVICE_TABLE(usb, dev_table);
@@ -264,8 +246,26 @@ MODULE_DEVICE_TABLE(usb, dev_table);
/* Supported rates of this hardware, bit 7 marks basic rates */
static const u8 hw_rates[] = { 0x82, 0x84, 0x0b, 0x16 };
+/* Frequency of each channel in MHz */
+static const long channel_frequency[] = {
+ 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+ 2447, 2452, 2457, 2462, 2467, 2472, 2484
+};
+
+#define NUM_CHANNELS ARRAY_SIZE(channel_frequency)
+
static const char *const preambles[] = { "long", "short", "auto" };
+static const char *const mac_states[] = {
+ [MAC_INIT] = "INIT",
+ [MAC_SCANNING] = "SCANNING",
+ [MAC_AUTH] = "AUTH",
+ [MAC_ASSOC] = "ASSOC",
+ [MAC_JOINING] = "JOINING",
+ [MAC_CONNECTED] = "CONNECTED",
+ [MAC_OWN_IBSS] = "OWN_IBSS"
+};
+
/* Firmware download */
/* DFU states */
#define STATE_IDLE 0x00
@@ -300,30 +300,17 @@ struct dfu_status {
static inline int at76_is_intersil(enum board_type board)
{
- if (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863)
- return 1;
- return 0;
+ return (board == BOARD_503_ISL3861 || board == BOARD_503_ISL3863);
}
static inline int at76_is_503rfmd(enum board_type board)
{
- if (board == BOARD_503 || board == BOARD_503_ACC)
- return 1;
- return 0;
-}
-
-static inline int at76_is_505(enum board_type board)
-{
- if (board == BOARD_505 || board == BOARD_505_2958)
- return 1;
- return 0;
+ return (board == BOARD_503 || board == BOARD_503_ACC);
}
static inline int at76_is_505a(enum board_type board)
{
- if (board == BOARD_505A || board == BOARD_505AMX)
- return 1;
- return 0;
+ return (board == BOARD_505A || board == BOARD_505AMX);
}
/* Load a block of the first (internal) part of the firmware */
@@ -504,6 +491,41 @@ exit:
return ret;
}
+/* Report that the scan results are ready */
+static inline void at76_iwevent_scan_complete(struct net_device *netdev)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ wireless_send_event(netdev, SIOCGIWSCAN, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", netdev->name);
+}
+
+static inline void at76_iwevent_bss_connect(struct net_device *netdev,
+ u8 *bssid)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
+ __func__);
+}
+
+static inline void at76_iwevent_bss_disconnect(struct net_device *netdev)
+{
+ union iwreq_data wrqu;
+ wrqu.data.length = 0;
+ wrqu.data.flags = 0;
+ memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+ wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+ wireless_send_event(netdev, SIOCGIWAP, &wrqu, NULL);
+ at76_dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", netdev->name,
+ __func__);
+}
+
#define HEX2STR_BUFFERS 4
#define HEX2STR_MAX_LEN 64
#define BIN2HEX(x) ((x) < 10 ? '0' + (x) : (x) + 'A' - 10)
@@ -575,6 +597,37 @@ static void at76_ledtrig_tx_activity(void)
mod_timer(&ledtrig_tx_timer, jiffies + HZ / 4);
}
+/* Check if the given ssid is hidden */
+static inline int at76_is_hidden_ssid(u8 *ssid, int length)
+{
+ static const u8 zeros[32];
+
+ if (length == 0)
+ return 1;
+
+ if (length == 1 && ssid[0] == ' ')
+ return 1;
+
+ return (memcmp(ssid, zeros, length) == 0);
+}
+
+static inline void at76_free_bss_list(struct at76_priv *priv)
+{
+ struct list_head *next, *ptr;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ priv->curr_bss = NULL;
+
+ list_for_each_safe(ptr, next, &priv->bss_list) {
+ list_del(ptr);
+ kfree(list_entry(ptr, struct bss_info, list));
+ }
+
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+}
+
static int at76_remap(struct usb_device *udev)
{
int ret;
@@ -598,7 +651,7 @@ static int at76_get_op_mode(struct usb_device *udev)
return -ENOMEM;
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x33,
USB_TYPE_VENDOR | USB_DIR_IN |
- USB_RECIP_INTERFACE, 0x01, 0, &op_mode, 1,
+ USB_RECIP_INTERFACE, 0x01, 0, op_mode, 1,
USB_CTRL_GET_TIMEOUT);
saved = *op_mode;
kfree(op_mode);
@@ -676,7 +729,7 @@ exit:
kfree(hwcfg);
if (ret < 0)
printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -685,15 +738,15 @@ static struct reg_domain const *at76_get_reg_domain(u16 code)
{
int i;
static struct reg_domain const fd_tab[] = {
- { 0x10, "FCC (USA)", 0x7ff }, /* ch 1-11 */
- { 0x20, "IC (Canada)", 0x7ff }, /* ch 1-11 */
- { 0x30, "ETSI (most of Europe)", 0x1fff }, /* ch 1-13 */
- { 0x31, "Spain", 0x600 }, /* ch 10-11 */
- { 0x32, "France", 0x1e00 }, /* ch 10-13 */
- { 0x40, "MKK (Japan)", 0x2000 }, /* ch 14 */
- { 0x41, "MKK1 (Japan)", 0x3fff }, /* ch 1-14 */
- { 0x50, "Israel", 0x3fc }, /* ch 3-9 */
- { 0x00, "<unknown>", 0xffffffff } /* ch 1-32 */
+ {0x10, "FCC (USA)", 0x7ff}, /* ch 1-11 */
+ {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */
+ {0x30, "ETSI (most of Europe)", 0x1fff}, /* ch 1-13 */
+ {0x31, "Spain", 0x600}, /* ch 10-11 */
+ {0x32, "France", 0x1e00}, /* ch 10-13 */
+ {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */
+ {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */
+ {0x50, "Israel", 0x3fc}, /* ch 3-9 */
+ {0x00, "<unknown>", 0xffffffff} /* ch 1-32 */
};
/* Last entry is fallback for unknown domain code */
@@ -731,7 +784,7 @@ static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0x22,
USB_TYPE_VENDOR | USB_DIR_IN |
USB_RECIP_INTERFACE, cmd, 0, stat_buf,
- sizeof(stat_buf), USB_CTRL_GET_TIMEOUT);
+ 40, USB_CTRL_GET_TIMEOUT);
if (ret >= 0)
ret = stat_buf[5];
kfree(stat_buf);
@@ -739,24 +792,6 @@ static inline int at76_get_cmd_status(struct usb_device *udev, u8 cmd)
return ret;
}
-#define MAKE_CMD_CASE(c) case (c): return #c
-
-static const char *at76_get_cmd_string(u8 cmd_status)
-{
- switch (cmd_status) {
- MAKE_CMD_CASE(CMD_SET_MIB);
- MAKE_CMD_CASE(CMD_GET_MIB);
- MAKE_CMD_CASE(CMD_SCAN);
- MAKE_CMD_CASE(CMD_JOIN);
- MAKE_CMD_CASE(CMD_START_IBSS);
- MAKE_CMD_CASE(CMD_RADIO_ON);
- MAKE_CMD_CASE(CMD_RADIO_OFF);
- MAKE_CMD_CASE(CMD_STARTUP);
- }
-
- return "UNKNOWN";
-}
-
static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
int buf_size)
{
@@ -772,10 +807,6 @@ static int at76_set_card_command(struct usb_device *udev, u8 cmd, void *buf,
cmd_buf->size = cpu_to_le16(buf_size);
memcpy(cmd_buf->data, buf, buf_size);
- at76_dbg_dump(DBG_CMD, cmd_buf, sizeof(struct at76_command) + buf_size,
- "issuing command %s (0x%02x)",
- at76_get_cmd_string(cmd), cmd);
-
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0x0e,
USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
0, 0, cmd_buf,
@@ -813,13 +844,13 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
status = at76_get_cmd_status(priv->udev, cmd);
if (status < 0) {
printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
- wiphy_name(priv->hw->wiphy), status);
+ priv->netdev->name, status);
break;
}
at76_dbg(DBG_WAIT_COMPLETE,
"%s: Waiting on cmd %d, status = %d (%s)",
- wiphy_name(priv->hw->wiphy), cmd, status,
+ priv->netdev->name, cmd, status,
at76_get_cmd_status_string(status));
if (status != CMD_STATUS_IN_PROGRESS
@@ -830,7 +861,7 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
if (time_after(jiffies, timeout)) {
printk(KERN_ERR
"%s: completion timeout for command %d\n",
- wiphy_name(priv->hw->wiphy), cmd);
+ priv->netdev->name, cmd);
status = -ETIMEDOUT;
break;
}
@@ -853,7 +884,7 @@ static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
if (ret != CMD_STATUS_COMPLETE) {
printk(KERN_INFO
"%s: set_mib: at76_wait_completion failed "
- "with %d\n", wiphy_name(priv->hw->wiphy), ret);
+ "with %d\n", priv->netdev->name, ret);
ret = -EIO;
}
@@ -874,7 +905,7 @@ static int at76_set_radio(struct at76_priv *priv, int enable)
ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
if (ret < 0)
printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
- wiphy_name(priv->hw->wiphy), cmd, ret);
+ priv->netdev->name, cmd, ret);
else
ret = 1;
@@ -895,7 +926,44 @@ static int at76_set_pm_mode(struct at76_priv *priv)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+/* Set the association id for power save mode */
+static int at76_set_associd(struct at76_priv *priv, u16 id)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, station_id);
+ priv->mib_buf.data.word = cpu_to_le16(id);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (associd) failed: %d\n",
+ priv->netdev->name, ret);
+
+ return ret;
+}
+
+/* Set the listen interval for power save mode */
+static int at76_set_listen_interval(struct at76_priv *priv, u16 interval)
+{
+ int ret = 0;
+
+ priv->mib_buf.type = MIB_MAC;
+ priv->mib_buf.size = 2;
+ priv->mib_buf.index = offsetof(struct mib_mac, listen_interval);
+ priv->mib_buf.data.word = cpu_to_le16(interval);
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR
+ "%s: set_mib (listen_interval) failed: %d\n",
+ priv->netdev->name, ret);
return ret;
}
@@ -912,7 +980,7 @@ static int at76_set_preamble(struct at76_priv *priv, u8 type)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -929,7 +997,7 @@ static int at76_set_frag(struct at76_priv *priv, u16 size)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -946,7 +1014,7 @@ static int at76_set_rts(struct at76_priv *priv, u16 size)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -963,41 +1031,24 @@ static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
-static int at76_set_tkip_bssid(struct at76_priv *priv, const void *addr)
+static int at76_add_mac_address(struct at76_priv *priv, void *addr)
{
int ret = 0;
- priv->mib_buf.type = MIB_MAC_ENCRYPTION;
+ priv->mib_buf.type = MIB_MAC_ADDR;
priv->mib_buf.size = ETH_ALEN;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption, tkip_bssid);
+ priv->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
memcpy(priv->mib_buf.data.addr, addr, ETH_ALEN);
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
- printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, tkip_bssid) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
-
- return ret;
-}
-
-static int at76_reset_rsc(struct at76_priv *priv)
-{
- int ret = 0;
-
- priv->mib_buf.type = MIB_MAC_ENCRYPTION;
- priv->mib_buf.size = 4 * 8;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption, key_rsc);
- memset(priv->mib_buf.data.data, 0 , priv->mib_buf.size);
-
- ret = at76_set_mib(priv, &priv->mib_buf);
- if (ret < 0)
- printk(KERN_ERR "%s: set_mib (MAC_ENCRYPTION, key_rsc) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ printk(KERN_ERR "%s: set_mib (MAC_ADDR, mac_addr) failed: %d\n",
+ priv->netdev->name, ret);
return ret;
}
@@ -1016,16 +1067,16 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv)
sizeof(struct mib_mac_addr));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x",
- wiphy_name(priv->hw->wiphy),
+ priv->netdev->name,
mac2str(m->mac_addr), m->res[0], m->res[1]);
for (i = 0; i < ARRAY_SIZE(m->group_addr); i++)
at76_dbg(DBG_MIB, "%s: MIB MAC_ADDR: group addr %d: %s, "
- "status %d", wiphy_name(priv->hw->wiphy), i,
+ "status %d", priv->netdev->name, i,
mac2str(m->group_addr[i]), m->group_addr_status[i]);
exit:
kfree(m);
@@ -1045,13 +1096,13 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
sizeof(struct mib_mac_wep));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: priv_invoked %u def_key_id %u "
"key_len %u excl_unencr %u wep_icv_err %u wep_excluded %u "
- "encr_level %u key %d", wiphy_name(priv->hw->wiphy),
+ "encr_level %u key %d", priv->netdev->name,
m->privacy_invoked, m->wep_default_key_id,
m->wep_key_mapping_len, m->exclude_unencrypted,
le32_to_cpu(m->wep_icv_error_count),
@@ -1063,55 +1114,12 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
for (i = 0; i < WEP_KEYS; i++)
at76_dbg(DBG_MIB, "%s: MIB MAC_WEP: key %d: %s",
- wiphy_name(priv->hw->wiphy), i,
+ priv->netdev->name, i,
hex2str(m->wep_default_keyvalue[i], key_len));
exit:
kfree(m);
}
-static void at76_dump_mib_mac_encryption(struct at76_priv *priv)
-{
- int i;
- int ret;
- /*int key_len;*/
- struct mib_mac_encryption *m;
-
- m = kmalloc(sizeof(struct mib_mac_encryption), GFP_KERNEL);
- if (!m)
- return;
-
- ret = at76_get_mib(priv->udev, MIB_MAC_ENCRYPTION, m,
- sizeof(struct mib_mac_encryption));
- if (ret < 0) {
- dev_err(&priv->udev->dev,
- "%s: at76_get_mib (MAC_ENCRYPTION) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- goto exit;
- }
-
- at76_dbg(DBG_MIB,
- "%s: MIB MAC_ENCRYPTION: tkip_bssid %s priv_invoked %u "
- "ciph_key_id %u grp_key_id %u excl_unencr %u "
- "ckip_key_perm %u wep_icv_err %u wep_excluded %u",
- wiphy_name(priv->hw->wiphy), mac2str(m->tkip_bssid),
- m->privacy_invoked, m->cipher_default_key_id,
- m->cipher_default_group_key_id, m->exclude_unencrypted,
- m->ckip_key_permutation,
- le32_to_cpu(m->wep_icv_error_count),
- le32_to_cpu(m->wep_excluded_count));
-
- /*key_len = (m->encryption_level == 1) ?
- WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;*/
-
- for (i = 0; i < CIPHER_KEYS; i++)
- at76_dbg(DBG_MIB, "%s: MIB MAC_ENCRYPTION: key %d: %s",
- wiphy_name(priv->hw->wiphy), i,
- hex2str(m->cipher_default_keyvalue[i],
- CIPHER_KEY_LEN));
-exit:
- kfree(m);
-}
-
static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
{
int ret;
@@ -1125,7 +1133,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
sizeof(struct mib_mac_mgmt));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
@@ -1136,7 +1144,7 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
"pm_mode %d ibss_change %d res %d "
"multi_domain_capability_implemented %d "
"international_roaming %d country_string %.3s",
- wiphy_name(priv->hw->wiphy), le16_to_cpu(m->beacon_period),
+ priv->netdev->name, le16_to_cpu(m->beacon_period),
le16_to_cpu(m->CFP_max_duration),
le16_to_cpu(m->medium_occupancy_limit),
le16_to_cpu(m->station_id), le16_to_cpu(m->ATIM_window),
@@ -1161,7 +1169,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
@@ -1171,8 +1179,7 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
"scan_type %d scan_channel %d probe_delay %u "
"min_channel_time %d max_channel_time %d listen_int %d "
"desired_ssid %s desired_bssid %s desired_bsstype %d",
- wiphy_name(priv->hw->wiphy),
- le32_to_cpu(m->max_tx_msdu_lifetime),
+ priv->netdev->name, le32_to_cpu(m->max_tx_msdu_lifetime),
le32_to_cpu(m->max_rx_lifetime),
le16_to_cpu(m->frag_threshold), le16_to_cpu(m->rts_threshold),
le16_to_cpu(m->cwmin), le16_to_cpu(m->cwmax),
@@ -1198,7 +1205,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
@@ -1207,7 +1214,7 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
"mpdu_max_length %d cca_mode_supported %d operation_rate_set "
"0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
"phy_type %d current_reg_domain %d",
- wiphy_name(priv->hw->wiphy), le32_to_cpu(m->ed_threshold),
+ priv->netdev->name, le32_to_cpu(m->ed_threshold),
le16_to_cpu(m->slot_time), le16_to_cpu(m->sifs_time),
le16_to_cpu(m->preamble_length),
le16_to_cpu(m->plcp_header_length),
@@ -1231,14 +1238,13 @@ static void at76_dump_mib_local(struct at76_priv *priv)
ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB LOCAL: beacon_enable %d "
"txautorate_fallback %d ssid_size %d promiscuous_mode %d "
- "preamble_type %d", wiphy_name(priv->hw->wiphy),
- m->beacon_enable,
+ "preamble_type %d", priv->netdev->name, m->beacon_enable,
m->txautorate_fallback, m->ssid_size, m->promiscuous_mode,
m->preamble_type);
exit:
@@ -1257,21 +1263,118 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv)
sizeof(struct mib_mdomain));
if (ret < 0) {
printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
goto exit;
}
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s",
- wiphy_name(priv->hw->wiphy),
+ priv->netdev->name,
hex2str(m->channel_list, sizeof(m->channel_list)));
at76_dbg(DBG_MIB, "%s: MIB MDOMAIN: tx_powerlevel %s",
- wiphy_name(priv->hw->wiphy),
+ priv->netdev->name,
hex2str(m->tx_powerlevel, sizeof(m->tx_powerlevel)));
exit:
kfree(m);
}
+static int at76_get_current_bssid(struct at76_priv *priv)
+{
+ int ret = 0;
+ struct mib_mac_mgmt *mac_mgmt =
+ kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
+
+ if (!mac_mgmt) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, mac_mgmt,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
+ priv->netdev->name, ret);
+ goto error;
+ }
+ memcpy(priv->bssid, mac_mgmt->current_bssid, ETH_ALEN);
+ printk(KERN_INFO "%s: using BSSID %s\n", priv->netdev->name,
+ mac2str(priv->bssid));
+error:
+ kfree(mac_mgmt);
+exit:
+ return ret;
+}
+
+static int at76_get_current_channel(struct at76_priv *priv)
+{
+ int ret = 0;
+ struct mib_phy *phy = kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
+
+ if (!phy) {
+ ret = -ENOMEM;
+ goto exit;
+ }
+ ret = at76_get_mib(priv->udev, MIB_PHY, phy, sizeof(struct mib_phy));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib(MIB_PHY) failed: %d\n",
+ priv->netdev->name, ret);
+ goto error;
+ }
+ priv->channel = phy->channel_id;
+error:
+ kfree(phy);
+exit:
+ return ret;
+}
+
+/**
+ * at76_start_scan - start a scan
+ *
+ * @use_essid - use the configured ESSID in non passive mode
+ */
+static int at76_start_scan(struct at76_priv *priv, int use_essid)
+{
+ struct at76_req_scan scan;
+
+ memset(&scan, 0, sizeof(struct at76_req_scan));
+ memset(scan.bssid, 0xff, ETH_ALEN);
+
+ if (use_essid) {
+ memcpy(scan.essid, priv->essid, IW_ESSID_MAX_SIZE);
+ scan.essid_size = priv->essid_size;
+ } else
+ scan.essid_size = 0;
+
+ /* jal: why should we start at a certain channel? we do scan the whole
+ range allowed by reg domain. */
+ scan.channel = priv->channel;
+
+ /* atmelwlandriver differs between scan type 0 and 1 (active/passive)
+ For ad-hoc mode, it uses type 0 only. */
+ scan.scan_type = priv->scan_mode;
+
+ /* INFO: For probe_delay, not multiplying by 1024 as this will be
+ slightly less than min_channel_time
+ (per spec: probe delay < min. channel time) */
+ scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
+ scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
+ scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
+ scan.international_scan = 0;
+
+ /* other values are set to 0 for type 0 */
+
+ at76_dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, "
+ "channel = %d, probe_delay = %d, scan_min_time = %d, "
+ "scan_max_time = %d)",
+ priv->netdev->name, use_essid,
+ scan.international_scan, scan.channel,
+ le16_to_cpu(scan.probe_delay),
+ le16_to_cpu(scan.min_channel_time),
+ le16_to_cpu(scan.max_channel_time));
+
+ return at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+}
+
/* Enable monitor mode */
static int at76_start_monitor(struct at76_priv *priv)
{
@@ -1292,6 +1395,86 @@ static int at76_start_monitor(struct at76_priv *priv)
return ret;
}
+static int at76_start_ibss(struct at76_priv *priv)
+{
+ struct at76_req_ibss bss;
+ int ret;
+
+ WARN_ON(priv->mac_state != MAC_OWN_IBSS);
+ if (priv->mac_state != MAC_OWN_IBSS)
+ return -EBUSY;
+
+ memset(&bss, 0, sizeof(struct at76_req_ibss));
+ memset(bss.bssid, 0xff, ETH_ALEN);
+ memcpy(bss.essid, priv->essid, IW_ESSID_MAX_SIZE);
+ bss.essid_size = priv->essid_size;
+ bss.bss_type = ADHOC_MODE;
+ bss.channel = priv->channel;
+
+ ret = at76_set_card_command(priv->udev, CMD_START_IBSS, &bss,
+ sizeof(struct at76_req_ibss));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: start_ibss failed: %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ ret = at76_wait_completion(priv, CMD_START_IBSS);
+ if (ret != CMD_STATUS_COMPLETE) {
+ printk(KERN_ERR "%s: start_ibss failed to complete, %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ ret = at76_get_current_bssid(priv);
+ if (ret < 0)
+ return ret;
+
+ ret = at76_get_current_channel(priv);
+ if (ret < 0)
+ return ret;
+
+ /* not sure what this is good for ??? */
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
+ priv->mib_buf.data.byte = 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
+ priv->netdev->name, ret);
+ return ret;
+ }
+
+ netif_carrier_on(priv->netdev);
+ netif_start_queue(priv->netdev);
+ return 0;
+}
+
+/* Request card to join BSS in managed or ad-hoc mode */
+static int at76_join_bss(struct at76_priv *priv, struct bss_info *ptr)
+{
+ struct at76_req_join join;
+
+ BUG_ON(!ptr);
+
+ memset(&join, 0, sizeof(struct at76_req_join));
+ memcpy(join.bssid, ptr->bssid, ETH_ALEN);
+ memcpy(join.essid, ptr->ssid, ptr->ssid_len);
+ join.essid_size = ptr->ssid_len;
+ join.bss_type = (priv->iw_mode == IW_MODE_ADHOC ? 1 : 2);
+ join.channel = ptr->channel;
+ join.timeout = cpu_to_le16(2000);
+
+ at76_dbg(DBG_PROGRESS,
+ "%s join addr %s ssid %s type %d ch %d timeout %d",
+ priv->netdev->name, mac2str(join.bssid), join.essid,
+ join.bss_type, join.channel, le16_to_cpu(join.timeout));
+ return at76_set_card_command(priv->udev, CMD_JOIN, &join,
+ sizeof(struct at76_req_join));
+}
+
/* Calculate padding from txbuf->wlength (which excludes the USB TX header),
likely to compensate a flaw in the AT76C503A USB part ... */
static inline int at76_calc_padding(int wlen)
@@ -1310,6 +1493,14 @@ static inline int at76_calc_padding(int wlen)
return 0;
}
+/* We are doing a lot of things here in an interrupt. Need
+ a bh handler (Watching TV with a TV card is probably
+ a good test: if you see flickers, we are doing too much.
+ Currently I do see flickers... even with our tasklet :-( )
+ Maybe because the bttv driver and usb-uhci use the same interrupt
+*/
+/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't
+ * solve everything.. (alex) */
static void at76_rx_callback(struct urb *urb)
{
struct at76_priv *priv = urb->context;
@@ -1319,6 +1510,1758 @@ static void at76_rx_callback(struct urb *urb)
return;
}
+static void at76_tx_callback(struct urb *urb)
+{
+ struct at76_priv *priv = urb->context;
+ struct net_device_stats *stats = &priv->stats;
+ unsigned long flags;
+ struct at76_tx_buffer *mgmt_buf;
+ int ret;
+
+ switch (urb->status) {
+ case 0:
+ stats->tx_packets++;
+ break;
+ case -ENOENT:
+ case -ECONNRESET:
+ /* urb has been unlinked */
+ return;
+ default:
+ at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
+ __func__, urb->status);
+ stats->tx_errors++;
+ break;
+ }
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+ mgmt_buf = priv->next_mgmt_bulk;
+ priv->next_mgmt_bulk = NULL;
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+
+ if (!mgmt_buf) {
+ netif_wake_queue(priv->netdev);
+ return;
+ }
+
+ /* we don't copy the padding bytes, but add them
+ to the length */
+ memcpy(priv->bulk_out_buffer, mgmt_buf,
+ le16_to_cpu(mgmt_buf->wlength) + AT76_TX_HDRLEN);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
+ priv->bulk_out_buffer,
+ le16_to_cpu(mgmt_buf->wlength) + mgmt_buf->padding +
+ AT76_TX_HDRLEN, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret)
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ priv->netdev->name, ret);
+
+ kfree(mgmt_buf);
+}
+
+/* Send a management frame on bulk-out. txbuf->wlength must be set */
+static int at76_tx_mgmt(struct at76_priv *priv, struct at76_tx_buffer *txbuf)
+{
+ unsigned long flags;
+ int ret;
+ int urb_status;
+ void *oldbuf = NULL;
+
+ netif_carrier_off(priv->netdev); /* stop netdev watchdog */
+ netif_stop_queue(priv->netdev); /* stop tx data packets */
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+
+ urb_status = priv->tx_urb->status;
+ if (urb_status == -EINPROGRESS) {
+ /* cannot transmit now, put in the queue */
+ oldbuf = priv->next_mgmt_bulk;
+ priv->next_mgmt_bulk = txbuf;
+ }
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+
+ if (oldbuf) {
+ /* a data/mgmt tx is already pending in the URB -
+ if this is no error in some situations we must
+ implement a queue or silently modify the old msg */
+ printk(KERN_ERR "%s: removed pending mgmt buffer %s\n",
+ priv->netdev->name, hex2str(oldbuf, 64));
+ kfree(oldbuf);
+ return 0;
+ }
+
+ txbuf->tx_rate = TX_RATE_1MBIT;
+ txbuf->padding = at76_calc_padding(le16_to_cpu(txbuf->wlength));
+ memset(txbuf->reserved, 0, sizeof(txbuf->reserved));
+
+ if (priv->next_mgmt_bulk)
+ printk(KERN_ERR "%s: URB status %d, but mgmt is pending\n",
+ priv->netdev->name, urb_status);
+
+ at76_dbg(DBG_TX_MGMT,
+ "%s: tx mgmt: wlen %d tx_rate %d pad %d %s",
+ priv->netdev->name, le16_to_cpu(txbuf->wlength),
+ txbuf->tx_rate, txbuf->padding,
+ hex2str(txbuf->packet, le16_to_cpu(txbuf->wlength)));
+
+ /* txbuf was not consumed above -> send mgmt msg immediately */
+ memcpy(priv->bulk_out_buffer, txbuf,
+ le16_to_cpu(txbuf->wlength) + AT76_TX_HDRLEN);
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe,
+ priv->bulk_out_buffer,
+ le16_to_cpu(txbuf->wlength) + txbuf->padding +
+ AT76_TX_HDRLEN, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret)
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ priv->netdev->name, ret);
+
+ kfree(txbuf);
+
+ return ret;
+}
+
+/* Go to the next information element */
+static inline void next_ie(struct ieee80211_info_element **ie)
+{
+ *ie = (struct ieee80211_info_element *)(&(*ie)->data[(*ie)->len]);
+}
+
+/* Challenge is the challenge string (in TLV format)
+ we got with seq_nr 2 for shared secret authentication only and
+ send in seq_nr 3 WEP encrypted to prove we have the correct WEP key;
+ otherwise it is NULL */
+static int at76_auth_req(struct at76_priv *priv, struct bss_info *bss,
+ int seq_nr, struct ieee80211_info_element *challenge)
+{
+ struct at76_tx_buffer *tx_buffer;
+ struct ieee80211_hdr_3addr *mgmt;
+ struct ieee80211_auth *req;
+ int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE :
+ AUTH_FRAME_SIZE + 1 + 1 + challenge->len);
+
+ BUG_ON(!bss);
+ BUG_ON(seq_nr == 3 && !challenge);
+ tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC);
+ if (!tx_buffer)
+ return -ENOMEM;
+
+ req = (struct ieee80211_auth *)tx_buffer->packet;
+ mgmt = &req->header;
+
+ /* make wireless header */
+ /* first auth msg is not encrypted, only the second (seq_nr == 3) */
+ mgmt->frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH |
+ (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0));
+
+ mgmt->duration_id = cpu_to_le16(0x8000);
+ memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
+ memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
+ memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
+ mgmt->seq_ctl = cpu_to_le16(0);
+
+ req->algorithm = cpu_to_le16(priv->auth_mode);
+ req->transaction = cpu_to_le16(seq_nr);
+ req->status = cpu_to_le16(0);
+
+ if (seq_nr == 3)
+ memcpy(req->info_element, challenge, 1 + 1 + challenge->len);
+
+ /* init. at76_priv tx header */
+ tx_buffer->wlength = cpu_to_le16(buf_len - AT76_TX_HDRLEN);
+ at76_dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(req->algorithm), le16_to_cpu(req->transaction));
+ if (seq_nr == 3)
+ at76_dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...",
+ priv->netdev->name, hex2str(req->info_element, 18));
+
+ /* either send immediately (if no data tx is pending
+ or put it in pending list */
+ return at76_tx_mgmt(priv, tx_buffer);
+}
+
+static int at76_assoc_req(struct at76_priv *priv, struct bss_info *bss)
+{
+ struct at76_tx_buffer *tx_buffer;
+ struct ieee80211_hdr_3addr *mgmt;
+ struct ieee80211_assoc_request *req;
+ struct ieee80211_info_element *ie;
+ char *essid;
+ int essid_len;
+ u16 capa;
+
+ BUG_ON(!bss);
+
+ tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE, GFP_ATOMIC);
+ if (!tx_buffer)
+ return -ENOMEM;
+
+ req = (struct ieee80211_assoc_request *)tx_buffer->packet;
+ mgmt = &req->header;
+ ie = req->info_element;
+
+ /* make wireless header */
+ mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ASSOC_REQ);
+
+ mgmt->duration_id = cpu_to_le16(0x8000);
+ memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
+ memcpy(mgmt->addr2, priv->netdev->dev_addr, ETH_ALEN);
+ memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
+ mgmt->seq_ctl = cpu_to_le16(0);
+
+ /* we must set the Privacy bit in the capabilities to assure an
+ Agere-based AP with optional WEP transmits encrypted frames
+ to us. AP only set the Privacy bit in their capabilities
+ if WEP is mandatory in the BSS! */
+ capa = bss->capa;
+ if (priv->wep_enabled)
+ capa |= WLAN_CAPABILITY_PRIVACY;
+ if (priv->preamble_type != PREAMBLE_TYPE_LONG)
+ capa |= WLAN_CAPABILITY_SHORT_PREAMBLE;
+ req->capability = cpu_to_le16(capa);
+
+ req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
+
+ /* write TLV data elements */
+
+ ie->id = MFIE_TYPE_SSID;
+ ie->len = bss->ssid_len;
+ memcpy(ie->data, bss->ssid, bss->ssid_len);
+ next_ie(&ie);
+
+ ie->id = MFIE_TYPE_RATES;
+ ie->len = sizeof(hw_rates);
+ memcpy(ie->data, hw_rates, sizeof(hw_rates));
+ next_ie(&ie); /* ie points behind the supp_rates field */
+
+ /* init. at76_priv tx header */
+ tx_buffer->wlength = cpu_to_le16((u8 *)ie - (u8 *)mgmt);
+
+ ie = req->info_element;
+ essid = ie->data;
+ essid_len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
+
+ next_ie(&ie); /* points to IE of rates now */
+ at76_dbg(DBG_TX_MGMT,
+ "%s: AssocReq bssid %s capa 0x%04x ssid %.*s rates %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(req->capability), essid_len, essid,
+ hex2str(ie->data, ie->len));
+
+ /* either send immediately (if no data tx is pending
+ or put it in pending list */
+ return at76_tx_mgmt(priv, tx_buffer);
+}
+
+/* We got to check the bss_list for old entries */
+static void at76_bss_list_timeout(unsigned long par)
+{
+ struct at76_priv *priv = (struct at76_priv *)par;
+ unsigned long flags;
+ struct list_head *lptr, *nptr;
+ struct bss_info *ptr;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ list_for_each_safe(lptr, nptr, &priv->bss_list) {
+
+ ptr = list_entry(lptr, struct bss_info, list);
+
+ if (ptr != priv->curr_bss
+ && time_after(jiffies, ptr->last_rx + BSS_LIST_TIMEOUT)) {
+ at76_dbg(DBG_BSS_TABLE_RM,
+ "%s: bss_list: removing old BSS %s ch %d",
+ priv->netdev->name, mac2str(ptr->bssid),
+ ptr->channel);
+ list_del(&ptr->list);
+ kfree(ptr);
+ }
+ }
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+ /* restart the timer */
+ mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
+}
+
+static inline void at76_set_mac_state(struct at76_priv *priv,
+ enum mac_state mac_state)
+{
+ at76_dbg(DBG_MAC_STATE, "%s state: %s", priv->netdev->name,
+ mac_states[mac_state]);
+ priv->mac_state = mac_state;
+}
+
+static void at76_dump_bss_table(struct at76_priv *priv)
+{
+ struct bss_info *ptr;
+ unsigned long flags;
+ struct list_head *lptr;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ at76_dbg(DBG_BSS_TABLE, "%s BSS table (curr=%p):", priv->netdev->name,
+ priv->curr_bss);
+
+ list_for_each(lptr, &priv->bss_list) {
+ ptr = list_entry(lptr, struct bss_info, list);
+ at76_dbg(DBG_BSS_TABLE, "0x%p: bssid %s channel %d ssid %.*s "
+ "(%s) capa 0x%04x rates %s rssi %d link %d noise %d",
+ ptr, mac2str(ptr->bssid), ptr->channel, ptr->ssid_len,
+ ptr->ssid, hex2str(ptr->ssid, ptr->ssid_len),
+ ptr->capa, hex2str(ptr->rates, ptr->rates_len),
+ ptr->rssi, ptr->link_qual, ptr->noise_level);
+ }
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+}
+
+/* Called upon successful association to mark interface as connected */
+static void at76_work_assoc_done(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_assoc_done);
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_ASSOC);
+ WARN_ON(!priv->curr_bss);
+ if (priv->mac_state != MAC_ASSOC || !priv->curr_bss)
+ goto exit;
+
+ if (priv->iw_mode == IW_MODE_INFRA) {
+ if (priv->pm_mode != AT76_PM_OFF) {
+ /* calculate the listen interval in units of
+ beacon intervals of the curr_bss */
+ u32 pm_period_beacon = (priv->pm_period >> 10) /
+ priv->curr_bss->beacon_interval;
+
+ pm_period_beacon = max(pm_period_beacon, 2u);
+ pm_period_beacon = min(pm_period_beacon, 0xffffu);
+
+ at76_dbg(DBG_PM,
+ "%s: pm_mode %d assoc id 0x%x listen int %d",
+ priv->netdev->name, priv->pm_mode,
+ priv->assoc_id, pm_period_beacon);
+
+ at76_set_associd(priv, priv->assoc_id);
+ at76_set_listen_interval(priv, (u16)pm_period_beacon);
+ }
+ schedule_delayed_work(&priv->dwork_beacon, BEACON_TIMEOUT);
+ }
+ at76_set_pm_mode(priv);
+
+ netif_carrier_on(priv->netdev);
+ netif_wake_queue(priv->netdev);
+ at76_set_mac_state(priv, MAC_CONNECTED);
+ at76_iwevent_bss_connect(priv->netdev, priv->curr_bss->bssid);
+ at76_dbg(DBG_PROGRESS, "%s: connected to BSSID %s",
+ priv->netdev->name, mac2str(priv->curr_bss->bssid));
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* We only store the new mac address in netdev struct,
+ it gets set when the netdev is opened. */
+static int at76_set_mac_address(struct net_device *netdev, void *addr)
+{
+ struct sockaddr *mac = addr;
+ memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
+ return 1;
+}
+
+static struct net_device_stats *at76_get_stats(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ return &priv->stats;
+}
+
+static struct iw_statistics *at76_get_wireless_stats(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d",
+ priv->wstats.qual.qual, priv->wstats.qual.level,
+ priv->wstats.qual.noise, priv->wstats.qual.updated);
+
+ return &priv->wstats;
+}
+
+static void at76_set_multicast(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int promisc;
+
+ promisc = ((netdev->flags & IFF_PROMISC) != 0);
+ if (promisc != priv->promisc) {
+ /* This gets called in interrupt, must reschedule */
+ priv->promisc = promisc;
+ schedule_work(&priv->work_set_promisc);
+ }
+}
+
+/* Stop all network activity, flush all pending tasks */
+static void at76_quiesce(struct at76_priv *priv)
+{
+ unsigned long flags;
+
+ netif_stop_queue(priv->netdev);
+ netif_carrier_off(priv->netdev);
+
+ at76_set_mac_state(priv, MAC_INIT);
+
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ cancel_delayed_work(&priv->dwork_restart);
+
+ spin_lock_irqsave(&priv->mgmt_spinlock, flags);
+ kfree(priv->next_mgmt_bulk);
+ priv->next_mgmt_bulk = NULL;
+ spin_unlock_irqrestore(&priv->mgmt_spinlock, flags);
+}
+
+/*******************************************************************************
+ * at76_priv implementations of iw_handler functions:
+ */
+static int at76_iw_handler_commit(struct net_device *netdev,
+ struct iw_request_info *info,
+ void *null, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name,
+ __func__);
+
+ if (priv->mac_state != MAC_INIT)
+ at76_quiesce(priv);
+
+ /* Wait half second before the restart to process subsequent
+ * requests from the same iwconfig in a single restart */
+ schedule_delayed_work(&priv->dwork_restart, HZ / 2);
+
+ return 0;
+}
+
+static int at76_iw_handler_get_name(struct net_device *netdev,
+ struct iw_request_info *info,
+ char *name, char *extra)
+{
+ strcpy(name, "IEEE 802.11b");
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name);
+ return 0;
+}
+
+static int at76_iw_handler_set_freq(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int chan = -1;
+ int ret = -EIWCOMMIT;
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d",
+ netdev->name, freq->m, freq->e);
+
+ if ((freq->e == 0) && (freq->m <= 1000))
+ /* Setting by channel number */
+ chan = freq->m;
+ else {
+ /* Setting by frequency - search the table */
+ int mult = 1;
+ int i;
+
+ for (i = 0; i < (6 - freq->e); i++)
+ mult *= 10;
+
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ if (freq->m == (channel_frequency[i] * mult))
+ chan = i + 1;
+ }
+ }
+
+ if (chan < 1 || !priv->domain)
+ /* non-positive channels are invalid
+ * we need a domain info to set the channel
+ * either that or an invalid frequency was
+ * provided by the user */
+ ret = -EINVAL;
+ else if (!(priv->domain->channel_map & (1 << (chan - 1)))) {
+ printk(KERN_INFO "%s: channel %d not allowed for domain %s\n",
+ priv->netdev->name, chan, priv->domain->name);
+ ret = -EINVAL;
+ }
+
+ if (ret == -EIWCOMMIT) {
+ priv->channel = chan;
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name,
+ chan);
+ }
+
+ return ret;
+}
+
+static int at76_iw_handler_get_freq(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_freq *freq, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ freq->m = priv->channel;
+ freq->e = 0;
+
+ if (priv->channel)
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d",
+ netdev->name, channel_frequency[priv->channel - 1], 6);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name,
+ priv->channel);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode);
+
+ if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) &&
+ (*mode != IW_MODE_MONITOR))
+ return -EINVAL;
+
+ priv->iw_mode = *mode;
+ if (priv->iw_mode != IW_MODE_INFRA)
+ priv->pm_mode = AT76_PM_OFF;
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ __u32 *mode, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ *mode = priv->iw_mode;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode);
+
+ return 0;
+}
+
+static int at76_iw_handler_get_range(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ /* inspired by atmel.c */
+ struct at76_priv *priv = netdev_priv(netdev);
+ struct iw_range *range = (struct iw_range *)extra;
+ int i;
+
+ data->length = sizeof(struct iw_range);
+ memset(range, 0, sizeof(struct iw_range));
+
+ /* TODO: range->throughput = xxxxxx; */
+
+ range->min_nwid = 0x0000;
+ range->max_nwid = 0x0000;
+
+ /* this driver doesn't maintain sensitivity information */
+ range->sensitivity = 0;
+
+ range->max_qual.qual = 100;
+ range->max_qual.level = 100;
+ range->max_qual.noise = 0;
+ range->max_qual.updated = IW_QUAL_NOISE_INVALID;
+
+ range->avg_qual.qual = 50;
+ range->avg_qual.level = 50;
+ range->avg_qual.noise = 0;
+ range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
+
+ range->bitrate[0] = 1000000;
+ range->bitrate[1] = 2000000;
+ range->bitrate[2] = 5500000;
+ range->bitrate[3] = 11000000;
+ range->num_bitrates = 4;
+
+ range->min_rts = 0;
+ range->max_rts = MAX_RTS_THRESHOLD;
+
+ range->min_frag = MIN_FRAG_THRESHOLD;
+ range->max_frag = MAX_FRAG_THRESHOLD;
+
+ range->pmp_flags = IW_POWER_PERIOD;
+ range->pmt_flags = IW_POWER_ON;
+ range->pm_capa = IW_POWER_PERIOD | IW_POWER_ALL_R;
+
+ range->encoding_size[0] = WEP_SMALL_KEY_LEN;
+ range->encoding_size[1] = WEP_LARGE_KEY_LEN;
+ range->num_encoding_sizes = 2;
+ range->max_encoding_tokens = WEP_KEYS;
+
+ /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power
+ - take this for all (ignore antenna gains) */
+ range->txpower[0] = 15;
+ range->num_txpower = 1;
+ range->txpower_capa = IW_TXPOW_DBM;
+
+ range->we_version_source = WIRELESS_EXT;
+ range->we_version_compiled = WIRELESS_EXT;
+
+ /* same as the values used in atmel.c */
+ range->retry_capa = IW_RETRY_LIMIT;
+ range->retry_flags = IW_RETRY_LIMIT;
+ range->r_time_flags = 0;
+ range->min_retry = 1;
+ range->max_retry = 255;
+
+ range->num_channels = NUM_CHANNELS;
+ range->num_frequency = 0;
+
+ for (i = 0; i < NUM_CHANNELS; i++) {
+ /* test if channel map bit is raised */
+ if (priv->domain->channel_map & (0x1 << i)) {
+ range->num_frequency += 1;
+
+ range->freq[i].i = i + 1;
+ range->freq[i].m = channel_frequency[i] * 100000;
+ range->freq[i].e = 1; /* freq * 10^1 */
+ }
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_spy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d",
+ netdev->name, data->length);
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_set_spy(priv->netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ return ret;
+}
+
+static int at76_iw_handler_get_spy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_get_spy(priv->netdev, info,
+ (union iwreq_data *)data, extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d",
+ netdev->name, data->length);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_thrspy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)",
+ netdev->name, data->length);
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ return ret;
+}
+
+static int at76_iw_handler_get_thrspy(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret;
+
+ spin_lock_bh(&priv->spy_spinlock);
+ ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data,
+ extra);
+ spin_unlock_bh(&priv->spy_spinlock);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)",
+ netdev->name, data->length);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_wap(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name,
+ mac2str(ap_addr->sa_data));
+
+ /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has
+ chosen any or auto AP preference */
+ if (is_broadcast_ether_addr(ap_addr->sa_data)
+ || is_zero_ether_addr(ap_addr->sa_data))
+ priv->wanted_bssid_valid = 0;
+ else {
+ /* user wants to set a preferred AP address */
+ priv->wanted_bssid_valid = 1;
+ memcpy(priv->wanted_bssid, ap_addr->sa_data, ETH_ALEN);
+ }
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_wap(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct sockaddr *ap_addr, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ ap_addr->sa_family = ARPHRD_ETHER;
+ memcpy(ap_addr->sa_data, priv->bssid, ETH_ALEN);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name,
+ mac2str(ap_addr->sa_data));
+
+ return 0;
+}
+
+static int at76_iw_handler_set_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ if (!netif_running(netdev)) {
+ ret = -ENETDOWN;
+ goto exit;
+ }
+
+ /* jal: we don't allow "iwlist ethX scan" while we are
+ in monitor mode */
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ /* Discard old scan results */
+ if ((jiffies - priv->last_scan) > (20 * HZ))
+ priv->scan_state = SCAN_IDLE;
+ priv->last_scan = jiffies;
+
+ /* Initiate a scan command */
+ if (priv->scan_state == SCAN_IN_PROGRESS) {
+ ret = -EBUSY;
+ goto exit;
+ }
+
+ priv->scan_state = SCAN_IN_PROGRESS;
+
+ at76_quiesce(priv);
+
+ /* Try to do passive or active scan if WE asks as. */
+ if (wrqu->data.length
+ && wrqu->data.length == sizeof(struct iw_scan_req)) {
+ struct iw_scan_req *req = (struct iw_scan_req *)extra;
+
+ if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
+ priv->scan_mode = SCAN_TYPE_PASSIVE;
+ else if (req->scan_type == IW_SCAN_TYPE_ACTIVE)
+ priv->scan_mode = SCAN_TYPE_ACTIVE;
+
+ /* Sanity check values? */
+ if (req->min_channel_time > 0)
+ priv->scan_min_time = req->min_channel_time;
+
+ if (req->max_channel_time > 0)
+ priv->scan_max_time = req->max_channel_time;
+ }
+
+ /* change to scanning state */
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+
+exit:
+ mutex_unlock(&priv->mtx);
+ return ret;
+}
+
+static int at76_iw_handler_get_scan(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ unsigned long flags;
+ struct list_head *lptr, *nptr;
+ struct bss_info *curr_bss;
+ struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL);
+ char *curr_val, *curr_pos = extra;
+ int i;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name);
+
+ if (!iwe)
+ return -ENOMEM;
+
+ if (priv->scan_state != SCAN_COMPLETED) {
+ /* scan not yet finished */
+ kfree(iwe);
+ return -EAGAIN;
+ }
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+
+ list_for_each_safe(lptr, nptr, &priv->bss_list) {
+ curr_bss = list_entry(lptr, struct bss_info, list);
+
+ iwe->cmd = SIOCGIWAP;
+ iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
+ memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6);
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_ADDR_LEN);
+
+ iwe->u.data.length = curr_bss->ssid_len;
+ iwe->cmd = SIOCGIWESSID;
+ iwe->u.data.flags = 1;
+
+ curr_pos = iwe_stream_add_point(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ curr_bss->ssid);
+
+ iwe->cmd = SIOCGIWMODE;
+ iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ?
+ IW_MODE_ADHOC :
+ (curr_bss->capa & WLAN_CAPABILITY_ESS) ?
+ IW_MODE_MASTER : IW_MODE_AUTO;
+ /* IW_MODE_AUTO = 0 which I thought is
+ * the most logical value to return in this case */
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_UINT_LEN);
+
+ iwe->cmd = SIOCGIWFREQ;
+ iwe->u.freq.m = curr_bss->channel;
+ iwe->u.freq.e = 0;
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_FREQ_LEN);
+
+ iwe->cmd = SIOCGIWENCODE;
+ if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY)
+ iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+ else
+ iwe->u.data.flags = IW_ENCODE_DISABLED;
+
+ iwe->u.data.length = 0;
+ curr_pos = iwe_stream_add_point(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ NULL);
+
+ /* Add quality statistics */
+ iwe->cmd = IWEVQUAL;
+ iwe->u.qual.noise = 0;
+ iwe->u.qual.updated =
+ IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED;
+ iwe->u.qual.level = (curr_bss->rssi * 100 / 42);
+ if (iwe->u.qual.level > 100)
+ iwe->u.qual.level = 100;
+ if (at76_is_intersil(priv->board_type))
+ iwe->u.qual.qual = curr_bss->link_qual;
+ else {
+ iwe->u.qual.qual = 0;
+ iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID;
+ }
+ /* Add new value to event */
+ curr_pos = iwe_stream_add_event(info, curr_pos,
+ extra + IW_SCAN_MAX_DATA, iwe,
+ IW_EV_QUAL_LEN);
+
+ /* Rate: stuffing multiple values in a single event requires
+ * a bit more of magic - Jean II */
+ curr_val = curr_pos + IW_EV_LCP_LEN;
+
+ iwe->cmd = SIOCGIWRATE;
+ /* Those two flags are ignored... */
+ iwe->u.bitrate.fixed = 0;
+ iwe->u.bitrate.disabled = 0;
+ /* Max 8 values */
+ for (i = 0; i < curr_bss->rates_len; i++) {
+ /* Bit rate given in 500 kb/s units (+ 0x80) */
+ iwe->u.bitrate.value =
+ ((curr_bss->rates[i] & 0x7f) * 500000);
+ /* Add new value to event */
+ curr_val = iwe_stream_add_value(info, curr_pos,
+ curr_val,
+ extra +
+ IW_SCAN_MAX_DATA, iwe,
+ IW_EV_PARAM_LEN);
+ }
+
+ /* Check if we added any event */
+ if ((curr_val - curr_pos) > IW_EV_LCP_LEN)
+ curr_pos = curr_val;
+
+ /* more information may be sent back using IWECUSTOM */
+
+ }
+
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+
+ data->length = (curr_pos - extra);
+ data->flags = 0;
+
+ kfree(iwe);
+ return 0;
+}
+
+static int at76_iw_handler_set_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra);
+
+ if (data->flags) {
+ memcpy(priv->essid, extra, data->length);
+ priv->essid_size = data->length;
+ } else
+ priv->essid_size = 0; /* Use any SSID */
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_essid(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ if (priv->essid_size) {
+ /* not the ANY ssid in priv->essid */
+ data->flags = 1;
+ data->length = priv->essid_size;
+ memcpy(extra, priv->essid, data->length);
+ } else {
+ /* the ANY ssid was specified */
+ if (priv->mac_state == MAC_CONNECTED && priv->curr_bss) {
+ /* report the SSID we have found */
+ data->flags = 1;
+ data->length = priv->curr_bss->ssid_len;
+ memcpy(extra, priv->curr_bss->ssid, data->length);
+ } else {
+ /* report ANY back */
+ data->flags = 0;
+ data->length = 0;
+ }
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %.*s", netdev->name,
+ data->length, extra);
+
+ return 0;
+}
+
+static int at76_iw_handler_set_rate(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *bitrate, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name,
+ bitrate->value);
+
+ switch (bitrate->value) {
+ case -1:
+ priv->txrate = TX_RATE_AUTO;
+ break; /* auto rate */
+ case 1000000:
+ priv->txrate = TX_RATE_1MBIT;
+ break;
+ case 2000000:
+ priv->txrate = TX_RATE_2MBIT;
+ break;
+ case 5500000:
+ priv->txrate = TX_RATE_5_5MBIT;
+ break;
+ case 11000000:
+ priv->txrate = TX_RATE_11MBIT;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+static int at76_iw_handler_get_rate(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *bitrate, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ switch (priv->txrate) {
+ /* return max rate if RATE_AUTO */
+ case TX_RATE_AUTO:
+ bitrate->value = 11000000;
+ break;
+ case TX_RATE_1MBIT:
+ bitrate->value = 1000000;
+ break;
+ case TX_RATE_2MBIT:
+ bitrate->value = 2000000;
+ break;
+ case TX_RATE_5_5MBIT:
+ bitrate->value = 5500000;
+ break;
+ case TX_RATE_11MBIT:
+ bitrate->value = 11000000;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ bitrate->fixed = (priv->txrate != TX_RATE_AUTO);
+ bitrate->disabled = 0;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name,
+ bitrate->value);
+
+ return ret;
+}
+
+static int at76_iw_handler_set_rts(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+ int rthr = rts->value;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s",
+ netdev->name, rts->value, (rts->disabled) ? "true" : "false");
+
+ if (rts->disabled)
+ rthr = MAX_RTS_THRESHOLD;
+
+ if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD))
+ ret = -EINVAL;
+ else
+ priv->rts_threshold = rthr;
+
+ return ret;
+}
+
+static int at76_iw_handler_get_rts(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *rts, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ rts->value = priv->rts_threshold;
+ rts->disabled = (rts->value >= MAX_RTS_THRESHOLD);
+ rts->fixed = 1;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s",
+ netdev->name, rts->value, (rts->disabled) ? "true" : "false");
+
+ return 0;
+}
+
+static int at76_iw_handler_set_frag(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+ int fthr = frag->value;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s",
+ netdev->name, frag->value,
+ (frag->disabled) ? "true" : "false");
+
+ if (frag->disabled)
+ fthr = MAX_FRAG_THRESHOLD;
+
+ if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD))
+ ret = -EINVAL;
+ else
+ priv->frag_threshold = fthr & ~0x1; /* get an even value */
+
+ return ret;
+}
+
+static int at76_iw_handler_get_frag(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *frag, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ frag->value = priv->frag_threshold;
+ frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD);
+ frag->fixed = 1;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s",
+ netdev->name, frag->value,
+ (frag->disabled) ? "true" : "false");
+
+ return 0;
+}
+
+static int at76_iw_handler_get_txpow(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *power, char *extra)
+{
+ power->value = 15;
+ power->fixed = 1; /* No power control */
+ power->disabled = 0;
+ power->flags = IW_TXPOW_DBM;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name,
+ power->value);
+
+ return 0;
+}
+
+/* jal: short retry is handled by the firmware (at least 0.90.x),
+ while long retry is not (?) */
+static int at76_iw_handler_set_retry(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags 0x%x val %d",
+ netdev->name, retry->disabled, retry->flags, retry->value);
+
+ if (!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) {
+ if ((retry->flags & IW_RETRY_MIN) ||
+ !(retry->flags & IW_RETRY_MAX))
+ priv->short_retry_limit = retry->value;
+ else
+ ret = -EINVAL;
+ } else
+ ret = -EINVAL;
+
+ return ret;
+}
+
+/* Adapted (ripped) from atmel.c */
+static int at76_iw_handler_get_retry(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *retry, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name);
+
+ retry->disabled = 0; /* Can't be disabled */
+ retry->flags = IW_RETRY_LIMIT;
+ retry->value = priv->short_retry_limit;
+
+ return 0;
+}
+
+static int at76_iw_handler_set_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *encoding, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
+ int len = encoding->length;
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x "
+ "pointer %p len %d", netdev->name, encoding->flags,
+ encoding->pointer, encoding->length);
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d "
+ "auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id,
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ /* take the old default key if index is invalid */
+ if ((index < 0) || (index >= WEP_KEYS))
+ index = priv->wep_key_id;
+
+ if (len > 0) {
+ if (len > WEP_LARGE_KEY_LEN)
+ len = WEP_LARGE_KEY_LEN;
+
+ memset(priv->wep_keys[index], 0, WEP_KEY_LEN);
+ memcpy(priv->wep_keys[index], extra, len);
+ priv->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ?
+ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
+ priv->wep_enabled = 1;
+ }
+
+ priv->wep_key_id = index;
+ priv->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0);
+
+ if (encoding->flags & IW_ENCODE_RESTRICTED)
+ priv->auth_mode = WLAN_AUTH_SHARED_KEY;
+ if (encoding->flags & IW_ENCODE_OPEN)
+ priv->auth_mode = WLAN_AUTH_OPEN;
+
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d "
+ "key_len %d auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
+ priv->wep_keys_len[priv->wep_key_id],
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ return -EIWCOMMIT;
+}
+
+static int at76_iw_handler_get_encode(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *encoding, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
+
+ if ((index < 0) || (index >= WEP_KEYS))
+ index = priv->wep_key_id;
+
+ encoding->flags =
+ (priv->auth_mode == WLAN_AUTH_SHARED_KEY) ?
+ IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
+
+ if (!priv->wep_enabled)
+ encoding->flags |= IW_ENCODE_DISABLED;
+
+ if (encoding->pointer) {
+ encoding->length = priv->wep_keys_len[index];
+
+ memcpy(extra, priv->wep_keys[index], priv->wep_keys_len[index]);
+
+ encoding->flags |= (index + 1);
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x "
+ "pointer %p len %d", netdev->name, encoding->flags,
+ encoding->pointer, encoding->length);
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d "
+ "key_len %d auth_mode %s", netdev->name,
+ (priv->wep_enabled) ? "true" : "false", priv->wep_key_id + 1,
+ priv->wep_keys_len[priv->wep_key_id],
+ (priv->auth_mode ==
+ WLAN_AUTH_SHARED_KEY) ? "restricted" : "open");
+
+ return 0;
+}
+
+static int at76_iw_handler_set_power(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *prq, char *extra)
+{
+ int err = -EIWCOMMIT;
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_IOCTL,
+ "%s: SIOCSIWPOWER - disabled %s flags 0x%x value 0x%x",
+ netdev->name, (prq->disabled) ? "true" : "false", prq->flags,
+ prq->value);
+
+ if (prq->disabled)
+ priv->pm_mode = AT76_PM_OFF;
+ else {
+ switch (prq->flags & IW_POWER_MODE) {
+ case IW_POWER_ALL_R:
+ case IW_POWER_ON:
+ break;
+ default:
+ err = -EINVAL;
+ goto exit;
+ }
+ if (prq->flags & IW_POWER_PERIOD)
+ priv->pm_period = prq->value;
+
+ if (prq->flags & IW_POWER_TIMEOUT) {
+ err = -EINVAL;
+ goto exit;
+ }
+ priv->pm_mode = AT76_PM_ON;
+ }
+exit:
+ return err;
+}
+
+static int at76_iw_handler_get_power(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_param *power, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ power->disabled = (priv->pm_mode == AT76_PM_OFF);
+ if (!power->disabled) {
+ power->flags = IW_POWER_PERIOD | IW_POWER_ALL_R;
+ power->value = priv->pm_period;
+ }
+
+ at76_dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - %s flags 0x%x value 0x%x",
+ netdev->name, power->disabled ? "disabled" : "enabled",
+ power->flags, power->value);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Private IOCTLS
+ */
+static int at76_iw_set_short_preamble(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SHORT_PREAMBLE, %d",
+ netdev->name, val);
+
+ if (val < PREAMBLE_TYPE_LONG || val > PREAMBLE_TYPE_AUTO)
+ ret = -EINVAL;
+ else
+ priv->preamble_type = val;
+
+ return ret;
+}
+
+static int at76_iw_get_short_preamble(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ snprintf(wrqu->name, sizeof(wrqu->name), "%s (%d)",
+ preambles[priv->preamble_type], priv->preamble_type);
+ return 0;
+}
+
+static int at76_iw_set_debug(struct net_device *netdev,
+ struct iw_request_info *info,
+ struct iw_point *data, char *extra)
+{
+ char *ptr;
+ u32 val;
+
+ if (data->length > 0) {
+ val = simple_strtol(extra, &ptr, 0);
+
+ if (ptr == extra)
+ val = DBG_DEFAULTS;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG input %d: %s -> 0x%x",
+ netdev->name, data->length, extra, val);
+ } else
+ val = DBG_DEFAULTS;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_DEBUG, old 0x%x, new 0x%x",
+ netdev->name, at76_debug, val);
+
+ /* jal: some more output to pin down lockups */
+ at76_dbg(DBG_IOCTL, "%s: netif running %d queue_stopped %d "
+ "carrier_ok %d", netdev->name, netif_running(netdev),
+ netif_queue_stopped(netdev), netif_carrier_ok(netdev));
+
+ at76_debug = val;
+
+ return 0;
+}
+
+static int at76_iw_get_debug(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ snprintf(wrqu->name, sizeof(wrqu->name), "0x%08x", at76_debug);
+ return 0;
+}
+
+static int at76_iw_set_powersave_mode(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_POWERSAVE_MODE, %d (%s)",
+ netdev->name, val,
+ val == AT76_PM_OFF ? "active" : val == AT76_PM_ON ? "save" :
+ val == AT76_PM_SMART ? "smart save" : "<invalid>");
+ if (val < AT76_PM_OFF || val > AT76_PM_SMART)
+ ret = -EINVAL;
+ else
+ priv->pm_mode = val;
+
+ return ret;
+}
+
+static int at76_iw_get_powersave_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->pm_mode;
+ return 0;
+}
+
+static int at76_iw_set_scan_times(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int mint = *((int *)name);
+ int maxt = *((int *)name + 1);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_TIMES - min %d max %d",
+ netdev->name, mint, maxt);
+ if (mint <= 0 || maxt <= 0 || mint > maxt)
+ ret = -EINVAL;
+ else {
+ priv->scan_min_time = mint;
+ priv->scan_max_time = maxt;
+ }
+
+ return ret;
+}
+
+static int at76_iw_get_scan_times(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->scan_min_time;
+ param[1] = priv->scan_max_time;
+ return 0;
+}
+
+static int at76_iw_set_scan_mode(struct net_device *netdev,
+ struct iw_request_info *info, char *name,
+ char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int val = *((int *)name);
+ int ret = -EIWCOMMIT;
+
+ at76_dbg(DBG_IOCTL, "%s: AT76_SET_SCAN_MODE - mode %s",
+ netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" :
+ (val = SCAN_TYPE_PASSIVE) ? "passive" : "<invalid>");
+
+ if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE)
+ ret = -EINVAL;
+ else
+ priv->scan_mode = val;
+
+ return ret;
+}
+
+static int at76_iw_get_scan_mode(struct net_device *netdev,
+ struct iw_request_info *info,
+ union iwreq_data *wrqu, char *extra)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int *param = (int *)extra;
+
+ param[0] = priv->scan_mode;
+ return 0;
+}
+
+#define AT76_SET_HANDLER(h, f) [h - SIOCIWFIRST] = (iw_handler) f
+
+/* Standard wireless handlers */
+static const iw_handler at76_handlers[] = {
+ AT76_SET_HANDLER(SIOCSIWCOMMIT, at76_iw_handler_commit),
+ AT76_SET_HANDLER(SIOCGIWNAME, at76_iw_handler_get_name),
+ AT76_SET_HANDLER(SIOCSIWFREQ, at76_iw_handler_set_freq),
+ AT76_SET_HANDLER(SIOCGIWFREQ, at76_iw_handler_get_freq),
+ AT76_SET_HANDLER(SIOCSIWMODE, at76_iw_handler_set_mode),
+ AT76_SET_HANDLER(SIOCGIWMODE, at76_iw_handler_get_mode),
+ AT76_SET_HANDLER(SIOCGIWRANGE, at76_iw_handler_get_range),
+ AT76_SET_HANDLER(SIOCSIWSPY, at76_iw_handler_set_spy),
+ AT76_SET_HANDLER(SIOCGIWSPY, at76_iw_handler_get_spy),
+ AT76_SET_HANDLER(SIOCSIWTHRSPY, at76_iw_handler_set_thrspy),
+ AT76_SET_HANDLER(SIOCGIWTHRSPY, at76_iw_handler_get_thrspy),
+ AT76_SET_HANDLER(SIOCSIWAP, at76_iw_handler_set_wap),
+ AT76_SET_HANDLER(SIOCGIWAP, at76_iw_handler_get_wap),
+ AT76_SET_HANDLER(SIOCSIWSCAN, at76_iw_handler_set_scan),
+ AT76_SET_HANDLER(SIOCGIWSCAN, at76_iw_handler_get_scan),
+ AT76_SET_HANDLER(SIOCSIWESSID, at76_iw_handler_set_essid),
+ AT76_SET_HANDLER(SIOCGIWESSID, at76_iw_handler_get_essid),
+ AT76_SET_HANDLER(SIOCSIWRATE, at76_iw_handler_set_rate),
+ AT76_SET_HANDLER(SIOCGIWRATE, at76_iw_handler_get_rate),
+ AT76_SET_HANDLER(SIOCSIWRTS, at76_iw_handler_set_rts),
+ AT76_SET_HANDLER(SIOCGIWRTS, at76_iw_handler_get_rts),
+ AT76_SET_HANDLER(SIOCSIWFRAG, at76_iw_handler_set_frag),
+ AT76_SET_HANDLER(SIOCGIWFRAG, at76_iw_handler_get_frag),
+ AT76_SET_HANDLER(SIOCGIWTXPOW, at76_iw_handler_get_txpow),
+ AT76_SET_HANDLER(SIOCSIWRETRY, at76_iw_handler_set_retry),
+ AT76_SET_HANDLER(SIOCGIWRETRY, at76_iw_handler_get_retry),
+ AT76_SET_HANDLER(SIOCSIWENCODE, at76_iw_handler_set_encode),
+ AT76_SET_HANDLER(SIOCGIWENCODE, at76_iw_handler_get_encode),
+ AT76_SET_HANDLER(SIOCSIWPOWER, at76_iw_handler_set_power),
+ AT76_SET_HANDLER(SIOCGIWPOWER, at76_iw_handler_get_power)
+};
+
+#define AT76_SET_PRIV(h, f) [h - SIOCIWFIRSTPRIV] = (iw_handler) f
+
+/* Private wireless handlers */
+static const iw_handler at76_priv_handlers[] = {
+ AT76_SET_PRIV(AT76_SET_SHORT_PREAMBLE, at76_iw_set_short_preamble),
+ AT76_SET_PRIV(AT76_GET_SHORT_PREAMBLE, at76_iw_get_short_preamble),
+ AT76_SET_PRIV(AT76_SET_DEBUG, at76_iw_set_debug),
+ AT76_SET_PRIV(AT76_GET_DEBUG, at76_iw_get_debug),
+ AT76_SET_PRIV(AT76_SET_POWERSAVE_MODE, at76_iw_set_powersave_mode),
+ AT76_SET_PRIV(AT76_GET_POWERSAVE_MODE, at76_iw_get_powersave_mode),
+ AT76_SET_PRIV(AT76_SET_SCAN_TIMES, at76_iw_set_scan_times),
+ AT76_SET_PRIV(AT76_GET_SCAN_TIMES, at76_iw_get_scan_times),
+ AT76_SET_PRIV(AT76_SET_SCAN_MODE, at76_iw_set_scan_mode),
+ AT76_SET_PRIV(AT76_GET_SCAN_MODE, at76_iw_get_scan_mode),
+};
+
+/* Names and arguments of private wireless handlers */
+static const struct iw_priv_args at76_priv_args[] = {
+ /* 0 - long, 1 - short */
+ {AT76_SET_SHORT_PREAMBLE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_preamble"},
+
+ {AT76_GET_SHORT_PREAMBLE,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_preamble"},
+
+ /* we must pass the new debug mask as a string, because iwpriv cannot
+ * parse hex numbers starting with 0x :-( */
+ {AT76_SET_DEBUG,
+ IW_PRIV_TYPE_CHAR | 10, 0, "set_debug"},
+
+ {AT76_GET_DEBUG,
+ 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 10, "get_debug"},
+
+ /* 1 - active, 2 - power save, 3 - smart power save */
+ {AT76_SET_POWERSAVE_MODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_powersave"},
+
+ {AT76_GET_POWERSAVE_MODE,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_powersave"},
+
+ /* min_channel_time, max_channel_time */
+ {AT76_SET_SCAN_TIMES,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "set_scan_times"},
+
+ {AT76_GET_SCAN_TIMES,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, "get_scan_times"},
+
+ /* 0 - active, 1 - passive scan */
+ {AT76_SET_SCAN_MODE,
+ IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_scan_mode"},
+
+ {AT76_GET_SCAN_MODE,
+ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_scan_mode"},
+};
+
+static const struct iw_handler_def at76_handler_def = {
+ .num_standard = ARRAY_SIZE(at76_handlers),
+ .num_private = ARRAY_SIZE(at76_priv_handlers),
+ .num_private_args = ARRAY_SIZE(at76_priv_args),
+ .standard = at76_handlers,
+ .private = at76_priv_handlers,
+ .private_args = at76_priv_args,
+ .get_wireless_stats = at76_get_wireless_stats,
+};
+
+static const u8 snapsig[] = { 0xaa, 0xaa, 0x03 };
+
+/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with
+ * a SNAP OID of 0 (0x00, 0x00, 0x00) */
+static const u8 rfc1042sig[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
+
+static int at76_tx(struct sk_buff *skb, struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ struct net_device_stats *stats = &priv->stats;
+ int ret = 0;
+ int wlen;
+ int submit_len;
+ struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
+ struct ieee80211_hdr_3addr *i802_11_hdr =
+ (struct ieee80211_hdr_3addr *)tx_buffer->packet;
+ u8 *payload = i802_11_hdr->payload;
+ struct ethhdr *eh = (struct ethhdr *)skb->data;
+
+ if (netif_queue_stopped(netdev)) {
+ printk(KERN_ERR "%s: %s called while netdev is stopped\n",
+ netdev->name, __func__);
+ /* skip this packet */
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ if (priv->tx_urb->status == -EINPROGRESS) {
+ printk(KERN_ERR "%s: %s called while tx urb is pending\n",
+ netdev->name, __func__);
+ /* skip this packet */
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ if (skb->len < ETH_HLEN) {
+ printk(KERN_ERR "%s: %s: skb too short (%d)\n",
+ netdev->name, __func__, skb->len);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
+
+ /* we can get rid of memcpy if we set netdev->hard_header_len to
+ reserve enough space, but we would need to keep the skb around */
+
+ if (ntohs(eh->h_proto) <= ETH_DATA_LEN) {
+ /* this is a 802.3 packet */
+ if (skb->len >= ETH_HLEN + sizeof(rfc1042sig)
+ && skb->data[ETH_HLEN] == rfc1042sig[0]
+ && skb->data[ETH_HLEN + 1] == rfc1042sig[1]) {
+ /* higher layer delivered SNAP header - keep it */
+ memcpy(payload, skb->data + ETH_HLEN,
+ skb->len - ETH_HLEN);
+ wlen = IEEE80211_3ADDR_LEN + skb->len - ETH_HLEN;
+ } else {
+ printk(KERN_ERR "%s: dropping non-SNAP 802.2 packet "
+ "(DSAP 0x%02x SSAP 0x%02x cntrl 0x%02x)\n",
+ priv->netdev->name, skb->data[ETH_HLEN],
+ skb->data[ETH_HLEN + 1],
+ skb->data[ETH_HLEN + 2]);
+ dev_kfree_skb(skb);
+ return 0;
+ }
+ } else {
+ /* add RFC 1042 header in front */
+ memcpy(payload, rfc1042sig, sizeof(rfc1042sig));
+ memcpy(payload + sizeof(rfc1042sig), &eh->h_proto,
+ skb->len - offsetof(struct ethhdr, h_proto));
+ wlen = IEEE80211_3ADDR_LEN + sizeof(rfc1042sig) + skb->len -
+ offsetof(struct ethhdr, h_proto);
+ }
+
+ /* make wireless header */
+ i802_11_hdr->frame_ctl =
+ cpu_to_le16(IEEE80211_FTYPE_DATA |
+ (priv->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) |
+ (priv->iw_mode ==
+ IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0));
+
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ memcpy(i802_11_hdr->addr1, eh->h_dest, ETH_ALEN);
+ memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
+ memcpy(i802_11_hdr->addr3, priv->bssid, ETH_ALEN);
+ } else if (priv->iw_mode == IW_MODE_INFRA) {
+ memcpy(i802_11_hdr->addr1, priv->bssid, ETH_ALEN);
+ memcpy(i802_11_hdr->addr2, eh->h_source, ETH_ALEN);
+ memcpy(i802_11_hdr->addr3, eh->h_dest, ETH_ALEN);
+ }
+
+ i802_11_hdr->duration_id = cpu_to_le16(0);
+ i802_11_hdr->seq_ctl = cpu_to_le16(0);
+
+ /* setup 'Atmel' header */
+ tx_buffer->wlength = cpu_to_le16(wlen);
+ tx_buffer->tx_rate = priv->txrate;
+ /* for broadcast destination addresses, the firmware 0.100.x
+ seems to choose the highest rate set with CMD_STARTUP in
+ basic_rate_set replacing this value */
+
+ memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved));
+
+ tx_buffer->padding = at76_calc_padding(wlen);
+ submit_len = wlen + AT76_TX_HDRLEN + tx_buffer->padding;
+
+ at76_dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", priv->netdev->name,
+ hex2str(skb->data, 32));
+ at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr %s",
+ priv->netdev->name,
+ le16_to_cpu(tx_buffer->wlength),
+ tx_buffer->padding, tx_buffer->tx_rate,
+ hex2str(i802_11_hdr, sizeof(*i802_11_hdr)));
+ at76_dbg(DBG_TX_DATA_CONTENT, "%s payload %s", priv->netdev->name,
+ hex2str(payload, 48));
+
+ /* send stuff */
+ netif_stop_queue(netdev);
+ netdev->trans_start = jiffies;
+
+ usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
+ submit_len, at76_tx_callback, priv);
+ ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
+ if (ret) {
+ stats->tx_errors++;
+ printk(KERN_ERR "%s: error in tx submit urb: %d\n",
+ netdev->name, ret);
+ if (ret == -EINVAL)
+ printk(KERN_ERR
+ "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
+ priv->netdev->name, priv->tx_urb,
+ priv->tx_urb->hcpriv, priv->tx_urb->complete);
+ } else {
+ stats->tx_bytes += skb->len;
+ dev_kfree_skb(skb);
+ }
+
+ return ret;
+}
+
+static void at76_tx_timeout(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ if (!priv)
+ return;
+ dev_warn(&netdev->dev, "tx timeout.");
+
+ usb_unlink_urb(priv->tx_urb);
+ priv->stats.tx_errors++;
+}
+
static int at76_submit_rx_urb(struct at76_priv *priv)
{
int ret;
@@ -1327,7 +3270,7 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
if (!priv->rx_urb) {
printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
- wiphy_name(priv->hw->wiphy), __func__);
+ priv->netdev->name, __func__);
return -EFAULT;
}
@@ -1335,7 +3278,7 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
if (!skb) {
printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
- wiphy_name(priv->hw->wiphy));
+ priv->netdev->name);
ret = -ENOMEM;
goto exit;
}
@@ -1355,18 +3298,110 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
"usb_submit_urb returned -ENODEV");
else
printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
}
exit:
if (ret < 0 && ret != -ENODEV)
printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
"driver and/or power cycle the device\n",
- wiphy_name(priv->hw->wiphy));
+ priv->netdev->name);
return ret;
}
+static int at76_open(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ int ret = 0;
+
+ at76_dbg(DBG_PROC_ENTRY, "%s(): entry", __func__);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ /* if netdev->dev_addr != priv->mac_addr we must
+ set the mac address in the device ! */
+ if (compare_ether_addr(netdev->dev_addr, priv->mac_addr)) {
+ if (at76_add_mac_address(priv, netdev->dev_addr) >= 0)
+ at76_dbg(DBG_PROGRESS, "%s: set new MAC addr %s",
+ netdev->name, mac2str(netdev->dev_addr));
+ }
+
+ priv->scan_state = SCAN_IDLE;
+ priv->last_scan = jiffies;
+
+ ret = at76_submit_rx_urb(priv);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
+ netdev->name, ret);
+ goto error;
+ }
+
+ schedule_delayed_work(&priv->dwork_restart, 0);
+
+ at76_dbg(DBG_PROC_ENTRY, "%s(): end", __func__);
+error:
+ mutex_unlock(&priv->mtx);
+ return ret < 0 ? ret : 0;
+}
+
+static int at76_stop(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ at76_dbg(DBG_DEVSTART, "%s: ENTER", __func__);
+
+ if (mutex_lock_interruptible(&priv->mtx))
+ return -EINTR;
+
+ at76_quiesce(priv);
+
+ if (!priv->device_unplugged) {
+ /* We are called by "ifconfig ethX down", not because the
+ * device is not available anymore. */
+ at76_set_radio(priv, 0);
+
+ /* We unlink rx_urb because at76_open() re-submits it.
+ * If unplugged, at76_delete_device() takes care of it. */
+ usb_kill_urb(priv->rx_urb);
+ }
+
+ /* free the bss_list */
+ at76_free_bss_list(priv);
+
+ mutex_unlock(&priv->mtx);
+ at76_dbg(DBG_DEVSTART, "%s: EXIT", __func__);
+
+ return 0;
+}
+
+static void at76_ethtool_get_drvinfo(struct net_device *netdev,
+ struct ethtool_drvinfo *info)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+
+ strncpy(info->driver, DRIVER_NAME, sizeof(info->driver));
+ strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
+
+ usb_make_path(priv->udev, info->bus_info, sizeof(info->bus_info));
+
+ snprintf(info->fw_version, sizeof(info->fw_version), "%d.%d.%d-%d",
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+}
+
+static u32 at76_ethtool_get_link(struct net_device *netdev)
+{
+ struct at76_priv *priv = netdev_priv(netdev);
+ return priv->mac_state == MAC_CONNECTED;
+}
+
+static struct ethtool_ops at76_ethtool_ops = {
+ .get_drvinfo = at76_ethtool_get_drvinfo,
+ .get_link = at76_ethtool_get_link,
+};
+
/* Download external firmware */
static int at76_load_external_fw(struct usb_device *udev, struct fwentry *fwe)
{
@@ -1463,6 +3498,406 @@ exit:
return ret;
}
+static int at76_match_essid(struct at76_priv *priv, struct bss_info *ptr)
+{
+ /* common criteria for both modi */
+
+ int ret = (priv->essid_size == 0 /* ANY ssid */ ||
+ (priv->essid_size == ptr->ssid_len &&
+ !memcmp(priv->essid, ptr->ssid, ptr->ssid_len)));
+ if (!ret)
+ at76_dbg(DBG_BSS_MATCH,
+ "%s bss table entry %p: essid didn't match",
+ priv->netdev->name, ptr);
+ return ret;
+}
+
+static inline int at76_match_mode(struct at76_priv *priv, struct bss_info *ptr)
+{
+ int ret;
+
+ if (priv->iw_mode == IW_MODE_ADHOC)
+ ret = ptr->capa & WLAN_CAPABILITY_IBSS;
+ else
+ ret = ptr->capa & WLAN_CAPABILITY_ESS;
+ if (!ret)
+ at76_dbg(DBG_BSS_MATCH,
+ "%s bss table entry %p: mode didn't match",
+ priv->netdev->name, ptr);
+ return ret;
+}
+
+static int at76_match_rates(struct at76_priv *priv, struct bss_info *ptr)
+{
+ int i;
+
+ for (i = 0; i < ptr->rates_len; i++) {
+ u8 rate = ptr->rates[i];
+
+ if (!(rate & 0x80))
+ continue;
+
+ /* this is a basic rate we have to support
+ (see IEEE802.11, ch. 7.3.2.2) */
+ if (rate != (0x80 | hw_rates[0])
+ && rate != (0x80 | hw_rates[1])
+ && rate != (0x80 | hw_rates[2])
+ && rate != (0x80 | hw_rates[3])) {
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: bss table entry %p: basic rate %02x not "
+ "supported", priv->netdev->name, ptr, rate);
+ return 0;
+ }
+ }
+
+ /* if we use short preamble, the bss must support it */
+ if (priv->preamble_type == PREAMBLE_TYPE_SHORT &&
+ !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: %p does not support short preamble",
+ priv->netdev->name, ptr);
+ return 0;
+ } else
+ return 1;
+}
+
+static inline int at76_match_wep(struct at76_priv *priv, struct bss_info *ptr)
+{
+ if (!priv->wep_enabled && ptr->capa & WLAN_CAPABILITY_PRIVACY) {
+ /* we have disabled WEP, but the BSS signals privacy */
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: bss table entry %p: requires encryption",
+ priv->netdev->name, ptr);
+ return 0;
+ }
+ /* otherwise if the BSS does not signal privacy it may well
+ accept encrypted packets from us ... */
+ return 1;
+}
+
+static inline int at76_match_bssid(struct at76_priv *priv, struct bss_info *ptr)
+{
+ if (!priv->wanted_bssid_valid ||
+ !compare_ether_addr(ptr->bssid, priv->wanted_bssid))
+ return 1;
+
+ at76_dbg(DBG_BSS_MATCH,
+ "%s: requested bssid - %s does not match",
+ priv->netdev->name, mac2str(priv->wanted_bssid));
+ at76_dbg(DBG_BSS_MATCH,
+ " AP bssid - %s of bss table entry %p",
+ mac2str(ptr->bssid), ptr);
+ return 0;
+}
+
+/**
+ * at76_match_bss - try to find a matching bss in priv->bss
+ *
+ * last - last bss tried
+ *
+ * last == NULL signals a new round starting with priv->bss_list.next
+ * this function must be called inside an acquired priv->bss_list_spinlock
+ * otherwise the timeout on bss may remove the newly chosen entry
+ */
+static struct bss_info *at76_match_bss(struct at76_priv *priv,
+ struct bss_info *last)
+{
+ struct bss_info *ptr = NULL;
+ struct list_head *curr;
+
+ curr = last ? last->list.next : priv->bss_list.next;
+ while (curr != &priv->bss_list) {
+ ptr = list_entry(curr, struct bss_info, list);
+ if (at76_match_essid(priv, ptr) && at76_match_mode(priv, ptr)
+ && at76_match_wep(priv, ptr) && at76_match_rates(priv, ptr)
+ && at76_match_bssid(priv, ptr))
+ break;
+ curr = curr->next;
+ }
+
+ if (curr == &priv->bss_list)
+ ptr = NULL;
+ /* otherwise ptr points to the struct bss_info we have chosen */
+
+ at76_dbg(DBG_BSS_TABLE, "%s %s: returned %p", priv->netdev->name,
+ __func__, ptr);
+ return ptr;
+}
+
+/* Start joining a matching BSS, or create own IBSS */
+static void at76_work_join(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_join);
+ int ret;
+ unsigned long flags;
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_JOINING);
+ if (priv->mac_state != MAC_JOINING)
+ goto exit;
+
+ /* secure the access to priv->curr_bss ! */
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+ priv->curr_bss = at76_match_bss(priv, priv->curr_bss);
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
+
+ if (!priv->curr_bss) {
+ /* here we haven't found a matching (i)bss ... */
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ at76_set_mac_state(priv, MAC_OWN_IBSS);
+ at76_start_ibss(priv);
+ goto exit;
+ }
+ /* haven't found a matching BSS in infra mode - try again */
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+ goto exit;
+ }
+
+ ret = at76_join_bss(priv, priv->curr_bss);
+ if (ret < 0) {
+ printk(KERN_ERR "%s: join_bss failed with %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ ret = at76_wait_completion(priv, CMD_JOIN);
+ if (ret != CMD_STATUS_COMPLETE) {
+ if (ret != CMD_STATUS_TIME_OUT)
+ printk(KERN_ERR "%s: join_bss completed with %d\n",
+ priv->netdev->name, ret);
+ else
+ printk(KERN_INFO "%s: join_bss ssid %s timed out\n",
+ priv->netdev->name,
+ mac2str(priv->curr_bss->bssid));
+
+ /* retry next BSS immediately */
+ schedule_work(&priv->work_join);
+ goto exit;
+ }
+
+ /* here we have joined the (I)BSS */
+ if (priv->iw_mode == IW_MODE_ADHOC) {
+ struct bss_info *bptr = priv->curr_bss;
+ at76_set_mac_state(priv, MAC_CONNECTED);
+ /* get ESSID, BSSID and channel for priv->curr_bss */
+ priv->essid_size = bptr->ssid_len;
+ memcpy(priv->essid, bptr->ssid, bptr->ssid_len);
+ memcpy(priv->bssid, bptr->bssid, ETH_ALEN);
+ priv->channel = bptr->channel;
+ at76_iwevent_bss_connect(priv->netdev, bptr->bssid);
+ netif_carrier_on(priv->netdev);
+ netif_start_queue(priv->netdev);
+ /* just to be sure */
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ } else {
+ /* send auth req */
+ priv->retries = AUTH_RETRIES;
+ at76_set_mac_state(priv, MAC_AUTH);
+ at76_auth_req(priv, priv->curr_bss, 1, NULL);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Reap scan results */
+static void at76_dwork_get_scan(struct work_struct *work)
+{
+ int status;
+ int ret;
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_get_scan.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_SCANNING);
+ if (priv->mac_state != MAC_SCANNING)
+ goto exit;
+
+ status = at76_get_cmd_status(priv->udev, CMD_SCAN);
+ if (status < 0) {
+ printk(KERN_ERR "%s: %s: at76_get_cmd_status failed with %d\n",
+ priv->netdev->name, __func__, status);
+ status = CMD_STATUS_IN_PROGRESS;
+ /* INFO: Hope it was a one off error - if not, scanning
+ further down the line and stop this cycle */
+ }
+ at76_dbg(DBG_PROGRESS,
+ "%s %s: got cmd_status %d (state %s, need_any %d)",
+ priv->netdev->name, __func__, status,
+ mac_states[priv->mac_state], priv->scan_need_any);
+
+ if (status != CMD_STATUS_COMPLETE) {
+ if ((status != CMD_STATUS_IN_PROGRESS) &&
+ (status != CMD_STATUS_IDLE))
+ printk(KERN_ERR "%s: %s: Bad scan status: %s\n",
+ priv->netdev->name, __func__,
+ at76_get_cmd_status_string(status));
+
+ /* the first cmd status after scan start is always a IDLE ->
+ start the timer to poll again until COMPLETED */
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks",
+ __func__, __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ goto exit;
+ }
+
+ if (at76_debug & DBG_BSS_TABLE)
+ at76_dump_bss_table(priv);
+
+ if (priv->scan_need_any) {
+ ret = at76_start_scan(priv, 0);
+ if (ret < 0)
+ printk(KERN_ERR
+ "%s: %s: start_scan (ANY) failed with %d\n",
+ priv->netdev->name, __func__, ret);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks", __func__,
+ __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ priv->scan_need_any = 0;
+ } else {
+ priv->scan_state = SCAN_COMPLETED;
+ /* report the end of scan to user space */
+ at76_iwevent_scan_complete(priv->netdev);
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle loss of beacons from the AP */
+static void at76_dwork_beacon(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_beacon.work);
+
+ mutex_lock(&priv->mtx);
+ if (priv->mac_state != MAC_CONNECTED || priv->iw_mode != IW_MODE_INFRA)
+ goto exit;
+
+ /* We haven't received any beacons from out AP for BEACON_TIMEOUT */
+ printk(KERN_INFO "%s: lost beacon bssid %s\n",
+ priv->netdev->name, mac2str(priv->curr_bss->bssid));
+
+ netif_carrier_off(priv->netdev);
+ netif_stop_queue(priv->netdev);
+ at76_iwevent_bss_disconnect(priv->netdev);
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle authentication response timeout */
+static void at76_dwork_auth(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_auth.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_AUTH);
+ if (priv->mac_state != MAC_AUTH)
+ goto exit;
+
+ at76_dbg(DBG_PROGRESS, "%s: authentication response timeout",
+ priv->netdev->name);
+
+ if (priv->retries-- >= 0) {
+ at76_auth_req(priv, priv->curr_bss, 1, NULL);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
+ __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+ } else {
+ /* try to get next matching BSS */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Handle association response timeout */
+static void at76_dwork_assoc(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_assoc.work);
+
+ mutex_lock(&priv->mtx);
+ WARN_ON(priv->mac_state != MAC_ASSOC);
+ if (priv->mac_state != MAC_ASSOC)
+ goto exit;
+
+ at76_dbg(DBG_PROGRESS, "%s: association response timeout",
+ priv->netdev->name);
+
+ if (priv->retries-- >= 0) {
+ at76_assoc_req(priv, priv->curr_bss);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
+ __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
+ } else {
+ /* try to get next matching BSS */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
+/* Read new bssid in ad-hoc mode */
+static void at76_work_new_bss(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_new_bss);
+ int ret;
+ struct mib_mac_mgmt mac_mgmt;
+
+ mutex_lock(&priv->mtx);
+
+ ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, &mac_mgmt,
+ sizeof(struct mib_mac_mgmt));
+ if (ret < 0) {
+ printk(KERN_ERR "%s: at76_get_mib failed: %d\n",
+ priv->netdev->name, ret);
+ goto exit;
+ }
+
+ at76_dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt.ibss_change);
+ memcpy(priv->bssid, mac_mgmt.current_bssid, ETH_ALEN);
+ at76_dbg(DBG_PROGRESS, "using BSSID %s", mac2str(priv->bssid));
+
+ at76_iwevent_bss_connect(priv->netdev, priv->bssid);
+
+ priv->mib_buf.type = MIB_MAC_MGMT;
+ priv->mib_buf.size = 1;
+ priv->mib_buf.index = offsetof(struct mib_mac_mgmt, ibss_change);
+ priv->mib_buf.data.byte = 0;
+
+ ret = at76_set_mib(priv, &priv->mib_buf);
+ if (ret < 0)
+ printk(KERN_ERR "%s: set_mib (ibss change ok) failed: %d\n",
+ priv->netdev->name, ret);
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
static int at76_startup_device(struct at76_priv *priv)
{
struct at76_card_config *ccfg = &priv->card_config;
@@ -1470,14 +3905,14 @@ static int at76_startup_device(struct at76_priv *priv)
at76_dbg(DBG_PARAMS,
"%s param: ssid %.*s (%s) mode %s ch %d wep %s key %d "
- "keylen %d", wiphy_name(priv->hw->wiphy), priv->essid_size,
- priv->essid, hex2str(priv->essid, IW_ESSID_MAX_SIZE),
+ "keylen %d", priv->netdev->name, priv->essid_size, priv->essid,
+ hex2str(priv->essid, IW_ESSID_MAX_SIZE),
priv->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
priv->channel, priv->wep_enabled ? "enabled" : "disabled",
priv->wep_key_id, priv->wep_keys_len[priv->wep_key_id]);
at76_dbg(DBG_PARAMS,
"%s param: preamble %s rts %d retry %d frag %d "
- "txrate %s auth_mode %d", wiphy_name(priv->hw->wiphy),
+ "txrate %s auth_mode %d", priv->netdev->name,
preambles[priv->preamble_type], priv->rts_threshold,
priv->short_retry_limit, priv->frag_threshold,
priv->txrate == TX_RATE_1MBIT ? "1MBit" : priv->txrate ==
@@ -1488,7 +3923,7 @@ static int at76_startup_device(struct at76_priv *priv)
at76_dbg(DBG_PARAMS,
"%s param: pm_mode %d pm_period %d auth_mode %s "
"scan_times %d %d scan_mode %s",
- wiphy_name(priv->hw->wiphy), priv->pm_mode, priv->pm_period,
+ priv->netdev->name, priv->pm_mode, priv->pm_period,
priv->auth_mode == WLAN_AUTH_OPEN ? "open" : "shared_secret",
priv->scan_min_time, priv->scan_max_time,
priv->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive");
@@ -1522,8 +3957,7 @@ static int at76_startup_device(struct at76_priv *priv)
ccfg->ssid_len = priv->essid_size;
ccfg->wep_default_key_id = priv->wep_key_id;
- memcpy(ccfg->wep_default_key_value, priv->wep_keys,
- sizeof(priv->wep_keys));
+ memcpy(ccfg->wep_default_key_value, priv->wep_keys, 4 * WEP_KEY_LEN);
ccfg->short_preamble = priv->preamble_type;
ccfg->beacon_period = cpu_to_le16(priv->beacon_period);
@@ -1532,7 +3966,7 @@ static int at76_startup_device(struct at76_priv *priv)
sizeof(struct at76_card_config));
if (ret < 0) {
printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
return ret;
}
@@ -1578,6 +4012,69 @@ static int at76_startup_device(struct at76_priv *priv)
return 0;
}
+/* Restart the interface */
+static void at76_dwork_restart(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ dwork_restart.work);
+
+ mutex_lock(&priv->mtx);
+
+ netif_carrier_off(priv->netdev); /* stop netdev watchdog */
+ netif_stop_queue(priv->netdev); /* stop tx data packets */
+
+ at76_startup_device(priv);
+
+ if (priv->iw_mode != IW_MODE_MONITOR) {
+ priv->netdev->type = ARPHRD_ETHER;
+ at76_set_mac_state(priv, MAC_SCANNING);
+ schedule_work(&priv->work_start_scan);
+ } else {
+ priv->netdev->type = ARPHRD_IEEE80211_RADIOTAP;
+ at76_start_monitor(priv);
+ }
+
+ mutex_unlock(&priv->mtx);
+}
+
+/* Initiate scanning */
+static void at76_work_start_scan(struct work_struct *work)
+{
+ struct at76_priv *priv = container_of(work, struct at76_priv,
+ work_start_scan);
+ int ret;
+
+ mutex_lock(&priv->mtx);
+
+ WARN_ON(priv->mac_state != MAC_SCANNING);
+ if (priv->mac_state != MAC_SCANNING)
+ goto exit;
+
+ /* only clear the bss list when a scan is actively initiated,
+ * otherwise simply rely on at76_bss_list_timeout */
+ if (priv->scan_state == SCAN_IN_PROGRESS) {
+ at76_free_bss_list(priv);
+ priv->scan_need_any = 1;
+ } else
+ priv->scan_need_any = 0;
+
+ ret = at76_start_scan(priv, 1);
+
+ if (ret < 0)
+ printk(KERN_ERR "%s: %s: start_scan failed with %d\n",
+ priv->netdev->name, __func__, ret);
+ else {
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer for %d ticks",
+ __func__, __LINE__, SCAN_POLL_INTERVAL);
+ schedule_delayed_work(&priv->dwork_get_scan,
+ SCAN_POLL_INTERVAL);
+ }
+
+exit:
+ mutex_unlock(&priv->mtx);
+}
+
/* Enable or disable promiscuous mode */
static void at76_work_set_promisc(struct work_struct *work)
{
@@ -1595,7 +4092,7 @@ static void at76_work_set_promisc(struct work_struct *work)
ret = at76_set_mib(priv, &priv->mib_buf);
if (ret < 0)
printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
+ priv->netdev->name, ret);
mutex_unlock(&priv->mtx);
}
@@ -1611,759 +4108,1088 @@ static void at76_work_submit_rx(struct work_struct *work)
mutex_unlock(&priv->mtx);
}
-static void at76_rx_tasklet(unsigned long param)
+/* We got an association response */
+static void at76_rx_mgmt_assoc(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- struct urb *urb = (struct urb *)param;
- struct at76_priv *priv = urb->context;
- struct at76_rx_buffer *buf;
- struct ieee80211_rx_status rx_status = { 0 };
-
- if (priv->device_unplugged) {
- at76_dbg(DBG_DEVSTART, "device unplugged");
- if (urb)
- at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ struct ieee80211_assoc_response *resp =
+ (struct ieee80211_assoc_response *)buf->packet;
+ u16 assoc_id = le16_to_cpu(resp->aid);
+ u16 status = le16_to_cpu(resp->status);
+
+ at76_dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa 0x%04x status "
+ "0x%04x assoc_id 0x%04x rates %s", priv->netdev->name,
+ mac2str(resp->header.addr3), le16_to_cpu(resp->capability),
+ status, assoc_id, hex2str(resp->info_element->data,
+ resp->info_element->len));
+
+ if (priv->mac_state != MAC_ASSOC) {
+ printk(KERN_INFO "%s: AssocResp in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
return;
}
- if (!priv->rx_skb || !priv->rx_skb->data)
- return;
-
- buf = (struct at76_rx_buffer *)priv->rx_skb->data;
-
- if (urb->status != 0) {
- if (urb->status != -ENOENT && urb->status != -ECONNRESET)
- at76_dbg(DBG_URB,
- "%s %s: - nonzero Rx bulk status received: %d",
- __func__, wiphy_name(priv->hw->wiphy),
- urb->status);
- return;
+ BUG_ON(!priv->curr_bss);
+
+ cancel_delayed_work(&priv->dwork_assoc);
+ if (status == WLAN_STATUS_SUCCESS) {
+ struct bss_info *ptr = priv->curr_bss;
+ priv->assoc_id = assoc_id & 0x3fff;
+ /* update iwconfig params */
+ memcpy(priv->bssid, ptr->bssid, ETH_ALEN);
+ memcpy(priv->essid, ptr->ssid, ptr->ssid_len);
+ priv->essid_size = ptr->ssid_len;
+ priv->channel = ptr->channel;
+ schedule_work(&priv->work_assoc_done);
+ } else {
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
}
+}
- at76_dbg(DBG_RX_ATMEL_HDR,
- "%s: rx frame: rate %d rssi %d noise %d link %d",
- wiphy_name(priv->hw->wiphy), buf->rx_rate, buf->rssi,
- buf->noise_level, buf->link_quality);
-
- skb_trim(priv->rx_skb, le16_to_cpu(buf->wlength) + AT76_RX_HDRLEN);
- at76_dbg_dump(DBG_RX_DATA, &priv->rx_skb->data[AT76_RX_HDRLEN],
- priv->rx_skb->len, "RX: len=%d",
- (int)(priv->rx_skb->len - AT76_RX_HDRLEN));
+/* Process disassociation request from the AP */
+static void at76_rx_mgmt_disassoc(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_disassoc *resp =
+ (struct ieee80211_disassoc *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+
+ at76_dbg(DBG_RX_MGMT,
+ "%s: rx DisAssoc bssid %s reason 0x%04x destination %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
+
+ /* We are not connected, ignore */
+ if (priv->mac_state == MAC_SCANNING || priv->mac_state == MAC_INIT
+ || !priv->curr_bss)
+ return;
- rx_status.signal = buf->rssi;
- /* FIXME: is rate_idx still present in structure? */
- rx_status.rate_idx = buf->rx_rate;
- rx_status.flag |= RX_FLAG_DECRYPTED;
- rx_status.flag |= RX_FLAG_IV_STRIPPED;
+ /* Not our BSSID, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
+ return;
- skb_pull(priv->rx_skb, AT76_RX_HDRLEN);
- at76_dbg(DBG_MAC80211, "calling ieee80211_rx_irqsafe(): %d/%d",
- priv->rx_skb->len, priv->rx_skb->data_len);
- ieee80211_rx_irqsafe(priv->hw, priv->rx_skb, &rx_status);
+ /* Not for our STA and not broadcast, ignore */
+ if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
+ && !is_broadcast_ether_addr(mgmt->addr1))
+ return;
- /* Use a new skb for the next receive */
- priv->rx_skb = NULL;
+ if (priv->mac_state != MAC_ASSOC && priv->mac_state != MAC_CONNECTED
+ && priv->mac_state != MAC_JOINING) {
+ printk(KERN_INFO "%s: DisAssoc in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
- at76_submit_rx_urb(priv);
+ if (priv->mac_state == MAC_CONNECTED) {
+ netif_carrier_off(priv->netdev);
+ netif_stop_queue(priv->netdev);
+ at76_iwevent_bss_disconnect(priv->netdev);
+ }
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
}
-/* Load firmware into kernel memory and parse it */
-static struct fwentry *at76_load_firmware(struct usb_device *udev,
- enum board_type board_type)
+static void at76_rx_mgmt_auth(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- int ret;
- char *str;
- struct at76_fw_header *fwh;
- struct fwentry *fwe = &firmwares[board_type];
-
- mutex_lock(&fw_mutex);
-
- if (fwe->loaded) {
- at76_dbg(DBG_FW, "re-using previously loaded fw");
- goto exit;
+ struct ieee80211_auth *resp = (struct ieee80211_auth *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+ int seq_nr = le16_to_cpu(resp->transaction);
+ int alg = le16_to_cpu(resp->algorithm);
+ int status = le16_to_cpu(resp->status);
+
+ at76_dbg(DBG_RX_MGMT,
+ "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d "
+ "destination %s", priv->netdev->name, mac2str(mgmt->addr3),
+ alg, seq_nr, status, mac2str(mgmt->addr1));
+
+ if (alg == WLAN_AUTH_SHARED_KEY && seq_nr == 2)
+ at76_dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...",
+ priv->netdev->name, hex2str(resp->info_element, 18));
+
+ if (priv->mac_state != MAC_AUTH) {
+ printk(KERN_INFO "%s: ignored AuthFrame in state %s\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
}
-
- at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
- ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
- if (ret < 0) {
- dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
- fwe->fwname);
- dev_printk(KERN_ERR, &udev->dev,
- "you may need to download the firmware from "
- "http://developer.berlios.de/projects/at76c503a/\n");
- goto exit;
+ if (priv->auth_mode != alg) {
+ printk(KERN_INFO "%s: ignored AuthFrame for alg %d\n",
+ priv->netdev->name, alg);
+ return;
}
- at76_dbg(DBG_FW, "got it.");
- fwh = (struct at76_fw_header *)(fwe->fw->data);
+ BUG_ON(!priv->curr_bss);
- if (fwe->fw->size <= sizeof(*fwh)) {
- dev_printk(KERN_ERR, &udev->dev,
- "firmware is too short (0x%zx)\n", fwe->fw->size);
- goto exit;
+ /* Not our BSSID or not for our STA, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid)
+ || compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1))
+ return;
+
+ cancel_delayed_work(&priv->dwork_auth);
+ if (status != WLAN_STATUS_SUCCESS) {
+ /* try to join next bss */
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ return;
}
- /* CRC currently not checked */
- fwe->board_type = le32_to_cpu(fwh->board_type);
- if (fwe->board_type != board_type) {
- dev_printk(KERN_ERR, &udev->dev,
- "board type mismatch, requested %u, got %u\n",
- board_type, fwe->board_type);
- goto exit;
+ if (priv->auth_mode == WLAN_AUTH_OPEN || seq_nr == 4) {
+ priv->retries = ASSOC_RETRIES;
+ at76_set_mac_state(priv, MAC_ASSOC);
+ at76_assoc_req(priv, priv->curr_bss);
+ at76_dbg(DBG_MGMT_TIMER,
+ "%s:%d: starting mgmt_timer + HZ", __func__, __LINE__);
+ schedule_delayed_work(&priv->dwork_assoc, ASSOC_TIMEOUT);
+ return;
}
- fwe->fw_version.major = fwh->major;
- fwe->fw_version.minor = fwh->minor;
- fwe->fw_version.patch = fwh->patch;
- fwe->fw_version.build = fwh->build;
+ WARN_ON(seq_nr != 2);
+ at76_auth_req(priv, priv->curr_bss, seq_nr + 1, resp->info_element);
+ at76_dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ", __func__,
+ __LINE__);
+ schedule_delayed_work(&priv->dwork_auth, AUTH_TIMEOUT);
+}
- str = (char *)fwh + le32_to_cpu(fwh->str_offset);
- fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
- fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
- fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
- fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
+static void at76_rx_mgmt_deauth(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct ieee80211_disassoc *resp =
+ (struct ieee80211_disassoc *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &resp->header;
+
+ at76_dbg(DBG_RX_MGMT | DBG_PROGRESS,
+ "%s: rx DeAuth bssid %s reason 0x%04x destination %s",
+ priv->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->reason), mac2str(mgmt->addr1));
+
+ if (priv->mac_state != MAC_AUTH && priv->mac_state != MAC_ASSOC
+ && priv->mac_state != MAC_CONNECTED) {
+ printk(KERN_INFO "%s: DeAuth in state %s ignored\n",
+ priv->netdev->name, mac_states[priv->mac_state]);
+ return;
+ }
- fwe->loaded = 1;
+ BUG_ON(!priv->curr_bss);
- dev_printk(KERN_DEBUG, &udev->dev,
- "using firmware %s (version %d.%d.%d-%d)\n",
- fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
+ /* Not our BSSID, ignore */
+ if (compare_ether_addr(mgmt->addr3, priv->curr_bss->bssid))
+ return;
- at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
- le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
- le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
- at76_dbg(DBG_DEVSTART, "firmware id %s", str);
+ /* Not for our STA and not broadcast, ignore */
+ if (compare_ether_addr(priv->netdev->dev_addr, mgmt->addr1)
+ && !is_broadcast_ether_addr(mgmt->addr1))
+ return;
-exit:
- mutex_unlock(&fw_mutex);
+ if (priv->mac_state == MAC_CONNECTED)
+ at76_iwevent_bss_disconnect(priv->netdev);
- if (fwe->loaded)
- return fwe;
- else
- return NULL;
+ at76_set_mac_state(priv, MAC_JOINING);
+ schedule_work(&priv->work_join);
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
}
-static void at76_mac80211_tx_callback(struct urb *urb)
+static void at76_rx_mgmt_beacon(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- struct at76_priv *priv = urb->context;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(priv->tx_skb);
+ int varpar_len;
+ /* beacon content */
+ struct ieee80211_beacon *bdata = (struct ieee80211_beacon *)buf->packet;
+ struct ieee80211_hdr_3addr *mgmt = &bdata->header;
+
+ struct list_head *lptr;
+ struct bss_info *match; /* entry matching addr3 with its bssid */
+ int new_entry = 0;
+ int len;
+ struct ieee80211_info_element *ie;
+ int have_ssid = 0;
+ int have_rates = 0;
+ int have_channel = 0;
+ int keep_going = 1;
+ unsigned long flags;
+
+ spin_lock_irqsave(&priv->bss_list_spinlock, flags);
+ if (priv->mac_state == MAC_CONNECTED) {
+ /* in state MAC_CONNECTED we use the mgmt_timer to control
+ the beacon of the BSS */
+ BUG_ON(!priv->curr_bss);
+
+ if (!compare_ether_addr(priv->curr_bss->bssid, mgmt->addr3)) {
+ /* We got our AP's beacon, defer the timeout handler.
+ Kill pending work first, as schedule_delayed_work()
+ won't do it. */
+ cancel_delayed_work(&priv->dwork_beacon);
+ schedule_delayed_work(&priv->dwork_beacon,
+ BEACON_TIMEOUT);
+ priv->curr_bss->rssi = buf->rssi;
+ priv->beacons_received++;
+ goto exit;
+ }
+ }
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ /* look if we have this BSS already in the list */
+ match = NULL;
- switch (urb->status) {
- case 0:
- /* success */
- /* FIXME:
- * is the frame really ACKed when tx_callback is called ? */
- info->flags |= IEEE80211_TX_STAT_ACK;
- break;
- case -ENOENT:
- case -ECONNRESET:
- /* fail, urb has been unlinked */
- /* FIXME: add error message */
- break;
- default:
- at76_dbg(DBG_URB, "%s - nonzero tx status received: %d",
- __func__, urb->status);
- break;
+ if (!list_empty(&priv->bss_list)) {
+ list_for_each(lptr, &priv->bss_list) {
+ struct bss_info *bss_ptr =
+ list_entry(lptr, struct bss_info, list);
+ if (!compare_ether_addr(bss_ptr->bssid, mgmt->addr3)) {
+ match = bss_ptr;
+ break;
+ }
+ }
}
- memset(&info->status, 0, sizeof(info->status));
+ if (!match) {
+ /* BSS not in the list - append it */
+ match = kzalloc(sizeof(struct bss_info), GFP_ATOMIC);
+ if (!match) {
+ at76_dbg(DBG_BSS_TABLE,
+ "%s: cannot kmalloc new bss info (%zd byte)",
+ priv->netdev->name, sizeof(struct bss_info));
+ goto exit;
+ }
+ new_entry = 1;
+ list_add_tail(&match->list, &priv->bss_list);
+ }
- ieee80211_tx_status_irqsafe(priv->hw, priv->tx_skb);
+ match->capa = le16_to_cpu(bdata->capability);
+ match->beacon_interval = le16_to_cpu(bdata->beacon_interval);
+ match->rssi = buf->rssi;
+ match->link_qual = buf->link_quality;
+ match->noise_level = buf->noise_level;
+ memcpy(match->bssid, mgmt->addr3, ETH_ALEN);
+ at76_dbg(DBG_RX_BEACON, "%s: bssid %s", priv->netdev->name,
+ mac2str(match->bssid));
+
+ ie = bdata->info_element;
+
+ /* length of var length beacon parameters */
+ varpar_len = min_t(int, le16_to_cpu(buf->wlength) -
+ sizeof(struct ieee80211_beacon),
+ BEACON_MAX_DATA_LENGTH);
+
+ /* This routine steps through the bdata->data array to get
+ * some useful information about the access point.
+ * Currently, this implementation supports receipt of: SSID,
+ * supported transfer rates and channel, in any order, with some
+ * tolerance for intermittent unknown codes (although this
+ * functionality may not be necessary as the useful information will
+ * usually arrive in consecutively, but there have been some
+ * reports of some of the useful information fields arriving in a
+ * different order).
+ * It does not support any more IE types although MFIE_TYPE_TIM may
+ * be supported (on my AP at least).
+ * The bdata->data array is about 1500 bytes long but only ~36 of those
+ * bytes are useful, hence the have_ssid etc optimizations. */
+
+ while (keep_going &&
+ ((&ie->data[ie->len] - (u8 *)bdata->info_element) <=
+ varpar_len)) {
+
+ switch (ie->id) {
+
+ case MFIE_TYPE_SSID:
+ if (have_ssid)
+ break;
- priv->tx_skb = NULL;
+ len = min_t(int, IW_ESSID_MAX_SIZE, ie->len);
- ieee80211_wake_queues(priv->hw);
-}
+ /* we copy only if this is a new entry,
+ or the incoming SSID is not a hidden SSID. This
+ will protect us from overwriting a real SSID read
+ in a ProbeResponse with a hidden one from a
+ following beacon. */
+ if (!new_entry && at76_is_hidden_ssid(ie->data, len)) {
+ have_ssid = 1;
+ break;
+ }
-static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
-{
- struct at76_priv *priv = hw->priv;
- struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- int padding, submit_len, ret;
+ match->ssid_len = len;
+ memcpy(match->ssid, ie->data, len);
+ at76_dbg(DBG_RX_BEACON, "%s: SSID - %.*s",
+ priv->netdev->name, len, match->ssid);
+ have_ssid = 1;
+ break;
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ case MFIE_TYPE_RATES:
+ if (have_rates)
+ break;
- if (priv->tx_urb->status == -EINPROGRESS) {
- printk(KERN_ERR "%s: %s called while tx urb is pending\n",
- wiphy_name(priv->hw->wiphy), __func__);
- return NETDEV_TX_BUSY;
- }
+ match->rates_len =
+ min_t(int, sizeof(match->rates), ie->len);
+ memcpy(match->rates, ie->data, match->rates_len);
+ have_rates = 1;
+ at76_dbg(DBG_RX_BEACON, "%s: SUPPORTED RATES %s",
+ priv->netdev->name,
+ hex2str(ie->data, ie->len));
+ break;
- ieee80211_stop_queues(hw);
+ case MFIE_TYPE_DS_SET:
+ if (have_channel)
+ break;
- at76_ledtrig_tx_activity(); /* tell ledtrigger we send a packet */
+ match->channel = ie->data[0];
+ have_channel = 1;
+ at76_dbg(DBG_RX_BEACON, "%s: CHANNEL - %d",
+ priv->netdev->name, match->channel);
+ break;
- WARN_ON(priv->tx_skb != NULL);
+ case MFIE_TYPE_CF_SET:
+ case MFIE_TYPE_TIM:
+ case MFIE_TYPE_IBSS_SET:
+ default:
+ at76_dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
+ priv->netdev->name, ie->id, ie->len,
+ hex2str(ie->data, ie->len));
+ break;
+ }
- priv->tx_skb = skb;
- padding = at76_calc_padding(skb->len);
- submit_len = AT76_TX_HDRLEN + skb->len + padding;
+ /* advance to the next informational element */
+ next_ie(&ie);
- /* setup 'Atmel' header */
- memset(tx_buffer, 0, sizeof(*tx_buffer));
- tx_buffer->padding = padding;
- tx_buffer->wlength = cpu_to_le16(skb->len);
- tx_buffer->tx_rate = ieee80211_get_tx_rate(hw, info)->hw_value;
- if (FIRMWARE_IS_WPA(priv->fw_version) && info->control.hw_key) {
- tx_buffer->key_id = (info->control.hw_key->keyidx);
- tx_buffer->cipher_type =
- priv->keys[info->control.hw_key->keyidx].cipher;
- tx_buffer->cipher_length =
- priv->keys[info->control.hw_key->keyidx].keylen;
- tx_buffer->reserved = 0;
- } else {
- tx_buffer->key_id = 0;
- tx_buffer->cipher_type = 0;
- tx_buffer->cipher_length = 0;
- tx_buffer->reserved = 0;
- };
- /* memset(tx_buffer->reserved, 0, sizeof(tx_buffer->reserved)); */
- memcpy(tx_buffer->packet, skb->data, skb->len);
+ /* Optimization: after all, the bdata->data array is
+ * varpar_len bytes long, whereas we get all of the useful
+ * information after only ~36 bytes, this saves us a lot of
+ * time (and trouble as the remaining portion of the array
+ * could be full of junk)
+ * Comment this out if you want to see what other information
+ * comes from the AP - although little of it may be useful */
+ }
- at76_dbg(DBG_TX_DATA, "%s tx: wlen 0x%x pad 0x%x rate %d hdr",
- wiphy_name(priv->hw->wiphy), le16_to_cpu(tx_buffer->wlength),
- tx_buffer->padding, tx_buffer->tx_rate);
+ at76_dbg(DBG_RX_BEACON, "%s: Finished processing beacon data",
+ priv->netdev->name);
- /* send stuff */
- at76_dbg_dump(DBG_TX_DATA_CONTENT, tx_buffer, submit_len,
- "%s(): tx_buffer %d bytes:", __func__, submit_len);
- usb_fill_bulk_urb(priv->tx_urb, priv->udev, priv->tx_pipe, tx_buffer,
- submit_len, at76_mac80211_tx_callback, priv);
- ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
- if (ret) {
- printk(KERN_ERR "%s: error in tx submit urb: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- if (ret == -EINVAL)
- printk(KERN_ERR
- "%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
- wiphy_name(priv->hw->wiphy), priv->tx_urb,
- priv->tx_urb->hcpriv, priv->tx_urb->complete);
- }
+ match->last_rx = jiffies; /* record last rx of beacon */
- return 0;
+exit:
+ spin_unlock_irqrestore(&priv->bss_list_spinlock, flags);
}
-static int at76_mac80211_start(struct ieee80211_hw *hw)
+/* Calculate the link level from a given rx_buffer */
+static void at76_calc_level(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
{
- struct at76_priv *priv = hw->priv;
- int ret;
-
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ /* just a guess for now, might be different for other chips */
+ int max_rssi = 42;
- mutex_lock(&priv->mtx);
-
- ret = at76_submit_rx_urb(priv);
- if (ret < 0) {
- printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- goto error;
- }
+ qual->level = (buf->rssi * 100 / max_rssi);
+ if (qual->level > 100)
+ qual->level = 100;
+ qual->updated |= IW_QUAL_LEVEL_UPDATED;
+}
- at76_startup_device(priv);
+/* Calculate the link quality from a given rx_buffer */
+static void at76_calc_qual(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
+{
+ if (at76_is_intersil(priv->board_type))
+ qual->qual = buf->link_quality;
+ else {
+ unsigned long elapsed;
- at76_start_monitor(priv);
+ /* Update qual at most once a second */
+ elapsed = jiffies - priv->beacons_last_qual;
+ if (elapsed < 1 * HZ)
+ return;
-error:
- mutex_unlock(&priv->mtx);
+ qual->qual = qual->level * priv->beacons_received *
+ msecs_to_jiffies(priv->beacon_period) / elapsed;
- return 0;
+ priv->beacons_last_qual = jiffies;
+ priv->beacons_received = 0;
+ }
+ qual->qual = (qual->qual > 100) ? 100 : qual->qual;
+ qual->updated |= IW_QUAL_QUAL_UPDATED;
}
-static void at76_mac80211_stop(struct ieee80211_hw *hw)
+/* Calculate the noise quality from a given rx_buffer */
+static void at76_calc_noise(struct at76_priv *priv, struct at76_rx_buffer *buf,
+ struct iw_quality *qual)
{
- struct at76_priv *priv = hw->priv;
-
- at76_dbg(DBG_MAC80211, "%s()", __func__);
-
- mutex_lock(&priv->mtx);
+ qual->noise = 0;
+ qual->updated |= IW_QUAL_NOISE_INVALID;
+}
- if (!priv->device_unplugged) {
- /* We are called by "ifconfig ethX down", not because the
- * device is not available anymore. */
- if (at76_set_radio(priv, 0) == 1)
- at76_wait_completion(priv, CMD_RADIO_ON);
+static void at76_update_wstats(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
+{
+ struct iw_quality *qual = &priv->wstats.qual;
- /* We unlink rx_urb because at76_open() re-submits it.
- * If unplugged, at76_delete_device() takes care of it. */
- usb_kill_urb(priv->rx_urb);
+ if (buf->rssi && priv->mac_state == MAC_CONNECTED) {
+ qual->updated = 0;
+ at76_calc_level(priv, buf, qual);
+ at76_calc_qual(priv, buf, qual);
+ at76_calc_noise(priv, buf, qual);
+ } else {
+ qual->qual = 0;
+ qual->level = 0;
+ qual->noise = 0;
+ qual->updated = IW_QUAL_ALL_INVALID;
}
-
- mutex_unlock(&priv->mtx);
}
-static int at76_add_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
+static void at76_rx_mgmt(struct at76_priv *priv, struct at76_rx_buffer *buf)
{
- struct at76_priv *priv = hw->priv;
- int ret = 0;
+ struct ieee80211_hdr_3addr *mgmt =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ u16 framectl = le16_to_cpu(mgmt->frame_ctl);
+
+ /* update wstats */
+ if (priv->mac_state != MAC_INIT && priv->mac_state != MAC_SCANNING) {
+ /* jal: this is a dirty hack needed by Tim in ad-hoc mode */
+ /* Data packets always seem to have a 0 link level, so we
+ only read link quality info from management packets.
+ Atmel driver actually averages the present, and previous
+ values, we just present the raw value at the moment - TJS */
+ if (priv->iw_mode == IW_MODE_ADHOC
+ || (priv->curr_bss
+ && !compare_ether_addr(mgmt->addr3,
+ priv->curr_bss->bssid)))
+ at76_update_wstats(priv, buf);
+ }
- at76_dbg(DBG_MAC80211, "%s()", __func__);
+ at76_dbg(DBG_RX_MGMT_CONTENT, "%s rx mgmt framectl 0x%x %s",
+ priv->netdev->name, framectl,
+ hex2str(mgmt, le16_to_cpu(buf->wlength)));
- mutex_lock(&priv->mtx);
+ switch (framectl & IEEE80211_FCTL_STYPE) {
+ case IEEE80211_STYPE_BEACON:
+ case IEEE80211_STYPE_PROBE_RESP:
+ at76_rx_mgmt_beacon(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_ASSOC_RESP:
+ at76_rx_mgmt_assoc(priv, buf);
+ break;
- switch (conf->type) {
- case NL80211_IFTYPE_STATION:
- priv->iw_mode = IW_MODE_INFRA;
+ case IEEE80211_STYPE_DISASSOC:
+ at76_rx_mgmt_disassoc(priv, buf);
break;
+
+ case IEEE80211_STYPE_AUTH:
+ at76_rx_mgmt_auth(priv, buf);
+ break;
+
+ case IEEE80211_STYPE_DEAUTH:
+ at76_rx_mgmt_deauth(priv, buf);
+ break;
+
default:
- ret = -EOPNOTSUPP;
- goto exit;
+ printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
+ priv->netdev->name, framectl);
}
-exit:
- mutex_unlock(&priv->mtx);
-
- return ret;
+ return;
}
-static void at76_remove_interface(struct ieee80211_hw *hw,
- struct ieee80211_if_init_conf *conf)
+/* Convert the 802.11 header into an ethernet-style header, make skb
+ * ready for consumption by netif_rx() */
+static void at76_ieee80211_to_eth(struct sk_buff *skb, int iw_mode)
{
- at76_dbg(DBG_MAC80211, "%s()", __func__);
-}
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ struct ethhdr *eth_hdr_p;
+ u8 *src_addr;
+ u8 *dest_addr;
-static int at76_join(struct at76_priv *priv)
-{
- struct at76_req_join join;
- int ret;
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
- memset(&join, 0, sizeof(struct at76_req_join));
- memcpy(join.essid, priv->essid, priv->essid_size);
- join.essid_size = priv->essid_size;
- memcpy(join.bssid, priv->bssid, ETH_ALEN);
- join.bss_type = INFRASTRUCTURE_MODE;
- join.channel = priv->channel;
- join.timeout = cpu_to_le16(2000);
+ /* That would be the ethernet header if the hardware converted
+ * the frame for us. Make sure the source and the destination
+ * match the 802.11 header. Which hardware does it? */
+ eth_hdr_p = (struct ethhdr *)skb_pull(skb, IEEE80211_3ADDR_LEN);
- at76_dbg(DBG_MAC80211, "%s: sending CMD_JOIN", __func__);
- ret = at76_set_card_command(priv->udev, CMD_JOIN, &join,
- sizeof(struct at76_req_join));
+ dest_addr = i802_11_hdr->addr1;
+ if (iw_mode == IW_MODE_ADHOC)
+ src_addr = i802_11_hdr->addr2;
+ else
+ src_addr = i802_11_hdr->addr3;
- if (ret < 0) {
- printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- return 0;
- }
+ if (!compare_ether_addr(eth_hdr_p->h_source, src_addr) &&
+ !compare_ether_addr(eth_hdr_p->h_dest, dest_addr))
+ /* Yes, we already have an ethernet header */
+ skb_reset_mac_header(skb);
+ else {
+ u16 len;
+
+ /* Need to build an ethernet header */
+ if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
+ /* SNAP frame - decapsulate, keep proto */
+ skb_push(skb, offsetof(struct ethhdr, h_proto) -
+ sizeof(rfc1042sig));
+ len = 0;
+ } else {
+ /* 802.3 frame, proto is length */
+ len = skb->len;
+ skb_push(skb, ETH_HLEN);
+ }
- ret = at76_wait_completion(priv, CMD_JOIN);
- at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
- if (ret != CMD_STATUS_COMPLETE) {
- printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
- wiphy_name(priv->hw->wiphy), ret);
- return 0;
+ skb_reset_mac_header(skb);
+ eth_hdr_p = eth_hdr(skb);
+ /* This needs to be done in this order (eth_hdr_p->h_dest may
+ * overlap src_addr) */
+ memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN);
+ memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN);
+ if (len)
+ eth_hdr_p->h_proto = htons(len);
}
- at76_set_tkip_bssid(priv, priv->bssid);
- at76_set_pm_mode(priv);
-
- return 0;
+ skb->protocol = eth_type_trans(skb, skb->dev);
}
-static void at76_dwork_hw_scan(struct work_struct *work)
+/* Check for fragmented data in priv->rx_skb. If the packet was no fragment
+ or it was the last of a fragment set a skb containing the whole packet
+ is returned for further processing. Otherwise we get NULL and are
+ done and the packet is either stored inside the fragment buffer
+ or thrown away. Every returned skb starts with the ieee802_11 header
+ and contains _no_ FCS at the end */
+static struct sk_buff *at76_check_for_rx_frags(struct at76_priv *priv)
{
- struct at76_priv *priv = container_of(work, struct at76_priv,
- dwork_hw_scan.work);
- int ret;
+ struct sk_buff *skb = priv->rx_skb;
+ struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
+ struct ieee80211_hdr_3addr *i802_11_hdr =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ /* seq_ctrl, fragment_number, sequence number of new packet */
+ u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl);
+ u16 fragnr = sctl & 0xf;
+ u16 seqnr = sctl >> 4;
+ u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
- ret = at76_get_cmd_status(priv->udev, CMD_SCAN);
- at76_dbg(DBG_MAC80211, "%s: CMD_SCAN status 0x%02x", __func__, ret);
+ /* Length including the IEEE802.11 header, but without the trailing
+ * FCS and without the Atmel Rx header */
+ int length = le16_to_cpu(buf->wlength) - IEEE80211_FCS_LEN;
- /* FIXME: add maximum time for scan to complete */
+ /* where does the data payload start in skb->data ? */
+ u8 *data = i802_11_hdr->payload;
- if (ret != CMD_STATUS_COMPLETE) {
- queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
- SCAN_POLL_INTERVAL);
- goto exit;
+ /* length of payload, excl. the trailing FCS */
+ int data_len = length - IEEE80211_3ADDR_LEN;
+
+ int i;
+ struct rx_data_buf *bptr, *optr;
+ unsigned long oldest = ~0UL;
+
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d "
+ "length %d data %d: %s ...", priv->netdev->name, frame_ctl,
+ mac2str(i802_11_hdr->addr2), seqnr, fragnr, length, data_len,
+ hex2str(data, 32));
+
+ at76_dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p "
+ "tail %p end %p len %d", priv->netdev->name, skb->head,
+ skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
+ skb->len);
+
+ if (data_len < 0) {
+ /* make sure data starts in the buffer */
+ printk(KERN_INFO "%s: data frame too short\n",
+ priv->netdev->name);
+ return NULL;
}
- ieee80211_scan_completed(priv->hw);
+ WARN_ON(length <= AT76_RX_HDRLEN);
+ if (length <= AT76_RX_HDRLEN)
+ return NULL;
- if (is_valid_ether_addr(priv->bssid)) {
- ieee80211_wake_queues(priv->hw);
- at76_join(priv);
+ /* remove the at76_rx_buffer header - we don't need it anymore */
+ /* we need the IEEE802.11 header (for the addresses) if this packet
+ is the first of a chain */
+ skb_pull(skb, AT76_RX_HDRLEN);
+
+ /* remove FCS at end */
+ skb_trim(skb, length);
+
+ at76_dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p "
+ "end %p len %d data %p data_len %d", priv->netdev->name,
+ skb->head, skb->data, skb_tail_pointer(skb),
+ skb_end_pointer(skb), skb->len, data, data_len);
+
+ if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) {
+ /* unfragmented packet received */
+ /* Use a new skb for the next receive */
+ priv->rx_skb = NULL;
+ at76_dbg(DBG_RX_FRAGS, "%s: unfragmented", priv->netdev->name);
+ return skb;
}
- ieee80211_wake_queues(priv->hw);
+ /* look if we've got a chain for the sender address.
+ afterwards optr points to first free or the oldest entry,
+ or, if i < NR_RX_DATA_BUF, bptr points to the entry for the
+ sender address */
+ /* determining the oldest entry doesn't cope with jiffies wrapping
+ but I don't care to delete a young entry at these rare moments ... */
+
+ bptr = priv->rx_data;
+ optr = NULL;
+ for (i = 0; i < NR_RX_DATA_BUF; i++, bptr++) {
+ if (!bptr->skb) {
+ optr = bptr;
+ oldest = 0UL;
+ continue;
+ }
-exit:
- return;
-}
+ if (!compare_ether_addr(i802_11_hdr->addr2, bptr->sender))
+ break;
-static int at76_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
-{
- struct at76_priv *priv = hw->priv;
- struct at76_req_scan scan;
- int ret;
+ if (!optr) {
+ optr = bptr;
+ oldest = bptr->last_rx;
+ } else if (bptr->last_rx < oldest)
+ optr = bptr;
+ }
- at76_dbg(DBG_MAC80211, "%s():", __func__);
- at76_dbg_dump(DBG_MAC80211, ssid, len, "ssid %zd bytes:", len);
+ if (i < NR_RX_DATA_BUF) {
+
+ at76_dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag = %d/%d) "
+ "matched sender addr",
+ priv->netdev->name, i, bptr->seqnr, bptr->fragnr);
+
+ /* bptr points to an entry for the sender address */
+ if (bptr->seqnr == seqnr) {
+ int left;
+ /* the fragment has the current sequence number */
+ if (((bptr->fragnr + 1) & 0xf) != fragnr) {
+ /* wrong fragment number -> ignore it */
+ /* is & 0xf necessary above ??? */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: frag nr mismatch: %d + 1 != %d",
+ priv->netdev->name, bptr->fragnr,
+ fragnr);
+ return NULL;
+ }
+ bptr->last_rx = jiffies;
+ /* the next following fragment number ->
+ add the data at the end */
+
+ /* for test only ??? */
+ left = skb_tailroom(bptr->skb);
+ if (left < data_len)
+ printk(KERN_INFO
+ "%s: only %d byte free (need %d)\n",
+ priv->netdev->name, left, data_len);
+ else
+ memcpy(skb_put(bptr->skb, data_len), data,
+ data_len);
+
+ bptr->fragnr = fragnr;
+ if (frame_ctl & IEEE80211_FCTL_MOREFRAGS)
+ return NULL;
+
+ /* this was the last fragment - send it */
+ skb = bptr->skb;
+ bptr->skb = NULL; /* free the entry */
+ at76_dbg(DBG_RX_FRAGS, "%s: last frag of seq %d",
+ priv->netdev->name, seqnr);
+ return skb;
+ }
- mutex_lock(&priv->mtx);
+ /* got another sequence number */
+ if (fragnr == 0) {
+ /* it's the start of a new chain - replace the
+ old one by this */
+ /* bptr->sender has the correct value already */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: start of new seq %d, removing old seq %d",
+ priv->netdev->name, seqnr, bptr->seqnr);
+ bptr->seqnr = seqnr;
+ bptr->fragnr = 0;
+ bptr->last_rx = jiffies;
+ /* swap bptr->skb and priv->rx_skb */
+ skb = bptr->skb;
+ bptr->skb = priv->rx_skb;
+ priv->rx_skb = skb;
+ } else {
+ /* it from the middle of a new chain ->
+ delete the old entry and skip the new one */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: middle of new seq %d (%d) "
+ "removing old seq %d",
+ priv->netdev->name, seqnr, fragnr,
+ bptr->seqnr);
+ dev_kfree_skb(bptr->skb);
+ bptr->skb = NULL;
+ }
+ return NULL;
+ }
- ieee80211_stop_queues(hw);
+ /* if we didn't find a chain for the sender address, optr
+ points either to the first free or the oldest entry */
- memset(&scan, 0, sizeof(struct at76_req_scan));
- memset(scan.bssid, 0xFF, ETH_ALEN);
- scan.scan_type = SCAN_TYPE_ACTIVE;
- if (priv->essid_size > 0) {
- memcpy(scan.essid, ssid, len);
- scan.essid_size = len;
+ if (fragnr != 0) {
+ /* this is not the begin of a fragment chain ... */
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: no chain for non-first fragment (%d)",
+ priv->netdev->name, fragnr);
+ return NULL;
}
- scan.min_channel_time = cpu_to_le16(priv->scan_min_time);
- scan.max_channel_time = cpu_to_le16(priv->scan_max_time);
- scan.probe_delay = cpu_to_le16(priv->scan_min_time * 1000);
- scan.international_scan = 0;
- at76_dbg(DBG_MAC80211, "%s: sending CMD_SCAN", __func__);
- ret = at76_set_card_command(priv->udev, CMD_SCAN, &scan, sizeof(scan));
+ BUG_ON(!optr);
+ if (optr->skb) {
+ /* swap the skb's */
+ skb = optr->skb;
+ optr->skb = priv->rx_skb;
+ priv->rx_skb = skb;
- if (ret < 0) {
- err("CMD_SCAN failed: %d", ret);
- goto exit;
- }
+ at76_dbg(DBG_RX_FRAGS,
+ "%s: free old contents: sender %s seq/frag %d/%d",
+ priv->netdev->name, mac2str(optr->sender),
+ optr->seqnr, optr->fragnr);
- queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
- SCAN_POLL_INTERVAL);
+ } else {
+ /* take the skb from priv->rx_skb */
+ optr->skb = priv->rx_skb;
+ /* let at76_submit_rx_urb() allocate a new skb */
+ priv->rx_skb = NULL;
-exit:
- mutex_unlock(&priv->mtx);
+ at76_dbg(DBG_RX_FRAGS, "%s: use a free entry",
+ priv->netdev->name);
+ }
+ memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN);
+ optr->seqnr = seqnr;
+ optr->fragnr = 0;
+ optr->last_rx = jiffies;
- return 0;
+ return NULL;
}
-static int at76_config(struct ieee80211_hw *hw, u32 changed)
+/* Rx interrupt: we expect the complete data buffer in priv->rx_skb */
+static void at76_rx_data(struct at76_priv *priv)
{
- struct at76_priv *priv = hw->priv;
- struct ieee80211_conf *conf = &hw->conf;
+ struct net_device *netdev = priv->netdev;
+ struct net_device_stats *stats = &priv->stats;
+ struct sk_buff *skb = priv->rx_skb;
+ struct at76_rx_buffer *buf = (struct at76_rx_buffer *)skb->data;
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ int length = le16_to_cpu(buf->wlength);
- at76_dbg(DBG_MAC80211, "%s(): channel %d radio %d",
- __func__, conf->channel->hw_value, conf->radio_enabled);
- at76_dbg_dump(DBG_MAC80211, priv->essid, priv->essid_size, "ssid:");
- at76_dbg_dump(DBG_MAC80211, priv->bssid, ETH_ALEN, "bssid:");
+ at76_dbg(DBG_RX_DATA, "%s received data packet: %s", netdev->name,
+ hex2str(skb->data, AT76_RX_HDRLEN));
- mutex_lock(&priv->mtx);
+ at76_dbg(DBG_RX_DATA_CONTENT, "rx packet: %s",
+ hex2str(skb->data + AT76_RX_HDRLEN, length));
- priv->channel = conf->channel->hw_value;
+ skb = at76_check_for_rx_frags(priv);
+ if (!skb)
+ return;
- if (is_valid_ether_addr(priv->bssid)) {
- at76_join(priv);
- ieee80211_wake_queues(priv->hw);
- } else {
- ieee80211_stop_queues(priv->hw);
- at76_start_monitor(priv);
- };
+ /* Atmel header and the FCS are already removed */
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
- mutex_unlock(&priv->mtx);
+ skb->dev = netdev;
+ skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */
- return 0;
-}
+ if (is_broadcast_ether_addr(i802_11_hdr->addr1)) {
+ if (!compare_ether_addr(i802_11_hdr->addr1, netdev->broadcast))
+ skb->pkt_type = PACKET_BROADCAST;
+ else
+ skb->pkt_type = PACKET_MULTICAST;
+ } else if (compare_ether_addr(i802_11_hdr->addr1, netdev->dev_addr))
+ skb->pkt_type = PACKET_OTHERHOST;
-static int at76_config_interface(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif,
- struct ieee80211_if_conf *conf)
-{
- struct at76_priv *priv = hw->priv;
+ at76_ieee80211_to_eth(skb, priv->iw_mode);
- at76_dbg_dump(DBG_MAC80211, conf->bssid, ETH_ALEN, "bssid:");
+ netdev->last_rx = jiffies;
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
- mutex_lock(&priv->mtx);
+ return;
+}
- memcpy(priv->bssid, conf->bssid, ETH_ALEN);
-// memcpy(priv->essid, conf->ssid, conf->ssid_len);
-// priv->essid_size = conf->ssid_len;
+static void at76_rx_monitor_mode(struct at76_priv *priv)
+{
+ struct at76_rx_radiotap *rt;
+ u8 *payload;
+ int skblen;
+ struct net_device *netdev = priv->netdev;
+ struct at76_rx_buffer *buf =
+ (struct at76_rx_buffer *)priv->rx_skb->data;
+ /* length including the IEEE802.11 header and the trailing FCS,
+ but not at76_rx_buffer */
+ int length = le16_to_cpu(buf->wlength);
+ struct sk_buff *skb = priv->rx_skb;
+ struct net_device_stats *stats = &priv->stats;
- if (is_valid_ether_addr(priv->bssid)) {
- /* mac80211 is joining a bss */
- ieee80211_wake_queues(priv->hw);
- at76_join(priv);
- } else
- ieee80211_stop_queues(priv->hw);
+ if (length < IEEE80211_FCS_LEN) {
+ /* buffer contains no data */
+ at76_dbg(DBG_MONITOR_MODE,
+ "%s: MONITOR MODE: rx skb without data",
+ priv->netdev->name);
+ return;
+ }
- mutex_unlock(&priv->mtx);
+ skblen = sizeof(struct at76_rx_radiotap) + length;
- return 0;
+ skb = dev_alloc_skb(skblen);
+ if (!skb) {
+ printk(KERN_ERR "%s: MONITOR MODE: dev_alloc_skb for radiotap "
+ "header returned NULL\n", priv->netdev->name);
+ return;
+ }
+
+ skb_put(skb, skblen);
+
+ rt = (struct at76_rx_radiotap *)skb->data;
+ payload = skb->data + sizeof(struct at76_rx_radiotap);
+
+ rt->rt_hdr.it_version = 0;
+ rt->rt_hdr.it_pad = 0;
+ rt->rt_hdr.it_len = cpu_to_le16(sizeof(struct at76_rx_radiotap));
+ rt->rt_hdr.it_present = cpu_to_le32(AT76_RX_RADIOTAP_PRESENT);
+
+ rt->rt_tsft = cpu_to_le64(le32_to_cpu(buf->rx_time));
+ rt->rt_rate = hw_rates[buf->rx_rate] & (~0x80);
+ rt->rt_signal = buf->rssi;
+ rt->rt_noise = buf->noise_level;
+ rt->rt_flags = IEEE80211_RADIOTAP_F_FCS;
+ if (buf->fragmentation)
+ rt->rt_flags |= IEEE80211_RADIOTAP_F_FRAG;
+
+ memcpy(payload, buf->packet, length);
+ skb->dev = netdev;
+ skb->ip_summed = CHECKSUM_NONE;
+ skb_reset_mac_header(skb);
+ skb->pkt_type = PACKET_OTHERHOST;
+ skb->protocol = htons(ETH_P_802_2);
+
+ netdev->last_rx = jiffies;
+ netif_rx(skb);
+ stats->rx_packets++;
+ stats->rx_bytes += length;
}
-/* must be atomic */
-static void at76_configure_filter(struct ieee80211_hw *hw,
- unsigned int changed_flags,
- unsigned int *total_flags, int mc_count,
- struct dev_addr_list *mc_list)
+/* Check if we spy on the sender address in buf and update stats */
+static void at76_iwspy_update(struct at76_priv *priv,
+ struct at76_rx_buffer *buf)
{
- struct at76_priv *priv = hw->priv;
- int flags;
-
- at76_dbg(DBG_MAC80211, "%s(): changed_flags=0x%08x "
- "total_flags=0x%08x mc_count=%d",
- __func__, changed_flags, *total_flags, mc_count);
+ struct ieee80211_hdr_3addr *hdr =
+ (struct ieee80211_hdr_3addr *)buf->packet;
+ struct iw_quality qual;
- flags = changed_flags & AT76_SUPPORTED_FILTERS;
- *total_flags = AT76_SUPPORTED_FILTERS;
+ /* We can only set the level here */
+ qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
+ qual.level = 0;
+ qual.noise = 0;
+ at76_calc_level(priv, buf, &qual);
- /* FIXME: access to priv->promisc should be protected with
- * priv->mtx, but it's impossible because this function needs to be
- * atomic */
+ spin_lock_bh(&priv->spy_spinlock);
- if (flags && !priv->promisc) {
- /* mac80211 wants us to enable promiscuous mode */
- priv->promisc = 1;
- } else if (!flags && priv->promisc) {
- /* we need to disable promiscuous mode */
- priv->promisc = 0;
- } else
- return;
+ if (priv->spy_data.spy_number > 0)
+ wireless_spy_update(priv->netdev, hdr->addr2, &qual);
- queue_work(hw->workqueue, &priv->work_set_promisc);
+ spin_unlock_bh(&priv->spy_spinlock);
}
-static int at76_set_key_oldfw(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
- struct ieee80211_key_conf *key)
+static void at76_rx_tasklet(unsigned long param)
{
- struct at76_priv *priv = hw->priv;
-
- int i;
-
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
- "key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ struct urb *urb = (struct urb *)param;
+ struct at76_priv *priv = urb->context;
+ struct net_device *netdev = priv->netdev;
+ struct at76_rx_buffer *buf;
+ struct ieee80211_hdr_3addr *i802_11_hdr;
+ u16 frame_ctl;
- if (key->alg != ALG_WEP)
- return -EOPNOTSUPP;
+ if (priv->device_unplugged) {
+ at76_dbg(DBG_DEVSTART, "device unplugged");
+ if (urb)
+ at76_dbg(DBG_DEVSTART, "urb status %d", urb->status);
+ return;
+ }
- key->hw_key_idx = key->keyidx;
+ if (!priv->rx_skb || !netdev || !priv->rx_skb->data)
+ return;
- mutex_lock(&priv->mtx);
+ buf = (struct at76_rx_buffer *)priv->rx_skb->data;
- switch (cmd) {
- case SET_KEY:
- memcpy(priv->wep_keys[key->keyidx], key->key, key->keylen);
- priv->wep_keys_len[key->keyidx] = key->keylen;
+ i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet;
- /* FIXME: find out how to do this properly */
- priv->wep_key_id = key->keyidx;
+ frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
- break;
- case DISABLE_KEY:
- default:
- priv->wep_keys_len[key->keyidx] = 0;
- break;
+ if (urb->status != 0) {
+ if (urb->status != -ENOENT && urb->status != -ECONNRESET)
+ at76_dbg(DBG_URB,
+ "%s %s: - nonzero Rx bulk status received: %d",
+ __func__, netdev->name, urb->status);
+ return;
}
- priv->wep_enabled = 0;
+ at76_dbg(DBG_RX_ATMEL_HDR,
+ "%s: rx frame: rate %d rssi %d noise %d link %d %s",
+ priv->netdev->name, buf->rx_rate, buf->rssi, buf->noise_level,
+ buf->link_quality, hex2str(i802_11_hdr, 48));
+ if (priv->iw_mode == IW_MODE_MONITOR) {
+ at76_rx_monitor_mode(priv);
+ goto exit;
+ }
- for (i = 0; i < WEP_KEYS; i++) {
- if (priv->wep_keys_len[i] != 0)
- priv->wep_enabled = 1;
+ /* there is a new bssid around, accept it: */
+ if (buf->newbss && priv->iw_mode == IW_MODE_ADHOC) {
+ at76_dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name);
+ schedule_work(&priv->work_new_bss);
}
- at76_startup_device(priv);
+ switch (frame_ctl & IEEE80211_FCTL_FTYPE) {
+ case IEEE80211_FTYPE_DATA:
+ at76_rx_data(priv);
+ break;
- mutex_unlock(&priv->mtx);
+ case IEEE80211_FTYPE_MGMT:
+ /* jal: TODO: find out if we can update iwspy also on
+ other frames than management (might depend on the
+ radio chip / firmware version !) */
- return 0;
-}
+ at76_iwspy_update(priv, buf);
-static int at76_set_key_newfw(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
- struct ieee80211_key_conf *key)
-{
- struct at76_priv *priv = hw->priv;
- int ret = -EOPNOTSUPP;
-
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
- "key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ at76_rx_mgmt(priv, buf);
+ break;
- mutex_lock(&priv->mtx);
+ case IEEE80211_FTYPE_CTL:
+ at76_dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x",
+ priv->netdev->name, frame_ctl);
+ break;
- priv->mib_buf.type = MIB_MAC_ENCRYPTION;
+ default:
+ printk(KERN_DEBUG "%s: ignoring frame with framectl 0x%04x\n",
+ priv->netdev->name, frame_ctl);
+ }
+exit:
+ at76_submit_rx_urb(priv);
+}
- if (cmd == DISABLE_KEY) {
- priv->mib_buf.size = CIPHER_KEY_LEN;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- cipher_default_keyvalue[key->keyidx]);
- memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN);
- if (at76_set_mib(priv, &priv->mib_buf) != CMD_STATUS_COMPLETE)
- ret = -EOPNOTSUPP; /* -EIO would be probably better */
- else {
+/* Load firmware into kernel memory and parse it */
+static struct fwentry *at76_load_firmware(struct usb_device *udev,
+ enum board_type board_type)
+{
+ int ret;
+ char *str;
+ struct at76_fw_header *fwh;
+ struct fwentry *fwe = &firmwares[board_type];
- priv->keys[key->keyidx].cipher = CIPHER_NONE;
- priv->keys[key->keyidx].keylen = 0;
- };
- if (priv->default_group_key == key->keyidx)
- priv->default_group_key = 0xff;
+ mutex_lock(&fw_mutex);
- if (priv->default_pairwise_key == key->keyidx)
- priv->default_pairwise_key = 0xff;
- /* If default pairwise key is removed, fall back to
- * group key? */
- ret = 0;
+ if (fwe->loaded) {
+ at76_dbg(DBG_FW, "re-using previously loaded fw");
goto exit;
- };
-
- if (cmd == SET_KEY) {
- /* store key into MIB */
- priv->mib_buf.size = CIPHER_KEY_LEN;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- cipher_default_keyvalue[key->keyidx]);
- memset(priv->mib_buf.data.data, 0, CIPHER_KEY_LEN);
- memcpy(priv->mib_buf.data.data, key->key, key->keylen);
-
- switch (key->alg) {
- case ALG_WEP:
- if (key->keylen == 5) {
- priv->keys[key->keyidx].cipher =
- CIPHER_WEP64;
- priv->keys[key->keyidx].keylen = 8;
- } else if (key->keylen == 13) {
- priv->keys[key->keyidx].cipher =
- CIPHER_WEP128;
- /* Firmware needs this */
- priv->keys[key->keyidx].keylen = 8;
- } else {
- ret = -EOPNOTSUPP;
- goto exit;
- };
- break;
- case ALG_TKIP:
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- priv->keys[key->keyidx].cipher = CIPHER_TKIP;
- priv->keys[key->keyidx].keylen = 12;
- break;
+ }
- case ALG_CCMP:
- if (!at76_is_505a(priv->board_type)) {
- ret = -EOPNOTSUPP;
- goto exit;
- };
- key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
- priv->keys[key->keyidx].cipher = CIPHER_CCMP;
- priv->keys[key->keyidx].keylen = 16;
- break;
+ at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname);
+ ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &udev->dev, "firmware %s not found!\n",
+ fwe->fwname);
+ dev_printk(KERN_ERR, &udev->dev,
+ "you may need to download the firmware from "
+ "http://developer.berlios.de/projects/at76c503a/");
+ goto exit;
+ }
- default:
- ret = -EOPNOTSUPP;
- goto exit;
- };
-
- priv->mib_buf.data.data[38] = priv->keys[key->keyidx].cipher;
- priv->mib_buf.data.data[39] = 1; /* Taken from atmelwlandriver,
- not documented */
-
- if (is_valid_ether_addr(address))
- /* Pairwise key */
- priv->mib_buf.data.data[39] |= (KEY_PAIRWISE | KEY_TX);
- else if (is_broadcast_ether_addr(address))
- /* Group key */
- priv->mib_buf.data.data[39] |= (KEY_TX);
- else /* Key used only for transmission ??? */
- priv->mib_buf.data.data[39] |= (KEY_TX);
-
- if (at76_set_mib(priv, &priv->mib_buf) !=
- CMD_STATUS_COMPLETE) {
- ret = -EOPNOTSUPP; /* -EIO would be probably better */
- goto exit;
- };
+ at76_dbg(DBG_FW, "got it.");
+ fwh = (struct at76_fw_header *)(fwe->fw->data);
- if ((key->alg == ALG_TKIP) || (key->alg == ALG_CCMP))
- at76_reset_rsc(priv);
+ if (fwe->fw->size <= sizeof(*fwh)) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "firmware is too short (0x%zx)\n", fwe->fw->size);
+ goto exit;
+ }
- key->hw_key_idx = key->keyidx;
+ /* CRC currently not checked */
+ fwe->board_type = le32_to_cpu(fwh->board_type);
+ if (fwe->board_type != board_type) {
+ dev_printk(KERN_ERR, &udev->dev,
+ "board type mismatch, requested %u, got %u\n",
+ board_type, fwe->board_type);
+ goto exit;
+ }
- /* Set up default keys */
- if (is_broadcast_ether_addr(address))
- priv->default_group_key = key->keyidx;
- if (is_valid_ether_addr(address))
- priv->default_pairwise_key = key->keyidx;
+ fwe->fw_version.major = fwh->major;
+ fwe->fw_version.minor = fwh->minor;
+ fwe->fw_version.patch = fwh->patch;
+ fwe->fw_version.build = fwh->build;
- /* Set up encryption MIBs */
+ str = (char *)fwh + le32_to_cpu(fwh->str_offset);
+ fwe->intfw = (u8 *)fwh + le32_to_cpu(fwh->int_fw_offset);
+ fwe->intfw_size = le32_to_cpu(fwh->int_fw_len);
+ fwe->extfw = (u8 *)fwh + le32_to_cpu(fwh->ext_fw_offset);
+ fwe->extfw_size = le32_to_cpu(fwh->ext_fw_len);
- /* first block of settings */
- priv->mib_buf.size = 3;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- privacy_invoked);
- priv->mib_buf.data.data[0] = 1; /* privacy_invoked */
- priv->mib_buf.data.data[1] = priv->default_pairwise_key;
- priv->mib_buf.data.data[2] = priv->default_group_key;
+ fwe->loaded = 1;
- ret = at76_set_mib(priv, &priv->mib_buf);
- if (ret != CMD_STATUS_COMPLETE)
- goto exit;
+ dev_printk(KERN_DEBUG, &udev->dev,
+ "using firmware %s (version %d.%d.%d-%d)\n",
+ fwe->fwname, fwh->major, fwh->minor, fwh->patch, fwh->build);
- /* second block of settings */
- priv->mib_buf.size = 3;
- priv->mib_buf.index = offsetof(struct mib_mac_encryption,
- exclude_unencrypted);
- priv->mib_buf.data.data[0] = 1; /* exclude_unencrypted */
- priv->mib_buf.data.data[1] = 0; /* wep_encryption_type */
- priv->mib_buf.data.data[2] = 0; /* ckip_key_permutation */
+ at76_dbg(DBG_DEVSTART, "board %u, int %d:%d, ext %d:%d", board_type,
+ le32_to_cpu(fwh->int_fw_offset), le32_to_cpu(fwh->int_fw_len),
+ le32_to_cpu(fwh->ext_fw_offset), le32_to_cpu(fwh->ext_fw_len));
+ at76_dbg(DBG_DEVSTART, "firmware id %s", str);
- ret = at76_set_mib(priv, &priv->mib_buf);
- if (ret != CMD_STATUS_COMPLETE)
- goto exit;
- ret = 0;
- };
exit:
- at76_dump_mib_mac_encryption(priv);
- mutex_unlock(&priv->mtx);
- return ret;
-}
-
-static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
- const u8 *local_address, const u8 *address,
- struct ieee80211_key_conf *key)
-{
- struct at76_priv *priv = hw->priv;
-
- at76_dbg(DBG_MAC80211, "%s(): cmd %d key->alg %d key->keyidx %d "
- "key->keylen %d",
- __func__, cmd, key->alg, key->keyidx, key->keylen);
+ mutex_unlock(&fw_mutex);
- if (FIRMWARE_IS_WPA(priv->fw_version))
- return at76_set_key_newfw(hw, cmd, local_address, address, key);
+ if (fwe->loaded)
+ return fwe;
else
- return at76_set_key_oldfw(hw, cmd, local_address, address, key);
-
+ return NULL;
}
-static const struct ieee80211_ops at76_ops = {
- .tx = at76_mac80211_tx,
- .add_interface = at76_add_interface,
- .remove_interface = at76_remove_interface,
- .config = at76_config,
- .config_interface = at76_config_interface,
- .configure_filter = at76_configure_filter,
- .start = at76_mac80211_start,
- .stop = at76_mac80211_stop,
- .hw_scan = at76_hw_scan,
- .set_key = at76_set_key,
-};
-
/* Allocate network device and initialize private data */
static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
{
- struct ieee80211_hw *hw;
+ struct net_device *netdev;
struct at76_priv *priv;
+ int i;
- hw = ieee80211_alloc_hw(sizeof(struct at76_priv), &at76_ops);
- if (!hw) {
- printk(KERN_ERR DRIVER_NAME ": could not register"
- " ieee80211_hw\n");
+ /* allocate memory for our device state and initialize it */
+ netdev = alloc_etherdev(sizeof(struct at76_priv));
+ if (!netdev) {
+ dev_printk(KERN_ERR, &udev->dev, "out of memory\n");
return NULL;
}
- priv = hw->priv;
- priv->hw = hw;
+ priv = netdev_priv(netdev);
priv->udev = udev;
+ priv->netdev = netdev;
mutex_init(&priv->mtx);
+ INIT_WORK(&priv->work_assoc_done, at76_work_assoc_done);
+ INIT_WORK(&priv->work_join, at76_work_join);
+ INIT_WORK(&priv->work_new_bss, at76_work_new_bss);
+ INIT_WORK(&priv->work_start_scan, at76_work_start_scan);
INIT_WORK(&priv->work_set_promisc, at76_work_set_promisc);
INIT_WORK(&priv->work_submit_rx, at76_work_submit_rx);
- INIT_DELAYED_WORK(&priv->dwork_hw_scan, at76_dwork_hw_scan);
+ INIT_DELAYED_WORK(&priv->dwork_restart, at76_dwork_restart);
+ INIT_DELAYED_WORK(&priv->dwork_get_scan, at76_dwork_get_scan);
+ INIT_DELAYED_WORK(&priv->dwork_beacon, at76_dwork_beacon);
+ INIT_DELAYED_WORK(&priv->dwork_auth, at76_dwork_auth);
+ INIT_DELAYED_WORK(&priv->dwork_assoc, at76_dwork_assoc);
+
+ spin_lock_init(&priv->mgmt_spinlock);
+ priv->next_mgmt_bulk = NULL;
+ priv->mac_state = MAC_INIT;
+
+ /* initialize empty BSS list */
+ priv->curr_bss = NULL;
+ INIT_LIST_HEAD(&priv->bss_list);
+ spin_lock_init(&priv->bss_list_spinlock);
+
+ init_timer(&priv->bss_list_timer);
+ priv->bss_list_timer.data = (unsigned long)priv;
+ priv->bss_list_timer.function = at76_bss_list_timeout;
+
+ spin_lock_init(&priv->spy_spinlock);
+
+ /* mark all rx data entries as unused */
+ for (i = 0; i < NR_RX_DATA_BUF; i++)
+ priv->rx_data[i].skb = NULL;
priv->rx_tasklet.func = at76_rx_tasklet;
priv->rx_tasklet.data = 0;
@@ -2371,9 +5197,6 @@ static struct at76_priv *at76_alloc_new_device(struct usb_device *udev)
priv->pm_mode = AT76_PM_OFF;
priv->pm_period = 0;
- /* unit us */
- priv->hw->channel_change_time = 100000;
-
return priv;
}
@@ -2436,42 +5259,11 @@ static int at76_alloc_urbs(struct at76_priv *priv,
return 0;
}
-static struct ieee80211_rate at76_rates[] = {
- { .bitrate = 10, .hw_value = TX_RATE_1MBIT, },
- { .bitrate = 20, .hw_value = TX_RATE_2MBIT, },
- { .bitrate = 55, .hw_value = TX_RATE_5_5MBIT, },
- { .bitrate = 110, .hw_value = TX_RATE_11MBIT, },
-};
-
-static struct ieee80211_channel at76_channels[] = {
- { .center_freq = 2412, .hw_value = 1 },
- { .center_freq = 2417, .hw_value = 2 },
- { .center_freq = 2422, .hw_value = 3 },
- { .center_freq = 2427, .hw_value = 4 },
- { .center_freq = 2432, .hw_value = 5 },
- { .center_freq = 2437, .hw_value = 6 },
- { .center_freq = 2442, .hw_value = 7 },
- { .center_freq = 2447, .hw_value = 8 },
- { .center_freq = 2452, .hw_value = 9 },
- { .center_freq = 2457, .hw_value = 10 },
- { .center_freq = 2462, .hw_value = 11 },
- { .center_freq = 2467, .hw_value = 12 },
- { .center_freq = 2472, .hw_value = 13 },
- { .center_freq = 2484, .hw_value = 14 }
-};
-
-static struct ieee80211_supported_band at76_supported_band = {
- .channels = at76_channels,
- .n_channels = ARRAY_SIZE(at76_channels),
- .bitrates = at76_rates,
- .n_bitrates = ARRAY_SIZE(at76_rates),
-};
-
/* Register network device and initialize the hardware */
static int at76_init_new_device(struct at76_priv *priv,
struct usb_interface *interface)
{
- struct device *dev = &interface->dev;
+ struct net_device *netdev = priv->netdev;
int ret;
/* set up the endpoint information */
@@ -2487,11 +5279,14 @@ static int at76_init_new_device(struct at76_priv *priv,
/* MAC address */
ret = at76_get_hw_config(priv);
if (ret < 0) {
- dev_err(dev, "cannot get MAC address\n");
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot get MAC address\n");
goto exit;
}
priv->domain = at76_get_reg_domain(priv->regulatory_domain);
+ /* init. netdev->dev_addr */
+ memcpy(netdev->dev_addr, priv->mac_addr, ETH_ALEN);
priv->channel = DEF_CHANNEL;
priv->iw_mode = IW_MODE_INFRA;
@@ -2501,54 +5296,47 @@ static int at76_init_new_device(struct at76_priv *priv,
priv->txrate = TX_RATE_AUTO;
priv->preamble_type = PREAMBLE_TYPE_LONG;
priv->beacon_period = 100;
+ priv->beacons_last_qual = jiffies;
priv->auth_mode = WLAN_AUTH_OPEN;
priv->scan_min_time = DEF_SCAN_MIN_TIME;
priv->scan_max_time = DEF_SCAN_MAX_TIME;
priv->scan_mode = SCAN_TYPE_ACTIVE;
- priv->default_pairwise_key = 0xff;
- priv->default_group_key = 0xff;
-
- /* mac80211 initialisation */
- priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &at76_supported_band;
- if (FIRMWARE_IS_WPA(priv->fw_version) &&
- (at76_is_503rfmd(priv->board_type) ||
- at76_is_505(priv->board_type)))
- priv->hw->flags = IEEE80211_HW_SIGNAL_UNSPEC;
- else
- priv->hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
- IEEE80211_HW_SIGNAL_UNSPEC;
-
- priv->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
-
- SET_IEEE80211_DEV(priv->hw, &interface->dev);
- SET_IEEE80211_PERM_ADDR(priv->hw, priv->mac_addr);
-
- ret = ieee80211_register_hw(priv->hw);
+ netdev->flags &= ~IFF_MULTICAST; /* not yet or never */
+ netdev->open = at76_open;
+ netdev->stop = at76_stop;
+ netdev->get_stats = at76_get_stats;
+ netdev->ethtool_ops = &at76_ethtool_ops;
+
+ /* Add pointers to enable iwspy support. */
+ priv->wireless_data.spy_data = &priv->spy_data;
+ netdev->wireless_data = &priv->wireless_data;
+
+ netdev->hard_start_xmit = at76_tx;
+ netdev->tx_timeout = at76_tx_timeout;
+ netdev->watchdog_timeo = 2 * HZ;
+ netdev->wireless_handlers = &at76_handler_def;
+ netdev->set_multicast_list = at76_set_multicast;
+ netdev->set_mac_address = at76_set_mac_address;
+ dev_alloc_name(netdev, "wlan%d");
+
+ ret = register_netdev(priv->netdev);
if (ret) {
- dev_err(dev, "cannot register mac80211 hw (status %d)!\n", ret);
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot register netdevice (status %d)!\n", ret);
goto exit;
}
+ priv->netdev_registered = 1;
- priv->mac80211_registered = 1;
+ printk(KERN_INFO "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
+ netdev->name, dev_name(&interface->dev), mac2str(priv->mac_addr),
+ priv->fw_version.major, priv->fw_version.minor,
+ priv->fw_version.patch, priv->fw_version.build);
+ printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n", netdev->name,
+ priv->regulatory_domain, priv->domain->name);
- dev_info(dev, "%s: USB %s, MAC %s, firmware %d.%d.%d-%d\n",
- wiphy_name(priv->hw->wiphy),
- dev_name(&interface->dev), mac2str(priv->mac_addr),
- priv->fw_version.major, priv->fw_version.minor,
- priv->fw_version.patch, priv->fw_version.build);
- dev_info(dev, "%s: regulatory domain 0x%02x: %s\n",
- wiphy_name(priv->hw->wiphy),
- priv->regulatory_domain, priv->domain->name);
- dev_info(dev, "%s: WPA support: ", wiphy_name(priv->hw->wiphy));
- if (!FIRMWARE_IS_WPA(priv->fw_version))
- printk("none\n");
- else {
- if (!at76_is_505a(priv->board_type))
- printk("TKIP\n");
- else
- printk("TKIP, AES/CCMP\n");
- };
+ /* we let this timer run the whole time this driver instance lives */
+ mod_timer(&priv->bss_list_timer, jiffies + BSS_LIST_TIMEOUT);
exit:
return ret;
@@ -2556,13 +5344,15 @@ exit:
static void at76_delete_device(struct at76_priv *priv)
{
+ int i;
+
at76_dbg(DBG_PROC_ENTRY, "%s: ENTER", __func__);
/* The device is gone, don't bother turning it off */
priv->device_unplugged = 1;
- if (priv->mac80211_registered)
- ieee80211_unregister_hw(priv->hw);
+ if (priv->netdev_registered)
+ unregister_netdev(priv->netdev);
/* assuming we used keventd, it must quiesce too */
flush_scheduled_work();
@@ -2583,11 +5373,25 @@ static void at76_delete_device(struct at76_priv *priv)
if (priv->rx_skb)
kfree_skb(priv->rx_skb);
+ at76_free_bss_list(priv);
+ del_timer_sync(&priv->bss_list_timer);
+ cancel_delayed_work(&priv->dwork_get_scan);
+ cancel_delayed_work(&priv->dwork_beacon);
+ cancel_delayed_work(&priv->dwork_auth);
+ cancel_delayed_work(&priv->dwork_assoc);
+
+ if (priv->mac_state == MAC_CONNECTED)
+ at76_iwevent_bss_disconnect(priv->netdev);
+
+ for (i = 0; i < NR_RX_DATA_BUF; i++)
+ if (priv->rx_data[i].skb) {
+ dev_kfree_skb(priv->rx_data[i].skb);
+ priv->rx_data[i].skb = NULL;
+ }
usb_put_dev(priv->udev);
- at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw",
- __func__);
- ieee80211_free_hw(priv->hw);
+ at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/netdev", __func__);
+ free_netdev(priv->netdev); /* priv is in netdev */
at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
}
@@ -2621,8 +5425,8 @@ static int at76_probe(struct usb_interface *interface,
we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
if (op_mode == OPMODE_HW_CONFIG_MODE) {
- dev_err(&interface->dev,
- "cannot handle a device in HW_CONFIG_MODE\n");
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot handle a device in HW_CONFIG_MODE\n");
ret = -EBUSY;
goto error;
}
@@ -2630,12 +5434,13 @@ static int at76_probe(struct usb_interface *interface,
if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
&& op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
/* download internal firmware part */
- dev_dbg(&interface->dev, "downloading internal firmware\n");
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading internal firmware\n");
ret = at76_load_internal_fw(udev, fwe);
if (ret < 0) {
- dev_err(&interface->dev,
- "error %d downloading internal firmware\n",
- ret);
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d downloading internal firmware\n",
+ ret);
goto error;
}
usb_put_dev(udev);
@@ -2660,7 +5465,8 @@ static int at76_probe(struct usb_interface *interface,
need_ext_fw = 1;
if (need_ext_fw) {
- dev_dbg(&interface->dev, "downloading external firmware\n");
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading external firmware\n");
ret = at76_load_external_fw(udev, fwe);
if (ret)
@@ -2669,8 +5475,8 @@ static int at76_probe(struct usb_interface *interface,
/* Re-check firmware version */
ret = at76_get_mib(udev, MIB_FW_VERSION, &fwv, sizeof(fwv));
if (ret < 0) {
- dev_err(&interface->dev,
- "error %d getting firmware version\n", ret);
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d getting firmware version\n", ret);
goto error;
}
}
@@ -2681,6 +5487,7 @@ static int at76_probe(struct usb_interface *interface,
goto error;
}
+ SET_NETDEV_DEV(priv->netdev, &interface->dev);
usb_set_intfdata(interface, priv);
memcpy(&priv->fw_version, &fwv, sizeof(struct mib_fw_version));
@@ -2708,7 +5515,7 @@ static void at76_disconnect(struct usb_interface *interface)
if (!priv)
return;
- printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy));
+ printk(KERN_INFO "%s: disconnecting\n", priv->netdev->name);
at76_delete_device(priv);
dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
}
@@ -2764,8 +5571,5 @@ MODULE_AUTHOR("Alex <alex@foogod.com>");
MODULE_AUTHOR("Nick Jones");
MODULE_AUTHOR("Balint Seeber <n0_5p4m_p13453@hotmail.com>");
MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
-MODULE_AUTHOR("Guido Guenther <agx@sigxcpu.org>");
-MODULE_AUTHOR("Kalle Valo <kalle.valo@iki.fi>");
-MODULE_AUTHOR("Milan Plzik <milan.plzik@gmail.com>");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/at76_usb/at76_usb.h b/drivers/staging/at76_usb/at76_usb.h
index 8bb352f16d45..b20be9da1fa1 100644
--- a/drivers/staging/at76_usb/at76_usb.h
+++ b/drivers/staging/at76_usb/at76_usb.h
@@ -34,6 +34,23 @@ enum board_type {
BOARD_505AMX = 8
};
+/* our private ioctl's */
+/* preamble length (0 - long, 1 - short, 2 - auto) */
+#define AT76_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0)
+#define AT76_GET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 1)
+/* which debug channels are enabled */
+#define AT76_SET_DEBUG (SIOCIWFIRSTPRIV + 2)
+#define AT76_GET_DEBUG (SIOCIWFIRSTPRIV + 3)
+/* power save mode (incl. the Atmel proprietary smart save mode) */
+#define AT76_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 4)
+#define AT76_GET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 5)
+/* min and max channel times for scan */
+#define AT76_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 6)
+#define AT76_GET_SCAN_TIMES (SIOCIWFIRSTPRIV + 7)
+/* scan mode (0 - active, 1 - passive) */
+#define AT76_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 8)
+#define AT76_GET_SCAN_MODE (SIOCIWFIRSTPRIV + 9)
+
#define CMD_STATUS_IDLE 0x00
#define CMD_STATUS_COMPLETE 0x01
#define CMD_STATUS_UNKNOWN 0x02
@@ -65,7 +82,6 @@ enum board_type {
#define MIB_MAC 0x03
#define MIB_MAC_MGMT 0x05
#define MIB_MAC_WEP 0x06
-#define MIB_MAC_ENCRYPTION 0x06
#define MIB_PHY 0x07
#define MIB_FW_VERSION 0x08
#define MIB_MDOMAIN 0x09
@@ -90,26 +106,6 @@ enum board_type {
#define AT76_PM_ON 2
#define AT76_PM_SMART 3
-/* cipher values for encryption keys */
-#define CIPHER_NONE 0 /* this value is only guessed */
-#define CIPHER_WEP64 1
-#define CIPHER_TKIP 2
-#define CIPHER_CCMP 3
-#define CIPHER_CCX 4 /* for consistency sake only */
-#define CIPHER_WEP128 5
-
-/* bit flags key types for encryption keys */
-#define KEY_PAIRWISE 2
-#define KEY_TX 4
-
-#define CIPHER_KEYS (4)
-#define CIPHER_KEY_LEN (40)
-
-struct key_config {
- u8 cipher;
- u8 keylen;
-};
-
struct hwcfg_r505 {
u8 cr39_values[14];
u8 reserved1[14];
@@ -151,9 +147,6 @@ union at76_hwcfg {
#define WEP_SMALL_KEY_LEN (40 / 8)
#define WEP_LARGE_KEY_LEN (104 / 8)
-#define WEP_KEYS (4)
-
-
struct at76_card_config {
u8 exclude_unencrypted;
@@ -168,7 +161,7 @@ struct at76_card_config {
u8 privacy_invoked;
u8 wep_default_key_id; /* 0..3 */
u8 current_ssid[32];
- u8 wep_default_key_value[4][WEP_LARGE_KEY_LEN];
+ u8 wep_default_key_value[4][WEP_KEY_LEN];
u8 ssid_len;
u8 short_preamble;
__le16 beacon_period;
@@ -193,7 +186,7 @@ struct at76_rx_buffer {
u8 link_quality;
u8 noise_level;
__le32 rx_time;
- u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+ u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
} __attribute__((packed));
/* Length of Atmel-specific Tx header before 802.11 frame */
@@ -203,11 +196,8 @@ struct at76_tx_buffer {
__le16 wlength;
u8 tx_rate;
u8 padding;
- u8 key_id;
- u8 cipher_type;
- u8 cipher_length;
- u8 reserved;
- u8 packet[IEEE80211_MAX_FRAG_THRESHOLD];
+ u8 reserved[4];
+ u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
} __attribute__((packed));
/* defines for scan_type below */
@@ -254,7 +244,6 @@ struct set_mib_buffer {
u8 byte;
__le16 word;
u8 addr[ETH_ALEN];
- u8 data[256]; /* we need more space for mib_mac_encryption */
} data;
} __attribute__((packed));
@@ -328,24 +317,10 @@ struct mib_mac_wep {
u8 exclude_unencrypted;
__le32 wep_icv_error_count;
__le32 wep_excluded_count;
- u8 wep_default_keyvalue[WEP_KEYS][WEP_LARGE_KEY_LEN];
+ u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN];
u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
} __attribute__((packed));
-struct mib_mac_encryption {
- u8 cipher_default_keyvalue[CIPHER_KEYS][CIPHER_KEY_LEN];
- u8 tkip_bssid[6];
- u8 privacy_invoked;
- u8 cipher_default_key_id;
- u8 cipher_default_group_key_id;
- u8 exclude_unencrypted;
- u8 wep_encryption_type;
- u8 ckip_key_permutation; /* bool */
- __le32 wep_icv_error_count;
- __le32 wep_excluded_count;
- u8 key_rsc[CIPHER_KEYS][8];
-} __attribute__((packed));
-
struct mib_phy {
__le32 ed_threshold;
@@ -389,6 +364,16 @@ struct at76_fw_header {
__le32 ext_fw_len; /* external firmware image length */
} __attribute__((packed));
+enum mac_state {
+ MAC_INIT,
+ MAC_SCANNING,
+ MAC_AUTH,
+ MAC_ASSOC,
+ MAC_JOINING,
+ MAC_CONNECTED,
+ MAC_OWN_IBSS
+};
+
/* a description of a regulatory domain and the allowed channels */
struct reg_domain {
u16 code;
@@ -396,6 +381,47 @@ struct reg_domain {
u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
};
+/* how long do we keep a (I)BSS in the bss_list in jiffies
+ this should be long enough for the user to retrieve the table
+ (by iwlist ?) after the device started, because all entries from
+ other channels than the one the device locks on get removed, too */
+#define BSS_LIST_TIMEOUT (120 * HZ)
+/* struct to store BSS info found during scan */
+#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */
+
+struct bss_info {
+ struct list_head list;
+
+ u8 bssid[ETH_ALEN]; /* bssid */
+ u8 ssid[IW_ESSID_MAX_SIZE]; /* essid */
+ u8 ssid_len; /* length of ssid above */
+ u8 channel;
+ u16 capa; /* BSS capabilities */
+ u16 beacon_interval; /* beacon interval, Kus (1024 microseconds) */
+ u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates in units of
+ 500 kbps, ORed with 0x80 for
+ basic rates */
+ u8 rates_len;
+
+ /* quality of received beacon */
+ u8 rssi;
+ u8 link_qual;
+ u8 noise_level;
+
+ unsigned long last_rx; /* time (jiffies) of last beacon received */
+};
+
+/* a rx data buffer to collect rx fragments */
+struct rx_data_buf {
+ u8 sender[ETH_ALEN]; /* sender address */
+ u16 seqnr; /* sequence number */
+ u16 fragnr; /* last fragment received */
+ unsigned long last_rx; /* jiffies of last rx */
+ struct sk_buff *skb; /* == NULL if entry is free */
+};
+
+#define NR_RX_DATA_BUF 8
+
/* Data for one loaded firmware file */
struct fwentry {
const char *const fwname;
@@ -412,9 +438,11 @@ struct fwentry {
struct at76_priv {
struct usb_device *udev; /* USB device pointer */
+ struct net_device *netdev; /* net device pointer */
+ struct net_device_stats stats; /* net device stats */
+ struct iw_statistics wstats; /* wireless stats */
struct sk_buff *rx_skb; /* skbuff for receiving data */
- struct sk_buff *tx_skb; /* skbuff for transmitting data */
void *bulk_out_buffer; /* buffer for sending data */
struct urb *tx_urb; /* URB for sending data */
@@ -426,17 +454,26 @@ struct at76_priv {
struct mutex mtx; /* locks this structure */
/* work queues */
+ struct work_struct work_assoc_done;
+ struct work_struct work_join;
+ struct work_struct work_new_bss;
+ struct work_struct work_start_scan;
struct work_struct work_set_promisc;
struct work_struct work_submit_rx;
- struct delayed_work dwork_hw_scan;
+ struct delayed_work dwork_restart;
+ struct delayed_work dwork_get_scan;
+ struct delayed_work dwork_beacon;
+ struct delayed_work dwork_auth;
+ struct delayed_work dwork_assoc;
struct tasklet_struct rx_tasklet;
/* the WEP stuff */
int wep_enabled; /* 1 if WEP is enabled */
int wep_key_id; /* key id to be used */
- u8 wep_keys[WEP_KEYS][WEP_LARGE_KEY_LEN]; /* WEP keys */
- u8 wep_keys_len[WEP_KEYS]; /* length of WEP keys */
+ u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys,
+ 5 or 13 bytes are used */
+ u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */
int channel;
int iw_mode;
@@ -458,13 +495,44 @@ struct at76_priv {
int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
int scan_need_any; /* if set, need to scan for any ESSID */
+ /* the list we got from scanning */
+ spinlock_t bss_list_spinlock; /* protects bss_list operations */
+ struct list_head bss_list; /* list of BSS we got beacons from */
+ struct timer_list bss_list_timer; /* timer to purge old entries
+ from bss_list */
+ struct bss_info *curr_bss; /* current BSS */
u16 assoc_id; /* current association ID, if associated */
+ u8 wanted_bssid[ETH_ALEN];
+ int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */
+
+ /* some data for infrastructure mode only */
+ spinlock_t mgmt_spinlock; /* this spinlock protects access to
+ next_mgmt_bulk */
+
+ struct at76_tx_buffer *next_mgmt_bulk; /* pending management msg to
+ send via bulk out */
+ enum mac_state mac_state;
+ enum {
+ SCAN_IDLE,
+ SCAN_IN_PROGRESS,
+ SCAN_COMPLETED
+ } scan_state;
+ time_t last_scan;
+
+ int retries; /* remaining retries in case of timeout when
+ * sending AuthReq or AssocReq */
u8 pm_mode; /* power management mode */
u32 pm_period; /* power management period in microseconds */
struct reg_domain const *domain; /* reg domain description */
+ /* iwspy support */
+ spinlock_t spy_spinlock;
+ struct iw_spy_data spy_data;
+
+ struct iw_public_data wireless_data;
+
/* These fields contain HW config provided by the device (not all of
* these fields are used by all board types) */
u8 mac_addr[ETH_ALEN];
@@ -472,6 +540,9 @@ struct at76_priv {
struct at76_card_config card_config;
+ /* store rx fragments until complete */
+ struct rx_data_buf rx_data[NR_RX_DATA_BUF];
+
enum board_type board_type;
struct mib_fw_version fw_version;
@@ -479,20 +550,58 @@ struct at76_priv {
unsigned int netdev_registered:1;
struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
+ /* beacon counting */
int beacon_period; /* period of mgmt beacons, Kus */
+ int beacons_received;
+ unsigned long beacons_last_qual; /* time we restarted counting
+ beacons */
+};
- struct ieee80211_hw *hw;
- int mac80211_registered;
-
- struct key_config keys[4]; /* installed key types */
- u8 default_pairwise_key;
- u8 default_group_key;
+struct at76_rx_radiotap {
+ struct ieee80211_radiotap_header rt_hdr;
+ __le64 rt_tsft;
+ u8 rt_flags;
+ u8 rt_rate;
+ s8 rt_signal;
+ s8 rt_noise;
};
-#define AT76_SUPPORTED_FILTERS FIF_PROMISC_IN_BSS
+#define AT76_RX_RADIOTAP_PRESENT \
+ ((1 << IEEE80211_RADIOTAP_TSFT) | \
+ (1 << IEEE80211_RADIOTAP_FLAGS) | \
+ (1 << IEEE80211_RADIOTAP_RATE) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
+ (1 << IEEE80211_RADIOTAP_DB_ANTNOISE))
+
+#define BEACON_MAX_DATA_LENGTH 1500
+
+/* the maximum size of an AssocReq packet */
+#define ASSOCREQ_MAX_SIZE \
+ (AT76_TX_HDRLEN + sizeof(struct ieee80211_assoc_request) + \
+ 1 + 1 + IW_ESSID_MAX_SIZE + 1 + 1 + 4)
+
+/* for shared secret auth, add the challenge text size */
+#define AUTH_FRAME_SIZE (AT76_TX_HDRLEN + sizeof(struct ieee80211_auth))
+
+/* Maximal number of AuthReq retries */
+#define AUTH_RETRIES 3
+/* Maximal number of AssocReq retries */
+#define ASSOC_RETRIES 3
+
+/* Beacon timeout in managed mode when we are connected */
+#define BEACON_TIMEOUT (10 * HZ)
+
+/* Timeout for authentication response */
+#define AUTH_TIMEOUT (1 * HZ)
+
+/* Timeout for association response */
+#define ASSOC_TIMEOUT (1 * HZ)
+
+/* Polling interval when scan is running */
#define SCAN_POLL_INTERVAL (HZ / 4)
+/* Command completion timeout */
#define CMD_COMPLETION_TIMEOUT (5 * HZ)
#define DEF_RTS_THRESHOLD 1536
@@ -502,6 +611,8 @@ struct at76_priv {
#define DEF_SCAN_MIN_TIME 10
#define DEF_SCAN_MAX_TIME 120
+#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1)
+
/* the max padding size for tx in bytes (see calc_padding) */
#define MAX_PADDING_SIZE 53
diff --git a/drivers/staging/benet/Kconfig b/drivers/staging/benet/Kconfig
deleted file mode 100644
index f6806074f998..000000000000
--- a/drivers/staging/benet/Kconfig
+++ /dev/null
@@ -1,7 +0,0 @@
-config BENET
- tristate "ServerEngines 10Gb NIC - BladeEngine"
- depends on PCI && INET
- select INET_LRO
- help
- This driver implements the NIC functionality for ServerEngines
- 10Gb network adapter BladeEngine (EC 3210).
diff --git a/drivers/staging/benet/MAINTAINERS b/drivers/staging/benet/MAINTAINERS
deleted file mode 100644
index d5ce340218b3..000000000000
--- a/drivers/staging/benet/MAINTAINERS
+++ /dev/null
@@ -1,6 +0,0 @@
-SERVER ENGINES 10Gbe NIC - BLADE-ENGINE
-P: Subbu Seetharaman
-M: subbus@serverengines.com
-L: netdev@vger.kernel.org
-W: http://www.serverengines.com
-S: Supported
diff --git a/drivers/staging/benet/Makefile b/drivers/staging/benet/Makefile
deleted file mode 100644
index 460b923b99bd..000000000000
--- a/drivers/staging/benet/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-#
-# Makefile to build the network driver for ServerEngine's BladeEngine
-#
-obj-$(CONFIG_BENET) += benet.o
-
-benet-y := be_init.o \
- be_int.o \
- be_netif.o \
- be_ethtool.o \
- funcobj.o \
- cq.o \
- eq.o \
- mpu.o \
- eth.o
diff --git a/drivers/staging/benet/TODO b/drivers/staging/benet/TODO
deleted file mode 100644
index a51dfb59a62f..000000000000
--- a/drivers/staging/benet/TODO
+++ /dev/null
@@ -1,6 +0,0 @@
-TODO:
- - remove wrappers around common iowrite functions
- - full netdev audit of common problems/issues
-
-Please send all patches and questions to Subbu Seetharaman
-<subbus@serverengines.com> and Greg Kroah-Hartman <greg@kroah.com>
diff --git a/drivers/staging/benet/asyncmesg.h b/drivers/staging/benet/asyncmesg.h
deleted file mode 100644
index d1e779adb848..000000000000
--- a/drivers/staging/benet/asyncmesg.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __asyncmesg_amap_h__
-#define __asyncmesg_amap_h__
-#include "fwcmd_common.h"
-
-/* --- ASYNC_EVENT_CODES --- */
-#define ASYNC_EVENT_CODE_LINK_STATE (1)
-#define ASYNC_EVENT_CODE_ISCSI (2)
-
-/* --- ASYNC_LINK_STATES --- */
-#define ASYNC_EVENT_LINK_DOWN (0) /* Link Down on a port */
-#define ASYNC_EVENT_LINK_UP (1) /* Link Up on a port */
-
-/*
- * The last 4 bytes of the async events have this common format. It allows
- * the driver to distinguish [link]MCC_CQ_ENTRY[/link] structs from
- * asynchronous events. Both arrive on the same completion queue. This
- * structure also contains the common fields used to decode the async event.
- */
-struct BE_ASYNC_EVENT_TRAILER_AMAP {
- u8 rsvd0[8]; /* DWORD 0 */
- u8 event_code[8]; /* DWORD 0 */
- u8 event_type[8]; /* DWORD 0 */
- u8 rsvd1[6]; /* DWORD 0 */
- u8 async_event; /* DWORD 0 */
- u8 valid; /* DWORD 0 */
-} __packed;
-struct ASYNC_EVENT_TRAILER_AMAP {
- u32 dw[1];
-};
-
-/*
- * Applicable in Initiator, Target and NIC modes.
- * A link state async event is seen by all device drivers as soon they
- * create an MCC ring. Thereafter, anytime the link status changes the
- * drivers will receive a link state async event. Notifications continue to
- * be sent until a driver destroys its MCC ring. A link down event is
- * reported when either port loses link. A link up event is reported
- * when either port regains link. When BE's failover mechanism is enabled, a
- * link down on the active port causes traffic to be diverted to the standby
- * port by the BE's ARM firmware (assuming the standby port has link). In
- * this case, the standy port assumes the active status. Note: when link is
- * restored on the failed port, traffic continues on the currently active
- * port. The ARM firmware does not attempt to 'fail back' traffic to
- * the restored port.
- */
-struct BE_ASYNC_EVENT_LINK_STATE_AMAP {
- u8 port0_link_status[8];
- u8 port1_link_status[8];
- u8 active_port[8];
- u8 rsvd0[8]; /* DWORD 0 */
- u8 port0_duplex[8];
- u8 port0_speed[8];
- u8 port1_duplex[8];
- u8 port1_speed[8];
- u8 port0_fault[8];
- u8 port1_fault[8];
- u8 rsvd1[2][8]; /* DWORD 2 */
- struct BE_ASYNC_EVENT_TRAILER_AMAP trailer;
-} __packed;
-struct ASYNC_EVENT_LINK_STATE_AMAP {
- u32 dw[4];
-};
-#endif /* __asyncmesg_amap_h__ */
diff --git a/drivers/staging/benet/be_cm.h b/drivers/staging/benet/be_cm.h
deleted file mode 100644
index b7a1dfd20c36..000000000000
--- a/drivers/staging/benet/be_cm.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __be_cm_amap_h__
-#define __be_cm_amap_h__
-#include "be_common.h"
-#include "etx_context.h"
-#include "mpu_context.h"
-
-/*
- * --- CEV_WATERMARK_ENUM ---
- * CQ/EQ Watermark Encodings. Encoded as number of free entries in
- * Queue when Watermark is reached.
- */
-#define CEV_WMARK_0 (0) /* Watermark when Queue full */
-#define CEV_WMARK_16 (1) /* Watermark at 16 free entries */
-#define CEV_WMARK_32 (2) /* Watermark at 32 free entries */
-#define CEV_WMARK_48 (3) /* Watermark at 48 free entries */
-#define CEV_WMARK_64 (4) /* Watermark at 64 free entries */
-#define CEV_WMARK_80 (5) /* Watermark at 80 free entries */
-#define CEV_WMARK_96 (6) /* Watermark at 96 free entries */
-#define CEV_WMARK_112 (7) /* Watermark at 112 free entries */
-#define CEV_WMARK_128 (8) /* Watermark at 128 free entries */
-#define CEV_WMARK_144 (9) /* Watermark at 144 free entries */
-#define CEV_WMARK_160 (10) /* Watermark at 160 free entries */
-#define CEV_WMARK_176 (11) /* Watermark at 176 free entries */
-#define CEV_WMARK_192 (12) /* Watermark at 192 free entries */
-#define CEV_WMARK_208 (13) /* Watermark at 208 free entries */
-#define CEV_WMARK_224 (14) /* Watermark at 224 free entries */
-#define CEV_WMARK_240 (15) /* Watermark at 240 free entries */
-
-/*
- * --- CQ_CNT_ENUM ---
- * Completion Queue Count Encodings.
- */
-#define CEV_CQ_CNT_256 (0) /* CQ has 256 entries */
-#define CEV_CQ_CNT_512 (1) /* CQ has 512 entries */
-#define CEV_CQ_CNT_1024 (2) /* CQ has 1024 entries */
-
-/*
- * --- EQ_CNT_ENUM ---
- * Event Queue Count Encodings.
- */
-#define CEV_EQ_CNT_256 (0) /* EQ has 256 entries (16-byte EQEs only) */
-#define CEV_EQ_CNT_512 (1) /* EQ has 512 entries (16-byte EQEs only) */
-#define CEV_EQ_CNT_1024 (2) /* EQ has 1024 entries (4-byte or */
- /* 16-byte EQEs only) */
-#define CEV_EQ_CNT_2048 (3) /* EQ has 2048 entries (4-byte or */
- /* 16-byte EQEs only) */
-#define CEV_EQ_CNT_4096 (4) /* EQ has 4096 entries (4-byte EQEs only) */
-
-/*
- * --- EQ_SIZE_ENUM ---
- * Event Queue Entry Size Encoding.
- */
-#define CEV_EQ_SIZE_4 (0) /* EQE is 4 bytes */
-#define CEV_EQ_SIZE_16 (1) /* EQE is 16 bytes */
-
-/*
- * Completion Queue Context Table Entry. Contains the state of a CQ.
- * Located in RAM within the CEV block.
- */
-struct BE_CQ_CONTEXT_AMAP {
- u8 Cidx[11]; /* DWORD 0 */
- u8 Watermark[4]; /* DWORD 0 */
- u8 NoDelay; /* DWORD 0 */
- u8 EPIdx[11]; /* DWORD 0 */
- u8 Count[2]; /* DWORD 0 */
- u8 valid; /* DWORD 0 */
- u8 SolEvent; /* DWORD 0 */
- u8 Eventable; /* DWORD 0 */
- u8 Pidx[11]; /* DWORD 1 */
- u8 PD[10]; /* DWORD 1 */
- u8 EQID[7]; /* DWORD 1 */
- u8 Func; /* DWORD 1 */
- u8 WME; /* DWORD 1 */
- u8 Stalled; /* DWORD 1 */
- u8 Armed; /* DWORD 1 */
-} __packed;
-struct CQ_CONTEXT_AMAP {
- u32 dw[2];
-};
-
-/*
- * Event Queue Context Table Entry. Contains the state of an EQ.
- * Located in RAM in the CEV block.
- */
-struct BE_EQ_CONTEXT_AMAP {
- u8 Cidx[13]; /* DWORD 0 */
- u8 rsvd0[2]; /* DWORD 0 */
- u8 Func; /* DWORD 0 */
- u8 EPIdx[13]; /* DWORD 0 */
- u8 valid; /* DWORD 0 */
- u8 rsvd1; /* DWORD 0 */
- u8 Size; /* DWORD 0 */
- u8 Pidx[13]; /* DWORD 1 */
- u8 rsvd2[3]; /* DWORD 1 */
- u8 PD[10]; /* DWORD 1 */
- u8 Count[3]; /* DWORD 1 */
- u8 SolEvent; /* DWORD 1 */
- u8 Stalled; /* DWORD 1 */
- u8 Armed; /* DWORD 1 */
- u8 Watermark[4]; /* DWORD 2 */
- u8 WME; /* DWORD 2 */
- u8 rsvd3[3]; /* DWORD 2 */
- u8 EventVect[6]; /* DWORD 2 */
- u8 rsvd4[2]; /* DWORD 2 */
- u8 Delay[8]; /* DWORD 2 */
- u8 rsvd5[6]; /* DWORD 2 */
- u8 TMR; /* DWORD 2 */
- u8 rsvd6; /* DWORD 2 */
- u8 rsvd7[32]; /* DWORD 3 */
-} __packed;
-struct EQ_CONTEXT_AMAP {
- u32 dw[4];
-};
-
-#endif /* __be_cm_amap_h__ */
diff --git a/drivers/staging/benet/be_common.h b/drivers/staging/benet/be_common.h
deleted file mode 100644
index 7e63dc5e3348..000000000000
--- a/drivers/staging/benet/be_common.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __be_common_amap_h__
-#define __be_common_amap_h__
-
-/* Physical Address. */
-struct BE_PHYS_ADDR_AMAP {
- u8 lo[32]; /* DWORD 0 */
- u8 hi[32]; /* DWORD 1 */
-} __packed;
-struct PHYS_ADDR_AMAP {
- u32 dw[2];
-};
-
-/* Virtual Address. */
-struct BE_VIRT_ADDR_AMAP {
- u8 lo[32]; /* DWORD 0 */
- u8 hi[32]; /* DWORD 1 */
-} __packed;
-struct VIRT_ADDR_AMAP {
- u32 dw[2];
-};
-
-/* Scatter gather element. */
-struct BE_SGE_AMAP {
- u8 addr_hi[32]; /* DWORD 0 */
- u8 addr_lo[32]; /* DWORD 1 */
- u8 rsvd0[32]; /* DWORD 2 */
- u8 len[16]; /* DWORD 3 */
- u8 rsvd1[16]; /* DWORD 3 */
-} __packed;
-struct SGE_AMAP {
- u32 dw[4];
-};
-
-#endif /* __be_common_amap_h__ */
diff --git a/drivers/staging/benet/be_ethtool.c b/drivers/staging/benet/be_ethtool.c
deleted file mode 100644
index 027af85707aa..000000000000
--- a/drivers/staging/benet/be_ethtool.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * be_ethtool.c
- *
- * This file contains various functions that ethtool can use
- * to talk to the driver and the BE H/W.
- */
-
-#include "benet.h"
-
-#include <linux/ethtool.h>
-
-static const char benet_gstrings_stats[][ETH_GSTRING_LEN] = {
-/* net_device_stats */
- "rx_packets",
- "tx_packets",
- "rx_bytes",
- "tx_bytes",
- "rx_errors",
- "tx_errors",
- "rx_dropped",
- "tx_dropped",
- "multicast",
- "collisions",
- "rx_length_errors",
- "rx_over_errors",
- "rx_crc_errors",
- "rx_frame_errors",
- "rx_fifo_errors",
- "rx_missed_errors",
- "tx_aborted_errors",
- "tx_carrier_errors",
- "tx_fifo_errors",
- "tx_heartbeat_errors",
- "tx_window_errors",
- "rx_compressed",
- "tc_compressed",
-/* BE driver Stats */
- "bes_tx_reqs",
- "bes_tx_fails",
- "bes_fwd_reqs",
- "bes_tx_wrbs",
- "bes_interrupts",
- "bes_events",
- "bes_tx_events",
- "bes_rx_events",
- "bes_tx_compl",
- "bes_rx_compl",
- "bes_ethrx_post_fail",
- "bes_802_3_dropped_frames",
- "bes_802_3_malformed_frames",
- "bes_rx_misc_pkts",
- "bes_eth_tx_rate",
- "bes_eth_rx_rate",
- "Num Packets collected",
- "Num Times Flushed",
-};
-
-#define NET_DEV_STATS_LEN \
- (sizeof(struct net_device_stats)/sizeof(unsigned long))
-
-#define BENET_STATS_LEN ARRAY_SIZE(benet_gstrings_stats)
-
-static void
-be_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- strncpy(drvinfo->driver, be_driver_name, 32);
- strncpy(drvinfo->version, be_drvr_ver, 32);
- strncpy(drvinfo->fw_version, be_fw_ver, 32);
- strcpy(drvinfo->bus_info, pci_name(adapter->pdev));
- drvinfo->testinfo_len = 0;
- drvinfo->regdump_len = 0;
- drvinfo->eedump_len = 0;
-}
-
-static int
-be_get_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- coalesce->rx_max_coalesced_frames = adapter->max_rx_coal;
-
- coalesce->rx_coalesce_usecs = adapter->cur_eqd;
- coalesce->rx_coalesce_usecs_high = adapter->max_eqd;
- coalesce->rx_coalesce_usecs_low = adapter->min_eqd;
-
- coalesce->tx_coalesce_usecs = adapter->cur_eqd;
- coalesce->tx_coalesce_usecs_high = adapter->max_eqd;
- coalesce->tx_coalesce_usecs_low = adapter->min_eqd;
-
- coalesce->use_adaptive_rx_coalesce = adapter->enable_aic;
- coalesce->use_adaptive_tx_coalesce = adapter->enable_aic;
-
- return 0;
-}
-
-/*
- * This routine is used to set interrup coalescing delay *as well as*
- * the number of pkts to coalesce for LRO.
- */
-static int
-be_set_coalesce(struct net_device *netdev, struct ethtool_coalesce *coalesce)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- struct be_eq_object *eq_objectp;
- u32 max, min, cur;
- int status;
-
- adapter->max_rx_coal = coalesce->rx_max_coalesced_frames;
- if (adapter->max_rx_coal >= BE_LRO_MAX_PKTS)
- adapter->max_rx_coal = BE_LRO_MAX_PKTS;
-
- if (adapter->enable_aic == 0 &&
- coalesce->use_adaptive_rx_coalesce == 1) {
- /* if AIC is being turned on now, start with an EQD of 0 */
- adapter->cur_eqd = 0;
- }
- adapter->enable_aic = coalesce->use_adaptive_rx_coalesce;
-
- /* round off to nearest multiple of 8 */
- max = (((coalesce->rx_coalesce_usecs_high + 4) >> 3) << 3);
- min = (((coalesce->rx_coalesce_usecs_low + 4) >> 3) << 3);
- cur = (((coalesce->rx_coalesce_usecs + 4) >> 3) << 3);
-
- if (adapter->enable_aic) {
- /* accept low and high if AIC is enabled */
- if (max > MAX_EQD)
- max = MAX_EQD;
- if (min > max)
- min = max;
- adapter->max_eqd = max;
- adapter->min_eqd = min;
- if (adapter->cur_eqd > max)
- adapter->cur_eqd = max;
- if (adapter->cur_eqd < min)
- adapter->cur_eqd = min;
- } else {
- /* accept specified coalesce_usecs only if AIC is disabled */
- if (cur > MAX_EQD)
- cur = MAX_EQD;
- eq_objectp = &pnob->event_q_obj;
- status =
- be_eq_modify_delay(&pnob->fn_obj, 1, &eq_objectp, &cur,
- NULL, NULL, NULL);
- if (status == BE_SUCCESS)
- adapter->cur_eqd = cur;
- }
- return 0;
-}
-
-static u32 be_get_rx_csum(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- return adapter->rx_csum;
-}
-
-static int be_set_rx_csum(struct net_device *netdev, uint32_t data)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- if (data)
- adapter->rx_csum = 1;
- else
- adapter->rx_csum = 0;
-
- return 0;
-}
-
-static void
-be_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data)
-{
- switch (stringset) {
- case ETH_SS_STATS:
- memcpy(data, *benet_gstrings_stats,
- sizeof(benet_gstrings_stats));
- break;
- }
-}
-
-static int be_get_stats_count(struct net_device *netdev)
-{
- return BENET_STATS_LEN;
-}
-
-static void
-be_get_ethtool_stats(struct net_device *netdev,
- struct ethtool_stats *stats, uint64_t *data)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- int i;
-
- benet_get_stats(netdev);
-
- for (i = 0; i <= NET_DEV_STATS_LEN; i++)
- data[i] = ((unsigned long *)&adapter->benet_stats)[i];
-
- data[i] = adapter->be_stat.bes_tx_reqs;
- data[i++] = adapter->be_stat.bes_tx_fails;
- data[i++] = adapter->be_stat.bes_fwd_reqs;
- data[i++] = adapter->be_stat.bes_tx_wrbs;
-
- data[i++] = adapter->be_stat.bes_ints;
- data[i++] = adapter->be_stat.bes_events;
- data[i++] = adapter->be_stat.bes_tx_events;
- data[i++] = adapter->be_stat.bes_rx_events;
- data[i++] = adapter->be_stat.bes_tx_compl;
- data[i++] = adapter->be_stat.bes_rx_compl;
- data[i++] = adapter->be_stat.bes_ethrx_post_fail;
- data[i++] = adapter->be_stat.bes_802_3_dropped_frames;
- data[i++] = adapter->be_stat.bes_802_3_malformed_frames;
- data[i++] = adapter->be_stat.bes_rx_misc_pkts;
- data[i++] = adapter->be_stat.bes_eth_tx_rate;
- data[i++] = adapter->be_stat.bes_eth_rx_rate;
- data[i++] = adapter->be_stat.bes_rx_coal;
- data[i++] = adapter->be_stat.bes_rx_flush;
-
-}
-
-static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
-{
- ecmd->speed = SPEED_10000;
- ecmd->duplex = DUPLEX_FULL;
- ecmd->autoneg = AUTONEG_DISABLE;
- return 0;
-}
-
-/* Get the Ring parameters from the pnob */
-static void
-be_get_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- /* Pre Set Maxims */
- ring->rx_max_pending = pnob->rx_q_len;
- ring->rx_mini_max_pending = ring->rx_mini_max_pending;
- ring->rx_jumbo_max_pending = ring->rx_jumbo_max_pending;
- ring->tx_max_pending = pnob->tx_q_len;
-
- /* Current hardware Settings */
- ring->rx_pending = atomic_read(&pnob->rx_q_posted);
- ring->rx_mini_pending = ring->rx_mini_pending;
- ring->rx_jumbo_pending = ring->rx_jumbo_pending;
- ring->tx_pending = atomic_read(&pnob->tx_q_used);
-
-}
-
-static void
-be_get_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- bool rxfc, txfc;
- int status;
-
- status = be_eth_get_flow_control(&pnob->fn_obj, &txfc, &rxfc);
- if (status != BE_SUCCESS) {
- dev_info(&netdev->dev, "Unable to get pause frame settings\n");
- /* return defaults */
- ecmd->rx_pause = 1;
- ecmd->tx_pause = 0;
- ecmd->autoneg = AUTONEG_ENABLE;
- return;
- }
-
- if (txfc == true)
- ecmd->tx_pause = 1;
- else
- ecmd->tx_pause = 0;
-
- if (rxfc == true)
- ecmd->rx_pause = 1;
- else
- ecmd->rx_pause = 0;
-
- ecmd->autoneg = AUTONEG_ENABLE;
-}
-
-static int
-be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- bool txfc, rxfc;
- int status;
-
- if (ecmd->autoneg != AUTONEG_ENABLE)
- return -EINVAL;
-
- if (ecmd->tx_pause)
- txfc = true;
- else
- txfc = false;
-
- if (ecmd->rx_pause)
- rxfc = true;
- else
- rxfc = false;
-
- status = be_eth_set_flow_control(&pnob->fn_obj, txfc, rxfc);
- if (status != BE_SUCCESS) {
- dev_info(&netdev->dev, "Unable to set pause frame settings\n");
- return -1;
- }
- return 0;
-}
-
-struct ethtool_ops be_ethtool_ops = {
- .get_settings = be_get_settings,
- .get_drvinfo = be_get_drvinfo,
- .get_link = ethtool_op_get_link,
- .get_coalesce = be_get_coalesce,
- .set_coalesce = be_set_coalesce,
- .get_ringparam = be_get_ringparam,
- .get_pauseparam = be_get_pauseparam,
- .set_pauseparam = be_set_pauseparam,
- .get_rx_csum = be_get_rx_csum,
- .set_rx_csum = be_set_rx_csum,
- .get_tx_csum = ethtool_op_get_tx_csum,
- .set_tx_csum = ethtool_op_set_tx_csum,
- .get_sg = ethtool_op_get_sg,
- .set_sg = ethtool_op_set_sg,
- .get_tso = ethtool_op_get_tso,
- .set_tso = ethtool_op_set_tso,
- .get_strings = be_get_strings,
- .get_stats_count = be_get_stats_count,
- .get_ethtool_stats = be_get_ethtool_stats,
-};
diff --git a/drivers/staging/benet/be_init.c b/drivers/staging/benet/be_init.c
deleted file mode 100644
index 12a026c3f9e1..000000000000
--- a/drivers/staging/benet/be_init.c
+++ /dev/null
@@ -1,1382 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include <linux/etherdevice.h>
-#include "benet.h"
-
-#define DRVR_VERSION "1.0.728"
-
-static const struct pci_device_id be_device_id_table[] = {
- {PCI_DEVICE(0x19a2, 0x0201)},
- {0}
-};
-
-MODULE_DEVICE_TABLE(pci, be_device_id_table);
-
-MODULE_VERSION(DRVR_VERSION);
-
-#define DRV_DESCRIPTION "ServerEngines BladeEngine Network Driver Version "
-
-MODULE_DESCRIPTION(DRV_DESCRIPTION DRVR_VERSION);
-MODULE_AUTHOR("ServerEngines");
-MODULE_LICENSE("GPL");
-
-static unsigned int msix = 1;
-module_param(msix, uint, S_IRUGO);
-MODULE_PARM_DESC(msix, "Use MSI-x interrupts");
-
-static unsigned int rxbuf_size = 2048; /* Default RX frag size */
-module_param(rxbuf_size, uint, S_IRUGO);
-MODULE_PARM_DESC(rxbuf_size, "Size of buffers to hold Rx data");
-
-const char be_drvr_ver[] = DRVR_VERSION;
-char be_fw_ver[32]; /* F/W version filled in by be_probe */
-char be_driver_name[] = "benet";
-
-/*
- * Number of entries in each queue.
- */
-#define EVENT_Q_LEN 1024
-#define ETH_TXQ_LEN 2048
-#define ETH_TXCQ_LEN 1024
-#define ETH_RXQ_LEN 1024 /* Does not support any other value */
-#define ETH_UC_RXCQ_LEN 1024
-#define ETH_BC_RXCQ_LEN 256
-#define MCC_Q_LEN 64 /* total size not to exceed 8 pages */
-#define MCC_CQ_LEN 256
-
-/* Bit mask describing events of interest to be traced */
-unsigned int trace_level;
-
-static int
-init_pci_be_function(struct be_adapter *adapter, struct pci_dev *pdev)
-{
- u64 pa;
-
- /* CSR */
- pa = pci_resource_start(pdev, 2);
- adapter->csr_va = ioremap_nocache(pa, pci_resource_len(pdev, 2));
- if (adapter->csr_va == NULL)
- return -ENOMEM;
-
- /* Door Bell */
- pa = pci_resource_start(pdev, 4);
- adapter->db_va = ioremap_nocache(pa, (128 * 1024));
- if (adapter->db_va == NULL) {
- iounmap(adapter->csr_va);
- return -ENOMEM;
- }
-
- /* PCI */
- pa = pci_resource_start(pdev, 1);
- adapter->pci_va = ioremap_nocache(pa, pci_resource_len(pdev, 1));
- if (adapter->pci_va == NULL) {
- iounmap(adapter->csr_va);
- iounmap(adapter->db_va);
- return -ENOMEM;
- }
- return 0;
-}
-
-/*
- This function enables the interrupt corresponding to the Event
- queue ID for the given NetObject
-*/
-void be_enable_eq_intr(struct be_net_object *pnob)
-{
- struct CQ_DB_AMAP cqdb;
- cqdb.dw[0] = 0;
- AMAP_SET_BITS_PTR(CQ_DB, event, &cqdb, 1);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, 1);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, 0);
- AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, pnob->event_q_id);
- PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]);
-}
-
-/*
- This function disables the interrupt corresponding to the Event
- queue ID for the given NetObject
-*/
-void be_disable_eq_intr(struct be_net_object *pnob)
-{
- struct CQ_DB_AMAP cqdb;
- cqdb.dw[0] = 0;
- AMAP_SET_BITS_PTR(CQ_DB, event, &cqdb, 1);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, 0);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, 0);
- AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, pnob->event_q_id);
- PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]);
-}
-
-/*
- This function enables the interrupt from the network function
- of the BladeEngine. Use the function be_disable_eq_intr()
- to enable the interrupt from the event queue of only one specific
- NetObject
-*/
-void be_enable_intr(struct be_net_object *pnob)
-{
- struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl;
- u32 host_intr;
-
- ctrl.dw[0] = PCICFG1_READ(&pnob->fn_obj, host_timer_int_ctrl);
- host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR,
- hostintr, ctrl.dw);
- if (!host_intr) {
- AMAP_SET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR,
- hostintr, ctrl.dw, 1);
- PCICFG1_WRITE(&pnob->fn_obj, host_timer_int_ctrl,
- ctrl.dw[0]);
- }
-}
-
-/*
- This function disables the interrupt from the network function of
- the BladeEngine. Use the function be_disable_eq_intr() to
- disable the interrupt from the event queue of only one specific NetObject
-*/
-void be_disable_intr(struct be_net_object *pnob)
-{
-
- struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl;
- u32 host_intr;
- ctrl.dw[0] = PCICFG1_READ(&pnob->fn_obj, host_timer_int_ctrl);
- host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR,
- hostintr, ctrl.dw);
- if (host_intr) {
- AMAP_SET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR, hostintr,
- ctrl.dw, 0);
- PCICFG1_WRITE(&pnob->fn_obj, host_timer_int_ctrl,
- ctrl.dw[0]);
- }
-}
-
-static int be_enable_msix(struct be_adapter *adapter)
-{
- int i, ret;
-
- if (!msix)
- return -1;
-
- for (i = 0; i < BE_MAX_REQ_MSIX_VECTORS; i++)
- adapter->msix_entries[i].entry = i;
-
- ret = pci_enable_msix(adapter->pdev, adapter->msix_entries,
- BE_MAX_REQ_MSIX_VECTORS);
-
- if (ret == 0)
- adapter->msix_enabled = 1;
- return ret;
-}
-
-static int be_register_isr(struct be_adapter *adapter,
- struct be_net_object *pnob)
-{
- struct net_device *netdev = pnob->netdev;
- int intx = 0, r;
-
- netdev->irq = adapter->pdev->irq;
- r = be_enable_msix(adapter);
-
- if (r == 0) {
- r = request_irq(adapter->msix_entries[0].vector,
- be_int, IRQF_SHARED, netdev->name, netdev);
- if (r) {
- printk(KERN_WARNING
- "MSIX Request IRQ failed - Errno %d\n", r);
- intx = 1;
- pci_disable_msix(adapter->pdev);
- adapter->msix_enabled = 0;
- }
- } else {
- intx = 1;
- }
-
- if (intx) {
- r = request_irq(netdev->irq, be_int, IRQF_SHARED,
- netdev->name, netdev);
- if (r) {
- printk(KERN_WARNING
- "INTx Request IRQ failed - Errno %d\n", r);
- return -1;
- }
- }
- adapter->isr_registered = 1;
- return 0;
-}
-
-static void be_unregister_isr(struct be_adapter *adapter)
-{
- struct net_device *netdev = adapter->netdevp;
- if (adapter->isr_registered) {
- if (adapter->msix_enabled) {
- free_irq(adapter->msix_entries[0].vector, netdev);
- pci_disable_msix(adapter->pdev);
- adapter->msix_enabled = 0;
- } else {
- free_irq(netdev->irq, netdev);
- }
- adapter->isr_registered = 0;
- }
-}
-
-/*
- This function processes the Flush Completions that are issued by the
- ARM F/W, when a Recv Ring is destroyed. A flush completion is
- identified when a Rx COmpl descriptor has the tcpcksum and udpcksum
- set and the pktsize is 32. These completions are received on the
- Rx Completion Queue.
-*/
-static u32 be_process_rx_flush_cmpl(struct be_net_object *pnob)
-{
- struct ETH_RX_COMPL_AMAP *rxcp;
- unsigned int i = 0;
- while ((rxcp = be_get_rx_cmpl(pnob)) != NULL) {
- be_notify_cmpl(pnob, 1, pnob->rx_cq_id, 1);
- i++;
- }
- return i;
-}
-
-static void be_tx_q_clean(struct be_net_object *pnob)
-{
- while (atomic_read(&pnob->tx_q_used))
- process_one_tx_compl(pnob, tx_compl_lastwrb_idx_get(pnob));
-}
-
-static void be_rx_q_clean(struct be_net_object *pnob)
-{
- if (pnob->rx_ctxt) {
- int i;
- struct be_rx_page_info *rx_page_info;
- for (i = 0; i < pnob->rx_q_len; i++) {
- rx_page_info = &(pnob->rx_page_info[i]);
- if (!pnob->rx_pg_shared || rx_page_info->page_offset) {
- pci_unmap_page(pnob->adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- pnob->rx_buf_size,
- PCI_DMA_FROMDEVICE);
- }
- if (rx_page_info->page)
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- }
- pnob->rx_pg_info_hd = 0;
- }
-}
-
-static void be_destroy_netobj(struct be_net_object *pnob)
-{
- int status;
-
- if (pnob->tx_q_created) {
- status = be_eth_sq_destroy(&pnob->tx_q_obj);
- pnob->tx_q_created = 0;
- }
-
- if (pnob->rx_q_created) {
- status = be_eth_rq_destroy(&pnob->rx_q_obj);
- if (status != 0) {
- status = be_eth_rq_destroy_options(&pnob->rx_q_obj, 0,
- NULL, NULL);
- BUG_ON(status);
- }
- pnob->rx_q_created = 0;
- }
-
- be_process_rx_flush_cmpl(pnob);
-
- if (pnob->tx_cq_created) {
- status = be_cq_destroy(&pnob->tx_cq_obj);
- pnob->tx_cq_created = 0;
- }
-
- if (pnob->rx_cq_created) {
- status = be_cq_destroy(&pnob->rx_cq_obj);
- pnob->rx_cq_created = 0;
- }
-
- if (pnob->mcc_q_created) {
- status = be_mcc_ring_destroy(&pnob->mcc_q_obj);
- pnob->mcc_q_created = 0;
- }
- if (pnob->mcc_cq_created) {
- status = be_cq_destroy(&pnob->mcc_cq_obj);
- pnob->mcc_cq_created = 0;
- }
-
- if (pnob->event_q_created) {
- status = be_eq_destroy(&pnob->event_q_obj);
- pnob->event_q_created = 0;
- }
- be_function_cleanup(&pnob->fn_obj);
-}
-
-/*
- * free all resources associated with a pnob
- * Called at the time of module cleanup as well a any error during
- * module init. Some resources may be partially allocated in a NetObj.
- */
-static void netobject_cleanup(struct be_adapter *adapter,
- struct be_net_object *pnob)
-{
- struct net_device *netdev = adapter->netdevp;
-
- if (netif_running(netdev)) {
- netif_stop_queue(netdev);
- be_wait_nic_tx_cmplx_cmpl(pnob);
- be_disable_eq_intr(pnob);
- }
-
- be_unregister_isr(adapter);
-
- if (adapter->tasklet_started) {
- tasklet_kill(&(adapter->sts_handler));
- adapter->tasklet_started = 0;
- }
- if (pnob->fn_obj_created)
- be_disable_intr(pnob);
-
- if (adapter->dev_state != BE_DEV_STATE_NONE)
- unregister_netdev(netdev);
-
- if (pnob->fn_obj_created)
- be_destroy_netobj(pnob);
-
- adapter->net_obj = NULL;
- adapter->netdevp = NULL;
-
- be_rx_q_clean(pnob);
- if (pnob->rx_ctxt) {
- kfree(pnob->rx_page_info);
- kfree(pnob->rx_ctxt);
- }
-
- be_tx_q_clean(pnob);
- kfree(pnob->tx_ctxt);
-
- if (pnob->mcc_q)
- pci_free_consistent(adapter->pdev, pnob->mcc_q_size,
- pnob->mcc_q, pnob->mcc_q_bus);
-
- if (pnob->mcc_wrb_ctxt)
- free_pages((unsigned long)pnob->mcc_wrb_ctxt,
- get_order(pnob->mcc_wrb_ctxt_size));
-
- if (pnob->mcc_cq)
- pci_free_consistent(adapter->pdev, pnob->mcc_cq_size,
- pnob->mcc_cq, pnob->mcc_cq_bus);
-
- if (pnob->event_q)
- pci_free_consistent(adapter->pdev, pnob->event_q_size,
- pnob->event_q, pnob->event_q_bus);
-
- if (pnob->tx_cq)
- pci_free_consistent(adapter->pdev, pnob->tx_cq_size,
- pnob->tx_cq, pnob->tx_cq_bus);
-
- if (pnob->tx_q)
- pci_free_consistent(adapter->pdev, pnob->tx_q_size,
- pnob->tx_q, pnob->tx_q_bus);
-
- if (pnob->rx_q)
- pci_free_consistent(adapter->pdev, pnob->rx_q_size,
- pnob->rx_q, pnob->rx_q_bus);
-
- if (pnob->rx_cq)
- pci_free_consistent(adapter->pdev, pnob->rx_cq_size,
- pnob->rx_cq, pnob->rx_cq_bus);
-
-
- if (pnob->mb_ptr)
- pci_free_consistent(adapter->pdev, pnob->mb_size, pnob->mb_ptr,
- pnob->mb_bus);
-
- free_netdev(netdev);
-}
-
-
-static int be_nob_ring_alloc(struct be_adapter *adapter,
- struct be_net_object *pnob)
-{
- u32 size;
-
- /* Mail box rd; mailbox pointer needs to be 16 byte aligned */
- pnob->mb_size = sizeof(struct MCC_MAILBOX_AMAP) + 16;
- pnob->mb_ptr = pci_alloc_consistent(adapter->pdev, pnob->mb_size,
- &pnob->mb_bus);
- if (!pnob->mb_bus)
- return -1;
- memset(pnob->mb_ptr, 0, pnob->mb_size);
- pnob->mb_rd.va = PTR_ALIGN(pnob->mb_ptr, 16);
- pnob->mb_rd.pa = PTR_ALIGN(pnob->mb_bus, 16);
- pnob->mb_rd.length = sizeof(struct MCC_MAILBOX_AMAP);
- /*
- * Event queue
- */
- pnob->event_q_len = EVENT_Q_LEN;
- pnob->event_q_size = pnob->event_q_len * sizeof(struct EQ_ENTRY_AMAP);
- pnob->event_q = pci_alloc_consistent(adapter->pdev, pnob->event_q_size,
- &pnob->event_q_bus);
- if (!pnob->event_q_bus)
- return -1;
- memset(pnob->event_q, 0, pnob->event_q_size);
- /*
- * Eth TX queue
- */
- pnob->tx_q_len = ETH_TXQ_LEN;
- pnob->tx_q_port = 0;
- pnob->tx_q_size = pnob->tx_q_len * sizeof(struct ETH_WRB_AMAP);
- pnob->tx_q = pci_alloc_consistent(adapter->pdev, pnob->tx_q_size,
- &pnob->tx_q_bus);
- if (!pnob->tx_q_bus)
- return -1;
- memset(pnob->tx_q, 0, pnob->tx_q_size);
- /*
- * Eth TX Compl queue
- */
- pnob->txcq_len = ETH_TXCQ_LEN;
- pnob->tx_cq_size = pnob->txcq_len * sizeof(struct ETH_TX_COMPL_AMAP);
- pnob->tx_cq = pci_alloc_consistent(adapter->pdev, pnob->tx_cq_size,
- &pnob->tx_cq_bus);
- if (!pnob->tx_cq_bus)
- return -1;
- memset(pnob->tx_cq, 0, pnob->tx_cq_size);
- /*
- * Eth RX queue
- */
- pnob->rx_q_len = ETH_RXQ_LEN;
- pnob->rx_q_size = pnob->rx_q_len * sizeof(struct ETH_RX_D_AMAP);
- pnob->rx_q = pci_alloc_consistent(adapter->pdev, pnob->rx_q_size,
- &pnob->rx_q_bus);
- if (!pnob->rx_q_bus)
- return -1;
- memset(pnob->rx_q, 0, pnob->rx_q_size);
- /*
- * Eth Unicast RX Compl queue
- */
- pnob->rx_cq_len = ETH_UC_RXCQ_LEN;
- pnob->rx_cq_size = pnob->rx_cq_len *
- sizeof(struct ETH_RX_COMPL_AMAP);
- pnob->rx_cq = pci_alloc_consistent(adapter->pdev, pnob->rx_cq_size,
- &pnob->rx_cq_bus);
- if (!pnob->rx_cq_bus)
- return -1;
- memset(pnob->rx_cq, 0, pnob->rx_cq_size);
-
- /* TX resources */
- size = pnob->tx_q_len * sizeof(void **);
- pnob->tx_ctxt = kzalloc(size, GFP_KERNEL);
- if (pnob->tx_ctxt == NULL)
- return -1;
-
- /* RX resources */
- size = pnob->rx_q_len * sizeof(void *);
- pnob->rx_ctxt = kzalloc(size, GFP_KERNEL);
- if (pnob->rx_ctxt == NULL)
- return -1;
-
- size = (pnob->rx_q_len * sizeof(struct be_rx_page_info));
- pnob->rx_page_info = kzalloc(size, GFP_KERNEL);
- if (pnob->rx_page_info == NULL)
- return -1;
-
- adapter->eth_statsp = kzalloc(sizeof(struct FWCMD_ETH_GET_STATISTICS),
- GFP_KERNEL);
- if (adapter->eth_statsp == NULL)
- return -1;
- pnob->rx_buf_size = rxbuf_size;
- return 0;
-}
-
-/*
- This function initializes the be_net_object for subsequent
- network operations.
-
- Before calling this function, the driver must have allocated
- space for the NetObject structure, initialized the structure,
- allocated DMAable memory for all the network queues that form
- part of the NetObject and populated the start address (virtual)
- and number of entries allocated for each queue in the NetObject structure.
-
- The driver must also have allocated memory to hold the
- mailbox structure (MCC_MAILBOX) and post the physical address,
- virtual addresses and the size of the mailbox memory in the
- NetObj.mb_rd. This structure is used by BECLIB for
- initial communication with the embedded MCC processor. BECLIB
- uses the mailbox until MCC rings are created for more efficient
- communication with the MCC processor.
-
- If the driver wants to create multiple network interface for more
- than one protection domain, it can call be_create_netobj()
- multiple times once for each protection domain. A Maximum of
- 32 protection domains are supported.
-
-*/
-static int
-be_create_netobj(struct be_net_object *pnob, u8 __iomem *csr_va,
- u8 __iomem *db_va, u8 __iomem *pci_va)
-{
- int status = 0;
- bool eventable = false, tx_no_delay = false, rx_no_delay = false;
- struct be_eq_object *eq_objectp = NULL;
- struct be_function_object *pfob = &pnob->fn_obj;
- struct ring_desc rd;
- u32 set_rxbuf_size;
- u32 tx_cmpl_wm = CEV_WMARK_96; /* 0xffffffff to disable */
- u32 rx_cmpl_wm = CEV_WMARK_160; /* 0xffffffff to disable */
- u32 eq_delay = 0; /* delay in 8usec units. 0xffffffff to disable */
-
- memset(&rd, 0, sizeof(struct ring_desc));
-
- status = be_function_object_create(csr_va, db_va, pci_va,
- BE_FUNCTION_TYPE_NETWORK, &pnob->mb_rd, pfob);
- if (status != BE_SUCCESS)
- return status;
- pnob->fn_obj_created = true;
-
- if (tx_cmpl_wm == 0xffffffff)
- tx_no_delay = true;
- if (rx_cmpl_wm == 0xffffffff)
- rx_no_delay = true;
- /*
- * now create the necessary rings
- * Event Queue first.
- */
- if (pnob->event_q_len) {
- rd.va = pnob->event_q;
- rd.pa = pnob->event_q_bus;
- rd.length = pnob->event_q_size;
-
- status = be_eq_create(pfob, &rd, 4, pnob->event_q_len,
- (u32) -1, /* CEV_WMARK_* or -1 */
- eq_delay, /* in 8us units, or -1 */
- &pnob->event_q_obj);
- if (status != BE_SUCCESS)
- goto error_ret;
- pnob->event_q_id = pnob->event_q_obj.eq_id;
- pnob->event_q_created = 1;
- eventable = true;
- eq_objectp = &pnob->event_q_obj;
- }
- /*
- * Now Eth Tx Compl. queue.
- */
- if (pnob->txcq_len) {
- rd.va = pnob->tx_cq;
- rd.pa = pnob->tx_cq_bus;
- rd.length = pnob->tx_cq_size;
-
- status = be_cq_create(pfob, &rd,
- pnob->txcq_len * sizeof(struct ETH_TX_COMPL_AMAP),
- false, /* solicted events, */
- tx_no_delay, /* nodelay */
- tx_cmpl_wm, /* Watermark encodings */
- eq_objectp, &pnob->tx_cq_obj);
- if (status != BE_SUCCESS)
- goto error_ret;
-
- pnob->tx_cq_id = pnob->tx_cq_obj.cq_id;
- pnob->tx_cq_created = 1;
- }
- /*
- * Eth Tx queue
- */
- if (pnob->tx_q_len) {
- struct be_eth_sq_parameters ex_params = { 0 };
- u32 type;
-
- if (pnob->tx_q_port) {
- /* TXQ to be bound to a specific port */
- type = BE_ETH_TX_RING_TYPE_BOUND;
- ex_params.port = pnob->tx_q_port - 1;
- } else
- type = BE_ETH_TX_RING_TYPE_STANDARD;
-
- rd.va = pnob->tx_q;
- rd.pa = pnob->tx_q_bus;
- rd.length = pnob->tx_q_size;
-
- status = be_eth_sq_create_ex(pfob, &rd,
- pnob->tx_q_len * sizeof(struct ETH_WRB_AMAP),
- type, 2, &pnob->tx_cq_obj,
- &ex_params, &pnob->tx_q_obj);
-
- if (status != BE_SUCCESS)
- goto error_ret;
-
- pnob->tx_q_id = pnob->tx_q_obj.bid;
- pnob->tx_q_created = 1;
- }
- /*
- * Now Eth Rx compl. queue. Always needed.
- */
- rd.va = pnob->rx_cq;
- rd.pa = pnob->rx_cq_bus;
- rd.length = pnob->rx_cq_size;
-
- status = be_cq_create(pfob, &rd,
- pnob->rx_cq_len * sizeof(struct ETH_RX_COMPL_AMAP),
- false, /* solicted events, */
- rx_no_delay, /* nodelay */
- rx_cmpl_wm, /* Watermark encodings */
- eq_objectp, &pnob->rx_cq_obj);
- if (status != BE_SUCCESS)
- goto error_ret;
-
- pnob->rx_cq_id = pnob->rx_cq_obj.cq_id;
- pnob->rx_cq_created = 1;
-
- status = be_eth_rq_set_frag_size(pfob, pnob->rx_buf_size,
- (u32 *) &set_rxbuf_size);
- if (status != BE_SUCCESS) {
- be_eth_rq_get_frag_size(pfob, (u32 *) &pnob->rx_buf_size);
- if ((pnob->rx_buf_size != 2048) && (pnob->rx_buf_size != 4096)
- && (pnob->rx_buf_size != 8192))
- goto error_ret;
- } else {
- if (pnob->rx_buf_size != set_rxbuf_size)
- pnob->rx_buf_size = set_rxbuf_size;
- }
- /*
- * Eth RX queue. be_eth_rq_create() always assumes 2 pages size
- */
- rd.va = pnob->rx_q;
- rd.pa = pnob->rx_q_bus;
- rd.length = pnob->rx_q_size;
-
- status = be_eth_rq_create(pfob, &rd, &pnob->rx_cq_obj,
- &pnob->rx_cq_obj, &pnob->rx_q_obj);
-
- if (status != BE_SUCCESS)
- goto error_ret;
-
- pnob->rx_q_id = pnob->rx_q_obj.rid;
- pnob->rx_q_created = 1;
-
- return BE_SUCCESS; /* All required queues created. */
-
-error_ret:
- be_destroy_netobj(pnob);
- return status;
-}
-
-static int be_nob_ring_init(struct be_adapter *adapter,
- struct be_net_object *pnob)
-{
- int status;
-
- pnob->event_q_tl = 0;
-
- pnob->tx_q_hd = 0;
- pnob->tx_q_tl = 0;
-
- pnob->tx_cq_tl = 0;
-
- pnob->rx_cq_tl = 0;
-
- memset(pnob->event_q, 0, pnob->event_q_size);
- memset(pnob->tx_cq, 0, pnob->tx_cq_size);
- memset(pnob->tx_ctxt, 0, pnob->tx_q_len * sizeof(void **));
- memset(pnob->rx_ctxt, 0, pnob->rx_q_len * sizeof(void *));
- pnob->rx_pg_info_hd = 0;
- pnob->rx_q_hd = 0;
- atomic_set(&pnob->rx_q_posted, 0);
-
- status = be_create_netobj(pnob, adapter->csr_va, adapter->db_va,
- adapter->pci_va);
- if (status != BE_SUCCESS)
- return -1;
-
- be_post_eth_rx_buffs(pnob);
- return 0;
-}
-
-/* This function handles async callback for link status */
-static void
-be_link_status_async_callback(void *context, u32 event_code, void *event)
-{
- struct ASYNC_EVENT_LINK_STATE_AMAP *link_status = event;
- struct be_adapter *adapter = context;
- bool link_enable = false;
- struct be_net_object *pnob;
- struct ASYNC_EVENT_TRAILER_AMAP *async_trailer;
- struct net_device *netdev;
- u32 async_event_code, async_event_type, active_port;
- u32 port0_link_status, port1_link_status, port0_duplex, port1_duplex;
- u32 port0_speed, port1_speed;
-
- if (event_code != ASYNC_EVENT_CODE_LINK_STATE) {
- /* Not our event to handle */
- return;
- }
- async_trailer = (struct ASYNC_EVENT_TRAILER_AMAP *)
- ((u8 *) event + sizeof(struct MCC_CQ_ENTRY_AMAP) -
- sizeof(struct ASYNC_EVENT_TRAILER_AMAP));
-
- async_event_code = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, event_code,
- async_trailer);
- BUG_ON(async_event_code != ASYNC_EVENT_CODE_LINK_STATE);
-
- pnob = adapter->net_obj;
- netdev = pnob->netdev;
-
- /* Determine if this event is a switch VLD or a physical link event */
- async_event_type = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER, event_type,
- async_trailer);
- active_port = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- active_port, link_status);
- port0_link_status = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port0_link_status, link_status);
- port1_link_status = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port1_link_status, link_status);
- port0_duplex = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port0_duplex, link_status);
- port1_duplex = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port1_duplex, link_status);
- port0_speed = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port0_speed, link_status);
- port1_speed = AMAP_GET_BITS_PTR(ASYNC_EVENT_LINK_STATE,
- port1_speed, link_status);
- if (async_event_type == NTWK_LINK_TYPE_VIRTUAL) {
- adapter->be_stat.bes_link_change_virtual++;
- if (adapter->be_link_sts->active_port != active_port) {
- dev_notice(&netdev->dev,
- "Active port changed due to VLD on switch\n");
- } else {
- dev_notice(&netdev->dev, "Link status update\n");
- }
-
- } else {
- adapter->be_stat.bes_link_change_physical++;
- if (adapter->be_link_sts->active_port != active_port) {
- dev_notice(&netdev->dev,
- "Active port changed due to port link"
- " status change\n");
- } else {
- dev_notice(&netdev->dev, "Link status update\n");
- }
- }
-
- memset(adapter->be_link_sts, 0, sizeof(adapter->be_link_sts));
-
- if ((port0_link_status == ASYNC_EVENT_LINK_UP) ||
- (port1_link_status == ASYNC_EVENT_LINK_UP)) {
- if ((adapter->port0_link_sts == BE_PORT_LINK_DOWN) &&
- (adapter->port1_link_sts == BE_PORT_LINK_DOWN)) {
- /* Earlier both the ports are down So link is up */
- link_enable = true;
- }
-
- if (port0_link_status == ASYNC_EVENT_LINK_UP) {
- adapter->port0_link_sts = BE_PORT_LINK_UP;
- adapter->be_link_sts->mac0_duplex = port0_duplex;
- adapter->be_link_sts->mac0_speed = port0_speed;
- if (active_port == NTWK_PORT_A)
- adapter->be_link_sts->active_port = 0;
- } else
- adapter->port0_link_sts = BE_PORT_LINK_DOWN;
-
- if (port1_link_status == ASYNC_EVENT_LINK_UP) {
- adapter->port1_link_sts = BE_PORT_LINK_UP;
- adapter->be_link_sts->mac1_duplex = port1_duplex;
- adapter->be_link_sts->mac1_speed = port1_speed;
- if (active_port == NTWK_PORT_B)
- adapter->be_link_sts->active_port = 1;
- } else
- adapter->port1_link_sts = BE_PORT_LINK_DOWN;
-
- printk(KERN_INFO "Link Properties for %s:\n", netdev->name);
- dev_info(&netdev->dev, "Link Properties:\n");
- be_print_link_info(adapter->be_link_sts);
-
- if (!link_enable)
- return;
- /*
- * Both ports were down previously, but atleast one of
- * them has come up if this netdevice's carrier is not up,
- * then indicate to stack
- */
- if (!netif_carrier_ok(netdev)) {
- netif_start_queue(netdev);
- netif_carrier_on(netdev);
- }
- return;
- }
-
- /* Now both the ports are down. Tell the stack about it */
- dev_info(&netdev->dev, "Both ports are down\n");
- adapter->port0_link_sts = BE_PORT_LINK_DOWN;
- adapter->port1_link_sts = BE_PORT_LINK_DOWN;
- if (netif_carrier_ok(netdev)) {
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
- }
- return;
-}
-
-static int be_mcc_create(struct be_adapter *adapter)
-{
- struct be_net_object *pnob;
-
- pnob = adapter->net_obj;
- /*
- * Create the MCC ring so that all further communication with
- * MCC can go thru the ring. we do this at the end since
- * we do not want to be dealing with interrupts until the
- * initialization is complete.
- */
- pnob->mcc_q_len = MCC_Q_LEN;
- pnob->mcc_q_size = pnob->mcc_q_len * sizeof(struct MCC_WRB_AMAP);
- pnob->mcc_q = pci_alloc_consistent(adapter->pdev, pnob->mcc_q_size,
- &pnob->mcc_q_bus);
- if (!pnob->mcc_q_bus)
- return -1;
- /*
- * space for MCC WRB context
- */
- pnob->mcc_wrb_ctxtLen = MCC_Q_LEN;
- pnob->mcc_wrb_ctxt_size = pnob->mcc_wrb_ctxtLen *
- sizeof(struct be_mcc_wrb_context);
- pnob->mcc_wrb_ctxt = (void *)__get_free_pages(GFP_KERNEL,
- get_order(pnob->mcc_wrb_ctxt_size));
- if (pnob->mcc_wrb_ctxt == NULL)
- return -1;
- /*
- * Space for MCC compl. ring
- */
- pnob->mcc_cq_len = MCC_CQ_LEN;
- pnob->mcc_cq_size = pnob->mcc_cq_len * sizeof(struct MCC_CQ_ENTRY_AMAP);
- pnob->mcc_cq = pci_alloc_consistent(adapter->pdev, pnob->mcc_cq_size,
- &pnob->mcc_cq_bus);
- if (!pnob->mcc_cq_bus)
- return -1;
- return 0;
-}
-
-/*
- This function creates the MCC request and completion ring required
- for communicating with the ARM processor. The caller must have
- allocated required amount of memory for the MCC ring and MCC
- completion ring and posted the virtual address and number of
- entries in the corresponding members (mcc_q and mcc_cq) in the
- NetObject struture.
-
- When this call is completed, all further communication with
- ARM will switch from mailbox to this ring.
-
- pnob - Pointer to the NetObject structure. This NetObject should
- have been created using a previous call to be_create_netobj()
-*/
-int be_create_mcc_rings(struct be_net_object *pnob)
-{
- int status = 0;
- struct ring_desc rd;
- struct be_function_object *pfob = &pnob->fn_obj;
-
- memset(&rd, 0, sizeof(struct ring_desc));
- if (pnob->mcc_cq_len) {
- rd.va = pnob->mcc_cq;
- rd.pa = pnob->mcc_cq_bus;
- rd.length = pnob->mcc_cq_size;
-
- status = be_cq_create(pfob, &rd,
- pnob->mcc_cq_len * sizeof(struct MCC_CQ_ENTRY_AMAP),
- false, /* solicted events, */
- true, /* nodelay */
- 0, /* 0 Watermark since Nodelay is true */
- &pnob->event_q_obj,
- &pnob->mcc_cq_obj);
-
- if (status != BE_SUCCESS)
- return status;
-
- pnob->mcc_cq_id = pnob->mcc_cq_obj.cq_id;
- pnob->mcc_cq_created = 1;
- }
- if (pnob->mcc_q_len) {
- rd.va = pnob->mcc_q;
- rd.pa = pnob->mcc_q_bus;
- rd.length = pnob->mcc_q_size;
-
- status = be_mcc_ring_create(pfob, &rd,
- pnob->mcc_q_len * sizeof(struct MCC_WRB_AMAP),
- pnob->mcc_wrb_ctxt, pnob->mcc_wrb_ctxtLen,
- &pnob->mcc_cq_obj, &pnob->mcc_q_obj);
-
- if (status != BE_SUCCESS)
- return status;
-
- pnob->mcc_q_created = 1;
- }
- return BE_SUCCESS;
-}
-
-static int be_mcc_init(struct be_adapter *adapter)
-{
- u32 r;
- struct be_net_object *pnob;
-
- pnob = adapter->net_obj;
- memset(pnob->mcc_q, 0, pnob->mcc_q_size);
- pnob->mcc_q_hd = 0;
-
- memset(pnob->mcc_wrb_ctxt, 0, pnob->mcc_wrb_ctxt_size);
-
- memset(pnob->mcc_cq, 0, pnob->mcc_cq_size);
- pnob->mcc_cq_tl = 0;
-
- r = be_create_mcc_rings(adapter->net_obj);
- if (r != BE_SUCCESS)
- return -1;
-
- return 0;
-}
-
-static void be_remove(struct pci_dev *pdev)
-{
- struct be_net_object *pnob;
- struct be_adapter *adapter;
-
- adapter = pci_get_drvdata(pdev);
- if (!adapter)
- return;
-
- pci_set_drvdata(pdev, NULL);
- pnob = (struct be_net_object *)adapter->net_obj;
-
- flush_scheduled_work();
-
- if (pnob) {
- /* Unregister async callback function for link status updates */
- if (pnob->mcc_q_created)
- be_mcc_add_async_event_callback(&pnob->mcc_q_obj,
- NULL, NULL);
- netobject_cleanup(adapter, pnob);
- }
-
- if (adapter->csr_va)
- iounmap(adapter->csr_va);
- if (adapter->db_va)
- iounmap(adapter->db_va);
- if (adapter->pci_va)
- iounmap(adapter->pci_va);
-
- pci_release_regions(adapter->pdev);
- pci_disable_device(adapter->pdev);
-
- kfree(adapter->be_link_sts);
- kfree(adapter->eth_statsp);
-
- if (adapter->timer_ctxt.get_stats_timer.function)
- del_timer_sync(&adapter->timer_ctxt.get_stats_timer);
- kfree(adapter);
-}
-
-/*
- * This function is called by the PCI sub-system when it finds a PCI
- * device with dev/vendor IDs that match with one of our devices.
- * All of the driver initialization is done in this function.
- */
-static int be_probe(struct pci_dev *pdev, const struct pci_device_id *pdev_id)
-{
- int status = 0;
- struct be_adapter *adapter;
- struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD get_fwv;
- struct be_net_object *pnob;
- struct net_device *netdev;
-
- status = pci_enable_device(pdev);
- if (status)
- goto error;
-
- status = pci_request_regions(pdev, be_driver_name);
- if (status)
- goto error_pci_req;
-
- pci_set_master(pdev);
- adapter = kzalloc(sizeof(struct be_adapter), GFP_KERNEL);
- if (adapter == NULL) {
- status = -ENOMEM;
- goto error_adapter;
- }
- adapter->dev_state = BE_DEV_STATE_NONE;
- adapter->pdev = pdev;
- pci_set_drvdata(pdev, adapter);
-
- adapter->enable_aic = 1;
- adapter->max_eqd = MAX_EQD;
- adapter->min_eqd = 0;
- adapter->cur_eqd = 0;
-
- status = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
- if (!status) {
- adapter->dma_64bit_cap = true;
- } else {
- adapter->dma_64bit_cap = false;
- status = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
- if (status != 0) {
- printk(KERN_ERR "Could not set PCI DMA Mask\n");
- goto cleanup;
- }
- }
-
- status = init_pci_be_function(adapter, pdev);
- if (status != 0) {
- printk(KERN_ERR "Failed to map PCI BARS\n");
- status = -ENOMEM;
- goto cleanup;
- }
-
- be_trace_set_level(DL_ALWAYS | DL_ERR);
-
- adapter->be_link_sts = kmalloc(sizeof(struct BE_LINK_STATUS),
- GFP_KERNEL);
- if (adapter->be_link_sts == NULL) {
- printk(KERN_ERR "Memory allocation for link status "
- "buffer failed\n");
- goto cleanup;
- }
- spin_lock_init(&adapter->txq_lock);
-
- netdev = alloc_etherdev(sizeof(struct be_net_object));
- if (netdev == NULL) {
- status = -ENOMEM;
- goto cleanup;
- }
- pnob = netdev_priv(netdev);
- adapter->net_obj = pnob;
- adapter->netdevp = netdev;
- pnob->adapter = adapter;
- pnob->netdev = netdev;
-
- status = be_nob_ring_alloc(adapter, pnob);
- if (status != 0)
- goto cleanup;
-
- status = be_nob_ring_init(adapter, pnob);
- if (status != 0)
- goto cleanup;
-
- be_rxf_mac_address_read_write(&pnob->fn_obj, false, false, false,
- false, false, netdev->dev_addr, NULL, NULL);
-
- netdev->init = &benet_init;
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
- SET_NETDEV_DEV(netdev, &(adapter->pdev->dev));
-
- netif_napi_add(netdev, &pnob->napi, be_poll, 64);
-
- /* if the rx_frag size if 2K, one page is shared as two RX frags */
- pnob->rx_pg_shared =
- (pnob->rx_buf_size <= PAGE_SIZE / 2) ? true : false;
- if (pnob->rx_buf_size != rxbuf_size) {
- printk(KERN_WARNING
- "Could not set Rx buffer size to %d. Using %d\n",
- rxbuf_size, pnob->rx_buf_size);
- rxbuf_size = pnob->rx_buf_size;
- }
-
- tasklet_init(&(adapter->sts_handler), be_process_intr,
- (unsigned long)adapter);
- adapter->tasklet_started = 1;
- spin_lock_init(&(adapter->int_lock));
-
- status = be_register_isr(adapter, pnob);
- if (status != 0)
- goto cleanup;
-
- adapter->rx_csum = 1;
- adapter->max_rx_coal = BE_LRO_MAX_PKTS;
-
- memset(&get_fwv, 0,
- sizeof(struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD));
- printk(KERN_INFO "BladeEngine Driver version:%s. "
- "Copyright ServerEngines, Corporation 2005 - 2008\n",
- be_drvr_ver);
- status = be_function_get_fw_version(&pnob->fn_obj, &get_fwv, NULL,
- NULL);
- if (status == BE_SUCCESS) {
- strncpy(be_fw_ver, get_fwv.firmware_version_string, 32);
- printk(KERN_INFO "BladeEngine Firmware Version:%s\n",
- get_fwv.firmware_version_string);
- } else {
- printk(KERN_WARNING "Unable to get BE Firmware Version\n");
- }
-
- sema_init(&adapter->get_eth_stat_sem, 0);
- init_timer(&adapter->timer_ctxt.get_stats_timer);
- atomic_set(&adapter->timer_ctxt.get_stat_flag, 0);
- adapter->timer_ctxt.get_stats_timer.function =
- &be_get_stats_timer_handler;
-
- status = be_mcc_create(adapter);
- if (status < 0)
- goto cleanup;
- status = be_mcc_init(adapter);
- if (status < 0)
- goto cleanup;
-
-
- status = be_mcc_add_async_event_callback(&adapter->net_obj->mcc_q_obj,
- be_link_status_async_callback, (void *)adapter);
- if (status != BE_SUCCESS) {
- printk(KERN_WARNING "add_async_event_callback failed");
- printk(KERN_WARNING
- "Link status changes may not be reflected\n");
- }
-
- status = register_netdev(netdev);
- if (status != 0)
- goto cleanup;
- be_update_link_status(adapter);
- adapter->dev_state = BE_DEV_STATE_INIT;
- return 0;
-
-cleanup:
- be_remove(pdev);
- return status;
-error_adapter:
- pci_release_regions(pdev);
-error_pci_req:
- pci_disable_device(pdev);
-error:
- printk(KERN_ERR "BladeEngine initalization failed\n");
- return status;
-}
-
-/*
- * Get the current link status and print the status on console
- */
-void be_update_link_status(struct be_adapter *adapter)
-{
- int status;
- struct be_net_object *pnob = adapter->net_obj;
-
- status = be_rxf_link_status(&pnob->fn_obj, adapter->be_link_sts, NULL,
- NULL, NULL);
- if (status == BE_SUCCESS) {
- if (adapter->be_link_sts->mac0_speed &&
- adapter->be_link_sts->mac0_duplex)
- adapter->port0_link_sts = BE_PORT_LINK_UP;
- else
- adapter->port0_link_sts = BE_PORT_LINK_DOWN;
-
- if (adapter->be_link_sts->mac1_speed &&
- adapter->be_link_sts->mac1_duplex)
- adapter->port1_link_sts = BE_PORT_LINK_UP;
- else
- adapter->port1_link_sts = BE_PORT_LINK_DOWN;
-
- dev_info(&pnob->netdev->dev, "Link Properties:\n");
- be_print_link_info(adapter->be_link_sts);
- return;
- }
- dev_info(&pnob->netdev->dev, "Could not get link status\n");
- return;
-}
-
-
-#ifdef CONFIG_PM
-static void
-be_pm_cleanup(struct be_adapter *adapter,
- struct be_net_object *pnob, struct net_device *netdev)
-{
- netif_carrier_off(netdev);
- netif_stop_queue(netdev);
-
- be_wait_nic_tx_cmplx_cmpl(pnob);
- be_disable_eq_intr(pnob);
-
- if (adapter->tasklet_started) {
- tasklet_kill(&adapter->sts_handler);
- adapter->tasklet_started = 0;
- }
-
- be_unregister_isr(adapter);
- be_disable_intr(pnob);
-
- be_tx_q_clean(pnob);
- be_rx_q_clean(pnob);
-
- be_destroy_netobj(pnob);
-}
-
-static int be_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct be_adapter *adapter = pci_get_drvdata(pdev);
- struct net_device *netdev = adapter->netdevp;
- struct be_net_object *pnob = netdev_priv(netdev);
-
- adapter->dev_pm_state = adapter->dev_state;
- adapter->dev_state = BE_DEV_STATE_SUSPEND;
-
- netif_device_detach(netdev);
- if (netif_running(netdev))
- be_pm_cleanup(adapter, pnob, netdev);
-
- pci_enable_wake(pdev, 3, 1);
- pci_enable_wake(pdev, 4, 1); /* D3 Cold = 4 */
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return 0;
-}
-
-static void be_up(struct be_adapter *adapter)
-{
- struct be_net_object *pnob = adapter->net_obj;
-
- if (pnob->num_vlans != 0)
- be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans,
- pnob->vlan_tag, NULL, NULL, NULL);
-
-}
-
-static int be_resume(struct pci_dev *pdev)
-{
- int status = 0;
- struct be_adapter *adapter = pci_get_drvdata(pdev);
- struct net_device *netdev = adapter->netdevp;
- struct be_net_object *pnob = netdev_priv(netdev);
-
- netif_device_detach(netdev);
-
- status = pci_enable_device(pdev);
- if (status)
- return status;
-
- pci_set_power_state(pdev, 0);
- pci_restore_state(pdev);
- pci_enable_wake(pdev, 3, 0);
- pci_enable_wake(pdev, 4, 0); /* 4 is D3 cold */
-
- netif_carrier_on(netdev);
- netif_start_queue(netdev);
-
- if (netif_running(netdev)) {
- be_rxf_mac_address_read_write(&pnob->fn_obj, false, false,
- false, true, false, netdev->dev_addr, NULL, NULL);
-
- status = be_nob_ring_init(adapter, pnob);
- if (status < 0)
- return status;
-
- tasklet_init(&(adapter->sts_handler), be_process_intr,
- (unsigned long)adapter);
- adapter->tasklet_started = 1;
-
- if (be_register_isr(adapter, pnob) != 0) {
- printk(KERN_ERR "be_register_isr failed\n");
- return status;
- }
-
-
- status = be_mcc_init(adapter);
- if (status < 0) {
- printk(KERN_ERR "be_mcc_init failed\n");
- return status;
- }
- be_update_link_status(adapter);
- /*
- * Register async call back function to handle link
- * status updates
- */
- status = be_mcc_add_async_event_callback(
- &adapter->net_obj->mcc_q_obj,
- be_link_status_async_callback, (void *)adapter);
- if (status != BE_SUCCESS) {
- printk(KERN_WARNING "add_async_event_callback failed");
- printk(KERN_WARNING
- "Link status changes may not be reflected\n");
- }
- be_enable_intr(pnob);
- be_enable_eq_intr(pnob);
- be_up(adapter);
- }
- netif_device_attach(netdev);
- adapter->dev_state = adapter->dev_pm_state;
- return 0;
-
-}
-
-#endif
-
-/* Wait until no more pending transmits */
-void be_wait_nic_tx_cmplx_cmpl(struct be_net_object *pnob)
-{
- int i;
-
- /* Wait for 20us * 50000 (= 1s) and no more */
- i = 0;
- while ((pnob->tx_q_tl != pnob->tx_q_hd) && (i < 50000)) {
- ++i;
- udelay(20);
- }
-
- /* Check for no more pending transmits */
- if (i >= 50000) {
- printk(KERN_WARNING
- "Did not receive completions for all TX requests\n");
- }
-}
-
-static struct pci_driver be_driver = {
- .name = be_driver_name,
- .id_table = be_device_id_table,
- .probe = be_probe,
-#ifdef CONFIG_PM
- .suspend = be_suspend,
- .resume = be_resume,
-#endif
- .remove = be_remove
-};
-
-/*
- * Module init entry point. Registers our our device and return.
- * Our probe will be called if the device is found.
- */
-static int __init be_init_module(void)
-{
- int ret;
-
- if (rxbuf_size != 8192 && rxbuf_size != 4096 && rxbuf_size != 2048) {
- printk(KERN_WARNING
- "Unsupported receive buffer size (%d) requested\n",
- rxbuf_size);
- printk(KERN_WARNING
- "Must be 2048, 4096 or 8192. Defaulting to 2048\n");
- rxbuf_size = 2048;
- }
-
- ret = pci_register_driver(&be_driver);
-
- return ret;
-}
-
-module_init(be_init_module);
-
-/*
- * be_exit_module - Driver Exit Cleanup Routine
- */
-static void __exit be_exit_module(void)
-{
- pci_unregister_driver(&be_driver);
-}
-
-module_exit(be_exit_module);
diff --git a/drivers/staging/benet/be_int.c b/drivers/staging/benet/be_int.c
deleted file mode 100644
index cba95d09a8b6..000000000000
--- a/drivers/staging/benet/be_int.c
+++ /dev/null
@@ -1,863 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include <linux/if_vlan.h>
-#include <linux/inet_lro.h>
-
-#include "benet.h"
-
-/* number of bytes of RX frame that are copied to skb->data */
-#define BE_HDR_LEN 64
-
-#define NETIF_RX(skb) netif_receive_skb(skb)
-#define VLAN_ACCEL_RX(skb, pnob, vt) \
- vlan_hwaccel_rx(skb, pnob->vlan_grp, vt)
-
-/*
- This function notifies BladeEngine of the number of completion
- entries processed from the specified completion queue by writing
- the number of popped entries to the door bell.
-
- pnob - Pointer to the NetObject structure
- n - Number of completion entries processed
- cq_id - Queue ID of the completion queue for which notification
- is being done.
- re_arm - 1 - rearm the completion ring to generate an event.
- - 0 - dont rearm the completion ring to generate an event
-*/
-void be_notify_cmpl(struct be_net_object *pnob, int n, int cq_id, int re_arm)
-{
- struct CQ_DB_AMAP cqdb;
-
- cqdb.dw[0] = 0;
- AMAP_SET_BITS_PTR(CQ_DB, qid, &cqdb, cq_id);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &cqdb, re_arm);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &cqdb, n);
- PD_WRITE(&pnob->fn_obj, cq_db, cqdb.dw[0]);
-}
-
-/*
- * adds additional receive frags indicated by BE starting from given
- * frag index (fi) to specified skb's frag list
- */
-static void
-add_skb_frags(struct be_net_object *pnob, struct sk_buff *skb,
- u32 nresid, u32 fi)
-{
- struct be_adapter *adapter = pnob->adapter;
- u32 sk_frag_idx, n;
- struct be_rx_page_info *rx_page_info;
- u32 frag_sz = pnob->rx_buf_size;
-
- sk_frag_idx = skb_shinfo(skb)->nr_frags;
- while (nresid) {
- index_inc(&fi, pnob->rx_q_len);
-
- rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi];
- pnob->rx_ctxt[fi] = NULL;
- if ((rx_page_info->page_offset) ||
- (pnob->rx_pg_shared == false)) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- frag_sz, PCI_DMA_FROMDEVICE);
- }
-
- n = min(nresid, frag_sz);
- skb_shinfo(skb)->frags[sk_frag_idx].page = rx_page_info->page;
- skb_shinfo(skb)->frags[sk_frag_idx].page_offset
- = rx_page_info->page_offset;
- skb_shinfo(skb)->frags[sk_frag_idx].size = n;
-
- sk_frag_idx++;
- skb->len += n;
- skb->data_len += n;
- skb_shinfo(skb)->nr_frags++;
- nresid -= n;
-
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- atomic_dec(&pnob->rx_q_posted);
- }
-}
-
-/*
- * This function processes incoming nic packets over various Rx queues.
- * This function takes the adapter, the current Rx status descriptor
- * entry and the Rx completion queue ID as argument.
- */
-static inline int process_nic_rx_completion(struct be_net_object *pnob,
- struct ETH_RX_COMPL_AMAP *rxcp)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct sk_buff *skb;
- int udpcksm, tcpcksm;
- int n;
- u32 nresid, fi;
- u32 frag_sz = pnob->rx_buf_size;
- u8 *va;
- struct be_rx_page_info *rx_page_info;
- u32 numfrags, vtp, vtm, vlan_tag, pktsize;
-
- fi = AMAP_GET_BITS_PTR(ETH_RX_COMPL, fragndx, rxcp);
- BUG_ON(fi >= (int)pnob->rx_q_len);
- BUG_ON(fi < 0);
-
- rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi];
- BUG_ON(!rx_page_info->page);
- pnob->rx_ctxt[fi] = NULL;
-
- /*
- * If one page is used per fragment or if this is the second half of
- * of the page, unmap the page here
- */
- if ((rx_page_info->page_offset) || (pnob->rx_pg_shared == false)) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus), frag_sz,
- PCI_DMA_FROMDEVICE);
- }
-
- atomic_dec(&pnob->rx_q_posted);
- udpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, udpcksm, rxcp);
- tcpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, tcpcksm, rxcp);
- pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp);
- /*
- * get rid of RX flush completions first.
- */
- if ((tcpcksm) && (udpcksm) && (pktsize == 32)) {
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- return 0;
- }
- skb = netdev_alloc_skb(pnob->netdev, BE_HDR_LEN + NET_IP_ALIGN);
- if (skb == NULL) {
- dev_info(&pnob->netdev->dev, "alloc_skb() failed\n");
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- goto free_frags;
- }
- skb_reserve(skb, NET_IP_ALIGN);
-
- skb->dev = pnob->netdev;
-
- n = min(pktsize, frag_sz);
-
- va = page_address(rx_page_info->page) + rx_page_info->page_offset;
- prefetch(va);
-
- skb->len = n;
- skb->data_len = n;
- if (n <= BE_HDR_LEN) {
- memcpy(skb->data, va, n);
- put_page(rx_page_info->page);
- skb->data_len -= n;
- skb->tail += n;
- } else {
-
- /* Setup the SKB with page buffer information */
- skb_shinfo(skb)->frags[0].page = rx_page_info->page;
- skb_shinfo(skb)->nr_frags++;
-
- /* Copy the header into the skb_data */
- memcpy(skb->data, va, BE_HDR_LEN);
- skb_shinfo(skb)->frags[0].page_offset =
- rx_page_info->page_offset + BE_HDR_LEN;
- skb_shinfo(skb)->frags[0].size = n - BE_HDR_LEN;
- skb->data_len -= BE_HDR_LEN;
- skb->tail += BE_HDR_LEN;
- }
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- nresid = pktsize - n;
-
- skb->protocol = eth_type_trans(skb, pnob->netdev);
-
- if ((tcpcksm || udpcksm) && adapter->rx_csum)
- skb->ip_summed = CHECKSUM_UNNECESSARY;
- else
- skb->ip_summed = CHECKSUM_NONE;
- /*
- * if we have more bytes left, the frame has been
- * given to us in multiple fragments. This happens
- * with Jumbo frames. Add the remaining fragments to
- * skb->frags[] array.
- */
- if (nresid)
- add_skb_frags(pnob, skb, nresid, fi);
-
- /* update the the true size of the skb. */
- skb->truesize = skb->len + sizeof(struct sk_buff);
-
- /*
- * If a 802.3 frame or 802.2 LLC frame
- * (i.e) contains length field in MAC Hdr
- * and frame len is greater than 64 bytes
- */
- if (((skb->protocol == ntohs(ETH_P_802_2)) ||
- (skb->protocol == ntohs(ETH_P_802_3)))
- && (pktsize > BE_HDR_LEN)) {
- /*
- * If the length given in Mac Hdr is less than frame size
- * Erraneous frame, Drop it
- */
- if ((ntohs(*(u16 *) (va + 12)) + ETH_HLEN) < pktsize) {
- /* Increment Non Ether type II frames dropped */
- adapter->be_stat.bes_802_3_dropped_frames++;
-
- kfree_skb(skb);
- return 0;
- }
- /*
- * else if the length given in Mac Hdr is greater than
- * frame size, should not be seeing this sort of frames
- * dump the pkt and pass to stack
- */
- else if ((ntohs(*(u16 *) (va + 12)) + ETH_HLEN) > pktsize) {
- /* Increment Non Ether type II frames malformed */
- adapter->be_stat.bes_802_3_malformed_frames++;
- }
- }
-
- vtp = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtp, rxcp);
- vtm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtm, rxcp);
- if (vtp && vtm) {
- /* Vlan tag present in pkt and BE found
- * that the tag matched an entry in VLAN table
- */
- if (!pnob->vlan_grp || pnob->num_vlans == 0) {
- /* But we have no VLANs configured.
- * This should never happen. Drop the packet.
- */
- dev_info(&pnob->netdev->dev,
- "BladeEngine: Unexpected vlan tagged packet\n");
- kfree_skb(skb);
- return 0;
- }
- /* pass the VLAN packet to stack */
- vlan_tag = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vlan_tag, rxcp);
- VLAN_ACCEL_RX(skb, pnob, be16_to_cpu(vlan_tag));
-
- } else {
- NETIF_RX(skb);
- }
- return 0;
-
-free_frags:
- /* free all frags associated with the current rxcp */
- numfrags = AMAP_GET_BITS_PTR(ETH_RX_COMPL, numfrags, rxcp);
- while (numfrags-- > 1) {
- index_inc(&fi, pnob->rx_q_len);
-
- rx_page_info = (struct be_rx_page_info *)
- pnob->rx_ctxt[fi];
- pnob->rx_ctxt[fi] = (void *)NULL;
- if (rx_page_info->page_offset || !pnob->rx_pg_shared) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- frag_sz, PCI_DMA_FROMDEVICE);
- }
-
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- atomic_dec(&pnob->rx_q_posted);
- }
- return -ENOMEM;
-}
-
-static void process_nic_rx_completion_lro(struct be_net_object *pnob,
- struct ETH_RX_COMPL_AMAP *rxcp)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct skb_frag_struct rx_frags[BE_MAX_FRAGS_PER_FRAME];
- unsigned int udpcksm, tcpcksm;
- u32 numfrags, vlanf, vtm, vlan_tag, nresid;
- u16 vlant;
- unsigned int fi, idx, n;
- struct be_rx_page_info *rx_page_info;
- u32 frag_sz = pnob->rx_buf_size, pktsize;
- bool rx_coal = (adapter->max_rx_coal <= 1) ? 0 : 1;
- u8 err, *va;
- __wsum csum = 0;
-
- if (AMAP_GET_BITS_PTR(ETH_RX_COMPL, ipsec, rxcp)) {
- /* Drop the pkt and move to the next completion. */
- adapter->be_stat.bes_rx_misc_pkts++;
- return;
- }
- err = AMAP_GET_BITS_PTR(ETH_RX_COMPL, err, rxcp);
- if (err || !rx_coal) {
- /* We won't coalesce Rx pkts if the err bit set.
- * take the path of normal completion processing */
- process_nic_rx_completion(pnob, rxcp);
- return;
- }
-
- fi = AMAP_GET_BITS_PTR(ETH_RX_COMPL, fragndx, rxcp);
- BUG_ON(fi >= (int)pnob->rx_q_len);
- BUG_ON(fi < 0);
- rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi];
- BUG_ON(!rx_page_info->page);
- pnob->rx_ctxt[fi] = (void *)NULL;
- /* If one page is used per fragment or if this is the
- * second half of the page, unmap the page here
- */
- if (rx_page_info->page_offset || !pnob->rx_pg_shared) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- frag_sz, PCI_DMA_FROMDEVICE);
- }
-
- numfrags = AMAP_GET_BITS_PTR(ETH_RX_COMPL, numfrags, rxcp);
- udpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, udpcksm, rxcp);
- tcpcksm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, tcpcksm, rxcp);
- vlan_tag = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vlan_tag, rxcp);
- vlant = be16_to_cpu(vlan_tag);
- vlanf = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtp, rxcp);
- vtm = AMAP_GET_BITS_PTR(ETH_RX_COMPL, vtm, rxcp);
- pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp);
-
- atomic_dec(&pnob->rx_q_posted);
-
- if (tcpcksm && udpcksm && pktsize == 32) {
- /* flush completion entries */
- put_page(rx_page_info->page);
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- return;
- }
- /* Only one of udpcksum and tcpcksum can be set */
- BUG_ON(udpcksm && tcpcksm);
-
- /* jumbo frames could come in multiple fragments */
- BUG_ON(numfrags != ((pktsize + (frag_sz - 1)) / frag_sz));
- n = min(pktsize, frag_sz);
- nresid = pktsize - n; /* will be useful for jumbo pkts */
- idx = 0;
-
- va = page_address(rx_page_info->page) + rx_page_info->page_offset;
- prefetch(va);
- rx_frags[idx].page = rx_page_info->page;
- rx_frags[idx].page_offset = (rx_page_info->page_offset);
- rx_frags[idx].size = n;
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
-
- /* If we got multiple fragments, we have more data. */
- while (nresid) {
- idx++;
- index_inc(&fi, pnob->rx_q_len);
-
- rx_page_info = (struct be_rx_page_info *)pnob->rx_ctxt[fi];
- pnob->rx_ctxt[fi] = (void *)NULL;
- if (rx_page_info->page_offset || !pnob->rx_pg_shared) {
- pci_unmap_page(adapter->pdev,
- pci_unmap_addr(rx_page_info, bus),
- frag_sz, PCI_DMA_FROMDEVICE);
- }
-
- n = min(nresid, frag_sz);
- rx_frags[idx].page = rx_page_info->page;
- rx_frags[idx].page_offset = (rx_page_info->page_offset);
- rx_frags[idx].size = n;
-
- nresid -= n;
- memset(rx_page_info, 0, sizeof(struct be_rx_page_info));
- atomic_dec(&pnob->rx_q_posted);
- }
-
- if (likely(!(vlanf && vtm))) {
- lro_receive_frags(&pnob->lro_mgr, rx_frags,
- pktsize, pktsize,
- (void *)(unsigned long)csum, csum);
- } else {
- /* Vlan tag present in pkt and BE found
- * that the tag matched an entry in VLAN table
- */
- if (unlikely(!pnob->vlan_grp || pnob->num_vlans == 0)) {
- /* But we have no VLANs configured.
- * This should never happen. Drop the packet.
- */
- dev_info(&pnob->netdev->dev,
- "BladeEngine: Unexpected vlan tagged packet\n");
- return;
- }
- /* pass the VLAN packet to stack */
- lro_vlan_hwaccel_receive_frags(&pnob->lro_mgr,
- rx_frags, pktsize, pktsize,
- pnob->vlan_grp, vlant,
- (void *)(unsigned long)csum,
- csum);
- }
-
- adapter->be_stat.bes_rx_coal++;
-}
-
-struct ETH_RX_COMPL_AMAP *be_get_rx_cmpl(struct be_net_object *pnob)
-{
- struct ETH_RX_COMPL_AMAP *rxcp = &pnob->rx_cq[pnob->rx_cq_tl];
- u32 valid, ct;
-
- valid = AMAP_GET_BITS_PTR(ETH_RX_COMPL, valid, rxcp);
- if (valid == 0)
- return NULL;
-
- ct = AMAP_GET_BITS_PTR(ETH_RX_COMPL, ct, rxcp);
- if (ct != 0) {
- /* Invalid chute #. treat as error */
- AMAP_SET_BITS_PTR(ETH_RX_COMPL, err, rxcp, 1);
- }
-
- be_adv_rxcq_tl(pnob);
- AMAP_SET_BITS_PTR(ETH_RX_COMPL, valid, rxcp, 0);
- return rxcp;
-}
-
-static void update_rx_rate(struct be_adapter *adapter)
-{
- /* update the rate once in two seconds */
- if ((jiffies - adapter->eth_rx_jiffies) > 2 * (HZ)) {
- u32 r;
- r = adapter->eth_rx_bytes /
- ((jiffies - adapter->eth_rx_jiffies) / (HZ));
- r = (r / 1000000); /* MB/Sec */
-
- /* Mega Bits/Sec */
- adapter->be_stat.bes_eth_rx_rate = (r * 8);
- adapter->eth_rx_jiffies = jiffies;
- adapter->eth_rx_bytes = 0;
- }
-}
-
-static int process_rx_completions(struct be_net_object *pnob, int max_work)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct ETH_RX_COMPL_AMAP *rxcp;
- u32 nc = 0;
- unsigned int pktsize;
-
- while (max_work && (rxcp = be_get_rx_cmpl(pnob))) {
- prefetch(rxcp);
- pktsize = AMAP_GET_BITS_PTR(ETH_RX_COMPL, pktsize, rxcp);
- process_nic_rx_completion_lro(pnob, rxcp);
- adapter->eth_rx_bytes += pktsize;
- update_rx_rate(adapter);
- nc++;
- max_work--;
- adapter->be_stat.bes_rx_compl++;
- }
- if (likely(adapter->max_rx_coal > 1)) {
- adapter->be_stat.bes_rx_flush++;
- lro_flush_all(&pnob->lro_mgr);
- }
-
- /* Refill the queue */
- if (atomic_read(&pnob->rx_q_posted) < 900)
- be_post_eth_rx_buffs(pnob);
-
- return nc;
-}
-
-static struct ETH_TX_COMPL_AMAP *be_get_tx_cmpl(struct be_net_object *pnob)
-{
- struct ETH_TX_COMPL_AMAP *txcp = &pnob->tx_cq[pnob->tx_cq_tl];
- u32 valid;
-
- valid = AMAP_GET_BITS_PTR(ETH_TX_COMPL, valid, txcp);
- if (valid == 0)
- return NULL;
-
- AMAP_SET_BITS_PTR(ETH_TX_COMPL, valid, txcp, 0);
- be_adv_txcq_tl(pnob);
- return txcp;
-
-}
-
-void process_one_tx_compl(struct be_net_object *pnob, u32 end_idx)
-{
- struct be_adapter *adapter = pnob->adapter;
- int cur_index, tx_wrbs_completed = 0;
- struct sk_buff *skb;
- u64 busaddr, pa, pa_lo, pa_hi;
- struct ETH_WRB_AMAP *wrb;
- u32 frag_len, last_index, j;
-
- last_index = tx_compl_lastwrb_idx_get(pnob);
- BUG_ON(last_index != end_idx);
- pnob->tx_ctxt[pnob->tx_q_tl] = NULL;
- do {
- cur_index = pnob->tx_q_tl;
- wrb = &pnob->tx_q[cur_index];
- pa_hi = AMAP_GET_BITS_PTR(ETH_WRB, frag_pa_hi, wrb);
- pa_lo = AMAP_GET_BITS_PTR(ETH_WRB, frag_pa_lo, wrb);
- frag_len = AMAP_GET_BITS_PTR(ETH_WRB, frag_len, wrb);
- busaddr = (pa_hi << 32) | pa_lo;
- if (busaddr != 0) {
- pa = le64_to_cpu(busaddr);
- pci_unmap_single(adapter->pdev, pa,
- frag_len, PCI_DMA_TODEVICE);
- }
- if (cur_index == last_index) {
- skb = (struct sk_buff *)pnob->tx_ctxt[cur_index];
- BUG_ON(!skb);
- for (j = 0; j < skb_shinfo(skb)->nr_frags; j++) {
- struct skb_frag_struct *frag;
- frag = &skb_shinfo(skb)->frags[j];
- pci_unmap_page(adapter->pdev,
- (ulong) frag->page, frag->size,
- PCI_DMA_TODEVICE);
- }
- kfree_skb(skb);
- pnob->tx_ctxt[cur_index] = NULL;
- } else {
- BUG_ON(pnob->tx_ctxt[cur_index]);
- }
- tx_wrbs_completed++;
- be_adv_txq_tl(pnob);
- } while (cur_index != last_index);
- atomic_sub(tx_wrbs_completed, &pnob->tx_q_used);
-}
-
-/* there is no need to take an SMP lock here since currently
- * we have only one instance of the tasklet that does completion
- * processing.
- */
-static void process_nic_tx_completions(struct be_net_object *pnob)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct ETH_TX_COMPL_AMAP *txcp;
- struct net_device *netdev = pnob->netdev;
- u32 end_idx, num_processed = 0;
-
- adapter->be_stat.bes_tx_events++;
-
- while ((txcp = be_get_tx_cmpl(pnob))) {
- end_idx = AMAP_GET_BITS_PTR(ETH_TX_COMPL, wrb_index, txcp);
- process_one_tx_compl(pnob, end_idx);
- num_processed++;
- adapter->be_stat.bes_tx_compl++;
- }
- be_notify_cmpl(pnob, num_processed, pnob->tx_cq_id, 1);
- /*
- * We got Tx completions and have usable WRBs.
- * If the netdev's queue has been stopped
- * because we had run out of WRBs, wake it now.
- */
- spin_lock(&adapter->txq_lock);
- if (netif_queue_stopped(netdev)
- && atomic_read(&pnob->tx_q_used) < pnob->tx_q_len / 2) {
- netif_wake_queue(netdev);
- }
- spin_unlock(&adapter->txq_lock);
-}
-
-static u32 post_rx_buffs(struct be_net_object *pnob, struct list_head *rxbl)
-{
- u32 nposted = 0;
- struct ETH_RX_D_AMAP *rxd = NULL;
- struct be_recv_buffer *rxbp;
- void **rx_ctxp;
- struct RQ_DB_AMAP rqdb;
-
- rx_ctxp = pnob->rx_ctxt;
-
- while (!list_empty(rxbl) &&
- (rx_ctxp[pnob->rx_q_hd] == NULL) && nposted < 255) {
-
- rxbp = list_first_entry(rxbl, struct be_recv_buffer, rxb_list);
- list_del(&rxbp->rxb_list);
- rxd = pnob->rx_q + pnob->rx_q_hd;
- AMAP_SET_BITS_PTR(ETH_RX_D, fragpa_lo, rxd, rxbp->rxb_pa_lo);
- AMAP_SET_BITS_PTR(ETH_RX_D, fragpa_hi, rxd, rxbp->rxb_pa_hi);
-
- rx_ctxp[pnob->rx_q_hd] = rxbp->rxb_ctxt;
- be_adv_rxq_hd(pnob);
- nposted++;
- }
-
- if (nposted) {
- /* Now press the door bell to notify BladeEngine. */
- rqdb.dw[0] = 0;
- AMAP_SET_BITS_PTR(RQ_DB, numPosted, &rqdb, nposted);
- AMAP_SET_BITS_PTR(RQ_DB, rq, &rqdb, pnob->rx_q_id);
- PD_WRITE(&pnob->fn_obj, erx_rq_db, rqdb.dw[0]);
- }
- atomic_add(nposted, &pnob->rx_q_posted);
- return nposted;
-}
-
-void be_post_eth_rx_buffs(struct be_net_object *pnob)
-{
- struct be_adapter *adapter = pnob->adapter;
- u32 num_bufs, r;
- u64 busaddr = 0, tmp_pa;
- u32 max_bufs, pg_hd;
- u32 frag_size;
- struct be_recv_buffer *rxbp;
- struct list_head rxbl;
- struct be_rx_page_info *rx_page_info;
- struct page *page = NULL;
- u32 page_order = 0;
- gfp_t alloc_flags = GFP_ATOMIC;
-
- BUG_ON(!adapter);
-
- max_bufs = 64; /* should be even # <= 255. */
-
- frag_size = pnob->rx_buf_size;
- page_order = get_order(frag_size);
-
- if (frag_size == 8192)
- alloc_flags |= (gfp_t) __GFP_COMP;
- /*
- * Form a linked list of RECV_BUFFFER structure to be be posted.
- * We will post even number of buffer so that pages can be
- * shared.
- */
- INIT_LIST_HEAD(&rxbl);
-
- for (num_bufs = 0; num_bufs < max_bufs &&
- !pnob->rx_page_info[pnob->rx_pg_info_hd].page; ++num_bufs) {
-
- rxbp = &pnob->eth_rx_bufs[num_bufs];
- pg_hd = pnob->rx_pg_info_hd;
- rx_page_info = &pnob->rx_page_info[pg_hd];
-
- if (!page) {
- page = alloc_pages(alloc_flags, page_order);
- if (unlikely(page == NULL)) {
- adapter->be_stat.bes_ethrx_post_fail++;
- pnob->rxbuf_post_fail++;
- break;
- }
- pnob->rxbuf_post_fail = 0;
- busaddr = pci_map_page(adapter->pdev, page, 0,
- frag_size, PCI_DMA_FROMDEVICE);
- rx_page_info->page_offset = 0;
- rx_page_info->page = page;
- /*
- * If we are sharing a page among two skbs,
- * alloc a new one on the next iteration
- */
- if (pnob->rx_pg_shared == false)
- page = NULL;
- } else {
- get_page(page);
- rx_page_info->page_offset += frag_size;
- rx_page_info->page = page;
- /*
- * We are finished with the alloced page,
- * Alloc a new one on the next iteration
- */
- page = NULL;
- }
- rxbp->rxb_ctxt = (void *)rx_page_info;
- index_inc(&pnob->rx_pg_info_hd, pnob->rx_q_len);
-
- pci_unmap_addr_set(rx_page_info, bus, busaddr);
- tmp_pa = busaddr + rx_page_info->page_offset;
- rxbp->rxb_pa_lo = (tmp_pa & 0xFFFFFFFF);
- rxbp->rxb_pa_hi = (tmp_pa >> 32);
- rxbp->rxb_len = frag_size;
- list_add_tail(&rxbp->rxb_list, &rxbl);
- } /* End of for */
-
- r = post_rx_buffs(pnob, &rxbl);
- BUG_ON(r != num_bufs);
- return;
-}
-
-/*
- * Interrupt service for network function. We just schedule the
- * tasklet which does all completion processing.
- */
-irqreturn_t be_int(int irq, void *dev)
-{
- struct net_device *netdev = dev;
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- u32 isr;
-
- isr = CSR_READ(&pnob->fn_obj, cev.isr1);
- if (unlikely(!isr))
- return IRQ_NONE;
-
- spin_lock(&adapter->int_lock);
- adapter->isr |= isr;
- spin_unlock(&adapter->int_lock);
-
- adapter->be_stat.bes_ints++;
-
- tasklet_schedule(&adapter->sts_handler);
- return IRQ_HANDLED;
-}
-
-/*
- * Poll function called by NAPI with a work budget.
- * We process as many UC. BC and MC receive completions
- * as the budget allows and return the actual number of
- * RX ststutses processed.
- */
-int be_poll(struct napi_struct *napi, int budget)
-{
- struct be_net_object *pnob =
- container_of(napi, struct be_net_object, napi);
- u32 work_done;
-
- pnob->adapter->be_stat.bes_polls++;
- work_done = process_rx_completions(pnob, budget);
- BUG_ON(work_done > budget);
-
- /* All consumed */
- if (work_done < budget) {
- netif_rx_complete(napi);
- /* enable intr */
- be_notify_cmpl(pnob, work_done, pnob->rx_cq_id, 1);
- } else {
- /* More to be consumed; continue with interrupts disabled */
- be_notify_cmpl(pnob, work_done, pnob->rx_cq_id, 0);
- }
- return work_done;
-}
-
-static struct EQ_ENTRY_AMAP *get_event(struct be_net_object *pnob)
-{
- struct EQ_ENTRY_AMAP *eqp = &(pnob->event_q[pnob->event_q_tl]);
- if (!AMAP_GET_BITS_PTR(EQ_ENTRY, Valid, eqp))
- return NULL;
- be_adv_eq_tl(pnob);
- return eqp;
-}
-
-/*
- * Processes all valid events in the event ring associated with given
- * NetObject. Also, notifies BE the number of events processed.
- */
-static inline u32 process_events(struct be_net_object *pnob)
-{
- struct be_adapter *adapter = pnob->adapter;
- struct EQ_ENTRY_AMAP *eqp;
- u32 rid, num_events = 0;
- struct net_device *netdev = pnob->netdev;
-
- while ((eqp = get_event(pnob)) != NULL) {
- adapter->be_stat.bes_events++;
- rid = AMAP_GET_BITS_PTR(EQ_ENTRY, ResourceID, eqp);
- if (rid == pnob->rx_cq_id) {
- adapter->be_stat.bes_rx_events++;
- netif_rx_schedule(&pnob->napi);
- } else if (rid == pnob->tx_cq_id) {
- process_nic_tx_completions(pnob);
- } else if (rid == pnob->mcc_cq_id) {
- be_mcc_process_cq(&pnob->mcc_q_obj, 1);
- } else {
- dev_info(&netdev->dev,
- "Invalid EQ ResourceID %d\n", rid);
- }
- AMAP_SET_BITS_PTR(EQ_ENTRY, Valid, eqp, 0);
- AMAP_SET_BITS_PTR(EQ_ENTRY, ResourceID, eqp, 0);
- num_events++;
- }
- return num_events;
-}
-
-static void update_eqd(struct be_adapter *adapter, struct be_net_object *pnob)
-{
- int status;
- struct be_eq_object *eq_objectp;
-
- /* update once a second */
- if ((jiffies - adapter->ips_jiffies) > 1 * (HZ)) {
- /* One second elapsed since last update */
- u32 r, new_eqd = -1;
- r = adapter->be_stat.bes_ints - adapter->be_stat.bes_prev_ints;
- r = r / ((jiffies - adapter->ips_jiffies) / (HZ));
- adapter->be_stat.bes_ips = r;
- adapter->ips_jiffies = jiffies;
- adapter->be_stat.bes_prev_ints = adapter->be_stat.bes_ints;
- if (r > IPS_HI_WM && adapter->cur_eqd < adapter->max_eqd)
- new_eqd = (adapter->cur_eqd + 8);
- if (r < IPS_LO_WM && adapter->cur_eqd > adapter->min_eqd)
- new_eqd = (adapter->cur_eqd - 8);
- if (adapter->enable_aic && new_eqd != -1) {
- eq_objectp = &pnob->event_q_obj;
- status = be_eq_modify_delay(&pnob->fn_obj, 1,
- &eq_objectp, &new_eqd, NULL,
- NULL, NULL);
- if (status == BE_SUCCESS)
- adapter->cur_eqd = new_eqd;
- }
- }
-}
-
-/*
- This function notifies BladeEngine of how many events were processed
- from the event queue by ringing the corresponding door bell and
- optionally re-arms the event queue.
- n - number of events processed
- re_arm - 1 - re-arm the EQ, 0 - do not re-arm the EQ
-
-*/
-static void be_notify_event(struct be_net_object *pnob, int n, int re_arm)
-{
- struct CQ_DB_AMAP eqdb;
- eqdb.dw[0] = 0;
-
- AMAP_SET_BITS_PTR(CQ_DB, qid, &eqdb, pnob->event_q_id);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &eqdb, re_arm);
- AMAP_SET_BITS_PTR(CQ_DB, event, &eqdb, 1);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &eqdb, n);
- /*
- * Under some situations we see an interrupt and no valid
- * EQ entry. To keep going, we need to ring the DB even if
- * numPOsted is 0.
- */
- PD_WRITE(&pnob->fn_obj, cq_db, eqdb.dw[0]);
- return;
-}
-
-/*
- * Called from the tasklet scheduled by ISR. All real interrupt processing
- * is done here.
- */
-void be_process_intr(unsigned long context)
-{
- struct be_adapter *adapter = (struct be_adapter *)context;
- struct be_net_object *pnob = adapter->net_obj;
- u32 isr, n;
- ulong flags = 0;
-
- isr = adapter->isr;
-
- /*
- * we create only one NIC event queue in Linux. Event is
- * expected only in the first event queue
- */
- BUG_ON(isr & 0xfffffffe);
- if ((isr & 1) == 0)
- return; /* not our interrupt */
- n = process_events(pnob);
- /*
- * Clear the event bit. adapter->isr is set by
- * hard interrupt. Prevent race with lock.
- */
- spin_lock_irqsave(&adapter->int_lock, flags);
- adapter->isr &= ~1;
- spin_unlock_irqrestore(&adapter->int_lock, flags);
- be_notify_event(pnob, n, 1);
- /*
- * If previous allocation attempts had failed and
- * BE has used up all posted buffers, post RX buffers here
- */
- if (pnob->rxbuf_post_fail && atomic_read(&pnob->rx_q_posted) == 0)
- be_post_eth_rx_buffs(pnob);
- update_eqd(adapter, pnob);
- return;
-}
diff --git a/drivers/staging/benet/be_netif.c b/drivers/staging/benet/be_netif.c
deleted file mode 100644
index 2b8daf63dc7d..000000000000
--- a/drivers/staging/benet/be_netif.c
+++ /dev/null
@@ -1,705 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * be_netif.c
- *
- * This file contains various entry points of drivers seen by tcp/ip stack.
- */
-
-#include <linux/if_vlan.h>
-#include <linux/in.h>
-#include "benet.h"
-#include <linux/ip.h>
-#include <linux/inet_lro.h>
-
-/* Strings to print Link properties */
-static const char *link_speed[] = {
- "Invalid link Speed Value",
- "10 Mbps",
- "100 Mbps",
- "1 Gbps",
- "10 Gbps"
-};
-
-static const char *link_duplex[] = {
- "Invalid Duplex Value",
- "Half Duplex",
- "Full Duplex"
-};
-
-static const char *link_state[] = {
- "",
- "(active)"
-};
-
-void be_print_link_info(struct BE_LINK_STATUS *lnk_status)
-{
- u16 si, di, ai;
-
- /* Port 0 */
- if (lnk_status->mac0_speed && lnk_status->mac0_duplex) {
- /* Port is up and running */
- si = (lnk_status->mac0_speed < 5) ? lnk_status->mac0_speed : 0;
- di = (lnk_status->mac0_duplex < 3) ?
- lnk_status->mac0_duplex : 0;
- ai = (lnk_status->active_port == 0) ? 1 : 0;
- printk(KERN_INFO "PortNo. 0: Speed - %s %s %s\n",
- link_speed[si], link_duplex[di], link_state[ai]);
- } else
- printk(KERN_INFO "PortNo. 0: Down\n");
-
- /* Port 1 */
- if (lnk_status->mac1_speed && lnk_status->mac1_duplex) {
- /* Port is up and running */
- si = (lnk_status->mac1_speed < 5) ? lnk_status->mac1_speed : 0;
- di = (lnk_status->mac1_duplex < 3) ?
- lnk_status->mac1_duplex : 0;
- ai = (lnk_status->active_port == 0) ? 1 : 0;
- printk(KERN_INFO "PortNo. 1: Speed - %s %s %s\n",
- link_speed[si], link_duplex[di], link_state[ai]);
- } else
- printk(KERN_INFO "PortNo. 1: Down\n");
-
- return;
-}
-
-static int
-be_get_frag_header(struct skb_frag_struct *frag, void **mac_hdr,
- void **ip_hdr, void **tcpudp_hdr,
- u64 *hdr_flags, void *priv)
-{
- struct ethhdr *eh;
- struct vlan_ethhdr *veh;
- struct iphdr *iph;
- u8 *va = page_address(frag->page) + frag->page_offset;
- unsigned long ll_hlen;
-
- /* find the mac header, abort if not IPv4 */
-
- prefetch(va);
- eh = (struct ethhdr *)va;
- *mac_hdr = eh;
- ll_hlen = ETH_HLEN;
- if (eh->h_proto != htons(ETH_P_IP)) {
- if (eh->h_proto == htons(ETH_P_8021Q)) {
- veh = (struct vlan_ethhdr *)va;
- if (veh->h_vlan_encapsulated_proto != htons(ETH_P_IP))
- return -1;
-
- ll_hlen += VLAN_HLEN;
-
- } else {
- return -1;
- }
- }
- *hdr_flags = LRO_IPV4;
-
- iph = (struct iphdr *)(va + ll_hlen);
- *ip_hdr = iph;
- if (iph->protocol != IPPROTO_TCP)
- return -1;
- *hdr_flags |= LRO_TCP;
- *tcpudp_hdr = (u8 *) (*ip_hdr) + (iph->ihl << 2);
-
- return 0;
-}
-
-static int benet_open(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- struct net_lro_mgr *lro_mgr;
-
- if (adapter->dev_state < BE_DEV_STATE_INIT)
- return -EAGAIN;
-
- lro_mgr = &pnob->lro_mgr;
- lro_mgr->dev = netdev;
-
- lro_mgr->features = LRO_F_NAPI;
- lro_mgr->ip_summed = CHECKSUM_UNNECESSARY;
- lro_mgr->ip_summed_aggr = CHECKSUM_UNNECESSARY;
- lro_mgr->max_desc = BE_MAX_LRO_DESCRIPTORS;
- lro_mgr->lro_arr = pnob->lro_desc;
- lro_mgr->get_frag_header = be_get_frag_header;
- lro_mgr->max_aggr = adapter->max_rx_coal;
- lro_mgr->frag_align_pad = 2;
- if (lro_mgr->max_aggr > MAX_SKB_FRAGS)
- lro_mgr->max_aggr = MAX_SKB_FRAGS;
-
- adapter->max_rx_coal = BE_LRO_MAX_PKTS;
-
- be_update_link_status(adapter);
-
- /*
- * Set carrier on only if Physical Link up
- * Either of the port link status up signifies this
- */
- if ((adapter->port0_link_sts == BE_PORT_LINK_UP) ||
- (adapter->port1_link_sts == BE_PORT_LINK_UP)) {
- netif_start_queue(netdev);
- netif_carrier_on(netdev);
- }
-
- adapter->dev_state = BE_DEV_STATE_OPEN;
- napi_enable(&pnob->napi);
- be_enable_intr(pnob);
- be_enable_eq_intr(pnob);
- /*
- * RX completion queue may be in dis-armed state. Arm it.
- */
- be_notify_cmpl(pnob, 0, pnob->rx_cq_id, 1);
-
- return 0;
-}
-
-static int benet_close(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- netif_stop_queue(netdev);
- synchronize_irq(netdev->irq);
-
- be_wait_nic_tx_cmplx_cmpl(pnob);
- adapter->dev_state = BE_DEV_STATE_INIT;
- netif_carrier_off(netdev);
-
- adapter->port0_link_sts = BE_PORT_LINK_DOWN;
- adapter->port1_link_sts = BE_PORT_LINK_DOWN;
- be_disable_intr(pnob);
- be_disable_eq_intr(pnob);
- napi_disable(&pnob->napi);
-
- return 0;
-}
-
-/*
- * Setting a Mac Address for BE
- * Takes netdev and a void pointer as arguments.
- * The pointer holds the new addres to be used.
- */
-static int benet_set_mac_addr(struct net_device *netdev, void *p)
-{
- struct sockaddr *addr = p;
- struct be_net_object *pnob = netdev_priv(netdev);
-
- memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- be_rxf_mac_address_read_write(&pnob->fn_obj, 0, 0, false, true, false,
- netdev->dev_addr, NULL, NULL);
- /*
- * Since we are doing Active-Passive failover, both
- * ports should have matching MAC addresses everytime.
- */
- be_rxf_mac_address_read_write(&pnob->fn_obj, 1, 0, false, true, false,
- netdev->dev_addr, NULL, NULL);
-
- return 0;
-}
-
-void be_get_stats_timer_handler(unsigned long context)
-{
- struct be_timer_ctxt *ctxt = (struct be_timer_ctxt *)context;
-
- if (atomic_read(&ctxt->get_stat_flag)) {
- atomic_dec(&ctxt->get_stat_flag);
- up((void *)ctxt->get_stat_sem_addr);
- }
- del_timer(&ctxt->get_stats_timer);
- return;
-}
-
-void be_get_stat_cb(void *context, int status,
- struct MCC_WRB_AMAP *optional_wrb)
-{
- struct be_timer_ctxt *ctxt = (struct be_timer_ctxt *)context;
- /*
- * just up the semaphore if the get_stat_flag
- * reads 1. so that the waiter can continue.
- * If it is 0, then it was handled by the timer handler.
- */
- del_timer(&ctxt->get_stats_timer);
- if (atomic_read(&ctxt->get_stat_flag)) {
- atomic_dec(&ctxt->get_stat_flag);
- up((void *)ctxt->get_stat_sem_addr);
- }
-}
-
-struct net_device_stats *benet_get_stats(struct net_device *dev)
-{
- struct be_net_object *pnob = netdev_priv(dev);
- struct be_adapter *adapter = pnob->adapter;
- u64 pa;
- struct be_timer_ctxt *ctxt = &adapter->timer_ctxt;
-
- if (adapter->dev_state != BE_DEV_STATE_OPEN) {
- /* Return previously read stats */
- return &(adapter->benet_stats);
- }
- /* Get Physical Addr */
- pa = pci_map_single(adapter->pdev, adapter->eth_statsp,
- sizeof(struct FWCMD_ETH_GET_STATISTICS),
- PCI_DMA_FROMDEVICE);
- ctxt->get_stat_sem_addr = (unsigned long)&adapter->get_eth_stat_sem;
- atomic_inc(&ctxt->get_stat_flag);
-
- be_rxf_query_eth_statistics(&pnob->fn_obj, adapter->eth_statsp,
- cpu_to_le64(pa), be_get_stat_cb, ctxt,
- NULL);
-
- ctxt->get_stats_timer.data = (unsigned long)ctxt;
- mod_timer(&ctxt->get_stats_timer, (jiffies + (HZ * 2)));
- down((void *)ctxt->get_stat_sem_addr); /* callback will unblock us */
-
- /* Adding port0 and port1 stats. */
- adapter->benet_stats.rx_packets =
- adapter->eth_statsp->params.response.p0recvdtotalframes +
- adapter->eth_statsp->params.response.p1recvdtotalframes;
- adapter->benet_stats.tx_packets =
- adapter->eth_statsp->params.response.p0xmitunicastframes +
- adapter->eth_statsp->params.response.p1xmitunicastframes;
- adapter->benet_stats.tx_bytes =
- adapter->eth_statsp->params.response.p0xmitbyteslsd +
- adapter->eth_statsp->params.response.p1xmitbyteslsd;
- adapter->benet_stats.rx_errors =
- adapter->eth_statsp->params.response.p0crcerrors +
- adapter->eth_statsp->params.response.p1crcerrors;
- adapter->benet_stats.rx_errors +=
- adapter->eth_statsp->params.response.p0alignmentsymerrs +
- adapter->eth_statsp->params.response.p1alignmentsymerrs;
- adapter->benet_stats.rx_errors +=
- adapter->eth_statsp->params.response.p0inrangelenerrors +
- adapter->eth_statsp->params.response.p1inrangelenerrors;
- adapter->benet_stats.rx_bytes =
- adapter->eth_statsp->params.response.p0recvdtotalbytesLSD +
- adapter->eth_statsp->params.response.p1recvdtotalbytesLSD;
- adapter->benet_stats.rx_crc_errors =
- adapter->eth_statsp->params.response.p0crcerrors +
- adapter->eth_statsp->params.response.p1crcerrors;
-
- adapter->benet_stats.tx_packets +=
- adapter->eth_statsp->params.response.p0xmitmulticastframes +
- adapter->eth_statsp->params.response.p1xmitmulticastframes;
- adapter->benet_stats.tx_packets +=
- adapter->eth_statsp->params.response.p0xmitbroadcastframes +
- adapter->eth_statsp->params.response.p1xmitbroadcastframes;
- adapter->benet_stats.tx_errors = 0;
-
- adapter->benet_stats.multicast =
- adapter->eth_statsp->params.response.p0xmitmulticastframes +
- adapter->eth_statsp->params.response.p1xmitmulticastframes;
-
- adapter->benet_stats.rx_fifo_errors =
- adapter->eth_statsp->params.response.p0rxfifooverflowdropped +
- adapter->eth_statsp->params.response.p1rxfifooverflowdropped;
- adapter->benet_stats.rx_frame_errors =
- adapter->eth_statsp->params.response.p0alignmentsymerrs +
- adapter->eth_statsp->params.response.p1alignmentsymerrs;
- adapter->benet_stats.rx_length_errors =
- adapter->eth_statsp->params.response.p0inrangelenerrors +
- adapter->eth_statsp->params.response.p1inrangelenerrors;
- adapter->benet_stats.rx_length_errors +=
- adapter->eth_statsp->params.response.p0outrangeerrors +
- adapter->eth_statsp->params.response.p1outrangeerrors;
- adapter->benet_stats.rx_length_errors +=
- adapter->eth_statsp->params.response.p0frametoolongerrors +
- adapter->eth_statsp->params.response.p1frametoolongerrors;
-
- pci_unmap_single(adapter->pdev, (ulong) adapter->eth_statsp,
- sizeof(struct FWCMD_ETH_GET_STATISTICS),
- PCI_DMA_FROMDEVICE);
- return &(adapter->benet_stats);
-
-}
-
-static void be_start_tx(struct be_net_object *pnob, u32 nposted)
-{
-#define CSR_ETH_MAX_SQPOSTS 255
- struct SQ_DB_AMAP sqdb;
-
- sqdb.dw[0] = 0;
-
- AMAP_SET_BITS_PTR(SQ_DB, cid, &sqdb, pnob->tx_q_id);
- while (nposted) {
- if (nposted > CSR_ETH_MAX_SQPOSTS) {
- AMAP_SET_BITS_PTR(SQ_DB, numPosted, &sqdb,
- CSR_ETH_MAX_SQPOSTS);
- nposted -= CSR_ETH_MAX_SQPOSTS;
- } else {
- AMAP_SET_BITS_PTR(SQ_DB, numPosted, &sqdb, nposted);
- nposted = 0;
- }
- PD_WRITE(&pnob->fn_obj, etx_sq_db, sqdb.dw[0]);
- }
-
- return;
-}
-
-static void update_tx_rate(struct be_adapter *adapter)
-{
- /* update the rate once in two seconds */
- if ((jiffies - adapter->eth_tx_jiffies) > 2 * (HZ)) {
- u32 r;
- r = adapter->eth_tx_bytes /
- ((jiffies - adapter->eth_tx_jiffies) / (HZ));
- r = (r / 1000000); /* M bytes/s */
- adapter->be_stat.bes_eth_tx_rate = (r * 8); /* M bits/s */
- adapter->eth_tx_jiffies = jiffies;
- adapter->eth_tx_bytes = 0;
- }
-}
-
-static int wrb_cnt_in_skb(struct sk_buff *skb)
-{
- int cnt = 0;
- while (skb) {
- if (skb->len > skb->data_len)
- cnt++;
- cnt += skb_shinfo(skb)->nr_frags;
- skb = skb_shinfo(skb)->frag_list;
- }
- BUG_ON(cnt > BE_MAX_TX_FRAG_COUNT);
- return cnt;
-}
-
-static void wrb_fill(struct ETH_WRB_AMAP *wrb, u64 addr, int len)
-{
- AMAP_SET_BITS_PTR(ETH_WRB, frag_pa_hi, wrb, addr >> 32);
- AMAP_SET_BITS_PTR(ETH_WRB, frag_pa_lo, wrb, addr & 0xFFFFFFFF);
- AMAP_SET_BITS_PTR(ETH_WRB, frag_len, wrb, len);
-}
-
-static void wrb_fill_extra(struct ETH_WRB_AMAP *wrb, struct sk_buff *skb,
- struct be_net_object *pnob)
-{
- wrb->dw[2] = 0;
- wrb->dw[3] = 0;
- AMAP_SET_BITS_PTR(ETH_WRB, crc, wrb, 1);
- if (skb_shinfo(skb)->gso_segs > 1 && skb_shinfo(skb)->gso_size) {
- AMAP_SET_BITS_PTR(ETH_WRB, lso, wrb, 1);
- AMAP_SET_BITS_PTR(ETH_WRB, lso_mss, wrb,
- skb_shinfo(skb)->gso_size);
- } else if (skb->ip_summed == CHECKSUM_PARTIAL) {
- u8 proto = ((struct iphdr *)ip_hdr(skb))->protocol;
- if (proto == IPPROTO_TCP)
- AMAP_SET_BITS_PTR(ETH_WRB, tcpcs, wrb, 1);
- else if (proto == IPPROTO_UDP)
- AMAP_SET_BITS_PTR(ETH_WRB, udpcs, wrb, 1);
- }
- if (pnob->vlan_grp && vlan_tx_tag_present(skb)) {
- AMAP_SET_BITS_PTR(ETH_WRB, vlan, wrb, 1);
- AMAP_SET_BITS_PTR(ETH_WRB, vlan_tag, wrb, vlan_tx_tag_get(skb));
- }
-}
-
-static inline void wrb_copy_extra(struct ETH_WRB_AMAP *to,
- struct ETH_WRB_AMAP *from)
-{
-
- to->dw[2] = from->dw[2];
- to->dw[3] = from->dw[3];
-}
-
-/* Returns the actual count of wrbs used including a possible dummy */
-static int copy_skb_to_txq(struct be_net_object *pnob, struct sk_buff *skb,
- u32 wrb_cnt, u32 *copied)
-{
- u64 busaddr;
- struct ETH_WRB_AMAP *wrb = NULL, *first = NULL;
- u32 i;
- bool dummy = true;
- struct pci_dev *pdev = pnob->adapter->pdev;
-
- if (wrb_cnt & 1)
- wrb_cnt++;
- else
- dummy = false;
-
- atomic_add(wrb_cnt, &pnob->tx_q_used);
-
- while (skb) {
- if (skb->len > skb->data_len) {
- int len = skb->len - skb->data_len;
- busaddr = pci_map_single(pdev, skb->data, len,
- PCI_DMA_TODEVICE);
- busaddr = cpu_to_le64(busaddr);
- wrb = &pnob->tx_q[pnob->tx_q_hd];
- if (first == NULL) {
- wrb_fill_extra(wrb, skb, pnob);
- first = wrb;
- } else {
- wrb_copy_extra(wrb, first);
- }
- wrb_fill(wrb, busaddr, len);
- be_adv_txq_hd(pnob);
- *copied += len;
- }
-
- for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
- struct skb_frag_struct *frag =
- &skb_shinfo(skb)->frags[i];
- busaddr = pci_map_page(pdev, frag->page,
- frag->page_offset, frag->size,
- PCI_DMA_TODEVICE);
- busaddr = cpu_to_le64(busaddr);
- wrb = &pnob->tx_q[pnob->tx_q_hd];
- if (first == NULL) {
- wrb_fill_extra(wrb, skb, pnob);
- first = wrb;
- } else {
- wrb_copy_extra(wrb, first);
- }
- wrb_fill(wrb, busaddr, frag->size);
- be_adv_txq_hd(pnob);
- *copied += frag->size;
- }
- skb = skb_shinfo(skb)->frag_list;
- }
-
- if (dummy) {
- wrb = &pnob->tx_q[pnob->tx_q_hd];
- BUG_ON(first == NULL);
- wrb_copy_extra(wrb, first);
- wrb_fill(wrb, 0, 0);
- be_adv_txq_hd(pnob);
- }
- AMAP_SET_BITS_PTR(ETH_WRB, complete, wrb, 1);
- AMAP_SET_BITS_PTR(ETH_WRB, last, wrb, 1);
- return wrb_cnt;
-}
-
-/* For each skb transmitted, tx_ctxt stores the num of wrbs in the
- * start index and skb pointer in the end index
- */
-static inline void be_tx_wrb_info_remember(struct be_net_object *pnob,
- struct sk_buff *skb, int wrb_cnt,
- u32 start)
-{
- *(u32 *) (&pnob->tx_ctxt[start]) = wrb_cnt;
- index_adv(&start, wrb_cnt - 1, pnob->tx_q_len);
- pnob->tx_ctxt[start] = skb;
-}
-
-static int benet_xmit(struct sk_buff *skb, struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
- u32 wrb_cnt, copied = 0;
- u32 start = pnob->tx_q_hd;
-
- adapter->be_stat.bes_tx_reqs++;
-
- wrb_cnt = wrb_cnt_in_skb(skb);
- spin_lock_bh(&adapter->txq_lock);
- if ((pnob->tx_q_len - 2 - atomic_read(&pnob->tx_q_used)) <= wrb_cnt) {
- netif_stop_queue(pnob->netdev);
- spin_unlock_bh(&adapter->txq_lock);
- adapter->be_stat.bes_tx_fails++;
- return NETDEV_TX_BUSY;
- }
- spin_unlock_bh(&adapter->txq_lock);
-
- wrb_cnt = copy_skb_to_txq(pnob, skb, wrb_cnt, &copied);
- be_tx_wrb_info_remember(pnob, skb, wrb_cnt, start);
-
- be_start_tx(pnob, wrb_cnt);
-
- adapter->eth_tx_bytes += copied;
- adapter->be_stat.bes_tx_wrbs += wrb_cnt;
- update_tx_rate(adapter);
- netdev->trans_start = jiffies;
-
- return NETDEV_TX_OK;
-}
-
-/*
- * This is the driver entry point to change the mtu of the device
- * Returns 0 for success and errno for failure.
- */
-static int benet_change_mtu(struct net_device *netdev, int new_mtu)
-{
- /*
- * BE supports jumbo frame size upto 9000 bytes including the link layer
- * header. Considering the different variants of frame formats possible
- * like VLAN, SNAP/LLC, the maximum possible value for MTU is 8974 bytes
- */
-
- if (new_mtu < (ETH_ZLEN + ETH_FCS_LEN) || (new_mtu > BE_MAX_MTU)) {
- dev_info(&netdev->dev, "Invalid MTU requested. "
- "Must be between %d and %d bytes\n",
- (ETH_ZLEN + ETH_FCS_LEN), BE_MAX_MTU);
- return -EINVAL;
- }
- dev_info(&netdev->dev, "MTU changed from %d to %d\n",
- netdev->mtu, new_mtu);
- netdev->mtu = new_mtu;
- return 0;
-}
-
-/*
- * This is the driver entry point to register a vlan with the device
- */
-static void benet_vlan_register(struct net_device *netdev,
- struct vlan_group *grp)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- be_disable_eq_intr(pnob);
- pnob->vlan_grp = grp;
- pnob->num_vlans = 0;
- be_enable_eq_intr(pnob);
-}
-
-/*
- * This is the driver entry point to add a vlan vlan_id
- * with the device netdev
- */
-static void benet_vlan_add_vid(struct net_device *netdev, u16 vlan_id)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- if (pnob->num_vlans == (BE_NUM_VLAN_SUPPORTED - 1)) {
- /* no way to return an error */
- dev_info(&netdev->dev,
- "BladeEngine: Cannot configure more than %d Vlans\n",
- BE_NUM_VLAN_SUPPORTED);
- return;
- }
- /* The new vlan tag will be in the slot indicated by num_vlans. */
- pnob->vlan_tag[pnob->num_vlans++] = vlan_id;
- be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans,
- pnob->vlan_tag, NULL, NULL, NULL);
-}
-
-/*
- * This is the driver entry point to remove a vlan vlan_id
- * with the device netdev
- */
-static void benet_vlan_rem_vid(struct net_device *netdev, u16 vlan_id)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- u32 i, value;
-
- /*
- * In Blade Engine, we support 32 vlan tag filters across both ports.
- * To program a vlan tag, the RXF_RTPR_CSR register is used.
- * Each 32-bit value of RXF_RTDR_CSR can address 2 vlan tag entries.
- * The Vlan table is of depth 16. thus we support 32 tags.
- */
-
- value = vlan_id | VLAN_VALID_BIT;
- for (i = 0; i < BE_NUM_VLAN_SUPPORTED; i++) {
- if (pnob->vlan_tag[i] == vlan_id)
- break;
- }
-
- if (i == BE_NUM_VLAN_SUPPORTED)
- return;
- /* Now compact the vlan tag array by removing hole created. */
- while ((i + 1) < BE_NUM_VLAN_SUPPORTED) {
- pnob->vlan_tag[i] = pnob->vlan_tag[i + 1];
- i++;
- }
- if ((i + 1) == BE_NUM_VLAN_SUPPORTED)
- pnob->vlan_tag[i] = (u16) 0x0;
- pnob->num_vlans--;
- be_rxf_vlan_config(&pnob->fn_obj, false, pnob->num_vlans,
- pnob->vlan_tag, NULL, NULL, NULL);
-}
-
-/*
- * This function is called to program multicast
- * address in the multicast filter of the ASIC.
- */
-static void be_set_multicast_filter(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct dev_mc_list *mc_ptr;
- u8 mac_addr[32][ETH_ALEN];
- int i;
-
- if (netdev->flags & IFF_ALLMULTI) {
- /* set BE in Multicast promiscuous */
- be_rxf_multicast_config(&pnob->fn_obj, true, 0, NULL, NULL,
- NULL, NULL);
- return;
- }
-
- for (mc_ptr = netdev->mc_list, i = 0; mc_ptr;
- mc_ptr = mc_ptr->next, i++) {
- memcpy(&mac_addr[i][0], mc_ptr->dmi_addr, ETH_ALEN);
- }
-
- /* reset the promiscuous mode also. */
- be_rxf_multicast_config(&pnob->fn_obj, false, i,
- &mac_addr[0][0], NULL, NULL, NULL);
-}
-
-/*
- * This is the driver entry point to set multicast list
- * with the device netdev. This function will be used to
- * set promiscuous mode or multicast promiscuous mode
- * or multicast mode....
- */
-static void benet_set_multicast_list(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
-
- if (netdev->flags & IFF_PROMISC) {
- be_rxf_promiscuous(&pnob->fn_obj, 1, 1, NULL, NULL, NULL);
- } else {
- be_rxf_promiscuous(&pnob->fn_obj, 0, 0, NULL, NULL, NULL);
- be_set_multicast_filter(netdev);
- }
-}
-
-int benet_init(struct net_device *netdev)
-{
- struct be_net_object *pnob = netdev_priv(netdev);
- struct be_adapter *adapter = pnob->adapter;
-
- ether_setup(netdev);
-
- netdev->open = &benet_open;
- netdev->stop = &benet_close;
- netdev->hard_start_xmit = &benet_xmit;
-
- netdev->get_stats = &benet_get_stats;
-
- netdev->set_multicast_list = &benet_set_multicast_list;
-
- netdev->change_mtu = &benet_change_mtu;
- netdev->set_mac_address = &benet_set_mac_addr;
-
- netdev->vlan_rx_register = benet_vlan_register;
- netdev->vlan_rx_add_vid = benet_vlan_add_vid;
- netdev->vlan_rx_kill_vid = benet_vlan_rem_vid;
-
- netdev->features =
- NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_HW_VLAN_RX | NETIF_F_TSO |
- NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER | NETIF_F_IP_CSUM;
-
- netdev->flags |= IFF_MULTICAST;
-
- /* If device is DAC Capable, set the HIGHDMA flag for netdevice. */
- if (adapter->dma_64bit_cap)
- netdev->features |= NETIF_F_HIGHDMA;
-
- SET_ETHTOOL_OPS(netdev, &be_ethtool_ops);
- return 0;
-}
diff --git a/drivers/staging/benet/benet.h b/drivers/staging/benet/benet.h
deleted file mode 100644
index 09a1f0817722..000000000000
--- a/drivers/staging/benet/benet.h
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#ifndef _BENET_H_
-#define _BENET_H_
-
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/inet_lro.h>
-#include "hwlib.h"
-
-#define _SA_MODULE_NAME "net-driver"
-
-#define VLAN_VALID_BIT 0x8000
-#define BE_NUM_VLAN_SUPPORTED 32
-#define BE_PORT_LINK_DOWN 0000
-#define BE_PORT_LINK_UP 0001
-#define BE_MAX_TX_FRAG_COUNT (30)
-
-/* Flag bits for send operation */
-#define IPCS (1 << 0) /* Enable IP checksum offload */
-#define UDPCS (1 << 1) /* Enable UDP checksum offload */
-#define TCPCS (1 << 2) /* Enable TCP checksum offload */
-#define LSO (1 << 3) /* Enable Large Segment offload */
-#define ETHVLAN (1 << 4) /* Enable VLAN insert */
-#define ETHEVENT (1 << 5) /* Generate event on completion */
-#define ETHCOMPLETE (1 << 6) /* Generate completion when done */
-#define IPSEC (1 << 7) /* Enable IPSEC */
-#define FORWARD (1 << 8) /* Send the packet in forwarding path */
-#define FIN (1 << 9) /* Issue FIN segment */
-
-#define BE_MAX_MTU 8974
-
-#define BE_MAX_LRO_DESCRIPTORS 8
-#define BE_LRO_MAX_PKTS 64
-#define BE_MAX_FRAGS_PER_FRAME 6
-
-extern const char be_drvr_ver[];
-extern char be_fw_ver[];
-extern char be_driver_name[];
-
-extern struct ethtool_ops be_ethtool_ops;
-
-#define BE_DEV_STATE_NONE 0
-#define BE_DEV_STATE_INIT 1
-#define BE_DEV_STATE_OPEN 2
-#define BE_DEV_STATE_SUSPEND 3
-
-/* This structure is used to describe physical fragments to use
- * for DMAing data from NIC.
- */
-struct be_recv_buffer {
- struct list_head rxb_list; /* for maintaining a linked list */
- void *rxb_va; /* buffer virtual address */
- u32 rxb_pa_lo; /* low part of physical address */
- u32 rxb_pa_hi; /* high part of physical address */
- u32 rxb_len; /* length of recv buffer */
- void *rxb_ctxt; /* context for OSM driver to use */
-};
-
-/*
- * fragment list to describe scattered data.
- */
-struct be_tx_frag_list {
- u32 txb_len; /* Size of this fragment */
- u32 txb_pa_lo; /* Lower 32 bits of 64 bit physical addr */
- u32 txb_pa_hi; /* Higher 32 bits of 64 bit physical addr */
-};
-
-struct be_rx_page_info {
- struct page *page;
- dma_addr_t bus;
- u16 page_offset;
-};
-
-/*
- * This structure is the main tracking structure for a NIC interface.
- */
-struct be_net_object {
- /* MCC Ring - used to send fwcmds to embedded ARM processor */
- struct MCC_WRB_AMAP *mcc_q; /* VA of the start of the ring */
- u32 mcc_q_len; /* # of WRB entries in this ring */
- u32 mcc_q_size;
- u32 mcc_q_hd; /* MCC ring head */
- u8 mcc_q_created; /* flag to help cleanup */
- struct be_mcc_object mcc_q_obj; /* BECLIB's MCC ring Object */
- dma_addr_t mcc_q_bus; /* DMA'ble bus address */
-
- /* MCC Completion Ring - FW responses to fwcmds sent from MCC ring */
- struct MCC_CQ_ENTRY_AMAP *mcc_cq; /* VA of the start of the ring */
- u32 mcc_cq_len; /* # of compl. entries in this ring */
- u32 mcc_cq_size;
- u32 mcc_cq_tl; /* compl. ring tail */
- u8 mcc_cq_created; /* flag to help cleanup */
- struct be_cq_object mcc_cq_obj; /* BECLIB's MCC compl. ring object */
- u32 mcc_cq_id; /* MCC ring ID */
- dma_addr_t mcc_cq_bus; /* DMA'ble bus address */
-
- struct ring_desc mb_rd; /* RD for MCC_MAIL_BOX */
- void *mb_ptr; /* mailbox ptr to be freed */
- dma_addr_t mb_bus; /* DMA'ble bus address */
- u32 mb_size;
-
- /* BEClib uses an array of context objects to track outstanding
- * requests to the MCC. We need allocate the same number of
- * conext entries as the number of entries in the MCC WRB ring
- */
- u32 mcc_wrb_ctxt_size;
- void *mcc_wrb_ctxt; /* pointer to the context area */
- u32 mcc_wrb_ctxtLen; /* Number of entries in the context */
- /*
- * NIC send request ring - used for xmitting raw ether frames.
- */
- struct ETH_WRB_AMAP *tx_q; /* VA of the start of the ring */
- u32 tx_q_len; /* # if entries in the send ring */
- u32 tx_q_size;
- u32 tx_q_hd; /* Head index. Next req. goes here */
- u32 tx_q_tl; /* Tail indx. oldest outstanding req. */
- u8 tx_q_created; /* flag to help cleanup */
- struct be_ethsq_object tx_q_obj;/* BECLIB's send Q handle */
- dma_addr_t tx_q_bus; /* DMA'ble bus address */
- u32 tx_q_id; /* send queue ring ID */
- u32 tx_q_port; /* 0 no binding, 1 port A, 2 port B */
- atomic_t tx_q_used; /* # of WRBs used */
- /* ptr to an array in which we store context info for each send req. */
- void **tx_ctxt;
- /*
- * NIC Send compl. ring - completion status for all NIC frames xmitted.
- */
- struct ETH_TX_COMPL_AMAP *tx_cq;/* VA of start of the ring */
- u32 txcq_len; /* # of entries in the ring */
- u32 tx_cq_size;
- /*
- * index into compl ring where the host expects next completion entry
- */
- u32 tx_cq_tl;
- u32 tx_cq_id; /* completion queue id */
- u8 tx_cq_created; /* flag to help cleanup */
- struct be_cq_object tx_cq_obj;
- dma_addr_t tx_cq_bus; /* DMA'ble bus address */
- /*
- * Event Queue - all completion entries post events here.
- */
- struct EQ_ENTRY_AMAP *event_q; /* VA of start of event queue */
- u32 event_q_len; /* # of entries */
- u32 event_q_size;
- u32 event_q_tl; /* Tail of the event queue */
- u32 event_q_id; /* Event queue ID */
- u8 event_q_created; /* flag to help cleanup */
- struct be_eq_object event_q_obj; /* Queue handle */
- dma_addr_t event_q_bus; /* DMA'ble bus address */
- /*
- * NIC receive queue - Data buffers to be used for receiving unicast,
- * broadcast and multi-cast frames are posted here.
- */
- struct ETH_RX_D_AMAP *rx_q; /* VA of start of the queue */
- u32 rx_q_len; /* # of entries */
- u32 rx_q_size;
- u32 rx_q_hd; /* Head of the queue */
- atomic_t rx_q_posted; /* number of posted buffers */
- u32 rx_q_id; /* queue ID */
- u8 rx_q_created; /* flag to help cleanup */
- struct be_ethrq_object rx_q_obj; /* NIC RX queue handle */
- dma_addr_t rx_q_bus; /* DMA'ble bus address */
- /*
- * Pointer to an array of opaque context object for use by OSM driver
- */
- void **rx_ctxt;
- /*
- * NIC unicast RX completion queue - all unicast ether frame completion
- * statuses from BE come here.
- */
- struct ETH_RX_COMPL_AMAP *rx_cq; /* VA of start of the queue */
- u32 rx_cq_len; /* # of entries */
- u32 rx_cq_size;
- u32 rx_cq_tl; /* Tail of the queue */
- u32 rx_cq_id; /* queue ID */
- u8 rx_cq_created; /* flag to help cleanup */
- struct be_cq_object rx_cq_obj; /* queue handle */
- dma_addr_t rx_cq_bus; /* DMA'ble bus address */
- struct be_function_object fn_obj; /* function object */
- bool fn_obj_created;
- u32 rx_buf_size; /* Size of the RX buffers */
-
- struct net_device *netdev;
- struct be_recv_buffer eth_rx_bufs[256]; /* to pass Rx buffer
- addresses */
- struct be_adapter *adapter; /* Pointer to OSM adapter */
- u32 devno; /* OSM, network dev no. */
- u32 use_port; /* Current active port */
- struct be_rx_page_info *rx_page_info; /* Array of Rx buf pages */
- u32 rx_pg_info_hd; /* Head of queue */
- int rxbuf_post_fail; /* RxBuff posting fail count */
- bool rx_pg_shared; /* Is an allocsted page shared as two frags ? */
- struct vlan_group *vlan_grp;
- u32 num_vlans; /* Number of vlans in BE's filter */
- u16 vlan_tag[BE_NUM_VLAN_SUPPORTED]; /* vlans currently configured */
- struct napi_struct napi;
- struct net_lro_mgr lro_mgr;
- struct net_lro_desc lro_desc[BE_MAX_LRO_DESCRIPTORS];
-};
-
-#define NET_FH(np) (&(np)->fn_obj)
-
-/*
- * BE driver statistics.
- */
-struct be_drvr_stat {
- u32 bes_tx_reqs; /* number of TX requests initiated */
- u32 bes_tx_fails; /* number of TX requests that failed */
- u32 bes_fwd_reqs; /* number of send reqs through forwarding i/f */
- u32 bes_tx_wrbs; /* number of tx WRBs used */
-
- u32 bes_ints; /* number of interrupts */
- u32 bes_polls; /* number of times NAPI called poll function */
- u32 bes_events; /* total evet entries processed */
- u32 bes_tx_events; /* number of tx completion events */
- u32 bes_rx_events; /* number of ucast rx completion events */
- u32 bes_tx_compl; /* number of tx completion entries processed */
- u32 bes_rx_compl; /* number of rx completion entries
- processed */
- u32 bes_ethrx_post_fail; /* number of ethrx buffer alloc
- failures */
- /*
- * number of non ether type II frames dropped where
- * frame len > length field of Mac Hdr
- */
- u32 bes_802_3_dropped_frames;
- /*
- * number of non ether type II frames malformed where
- * in frame len < length field of Mac Hdr
- */
- u32 bes_802_3_malformed_frames;
- u32 bes_ips; /* interrupts / sec */
- u32 bes_prev_ints; /* bes_ints at last IPS calculation */
- u16 bes_eth_tx_rate; /* ETH TX rate - Mb/sec */
- u16 bes_eth_rx_rate; /* ETH RX rate - Mb/sec */
- u32 bes_rx_coal; /* Num pkts coalasced */
- u32 bes_rx_flush; /* Num times coalasced */
- u32 bes_link_change_physical; /*Num of times physical link changed */
- u32 bes_link_change_virtual; /*Num of times virtual link changed */
- u32 bes_rx_misc_pkts; /* Misc pkts received */
-};
-
-/* Maximum interrupt delay (in microseconds) allowed */
-#define MAX_EQD 120
-
-/*
- * timer to prevent system shutdown hang for ever if h/w stops responding
- */
-struct be_timer_ctxt {
- atomic_t get_stat_flag;
- struct timer_list get_stats_timer;
- unsigned long get_stat_sem_addr;
-} ;
-
-/* This structure is the main BladeEngine driver context. */
-struct be_adapter {
- struct net_device *netdevp;
- struct be_drvr_stat be_stat;
- struct net_device_stats benet_stats;
-
- /* PCI BAR mapped addresses */
- u8 __iomem *csr_va; /* CSR */
- u8 __iomem *db_va; /* Door Bell */
- u8 __iomem *pci_va; /* PCI Config */
-
- struct tasklet_struct sts_handler;
- struct timer_list cq_timer;
- spinlock_t int_lock; /* to protect the isr field in adapter */
-
- struct FWCMD_ETH_GET_STATISTICS *eth_statsp;
- /*
- * This will enable the use of ethtool to enable or disable
- * Checksum on Rx pkts to be obeyed or disobeyed.
- * If this is true = 1, then whatever is the checksum on the
- * Received pkt as per BE, it will be given to the stack.
- * Else the stack will re calculate it.
- */
- bool rx_csum;
- /*
- * This will enable the use of ethtool to enable or disable
- * Coalese on Rx pkts to be obeyed or disobeyed.
- * If this is grater than 0 and less than 16 then coalascing
- * is enabled else it is disabled
- */
- u32 max_rx_coal;
- struct pci_dev *pdev; /* Pointer to OS's PCI dvice */
-
- spinlock_t txq_lock; /* to stop/wake queue based on tx_q_used */
-
- u32 isr; /* copy of Intr status reg. */
-
- u32 port0_link_sts; /* Port 0 link status */
- u32 port1_link_sts; /* port 1 list status */
- struct BE_LINK_STATUS *be_link_sts;
-
- /* pointer to the first netobject of this adapter */
- struct be_net_object *net_obj;
-
- /* Flags to indicate what to clean up */
- bool tasklet_started;
- bool isr_registered;
- /*
- * adaptive interrupt coalescing (AIC) related
- */
- bool enable_aic; /* 1 if AIC is enabled */
- u16 min_eqd; /* minimum EQ delay in usec */
- u16 max_eqd; /* minimum EQ delay in usec */
- u16 cur_eqd; /* current EQ delay in usec */
- /*
- * book keeping for interrupt / sec and TX/RX rate calculation
- */
- ulong ips_jiffies; /* jiffies at last IPS calc */
- u32 eth_tx_bytes;
- ulong eth_tx_jiffies;
- u32 eth_rx_bytes;
- ulong eth_rx_jiffies;
-
- struct semaphore get_eth_stat_sem;
-
- /* timer ctxt to prevent shutdown hanging due to un-responsive BE */
- struct be_timer_ctxt timer_ctxt;
-
-#define BE_MAX_MSIX_VECTORS 32
-#define BE_MAX_REQ_MSIX_VECTORS 1 /* only one EQ in Linux driver */
- struct msix_entry msix_entries[BE_MAX_MSIX_VECTORS];
- bool msix_enabled;
- bool dma_64bit_cap; /* the Device DAC capable or not */
- u8 dev_state; /* The current state of the device */
- u8 dev_pm_state; /* The State of device before going to suspend */
-};
-
-/*
- * Every second we look at the ints/sec and adjust eq_delay
- * between adapter->min_eqd and adapter->max_eqd to keep the ints/sec between
- * IPS_HI_WM and IPS_LO_WM.
- */
-#define IPS_HI_WM 18000
-#define IPS_LO_WM 8000
-
-
-static inline void index_adv(u32 *index, u32 val, u32 limit)
-{
- BUG_ON(limit & (limit-1));
- *index = (*index + val) & (limit - 1);
-}
-
-static inline void index_inc(u32 *index, u32 limit)
-{
- BUG_ON(limit & (limit-1));
- *index = (*index + 1) & (limit - 1);
-}
-
-static inline void be_adv_eq_tl(struct be_net_object *pnob)
-{
- index_inc(&pnob->event_q_tl, pnob->event_q_len);
-}
-
-static inline void be_adv_txq_hd(struct be_net_object *pnob)
-{
- index_inc(&pnob->tx_q_hd, pnob->tx_q_len);
-}
-
-static inline void be_adv_txq_tl(struct be_net_object *pnob)
-{
- index_inc(&pnob->tx_q_tl, pnob->tx_q_len);
-}
-
-static inline void be_adv_txcq_tl(struct be_net_object *pnob)
-{
- index_inc(&pnob->tx_cq_tl, pnob->txcq_len);
-}
-
-static inline void be_adv_rxq_hd(struct be_net_object *pnob)
-{
- index_inc(&pnob->rx_q_hd, pnob->rx_q_len);
-}
-
-static inline void be_adv_rxcq_tl(struct be_net_object *pnob)
-{
- index_inc(&pnob->rx_cq_tl, pnob->rx_cq_len);
-}
-
-static inline u32 tx_compl_lastwrb_idx_get(struct be_net_object *pnob)
-{
- return (pnob->tx_q_tl + *(u32 *)&pnob->tx_ctxt[pnob->tx_q_tl] - 1)
- & (pnob->tx_q_len - 1);
-}
-
-int benet_init(struct net_device *);
-int be_ethtool_ioctl(struct net_device *, struct ifreq *);
-struct net_device_stats *benet_get_stats(struct net_device *);
-void be_process_intr(unsigned long context);
-irqreturn_t be_int(int irq, void *dev);
-void be_post_eth_rx_buffs(struct be_net_object *);
-void be_get_stat_cb(void *, int, struct MCC_WRB_AMAP *);
-void be_get_stats_timer_handler(unsigned long);
-void be_wait_nic_tx_cmplx_cmpl(struct be_net_object *);
-void be_print_link_info(struct BE_LINK_STATUS *);
-void be_update_link_status(struct be_adapter *);
-void be_init_procfs(struct be_adapter *);
-void be_cleanup_procfs(struct be_adapter *);
-int be_poll(struct napi_struct *, int);
-struct ETH_RX_COMPL_AMAP *be_get_rx_cmpl(struct be_net_object *);
-void be_notify_cmpl(struct be_net_object *, int, int, int);
-void be_enable_intr(struct be_net_object *);
-void be_enable_eq_intr(struct be_net_object *);
-void be_disable_intr(struct be_net_object *);
-void be_disable_eq_intr(struct be_net_object *);
-int be_set_uc_mac_adr(struct be_net_object *, u8, u8, u8,
- u8 *, mcc_wrb_cqe_callback, void *);
-int be_get_flow_ctl(struct be_function_object *pFnObj, bool *, bool *);
-void process_one_tx_compl(struct be_net_object *pnob, u32 end_idx);
-
-#endif /* _BENET_H_ */
diff --git a/drivers/staging/benet/bestatus.h b/drivers/staging/benet/bestatus.h
deleted file mode 100644
index 59c7a4b62223..000000000000
--- a/drivers/staging/benet/bestatus.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#ifndef _BESTATUS_H_
-#define _BESTATUS_H_
-
-#define BE_SUCCESS (0x00000000L)
-/*
- * MessageId: BE_PENDING
- * The BladeEngine Driver call succeeded, and pended operation.
- */
-#define BE_PENDING (0x20070001L)
-#define BE_STATUS_PENDING (BE_PENDING)
-/*
- * MessageId: BE_NOT_OK
- * An error occurred.
- */
-#define BE_NOT_OK (0xE0070002L)
-/*
- * MessageId: BE_STATUS_SYSTEM_RESOURCES
- * Insufficient host system resources exist to complete the API.
- */
-#define BE_STATUS_SYSTEM_RESOURCES (0xE0070003L)
-/*
- * MessageId: BE_STATUS_CHIP_RESOURCES
- * Insufficient chip resources exist to complete the API.
- */
-#define BE_STATUS_CHIP_RESOURCES (0xE0070004L)
-/*
- * MessageId: BE_STATUS_NO_RESOURCE
- * Insufficient resources to complete request.
- */
-#define BE_STATUS_NO_RESOURCE (0xE0070005L)
-/*
- * MessageId: BE_STATUS_BUSY
- * Resource is currently busy.
- */
-#define BE_STATUS_BUSY (0xE0070006L)
-/*
- * MessageId: BE_STATUS_INVALID_PARAMETER
- * Invalid Parameter in request.
- */
-#define BE_STATUS_INVALID_PARAMETER (0xE0000007L)
-/*
- * MessageId: BE_STATUS_NOT_SUPPORTED
- * Requested operation is not supported.
- */
-#define BE_STATUS_NOT_SUPPORTED (0xE000000DL)
-
-/*
- * ***************************************************************************
- * E T H E R N E T S T A T U S
- * ***************************************************************************
- */
-
-/*
- * MessageId: BE_ETH_TX_ERROR
- * The Ethernet device driver failed to transmit a packet.
- */
-#define BE_ETH_TX_ERROR (0xE0070101L)
-
-/*
- * ***************************************************************************
- * S H A R E D S T A T U S
- * ***************************************************************************
- */
-
-/*
- * MessageId: BE_STATUS_VBD_INVALID_VERSION
- * The device driver is not compatible with this version of the VBD.
- */
-#define BE_STATUS_INVALID_VERSION (0xE0070402L)
-/*
- * MessageId: BE_STATUS_DOMAIN_DENIED
- * The operation failed to complete due to insufficient access
- * rights for the requesting domain.
- */
-#define BE_STATUS_DOMAIN_DENIED (0xE0070403L)
-/*
- * MessageId: BE_STATUS_TCP_NOT_STARTED
- * The embedded TCP/IP stack has not been started.
- */
-#define BE_STATUS_TCP_NOT_STARTED (0xE0070409L)
-/*
- * MessageId: BE_STATUS_NO_MCC_WRB
- * No free MCC WRB are available for posting the request.
- */
-#define BE_STATUS_NO_MCC_WRB (0xE0070414L)
-
-#endif /* _BESTATUS_ */
diff --git a/drivers/staging/benet/cev.h b/drivers/staging/benet/cev.h
deleted file mode 100644
index 30996920a544..000000000000
--- a/drivers/staging/benet/cev.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __cev_amap_h__
-#define __cev_amap_h__
-#include "ep.h"
-
-/*
- * Host Interrupt Status Register 0. The first of four application
- * interrupt status registers. This register contains the interrupts
- * for Event Queues EQ0 through EQ31.
- */
-struct BE_CEV_ISR0_CSR_AMAP {
- u8 interrupt0; /* DWORD 0 */
- u8 interrupt1; /* DWORD 0 */
- u8 interrupt2; /* DWORD 0 */
- u8 interrupt3; /* DWORD 0 */
- u8 interrupt4; /* DWORD 0 */
- u8 interrupt5; /* DWORD 0 */
- u8 interrupt6; /* DWORD 0 */
- u8 interrupt7; /* DWORD 0 */
- u8 interrupt8; /* DWORD 0 */
- u8 interrupt9; /* DWORD 0 */
- u8 interrupt10; /* DWORD 0 */
- u8 interrupt11; /* DWORD 0 */
- u8 interrupt12; /* DWORD 0 */
- u8 interrupt13; /* DWORD 0 */
- u8 interrupt14; /* DWORD 0 */
- u8 interrupt15; /* DWORD 0 */
- u8 interrupt16; /* DWORD 0 */
- u8 interrupt17; /* DWORD 0 */
- u8 interrupt18; /* DWORD 0 */
- u8 interrupt19; /* DWORD 0 */
- u8 interrupt20; /* DWORD 0 */
- u8 interrupt21; /* DWORD 0 */
- u8 interrupt22; /* DWORD 0 */
- u8 interrupt23; /* DWORD 0 */
- u8 interrupt24; /* DWORD 0 */
- u8 interrupt25; /* DWORD 0 */
- u8 interrupt26; /* DWORD 0 */
- u8 interrupt27; /* DWORD 0 */
- u8 interrupt28; /* DWORD 0 */
- u8 interrupt29; /* DWORD 0 */
- u8 interrupt30; /* DWORD 0 */
- u8 interrupt31; /* DWORD 0 */
-} __packed;
-struct CEV_ISR0_CSR_AMAP {
- u32 dw[1];
-};
-
-/*
- * Host Interrupt Status Register 1. The second of four application
- * interrupt status registers. This register contains the interrupts
- * for Event Queues EQ32 through EQ63.
- */
-struct BE_CEV_ISR1_CSR_AMAP {
- u8 interrupt32; /* DWORD 0 */
- u8 interrupt33; /* DWORD 0 */
- u8 interrupt34; /* DWORD 0 */
- u8 interrupt35; /* DWORD 0 */
- u8 interrupt36; /* DWORD 0 */
- u8 interrupt37; /* DWORD 0 */
- u8 interrupt38; /* DWORD 0 */
- u8 interrupt39; /* DWORD 0 */
- u8 interrupt40; /* DWORD 0 */
- u8 interrupt41; /* DWORD 0 */
- u8 interrupt42; /* DWORD 0 */
- u8 interrupt43; /* DWORD 0 */
- u8 interrupt44; /* DWORD 0 */
- u8 interrupt45; /* DWORD 0 */
- u8 interrupt46; /* DWORD 0 */
- u8 interrupt47; /* DWORD 0 */
- u8 interrupt48; /* DWORD 0 */
- u8 interrupt49; /* DWORD 0 */
- u8 interrupt50; /* DWORD 0 */
- u8 interrupt51; /* DWORD 0 */
- u8 interrupt52; /* DWORD 0 */
- u8 interrupt53; /* DWORD 0 */
- u8 interrupt54; /* DWORD 0 */
- u8 interrupt55; /* DWORD 0 */
- u8 interrupt56; /* DWORD 0 */
- u8 interrupt57; /* DWORD 0 */
- u8 interrupt58; /* DWORD 0 */
- u8 interrupt59; /* DWORD 0 */
- u8 interrupt60; /* DWORD 0 */
- u8 interrupt61; /* DWORD 0 */
- u8 interrupt62; /* DWORD 0 */
- u8 interrupt63; /* DWORD 0 */
-} __packed;
-struct CEV_ISR1_CSR_AMAP {
- u32 dw[1];
-};
-/*
- * Host Interrupt Status Register 2. The third of four application
- * interrupt status registers. This register contains the interrupts
- * for Event Queues EQ64 through EQ95.
- */
-struct BE_CEV_ISR2_CSR_AMAP {
- u8 interrupt64; /* DWORD 0 */
- u8 interrupt65; /* DWORD 0 */
- u8 interrupt66; /* DWORD 0 */
- u8 interrupt67; /* DWORD 0 */
- u8 interrupt68; /* DWORD 0 */
- u8 interrupt69; /* DWORD 0 */
- u8 interrupt70; /* DWORD 0 */
- u8 interrupt71; /* DWORD 0 */
- u8 interrupt72; /* DWORD 0 */
- u8 interrupt73; /* DWORD 0 */
- u8 interrupt74; /* DWORD 0 */
- u8 interrupt75; /* DWORD 0 */
- u8 interrupt76; /* DWORD 0 */
- u8 interrupt77; /* DWORD 0 */
- u8 interrupt78; /* DWORD 0 */
- u8 interrupt79; /* DWORD 0 */
- u8 interrupt80; /* DWORD 0 */
- u8 interrupt81; /* DWORD 0 */
- u8 interrupt82; /* DWORD 0 */
- u8 interrupt83; /* DWORD 0 */
- u8 interrupt84; /* DWORD 0 */
- u8 interrupt85; /* DWORD 0 */
- u8 interrupt86; /* DWORD 0 */
- u8 interrupt87; /* DWORD 0 */
- u8 interrupt88; /* DWORD 0 */
- u8 interrupt89; /* DWORD 0 */
- u8 interrupt90; /* DWORD 0 */
- u8 interrupt91; /* DWORD 0 */
- u8 interrupt92; /* DWORD 0 */
- u8 interrupt93; /* DWORD 0 */
- u8 interrupt94; /* DWORD 0 */
- u8 interrupt95; /* DWORD 0 */
-} __packed;
-struct CEV_ISR2_CSR_AMAP {
- u32 dw[1];
-};
-
-/*
- * Host Interrupt Status Register 3. The fourth of four application
- * interrupt status registers. This register contains the interrupts
- * for Event Queues EQ96 through EQ127.
- */
-struct BE_CEV_ISR3_CSR_AMAP {
- u8 interrupt96; /* DWORD 0 */
- u8 interrupt97; /* DWORD 0 */
- u8 interrupt98; /* DWORD 0 */
- u8 interrupt99; /* DWORD 0 */
- u8 interrupt100; /* DWORD 0 */
- u8 interrupt101; /* DWORD 0 */
- u8 interrupt102; /* DWORD 0 */
- u8 interrupt103; /* DWORD 0 */
- u8 interrupt104; /* DWORD 0 */
- u8 interrupt105; /* DWORD 0 */
- u8 interrupt106; /* DWORD 0 */
- u8 interrupt107; /* DWORD 0 */
- u8 interrupt108; /* DWORD 0 */
- u8 interrupt109; /* DWORD 0 */
- u8 interrupt110; /* DWORD 0 */
- u8 interrupt111; /* DWORD 0 */
- u8 interrupt112; /* DWORD 0 */
- u8 interrupt113; /* DWORD 0 */
- u8 interrupt114; /* DWORD 0 */
- u8 interrupt115; /* DWORD 0 */
- u8 interrupt116; /* DWORD 0 */
- u8 interrupt117; /* DWORD 0 */
- u8 interrupt118; /* DWORD 0 */
- u8 interrupt119; /* DWORD 0 */
- u8 interrupt120; /* DWORD 0 */
- u8 interrupt121; /* DWORD 0 */
- u8 interrupt122; /* DWORD 0 */
- u8 interrupt123; /* DWORD 0 */
- u8 interrupt124; /* DWORD 0 */
- u8 interrupt125; /* DWORD 0 */
- u8 interrupt126; /* DWORD 0 */
- u8 interrupt127; /* DWORD 0 */
-} __packed;
-struct CEV_ISR3_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Completions and Events block Registers. */
-struct BE_CEV_CSRMAP_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[32]; /* DWORD 1 */
- u8 rsvd2[32]; /* DWORD 2 */
- u8 rsvd3[32]; /* DWORD 3 */
- struct BE_CEV_ISR0_CSR_AMAP isr0;
- struct BE_CEV_ISR1_CSR_AMAP isr1;
- struct BE_CEV_ISR2_CSR_AMAP isr2;
- struct BE_CEV_ISR3_CSR_AMAP isr3;
- u8 rsvd4[32]; /* DWORD 8 */
- u8 rsvd5[32]; /* DWORD 9 */
- u8 rsvd6[32]; /* DWORD 10 */
- u8 rsvd7[32]; /* DWORD 11 */
- u8 rsvd8[32]; /* DWORD 12 */
- u8 rsvd9[32]; /* DWORD 13 */
- u8 rsvd10[32]; /* DWORD 14 */
- u8 rsvd11[32]; /* DWORD 15 */
- u8 rsvd12[32]; /* DWORD 16 */
- u8 rsvd13[32]; /* DWORD 17 */
- u8 rsvd14[32]; /* DWORD 18 */
- u8 rsvd15[32]; /* DWORD 19 */
- u8 rsvd16[32]; /* DWORD 20 */
- u8 rsvd17[32]; /* DWORD 21 */
- u8 rsvd18[32]; /* DWORD 22 */
- u8 rsvd19[32]; /* DWORD 23 */
- u8 rsvd20[32]; /* DWORD 24 */
- u8 rsvd21[32]; /* DWORD 25 */
- u8 rsvd22[32]; /* DWORD 26 */
- u8 rsvd23[32]; /* DWORD 27 */
- u8 rsvd24[32]; /* DWORD 28 */
- u8 rsvd25[32]; /* DWORD 29 */
- u8 rsvd26[32]; /* DWORD 30 */
- u8 rsvd27[32]; /* DWORD 31 */
- u8 rsvd28[32]; /* DWORD 32 */
- u8 rsvd29[32]; /* DWORD 33 */
- u8 rsvd30[192]; /* DWORD 34 */
- u8 rsvd31[192]; /* DWORD 40 */
- u8 rsvd32[160]; /* DWORD 46 */
- u8 rsvd33[160]; /* DWORD 51 */
- u8 rsvd34[160]; /* DWORD 56 */
- u8 rsvd35[96]; /* DWORD 61 */
- u8 rsvd36[192][32]; /* DWORD 64 */
-} __packed;
-struct CEV_CSRMAP_AMAP {
- u32 dw[256];
-};
-
-#endif /* __cev_amap_h__ */
diff --git a/drivers/staging/benet/cq.c b/drivers/staging/benet/cq.c
deleted file mode 100644
index 650458645433..000000000000
--- a/drivers/staging/benet/cq.c
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include "hwlib.h"
-#include "bestatus.h"
-
-/*
- * Completion Queue Objects
- */
-/*
- *============================================================================
- * P U B L I C R O U T I N E S
- *============================================================================
- */
-
-/*
- This routine creates a completion queue based on the client completion
- queue configuration information.
-
-
- FunctionObject - Handle to a function object
- CqBaseVa - Base VA for a the CQ ring
- NumEntries - CEV_CQ_CNT_* values
- solEventEnable - 0 = All CQEs can generate Events if CQ is eventable
- 1 = only CQEs with solicited bit set are eventable
- eventable - Eventable CQ, generates interrupts.
- nodelay - 1 = Force interrupt, relevent if CQ eventable.
- Interrupt is asserted immediately after EQE
- write is confirmed, regardless of EQ Timer
- or watermark settings.
- wme - Enable watermark based coalescing
- wmThresh - High watermark(CQ fullness at which event
- or interrupt should be asserted). These are the
- CEV_WATERMARK encoded values.
- EqObject - EQ Handle to assign to this CQ
- ppCqObject - Internal CQ Handle returned.
-
- Returns BE_SUCCESS if successfull, otherwise a useful error code is
- returned.
-
- IRQL < DISPATCH_LEVEL
-
-*/
-int be_cq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length, bool solicited_eventable,
- bool no_delay, u32 wm_thresh,
- struct be_eq_object *eq_object, struct be_cq_object *cq_object)
-{
- int status = BE_SUCCESS;
- u32 num_entries_encoding;
- u32 num_entries = length / sizeof(struct MCC_CQ_ENTRY_AMAP);
- struct FWCMD_COMMON_CQ_CREATE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 n;
- unsigned long irql;
-
- ASSERT(rd);
- ASSERT(cq_object);
- ASSERT(length % sizeof(struct MCC_CQ_ENTRY_AMAP) == 0);
-
- switch (num_entries) {
- case 256:
- num_entries_encoding = CEV_CQ_CNT_256;
- break;
- case 512:
- num_entries_encoding = CEV_CQ_CNT_512;
- break;
- case 1024:
- num_entries_encoding = CEV_CQ_CNT_1024;
- break;
- default:
- ASSERT(0);
- return BE_STATUS_INVALID_PARAMETER;
- }
-
- /*
- * All cq entries all the same size. Use iSCSI version
- * as a test for the proper rd length.
- */
- memset(cq_object, 0, sizeof(*cq_object));
-
- atomic_set(&cq_object->ref_count, 0);
- cq_object->parent_function = pfob;
- cq_object->eq_object = eq_object;
- cq_object->num_entries = num_entries;
- /* save for MCC cq processing */
- cq_object->va = rd->va;
-
- /* map into UT. */
- length = num_entries * sizeof(struct MCC_CQ_ENTRY_AMAP);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in create EQ.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_CQ_CREATE);
-
- fwcmd->params.request.num_pages = PAGES_SPANNED(OFFSET_IN_PAGE(rd->va),
- length);
-
- AMAP_SET_BITS_PTR(CQ_CONTEXT, valid, &fwcmd->params.request.context, 1);
- n = pfob->pci_function_number;
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Func, &fwcmd->params.request.context, n);
-
- n = (eq_object != NULL);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Eventable,
- &fwcmd->params.request.context, n);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Armed, &fwcmd->params.request.context, 1);
-
- n = eq_object ? eq_object->eq_id : 0;
- AMAP_SET_BITS_PTR(CQ_CONTEXT, EQID, &fwcmd->params.request.context, n);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Count,
- &fwcmd->params.request.context, num_entries_encoding);
-
- n = 0; /* Protection Domain is always 0 in Linux driver */
- AMAP_SET_BITS_PTR(CQ_CONTEXT, PD, &fwcmd->params.request.context, n);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, NoDelay,
- &fwcmd->params.request.context, no_delay);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, SolEvent,
- &fwcmd->params.request.context, solicited_eventable);
-
- n = (wm_thresh != 0xFFFFFFFF);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, WME, &fwcmd->params.request.context, n);
-
- n = (n ? wm_thresh : 0);
- AMAP_SET_BITS_PTR(CQ_CONTEXT, Watermark,
- &fwcmd->params.request.context, n);
- /* Create a page list for the FWCMD. */
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "MCC to create CQ failed.");
- goto Error;
- }
- /* Remember the CQ id. */
- cq_object->cq_id = fwcmd->params.response.cq_id;
-
- /* insert this cq into eq_object reference */
- if (eq_object) {
- atomic_inc(&eq_object->ref_count);
- list_add_tail(&cq_object->cqlist_for_eq,
- &eq_object->cq_list_head);
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
-
- Deferences the given object. Once the object's reference count drops to
- zero, the object is destroyed and all resources that are held by this object
- are released. The on-chip context is also destroyed along with the queue
- ID, and any mappings made into the UT.
-
- cq_object - CQ handle returned from cq_object_create.
-
- returns the current reference count on the object
-
- IRQL: IRQL < DISPATCH_LEVEL
-*/
-int be_cq_destroy(struct be_cq_object *cq_object)
-{
- int status = 0;
-
- /* Nothing should reference this CQ at this point. */
- ASSERT(atomic_read(&cq_object->ref_count) == 0);
-
- /* Send fwcmd to destroy the CQ. */
- status = be_function_ring_destroy(cq_object->parent_function,
- cq_object->cq_id, FWCMD_RING_TYPE_CQ,
- NULL, NULL, NULL, NULL);
- ASSERT(status == 0);
-
- /* Remove reference if this is an eventable CQ. */
- if (cq_object->eq_object) {
- atomic_dec(&cq_object->eq_object->ref_count);
- list_del(&cq_object->cqlist_for_eq);
- }
- return BE_SUCCESS;
-}
-
diff --git a/drivers/staging/benet/descriptors.h b/drivers/staging/benet/descriptors.h
deleted file mode 100644
index 8da438c407d2..000000000000
--- a/drivers/staging/benet/descriptors.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __descriptors_amap_h__
-#define __descriptors_amap_h__
-
-/*
- * --- IPC_NODE_ID_ENUM ---
- * IPC processor id values
- */
-#define TPOST_NODE_ID (0) /* TPOST ID */
-#define TPRE_NODE_ID (1) /* TPRE ID */
-#define TXULP0_NODE_ID (2) /* TXULP0 ID */
-#define TXULP1_NODE_ID (3) /* TXULP1 ID */
-#define TXULP2_NODE_ID (4) /* TXULP2 ID */
-#define RXULP0_NODE_ID (5) /* RXULP0 ID */
-#define RXULP1_NODE_ID (6) /* RXULP1 ID */
-#define RXULP2_NODE_ID (7) /* RXULP2 ID */
-#define MPU_NODE_ID (15) /* MPU ID */
-
-/*
- * --- MAC_ID_ENUM ---
- * Meaning of the mac_id field in rxpp_eth_d
- */
-#define PORT0_HOST_MAC0 (0) /* PD 0, Port 0, host networking, MAC 0. */
-#define PORT0_HOST_MAC1 (1) /* PD 0, Port 0, host networking, MAC 1. */
-#define PORT0_STORAGE_MAC0 (2) /* PD 0, Port 0, host storage, MAC 0. */
-#define PORT0_STORAGE_MAC1 (3) /* PD 0, Port 0, host storage, MAC 1. */
-#define PORT1_HOST_MAC0 (4) /* PD 0, Port 1 host networking, MAC 0. */
-#define PORT1_HOST_MAC1 (5) /* PD 0, Port 1 host networking, MAC 1. */
-#define PORT1_STORAGE_MAC0 (6) /* PD 0, Port 1 host storage, MAC 0. */
-#define PORT1_STORAGE_MAC1 (7) /* PD 0, Port 1 host storage, MAC 1. */
-#define FIRST_VM_MAC (8) /* PD 1 MAC. Protection domains have IDs */
- /* from 0x8-0x26, one per PD. */
-#define LAST_VM_MAC (38) /* PD 31 MAC. */
-#define MGMT_MAC (39) /* Management port MAC. */
-#define MARBLE_MAC0 (59) /* Used for flushing function 0 receive */
- /*
- * queues before re-using a torn-down
- * receive ring. the DA =
- * 00-00-00-00-00-00, and the MSB of the
- * SA = 00
- */
-#define MARBLE_MAC1 (60) /* Used for flushing function 1 receive */
- /*
- * queues before re-using a torn-down
- * receive ring. the DA =
- * 00-00-00-00-00-00, and the MSB of the
- * SA != 00
- */
-#define NULL_MAC (61) /* Promiscuous mode, indicates no match */
-#define MCAST_MAC (62) /* Multicast match. */
-#define BCAST_MATCH (63) /* Broadcast match. */
-
-#endif /* __descriptors_amap_h__ */
diff --git a/drivers/staging/benet/doorbells.h b/drivers/staging/benet/doorbells.h
deleted file mode 100644
index 550cc4d5d6f7..000000000000
--- a/drivers/staging/benet/doorbells.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __doorbells_amap_h__
-#define __doorbells_amap_h__
-
-/* The TX/RDMA send queue doorbell. */
-struct BE_SQ_DB_AMAP {
- u8 cid[11]; /* DWORD 0 */
- u8 rsvd0[5]; /* DWORD 0 */
- u8 numPosted[14]; /* DWORD 0 */
- u8 rsvd1[2]; /* DWORD 0 */
-} __packed;
-struct SQ_DB_AMAP {
- u32 dw[1];
-};
-
-/* The receive queue doorbell. */
-struct BE_RQ_DB_AMAP {
- u8 rq[10]; /* DWORD 0 */
- u8 rsvd0[13]; /* DWORD 0 */
- u8 Invalidate; /* DWORD 0 */
- u8 numPosted[8]; /* DWORD 0 */
-} __packed;
-struct RQ_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * The CQ/EQ doorbell. Software MUST set reserved fields in this
- * descriptor to zero, otherwise (CEV) hardware will not execute the
- * doorbell (flagging a bad_db_qid error instead).
- */
-struct BE_CQ_DB_AMAP {
- u8 qid[10]; /* DWORD 0 */
- u8 rsvd0[4]; /* DWORD 0 */
- u8 rearm; /* DWORD 0 */
- u8 event; /* DWORD 0 */
- u8 num_popped[13]; /* DWORD 0 */
- u8 rsvd1[3]; /* DWORD 0 */
-} __packed;
-struct CQ_DB_AMAP {
- u32 dw[1];
-};
-
-struct BE_TPM_RQ_DB_AMAP {
- u8 qid[10]; /* DWORD 0 */
- u8 rsvd0[6]; /* DWORD 0 */
- u8 numPosted[11]; /* DWORD 0 */
- u8 mss_cnt[5]; /* DWORD 0 */
-} __packed;
-struct TPM_RQ_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * Post WRB Queue Doorbell Register used by the host Storage stack
- * to notify the controller of a posted Work Request Block
- */
-struct BE_WRB_POST_DB_AMAP {
- u8 wrb_cid[10]; /* DWORD 0 */
- u8 rsvd0[6]; /* DWORD 0 */
- u8 wrb_index[8]; /* DWORD 0 */
- u8 numberPosted[8]; /* DWORD 0 */
-} __packed;
-struct WRB_POST_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * Update Default PDU Queue Doorbell Register used to communicate
- * to the controller that the driver has stopped processing the queue
- * and where in the queue it stopped, this is
- * a CQ Entry Type. Used by storage driver.
- */
-struct BE_DEFAULT_PDU_DB_AMAP {
- u8 qid[10]; /* DWORD 0 */
- u8 rsvd0[4]; /* DWORD 0 */
- u8 rearm; /* DWORD 0 */
- u8 event; /* DWORD 0 */
- u8 cqproc[14]; /* DWORD 0 */
- u8 rsvd1[2]; /* DWORD 0 */
-} __packed;
-struct DEFAULT_PDU_DB_AMAP {
- u32 dw[1];
-};
-
-/* Management Command and Controller default fragment ring */
-struct BE_MCC_DB_AMAP {
- u8 rid[11]; /* DWORD 0 */
- u8 rsvd0[5]; /* DWORD 0 */
- u8 numPosted[14]; /* DWORD 0 */
- u8 rsvd1[2]; /* DWORD 0 */
-} __packed;
-struct MCC_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * Used for bootstrapping the Host interface. This register is
- * used for driver communication with the MPU when no MCC Rings exist.
- * The software must write this register twice to post any MCC
- * command. First, it writes the register with hi=1 and the upper bits of
- * the physical address for the MCC_MAILBOX structure. Software must poll
- * the ready bit until this is acknowledged. Then, sotware writes the
- * register with hi=0 with the lower bits in the address. It must
- * poll the ready bit until the MCC command is complete. Upon completion,
- * the MCC_MAILBOX will contain a valid completion queue entry.
- */
-struct BE_MPU_MAILBOX_DB_AMAP {
- u8 ready; /* DWORD 0 */
- u8 hi; /* DWORD 0 */
- u8 address[30]; /* DWORD 0 */
-} __packed;
-struct MPU_MAILBOX_DB_AMAP {
- u32 dw[1];
-};
-
-/*
- * This is the protection domain doorbell register map. Note that
- * while this map shows doorbells for all Blade Engine supported
- * protocols, not all of these may be valid in a given function or
- * protection domain. It is the responsibility of the application
- * accessing the doorbells to know which are valid. Each doorbell
- * occupies 32 bytes of space, but unless otherwise specified,
- * only the first 4 bytes should be written. There are 32 instances
- * of these doorbells for the host and 31 virtual machines respectively.
- * The host and VMs will only map the doorbell pages belonging to its
- * protection domain. It will not be able to touch the doorbells for
- * another VM. The doorbells are the only registers directly accessible
- * by a virtual machine. Similarly, there are 511 additional
- * doorbells for RDMA protection domains. PD 0 for RDMA shares
- * the same physical protection domain doorbell page as ETH/iSCSI.
- *
- */
-struct BE_PROTECTION_DOMAIN_DBMAP_AMAP {
- u8 rsvd0[512]; /* DWORD 0 */
- struct BE_SQ_DB_AMAP rdma_sq_db;
- u8 rsvd1[7][32]; /* DWORD 17 */
- struct BE_WRB_POST_DB_AMAP iscsi_wrb_post_db;
- u8 rsvd2[7][32]; /* DWORD 25 */
- struct BE_SQ_DB_AMAP etx_sq_db;
- u8 rsvd3[7][32]; /* DWORD 33 */
- struct BE_RQ_DB_AMAP rdma_rq_db;
- u8 rsvd4[7][32]; /* DWORD 41 */
- struct BE_DEFAULT_PDU_DB_AMAP iscsi_default_pdu_db;
- u8 rsvd5[7][32]; /* DWORD 49 */
- struct BE_TPM_RQ_DB_AMAP tpm_rq_db;
- u8 rsvd6[7][32]; /* DWORD 57 */
- struct BE_RQ_DB_AMAP erx_rq_db;
- u8 rsvd7[7][32]; /* DWORD 65 */
- struct BE_CQ_DB_AMAP cq_db;
- u8 rsvd8[7][32]; /* DWORD 73 */
- struct BE_MCC_DB_AMAP mpu_mcc_db;
- u8 rsvd9[7][32]; /* DWORD 81 */
- struct BE_MPU_MAILBOX_DB_AMAP mcc_bootstrap_db;
- u8 rsvd10[935][32]; /* DWORD 89 */
-} __packed;
-struct PROTECTION_DOMAIN_DBMAP_AMAP {
- u32 dw[1024];
-};
-
-#endif /* __doorbells_amap_h__ */
diff --git a/drivers/staging/benet/ep.h b/drivers/staging/benet/ep.h
deleted file mode 100644
index 72fcf64a9ffb..000000000000
--- a/drivers/staging/benet/ep.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __ep_amap_h__
-#define __ep_amap_h__
-
-/* General Control and Status Register. */
-struct BE_EP_CONTROL_CSR_AMAP {
- u8 m0_RxPbuf; /* DWORD 0 */
- u8 m1_RxPbuf; /* DWORD 0 */
- u8 m2_RxPbuf; /* DWORD 0 */
- u8 ff_en; /* DWORD 0 */
- u8 rsvd0[27]; /* DWORD 0 */
- u8 CPU_reset; /* DWORD 0 */
-} __packed;
-struct EP_CONTROL_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Semaphore Register. */
-struct BE_EP_SEMAPHORE_CSR_AMAP {
- u8 value[32]; /* DWORD 0 */
-} __packed;
-struct EP_SEMAPHORE_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Embedded Processor Specific Registers. */
-struct BE_EP_CSRMAP_AMAP {
- struct BE_EP_CONTROL_CSR_AMAP ep_control;
- u8 rsvd0[32]; /* DWORD 1 */
- u8 rsvd1[32]; /* DWORD 2 */
- u8 rsvd2[32]; /* DWORD 3 */
- u8 rsvd3[32]; /* DWORD 4 */
- u8 rsvd4[32]; /* DWORD 5 */
- u8 rsvd5[8][128]; /* DWORD 6 */
- u8 rsvd6[32]; /* DWORD 38 */
- u8 rsvd7[32]; /* DWORD 39 */
- u8 rsvd8[32]; /* DWORD 40 */
- u8 rsvd9[32]; /* DWORD 41 */
- u8 rsvd10[32]; /* DWORD 42 */
- struct BE_EP_SEMAPHORE_CSR_AMAP ep_semaphore;
- u8 rsvd11[32]; /* DWORD 44 */
- u8 rsvd12[19][32]; /* DWORD 45 */
-} __packed;
-struct EP_CSRMAP_AMAP {
- u32 dw[64];
-};
-
-#endif /* __ep_amap_h__ */
diff --git a/drivers/staging/benet/eq.c b/drivers/staging/benet/eq.c
deleted file mode 100644
index db92ccd8fed8..000000000000
--- a/drivers/staging/benet/eq.c
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include "hwlib.h"
-#include "bestatus.h"
-/*
- This routine creates an event queue based on the client completion
- queue configuration information.
-
- FunctionObject - Handle to a function object
- EqBaseVa - Base VA for a the EQ ring
- SizeEncoding - The encoded size for the EQ entries. This value is
- either CEV_EQ_SIZE_4 or CEV_EQ_SIZE_16
- NumEntries - CEV_CQ_CNT_* values.
- Watermark - Enables watermark based coalescing. This parameter
- must be of the type CEV_WMARK_* if watermarks
- are enabled. If watermarks to to be disabled
- this value should be-1.
- TimerDelay - If a timer delay is enabled this value should be the
- time of the delay in 8 microsecond units. If
- delays are not used this parameter should be
- set to -1.
- ppEqObject - Internal EQ Handle returned.
-
- Returns BE_SUCCESS if successfull,, otherwise a useful error code
- is returned.
-
- IRQL < DISPATCH_LEVEL
-*/
-int
-be_eq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 eqe_size, u32 num_entries,
- u32 watermark, /* CEV_WMARK_* or -1 */
- u32 timer_delay, /* in 8us units, or -1 */
- struct be_eq_object *eq_object)
-{
- int status = BE_SUCCESS;
- u32 num_entries_encoding, eqe_size_encoding, length;
- struct FWCMD_COMMON_EQ_CREATE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 n;
- unsigned long irql;
-
- ASSERT(rd);
- ASSERT(eq_object);
-
- switch (num_entries) {
- case 256:
- num_entries_encoding = CEV_EQ_CNT_256;
- break;
- case 512:
- num_entries_encoding = CEV_EQ_CNT_512;
- break;
- case 1024:
- num_entries_encoding = CEV_EQ_CNT_1024;
- break;
- case 2048:
- num_entries_encoding = CEV_EQ_CNT_2048;
- break;
- case 4096:
- num_entries_encoding = CEV_EQ_CNT_4096;
- break;
- default:
- ASSERT(0);
- return BE_STATUS_INVALID_PARAMETER;
- }
-
- switch (eqe_size) {
- case 4:
- eqe_size_encoding = CEV_EQ_SIZE_4;
- break;
- case 16:
- eqe_size_encoding = CEV_EQ_SIZE_16;
- break;
- default:
- ASSERT(0);
- return BE_STATUS_INVALID_PARAMETER;
- }
-
- if ((eqe_size == 4 && num_entries < 1024) ||
- (eqe_size == 16 && num_entries == 4096)) {
- TRACE(DL_ERR, "Bad EQ size. eqe_size:%d num_entries:%d",
- eqe_size, num_entries);
- ASSERT(0);
- return BE_STATUS_INVALID_PARAMETER;
- }
-
- memset(eq_object, 0, sizeof(*eq_object));
-
- atomic_set(&eq_object->ref_count, 0);
- eq_object->parent_function = pfob;
- eq_object->eq_id = 0xFFFFFFFF;
-
- INIT_LIST_HEAD(&eq_object->cq_list_head);
-
- length = num_entries * eqe_size;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in create EQ.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_EQ_CREATE);
-
- fwcmd->params.request.num_pages = PAGES_SPANNED(OFFSET_IN_PAGE(rd->va),
- length);
- n = pfob->pci_function_number;
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Func, &fwcmd->params.request.context, n);
-
- AMAP_SET_BITS_PTR(EQ_CONTEXT, valid, &fwcmd->params.request.context, 1);
-
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Size,
- &fwcmd->params.request.context, eqe_size_encoding);
-
- n = 0; /* Protection Domain is always 0 in Linux driver */
- AMAP_SET_BITS_PTR(EQ_CONTEXT, PD, &fwcmd->params.request.context, n);
-
- /* Let the caller ARM the EQ with the doorbell. */
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Armed, &fwcmd->params.request.context, 0);
-
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Count, &fwcmd->params.request.context,
- num_entries_encoding);
-
- n = pfob->pci_function_number * 32;
- AMAP_SET_BITS_PTR(EQ_CONTEXT, EventVect,
- &fwcmd->params.request.context, n);
- if (watermark != -1) {
- AMAP_SET_BITS_PTR(EQ_CONTEXT, WME,
- &fwcmd->params.request.context, 1);
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Watermark,
- &fwcmd->params.request.context, watermark);
- ASSERT(watermark <= CEV_WMARK_240);
- } else
- AMAP_SET_BITS_PTR(EQ_CONTEXT, WME,
- &fwcmd->params.request.context, 0);
- if (timer_delay != -1) {
- AMAP_SET_BITS_PTR(EQ_CONTEXT, TMR,
- &fwcmd->params.request.context, 1);
-
- ASSERT(timer_delay <= 250); /* max value according to EAS */
- timer_delay = min(timer_delay, (u32)250);
-
- AMAP_SET_BITS_PTR(EQ_CONTEXT, Delay,
- &fwcmd->params.request.context, timer_delay);
- } else {
- AMAP_SET_BITS_PTR(EQ_CONTEXT, TMR,
- &fwcmd->params.request.context, 0);
- }
- /* Create a page list for the FWCMD. */
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
-
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "MCC to create EQ failed.");
- goto Error;
- }
- /* Get the EQ id. The MPU allocates the IDs. */
- eq_object->eq_id = fwcmd->params.response.eq_id;
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- Deferences the given object. Once the object's reference count drops to
- zero, the object is destroyed and all resources that are held by this
- object are released. The on-chip context is also destroyed along with
- the queue ID, and any mappings made into the UT.
-
- eq_object - EQ handle returned from eq_object_create.
-
- Returns BE_SUCCESS if successfull, otherwise a useful error code
- is returned.
-
- IRQL: IRQL < DISPATCH_LEVEL
-*/
-int be_eq_destroy(struct be_eq_object *eq_object)
-{
- int status = 0;
-
- ASSERT(atomic_read(&eq_object->ref_count) == 0);
- /* no CQs should reference this EQ now */
- ASSERT(list_empty(&eq_object->cq_list_head));
-
- /* Send fwcmd to destroy the EQ. */
- status = be_function_ring_destroy(eq_object->parent_function,
- eq_object->eq_id, FWCMD_RING_TYPE_EQ,
- NULL, NULL, NULL, NULL);
- ASSERT(status == 0);
-
- return BE_SUCCESS;
-}
-/*
- *---------------------------------------------------------------------------
- * Function: be_eq_modify_delay
- * Changes the EQ delay for a group of EQs.
- * num_eq - The number of EQs in the eq_array to adjust.
- * This also is the number of delay values in
- * the eq_delay_array.
- * eq_array - Array of struct be_eq_object pointers to adjust.
- * eq_delay_array - Array of "num_eq" timer delays in units
- * of microseconds. The be_eq_query_delay_range
- * fwcmd returns the resolution and range of
- * legal EQ delays.
- * cb -
- * cb_context -
- * q_ctxt - Optional. Pointer to a previously allocated
- * struct. If the MCC WRB ring is full, this
- * structure is used to queue the operation. It
- * will be posted to the MCC ring when space
- * becomes available. All queued commands will
- * be posted to the ring in the order they are
- * received. It is always valid to pass a pointer to
- * a generic be_generic_q_cntxt. However,
- * the specific context structs
- * are generally smaller than the generic struct.
- * return pend_status - BE_SUCCESS (0) on success.
- * BE_PENDING (postive value) if the FWCMD
- * completion is pending. Negative error code on failure.
- *-------------------------------------------------------------------------
- */
-int
-be_eq_modify_delay(struct be_function_object *pfob,
- u32 num_eq, struct be_eq_object **eq_array,
- u32 *eq_delay_array, mcc_wrb_cqe_callback cb,
- void *cb_context, struct be_eq_modify_delay_q_ctxt *q_ctxt)
-{
- struct FWCMD_COMMON_MODIFY_EQ_DELAY *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *gen_ctxt = NULL;
- u32 i;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- gen_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- gen_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_MODIFY_EQ_DELAY);
-
- ASSERT(num_eq > 0);
- ASSERT(num_eq <= ARRAY_SIZE(fwcmd->params.request.delay));
- fwcmd->params.request.num_eq = num_eq;
- for (i = 0; i < num_eq; i++) {
- fwcmd->params.request.delay[i].eq_id = eq_array[i]->eq_id;
- fwcmd->params.request.delay[i].delay_in_microseconds =
- eq_delay_array[i];
- }
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, gen_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, NULL);
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
diff --git a/drivers/staging/benet/eth.c b/drivers/staging/benet/eth.c
deleted file mode 100644
index f641b6260d07..000000000000
--- a/drivers/staging/benet/eth.c
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include <linux/if_ether.h>
-#include "hwlib.h"
-#include "bestatus.h"
-
-/*
- *---------------------------------------------------------
- * Function: be_eth_sq_create_ex
- * Creates an ethernet send ring - extended version with
- * additional parameters.
- * pfob -
- * rd - ring address
- * length_in_bytes -
- * type - The type of ring to create.
- * ulp - The requested ULP number for the ring.
- * This should be zero based, i.e. 0,1,2. This must
- * be valid NIC ULP based on the firmware config.
- * All doorbells for this ring must be sent to
- * this ULP. The first network ring allocated for
- * each ULP are higher performance than subsequent rings.
- * cq_object - cq object for completions
- * ex_parameters - Additional parameters (that may increase in
- * future revisions). These parameters are only used
- * for certain ring types -- see
- * struct be_eth_sq_parameters for details.
- * eth_sq -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *---------------------------------------------------------
- */
-int
-be_eth_sq_create_ex(struct be_function_object *pfob, struct ring_desc *rd,
- u32 length, u32 type, u32 ulp, struct be_cq_object *cq_object,
- struct be_eth_sq_parameters *ex_parameters,
- struct be_ethsq_object *eth_sq)
-{
- struct FWCMD_COMMON_ETH_TX_CREATE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- u32 n;
- unsigned long irql;
-
- ASSERT(rd);
- ASSERT(eth_sq);
- ASSERT(ex_parameters);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- memset(eth_sq, 0, sizeof(*eth_sq));
-
- eth_sq->parent_function = pfob;
- eth_sq->bid = 0xFFFFFFFF;
- eth_sq->cq_object = cq_object;
-
- /* Translate hwlib interface to arm interface. */
- switch (type) {
- case BE_ETH_TX_RING_TYPE_FORWARDING:
- type = ETH_TX_RING_TYPE_FORWARDING;
- break;
- case BE_ETH_TX_RING_TYPE_STANDARD:
- type = ETH_TX_RING_TYPE_STANDARD;
- break;
- case BE_ETH_TX_RING_TYPE_BOUND:
- ASSERT(ex_parameters->port < 2);
- type = ETH_TX_RING_TYPE_BOUND;
- break;
- default:
- TRACE(DL_ERR, "Invalid eth tx ring type:%d", type);
- return BE_NOT_OK;
- break;
- }
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in create EQ.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* NIC must be supported by the current config. */
- ASSERT(pfob->fw_config.nic_ulp_mask);
-
- /*
- * The ulp parameter must select a valid NIC ULP
- * for the current config.
- */
- ASSERT((1 << ulp) & pfob->fw_config.nic_ulp_mask);
-
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_TX_CREATE);
- fwcmd->header.request.port_number = ex_parameters->port;
-
- AMAP_SET_BITS_PTR(ETX_CONTEXT, pd_id,
- &fwcmd->params.request.context, 0);
-
- n = be_ring_length_to_encoding(length, sizeof(struct ETH_WRB_AMAP));
- AMAP_SET_BITS_PTR(ETX_CONTEXT, tx_ring_size,
- &fwcmd->params.request.context, n);
-
- AMAP_SET_BITS_PTR(ETX_CONTEXT, cq_id_send,
- &fwcmd->params.request.context, cq_object->cq_id);
-
- n = pfob->pci_function_number;
- AMAP_SET_BITS_PTR(ETX_CONTEXT, func, &fwcmd->params.request.context, n);
-
- fwcmd->params.request.type = type;
- fwcmd->params.request.ulp_num = (1 << ulp);
- fwcmd->params.request.num_pages = DIV_ROUND_UP(length, PAGE_SIZE);
- ASSERT(PAGES_SPANNED(rd->va, rd->length) >=
- fwcmd->params.request.num_pages);
-
- /* Create a page list for the FWCMD. */
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
-
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "MCC to create etx queue failed.");
- goto Error;
- }
- /* save the butler ID */
- eth_sq->bid = fwcmd->params.response.cid;
-
- /* add a reference to the corresponding CQ */
- atomic_inc(&cq_object->ref_count);
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-/*
- This routine destroys an ethernet send queue
-
- EthSq - EthSq Handle returned from EthSqCreate
-
- This function always return BE_SUCCESS.
-
- This function frees memory allocated by EthSqCreate for the EthSq Object.
-
-*/
-int be_eth_sq_destroy(struct be_ethsq_object *eth_sq)
-{
- int status = 0;
-
- /* Send fwcmd to destroy the queue. */
- status = be_function_ring_destroy(eth_sq->parent_function, eth_sq->bid,
- FWCMD_RING_TYPE_ETH_TX, NULL, NULL, NULL, NULL);
- ASSERT(status == 0);
-
- /* Derefence any associated CQs. */
- atomic_dec(&eth_sq->cq_object->ref_count);
- return status;
-}
-/*
- This routine attempts to set the transmit flow control parameters.
-
- FunctionObject - Handle to a function object
-
- txfc_enable - transmit flow control enable - true for
- enable, false for disable
-
- rxfc_enable - receive flow control enable - true for
- enable, false for disable
-
- Returns BE_SUCCESS if successfull, otherwise a useful int error
- code is returned.
-
- IRQL: < DISPATCH_LEVEL
-
- This function always fails in non-privileged machine context.
-*/
-int
-be_eth_set_flow_control(struct be_function_object *pfob,
- bool txfc_enable, bool rxfc_enable)
-{
- struct FWCMD_COMMON_SET_FLOW_CONTROL *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FLOW_CONTROL);
-
- fwcmd->params.request.rx_flow_control = rxfc_enable;
- fwcmd->params.request.tx_flow_control = txfc_enable;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "set flow control fwcmd failed.");
- goto error;
- }
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine attempts to get the transmit flow control parameters.
-
- pfob - Handle to a function object
-
- txfc_enable - transmit flow control enable - true for
- enable, false for disable
-
- rxfc_enable - receive flow control enable - true for enable,
- false for disable
-
- Returns BE_SUCCESS if successfull, otherwise a useful int error code
- is returned.
-
- IRQL: < DISPATCH_LEVEL
-
- This function always fails in non-privileged machine context.
-*/
-int
-be_eth_get_flow_control(struct be_function_object *pfob,
- bool *txfc_enable, bool *rxfc_enable)
-{
- struct FWCMD_COMMON_GET_FLOW_CONTROL *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_FLOW_CONTROL);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "get flow control fwcmd failed.");
- goto error;
- }
-
- *txfc_enable = fwcmd->params.response.tx_flow_control;
- *rxfc_enable = fwcmd->params.response.rx_flow_control;
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- *---------------------------------------------------------
- * Function: be_eth_set_qos
- * This function sets the ethernet transmit Quality of Service (QoS)
- * characteristics of BladeEngine for the domain. All ethernet
- * transmit rings of the domain will evenly share the bandwidth.
- * The exeception to sharing is the host primary (super) ethernet
- * transmit ring as well as the host ethernet forwarding ring
- * for missed offload data.
- * pfob -
- * max_bps - the maximum bits per second in units of
- * 10 Mbps (valid 0-100)
- * max_pps - the maximum packets per second in units
- * of 1 Kpps (0 indicates no limit)
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *---------------------------------------------------------
- */
-int
-be_eth_set_qos(struct be_function_object *pfob, u32 max_bps, u32 max_pps)
-{
- struct FWCMD_COMMON_SET_QOS *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_QOS);
-
- /* Set fields in fwcmd */
- fwcmd->params.request.max_bits_per_second_NIC = max_bps;
- fwcmd->params.request.max_packets_per_second_NIC = max_pps;
- fwcmd->params.request.valid_flags = QOS_BITS_NIC | QOS_PKTS_NIC;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0)
- TRACE(DL_ERR, "network set qos fwcmd failed.");
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- *---------------------------------------------------------
- * Function: be_eth_get_qos
- * This function retrieves the ethernet transmit Quality of Service (QoS)
- * characteristics for the domain.
- * max_bps - the maximum bits per second in units of
- * 10 Mbps (valid 0-100)
- * max_pps - the maximum packets per second in units of
- * 1 Kpps (0 indicates no limit)
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *---------------------------------------------------------
- */
-int
-be_eth_get_qos(struct be_function_object *pfob, u32 *max_bps, u32 *max_pps)
-{
- struct FWCMD_COMMON_GET_QOS *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_QOS);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "network get qos fwcmd failed.");
- goto error;
- }
-
- *max_bps = fwcmd->params.response.max_bits_per_second_NIC;
- *max_pps = fwcmd->params.response.max_packets_per_second_NIC;
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- *---------------------------------------------------------
- * Function: be_eth_set_frame_size
- * This function sets the ethernet maximum frame size. The previous
- * values are returned.
- * pfob -
- * tx_frame_size - maximum transmit frame size in bytes
- * rx_frame_size - maximum receive frame size in bytes
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *---------------------------------------------------------
- */
-int
-be_eth_set_frame_size(struct be_function_object *pfob,
- u32 *tx_frame_size, u32 *rx_frame_size)
-{
- struct FWCMD_COMMON_SET_FRAME_SIZE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_SET_FRAME_SIZE);
- fwcmd->params.request.max_tx_frame_size = *tx_frame_size;
- fwcmd->params.request.max_rx_frame_size = *rx_frame_size;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "network set frame size fwcmd failed.");
- goto error;
- }
-
- *tx_frame_size = fwcmd->params.response.chip_max_tx_frame_size;
- *rx_frame_size = fwcmd->params.response.chip_max_rx_frame_size;
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-/*
- This routine creates a Ethernet receive ring.
-
- pfob - handle to a function object
- rq_base_va - base VA for the default receive ring. this must be
- exactly 8K in length and continguous physical memory.
- cq_object - handle to a previously created CQ to be associated
- with the RQ.
- pp_eth_rq - pointer to an opqaue handle where an eth
- receive object is returned.
- Returns BE_SUCCESS if successfull, , otherwise a useful
- int error code is returned.
-
- IRQL: < DISPATCH_LEVEL
- this function allocates a struct be_ethrq_object *object.
- there must be no more than 1 of these per function object, unless the
- function object supports RSS (is networking and on the host).
- the rq_base_va must point to a buffer of exactly 8K.
- the erx::host_cqid (or host_stor_cqid) register and erx::ring_page registers
- will be updated as appropriate on return
-*/
-int
-be_eth_rq_create(struct be_function_object *pfob,
- struct ring_desc *rd, struct be_cq_object *cq_object,
- struct be_cq_object *bcmc_cq_object,
- struct be_ethrq_object *eth_rq)
-{
- int status = 0;
- struct MCC_WRB_AMAP *wrb = NULL;
- struct FWCMD_COMMON_ETH_RX_CREATE *fwcmd = NULL;
- unsigned long irql;
-
- /* MPU will set the */
- ASSERT(rd);
- ASSERT(eth_rq);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- eth_rq->parent_function = pfob;
- eth_rq->cq_object = cq_object;
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_ETH_RX_CREATE);
-
- fwcmd->params.request.num_pages = 2; /* required length */
- fwcmd->params.request.cq_id = cq_object->cq_id;
-
- if (bcmc_cq_object)
- fwcmd->params.request.bcmc_cq_id = bcmc_cq_object->cq_id;
- else
- fwcmd->params.request.bcmc_cq_id = 0xFFFF;
-
- /* Create a page list for the FWCMD. */
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "fwcmd to map eth rxq frags failed.");
- goto Error;
- }
- /* Save the ring ID for cleanup. */
- eth_rq->rid = fwcmd->params.response.id;
-
- atomic_inc(&cq_object->ref_count);
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine destroys an Ethernet receive queue
-
- eth_rq - ethernet receive queue handle returned from eth_rq_create
-
- Returns BE_SUCCESS on success and an appropriate int on failure.
-
- This function frees resourcs allocated by EthRqCreate.
- The erx::host_cqid (or host_stor_cqid) register and erx::ring_page
- registers will be updated as appropriate on return
- IRQL: < DISPATCH_LEVEL
-*/
-
-static void be_eth_rq_destroy_internal_cb(void *context, int status,
- struct MCC_WRB_AMAP *wrb)
-{
- struct be_ethrq_object *eth_rq = (struct be_ethrq_object *) context;
-
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "Destroy eth rq failed in internal callback.\n");
- } else {
- /* Dereference any CQs associated with this queue. */
- atomic_dec(&eth_rq->cq_object->ref_count);
- }
-
- return;
-}
-
-int be_eth_rq_destroy(struct be_ethrq_object *eth_rq)
-{
- int status = BE_SUCCESS;
-
- /* Send fwcmd to destroy the RQ. */
- status = be_function_ring_destroy(eth_rq->parent_function,
- eth_rq->rid, FWCMD_RING_TYPE_ETH_RX, NULL, NULL,
- be_eth_rq_destroy_internal_cb, eth_rq);
-
- return status;
-}
-
-/*
- *---------------------------------------------------------------------------
- * Function: be_eth_rq_destroy_options
- * Destroys an ethernet receive ring with finer granularity options
- * than the standard be_eth_rq_destroy() API function.
- * eth_rq -
- * flush - Set to 1 to flush the ring, set to 0 to bypass the flush
- * cb - Callback function on completion
- * cb_context - Callback context
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *----------------------------------------------------------------------------
- */
-int
-be_eth_rq_destroy_options(struct be_ethrq_object *eth_rq, bool flush,
- mcc_wrb_cqe_callback cb, void *cb_context)
-{
- struct FWCMD_COMMON_RING_DESTROY *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = BE_SUCCESS;
- struct be_function_object *pfob = NULL;
- unsigned long irql;
-
- pfob = eth_rq->parent_function;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- TRACE(DL_INFO, "Destroy eth_rq ring id:%d, flush:%d", eth_rq->rid,
- flush);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in destroy eth_rq ring.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_RING_DESTROY);
-
- fwcmd->params.request.id = eth_rq->rid;
- fwcmd->params.request.ring_type = FWCMD_RING_TYPE_ETH_RX;
- fwcmd->params.request.bypass_flush = ((0 == flush) ? 1 : 0);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, cb_context,
- be_eth_rq_destroy_internal_cb, eth_rq, fwcmd, NULL);
-
- if (status != BE_SUCCESS && status != BE_PENDING) {
- TRACE(DL_ERR, "eth_rq ring destroy failed. id:%d, flush:%d",
- eth_rq->rid, flush);
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine queries the frag size for erx.
-
- pfob - handle to a function object
-
- frag_size_bytes - erx frag size in bytes that is/was set.
-
- Returns BE_SUCCESS if successfull, otherwise a useful int error
- code is returned.
-
- IRQL: < DISPATCH_LEVEL
-
-*/
-int
-be_eth_rq_get_frag_size(struct be_function_object *pfob, u32 *frag_size_bytes)
-{
- struct FWCMD_ETH_GET_RX_FRAG_SIZE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- ASSERT(frag_size_bytes);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- return BE_STATUS_NO_MCC_WRB;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_GET_RX_FRAG_SIZE);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "get frag size fwcmd failed.");
- goto error;
- }
-
- *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2;
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine attempts to set the frag size for erx. If the frag size is
- already set, the attempt fails and the current frag size is returned.
-
- pfob - Handle to a function object
-
- frag_size - Erx frag size in bytes that is/was set.
-
- current_frag_size_bytes - Pointer to location where currrent frag
- is to be rturned
-
- Returns BE_SUCCESS if successfull, otherwise a useful int error
- code is returned.
-
- IRQL: < DISPATCH_LEVEL
-
- This function always fails in non-privileged machine context.
-*/
-int
-be_eth_rq_set_frag_size(struct be_function_object *pfob,
- u32 frag_size, u32 *frag_size_bytes)
-{
- struct FWCMD_ETH_SET_RX_FRAG_SIZE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- ASSERT(frag_size_bytes);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_SET_RX_FRAG_SIZE);
-
- ASSERT(frag_size >= 128 && frag_size <= 16 * 1024);
-
- /* This is the log2 of the fragsize. This is not the exact
- * ERX encoding. */
- fwcmd->params.request.new_fragsize_log2 = __ilog2_u32(frag_size);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
-
- if (status != 0) {
- TRACE(DL_ERR, "set frag size fwcmd failed.");
- goto error;
- }
-
- *frag_size_bytes = 1 << fwcmd->params.response.actual_fragsize_log2;
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-/*
- This routine gets or sets a mac address for a domain
- given the port and mac.
-
- FunctionObject - Function object handle.
- port1 - Set to TRUE if this function will set/get the Port 1
- address. Only the host may set this to TRUE.
- mac1 - Set to TRUE if this function will set/get the
- MAC 1 address. Only the host may set this to TRUE.
- write - Set to TRUE if this function should write the mac address.
- mac_address - Buffer of the mac address to read or write.
-
- Returns BE_SUCCESS if successfull, otherwise a useful int is returned.
-
- IRQL: < DISPATCH_LEVEL
-*/
-int be_rxf_mac_address_read_write(struct be_function_object *pfob,
- bool port1, /* VM must always set to false */
- bool mac1, /* VM must always set to false */
- bool mgmt, bool write,
- bool permanent, u8 *mac_address,
- mcc_wrb_cqe_callback cb, /* optional */
- void *cb_context) /* optional */
-{
- int status = BE_SUCCESS;
- union {
- struct FWCMD_COMMON_NTWK_MAC_QUERY *query;
- struct FWCMD_COMMON_NTWK_MAC_SET *set;
- } fwcmd = {NULL};
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 type = 0;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- ASSERT(mac_address);
-
- ASSERT(port1 == false);
- ASSERT(mac1 == false);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
-
- if (mgmt) {
- type = MAC_ADDRESS_TYPE_MANAGEMENT;
- } else {
- if (pfob->type == BE_FUNCTION_TYPE_NETWORK)
- type = MAC_ADDRESS_TYPE_NETWORK;
- else
- type = MAC_ADDRESS_TYPE_STORAGE;
- }
-
- if (write) {
- /* Prepares an embedded fwcmd, including
- * request/response sizes.
- */
- fwcmd.set = BE_PREPARE_EMBEDDED_FWCMD(pfob,
- wrb, COMMON_NTWK_MAC_SET);
-
- fwcmd.set->params.request.invalidate = 0;
- fwcmd.set->params.request.mac1 = (mac1 ? 1 : 0);
- fwcmd.set->params.request.port = (port1 ? 1 : 0);
- fwcmd.set->params.request.type = type;
-
- /* Copy the mac address to set. */
- fwcmd.set->params.request.mac.SizeOfStructure =
- sizeof(fwcmd.set->params.request.mac);
- memcpy(fwcmd.set->params.request.mac.MACAddress,
- mac_address, ETH_ALEN);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL,
- cb, cb_context, NULL, NULL, fwcmd.set, NULL);
-
- } else {
-
- /*
- * Prepares an embedded fwcmd, including
- * request/response sizes.
- */
- fwcmd.query = BE_PREPARE_EMBEDDED_FWCMD(pfob,
- wrb, COMMON_NTWK_MAC_QUERY);
-
- fwcmd.query->params.request.mac1 = (mac1 ? 1 : 0);
- fwcmd.query->params.request.port = (port1 ? 1 : 0);
- fwcmd.query->params.request.type = type;
- fwcmd.query->params.request.permanent = permanent;
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_MAC_QUERY,
- params.response.mac.MACAddress);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_MAC_QUERY,
- params.response.mac.MACAddress);
- rc.va = mac_address;
- /* Post the f/w command (with a copy for the response) */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb,
- cb_context, NULL, NULL, fwcmd.query, &rc);
- }
-
- if (status < 0) {
- TRACE(DL_ERR, "mac set/query failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine writes data to context memory.
-
- pfob - Function object handle.
- mac_table - Set to the 128-bit multicast address hash table.
-
- Returns BE_SUCCESS if successfull, otherwise a useful int is returned.
-
- IRQL: < DISPATCH_LEVEL
-*/
-
-int be_rxf_multicast_config(struct be_function_object *pfob,
- bool promiscuous, u32 num, u8 *mac_table,
- mcc_wrb_cqe_callback cb, /* optional */
- void *cb_context,
- struct be_multicast_q_ctxt *q_ctxt)
-{
- int status = BE_SUCCESS;
- struct FWCMD_COMMON_NTWK_MULTICAST_SET *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
-
- ASSERT(num <= ARRAY_SIZE(fwcmd->params.request.mac));
-
- if (num > ARRAY_SIZE(fwcmd->params.request.mac)) {
- TRACE(DL_ERR, "Too many multicast addresses. BE supports %d.",
- (int) ARRAY_SIZE(fwcmd->params.request.mac));
- return BE_NOT_OK;
- }
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_MULTICAST_SET);
-
- fwcmd->params.request.promiscuous = promiscuous;
- if (!promiscuous) {
- fwcmd->params.request.num_mac = num;
- if (num > 0) {
- ASSERT(mac_table);
- memcpy(fwcmd->params.request.mac,
- mac_table, ETH_ALEN * num);
- }
- }
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, NULL);
- if (status < 0) {
- TRACE(DL_ERR, "multicast fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine adds or removes a vlan tag from the rxf table.
-
- FunctionObject - Function object handle.
- VLanTag - VLan tag to add or remove.
- Add - Set to TRUE if this will add a vlan tag
-
- Returns BE_SUCCESS if successfull, otherwise a useful int is returned.
-
- IRQL: < DISPATCH_LEVEL
-*/
-int be_rxf_vlan_config(struct be_function_object *pfob,
- bool promiscuous, u32 num, u16 *vlan_tag_array,
- mcc_wrb_cqe_callback cb, /* optional */
- void *cb_context,
- struct be_vlan_q_ctxt *q_ctxt) /* optional */
-{
- int status = BE_SUCCESS;
- struct FWCMD_COMMON_NTWK_VLAN_CONFIG *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
-
- if (num > ARRAY_SIZE(fwcmd->params.request.vlan_tag)) {
- TRACE(DL_ERR, "Too many VLAN tags.");
- return BE_NOT_OK;
- }
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_VLAN_CONFIG);
-
- fwcmd->params.request.promiscuous = promiscuous;
- if (!promiscuous) {
- fwcmd->params.request.num_vlan = num;
-
- if (num > 0) {
- ASSERT(vlan_tag_array);
- memcpy(fwcmd->params.request.vlan_tag, vlan_tag_array,
- num * sizeof(vlan_tag_array[0]));
- }
- }
-
- /* Post the commadn */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, NULL);
- if (status < 0) {
- TRACE(DL_ERR, "vlan fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-int be_rxf_link_status(struct be_function_object *pfob,
- struct BE_LINK_STATUS *link_status,
- mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_link_status_q_ctxt *q_ctxt)
-{
- struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- ASSERT(link_status);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
-
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb,
- COMMON_NTWK_LINK_STATUS_QUERY);
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY,
- params.response);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY,
- params.response);
- rc.va = link_status;
- /* Post or queue the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, &rc);
-
- if (status < 0) {
- TRACE(DL_ERR, "link status fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-int
-be_rxf_query_eth_statistics(struct be_function_object *pfob,
- struct FWCMD_ETH_GET_STATISTICS *va_for_fwcmd,
- u64 pa_for_fwcmd, mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_nonembedded_q_ctxt *q_ctxt)
-{
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
-
- ASSERT(va_for_fwcmd);
- ASSERT(pa_for_fwcmd);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
-
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
-
- TRACE(DL_INFO, "Query eth stats. fwcmd va:%p pa:0x%08x_%08x",
- va_for_fwcmd, upper_32_bits(pa_for_fwcmd), (u32)pa_for_fwcmd);
-
- /* Prepares an embedded fwcmd, including request/response sizes. */
- va_for_fwcmd = BE_PREPARE_NONEMBEDDED_FWCMD(pfob, wrb,
- va_for_fwcmd, pa_for_fwcmd, ETH_GET_STATISTICS);
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, va_for_fwcmd, NULL);
- if (status < 0) {
- TRACE(DL_ERR, "eth stats fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-int
-be_rxf_promiscuous(struct be_function_object *pfob,
- bool enable_port0, bool enable_port1,
- mcc_wrb_cqe_callback cb, void *cb_context,
- struct be_promiscuous_q_ctxt *q_ctxt)
-{
- struct FWCMD_ETH_PROMISCUOUS *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
-
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
-
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, ETH_PROMISCUOUS);
-
- fwcmd->params.request.port0_promiscuous = enable_port0;
- fwcmd->params.request.port1_promiscuous = enable_port1;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, NULL);
-
- if (status < 0) {
- TRACE(DL_ERR, "promiscuous fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-
-/*
- *-------------------------------------------------------------------------
- * Function: be_rxf_filter_config
- * Configures BladeEngine ethernet receive filter settings.
- * pfob -
- * settings - Pointer to the requested filter settings.
- * The response from BladeEngine will be placed back
- * in this structure.
- * cb - optional
- * cb_context - optional
- * q_ctxt - Optional. Pointer to a previously allocated struct.
- * If the MCC WRB ring is full, this structure is
- * used to queue the operation. It will be posted
- * to the MCC ring when space becomes available. All
- * queued commands will be posted to the ring in
- * the order they are received. It is always valid
- * to pass a pointer to a generic
- * be_generic_q_ctxt. However, the specific
- * context structs are generally smaller than
- * the generic struct.
- * return pend_status - BE_SUCCESS (0) on success.
- * BE_PENDING (postive value) if the FWCMD
- * completion is pending. Negative error code on failure.
- *---------------------------------------------------------------------------
- */
-int
-be_rxf_filter_config(struct be_function_object *pfob,
- struct NTWK_RX_FILTER_SETTINGS *settings,
- mcc_wrb_cqe_callback cb, void *cb_context,
- struct be_rxf_filter_q_ctxt *q_ctxt)
-{
- struct FWCMD_COMMON_NTWK_RX_FILTER *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- struct be_generic_q_ctxt *generic_ctxt = NULL;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- ASSERT(settings);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
-
- if (!wrb) {
- if (q_ctxt && cb) {
- wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- generic_ctxt = (struct be_generic_q_ctxt *) q_ctxt;
- generic_ctxt->context.bytes = sizeof(*q_ctxt);
- } else {
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_NTWK_RX_FILTER);
- memcpy(&fwcmd->params.request, settings, sizeof(*settings));
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_NTWK_RX_FILTER,
- params.response);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_NTWK_RX_FILTER,
- params.response);
- rc.va = settings;
- /* Post or queue the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, generic_ctxt,
- cb, cb_context, NULL, NULL, fwcmd, &rc);
-
- if (status < 0) {
- TRACE(DL_ERR, "RXF/ERX filter config fwcmd failed.");
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
diff --git a/drivers/staging/benet/etx_context.h b/drivers/staging/benet/etx_context.h
deleted file mode 100644
index 554fbe5d127b..000000000000
--- a/drivers/staging/benet/etx_context.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __etx_context_amap_h__
-#define __etx_context_amap_h__
-
-/* ETX ring context structure. */
-struct BE_ETX_CONTEXT_AMAP {
- u8 tx_cidx[11]; /* DWORD 0 */
- u8 rsvd0[5]; /* DWORD 0 */
- u8 rsvd1[16]; /* DWORD 0 */
- u8 tx_pidx[11]; /* DWORD 1 */
- u8 rsvd2; /* DWORD 1 */
- u8 tx_ring_size[4]; /* DWORD 1 */
- u8 pd_id[5]; /* DWORD 1 */
- u8 pd_id_not_valid; /* DWORD 1 */
- u8 cq_id_send[10]; /* DWORD 1 */
- u8 rsvd3[32]; /* DWORD 2 */
- u8 rsvd4[32]; /* DWORD 3 */
- u8 cur_bytes[32]; /* DWORD 4 */
- u8 max_bytes[32]; /* DWORD 5 */
- u8 time_stamp[32]; /* DWORD 6 */
- u8 rsvd5[11]; /* DWORD 7 */
- u8 func; /* DWORD 7 */
- u8 rsvd6[20]; /* DWORD 7 */
- u8 cur_txd_count[32]; /* DWORD 8 */
- u8 max_txd_count[32]; /* DWORD 9 */
- u8 rsvd7[32]; /* DWORD 10 */
- u8 rsvd8[32]; /* DWORD 11 */
- u8 rsvd9[32]; /* DWORD 12 */
- u8 rsvd10[32]; /* DWORD 13 */
- u8 rsvd11[32]; /* DWORD 14 */
- u8 rsvd12[32]; /* DWORD 15 */
-} __packed;
-struct ETX_CONTEXT_AMAP {
- u32 dw[16];
-};
-
-#endif /* __etx_context_amap_h__ */
diff --git a/drivers/staging/benet/funcobj.c b/drivers/staging/benet/funcobj.c
deleted file mode 100644
index 0f57eb58daef..000000000000
--- a/drivers/staging/benet/funcobj.c
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include "hwlib.h"
-#include "bestatus.h"
-
-
-int
-be_function_internal_query_firmware_config(struct be_function_object *pfob,
- struct BE_FIRMWARE_CONFIG *config)
-{
- struct FWCMD_COMMON_FIRMWARE_CONFIG *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_FIRMWARE_CONFIG);
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_FIRMWARE_CONFIG,
- params.response);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_FIRMWARE_CONFIG,
- params.response);
- rc.va = config;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL,
- NULL, NULL, NULL, fwcmd, &rc);
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This allocates and initializes a function object based on the information
- provided by upper layer drivers.
-
- Returns BE_SUCCESS on success and an appropriate int on failure.
-
- A function object represents a single BladeEngine (logical) PCI function.
- That is a function object either represents
- the networking side of BladeEngine or the iSCSI side of BladeEngine.
-
- This routine will also detect and create an appropriate PD object for the
- PCI function as needed.
-*/
-int
-be_function_object_create(u8 __iomem *csr_va, u8 __iomem *db_va,
- u8 __iomem *pci_va, u32 function_type,
- struct ring_desc *mailbox, struct be_function_object *pfob)
-{
- int status;
-
- ASSERT(pfob); /* not a magic assert */
- ASSERT(function_type <= 2);
-
- TRACE(DL_INFO, "Create function object. type:%s object:0x%p",
- (function_type == BE_FUNCTION_TYPE_ISCSI ? "iSCSI" :
- (function_type == BE_FUNCTION_TYPE_NETWORK ? "Network" :
- "Arm")), pfob);
-
- memset(pfob, 0, sizeof(*pfob));
-
- pfob->type = function_type;
- pfob->csr_va = csr_va;
- pfob->db_va = db_va;
- pfob->pci_va = pci_va;
-
- spin_lock_init(&pfob->cq_lock);
- spin_lock_init(&pfob->post_lock);
- spin_lock_init(&pfob->mcc_context_lock);
-
-
- pfob->pci_function_number = 1;
-
-
- pfob->emulate = false;
- TRACE(DL_NOTE, "Non-emulation mode");
- status = be_drive_POST(pfob);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "BladeEngine POST failed.");
- goto error;
- }
-
- /* Initialize the mailbox */
- status = be_mpu_init_mailbox(pfob, mailbox);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "Failed to initialize mailbox.");
- goto error;
- }
- /*
- * Cache the firmware config for ASSERTs in hwclib and later
- * driver queries.
- */
- status = be_function_internal_query_firmware_config(pfob,
- &pfob->fw_config);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "Failed to query firmware config.");
- goto error;
- }
-
-error:
- if (status != BE_SUCCESS) {
- /* No cleanup necessary */
- TRACE(DL_ERR, "Failed to create function.");
- memset(pfob, 0, sizeof(*pfob));
- }
- return status;
-}
-
-/*
- This routine drops the reference count on a given function object. Once
- the reference count falls to zero, the function object is destroyed and all
- resources held are freed.
-
- FunctionObject - The function object to drop the reference to.
-*/
-int be_function_object_destroy(struct be_function_object *pfob)
-{
- TRACE(DL_INFO, "Destroy pfob. Object:0x%p",
- pfob);
-
-
- ASSERT(pfob->mcc == NULL);
-
- return BE_SUCCESS;
-}
-
-int be_function_cleanup(struct be_function_object *pfob)
-{
- int status = 0;
- u32 isr;
- u32 host_intr;
- struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP ctrl;
-
-
- if (pfob->type == BE_FUNCTION_TYPE_NETWORK) {
- status = be_rxf_multicast_config(pfob, false, 0,
- NULL, NULL, NULL, NULL);
- ASSERT(status == BE_SUCCESS);
- }
- /* VLAN */
- status = be_rxf_vlan_config(pfob, false, 0, NULL, NULL, NULL, NULL);
- ASSERT(status == BE_SUCCESS);
- /*
- * MCC Queue -- Switches to mailbox mode. May want to destroy
- * all but the MCC CQ before this call if polling CQ is much better
- * performance than polling mailbox register.
- */
- if (pfob->mcc)
- status = be_mcc_ring_destroy(pfob->mcc);
- /*
- * If interrupts are disabled, clear any CEV interrupt assertions that
- * fired after we stopped processing EQs.
- */
- ctrl.dw[0] = PCICFG1_READ(pfob, host_timer_int_ctrl);
- host_intr = AMAP_GET_BITS_PTR(PCICFG_HOST_TIMER_INT_CTRL_CSR,
- hostintr, ctrl.dw);
- if (!host_intr)
- if (pfob->type == BE_FUNCTION_TYPE_NETWORK)
- isr = CSR_READ(pfob, cev.isr1);
- else
- isr = CSR_READ(pfob, cev.isr0);
- else
- /* This should never happen... */
- TRACE(DL_ERR, "function_cleanup called with interrupt enabled");
- /* Function object destroy */
- status = be_function_object_destroy(pfob);
- ASSERT(status == BE_SUCCESS);
-
- return status;
-}
-
-
-void *
-be_function_prepare_embedded_fwcmd(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, u32 payld_len, u32 request_length,
- u32 response_length, u32 opcode, u32 subsystem)
-{
- struct FWCMD_REQUEST_HEADER *header = NULL;
- u32 n;
-
- ASSERT(wrb);
-
- n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8;
- AMAP_SET_BITS_PTR(MCC_WRB, embedded, wrb, 1);
- AMAP_SET_BITS_PTR(MCC_WRB, payload_length, wrb, min(payld_len, n));
- header = (struct FWCMD_REQUEST_HEADER *)((u8 *)wrb + n);
-
- header->timeout = 0;
- header->domain = 0;
- header->request_length = max(request_length, response_length);
- header->opcode = opcode;
- header->subsystem = subsystem;
-
- return header;
-}
-
-void *
-be_function_prepare_nonembedded_fwcmd(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb,
- void *fwcmd_va, u64 fwcmd_pa,
- u32 payld_len,
- u32 request_length,
- u32 response_length,
- u32 opcode, u32 subsystem)
-{
- struct FWCMD_REQUEST_HEADER *header = NULL;
- u32 n;
- struct MCC_WRB_PAYLOAD_AMAP *plp;
-
- ASSERT(wrb);
- ASSERT(fwcmd_va);
-
- header = (struct FWCMD_REQUEST_HEADER *) fwcmd_va;
-
- AMAP_SET_BITS_PTR(MCC_WRB, embedded, wrb, 0);
- AMAP_SET_BITS_PTR(MCC_WRB, payload_length, wrb, payld_len);
-
- /*
- * Assume one fragment. The caller may override the SGL by
- * rewriting the 0th length and adding more entries. They
- * will also need to update the sge_count.
- */
- AMAP_SET_BITS_PTR(MCC_WRB, sge_count, wrb, 1);
-
- n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8;
- plp = (struct MCC_WRB_PAYLOAD_AMAP *)((u8 *)wrb + n);
- AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].length, plp, payld_len);
- AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].pa_lo, plp, (u32)fwcmd_pa);
- AMAP_SET_BITS_PTR(MCC_WRB_PAYLOAD, sgl[0].pa_hi, plp,
- upper_32_bits(fwcmd_pa));
-
- header->timeout = 0;
- header->domain = 0;
- header->request_length = max(request_length, response_length);
- header->opcode = opcode;
- header->subsystem = subsystem;
-
- return header;
-}
-
-struct MCC_WRB_AMAP *
-be_function_peek_mcc_wrb(struct be_function_object *pfob)
-{
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 offset;
-
- if (pfob->mcc)
- wrb = _be_mpu_peek_ring_wrb(pfob->mcc, false);
- else {
- offset = offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8;
- wrb = (struct MCC_WRB_AMAP *) ((u8 *) pfob->mailbox.va +
- offset);
- }
-
- if (wrb)
- memset(wrb, 0, sizeof(struct MCC_WRB_AMAP));
-
- return wrb;
-}
-
-#if defined(BE_DEBUG)
-void be_function_debug_print_wrb(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, void *optional_fwcmd_va,
- struct be_mcc_wrb_context *wrb_context)
-{
-
- struct FWCMD_REQUEST_HEADER *header = NULL;
- u8 embedded;
- u32 n;
-
- embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, wrb);
-
- if (embedded) {
- n = offsetof(struct BE_MCC_WRB_AMAP, payload)/8;
- header = (struct FWCMD_REQUEST_HEADER *)((u8 *)wrb + n);
- } else {
- header = (struct FWCMD_REQUEST_HEADER *) optional_fwcmd_va;
- }
-
- /* Save the completed count before posting for a debug assert. */
-
- if (header) {
- wrb_context->opcode = header->opcode;
- wrb_context->subsystem = header->subsystem;
-
- } else {
- wrb_context->opcode = 0;
- wrb_context->subsystem = 0;
- }
-}
-#else
-#define be_function_debug_print_wrb(a_, b_, c_, d_)
-#endif
-
-int
-be_function_post_mcc_wrb(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb,
- struct be_generic_q_ctxt *q_ctxt,
- mcc_wrb_cqe_callback cb, void *cb_context,
- mcc_wrb_cqe_callback internal_cb,
- void *internal_cb_context, void *optional_fwcmd_va,
- struct be_mcc_wrb_response_copy *rc)
-{
- int status;
- struct be_mcc_wrb_context *wrb_context = NULL;
- u64 *p;
-
- if (q_ctxt) {
- /* Initialize context. */
- q_ctxt->context.internal_cb = internal_cb;
- q_ctxt->context.internal_cb_context = internal_cb_context;
- q_ctxt->context.cb = cb;
- q_ctxt->context.cb_context = cb_context;
- if (rc) {
- q_ctxt->context.copy.length = rc->length;
- q_ctxt->context.copy.fwcmd_offset = rc->fwcmd_offset;
- q_ctxt->context.copy.va = rc->va;
- } else
- q_ctxt->context.copy.length = 0;
-
- q_ctxt->context.optional_fwcmd_va = optional_fwcmd_va;
-
- /* Queue this request */
- status = be_function_queue_mcc_wrb(pfob, q_ctxt);
-
- goto Error;
- }
- /*
- * Allocate a WRB context struct to hold the callback pointers,
- * status, etc. This is required if commands complete out of order.
- */
- wrb_context = _be_mcc_allocate_wrb_context(pfob);
- if (!wrb_context) {
- TRACE(DL_WARN, "Failed to allocate MCC WRB context.");
- status = BE_STATUS_SYSTEM_RESOURCES;
- goto Error;
- }
- /* Initialize context. */
- memset(wrb_context, 0, sizeof(*wrb_context));
- wrb_context->internal_cb = internal_cb;
- wrb_context->internal_cb_context = internal_cb_context;
- wrb_context->cb = cb;
- wrb_context->cb_context = cb_context;
- if (rc) {
- wrb_context->copy.length = rc->length;
- wrb_context->copy.fwcmd_offset = rc->fwcmd_offset;
- wrb_context->copy.va = rc->va;
- } else
- wrb_context->copy.length = 0;
- wrb_context->wrb = wrb;
-
- /*
- * Copy the context pointer into the WRB opaque tag field.
- * Verify assumption of 64-bit tag with a compile time assert.
- */
- p = (u64 *) ((u8 *)wrb + offsetof(struct BE_MCC_WRB_AMAP, tag)/8);
- *p = (u64)(size_t)wrb_context;
-
- /* Print info about this FWCMD for debug builds. */
- be_function_debug_print_wrb(pfob, wrb, optional_fwcmd_va, wrb_context);
-
- /*
- * issue the WRB to the MPU as appropriate
- */
- if (pfob->mcc) {
- /*
- * we're in WRB mode, pass to the mcc layer
- */
- status = _be_mpu_post_wrb_ring(pfob->mcc, wrb, wrb_context);
- } else {
- /*
- * we're in mailbox mode
- */
- status = _be_mpu_post_wrb_mailbox(pfob, wrb, wrb_context);
-
- /* mailbox mode always completes synchronously */
- ASSERT(status != BE_STATUS_PENDING);
- }
-
-Error:
-
- return status;
-}
-
-int
-be_function_ring_destroy(struct be_function_object *pfob,
- u32 id, u32 ring_type, mcc_wrb_cqe_callback cb,
- void *cb_context, mcc_wrb_cqe_callback internal_cb,
- void *internal_cb_context)
-{
-
- struct FWCMD_COMMON_RING_DESTROY *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- int status = 0;
- unsigned long irql;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- TRACE(DL_INFO, "Destroy ring id:%d type:%d", id, ring_type);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in destroy ring.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_RING_DESTROY);
-
- fwcmd->params.request.id = id;
- fwcmd->params.request.ring_type = ring_type;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb, cb_context,
- internal_cb, internal_cb_context, fwcmd, NULL);
- if (status != BE_SUCCESS && status != BE_PENDING) {
- TRACE(DL_ERR, "Ring destroy fwcmd failed. id:%d ring_type:%d",
- id, ring_type);
- goto Error;
- }
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-void
-be_rd_to_pa_list(struct ring_desc *rd, struct PHYS_ADDR *pa_list, u32 max_num)
-{
- u32 num_pages = PAGES_SPANNED(rd->va, rd->length);
- u32 i = 0;
- u64 pa = rd->pa;
- __le64 lepa;
-
- ASSERT(pa_list);
- ASSERT(pa);
-
- for (i = 0; i < min(num_pages, max_num); i++) {
- lepa = cpu_to_le64(pa);
- pa_list[i].lo = (u32)lepa;
- pa_list[i].hi = upper_32_bits(lepa);
- pa += PAGE_SIZE;
- }
-}
-
-
-
-/*-----------------------------------------------------------------------------
- * Function: be_function_get_fw_version
- * Retrieves the firmware version on the adpater. If the callback is
- * NULL this call executes synchronously. If the callback is not NULL,
- * the returned status will be BE_PENDING if the command was issued
- * successfully.
- * pfob -
- * fwv - Pointer to response buffer if callback is NULL.
- * cb - Callback function invoked when the FWCMD completes.
- * cb_context - Passed to the callback function.
- * return pend_status - BE_SUCCESS (0) on success.
- * BE_PENDING (postive value) if the FWCMD
- * completion is pending. Negative error code on failure.
- *---------------------------------------------------------------------------
- */
-int
-be_function_get_fw_version(struct be_function_object *pfob,
- struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD *fwv,
- mcc_wrb_cqe_callback cb, void *cb_context)
-{
- int status = BE_SUCCESS;
- struct MCC_WRB_AMAP *wrb = NULL;
- struct FWCMD_COMMON_GET_FW_VERSION *fwcmd = NULL;
- unsigned long irql;
- struct be_mcc_wrb_response_copy rc;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- TRACE(DL_ERR, "MCC wrb peek failed.");
- status = BE_STATUS_NO_MCC_WRB;
- goto Error;
- }
-
- if (!cb && !fwv) {
- TRACE(DL_ERR, "callback and response buffer NULL!");
- status = BE_NOT_OK;
- goto Error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_GET_FW_VERSION);
-
- rc.length = FIELD_SIZEOF(struct FWCMD_COMMON_GET_FW_VERSION,
- params.response);
- rc.fwcmd_offset = offsetof(struct FWCMD_COMMON_GET_FW_VERSION,
- params.response);
- rc.va = fwv;
-
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, cb,
- cb_context, NULL, NULL, fwcmd, &rc);
-
-Error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-int
-be_function_queue_mcc_wrb(struct be_function_object *pfob,
- struct be_generic_q_ctxt *q_ctxt)
-{
- int status;
-
- ASSERT(q_ctxt);
-
- /*
- * issue the WRB to the MPU as appropriate
- */
- if (pfob->mcc) {
-
- /* We're in ring mode. Queue this item. */
- pfob->mcc->backlog_length++;
- list_add_tail(&q_ctxt->context.list, &pfob->mcc->backlog);
- status = BE_PENDING;
- } else {
- status = BE_NOT_OK;
- }
- return status;
-}
-
diff --git a/drivers/staging/benet/fwcmd_common.h b/drivers/staging/benet/fwcmd_common.h
deleted file mode 100644
index 406e0d6fa985..000000000000
--- a/drivers/staging/benet/fwcmd_common.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_common_amap_h__
-#define __fwcmd_common_amap_h__
-#include "host_struct.h"
-
-/* --- PHY_LINK_DUPLEX_ENUM --- */
-#define PHY_LINK_DUPLEX_NONE (0)
-#define PHY_LINK_DUPLEX_HALF (1)
-#define PHY_LINK_DUPLEX_FULL (2)
-
-/* --- PHY_LINK_SPEED_ENUM --- */
-#define PHY_LINK_SPEED_ZERO (0) /* No link. */
-#define PHY_LINK_SPEED_10MBPS (1) /* 10 Mbps */
-#define PHY_LINK_SPEED_100MBPS (2) /* 100 Mbps */
-#define PHY_LINK_SPEED_1GBPS (3) /* 1 Gbps */
-#define PHY_LINK_SPEED_10GBPS (4) /* 10 Gbps */
-
-/* --- PHY_LINK_FAULT_ENUM --- */
-#define PHY_LINK_FAULT_NONE (0) /* No fault status
- available or detected */
-#define PHY_LINK_FAULT_LOCAL (1) /* Local fault detected */
-#define PHY_LINK_FAULT_REMOTE (2) /* Remote fault detected */
-
-/* --- BE_ULP_MASK --- */
-#define BE_ULP0_MASK (1)
-#define BE_ULP1_MASK (2)
-#define BE_ULP2_MASK (4)
-
-/* --- NTWK_ACTIVE_PORT --- */
-#define NTWK_PORT_A (0) /* Port A is currently active */
-#define NTWK_PORT_B (1) /* Port B is currently active */
-#define NTWK_NO_ACTIVE_PORT (15) /* Both ports have lost link */
-
-/* --- NTWK_LINK_TYPE --- */
-#define NTWK_LINK_TYPE_PHYSICAL (0) /* link up/down event
- applies to BladeEngine's
- Physical Ports
- */
-#define NTWK_LINK_TYPE_VIRTUAL (1) /* Virtual link up/down event
- reported by BladeExchange.
- This applies only when the
- VLD feature is enabled
- */
-
-/*
- * --- FWCMD_MAC_TYPE_ENUM ---
- * This enum defines the types of MAC addresses in the RXF MAC Address Table.
- */
-#define MAC_ADDRESS_TYPE_STORAGE (0) /* Storage MAC Address */
-#define MAC_ADDRESS_TYPE_NETWORK (1) /* Network MAC Address */
-#define MAC_ADDRESS_TYPE_PD (2) /* Protection Domain MAC Addr */
-#define MAC_ADDRESS_TYPE_MANAGEMENT (3) /* Managment MAC Address */
-
-
-/* --- FWCMD_RING_TYPE_ENUM --- */
-#define FWCMD_RING_TYPE_ETH_RX (1) /* Ring created with */
- /* FWCMD_COMMON_ETH_RX_CREATE. */
-#define FWCMD_RING_TYPE_ETH_TX (2) /* Ring created with */
- /* FWCMD_COMMON_ETH_TX_CREATE. */
-#define FWCMD_RING_TYPE_ISCSI_WRBQ (3) /* Ring created with */
- /* FWCMD_COMMON_ISCSI_WRBQ_CREATE. */
-#define FWCMD_RING_TYPE_ISCSI_DEFQ (4) /* Ring created with */
- /* FWCMD_COMMON_ISCSI_DEFQ_CREATE. */
-#define FWCMD_RING_TYPE_TPM_WRBQ (5) /* Ring created with */
- /* FWCMD_COMMON_TPM_WRBQ_CREATE. */
-#define FWCMD_RING_TYPE_TPM_DEFQ (6) /* Ring created with */
- /* FWCMD_COMMONTPM_TDEFQ_CREATE. */
-#define FWCMD_RING_TYPE_TPM_RQ (7) /* Ring created with */
- /* FWCMD_COMMON_TPM_RQ_CREATE. */
-#define FWCMD_RING_TYPE_MCC (8) /* Ring created with */
- /* FWCMD_COMMON_MCC_CREATE. */
-#define FWCMD_RING_TYPE_CQ (9) /* Ring created with */
- /* FWCMD_COMMON_CQ_CREATE. */
-#define FWCMD_RING_TYPE_EQ (10) /* Ring created with */
- /* FWCMD_COMMON_EQ_CREATE. */
-#define FWCMD_RING_TYPE_QP (11) /* Ring created with */
- /* FWCMD_RDMA_QP_CREATE. */
-
-
-/* --- ETH_TX_RING_TYPE_ENUM --- */
-#define ETH_TX_RING_TYPE_FORWARDING (1) /* Ethernet ring for
- forwarding packets */
-#define ETH_TX_RING_TYPE_STANDARD (2) /* Ethernet ring for sending
- network packets. */
-#define ETH_TX_RING_TYPE_BOUND (3) /* Ethernet ring bound to the
- port specified in the command
- header.port_number field.
- Rings of this type are
- NOT subject to the
- failover logic implemented
- in the BladeEngine.
- */
-
-/* --- FWCMD_COMMON_QOS_TYPE_ENUM --- */
-#define QOS_BITS_NIC (1) /* max_bits_per_second_NIC */
- /* field is valid. */
-#define QOS_PKTS_NIC (2) /* max_packets_per_second_NIC */
- /* field is valid. */
-#define QOS_IOPS_ISCSI (4) /* max_ios_per_second_iSCSI */
- /*field is valid. */
-#define QOS_VLAN_TAG (8) /* domain_VLAN_tag field
- is valid. */
-#define QOS_FABRIC_ID (16) /* fabric_domain_ID field
- is valid. */
-#define QOS_OEM_PARAMS (32) /* qos_params_oem field
- is valid. */
-#define QOS_TPUT_ISCSI (64) /* max_bytes_per_second_iSCSI
- field is valid. */
-
-
-/*
- * --- FAILOVER_CONFIG_ENUM ---
- * Failover configuration setting used in FWCMD_COMMON_FORCE_FAILOVER
- */
-#define FAILOVER_CONFIG_NO_CHANGE (0) /* No change to automatic */
- /* port failover setting. */
-#define FAILOVER_CONFIG_ON (1) /* Automatic port failover
- on link down is enabled. */
-#define FAILOVER_CONFIG_OFF (2) /* Automatic port failover
- on link down is disabled. */
-
-/*
- * --- FAILOVER_PORT_ENUM ---
- * Failover port setting used in FWCMD_COMMON_FORCE_FAILOVER
- */
-#define FAILOVER_PORT_A (0) /* Selects port A. */
-#define FAILOVER_PORT_B (1) /* Selects port B. */
-#define FAILOVER_PORT_NONE (15) /* No port change requested. */
-
-
-/*
- * --- MGMT_FLASHROM_OPCODE ---
- * Flash ROM operation code
- */
-#define MGMT_FLASHROM_OPCODE_FLASH (1) /* Commit downloaded data
- to Flash ROM */
-#define MGMT_FLASHROM_OPCODE_SAVE (2) /* Save downloaded data to
- ARM's DDR - do not flash */
-#define MGMT_FLASHROM_OPCODE_CLEAR (3) /* Erase specified component
- from FlashROM */
-#define MGMT_FLASHROM_OPCODE_REPORT (4) /* Read specified component
- from Flash ROM */
-#define MGMT_FLASHROM_OPCODE_IMAGE_INFO (5) /* Returns size of a
- component */
-
-/*
- * --- MGMT_FLASHROM_OPTYPE ---
- * Flash ROM operation type
- */
-#define MGMT_FLASHROM_OPTYPE_CODE_FIRMWARE (0) /* Includes ARM firmware,
- IPSec (optional) and EP
- firmware */
-#define MGMT_FLASHROM_OPTYPE_CODE_REDBOOT (1)
-#define MGMT_FLASHROM_OPTYPE_CODE_BIOS (2)
-#define MGMT_FLASHROM_OPTYPE_CODE_PXE_BIOS (3)
-#define MGMT_FLASHROM_OPTYPE_CODE_CTRLS (4)
-#define MGMT_FLASHROM_OPTYPE_CFG_IPSEC (5)
-#define MGMT_FLASHROM_OPTYPE_CFG_INI (6)
-#define MGMT_FLASHROM_OPTYPE_ROM_OFFSET_SPECIFIED (7)
-
-/*
- * --- FLASHROM_TYPE ---
- * Flash ROM manufacturers supported in the f/w
- */
-#define INTEL (0)
-#define SPANSION (1)
-#define MICRON (2)
-
-/* --- DDR_CAS_TYPE --- */
-#define CAS_3 (0)
-#define CAS_4 (1)
-#define CAS_5 (2)
-
-/* --- DDR_SIZE_TYPE --- */
-#define SIZE_256MB (0)
-#define SIZE_512MB (1)
-
-/* --- DDR_MODE_TYPE --- */
-#define DDR_NO_ECC (0)
-#define DDR_ECC (1)
-
-/* --- INTERFACE_10GB_TYPE --- */
-#define CX4_TYPE (0)
-#define XFP_TYPE (1)
-
-/* --- BE_CHIP_MAX_MTU --- */
-#define CHIP_MAX_MTU (9000)
-
-/* --- XAUI_STATE_ENUM --- */
-#define XAUI_STATE_ENABLE (0) /* This MUST be the default
- value for all requests
- which set/change
- equalization parameter. */
-#define XAUI_STATE_DISABLE (255) /* The XAUI for both ports
- may be disabled for EMI
- tests. There is no
- provision for turning off
- individual ports.
- */
-/* --- BE_ASIC_REVISION --- */
-#define BE_ASIC_REV_A0 (1)
-#define BE_ASIC_REV_A1 (2)
-
-#endif /* __fwcmd_common_amap_h__ */
diff --git a/drivers/staging/benet/fwcmd_common_bmap.h b/drivers/staging/benet/fwcmd_common_bmap.h
deleted file mode 100644
index a007cf276500..000000000000
--- a/drivers/staging/benet/fwcmd_common_bmap.h
+++ /dev/null
@@ -1,717 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_common_bmap_h__
-#define __fwcmd_common_bmap_h__
-#include "fwcmd_types_bmap.h"
-#include "fwcmd_hdr_bmap.h"
-
-#if defined(__BIG_ENDIAN)
- /* Physical Address. */
-struct PHYS_ADDR {
- union {
- struct {
- u32 lo; /* DWORD 0 */
- u32 hi; /* DWORD 1 */
- } __packed; /* unnamed struct */
- u32 dw[2]; /* dword union */
- }; /* unnamed union */
-} __packed ;
-
-
-#else
- /* Physical Address. */
-struct PHYS_ADDR {
- union {
- struct {
- u32 lo; /* DWORD 0 */
- u32 hi; /* DWORD 1 */
- } __packed; /* unnamed struct */
- u32 dw[2]; /* dword union */
- }; /* unnamed union */
-} __packed ;
-
-struct BE_LINK_STATUS {
- u8 mac0_duplex;
- u8 mac0_speed;
- u8 mac1_duplex;
- u8 mac1_speed;
- u8 mgmt_mac_duplex;
- u8 mgmt_mac_speed;
- u8 active_port;
- u8 rsvd0;
- u8 mac0_fault;
- u8 mac1_fault;
- u16 rsvd1;
-} __packed;
-#endif
-
-struct FWCMD_COMMON_ANON_170_REQUEST {
- u32 rsvd0;
-} __packed;
-
-union LINK_STATUS_QUERY_PARAMS {
- struct BE_LINK_STATUS response;
- struct FWCMD_COMMON_ANON_170_REQUEST request;
-} __packed;
-
-/*
- * Queries the the link status for all ports. The valid values below
- * DO NOT indicate that a particular duplex or speed is supported by
- * BladeEngine. These enumerations simply list all possible duplexes
- * and speeds for any port. Consult BladeEngine product documentation
- * for the supported parameters.
- */
-struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY {
- union FWCMD_HEADER header;
- union LINK_STATUS_QUERY_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_171_REQUEST {
- u8 type;
- u8 port;
- u8 mac1;
- u8 permanent;
-} __packed;
-
-struct FWCMD_COMMON_ANON_172_RESPONSE {
- struct MAC_ADDRESS_FORMAT mac;
-} __packed;
-
-union NTWK_MAC_QUERY_PARAMS {
- struct FWCMD_COMMON_ANON_171_REQUEST request;
- struct FWCMD_COMMON_ANON_172_RESPONSE response;
-} __packed;
-
-/* Queries one MAC address. */
-struct FWCMD_COMMON_NTWK_MAC_QUERY {
- union FWCMD_HEADER header;
- union NTWK_MAC_QUERY_PARAMS params;
-} __packed;
-
-struct MAC_SET_PARAMS_IN {
- u8 type;
- u8 port;
- u8 mac1;
- u8 invalidate;
- struct MAC_ADDRESS_FORMAT mac;
-} __packed;
-
-struct MAC_SET_PARAMS_OUT {
- u32 rsvd0;
-} __packed;
-
-union MAC_SET_PARAMS {
- struct MAC_SET_PARAMS_IN request;
- struct MAC_SET_PARAMS_OUT response;
-} __packed;
-
-/* Sets a MAC address. */
-struct FWCMD_COMMON_NTWK_MAC_SET {
- union FWCMD_HEADER header;
- union MAC_SET_PARAMS params;
-} __packed;
-
-/* MAC address list. */
-struct NTWK_MULTICAST_MAC_LIST {
- u8 byte[6];
-} __packed;
-
-struct FWCMD_COMMON_NTWK_MULTICAST_SET_REQUEST_PAYLOAD {
- u16 num_mac;
- u8 promiscuous;
- u8 rsvd0;
- struct NTWK_MULTICAST_MAC_LIST mac[32];
-} __packed;
-
-struct FWCMD_COMMON_ANON_174_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_173_PARAMS {
- struct FWCMD_COMMON_NTWK_MULTICAST_SET_REQUEST_PAYLOAD request;
- struct FWCMD_COMMON_ANON_174_RESPONSE response;
-} __packed;
-
-/*
- * Sets multicast address hash. The MPU will merge the MAC address lists
- * from all clients, including the networking and storage functions.
- * This command may fail if the final merged list of MAC addresses exceeds
- * 32 entries.
- */
-struct FWCMD_COMMON_NTWK_MULTICAST_SET {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_173_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_NTWK_VLAN_CONFIG_REQUEST_PAYLOAD {
- u16 num_vlan;
- u8 promiscuous;
- u8 rsvd0;
- u16 vlan_tag[32];
-} __packed;
-
-struct FWCMD_COMMON_ANON_176_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_175_PARAMS {
- struct FWCMD_COMMON_NTWK_VLAN_CONFIG_REQUEST_PAYLOAD request;
- struct FWCMD_COMMON_ANON_176_RESPONSE response;
-} __packed;
-
-/*
- * Sets VLAN tag filter. The MPU will merge the VLAN tag list from all
- * clients, including the networking and storage functions. This command
- * may fail if the final vlan_tag array (from all functions) is longer
- * than 32 entries.
- */
-struct FWCMD_COMMON_NTWK_VLAN_CONFIG {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_175_PARAMS params;
-} __packed;
-
-struct RING_DESTROY_REQUEST {
- u16 ring_type;
- u16 id;
- u8 bypass_flush;
- u8 rsvd0;
- u16 rsvd1;
-} __packed;
-
-struct FWCMD_COMMON_ANON_190_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_189_PARAMS {
- struct RING_DESTROY_REQUEST request;
- struct FWCMD_COMMON_ANON_190_RESPONSE response;
-} __packed;
-/*
- * Command for destroying any ring. The connection(s) using the ring should
- * be quiesced before destroying the ring.
- */
-struct FWCMD_COMMON_RING_DESTROY {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_189_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_192_REQUEST {
- u16 num_pages;
- u16 rsvd0;
- struct CQ_CONTEXT_AMAP context;
- struct PHYS_ADDR pages[4];
-} __packed ;
-
-struct FWCMD_COMMON_ANON_193_RESPONSE {
- u16 cq_id;
-} __packed ;
-
-union FWCMD_COMMON_ANON_191_PARAMS {
- struct FWCMD_COMMON_ANON_192_REQUEST request;
- struct FWCMD_COMMON_ANON_193_RESPONSE response;
-} __packed ;
-
-/*
- * Command for creating a completion queue. A Completion Queue must span
- * at least 1 page and at most 4 pages. Each completion queue entry
- * is 16 bytes regardless of CQ entry format. Thus the ring must be
- * at least 256 entries deep (corresponding to 1 page) and can be at
- * most 1024 entries deep (corresponding to 4 pages). The number of
- * pages posted must contain the CQ ring size as encoded in the context.
- *
- */
-struct FWCMD_COMMON_CQ_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_191_PARAMS params;
-} __packed ;
-
-struct FWCMD_COMMON_ANON_198_REQUEST {
- u16 num_pages;
- u16 rsvd0;
- struct EQ_CONTEXT_AMAP context;
- struct PHYS_ADDR pages[8];
-} __packed ;
-
-struct FWCMD_COMMON_ANON_199_RESPONSE {
- u16 eq_id;
-} __packed ;
-
-union FWCMD_COMMON_ANON_197_PARAMS {
- struct FWCMD_COMMON_ANON_198_REQUEST request;
- struct FWCMD_COMMON_ANON_199_RESPONSE response;
-} __packed ;
-
-/*
- * Command for creating a event queue. An Event Queue must span at least
- * 1 page and at most 8 pages. The number of pages posted must contain
- * the EQ ring. The ring is defined by the size of the EQ entries (encoded
- * in the context) and the number of EQ entries (also encoded in the
- * context).
- */
-struct FWCMD_COMMON_EQ_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_197_PARAMS params;
-} __packed ;
-
-struct FWCMD_COMMON_ANON_201_REQUEST {
- u16 cq_id;
- u16 bcmc_cq_id;
- u16 num_pages;
- u16 rsvd0;
- struct PHYS_ADDR pages[2];
-} __packed;
-
-struct FWCMD_COMMON_ANON_202_RESPONSE {
- u16 id;
-} __packed;
-
-union FWCMD_COMMON_ANON_200_PARAMS {
- struct FWCMD_COMMON_ANON_201_REQUEST request;
- struct FWCMD_COMMON_ANON_202_RESPONSE response;
-} __packed;
-
-/*
- * Command for creating Ethernet receive ring. An ERX ring contains ETH_RX_D
- * entries (8 bytes each). An ERX ring must be 1024 entries deep
- * (corresponding to 2 pages).
- */
-struct FWCMD_COMMON_ETH_RX_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_200_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_204_REQUEST {
- u16 num_pages;
- u8 ulp_num;
- u8 type;
- struct ETX_CONTEXT_AMAP context;
- struct PHYS_ADDR pages[8];
-} __packed ;
-
-struct FWCMD_COMMON_ANON_205_RESPONSE {
- u16 cid;
- u8 ulp_num;
- u8 rsvd0;
-} __packed ;
-
-union FWCMD_COMMON_ANON_203_PARAMS {
- struct FWCMD_COMMON_ANON_204_REQUEST request;
- struct FWCMD_COMMON_ANON_205_RESPONSE response;
-} __packed ;
-
-/*
- * Command for creating an Ethernet transmit ring. An ETX ring contains
- * ETH_WRB entries (16 bytes each). An ETX ring must be at least 256
- * entries deep (corresponding to 1 page) and at most 2k entries deep
- * (corresponding to 8 pages).
- */
-struct FWCMD_COMMON_ETH_TX_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_203_PARAMS params;
-} __packed ;
-
-struct FWCMD_COMMON_ANON_222_REQUEST {
- u16 num_pages;
- u16 rsvd0;
- struct MCC_RING_CONTEXT_AMAP context;
- struct PHYS_ADDR pages[8];
-} __packed ;
-
-struct FWCMD_COMMON_ANON_223_RESPONSE {
- u16 id;
-} __packed ;
-
-union FWCMD_COMMON_ANON_221_PARAMS {
- struct FWCMD_COMMON_ANON_222_REQUEST request;
- struct FWCMD_COMMON_ANON_223_RESPONSE response;
-} __packed ;
-
-/*
- * Command for creating the MCC ring. An MCC ring must be at least 16
- * entries deep (corresponding to 1 page) and at most 128 entries deep
- * (corresponding to 8 pages).
- */
-struct FWCMD_COMMON_MCC_CREATE {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_221_PARAMS params;
-} __packed ;
-
-struct GET_QOS_IN {
- u32 qos_params_rsvd;
-} __packed;
-
-struct GET_QOS_OUT {
- u32 max_bits_per_second_NIC;
- u32 max_packets_per_second_NIC;
- u32 max_ios_per_second_iSCSI;
- u32 max_bytes_per_second_iSCSI;
- u16 domain_VLAN_tag;
- u16 fabric_domain_ID;
- u32 qos_params_oem[4];
-} __packed;
-
-union GET_QOS_PARAMS {
- struct GET_QOS_IN request;
- struct GET_QOS_OUT response;
-} __packed;
-
-/* QOS/Bandwidth settings per domain. Applicable only in VMs. */
-struct FWCMD_COMMON_GET_QOS {
- union FWCMD_HEADER header;
- union GET_QOS_PARAMS params;
-} __packed;
-
-struct SET_QOS_IN {
- u32 valid_flags;
- u32 max_bits_per_second_NIC;
- u32 max_packets_per_second_NIC;
- u32 max_ios_per_second_iSCSI;
- u32 max_bytes_per_second_iSCSI;
- u16 domain_VLAN_tag;
- u16 fabric_domain_ID;
- u32 qos_params_oem[4];
-} __packed;
-
-struct SET_QOS_OUT {
- u32 qos_params_rsvd;
-} __packed;
-
-union SET_QOS_PARAMS {
- struct SET_QOS_IN request;
- struct SET_QOS_OUT response;
-} __packed;
-
-/* QOS/Bandwidth settings per domain. Applicable only in VMs. */
-struct FWCMD_COMMON_SET_QOS {
- union FWCMD_HEADER header;
- union SET_QOS_PARAMS params;
-} __packed;
-
-struct SET_FRAME_SIZE_IN {
- u32 max_tx_frame_size;
- u32 max_rx_frame_size;
-} __packed;
-
-struct SET_FRAME_SIZE_OUT {
- u32 chip_max_tx_frame_size;
- u32 chip_max_rx_frame_size;
-} __packed;
-
-union SET_FRAME_SIZE_PARAMS {
- struct SET_FRAME_SIZE_IN request;
- struct SET_FRAME_SIZE_OUT response;
-} __packed;
-
-/* Set frame size command. Only host domain may issue this command. */
-struct FWCMD_COMMON_SET_FRAME_SIZE {
- union FWCMD_HEADER header;
- union SET_FRAME_SIZE_PARAMS params;
-} __packed;
-
-struct FORCE_FAILOVER_IN {
- u32 move_to_port;
- u32 failover_config;
-} __packed;
-
-struct FWCMD_COMMON_ANON_231_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_230_PARAMS {
- struct FORCE_FAILOVER_IN request;
- struct FWCMD_COMMON_ANON_231_RESPONSE response;
-} __packed;
-
-/*
- * Use this command to control failover in BladeEngine. It may be used
- * to failback to a restored port or to forcibly move traffic from
- * one port to another. It may also be used to enable or disable the
- * automatic failover feature. This command can only be issued by domain
- * 0.
- */
-struct FWCMD_COMMON_FORCE_FAILOVER {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_230_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_240_REQUEST {
- u64 context;
-} __packed;
-
-struct FWCMD_COMMON_ANON_241_RESPONSE {
- u64 context;
-} __packed;
-
-union FWCMD_COMMON_ANON_239_PARAMS {
- struct FWCMD_COMMON_ANON_240_REQUEST request;
- struct FWCMD_COMMON_ANON_241_RESPONSE response;
-} __packed;
-
-/*
- * This command can be used by clients as a no-operation request. Typical
- * uses for drivers are as a heartbeat mechanism, or deferred processing
- * catalyst. The ARM will always complete this command with a good completion.
- * The 64-bit parameter is not touched by the ARM processor.
- */
-struct FWCMD_COMMON_NOP {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_239_PARAMS params;
-} __packed;
-
-struct NTWK_RX_FILTER_SETTINGS {
- u8 promiscuous;
- u8 ip_cksum;
- u8 tcp_cksum;
- u8 udp_cksum;
- u8 pass_err;
- u8 pass_ckerr;
- u8 strip_crc;
- u8 mcast_en;
- u8 bcast_en;
- u8 mcast_promiscuous_en;
- u8 unicast_en;
- u8 vlan_promiscuous;
-} __packed;
-
-union FWCMD_COMMON_ANON_242_PARAMS {
- struct NTWK_RX_FILTER_SETTINGS request;
- struct NTWK_RX_FILTER_SETTINGS response;
-} __packed;
-
-/*
- * This command is used to modify the ethernet receive filter configuration.
- * Only domain 0 network function drivers may issue this command. The
- * applied configuration is returned in the response payload. Note:
- * Some receive packet filter settings are global on BladeEngine and
- * can affect both the storage and network function clients that the
- * BladeEngine hardware and firmware serve. Additionaly, depending
- * on the revision of BladeEngine, some ethernet receive filter settings
- * are dependent on others. If a dependency exists between settings
- * for the BladeEngine revision, and the command request settings do
- * not meet the dependency requirement, the invalid settings will not
- * be applied despite the comand succeeding. For example: a driver may
- * request to enable broadcast packets, but not enable multicast packets.
- * On early revisions of BladeEngine, there may be no distinction between
- * broadcast and multicast filters, so broadcast could not be enabled
- * without enabling multicast. In this scenario, the comand would still
- * succeed, but the response payload would indicate the previously
- * configured broadcast and multicast setting.
- */
-struct FWCMD_COMMON_NTWK_RX_FILTER {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_242_PARAMS params;
-} __packed;
-
-
-struct FWCMD_COMMON_ANON_244_REQUEST {
- u32 rsvd0;
-} __packed;
-
-struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD {
- u8 firmware_version_string[32];
- u8 fw_on_flash_version_string[32];
-} __packed;
-
-union FWCMD_COMMON_ANON_243_PARAMS {
- struct FWCMD_COMMON_ANON_244_REQUEST request;
- struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD response;
-} __packed;
-
-/* This comand retrieves the firmware version. */
-struct FWCMD_COMMON_GET_FW_VERSION {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_243_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_246_REQUEST {
- u16 tx_flow_control;
- u16 rx_flow_control;
-} __packed;
-
-struct FWCMD_COMMON_ANON_247_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_245_PARAMS {
- struct FWCMD_COMMON_ANON_246_REQUEST request;
- struct FWCMD_COMMON_ANON_247_RESPONSE response;
-} __packed;
-
-/*
- * This comand is used to program BladeEngine flow control behavior.
- * Only the host networking driver is allowed to use this comand.
- */
-struct FWCMD_COMMON_SET_FLOW_CONTROL {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_245_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_249_REQUEST {
- u32 rsvd0;
-} __packed;
-
-struct FWCMD_COMMON_ANON_250_RESPONSE {
- u16 tx_flow_control;
- u16 rx_flow_control;
-} __packed;
-
-union FWCMD_COMMON_ANON_248_PARAMS {
- struct FWCMD_COMMON_ANON_249_REQUEST request;
- struct FWCMD_COMMON_ANON_250_RESPONSE response;
-} __packed;
-
-/* This comand is used to read BladeEngine flow control settings. */
-struct FWCMD_COMMON_GET_FLOW_CONTROL {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_248_PARAMS params;
-} __packed;
-
-struct EQ_DELAY_PARAMS {
- u32 eq_id;
- u32 delay_in_microseconds;
-} __packed;
-
-struct FWCMD_COMMON_ANON_257_REQUEST {
- u32 num_eq;
- u32 rsvd0;
- struct EQ_DELAY_PARAMS delay[16];
-} __packed;
-
-struct FWCMD_COMMON_ANON_258_RESPONSE {
- u32 delay_resolution_in_microseconds;
- u32 delay_max_in_microseconds;
-} __packed;
-
-union MODIFY_EQ_DELAY_PARAMS {
- struct FWCMD_COMMON_ANON_257_REQUEST request;
- struct FWCMD_COMMON_ANON_258_RESPONSE response;
-} __packed;
-
-/* This comand changes the EQ delay for a given set of EQs. */
-struct FWCMD_COMMON_MODIFY_EQ_DELAY {
- union FWCMD_HEADER header;
- union MODIFY_EQ_DELAY_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_260_REQUEST {
- u32 rsvd0;
-} __packed;
-
-struct BE_FIRMWARE_CONFIG {
- u16 be_config_number;
- u16 asic_revision;
- u32 nic_ulp_mask;
- u32 tulp_mask;
- u32 iscsi_ulp_mask;
- u32 rdma_ulp_mask;
- u32 rsvd0[4];
- u32 eth_tx_id_start;
- u32 eth_tx_id_count;
- u32 eth_rx_id_start;
- u32 eth_rx_id_count;
- u32 tpm_wrbq_id_start;
- u32 tpm_wrbq_id_count;
- u32 tpm_defq_id_start;
- u32 tpm_defq_id_count;
- u32 iscsi_wrbq_id_start;
- u32 iscsi_wrbq_id_count;
- u32 iscsi_defq_id_start;
- u32 iscsi_defq_id_count;
- u32 rdma_qp_id_start;
- u32 rdma_qp_id_count;
- u32 rsvd1[8];
-} __packed;
-
-union FWCMD_COMMON_ANON_259_PARAMS {
- struct FWCMD_COMMON_ANON_260_REQUEST request;
- struct BE_FIRMWARE_CONFIG response;
-} __packed;
-
-/*
- * This comand queries the current firmware configuration parameters.
- * The static configuration type is defined by be_config_number. This
- * differentiates different BladeEngine builds, such as iSCSI Initiator
- * versus iSCSI Target. For a given static configuration, the Upper
- * Layer Protocol (ULP) processors may be reconfigured to support different
- * protocols. Each ULP processor supports one or more protocols. The
- * masks indicate which processors are configured for each protocol.
- * For a given static configuration, the number of TCP connections
- * supported for each protocol may vary. The *_id_start and *_id_count
- * variables define a linear range of IDs that are available for each
- * supported protocol. The *_id_count may be used by the driver to allocate
- * the appropriate number of connection resources. The *_id_start may
- * be used to map the arbitrary range of IDs to a zero-based range
- * of indices.
- */
-struct FWCMD_COMMON_FIRMWARE_CONFIG {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_259_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS {
- u32 emph_lev_sel_port0;
- u32 emph_lev_sel_port1;
- u8 xaui_vo_sel;
- u8 xaui_state;
- u16 rsvd0;
- u32 xaui_eq_vector;
-} __packed;
-
-struct FWCMD_COMMON_ANON_262_REQUEST {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_261_PARAMS {
- struct FWCMD_COMMON_ANON_262_REQUEST request;
- struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS response;
-} __packed;
-
-/*
- * This comand can be used to read XAUI equalization parameters. The
- * ARM firmware applies default equalization parameters during initialization.
- * These parameters may be customer-specific when derived from the
- * SEEPROM. See SEEPROM_DATA for equalization specific fields.
- */
-struct FWCMD_COMMON_GET_PORT_EQUALIZATION {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_261_PARAMS params;
-} __packed;
-
-struct FWCMD_COMMON_ANON_264_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_COMMON_ANON_263_PARAMS {
- struct FWCMD_COMMON_PORT_EQUALIZATION_PARAMS request;
- struct FWCMD_COMMON_ANON_264_RESPONSE response;
-} __packed;
-
-/*
- * This comand can be used to set XAUI equalization parameters. The ARM
- * firmware applies default equalization parameters during initialization.
- * These parameters may be customer-specific when derived from the
- * SEEPROM. See SEEPROM_DATA for equalization specific fields.
- */
-struct FWCMD_COMMON_SET_PORT_EQUALIZATION {
- union FWCMD_HEADER header;
- union FWCMD_COMMON_ANON_263_PARAMS params;
-} __packed;
-
-#endif /* __fwcmd_common_bmap_h__ */
diff --git a/drivers/staging/benet/fwcmd_eth_bmap.h b/drivers/staging/benet/fwcmd_eth_bmap.h
deleted file mode 100644
index 234b179eace6..000000000000
--- a/drivers/staging/benet/fwcmd_eth_bmap.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_eth_bmap_h__
-#define __fwcmd_eth_bmap_h__
-#include "fwcmd_hdr_bmap.h"
-#include "fwcmd_types_bmap.h"
-
-struct MIB_ETH_STATISTICS_PARAMS_IN {
- u32 rsvd0;
-} __packed;
-
-struct BE_RXF_STATS {
- u32 p0recvdtotalbytesLSD; /* DWORD 0 */
- u32 p0recvdtotalbytesMSD; /* DWORD 1 */
- u32 p0recvdtotalframes; /* DWORD 2 */
- u32 p0recvdunicastframes; /* DWORD 3 */
- u32 p0recvdmulticastframes; /* DWORD 4 */
- u32 p0recvdbroadcastframes; /* DWORD 5 */
- u32 p0crcerrors; /* DWORD 6 */
- u32 p0alignmentsymerrs; /* DWORD 7 */
- u32 p0pauseframesrecvd; /* DWORD 8 */
- u32 p0controlframesrecvd; /* DWORD 9 */
- u32 p0inrangelenerrors; /* DWORD 10 */
- u32 p0outrangeerrors; /* DWORD 11 */
- u32 p0frametoolongerrors; /* DWORD 12 */
- u32 p0droppedaddressmatch; /* DWORD 13 */
- u32 p0droppedvlanmismatch; /* DWORD 14 */
- u32 p0ipdroppedtoosmall; /* DWORD 15 */
- u32 p0ipdroppedtooshort; /* DWORD 16 */
- u32 p0ipdroppedhdrtoosmall; /* DWORD 17 */
- u32 p0tcpdroppedlen; /* DWORD 18 */
- u32 p0droppedrunt; /* DWORD 19 */
- u32 p0recvd64; /* DWORD 20 */
- u32 p0recvd65_127; /* DWORD 21 */
- u32 p0recvd128_256; /* DWORD 22 */
- u32 p0recvd256_511; /* DWORD 23 */
- u32 p0recvd512_1023; /* DWORD 24 */
- u32 p0recvd1518_1522; /* DWORD 25 */
- u32 p0recvd1522_2047; /* DWORD 26 */
- u32 p0recvd2048_4095; /* DWORD 27 */
- u32 p0recvd4096_8191; /* DWORD 28 */
- u32 p0recvd8192_9216; /* DWORD 29 */
- u32 p0rcvdipcksmerrs; /* DWORD 30 */
- u32 p0recvdtcpcksmerrs; /* DWORD 31 */
- u32 p0recvdudpcksmerrs; /* DWORD 32 */
- u32 p0recvdnonrsspackets; /* DWORD 33 */
- u32 p0recvdippackets; /* DWORD 34 */
- u32 p0recvdchute1packets; /* DWORD 35 */
- u32 p0recvdchute2packets; /* DWORD 36 */
- u32 p0recvdchute3packets; /* DWORD 37 */
- u32 p0recvdipsecpackets; /* DWORD 38 */
- u32 p0recvdmanagementpackets; /* DWORD 39 */
- u32 p0xmitbyteslsd; /* DWORD 40 */
- u32 p0xmitbytesmsd; /* DWORD 41 */
- u32 p0xmitunicastframes; /* DWORD 42 */
- u32 p0xmitmulticastframes; /* DWORD 43 */
- u32 p0xmitbroadcastframes; /* DWORD 44 */
- u32 p0xmitpauseframes; /* DWORD 45 */
- u32 p0xmitcontrolframes; /* DWORD 46 */
- u32 p0xmit64; /* DWORD 47 */
- u32 p0xmit65_127; /* DWORD 48 */
- u32 p0xmit128_256; /* DWORD 49 */
- u32 p0xmit256_511; /* DWORD 50 */
- u32 p0xmit512_1023; /* DWORD 51 */
- u32 p0xmit1518_1522; /* DWORD 52 */
- u32 p0xmit1522_2047; /* DWORD 53 */
- u32 p0xmit2048_4095; /* DWORD 54 */
- u32 p0xmit4096_8191; /* DWORD 55 */
- u32 p0xmit8192_9216; /* DWORD 56 */
- u32 p0rxfifooverflowdropped; /* DWORD 57 */
- u32 p0ipseclookupfaileddropped; /* DWORD 58 */
- u32 p1recvdtotalbytesLSD; /* DWORD 59 */
- u32 p1recvdtotalbytesMSD; /* DWORD 60 */
- u32 p1recvdtotalframes; /* DWORD 61 */
- u32 p1recvdunicastframes; /* DWORD 62 */
- u32 p1recvdmulticastframes; /* DWORD 63 */
- u32 p1recvdbroadcastframes; /* DWORD 64 */
- u32 p1crcerrors; /* DWORD 65 */
- u32 p1alignmentsymerrs; /* DWORD 66 */
- u32 p1pauseframesrecvd; /* DWORD 67 */
- u32 p1controlframesrecvd; /* DWORD 68 */
- u32 p1inrangelenerrors; /* DWORD 69 */
- u32 p1outrangeerrors; /* DWORD 70 */
- u32 p1frametoolongerrors; /* DWORD 71 */
- u32 p1droppedaddressmatch; /* DWORD 72 */
- u32 p1droppedvlanmismatch; /* DWORD 73 */
- u32 p1ipdroppedtoosmall; /* DWORD 74 */
- u32 p1ipdroppedtooshort; /* DWORD 75 */
- u32 p1ipdroppedhdrtoosmall; /* DWORD 76 */
- u32 p1tcpdroppedlen; /* DWORD 77 */
- u32 p1droppedrunt; /* DWORD 78 */
- u32 p1recvd64; /* DWORD 79 */
- u32 p1recvd65_127; /* DWORD 80 */
- u32 p1recvd128_256; /* DWORD 81 */
- u32 p1recvd256_511; /* DWORD 82 */
- u32 p1recvd512_1023; /* DWORD 83 */
- u32 p1recvd1518_1522; /* DWORD 84 */
- u32 p1recvd1522_2047; /* DWORD 85 */
- u32 p1recvd2048_4095; /* DWORD 86 */
- u32 p1recvd4096_8191; /* DWORD 87 */
- u32 p1recvd8192_9216; /* DWORD 88 */
- u32 p1rcvdipcksmerrs; /* DWORD 89 */
- u32 p1recvdtcpcksmerrs; /* DWORD 90 */
- u32 p1recvdudpcksmerrs; /* DWORD 91 */
- u32 p1recvdnonrsspackets; /* DWORD 92 */
- u32 p1recvdippackets; /* DWORD 93 */
- u32 p1recvdchute1packets; /* DWORD 94 */
- u32 p1recvdchute2packets; /* DWORD 95 */
- u32 p1recvdchute3packets; /* DWORD 96 */
- u32 p1recvdipsecpackets; /* DWORD 97 */
- u32 p1recvdmanagementpackets; /* DWORD 98 */
- u32 p1xmitbyteslsd; /* DWORD 99 */
- u32 p1xmitbytesmsd; /* DWORD 100 */
- u32 p1xmitunicastframes; /* DWORD 101 */
- u32 p1xmitmulticastframes; /* DWORD 102 */
- u32 p1xmitbroadcastframes; /* DWORD 103 */
- u32 p1xmitpauseframes; /* DWORD 104 */
- u32 p1xmitcontrolframes; /* DWORD 105 */
- u32 p1xmit64; /* DWORD 106 */
- u32 p1xmit65_127; /* DWORD 107 */
- u32 p1xmit128_256; /* DWORD 108 */
- u32 p1xmit256_511; /* DWORD 109 */
- u32 p1xmit512_1023; /* DWORD 110 */
- u32 p1xmit1518_1522; /* DWORD 111 */
- u32 p1xmit1522_2047; /* DWORD 112 */
- u32 p1xmit2048_4095; /* DWORD 113 */
- u32 p1xmit4096_8191; /* DWORD 114 */
- u32 p1xmit8192_9216; /* DWORD 115 */
- u32 p1rxfifooverflowdropped; /* DWORD 116 */
- u32 p1ipseclookupfaileddropped; /* DWORD 117 */
- u32 pxdroppednopbuf; /* DWORD 118 */
- u32 pxdroppednotxpb; /* DWORD 119 */
- u32 pxdroppednoipsecbuf; /* DWORD 120 */
- u32 pxdroppednoerxdescr; /* DWORD 121 */
- u32 pxdroppednotpredescr; /* DWORD 122 */
- u32 pxrecvdmanagementportpackets; /* DWORD 123 */
- u32 pxrecvdmanagementportbytes; /* DWORD 124 */
- u32 pxrecvdmanagementportpauseframes; /* DWORD 125 */
- u32 pxrecvdmanagementporterrors; /* DWORD 126 */
- u32 pxxmitmanagementportpackets; /* DWORD 127 */
- u32 pxxmitmanagementportbytes; /* DWORD 128 */
- u32 pxxmitmanagementportpause; /* DWORD 129 */
- u32 pxxmitmanagementportrxfifooverflow; /* DWORD 130 */
- u32 pxrecvdipsecipcksmerrs; /* DWORD 131 */
- u32 pxrecvdtcpsecipcksmerrs; /* DWORD 132 */
- u32 pxrecvdudpsecipcksmerrs; /* DWORD 133 */
- u32 pxipsecrunt; /* DWORD 134 */
- u32 pxipsecaddressmismatchdropped; /* DWORD 135 */
- u32 pxipsecrxfifooverflowdropped; /* DWORD 136 */
- u32 pxipsecframestoolong; /* DWORD 137 */
- u32 pxipsectotalipframes; /* DWORD 138 */
- u32 pxipseciptoosmall; /* DWORD 139 */
- u32 pxipseciptooshort; /* DWORD 140 */
- u32 pxipseciphdrtoosmall; /* DWORD 141 */
- u32 pxipsectcphdrbad; /* DWORD 142 */
- u32 pxrecvdipsecchute1; /* DWORD 143 */
- u32 pxrecvdipsecchute2; /* DWORD 144 */
- u32 pxrecvdipsecchute3; /* DWORD 145 */
- u32 pxdropped7frags; /* DWORD 146 */
- u32 pxdroppedfrags; /* DWORD 147 */
- u32 pxdroppedinvalidfragring; /* DWORD 148 */
- u32 pxnumforwardedpackets; /* DWORD 149 */
-} __packed;
-
-union MIB_ETH_STATISTICS_PARAMS {
- struct MIB_ETH_STATISTICS_PARAMS_IN request;
- struct BE_RXF_STATS response;
-} __packed;
-
-/*
- * Query ethernet statistics. All domains may issue this command. The
- * host domain drivers may optionally reset internal statistic counters
- * with a query.
- */
-struct FWCMD_ETH_GET_STATISTICS {
- union FWCMD_HEADER header;
- union MIB_ETH_STATISTICS_PARAMS params;
-} __packed;
-
-
-struct FWCMD_ETH_ANON_175_REQUEST {
- u8 port0_promiscuous;
- u8 port1_promiscuous;
- u16 rsvd0;
-} __packed;
-
-struct FWCMD_ETH_ANON_176_RESPONSE {
- u32 rsvd0;
-} __packed;
-
-union FWCMD_ETH_ANON_174_PARAMS {
- struct FWCMD_ETH_ANON_175_REQUEST request;
- struct FWCMD_ETH_ANON_176_RESPONSE response;
-} __packed;
-
-/* Enables/Disables promiscuous ethernet receive mode. */
-struct FWCMD_ETH_PROMISCUOUS {
- union FWCMD_HEADER header;
- union FWCMD_ETH_ANON_174_PARAMS params;
-} __packed;
-
-struct FWCMD_ETH_ANON_178_REQUEST {
- u32 new_fragsize_log2;
-} __packed;
-
-struct FWCMD_ETH_ANON_179_RESPONSE {
- u32 actual_fragsize_log2;
-} __packed;
-
-union FWCMD_ETH_ANON_177_PARAMS {
- struct FWCMD_ETH_ANON_178_REQUEST request;
- struct FWCMD_ETH_ANON_179_RESPONSE response;
-} __packed;
-
-/*
- * Sets the Ethernet RX fragment size. Only host (domain 0) networking
- * drivers may issue this command. This call will fail for non-host
- * protection domains. In this situation the MCC CQ status will indicate
- * a failure due to insufficient priviledges. The response should be
- * ignored, and the driver should use the FWCMD_ETH_GET_FRAG_SIZE to
- * query the existing ethernet receive fragment size. It must use this
- * fragment size for all fragments in the ethernet receive ring. If
- * the command succeeds, the driver must use the frag size indicated
- * in the command response since the requested frag size may not be applied
- * until the next reboot. When the requested fragsize matches the response
- * fragsize, this indicates the request was applied immediately.
- */
-struct FWCMD_ETH_SET_RX_FRAG_SIZE {
- union FWCMD_HEADER header;
- union FWCMD_ETH_ANON_177_PARAMS params;
-} __packed;
-
-struct FWCMD_ETH_ANON_181_REQUEST {
- u32 rsvd0;
-} __packed;
-
-struct FWCMD_ETH_ANON_182_RESPONSE {
- u32 actual_fragsize_log2;
-} __packed;
-
-union FWCMD_ETH_ANON_180_PARAMS {
- struct FWCMD_ETH_ANON_181_REQUEST request;
- struct FWCMD_ETH_ANON_182_RESPONSE response;
-} __packed;
-
-/*
- * Queries the Ethernet RX fragment size. All domains may issue this
- * command. The driver should call this command to determine the minimum
- * required fragment size for the ethernet RX ring buffers. Drivers
- * may choose to use a larger size for each fragment buffer, but BladeEngine
- * will use up to the configured minimum required fragsize in each ethernet
- * receive fragment buffer. For example, if the ethernet receive fragment
- * size is configured to 4kB, and a driver uses 8kB fragments, a 6kB
- * ethernet packet received by BladeEngine will be split accross two
- * of the driver's receive framgents (4kB in one fragment buffer, and
- * 2kB in the subsequent fragment buffer).
- */
-struct FWCMD_ETH_GET_RX_FRAG_SIZE {
- union FWCMD_HEADER header;
- union FWCMD_ETH_ANON_180_PARAMS params;
-} __packed;
-
-#endif /* __fwcmd_eth_bmap_h__ */
diff --git a/drivers/staging/benet/fwcmd_hdr_bmap.h b/drivers/staging/benet/fwcmd_hdr_bmap.h
deleted file mode 100644
index 28b45328fe7b..000000000000
--- a/drivers/staging/benet/fwcmd_hdr_bmap.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_hdr_bmap_h__
-#define __fwcmd_hdr_bmap_h__
-
-struct FWCMD_REQUEST_HEADER {
- u8 opcode;
- u8 subsystem;
- u8 port_number;
- u8 domain;
- u32 timeout;
- u32 request_length;
- u32 rsvd0;
-} __packed;
-
-struct FWCMD_RESPONSE_HEADER {
- u8 opcode;
- u8 subsystem;
- u8 rsvd0;
- u8 domain;
- u8 status;
- u8 additional_status;
- u16 rsvd1;
- u32 response_length;
- u32 actual_response_length;
-} __packed;
-
-/*
- * The firmware/driver overwrites the input FWCMD_REQUEST_HEADER with
- * the output FWCMD_RESPONSE_HEADER.
- */
-union FWCMD_HEADER {
- struct FWCMD_REQUEST_HEADER request;
- struct FWCMD_RESPONSE_HEADER response;
-} __packed;
-
-#endif /* __fwcmd_hdr_bmap_h__ */
diff --git a/drivers/staging/benet/fwcmd_mcc.h b/drivers/staging/benet/fwcmd_mcc.h
deleted file mode 100644
index 9eeca878c1fb..000000000000
--- a/drivers/staging/benet/fwcmd_mcc.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_mcc_amap_h__
-#define __fwcmd_mcc_amap_h__
-#include "fwcmd_opcodes.h"
-/*
- * Where applicable, a WRB, may contain a list of Scatter-gather elements.
- * Each element supports a 64 bit address and a 32bit length field.
- */
-struct BE_MCC_SGE_AMAP {
- u8 pa_lo[32]; /* DWORD 0 */
- u8 pa_hi[32]; /* DWORD 1 */
- u8 length[32]; /* DWORD 2 */
-} __packed;
-struct MCC_SGE_AMAP {
- u32 dw[3];
-};
-/*
- * The design of an MCC_SGE allows up to 19 elements to be embedded
- * in a WRB, supporting 64KB data transfers (assuming a 4KB page size).
- */
-struct BE_MCC_WRB_PAYLOAD_AMAP {
- union {
- struct BE_MCC_SGE_AMAP sgl[19];
- u8 embedded[59][32]; /* DWORD 0 */
- };
-} __packed;
-struct MCC_WRB_PAYLOAD_AMAP {
- u32 dw[59];
-};
-
-/*
- * This is the structure of the MCC Command WRB for commands
- * sent to the Management Processing Unit (MPU). See section
- * for usage in embedded and non-embedded modes.
- */
-struct BE_MCC_WRB_AMAP {
- u8 embedded; /* DWORD 0 */
- u8 rsvd0[2]; /* DWORD 0 */
- u8 sge_count[5]; /* DWORD 0 */
- u8 rsvd1[16]; /* DWORD 0 */
- u8 special[8]; /* DWORD 0 */
- u8 payload_length[32]; /* DWORD 1 */
- u8 tag[2][32]; /* DWORD 2 */
- u8 rsvd2[32]; /* DWORD 4 */
- struct BE_MCC_WRB_PAYLOAD_AMAP payload;
-} __packed;
-struct MCC_WRB_AMAP {
- u32 dw[64];
-};
-
-/* This is the structure of the MCC Completion queue entry */
-struct BE_MCC_CQ_ENTRY_AMAP {
- u8 completion_status[16]; /* DWORD 0 */
- u8 extended_status[16]; /* DWORD 0 */
- u8 mcc_tag[2][32]; /* DWORD 1 */
- u8 rsvd0[27]; /* DWORD 3 */
- u8 consumed; /* DWORD 3 */
- u8 completed; /* DWORD 3 */
- u8 hpi_buffer_completion; /* DWORD 3 */
- u8 async_event; /* DWORD 3 */
- u8 valid; /* DWORD 3 */
-} __packed;
-struct MCC_CQ_ENTRY_AMAP {
- u32 dw[4];
-};
-
-/* Mailbox structures used by the MPU during bootstrap */
-struct BE_MCC_MAILBOX_AMAP {
- struct BE_MCC_WRB_AMAP wrb;
- struct BE_MCC_CQ_ENTRY_AMAP cq;
-} __packed;
-struct MCC_MAILBOX_AMAP {
- u32 dw[68];
-};
-
-#endif /* __fwcmd_mcc_amap_h__ */
diff --git a/drivers/staging/benet/fwcmd_opcodes.h b/drivers/staging/benet/fwcmd_opcodes.h
deleted file mode 100644
index 23d569386b46..000000000000
--- a/drivers/staging/benet/fwcmd_opcodes.h
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_opcodes_amap_h__
-#define __fwcmd_opcodes_amap_h__
-
-/*
- * --- FWCMD_SUBSYSTEMS ---
- * The commands are grouped into the following subsystems. The subsystem
- * code along with the opcode uniquely identify a particular fwcmd.
- */
-#define FWCMD_SUBSYSTEM_RSVD (0) /* This subsystem is reserved. It is */
- /* never used. */
-#define FWCMD_SUBSYSTEM_COMMON (1) /* CMDs in this group are common to
- * all subsystems. See
- * COMMON_SUBSYSTEM_OPCODES for opcodes
- * and Common Host Configuration CMDs
- * for the FWCMD descriptions.
- */
-#define FWCMD_SUBSYSTEM_COMMON_ISCSI (2) /* CMDs in this group are */
- /*
- * common to Initiator and Target. See
- * COMMON_ISCSI_SUBSYSTEM_OPCODES and
- * Common iSCSI Initiator and Target
- * CMDs for the command descriptions.
- */
-#define FWCMD_SUBSYSTEM_ETH (3) /* This subsystem is used to
- execute Ethernet commands. */
-
-#define FWCMD_SUBSYSTEM_TPM (4) /* This subsystem is used
- to execute TPM commands. */
-#define FWCMD_SUBSYSTEM_PXE_UNDI (5) /* This subsystem is used
- * to execute PXE
- * and UNDI specific commands.
- */
-
-#define FWCMD_SUBSYSTEM_ISCSI_INI (6) /* This subsystem is used to
- execute ISCSI Initiator
- specific commands.
- */
-#define FWCMD_SUBSYSTEM_ISCSI_TGT (7) /* This subsystem is used
- to execute iSCSI Target
- specific commands.between
- PTL and ARM firmware.
- */
-#define FWCMD_SUBSYSTEM_MILI_PTL (8) /* This subsystem is used to
- execute iSCSI Target specific
- commands.between MILI
- and PTL. */
-#define FWCMD_SUBSYSTEM_MILI_TMD (9) /* This subsystem is used to
- execute iSCSI Target specific
- commands between MILI
- and TMD. */
-#define FWCMD_SUBSYSTEM_PROXY (11) /* This subsystem is used
- to execute proxied commands
- within the host at the
- explicit request of a
- non priviledged domain.
- This 'subsystem' is entirely
- virtual from the controller
- and firmware perspective as
- it is implemented in host
- drivers.
- */
-
-/*
- * --- COMMON_SUBSYSTEM_OPCODES ---
- * These opcodes are common to both networking and storage PCI
- * functions. They are used to reserve resources and configure
- * BladeEngine. These opcodes all use the FWCMD_SUBSYSTEM_COMMON
- * subsystem code.
- */
-#define OPCODE_COMMON_NTWK_MAC_QUERY (1)
-#define SUBSYSTEM_COMMON_NTWK_MAC_QUERY (1)
-#define SUBSYSTEM_COMMON_NTWK_MAC_SET (1)
-#define SUBSYSTEM_COMMON_NTWK_MULTICAST_SET (1)
-#define SUBSYSTEM_COMMON_NTWK_VLAN_CONFIG (1)
-#define SUBSYSTEM_COMMON_NTWK_LINK_STATUS_QUERY (1)
-#define SUBSYSTEM_COMMON_READ_FLASHROM (1)
-#define SUBSYSTEM_COMMON_WRITE_FLASHROM (1)
-#define SUBSYSTEM_COMMON_QUERY_MAX_FWCMD_BUFFER_SIZE (1)
-#define SUBSYSTEM_COMMON_ADD_PAGE_TABLES (1)
-#define SUBSYSTEM_COMMON_REMOVE_PAGE_TABLES (1)
-#define SUBSYSTEM_COMMON_RING_DESTROY (1)
-#define SUBSYSTEM_COMMON_CQ_CREATE (1)
-#define SUBSYSTEM_COMMON_EQ_CREATE (1)
-#define SUBSYSTEM_COMMON_ETH_RX_CREATE (1)
-#define SUBSYSTEM_COMMON_ETH_TX_CREATE (1)
-#define SUBSYSTEM_COMMON_ISCSI_DEFQ_CREATE (1)
-#define SUBSYSTEM_COMMON_ISCSI_WRBQ_CREATE (1)
-#define SUBSYSTEM_COMMON_MCC_CREATE (1)
-#define SUBSYSTEM_COMMON_JELL_CONFIG (1)
-#define SUBSYSTEM_COMMON_FORCE_FAILOVER (1)
-#define SUBSYSTEM_COMMON_ADD_TEMPLATE_HEADER_BUFFERS (1)
-#define SUBSYSTEM_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS (1)
-#define SUBSYSTEM_COMMON_POST_ZERO_BUFFER (1)
-#define SUBSYSTEM_COMMON_GET_QOS (1)
-#define SUBSYSTEM_COMMON_SET_QOS (1)
-#define SUBSYSTEM_COMMON_TCP_GET_STATISTICS (1)
-#define SUBSYSTEM_COMMON_SEEPROM_READ (1)
-#define SUBSYSTEM_COMMON_TCP_STATE_QUERY (1)
-#define SUBSYSTEM_COMMON_GET_CNTL_ATTRIBUTES (1)
-#define SUBSYSTEM_COMMON_NOP (1)
-#define SUBSYSTEM_COMMON_NTWK_RX_FILTER (1)
-#define SUBSYSTEM_COMMON_GET_FW_VERSION (1)
-#define SUBSYSTEM_COMMON_SET_FLOW_CONTROL (1)
-#define SUBSYSTEM_COMMON_GET_FLOW_CONTROL (1)
-#define SUBSYSTEM_COMMON_SET_TCP_PARAMETERS (1)
-#define SUBSYSTEM_COMMON_SET_FRAME_SIZE (1)
-#define SUBSYSTEM_COMMON_GET_FAT (1)
-#define SUBSYSTEM_COMMON_MODIFY_EQ_DELAY (1)
-#define SUBSYSTEM_COMMON_FIRMWARE_CONFIG (1)
-#define SUBSYSTEM_COMMON_ENABLE_DISABLE_DOMAINS (1)
-#define SUBSYSTEM_COMMON_GET_DOMAIN_CONFIG (1)
-#define SUBSYSTEM_COMMON_SET_VLD_CONFIG (1)
-#define SUBSYSTEM_COMMON_GET_VLD_CONFIG (1)
-#define SUBSYSTEM_COMMON_GET_PORT_EQUALIZATION (1)
-#define SUBSYSTEM_COMMON_SET_PORT_EQUALIZATION (1)
-#define SUBSYSTEM_COMMON_RED_CONFIG (1)
-#define OPCODE_COMMON_NTWK_MAC_SET (2)
-#define OPCODE_COMMON_NTWK_MULTICAST_SET (3)
-#define OPCODE_COMMON_NTWK_VLAN_CONFIG (4)
-#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY (5)
-#define OPCODE_COMMON_READ_FLASHROM (6)
-#define OPCODE_COMMON_WRITE_FLASHROM (7)
-#define OPCODE_COMMON_QUERY_MAX_FWCMD_BUFFER_SIZE (8)
-#define OPCODE_COMMON_ADD_PAGE_TABLES (9)
-#define OPCODE_COMMON_REMOVE_PAGE_TABLES (10)
-#define OPCODE_COMMON_RING_DESTROY (11)
-#define OPCODE_COMMON_CQ_CREATE (12)
-#define OPCODE_COMMON_EQ_CREATE (13)
-#define OPCODE_COMMON_ETH_RX_CREATE (14)
-#define OPCODE_COMMON_ETH_TX_CREATE (15)
-#define OPCODE_COMMON_NET_RESERVED0 (16) /* Reserved */
-#define OPCODE_COMMON_NET_RESERVED1 (17) /* Reserved */
-#define OPCODE_COMMON_NET_RESERVED2 (18) /* Reserved */
-#define OPCODE_COMMON_ISCSI_DEFQ_CREATE (19)
-#define OPCODE_COMMON_ISCSI_WRBQ_CREATE (20)
-#define OPCODE_COMMON_MCC_CREATE (21)
-#define OPCODE_COMMON_JELL_CONFIG (22)
-#define OPCODE_COMMON_FORCE_FAILOVER (23)
-#define OPCODE_COMMON_ADD_TEMPLATE_HEADER_BUFFERS (24)
-#define OPCODE_COMMON_REMOVE_TEMPLATE_HEADER_BUFFERS (25)
-#define OPCODE_COMMON_POST_ZERO_BUFFER (26)
-#define OPCODE_COMMON_GET_QOS (27)
-#define OPCODE_COMMON_SET_QOS (28)
-#define OPCODE_COMMON_TCP_GET_STATISTICS (29)
-#define OPCODE_COMMON_SEEPROM_READ (30)
-#define OPCODE_COMMON_TCP_STATE_QUERY (31)
-#define OPCODE_COMMON_GET_CNTL_ATTRIBUTES (32)
-#define OPCODE_COMMON_NOP (33)
-#define OPCODE_COMMON_NTWK_RX_FILTER (34)
-#define OPCODE_COMMON_GET_FW_VERSION (35)
-#define OPCODE_COMMON_SET_FLOW_CONTROL (36)
-#define OPCODE_COMMON_GET_FLOW_CONTROL (37)
-#define OPCODE_COMMON_SET_TCP_PARAMETERS (38)
-#define OPCODE_COMMON_SET_FRAME_SIZE (39)
-#define OPCODE_COMMON_GET_FAT (40)
-#define OPCODE_COMMON_MODIFY_EQ_DELAY (41)
-#define OPCODE_COMMON_FIRMWARE_CONFIG (42)
-#define OPCODE_COMMON_ENABLE_DISABLE_DOMAINS (43)
-#define OPCODE_COMMON_GET_DOMAIN_CONFIG (44)
-#define OPCODE_COMMON_SET_VLD_CONFIG (45)
-#define OPCODE_COMMON_GET_VLD_CONFIG (46)
-#define OPCODE_COMMON_GET_PORT_EQUALIZATION (47)
-#define OPCODE_COMMON_SET_PORT_EQUALIZATION (48)
-#define OPCODE_COMMON_RED_CONFIG (49)
-
-
-
-/*
- * --- ETH_SUBSYSTEM_OPCODES ---
- * These opcodes are used for configuring the Ethernet interfaces. These
- * opcodes all use the FWCMD_SUBSYSTEM_ETH subsystem code.
- */
-#define OPCODE_ETH_RSS_CONFIG (1)
-#define OPCODE_ETH_ACPI_CONFIG (2)
-#define SUBSYSTEM_ETH_RSS_CONFIG (3)
-#define SUBSYSTEM_ETH_ACPI_CONFIG (3)
-#define OPCODE_ETH_PROMISCUOUS (3)
-#define SUBSYSTEM_ETH_PROMISCUOUS (3)
-#define SUBSYSTEM_ETH_GET_STATISTICS (3)
-#define SUBSYSTEM_ETH_GET_RX_FRAG_SIZE (3)
-#define SUBSYSTEM_ETH_SET_RX_FRAG_SIZE (3)
-#define OPCODE_ETH_GET_STATISTICS (4)
-#define OPCODE_ETH_GET_RX_FRAG_SIZE (5)
-#define OPCODE_ETH_SET_RX_FRAG_SIZE (6)
-
-
-
-
-
-/*
- * --- MCC_STATUS_CODE ---
- * These are the global status codes used by all subsystems
- */
-#define MCC_STATUS_SUCCESS (0) /* Indicates a successful
- completion of the command */
-#define MCC_STATUS_INSUFFICIENT_PRIVILEGES (1) /* The client does not have
- sufficient privileges to
- execute the command */
-#define MCC_STATUS_INVALID_PARAMETER (2) /* A parameter in the command
- was invalid. The extended
- status contains the index
- of the parameter */
-#define MCC_STATUS_INSUFFICIENT_RESOURCES (3) /* There are insufficient
- chip resources to execute
- the command */
-#define MCC_STATUS_QUEUE_FLUSHING (4) /* The command is completing
- because the queue was
- getting flushed */
-#define MCC_STATUS_DMA_FAILED (5) /* The command is completing
- with a DMA error */
-
-/*
- * --- MGMT_ERROR_CODES ---
- * Error Codes returned in the status field of the FWCMD response header
- */
-#define MGMT_STATUS_SUCCESS (0) /* The FWCMD completed
- without errors */
-#define MGMT_STATUS_FAILED (1) /* Error status in the Status
- field of the
- struct FWCMD_RESPONSE_HEADER */
-#define MGMT_STATUS_ILLEGAL_REQUEST (2) /* Invalid FWCMD opcode */
-#define MGMT_STATUS_ILLEGAL_FIELD (3) /* Invalid parameter in
- the FWCMD payload */
-
-#endif /* __fwcmd_opcodes_amap_h__ */
diff --git a/drivers/staging/benet/fwcmd_types_bmap.h b/drivers/staging/benet/fwcmd_types_bmap.h
deleted file mode 100644
index 92217aff3a16..000000000000
--- a/drivers/staging/benet/fwcmd_types_bmap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __fwcmd_types_bmap_h__
-#define __fwcmd_types_bmap_h__
-
-/* MAC address format */
-struct MAC_ADDRESS_FORMAT {
- u16 SizeOfStructure;
- u8 MACAddress[6];
-} __packed;
-
-#endif /* __fwcmd_types_bmap_h__ */
diff --git a/drivers/staging/benet/host_struct.h b/drivers/staging/benet/host_struct.h
deleted file mode 100644
index 3de6722b980f..000000000000
--- a/drivers/staging/benet/host_struct.h
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __host_struct_amap_h__
-#define __host_struct_amap_h__
-#include "be_cm.h"
-#include "be_common.h"
-#include "descriptors.h"
-
-/* --- EQ_COMPLETION_MAJOR_CODE_ENUM --- */
-#define EQ_MAJOR_CODE_COMPLETION (0) /* Completion event on a */
- /* qcompletion ueue. */
-#define EQ_MAJOR_CODE_ETH (1) /* Affiliated Ethernet Event. */
-#define EQ_MAJOR_CODE_RESERVED (2) /* Reserved */
-#define EQ_MAJOR_CODE_RDMA (3) /* Affiliated RDMA Event. */
-#define EQ_MAJOR_CODE_ISCSI (4) /* Affiliated ISCSI Event */
-#define EQ_MAJOR_CODE_UNAFFILIATED (5) /* Unaffiliated Event */
-
-/* --- EQ_COMPLETION_MINOR_CODE_ENUM --- */
-#define EQ_MINOR_CODE_COMPLETION (0) /* Completion event on a */
- /* completion queue. */
-#define EQ_MINOR_CODE_OTHER (1) /* Other Event (TBD). */
-
-/* Queue Entry Definition for all 4 byte event queue types. */
-struct BE_EQ_ENTRY_AMAP {
- u8 Valid; /* DWORD 0 */
- u8 MajorCode[3]; /* DWORD 0 */
- u8 MinorCode[12]; /* DWORD 0 */
- u8 ResourceID[16]; /* DWORD 0 */
-} __packed;
-struct EQ_ENTRY_AMAP {
- u32 dw[1];
-};
-
-/*
- * --- ETH_EVENT_CODE ---
- * These codes are returned by the MPU when one of these events has occurred,
- * and the event is configured to report to an Event Queue when an event
- * is detected.
- */
-#define ETH_EQ_LINK_STATUS (0) /* Link status change event */
- /* detected. */
-#define ETH_EQ_WATERMARK (1) /* watermark event detected. */
-#define ETH_EQ_MAGIC_PKT (2) /* magic pkt event detected. */
-#define ETH_EQ_ACPI_PKT0 (3) /* ACPI interesting packet */
- /* detected. */
-#define ETH_EQ_ACPI_PKT1 (3) /* ACPI interesting packet */
- /* detected. */
-#define ETH_EQ_ACPI_PKT2 (3) /* ACPI interesting packet */
- /* detected. */
-#define ETH_EQ_ACPI_PKT3 (3) /* ACPI interesting packet */
- /* detected. */
-
-/*
- * --- ETH_TX_COMPL_STATUS_ENUM ---
- * Status codes contained in Ethernet TX completion descriptors.
- */
-#define ETH_COMP_VALID (0)
-#define ETH_COMP_ERROR (1)
-#define ETH_COMP_INVALID (15)
-
-/*
- * --- ETH_TX_COMPL_PORT_ENUM ---
- * Port indicator contained in Ethernet TX completion descriptors.
- */
-#define ETH_COMP_PORT0 (0)
-#define ETH_COMP_PORT1 (1)
-#define ETH_COMP_MGMT (2)
-
-/*
- * --- ETH_TX_COMPL_CT_ENUM ---
- * Completion type indicator contained in Ethernet TX completion descriptors.
- */
-#define ETH_COMP_ETH (0)
-
-/*
- * Work request block that the driver issues to the chip for
- * Ethernet transmissions. All control fields must be valid in each WRB for
- * a message. The controller, as specified by the flags, optionally writes
- * an entry to the Completion Ring and generate an event.
- */
-struct BE_ETH_WRB_AMAP {
- u8 frag_pa_hi[32]; /* DWORD 0 */
- u8 frag_pa_lo[32]; /* DWORD 1 */
- u8 complete; /* DWORD 2 */
- u8 event; /* DWORD 2 */
- u8 crc; /* DWORD 2 */
- u8 forward; /* DWORD 2 */
- u8 ipsec; /* DWORD 2 */
- u8 mgmt; /* DWORD 2 */
- u8 ipcs; /* DWORD 2 */
- u8 udpcs; /* DWORD 2 */
- u8 tcpcs; /* DWORD 2 */
- u8 lso; /* DWORD 2 */
- u8 last; /* DWORD 2 */
- u8 vlan; /* DWORD 2 */
- u8 dbg[3]; /* DWORD 2 */
- u8 hash_val[3]; /* DWORD 2 */
- u8 lso_mss[14]; /* DWORD 2 */
- u8 frag_len[16]; /* DWORD 3 */
- u8 vlan_tag[16]; /* DWORD 3 */
-} __packed;
-struct ETH_WRB_AMAP {
- u32 dw[4];
-};
-
-/* This is an Ethernet transmit completion descriptor */
-struct BE_ETH_TX_COMPL_AMAP {
- u8 user_bytes[16]; /* DWORD 0 */
- u8 nwh_bytes[8]; /* DWORD 0 */
- u8 lso; /* DWORD 0 */
- u8 rsvd0[7]; /* DWORD 0 */
- u8 wrb_index[16]; /* DWORD 1 */
- u8 ct[2]; /* DWORD 1 */
- u8 port[2]; /* DWORD 1 */
- u8 rsvd1[8]; /* DWORD 1 */
- u8 status[4]; /* DWORD 1 */
- u8 rsvd2[16]; /* DWORD 2 */
- u8 ringid[11]; /* DWORD 2 */
- u8 hash_val[4]; /* DWORD 2 */
- u8 valid; /* DWORD 2 */
- u8 rsvd3[32]; /* DWORD 3 */
-} __packed;
-struct ETH_TX_COMPL_AMAP {
- u32 dw[4];
-};
-
-/* Ethernet Receive Buffer descriptor */
-struct BE_ETH_RX_D_AMAP {
- u8 fragpa_hi[32]; /* DWORD 0 */
- u8 fragpa_lo[32]; /* DWORD 1 */
-} __packed;
-struct ETH_RX_D_AMAP {
- u32 dw[2];
-};
-
-/* This is an Ethernet Receive Completion Descriptor */
-struct BE_ETH_RX_COMPL_AMAP {
- u8 vlan_tag[16]; /* DWORD 0 */
- u8 pktsize[14]; /* DWORD 0 */
- u8 port; /* DWORD 0 */
- u8 rsvd0; /* DWORD 0 */
- u8 err; /* DWORD 1 */
- u8 rsshp; /* DWORD 1 */
- u8 ipf; /* DWORD 1 */
- u8 tcpf; /* DWORD 1 */
- u8 udpf; /* DWORD 1 */
- u8 ipcksm; /* DWORD 1 */
- u8 tcpcksm; /* DWORD 1 */
- u8 udpcksm; /* DWORD 1 */
- u8 macdst[6]; /* DWORD 1 */
- u8 vtp; /* DWORD 1 */
- u8 vtm; /* DWORD 1 */
- u8 fragndx[10]; /* DWORD 1 */
- u8 ct[2]; /* DWORD 1 */
- u8 ipsec; /* DWORD 1 */
- u8 numfrags[3]; /* DWORD 1 */
- u8 rsvd1[31]; /* DWORD 2 */
- u8 valid; /* DWORD 2 */
- u8 rsshash[32]; /* DWORD 3 */
-} __packed;
-struct ETH_RX_COMPL_AMAP {
- u32 dw[4];
-};
-
-#endif /* __host_struct_amap_h__ */
diff --git a/drivers/staging/benet/hwlib.h b/drivers/staging/benet/hwlib.h
deleted file mode 100644
index afedf4dc5903..000000000000
--- a/drivers/staging/benet/hwlib.h
+++ /dev/null
@@ -1,830 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#ifndef __hwlib_h__
-#define __hwlib_h__
-
-#include <linux/module.h>
-#include <linux/io.h>
-#include <linux/list.h>
-#include <linux/spinlock.h>
-
-#include "regmap.h" /* srcgen array map output */
-
-#include "asyncmesg.h"
-#include "fwcmd_opcodes.h"
-#include "post_codes.h"
-#include "fwcmd_mcc.h"
-
-#include "fwcmd_types_bmap.h"
-#include "fwcmd_common_bmap.h"
-#include "fwcmd_eth_bmap.h"
-#include "bestatus.h"
-/*
- *
- * Macros for reading/writing a protection domain or CSR registers
- * in BladeEngine.
- */
-#define PD_READ(fo, field) ioread32((fo)->db_va + \
- offsetof(struct BE_PROTECTION_DOMAIN_DBMAP_AMAP, field)/8)
-
-#define PD_WRITE(fo, field, val) iowrite32(val, (fo)->db_va + \
- offsetof(struct BE_PROTECTION_DOMAIN_DBMAP_AMAP, field)/8)
-
-#define CSR_READ(fo, field) ioread32((fo)->csr_va + \
- offsetof(struct BE_BLADE_ENGINE_CSRMAP_AMAP, field)/8)
-
-#define CSR_WRITE(fo, field, val) iowrite32(val, (fo)->csr_va + \
- offsetof(struct BE_BLADE_ENGINE_CSRMAP_AMAP, field)/8)
-
-#define PCICFG0_READ(fo, field) ioread32((fo)->pci_va + \
- offsetof(struct BE_PCICFG0_CSRMAP_AMAP, field)/8)
-
-#define PCICFG0_WRITE(fo, field, val) iowrite32(val, (fo)->pci_va + \
- offsetof(struct BE_PCICFG0_CSRMAP_AMAP, field)/8)
-
-#define PCICFG1_READ(fo, field) ioread32((fo)->pci_va + \
- offsetof(struct BE_PCICFG1_CSRMAP_AMAP, field)/8)
-
-#define PCICFG1_WRITE(fo, field, val) iowrite32(val, (fo)->pci_va + \
- offsetof(struct BE_PCICFG1_CSRMAP_AMAP, field)/8)
-
-#ifdef BE_DEBUG
-#define ASSERT(c) BUG_ON(!(c));
-#else
-#define ASSERT(c)
-#endif
-
-/* debug levels */
-enum BE_DEBUG_LEVELS {
- DL_ALWAYS = 0, /* cannot be masked */
- DL_ERR = 0x1, /* errors that should never happen */
- DL_WARN = 0x2, /* something questionable.
- recoverable errors */
- DL_NOTE = 0x4, /* infrequent, important debug info */
- DL_INFO = 0x8, /* debug information */
- DL_VERBOSE = 0x10, /* detailed info, such as buffer traces */
- BE_DL_MIN_VALUE = 0x1, /* this is the min value used */
- BE_DL_MAX_VALUE = 0x80 /* this is the higheset value used */
-} ;
-
-extern unsigned int trace_level;
-
-#define TRACE(lm, fmt, args...) { \
- if (trace_level & lm) { \
- printk(KERN_NOTICE "BE: %s:%d \n" fmt, \
- __FILE__ , __LINE__ , ## args); \
- } \
- }
-
-static inline unsigned int be_trace_set_level(unsigned int level)
-{
- unsigned int old_level = trace_level;
- trace_level = level;
- return old_level;
-}
-
-#define be_trace_get_level() trace_level
-/*
- * Returns number of pages spanned by the size of data
- * starting at the given address.
- */
-#define PAGES_SPANNED(_address, _size) \
- ((u32)((((size_t)(_address) & (PAGE_SIZE - 1)) + \
- (_size) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
-/* Byte offset into the page corresponding to given address */
-#define OFFSET_IN_PAGE(_addr_) ((size_t)(_addr_) & (PAGE_SIZE-1))
-
-/*
- * circular subtract.
- * Returns a - b assuming a circular number system, where a and b are
- * in range (0, maxValue-1). If a==b, zero is returned so the
- * highest value possible with this subtraction is maxValue-1.
- */
-static inline u32 be_subc(u32 a, u32 b, u32 max)
-{
- ASSERT(a <= max && b <= max);
- ASSERT(max > 0);
- return a >= b ? (a - b) : (max - b + a);
-}
-
-static inline u32 be_addc(u32 a, u32 b, u32 max)
-{
- ASSERT(a < max);
- ASSERT(max > 0);
- return (max - a > b) ? (a + b) : (b + a - max);
-}
-
-/* descriptor for a physically contiguous memory used for ring */
-struct ring_desc {
- u32 length; /* length in bytes */
- void *va; /* virtual address */
- u64 pa; /* bus address */
-} ;
-
-/*
- * This structure stores information about a ring shared between hardware
- * and software. Each ring is allocated by the driver in the uncached
- * extension and mapped into BladeEngine's unified table.
- */
-struct mp_ring {
- u32 pages; /* queue size in pages */
- u32 id; /* queue id assigned by beklib */
- u32 num; /* number of elements in queue */
- u32 cidx; /* consumer index */
- u32 pidx; /* producer index -- not used by most rings */
- u32 itemSize; /* size in bytes of one object */
-
- void *va; /* The virtual address of the ring.
- This should be last to allow 32 & 64
- bit debugger extensions to work. */
-} ;
-
-/*----------- amap bit filed get / set macros and functions -----*/
-/*
- * Structures defined in the map header files (under fw/amap/) with names
- * in the format BE_<name>_AMAP are pseudo structures with members
- * of type u8. These structures are templates that are used in
- * conjuntion with the structures with names in the format
- * <name>_AMAP to calculate the bit masks and bit offsets to get or set
- * bit fields in structures. The structures <name>_AMAP are arrays
- * of 32 bits words and have the correct size. The following macros
- * provide convenient ways to get and set the various members
- * in the structures without using strucctures with bit fields.
- * Always use the macros AMAP_GET_BITS_PTR and AMAP_SET_BITS_PTR
- * macros to extract and set various members.
- */
-
-/*
- * Returns the a bit mask for the register that is NOT shifted into location.
- * That means return values always look like: 0x1, 0xFF, 0x7FF, etc...
- */
-static inline u32 amap_mask(u32 bit_size)
-{
- return bit_size == 32 ? 0xFFFFFFFF : (1 << bit_size) - 1;
-}
-
-#define AMAP_BIT_MASK(_struct_, field) \
- amap_mask(AMAP_BIT_SIZE(_struct_, field))
-
-/*
- * non-optimized set bits function. First clears the bits and then assigns them.
- * This does not require knowledge of the particular DWORD you are setting.
- * e.g. AMAP_SET_BITS_PTR (struct, field1, &contextMemory, 123);
- */
-static inline void
-amap_set(void *ptr, u32 dw_offset, u32 mask, u32 offset, u32 value)
-{
- u32 *dw = (u32 *)ptr;
- *(dw + dw_offset) &= ~(mask << offset);
- *(dw + dw_offset) |= (mask & value) << offset;
-}
-
-#define AMAP_SET_BITS_PTR(_struct_, field, _structPtr_, val) \
- amap_set(_structPtr_, AMAP_WORD_OFFSET(_struct_, field),\
- AMAP_BIT_MASK(_struct_, field), \
- AMAP_BIT_OFFSET(_struct_, field), val)
-/*
- * Non-optimized routine that gets the bits without knowing the correct DWORD.
- * e.g. fieldValue = AMAP_GET_BITS_PTR (struct, field1, &contextMemory);
- */
-static inline u32
-amap_get(void *ptr, u32 dw_offset, u32 mask, u32 offset)
-{
- u32 *dw = (u32 *)ptr;
- return mask & (*(dw + dw_offset) >> offset);
-}
-#define AMAP_GET_BITS_PTR(_struct_, field, _structPtr_) \
- amap_get(_structPtr_, AMAP_WORD_OFFSET(_struct_, field), \
- AMAP_BIT_MASK(_struct_, field), \
- AMAP_BIT_OFFSET(_struct_, field))
-
-/* Returns 0-31 representing bit offset within a DWORD of a bitfield. */
-#define AMAP_BIT_OFFSET(_struct_, field) \
- (offsetof(struct BE_ ## _struct_ ## _AMAP, field) % 32)
-
-/* Returns 0-n representing DWORD offset of bitfield within the structure. */
-#define AMAP_WORD_OFFSET(_struct_, field) \
- (offsetof(struct BE_ ## _struct_ ## _AMAP, field)/32)
-
-/* Returns size of bitfield in bits. */
-#define AMAP_BIT_SIZE(_struct_, field) \
- sizeof(((struct BE_ ## _struct_ ## _AMAP*)0)->field)
-
-struct be_mcc_wrb_response_copy {
- u16 length; /* bytes in response */
- u16 fwcmd_offset; /* offset within the wrb of the response */
- void *va; /* user's va to copy response into */
-
-} ;
-typedef void (*mcc_wrb_cqe_callback) (void *context, int status,
- struct MCC_WRB_AMAP *optional_wrb);
-struct be_mcc_wrb_context {
-
- mcc_wrb_cqe_callback internal_cb; /* Function to call on
- completion */
- void *internal_cb_context; /* Parameter to pass
- to completion function */
-
- mcc_wrb_cqe_callback cb; /* Function to call on completion */
- void *cb_context; /* Parameter to pass to completion function */
-
- int *users_final_status; /* pointer to a local
- variable for synchronous
- commands */
- struct MCC_WRB_AMAP *wrb; /* pointer to original wrb for embedded
- commands only */
- struct list_head next; /* links context structs together in
- free list */
-
- struct be_mcc_wrb_response_copy copy; /* Optional parameters to copy
- embedded response to user's va */
-
-#if defined(BE_DEBUG)
- u16 subsystem, opcode; /* Track this FWCMD for debug builds. */
- struct MCC_WRB_AMAP *ring_wrb;
- u32 consumed_count;
-#endif
-} ;
-
-/*
- Represents a function object for network or storage. This
- is used to manage per-function resources like MCC CQs, etc.
-*/
-struct be_function_object {
-
- u32 magic; /*!< magic for detecting memory corruption. */
-
- /* PCI BAR mapped addresses */
- u8 __iomem *csr_va; /* CSR */
- u8 __iomem *db_va; /* Door Bell */
- u8 __iomem *pci_va; /* PCI config space */
- u32 emulate; /* if set, MPU is not available.
- Emulate everything. */
- u32 pend_queue_driving; /* if set, drive the queued WRBs
- after releasing the WRB lock */
-
- spinlock_t post_lock; /* lock for verifying one thread posting wrbs */
- spinlock_t cq_lock; /* lock for verifying one thread
- processing cq */
- spinlock_t mcc_context_lock; /* lock for protecting mcc
- context free list */
- unsigned long post_irq;
- unsigned long cq_irq;
-
- u32 type;
- u32 pci_function_number;
-
- struct be_mcc_object *mcc; /* mcc rings. */
-
- struct {
- struct MCC_MAILBOX_AMAP *va; /* VA to the mailbox */
- u64 pa; /* PA to the mailbox */
- u32 length; /* byte length of mailbox */
-
- /* One default context struct used for posting at
- * least one MCC_WRB
- */
- struct be_mcc_wrb_context default_context;
- bool default_context_allocated;
- } mailbox;
-
- struct {
-
- /* Wake on lans configured. */
- u32 wol_bitmask; /* bits 0,1,2,3 are set if
- corresponding index is enabled */
- } config;
-
-
- struct BE_FIRMWARE_CONFIG fw_config;
-} ;
-
-/*
- Represents an Event Queue
-*/
-struct be_eq_object {
- u32 magic;
- atomic_t ref_count;
-
- struct be_function_object *parent_function;
-
- struct list_head eq_list;
- struct list_head cq_list_head;
-
- u32 eq_id;
- void *cb_context;
-
-} ;
-
-/*
- Manages a completion queue
-*/
-struct be_cq_object {
- u32 magic;
- atomic_t ref_count;
-
- struct be_function_object *parent_function;
- struct be_eq_object *eq_object;
-
- struct list_head cq_list;
- struct list_head cqlist_for_eq;
-
- void *va;
- u32 num_entries;
-
- void *cb_context;
-
- u32 cq_id;
-
-} ;
-
-/*
- Manages an ethernet send queue
-*/
-struct be_ethsq_object {
- u32 magic;
-
- struct list_head list;
-
- struct be_function_object *parent_function;
- struct be_cq_object *cq_object;
- u32 bid;
-
-} ;
-
-/*
-@brief
- Manages an ethernet receive queue
-*/
-struct be_ethrq_object {
- u32 magic;
- struct list_head list;
- struct be_function_object *parent_function;
- u32 rid;
- struct be_cq_object *cq_object;
- struct be_cq_object *rss_cq_object[4];
-
-} ;
-
-/*
- Manages an MCC
-*/
-typedef void (*mcc_async_event_callback) (void *context, u32 event_code,
- void *event);
-struct be_mcc_object {
- u32 magic;
-
- struct be_function_object *parent_function;
- struct list_head mcc_list;
-
- struct be_cq_object *cq_object;
-
- /* Async event callback for MCC CQ. */
- mcc_async_event_callback async_cb;
- void *async_context;
-
- struct {
- struct be_mcc_wrb_context *base;
- u32 num;
- struct list_head list_head;
- } wrb_context;
-
- struct {
- struct ring_desc *rd;
- struct mp_ring ring;
- } sq;
-
- struct {
- struct mp_ring ring;
- } cq;
-
- u32 processing; /* flag indicating that one thread
- is processing CQ */
- u32 rearm; /* doorbell rearm setting to make
- sure the active processing thread */
- /* rearms the CQ if any of the threads requested it. */
-
- struct list_head backlog;
- u32 backlog_length;
- u32 driving_backlog;
- u32 consumed_index;
-
-} ;
-
-
-/* Queue context header -- the required software information for
- * queueing a WRB.
- */
-struct be_queue_driver_context {
- mcc_wrb_cqe_callback internal_cb; /* Function to call on
- completion */
- void *internal_cb_context; /* Parameter to pass
- to completion function */
-
- mcc_wrb_cqe_callback cb; /* Function to call on completion */
- void *cb_context; /* Parameter to pass to completion function */
-
- struct be_mcc_wrb_response_copy copy; /* Optional parameters to copy
- embedded response to user's va */
- void *optional_fwcmd_va;
- struct list_head list;
- u32 bytes;
-} ;
-
-/*
- * Common MCC WRB header that all commands require.
- */
-struct be_mcc_wrb_header {
- u8 rsvd[offsetof(struct BE_MCC_WRB_AMAP, payload)/8];
-} ;
-
-/*
- * All non embedded commands supported by hwlib functions only allow
- * 1 SGE. This queue context handles them all.
- */
-struct be_nonembedded_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct MCC_SGE_AMAP sge[1];
-} ;
-
-/*
- * ------------------------------------------------------------------------
- * This section contains the specific queue struct for each command.
- * The user could always provide a be_generic_q_ctxt but this is a
- * rather large struct. By using the specific struct, memory consumption
- * can be reduced.
- * ------------------------------------------------------------------------
- */
-
-struct be_link_status_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_NTWK_LINK_STATUS_QUERY fwcmd;
-} ;
-
-struct be_multicast_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_NTWK_MULTICAST_SET fwcmd;
-} ;
-
-
-struct be_vlan_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_NTWK_VLAN_CONFIG fwcmd;
-} ;
-
-struct be_promiscuous_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_ETH_PROMISCUOUS fwcmd;
-} ;
-
-struct be_force_failover_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_FORCE_FAILOVER fwcmd;
-} ;
-
-
-struct be_rxf_filter_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_NTWK_RX_FILTER fwcmd;
-} ;
-
-struct be_eq_modify_delay_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct FWCMD_COMMON_MODIFY_EQ_DELAY fwcmd;
-} ;
-
-/*
- * The generic context is the largest size that would be required.
- * It is the software context plus an entire WRB.
- */
-struct be_generic_q_ctxt {
- struct be_queue_driver_context context;
- struct be_mcc_wrb_header wrb_header;
- struct MCC_WRB_PAYLOAD_AMAP payload;
-} ;
-
-/*
- * Types for the BE_QUEUE_CONTEXT object.
- */
-#define BE_QUEUE_INVALID (0)
-#define BE_QUEUE_LINK_STATUS (0xA006)
-#define BE_QUEUE_ETH_STATS (0xA007)
-#define BE_QUEUE_TPM_STATS (0xA008)
-#define BE_QUEUE_TCP_STATS (0xA009)
-#define BE_QUEUE_MULTICAST (0xA00A)
-#define BE_QUEUE_VLAN (0xA00B)
-#define BE_QUEUE_RSS (0xA00C)
-#define BE_QUEUE_FORCE_FAILOVER (0xA00D)
-#define BE_QUEUE_PROMISCUOUS (0xA00E)
-#define BE_QUEUE_WAKE_ON_LAN (0xA00F)
-#define BE_QUEUE_NOP (0xA010)
-
-/* --- BE_FUNCTION_ENUM --- */
-#define BE_FUNCTION_TYPE_ISCSI (0)
-#define BE_FUNCTION_TYPE_NETWORK (1)
-#define BE_FUNCTION_TYPE_ARM (2)
-
-/* --- BE_ETH_TX_RING_TYPE_ENUM --- */
-#define BE_ETH_TX_RING_TYPE_FORWARDING (1) /* Ether ring for forwarding */
-#define BE_ETH_TX_RING_TYPE_STANDARD (2) /* Ether ring for sending */
- /* network packets. */
-#define BE_ETH_TX_RING_TYPE_BOUND (3) /* Ethernet ring for sending */
- /* network packets, bound */
- /* to a physical port. */
-/*
- * ----------------------------------------------------------------------
- * API MACROS
- * ----------------------------------------------------------------------
- */
-#define BE_FWCMD_NAME(_short_name_) struct FWCMD_##_short_name_
-#define BE_OPCODE_NAME(_short_name_) OPCODE_##_short_name_
-#define BE_SUBSYSTEM_NAME(_short_name_) SUBSYSTEM_##_short_name_
-
-
-#define BE_PREPARE_EMBEDDED_FWCMD(_pfob_, _wrb_, _short_name_) \
- ((BE_FWCMD_NAME(_short_name_) *) \
- be_function_prepare_embedded_fwcmd(_pfob_, _wrb_, \
- sizeof(BE_FWCMD_NAME(_short_name_)), \
- FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.request), \
- FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.response), \
- BE_OPCODE_NAME(_short_name_), \
- BE_SUBSYSTEM_NAME(_short_name_)));
-
-#define BE_PREPARE_NONEMBEDDED_FWCMD(_pfob_, _wrb_, _iva_, _ipa_, _short_name_)\
- ((BE_FWCMD_NAME(_short_name_) *) \
- be_function_prepare_nonembedded_fwcmd(_pfob_, _wrb_, (_iva_), (_ipa_), \
- sizeof(BE_FWCMD_NAME(_short_name_)), \
- FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.request), \
- FIELD_SIZEOF(BE_FWCMD_NAME(_short_name_), params.response), \
- BE_OPCODE_NAME(_short_name_), \
- BE_SUBSYSTEM_NAME(_short_name_)));
-
-int be_function_object_create(u8 __iomem *csr_va, u8 __iomem *db_va,
- u8 __iomem *pci_va, u32 function_type, struct ring_desc *mailbox_rd,
- struct be_function_object *pfob);
-
-int be_function_object_destroy(struct be_function_object *pfob);
-int be_function_cleanup(struct be_function_object *pfob);
-
-
-int be_function_get_fw_version(struct be_function_object *pfob,
- struct FWCMD_COMMON_GET_FW_VERSION_RESPONSE_PAYLOAD *fw_version,
- mcc_wrb_cqe_callback cb, void *cb_context);
-
-
-int be_eq_modify_delay(struct be_function_object *pfob,
- u32 num_eq, struct be_eq_object **eq_array,
- u32 *eq_delay_array, mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_eq_modify_delay_q_ctxt *q_ctxt);
-
-
-
-int be_eq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 eqe_size, u32 num_entries,
- u32 watermark, u32 timer_delay, struct be_eq_object *eq_object);
-
-int be_eq_destroy(struct be_eq_object *eq);
-
-int be_cq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length,
- bool solicited_eventable, bool no_delay,
- u32 wm_thresh, struct be_eq_object *eq_object,
- struct be_cq_object *cq_object);
-
-int be_cq_destroy(struct be_cq_object *cq);
-
-int be_mcc_ring_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length,
- struct be_mcc_wrb_context *context_array,
- u32 num_context_entries,
- struct be_cq_object *cq, struct be_mcc_object *mcc);
-int be_mcc_ring_destroy(struct be_mcc_object *mcc_object);
-
-int be_mcc_process_cq(struct be_mcc_object *mcc_object, bool rearm);
-
-int be_mcc_add_async_event_callback(struct be_mcc_object *mcc_object,
- mcc_async_event_callback cb, void *cb_context);
-
-int be_pci_soft_reset(struct be_function_object *pfob);
-
-
-int be_drive_POST(struct be_function_object *pfob);
-
-
-int be_eth_sq_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length_in_bytes,
- u32 type, u32 ulp, struct be_cq_object *cq_object,
- struct be_ethsq_object *eth_sq);
-
-struct be_eth_sq_parameters {
- u32 port;
- u32 rsvd0[2];
-} ;
-
-int be_eth_sq_create_ex(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length_in_bytes,
- u32 type, u32 ulp, struct be_cq_object *cq_object,
- struct be_eth_sq_parameters *ex_parameters,
- struct be_ethsq_object *eth_sq);
-int be_eth_sq_destroy(struct be_ethsq_object *eth_sq);
-
-int be_eth_set_flow_control(struct be_function_object *pfob,
- bool txfc_enable, bool rxfc_enable);
-
-int be_eth_get_flow_control(struct be_function_object *pfob,
- bool *txfc_enable, bool *rxfc_enable);
-int be_eth_set_qos(struct be_function_object *pfob, u32 max_bps, u32 max_pps);
-
-int be_eth_get_qos(struct be_function_object *pfob, u32 *max_bps, u32 *max_pps);
-
-int be_eth_set_frame_size(struct be_function_object *pfob,
- u32 *tx_frame_size, u32 *rx_frame_size);
-
-int be_eth_rq_create(struct be_function_object *pfob,
- struct ring_desc *rd, struct be_cq_object *cq_object,
- struct be_cq_object *bcmc_cq_object,
- struct be_ethrq_object *eth_rq);
-
-int be_eth_rq_destroy(struct be_ethrq_object *eth_rq);
-
-int be_eth_rq_destroy_options(struct be_ethrq_object *eth_rq, bool flush,
- mcc_wrb_cqe_callback cb, void *cb_context);
-int be_eth_rq_set_frag_size(struct be_function_object *pfob,
- u32 new_frag_size_bytes, u32 *actual_frag_size_bytes);
-int be_eth_rq_get_frag_size(struct be_function_object *pfob,
- u32 *frag_size_bytes);
-
-void *be_function_prepare_embedded_fwcmd(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb,
- u32 payload_length, u32 request_length,
- u32 response_length, u32 opcode, u32 subsystem);
-void *be_function_prepare_nonembedded_fwcmd(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, void *fwcmd_header_va, u64 fwcmd_header_pa,
- u32 payload_length, u32 request_length, u32 response_length,
- u32 opcode, u32 subsystem);
-
-
-struct MCC_WRB_AMAP *
-be_function_peek_mcc_wrb(struct be_function_object *pfob);
-
-int be_rxf_mac_address_read_write(struct be_function_object *pfob,
- bool port1, bool mac1, bool mgmt,
- bool write, bool permanent, u8 *mac_address,
- mcc_wrb_cqe_callback cb,
- void *cb_context);
-
-int be_rxf_multicast_config(struct be_function_object *pfob,
- bool promiscuous, u32 num, u8 *mac_table,
- mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_multicast_q_ctxt *q_ctxt);
-
-int be_rxf_vlan_config(struct be_function_object *pfob,
- bool promiscuous, u32 num, u16 *vlan_tag_array,
- mcc_wrb_cqe_callback cb, void *cb_context,
- struct be_vlan_q_ctxt *q_ctxt);
-
-
-int be_rxf_link_status(struct be_function_object *pfob,
- struct BE_LINK_STATUS *link_status,
- mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_link_status_q_ctxt *q_ctxt);
-
-
-int be_rxf_query_eth_statistics(struct be_function_object *pfob,
- struct FWCMD_ETH_GET_STATISTICS *va_for_fwcmd,
- u64 pa_for_fwcmd, mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_nonembedded_q_ctxt *q_ctxt);
-
-int be_rxf_promiscuous(struct be_function_object *pfob,
- bool enable_port0, bool enable_port1,
- mcc_wrb_cqe_callback cb, void *cb_context,
- struct be_promiscuous_q_ctxt *q_ctxt);
-
-
-int be_rxf_filter_config(struct be_function_object *pfob,
- struct NTWK_RX_FILTER_SETTINGS *settings,
- mcc_wrb_cqe_callback cb,
- void *cb_context,
- struct be_rxf_filter_q_ctxt *q_ctxt);
-
-/*
- * ------------------------------------------------------
- * internal functions used by hwlib
- * ------------------------------------------------------
- */
-
-
-int be_function_ring_destroy(struct be_function_object *pfob,
- u32 id, u32 ring_type, mcc_wrb_cqe_callback cb,
- void *cb_context,
- mcc_wrb_cqe_callback internal_cb,
- void *internal_callback_context);
-
-int be_function_post_mcc_wrb(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb,
- struct be_generic_q_ctxt *q_ctxt,
- mcc_wrb_cqe_callback cb, void *cb_context,
- mcc_wrb_cqe_callback internal_cb,
- void *internal_cb_context, void *optional_fwcmd_va,
- struct be_mcc_wrb_response_copy *response_copy);
-
-int be_function_queue_mcc_wrb(struct be_function_object *pfob,
- struct be_generic_q_ctxt *q_ctxt);
-
-/*
- * ------------------------------------------------------
- * MCC QUEUE
- * ------------------------------------------------------
- */
-
-int be_mpu_init_mailbox(struct be_function_object *pfob, struct ring_desc *rd);
-
-
-struct MCC_WRB_AMAP *
-_be_mpu_peek_ring_wrb(struct be_mcc_object *mcc, bool driving_queue);
-
-struct be_mcc_wrb_context *
-_be_mcc_allocate_wrb_context(struct be_function_object *pfob);
-
-void _be_mcc_free_wrb_context(struct be_function_object *pfob,
- struct be_mcc_wrb_context *context);
-
-int _be_mpu_post_wrb_mailbox(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context);
-
-int _be_mpu_post_wrb_ring(struct be_mcc_object *mcc,
- struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context);
-
-void be_drive_mcc_wrb_queue(struct be_mcc_object *mcc);
-
-
-/*
- * ------------------------------------------------------
- * Ring Sizes
- * ------------------------------------------------------
- */
-static inline u32 be_ring_encoding_to_length(u32 encoding, u32 object_size)
-{
-
- ASSERT(encoding != 1); /* 1 is rsvd */
- ASSERT(encoding < 16);
- ASSERT(object_size > 0);
-
- if (encoding == 0) /* 32k deep */
- encoding = 16;
-
- return (1 << (encoding - 1)) * object_size;
-}
-
-static inline
-u32 be_ring_length_to_encoding(u32 length_in_bytes, u32 object_size)
-{
-
- u32 count, encoding;
-
- ASSERT(object_size > 0);
- ASSERT(length_in_bytes % object_size == 0);
-
- count = length_in_bytes / object_size;
-
- ASSERT(count > 1);
- ASSERT(count <= 32 * 1024);
- ASSERT(length_in_bytes <= 8 * PAGE_SIZE); /* max ring size in UT */
-
- encoding = __ilog2_u32(count) + 1;
-
- if (encoding == 16)
- encoding = 0; /* 32k deep */
-
- return encoding;
-}
-
-void be_rd_to_pa_list(struct ring_desc *rd, struct PHYS_ADDR *pa_list,
- u32 max_num);
-#endif /* __hwlib_h__ */
diff --git a/drivers/staging/benet/mpu.c b/drivers/staging/benet/mpu.c
deleted file mode 100644
index 269cc11d3055..000000000000
--- a/drivers/staging/benet/mpu.c
+++ /dev/null
@@ -1,1364 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-#include <linux/delay.h>
-#include "hwlib.h"
-#include "bestatus.h"
-
-static
-inline void mp_ring_create(struct mp_ring *ring, u32 num, u32 size, void *va)
-{
- ASSERT(ring);
- memset(ring, 0, sizeof(struct mp_ring));
- ring->num = num;
- ring->pages = DIV_ROUND_UP(num * size, PAGE_SIZE);
- ring->itemSize = size;
- ring->va = va;
-}
-
-/*
- * -----------------------------------------------------------------------
- * Interface for 2 index rings. i.e. consumer/producer rings
- * --------------------------------------------------------------------------
- */
-
-/* Returns number items pending on ring. */
-static inline u32 mp_ring_num_pending(struct mp_ring *ring)
-{
- ASSERT(ring);
- if (ring->num == 0)
- return 0;
- return be_subc(ring->pidx, ring->cidx, ring->num);
-}
-
-/* Returns number items free on ring. */
-static inline u32 mp_ring_num_empty(struct mp_ring *ring)
-{
- ASSERT(ring);
- return ring->num - 1 - mp_ring_num_pending(ring);
-}
-
-/* Consume 1 item */
-static inline void mp_ring_consume(struct mp_ring *ring)
-{
- ASSERT(ring);
- ASSERT(ring->pidx != ring->cidx);
-
- ring->cidx = be_addc(ring->cidx, 1, ring->num);
-}
-
-/* Produce 1 item */
-static inline void mp_ring_produce(struct mp_ring *ring)
-{
- ASSERT(ring);
- ring->pidx = be_addc(ring->pidx, 1, ring->num);
-}
-
-/* Consume count items */
-static inline void mp_ring_consume_multiple(struct mp_ring *ring, u32 count)
-{
- ASSERT(ring);
- ASSERT(mp_ring_num_pending(ring) >= count);
- ring->cidx = be_addc(ring->cidx, count, ring->num);
-}
-
-static inline void *mp_ring_item(struct mp_ring *ring, u32 index)
-{
- ASSERT(ring);
- ASSERT(index < ring->num);
- ASSERT(ring->itemSize > 0);
- return (u8 *) ring->va + index * ring->itemSize;
-}
-
-/* Ptr to produce item */
-static inline void *mp_ring_producer_ptr(struct mp_ring *ring)
-{
- ASSERT(ring);
- return mp_ring_item(ring, ring->pidx);
-}
-
-/*
- * Returns a pointer to the current location in the ring.
- * This is used for rings with 1 index.
- */
-static inline void *mp_ring_current(struct mp_ring *ring)
-{
- ASSERT(ring);
- ASSERT(ring->pidx == 0); /* not used */
-
- return mp_ring_item(ring, ring->cidx);
-}
-
-/*
- * Increment index for rings with only 1 index.
- * This is used for rings with 1 index.
- */
-static inline void *mp_ring_next(struct mp_ring *ring)
-{
- ASSERT(ring);
- ASSERT(ring->num > 0);
- ASSERT(ring->pidx == 0); /* not used */
-
- ring->cidx = be_addc(ring->cidx, 1, ring->num);
- return mp_ring_current(ring);
-}
-
-/*
- This routine waits for a previously posted mailbox WRB to be completed.
- Specifically it waits for the mailbox to say that it's ready to accept
- more data by setting the LSB of the mailbox pd register to 1.
-
- pcontroller - The function object to post this data to
-
- IRQL < DISPATCH_LEVEL
-*/
-static void be_mcc_mailbox_wait(struct be_function_object *pfob)
-{
- struct MPU_MAILBOX_DB_AMAP mailbox_db;
- u32 i = 0;
- u32 ready;
-
- if (pfob->emulate) {
- /* No waiting for mailbox in emulated mode. */
- return;
- }
-
- mailbox_db.dw[0] = PD_READ(pfob, mcc_bootstrap_db);
- ready = AMAP_GET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db);
-
- while (ready == false) {
- if ((++i & 0x3FFFF) == 0) {
- TRACE(DL_WARN, "Waiting for mailbox ready - %dk polls",
- i / 1000);
- }
- udelay(1);
- mailbox_db.dw[0] = PD_READ(pfob, mcc_bootstrap_db);
- ready = AMAP_GET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db);
- }
-}
-
-/*
- This routine tells the MCC mailbox that there is data to processed
- in the mailbox. It does this by setting the physical address for the
- mailbox location and clearing the LSB. This routine returns immediately
- and does not wait for the WRB to be processed.
-
- pcontroller - The function object to post this data to
-
- IRQL < DISPATCH_LEVEL
-
-*/
-static void be_mcc_mailbox_notify(struct be_function_object *pfob)
-{
- struct MPU_MAILBOX_DB_AMAP mailbox_db;
- u32 pa;
-
- ASSERT(pfob->mailbox.pa);
- ASSERT(pfob->mailbox.va);
-
- /* If emulated, do not ring the mailbox */
- if (pfob->emulate) {
- TRACE(DL_WARN, "MPU disabled. Skipping mailbox notify.");
- return;
- }
-
- /* form the higher bits in the address */
- mailbox_db.dw[0] = 0; /* init */
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, hi, &mailbox_db, 1);
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db, 0);
-
- /* bits 34 to 63 */
- pa = (u32) (pfob->mailbox.pa >> 34);
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, address, &mailbox_db, pa);
-
- /* Wait for the MPU to be ready */
- be_mcc_mailbox_wait(pfob);
-
- /* Ring doorbell 1st time */
- PD_WRITE(pfob, mcc_bootstrap_db, mailbox_db.dw[0]);
-
- /* Wait for 1st write to be acknowledged. */
- be_mcc_mailbox_wait(pfob);
-
- /* lower bits 30 bits from 4th bit (bits 4 to 33)*/
- pa = (u32) (pfob->mailbox.pa >> 4) & 0x3FFFFFFF;
-
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, hi, &mailbox_db, 0);
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, ready, &mailbox_db, 0);
- AMAP_SET_BITS_PTR(MPU_MAILBOX_DB, address, &mailbox_db, pa);
-
- /* Ring doorbell 2nd time */
- PD_WRITE(pfob, mcc_bootstrap_db, mailbox_db.dw[0]);
-}
-
-/*
- This routine tells the MCC mailbox that there is data to processed
- in the mailbox. It does this by setting the physical address for the
- mailbox location and clearing the LSB. This routine spins until the
- MPU writes a 1 into the LSB indicating that the data has been received
- and is ready to be processed.
-
- pcontroller - The function object to post this data to
-
- IRQL < DISPATCH_LEVEL
-*/
-static void
-be_mcc_mailbox_notify_and_wait(struct be_function_object *pfob)
-{
- /*
- * Notify it
- */
- be_mcc_mailbox_notify(pfob);
- /*
- * Now wait for completion of WRB
- */
- be_mcc_mailbox_wait(pfob);
-}
-
-void
-be_mcc_process_cqe(struct be_function_object *pfob,
- struct MCC_CQ_ENTRY_AMAP *cqe)
-{
- struct be_mcc_wrb_context *wrb_context = NULL;
- u32 offset, status;
- u8 *p;
-
- ASSERT(cqe);
- /*
- * A command completed. Commands complete out-of-order.
- * Determine which command completed from the TAG.
- */
- offset = offsetof(struct BE_MCC_CQ_ENTRY_AMAP, mcc_tag)/8;
- p = (u8 *) cqe + offset;
- wrb_context = (struct be_mcc_wrb_context *)(void *)(size_t)(*(u64 *)p);
- ASSERT(wrb_context);
-
- /*
- * Perform a response copy if requested.
- * Only copy data if the FWCMD is successful.
- */
- status = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, completion_status, cqe);
- if (status == MGMT_STATUS_SUCCESS && wrb_context->copy.length > 0) {
- ASSERT(wrb_context->wrb);
- ASSERT(wrb_context->copy.va);
- p = (u8 *)wrb_context->wrb +
- offsetof(struct BE_MCC_WRB_AMAP, payload)/8;
- memcpy(wrb_context->copy.va,
- (u8 *)p + wrb_context->copy.fwcmd_offset,
- wrb_context->copy.length);
- }
-
- if (status)
- status = BE_NOT_OK;
- /* internal callback */
- if (wrb_context->internal_cb) {
- wrb_context->internal_cb(wrb_context->internal_cb_context,
- status, wrb_context->wrb);
- }
-
- /* callback */
- if (wrb_context->cb) {
- wrb_context->cb(wrb_context->cb_context,
- status, wrb_context->wrb);
- }
- /* Free the context structure */
- _be_mcc_free_wrb_context(pfob, wrb_context);
-}
-
-void be_drive_mcc_wrb_queue(struct be_mcc_object *mcc)
-{
- struct be_function_object *pfob = NULL;
- int status = BE_PENDING;
- struct be_generic_q_ctxt *q_ctxt;
- struct MCC_WRB_AMAP *wrb;
- struct MCC_WRB_AMAP *queue_wrb;
- u32 length, payload_length, sge_count, embedded;
- unsigned long irql;
-
- BUILD_BUG_ON((sizeof(struct be_generic_q_ctxt) <
- sizeof(struct be_queue_driver_context) +
- sizeof(struct MCC_WRB_AMAP)));
- pfob = mcc->parent_function;
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- if (mcc->driving_backlog) {
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return;
- }
- /* Acquire the flag to limit 1 thread to redrive posts. */
- mcc->driving_backlog = 1;
-
- while (!list_empty(&mcc->backlog)) {
- wrb = _be_mpu_peek_ring_wrb(mcc, true); /* Driving the queue */
- if (!wrb)
- break; /* No space in the ring yet. */
- /* Get the next queued entry to process. */
- q_ctxt = list_first_entry(&mcc->backlog,
- struct be_generic_q_ctxt, context.list);
- list_del(&q_ctxt->context.list);
- pfob->mcc->backlog_length--;
- /*
- * Compute the required length of the WRB.
- * Since the queue element may be smaller than
- * the complete WRB, copy only the required number of bytes.
- */
- queue_wrb = (struct MCC_WRB_AMAP *) &q_ctxt->wrb_header;
- embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, queue_wrb);
- if (embedded) {
- payload_length = AMAP_GET_BITS_PTR(MCC_WRB,
- payload_length, queue_wrb);
- length = sizeof(struct be_mcc_wrb_header) +
- payload_length;
- } else {
- sge_count = AMAP_GET_BITS_PTR(MCC_WRB, sge_count,
- queue_wrb);
- ASSERT(sge_count == 1); /* only 1 frag. */
- length = sizeof(struct be_mcc_wrb_header) +
- sge_count * sizeof(struct MCC_SGE_AMAP);
- }
-
- /*
- * Truncate the length based on the size of the
- * queue element. Some elements that have output parameters
- * can be smaller than the payload_length field would
- * indicate. We really only need to copy the request
- * parameters, not the response.
- */
- length = min(length, (u32) (q_ctxt->context.bytes -
- offsetof(struct be_generic_q_ctxt, wrb_header)));
-
- /* Copy the queue element WRB into the ring. */
- memcpy(wrb, &q_ctxt->wrb_header, length);
-
- /* Post the wrb. This should not fail assuming we have
- * enough context structs. */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL,
- q_ctxt->context.cb, q_ctxt->context.cb_context,
- q_ctxt->context.internal_cb,
- q_ctxt->context.internal_cb_context,
- q_ctxt->context.optional_fwcmd_va,
- &q_ctxt->context.copy);
-
- if (status == BE_SUCCESS) {
- /*
- * Synchronous completion. Since it was queued,
- * we will invoke the callback.
- * To the user, this is an asynchronous request.
- */
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
-
- ASSERT(q_ctxt->context.cb);
-
- q_ctxt->context.cb(
- q_ctxt->context.cb_context,
- BE_SUCCESS, NULL);
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- } else if (status != BE_PENDING) {
- /*
- * Another resource failed. Should never happen
- * if we have sufficient MCC_WRB_CONTEXT structs.
- * Return to head of the queue.
- */
- TRACE(DL_WARN, "Failed to post a queued WRB. 0x%x",
- status);
- list_add(&q_ctxt->context.list, &mcc->backlog);
- pfob->mcc->backlog_length++;
- break;
- }
- }
-
- /* Free the flag to limit 1 thread to redrive posts. */
- mcc->driving_backlog = 0;
- spin_unlock_irqrestore(&pfob->post_lock, irql);
-}
-
-/* This function asserts that the WRB was consumed in order. */
-#ifdef BE_DEBUG
-u32 be_mcc_wrb_consumed_in_order(struct be_mcc_object *mcc,
- struct MCC_CQ_ENTRY_AMAP *cqe)
-{
- struct be_mcc_wrb_context *wrb_context = NULL;
- u32 wrb_index;
- u32 wrb_consumed_in_order;
- u32 offset;
- u8 *p;
-
- ASSERT(cqe);
- /*
- * A command completed. Commands complete out-of-order.
- * Determine which command completed from the TAG.
- */
- offset = offsetof(struct BE_MCC_CQ_ENTRY_AMAP, mcc_tag)/8;
- p = (u8 *) cqe + offset;
- wrb_context = (struct be_mcc_wrb_context *)(void *)(size_t)(*(u64 *)p);
-
- ASSERT(wrb_context);
-
- wrb_index = (u32) (((u64)(size_t)wrb_context->ring_wrb -
- (u64)(size_t)mcc->sq.ring.va) / sizeof(struct MCC_WRB_AMAP));
-
- ASSERT(wrb_index < mcc->sq.ring.num);
-
- wrb_consumed_in_order = (u32) (wrb_index == mcc->consumed_index);
- mcc->consumed_index = be_addc(mcc->consumed_index, 1, mcc->sq.ring.num);
- return wrb_consumed_in_order;
-}
-#endif
-
-int be_mcc_process_cq(struct be_mcc_object *mcc, bool rearm)
-{
- struct be_function_object *pfob = NULL;
- struct MCC_CQ_ENTRY_AMAP *cqe;
- struct CQ_DB_AMAP db;
- struct mp_ring *cq_ring = &mcc->cq.ring;
- struct mp_ring *mp_ring = &mcc->sq.ring;
- u32 num_processed = 0;
- u32 consumed = 0, valid, completed, cqe_consumed, async_event;
-
- pfob = mcc->parent_function;
-
- spin_lock_irqsave(&pfob->cq_lock, pfob->cq_irq);
-
- /*
- * Verify that only one thread is processing the CQ at once.
- * We cannot hold the lock while processing the CQ due to
- * the callbacks into the OS. Therefore, this flag is used
- * to control it. If any of the threads want to
- * rearm the CQ, we need to honor that.
- */
- if (mcc->processing != 0) {
- mcc->rearm = mcc->rearm || rearm;
- goto Error;
- } else {
- mcc->processing = 1; /* lock processing for this thread. */
- mcc->rearm = rearm; /* set our rearm setting */
- }
-
- spin_unlock_irqrestore(&pfob->cq_lock, pfob->cq_irq);
-
- cqe = mp_ring_current(cq_ring);
- valid = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe);
- while (valid) {
-
- if (num_processed >= 8) {
- /* coalesce doorbells, but free space in cq
- * ring while processing. */
- db.dw[0] = 0; /* clear */
- AMAP_SET_BITS_PTR(CQ_DB, qid, &db, cq_ring->id);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &db, false);
- AMAP_SET_BITS_PTR(CQ_DB, event, &db, false);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &db,
- num_processed);
- num_processed = 0;
-
- PD_WRITE(pfob, cq_db, db.dw[0]);
- }
-
- async_event = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, async_event, cqe);
- if (async_event) {
- /* This is an asynchronous event. */
- struct ASYNC_EVENT_TRAILER_AMAP *async_trailer =
- (struct ASYNC_EVENT_TRAILER_AMAP *)
- ((u8 *) cqe + sizeof(struct MCC_CQ_ENTRY_AMAP) -
- sizeof(struct ASYNC_EVENT_TRAILER_AMAP));
- u32 event_code;
- async_event = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER,
- async_event, async_trailer);
- ASSERT(async_event == 1);
-
-
- valid = AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER,
- valid, async_trailer);
- ASSERT(valid == 1);
-
- /* Call the async event handler if it is installed. */
- if (mcc->async_cb) {
- event_code =
- AMAP_GET_BITS_PTR(ASYNC_EVENT_TRAILER,
- event_code, async_trailer);
- mcc->async_cb(mcc->async_context,
- (u32) event_code, (void *) cqe);
- }
-
- } else {
- /* This is a completion entry. */
-
- /* No vm forwarding in this driver. */
-
- cqe_consumed = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY,
- consumed, cqe);
- if (cqe_consumed) {
- /*
- * A command on the MCC ring was consumed.
- * Update the consumer index.
- * These occur in order.
- */
- ASSERT(be_mcc_wrb_consumed_in_order(mcc, cqe));
- consumed++;
- }
-
- completed = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY,
- completed, cqe);
- if (completed) {
- /* A command completed. Use tag to
- * determine which command. */
- be_mcc_process_cqe(pfob, cqe);
- }
- }
-
- /* Reset the CQE */
- AMAP_SET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe, false);
- num_processed++;
-
- /* Update our tracking for the CQ ring. */
- cqe = mp_ring_next(cq_ring);
- valid = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, valid, cqe);
- }
-
- TRACE(DL_INFO, "num_processed:0x%x, and consumed:0x%x",
- num_processed, consumed);
- /*
- * Grab the CQ lock to synchronize the "rearm" setting for
- * the doorbell, and for clearing the "processing" flag.
- */
- spin_lock_irqsave(&pfob->cq_lock, pfob->cq_irq);
-
- /*
- * Rearm the cq. This is done based on the global mcc->rearm
- * flag which combines the rearm parameter from the current
- * call to process_cq and any other threads
- * that tried to process the CQ while this one was active.
- * This handles the situation where a sync. fwcmd was processing
- * the CQ while the interrupt/dpc tries to process it.
- * The sync process gets to continue -- but it is now
- * responsible for the rearming.
- */
- if (num_processed > 0 || mcc->rearm == true) {
- db.dw[0] = 0; /* clear */
- AMAP_SET_BITS_PTR(CQ_DB, qid, &db, cq_ring->id);
- AMAP_SET_BITS_PTR(CQ_DB, rearm, &db, mcc->rearm);
- AMAP_SET_BITS_PTR(CQ_DB, event, &db, false);
- AMAP_SET_BITS_PTR(CQ_DB, num_popped, &db, num_processed);
-
- PD_WRITE(pfob, cq_db, db.dw[0]);
- }
- /*
- * Update the consumer index after ringing the CQ doorbell.
- * We don't want another thread to post more WRBs before we
- * have CQ space available.
- */
- mp_ring_consume_multiple(mp_ring, consumed);
-
- /* Clear the processing flag. */
- mcc->processing = 0;
-
-Error:
- spin_unlock_irqrestore(&pfob->cq_lock, pfob->cq_irq);
- /*
- * Use the local variable to detect if the current thread
- * holds the WRB post lock. If rearm is false, this is
- * either a synchronous command, or the upper layer driver is polling
- * from a thread. We do not drive the queue from that
- * context since the driver may hold the
- * wrb post lock already.
- */
- if (rearm)
- be_drive_mcc_wrb_queue(mcc);
- else
- pfob->pend_queue_driving = 1;
-
- return BE_SUCCESS;
-}
-
-/*
- *============================================================================
- * P U B L I C R O U T I N E S
- *============================================================================
- */
-
-/*
- This routine creates an MCC object. This object contains an MCC send queue
- and a CQ private to the MCC.
-
- pcontroller - Handle to a function object
-
- EqObject - EQ object that will be used to dispatch this MCC
-
- ppMccObject - Pointer to an internal Mcc Object returned.
-
- Returns BE_SUCCESS if successfull,, otherwise a useful error code
- is returned.
-
- IRQL < DISPATCH_LEVEL
-
-*/
-int
-be_mcc_ring_create(struct be_function_object *pfob,
- struct ring_desc *rd, u32 length,
- struct be_mcc_wrb_context *context_array,
- u32 num_context_entries,
- struct be_cq_object *cq, struct be_mcc_object *mcc)
-{
- int status = 0;
-
- struct FWCMD_COMMON_MCC_CREATE *fwcmd = NULL;
- struct MCC_WRB_AMAP *wrb = NULL;
- u32 num_entries_encoded, n, i;
- void *va = NULL;
- unsigned long irql;
-
- if (length < sizeof(struct MCC_WRB_AMAP) * 2) {
- TRACE(DL_ERR, "Invalid MCC ring length:%d", length);
- return BE_NOT_OK;
- }
- /*
- * Reduce the actual ring size to be less than the number
- * of context entries. This ensures that we run out of
- * ring WRBs first so the queuing works correctly. We never
- * queue based on context structs.
- */
- if (num_context_entries + 1 <
- length / sizeof(struct MCC_WRB_AMAP) - 1) {
-
- u32 max_length =
- (num_context_entries + 2) * sizeof(struct MCC_WRB_AMAP);
-
- if (is_power_of_2(max_length))
- length = __roundup_pow_of_two(max_length+1) / 2;
- else
- length = __roundup_pow_of_two(max_length) / 2;
-
- ASSERT(length <= max_length);
-
- TRACE(DL_WARN,
- "MCC ring length reduced based on context entries."
- " length:%d wrbs:%d context_entries:%d", length,
- (int) (length / sizeof(struct MCC_WRB_AMAP)),
- num_context_entries);
- }
-
- spin_lock_irqsave(&pfob->post_lock, irql);
-
- num_entries_encoded =
- be_ring_length_to_encoding(length, sizeof(struct MCC_WRB_AMAP));
-
- /* Init MCC object. */
- memset(mcc, 0, sizeof(*mcc));
- mcc->parent_function = pfob;
- mcc->cq_object = cq;
-
- INIT_LIST_HEAD(&mcc->backlog);
-
- wrb = be_function_peek_mcc_wrb(pfob);
- if (!wrb) {
- ASSERT(wrb);
- TRACE(DL_ERR, "No free MCC WRBs in create EQ.");
- status = BE_STATUS_NO_MCC_WRB;
- goto error;
- }
- /* Prepares an embedded fwcmd, including request/response sizes. */
- fwcmd = BE_PREPARE_EMBEDDED_FWCMD(pfob, wrb, COMMON_MCC_CREATE);
-
- fwcmd->params.request.num_pages = DIV_ROUND_UP(length, PAGE_SIZE);
- /*
- * Program MCC ring context
- */
- AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, pdid,
- &fwcmd->params.request.context, 0);
- AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, invalid,
- &fwcmd->params.request.context, false);
- AMAP_SET_BITS_PTR(MCC_RING_CONTEXT, ring_size,
- &fwcmd->params.request.context, num_entries_encoded);
-
- n = cq->cq_id;
- AMAP_SET_BITS_PTR(MCC_RING_CONTEXT,
- cq_id, &fwcmd->params.request.context, n);
- be_rd_to_pa_list(rd, fwcmd->params.request.pages,
- ARRAY_SIZE(fwcmd->params.request.pages));
- /* Post the f/w command */
- status = be_function_post_mcc_wrb(pfob, wrb, NULL, NULL, NULL,
- NULL, NULL, fwcmd, NULL);
- if (status != BE_SUCCESS) {
- TRACE(DL_ERR, "MCC to create CQ failed.");
- goto error;
- }
- /*
- * Create a linked list of context structures
- */
- mcc->wrb_context.base = context_array;
- mcc->wrb_context.num = num_context_entries;
- INIT_LIST_HEAD(&mcc->wrb_context.list_head);
- memset(context_array, 0,
- sizeof(struct be_mcc_wrb_context) * num_context_entries);
- for (i = 0; i < mcc->wrb_context.num; i++) {
- list_add_tail(&context_array[i].next,
- &mcc->wrb_context.list_head);
- }
-
- /*
- *
- * Create an mcc_ring for tracking WRB hw ring
- */
- va = rd->va;
- ASSERT(va);
- mp_ring_create(&mcc->sq.ring, length / sizeof(struct MCC_WRB_AMAP),
- sizeof(struct MCC_WRB_AMAP), va);
- mcc->sq.ring.id = fwcmd->params.response.id;
- /*
- * Init a mcc_ring for tracking the MCC CQ.
- */
- ASSERT(cq->va);
- mp_ring_create(&mcc->cq.ring, cq->num_entries,
- sizeof(struct MCC_CQ_ENTRY_AMAP), cq->va);
- mcc->cq.ring.id = cq->cq_id;
-
- /* Force zeroing of CQ. */
- memset(cq->va, 0, cq->num_entries * sizeof(struct MCC_CQ_ENTRY_AMAP));
-
- /* Initialize debug index. */
- mcc->consumed_index = 0;
-
- atomic_inc(&cq->ref_count);
- pfob->mcc = mcc;
-
- TRACE(DL_INFO, "MCC ring created. id:%d bytes:%d cq_id:%d cq_entries:%d"
- " num_context:%d", mcc->sq.ring.id, length,
- cq->cq_id, cq->num_entries, num_context_entries);
-
-error:
- spin_unlock_irqrestore(&pfob->post_lock, irql);
- if (pfob->pend_queue_driving && pfob->mcc) {
- pfob->pend_queue_driving = 0;
- be_drive_mcc_wrb_queue(pfob->mcc);
- }
- return status;
-}
-
-/*
- This routine destroys an MCC send queue
-
- MccObject - Internal Mcc Object to be destroyed.
-
- Returns BE_SUCCESS if successfull, otherwise an error code is returned.
-
- IRQL < DISPATCH_LEVEL
-
- The caller of this routine must ensure that no other WRB may be posted
- until this routine returns.
-
-*/
-int be_mcc_ring_destroy(struct be_mcc_object *mcc)
-{
- int status = 0;
- struct be_function_object *pfob = mcc->parent_function;
-
-
- ASSERT(mcc->processing == 0);
-
- /*
- * Remove the ring from the function object.
- * This transitions back to mailbox mode.
- */
- pfob->mcc = NULL;
-
- /* Send fwcmd to destroy the queue. (Using the mailbox.) */
- status = be_function_ring_destroy(mcc->parent_function, mcc->sq.ring.id,
- FWCMD_RING_TYPE_MCC, NULL, NULL, NULL, NULL);
- ASSERT(status == 0);
-
- /* Release the SQ reference to the CQ */
- atomic_dec(&mcc->cq_object->ref_count);
-
- return status;
-}
-
-static void
-mcc_wrb_sync_cb(void *context, int staus, struct MCC_WRB_AMAP *wrb)
-{
- struct be_mcc_wrb_context *wrb_context =
- (struct be_mcc_wrb_context *) context;
- ASSERT(wrb_context);
- *wrb_context->users_final_status = staus;
-}
-
-/*
- This routine posts a command to the MCC send queue
-
- mcc - Internal Mcc Object to be destroyed.
-
- wrb - wrb to post.
-
- Returns BE_SUCCESS if successfull, otherwise an error code is returned.
-
- IRQL < DISPATCH_LEVEL if CompletionCallback is not NULL
- IRQL <=DISPATCH_LEVEL if CompletionCallback is NULL
-
- If this routine is called with CompletionCallback != NULL the
- call is considered to be asynchronous and will return as soon
- as the WRB is posted to the MCC with BE_PENDING.
-
- If CompletionCallback is NULL, then this routine will not return until
- a completion for this MCC command has been processed.
- If called at DISPATCH_LEVEL the CompletionCallback must be NULL.
-
- This routine should only be called if the MPU has been boostraped past
- mailbox mode.
-
-
-*/
-int
-_be_mpu_post_wrb_ring(struct be_mcc_object *mcc, struct MCC_WRB_AMAP *wrb,
- struct be_mcc_wrb_context *wrb_context)
-{
-
- struct MCC_WRB_AMAP *ring_wrb = NULL;
- int status = BE_PENDING;
- int final_status = BE_PENDING;
- mcc_wrb_cqe_callback cb = NULL;
- struct MCC_DB_AMAP mcc_db;
- u32 embedded;
-
- ASSERT(mp_ring_num_empty(&mcc->sq.ring) > 0);
- /*
- * Input wrb is most likely the next wrb in the ring, since the client
- * can peek at the address.
- */
- ring_wrb = mp_ring_producer_ptr(&mcc->sq.ring);
- if (wrb != ring_wrb) {
- /* If not equal, copy it into the ring. */
- memcpy(ring_wrb, wrb, sizeof(struct MCC_WRB_AMAP));
- }
-#ifdef BE_DEBUG
- wrb_context->ring_wrb = ring_wrb;
-#endif
- embedded = AMAP_GET_BITS_PTR(MCC_WRB, embedded, ring_wrb);
- if (embedded) {
- /* embedded commands will have the response within the WRB. */
- wrb_context->wrb = ring_wrb;
- } else {
- /*
- * non-embedded commands will not have the response
- * within the WRB, and they may complete out-of-order.
- * The WRB will not be valid to inspect
- * during the completion.
- */
- wrb_context->wrb = NULL;
- }
- cb = wrb_context->cb;
-
- if (cb == NULL) {
- /* Assign our internal callback if this is a
- * synchronous call. */
- wrb_context->cb = mcc_wrb_sync_cb;
- wrb_context->cb_context = wrb_context;
- wrb_context->users_final_status = &final_status;
- }
- /* Increment producer index */
-
- mcc_db.dw[0] = 0; /* initialize */
- AMAP_SET_BITS_PTR(MCC_DB, rid, &mcc_db, mcc->sq.ring.id);
- AMAP_SET_BITS_PTR(MCC_DB, numPosted, &mcc_db, 1);
-
- mp_ring_produce(&mcc->sq.ring);
- PD_WRITE(mcc->parent_function, mpu_mcc_db, mcc_db.dw[0]);
- TRACE(DL_INFO, "pidx: %x and cidx: %x.", mcc->sq.ring.pidx,
- mcc->sq.ring.cidx);
-
- if (cb == NULL) {
- int polls = 0; /* At >= 1 us per poll */
- /* Wait until this command completes, polling the CQ. */
- do {
- TRACE(DL_INFO, "FWCMD submitted in the poll mode.");
- /* Do not rearm CQ in this context. */
- be_mcc_process_cq(mcc, false);
-
- if (final_status == BE_PENDING) {
- if ((++polls & 0x7FFFF) == 0) {
- TRACE(DL_WARN,
- "Warning : polling MCC CQ for %d"
- "ms.", polls / 1000);
- }
-
- udelay(1);
- }
-
- /* final_status changed when the command completes */
- } while (final_status == BE_PENDING);
-
- status = final_status;
- }
-
- return status;
-}
-
-struct MCC_WRB_AMAP *
-_be_mpu_peek_ring_wrb(struct be_mcc_object *mcc, bool driving_queue)
-{
- /* If we have queued items, do not allow a post to bypass the queue. */
- if (!driving_queue && !list_empty(&mcc->backlog))
- return NULL;
-
- if (mp_ring_num_empty(&mcc->sq.ring) <= 0)
- return NULL;
- return (struct MCC_WRB_AMAP *) mp_ring_producer_ptr(&mcc->sq.ring);
-}
-
-int
-be_mpu_init_mailbox(struct be_function_object *pfob, struct ring_desc *mailbox)
-{
- ASSERT(mailbox);
- pfob->mailbox.va = mailbox->va;
- pfob->mailbox.pa = cpu_to_le64(mailbox->pa);
- pfob->mailbox.length = mailbox->length;
-
- ASSERT(((u32)(size_t)pfob->mailbox.va & 0xf) == 0);
- ASSERT(((u32)(size_t)pfob->mailbox.pa & 0xf) == 0);
- /*
- * Issue the WRB to set MPU endianness
- */
- {
- u64 *endian_check = (u64 *) (pfob->mailbox.va +
- offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8);
- *endian_check = 0xFF1234FFFF5678FFULL;
- }
-
- be_mcc_mailbox_notify_and_wait(pfob);
-
- return BE_SUCCESS;
-}
-
-
-/*
- This routine posts a command to the MCC mailbox.
-
- FuncObj - Function Object to post the WRB on behalf of.
- wrb - wrb to post.
- CompletionCallback - Address of a callback routine to invoke once the WRB
- is completed.
- CompletionCallbackContext - Opaque context to be passed during the call to
- the CompletionCallback.
- Returns BE_SUCCESS if successfull, otherwise an error code is returned.
-
- IRQL <=DISPATCH_LEVEL if CompletionCallback is NULL
-
- This routine will block until a completion for this MCC command has been
- processed. If called at DISPATCH_LEVEL the CompletionCallback must be NULL.
-
- This routine should only be called if the MPU has not been boostraped past
- mailbox mode.
-*/
-int
-_be_mpu_post_wrb_mailbox(struct be_function_object *pfob,
- struct MCC_WRB_AMAP *wrb, struct be_mcc_wrb_context *wrb_context)
-{
- struct MCC_MAILBOX_AMAP *mailbox = NULL;
- struct MCC_WRB_AMAP *mb_wrb;
- struct MCC_CQ_ENTRY_AMAP *mb_cq;
- u32 offset, status;
-
- ASSERT(pfob->mcc == NULL);
- mailbox = pfob->mailbox.va;
- ASSERT(mailbox);
-
- offset = offsetof(struct BE_MCC_MAILBOX_AMAP, wrb)/8;
- mb_wrb = (struct MCC_WRB_AMAP *) (u8 *)mailbox + offset;
- if (mb_wrb != wrb) {
- memset(mailbox, 0, sizeof(*mailbox));
- memcpy(mb_wrb, wrb, sizeof(struct MCC_WRB_AMAP));
- }
- /* The callback can inspect the final WRB to get output parameters. */
- wrb_context->wrb = mb_wrb;
-
- be_mcc_mailbox_notify_and_wait(pfob);
-
- /* A command completed. Use tag to determine which command. */
- offset = offsetof(struct BE_MCC_MAILBOX_AMAP, cq)/8;
- mb_cq = (struct MCC_CQ_ENTRY_AMAP *) ((u8 *)mailbox + offset);
- be_mcc_process_cqe(pfob, mb_cq);
-
- status = AMAP_GET_BITS_PTR(MCC_CQ_ENTRY, completion_status, mb_cq);
- if (status)
- status = BE_NOT_OK;
- return status;
-}
-
-struct be_mcc_wrb_context *
-_be_mcc_allocate_wrb_context(struct be_function_object *pfob)
-{
- struct be_mcc_wrb_context *context = NULL;
- unsigned long irq;
-
- spin_lock_irqsave(&pfob->mcc_context_lock, irq);
-
- if (!pfob->mailbox.default_context_allocated) {
- /* Use the single default context that we
- * always have allocated. */
- pfob->mailbox.default_context_allocated = true;
- context = &pfob->mailbox.default_context;
- } else if (pfob->mcc) {
- /* Get a context from the free list. If any are available. */
- if (!list_empty(&pfob->mcc->wrb_context.list_head)) {
- context = list_first_entry(
- &pfob->mcc->wrb_context.list_head,
- struct be_mcc_wrb_context, next);
- }
- }
-
- spin_unlock_irqrestore(&pfob->mcc_context_lock, irq);
-
- return context;
-}
-
-void
-_be_mcc_free_wrb_context(struct be_function_object *pfob,
- struct be_mcc_wrb_context *context)
-{
- unsigned long irq;
-
- ASSERT(context);
- /*
- * Zero during free to try and catch any bugs where the context
- * is accessed after a free.
- */
- memset(context, 0, sizeof(context));
-
- spin_lock_irqsave(&pfob->mcc_context_lock, irq);
-
- if (context == &pfob->mailbox.default_context) {
- /* Free the default context. */
- ASSERT(pfob->mailbox.default_context_allocated);
- pfob->mailbox.default_context_allocated = false;
- } else {
- /* Add to free list. */
- ASSERT(pfob->mcc);
- list_add_tail(&context->next,
- &pfob->mcc->wrb_context.list_head);
- }
-
- spin_unlock_irqrestore(&pfob->mcc_context_lock, irq);
-}
-
-int
-be_mcc_add_async_event_callback(struct be_mcc_object *mcc_object,
- mcc_async_event_callback cb, void *cb_context)
-{
- /* Lock against anyone trying to change the callback/context pointers
- * while being used. */
- spin_lock_irqsave(&mcc_object->parent_function->cq_lock,
- mcc_object->parent_function->cq_irq);
-
- /* Assign the async callback. */
- mcc_object->async_context = cb_context;
- mcc_object->async_cb = cb;
-
- spin_unlock_irqrestore(&mcc_object->parent_function->cq_lock,
- mcc_object->parent_function->cq_irq);
-
- return BE_SUCCESS;
-}
-
-#define MPU_EP_CONTROL 0
-#define MPU_EP_SEMAPHORE 0xac
-
-/*
- *-------------------------------------------------------------------
- * Function: be_wait_for_POST_complete
- * Waits until the BladeEngine POST completes (either in error or success).
- * pfob -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *-------------------------------------------------------------------
- */
-static int be_wait_for_POST_complete(struct be_function_object *pfob)
-{
- struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status;
- int s;
- u32 post_error, post_stage;
-
- const u32 us_per_loop = 1000; /* 1000us */
- const u32 print_frequency_loops = 1000000 / us_per_loop;
- const u32 max_loops = 60 * print_frequency_loops;
- u32 loops = 0;
-
- /*
- * Wait for arm fw indicating it is done or a fatal error happened.
- * Note: POST can take some time to complete depending on configuration
- * settings (consider ARM attempts to acquire an IP address
- * over DHCP!!!).
- *
- */
- do {
- status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE);
- post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT,
- error, &status);
- post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT,
- stage, &status);
- if (0 == (loops % print_frequency_loops)) {
- /* Print current status */
- TRACE(DL_INFO, "POST status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- }
- udelay(us_per_loop);
- } while ((post_error != 1) &&
- (post_stage != POST_STAGE_ARMFW_READY) &&
- (++loops < max_loops));
-
- if (post_error == 1) {
- TRACE(DL_ERR, "POST error! Status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- s = BE_NOT_OK;
- } else if (post_stage != POST_STAGE_ARMFW_READY) {
- TRACE(DL_ERR, "POST time-out! Status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- s = BE_NOT_OK;
- } else {
- s = BE_SUCCESS;
- }
- return s;
-}
-
-/*
- *-------------------------------------------------------------------
- * Function: be_kickoff_and_wait_for_POST
- * Interacts with the BladeEngine management processor to initiate POST, and
- * subsequently waits until POST completes (either in error or success).
- * The caller must acquire the reset semaphore before initiating POST
- * to prevent multiple drivers interacting with the management processor.
- * Once POST is complete the caller must release the reset semaphore.
- * Callers who only want to wait for POST complete may call
- * be_wait_for_POST_complete.
- * pfob -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *-------------------------------------------------------------------
- */
-static int
-be_kickoff_and_wait_for_POST(struct be_function_object *pfob)
-{
- struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status;
- int s;
-
- const u32 us_per_loop = 1000; /* 1000us */
- const u32 print_frequency_loops = 1000000 / us_per_loop;
- const u32 max_loops = 5 * print_frequency_loops;
- u32 loops = 0;
- u32 post_error, post_stage;
-
- /* Wait for arm fw awaiting host ready or a fatal error happened. */
- TRACE(DL_INFO, "Wait for BladeEngine ready to POST");
- do {
- status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE);
- post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT,
- error, &status);
- post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT,
- stage, &status);
- if (0 == (loops % print_frequency_loops)) {
- /* Print current status */
- TRACE(DL_INFO, "POST status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- }
- udelay(us_per_loop);
- } while ((post_error != 1) &&
- (post_stage < POST_STAGE_AWAITING_HOST_RDY) &&
- (++loops < max_loops));
-
- if (post_error == 1) {
- TRACE(DL_ERR, "Pre-POST error! Status = 0x%x (stage = 0x%x)",
- status.dw[0], post_stage);
- s = BE_NOT_OK;
- } else if (post_stage == POST_STAGE_AWAITING_HOST_RDY) {
- iowrite32(POST_STAGE_HOST_RDY, pfob->csr_va + MPU_EP_SEMAPHORE);
-
- /* Wait for POST to complete */
- s = be_wait_for_POST_complete(pfob);
- } else {
- /*
- * Either a timeout waiting for host ready signal or POST has
- * moved ahead without requiring a host ready signal.
- * Might as well give POST a chance to complete
- * (or timeout again).
- */
- s = be_wait_for_POST_complete(pfob);
- }
- return s;
-}
-
-/*
- *-------------------------------------------------------------------
- * Function: be_pci_soft_reset
- * This function is called to issue a BladeEngine soft reset.
- * Callers should acquire the soft reset semaphore before calling this
- * function. Additionaly, callers should ensure they cannot be pre-empted
- * while the routine executes. Upon completion of this routine, callers
- * should release the reset semaphore. This routine implicitly waits
- * for BladeEngine POST to complete.
- * pfob -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *-------------------------------------------------------------------
- */
-int be_pci_soft_reset(struct be_function_object *pfob)
-{
- struct PCICFG_SOFT_RESET_CSR_AMAP soft_reset;
- struct PCICFG_ONLINE0_CSR_AMAP pciOnline0;
- struct PCICFG_ONLINE1_CSR_AMAP pciOnline1;
- struct EP_CONTROL_CSR_AMAP epControlCsr;
- int status = BE_SUCCESS;
- u32 i, soft_reset_bit;
-
- TRACE(DL_NOTE, "PCI reset...");
-
- /* Issue soft reset #1 to get BladeEngine into a known state. */
- soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset);
- AMAP_SET_BITS_PTR(PCICFG_SOFT_RESET_CSR, softreset, soft_reset.dw, 1);
- PCICFG0_WRITE(pfob, host_timer_int_ctrl, soft_reset.dw[0]);
- /*
- * wait til soft reset is deasserted - hardware
- * deasserts after some time.
- */
- i = 0;
- do {
- udelay(50);
- soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset);
- soft_reset_bit = AMAP_GET_BITS_PTR(PCICFG_SOFT_RESET_CSR,
- softreset, soft_reset.dw);
- } while (soft_reset_bit && (i++ < 1024));
- if (soft_reset_bit != 0) {
- TRACE(DL_ERR, "Soft-reset #1 did not deassert as expected.");
- status = BE_NOT_OK;
- goto Error_label;
- }
- /* Mask everything */
- PCICFG0_WRITE(pfob, ue_status_low_mask, 0xFFFFFFFF);
- PCICFG0_WRITE(pfob, ue_status_hi_mask, 0xFFFFFFFF);
- /*
- * Set everything offline except MPU IRAM (it is offline with
- * the soft-reset, but soft-reset does not reset the PCICFG registers!)
- */
- pciOnline0.dw[0] = 0;
- pciOnline1.dw[0] = 0;
- AMAP_SET_BITS_PTR(PCICFG_ONLINE1_CSR, mpu_iram_online,
- pciOnline1.dw, 1);
- PCICFG0_WRITE(pfob, online0, pciOnline0.dw[0]);
- PCICFG0_WRITE(pfob, online1, pciOnline1.dw[0]);
-
- udelay(20000);
-
- /* Issue soft reset #2. */
- AMAP_SET_BITS_PTR(PCICFG_SOFT_RESET_CSR, softreset, soft_reset.dw, 1);
- PCICFG0_WRITE(pfob, host_timer_int_ctrl, soft_reset.dw[0]);
- /*
- * wait til soft reset is deasserted - hardware
- * deasserts after some time.
- */
- i = 0;
- do {
- udelay(50);
- soft_reset.dw[0] = PCICFG0_READ(pfob, soft_reset);
- soft_reset_bit = AMAP_GET_BITS_PTR(PCICFG_SOFT_RESET_CSR,
- softreset, soft_reset.dw);
- } while (soft_reset_bit && (i++ < 1024));
- if (soft_reset_bit != 0) {
- TRACE(DL_ERR, "Soft-reset #1 did not deassert as expected.");
- status = BE_NOT_OK;
- goto Error_label;
- }
-
-
- udelay(20000);
-
- /* Take MPU out of reset. */
-
- epControlCsr.dw[0] = ioread32(pfob->csr_va + MPU_EP_CONTROL);
- AMAP_SET_BITS_PTR(EP_CONTROL_CSR, CPU_reset, &epControlCsr, 0);
- iowrite32((u32)epControlCsr.dw[0], pfob->csr_va + MPU_EP_CONTROL);
-
- /* Kickoff BE POST and wait for completion */
- status = be_kickoff_and_wait_for_POST(pfob);
-
-Error_label:
- return status;
-}
-
-
-/*
- *-------------------------------------------------------------------
- * Function: be_pci_reset_required
- * This private function is called to detect if a host entity is
- * required to issue a PCI soft reset and subsequently drive
- * BladeEngine POST. Scenarios where this is required:
- * 1) BIOS-less configuration
- * 2) Hot-swap/plug/power-on
- * pfob -
- * return true if a reset is required, false otherwise
- *-------------------------------------------------------------------
- */
-static bool be_pci_reset_required(struct be_function_object *pfob)
-{
- struct MGMT_HBA_POST_STATUS_STRUCT_AMAP status;
- bool do_reset = false;
- u32 post_error, post_stage;
-
- /*
- * Read the POST status register
- */
- status.dw[0] = ioread32(pfob->csr_va + MPU_EP_SEMAPHORE);
- post_error = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, error,
- &status);
- post_stage = AMAP_GET_BITS_PTR(MGMT_HBA_POST_STATUS_STRUCT, stage,
- &status);
- if (post_stage <= POST_STAGE_AWAITING_HOST_RDY) {
- /*
- * If BladeEngine is waiting for host ready indication,
- * we want to do a PCI reset.
- */
- do_reset = true;
- }
-
- return do_reset;
-}
-
-/*
- *-------------------------------------------------------------------
- * Function: be_drive_POST
- * This function is called to drive BladeEngine POST. The
- * caller should ensure they cannot be pre-empted while this routine executes.
- * pfob -
- * return status - BE_SUCCESS (0) on success. Negative error code on failure.
- *-------------------------------------------------------------------
- */
-int be_drive_POST(struct be_function_object *pfob)
-{
- int status;
-
- if (false != be_pci_reset_required(pfob)) {
- /* PCI reset is needed (implicitly starts and waits for POST) */
- status = be_pci_soft_reset(pfob);
- } else {
- /* No PCI reset is needed, start POST */
- status = be_kickoff_and_wait_for_POST(pfob);
- }
-
- return status;
-}
diff --git a/drivers/staging/benet/mpu.h b/drivers/staging/benet/mpu.h
deleted file mode 100644
index 41f3f87516e5..000000000000
--- a/drivers/staging/benet/mpu.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __mpu_amap_h__
-#define __mpu_amap_h__
-#include "ep.h"
-
-/* Provide control parameters for the Managment Processor Unit. */
-struct BE_MPU_CSRMAP_AMAP {
- struct BE_EP_CSRMAP_AMAP ep;
- u8 rsvd0[128]; /* DWORD 64 */
- u8 rsvd1[32]; /* DWORD 68 */
- u8 rsvd2[192]; /* DWORD 69 */
- u8 rsvd3[192]; /* DWORD 75 */
- u8 rsvd4[32]; /* DWORD 81 */
- u8 rsvd5[32]; /* DWORD 82 */
- u8 rsvd6[32]; /* DWORD 83 */
- u8 rsvd7[32]; /* DWORD 84 */
- u8 rsvd8[32]; /* DWORD 85 */
- u8 rsvd9[32]; /* DWORD 86 */
- u8 rsvd10[32]; /* DWORD 87 */
- u8 rsvd11[32]; /* DWORD 88 */
- u8 rsvd12[32]; /* DWORD 89 */
- u8 rsvd13[32]; /* DWORD 90 */
- u8 rsvd14[32]; /* DWORD 91 */
- u8 rsvd15[32]; /* DWORD 92 */
- u8 rsvd16[32]; /* DWORD 93 */
- u8 rsvd17[32]; /* DWORD 94 */
- u8 rsvd18[32]; /* DWORD 95 */
- u8 rsvd19[32]; /* DWORD 96 */
- u8 rsvd20[32]; /* DWORD 97 */
- u8 rsvd21[32]; /* DWORD 98 */
- u8 rsvd22[32]; /* DWORD 99 */
- u8 rsvd23[32]; /* DWORD 100 */
- u8 rsvd24[32]; /* DWORD 101 */
- u8 rsvd25[32]; /* DWORD 102 */
- u8 rsvd26[32]; /* DWORD 103 */
- u8 rsvd27[32]; /* DWORD 104 */
- u8 rsvd28[96]; /* DWORD 105 */
- u8 rsvd29[32]; /* DWORD 108 */
- u8 rsvd30[32]; /* DWORD 109 */
- u8 rsvd31[32]; /* DWORD 110 */
- u8 rsvd32[32]; /* DWORD 111 */
- u8 rsvd33[32]; /* DWORD 112 */
- u8 rsvd34[96]; /* DWORD 113 */
- u8 rsvd35[32]; /* DWORD 116 */
- u8 rsvd36[32]; /* DWORD 117 */
- u8 rsvd37[32]; /* DWORD 118 */
- u8 rsvd38[32]; /* DWORD 119 */
- u8 rsvd39[32]; /* DWORD 120 */
- u8 rsvd40[32]; /* DWORD 121 */
- u8 rsvd41[134][32]; /* DWORD 122 */
-} __packed;
-struct MPU_CSRMAP_AMAP {
- u32 dw[256];
-};
-
-#endif /* __mpu_amap_h__ */
diff --git a/drivers/staging/benet/mpu_context.h b/drivers/staging/benet/mpu_context.h
deleted file mode 100644
index 8ce90f9c46c2..000000000000
--- a/drivers/staging/benet/mpu_context.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __mpu_context_amap_h__
-#define __mpu_context_amap_h__
-
-/*
- * Management command and control ring context. The MPUs BTLR_CTRL1 CSR
- * controls the writeback behavior of the producer and consumer index values.
- */
-struct BE_MCC_RING_CONTEXT_AMAP {
- u8 con_index[16]; /* DWORD 0 */
- u8 ring_size[4]; /* DWORD 0 */
- u8 cq_id[11]; /* DWORD 0 */
- u8 rsvd0; /* DWORD 0 */
- u8 prod_index[16]; /* DWORD 1 */
- u8 pdid[15]; /* DWORD 1 */
- u8 invalid; /* DWORD 1 */
- u8 cmd_pending_current[7]; /* DWORD 2 */
- u8 rsvd1[25]; /* DWORD 2 */
- u8 hpi_port_cq_id[11]; /* DWORD 3 */
- u8 rsvd2[5]; /* DWORD 3 */
- u8 cmd_pending_max[7]; /* DWORD 3 */
- u8 rsvd3[9]; /* DWORD 3 */
-} __packed;
-struct MCC_RING_CONTEXT_AMAP {
- u32 dw[4];
-};
-
-#endif /* __mpu_context_amap_h__ */
diff --git a/drivers/staging/benet/pcicfg.h b/drivers/staging/benet/pcicfg.h
deleted file mode 100644
index 7c15684adf4a..000000000000
--- a/drivers/staging/benet/pcicfg.h
+++ /dev/null
@@ -1,825 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __pcicfg_amap_h__
-#define __pcicfg_amap_h__
-
-/* Vendor and Device ID Register. */
-struct BE_PCICFG_ID_CSR_AMAP {
- u8 vendorid[16]; /* DWORD 0 */
- u8 deviceid[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ID_CSR_AMAP {
- u32 dw[1];
-};
-
-/* IO Bar Register. */
-struct BE_PCICFG_IOBAR_CSR_AMAP {
- u8 iospace; /* DWORD 0 */
- u8 rsvd0[7]; /* DWORD 0 */
- u8 iobar[24]; /* DWORD 0 */
-} __packed;
-struct PCICFG_IOBAR_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 0 Register. */
-struct BE_PCICFG_MEMBAR0_CSR_AMAP {
- u8 memspace; /* DWORD 0 */
- u8 type[2]; /* DWORD 0 */
- u8 pf; /* DWORD 0 */
- u8 rsvd0[10]; /* DWORD 0 */
- u8 membar0[18]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR0_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 1 - Low Address Register. */
-struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP {
- u8 memspace; /* DWORD 0 */
- u8 type[2]; /* DWORD 0 */
- u8 pf; /* DWORD 0 */
- u8 rsvd0[13]; /* DWORD 0 */
- u8 membar1lo[15]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR1_LO_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 1 - High Address Register. */
-struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP {
- u8 membar1hi[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR1_HI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 2 - Low Address Register. */
-struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP {
- u8 memspace; /* DWORD 0 */
- u8 type[2]; /* DWORD 0 */
- u8 pf; /* DWORD 0 */
- u8 rsvd0[17]; /* DWORD 0 */
- u8 membar2lo[11]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR2_LO_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Memory BAR 2 - High Address Register. */
-struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP {
- u8 membar2hi[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MEMBAR2_HI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Subsystem Vendor and ID (Function 0) Register. */
-struct BE_PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP {
- u8 subsys_vendor_id[16]; /* DWORD 0 */
- u8 subsys_id[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Subsystem Vendor and ID (Function 1) Register. */
-struct BE_PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP {
- u8 subsys_vendor_id[16]; /* DWORD 0 */
- u8 subsys_id[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Semaphore Register. */
-struct BE_PCICFG_SEMAPHORE_CSR_AMAP {
- u8 locked; /* DWORD 0 */
- u8 rsvd0[31]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SEMAPHORE_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Soft Reset Register. */
-struct BE_PCICFG_SOFT_RESET_CSR_AMAP {
- u8 rsvd0[7]; /* DWORD 0 */
- u8 softreset; /* DWORD 0 */
- u8 rsvd1[16]; /* DWORD 0 */
- u8 nec_ll_rcvdetect_i[8]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SOFT_RESET_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Unrecoverable Error Status (Low) Register. Each bit corresponds to
- * an internal Unrecoverable Error. These are set by hardware and may be
- * cleared by writing a one to the respective bit(s) to be cleared. Any
- * bit being set that is also unmasked will result in Unrecoverable Error
- * interrupt notification to the host CPU and/or Server Management chip
- * and the transitioning of BladeEngine to an Offline state.
- */
-struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP {
- u8 cev_ue_status; /* DWORD 0 */
- u8 ctx_ue_status; /* DWORD 0 */
- u8 dbuf_ue_status; /* DWORD 0 */
- u8 erx_ue_status; /* DWORD 0 */
- u8 host_ue_status; /* DWORD 0 */
- u8 mpu_ue_status; /* DWORD 0 */
- u8 ndma_ue_status; /* DWORD 0 */
- u8 ptc_ue_status; /* DWORD 0 */
- u8 rdma_ue_status; /* DWORD 0 */
- u8 rxf_ue_status; /* DWORD 0 */
- u8 rxips_ue_status; /* DWORD 0 */
- u8 rxulp0_ue_status; /* DWORD 0 */
- u8 rxulp1_ue_status; /* DWORD 0 */
- u8 rxulp2_ue_status; /* DWORD 0 */
- u8 tim_ue_status; /* DWORD 0 */
- u8 tpost_ue_status; /* DWORD 0 */
- u8 tpre_ue_status; /* DWORD 0 */
- u8 txips_ue_status; /* DWORD 0 */
- u8 txulp0_ue_status; /* DWORD 0 */
- u8 txulp1_ue_status; /* DWORD 0 */
- u8 uc_ue_status; /* DWORD 0 */
- u8 wdma_ue_status; /* DWORD 0 */
- u8 txulp2_ue_status; /* DWORD 0 */
- u8 host1_ue_status; /* DWORD 0 */
- u8 p0_ob_link_ue_status; /* DWORD 0 */
- u8 p1_ob_link_ue_status; /* DWORD 0 */
- u8 host_gpio_ue_status; /* DWORD 0 */
- u8 mbox_netw_ue_status; /* DWORD 0 */
- u8 mbox_stor_ue_status; /* DWORD 0 */
- u8 axgmac0_ue_status; /* DWORD 0 */
- u8 axgmac1_ue_status; /* DWORD 0 */
- u8 mpu_intpend_ue_status; /* DWORD 0 */
-} __packed;
-struct PCICFG_UE_STATUS_LOW_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Unrecoverable Error Status (High) Register. Each bit corresponds to
- * an internal Unrecoverable Error. These are set by hardware and may be
- * cleared by writing a one to the respective bit(s) to be cleared. Any
- * bit being set that is also unmasked will result in Unrecoverable Error
- * interrupt notification to the host CPU and/or Server Management chip;
- * and the transitioning of BladeEngine to an Offline state.
- */
-struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP {
- u8 jtag_ue_status; /* DWORD 0 */
- u8 lpcmemhost_ue_status; /* DWORD 0 */
- u8 mgmt_mac_ue_status; /* DWORD 0 */
- u8 mpu_iram_ue_status; /* DWORD 0 */
- u8 pcs0online_ue_status; /* DWORD 0 */
- u8 pcs1online_ue_status; /* DWORD 0 */
- u8 pctl0_ue_status; /* DWORD 0 */
- u8 pctl1_ue_status; /* DWORD 0 */
- u8 pmem_ue_status; /* DWORD 0 */
- u8 rr_ue_status; /* DWORD 0 */
- u8 rxpp_ue_status; /* DWORD 0 */
- u8 txpb_ue_status; /* DWORD 0 */
- u8 txp_ue_status; /* DWORD 0 */
- u8 xaui_ue_status; /* DWORD 0 */
- u8 arm_ue_status; /* DWORD 0 */
- u8 ipc_ue_status; /* DWORD 0 */
- u8 rsvd0[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_UE_STATUS_HI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Unrecoverable Error Mask (Low) Register. Each bit, when set to one,
- * will mask the associated Unrecoverable Error status bit from notification
- * of Unrecoverable Error to the host CPU and/or Server Managment chip and the
- * transitioning of all BladeEngine units to an Offline state.
- */
-struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP {
- u8 cev_ue_mask; /* DWORD 0 */
- u8 ctx_ue_mask; /* DWORD 0 */
- u8 dbuf_ue_mask; /* DWORD 0 */
- u8 erx_ue_mask; /* DWORD 0 */
- u8 host_ue_mask; /* DWORD 0 */
- u8 mpu_ue_mask; /* DWORD 0 */
- u8 ndma_ue_mask; /* DWORD 0 */
- u8 ptc_ue_mask; /* DWORD 0 */
- u8 rdma_ue_mask; /* DWORD 0 */
- u8 rxf_ue_mask; /* DWORD 0 */
- u8 rxips_ue_mask; /* DWORD 0 */
- u8 rxulp0_ue_mask; /* DWORD 0 */
- u8 rxulp1_ue_mask; /* DWORD 0 */
- u8 rxulp2_ue_mask; /* DWORD 0 */
- u8 tim_ue_mask; /* DWORD 0 */
- u8 tpost_ue_mask; /* DWORD 0 */
- u8 tpre_ue_mask; /* DWORD 0 */
- u8 txips_ue_mask; /* DWORD 0 */
- u8 txulp0_ue_mask; /* DWORD 0 */
- u8 txulp1_ue_mask; /* DWORD 0 */
- u8 uc_ue_mask; /* DWORD 0 */
- u8 wdma_ue_mask; /* DWORD 0 */
- u8 txulp2_ue_mask; /* DWORD 0 */
- u8 host1_ue_mask; /* DWORD 0 */
- u8 p0_ob_link_ue_mask; /* DWORD 0 */
- u8 p1_ob_link_ue_mask; /* DWORD 0 */
- u8 host_gpio_ue_mask; /* DWORD 0 */
- u8 mbox_netw_ue_mask; /* DWORD 0 */
- u8 mbox_stor_ue_mask; /* DWORD 0 */
- u8 axgmac0_ue_mask; /* DWORD 0 */
- u8 axgmac1_ue_mask; /* DWORD 0 */
- u8 mpu_intpend_ue_mask; /* DWORD 0 */
-} __packed;
-struct PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Unrecoverable Error Mask (High) Register. Each bit, when set to one,
- * will mask the associated Unrecoverable Error status bit from notification
- * of Unrecoverable Error to the host CPU and/or Server Managment chip and the
- * transitioning of all BladeEngine units to an Offline state.
- */
-struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP {
- u8 jtag_ue_mask; /* DWORD 0 */
- u8 lpcmemhost_ue_mask; /* DWORD 0 */
- u8 mgmt_mac_ue_mask; /* DWORD 0 */
- u8 mpu_iram_ue_mask; /* DWORD 0 */
- u8 pcs0online_ue_mask; /* DWORD 0 */
- u8 pcs1online_ue_mask; /* DWORD 0 */
- u8 pctl0_ue_mask; /* DWORD 0 */
- u8 pctl1_ue_mask; /* DWORD 0 */
- u8 pmem_ue_mask; /* DWORD 0 */
- u8 rr_ue_mask; /* DWORD 0 */
- u8 rxpp_ue_mask; /* DWORD 0 */
- u8 txpb_ue_mask; /* DWORD 0 */
- u8 txp_ue_mask; /* DWORD 0 */
- u8 xaui_ue_mask; /* DWORD 0 */
- u8 arm_ue_mask; /* DWORD 0 */
- u8 ipc_ue_mask; /* DWORD 0 */
- u8 rsvd0[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_UE_STATUS_HI_MASK_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Online Control Register 0. This register controls various units within
- * BladeEngine being in an Online or Offline state.
- */
-struct BE_PCICFG_ONLINE0_CSR_AMAP {
- u8 cev_online; /* DWORD 0 */
- u8 ctx_online; /* DWORD 0 */
- u8 dbuf_online; /* DWORD 0 */
- u8 erx_online; /* DWORD 0 */
- u8 host_online; /* DWORD 0 */
- u8 mpu_online; /* DWORD 0 */
- u8 ndma_online; /* DWORD 0 */
- u8 ptc_online; /* DWORD 0 */
- u8 rdma_online; /* DWORD 0 */
- u8 rxf_online; /* DWORD 0 */
- u8 rxips_online; /* DWORD 0 */
- u8 rxulp0_online; /* DWORD 0 */
- u8 rxulp1_online; /* DWORD 0 */
- u8 rxulp2_online; /* DWORD 0 */
- u8 tim_online; /* DWORD 0 */
- u8 tpost_online; /* DWORD 0 */
- u8 tpre_online; /* DWORD 0 */
- u8 txips_online; /* DWORD 0 */
- u8 txulp0_online; /* DWORD 0 */
- u8 txulp1_online; /* DWORD 0 */
- u8 uc_online; /* DWORD 0 */
- u8 wdma_online; /* DWORD 0 */
- u8 txulp2_online; /* DWORD 0 */
- u8 host1_online; /* DWORD 0 */
- u8 p0_ob_link_online; /* DWORD 0 */
- u8 p1_ob_link_online; /* DWORD 0 */
- u8 host_gpio_online; /* DWORD 0 */
- u8 mbox_netw_online; /* DWORD 0 */
- u8 mbox_stor_online; /* DWORD 0 */
- u8 axgmac0_online; /* DWORD 0 */
- u8 axgmac1_online; /* DWORD 0 */
- u8 mpu_intpend_online; /* DWORD 0 */
-} __packed;
-struct PCICFG_ONLINE0_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Online Control Register 1. This register controls various units within
- * BladeEngine being in an Online or Offline state.
- */
-struct BE_PCICFG_ONLINE1_CSR_AMAP {
- u8 jtag_online; /* DWORD 0 */
- u8 lpcmemhost_online; /* DWORD 0 */
- u8 mgmt_mac_online; /* DWORD 0 */
- u8 mpu_iram_online; /* DWORD 0 */
- u8 pcs0online_online; /* DWORD 0 */
- u8 pcs1online_online; /* DWORD 0 */
- u8 pctl0_online; /* DWORD 0 */
- u8 pctl1_online; /* DWORD 0 */
- u8 pmem_online; /* DWORD 0 */
- u8 rr_online; /* DWORD 0 */
- u8 rxpp_online; /* DWORD 0 */
- u8 txpb_online; /* DWORD 0 */
- u8 txp_online; /* DWORD 0 */
- u8 xaui_online; /* DWORD 0 */
- u8 arm_online; /* DWORD 0 */
- u8 ipc_online; /* DWORD 0 */
- u8 rsvd0[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ONLINE1_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Host Timer Register. */
-struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP {
- u8 hosttimer[24]; /* DWORD 0 */
- u8 hostintr; /* DWORD 0 */
- u8 rsvd0[7]; /* DWORD 0 */
-} __packed;
-struct PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP {
- u32 dw[1];
-};
-
-/* Scratchpad Register (for software use). */
-struct BE_PCICFG_SCRATCHPAD_CSR_AMAP {
- u8 scratchpad[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_SCRATCHPAD_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Capabilities Register. */
-struct BE_PCICFG_PCIE_CAP_CSR_AMAP {
- u8 capid[8]; /* DWORD 0 */
- u8 nextcap[8]; /* DWORD 0 */
- u8 capver[4]; /* DWORD 0 */
- u8 devport[4]; /* DWORD 0 */
- u8 rsvd0[6]; /* DWORD 0 */
- u8 rsvd1[2]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_CAP_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Device Capabilities Register. */
-struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP {
- u8 payload[3]; /* DWORD 0 */
- u8 rsvd0[3]; /* DWORD 0 */
- u8 lo_lat[3]; /* DWORD 0 */
- u8 l1_lat[3]; /* DWORD 0 */
- u8 rsvd1[3]; /* DWORD 0 */
- u8 rsvd2[3]; /* DWORD 0 */
- u8 pwr_value[8]; /* DWORD 0 */
- u8 pwr_scale[2]; /* DWORD 0 */
- u8 rsvd3[4]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_DEVCAP_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Device Control/Status Registers. */
-struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP {
- u8 CorrErrReportEn; /* DWORD 0 */
- u8 NonFatalErrReportEn; /* DWORD 0 */
- u8 FatalErrReportEn; /* DWORD 0 */
- u8 UnsuppReqReportEn; /* DWORD 0 */
- u8 EnableRelaxOrder; /* DWORD 0 */
- u8 Max_Payload_Size[3]; /* DWORD 0 */
- u8 ExtendTagFieldEnable; /* DWORD 0 */
- u8 PhantomFnEnable; /* DWORD 0 */
- u8 AuxPwrPMEnable; /* DWORD 0 */
- u8 EnableNoSnoop; /* DWORD 0 */
- u8 Max_Read_Req_Size[3]; /* DWORD 0 */
- u8 rsvd0; /* DWORD 0 */
- u8 CorrErrDetect; /* DWORD 0 */
- u8 NonFatalErrDetect; /* DWORD 0 */
- u8 FatalErrDetect; /* DWORD 0 */
- u8 UnsuppReqDetect; /* DWORD 0 */
- u8 AuxPwrDetect; /* DWORD 0 */
- u8 TransPending; /* DWORD 0 */
- u8 rsvd1[10]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Link Capabilities Register. */
-struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP {
- u8 MaxLinkSpeed[4]; /* DWORD 0 */
- u8 MaxLinkWidth[6]; /* DWORD 0 */
- u8 ASPMSupport[2]; /* DWORD 0 */
- u8 L0sExitLat[3]; /* DWORD 0 */
- u8 L1ExitLat[3]; /* DWORD 0 */
- u8 rsvd0[6]; /* DWORD 0 */
- u8 PortNum[8]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_LINK_CAP_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express Link Status Register. */
-struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP {
- u8 ASPMCtl[2]; /* DWORD 0 */
- u8 rsvd0; /* DWORD 0 */
- u8 ReadCmplBndry; /* DWORD 0 */
- u8 LinkDisable; /* DWORD 0 */
- u8 RetrainLink; /* DWORD 0 */
- u8 CommonClkConfig; /* DWORD 0 */
- u8 ExtendSync; /* DWORD 0 */
- u8 rsvd1[8]; /* DWORD 0 */
- u8 LinkSpeed[4]; /* DWORD 0 */
- u8 NegLinkWidth[6]; /* DWORD 0 */
- u8 LinkTrainErr; /* DWORD 0 */
- u8 LinkTrain; /* DWORD 0 */
- u8 SlotClkConfig; /* DWORD 0 */
- u8 rsvd2[3]; /* DWORD 0 */
-} __packed;
-struct PCICFG_PCIE_LINK_STATUS_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI Configuration Register. */
-struct BE_PCICFG_MSI_CSR_AMAP {
- u8 capid[8]; /* DWORD 0 */
- u8 nextptr[8]; /* DWORD 0 */
- u8 tablesize[11]; /* DWORD 0 */
- u8 rsvd0[3]; /* DWORD 0 */
- u8 funcmask; /* DWORD 0 */
- u8 en; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* MSI-X Table Offset Register. */
-struct BE_PCICFG_MSIX_TABLE_CSR_AMAP {
- u8 tablebir[3]; /* DWORD 0 */
- u8 offset[29]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_TABLE_CSR_AMAP {
- u32 dw[1];
-};
-
-/* MSI-X PBA Offset Register. */
-struct BE_PCICFG_MSIX_PBA_CSR_AMAP {
- u8 pbabir[3]; /* DWORD 0 */
- u8 offset[29]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_PBA_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI-X Message Vector Control Register. */
-struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP {
- u8 vector_control; /* DWORD 0 */
- u8 rsvd0[31]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI-X Message Data Register. */
-struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP {
- u8 data[16]; /* DWORD 0 */
- u8 rsvd0[16]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_MSG_DATA_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI-X Message Address Register - High Part. */
-struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP {
- u8 addr[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP {
- u32 dw[1];
-};
-
-/* PCI Express MSI-X Message Address Register - Low Part. */
-struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP {
- u8 rsvd0[2]; /* DWORD 0 */
- u8 addr[30]; /* DWORD 0 */
-} __packed;
-struct PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_18_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_18_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_19_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_19_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_20_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[25][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_20_RSVD_AMAP {
- u32 dw[26];
-};
-
-struct BE_PCICFG_ANON_21_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[1919][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_21_RSVD_AMAP {
- u32 dw[1920];
-};
-
-struct BE_PCICFG_ANON_22_MESSAGE_AMAP {
- struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP vec_ctrl;
- struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP msg_data;
- struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP addr_hi;
- struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP addr_low;
-} __packed;
-struct PCICFG_ANON_22_MESSAGE_AMAP {
- u32 dw[4];
-};
-
-struct BE_PCICFG_ANON_23_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[895][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_23_RSVD_AMAP {
- u32 dw[896];
-};
-
-/* These PCI Configuration Space registers are for the Storage Function of
- * BladeEngine (Function 0). In the memory map of the registers below their
- * table,
- */
-struct BE_PCICFG0_CSRMAP_AMAP {
- struct BE_PCICFG_ID_CSR_AMAP id;
- u8 rsvd0[32]; /* DWORD 1 */
- u8 rsvd1[32]; /* DWORD 2 */
- u8 rsvd2[32]; /* DWORD 3 */
- struct BE_PCICFG_IOBAR_CSR_AMAP iobar;
- struct BE_PCICFG_MEMBAR0_CSR_AMAP membar0;
- struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP membar1_lo;
- struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP membar1_hi;
- struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP membar2_lo;
- struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP membar2_hi;
- u8 rsvd3[32]; /* DWORD 10 */
- struct BE_PCICFG_SUBSYSTEM_ID_F0_CSR_AMAP subsystem_id;
- u8 rsvd4[32]; /* DWORD 12 */
- u8 rsvd5[32]; /* DWORD 13 */
- u8 rsvd6[32]; /* DWORD 14 */
- u8 rsvd7[32]; /* DWORD 15 */
- struct BE_PCICFG_SEMAPHORE_CSR_AMAP semaphore[4];
- struct BE_PCICFG_SOFT_RESET_CSR_AMAP soft_reset;
- u8 rsvd8[32]; /* DWORD 21 */
- struct BE_PCICFG_SCRATCHPAD_CSR_AMAP scratchpad;
- u8 rsvd9[32]; /* DWORD 23 */
- u8 rsvd10[32]; /* DWORD 24 */
- u8 rsvd11[32]; /* DWORD 25 */
- u8 rsvd12[32]; /* DWORD 26 */
- u8 rsvd13[32]; /* DWORD 27 */
- u8 rsvd14[2][32]; /* DWORD 28 */
- u8 rsvd15[32]; /* DWORD 30 */
- u8 rsvd16[32]; /* DWORD 31 */
- u8 rsvd17[8][32]; /* DWORD 32 */
- struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP ue_status_low;
- struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP ue_status_hi;
- struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP ue_status_low_mask;
- struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP ue_status_hi_mask;
- struct BE_PCICFG_ONLINE0_CSR_AMAP online0;
- struct BE_PCICFG_ONLINE1_CSR_AMAP online1;
- u8 rsvd18[32]; /* DWORD 46 */
- u8 rsvd19[32]; /* DWORD 47 */
- u8 rsvd20[32]; /* DWORD 48 */
- u8 rsvd21[32]; /* DWORD 49 */
- struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP host_timer_int_ctrl;
- u8 rsvd22[32]; /* DWORD 51 */
- struct BE_PCICFG_PCIE_CAP_CSR_AMAP pcie_cap;
- struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP pcie_devcap;
- struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP pcie_control_status;
- struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP pcie_link_cap;
- struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP pcie_link_status;
- struct BE_PCICFG_MSI_CSR_AMAP msi;
- struct BE_PCICFG_MSIX_TABLE_CSR_AMAP msix_table_offset;
- struct BE_PCICFG_MSIX_PBA_CSR_AMAP msix_pba_offset;
- u8 rsvd23[32]; /* DWORD 60 */
- u8 rsvd24[32]; /* DWORD 61 */
- u8 rsvd25[32]; /* DWORD 62 */
- u8 rsvd26[32]; /* DWORD 63 */
- u8 rsvd27[32]; /* DWORD 64 */
- u8 rsvd28[32]; /* DWORD 65 */
- u8 rsvd29[32]; /* DWORD 66 */
- u8 rsvd30[32]; /* DWORD 67 */
- u8 rsvd31[32]; /* DWORD 68 */
- u8 rsvd32[32]; /* DWORD 69 */
- u8 rsvd33[32]; /* DWORD 70 */
- u8 rsvd34[32]; /* DWORD 71 */
- u8 rsvd35[32]; /* DWORD 72 */
- u8 rsvd36[32]; /* DWORD 73 */
- u8 rsvd37[32]; /* DWORD 74 */
- u8 rsvd38[32]; /* DWORD 75 */
- u8 rsvd39[32]; /* DWORD 76 */
- u8 rsvd40[32]; /* DWORD 77 */
- u8 rsvd41[32]; /* DWORD 78 */
- u8 rsvd42[32]; /* DWORD 79 */
- u8 rsvd43[32]; /* DWORD 80 */
- u8 rsvd44[32]; /* DWORD 81 */
- u8 rsvd45[32]; /* DWORD 82 */
- u8 rsvd46[32]; /* DWORD 83 */
- u8 rsvd47[32]; /* DWORD 84 */
- u8 rsvd48[32]; /* DWORD 85 */
- u8 rsvd49[32]; /* DWORD 86 */
- u8 rsvd50[32]; /* DWORD 87 */
- u8 rsvd51[32]; /* DWORD 88 */
- u8 rsvd52[32]; /* DWORD 89 */
- u8 rsvd53[32]; /* DWORD 90 */
- u8 rsvd54[32]; /* DWORD 91 */
- u8 rsvd55[32]; /* DWORD 92 */
- u8 rsvd56[832]; /* DWORD 93 */
- u8 rsvd57[32]; /* DWORD 119 */
- u8 rsvd58[32]; /* DWORD 120 */
- u8 rsvd59[32]; /* DWORD 121 */
- u8 rsvd60[32]; /* DWORD 122 */
- u8 rsvd61[32]; /* DWORD 123 */
- u8 rsvd62[32]; /* DWORD 124 */
- u8 rsvd63[32]; /* DWORD 125 */
- u8 rsvd64[32]; /* DWORD 126 */
- u8 rsvd65[32]; /* DWORD 127 */
- u8 rsvd66[61440]; /* DWORD 128 */
- struct BE_PCICFG_ANON_22_MESSAGE_AMAP message[32];
- u8 rsvd67[28672]; /* DWORD 2176 */
- u8 rsvd68[32]; /* DWORD 3072 */
- u8 rsvd69[1023][32]; /* DWORD 3073 */
-} __packed;
-struct PCICFG0_CSRMAP_AMAP {
- u32 dw[4096];
-};
-
-struct BE_PCICFG_ANON_24_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_24_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_25_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_25_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_26_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
-} __packed;
-struct PCICFG_ANON_26_RSVD_AMAP {
- u32 dw[1];
-};
-
-struct BE_PCICFG_ANON_27_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_27_RSVD_AMAP {
- u32 dw[2];
-};
-
-struct BE_PCICFG_ANON_28_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[3][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_28_RSVD_AMAP {
- u32 dw[4];
-};
-
-struct BE_PCICFG_ANON_29_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[36][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_29_RSVD_AMAP {
- u32 dw[37];
-};
-
-struct BE_PCICFG_ANON_30_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[1930][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_30_RSVD_AMAP {
- u32 dw[1931];
-};
-
-struct BE_PCICFG_ANON_31_MESSAGE_AMAP {
- struct BE_PCICFG_MSIX_VECTOR_CONTROL_CSR_AMAP vec_ctrl;
- struct BE_PCICFG_MSIX_MSG_DATA_CSR_AMAP msg_data;
- struct BE_PCICFG_MSIX_MSG_ADDR_HI_CSR_AMAP addr_hi;
- struct BE_PCICFG_MSIX_MSG_ADDR_LO_CSR_AMAP addr_low;
-} __packed;
-struct PCICFG_ANON_31_MESSAGE_AMAP {
- u32 dw[4];
-};
-
-struct BE_PCICFG_ANON_32_RSVD_AMAP {
- u8 rsvd0[32]; /* DWORD 0 */
- u8 rsvd1[895][32]; /* DWORD 1 */
-} __packed;
-struct PCICFG_ANON_32_RSVD_AMAP {
- u32 dw[896];
-};
-
-/* This PCI configuration space register map is for the Networking Function of
- * BladeEngine (Function 1).
- */
-struct BE_PCICFG1_CSRMAP_AMAP {
- struct BE_PCICFG_ID_CSR_AMAP id;
- u8 rsvd0[32]; /* DWORD 1 */
- u8 rsvd1[32]; /* DWORD 2 */
- u8 rsvd2[32]; /* DWORD 3 */
- struct BE_PCICFG_IOBAR_CSR_AMAP iobar;
- struct BE_PCICFG_MEMBAR0_CSR_AMAP membar0;
- struct BE_PCICFG_MEMBAR1_LO_CSR_AMAP membar1_lo;
- struct BE_PCICFG_MEMBAR1_HI_CSR_AMAP membar1_hi;
- struct BE_PCICFG_MEMBAR2_LO_CSR_AMAP membar2_lo;
- struct BE_PCICFG_MEMBAR2_HI_CSR_AMAP membar2_hi;
- u8 rsvd3[32]; /* DWORD 10 */
- struct BE_PCICFG_SUBSYSTEM_ID_F1_CSR_AMAP subsystem_id;
- u8 rsvd4[32]; /* DWORD 12 */
- u8 rsvd5[32]; /* DWORD 13 */
- u8 rsvd6[32]; /* DWORD 14 */
- u8 rsvd7[32]; /* DWORD 15 */
- struct BE_PCICFG_SEMAPHORE_CSR_AMAP semaphore[4];
- struct BE_PCICFG_SOFT_RESET_CSR_AMAP soft_reset;
- u8 rsvd8[32]; /* DWORD 21 */
- struct BE_PCICFG_SCRATCHPAD_CSR_AMAP scratchpad;
- u8 rsvd9[32]; /* DWORD 23 */
- u8 rsvd10[32]; /* DWORD 24 */
- u8 rsvd11[32]; /* DWORD 25 */
- u8 rsvd12[32]; /* DWORD 26 */
- u8 rsvd13[32]; /* DWORD 27 */
- u8 rsvd14[2][32]; /* DWORD 28 */
- u8 rsvd15[32]; /* DWORD 30 */
- u8 rsvd16[32]; /* DWORD 31 */
- u8 rsvd17[8][32]; /* DWORD 32 */
- struct BE_PCICFG_UE_STATUS_LOW_CSR_AMAP ue_status_low;
- struct BE_PCICFG_UE_STATUS_HI_CSR_AMAP ue_status_hi;
- struct BE_PCICFG_UE_STATUS_LOW_MASK_CSR_AMAP ue_status_low_mask;
- struct BE_PCICFG_UE_STATUS_HI_MASK_CSR_AMAP ue_status_hi_mask;
- struct BE_PCICFG_ONLINE0_CSR_AMAP online0;
- struct BE_PCICFG_ONLINE1_CSR_AMAP online1;
- u8 rsvd18[32]; /* DWORD 46 */
- u8 rsvd19[32]; /* DWORD 47 */
- u8 rsvd20[32]; /* DWORD 48 */
- u8 rsvd21[32]; /* DWORD 49 */
- struct BE_PCICFG_HOST_TIMER_INT_CTRL_CSR_AMAP host_timer_int_ctrl;
- u8 rsvd22[32]; /* DWORD 51 */
- struct BE_PCICFG_PCIE_CAP_CSR_AMAP pcie_cap;
- struct BE_PCICFG_PCIE_DEVCAP_CSR_AMAP pcie_devcap;
- struct BE_PCICFG_PCIE_CONTROL_STATUS_CSR_AMAP pcie_control_status;
- struct BE_PCICFG_PCIE_LINK_CAP_CSR_AMAP pcie_link_cap;
- struct BE_PCICFG_PCIE_LINK_STATUS_CSR_AMAP pcie_link_status;
- struct BE_PCICFG_MSI_CSR_AMAP msi;
- struct BE_PCICFG_MSIX_TABLE_CSR_AMAP msix_table_offset;
- struct BE_PCICFG_MSIX_PBA_CSR_AMAP msix_pba_offset;
- u8 rsvd23[64]; /* DWORD 60 */
- u8 rsvd24[32]; /* DWORD 62 */
- u8 rsvd25[32]; /* DWORD 63 */
- u8 rsvd26[32]; /* DWORD 64 */
- u8 rsvd27[32]; /* DWORD 65 */
- u8 rsvd28[32]; /* DWORD 66 */
- u8 rsvd29[32]; /* DWORD 67 */
- u8 rsvd30[32]; /* DWORD 68 */
- u8 rsvd31[32]; /* DWORD 69 */
- u8 rsvd32[32]; /* DWORD 70 */
- u8 rsvd33[32]; /* DWORD 71 */
- u8 rsvd34[32]; /* DWORD 72 */
- u8 rsvd35[32]; /* DWORD 73 */
- u8 rsvd36[32]; /* DWORD 74 */
- u8 rsvd37[128]; /* DWORD 75 */
- u8 rsvd38[32]; /* DWORD 79 */
- u8 rsvd39[1184]; /* DWORD 80 */
- u8 rsvd40[61792]; /* DWORD 117 */
- struct BE_PCICFG_ANON_31_MESSAGE_AMAP message[32];
- u8 rsvd41[28672]; /* DWORD 2176 */
- u8 rsvd42[32]; /* DWORD 3072 */
- u8 rsvd43[1023][32]; /* DWORD 3073 */
-} __packed;
-struct PCICFG1_CSRMAP_AMAP {
- u32 dw[4096];
-};
-
-#endif /* __pcicfg_amap_h__ */
diff --git a/drivers/staging/benet/post_codes.h b/drivers/staging/benet/post_codes.h
deleted file mode 100644
index 6d1621f5f5fb..000000000000
--- a/drivers/staging/benet/post_codes.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __post_codes_amap_h__
-#define __post_codes_amap_h__
-
-/* --- MGMT_HBA_POST_STAGE_ENUM --- */
-#define POST_STAGE_POWER_ON_RESET (0) /* State after a cold or warm boot. */
-#define POST_STAGE_AWAITING_HOST_RDY (1) /* ARM boot code awaiting a
- go-ahed from the host. */
-#define POST_STAGE_HOST_RDY (2) /* Host has given go-ahed to ARM. */
-#define POST_STAGE_BE_RESET (3) /* Host wants to reset chip, this is a chip
- workaround */
-#define POST_STAGE_SEEPROM_CS_START (256) /* SEEPROM checksum
- test start. */
-#define POST_STAGE_SEEPROM_CS_DONE (257) /* SEEPROM checksum test
- done. */
-#define POST_STAGE_DDR_CONFIG_START (512) /* DDR configuration start. */
-#define POST_STAGE_DDR_CONFIG_DONE (513) /* DDR configuration done. */
-#define POST_STAGE_DDR_CALIBRATE_START (768) /* DDR calibration start. */
-#define POST_STAGE_DDR_CALIBRATE_DONE (769) /* DDR calibration done. */
-#define POST_STAGE_DDR_TEST_START (1024) /* DDR memory test start. */
-#define POST_STAGE_DDR_TEST_DONE (1025) /* DDR memory test done. */
-#define POST_STAGE_REDBOOT_INIT_START (1536) /* Redboot starts execution. */
-#define POST_STAGE_REDBOOT_INIT_DONE (1537) /* Redboot done execution. */
-#define POST_STAGE_FW_IMAGE_LOAD_START (1792) /* Firmware image load to
- DDR start. */
-#define POST_STAGE_FW_IMAGE_LOAD_DONE (1793) /* Firmware image load
- to DDR done. */
-#define POST_STAGE_ARMFW_START (2048) /* ARMfw runtime code
- starts execution. */
-#define POST_STAGE_DHCP_QUERY_START (2304) /* DHCP server query start. */
-#define POST_STAGE_DHCP_QUERY_DONE (2305) /* DHCP server query done. */
-#define POST_STAGE_BOOT_TARGET_DISCOVERY_START (2560) /* Boot Target
- Discovery Start. */
-#define POST_STAGE_BOOT_TARGET_DISCOVERY_DONE (2561) /* Boot Target
- Discovery Done. */
-#define POST_STAGE_RC_OPTION_SET (2816) /* Remote configuration
- option is set in SEEPROM */
-#define POST_STAGE_SWITCH_LINK (2817) /* Wait for link up on switch */
-#define POST_STAGE_SEND_ICDS_MESSAGE (2818) /* Send the ICDS message
- to switch */
-#define POST_STAGE_PERFROM_TFTP (2819) /* Download xml using TFTP */
-#define POST_STAGE_PARSE_XML (2820) /* Parse XML file */
-#define POST_STAGE_DOWNLOAD_IMAGE (2821) /* Download IMAGE from
- TFTP server */
-#define POST_STAGE_FLASH_IMAGE (2822) /* Flash the IMAGE */
-#define POST_STAGE_RC_DONE (2823) /* Remote configuration
- complete */
-#define POST_STAGE_REBOOT_SYSTEM (2824) /* Upgrade IMAGE done,
- reboot required */
-#define POST_STAGE_MAC_ADDRESS (3072) /* MAC Address Check */
-#define POST_STAGE_ARMFW_READY (49152) /* ARMfw is done with POST
- and ready. */
-#define POST_STAGE_ARMFW_UE (61440) /* ARMfw has asserted an
- unrecoverable error. The
- lower 3 hex digits of the
- stage code identify the
- unique error code.
- */
-
-/* This structure defines the format of the MPU semaphore
- * register when used for POST.
- */
-struct BE_MGMT_HBA_POST_STATUS_STRUCT_AMAP {
- u8 stage[16]; /* DWORD 0 */
- u8 rsvd0[10]; /* DWORD 0 */
- u8 iscsi_driver_loaded; /* DWORD 0 */
- u8 option_rom_installed; /* DWORD 0 */
- u8 iscsi_ip_conflict; /* DWORD 0 */
- u8 iscsi_no_ip; /* DWORD 0 */
- u8 backup_fw; /* DWORD 0 */
- u8 error; /* DWORD 0 */
-} __packed;
-struct MGMT_HBA_POST_STATUS_STRUCT_AMAP {
- u32 dw[1];
-};
-
-/* --- MGMT_HBA_POST_DUMMY_BITS_ENUM --- */
-#define POST_BIT_ISCSI_LOADED (26)
-#define POST_BIT_OPTROM_INST (27)
-#define POST_BIT_BAD_IP_ADDR (28)
-#define POST_BIT_NO_IP_ADDR (29)
-#define POST_BIT_BACKUP_FW (30)
-#define POST_BIT_ERROR (31)
-
-/* --- MGMT_HBA_POST_DUMMY_VALUES_ENUM --- */
-#define POST_ISCSI_DRIVER_LOADED (67108864)
-#define POST_OPTROM_INSTALLED (134217728)
-#define POST_ISCSI_IP_ADDRESS_CONFLICT (268435456)
-#define POST_ISCSI_NO_IP_ADDRESS (536870912)
-#define POST_BACKUP_FW_LOADED (1073741824)
-#define POST_FATAL_ERROR (2147483648)
-
-#endif /* __post_codes_amap_h__ */
diff --git a/drivers/staging/benet/regmap.h b/drivers/staging/benet/regmap.h
deleted file mode 100644
index e816ba210e83..000000000000
--- a/drivers/staging/benet/regmap.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2005 - 2008 ServerEngines
- * All rights reserved.
- *
- * 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. The full GNU General
- * Public License is included in this distribution in the file called COPYING.
- *
- * Contact Information:
- * linux-drivers@serverengines.com
- *
- * ServerEngines
- * 209 N. Fair Oaks Ave
- * Sunnyvale, CA 94085
- */
-/*
- * Autogenerated by srcgen version: 0127
- */
-#ifndef __regmap_amap_h__
-#define __regmap_amap_h__
-#include "pcicfg.h"
-#include "ep.h"
-#include "cev.h"
-#include "mpu.h"
-#include "doorbells.h"
-
-/*
- * This is the control and status register map for BladeEngine, showing
- * the relative size and offset of each sub-module. The CSR registers
- * are identical for the network and storage PCI functions. The
- * CSR map is shown below, followed by details of each block,
- * in sub-sections. The sub-sections begin with a description
- * of CSRs that are instantiated in multiple blocks.
- */
-struct BE_BLADE_ENGINE_CSRMAP_AMAP {
- struct BE_MPU_CSRMAP_AMAP mpu;
- u8 rsvd0[8192]; /* DWORD 256 */
- u8 rsvd1[8192]; /* DWORD 512 */
- struct BE_CEV_CSRMAP_AMAP cev;
- u8 rsvd2[8192]; /* DWORD 1024 */
- u8 rsvd3[8192]; /* DWORD 1280 */
- u8 rsvd4[8192]; /* DWORD 1536 */
- u8 rsvd5[8192]; /* DWORD 1792 */
- u8 rsvd6[8192]; /* DWORD 2048 */
- u8 rsvd7[8192]; /* DWORD 2304 */
- u8 rsvd8[8192]; /* DWORD 2560 */
- u8 rsvd9[8192]; /* DWORD 2816 */
- u8 rsvd10[8192]; /* DWORD 3072 */
- u8 rsvd11[8192]; /* DWORD 3328 */
- u8 rsvd12[8192]; /* DWORD 3584 */
- u8 rsvd13[8192]; /* DWORD 3840 */
- u8 rsvd14[8192]; /* DWORD 4096 */
- u8 rsvd15[8192]; /* DWORD 4352 */
- u8 rsvd16[8192]; /* DWORD 4608 */
- u8 rsvd17[8192]; /* DWORD 4864 */
- u8 rsvd18[8192]; /* DWORD 5120 */
- u8 rsvd19[8192]; /* DWORD 5376 */
- u8 rsvd20[8192]; /* DWORD 5632 */
- u8 rsvd21[8192]; /* DWORD 5888 */
- u8 rsvd22[8192]; /* DWORD 6144 */
- u8 rsvd23[17152][32]; /* DWORD 6400 */
-} __packed;
-struct BLADE_ENGINE_CSRMAP_AMAP {
- u32 dw[23552];
-};
-
-#endif /* __regmap_amap_h__ */
diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c
index 5ffe269c2382..c2747bc88c6f 100644
--- a/drivers/staging/panel/panel.c
+++ b/drivers/staging/panel/panel.c
@@ -622,7 +622,7 @@ static int set_ctrl_bits(void)
}
/* sets ctrl & data port bits according to current signals values */
-static void set_bits(void)
+static void panel_set_bits(void)
{
set_data_bits();
set_ctrl_bits();
@@ -707,12 +707,12 @@ static void lcd_send_serial(int byte)
*/
for (bit = 0; bit < 8; bit++) {
bits.cl = BIT_CLR; /* CLK low */
- set_bits();
+ panel_set_bits();
bits.da = byte & 1;
- set_bits();
+ panel_set_bits();
udelay(2); /* maintain the data during 2 us before CLK up */
bits.cl = BIT_SET; /* CLK high */
- set_bits();
+ panel_set_bits();
udelay(1); /* maintain the strobe during 1 us */
byte >>= 1;
}
@@ -727,7 +727,7 @@ static void lcd_backlight(int on)
/* The backlight is activated by seting the AUTOFEED line to +5V */
spin_lock(&pprt_lock);
bits.bl = on;
- set_bits();
+ panel_set_bits();
spin_unlock(&pprt_lock);
}
@@ -2164,19 +2164,20 @@ static void __exit panel_cleanup_module(void)
if (scan_timer.function != NULL)
del_timer(&scan_timer);
- if (keypad_enabled)
- misc_deregister(&keypad_dev);
-
- if (lcd_enabled) {
- panel_lcd_print("\x0cLCD driver " PANEL_VERSION
- "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
- misc_deregister(&lcd_dev);
- }
+ if (pprt != NULL) {
+ if (keypad_enabled)
+ misc_deregister(&keypad_dev);
- /* TODO: free all input signals */
+ if (lcd_enabled) {
+ panel_lcd_print("\x0cLCD driver " PANEL_VERSION
+ "\nunloaded.\x1b[Lc\x1b[Lb\x1b[L-");
+ misc_deregister(&lcd_dev);
+ }
- parport_release(pprt);
- parport_unregister_device(pprt);
+ /* TODO: free all input signals */
+ parport_release(pprt);
+ parport_unregister_device(pprt);
+ }
parport_unregister_driver(&panel_driver);
}
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig
index 79c225acd1ad..f636296b54bc 100644
--- a/drivers/staging/rtl8187se/Kconfig
+++ b/drivers/staging/rtl8187se/Kconfig
@@ -1,5 +1,6 @@
config RTL8187SE
tristate "RealTek RTL8187SE Wireless LAN NIC driver"
depends on PCI
+ depends on WIRELESS_EXT && COMPAT_NET_DEV_OPS
default N
---help---
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
index af64cfbe16db..7370296225e1 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
@@ -234,20 +234,21 @@ out:
void ieee80211_crypto_deinit(void)
{
struct list_head *ptr, *n;
+ struct ieee80211_crypto_alg *alg = NULL;
if (hcrypt == NULL)
return;
- for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs;
- ptr = n, n = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
- list_del(ptr);
- printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm "
- "'%s' (deinit)\n", alg->ops->name);
- kfree(alg);
+ list_for_each_safe(ptr, n, &hcrypt->algs) {
+ alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
+ if (alg) {
+ list_del(ptr);
+ printk(KERN_DEBUG
+ "ieee80211_crypt: unregistered algorithm '%s' (deinit)\n",
+ alg->ops->name);
+ kfree(alg);
+ }
}
-
kfree(hcrypt);
}
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index 94534955e38b..66de5cc8ddf1 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -6161,10 +6161,10 @@ static void __exit rtl8180_pci_module_exit(void)
{
pci_unregister_driver (&rtl8180_pci_driver);
rtl8180_proc_module_remove();
- ieee80211_crypto_deinit();
ieee80211_crypto_tkip_exit();
ieee80211_crypto_ccmp_exit();
ieee80211_crypto_wep_exit();
+ ieee80211_crypto_deinit();
DMESG("Exiting");
}
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c
index b003f9a7e151..f716b2e92b65 100644
--- a/drivers/staging/winbond/wbusb.c
+++ b/drivers/staging/winbond/wbusb.c
@@ -319,16 +319,18 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
struct usb_device *udev = interface_to_usbdev(intf);
struct wbsoft_priv *priv;
struct ieee80211_hw *dev;
- int err;
+ int nr, err;
usb_get_dev(udev);
// 20060630.2 Check the device if it already be opened
- err = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
- 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
- 0x0, 0x400, &ltmp, 4, HZ*100 );
- if (err)
+ nr = usb_control_msg(udev, usb_rcvctrlpipe( udev, 0 ),
+ 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
+ 0x0, 0x400, &ltmp, 4, HZ*100 );
+ if (nr < 0) {
+ err = nr;
goto error;
+ }
ltmp = cpu_to_le32(ltmp);
if (ltmp) { // Is already initialized?
@@ -337,8 +339,10 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
}
dev = ieee80211_alloc_hw(sizeof(*priv), &wbsoft_ops);
- if (!dev)
+ if (!dev) {
+ err = -ENOMEM;
goto error;
+ }
priv = dev->priv;
@@ -369,9 +373,11 @@ static int wb35_probe(struct usb_interface *intf, const struct usb_device_id *id
}
dev->extra_tx_headroom = 12; /* FIXME */
- dev->flags = 0;
+ dev->flags = IEEE80211_HW_SIGNAL_UNSPEC;
+ dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
dev->channel_change_time = 1000;
+ dev->max_signal = 100;
dev->queues = 1;
dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &wbsoft_band_2GHz;