diff options
author | John W. Linville <linville@tuxdriver.com> | 2012-07-12 13:44:50 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-07-12 13:44:50 -0400 |
commit | 38a00840638b4932152bca48098dbfa069d942a2 (patch) | |
tree | dd12897854f6df8aac237d5fd46551c74be8153a /drivers/net/wimax | |
parent | 391e5c22f5f4e55817f8ba18a08ea717ed2d4a1f (diff) | |
parent | 2f8684ce7a47c91da7e0ccba2686277c103d02b6 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Diffstat (limited to 'drivers/net/wimax')
-rw-r--r-- | drivers/net/wimax/i2400m/Kconfig | 22 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/Makefile | 8 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/driver.c | 3 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/fw.c | 3 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/i2400m-sdio.h | 157 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/i2400m.h | 13 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/sdio-debug-levels.h | 22 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/sdio-fw.c | 210 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/sdio-rx.c | 301 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/sdio-tx.c | 177 | ||||
-rw-r--r-- | drivers/net/wimax/i2400m/sdio.c | 602 |
11 files changed, 8 insertions, 1510 deletions
diff --git a/drivers/net/wimax/i2400m/Kconfig b/drivers/net/wimax/i2400m/Kconfig index 672de18a776..71453db1425 100644 --- a/drivers/net/wimax/i2400m/Kconfig +++ b/drivers/net/wimax/i2400m/Kconfig @@ -7,9 +7,6 @@ config WIMAX_I2400M comment "Enable USB support to see WiMAX USB drivers" depends on USB = n -comment "Enable MMC support to see WiMAX SDIO drivers" - depends on MMC = n - config WIMAX_I2400M_USB tristate "Intel Wireless WiMAX Connection 2400 over USB (including 5x50)" depends on WIMAX && USB @@ -21,25 +18,6 @@ config WIMAX_I2400M_USB If unsure, it is safe to select M (module). -config WIMAX_I2400M_SDIO - tristate "Intel Wireless WiMAX Connection 2400 over SDIO" - depends on WIMAX && MMC - select WIMAX_I2400M - help - Select if you have a device based on the Intel WiMAX - Connection 2400 over SDIO. - - If unsure, it is safe to select M (module). - -config WIMAX_IWMC3200_SDIO - bool "Intel Wireless Multicom WiMAX Connection 3200 over SDIO (EXPERIMENTAL)" - depends on WIMAX_I2400M_SDIO - depends on EXPERIMENTAL - select IWMC3200TOP - help - Select if you have a device based on the Intel Multicom WiMAX - Connection 3200 over SDIO. - config WIMAX_I2400M_DEBUG_LEVEL int "WiMAX i2400m debug level" depends on WIMAX_I2400M diff --git a/drivers/net/wimax/i2400m/Makefile b/drivers/net/wimax/i2400m/Makefile index 5d9e018d31a..f6d19c34808 100644 --- a/drivers/net/wimax/i2400m/Makefile +++ b/drivers/net/wimax/i2400m/Makefile @@ -1,7 +1,6 @@ obj-$(CONFIG_WIMAX_I2400M) += i2400m.o obj-$(CONFIG_WIMAX_I2400M_USB) += i2400m-usb.o -obj-$(CONFIG_WIMAX_I2400M_SDIO) += i2400m-sdio.o i2400m-y := \ control.o \ @@ -21,10 +20,3 @@ i2400m-usb-y := \ usb-tx.o \ usb-rx.o \ usb.o - - -i2400m-sdio-y := \ - sdio.o \ - sdio-tx.o \ - sdio-fw.o \ - sdio-rx.o diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index 47cae7150bc..850b8bc38be 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c @@ -754,8 +754,7 @@ EXPORT_SYMBOL_GPL(i2400m_error_recovery); /* * Alloc the command and ack buffers for boot mode * - * Get the buffers needed to deal with boot mode messages. These - * buffers need to be allocated before the sdio receive irq is setup. + * Get the buffers needed to deal with boot mode messages. */ static int i2400m_bm_buf_alloc(struct i2400m *i2400m) diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index d09e44970e6..283237f6f07 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c @@ -51,8 +51,7 @@ * firmware. Normal hardware takes only signed firmware. * * On boot mode, in USB, we write to the device using the bulk out - * endpoint and read from it in the notification endpoint. In SDIO we - * talk to it via the write address and read from the read address. + * endpoint and read from it in the notification endpoint. * * Upon entrance to boot mode, the device sends (preceded with a few * zero length packets (ZLPs) on the notification endpoint in USB) a diff --git a/drivers/net/wimax/i2400m/i2400m-sdio.h b/drivers/net/wimax/i2400m/i2400m-sdio.h deleted file mode 100644 index 1d63ffdedfd..00000000000 --- a/drivers/net/wimax/i2400m/i2400m-sdio.h +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Intel Wireless WiMAX Connection 2400m - * SDIO-specific i2400m driver definitions - * - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Intel Corporation <linux-wimax@intel.com> - * Brian Bian <brian.bian@intel.com> - * Dirk Brandewie <dirk.j.brandewie@intel.com> - * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> - * Yanir Lubetkin <yanirx.lubetkin@intel.com> - * - Initial implementation - * - * - * This driver implements the bus-specific part of the i2400m for - * SDIO. Check i2400m.h for a generic driver description. - * - * ARCHITECTURE - * - * This driver sits under the bus-generic i2400m driver, providing the - * connection to the device. - * - * When probed, all the function pointers are setup and then the - * bus-generic code called. The generic driver will then use the - * provided pointers for uploading firmware (i2400ms_bus_bm*() in - * sdio-fw.c) and then setting up the device (i2400ms_dev_*() in - * sdio.c). - * - * Once firmware is uploaded, TX functions (sdio-tx.c) are called when - * data is ready for transmission in the TX fifo; then the SDIO IRQ is - * fired and data is available (sdio-rx.c), it is sent to the generic - * driver for processing with i2400m_rx. - */ - -#ifndef __I2400M_SDIO_H__ -#define __I2400M_SDIO_H__ - -#include "i2400m.h" - -/* Host-Device interface for SDIO */ -enum { - I2400M_SDIO_BOOT_RETRIES = 3, - I2400MS_BLK_SIZE = 256, - I2400MS_PL_SIZE_MAX = 0x3E00, - - I2400MS_DATA_ADDR = 0x0, - I2400MS_INTR_STATUS_ADDR = 0x13, - I2400MS_INTR_CLEAR_ADDR = 0x13, - I2400MS_INTR_ENABLE_ADDR = 0x14, - I2400MS_INTR_GET_SIZE_ADDR = 0x2C, - /* The number of ticks to wait for the device to signal that - * it is ready */ - I2400MS_INIT_SLEEP_INTERVAL = 100, - /* How long to wait for the device to settle after reset */ - I2400MS_SETTLE_TIME = 40, - /* The number of msec to wait for IOR after sending IOE */ - IWMC3200_IOR_TIMEOUT = 10, -}; - - -/** - * struct i2400ms - descriptor for a SDIO connected i2400m - * - * @i2400m: bus-generic i2400m implementation; has to be first (see - * it's documentation in i2400m.h). - * - * @func: pointer to our SDIO function - * - * @tx_worker: workqueue struct used to TX data when the bus-generic - * code signals packets are pending for transmission to the device. - * - * @tx_workqueue: workqeueue used for data TX; we don't use the - * system's workqueue as that might cause deadlocks with code in - * the bus-generic driver. The read/write operation to the queue - * is protected with spinlock (tx_lock in struct i2400m) to avoid - * the queue being destroyed in the middle of a the queue read/write - * operation. - * - * @debugfs_dentry: dentry for the SDIO specific debugfs files - * - * Note this value is set to NULL upon destruction; this is - * because some routinges use it to determine if we are inside the - * probe() path or some other path. When debugfs is disabled, - * creation sets the dentry to '(void*) -ENODEV', which is valid - * for the test. - */ -struct i2400ms { - struct i2400m i2400m; /* FIRST! See doc */ - struct sdio_func *func; - - struct work_struct tx_worker; - struct workqueue_struct *tx_workqueue; - char tx_wq_name[32]; - - struct dentry *debugfs_dentry; - - wait_queue_head_t bm_wfa_wq; - int bm_wait_result; - size_t bm_ack_size; - - /* Device is any of the iwmc3200 SKUs */ - unsigned iwmc3200:1; -}; - - -static inline -void i2400ms_init(struct i2400ms *i2400ms) -{ - i2400m_init(&i2400ms->i2400m); -} - - -extern int i2400ms_rx_setup(struct i2400ms *); -extern void i2400ms_rx_release(struct i2400ms *); - -extern int i2400ms_tx_setup(struct i2400ms *); -extern void i2400ms_tx_release(struct i2400ms *); -extern void i2400ms_bus_tx_kick(struct i2400m *); - -extern ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *, - const struct i2400m_bootrom_header *, - size_t, int); -extern ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *, - struct i2400m_bootrom_header *, - size_t); -extern void i2400ms_bus_bm_release(struct i2400m *); -extern int i2400ms_bus_bm_setup(struct i2400m *); - -#endif /* #ifndef __I2400M_SDIO_H__ */ diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index c806d455021..79c6505b5c2 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -46,7 +46,7 @@ * - bus generic driver (this part) * * The bus specific driver sets up stuff specific to the bus the - * device is connected to (USB, SDIO, PCI, tam-tam...non-authoritative + * device is connected to (USB, PCI, tam-tam...non-authoritative * nor binding list) which is basically the device-model management * (probe/disconnect, etc), moving data from device to kernel and * back, doing the power saving details and reseting the device. @@ -238,14 +238,13 @@ struct i2400m_barker_db; * amount needed for loading firmware, where us dev_start/stop setup * the rest needed to do full data/control traffic. * - * @bus_tx_block_size: [fill] SDIO imposes a 256 block size, USB 16, - * so we have a tx_blk_size variable that the bus layer sets to - * tell the engine how much of that we need. + * @bus_tx_block_size: [fill] USB imposes a 16 block size, but other + * busses will differ. So we have a tx_blk_size variable that the + * bus layer sets to tell the engine how much of that we need. * * @bus_tx_room_min: [fill] Minimum room required while allocating - * TX queue's buffer space for message header. SDIO requires - * 224 bytes and USB 16 bytes. Refer bus specific driver code - * for details. + * TX queue's buffer space for message header. USB requires + * 16 bytes. Refer to bus specific driver code for details. * * @bus_pl_size_max: [fill] Maximum payload size. * diff --git a/drivers/net/wimax/i2400m/sdio-debug-levels.h b/drivers/net/wimax/i2400m/sdio-debug-levels.h deleted file mode 100644 index c5199874130..00000000000 --- a/drivers/net/wimax/i2400m/sdio-debug-levels.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * debug levels control file for the i2400m module's - */ -#ifndef __debug_levels__h__ -#define __debug_levels__h__ - -/* Maximum compile and run time debug level for all submodules */ -#define D_MODULENAME i2400m_sdio -#define D_MASTER CONFIG_WIMAX_I2400M_DEBUG_LEVEL - -#include <linux/wimax/debug.h> - -/* List of all the enabled modules */ -enum d_module { - D_SUBMODULE_DECLARE(main), - D_SUBMODULE_DECLARE(tx), - D_SUBMODULE_DECLARE(rx), - D_SUBMODULE_DECLARE(fw) -}; - - -#endif /* #ifndef __debug_levels__h__ */ diff --git a/drivers/net/wimax/i2400m/sdio-fw.c b/drivers/net/wimax/i2400m/sdio-fw.c deleted file mode 100644 index 8e025418f5b..00000000000 --- a/drivers/net/wimax/i2400m/sdio-fw.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Intel Wireless WiMAX Connection 2400m - * Firmware uploader's SDIO specifics - * - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Intel Corporation <linux-wimax@intel.com> - * Yanir Lubetkin <yanirx.lubetkin@intel.com> - * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> - * - Initial implementation - * - * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> - * - Bus generic/specific split for USB - * - * Dirk Brandewie <dirk.j.brandewie@intel.com> - * - Initial implementation for SDIO - * - * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> - * - SDIO rehash for changes in the bus-driver model - * - * Dirk Brandewie <dirk.j.brandewie@intel.com> - * - Make it IRQ based, not polling - * - * THE PROCEDURE - * - * See fw.c for the generic description of this procedure. - * - * This file implements only the SDIO specifics. It boils down to how - * to send a command and waiting for an acknowledgement from the - * device. - * - * All this code is sequential -- all i2400ms_bus_bm_*() functions are - * executed in the same thread, except i2400ms_bm_irq() [on its own by - * the SDIO driver]. This makes it possible to avoid locking. - * - * COMMAND EXECUTION - * - * The generic firmware upload code will call i2400m_bus_bm_cmd_send() - * to send commands. - * - * The SDIO devices expects things in 256 byte blocks, so it will pad - * it, compute the checksum (if needed) and pass it to SDIO. - * - * ACK RECEPTION - * - * This works in IRQ mode -- the fw loader says when to wait for data - * and for that it calls i2400ms_bus_bm_wait_for_ack(). - * - * This checks if there is any data available (RX size > 0); if not, - * waits for the IRQ handler to notify about it. Once there is data, - * it is read and passed to the caller. Doing it this way we don't - * need much coordination/locking, and it makes it much more difficult - * for an interrupt to be lost and the wait_for_ack() function getting - * stuck even when data is pending. - */ -#include <linux/mmc/sdio_func.h> -#include "i2400m-sdio.h" - - -#define D_SUBMODULE fw -#include "sdio-debug-levels.h" - - -/* - * Send a boot-mode command to the SDIO function - * - * We use a bounce buffer (i2400m->bm_cmd_buf) because we need to - * touch the header if the RAW flag is not set. - * - * @flags: pass thru from i2400m_bm_cmd() - * @return: cmd_size if ok, < 0 errno code on error. - * - * Note the command is padded to the SDIO block size for the device. - */ -ssize_t i2400ms_bus_bm_cmd_send(struct i2400m *i2400m, - const struct i2400m_bootrom_header *_cmd, - size_t cmd_size, int flags) -{ - ssize_t result; - struct device *dev = i2400m_dev(i2400m); - struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); - int opcode = _cmd == NULL ? -1 : i2400m_brh_get_opcode(_cmd); - struct i2400m_bootrom_header *cmd; - /* SDIO restriction */ - size_t cmd_size_a = ALIGN(cmd_size, I2400MS_BLK_SIZE); - - d_fnstart(5, dev, "(i2400m %p cmd %p size %zu)\n", - i2400m, _cmd, cmd_size); - result = -E2BIG; - if (cmd_size > I2400M_BM_CMD_BUF_SIZE) - goto error_too_big; - - if (_cmd != i2400m->bm_cmd_buf) - memmove(i2400m->bm_cmd_buf, _cmd, cmd_size); - cmd = i2400m->bm_cmd_buf; - if (cmd_size_a > cmd_size) /* Zero pad space */ - memset(i2400m->bm_cmd_buf + cmd_size, 0, cmd_size_a - cmd_size); - if ((flags & I2400M_BM_CMD_RAW) == 0) { - if (WARN_ON(i2400m_brh_get_response_required(cmd) == 0)) - dev_warn(dev, "SW BUG: response_required == 0\n"); - i2400m_bm_cmd_prepare(cmd); - } - d_printf(4, dev, "BM cmd %d: %zu bytes (%zu padded)\n", - opcode, cmd_size, cmd_size_a); - d_dump(5, dev, cmd, cmd_size); - - sdio_claim_host(i2400ms->func); /* Send & check */ - result = sdio_memcpy_toio(i2400ms->func, I2400MS_DATA_ADDR, - i2400m->bm_cmd_buf, cmd_size_a); - sdio_release_host(i2400ms->func); - if (result < 0) { - dev_err(dev, "BM cmd %d: cannot send: %ld\n", - opcode, (long) result); - goto error_cmd_send; - } - result = cmd_size; -error_cmd_send: -error_too_big: - d_fnend(5, dev, "(i2400m %p cmd %p size %zu) = %d\n", - i2400m, _cmd, cmd_size, (int) result); - return result; -} - - -/* - * Read an ack from the device's boot-mode - * - * @i2400m: - * @_ack: pointer to where to store the read data - * @ack_size: how many bytes we should read - * - * Returns: < 0 errno code on error; otherwise, amount of received bytes. - * - * The ACK for a BM command is always at least sizeof(*ack) bytes, so - * check for that. We don't need to check for device reboots - * - */ -ssize_t i2400ms_bus_bm_wait_for_ack(struct i2400m *i2400m, - struct i2400m_bootrom_header *ack, - size_t ack_size) -{ - ssize_t result; - struct i2400ms *i2400ms = container_of(i2400m, struct i2400ms, i2400m); - struct sdio_func *func = i2400ms->func; - struct device *dev = &func->dev; - int size; - - BUG_ON(sizeof(*ack) > ack_size); - - d_fnstart(5, dev, "(i2400m %p ack %p size %zu)\n", - i2400m, ack, ack_size); - - result = wait_event_timeout(i2400ms->bm_wfa_wq, - i2400ms->bm_ack_size != -EINPROGRESS, - 2 * HZ); - if (result == 0) { - result = -ETIMEDOUT; - dev_err(dev, "BM: error waiting for an ack\n"); - goto error_timeout; - } - - spin_lock(&i2400m->rx_lock); - result = i2400ms->bm_ack_size; - BUG_ON(result == -EINPROGRESS); - if (result < 0) /* so we exit when rx_release() is called */ - dev_err(dev, "BM: %s failed: %zd\n", __func__, result); - else { - size = min(ack_size, i2400ms->bm_ack_size); - memcpy(ack, i2400m->bm_ack_buf, size); - } - /* - * Remember always to clear the bm_ack_size to -EINPROGRESS - * after the RX data is processed - */ - i2400ms->bm_ack_size = -EINPROGRESS; - spin_unlock(&i2400m->rx_lock); - -error_timeout: - d_fnend(5, dev, "(i2400m %p ack %p size %zu) = %zd\n", - i2400m, ack, ack_size, result); - return result; -} diff --git a/drivers/net/wimax/i2400m/sdio-rx.c b/drivers/net/wimax/i2400m/sdio-rx.c deleted file mode 100644 index fb6396dd115..00000000000 --- a/drivers/net/wimax/i2400m/sdio-rx.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Intel Wireless WiMAX Connection 2400m - * SDIO RX handling - * - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Intel Corporation <linux-wimax@intel.com> - * Dirk Brandewie <dirk.j.brandewie@intel.com> - * - Initial implementation - * - * - * This handles the RX path on SDIO. - * - * The SDIO bus driver calls the "irq" routine when data is available. - * This is not a traditional interrupt routine since the SDIO bus - * driver calls us from its irq thread context. Because of this - * sleeping in the SDIO RX IRQ routine is okay. - * - * From there on, we obtain the size of the data that is available, - * allocate an skb, copy it and then pass it to the generic driver's - * RX routine [i2400m_rx()]. - * - * ROADMAP - * - * i2400ms_irq() - * i2400ms_rx() - * __i2400ms_rx_get_size() - * i2400m_is_boot_barker() - * i2400m_rx() - * - * i2400ms_rx_setup() - * - * i2400ms_rx_release() - */ -#include <linux/workqueue.h> -#include <linux/wait.h> -#include <linux/skbuff.h> -#include <linux/mmc/sdio.h> -#include <linux/mmc/sdio_func.h> -#include <linux/slab.h> -#include "i2400m-sdio.h" - -#define D_SUBMODULE rx -#include "sdio-debug-levels.h" - -static const __le32 i2400m_ACK_BARKER[4] = { - __constant_cpu_to_le32(I2400M_ACK_BARKER), - __constant_cpu_to_le32(I2400M_ACK_BARKER), - __constant_cpu_to_le32(I2400M_ACK_BARKER), - __constant_cpu_to_le32(I2400M_ACK_BARKER) -}; - - -/* - * Read and return the amount of bytes available for RX - * - * The RX size has to be read like this: byte reads of three - * sequential locations; then glue'em together. - * - * sdio_readl() doesn't work. - */ -static ssize_t __i2400ms_rx_get_size(struct i2400ms *i2400ms) -{ - int ret, cnt, val; - ssize_t rx_size; - unsigned xfer_size_addr; - struct sdio_func *func = i2400ms->func; - struct device *dev = &i2400ms->func->dev; - - d_fnstart(7, dev, "(i2400ms %p)\n", i2400ms); - xfer_size_addr = I2400MS_INTR_GET_SIZE_ADDR; - rx_size = 0; - for (cnt = 0; cnt < 3; cnt++) { - val = sdio_readb(func, xfer_size_addr + cnt, &ret); - if (ret < 0) { - dev_err(dev, "RX: Can't read byte %d of RX size from " - "0x%08x: %d\n", cnt, xfer_size_addr + cnt, ret); - rx_size = ret; - goto error_read; - } - rx_size = rx_size << 8 | (val & 0xff); - } - d_printf(6, dev, "RX: rx_size is %ld\n", (long) rx_size); -error_read: - d_fnend(7, dev, "(i2400ms %p) = %ld\n", i2400ms, (long) rx_size); - return rx_size; -} - - -/* - * Read data from the device (when in normal) - * - * Allocate an SKB of the right size, read the data in and then - * deliver it to the generic layer. - * - * We also check for a reboot barker. That means the device died and - * we have to reboot it. - */ -static -void i2400ms_rx(struct i2400ms *i2400ms) -{ - int ret; - struct sdio_func *func = i2400ms->func; - struct device *dev = &func->dev; - struct i2400m *i2400m = &i2400ms->i2400m; - struct sk_buff *skb; - ssize_t rx_size; - - d_fnstart(7, dev, "(i2400ms %p)\n", i2400ms); - rx_size = __i2400ms_rx_get_size(i2400ms); - if (rx_size < 0) { - ret = rx_size; - goto error_get_size; - } - /* - * Hardware quirk: make sure to clear the INTR status register - * AFTER getting the data transfer size. - */ - sdio_writeb(func, 1, I2400MS_INTR_CLEAR_ADDR, &ret); - - ret = -ENOMEM; - skb = alloc_skb(rx_size, GFP_ATOMIC); - if (NULL == skb) { - dev_err(dev, "RX: unable to alloc skb\n"); - goto error_alloc_skb; - } - ret = sdio_memcpy_fromio(func, skb->data, - I2400MS_DATA_ADDR, rx_size); - if (ret < 0) { - dev_err(dev, "RX: SDIO data read failed: %d\n", ret); - goto error_memcpy_fromio; - } - - rmb(); /* make sure we get boot_mode from dev_reset_handle */ - if (unlikely(i2400m->boot_mode == 1)) { - spin_lock(&i2400m->rx_lock); - i2400ms->bm_ack_size = rx_size; - spin_unlock(&i2400m->rx_lock); - memcpy(i2400m->bm_ack_buf, skb->data, rx_size); - wake_up(&i2400ms->bm_wfa_wq); - d_printf(5, dev, "RX: SDIO boot mode message\n"); - kfree_skb(skb); - goto out; - } - ret = -EIO; - if (unlikely(rx_size < sizeof(__le32))) { - dev_err(dev, "HW BUG? only %zu bytes received\n", rx_size); - goto error_bad_size; - } - if (likely(i2400m_is_d2h_barker(skb->data))) { - skb_put(skb, rx_size); - i2400m_rx(i2400m, skb); - } else if (unlikely(i2400m_is_boot_barker(i2400m, - skb->data, rx_size))) { - ret = i2400m_dev_reset_handle(i2400m, "device rebooted"); - dev_err(dev, "RX: SDIO reboot barker\n"); - kfree_skb(skb); - } else { - i2400m_unknown_barker(i2400m, skb->data, rx_size); - kfree_skb(skb); - } -out: - d_fnend(7, dev, "(i2400ms %p) = void\n", i2400ms); - return; - -error_memcpy_fromio: - kfree_skb(skb); -error_alloc_skb: -error_get_size: -error_bad_size: - d_fnend(7, dev, "(i2400ms %p) = %d\n", i2400ms, ret); -} - - -/* - * Process an interrupt from the SDIO card - * - * FIXME: need to process other events that are not just ready-to-read - * - * Checks there is data ready and then proceeds to read it. - */ -static -void i2400ms_irq(struct sdio_func *func) -{ - int ret; - struct i2400ms *i2400ms = sdio_get_drvdata(func); - struct device *dev = &func->dev; - int val; - - d_fnstart(6, dev, "(i2400ms %p)\n", i2400ms); - val = sdio_readb(func, I2400MS_INTR_STATUS_ADDR, &ret); - if (ret < 0) { - dev_err(dev, "RX: Can't read interrupt status: %d\n", ret); - goto error_no_irq; - } - if (!val) { - dev_err(dev, "RX: BUG? got IRQ but no interrupt ready?\n"); - goto error_no_irq; - } - i2400ms_rx(i2400ms); -error_no_irq: - d_fnend(6, dev, "(i2400ms %p) = void\n", i2400ms); -} - - -/* - * Setup SDIO RX - * - * Hooks up the IRQ handler and then enables IRQs. - */ -int i2400ms_rx_setup(struct i2400ms *i2400ms) -{ - int result; - struct sdio_func *func = i2400ms->func; - struct device *dev = &func->dev; - struct i2400m *i2400m = &i2400ms->i2400m; - - d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); - - init_waitqueue_head(&i2400ms->bm_wfa_wq); - spin_lock(&i2400m->rx_lock); - i2400ms->bm_wait_result = -EINPROGRESS; - /* - * Before we are about to enable the RX interrupt, make sure - * bm_ack_size is cleared to -EINPROGRESS which indicates - * no RX interrupt happened yet or the previous interrupt - * has been handled, we are ready to take the new interrupt - */ - i2400ms->bm_ack_size = -EINPROGRESS; - spin_unlock(&i2400m->rx_lock); - - sdio_claim_host(func); - result = sdio_claim_irq(func, i2400ms_irq); - if (result < 0) { - dev_err(dev, "Cannot claim IRQ: %d\n", result); - goto error_irq_claim; - } - result = 0; - sdio_writeb(func, 1, I2400MS_INTR_ENABLE_ADDR, &result); - if (result < 0) { - sdio_release_irq(func); - dev_err(dev, "Failed to enable interrupts %d\n", result); - } -error_irq_claim: - sdio_release_host(func); - d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result); - return result; -} - - -/* - * Tear down SDIO RX - * - * Disables IRQs in the device and removes the IRQ handler. - */ -void i2400ms_rx_release(struct i2400ms *i2400ms) -{ - int result; - struct sdio_func *func = i2400ms->func; - struct device *dev = &func->dev; - struct i2400m *i2400m = &i2400ms->i2400m; - - d_fnstart(5, dev, "(i2400ms %p)\n", i2400ms); - spin_lock(&i2400m->rx_lock); - i2400ms->bm_ack_size = -EINTR; - spin_unlock(&i2400m->rx_lock); - wake_up_all(&i2400ms->bm_wfa_wq); - sdio_claim_host(func); - sdio_writeb(func, 0, I2400MS_INTR_ENABLE_ADDR, &result); - sdio_release_irq(func); - sdio_release_host(func); - d_fnend(5, dev, "(i2400ms %p) = %d\n", i2400ms, result); -} diff --git a/drivers/net/wimax/i2400m/sdio-tx.c b/drivers/net/wimax/i2400m/sdio-tx.c deleted file mode 100644 index b53cd1c80e3..00000000000 --- a/drivers/net/wimax/i2400m/sdio-tx.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Intel Wireless WiMAX Connection 2400m - * SDIO TX transaction backends - * - * - * Copyright (C) 2007-2008 Intel Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Intel Corporation <linux-wimax@intel.com> - * Dirk Brandewie <dirk.j.brandewie@intel.com> - * - Initial implementation - * - * - * Takes the TX messages in the i2400m's driver TX FIFO and sends them - * to the device until there are no more. - * - * If we fail sending the message, we just drop it. There isn't much - * we can do at this point. Most of the traffic is network, which has - * recovery methods for dropped packets. - * - * The SDIO functions are not atomic, so we can't run from the context - * where i2400m->bus_tx_kick() [i2400ms_bus_tx_kick()] is being called - * (some times atomic). Thus, the actual TX work is deferred to a - * workqueue. - * - * ROADMAP - * - * i2400ms_bus_tx_kick() - * i2400ms_tx_submit() [through workqueue] - * - * i2400m_tx_setup() - * - * i2400m_tx_release() - */ -#include <linux/mmc/sdio_func.h> -#include "i2400m-sdio.h" - -#define D_SUBMODULE tx -#include "sdio-debug-levels.h" - - -/* - * Pull TX transations from the TX FIFO and send them to the device - * until there are no more. - */ -static -void i2400ms_tx_submit(struct work_struct *ws) -{ - int result; - struct i2400ms *i2400ms = container_of(ws, struct i2400ms, tx_worker); - struct i2400m *i2400m = &i2400ms->i2400m; - struct sdio_func *func = i2400ms->func; - struct device *dev = &func->dev; - struct i2400m_msg_hdr *tx_msg; - size_t tx_msg_size; - - d_fnstart(4, dev, "(i2400ms %p, i2400m %p)\n", i2400ms, i2400ms); - - while (NULL != (tx_msg = i2400m_tx_msg_get(i2400m, &tx_msg_size))) { - d_printf(2, dev, "TX: submitting %zu bytes\n", tx_msg_size); - d_dump(5, dev, tx_msg, tx_msg_size); - |