From 4184ea7f908d95f329febc3665cf66da8568b467 Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 10 Mar 2009 12:39:20 -0400 Subject: Btrfs: Fix locking around adding new space_info Storage allocated to different raid levels in btrfs is tracked by a btrfs_space_info structure, and all of the current space_infos are collected into a list_head. Most filesystems have 3 or 4 of these structs total, and the list is only changed when new raid levels are added or at unmount time. This commit adds rcu locking on the list head, and properly frees things at unmount time. It also clears the space_info->full flag whenever new space is added to the FS. The locking for the space info list goes like this: reads: protected by rcu_read_lock() writes: protected by the chunk_mutex At unmount time we don't need special locking because all the readers are gone. Signed-off-by: Chris Mason --- fs/btrfs/ctree.h | 9 +++++++++ fs/btrfs/extent-tree.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- fs/btrfs/volumes.c | 2 ++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 82491ba8fa4..5e1d4e30e9d 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -784,7 +784,14 @@ struct btrfs_fs_info { struct list_head dirty_cowonly_roots; struct btrfs_fs_devices *fs_devices; + + /* + * the space_info list is almost entirely read only. It only changes + * when we add a new raid type to the FS, and that happens + * very rarely. RCU is used to protect it. + */ struct list_head space_info; + spinlock_t delalloc_lock; spinlock_t new_trans_lock; u64 delalloc_bytes; @@ -1797,6 +1804,8 @@ int btrfs_cleanup_reloc_trees(struct btrfs_root *root); int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len); u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags); void btrfs_set_inode_space_info(struct btrfs_root *root, struct inode *ionde); +void btrfs_clear_space_info_full(struct btrfs_fs_info *info); + int btrfs_check_metadata_free_space(struct btrfs_root *root); int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode, u64 bytes); diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 9abf81f71c4..fefe83ad205 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "compat.h" #include "hash.h" #include "crc32c.h" @@ -330,13 +331,33 @@ static struct btrfs_space_info *__find_space_info(struct btrfs_fs_info *info, { struct list_head *head = &info->space_info; struct btrfs_space_info *found; - list_for_each_entry(found, head, list) { - if (found->flags == flags) + + rcu_read_lock(); + list_for_each_entry_rcu(found, head, list) { + if (found->flags == flags) { + rcu_read_unlock(); return found; + } } + rcu_read_unlock(); return NULL; } +/* + * after adding space to the filesystem, we need to clear the full flags + * on all the space infos. + */ +void btrfs_clear_space_info_full(struct btrfs_fs_info *info) +{ + struct list_head *head = &info->space_info; + struct btrfs_space_info *found; + + rcu_read_lock(); + list_for_each_entry_rcu(found, head, list) + found->full = 0; + rcu_read_unlock(); +} + static u64 div_factor(u64 num, int factor) { if (factor == 10) @@ -1903,7 +1924,6 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, if (!found) return -ENOMEM; - list_add(&found->list, &info->space_info); INIT_LIST_HEAD(&found->block_groups); init_rwsem(&found->groups_sem); spin_lock_init(&found->lock); @@ -1917,6 +1937,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags, found->full = 0; found->force_alloc = 0; *space_info = found; + list_add_rcu(&found->list, &info->space_info); return 0; } @@ -6320,6 +6341,7 @@ out: int btrfs_free_block_groups(struct btrfs_fs_info *info) { struct btrfs_block_group_cache *block_group; + struct btrfs_space_info *space_info; struct rb_node *n; spin_lock(&info->block_group_cache_lock); @@ -6341,6 +6363,23 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info) spin_lock(&info->block_group_cache_lock); } spin_unlock(&info->block_group_cache_lock); + + /* now that all the block groups are freed, go through and + * free all the space_info structs. This is only called during + * the final stages of unmount, and so we know nobody is + * using them. We call synchronize_rcu() once before we start, + * just to be on the safe side. + */ + synchronize_rcu(); + + while(!list_empty(&info->space_info)) { + space_info = list_entry(info->space_info.next, + struct btrfs_space_info, + list); + + list_del(&space_info->list); + kfree(space_info); + } return 0; } diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 1316139bf9e..7aa3810d7f6 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1459,6 +1459,8 @@ static int __btrfs_grow_device(struct btrfs_trans_handle *trans, device->fs_devices->total_rw_bytes += diff; device->total_bytes = new_size; + btrfs_clear_space_info_full(device->dev_root->fs_info); + return btrfs_update_device(trans, device); } -- cgit v1.2.3 From 913d952eb573c3d1f7487e83b5590e13e7cae2bd Mon Sep 17 00:00:00 2001 From: Chris Mason Date: Tue, 10 Mar 2009 13:17:18 -0400 Subject: Btrfs: Clear space_info full when adding new devices The full flag on the space info structs tells the allocator not to try and allocate more chunks because the devices in the FS are fully allocated. When more devices are added, we need to clear the full flag so the allocator knows it has more space available. Signed-off-by: Chris Mason --- fs/btrfs/volumes.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 7aa3810d7f6..dd06e18e5aa 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -1374,6 +1374,12 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) ret = btrfs_add_device(trans, root, device); } + /* + * we've got more storage, clear any full flags on the space + * infos + */ + btrfs_clear_space_info_full(root->fs_info); + unlock_chunks(root); btrfs_commit_transaction(trans, root); -- cgit v1.2.3 From 48e7a3c95c9f98c2cb6f894820e3cc2d0448e92f Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Tue, 10 Mar 2009 22:43:56 +0100 Subject: HID: fix incorrect free in hiddev If hiddev_open() fails, it wrongly frees the shared hiddev structure kept in hiddev_table instead of the hiddev_list structure allocated for the opened file descriptor. Existing references to this structure will then accessed free memory. This was introduced by 079034073 "HID: hiddev cleanup -- handle all error conditions properly". Signed-off-by: Johannes Weiner Cc: Oliver Neukum Cc: Jiri Kosina Signed-off-by: Andrew Morton Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hiddev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 4940e4d70c2..00ea1ed282a 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -306,7 +306,7 @@ static int hiddev_open(struct inode *inode, struct file *file) return 0; bail: file->private_data = NULL; - kfree(list->hiddev); + kfree(list); return res; } -- cgit v1.2.3 From 96fe2ab830d7dffee1b3d8abf27ced4d7d5765e7 Mon Sep 17 00:00:00 2001 From: Johannes Weiner Date: Tue, 10 Mar 2009 22:44:01 +0100 Subject: HID: fix waitqueue usage in hiddev DECLARE_WAITQUEUE doesn't initialize the wait descriptor's task_list to 'empty' but to zero. prepare_to_wait() will not enqueue the descriptor to the waitqueue and finish_wait() will do list_del_init() on a list head that contains NULL pointers, which oopses. This was introduced by 079034073 "HID: hiddev cleanup -- handle all error conditions properly". The prior code used an unconditional add_to_waitqueue() which didn't care about the wait descriptor's list head and enqueued the thing unconditionally. The new code uses prepare_to_wait() which DOES check the prior list state, so use DEFINE_WAIT instead. Signed-off-by: Johannes Weiner Cc: Oliver Neukum Cc: Jiri Kosina Signed-off-by: Andrew Morton Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hiddev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 00ea1ed282a..1f5b5d4c3c3 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -323,7 +323,7 @@ static ssize_t hiddev_write(struct file * file, const char __user * buffer, size */ static ssize_t hiddev_read(struct file * file, char __user * buffer, size_t count, loff_t *ppos) { - DECLARE_WAITQUEUE(wait, current); + DEFINE_WAIT(wait); struct hiddev_list *list = file->private_data; int event_size; int retval; -- cgit v1.2.3 From 395a87bfefbc400011417e9eaae33169f9f036c0 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Tue, 10 Mar 2009 18:18:47 -0400 Subject: ext4: fix header check in ext4_ext_search_right() for deep extent trees. The ext4_ext_search_right() function is confusing; it uses a "depth" variable which is 0 at the root and maximum at the leaves, but the on-disk metadata uses a "depth" (actually eh_depth) which is opposite: maximum at the root, and 0 at the leaves. The ext4_ext_check_header() function is given a depth and checks the header agaisnt that depth; it expects the on-disk semantics, but we are giving it the opposite in the while loop in this function. We should be giving it the on-disk notion of "depth" which we can get from (p_depth - depth) - and if you look, the last (more commonly hit) call to ext4_ext_check_header() does just this. Sending in the wrong depth results in (incorrect) messages about corruption: EXT4-fs error (device sdb1): ext4_ext_search_right: bad header in inode #2621457: unexpected eh_depth - magic f30a, entries 340, max 340(0), depth 1(2) http://bugzilla.kernel.org/show_bug.cgi?id=12821 Reported-by: David Dindorp Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" --- fs/ext4/extents.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e2eab196875..e0aa4fe4f59 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -1122,7 +1122,8 @@ ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path, struct ext4_extent_idx *ix; struct ext4_extent *ex; ext4_fsblk_t block; - int depth, ee_len; + int depth; /* Note, NOT eh_depth; depth from top of tree */ + int ee_len; BUG_ON(path == NULL); depth = path->p_depth; @@ -1179,7 +1180,8 @@ got_index: if (bh == NULL) return -EIO; eh = ext_block_hdr(bh); - if (ext4_ext_check_header(inode, eh, depth)) { + /* subtract from p_depth to get proper eh_depth */ + if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) { put_bh(bh); return -EIO; } -- cgit v1.2.3 From 2842c3b5449f31470b61db716f1926b594fb6156 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 12 Mar 2009 12:20:01 -0400 Subject: ext4: Print the find_group_flex() warning only once This is a short-term warning, and even printk_ratelimit() can result in too much noise in system logs. So only print it once as a warning. Signed-off-by: "Theodore Ts'o" --- fs/ext4/ialloc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 627f8c3337a..2d2b3585ee9 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c @@ -698,6 +698,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) struct inode *ret; ext4_group_t i; int free = 0; + static int once = 1; ext4_group_t flex_group; /* Cannot create files in a deleted directory */ @@ -719,7 +720,8 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode) ret2 = find_group_flex(sb, dir, &group); if (ret2 == -1) { ret2 = find_group_other(sb, dir, &group); - if (ret2 == 0 && printk_ratelimit()) + if (ret2 == 0 && once) + once = 0; printk(KERN_NOTICE "ext4: find_group_flex " "failed, fallback succeeded dir %lu\n", dir->i_ino); -- cgit v1.2.3 From f507cd22035fdadd5dbb476dd05e9e7ee21c3b84 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Fri, 6 Mar 2009 02:54:09 +0000 Subject: ps3/block: Replace mtd/ps3vram by block/ps3vram Convert the PS3 Video RAM Storage Driver from an MTD driver to a plain block device driver. The ps3vram driver exposes unused video RAM on the PS3 as a block device suitable for storage or swap. Fast data transfer is achieved using a local cache in system RAM and DMA transfers via the GPU. The new driver is ca. 50% faster for reading, and ca. 10% for writing. Signed-off-by: Geert Uytterhoeven Acked-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/ps3/Kconfig | 7 + drivers/block/Makefile | 1 + drivers/block/ps3vram.c | 865 +++++++++++++++++++++++++++++++++++++ drivers/mtd/devices/Kconfig | 7 - drivers/mtd/devices/Makefile | 1 - drivers/mtd/devices/ps3vram.c | 768 -------------------------------- 6 files changed, 873 insertions(+), 776 deletions(-) create mode 100644 drivers/block/ps3vram.c delete mode 100644 drivers/mtd/devices/ps3vram.c diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig index 920cf7a454b..740ef56a155 100644 --- a/arch/powerpc/platforms/ps3/Kconfig +++ b/arch/powerpc/platforms/ps3/Kconfig @@ -128,6 +128,13 @@ config PS3_FLASH be disabled on the kernel command line using "ps3flash=off", to not allocate this fixed buffer. +config PS3_VRAM + tristate "PS3 Video RAM Storage Driver" + depends on FB_PS3=y && BLOCK && m + help + This driver allows you to use excess PS3 video RAM as volatile + storage or system swap. + config PS3_LPM tristate "PS3 Logical Performance Monitor support" depends on PPC_PS3 diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 204332b2957..87e120e0a79 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_MAC_FLOPPY) += swim3.o obj-$(CONFIG_BLK_DEV_FD) += floppy.o obj-$(CONFIG_AMIGA_FLOPPY) += amiflop.o obj-$(CONFIG_PS3_DISK) += ps3disk.o +obj-$(CONFIG_PS3_VRAM) += ps3vram.o obj-$(CONFIG_ATARI_FLOPPY) += ataflop.o obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o obj-$(CONFIG_BLK_DEV_RAM) += brd.o diff --git a/drivers/block/ps3vram.c b/drivers/block/ps3vram.c new file mode 100644 index 00000000000..393ed6760d7 --- /dev/null +++ b/drivers/block/ps3vram.c @@ -0,0 +1,865 @@ +/* + * ps3vram - Use extra PS3 video ram as MTD block device. + * + * Copyright 2009 Sony Corporation + * + * Based on the MTD ps3vram driver, which is + * Copyright (c) 2007-2008 Jim Paris + * Added support RSX DMA Vivien Chappelier + */ + +#include +#include +#include +#include + +#include +#include +#include + + +#define DEVICE_NAME "ps3vram" + + +#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */ +#define XDR_IOIF 0x0c000000 + +#define FIFO_BASE XDR_IOIF +#define FIFO_SIZE (64 * 1024) + +#define DMA_PAGE_SIZE (4 * 1024) + +#define CACHE_PAGE_SIZE (256 * 1024) +#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE) + +#define CACHE_OFFSET CACHE_PAGE_SIZE +#define FIFO_OFFSET 0 + +#define CTRL_PUT 0x10 +#define CTRL_GET 0x11 +#define CTRL_TOP 0x15 + +#define UPLOAD_SUBCH 1 +#define DOWNLOAD_SUBCH 2 + +#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c +#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 + +#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 + +#define CACHE_PAGE_PRESENT 1 +#define CACHE_PAGE_DIRTY 2 + +struct ps3vram_tag { + unsigned int address; + unsigned int flags; +}; + +struct ps3vram_cache { + unsigned int page_count; + unsigned int page_size; + struct ps3vram_tag *tags; + unsigned int hit; + unsigned int miss; +}; + +struct ps3vram_priv { + struct request_queue *queue; + struct gendisk *gendisk; + + u64 size; + + u64 memory_handle; + u64 context_handle; + u32 *ctrl; + u32 *reports; + u8 __iomem *ddr_base; + u8 *xdr_buf; + + u32 *fifo_base; + u32 *fifo_ptr; + + struct ps3vram_cache cache; + + /* Used to serialize cache/DMA operations */ + struct mutex lock; +}; + + +static int ps3vram_major; + + +static struct block_device_operations ps3vram_fops = { + .owner = THIS_MODULE, +}; + + +#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */ +#define DMA_NOTIFIER_OFFSET_BASE 0x1000 /* first DMA notifier offset */ +#define DMA_NOTIFIER_SIZE 0x40 +#define NOTIFIER 7 /* notifier used for completion report */ + +static char *size = "256M"; +module_param(size, charp, 0); +MODULE_PARM_DESC(size, "memory size"); + +static u32 *ps3vram_get_notifier(u32 *reports, int notifier) +{ + return (void *)reports + DMA_NOTIFIER_OFFSET_BASE + + DMA_NOTIFIER_SIZE * notifier; +} + +static void ps3vram_notifier_reset(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); + int i; + + for (i = 0; i < 4; i++) + notify[i] = 0xffffffff; +} + +static int ps3vram_notifier_wait(struct ps3_system_bus_device *dev, + unsigned int timeout_ms) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); + unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); + + do { + if (!notify[3]) + return 0; + msleep(1); + } while (time_before(jiffies, timeout)); + + return -ETIMEDOUT; +} + +static void ps3vram_init_ring(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + + priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; + priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; +} + +static int ps3vram_wait_ring(struct ps3_system_bus_device *dev, + unsigned int timeout_ms) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); + + do { + if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) + return 0; + msleep(1); + } while (time_before(jiffies, timeout)); + + dev_warn(&dev->core, "FIFO timeout (%08x/%08x/%08x)\n", + priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET], + priv->ctrl[CTRL_TOP]); + + return -ETIMEDOUT; +} + +static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data) +{ + *(priv->fifo_ptr)++ = data; +} + +static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, u32 tag, + u32 size) +{ + ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag); +} + +static void ps3vram_rewind_ring(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + int status; + + ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); + + priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; + + /* asking the HV for a blit will kick the FIFO */ + status = lv1_gpu_context_attribute(priv->context_handle, + L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0, + 0, 0, 0); + if (status) + dev_err(&dev->core, + "%s: lv1_gpu_context_attribute failed %d\n", __func__, + status); + + priv->fifo_ptr = priv->fifo_base; +} + +static void ps3vram_fire_ring(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + int status; + + mutex_lock(&ps3_gpu_mutex); + + priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + + (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); + + /* asking the HV for a blit will kick the FIFO */ + status = lv1_gpu_context_attribute(priv->context_handle, + L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 0, + 0, 0, 0); + if (status) + dev_err(&dev->core, + "%s: lv1_gpu_context_attribute failed %d\n", __func__, + status); + + if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > + FIFO_SIZE - 1024) { + dev_dbg(&dev->core, "FIFO full, rewinding\n"); + ps3vram_wait_ring(dev, 200); + ps3vram_rewind_ring(dev); + } + + mutex_unlock(&ps3_gpu_mutex); +} + +static void ps3vram_bind(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + + ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); + ps3vram_out_ring(priv, 0x31337303); + ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3); + ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); + ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ + ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ + + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1); + ps3vram_out_ring(priv, 0x3137c0de); + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3); + ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); + ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ + ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ + + ps3vram_fire_ring(dev); +} + +static int ps3vram_upload(struct ps3_system_bus_device *dev, + unsigned int src_offset, unsigned int dst_offset, + int len, int count) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + + ps3vram_begin_ring(priv, UPLOAD_SUBCH, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + ps3vram_out_ring(priv, XDR_IOIF + src_offset); + ps3vram_out_ring(priv, dst_offset); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, count); + ps3vram_out_ring(priv, (1 << 8) | 1); + ps3vram_out_ring(priv, 0); + + ps3vram_notifier_reset(dev); + ps3vram_begin_ring(priv, UPLOAD_SUBCH, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); + ps3vram_out_ring(priv, 0); + ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1); + ps3vram_out_ring(priv, 0); + ps3vram_fire_ring(dev); + if (ps3vram_notifier_wait(dev, 200) < 0) { + dev_warn(&dev->core, "%s: Notifier timeout\n", __func__); + return -1; + } + + return 0; +} + +static int ps3vram_download(struct ps3_system_bus_device *dev, + unsigned int src_offset, unsigned int dst_offset, + int len, int count) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + ps3vram_out_ring(priv, src_offset); + ps3vram_out_ring(priv, XDR_IOIF + dst_offset); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, len); + ps3vram_out_ring(priv, count); + ps3vram_out_ring(priv, (1 << 8) | 1); + ps3vram_out_ring(priv, 0); + + ps3vram_notifier_reset(dev); + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); + ps3vram_out_ring(priv, 0); + ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1); + ps3vram_out_ring(priv, 0); + ps3vram_fire_ring(dev); + if (ps3vram_notifier_wait(dev, 200) < 0) { + dev_warn(&dev->core, "%s: Notifier timeout\n", __func__); + return -1; + } + + return 0; +} + +static void ps3vram_cache_evict(struct ps3_system_bus_device *dev, int entry) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + struct ps3vram_cache *cache = &priv->cache; + + if (!(cache->tags[entry].flags & CACHE_PAGE_DIRTY)) + return; + + dev_dbg(&dev->core, "Flushing %d: 0x%08x\n", entry, + cache->tags[entry].address); + if (ps3vram_upload(dev, CACHE_OFFSET + entry * cache->page_size, + cache->tags[entry].address, DMA_PAGE_SIZE, + cache->page_size / DMA_PAGE_SIZE) < 0) { + dev_err(&dev->core, + "Failed to upload from 0x%x to " "0x%x size 0x%x\n", + entry * cache->page_size, cache->tags[entry].address, + cache->page_size); + } + cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY; +} + +static void ps3vram_cache_load(struct ps3_system_bus_device *dev, int entry, + unsigned int address) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + struct ps3vram_cache *cache = &priv->cache; + + dev_dbg(&dev->core, "Fetching %d: 0x%08x\n", entry, address); + if (ps3vram_download(dev, address, + CACHE_OFFSET + entry * cache->page_size, + DMA_PAGE_SIZE, + cache->page_size / DMA_PAGE_SIZE) < 0) { + dev_err(&dev->core, + "Failed to download from 0x%x to 0x%x size 0x%x\n", + address, entry * cache->page_size, cache->page_size); + } + + cache->tags[entry].address = address; + cache->tags[entry].flags |= CACHE_PAGE_PRESENT; +} + + +static void ps3vram_cache_flush(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + struct ps3vram_cache *cache = &priv->cache; + int i; + + dev_dbg(&dev->core, "FLUSH\n"); + for (i = 0; i < cache->page_count; i++) { + ps3vram_cache_evict(dev, i); + cache->tags[i].flags = 0; + } +} + +static unsigned int ps3vram_cache_match(struct ps3_system_bus_device *dev, + loff_t address) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + struct ps3vram_cache *cache = &priv->cache; + unsigned int base; + unsigned int offset; + int i; + static int counter; + + offset = (unsigned int) (address & (cache->page_size - 1)); + base = (unsigned int) (address - offset); + + /* fully associative check */ + for (i = 0; i < cache->page_count; i++) { + if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) && + cache->tags[i].address == base) { + cache->hit++; + dev_dbg(&dev->core, "Found entry %d: 0x%08x\n", i, + cache->tags[i].address); + return i; + } + } + + /* choose a random entry */ + i = (jiffies + (counter++)) % cache->page_count; + dev_dbg(&dev->core, "Using entry %d\n", i); + + ps3vram_cache_evict(dev, i); + ps3vram_cache_load(dev, i, base); + + cache->miss++; + return i; +} + +static int ps3vram_cache_init(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + + priv->cache.page_count = CACHE_PAGE_COUNT; + priv->cache.page_size = CACHE_PAGE_SIZE; + priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * + CACHE_PAGE_COUNT, GFP_KERNEL); + if (priv->cache.tags == NULL) { + dev_err(&dev->core, "Could not allocate cache tags\n"); + return -ENOMEM; + } + + dev_info(&dev->core, "Created ram cache: %d entries, %d KiB each\n", + CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024); + + return 0; +} + +static void ps3vram_cache_cleanup(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + + ps3vram_cache_flush(dev); + kfree(priv->cache.tags); +} + +static int ps3vram_read(struct ps3_system_bus_device *dev, loff_t from, + size_t len, size_t *retlen, u_char *buf) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + unsigned int cached, count; + + dev_dbg(&dev->core, "%s: from=0x%08x len=0x%zx\n", __func__, + (unsigned int)from, len); + + if (from >= priv->size) + return -EIO; + + if (len > priv->size - from) + len = priv->size - from; + + /* Copy from vram to buf */ + count = len; + while (count) { + unsigned int offset, avail; + unsigned int entry; + + offset = (unsigned int) (from & (priv->cache.page_size - 1)); + avail = priv->cache.page_size - offset; + + mutex_lock(&priv->lock); + + entry = ps3vram_cache_match(dev, from); + cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; + + dev_dbg(&dev->core, "%s: from=%08x cached=%08x offset=%08x " + "avail=%08x count=%08x\n", __func__, + (unsigned int)from, cached, offset, avail, count); + + if (avail > count) + avail = count; + memcpy(buf, priv->xdr_buf + cached, avail); + + mutex_unlock(&priv->lock); + + buf += avail; + count -= avail; + from += avail; + } + + *retlen = len; + return 0; +} + +static int ps3vram_write(struct ps3_system_bus_device *dev, loff_t to, + size_t len, size_t *retlen, const u_char *buf) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + unsigned int cached, count; + + if (to >= priv->size) + return -EIO; + + if (len > priv->size - to) + len = priv->size - to; + + /* Copy from buf to vram */ + count = len; + while (count) { + unsigned int offset, avail; + unsigned int entry; + + offset = (unsigned int) (to & (priv->cache.page_size - 1)); + avail = priv->cache.page_size - offset; + + mutex_lock(&priv->lock); + + entry = ps3vram_cache_match(dev, to); + cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; + + dev_dbg(&dev->core, "%s: to=%08x cached=%08x offset=%08x " + "avail=%08x count=%08x\n", __func__, (unsigned int)to, + cached, offset, avail, count); + + if (avail > count) + avail = count; + memcpy(priv->xdr_buf + cached, buf, avail); + + priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; + + mutex_unlock(&priv->lock); + + buf += avail; + count -= avail; + to += avail; + } + + *retlen = len; + return 0; +} + +static int ps3vram_proc_show(struct seq_file *m, void *v) +{ + struct ps3vram_priv *priv = m->private; + + seq_printf(m, "hit:%u\nmiss:%u\n", priv->cache.hit, priv->cache.miss); + return 0; +} + +static int ps3vram_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, ps3vram_proc_show, PDE(inode)->data); +} + +static const struct file_operations ps3vram_proc_fops = { + .owner = THIS_MODULE, + .open = ps3vram_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static void __devinit ps3vram_proc_init(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + struct proc_dir_entry *pde; + + pde = proc_create(DEVICE_NAME, 0444, NULL, &ps3vram_proc_fops); + if (!pde) { + dev_warn(&dev->core, "failed to create /proc entry\n"); + return; + } + + pde->owner = THIS_MODULE; + pde->data = priv; +} + +static int ps3vram_make_request(struct request_queue *q, struct bio *bio) +{ + struct ps3_system_bus_device *dev = q->queuedata; + int write = bio_data_dir(bio) == WRITE; + const char *op = write ? "write" : "read"; + loff_t offset = bio->bi_sector << 9; + int error = 0; + struct bio_vec *bvec; + unsigned int i; + + dev_dbg(&dev->core, "%s\n", __func__); + + bio_for_each_segment(bvec, bio, i) { + /* PS3 is ppc64, so we don't handle highmem */ + char *ptr = page_address(bvec->bv_page) + bvec->bv_offset; + size_t len = bvec->bv_len, retlen; + + dev_dbg(&dev->core, " %s %zu bytes at offset %llu\n", op, + len, offset); + if (write) + error = ps3vram_write(dev, offset, len, &retlen, ptr); + else + error = ps3vram_read(dev, offset, len, &retlen, ptr); + + if (error) { + dev_err(&dev->core, "%s failed\n", op); + goto out; + } + + if (retlen != len) { + dev_err(&dev->core, "Short %s\n", op); + goto out; + } + + offset += len; + } + + dev_dbg(&dev->core, "%s completed\n", op); + +out: + bio_endio(bio, error); + return 0; +} + +static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv; + int error, status; + struct request_queue *queue; + struct gendisk *gendisk; + u64 ddr_lpar, ctrl_lpar, info_lpar, reports_lpar, ddr_size, + reports_size; + char *rest; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + error = -ENOMEM; + goto fail; + } + + mutex_init(&priv->lock); + dev->core.driver_data = priv; + + priv = dev->core.driver_data; + + /* Allocate XDR buffer (1MiB aligned) */ + priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, + get_order(XDR_BUF_SIZE)); + if (priv->xdr_buf == NULL) { + dev_err(&dev->core, "Could not allocate XDR buffer\n"); + error = -ENOMEM; + goto fail_free_priv; + } + + /* Put FIFO at begginning of XDR buffer */ + priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET); + priv->fifo_ptr = priv->fifo_base; + + /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ + if (ps3_open_hv_device(dev)) { + dev_err(&dev->core, "ps3_open_hv_device failed\n"); + error = -EAGAIN; + goto out_close_gpu; + } + + /* Request memory */ + status = -1; + ddr_size = ALIGN(memparse(size, &rest), 1024*1024); + if (!ddr_size) { + dev_err(&dev->core, "Specified size is too small\n"); + error = -EINVAL; + goto out_close_gpu; + } + + while (ddr_size > 0) { + status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, + &priv->memory_handle, + &ddr_lpar); + if (!status) + break; + ddr_size -= 1024*1024; + } + if (status) { + dev_err(&dev->core, "lv1_gpu_memory_allocate failed %d\n", + status); + error = -ENOMEM; + goto out_free_xdr_buf; + } + + /* Request context */ + status = lv1_gpu_context_allocate(priv->memory_handle, 0, + &priv->context_handle, &ctrl_lpar, + &info_lpar, &reports_lpar, + &reports_size); + if (status) { + dev_err(&dev->core, "lv1_gpu_context_allocate failed %d\n", + status); + error = -ENOMEM; + goto out_free_memory; + } + + /* Map XDR buffer to RSX */ + status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, + ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), + XDR_BUF_SIZE, 0); + if (status) { + dev_err(&dev->core, "lv1_gpu_context_iomap failed %d\n", + status); + error = -ENOMEM; + goto out_free_context; + } + + priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); + + if (!priv->ddr_base) { + dev_err(&dev->core, "ioremap DDR failed\n"); + error = -ENOMEM; + goto out_free_context; + } + + priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); + if (!priv->ctrl) { + dev_err(&dev->core, "ioremap CTRL failed\n"); + error = -ENOMEM; + goto out_unmap_vram; + } + + priv->reports = ioremap(reports_lpar, reports_size); + if (!priv->reports) { + dev_err(&dev->core, "ioremap REPORTS failed\n"); + error = -ENOMEM; + goto out_unmap_ctrl; + } + + mutex_lock(&ps3_gpu_mutex); + ps3vram_init_ring(dev); + mutex_unlock(&ps3_gpu_mutex); + + priv->size = ddr_size; + + ps3vram_bind(dev); + + mutex_lock(&ps3_gpu_mutex); + error = ps3vram_wait_ring(dev, 100); + mutex_unlock(&ps3_gpu_mutex); + if (error < 0) { + dev_err(&dev->core, "Failed to initialize channels\n"); + error = -ETIMEDOUT; + goto out_unmap_reports; + } + + ps3vram_cache_init(dev); + ps3vram_proc_init(dev); + + queue = blk_alloc_queue(GFP_KERNEL); + if (!queue) { + dev_err(&dev->core, "blk_alloc_queue failed\n"); + error = -ENOMEM; + goto out_cache_cleanup; + } + + priv->queue = queue; + queue->queuedata = dev; + blk_queue_make_request(queue, ps3vram_make_request); + blk_queue_max_phys_segments(queue, MAX_PHYS_SEGMENTS); + blk_queue_max_hw_segments(queue, MAX_HW_SEGMENTS); + blk_queue_max_segment_size(queue, MAX_SEGMENT_SIZE); + blk_queue_max_sectors(queue, SAFE_MAX_SECTORS); + + gendisk = alloc_disk(1); + if (!gendisk) { + dev_err(&dev->core, "alloc_disk failed\n"); + error = -ENOMEM; + goto fail_cleanup_queue; + } + + priv->gendisk = gendisk; + gendisk->major = ps3vram_major; + gendisk->first_minor = 0; + gendisk->fops = &ps3vram_fops; + gendisk->queue = queue; + gendisk->private_data = dev; + gendisk->driverfs_dev = &dev->core; + strlcpy(gendisk->disk_name, DEVICE_NAME, sizeof(gendisk->disk_name)); + set_capacity(gendisk, priv->size >> 9); + + dev_info(&dev->core, "%s: Using %lu MiB of GPU memory\n", + gendisk->disk_name, get_capacity(gendisk) >> 11); + + add_disk(gendisk); + return 0; + +fail_cleanup_queue: + blk_cleanup_queue(queue); +out_cache_cleanup: + remove_proc_entry(DEVICE_NAME, NULL); + ps3vram_cache_cleanup(dev); +out_unmap_reports: + iounmap(priv->reports); +out_unmap_ctrl: + iounmap(priv->ctrl); +out_unmap_vram: + iounmap(priv->ddr_base); +out_free_context: + lv1_gpu_context_free(priv->context_handle); +out_free_memory: + lv1_gpu_memory_free(priv->memory_handle); +out_close_gpu: + ps3_close_hv_device(dev); +out_free_xdr_buf: + free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); +fail_free_priv: + kfree(priv); + dev->core.driver_data = NULL; +fail: + return error; +} + +static int ps3vram_remove(struct ps3_system_bus_device *dev) +{ + struct ps3vram_priv *priv = dev->core.driver_data; + + del_gendisk(priv->gendisk); + put_disk(priv->gendisk); + blk_cleanup_queue(priv->queue); + remove_proc_entry(DEVICE_NAME, NULL); + ps3vram_cache_cleanup(dev); + iounmap(priv->reports); + iounmap(priv->ctrl); + iounmap(priv->ddr_base); + lv1_gpu_context_free(priv->context_handle); + lv1_gpu_memory_free(priv->memory_handle); + ps3_close_hv_device(dev); + free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); + kfree(priv); + dev->core.driver_data = NULL; + return 0; +} + +static struct ps3_system_bus_driver ps3vram = { + .match_id = PS3_MATCH_ID_GPU, + .match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK, + .core.name = DEVICE_NAME, + .core.owner = THIS_MODULE, + .probe = ps3vram_probe, + .remove = ps3vram_remove, + .shutdown = ps3vram_remove, +}; + + +static int __init ps3vram_init(void) +{ + int error; + + if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) + return -ENODEV; + + error = register_blkdev(0, DEVICE_NAME); + if (error <= 0) { + pr_err("%s: register_blkdev failed %d\n", DEVICE_NAME, error); + return error; + } + ps3vram_major = error; + + pr_info("%s: registered block device major %d\n", DEVICE_NAME, + ps3vram_major); + + error = ps3_system_bus_driver_register(&ps3vram); + if (error) + unregister_blkdev(ps3vram_major, DEVICE_NAME); + + return error; +} + +static void __exit ps3vram_exit(void) +{ + ps3_system_bus_driver_unregister(&ps3vram); + unregister_blkdev(ps3vram_major, DEVICE_NAME); +} + +module_init(ps3vram_init); +module_exit(ps3vram_exit); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("PS3 Video RAM Storage Driver"); +MODULE_AUTHOR("Sony Corporation"); +MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK); diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index bc33200535f..6fde0a2e356 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -120,13 +120,6 @@ config MTD_PHRAM doesn't have access to, memory beyond the mem=xxx limit, nvram, memory on the video card, etc... -config MTD_PS3VRAM - tristate "PS3 video RAM" - depends on FB_PS3 - help - This driver allows you to use excess PS3 video RAM as volatile - storage or system swap. - config MTD_LART tristate "28F160xx flash driver for LART" depends on SA1100_LART diff --git a/drivers/mtd/devices/Makefile b/drivers/mtd/devices/Makefile index e51521df4e4..0993d5cf392 100644 --- a/drivers/mtd/devices/Makefile +++ b/drivers/mtd/devices/Makefile @@ -16,4 +16,3 @@ obj-$(CONFIG_MTD_LART) += lart.o obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o obj-$(CONFIG_MTD_DATAFLASH) += mtd_dataflash.o obj-$(CONFIG_MTD_M25P80) += m25p80.o -obj-$(CONFIG_MTD_PS3VRAM) += ps3vram.o diff --git a/drivers/mtd/devices/ps3vram.c b/drivers/mtd/devices/ps3vram.c deleted file mode 100644 index d21e9beb7ed..00000000000 --- a/drivers/mtd/devices/ps3vram.c +++ /dev/null @@ -1,768 +0,0 @@ -/** - * ps3vram - Use extra PS3 video ram as MTD block device. - * - * Copyright (c) 2007-2008 Jim Paris - * Added support RSX DMA Vivien Chappelier - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define DEVICE_NAME "ps3vram" - -#define XDR_BUF_SIZE (2 * 1024 * 1024) /* XDR buffer (must be 1MiB aligned) */ -#define XDR_IOIF 0x0c000000 - -#define FIFO_BASE XDR_IOIF -#define FIFO_SIZE (64 * 1024) - -#define DMA_PAGE_SIZE (4 * 1024) - -#define CACHE_PAGE_SIZE (256 * 1024) -#define CACHE_PAGE_COUNT ((XDR_BUF_SIZE - FIFO_SIZE) / CACHE_PAGE_SIZE) - -#define CACHE_OFFSET CACHE_PAGE_SIZE -#define FIFO_OFFSET 0 - -#define CTRL_PUT 0x10 -#define CTRL_GET 0x11 -#define CTRL_TOP 0x15 - -#define UPLOAD_SUBCH 1 -#define DOWNLOAD_SUBCH 2 - -#define NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN 0x0000030c -#define NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY 0x00000104 - -#define L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT 0x601 - -struct mtd_info ps3vram_mtd; - -#define CACHE_PAGE_PRESENT 1 -#define CACHE_PAGE_DIRTY 2 - -struct ps3vram_tag { - unsigned int address; - unsigned int flags; -}; - -struct ps3vram_cache { - unsigned int page_count; - unsigned int page_size; - struct ps3vram_tag *tags; -}; - -struct ps3vram_priv { - u64 memory_handle; - u64 context_handle; - u32 *ctrl; - u32 *reports; - u8 __iomem *ddr_base; - u8 *xdr_buf; - - u32 *fifo_base; - u32 *fifo_ptr; - - struct device *dev; - struct ps3vram_cache cache; - - /* Used to serialize cache/DMA operations */ - struct mutex lock; -}; - -#define DMA_NOTIFIER_HANDLE_BASE 0x66604200 /* first DMA notifier handle */ -#define DMA_NOTIFIER_OFFSET_BASE 0x1000 /* first DMA notifier offset */ -#define DMA_NOTIFIER_SIZE 0x40 -#define NOTIFIER 7 /* notifier used for completion report */ - -/* A trailing '-' means to subtract off ps3fb_videomemory.size */ -char *size = "256M-"; -module_param(size, charp, 0); -MODULE_PARM_DESC(size, "memory size"); - -static u32 *ps3vram_get_notifier(u32 *reports, int notifier) -{ - return (void *) reports + - DMA_NOTIFIER_OFFSET_BASE + - DMA_NOTIFIER_SIZE * notifier; -} - -static void ps3vram_notifier_reset(struct mtd_info *mtd) -{ - int i; - - struct ps3vram_priv *priv = mtd->priv; - u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); - for (i = 0; i < 4; i++) - notify[i] = 0xffffffff; -} - -static int ps3vram_notifier_wait(struct mtd_info *mtd, unsigned int timeout_ms) -{ - struct ps3vram_priv *priv = mtd->priv; - u32 *notify = ps3vram_get_notifier(priv->reports, NOTIFIER); - unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); - - do { - if (!notify[3]) - return 0; - msleep(1); - } while (time_before(jiffies, timeout)); - - return -ETIMEDOUT; -} - -static void ps3vram_init_ring(struct mtd_info *mtd) -{ - struct ps3vram_priv *priv = mtd->priv; - - priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; - priv->ctrl[CTRL_GET] = FIFO_BASE + FIFO_OFFSET; -} - -static int ps3vram_wait_ring(struct mtd_info *mtd, unsigned int timeout_ms) -{ - struct ps3vram_priv *priv = mtd->priv; - unsigned long timeout = jiffies + msecs_to_jiffies(timeout_ms); - - do { - if (priv->ctrl[CTRL_PUT] == priv->ctrl[CTRL_GET]) - return 0; - msleep(1); - } while (time_before(jiffies, timeout)); - - dev_dbg(priv->dev, "%s:%d: FIFO timeout (%08x/%08x/%08x)\n", __func__, - __LINE__, priv->ctrl[CTRL_PUT], priv->ctrl[CTRL_GET], - priv->ctrl[CTRL_TOP]); - - return -ETIMEDOUT; -} - -static void ps3vram_out_ring(struct ps3vram_priv *priv, u32 data) -{ - *(priv->fifo_ptr)++ = data; -} - -static void ps3vram_begin_ring(struct ps3vram_priv *priv, u32 chan, - u32 tag, u32 size) -{ - ps3vram_out_ring(priv, (size << 18) | (chan << 13) | tag); -} - -static void ps3vram_rewind_ring(struct mtd_info *mtd) -{ - struct ps3vram_priv *priv = mtd->priv; - u64 status; - - ps3vram_out_ring(priv, 0x20000000 | (FIFO_BASE + FIFO_OFFSET)); - - priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET; - - /* asking the HV for a blit will kick the fifo */ - status = lv1_gpu_context_attribute(priv->context_handle, - L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, - 0, 0, 0, 0); - if (status) - dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", - __func__, __LINE__); - - priv->fifo_ptr = priv->fifo_base; -} - -static void ps3vram_fire_ring(struct mtd_info *mtd) -{ - struct ps3vram_priv *priv = mtd->priv; - u64 status; - - mutex_lock(&ps3_gpu_mutex); - - priv->ctrl[CTRL_PUT] = FIFO_BASE + FIFO_OFFSET + - (priv->fifo_ptr - priv->fifo_base) * sizeof(u32); - - /* asking the HV for a blit will kick the fifo */ - status = lv1_gpu_context_attribute(priv->context_handle, - L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, - 0, 0, 0, 0); - if (status) - dev_err(priv->dev, "%s:%d: lv1_gpu_context_attribute failed\n", - __func__, __LINE__); - - if ((priv->fifo_ptr - priv->fifo_base) * sizeof(u32) > - FIFO_SIZE - 1024) { - dev_dbg(priv->dev, "%s:%d: fifo full, rewinding\n", __func__, - __LINE__); - ps3vram_wait_ring(mtd, 200); - ps3vram_rewind_ring(mtd); - } - - mutex_unlock(&ps3_gpu_mutex); -} - -static void ps3vram_bind(struct mtd_info *mtd) -{ - struct ps3vram_priv *priv = mtd->priv; - - ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0, 1); - ps3vram_out_ring(priv, 0x31337303); - ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x180, 3); - ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); - ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ - ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ - - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0, 1); - ps3vram_out_ring(priv, 0x3137c0de); - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x180, 3); - ps3vram_out_ring(priv, DMA_NOTIFIER_HANDLE_BASE + NOTIFIER); - ps3vram_out_ring(priv, 0xfeed0000); /* DMA video RAM instance */ - ps3vram_out_ring(priv, 0xfeed0001); /* DMA system RAM instance */ - - ps3vram_fire_ring(mtd); -} - -static int ps3vram_upload(struct mtd_info *mtd, unsigned int src_offset, - unsigned int dst_offset, int len, int count) -{ - struct ps3vram_priv *priv = mtd->priv; - - ps3vram_begin_ring(priv, UPLOAD_SUBCH, - NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - ps3vram_out_ring(priv, XDR_IOIF + src_offset); - ps3vram_out_ring(priv, dst_offset); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, count); - ps3vram_out_ring(priv, (1 << 8) | 1); - ps3vram_out_ring(priv, 0); - - ps3vram_notifier_reset(mtd); - ps3vram_begin_ring(priv, UPLOAD_SUBCH, - NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); - ps3vram_out_ring(priv, 0); - ps3vram_begin_ring(priv, UPLOAD_SUBCH, 0x100, 1); - ps3vram_out_ring(priv, 0); - ps3vram_fire_ring(mtd); - if (ps3vram_notifier_wait(mtd, 200) < 0) { - dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, - __LINE__); - return -1; - } - - return 0; -} - -static int ps3vram_download(struct mtd_info *mtd, unsigned int src_offset, - unsigned int dst_offset, int len, int count) -{ - struct ps3vram_priv *priv = mtd->priv; - - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, - NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); - ps3vram_out_ring(priv, src_offset); - ps3vram_out_ring(priv, XDR_IOIF + dst_offset); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, len); - ps3vram_out_ring(priv, count); - ps3vram_out_ring(priv, (1 << 8) | 1); - ps3vram_out_ring(priv, 0); - - ps3vram_notifier_reset(mtd); - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, - NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); - ps3vram_out_ring(priv, 0); - ps3vram_begin_ring(priv, DOWNLOAD_SUBCH, 0x100, 1); - ps3vram_out_ring(priv, 0); - ps3vram_fire_ring(mtd); - if (ps3vram_notifier_wait(mtd, 200) < 0) { - dev_dbg(priv->dev, "%s:%d: notifier timeout\n", __func__, - __LINE__); - return -1; - } - - return 0; -} - -static void ps3vram_cache_evict(struct mtd_info *mtd, int entry) -{ - struct ps3vram_priv *priv = mtd->priv; - struct ps3vram_cache *cache = &priv->cache; - - if (cache->tags[entry].flags & CACHE_PAGE_DIRTY) { - dev_dbg(priv->dev, "%s:%d: flushing %d : 0x%08x\n", __func__, - __LINE__, entry, cache->tags[entry].address); - if (ps3vram_upload(mtd, - CACHE_OFFSET + entry * cache->page_size, - cache->tags[entry].address, - DMA_PAGE_SIZE, - cache->page_size / DMA_PAGE_SIZE) < 0) { - dev_dbg(priv->dev, "%s:%d: failed to upload from " - "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, - entry * cache->page_size, - cache->tags[entry].address, cache->page_size); - } - cache->tags[entry].flags &= ~CACHE_PAGE_DIRTY; - } -} - -static void ps3vram_cache_load(struct mtd_info *mtd, int entry, - unsigned int address) -{ - struct ps3vram_priv *priv = mtd->priv; - struct ps3vram_cache *cache = &priv->cache; - - dev_dbg(priv->dev, "%s:%d: fetching %d : 0x%08x\n", __func__, __LINE__, - entry, address); - if (ps3vram_download(mtd, - address, - CACHE_OFFSET + entry * cache->page_size, - DMA_PAGE_SIZE, - cache->page_size / DMA_PAGE_SIZE) < 0) { - dev_err(priv->dev, "%s:%d: failed to download from " - "0x%x to 0x%x size 0x%x\n", __func__, __LINE__, address, - entry * cache->page_size, cache->page_size); - } - - cache->tags[entry].address = address; - cache->tags[entry].flags |= CACHE_PAGE_PRESENT; -} - - -static void ps3vram_cache_flush(struct mtd_info *mtd) -{ - struct ps3vram_priv *priv = mtd->priv; - struct ps3vram_cache *cache = &priv->cache; - int i; - - dev_dbg(priv->dev, "%s:%d: FLUSH\n", __func__, __LINE__); - for (i = 0; i < cache->page_count; i++) { - ps3vram_cache_evict(mtd, i); - cache->tags[i].flags = 0; - } -} - -static unsigned int ps3vram_cache_match(struct mtd_info *mtd, loff_t address) -{ - struct ps3vram_priv *priv = mtd->priv; - struct ps3vram_cache *cache = &priv->cache; - unsigned int base; - unsigned int offset; - int i; - static int counter; - - offset = (unsigned int) (address & (cache->page_size - 1)); - base = (unsigned int) (address - offset); - - /* fully associative check */ - for (i = 0; i < cache->page_count; i++) { - if ((cache->tags[i].flags & CACHE_PAGE_PRESENT) && - cache->tags[i].address == base) { - dev_dbg(priv->dev, "%s:%d: found entry %d : 0x%08x\n", - __func__, __LINE__, i, cache->tags[i].address); - return i; - } - } - - /* choose a random entry */ - i = (jiffies + (counter++)) % cache->page_count; - dev_dbg(priv->dev, "%s:%d: using entry %d\n", __func__, __LINE__, i); - - ps3vram_cache_evict(mtd, i); - ps3vram_cache_load(mtd, i, base); - - return i; -} - -static int ps3vram_cache_init(struct mtd_info *mtd) -{ - struct ps3vram_priv *priv = mtd->priv; - - priv->cache.page_count = CACHE_PAGE_COUNT; - priv->cache.page_size = CACHE_PAGE_SIZE; - priv->cache.tags = kzalloc(sizeof(struct ps3vram_tag) * - CACHE_PAGE_COUNT, GFP_KERNEL); - if (priv->cache.tags == NULL) { - dev_err(priv->dev, "%s:%d: could not allocate cache tags\n", - __func__, __LINE__); - return -ENOMEM; - } - - dev_info(priv->dev, "created ram cache: %d entries, %d KiB each\n", - CACHE_PAGE_COUNT, CACHE_PAGE_SIZE / 1024); - - return 0; -} - -static void ps3vram_cache_cleanup(struct mtd_info *mtd) -{ - struct ps3vram_priv *priv = mtd->priv; - - ps3vram_cache_flush(mtd); - kfree(priv->cache.tags); -} - -static int ps3vram_erase(struct mtd_info *mtd, struct erase_info *instr) -{ - struct ps3vram_priv *priv = mtd->priv; - - if (instr->addr + instr->len > mtd->size) - return -EINVAL; - - mutex_lock(&priv->lock); - - ps3vram_cache_flush(mtd); - - /* Set bytes to 0xFF */ - memset_io(priv->ddr_base + instr->addr, 0xFF, instr->len); - - mutex_unlock(&priv->lock); - - instr->state = MTD_ERASE_DONE; - mtd_erase_callback(instr); - - return 0; -} - -static int ps3vram_read(struct mtd_info *mtd, loff_t from, size_t len, - size_t *retlen, u_char *buf) -{ - struct ps3vram_priv *priv = mtd->priv; - unsigned int cached, count; - - dev_dbg(priv->dev, "%s:%d: from=0x%08x len=0x%zx\n", __func__, __LINE__, - (unsigned int)from, len); - - if (from >= mtd->size) - return -EINVAL; - - if (len > mtd->size - from) - len = mtd->size - from; - - /* Copy from vram to buf */ - count = len; - while (count) { - unsigned int offset, avail; - unsigned int entry; - - offset = (unsigned int) (from & (priv->cache.page_size - 1)); - avail = priv->cache.page_size - offset; - - mutex_lock(&priv->lock); - - entry = ps3vram_cache_match(mtd, from); - cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; - - dev_dbg(priv->dev, "%s:%d: from=%08x cached=%08x offset=%08x " - "avail=%08x count=%08x\n", __func__, __LINE__, - (unsigned int)from, cached, offset, avail, count); - - if (avail > count) - avail = count; - memcpy(buf, priv->xdr_buf + cached, avail); - - mutex_unlock(&priv->lock); - - buf += avail; - count -= avail; - from += avail; - } - - *retlen = len; - return 0; -} - -static int ps3vram_write(struct mtd_info *mtd, loff_t to, size_t len, - size_t *retlen, const u_char *buf) -{ - struct ps3vram_priv *priv = mtd->priv; - unsigned int cached, count; - - if (to >= mtd->size) - return -EINVAL; - - if (len > mtd->size - to) - len = mtd->size - to; - - /* Copy from buf to vram */ - count = len; - while (count) { - unsigned int offset, avail; - unsigned int entry; - - offset = (unsigned int) (to & (priv->cache.page_size - 1)); - avail = priv->cache.page_size - offset; - - mutex_lock(&priv->lock); - - entry = ps3vram_cache_match(mtd, to); - cached = CACHE_OFFSET + entry * priv->cache.page_size + offset; - - dev_dbg(priv->dev, "%s:%d: to=%08x cached=%08x offset=%08x " - "avail=%08x count=%08x\n", __func__, __LINE__, - (unsigned int)to, cached, offset, avail, count); - - if (avail > count) - avail = count; - memcpy(priv->xdr_buf + cached, buf, avail); - - priv->cache.tags[entry].flags |= CACHE_PAGE_DIRTY; - - mutex_unlock(&priv->lock); - - buf += avail; - count -= avail; - to += avail; - } - - *retlen = len; - return 0; -} - -static int __devinit ps3vram_probe(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv; - int status; - u64 ddr_lpar; - u64 ctrl_lpar; - u64 info_lpar; - u64 reports_lpar; - u64 ddr_size; - u64 reports_size; - int ret = -ENOMEM; - char *rest; - - ret = -EIO; - ps3vram_mtd.priv = kzalloc(sizeof(struct ps3vram_priv), GFP_KERNEL); - if (!ps3vram_mtd.priv) - goto out; - priv = ps3vram_mtd.priv; - - mutex_init(&priv->lock); - priv->dev = &dev->core; - - /* Allocate XDR buffer (1MiB aligned) */ - priv->xdr_buf = (void *)__get_free_pages(GFP_KERNEL, - get_order(XDR_BUF_SIZE)); - if (priv->xdr_buf == NULL) { - dev_dbg(&dev->core, "%s:%d: could not allocate XDR buffer\n", - __func__, __LINE__); - ret = -ENOMEM; - goto out_free_priv; - } - - /* Put FIFO at begginning of XDR buffer */ - priv->fifo_base = (u32 *) (priv->xdr_buf + FIFO_OFFSET); - priv->fifo_ptr = priv->fifo_base; - - /* XXX: Need to open GPU, in case ps3fb or snd_ps3 aren't loaded */ - if (ps3_open_hv_device(dev)) { - dev_err(&dev->core, "%s:%d: ps3_open_hv_device failed\n", - __func__, __LINE__); - ret = -EAGAIN; - goto out_close_gpu; - } - - /* Request memory */ - status = -1; - ddr_size = memparse(size, &rest); - if (*rest == '-') - ddr_size -= ps3fb_videomemory.size; - ddr_size = ALIGN(ddr_size, 1024*1024); - if (ddr_size <= 0) { - dev_err(&dev->core, "%s:%d: specified size is too small\n", - __func__, __LINE__); - ret = -EINVAL; - goto out_close_gpu; - } - - while (ddr_size > 0) { - status = lv1_gpu_memory_allocate(ddr_size, 0, 0, 0, 0, - &priv->memory_handle, - &ddr_lpar); - if (!status) - break; - ddr_size -= 1024*1024; - } - if (status || ddr_size <= 0) { - dev_err(&dev->core, "%s:%d: lv1_gpu_memory_allocate failed\n", - __func__, __LINE__); - ret = -ENOMEM; - goto out_free_xdr_buf; - } - - /* Request context */ - status = lv1_gpu_context_allocate(priv->memory_handle, - 0, - &priv->context_handle, - &ctrl_lpar, - &info_lpar, - &reports_lpar, - &reports_size); - if (status) { - dev_err(&dev->core, "%s:%d: lv1_gpu_context_allocate failed\n", - __func__, __LINE__); - ret = -ENOMEM; - goto out_free_memory; - } - - /* Map XDR buffer to RSX */ - status = lv1_gpu_context_iomap(priv->context_handle, XDR_IOIF, - ps3_mm_phys_to_lpar(__pa(priv->xdr_buf)), - XDR_BUF_SIZE, 0); - if (status) { - dev_err(&dev->core, "%s:%d: lv1_gpu_context_iomap failed\n", - __func__, __LINE__); - ret = -ENOMEM; - goto out_free_context; - } - - priv->ddr_base = ioremap_flags(ddr_lpar, ddr_size, _PAGE_NO_CACHE); - - if (!priv->ddr_base) { - dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, - __LINE__); - ret = -ENOMEM; - goto out_free_context; - } - - priv->ctrl = ioremap(ctrl_lpar, 64 * 1024); - if (!priv->ctrl) { - dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, - __LINE__); - ret = -ENOMEM; - goto out_unmap_vram; - } - - priv->reports = ioremap(reports_lpar, reports_size); - if (!priv->reports) { - dev_err(&dev->core, "%s:%d: ioremap failed\n", __func__, - __LINE__); - ret = -ENOMEM; - goto out_unmap_ctrl; - } - - mutex_lock(&ps3_gpu_mutex); - ps3vram_init_ring(&ps3vram_mtd); - mutex_unlock(&ps3_gpu_mutex); - - ps3vram_mtd.name = "ps3vram"; - ps3vram_mtd.size = ddr_size; - ps3vram_mtd.flags = MTD_CAP_RAM; - ps3vram_mtd.erase = ps3vram_erase; - ps3vram_mtd.point = NULL; - ps3vram_mtd.unpoint = NULL; - ps3vram_mtd.read = ps3vram_read; - ps3vram_mtd.write = ps3vram_write; - ps3vram_mtd.owner = THIS_MODULE; - ps3vram_mtd.type = MTD_RAM; - ps3vram_mtd.erasesize = CACHE_PAGE_SIZE; - ps3vram_mtd.writesize = 1; - - ps3vram_bind(&ps3vram_mtd); - - mutex_lock(&ps3_gpu_mutex); - ret = ps3vram_wait_ring(&ps3vram_mtd, 100); - mutex_unlock(&ps3_gpu_mutex); - if (ret < 0) { - dev_err(&dev->core, "%s:%d: failed to initialize channels\n", - __func__, __LINE__); - ret = -ETIMEDOUT; - goto out_unmap_reports; - } - - ps3vram_cache_init(&ps3vram_mtd); - - if (add_mtd_device(&ps3vram_mtd)) { - dev_err(&dev->core, "%s:%d: add_mtd_device failed\n", - __func__, __LINE__); - ret = -EAGAIN; - goto out_cache_cleanup; - } - - dev_info(&dev->core, "reserved %u MiB of gpu memory\n", - (unsigned int)(ddr_size / 1024 / 1024)); - - return 0; - -out_cache_cleanup: - ps3vram_cache_cleanup(&ps3vram_mtd); -out_unmap_reports: - iounmap(priv->reports); -out_unmap_ctrl: - iounmap(priv->ctrl); -out_unmap_vram: - iounmap(priv->ddr_base); -out_free_context: - lv1_gpu_context_free(priv->context_handle); -out_free_memory: - lv1_gpu_memory_free(priv->memory_handle); -out_close_gpu: - ps3_close_hv_device(dev); -out_free_xdr_buf: - free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); -out_free_priv: - kfree(ps3vram_mtd.priv); - ps3vram_mtd.priv = NULL; -out: - return ret; -} - -static int ps3vram_shutdown(struct ps3_system_bus_device *dev) -{ - struct ps3vram_priv *priv; - - priv = ps3vram_mtd.priv; - - del_mtd_device(&ps3vram_mtd); - ps3vram_cache_cleanup(&ps3vram_mtd); - iounmap(priv->reports); - iounmap(priv->ctrl); - iounmap(priv->ddr_base); - lv1_gpu_context_free(priv->context_handle); - lv1_gpu_memory_free(priv->memory_handle); - ps3_close_hv_device(dev); - free_pages((unsigned long) priv->xdr_buf, get_order(XDR_BUF_SIZE)); - kfree(priv); - return 0; -} - -static struct ps3_system_bus_driver ps3vram_driver = { - .match_id = PS3_MATCH_ID_GPU, - .match_sub_id = PS3_MATCH_SUB_ID_GPU_RAMDISK, - .core.name = DEVICE_NAME, - .core.owner = THIS_MODULE, - .probe = ps3vram_probe, - .remove = ps3vram_shutdown, - .shutdown = ps3vram_shutdown, -}; - -static int __init ps3vram_init(void) -{ - return ps3_system_bus_driver_register(&ps3vram_driver); -} - -static void __exit ps3vram_exit(void) -{ - ps3_system_bus_driver_unregister(&ps3vram_driver); -} - -module_init(ps3vram_init); -module_exit(ps3vram_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jim Paris "); -MODULE_DESCRIPTION("MTD driver for PS3 video RAM"); -MODULE_ALIAS(PS3_MODULE_ALIAS_GPU_RAMDISK); -- cgit v1.2.3 From 8d03c7a0c550e7ab24cadcef5e66656bfadec8b9 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Sat, 14 Mar 2009 11:51:46 -0400 Subject: ext4: fix bogus BUG_ONs in in mballoc code Thiemo Nagel reported that: # dd if=/dev/zero of=image.ext4 bs=1M count=2 # mkfs.ext4 -v -F -b 1024 -m 0 -g 512 -G 4 -I 128 -N 1 \ -O large_file,dir_index,flex_bg,extent,sparse_super image.ext4 # mount -o loop image.ext4 mnt/ # dd if=/dev/zero of=mnt/file oopsed, with a BUG_ON in ext4_mb_normalize_request because size == EXT4_BLOCKS_PER_GROUP It appears to me (esp. after talking to Andreas) that the BUG_ON is bogus; a request of exactly EXT4_BLOCKS_PER_GROUP should be allowed, though larger sizes do indicate a problem. Fix that an another (apparently rare) codepath with a similar check. Reported-by: Thiemo Nagel Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 4415beeb0b6..41f4348b62f 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -1447,7 +1447,7 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac, struct ext4_free_extent *gex = &ac->ac_g_ex; BUG_ON(ex->fe_len <= 0); - BUG_ON(ex->fe_len >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); + BUG_ON(ex->fe_len > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); BUG_ON(ex->fe_start >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); BUG_ON(ac->ac_status != AC_STATUS_CONTINUE); @@ -3292,7 +3292,7 @@ ext4_mb_normalize_request(struct ext4_allocation_context *ac, } BUG_ON(start + size <= ac->ac_o_ex.fe_logical && start > ac->ac_o_ex.fe_logical); - BUG_ON(size <= 0 || size >= EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); + BUG_ON(size <= 0 || size > EXT4_BLOCKS_PER_GROUP(ac->ac_sb)); /* now prepare goal request */ -- cgit v1.2.3 From d33a1976fbee1ee321d6f014333d8f03a39d526c Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Mon, 16 Mar 2009 23:25:40 -0400 Subject: ext4: fix bb_prealloc_list corruption due to wrong group locking This is for Red Hat bug 490026: EXT4 panic, list corruption in ext4_mb_new_inode_pa ext4_lock_group(sb, group) is supposed to protect this list for each group, and a common code flow to remove an album is like this: ext4_get_group_no_and_offset(sb, pa->pa_pstart, &grp, NULL); ext4_lock_group(sb, grp); list_del(&pa->pa_group_list); ext4_unlock_group(sb, grp); so it's critical that we get the right group number back for this prealloc context, to lock the right group (the one associated with this pa) and prevent concurrent list manipulation. however, ext4_mb_put_pa() passes in (pa->pa_pstart - 1) with a comment, "-1 is to protect from crossing allocation group". This makes sense for the group_pa, where pa_pstart is advanced by the length which has been used (in ext4_mb_release_context()), and when the entire length has been used, pa_pstart has been advanced to the first block of the next group. However, for inode_pa, pa_pstart is never advanced; it's just set once to the first block in the group and not moved after that. So in this case, if we subtract one in ext4_mb_put_pa(), we are actually locking the *previous* group, and opening the race with the other threads which do not subtract off the extra block. Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 41f4348b62f..9f61e62f435 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -3589,6 +3589,7 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, struct super_block *sb, struct ext4_prealloc_space *pa) { ext4_group_t grp; + ext4_fsblk_t grp_blk; if (!atomic_dec_and_test(&pa->pa_count) || pa->pa_free != 0) return; @@ -3603,8 +3604,12 @@ static void ext4_mb_put_pa(struct ext4_allocation_context *ac, pa->pa_deleted = 1; spin_unlock(&pa->pa_lock); - /* -1 is to protect from crossing allocation group */ - ext4_get_group_no_and_offset(sb, pa->pa_pstart - 1, &grp, NULL); + grp_blk = pa->pa_pstart; + /* If linear, pa_pstart may be in the next group when pa is used up */ + if (pa->pa_linear) + grp_blk--; + + ext4_get_group_no_and_offset(sb, grp_blk, &grp, NULL); /* * possible race: -- cgit v1.2.3 From dde332b660cf0bc2baaba678b52768a0fb6e6da2 Mon Sep 17 00:00:00 2001 From: Krzysztof Helt Date: Mon, 16 Mar 2009 21:32:25 +0100 Subject: ALSA: opl3sa2 - Fix NULL dereference when suspending snd_opl3sa2 Fix the OOPS during a opl3sa2 card suspend and resume if the driver is loaded but the card is not found. Signed-off-by: Krzysztof Helt Cc: Signed-off-by: Takashi Iwai --- sound/isa/opl3sa2.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 58c972b2af0..b848d100186 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -550,21 +550,27 @@ static int __devinit snd_opl3sa2_mixer(struct snd_card *card) #ifdef CONFIG_PM static int snd_opl3sa2_suspend(struct snd_card *card, pm_message_t state) { - struct snd_opl3sa2 *chip = card->private_data; + if (card) { + struct snd_opl3sa2 *chip = card->private_data; - snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - chip->wss->suspend(chip->wss); - /* power down */ - snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); + chip->wss->suspend(chip->wss); + /* power down */ + snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D3); + } return 0; } static int snd_opl3sa2_resume(struct snd_card *card) { - struct snd_opl3sa2 *chip = card->private_data; + struct snd_opl3sa2 *chip; int i; + if (!card) + return 0; + + chip = card->private_data; /* power up */ snd_opl3sa2_write(chip, OPL3SA2_PM_CTRL, OPL3SA2_PM_D0); -- cgit v1.2.3 From c9310920e6e7ae0a5c0accbd57d34c194cb31780 Mon Sep 17 00:00:00 2001 From: Piotr Ziecik Date: Tue, 17 Mar 2009 09:17:50 -0600 Subject: powerpc/5200: Enable CPU_FTR_NEED_COHERENT for MPC52xx BestComm, a DMA engine in MPC52xx SoC, requires snooping when CPU caches are enabled to work properly. Adding CPU_FTR_NEED_COHERENT fixes NFS problems on MPC52xx machines introduced by 'powerpc/mm: Fix handling of _PAGE_COHERENT in BAT setup code' (sha1: 4c456a67f501b8b15542c7c21c28812bf88f484b). Signed-off-by: Piotr Ziecik Signed-off-by: Grant Likely --- arch/powerpc/include/asm/cputable.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index 4911104791c..21172badd70 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -241,9 +241,11 @@ extern const char *powerpc_base_platform; /* We need to mark all pages as being coherent if we're SMP or we have a * 74[45]x and an MPC107 host bridge. Also 83xx and PowerQUICC II * require it for PCI "streaming/prefetch" to work properly. + * This is also required by 52xx family. */ #if defined(CONFIG_SMP) || defined(CONFIG_MPC10X_BRIDGE) \ - || defined(CONFIG_PPC_83xx) || defined(CONFIG_8260) + || defined(CONFIG_PPC_83xx) || defined(CONFIG_8260) \ + || defined(CONFIG_PPC_MPC52xx) #define CPU_FTR_COMMON CPU_FTR_NEED_COHERENT #else #define CPU_FTR_COMMON 0 -- cgit v1.2.3 From a4bd6a93c3f14691c8a29e53eb04dc734b27f0db Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Tue, 17 Mar 2009 09:17:50 -0600 Subject: powerpc/mm: Respect _PAGE_COHERENT on classic ppc32 SW Since we now set _PAGE_COHERENT in the Linux PTE we shouldn't be clearing it out before we setup the SW TLB. Today all the SW TLB machines (603/e300) that we support are non-SMP, however there are some errata on some devices that cause us to set _PAGE_COHERENT via CPU_FTR_NEED_COHERENT. Signed-off-by: Kumar Gala Signed-off-by: Grant Likely --- arch/powerpc/kernel/head_32.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S index a1c4cfd25de..7db2e42d97a 100644 --- a/arch/powerpc/kernel/head_32.S +++ b/arch/powerpc/kernel/head_32.S @@ -511,7 +511,7 @@ InstructionTLBMiss: and r1,r1,r2 /* writable if _RW and _DIRTY */ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ - ori r1,r1,0xe14 /* clear out reserved bits and M */ + ori r1,r1,0xe04 /* clear out reserved bits */ andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ mtspr SPRN_RPA,r1 mfspr r3,SPRN_IMISS @@ -585,7 +585,7 @@ DataLoadTLBMiss: and r1,r1,r2 /* writable if _RW and _DIRTY */ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ - ori r1,r1,0xe14 /* clear out reserved bits and M */ + ori r1,r1,0xe04 /* clear out reserved bits */ andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ mtspr SPRN_RPA,r1 mfspr r3,SPRN_DMISS @@ -653,7 +653,7 @@ DataStoreTLBMiss: stw r3,0(r2) /* update PTE (accessed/dirty bits) */ /* Convert linux-style PTE to low word of PPC-style PTE */ rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ - li r1,0xe15 /* clear out reserved bits and M */ + li r1,0xe05 /* clear out reserved bits & PP lsb */ andc r1,r3,r1 /* PP = user? 2: 0 */ mtspr SPRN_RPA,r1 mfspr r3,SPRN_DMISS -- cgit v1.2.3 From 84f09f46b4ee9e4e9b6381f8af31817516d2091b Mon Sep 17 00:00:00 2001 From: Benny Halevy Date: Wed, 4 Mar 2009 23:05:35 +0200 Subject: NFSD: provide encode routine for OP_OPENATTR Although this operation is unsupported by our implementation we still need to provide an encode routine for it to merely encode its (error) status back in the compound reply. Thanks for Bill Baker at sun.com for testing with the Sun OpenSolaris' client, finding, and reporting this bug at Connectathon 2009. This bug was introduced in 2.6.27 Signed-off-by: Benny Halevy Cc: stable@kernel.org Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index f65953be39c..9250067943d 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2596,6 +2596,7 @@ static nfsd4_enc nfsd4_enc_ops[] = { [OP_LOOKUPP] = (nfsd4_enc)nfsd4_encode_noop, [OP_NVERIFY] = (nfsd4_enc)nfsd4_encode_noop, [OP_OPEN] = (nfsd4_enc)nfsd4_encode_open, + [OP_OPENATTR] = (nfsd4_enc)nfsd4_encode_noop, [OP_OPEN_CONFIRM] = (nfsd4_enc)nfsd4_encode_open_confirm, [OP_OPEN_DOWNGRADE] = (nfsd4_enc)nfsd4_encode_open_downgrade, [OP_PUTFH] = (nfsd4_enc)nfsd4_encode_noop, -- cgit v1.2.3 From 76a67ec6fb79ff3570dcb5342142c16098299911 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 16 Mar 2009 18:34:20 -0400 Subject: nfsd: nfsd should drop CAP_MKNOD for non-root Since creating a device node is normally an operation requiring special privilege, Igor Zhbanov points out that it is surprising (to say the least) that a client can, for example, create a device node on a filesystem exported with root_squash. So, make sure CAP_MKNOD is among the capabilities dropped when an nfsd thread handles a request from a non-root user. Reported-by: Igor Zhbanov Cc: stable@kernel.org Signed-off-by: J. Bruce Fields --- include/linux/capability.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/linux/capability.h b/include/linux/capability.h index 1b987255613..4864a43b2b4 100644 --- a/include/linux/capability.h +++ b/include/linux/capability.h @@ -393,8 +393,10 @@ struct cpu_vfs_cap_data { # define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }}) # define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }}) # define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0, CAP_FS_MASK_B1 } }) -# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0|CAP_TO_MASK(CAP_SYS_RESOURCE), \ - CAP_FS_MASK_B1 } }) +# define CAP_NFSD_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \ + | CAP_TO_MASK(CAP_SYS_RESOURCE) \ + | CAP_TO_MASK(CAP_MKNOD), \ + CAP_FS_MASK_B1 } }) #endif /* _KERNEL_CAPABILITY_U32S != 2 */ -- cgit v1.2.3 From 5b10916ea0a62920204517e1c4ce14560b4f96ab Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 10 Mar 2009 20:42:55 -0700 Subject: USB: usbtmc: fix stupid bug in open() open() will never succeed, as we always return -ENODEV. Fix this obvious bug. Thanks to Jouni Ryno for reporting it. Reported-by: Jouni Ryno Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 0f5c05f6f9d..895a0983900 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -106,12 +106,13 @@ static int usbtmc_open(struct inode *inode, struct file *filp) { struct usb_interface *intf; struct usbtmc_device_data *data; - int retval = -ENODEV; + int retval = 0; intf = usb_find_interface(&usbtmc_driver, iminor(inode)); if (!intf) { printk(KERN_ERR KBUILD_MODNAME ": can not find device for minor %d", iminor(inode)); + retval = -ENODEV; goto exit; } -- cgit v1.2.3 From 228dd05dbfdd0fced8ab1a28ed73b500ba6bb0a6 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 11 Mar 2009 13:51:42 -0700 Subject: USB: usbtmc: add protocol 1 support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The driver already supports the 1 protocol support, so just add it to the MODULE_DEVICE_TABLE entry so it properly picks up these devices. Thanks to Jouni Rynö for pointing this out. Reported-by: Jouni Ryno Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/usbtmc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 895a0983900..c40a9b284cc 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c @@ -50,6 +50,7 @@ static struct usb_device_id usbtmc_devices[] = { { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, + { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), }, { 0, } /* terminating entry */ }; MODULE_DEVICE_TABLE(usb, usbtmc_devices); -- cgit v1.2.3 From 6ff10464096540e14d7575a72c50d0316d003714 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 9 Mar 2009 13:44:02 -0400 Subject: USB: usbfs: keep async URBs until the device file is closed The usbfs driver manages a list of completed asynchronous URBs. But it is too eager to free the entries on this list: destroy_async() gets called whenever an interface is unbound or a device is removed, and it deallocates the outstanding struct async entries for all URBs on that interface or device. This is wrong; the user program should be able to reap an URB any time after it has completed, regardless of whether or not the interface is still bound or the device is still present. This patch (as1222) moves the code for deallocating the completed list entries from destroy_async() to usbdev_release(). The outstanding entries won't be freed until the user program has closed the device file, thereby eliminating any possibility that the remaining URBs might still be reaped. This fixes a bug in which a program can hang in the USBDEVFS_REAPURB ioctl when the device is unplugged. Reported-and-tested-by: Martin Poupe Signed-off-by: Alan Stern Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/devio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 7513bb083c1..6585f527e38 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -359,11 +359,6 @@ static void destroy_async(struct dev_state *ps, struct list_head *list) spin_lock_irqsave(&ps->lock, flags); } spin_unlock_irqrestore(&ps->lock, flags); - as = async_getcompleted(ps); - while (as) { - free_async(as); - as = async_getcompleted(ps); - } } static void destroy_async_on_interface(struct dev_state *ps, @@ -643,6 +638,7 @@ static int usbdev_release(struct inode *inode, struct file *file) struct dev_state *ps = file->private_data; struct usb_device *dev = ps->dev; unsigned int ifnum; + struct async *as; usb_lock_device(dev); @@ -661,6 +657,12 @@ static int usbdev_release(struct inode *inode, struct file *file) usb_unlock_device(dev); usb_put_dev(dev); put_pid(ps->disc_pid); + + as = async_getcompleted(ps); + while (as) { + free_async(as); + as = async_getcompleted(ps); + } kfree(ps); return 0; } -- cgit v1.2.3 From 7f82b6dd7015aabca2fd55fb690248f742cd67f3 Mon Sep 17 00:00:00 2001 From: Axel Wachtler Date: Thu, 5 Mar 2009 14:09:22 -0800 Subject: USB: serial: add FTDI USB/Serial converter devices Add the following devices to the USB FTDI SIO device table: Bus 001 Device 009: ID 03eb:2109 Atmel Corp. http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4187 Bus 001 Device 008: ID 1cf1:0001 http://www.dresden-elektronik.de/shop/prod75.html Bus 001 Device 007: ID 1c1f:0004 http://www.dresden-elektronik.de/shop/prod64.html Signed-off-by: Axel Wachtler Signed-off-by: Robert Richter Signed-off-by: Andrew Morton Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 3 +++ drivers/usb/serial/ftdi_sio.h | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f92f4d77337..f77339265ee 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -663,6 +663,9 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) }, + { USB_DEVICE(ATMEL_VID, STK541_PID) }, + { USB_DEVICE(DE_VID, STB_PID) }, + { USB_DEVICE(DE_VID, WHT_PID) }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index e300c840f8c..f2745edabcd 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -892,6 +892,19 @@ */ #define DIEBOLD_BCS_SE923_PID 0xfb99 +/* + * Atmel STK541 + */ +#define ATMEL_VID 0x03eb /* Vendor ID */ +#define STK541_PID 0x2109 /* Zigbee Controller */ + +/* + * Dresden Elektronic Sensor Terminal Board + */ +#define DE_VID 0x1cf1 /* Vendor ID */ +#define STB_PID 0x0001 /* Sensor Terminal Board */ +#define WHT_PID 0x0004 /* Wireless Handheld Terminal */ + /* * BmRequestType: 1100 0000b * bRequest: FTDI_E2_READ -- cgit v1.2.3 From b0d659002168146ec6b03d1ef062d8dcf05ff510 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 6 Mar 2009 14:07:43 -0800 Subject: USB: serial: ftdi: enable UART detection on gnICE JTAG adaptors blacklist interface0 Signed-off-by: Michael Hennerich Signed-off-by: Bryan Wu Signed-off-by: Andrew Morton Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio.h | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index f77339265ee..ae84c326a54 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -666,6 +666,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(ATMEL_VID, STK541_PID) }, { USB_DEVICE(DE_VID, STB_PID) }, { USB_DEVICE(DE_VID, WHT_PID) }, + { USB_DEVICE(ADI_VID, ADI_GNICE_PID), + .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, { }, /* Optional parameter entry */ { } /* Terminating entry */ }; diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index f2745edabcd..daaf63db0b5 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -905,6 +905,13 @@ #define STB_PID 0x0001 /* Sensor Terminal Board */ #define WHT_PID 0x0004 /* Wireless Handheld Terminal */ +/* + * Blackfin gnICE JTAG + * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice + */ +#define ADI_VID 0x0456 +#define ADI_GNICE_PID 0xF000 + /* * BmRequestType: 1100 0000b * bRequest: FTDI_E2_READ -- cgit v1.2.3 From c6535668798b0644e1af5934c2aec0e912280449 Mon Sep 17 00:00:00 2001 From: "Robert M. Kenney" Date: Thu, 26 Feb 2009 14:58:39 -0500 Subject: USB: serial: new cp2101 device id From: Robert M. Kenney Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp2101.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 027f4b7dde8..9b4082b58c5 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c @@ -79,6 +79,7 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ + { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ -- cgit v1.2.3 From c497e715f93d148d751c055401568684eea0bf6b Mon Sep 17 00:00:00 2001 From: Jan Dumon Date: Tue, 10 Mar 2009 17:29:47 +0100 Subject: USB: unusual_devs: Add support for GI 0431 SD-Card interface Enable the SD-Card interface on the GI 0431 HSUPA stick from Option. The unusual_devs.h entry is necessary because the device descriptor is vendor-specific. That prevents usb-storage from binding to it as an interface driver. T: Bus=07 Lev=01 Prnt=01 Port=01 Cnt=02 Dev#= 15 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=ff(vend.) Sub=ff Prot=ff MxPS=64 #Cfgs= 1 P: Vendor=0af0 ProdID=7501 Rev= 0.00 S: Manufacturer=Option N.V. S: Product=Globetrotter HSUPA Modem C:* #Ifs=11 Cfg#= 1 Atr=a0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=hso E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 3 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=hso E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 5 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=86(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 6 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=hso E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 7 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=hso E: Ad=88(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=08(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 8 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=(none) E: Ad=89(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#= 9 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=ff Driver=hso E: Ad=8a(I) Atr=03(Int.) MxPS= 64 Ivl=2ms E: Ad=8b(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=4ms I:* If#=10 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8c(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Jan Dumon Signed-off-by: Phil Dibowitz Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 6f59c8e510e..bfa8db0d8aa 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1390,6 +1390,16 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000, US_SC_DEVICE, US_PR_DEVICE, NULL, 0 ), +/* Reported by Jan Dumon + * This device (wrongly) has a vendor-specific device descriptor. + * The entry is needed so usb-storage can bind to it's mass-storage + * interface as an interface driver */ +UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, + "Option", + "GI 0431 SD-Card", + US_SC_DEVICE, US_PR_DEVICE, NULL, + 0 ), + /* Reported by Ben Efros */ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, "Seagate", -- cgit v1.2.3 From eeafa64b7a4134da24d48ed944e48541f8171152 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 11 Mar 2009 21:47:36 +0100 Subject: USB: atm/cxacru, fix lock imbalance We do not hold mutex in one place in cxacru_cm, but unlock it on fail path. Fix this. Signed-off-by: Jiri Slaby Cc: Simon Arlott Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 5ed4ae07bac..6789089e246 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -485,7 +485,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n", wbuflen, rbuflen); ret = -ENOMEM; - goto fail; + goto err; } mutex_lock(&instance->cm_serialize); @@ -565,6 +565,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, dbg("cm %#x", cm); fail: mutex_unlock(&instance->cm_serialize); +err: return ret; } -- cgit v1.2.3 From 909b6c3fc20ea772dc63a03986d74148fcbb1a1d Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 11 Mar 2009 21:47:37 +0100 Subject: USB: image/mdc800, fix lock imbalance There is an omitted unlock in mdc800_usb_probe's fail path. Add it. Signed-off-by: Jiri Slaby Cc: Henning Zabel Signed-off-by: Greg Kroah-Hartman --- drivers/usb/image/mdc800.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 878c77ca086..972f20b3406 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c @@ -499,6 +499,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, retval = usb_register_dev(intf, &mdc800_class); if (retval) { dev_err(&intf->dev, "Not able to get a minor for this device.\n"); + mutex_unlock(&mdc800->io_lock); return -ENODEV; } -- cgit v1.2.3 From 46c9844c4014be53c67622dcd3ba4302f36e9cac Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 11 Mar 2009 21:47:38 +0100 Subject: USB: misc/adutux, fix lock imbalance Don't unlock adutux_mutex when not held. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/adutux.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 7b6922e08ed..20352654201 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -376,7 +376,7 @@ static int adu_release(struct inode *inode, struct file *file) if (dev->open_count <= 0) { dbg(1," %s : device not opened", __func__); retval = -ENODEV; - goto exit; + goto unlock; } adu_release_internal(dev); @@ -385,9 +385,9 @@ static int adu_release(struct inode *inode, struct file *file) if (!dev->open_count) /* ... and we're the last user */ adu_delete(dev); } - -exit: +unlock: mutex_unlock(&adutux_mutex); +exit: dbg(2," %s : leave, return value %d", __func__, retval); return retval; } -- cgit v1.2.3 From a08b43aee46ed4272ad7bee2c785edcf313339b3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 11 Mar 2009 21:47:39 +0100 Subject: USB: misc/vstusb, fix lock imbalance Make sure we don't leak locked vstdev->lock in vstusb_write. Unlock properly on one fail path. Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/usb/misc/vstusb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/usb/misc/vstusb.c b/drivers/usb/misc/vstusb.c index 63dff9ba73c..f26ea8dc157 100644 --- a/drivers/usb/misc/vstusb.c +++ b/drivers/usb/misc/vstusb.c @@ -401,6 +401,7 @@ static ssize_t vstusb_write(struct file *file, const char __user *buffer, } if (copy_from_user(buf, buffer, count)) { + mutex_unlock(&vstdev->lock); dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__); retval = -EFAULT; goto exit; -- cgit v1.2.3 From 49fa09215c03116449184057f062c6aea2f1d0b4 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 11 Mar 2009 21:47:40 +0100 Subject: USB: wusbcore/wa-xfer, fix lock imbalance Fix locking on one wa_urb_enqueue_b's fail path. There was omitted unlock. Signed-off-by: Jiri Slaby Cc: Inaky Perez-Gonzalez Signed-off-by: Greg Kroah-Hartman --- drivers/usb/wusbcore/wa-xfer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 238a96aee3a..613a5fc490d 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c @@ -921,8 +921,10 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer) result = -ENODEV; /* FIXME: segmentation broken -- kills DWA */ mutex_lock(&wusbhc->mutex); /* get a WUSB dev */ - if (urb->dev == NULL) + if (urb->dev == NULL) { + mutex_unlock(&wusbhc->mutex); goto error_dev_gone; + } wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); if (wusb_dev == NULL) { mutex_unlock(&wusbhc->mutex); -- cgit v1.2.3 From 9ea19b82f3126da4e47d6b94563a3c2cd586f6e2 Mon Sep 17 00:00:00 2001 From: Albert Pauw Date: Sun, 1 Mar 2009 09:37:52 +0100 Subject: USB: option.c: add ZTE 622 modem device Please consider this small patch for the usb option-card driver. This patch adds the ZTE 622 usb modem device. Signed-off-by: Albert Pauw Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index b7c132bded7..ddd0a0b7e1a 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -288,6 +288,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po /* ZTE PRODUCTS */ #define ZTE_VENDOR_ID 0x19d2 +#define ZTE_PRODUCT_MF622 0x0001 #define ZTE_PRODUCT_MF628 0x0015 #define ZTE_PRODUCT_MF626 0x0031 #define ZTE_PRODUCT_CDMA_TECH 0xfffe @@ -510,6 +511,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, + { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, -- cgit v1.2.3 From 508db8c954d55ed30f870d2c24d741ba6269d13c Mon Sep 17 00:00:00 2001 From: Karsten Wiese Date: Thu, 26 Feb 2009 01:47:48 +0100 Subject: USB: EHCI: Fix isochronous URB leak ehci-hcd uses usb_get_urb() and usb_put_urb() in an unbalanced way causing isochronous URB's kref.counts incrementing once per usb_submit_urb() call. The culprit is *usb being set to NULL when usb_put_urb() is called after URB is given back. Due to other fixes there is no need for ehci-hcd to deal with usb_get_urb() nor usb_put_urb() anymore, so patch removes their usages in ehci-hcd. Patch also makes ehci_to_hcd(ehci)->self.bandwidth_allocated adjust, if a stream finishes. Signed-off-by: Karsten Wiese Cc: David Brownell Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-sched.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 07bcb931021..1d0b49e3f19 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -1536,7 +1536,7 @@ itd_link_urb ( struct ehci_itd, itd_list); list_move_tail (&itd->itd_list, &stream->td_list); itd->stream = iso_stream_get (stream); - itd->urb = usb_get_urb (urb); + itd->urb = urb; itd_init (ehci, stream, itd); } @@ -1645,7 +1645,7 @@ itd_complete ( (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; - if (unlikely (list_empty (&stream->td_list))) { + if (unlikely(list_is_singular(&stream->td_list))) { ehci_to_hcd(ehci)->self.bandwidth_allocated -= stream->bandwidth; ehci_vdbg (ehci, @@ -1656,7 +1656,6 @@ itd_complete ( iso_stream_put (ehci, stream); done: - usb_put_urb(urb); itd->urb = NULL; if (ehci->clock_frame != itd->frame || itd->index[7] != -1) { /* OK to recycle this ITD now. */ @@ -1949,7 +1948,7 @@ sitd_link_urb ( struct ehci_sitd, sitd_list); list_move_tail (&sitd->sitd_list, &stream->td_list); sitd->stream = iso_stream_get (stream); - sitd->urb = usb_get_urb (urb); + sitd->urb = urb; sitd_patch(ehci, stream, sitd, sched, packet); sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, @@ -2034,7 +2033,7 @@ sitd_complete ( (void) disable_periodic(ehci); ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; - if (list_empty (&stream->td_list)) { + if (list_is_singular(&stream->td_list)) { ehci_to_hcd(ehci)->self.bandwidth_allocated -= stream->bandwidth; ehci_vdbg (ehci, @@ -2045,7 +2044,6 @@ sitd_complete ( iso_stream_put (ehci, stream); /* OK to recycle this SITD now that its completion callback ran. */ done: - usb_put_urb(urb); sitd->urb = NULL; sitd->stream = NULL; list_move(&sitd->sitd_list, &stream->free_list); -- cgit v1.2.3 From 391016f6e2fe3b9979b4c6880a76e5e434d6947c Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 16 Mar 2009 14:21:56 -0400 Subject: USB: EHCI: expedite unlinks when the root hub is suspended This patch (as1225) fixes a bug in ehci-hcd. The condition for whether unlinked QHs can become IDLE should not be that the controller is halted, but rather that the controller isn't running. In other words when the root hub is suspended, the hardware doesn't own any QHs. This fixes a problem that can show up during hibernation: If a QH is only partially unlinked when the root hub is frozen, then when the root hub is thawed the QH won't be in the IDLE state. As a result it can't be used properly for new URB submissions. Signed-off-by: Alan Stern Reported-by: Brandon Philips Tested-by: Brandon Philips Acked-by: David Brownell Cc: Stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 3712b925b31..ecc9b66c03c 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1095,7 +1095,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) prev->qh_next = qh->qh_next; wmb (); - if (unlikely (ehci_to_hcd(ehci)->state == HC_STATE_HALT)) { + /* If the controller isn't running, we don't have to wait for it */ + if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) { /* if (unlikely (qh->reclaim != 0)) * this will recurse, probably not much */ -- cgit v1.2.3 From 0cc6bfe901b946df125d8e37186d8e45f876457d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 12 Mar 2009 06:53:00 -0400 Subject: USB: Option: let cdc-acm handle Sony Ericsson F3507g / Dell 5530 The generic cdc-acm driver is now the best one to handle Sony Ericsson F3507g-based devices (which the Dell 5530 is a rebrand of), now that all the pieces are in place (ie, cac477e8f1038c41b6f29d3161ce351462ef3df7). Removing the IDs from option allows cdc-acm to handle the device. Signed-off-by: Dan Williams Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index ddd0a0b7e1a..3cf765b0bed 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -293,11 +293,6 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po #define ZTE_PRODUCT_MF626 0x0031 #define ZTE_PRODUCT_CDMA_TECH 0xfffe -/* Ericsson products */ -#define ERICSSON_VENDOR_ID 0x0bdb -#define ERICSSON_PRODUCT_F3507G_1 0x1900 -#define ERICSSON_PRODUCT_F3507G_2 0x1902 - #define BENQ_VENDOR_ID 0x04a5 #define BENQ_PRODUCT_H10 0x4068 @@ -443,7 +438,6 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ - { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ @@ -515,8 +509,6 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, - { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_1) }, - { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G_2) }, { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ { } /* Terminating entry */ -- cgit v1.2.3 From 716a9c8561d9c50ec454f4fbd39a265892feda2c Mon Sep 17 00:00:00 2001 From: Moritz Muehlenhoff Date: Sat, 14 Mar 2009 00:43:21 +0100 Subject: USB: Updated unusual-devs entry for USB mass storage on Nokia 6233 Current firmware revision 5.60 still behaves the same, so update the quirk up a (non-existing) 99.99 revision. http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=493415 Signed-off-by: Moritz Muehlenhoff Tested-by: Jan Heitkoetter Cc: stable Signed-off-by: Phil Dibowitz --- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index bfa8db0d8aa..84ca4332e6b 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -226,7 +226,7 @@ UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0610, US_FL_MAX_SECTORS_64 ), /* Reported by Manuel Osdoba */ -UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452, +UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x9999, "Nokia", "Nokia 6233", US_SC_DEVICE, US_PR_DEVICE, NULL, -- cgit v1.2.3 From 56a21827439a4d715b510bfaf488534e6f4ad2f8 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sat, 14 Mar 2009 20:47:39 -0700 Subject: USB: Add Vendor/Product ID for new CDMA U727 to option driver * newer versions of the Novatel Wireless U727 CDMA 3G USB stick have a different Product ID (0x5010); adding this ID makes them work just fine with the option driver Signed-off-by: Dirk Hohndel Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 3cf765b0bed..d31fc2bcf77 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -197,6 +197,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po /* OVATION PRODUCTS */ #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 +#define NOVATELWIRELESS_PRODUCT_U727 0x5010 /* FUTURE NOVATEL PRODUCTS */ #define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000 @@ -411,6 +412,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ + { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ -- cgit v1.2.3 From e7f2f0d77a7b483a26054f29ba8393831b25a8a4 Mon Sep 17 00:00:00 2001 From: Achilleas Kotsis Date: Mon, 16 Mar 2009 16:35:02 +0200 Subject: USB: Add device id for Option GTM380 to option driver Option GTM380 in Modem mode uses Product ID 0x7201. This has been tested and works on production systems for over 6 months. Signed-off-by: Achilleas Kotsis Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index d31fc2bcf77..61ebddc4849 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -89,6 +89,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po #define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 #define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 #define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 +#define OPTION_PRODUCT_GTM380_MODEM 0x7201 #define HUAWEI_VENDOR_ID 0x12D1 #define HUAWEI_PRODUCT_E600 0x1001 @@ -322,6 +323,7 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, + { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) }, { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, -- cgit v1.2.3 From 8a0845c51b2e300f5204a323b874f7f58ea0eff7 Mon Sep 17 00:00:00 2001 From: Thomas Bartosik Date: Mon, 16 Mar 2009 16:04:38 +0100 Subject: USB: storage: Unusual USB device Prolific 2507 variation added The "c-enter" USB to Toshiba 1.8" IDE enclosure needs special treatment to work flawlessly. This patch is absolutely trivial, as the integrated USB-IDE bridge is already identified to be an "unusual" device, only the bcdDevice is different (lower) to the bcdDeviceMin already included in the kernel. It is a Prolific 2507 bridge. T: Bus=02 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 4 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=067b ProdID=2507 Rev= 0.01 S: Manufacturer=Prolific Technology Inc. S: Product=ATAPI-6 Bridge Controller S: SerialNumber=00000272 C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms Signed-off-by: Thomas Bartosik Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 84ca4332e6b..cfde74a6faa 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -951,7 +951,9 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, US_FL_FIX_CAPACITY ), /* Reported by Richard -=[]=- */ -UNUSUAL_DEV( 0x067b, 0x2507, 0x0100, 0x0100, +/* Change to bcdDeviceMin (0x0100 to 0x0001) reported by + * Thomas Bartosik */ +UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100, "Prolific Technology Inc.", "Mass Storage Device", US_SC_DEVICE, US_PR_DEVICE, NULL, -- cgit v1.2.3 From 6e2b75740bed35df98b8113300579e13ed2ce848 Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Mon, 16 Mar 2009 18:13:36 -0400 Subject: module: fix refptr allocation and release order Impact: fix ref-after-free crash on failed module load Fix refptr bug: Change refptr allocation and release order not to access a module data structure pointed by 'mod' after freeing mod->module_core. This bug will cause kernel panic(e.g. failed to find undefined symbols). This bug was reported on systemtap bugzilla. http://sources.redhat.com/bugzilla/show_bug.cgi?id=9927 Signed-off-by: Masami Hiramatsu Cc: Eric Dumazet Signed-off-by: Rusty Russell --- kernel/module.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/kernel/module.c b/kernel/module.c index ba22484a987..1196f5d1170 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -2015,14 +2015,6 @@ static noinline struct module *load_module(void __user *umod, if (err < 0) goto free_mod; -#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) - mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), - mod->name); - if (!mod->refptr) { - err = -ENOMEM; - goto free_mod; - } -#endif if (pcpuindex) { /* We have a special allocation for this section. */ percpu = percpu_modalloc(sechdrs[pcpuindex].sh_size, @@ -2030,7 +2022,7 @@ static noinline struct module *load_module(void __user *umod, mod->name); if (!percpu) { err = -ENOMEM; - goto free_percpu; + goto free_mod; } sechdrs[pcpuindex].sh_flags &= ~(unsigned long)SHF_ALLOC; mod->percpu = percpu; @@ -2082,6 +2074,14 @@ static noinline struct module *load_module(void __user *umod, /* Module has been moved. */ mod = (void *)sechdrs[modindex].sh_addr; +#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) + mod->refptr = percpu_modalloc(sizeof(local_t), __alignof__(local_t), + mod->name); + if (!mod->refptr) { + err = -ENOMEM; + goto free_init; + } +#endif /* Now we've moved module, initialize linked lists, etc. */ module_unload_init(mod); @@ -2288,15 +2288,17 @@ static noinline struct module *load_module(void __user *umod, ftrace_release(mod->module_core, mod->core_size); free_unload: module_unload_free(mod); + free_init: +#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) + percpu_modfree(mod->refptr); +#endif module_free(mod, mod->module_init); free_core: module_free(mod, mod->module_core); + /* mod will be freed with core. Don't access it beyond this line! */ free_percpu: if (percpu) percpu_modfree(percpu); -#if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP) - percpu_modfree(mod->refptr); -#endif free_mod: kfree(args); free_hdr: -- cgit v1.2.3 From 9aac397525dc7945b1582a80cef5860516bca452 Mon Sep 17 00:00:00 2001 From: Geoff Levand Date: Fri, 13 Mar 2009 06:52:22 +0000 Subject: powerpc/ps3: ps3_defconfig updates Update ps3_defconfig. Sets these options: CONFIG_PS3_VRAM=m CONFIG_BLK_DEV_DM=m CONFIG_USB_HIDDEV=y CONFIG_EXT4_FS=y Signed-off-by: Geoff Levand Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/configs/ps3_defconfig | 250 ++++++++++++++++++++++++++++--------- 1 file changed, 190 insertions(+), 60 deletions(-) diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index b6eee7c93cd..ac14f5245d2 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.27-rc3 -# Wed Aug 20 08:16:53 2008 +# Linux kernel version: 2.6.29-rc8 +# Fri Mar 13 09:28:45 2009 # CONFIG_PPC64=y @@ -16,13 +16,14 @@ CONFIG_PPC_FPU=y CONFIG_ALTIVEC=y # CONFIG_VSX is not set CONFIG_PPC_STD_MMU=y +CONFIG_PPC_STD_MMU_64=y CONFIG_PPC_MM_SLICES=y CONFIG_VIRT_CPU_ACCOUNTING=y CONFIG_SMP=y CONFIG_NR_CPUS=2 CONFIG_64BIT=y CONFIG_WORD_SIZE=64 -CONFIG_PPC_MERGE=y +CONFIG_ARCH_PHYS_ADDR_T_64BIT=y CONFIG_MMU=y CONFIG_GENERIC_CMOS_UPDATE=y CONFIG_GENERIC_TIME=y @@ -46,7 +47,7 @@ CONFIG_PPC=y CONFIG_EARLY_PRINTK=y CONFIG_COMPAT=y CONFIG_SYSVIPC_COMPAT=y -CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_SCHED_OMIT_FRAME_POINTER=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_PPC_OF=y CONFIG_OF=y @@ -74,10 +75,19 @@ CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set # CONFIG_TASKSTATS is not set # CONFIG_AUDIT is not set + +# +# RCU Subsystem +# +CONFIG_CLASSIC_RCU=y +# CONFIG_TREE_RCU is not set +# CONFIG_PREEMPT_RCU is not set +# CONFIG_TREE_RCU_TRACE is not set +# CONFIG_PREEMPT_RCU_TRACE is not set # CONFIG_IKCONFIG is not set CONFIG_LOG_BUF_SHIFT=17 -# CONFIG_CGROUPS is not set # CONFIG_GROUP_SCHED is not set +# CONFIG_CGROUPS is not set CONFIG_SYSFS_DEPRECATED=y CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_RELAY is not set @@ -86,11 +96,13 @@ CONFIG_NAMESPACES=y # CONFIG_IPC_NS is not set # CONFIG_USER_NS is not set # CONFIG_PID_NS is not set +# CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_INITRAMFS_SOURCE="" CONFIG_CC_OPTIMIZE_FOR_SIZE=y CONFIG_SYSCTL=y -# CONFIG_EMBEDDED is not set +CONFIG_ANON_INODES=y +CONFIG_EMBEDDED=y CONFIG_SYSCTL_SYSCALL=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y @@ -99,37 +111,36 @@ CONFIG_HOTPLUG=y CONFIG_PRINTK=y CONFIG_BUG=y CONFIG_ELF_CORE=y -# CONFIG_COMPAT_BRK is not set CONFIG_BASE_FULL=y CONFIG_FUTEX=y -CONFIG_ANON_INODES=y CONFIG_EPOLL=y CONFIG_SIGNALFD=y CONFIG_TIMERFD=y CONFIG_EVENTFD=y CONFIG_SHMEM=y +CONFIG_AIO=y CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y # CONFIG_SLUB is not set # CONFIG_SLOB is not set CONFIG_PROFILING=y -# CONFIG_MARKERS is not set +CONFIG_TRACEPOINTS=y +CONFIG_MARKERS=y CONFIG_OPROFILE=m CONFIG_HAVE_OPROFILE=y # CONFIG_KPROBES is not set CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_HAVE_SYSCALL_WRAPPERS=y CONFIG_HAVE_IOREMAP_PROT=y CONFIG_HAVE_KPROBES=y CONFIG_HAVE_KRETPROBES=y CONFIG_HAVE_ARCH_TRACEHOOK=y CONFIG_HAVE_DMA_ATTRS=y CONFIG_USE_GENERIC_SMP_HELPERS=y -# CONFIG_HAVE_CLK is not set -CONFIG_PROC_PAGE_MONITOR=y # CONFIG_HAVE_GENERIC_DMA_COHERENT is not set CONFIG_SLABINFO=y CONFIG_RT_MUTEXES=y -# CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 CONFIG_MODULES=y # CONFIG_MODULE_FORCE_LOAD is not set @@ -137,7 +148,6 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y CONFIG_STOP_MACHINE=y CONFIG_BLOCK=y # CONFIG_BLK_DEV_IO_TRACE is not set @@ -157,7 +167,7 @@ CONFIG_DEFAULT_AS=y # CONFIG_DEFAULT_CFQ is not set # CONFIG_DEFAULT_NOOP is not set CONFIG_DEFAULT_IOSCHED="anticipatory" -CONFIG_CLASSIC_RCU=y +# CONFIG_FREEZER is not set # # Platform support @@ -183,18 +193,20 @@ CONFIG_PS3_STORAGE=y CONFIG_PS3_DISK=y CONFIG_PS3_ROM=y CONFIG_PS3_FLASH=y -CONFIG_OPROFILE_PS3=y +CONFIG_PS3_VRAM=m CONFIG_PS3_LPM=m CONFIG_PPC_CELL=y # CONFIG_PPC_CELL_NATIVE is not set # CONFIG_PPC_IBM_CELL_BLADE is not set # CONFIG_PPC_CELLEB is not set +# CONFIG_PPC_CELL_QPACE is not set # # Cell Broadband Engine options # CONFIG_SPU_FS=y CONFIG_SPU_FS_64K_LS=y +# CONFIG_SPU_TRACE is not set CONFIG_SPU_BASE=y # CONFIG_PQ2ADS is not set # CONFIG_IPIC is not set @@ -210,6 +222,7 @@ CONFIG_SPU_BASE=y # CONFIG_GENERIC_IOMAP is not set # CONFIG_CPU_FREQ is not set # CONFIG_FSL_ULI1575 is not set +# CONFIG_SIMPLE_GPIO is not set # # Kernel options @@ -229,6 +242,8 @@ CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT is not set CONFIG_BINFMT_ELF=y CONFIG_COMPAT_BINFMT_ELF=y +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set +# CONFIG_HAVE_AOUT is not set CONFIG_BINFMT_MISC=y CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y # CONFIG_IOMMU_VMERGE is not set @@ -251,7 +266,6 @@ CONFIG_SELECT_MEMORY_MODEL=y CONFIG_SPARSEMEM_MANUAL=y CONFIG_SPARSEMEM=y CONFIG_HAVE_MEMORY_PRESENT=y -# CONFIG_SPARSEMEM_STATIC is not set CONFIG_SPARSEMEM_EXTREME=y CONFIG_SPARSEMEM_VMEMMAP_ENABLE=y # CONFIG_SPARSEMEM_VMEMMAP is not set @@ -261,11 +275,14 @@ CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_PAGEFLAGS_EXTENDED=y CONFIG_SPLIT_PTLOCK_CPUS=4 CONFIG_MIGRATION=y -CONFIG_RESOURCES_64BIT=y +CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_ZONE_DMA_FLAG=1 CONFIG_BOUNCE=y +CONFIG_UNEVICTABLE_LRU=y CONFIG_ARCH_MEMORY_PROBE=y CONFIG_PPC_HAS_HASH_64K=y +CONFIG_PPC_4K_PAGES=y +# CONFIG_PPC_16K_PAGES is not set # CONFIG_PPC_64K_PAGES is not set CONFIG_FORCE_MAX_ZONEORDER=13 CONFIG_SCHED_SMT=y @@ -299,6 +316,7 @@ CONFIG_NET=y # # Networking options # +CONFIG_COMPAT_NET_DEV_OPS=y CONFIG_PACKET=y CONFIG_PACKET_MMAP=y CONFIG_UNIX=y @@ -361,6 +379,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_TIPC is not set # CONFIG_ATM is not set # CONFIG_BRIDGE is not set +# CONFIG_NET_DSA is not set # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set # CONFIG_LLC2 is not set @@ -371,6 +390,7 @@ CONFIG_IPV6_NDISC_NODETYPE=y # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_SCHED is not set +# CONFIG_DCB is not set # # Network testing @@ -392,39 +412,37 @@ CONFIG_BT_HIDP=m # # Bluetooth device drivers # -CONFIG_BT_HCIUSB=m -CONFIG_BT_HCIUSB_SCO=y +CONFIG_BT_HCIBTUSB=m # CONFIG_BT_HCIUART is not set # CONFIG_BT_HCIBCM203X is not set # CONFIG_BT_HCIBPA10X is not set # CONFIG_BT_HCIBFUSB is not set # CONFIG_BT_HCIVHCI is not set # CONFIG_AF_RXRPC is not set - -# -# Wireless -# +# CONFIG_PHONET is not set +CONFIG_WIRELESS=y CONFIG_CFG80211=m +# CONFIG_CFG80211_REG_DEBUG is not set CONFIG_NL80211=y +# CONFIG_WIRELESS_OLD_REGULATORY is not set CONFIG_WIRELESS_EXT=y # CONFIG_WIRELESS_EXT_SYSFS is not set +# CONFIG_LIB80211 is not set CONFIG_MAC80211=m # # Rate control algorithm selection # CONFIG_MAC80211_RC_PID=y +# CONFIG_MAC80211_RC_MINSTREL is not set CONFIG_MAC80211_RC_DEFAULT_PID=y +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set CONFIG_MAC80211_RC_DEFAULT="pid" # CONFIG_MAC80211_MESH is not set # CONFIG_MAC80211_LEDS is not set # CONFIG_MAC80211_DEBUGFS is not set # CONFIG_MAC80211_DEBUG_MENU is not set -CONFIG_IEEE80211=m -# CONFIG_IEEE80211_DEBUG is not set -CONFIG_IEEE80211_CRYPT_WEP=m -CONFIG_IEEE80211_CRYPT_CCMP=m -CONFIG_IEEE80211_CRYPT_TKIP=m +# CONFIG_WIMAX is not set # CONFIG_RFKILL is not set # CONFIG_NET_9P is not set @@ -450,6 +468,7 @@ CONFIG_MTD_DEBUG=y CONFIG_MTD_DEBUG_VERBOSE=0 # CONFIG_MTD_CONCAT is not set # CONFIG_MTD_PARTITIONS is not set +# CONFIG_MTD_TESTS is not set # # User Modules And Translation Layers @@ -494,7 +513,6 @@ CONFIG_MTD_CFI_I2=y # # CONFIG_MTD_SLRAM is not set # CONFIG_MTD_PHRAM is not set -CONFIG_MTD_PS3VRAM=y # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLOCK2MTD is not set @@ -507,6 +525,11 @@ CONFIG_MTD_PS3VRAM=y # CONFIG_MTD_NAND is not set # CONFIG_MTD_ONENAND is not set +# +# LPDDR flash memory drivers +# +# CONFIG_MTD_LPDDR is not set + # # UBI - Unsorted block images # @@ -528,8 +551,13 @@ CONFIG_BLK_DEV_RAM_SIZE=65535 # CONFIG_ATA_OVER_ETH is not set # CONFIG_BLK_DEV_HD is not set CONFIG_MISC_DEVICES=y -# CONFIG_EEPROM_93CX6 is not set # CONFIG_ENCLOSURE_SERVICES is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +# CONFIG_EEPROM_93CX6 is not set CONFIG_HAVE_IDE=y # CONFIG_IDE is not set @@ -575,7 +603,17 @@ CONFIG_SCSI_WAIT_SCAN=m # CONFIG_SCSI_LOWLEVEL is not set # CONFIG_SCSI_DH is not set # CONFIG_ATA is not set -# CONFIG_MD is not set +CONFIG_MD=y +# CONFIG_BLK_DEV_MD is not set +CONFIG_BLK_DEV_DM=m +# CONFIG_DM_DEBUG is not set +# CONFIG_DM_CRYPT is not set +# CONFIG_DM_SNAPSHOT is not set +# CONFIG_DM_MIRROR is not set +# CONFIG_DM_ZERO is not set +# CONFIG_DM_MULTIPATH is not set +# CONFIG_DM_DELAY is not set +# CONFIG_DM_UEVENT is not set # CONFIG_MACINTOSH_DRIVERS is not set CONFIG_NETDEVICES=y # CONFIG_DUMMY is not set @@ -591,6 +629,9 @@ CONFIG_MII=m # CONFIG_IBM_NEW_EMAC_RGMII is not set # CONFIG_IBM_NEW_EMAC_TAH is not set # CONFIG_IBM_NEW_EMAC_EMAC4 is not set +# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set +# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set +# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set # CONFIG_B44 is not set CONFIG_NETDEV_1000=y CONFIG_GELIC_NET=y @@ -604,6 +645,7 @@ CONFIG_GELIC_WIRELESS_OLD_PSK_INTERFACE=y # CONFIG_WLAN_PRE80211 is not set CONFIG_WLAN_80211=y # CONFIG_LIBERTAS is not set +# CONFIG_LIBERTAS_THINFIRM is not set # CONFIG_USB_ZD1201 is not set # CONFIG_USB_NET_RNDIS_WLAN is not set # CONFIG_RTL8187 is not set @@ -615,13 +657,11 @@ CONFIG_WLAN_80211=y # CONFIG_B43LEGACY is not set CONFIG_ZD1211RW=m # CONFIG_ZD1211RW_DEBUG is not set -CONFIG_RT2X00=m -CONFIG_RT2X00_LIB=m -CONFIG_RT2X00_LIB_USB=m -CONFIG_RT2X00_LIB_FIRMWARE=y -# CONFIG_RT2500USB is not set -CONFIG_RT73USB=m -# CONFIG_RT2X00_DEBUG is not set +# CONFIG_RT2X00 is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# # # USB Network Adapters @@ -634,6 +674,7 @@ CONFIG_USB_USBNET=m CONFIG_USB_NET_AX8817X=m # CONFIG_USB_NET_CDCETHER is not set # CONFIG_USB_NET_DM9601 is not set +# CONFIG_USB_NET_SMSC95XX is not set # CONFIG_USB_NET_GL620A is not set # CONFIG_USB_NET_NET1080 is not set # CONFIG_USB_NET_PLUSB is not set @@ -664,7 +705,7 @@ CONFIG_SLHC=m # Input device support # CONFIG_INPUT=y -# CONFIG_INPUT_FF_MEMLESS is not set +CONFIG_INPUT_FF_MEMLESS=m # CONFIG_INPUT_POLLDEV is not set # @@ -735,8 +776,10 @@ CONFIG_DEVKMEM=y # Non-8250 serial port support # CONFIG_UNIX98_PTYS=y +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=16 +# CONFIG_HVC_UDBG is not set # CONFIG_IPMI_HANDLER is not set # CONFIG_HW_RANDOM is not set # CONFIG_R3964 is not set @@ -753,11 +796,11 @@ CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y # CONFIG_THERMAL is not set # CONFIG_THERMAL_HWMON is not set # CONFIG_WATCHDOG is not set +CONFIG_SSB_POSSIBLE=y # # Sonics Silicon Backplane # -CONFIG_SSB_POSSIBLE=y # CONFIG_SSB is not set # @@ -767,6 +810,7 @@ CONFIG_SSB_POSSIBLE=y # CONFIG_MFD_SM501 is not set # CONFIG_HTC_PASIC3 is not set # CONFIG_MFD_TMIO is not set +# CONFIG_REGULATOR is not set # # Multimedia devices @@ -792,6 +836,7 @@ CONFIG_VIDEO_OUTPUT_CONTROL=m CONFIG_FB=y # CONFIG_FIRMWARE_EDID is not set # CONFIG_FB_DDC is not set +# CONFIG_FB_BOOT_VESA_SUPPORT is not set # CONFIG_FB_CFB_FILLRECT is not set # CONFIG_FB_CFB_COPYAREA is not set # CONFIG_FB_CFB_IMAGEBLIT is not set @@ -817,6 +862,8 @@ CONFIG_FB_SYS_FOPS=y CONFIG_FB_PS3=y CONFIG_FB_PS3_DEFAULT_SIZE_M=9 # CONFIG_FB_VIRTUAL is not set +# CONFIG_FB_METRONOME is not set +# CONFIG_FB_MB862XX is not set # CONFIG_BACKLIGHT_LCD_SUPPORT is not set # @@ -841,6 +888,7 @@ CONFIG_FB_LOGO_EXTRA=y # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y CONFIG_SOUND=m +# CONFIG_SOUND_OSS_CORE is not set CONFIG_SND=m CONFIG_SND_TIMER=m CONFIG_SND_PCM=m @@ -849,6 +897,7 @@ CONFIG_SND_RAWMIDI=m # CONFIG_SND_SEQUENCER is not set # CONFIG_SND_MIXER_OSS is not set # CONFIG_SND_PCM_OSS is not set +# CONFIG_SND_HRTIMER is not set # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y CONFIG_SND_VERBOSE_PROCFS=y @@ -873,15 +922,40 @@ CONFIG_HIDRAW=y # USB Input Devices # CONFIG_USB_HID=m -# CONFIG_USB_HIDINPUT_POWERBOOK is not set -# CONFIG_HID_FF is not set -# CONFIG_USB_HIDDEV is not set +# CONFIG_HID_PID is not set +CONFIG_USB_HIDDEV=y # # USB HID Boot Protocol drivers # # CONFIG_USB_KBD is not set # CONFIG_USB_MOUSE is not set + +# +# Special HID drivers +# +# CONFIG_HID_COMPAT is not set +# CONFIG_HID_A4TECH is not set +# CONFIG_HID_APPLE is not set +# CONFIG_HID_BELKIN is not set +# CONFIG_HID_CHERRY is not set +# CONFIG_HID_CHICONY is not set +# CONFIG_HID_CYPRESS is not set +# CONFIG_HID_EZKEY is not set +# CONFIG_HID_GYRATION is not set +# CONFIG_HID_LOGITECH is not set +# CONFIG_HID_MICROSOFT is not set +# CONFIG_HID_MONTEREY is not set +# CONFIG_HID_NTRIG is not set +# CONFIG_HID_PANTHERLORD is not set +# CONFIG_HID_PETALYNX is not set +# CONFIG_HID_SAMSUNG is not set +# CONFIG_HID_SONY is not set +# CONFIG_HID_SUNPLUS is not set +# CONFIG_GREENASIA_FF is not set +# CONFIG_HID_TOPSEED is not set +# CONFIG_THRUSTMASTER_FF is not set +# CONFIG_ZEROPLUS_FF is not set CONFIG_USB_SUPPORT=y CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y @@ -898,7 +972,11 @@ CONFIG_USB_DEVICEFS=y # CONFIG_USB_DYNAMIC_MINORS is not set CONFIG_USB_SUSPEND=y # CONFIG_USB_OTG is not set -CONFIG_USB_MON=y +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +CONFIG_USB_MON=m +# CONFIG_USB_WUSB is not set +# CONFIG_USB_WUSB_CBAF is not set # # USB Host Controller Drivers @@ -909,6 +987,7 @@ CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_TT_NEWSCHED is not set CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y # CONFIG_USB_EHCI_HCD_PPC_OF is not set +# CONFIG_USB_OXU210HP_HCD is not set # CONFIG_USB_ISP116X_HCD is not set # CONFIG_USB_ISP1760_HCD is not set CONFIG_USB_OHCI_HCD=m @@ -918,6 +997,7 @@ CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_SL811_HCD is not set # CONFIG_USB_R8A66597_HCD is not set +# CONFIG_USB_HWA_HCD is not set # # Enable Host or Gadget support to see Inventra options @@ -929,20 +1009,20 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y # CONFIG_USB_ACM is not set # CONFIG_USB_PRINTER is not set # CONFIG_USB_WDM is not set +# CONFIG_USB_TMC is not set # -# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed; # # -# may also be needed; see USB_STORAGE Help for more information +# see USB_STORAGE Help for more information # CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_DEBUG is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set # CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set @@ -950,7 +1030,6 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_STORAGE_ALAUDA is not set # CONFIG_USB_STORAGE_ONETOUCH is not set # CONFIG_USB_STORAGE_KARMA is not set -# CONFIG_USB_STORAGE_SIERRA is not set # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set # CONFIG_USB_LIBUSUAL is not set @@ -971,6 +1050,7 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set # CONFIG_USB_ADUTUX is not set +# CONFIG_USB_SEVSEG is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set @@ -988,7 +1068,12 @@ CONFIG_USB_STORAGE=m # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_TEST is not set # CONFIG_USB_ISIGHTFW is not set +# CONFIG_USB_VST is not set # CONFIG_USB_GADGET is not set + +# +# OTG and related infrastructure +# # CONFIG_MMC is not set # CONFIG_MEMSTICK is not set # CONFIG_NEW_LEDS is not set @@ -1014,12 +1099,15 @@ CONFIG_RTC_INTF_DEV=y # Platform RTC drivers # # CONFIG_RTC_DRV_CMOS is not set +# CONFIG_RTC_DRV_DS1286 is not set # CONFIG_RTC_DRV_DS1511 is not set # CONFIG_RTC_DRV_DS1553 is not set # CONFIG_RTC_DRV_DS1742 is not set # CONFIG_RTC_DRV_STK17TA8 is not set # CONFIG_RTC_DRV_M48T86 is not set +# CONFIG_RTC_DRV_M48T35 is not set # CONFIG_RTC_DRV_M48T59 is not set +# CONFIG_RTC_DRV_BQ4802 is not set # CONFIG_RTC_DRV_V3020 is not set # @@ -1028,6 +1116,7 @@ CONFIG_RTC_INTF_DEV=y CONFIG_RTC_DRV_PPC=m # CONFIG_DMADEVICES is not set # CONFIG_UIO is not set +# CONFIG_STAGING is not set # # File systems @@ -1035,26 +1124,35 @@ CONFIG_RTC_DRV_PPC=m CONFIG_EXT2_FS=m # CONFIG_EXT2_FS_XATTR is not set # CONFIG_EXT2_FS_XIP is not set -CONFIG_EXT3_FS=y +CONFIG_EXT3_FS=m CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set # CONFIG_EXT3_FS_SECURITY is not set -# CONFIG_EXT4DEV_FS is not set -CONFIG_JBD=y +CONFIG_EXT4_FS=y +# CONFIG_EXT4DEV_COMPAT is not set +CONFIG_EXT4_FS_XATTR=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# CONFIG_EXT4_FS_SECURITY is not set +CONFIG_JBD=m # CONFIG_JBD_DEBUG is not set +CONFIG_JBD2=y +# CONFIG_JBD2_DEBUG is not set CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set # CONFIG_FS_POSIX_ACL is not set +CONFIG_FILE_LOCKING=y # CONFIG_XFS_FS is not set # CONFIG_GFS2_FS is not set # CONFIG_OCFS2_FS is not set +# CONFIG_BTRFS_FS is not set CONFIG_DNOTIFY=y CONFIG_INOTIFY=y CONFIG_INOTIFY_USER=y CONFIG_QUOTA=y # CONFIG_QUOTA_NETLINK_INTERFACE is not set CONFIG_PRINT_QUOTA_WARNING=y +CONFIG_QUOTA_TREE=y # CONFIG_QFMT_V1 is not set CONFIG_QFMT_V2=y CONFIG_QUOTACTL=y @@ -1087,16 +1185,14 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_TMPFS_POSIX_ACL is not set CONFIG_HUGETLBFS=y CONFIG_HUGETLB_PAGE=y # CONFIG_CONFIGFS_FS is not set - -# -# Miscellaneous filesystems -# +CONFIG_MISC_FILESYSTEMS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set @@ -1106,6 +1202,7 @@ CONFIG_HUGETLB_PAGE=y # CONFIG_EFS_FS is not set # CONFIG_JFFS2_FS is not set # CONFIG_CRAMFS is not set +# CONFIG_SQUASHFS is not set # CONFIG_VXFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_OMFS_FS is not set @@ -1126,6 +1223,7 @@ CONFIG_LOCKD_V4=y CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y +# CONFIG_SUNRPC_REGISTER_V4 is not set CONFIG_RPCSEC_GSS_KRB5=y # CONFIG_RPCSEC_GSS_SPKM3 is not set # CONFIG_SMB_FS is not set @@ -1190,9 +1288,9 @@ CONFIG_NLS_ISO8859_1=y # Library routines # CONFIG_BITREVERSE=y -# CONFIG_GENERIC_FIND_FIRST_BIT is not set +CONFIG_GENERIC_FIND_LAST_BIT=y CONFIG_CRC_CCITT=m -# CONFIG_CRC16 is not set +CONFIG_CRC16=y CONFIG_CRC_T10DIF=y CONFIG_CRC_ITU_T=m CONFIG_CRC32=y @@ -1250,27 +1348,44 @@ CONFIG_DEBUG_WRITECOUNT=y CONFIG_DEBUG_MEMORY_INIT=y CONFIG_DEBUG_LIST=y # CONFIG_DEBUG_SG is not set -CONFIG_FRAME_POINTER=y +# CONFIG_DEBUG_NOTIFIERS is not set # CONFIG_BOOT_PRINTK_DELAY is not set # CONFIG_RCU_TORTURE_TEST is not set +# CONFIG_RCU_CPU_STALL_DETECTOR is not set # CONFIG_BACKTRACE_SELF_TEST is not set +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set # CONFIG_FAULT_INJECTION is not set # CONFIG_LATENCYTOP is not set CONFIG_SYSCTL_SYSCALL_CHECK=y -CONFIG_HAVE_FTRACE=y +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y CONFIG_HAVE_DYNAMIC_FTRACE=y -# CONFIG_FTRACE is not set +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_RING_BUFFER=y +CONFIG_TRACING=y + +# +# Tracers +# +# CONFIG_FUNCTION_TRACER is not set # CONFIG_IRQSOFF_TRACER is not set # CONFIG_SCHED_TRACER is not set # CONFIG_CONTEXT_SWITCH_TRACER is not set +# CONFIG_BOOT_TRACER is not set +# CONFIG_TRACE_BRANCH_PROFILING is not set +# CONFIG_STACK_TRACER is not set +# CONFIG_FTRACE_STARTUP_TEST is not set +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set # CONFIG_SAMPLES is not set CONFIG_HAVE_ARCH_KGDB=y # CONFIG_KGDB is not set +CONFIG_PRINT_STACK_DEPTH=64 CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_STACK_USAGE is not set # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_CODE_PATCHING_SELFTEST is not set # CONFIG_FTR_FIXUP_SELFTEST is not set +# CONFIG_MSI_BITMAP_SELFTEST is not set # CONFIG_XMON is not set CONFIG_IRQSTACKS=y # CONFIG_VIRQ_DEBUG is not set @@ -1282,16 +1397,26 @@ CONFIG_IRQSTACKS=y # # CONFIG_KEYS is not set # CONFIG_SECURITY is not set +# CONFIG_SECURITYFS is not set # CONFIG_SECURITY_FILE_CAPABILITIES is not set CONFIG_CRYPTO=y # # Crypto core or helper # +# CONFIG_CRYPTO_FIPS is not set CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y CONFIG_CRYPTO_GF128MUL=m # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_CRYPTD is not set @@ -1363,6 +1488,11 @@ CONFIG_CRYPTO_SALSA20=m # # CONFIG_CRYPTO_DEFLATE is not set CONFIG_CRYPTO_LZO=m + +# +# Random Number Generation +# +# CONFIG_CRYPTO_ANSI_CPRNG is not set CONFIG_CRYPTO_HW=y # CONFIG_PPC_CLOCK is not set # CONFIG_VIRTUALIZATION is not set -- cgit v1.2.3 From 09240cf429505891d6123ce14a29f58f2a60121e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 17 Mar 2009 07:47:18 +0100 Subject: ALSA: hda - Fix DMA mask for ATI controllers ATI controllers (at least some SB0600 models) appear buggy to handle 64bit DMA. As a workaround, reset GCAP bit0 and let the driver to use only 32bit DMA on these controllers. Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 5e909e0da04..643f0e49929 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2210,9 +2210,17 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, gcap = azx_readw(chip, GCAP); snd_printdd("chipset global capabilities = 0x%x\n", gcap); + /* ATI chips seems buggy about 64bit DMA addresses */ + if (chip->driver_type == AZX_DRIVER_ATI) + gcap &= ~0x01; + /* allow 64bit DMA address if supported by H/W */ if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK)) pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK); + else { + pci_set_dma_mask(pci, DMA_32BIT_MASK); + pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK); + } /* read number of streams from GCAP register instead of using * hardcoded value -- cgit v1.2.3 From c673ba1c23941173c16ff24c7cb34199e826c8b5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 17 Mar 2009 07:49:14 +0100 Subject: ALSA: hda - Workaround for buggy DMA position on ATI controllers The position-buffer on ATI controllers are unreliable as well as on VIA chips, thus the same workaround for DMA position reading as VIA is useful for ATI. Cc: Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 643f0e49929..f3b5723c285 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2059,26 +2059,31 @@ static int __devinit check_position_fix(struct azx *chip, int fix) { const struct snd_pci_quirk *q; - /* Check VIA HD Audio Controller exist */ - if (chip->pci->vendor == PCI_VENDOR_ID_VIA && - chip->pci->device == VIA_HDAC_DEVICE_ID) { + switch (fix) { + case POS_FIX_LPIB: + case POS_FIX_POSBUF: + return fix; + } + + /* Check VIA/ATI HD Audio Controller exist */ + switch (chip->driver_type) { + case AZX_DRIVER_VIA: + case AZX_DRIVER_ATI: chip->via_dmapos_patch = 1; /* Use link position directly, avoid any transfer problem. */ return POS_FIX_LPIB; } chip->via_dmapos_patch = 0; - if (fix == POS_FIX_AUTO) { - q = snd_pci_quirk_lookup(chip->pci, position_fix_list); - if (q) { - printk(KERN_INFO - "hda_intel: position_fix set to %d " - "for device %04x:%04x\n", - q->value, q->subvendor, q->subdevice); - return q->value; - } + q = snd_pci_quirk_lookup(chip->pci, position_fix_list); + if (q) { + printk(KERN_INFO + "hda_intel: position_fix set to %d " + "for device %04x:%04x\n", + q->value, q->subvendor, q->subdevice); + return q->value; } - return fix; + return POS_FIX_AUTO; } /* -- cgit v1.2.3 From 36c7b833e5d2501142a371e4e75281d3a29fbd6b Mon Sep 17 00:00:00 2001 From: Viral Mehta Date: Tue, 10 Mar 2009 15:43:18 +0100 Subject: ALSA: oss-mixer - Fixes recording gain control At the time of initialization, SNDRV_MIXER_OSS_PRESENT_PVOLUME bit is not set for MIC (slot 7). So, the same should not be checked when an application tries to do gain control for audio recording devices. Just check slot->present for SNDRV_MIXER_OSS_PRESENT_CVOLUME independently. Verified with a simple application which opens /dev/dsp for recording and /dev/mixer for volume control. Have tested two usb audio mic devices. Signed-off-by: Viral Mehta Signed-off-by: Takashi Iwai --- sound/core/oss/mixer_oss.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c index 4690b8b5681..e570649184e 100644 --- a/sound/core/oss/mixer_oss.c +++ b/sound/core/oss/mixer_oss.c @@ -692,6 +692,9 @@ static int snd_mixer_oss_put_volume1(struct snd_mixer_oss_file *fmixer, snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_PVOLUME], left, right); if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right); + } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_CVOLUME) { + snd_mixer_oss_put_volume1_vol(fmixer, pslot, + slot->numid[SNDRV_MIXER_OSS_ITEM_CVOLUME], left, right); } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GVOLUME) { snd_mixer_oss_put_volume1_vol(fmixer, pslot, slot->numid[SNDRV_MIXER_OSS_ITEM_GVOLUME], left, right); } else if (slot->present & SNDRV_MIXER_OSS_PRESENT_GLOBAL) { -- cgit v1.2.3 From 91054598f794fb5d8a0b1e747ff8e2e8fc2115b3 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 11 Mar 2009 20:11:40 +0100 Subject: ALSA: pcm_oss, fix locking typo s/mutex_lock/mutex_unlock/ on 2 fail paths in snd_pcm_oss_proc_write. Probably a typo, lock should be unlocked when leaving the function. Signed-off-by: Jiri Slaby Cc: Signed-off-by: Takashi Iwai --- sound/core/oss/pcm_oss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c index 0a1798eafb0..699d2890535 100644 --- a/sound/core/oss/pcm_oss.c +++ b/sound/core/oss/pcm_oss.c @@ -2872,7 +2872,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, setup = kmalloc(sizeof(*setup), GFP_KERNEL); if (! setup) { buffer->error = -ENOMEM; - mutex_lock(&pstr->oss.setup_mutex); + mutex_unlock(&pstr->oss.setup_mutex); return; } if (pstr->oss.setup_list == NULL) @@ -2886,7 +2886,7 @@ static void snd_pcm_oss_proc_write(struct snd_info_entry *entry, if (! template.task_name) { kfree(setup); buffer->error = -ENOMEM; - mutex_lock(&pstr->oss.setup_mutex); + mutex_unlock(&pstr->oss.setup_mutex); return; } } -- cgit v1.2.3 From 82f5d57163abed2e5ff271d03217b6f90c616eb8 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 11 Mar 2009 20:11:41 +0100 Subject: ALSA: mixart, fix lock imbalance There is an omitted unlock in one snd_mixart_hw_params fail path. Fix it. Signed-off-by: Jiri Slaby Cc: Signed-off-by: Takashi Iwai --- sound/pci/mixart/mixart.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index f23a73577c2..bb162507fe6 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -607,6 +607,7 @@ static int snd_mixart_hw_params(struct snd_pcm_substream *subs, /* set the format to the board */ err = mixart_set_format(stream, format); if(err < 0) { + mutex_unlock(&mgr->setup_mutex); return err; } -- cgit v1.2.3 From 6af845e4eb36fb91b322aaf77ec1cab2220a48ad Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 17 Mar 2009 14:00:06 +0100 Subject: ALSA: Fix vunmap and free order in snd_free_sgbuf_pages() In snd_free_sgbuf_pags(), vunmap() is called after releasing the SG pages, and it causes errors on Xen as Xen manages the pages differently. Although no significant errors have been reported on the actual hardware, this order should be fixed other way round, first vunmap() then free pages. Cc: Jan Beulich Cc: Signed-off-by: Takashi Iwai --- sound/core/sgbuf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c index d4564edd61d..4e7ec2b4987 100644 --- a/sound/core/sgbuf.c +++ b/sound/core/sgbuf.c @@ -38,6 +38,10 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) if (! sgbuf) return -EINVAL; + if (dmab->area) + vunmap(dmab->area); + dmab->area = NULL; + tmpb.dev.type = SNDRV_DMA_TYPE_DEV; tmpb.dev.dev = sgbuf->dev; for (i = 0; i < sgbuf->pages; i++) { @@ -48,9 +52,6 @@ int snd_free_sgbuf_pages(struct snd_dma_buffer *dmab) tmpb.bytes = (sgbuf->table[i].addr & ~PAGE_MASK) << PAGE_SHIFT; snd_dma_free_pages(&tmpb); } - if (dmab->area) - vunmap(dmab->area); - dmab->area = NULL; kfree(sgbuf->table); kfree(sgbuf->page_table); -- cgit v1.2.3 From 18aecd362a1c991fbf5f7919ae051a77532ba2f8 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 18 Mar 2009 08:56:58 +0100 Subject: tracing: stop command line recording when tracing is disabled Impact: prevent overwrite of command line entries When the tracer is stopped the command line recording continues to record. The check for tracing_is_on() is not sufficient here as the ringbuffer status is not affected by setting debug/tracing/tracing_enabled to 0. On a non idle system this can result in the loss of the command line information for the stopped trace, which makes the trace harder to read and analyse. Check tracer_enabled to allow further recording. Signed-off-by: Thomas Gleixner Cc: Steven Rostedt Cc: Frederic Weisbecker LKML-Reference: Signed-off-by: Ingo Molnar --- kernel/trace/trace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 1ce6208fd72..7b6043ea256 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -797,7 +797,8 @@ void trace_find_cmdline(int pid, char comm[]) void tracing_record_cmdline(struct task_struct *tsk) { - if (atomic_read(&trace_record_cmdline_disabled) || !tracing_is_on()) + if (atomic_read(&trace_record_cmdline_disabled) || !tracer_enabled || + !tracing_is_on()) return; trace_save_cmdline(tsk); -- cgit v1.2.3 From 2c7eea4c62ba090b7f4583c3d7337ea0019be900 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 18 Mar 2009 09:03:19 +0100 Subject: tracing: replace the crude (unsigned) -1 hackery Impact: cleanup The command line recorder uses (unsigned) -1 to mark non mapped entries in the pid to command line maps. The validity check is completely unintuitive: idx >= SAVED_CMDLINES There is no need for such casting games. Use a constant to mark unmapped entries and check for that constant to make the code readable and understandable. Signed-off-by: Thomas Gleixner Cc: Steven Rostedt Cc: Frederic Weisbecker LKML-Reference: Signed-off-by: Ingo Molnar --- kernel/trace/trace.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 7b6043ea256..ca673c47568 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -633,6 +633,7 @@ void tracing_reset_online_cpus(struct trace_array *tr) } #define SAVED_CMDLINES 128 +#define NO_CMDLINE_MAP UINT_MAX static unsigned map_pid_to_cmdline[PID_MAX_DEFAULT+1]; static unsigned map_cmdline_to_pid[SAVED_CMDLINES]; static char saved_cmdlines[SAVED_CMDLINES][TASK_COMM_LEN]; @@ -644,8 +645,8 @@ static atomic_t trace_record_cmdline_disabled __read_mostly; static void trace_init_cmdlines(void) { - memset(&map_pid_to_cmdline, -1, sizeof(map_pid_to_cmdline)); - memset(&map_cmdline_to_pid, -1, sizeof(map_cmdline_to_pid)); + memset(&map_pid_to_cmdline, NO_CMDLINE_MAP, sizeof(map_pid_to_cmdline)); + memset(&map_cmdline_to_pid, NO_CMDLINE_MAP, sizeof(map_cmdline_to_pid)); cmdline_idx = 0; } @@ -753,12 +754,12 @@ static void trace_save_cmdline(struct task_struct *tsk) return; idx = map_pid_to_cmdline[tsk->pid]; - if (idx >= SAVED_CMDLINES) { + if (idx == NO_CMDLINE_MAP) { idx = (cmdline_idx + 1) % SAVED_CMDLINES; map = map_cmdline_to_pid[idx]; - if (map <= PID_MAX_DEFAULT) - map_pid_to_cmdline[map] = (unsigned)-1; + if (map != NO_CMDLINE_MAP) + map_pid_to_cmdline[map] = NO_CMDLINE_MAP; map_pid_to_cmdline[tsk->pid] = idx; @@ -786,7 +787,7 @@ void trace_find_cmdline(int pid, char comm[]) __raw_spin_lock(&trace_cmdline_lock); map = map_pid_to_cmdline[pid]; - if (map >= SAVED_CMDLINES) + if (map == NO_CMDLINE_MAP) goto out; strcpy(comm, saved_cmdlines[map]); -- cgit v1.2.3 From 50d88758a3f9787cbdbdbc030560b815721eab4b Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Wed, 18 Mar 2009 08:58:44 +0100 Subject: tracing: fix trace_find_cmdline() Impact: prevent stale command line output In case there is no valid command line mapping for a pid trace_find_cmdline() returns without updating the comm buffer. The trace dump keeps the previous entry which results in confusing trace output: -0 [000] 280.702056 .... -23456 [000] 280.702080 .... Update the comm buffer with "<...>" when no mapping is found. Signed-off-by: Thomas Gleixner Cc: Steven Rostedt Cc: Frederic Weisbecker LKML-Reference: Signed-off-by: Ingo Molnar --- kernel/trace/trace.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index ca673c47568..06c69a26032 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -787,12 +787,11 @@ void trace_find_cmdline(int pid, char comm[]) __raw_spin_lock(&trace_cmdline_lock); map = map_pid_to_cmdline[pid]; - if (map == NO_CMDLINE_MAP) - goto out; - - strcpy(comm, saved_cmdlines[map]); + if (map != NO_CMDLINE_MAP) + strcpy(comm, saved_cmdlines[map]); + else + strcpy(comm, "<...>"); - out: __raw_spin_unlock(&trace_cmdline_lock); } -- cgit v1.2.3 From a635cf0497342978d417cae19d4a4823932977ff Mon Sep 17 00:00:00 2001 From: Carsten Emde Date: Wed, 18 Mar 2009 09:00:41 +0100 Subject: tracing: fix command line to pid reverse map Impact: fix command line to pid mapping map_cmdline_to_pid[] is checked in trace_save_cmdline(), but never updated. This results in stale pid to command line mappings and the tracer output will associate the wrong comm string. Signed-off-by: Carsten Emde Signed-off-by: Thomas Gleixner Cc: Steven Rostedt Cc: Frederic Weisbecker LKML-Reference: Signed-off-by: Ingo Molnar --- kernel/trace/trace.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 06c69a26032..305c562dae2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -738,8 +738,7 @@ void trace_stop_cmdline_recording(void); static void trace_save_cmdline(struct task_struct *tsk) { - unsigned map; - unsigned idx; + unsigned pid, idx; if (!tsk->pid || unlikely(tsk->pid > PID_MAX_DEFAULT)) return; @@ -757,10 +756,17 @@ static void trace_save_cmdline(struct task_struct *tsk) if (idx == NO_CMDLINE_MAP) { idx = (cmdline_idx + 1) % SAVED_CMDLINES; - map = map_cmdline_to_pid[idx]; - if (map != NO_CMDLINE_MAP) - map_pid_to_cmdline[map] = NO_CMDLINE_MAP; + /* + * Check whether the cmdline buffer at idx has a pid + * mapped. We are going to overwrite that entry so we + * need to clear the map_pid_to_cmdline. Otherwise we + * would read the new comm for the old pid. + */ + pid = map_cmdline_to_pid[idx]; + if (pid != NO_CMDLINE_MAP) + map_pid_to_cmdline[pid] = NO_CMDLINE_MAP; + map_cmdline_to_pid[idx] = tsk->pid; map_pid_to_cmdline[tsk->pid] = idx; cmdline_idx = idx; -- cgit v1.2.3 From f02b8624fedca39886b0eef770dca70c2f0749b3 Mon Sep 17 00:00:00 2001 From: Ananth N Mavinakayanahalli Date: Wed, 18 Mar 2009 17:06:21 +0530 Subject: kprobes: Fix locking imbalance in kretprobes Fix locking imbalance in kretprobes: ===================================== [ BUG: bad unlock balance detected! ] ------------------------------------- kthreadd/2 is trying to release lock (&rp->lock) at: [] pre_handler_kretprobe+0xea/0xf4 but there are no more locks to release! other info that might help us debug this: 1 lock held by kthreadd/2: #0: (rcu_read_lock){..--}, at: [] __atomic_notifier_call_chain+0x0/0x5a stack backtrace: Pid: 2, comm: kthreadd Not tainted 2.6.29-rc8 #1 Call Trace: [] ? printk+0xf/0x17 [] ? pre_handler_kretprobe+0xea/0xf4 [] print_unlock_inbalance_bug+0xc3/0xce [] ? clocksource_read+0x7/0xa [] ? getnstimeofday+0x5f/0xf6 [] ? register_lock_class+0x17/0x293 [] ? mark_lock+0x1e/0x30b [] ? tick_dev_program_event+0x4a/0xbc [] ? __slab_alloc+0xa5/0x415 [] ? pre_handler_kretprobe+0x28/0xf4 [] ? pre_handler_kretprobe+0xea/0xf4 [] lock_release_non_nested+0xa4/0x1a5 [] ? pre_handler_kretprobe+0xea/0xf4 [] lock_release+0x141/0x166 [] _spin_unlock_irqrestore+0x19/0x50 [] pre_handler_kretprobe+0xea/0xf4 [] kprobe_exceptions_notify+0x1c9/0x43e [] notifier_call_chain+0x26/0x48 [] __atomic_notifier_call_chain+0x37/0x5a [] ? __atomic_notifier_call_chain+0x0/0x5a [] atomic_notifier_call_chain+0xc/0xe [] notify_die+0x2d/0x2f [] do_int3+0x1f/0x71 [] int3+0x2c/0x34 [] ? do_fork+0x1/0x288 [] ? kernel_thread+0x71/0x79 [] ? kthread+0x0/0x60 [] ? kthread+0x0/0x60 [] ? kernel_thread_helper+0x0/0x10 [] kthreadd+0xac/0x148 [] ? kthreadd+0x0/0x148 [] kernel_thread_helper+0x7/0x10 Signed-off-by: Ananth N Mavinakayanahalli Tested-by: Bharata B Rao Cc: Masami Hiramatsu Cc: Jim Keniston Cc: Linus Torvalds Cc: Andrew Morton Cc: [2.6.29.x, 2.6.28.x, 2.6.27.x] LKML-Reference: <20090318113621.GB4129@in.ibm.com> Signed-off-by: Ingo Molnar --- kernel/kprobes.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 479d4d5672f..5016bfb682b 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -919,10 +919,8 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p, ri->rp = rp; ri->task = current; - if (rp->entry_handler && rp->entry_handler(ri, regs)) { - spin_unlock_irqrestore(&rp->lock, flags); + if (rp->entry_handler && rp->entry_handler(ri, regs)) return 0; - } arch_prepare_kretprobe(ri, regs); -- cgit v1.2.3 From 4fa81ed27781a12f6303b9263056635ae74e3e21 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 18 Mar 2009 13:27:32 +0100 Subject: [S390] __div64_31 broken for CONFIG_MARCH_G5 The implementation of __div64_31 for G5 machines is broken. The comments in __div64_31 are correct, only the code does not do what the comments say. The part "If the remainder has overflown subtract base and increase the quotient" is only partially realized, the base is subtracted correctly but the quotient is only increased if the dividend had the last bit set. Using the correct instruction fixes the problem. Cc: stable@kernel.org Reported-by: Frans Pop Tested-by: Frans Pop Signed-off-by: Martin Schwidefsky --- arch/s390/lib/div64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/s390/lib/div64.c b/arch/s390/lib/div64.c index a5f8300bf3e..d9e62c0b576 100644 --- a/arch/s390/lib/div64.c +++ b/arch/s390/lib/div64.c @@ -61,7 +61,7 @@ static uint32_t __div64_31(uint64_t *n, uint32_t base) " clr %0,%3\n" " jl 0f\n" " slr %0,%3\n" - " alr %1,%2\n" + " ahi %1,1\n" "0:\n" : "+d" (reg2), "+d" (reg3), "=d" (tmp) : "d" (base), "2" (1UL) : "cc" ); -- cgit v1.2.3 From f55d63854e426e95d7858c2662c2353262a5af70 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 18 Mar 2009 13:27:33 +0100 Subject: [S390] topology: define SD_MC_INIT to fix performance regression The default values for SD_MC_INIT cause an additional cpu usage of up to 40% on some network benchmarks compared to the plain SD_CPU_INIT values. So just define SD_MC_INIT to SD_CPU_INIT. More tuning needs to be done. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/topology.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h index c93eb50e1d0..c979c3b56ab 100644 --- a/arch/s390/include/asm/topology.h +++ b/arch/s390/include/asm/topology.h @@ -30,6 +30,8 @@ static inline void s390_init_cpu_topology(void) }; #endif +#define SD_MC_INIT SD_CPU_INIT + #include #endif /* _ASM_S390_TOPOLOGY_H */ -- cgit v1.2.3 From cf087343805ebfea2b1234b06fd5f12273e865b1 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 18 Mar 2009 13:27:34 +0100 Subject: [S390] ftrace/mcount: fix kernel stack backchain With packed stack the backchain is at a different location. Just use __SF_BACKCHAIN as an offset to store the backchain. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/mcount.S | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/s390/kernel/mcount.S b/arch/s390/kernel/mcount.S index 397d131a345..80641224a09 100644 --- a/arch/s390/kernel/mcount.S +++ b/arch/s390/kernel/mcount.S @@ -5,6 +5,8 @@ * */ +#include + #ifndef CONFIG_64BIT .globl _mcount _mcount: @@ -14,7 +16,7 @@ _mcount: ahi %r15,-96 l %r3,100(%r15) la %r2,0(%r14) - st %r1,0(%r15) + st %r1,__SF_BACKCHAIN(%r15) la %r3,0(%r3) bras %r14,0f .long ftrace_trace_function @@ -38,7 +40,7 @@ _mcount: stg %r14,112(%r15) lgr %r1,%r15 aghi %r15,-160 - stg %r1,0(%r15) + stg %r1,__SF_BACKCHAIN(%r15) lgr %r2,%r14 lg %r3,168(%r15) larl %r14,ftrace_trace_function -- cgit v1.2.3 From 2887fc5aa60803b9d6d38c79248805f08d8b0e28 Mon Sep 17 00:00:00 2001 From: Gerald Schaefer Date: Wed, 18 Mar 2009 13:27:35 +0100 Subject: [S390] Dont check for pfn_valid() in uaccess_pt.c pfn_valid() actually checks for a valid struct page and not for a valid pfn. Using xip mappings w/o struct pages, this will result in -EFAULT returned by the (page table walk) user copy functions, even though there is valid memory. Those user copy functions don't need a struct page, so this patch just removes the pfn_valid() check. Signed-off-by: Gerald Schaefer Signed-off-by: Martin Schwidefsky --- arch/s390/lib/uaccess_pt.c | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c index d66215b0fde..b0b84c35b0a 100644 --- a/arch/s390/lib/uaccess_pt.c +++ b/arch/s390/lib/uaccess_pt.c @@ -119,8 +119,6 @@ retry: goto fault; pfn = pte_pfn(*pte); - if (!pfn_valid(pfn)) - goto out; offset = uaddr & (PAGE_SIZE - 1); size = min(n - done, PAGE_SIZE - offset); @@ -135,7 +133,6 @@ retry: done += size; uaddr += size; } while (done < n); -out: spin_unlock(&mm->page_table_lock); return n - done; fault: @@ -163,9 +160,6 @@ retry: goto fault; pfn = pte_pfn(*pte); - if (!pfn_valid(pfn)) - goto out; - ret = (pfn << PAGE_SHIFT) + (uaddr & (PAGE_SIZE - 1)); out: return ret; @@ -244,11 +238,6 @@ retry: goto fault; pfn = pte_pfn(*pte); - if (!pfn_valid(pfn)) { - done = -1; - goto out; - } - offset = uaddr & (PAGE_SIZE-1); addr = (char *)(pfn << PAGE_SHIFT) + offset; len = min(count - done, PAGE_SIZE - offset); @@ -256,7 +245,6 @@ retry: done += len_str; uaddr += len_str; } while ((len_str == len) && (done < count)); -out: spin_unlock(&mm->page_table_lock); return done + 1; fault: @@ -325,12 +313,7 @@ retry: } pfn_from = pte_pfn(*pte_from); - if (!pfn_valid(pfn_from)) - goto out; pfn_to = pte_pfn(*pte_to); - if (!pfn_valid(pfn_to)) - goto out; - offset_from = uaddr_from & (PAGE_SIZE-1); offset_to = uaddr_from & (PAGE_SIZE-1); offset_max = max(offset_from, offset_to); @@ -342,7 +325,6 @@ retry: uaddr_from += size; uaddr_to += size; } while (done < n); -out: spin_unlock(&mm->page_table_lock); return n - done; fault: -- cgit v1.2.3 From f481bfafd36e621d6cbc62d4b25f74811410aef7 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 18 Mar 2009 13:27:36 +0100 Subject: [S390] make page table walking more robust Make page table walking on s390 more robust. The current code requires that the pgd/pud/pmd/pte loop is only done for address ranges that are below the end address of the last vma of the address space. But this is not always true, e.g. the generic page table walker does not guarantee this. Change TASK_SIZE/TASK_SIZE_OF to reflect the current size of the address space. This makes the generic page table walker happy but it breaks the upgrade of a 3 level page table to a 4 level page table. To make the upgrade work again another fix is required. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/processor.h | 5 ++--- arch/s390/mm/mmap.c | 4 ++-- arch/s390/mm/pgtable.c | 2 ++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index 066b99502e0..db4523fe38a 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h @@ -61,7 +61,7 @@ extern void print_cpu_info(struct cpuinfo_S390 *); extern int get_cpu_capability(unsigned int *); /* - * User space process size: 2GB for 31 bit, 4TB for 64 bit. + * User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit. */ #ifndef __s390x__ @@ -70,8 +70,7 @@ extern int get_cpu_capability(unsigned int *); #else /* __s390x__ */ -#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk,TIF_31BIT) ? \ - (1UL << 31) : (1UL << 53)) +#define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit) #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ (1UL << 30) : (1UL << 41)) #define TASK_SIZE TASK_SIZE_OF(current) diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 5932a824547..346dd0c5cbd 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -35,7 +35,7 @@ * Leave an at least ~128 MB hole. */ #define MIN_GAP (128*1024*1024) -#define MAX_GAP (TASK_SIZE/6*5) +#define MAX_GAP (STACK_TOP/6*5) static inline unsigned long mmap_base(void) { @@ -46,7 +46,7 @@ static inline unsigned long mmap_base(void) else if (gap > MAX_GAP) gap = MAX_GAP; - return TASK_SIZE - (gap & PAGE_MASK); + return STACK_TOP - (gap & PAGE_MASK); } static inline int mmap_is_legacy(void) diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 0767827540b..6b6ddc4ea02 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c @@ -117,6 +117,7 @@ repeat: crst_table_init(table, entry); pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd); mm->pgd = (pgd_t *) table; + mm->task_size = mm->context.asce_limit; table = NULL; } spin_unlock(&mm->page_table_lock); @@ -154,6 +155,7 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit) BUG(); } mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN); + mm->task_size = mm->context.asce_limit; crst_table_free(mm, (unsigned long *) pgd); } update_mm(mm, current); -- cgit v1.2.3 From 0fb1d9bcbcf701a45835aa150c57ca54ea685bfa Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Wed, 18 Mar 2009 13:27:37 +0100 Subject: [S390] make page table upgrade work again After TASK_SIZE now gives the current size of the address space the upgrade of a 64 bit process from 3 to 4 levels of page table needs to use the arch_mmap_check hook to catch large mmap lengths. The get_unmapped_area* functions need to check for -ENOMEM from the arch_get_unmapped_area*, upgrade the page table and retry. Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/mman.h | 5 +++++ arch/s390/mm/mmap.c | 44 ++++++++++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/arch/s390/include/asm/mman.h b/arch/s390/include/asm/mman.h index 7839767d837..da01432e8f4 100644 --- a/arch/s390/include/asm/mman.h +++ b/arch/s390/include/asm/mman.h @@ -22,4 +22,9 @@ #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ +#if defined(__KERNEL__) && !defined(__ASSEMBLY__) && defined(CONFIG_64BIT) +int s390_mmap_check(unsigned long addr, unsigned long len); +#define arch_mmap_check(addr,len,flags) s390_mmap_check(addr,len) +#endif + #endif /* __S390_MMAN_H__ */ diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c index 346dd0c5cbd..e008d236cc1 100644 --- a/arch/s390/mm/mmap.c +++ b/arch/s390/mm/mmap.c @@ -89,42 +89,58 @@ EXPORT_SYMBOL_GPL(arch_pick_mmap_layout); #else +int s390_mmap_check(unsigned long addr, unsigned long len) +{ + if (!test_thread_flag(TIF_31BIT) && + len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) + return crst_table_upgrade(current->mm, 1UL << 53); + return 0; +} + static unsigned long s390_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { struct mm_struct *mm = current->mm; + unsigned long area; int rc; - addr = arch_get_unmapped_area(filp, addr, len, pgoff, flags); - if (addr & ~PAGE_MASK) - return addr; - if (unlikely(mm->context.asce_limit < addr + len)) { - rc = crst_table_upgrade(mm, addr + len); + area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); + if (!(area & ~PAGE_MASK)) + return area; + if (area == -ENOMEM && + !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { + /* Upgrade the page table to 4 levels and retry. */ + rc = crst_table_upgrade(mm, 1UL << 53); if (rc) return (unsigned long) rc; + area = arch_get_unmapped_area(filp, addr, len, pgoff, flags); } - return addr; + return area; } static unsigned long -s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, +s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr, const unsigned long len, const unsigned long pgoff, const unsigned long flags) { struct mm_struct *mm = current->mm; - unsigned long addr = addr0; + unsigned long area; int rc; - addr = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); - if (addr & ~PAGE_MASK) - return addr; - if (unlikely(mm->context.asce_limit < addr + len)) { - rc = crst_table_upgrade(mm, addr + len); + area = arch_get_unmapped_area_topdown(filp, addr, len, pgoff, flags); + if (!(area & ~PAGE_MASK)) + return area; + if (area == -ENOMEM && + !test_thread_flag(TIF_31BIT) && TASK_SIZE < (1UL << 53)) { + /* Upgrade the page table to 4 levels and retry. */ + rc = crst_table_upgrade(mm, 1UL << 53); if (rc) return (unsigned long) rc; + area = arch_get_unmapped_area_topdown(filp, addr, len, + pgoff, flags); } - return addr; + return area; } /* * This function, called very early during the creation of a new -- cgit v1.2.3 From d0573facf21d1e5cfbc1ddac272b7592722e6c01 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 18 Mar 2009 09:22:17 -0700 Subject: Staging: benet: remove driver now that it is merged in drivers/net/ The benet driver is now in the proper place in drivers/net/benet, so we can remove the staging version. Acked-by: Sathya Perla Cc: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/benet/Kconfig | 7 - drivers/staging/benet/MAINTAINERS | 6 - drivers/staging/benet/Makefile | 14 - drivers/staging/benet/TODO | 6 - drivers/staging/benet/asyncmesg.h | 82 -- drivers/staging/benet/be_cm.h | 134 --- drivers/staging/benet/be_common.h | 53 -- drivers/staging/benet/be_ethtool.c | 348 -------- drivers/staging/benet/be_init.c | 1382 ----------------------------- drivers/staging/benet/be_int.c | 863 ------------------ drivers/staging/benet/be_netif.c | 705 --------------- drivers/staging/benet/benet.h | 429 --------- drivers/staging/benet/bestatus.h | 103 --- drivers/staging/benet/cev.h | 243 ----- drivers/staging/benet/cq.c | 211 ----- drivers/staging/benet/descriptors.h | 71 -- drivers/staging/benet/doorbells.h | 179 ---- drivers/staging/benet/ep.h | 66 -- drivers/staging/benet/eq.c | 299 ------- drivers/staging/benet/eth.c | 1273 -------------------------- drivers/staging/benet/etx_context.h | 55 -- drivers/staging/benet/funcobj.c | 565 ------------ drivers/staging/benet/fwcmd_common.h | 222 ----- drivers/staging/benet/fwcmd_common_bmap.h | 717 --------------- drivers/staging/benet/fwcmd_eth_bmap.h | 280 ------ drivers/staging/benet/fwcmd_hdr_bmap.h | 54 -- drivers/staging/benet/fwcmd_mcc.h | 94 -- drivers/staging/benet/fwcmd_opcodes.h | 244 ----- drivers/staging/benet/fwcmd_types_bmap.h | 29 - drivers/staging/benet/host_struct.h | 182 ---- drivers/staging/benet/hwlib.h | 830 ----------------- drivers/staging/benet/mpu.c | 1364 ---------------------------- drivers/staging/benet/mpu.h | 74 -- drivers/staging/benet/mpu_context.h | 46 - drivers/staging/benet/pcicfg.h | 825 ----------------- drivers/staging/benet/post_codes.h | 111 --- drivers/staging/benet/regmap.h | 68 -- 39 files changed, 12237 deletions(-) delete mode 100644 drivers/staging/benet/Kconfig delete mode 100644 drivers/staging/benet/MAINTAINERS delete mode 100644 drivers/staging/benet/Makefile delete mode 100644 drivers/staging/benet/TODO delete mode 100644 drivers/staging/benet/asyncmesg.h delete mode 100644 drivers/staging/benet/be_cm.h delete mode 100644 drivers/staging/benet/be_common.h delete mode 100644 drivers/staging/benet/be_ethtool.c delete mode 100644 drivers/staging/benet/be_init.c delete mode 100644 drivers/staging/benet/be_int.c delete mode 100644 drivers/staging/benet/be_netif.c delete mode 100644 drivers/staging/benet/benet.h delete mode 100644 drivers/staging/benet/bestatus.h delete mode 100644 drivers/staging/benet/cev.h delete mode 100644 drivers/staging/benet/cq.c delete mode 100644 drivers/staging/benet/descriptors.h delete mode 100644 drivers/staging/benet/doorbells.h delete mode 100644 drivers/staging/benet/ep.h delete mode 100644 drivers/staging/benet/eq.c delete mode 100644 drivers/staging/benet/eth.c delete mode 100644 drivers/staging/benet/etx_context.h delete mode 100644 drivers/staging/benet/funcobj.c delete mode 100644 drivers/staging/benet/fwcmd_common.h delete mode 100644 drivers/staging/benet/fwcmd_common_bmap.h delete mode 100644 drivers/staging/benet/fwcmd_eth_bmap.h delete mode 100644 drivers/staging/benet/fwcmd_hdr_bmap.h delete mode 100644 drivers/staging/benet/fwcmd_mcc.h delete mode 100644 drivers/staging/benet/fwcmd_opcodes.h delete mode 100644 drivers/staging/benet/fwcmd_types_bmap.h delete mode 100644 drivers/staging/benet/host_struct.h delete mode 100644 drivers/staging/benet/hwlib.h delete mode 100644 drivers/staging/benet/mpu.c delete mode 100644 drivers/staging/benet/mpu.h delete mode 100644 drivers/staging/benet/mpu_context.h delete mode 100644 drivers/staging/benet/pcicfg.h delete mode 100644 drivers/staging/benet/post_codes.h delete mode 100644 drivers/staging/benet/regmap.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index ce6badded47..211af86a6c5 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 9ddcc2bb336..47a56f5ffab 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/benet/Kconfig b/drivers/staging/benet/Kconfig deleted file mode 100644 index f6806074f99..00000000000 --- 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 d5ce340218b..00000000000 --- 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 460b923b99b..00000000000 --- 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 a51dfb59a62..00000000000 --- 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 - and Greg Kroah-Hartman diff --git a/drivers/staging/benet/asyncmesg.h b/drivers/staging/benet/asyncmesg.h deleted file mode 100644 index d1e779adb84..00000000000 --- 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 b7a1dfd20c3..00000000000 --- 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 7e63dc5e334..00000000000 --- 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 027af85707a..00000000000 --- 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 - -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 12a026c3f9e..00000000000 --- 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 -#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 cba95d09a8b..00000000000 --- 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 -#include - -#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 2b8daf63dc7..00000000000 --- 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 -#include -#include "benet.h" -#include -#include - -/* 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 09a1f081772..00000000000 --- 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 -#include -#include -#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 59c7a4b6222..00000000000 --- 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 30996920a54..00000000000 --- 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 65045864543..00000000000 --- 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 8da438c407d..00000000000 --- 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 550cc4d5d6f..00000000000 --- 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 72fcf64a9ff..00000000000 --- 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 db92ccd8fed..00000000000 --- 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 f641b6260d0..00000000000 --- 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 -#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(ð_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(ð_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 554fbe5d127..00000000000 --- 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 0f57eb58dae..00000000000 --- 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 406e0d6fa98..00000000000 --- 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 a007cf27650..00000000000 --- 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 234b179eace..00000000000 --- 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 28b45328fe7..00000000000 --- 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 9eeca878c1f..00000000000 --- 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 23d569386b4..00000000000 --- 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 92217aff3a1..00000000000 --- 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 3de6722b980..00000000000 --- 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 afedf4dc590..00000000000 --- 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 -#include -#include -#include - -#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__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 - * _AMAP to calculate the bit masks and bit offsets to get or set - * bit fields in structures. The structures _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 269cc11d305..00000000000 --- 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 -#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 41f3f87516e..00000000000 --- 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 8ce90f9c46c..00000000000 --- 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 7c15684adf4..00000000000 --- 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 6d1621f5f5f..00000000000 --- 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 e816ba210e8..00000000000 --- 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__ */ -- cgit v1.2.3 From 68df3755e383e6fecf2354a67b08f92f18536594 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 19 Mar 2009 11:10:17 -0700 Subject: Add '-fwrapv' to gcc CFLAGS This makes sure that gcc doesn't try to optimize away wrapping arithmetic, which the kernel occasionally uses for overflow testing, ie things like if (ptr + offset < ptr) which technically is undefined for non-unsigned types. See http://bugzilla.kernel.org/show_bug.cgi?id=12597 for details. Not all versions of gcc support it, so we need to make it conditional (it looks like it was introduced in gcc-3.4). Reminded-by: Alan Cox Signed-off-by: Linus Torvalds --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 2e2f4a4324a..f607658ac89 100644 --- a/Makefile +++ b/Makefile @@ -347,6 +347,7 @@ KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common \ -Werror-implicit-function-declaration +KBUILD_CFLAGS += $(call cc-option,-fwrapv) KBUILD_AFLAGS := -D__ASSEMBLY__ # Read KERNELRELEASE from include/config/kernel.release (if it exists) -- cgit v1.2.3 From a8e7d49aa7be728c4ae241a75a2a124cdcabc0c5 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 19 Mar 2009 11:32:05 -0700 Subject: Fix race in create_empty_buffers() vs __set_page_dirty_buffers() Nick Piggin noticed this (very unlikely) race between setting a page dirty and creating the buffers for it - we need to hold the mapping private_lock until we've set the page dirty bit in order to make sure that create_empty_buffers() might not build up a set of buffers without the dirty bits set when the page is dirty. I doubt anybody has ever hit this race (and it didn't solve the issue Nick was looking at), but as Nick says: "Still, it does appear to solve a real race, which we should close." Acked-by: Nick Piggin Signed-off-by: Linus Torvalds --- fs/buffer.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 9f697419ed8..891e1c78e4f 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -760,15 +760,9 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode); * If warn is true, then emit a warning if the page is not uptodate and has * not been truncated. */ -static int __set_page_dirty(struct page *page, +static void __set_page_dirty(struct page *page, struct address_space *mapping, int warn) { - if (unlikely(!mapping)) - return !TestSetPageDirty(page); - - if (TestSetPageDirty(page)) - return 0; - spin_lock_irq(&mapping->tree_lock); if (page->mapping) { /* Race with truncate? */ WARN_ON_ONCE(warn && !PageUptodate(page)); @@ -785,8 +779,6 @@ static int __set_page_dirty(struct page *page, } spin_unlock_irq(&mapping->tree_lock); __mark_inode_dirty(mapping->host, I_DIRTY_PAGES); - - return 1; } /* @@ -816,6 +808,7 @@ static int __set_page_dirty(struct page *page, */ int __set_page_dirty_buffers(struct page *page) { + int newly_dirty; struct address_space *mapping = page_mapping(page); if (unlikely(!mapping)) @@ -831,9 +824,12 @@ int __set_page_dirty_buffers(struct page *page) bh = bh->b_this_page; } while (bh != head); } + newly_dirty = !TestSetPageDirty(page); spin_unlock(&mapping->private_lock); - return __set_page_dirty(page, mapping, 1); + if (newly_dirty) + __set_page_dirty(page, mapping, 1); + return newly_dirty; } EXPORT_SYMBOL(__set_page_dirty_buffers); @@ -1262,8 +1258,11 @@ void mark_buffer_dirty(struct buffer_head *bh) return; } - if (!test_set_buffer_dirty(bh)) - __set_page_dirty(bh->b_page, page_mapping(bh->b_page), 0); + if (!test_set_buffer_dirty(bh)) { + struct page *page = bh->b_page; + if (!TestSetPageDirty(page)) + __set_page_dirty(page, page_mapping(page), 0); + } } /* -- cgit v1.2.3 From d0115552cdb0b4d4146975889fee2e9355515c4b Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 19 Mar 2009 15:53:19 -0700 Subject: Move cc-option to below arch-specific setup Sam Ravnborg says: "We have several architectures that plays strange games with $(CC) and $(CROSS_COMPILE). So we need to postpone any use of $(call cc-option..) until we have included the arch specific Makefile so we try with the correct $(CC) version." Requested-by: Sam Ravnborg Signed-off-by: Linus Torvalds --- Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f607658ac89..a2c2efe9e82 100644 --- a/Makefile +++ b/Makefile @@ -347,7 +347,6 @@ KBUILD_CPPFLAGS := -D__KERNEL__ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -fno-common \ -Werror-implicit-function-declaration -KBUILD_CFLAGS += $(call cc-option,-fwrapv) KBUILD_AFLAGS := -D__ASSEMBLY__ # Read KERNELRELEASE from include/config/kernel.release (if it exists) @@ -567,6 +566,9 @@ KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) # disable pointer signed / unsigned warnings in gcc 4.0 KBUILD_CFLAGS += $(call cc-option,-Wno-pointer-sign,) +# disable invalid "can't wrap" optimzations for signed / pointers +KBUILD_CFLAGS += $(call cc-option,-fwrapv) + # Add user supplied CPPFLAGS, AFLAGS and CFLAGS as the last assignments # But warn user when we do so warn-assign = \ -- cgit v1.2.3 From 87c3a86e1c220121d0ced59d1a71e78ed9abc6dd Mon Sep 17 00:00:00 2001 From: Davide Libenzi Date: Wed, 18 Mar 2009 17:04:19 -0700 Subject: eventfd: remove fput() call from possible IRQ context Remove a source of fput() call from inside IRQ context. Myself, like Eric, wasn't able to reproduce an fput() call from IRQ context, but Jeff said he was able to, with the attached test program. Independently from this, the bug is conceptually there, so we might be better off fixing it. This patch adds an optimization similar to the one we already do on ->ki_filp, on ->ki_eventfd. Playing with ->f_count directly is not pretty in general, but the alternative here would be to add a brand new delayed fput() infrastructure, that I'm not sure is worth it. Signed-off-by: Davide Libenzi Cc: Benjamin LaHaise Cc: Trond Myklebust Cc: Eric Dumazet Signed-off-by: Jeff Moyer Cc: Zach Brown Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/aio.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index 8fa77e23394..4a9d4d641fb 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -443,7 +443,7 @@ static struct kiocb *__aio_get_req(struct kioctx *ctx) req->private = NULL; req->ki_iovec = NULL; INIT_LIST_HEAD(&req->ki_run_list); - req->ki_eventfd = ERR_PTR(-EINVAL); + req->ki_eventfd = NULL; /* Check if the completion queue has enough free space to * accept an event from this io. @@ -485,8 +485,6 @@ static inline void really_put_req(struct kioctx *ctx, struct kiocb *req) { assert_spin_locked(&ctx->ctx_lock); - if (!IS_ERR(req->ki_eventfd)) - fput(req->ki_eventfd); if (req->ki_dtor) req->ki_dtor(req); if (req->ki_iovec != &req->ki_inline_vec) @@ -508,8 +506,11 @@ static void aio_fput_routine(struct work_struct *data) list_del(&req->ki_list); spin_unlock_irq(&fput_lock); - /* Complete the fput */ - __fput(req->ki_filp); + /* Complete the fput(s) */ + if (req->ki_filp != NULL) + __fput(req->ki_filp); + if (req->ki_eventfd != NULL) + __fput(req->ki_eventfd); /* Link the iocb into the context's free list */ spin_lock_irq(&ctx->ctx_lock); @@ -527,12 +528,14 @@ static void aio_fput_routine(struct work_struct *data) */ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) { + int schedule_putreq = 0; + dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n", req, atomic_long_read(&req->ki_filp->f_count)); assert_spin_locked(&ctx->ctx_lock); - req->ki_users --; + req->ki_users--; BUG_ON(req->ki_users < 0); if (likely(req->ki_users)) return 0; @@ -540,10 +543,23 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) req->ki_cancel = NULL; req->ki_retry = NULL; - /* Must be done under the lock to serialise against cancellation. - * Call this aio_fput as it duplicates fput via the fput_work. + /* + * Try to optimize the aio and eventfd file* puts, by avoiding to + * schedule work in case it is not __fput() time. In normal cases, + * we would not be holding the last reference to the file*, so + * this function will be executed w/out any aio kthread wakeup. */ - if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) { + if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) + schedule_putreq++; + else + req->ki_filp = NULL; + if (req->ki_eventfd != NULL) { + if (unlikely(atomic_long_dec_and_test(&req->ki_eventfd->f_count))) + schedule_putreq++; + else + req->ki_eventfd = NULL; + } + if (unlikely(schedule_putreq)) { get_ioctx(ctx); spin_lock(&fput_lock); list_add(&req->ki_list, &fput_head); @@ -1009,7 +1025,7 @@ int aio_complete(struct kiocb *iocb, long res, long res2) * eventfd. The eventfd_signal() function is safe to be called * from IRQ context. */ - if (!IS_ERR(iocb->ki_eventfd)) + if (iocb->ki_eventfd != NULL) eventfd_signal(iocb->ki_eventfd, 1); put_rq: @@ -1608,6 +1624,7 @@ static int io_submit_one(struct kioctx *ctx, struct iocb __user *user_iocb, req->ki_eventfd = eventfd_fget((int) iocb->aio_resfd); if (IS_ERR(req->ki_eventfd)) { ret = PTR_ERR(req->ki_eventfd); + req->ki_eventfd = NULL; goto out_put_req; } } -- cgit v1.2.3 From 65c24491b4fef017c64e39ec64384fde5e05e0a0 Mon Sep 17 00:00:00 2001 From: Jeff Moyer Date: Wed, 18 Mar 2009 17:04:21 -0700 Subject: aio: lookup_ioctx can return the wrong value when looking up a bogus context The libaio test harness turned up a problem whereby lookup_ioctx on a bogus io context was returning the 1 valid io context from the list (harness/cases/3.p). Because of that, an extra put_iocontext was done, and when the process exited, it hit a BUG_ON in the put_iocontext macro called from exit_aio (since we expect a users count of 1 and instead get 0). The problem was introduced by "aio: make the lookup_ioctx() lockless" (commit abf137dd7712132ee56d5b3143c2ff61a72a5faa). Thanks to Zach for pointing out that hlist_for_each_entry_rcu will not return with a NULL tpos at the end of the loop, even if the entry was not found. Signed-off-by: Jeff Moyer Acked-by: Zach Brown Acked-by: Jens Axboe Cc: Benjamin LaHaise Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/aio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/aio.c b/fs/aio.c index 4a9d4d641fb..76da1253795 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -587,7 +587,7 @@ int aio_put_req(struct kiocb *req) static struct kioctx *lookup_ioctx(unsigned long ctx_id) { struct mm_struct *mm = current->mm; - struct kioctx *ctx = NULL; + struct kioctx *ctx, *ret = NULL; struct hlist_node *n; rcu_read_lock(); @@ -595,12 +595,13 @@ static struct kioctx *lookup_ioctx(unsigned long ctx_id) hlist_for_each_entry_rcu(ctx, n, &mm->ioctx_list, list) { if (ctx->user_id == ctx_id && !ctx->dead) { get_ioctx(ctx); + ret = ctx; break; } } rcu_read_unlock(); - return ctx; + return ret; } /* -- cgit v1.2.3