diff options
98 files changed, 533 insertions, 19333 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 2b339a9e5ab6..2cce3a8d2595 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -21241,7 +21241,7 @@ S: Maintained F: drivers/staging/sm750fb/ STAGING - VIA VT665X DRIVERS -M: Forest Bond <forest@alittletooquiet.net> +M: Philipp Hortmann <philipp.g.hortmann@gmail.com> S: Odd Fixes F: drivers/staging/vt665?/ diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 5175b1c4f161..db4a392841b1 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -24,8 +24,6 @@ menuconfig STAGING if STAGING -source "drivers/staging/wlan-ng/Kconfig" - source "drivers/staging/olpc_dcon/Kconfig" source "drivers/staging/rtl8192e/Kconfig" @@ -62,8 +60,6 @@ source "drivers/staging/greybus/Kconfig" source "drivers/staging/vc04_services/Kconfig" -source "drivers/staging/pi433/Kconfig" - source "drivers/staging/axis-fifo/Kconfig" source "drivers/staging/fieldbus/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 67399c0ad871..5390879b5d1b 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -2,7 +2,6 @@ # Makefile for staging directory obj-y += media/ -obj-$(CONFIG_PRISM2_USB) += wlan-ng/ obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_RTL8723BS) += rtl8723bs/ @@ -21,6 +20,5 @@ obj-$(CONFIG_MOST) += most/ obj-$(CONFIG_KS7010) += ks7010/ obj-$(CONFIG_GREYBUS) += greybus/ obj-$(CONFIG_BCM2835_VCHIQ) += vc04_services/ -obj-$(CONFIG_PI433) += pi433/ obj-$(CONFIG_XIL_AXIS_FIFO) += axis-fifo/ obj-$(CONFIG_FIELDBUS_DEV) += fieldbus/ diff --git a/drivers/staging/axis-fifo/axis-fifo.c b/drivers/staging/axis-fifo/axis-fifo.c index c51818c56dd2..1bbb9a6db597 100644 --- a/drivers/staging/axis-fifo/axis-fifo.c +++ b/drivers/staging/axis-fifo/axis-fifo.c @@ -376,8 +376,8 @@ static ssize_t axis_fifo_read(struct file *f, char __user *buf, */ mutex_lock(&fifo->read_lock); ret = wait_event_interruptible_timeout(fifo->read_queue, - ioread32(fifo->base_addr + XLLF_RDFO_OFFSET), - read_timeout); + ioread32(fifo->base_addr + XLLF_RDFO_OFFSET), + read_timeout); if (ret <= 0) { if (ret == 0) { @@ -517,9 +517,9 @@ static ssize_t axis_fifo_write(struct file *f, const char __user *buf, */ mutex_lock(&fifo->write_lock); ret = wait_event_interruptible_timeout(fifo->write_queue, - ioread32(fifo->base_addr + XLLF_TDFV_OFFSET) - >= words_to_write, - write_timeout); + ioread32(fifo->base_addr + XLLF_TDFV_OFFSET) + >= words_to_write, + write_timeout); if (ret <= 0) { if (ret == 0) { diff --git a/drivers/staging/fbtft/fb_seps525.c b/drivers/staging/fbtft/fb_seps525.c index 05882e2cde7f..46c257308b49 100644 --- a/drivers/staging/fbtft/fb_seps525.c +++ b/drivers/staging/fbtft/fb_seps525.c @@ -16,11 +16,10 @@ * GNU General Public License for more details. */ -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/gpio.h> +#include <linux/bits.h> #include <linux/delay.h> +#include <linux/init.h> +#include <linux/module.h> #include "fbtft.h" diff --git a/drivers/staging/greybus/arche-apb-ctrl.c b/drivers/staging/greybus/arche-apb-ctrl.c index 8541995008da..aa6f266b62a1 100644 --- a/drivers/staging/greybus/arche-apb-ctrl.c +++ b/drivers/staging/greybus/arche-apb-ctrl.c @@ -466,6 +466,7 @@ static const struct of_device_id arche_apb_ctrl_of_match[] = { { .compatible = "usbffff,2", }, { }, }; +MODULE_DEVICE_TABLE(of, arche_apb_ctrl_of_match); static struct platform_driver arche_apb_ctrl_device_driver = { .probe = arche_apb_ctrl_probe, diff --git a/drivers/staging/greybus/arche-platform.c b/drivers/staging/greybus/arche-platform.c index 891b75327d7f..b33977ccd527 100644 --- a/drivers/staging/greybus/arche-platform.c +++ b/drivers/staging/greybus/arche-platform.c @@ -619,14 +619,7 @@ static const struct of_device_id arche_platform_of_match[] = { { .compatible = "google,arche-platform", }, { }, }; - -static const struct of_device_id arche_combined_id[] = { - /* Use PID/VID of SVC device */ - { .compatible = "google,arche-platform", }, - { .compatible = "usbffff,2", }, - { }, -}; -MODULE_DEVICE_TABLE(of, arche_combined_id); +MODULE_DEVICE_TABLE(of, arche_platform_of_match); static struct platform_driver arche_platform_device_driver = { .probe = arche_platform_probe, diff --git a/drivers/staging/greybus/audio_manager_module.c b/drivers/staging/greybus/audio_manager_module.c index 5f9dcbdbc191..4a4dfb42f50f 100644 --- a/drivers/staging/greybus/audio_manager_module.c +++ b/drivers/staging/greybus/audio_manager_module.c @@ -144,7 +144,7 @@ static struct attribute *gb_audio_module_default_attrs[] = { }; ATTRIBUTE_GROUPS(gb_audio_module_default); -static struct kobj_type gb_audio_module_type = { +static const struct kobj_type gb_audio_module_type = { .sysfs_ops = &gb_audio_module_sysfs_ops, .release = gb_audio_module_release, .default_groups = gb_audio_module_default_groups, diff --git a/drivers/staging/greybus/camera.c b/drivers/staging/greybus/camera.c index a8173aa3a995..b8b2bdfa59e5 100644 --- a/drivers/staging/greybus/camera.c +++ b/drivers/staging/greybus/camera.c @@ -180,10 +180,6 @@ static const struct gb_camera_fmt_info *gb_camera_get_format_info(u16 gb_fmt) #define GB_CAMERA_MAX_SETTINGS_SIZE 8192 -#define gcam_dbg(gcam, format...) dev_dbg(&gcam->bundle->dev, format) -#define gcam_info(gcam, format...) dev_info(&gcam->bundle->dev, format) -#define gcam_err(gcam, format...) dev_err(&gcam->bundle->dev, format) - static int gb_camera_operation_sync_flags(struct gb_connection *connection, int type, unsigned int flags, void *request, size_t request_size, @@ -232,8 +228,8 @@ static int gb_camera_get_max_pkt_size(struct gb_camera *gcam, fmt_info = gb_camera_get_format_info(cfg->format); if (!fmt_info) { - gcam_err(gcam, "unsupported greybus image format: %d\n", - cfg->format); + dev_err(&gcam->bundle->dev, "unsupported greybus image format: %d\n", + cfg->format); return -EIO; } @@ -241,18 +237,18 @@ static int gb_camera_get_max_pkt_size(struct gb_camera *gcam, pkt_size = le32_to_cpu(cfg->max_pkt_size); if (pkt_size == 0) { - gcam_err(gcam, - "Stream %u: invalid zero maximum packet size\n", - i); + dev_err(&gcam->bundle->dev, + "Stream %u: invalid zero maximum packet size\n", + i); return -EIO; } } else { pkt_size = le16_to_cpu(cfg->width) * fmt_info->bpp / 8; if (pkt_size != le32_to_cpu(cfg->max_pkt_size)) { - gcam_err(gcam, - "Stream %u: maximum packet size mismatch (%u/%u)\n", - i, pkt_size, cfg->max_pkt_size); + dev_err(&gcam->bundle->dev, + "Stream %u: maximum packet size mismatch (%u/%u)\n", + i, pkt_size, cfg->max_pkt_size); return -EIO; } } @@ -275,13 +271,13 @@ static const int gb_camera_configure_streams_validate_response(struct gb_camera /* Validate the returned response structure */ if (resp->padding[0] || resp->padding[1]) { - gcam_err(gcam, "response padding != 0\n"); + dev_err(&gcam->bundle->dev, "response padding != 0\n"); return -EIO; } if (resp->num_streams > nstreams) { - gcam_err(gcam, "got #streams %u > request %u\n", - resp->num_streams, nstreams); + dev_err(&gcam->bundle->dev, "got #streams %u > request %u\n", + resp->num_streams, nstreams); return -EIO; } @@ -289,7 +285,7 @@ static const int gb_camera_configure_streams_validate_response(struct gb_camera struct gb_camera_stream_config_response *cfg = &resp->config[i]; if (cfg->padding) { - gcam_err(gcam, "stream #%u padding != 0\n", i); + dev_err(&gcam->bundle->dev, "stream #%u padding != 0\n", i); return -EIO; } } @@ -340,16 +336,16 @@ static int gb_camera_set_power_mode(struct gb_camera *gcam, bool hs) ret = gb_camera_set_intf_power_mode(gcam, intf->interface_id, hs); if (ret < 0) { - gcam_err(gcam, "failed to set module interface to %s (%d)\n", - hs ? "HS" : "PWM", ret); + dev_err(&gcam->bundle->dev, "failed to set module interface to %s (%d)\n", + hs ? "HS" : "PWM", ret); return ret; } ret = gb_camera_set_intf_power_mode(gcam, svc->ap_intf_id, hs); if (ret < 0) { gb_camera_set_intf_power_mode(gcam, intf->interface_id, !hs); - gcam_err(gcam, "failed to set AP interface to %s (%d)\n", - hs ? "HS" : "PWM", ret); + dev_err(&gcam->bundle->dev, "failed to set AP interface to %s (%d)\n", + hs ? "HS" : "PWM", ret); return ret; } @@ -435,7 +431,7 @@ static int gb_camera_setup_data_connection(struct gb_camera *gcam, sizeof(csi_cfg), GB_APB_REQUEST_CSI_TX_CONTROL, false); if (ret < 0) { - gcam_err(gcam, "failed to start the CSI transmitter\n"); + dev_err(&gcam->bundle->dev, "failed to start the CSI transmitter\n"); goto error_power; } @@ -470,7 +466,7 @@ static void gb_camera_teardown_data_connection(struct gb_camera *gcam) GB_APB_REQUEST_CSI_TX_CONTROL, false); if (ret < 0) - gcam_err(gcam, "failed to stop the CSI transmitter\n"); + dev_err(&gcam->bundle->dev, "failed to stop the CSI transmitter\n"); /* Set the UniPro link to low speed mode. */ gb_camera_set_power_mode(gcam, false); @@ -507,7 +503,7 @@ static int gb_camera_capabilities(struct gb_camera *gcam, NULL, 0, (void *)capabilities, size); if (ret) - gcam_err(gcam, "failed to retrieve capabilities: %d\n", ret); + dev_err(&gcam->bundle->dev, "failed to retrieve capabilities: %d\n", ret); done: mutex_unlock(&gcam->mutex); @@ -723,22 +719,22 @@ static int gb_camera_request_handler(struct gb_operation *op) struct gb_message *request; if (op->type != GB_CAMERA_TYPE_METADATA) { - gcam_err(gcam, "Unsupported unsolicited event: %u\n", op->type); + dev_err(&gcam->bundle->dev, "Unsupported unsolicited event: %u\n", op->type); return -EINVAL; } request = op->request; if (request->payload_size < sizeof(*payload)) { - gcam_err(gcam, "Wrong event size received (%zu < %zu)\n", - request->payload_size, sizeof(*payload)); + dev_err(&gcam->bundle->dev, "Wrong event size received (%zu < %zu)\n", + request->payload_size, sizeof(*payload)); return -EINVAL; } payload = request->payload; - gcam_dbg(gcam, "received metadata for request %u, frame %u, stream %u\n", - payload->request_id, payload->frame_number, payload->stream); + dev_dbg(&gcam->bundle->dev, "received metadata for request %u, frame %u, stream %u\n", + payload->request_id, payload->frame_number, payload->stream); return 0; } @@ -1347,15 +1343,15 @@ static int gb_camera_resume(struct device *dev) ret = gb_connection_enable(gcam->connection); if (ret) { - gcam_err(gcam, "failed to enable connection: %d\n", ret); + dev_err(&gcam->bundle->dev, "failed to enable connection: %d\n", ret); return ret; } if (gcam->data_connection) { ret = gb_connection_enable(gcam->data_connection); if (ret) { - gcam_err(gcam, - "failed to enable data connection: %d\n", ret); + dev_err(&gcam->bundle->dev, + "failed to enable data connection: %d\n", ret); return ret; } } diff --git a/drivers/staging/greybus/fw-management.c b/drivers/staging/greybus/fw-management.c index 3054f084d777..a47385175582 100644 --- a/drivers/staging/greybus/fw-management.c +++ b/drivers/staging/greybus/fw-management.c @@ -123,8 +123,7 @@ static int fw_mgmt_interface_fw_version_operation(struct fw_mgmt *fw_mgmt, fw_info->major = le16_to_cpu(response.major); fw_info->minor = le16_to_cpu(response.minor); - strncpy(fw_info->firmware_tag, response.firmware_tag, - GB_FIRMWARE_TAG_MAX_SIZE); + strscpy_pad(fw_info->firmware_tag, response.firmware_tag); /* * The firmware-tag should be NULL terminated, otherwise throw error but @@ -153,7 +152,7 @@ static int fw_mgmt_load_and_validate_operation(struct fw_mgmt *fw_mgmt, } request.load_method = load_method; - strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE); + strscpy_pad(request.firmware_tag, tag); /* * The firmware-tag should be NULL terminated, otherwise throw error and @@ -249,8 +248,7 @@ static int fw_mgmt_backend_fw_version_operation(struct fw_mgmt *fw_mgmt, struct gb_fw_mgmt_backend_fw_version_response response; int ret; - strncpy(request.firmware_tag, fw_info->firmware_tag, - GB_FIRMWARE_TAG_MAX_SIZE); + strscpy_pad(request.firmware_tag, fw_info->firmware_tag); /* * The firmware-tag should be NULL terminated, otherwise throw error and @@ -303,13 +301,13 @@ static int fw_mgmt_backend_fw_update_operation(struct fw_mgmt *fw_mgmt, struct gb_fw_mgmt_backend_fw_update_request request; int ret; - strncpy(request.firmware_tag, tag, GB_FIRMWARE_TAG_MAX_SIZE); + ret = strscpy_pad(request.firmware_tag, tag); /* * The firmware-tag should be NULL terminated, otherwise throw error and * fail. */ - if (request.firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE - 1] != '\0') { + if (ret == -E2BIG) { dev_err(fw_mgmt->parent, "backend-update: firmware-tag is not NULL terminated\n"); return -EINVAL; } diff --git a/drivers/staging/greybus/light.c b/drivers/staging/greybus/light.c index a5c2fe963866..00360f4a0485 100644 --- a/drivers/staging/greybus/light.c +++ b/drivers/staging/greybus/light.c @@ -142,6 +142,9 @@ static int __gb_lights_flash_brightness_set(struct gb_channel *channel) channel = get_channel_from_mode(channel->light, GB_CHANNEL_MODE_TORCH); + if (!channel) + return -EINVAL; + /* For not flash we need to convert brightness to intensity */ intensity = channel->intensity_uA.min + (channel->intensity_uA.step * channel->led->brightness); @@ -528,7 +531,10 @@ static int gb_lights_light_v4l2_register(struct gb_light *light) } channel_flash = get_channel_from_mode(light, GB_CHANNEL_MODE_FLASH); - WARN_ON(!channel_flash); + if (!channel_flash) { + dev_err(dev, "failed to get flash channel from mode\n"); + return -EINVAL; + } fled = &channel_flash->fled; diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index bb33379b5297..4313d3bbc23a 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -101,6 +101,7 @@ struct gb_loopback { static struct class loopback_class = { .name = "gb_loopback", }; + static DEFINE_IDA(loopback_ida); /* Min/max values in jiffies */ diff --git a/drivers/staging/ks7010/ks7010_sdio.c b/drivers/staging/ks7010/ks7010_sdio.c index f1d44e4955fc..8df0e77b57f6 100644 --- a/drivers/staging/ks7010/ks7010_sdio.c +++ b/drivers/staging/ks7010/ks7010_sdio.c @@ -1136,7 +1136,7 @@ static struct sdio_driver ks7010_sdio_driver = { .remove = ks7010_sdio_remove, }; -module_driver(ks7010_sdio_driver, sdio_register_driver, sdio_unregister_driver); +module_sdio_driver(ks7010_sdio_driver); MODULE_AUTHOR("Sang Engineering, Qi-Hardware, KeyStream"); MODULE_DESCRIPTION("Driver for KeyStream KS7010 based SDIO cards"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/nvec/TODO b/drivers/staging/nvec/TODO index 8afde3ccc960..33f9ebe6d59b 100644 --- a/drivers/staging/nvec/TODO +++ b/drivers/staging/nvec/TODO @@ -1,5 +1,4 @@ ToDo list (incomplete, unordered) - move the driver to the new i2c slave framework - finish suspend/resume support - - fix udelay in the isr - add atomic ops in order to fix shutoff/reboot problems diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 282a664c9176..e5ca78e57384 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -300,7 +300,9 @@ int nvec_write_sync(struct nvec_chip *nvec, { mutex_lock(&nvec->sync_write_mutex); - *msg = NULL; + if (msg != NULL) + *msg = NULL; + nvec->sync_write_pending = (data[1] << 8) + data[0]; if (nvec_write_async(nvec, data, size) < 0) { @@ -320,7 +322,10 @@ int nvec_write_sync(struct nvec_chip *nvec, dev_dbg(nvec->dev, "nvec_sync_write: pong!\n"); - *msg = nvec->last_sync_msg; + if (msg != NULL) + *msg = nvec->last_sync_msg; + else + nvec_msg_free(nvec, nvec->last_sync_msg); mutex_unlock(&nvec->sync_write_mutex); @@ -712,7 +717,7 @@ static irqreturn_t nvec_interrupt(int irq, void *dev) * TODO: replace the udelay with a read back after each writel above * in order to work around a hardware issue, see i2c-tegra.c * - * Unfortunately, this change causes an intialisation issue with the + * Unfortunately, this change causes an initialisation issue with the * touchpad, which needs to be fixed first. */ udelay(100); diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index f9a1da952c0a..d0259c80f810 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -148,15 +148,16 @@ static int nvec_kbd_probe(struct platform_device *pdev) nvec_register_notifier(nvec, &keys_dev.notifier, 0); /* Enable keyboard */ - nvec_write_async(nvec, enable_kbd, 2); + nvec_write_sync(nvec, enable_kbd, 2, NULL); /* configures wake on special keys */ - nvec_write_async(nvec, cnfg_wake, 4); + nvec_write_sync(nvec, cnfg_wake, 4, NULL); + /* enable wake key reporting */ - nvec_write_async(nvec, cnfg_wake_key_reporting, 3); + nvec_write_sync(nvec, cnfg_wake_key_reporting, 3, NULL); /* Disable caps lock LED */ - nvec_write_async(nvec, clear_leds, sizeof(clear_leds)); + nvec_write_sync(nvec, clear_leds, sizeof(clear_leds), NULL); return 0; } diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index cb6d71b8dc83..f34016c4a26b 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -60,16 +60,6 @@ static void ps2_stopstreaming(struct serio *ser_dev) nvec_write_async(ps2_dev.nvec, buf, sizeof(buf)); } -static int ps2_sendcommand(struct serio *ser_dev, unsigned char cmd) -{ - unsigned char buf[] = { NVEC_PS2, SEND_COMMAND, ENABLE_MOUSE, 1 }; - - buf[2] = cmd & 0xff; - - dev_dbg(&ser_dev->dev, "Sending ps2 cmd %02x\n", cmd); - return nvec_write_async(ps2_dev.nvec, buf, sizeof(buf)); -} - static int nvec_ps2_notifier(struct notifier_block *nb, unsigned long event_type, void *data) { @@ -98,6 +88,27 @@ static int nvec_ps2_notifier(struct notifier_block *nb, return NOTIFY_DONE; } +static int ps2_sendcommand(struct serio *ser_dev, unsigned char cmd) +{ + unsigned char buf[] = { NVEC_PS2, SEND_COMMAND, ENABLE_MOUSE, 1 }; + struct nvec_msg *msg; + int ret; + + buf[2] = cmd & 0xff; + + dev_dbg(&ser_dev->dev, "Sending ps2 cmd %02x\n", cmd); + + ret = nvec_write_sync(ps2_dev.nvec, buf, sizeof(buf), &msg); + if (ret < 0) + return ret; + + nvec_ps2_notifier(NULL, NVEC_PS2, msg->data); + + nvec_msg_free(ps2_dev.nvec, msg); + + return 0; +} + static int nvec_mouse_probe(struct platform_device *pdev) { struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); diff --git a/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dtso b/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dtso deleted file mode 100644 index 096137fcd5cc..000000000000 --- a/drivers/staging/pi433/Documentation/devicetree/pi433-overlay.dtso +++ /dev/null @@ -1,48 +0,0 @@ -// Definitions for Pi433 -/dts-v1/; -/plugin/; - -/ { - compatible = "brcm,bcm2835", "brcm,bcm2708", "brcm,bcm2709"; -}; - -&spi0 { - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - - spidev@0{ - reg = <0>; - status = "disabled"; - }; - - spidev@1{ - reg = <1>; - status = "disabled"; - }; -}; - -&gpio { - pi433_pins: pi433_pins { - brcm,pins = <7 25 24>; - brcm,function = <0 0 0>; // in in in - }; -}; - -&spi0 { - #address-cells = <1>; - #size-cells = <0>; - status = "okay"; - - pi433: pi433@0 { - compatible = "Smarthome-Wolf,pi433"; - reg = <0>; - spi-max-frequency = <10000000>; - status = "okay"; - - pinctrl-0 = <&pi433_pins>; - DIO0-gpio = <&gpio 24 0>; - DIO1-gpio = <&gpio 25 0>; - DIO2-gpio = <&gpio 7 0>; - }; -}; diff --git a/drivers/staging/pi433/Documentation/devicetree/pi433.txt b/drivers/staging/pi433/Documentation/devicetree/pi433.txt deleted file mode 100644 index d317c0ec3419..000000000000 --- a/drivers/staging/pi433/Documentation/devicetree/pi433.txt +++ /dev/null @@ -1,62 +0,0 @@ -* Smarthome-Wolf Pi433 - a 433MHz radio module/shield for Raspberry Pi (see www.pi433.de) - -Required properties: -- compatible: must be "Smarthome-Wolf,pi433" -- reg: chip select of SPI Interface -- DIOx-gpio must be dedicated to the GPIO, connected with DIOx of the RFM69 module - - -Example: - -With the following lines in gpio-section, the gpio pins, connected with pi433 are -reserved/declared. - -&gpio{ - [...] - - pi433_pins: pi433_pins { - brcm,pins = <7 25 24>; - brcm,function = <0 0 0>; // in in in - }; - - [...] -} - -With the following lines in spi section, the device pi433 is declared. -It consists of the three gpio pins and an spi interface (here chip select 0) - -&spi0{ - [...] - - pi433: pi433@0 { - compatible = "Smarthome-Wolf,pi433"; - reg = <0>; /* CE 0 */ - #address-cells = <1>; - #size-cells = <0>; - spi-max-frequency = <10000000>; - - pinctrl-0 = <&pi433_pins>; - DIO0-gpio = <&gpio 24 0>; - DIO1-gpio = <&gpio 25 0>; - DIO2-gpio = <&gpio 7 0>; - }; -} - - - -For Raspbian users only -======================= -Since Raspbian supports device tree overlays, you may use an overlay instead -of editing your boards device tree. -To use the overlay, you need to compile the file pi433-overlay.dtso which can -be found alongside this documentation. -The file needs to be compiled - either manually or by integration in your kernel -source tree. For a manual compile, you may use a command line like the following: -'linux/scripts/dtc/dtc -@ -I dts -O dtb -o pi433.dtbo pi433-overlay.dtso' - -For compiling inside of the kernel tree, you need to copy pi433-overlay.dtso to -arch/arm/boot/dts/overlays and you need to add the file to the list of files -in the Makefile over there. Execute 'make dtbs' in kernel tree root to make the -kernel make files compile the device tree overlay for you. - - diff --git a/drivers/staging/pi433/Documentation/pi433.txt b/drivers/staging/pi433/Documentation/pi433.txt deleted file mode 100644 index 4a0d34b4ad37..000000000000 --- a/drivers/staging/pi433/Documentation/pi433.txt +++ /dev/null @@ -1,274 +0,0 @@ -===== -Pi433 -===== - - -Introduction -============ -This driver is for controlling pi433, a radio module for the Raspberry Pi -(www.pi433.de). It supports transmission and reception. It can be opened -by multiple applications for transmission and reception. While transmit -jobs are queued and processed automatically in the background, the first -application asking for reception will block out all other applications -until something gets received terminates the read request. -The driver supports on the fly reloading of the hardware fifo of the rf -chip, thus enabling for much longer telegrams than the hardware fifo size. - -Description of driver operation -=============================== - -a) transmission - -Each transmission can take place with a different configuration of the rf -module. Therefore each application can set its own set of parameters. The driver -takes care, that each transmission takes place with the parameterset of the -application, that requests the transmission. To allow the transmission to take -place in the background, a tx thread is introduced. -The transfer of data from the main thread to the tx thread is realised by a -kfifo. With each write request of an application, the passed in data and the -corresponding parameter set gets written to the kfifo. -On the other "side" of the kfifo, the tx thread continuously checks, whether the -kfifo is empty. If not, it gets one set of config and data from the kfifo. If -there is no receive request or the receiver is still waiting for something in -the air, the rf module is set to standby, the parameters for transmission gets -set, the hardware fifo of the rf chip gets preloaded and the transmission gets -started. Upon hardware fifo threshold interrupt it gets reloaded, thus enabling -much longer telegrams than the hardware fifo size. If the telegram is sent and there -is more data available in the kfifo, the procedure is repeated. If not the -transmission cycle ends. - -b) reception - -Since there is only one application allowed to receive data at a time, for -reception there is only one configuration set. -As soon as an application sets a request for receiving a telegram, the reception -configuration set is written to the rf module and it gets set into receiving mode. -Now the driver is waiting, that a predefined RSSI level (signal strength at the -receiver) is reached. Until this hasn't happened, the reception can be -interrupted by the transmission thread at any time to insert a transmission cycle. -As soon as the predefined RSSI level is met, a receiving cycle starts. Similar -as described for the transmission cycle the read out of the hardware fifo is done -dynamically. Upon each hardware fifo threshold interrupt, a portion of data gets -read. So also for reception it is possible to receive more data than the hardware -fifo can hold. - - -Driver API -========== - -The driver is currently implemented as a character device. Therefore it supports -the calls open, ioctl, read, write and close. - - -params for ioctl ----------------- - -There are four options: -PI433_IOC_RD_TX_CFG - get the transmission parameters from the driver -PI433_IOC_WR_TX_CFG - set the transmission parameters -PI433_IOC_RD_RX_CFG - get the receiving parameters from the driver -PI433_IOC_WR_RX_CFG - set the receiving parameters - -The tx configuration is transferred via struct pi433_tx_cfg, the parameterset for transmission. -It is divided into two sections: rf parameters and packet format. - -rf params: - frequency - frequency used for transmission. - Allowed values: 433050000...434790000 - bit_rate - bit rate used for transmission. - Allowed values: ##### - dev_frequency - frequency deviation in case of FSK. - Allowed values: 600...500000 - modulation - FSK - frequency shift key - OOK - On-Off-key - modShaping - shapingOff - no shaping - shaping1_0 - gauss filter with BT 1 (FSK only) - shaping0_5 - gauss filter with BT 0.5 (FSK only) - shaping0_3 - gauss filter with BT 0.3 (FSK only) - shapingBR - filter cut off at BR (OOK only) - shaping2BR - filter cut off at 2*BR (OOK only) - pa_ramp (FSK only) - ramp3400 - amp ramps up in 3.4ms - ramp2000 - amp ramps up in 2.0ms - ramp1000 - amp ramps up in 1ms - ramp500 - amp ramps up in 500us - ramp250 - amp ramps up in 250us - ramp125 - amp ramps up in 125us - ramp100 - amp ramps up in 100us - ramp62 - amp ramps up in 62us - ramp50 - amp ramps up in 50us - ramp40 - amp ramps up in 40us - ramp31 - amp ramps up in 31us - ramp25 - amp ramps up in 25us - ramp20 - amp ramps up in 20us - ramp15 - amp ramps up in 15us - ramp12 - amp ramps up in 12us - ramp10 - amp ramps up in 10us - tx_start_condition - fifo_level - transmission starts, if fifo is filled to - threshold level - fifo_not_empty - transmission starts, as soon as there is one - byte in internal fifo - repetitions - This gives the option, to send a telegram multiple times. Default: 1 - -packet format: - enable_preamble - optionOn - a preamble will be automatically generated - optionOff - no preamble will be generated - enable_sync - optionOn - a sync word will be automatically added to - the telegram after the preamble - optionOff - no sync word will be added - Attention: While possible to generate sync without preamble, the - receiver won't be able to detect the sync without preamble. - enable_length_byte - optionOn - the length of the telegram will be automatically - added to the telegram. It's part of the payload - optionOff - no length information will be automatically added - to the telegram. - Attention: For telegram length over 255 bytes, this option can't be used - Attention: should be used in combination with sync, only - enable_address_byte - optionOn - the address byte will be automatically added to the - telegram. It's part of the payload - optionOff - the address byte will not be added to the telegram. - The address byte can be used for address filtering, so the receiver - will only receive telegrams with a given address byte. - Attention: should be used in combination with sync, only - enable_crc - optionOn - an crc will be automatically calculated over the - payload of the telegram and added to the telegram - after payload. - optionOff - no crc will be calculated - preamble_length - length of the preamble. Allowed values: 0...65536 - sync_length - length of the sync word. Allowed values: 0...8 - fixed_message_length - length of the payload of the telegram. Will override the length - given by the buffer, passed in with the write command. Will be - ignored if set to zero. - sync_pattern[8] - contains up to eight values, that are used as the sync pattern - on sync option - address_byte - one byte, used as address byte on address byte option. - - -The rx configuration is transferred via struct pi433_rx_cfg, the parameterset for receiving. It is divided into two sections: rf parameters and packet format. - -rf params: - frequency - frequency used for transmission. - Allowed values: 433050000...434790000 - bit_rate - bit rate used for transmission. - Allowed values: ##### - dev_frequency - frequency deviation in case of FSK. - Allowed values: 600...500000 - modulation - FSK - frequency shift key - OOK - on off key - rssi_threshold - threshold value for the signal strength on the receiver input. - If this value is exceeded, a reception cycle starts - Allowed values: 0...255 - threshold_decrement - in order to adapt to different levels of singnal strength, over - time the receiver gets more and more sensitive. This value - determs, how fast the sensitivity increases. - step_0_5db - increase in 0,5dB steps - step_1_0db - increase in 1 db steps - step_1_5db - increase in 1,5dB steps - step_2_0db - increase in 2 db steps - step_3_0db - increase in 3 db steps - step_4_0db - increase in 4 db steps - step_5_0db - increase in 5 db steps - step_6_0db - increase in 6 db steps - antenna_impedance - sets the electrical adoption of the antenna - fifty_ohm - for antennas with an impedance of 50Ohm - two_hundred_ohm - for antennas with an impedance of 200Ohm - lna_gain - sets the gain of the low noise amp - automatic - lna gain is determined by an agc - max - lna gain is set to maximum - max_minus_6 - lna gain is set to 6db below max - max_minus_12 - lna gain is set to 12db below max - max_minus_24 - lna gain is set to 24db below max - max_minus_36 - lna gain is set to 36db below max - max_minus_48 - lna gain is set to 48db below max - bw_mantisse - sets the bandwidth of the channel filter - part one: mantisse. - mantisse16 - mantisse is set to 16 - mantisse20 - mantisse is set to 20 - mantisse24 - mantisse is set to 24 - bw_exponent - sets the bandwidth of the channel filter - part two: exponent. - Allowd values: 0...7 - dagc; - operation mode of the digital automatic gain control - normal_mode - improve - improve_for_low_modulation_index - - packet format: - enable_sync - optionOn - sync detection is enabled. If configured sync pattern - isn't found, telegram will be internally discarded - optionOff - sync detection is disabled. - enable_length_byte - optionOn - First byte of payload will be used as a length byte, - regardless of the amount of bytes that were requested - by the read request. - optionOff - Number of bytes to be read will be set according to - amount of bytes that were requested by the read request. - Attention: should be used in combination with sync, only - enable_address_filtering; - filtering_off - no address filtering will take place - node_address - all telegrams, not matching the node - address will be internally discarded - node_or_broadcast_address - all telegrams, neither matching the - node, nor the broadcast address will - be internally discarded - Attention: Sync option must be enabled in order to use this feature - enable_crc - optionOn - a crc will be calculated over the payload of - the telegram, that was received. If the - calculated crc doesn't match to two bytes, - that follow the payload, the telegram will be - internally discarded. - Attention: This option is only operational if sync on and fixed length - or length byte is used - sync_length - Gives the length of the payload. - Attention: This setting must meet the setting of the transmitter, - if sync option is used. - fixed_message_length - Overrides the telegram length either given by the first byte of - payload or by the read request. - bytes_to_drop - gives the number of bytes, that will be dropped before transferring - data to the read buffer - This option is only useful if all packet helper are switched - off and the rf chip is used in raw receiving mode. This may be - needed, if a telegram of a third party device should be received, - using a protocol not compatible with the packet engine of the rf69 chip. - sync_pattern[8] - contains up to eight values, that are used as the sync pattern - on sync option. - This setting must meet the configuration of the transmitting device, - if sync option is enabled. - node_address - one byte, used as node address byte on address byte option. - broadcast_address - one byte, used as broadcast address byte on address byte option. - - diff --git a/drivers/staging/pi433/Kconfig b/drivers/staging/pi433/Kconfig deleted file mode 100644 index dd9e4709d1a8..000000000000 --- a/drivers/staging/pi433/Kconfig +++ /dev/null @@ -1,17 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config PI433 - tristate "Pi433 - a 433MHz radio module for Raspberry Pi" - depends on SPI - help - This option allows you to enable support for the radio module Pi433. - - Pi433 is a shield that fits onto the GPIO header of a Raspberry Pi - or compatible. It extends the Raspberry Pi with the option, to - send and receive data in the 433MHz ISM band - for example to - communicate between two systems without using ethernet or bluetooth - or for control or read sockets, actors, sensors, widely available - for low price. - - For details or the option to buy, please visit https://pi433.de/en.html - - If in doubt, say N here, but saying yes most probably won't hurt diff --git a/drivers/staging/pi433/Makefile b/drivers/staging/pi433/Makefile deleted file mode 100644 index 051132fe4dae..000000000000 --- a/drivers/staging/pi433/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_PI433) += pi433.o - -pi433-objs := pi433_if.o rf69.o diff --git a/drivers/staging/pi433/TODO b/drivers/staging/pi433/TODO deleted file mode 100644 index 23c808fc99de..000000000000 --- a/drivers/staging/pi433/TODO +++ /dev/null @@ -1,8 +0,0 @@ -* currently the code introduces new IOCTLs. I'm afraid this is a bad idea. - -> Replace this with another interface, hints are welcome! -* Some missing data (marked with ###) needs to be added in the documentation -* Change (struct pi433_tx_cfg)->bit_rate to be a u32 so that we can support - bit rates up to 300kbps per the spec. - -> This configuration needs to be moved to sysfs instead of being done through - IOCTL. Going forward, we need to port userspace tools to use sysfs instead - of IOCTL and then we would delete IOCTL. diff --git a/drivers/staging/pi433/pi433_if.c b/drivers/staging/pi433/pi433_if.c deleted file mode 100644 index b6c4917d515e..000000000000 --- a/drivers/staging/pi433/pi433_if.c +++ /dev/null @@ -1,1438 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * userspace interface for pi433 radio module - * - * Pi433 is a 433MHz radio module for the Raspberry Pi. - * It is based on the HopeRf Module RFM69CW. Therefore inside of this - * driver, you'll find an abstraction of the rf69 chip. - * - * If needed, this driver could be extended, to also support other - * devices, basing on HopeRfs rf69. - * - * The driver can also be extended, to support other modules of - * HopeRf with a similar interace - e. g. RFM69HCW, RFM12, RFM95, ... - * - * Copyright (C) 2016 Wolf-Entwicklungen - * Marcus Wolf <linux@wolf-entwicklungen.de> - */ - -#undef DEBUG - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/idr.h> -#include <linux/ioctl.h> -#include <linux/uaccess.h> -#include <linux/fs.h> -#include <linux/device.h> -#include <linux/cdev.h> -#include <linux/err.h> -#include <linux/kfifo.h> -#include <linux/errno.h> -#include <linux/mutex.h> -#include <linux/of.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio/consumer.h> -#include <linux/kthread.h> -#include <linux/wait.h> -#include <linux/spi/spi.h> -#ifdef CONFIG_COMPAT -#include <linux/compat.h> -#endif -#include <linux/debugfs.h> -#include <linux/seq_file.h> - -#include "pi433_if.h" -#include "rf69.h" - -#define N_PI433_MINORS BIT(MINORBITS) /*32*/ /* ... up to 256 */ -#define MAX_MSG_SIZE 900 /* min: FIFO_SIZE! */ -#define MSG_FIFO_SIZE 65536 /* 65536 = 2^16 */ -#define FIFO_THRESHOLD 15 /* bytes */ -#define NUM_DIO 2 - -static dev_t pi433_dev; -static DEFINE_IDR(pi433_idr); -static DEFINE_MUTEX(minor_lock); /* Protect idr accesses */ -static struct dentry *root_dir; /* debugfs root directory for the driver */ - -/* mainly for udev to create /dev/pi433 */ -static const struct class pi433_class = { - .name = "pi433", -}; - -/* - * tx config is instance specific - * so with each open a new tx config struct is needed - */ -/* - * rx config is device specific - * so we have just one rx config, ebedded in device struct - */ -struct pi433_device { - /* device handling related values */ - dev_t devt; - int minor; - struct device *dev; - struct cdev *cdev; - struct spi_device *spi; - - /* irq related values */ - struct gpio_desc *gpiod[NUM_DIO]; - int irq_num[NUM_DIO]; - u8 irq_state[NUM_DIO]; - - /* tx related values */ - STRUCT_KFIFO_REC_1(MSG_FIFO_SIZE) tx_fifo; - struct mutex tx_fifo_lock; /* serialize userspace writers */ - struct task_struct *tx_task_struct; - wait_queue_head_t tx_wait_queue; - u8 free_in_fifo; - char buffer[MAX_MSG_SIZE]; - - /* rx related values */ - struct pi433_rx_cfg rx_cfg; - u8 *rx_buffer; - unsigned int rx_buffer_size; - u32 rx_bytes_to_drop; - u32 rx_bytes_dropped; - unsigned int rx_position; - struct mutex rx_lock; /* protects rx_* variable accesses */ - wait_queue_head_t rx_wait_queue; - - /* fifo wait queue */ - struct task_struct *fifo_task_struct; - wait_queue_head_t fifo_wait_queue; - - /* flags */ - bool rx_active; - bool tx_active; - bool interrupt_rx_allowed; -}; - -struct pi433_instance { - struct pi433_device *device; - struct pi433_tx_cfg tx_cfg; - - /* control flags */ - bool tx_cfg_initialized; -}; - -/*-------------------------------------------------------------------------*/ - -/* GPIO interrupt handlers */ -static irqreturn_t DIO0_irq_handler(int irq, void *dev_id) -{ - struct pi433_device *device = dev_id; - - if (device->irq_state[DIO0] == DIO_PACKET_SENT) { - device->free_in_fifo = FIFO_SIZE; - dev_dbg(device->dev, "DIO0 irq: Packet sent\n"); - wake_up_interruptible(&device->fifo_wait_queue); - } else if (device->irq_state[DIO0] == DIO_RSSI_DIO0) { - dev_dbg(device->dev, "DIO0 irq: RSSI level over threshold\n"); - wake_up_interruptible(&device->rx_wait_queue); - } else if (device->irq_state[DIO0] == DIO_PAYLOAD_READY) { - dev_dbg(device->dev, "DIO0 irq: Payload ready\n"); - device->free_in_fifo = 0; - wake_up_interruptible(&device->fifo_wait_queue); - } - - return IRQ_HANDLED; -} - -static irqreturn_t DIO1_irq_handler(int irq, void *dev_id) -{ - struct pi433_device *device = dev_id; - - if (device->irq_state[DIO1] == DIO_FIFO_NOT_EMPTY_DIO1) { - device->free_in_fifo = FIFO_SIZE; - } else if (device->irq_state[DIO1] == DIO_FIFO_LEVEL) { - if (device->rx_active) - device->free_in_fifo = FIFO_THRESHOLD - 1; - else - device->free_in_fifo = FIFO_SIZE - FIFO_THRESHOLD - 1; - } - dev_dbg(device->dev, - "DIO1 irq: %d bytes free in fifo\n", device->free_in_fifo); - wake_up_interruptible(&device->fifo_wait_queue); - - return IRQ_HANDLED; -} - -/*-------------------------------------------------------------------------*/ - -static int -rf69_set_rx_cfg(struct pi433_device *dev, struct pi433_rx_cfg *rx_cfg) -{ - int ret; - int payload_length; - - /* receiver config */ - ret = rf69_set_frequency(dev->spi, rx_cfg->frequency); - if (ret < 0) - return ret; - ret = rf69_set_modulation(dev->spi, rx_cfg->modulation); - if (ret < 0) - return ret; - ret = rf69_set_bit_rate(dev->spi, rx_cfg->bit_rate); - if (ret < 0) - return ret; - ret = rf69_set_antenna_impedance(dev->spi, rx_cfg->antenna_impedance); - if (ret < 0) - return ret; - ret = rf69_set_rssi_threshold(dev->spi, rx_cfg->rssi_threshold); - if (ret < 0) - return ret; - ret = rf69_set_ook_threshold_dec(dev->spi, rx_cfg->threshold_decrement); - if (ret < 0) - return ret; - ret = rf69_set_bandwidth(dev->spi, rx_cfg->bw_mantisse, - rx_cfg->bw_exponent); - if (ret < 0) - return ret; - ret = rf69_set_bandwidth_during_afc(dev->spi, rx_cfg->bw_mantisse, - rx_cfg->bw_exponent); - if (ret < 0) - return ret; - ret = rf69_set_dagc(dev->spi, rx_cfg->dagc); - if (ret < 0) - return ret; - - dev->rx_bytes_to_drop = rx_cfg->bytes_to_drop; - - /* packet config */ - /* enable */ - if (rx_cfg->enable_sync == OPTION_ON) { - ret = rf69_enable_sync(dev->spi); - if (ret < 0) - return ret; - - ret = rf69_set_fifo_fill_condition(dev->spi, - after_sync_interrupt); - if (ret < 0) - return ret; - } else { - ret = rf69_disable_sync(dev->spi); - if (ret < 0) - return ret; - - ret = rf69_set_fifo_fill_condition(dev->spi, always); - if (ret < 0) - return ret; - } - if (rx_cfg->enable_length_byte == OPTION_ON) { - ret = rf69_set_packet_format(dev->spi, packet_length_var); - if (ret < 0) - return ret; - } else { - ret = rf69_set_packet_format(dev->spi, packet_length_fix); - if (ret < 0) - return ret; - } - ret = rf69_set_address_filtering(dev->spi, - rx_cfg->enable_address_filtering); - if (ret < 0) - return ret; - - if (rx_cfg->enable_crc == OPTION_ON) { - ret = rf69_enable_crc(dev->spi); - if (ret < 0) - return ret; - } else { - ret = rf69_disable_crc(dev->spi); - if (ret < 0) - return ret; - } - - /* lengths */ - ret = rf69_set_sync_size(dev->spi, rx_cfg->sync_length); - if (ret < 0) - return ret; - if (rx_cfg->enable_length_byte == OPTION_ON) { - ret = rf69_set_payload_length(dev->spi, 0xff); - if (ret < 0) - return ret; - } else if (rx_cfg->fixed_message_length != 0) { - payload_length = rx_cfg->fixed_message_length; - if (rx_cfg->enable_length_byte == OPTION_ON) - payload_length++; - if (rx_cfg->enable_address_filtering != filtering_off) - payload_length++; - ret = rf69_set_payload_length(dev->spi, payload_length); - if (ret < 0) - return ret; - } else { - ret = rf69_set_payload_length(dev->spi, 0); - if (ret < 0) - return ret; - } - - /* values */ - if (rx_cfg->enable_sync == OPTION_ON) { - ret = rf69_set_sync_values(dev->spi, rx_cfg->sync_pattern); - if (ret < 0) - return ret; - } - if (rx_cfg->enable_address_filtering != filtering_off) { - ret = rf69_set_node_address(dev->spi, rx_cfg->node_address); - if (ret < 0) - return ret; - ret = rf69_set_broadcast_address(dev->spi, - rx_cfg->broadcast_address); - if (ret < 0) - return ret; - } - - return 0; -} - -static int -rf69_set_tx_cfg(struct pi433_device *dev, struct pi433_tx_cfg *tx_cfg) -{ - int ret; - - ret = rf69_set_frequency(dev->spi, tx_cfg->frequency); - if (ret < 0) - return ret; - ret = rf69_set_modulation(dev->spi, tx_cfg->modulation); - if (ret < 0) - return ret; - ret = rf69_set_bit_rate(dev->spi, tx_cfg->bit_rate); - if (ret < 0) - return ret; - ret = rf69_set_deviation(dev->spi, tx_cfg->dev_frequency); - if (ret < 0) - return ret; - ret = rf69_set_pa_ramp(dev->spi, tx_cfg->pa_ramp); - if (ret < 0) - return ret; - ret = rf69_set_modulation_shaping(dev->spi, tx_cfg->mod_shaping); - if (ret < 0) - return ret; - ret = rf69_set_tx_start_condition(dev->spi, tx_cfg->tx_start_condition); - if (ret < 0) - return ret; - - /* packet format enable */ - if (tx_cfg->enable_preamble == OPTION_ON) { - ret = rf69_set_preamble_length(dev->spi, - tx_cfg->preamble_length); - if (ret < 0) - return ret; - } else { - ret = rf69_set_preamble_length(dev->spi, 0); - if (ret < 0) - return ret; - } - - if (tx_cfg->enable_sync == OPTION_ON) { - ret = rf69_set_sync_size(dev->spi, tx_cfg->sync_length); - if (ret < 0) - return ret; - ret = rf69_set_sync_values(dev->spi, tx_cfg->sync_pattern); - if (ret < 0) - return ret; - ret = rf69_enable_sync(dev->spi); - if (ret < 0) - return ret; - } else { - ret = rf69_disable_sync(dev->spi); - if (ret < 0) - return ret; - } - - if (tx_cfg->enable_length_byte == OPTION_ON) { - ret = rf69_set_packet_format(dev->spi, packet_length_var); - if (ret < 0) - return ret; - } else { - ret = rf69_set_packet_format(dev->spi, packet_length_fix); - if (ret < 0) - return ret; - } - - if (tx_cfg->enable_crc == OPTION_ON) { - ret = rf69_enable_crc(dev->spi); - if (ret < 0) - return ret; - } else { - ret = rf69_disable_crc(dev->spi); - if (ret < 0) - return ret; - } - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int pi433_start_rx(struct pi433_device *dev) -{ - int retval; - - /* return without action, if no pending read request */ - if (!dev->rx_active) - return 0; - - /* setup for receiving */ - retval = rf69_set_rx_cfg(dev, &dev->rx_cfg); - if (retval) - return retval; - - /* setup rssi irq */ - retval = rf69_set_dio_mapping(dev->spi, DIO0, DIO_RSSI_DIO0); - if (retval < 0) - return retval; - dev->irq_state[DIO0] = DIO_RSSI_DIO0; - irq_set_irq_type(dev->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); - - /* setup fifo level interrupt */ - retval = rf69_set_fifo_threshold(dev->spi, FIFO_SIZE - FIFO_THRESHOLD); - if (retval < 0) - return retval; - retval = rf69_set_dio_mapping(dev->spi, DIO1, DIO_FIFO_LEVEL); - if (retval < 0) - return retval; - dev->irq_state[DIO1] = DIO_FIFO_LEVEL; - irq_set_irq_type(dev->irq_num[DIO1], IRQ_TYPE_EDGE_RISING); - - /* set module to receiving mode */ - retval = rf69_set_mode(dev->spi, receive); - if (retval < 0) - return retval; - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int pi433_receive(void *data) -{ - struct pi433_device *dev = data; - struct spi_device *spi = dev->spi; - int bytes_to_read, bytes_total; - int retval; - - dev->interrupt_rx_allowed = false; - - /* wait for any tx to finish */ - dev_dbg(dev->dev, "rx: going to wait for any tx to finish\n"); - retval = wait_event_interruptible(dev->rx_wait_queue, !dev->tx_active); - if (retval) { - /* wait was interrupted */ - dev->interrupt_rx_allowed = true; - wake_up_interruptible(&dev->tx_wait_queue); - return retval; - } - - /* prepare status vars */ - dev->free_in_fifo = FIFO_SIZE; - dev->rx_position = 0; - dev->rx_bytes_dropped = 0; - - /* setup radio module to listen for something "in the air" */ - retval = pi433_start_rx(dev); - if (retval) - return retval; - - /* now check RSSI, if low wait for getting high (RSSI interrupt) */ - while (!(rf69_read_reg(spi, REG_IRQFLAGS1) & MASK_IRQFLAGS1_RSSI)) { - /* allow tx to interrupt us while waiting for high RSSI */ - dev->interrupt_rx_allowed = true; - wake_up_interruptible(&dev->tx_wait_queue); - - /* wait for RSSI level to become high */ - dev_dbg(dev->dev, "rx: going to wait for high RSSI level\n"); - retval = wait_event_interruptible(dev->rx_wait_queue, - rf69_read_reg(spi, REG_IRQFLAGS1) & - MASK_IRQFLAGS1_RSSI); - if (retval) /* wait was interrupted */ - goto abort; - dev->interrupt_rx_allowed = false; - - /* cross check for ongoing tx */ - if (!dev->tx_active) - break; - } - - /* configure payload ready irq */ - retval = rf69_set_dio_mapping(spi, DIO0, DIO_PAYLOAD_READY); - if (retval < 0) - goto abort; - dev->irq_state[DIO0] = DIO_PAYLOAD_READY; - irq_set_irq_type(dev->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); - - /* fixed or unlimited length? */ - if (dev->rx_cfg.fixed_message_length != 0) { - if (dev->rx_cfg.fixed_message_length > dev->rx_buffer_size) { - retval = -1; - goto abort; - } - bytes_total = dev->rx_cfg.fixed_message_length; - dev_dbg(dev->dev, "rx: msg len set to %d by fixed length\n", - bytes_total); - } else { - bytes_total = dev->rx_buffer_size; - dev_dbg(dev->dev, "rx: msg len set to %d as requested by read\n", - bytes_total); - } - - /* length byte enabled? */ - if (dev->rx_cfg.enable_length_byte == OPTION_ON) { - retval = wait_event_interruptible(dev->fifo_wait_queue, - dev->free_in_fifo < FIFO_SIZE); - if (retval) /* wait was interrupted */ - goto abort; - - rf69_read_fifo(spi, (u8 *)&bytes_total, 1); - if (bytes_total > dev->rx_buffer_size) { - retval = -1; - goto abort; - } - dev->free_in_fifo++; - dev_dbg(dev->dev, "rx: msg len reset to %d due to length byte\n", - bytes_total); - } - - /* address byte enabled? */ - if (dev->rx_cfg.enable_address_filtering != filtering_off) { - u8 dummy; - - bytes_total--; - - retval = wait_event_interruptible(dev->fifo_wait_queue, - dev->free_in_fifo < FIFO_SIZE); - if (retval) /* wait was interrupted */ - goto abort; - - rf69_read_fifo(spi, &dummy, 1); - dev->free_in_fifo++; - dev_dbg(dev->dev, "rx: address byte stripped off\n"); - } - - /* get payload */ - while (dev->rx_position < bytes_total) { - if (!(rf69_read_reg(spi, REG_IRQFLAGS2) & MASK_IRQFLAGS2_PAYLOAD_READY)) { - retval = wait_event_interruptible(dev->fifo_wait_queue, - dev->free_in_fifo < FIFO_SIZE); - if (retval) /* wait was interrupted */ - goto abort; - } - - /* need to drop bytes or acquire? */ - if (dev->rx_bytes_to_drop > dev->rx_bytes_dropped) - bytes_to_read = dev->rx_bytes_to_drop - - dev->rx_bytes_dropped; - else - bytes_to_read = bytes_total - dev->rx_position; - - /* access the fifo */ - if (bytes_to_read > FIFO_SIZE - dev->free_in_fifo) - bytes_to_read = FIFO_SIZE - dev->free_in_fifo; - retval = rf69_read_fifo(spi, - &dev->rx_buffer[dev->rx_position], - bytes_to_read); - if (retval) /* read failed */ - goto abort; - - dev->free_in_fifo += bytes_to_read; - - /* adjust status vars */ - if (dev->rx_bytes_to_drop > dev->rx_bytes_dropped) - dev->rx_bytes_dropped += bytes_to_read; - else - dev->rx_position += bytes_to_read; - } - - /* rx done, wait was interrupted or error occurred */ -abort: - dev->interrupt_rx_allowed = true; - if (rf69_set_mode(dev->spi, standby)) - pr_err("rf69_set_mode(): radio module failed to go standby\n"); - wake_up_interruptible(&dev->tx_wait_queue); - - if (retval) - return retval; - else - return bytes_total; -} - -static int pi433_tx_thread(void *data) -{ - struct pi433_device *device = data; - struct spi_device *spi = device->spi; - struct pi433_tx_cfg tx_cfg; - size_t size; - bool rx_interrupted = false; - int position, repetitions; - int retval; - - while (1) { - /* wait for fifo to be populated or for request to terminate*/ - dev_dbg(device->dev, "thread: going to wait for new messages\n"); - wait_event_interruptible(device->tx_wait_queue, - (!kfifo_is_empty(&device->tx_fifo) || - kthread_should_stop())); - if (kthread_should_stop()) - return 0; - - /* - * get data from fifo in the following order: - * - tx_cfg - * - size of message - * - message - */ - retval = kfifo_out(&device->tx_fifo, &tx_cfg, sizeof(tx_cfg)); - if (retval != sizeof(tx_cfg)) { - dev_dbg(device->dev, - "reading tx_cfg from fifo failed: got %d byte(s), expected %d\n", - retval, (unsigned int)sizeof(tx_cfg)); - continue; - } - - retval = kfifo_out(&device->tx_fifo, &size, sizeof(size_t)); - if (retval != sizeof(size_t)) { - dev_dbg(device->dev, - "reading msg size from fifo failed: got %d, expected %d\n", - retval, (unsigned int)sizeof(size_t)); - continue; - } - - /* use fixed message length, if requested */ - if (tx_cfg.fixed_message_length != 0) - size = tx_cfg.fixed_message_length; - - /* increase size, if len byte is requested */ - if (tx_cfg.enable_length_byte == OPTION_ON) - size++; - - /* increase size, if adr byte is requested */ - if (tx_cfg.enable_address_byte == OPTION_ON) - size++; - - /* prime buffer */ - memset(device->buffer, 0, size); - position = 0; - - /* add length byte, if requested */ - if (tx_cfg.enable_length_byte == OPTION_ON) - /* - * according to spec, length byte itself must be - * excluded from the length calculation - */ - device->buffer[position++] = size - 1; - - /* add adr byte, if requested */ - if (tx_cfg.enable_address_byte == OPTION_ON) - device->buffer[position++] = tx_cfg.address_byte; - - /* finally get message data from fifo */ - retval = kfifo_out(&device->tx_fifo, &device->buffer[position], - sizeof(device->buffer) - position); - dev_dbg(device->dev, - "read %d message byte(s) from fifo queue.\n", retval); - - /* - * if rx is active, we need to interrupt the waiting for - * incoming telegrams, to be able to send something. - * We are only allowed, if currently no reception takes - * place otherwise we need to wait for the incoming telegram - * to finish - */ - wait_event_interruptible(device->tx_wait_queue, - !device->rx_active || - device->interrupt_rx_allowed); - - /* - * prevent race conditions - * irq will be reenabled after tx config is set - */ - disable_irq(device->irq_num[DIO0]); - device->tx_active = true; - - /* clear fifo, set fifo threshold, set payload length */ - retval = rf69_set_mode(spi, standby); /* this clears the fifo */ - if (retval < 0) - goto abort; - - if (device->rx_active && !rx_interrupted) { - /* - * rx is currently waiting for a telegram; - * we need to set the radio module to standby - */ - rx_interrupted = true; - } - - retval = rf69_set_fifo_threshold(spi, FIFO_THRESHOLD); - if (retval < 0) - goto abort; - if (tx_cfg.enable_length_byte == OPTION_ON) { - retval = rf69_set_payload_length(spi, size * tx_cfg.repetitions); - if (retval < 0) - goto abort; - } else { - retval = rf69_set_payload_length(spi, 0); - if (retval < 0) - goto abort; - } - - /* configure the rf chip */ - retval = rf69_set_tx_cfg(device, &tx_cfg); - if (retval < 0) - goto abort; - - /* enable fifo level interrupt */ - retval = rf69_set_dio_mapping(spi, DIO1, DIO_FIFO_LEVEL); - if (retval < 0) - goto abort; - device->irq_state[DIO1] = DIO_FIFO_LEVEL; - irq_set_irq_type(device->irq_num[DIO1], IRQ_TYPE_EDGE_FALLING); - - /* enable packet sent interrupt */ - retval = rf69_set_dio_mapping(spi, DIO0, DIO_PACKET_SENT); - if (retval < 0) - goto abort; - device->irq_state[DIO0] = DIO_PACKET_SENT; - irq_set_irq_type(device->irq_num[DIO0], IRQ_TYPE_EDGE_RISING); - enable_irq(device->irq_num[DIO0]); /* was disabled by rx active check */ - - /* enable transmission */ - retval = rf69_set_mode(spi, transmit); - if (retval < 0) - goto abort; - - /* transfer this msg (and repetitions) to chip fifo */ - device->free_in_fifo = FIFO_SIZE; - position = 0; - repetitions = tx_cfg.repetitions; - while ((repetitions > 0) && (size > position)) { - if ((size - position) > device->free_in_fifo) { - /* msg to big for fifo - take a part */ - int write_size = device->free_in_fifo; - - device->free_in_fifo = 0; - rf69_write_fifo(spi, - &device->buffer[position], - write_size); - position += write_size; - } else { - /* msg fits into fifo - take all */ - device->free_in_fifo -= size; - repetitions--; - rf69_write_fifo(spi, - &device->buffer[position], - (size - position)); - position = 0; /* reset for next repetition */ - } - - retval = wait_event_interruptible(device->fifo_wait_queue, - device->free_in_fifo > 0); - if (retval) { - dev_dbg(device->dev, "ABORT\n"); - goto abort; - } - } - - /* we are done. Wait for packet to get sent */ - dev_dbg(device->dev, - "thread: wait for packet to get sent/fifo to be empty\n"); - wait_event_interruptible(device->fifo_wait_queue, - device->free_in_fifo == FIFO_SIZE || - kthread_should_stop()); - if (kthread_should_stop()) - return 0; - - /* STOP_TRANSMISSION */ - dev_dbg(device->dev, "thread: Packet sent. Set mode to stby.\n"); - retval = rf69_set_mode(spi, standby); - if (retval < 0) - goto abort; - - /* everything sent? */ - if (kfifo_is_empty(&device->tx_fifo)) { -abort: - if (rx_interrupted) { - rx_interrupted = false; - pi433_start_rx(device); - } - device->tx_active = false; - wake_up_interruptible(&device->rx_wait_queue); - } - } -} - -/*-------------------------------------------------------------------------*/ - -static ssize_t -pi433_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) -{ - struct pi433_instance *instance; - struct pi433_device *device; - int bytes_received; - ssize_t retval; - - /* check, whether internal buffer is big enough for requested size */ - if (size > MAX_MSG_SIZE) - return -EMSGSIZE; - - instance = filp->private_data; - device = instance->device; - - /* just one read request at a time */ - mutex_lock(&device->rx_lock); - if (device->rx_active) { - mutex_unlock(&device->rx_lock); - return -EAGAIN; - } - - device->rx_active = true; - mutex_unlock(&device->rx_lock); - - /* start receiving */ - /* will block until something was received*/ - device->rx_buffer_size = size; - bytes_received = pi433_receive(device); - - /* release rx */ - mutex_lock(&device->rx_lock); - device->rx_active = false; - mutex_unlock(&device->rx_lock); - - /* if read was successful copy to user space*/ - if (bytes_received > 0) { - retval = copy_to_user(buf, device->rx_buffer, bytes_received); - if (retval) - return -EFAULT; - } - - return bytes_received; -} - -static ssize_t -pi433_write(struct file *filp, const char __user *buf, - size_t count, loff_t *f_pos) -{ - struct pi433_instance *instance; - struct pi433_device *device; - int retval; - unsigned int required, available, copied; - - instance = filp->private_data; - device = instance->device; - - /* - * check, whether internal buffer (tx thread) is big enough - * for requested size - */ - if (count > MAX_MSG_SIZE) - return -EMSGSIZE; - - /* - * check if tx_cfg has been initialized otherwise we won't be able to - * config the RF trasmitter correctly due to invalid settings - */ - if (!instance->tx_cfg_initialized) { - dev_notice_once(device->dev, - "write: failed due to unconfigured tx_cfg (see PI433_IOC_WR_TX_CFG)\n"); - return -EINVAL; - } - - /* - * write the following sequence into fifo: - * - tx_cfg - * - size of message - * - message - */ - mutex_lock(&device->tx_fifo_lock); - - required = sizeof(instance->tx_cfg) + sizeof(size_t) + count; - available = kfifo_avail(&device->tx_fifo); - if (required > available) { - dev_dbg(device->dev, "write to fifo failed: %d bytes required but %d available\n", - required, available); - mutex_unlock(&device->tx_fifo_lock); - return -EAGAIN; - } - - retval = kfifo_in(&device->tx_fifo, &instance->tx_cfg, - sizeof(instance->tx_cfg)); - if (retval != sizeof(instance->tx_cfg)) - goto abort; - - retval = kfifo_in(&device->tx_fifo, &count, sizeof(size_t)); - if (retval != sizeof(size_t)) - goto abort; - - retval = kfifo_from_user(&device->tx_fifo, buf, count, &copied); - if (retval || copied != count) - goto abort; - - mutex_unlock(&device->tx_fifo_lock); - - /* start transfer */ - wake_up_interruptible(&device->tx_wait_queue); - dev_dbg(device->dev, "write: generated new msg with %d bytes.\n", copied); - - return copied; - -abort: - dev_warn(device->dev, - "write to fifo failed, non recoverable: 0x%x\n", retval); - mutex_unlock(&device->tx_fifo_lock); - return -EAGAIN; -} - -static long pi433_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - struct pi433_instance *instance; - struct pi433_device *device; - struct pi433_tx_cfg tx_cfg; - void __user *argp = (void __user *)arg; - - /* Check type and command number */ - if (_IOC_TYPE(cmd) != PI433_IOC_MAGIC) - return -ENOTTY; - - instance = filp->private_data; - device = instance->device; - - if (!device) - return -ESHUTDOWN; - - switch (cmd) { - case PI433_IOC_RD_TX_CFG: - if (copy_to_user(argp, &instance->tx_cfg, - sizeof(struct pi433_tx_cfg))) - return -EFAULT; - break; - case PI433_IOC_WR_TX_CFG: - if (copy_from_user(&tx_cfg, argp, sizeof(struct pi433_tx_cfg))) - return -EFAULT; - mutex_lock(&device->tx_fifo_lock); - memcpy(&instance->tx_cfg, &tx_cfg, sizeof(struct pi433_tx_cfg)); - instance->tx_cfg_initialized = true; - mutex_unlock(&device->tx_fifo_lock); - break; - case PI433_IOC_RD_RX_CFG: - if (copy_to_user(argp, &device->rx_cfg, - sizeof(struct pi433_rx_cfg))) - return -EFAULT; - break; - case PI433_IOC_WR_RX_CFG: - mutex_lock(&device->rx_lock); - - /* during pendig read request, change of config not allowed */ - if (device->rx_active) { - mutex_unlock(&device->rx_lock); - return -EAGAIN; - } - - if (copy_from_user(&device->rx_cfg, argp, - sizeof(struct pi433_rx_cfg))) { - mutex_unlock(&device->rx_lock); - return -EFAULT; - } - - mutex_unlock(&device->rx_lock); - break; - default: - return -EINVAL; - } - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int pi433_open(struct inode *inode, struct file *filp) -{ - struct pi433_device *device; - struct pi433_instance *instance; - - mutex_lock(&minor_lock); - device = idr_find(&pi433_idr, iminor(inode)); - mutex_unlock(&minor_lock); - if (!device) { - pr_debug("device: minor %d unknown.\n", iminor(inode)); - return -ENODEV; - } - - instance = kzalloc(sizeof(*instance), GFP_KERNEL); - if (!instance) - return -ENOMEM; - - /* setup instance data*/ - instance->device = device; - - /* instance data as context */ - filp->private_data = instance; - stream_open(inode, filp); - - return 0; -} - -static int pi433_release(struct inode *inode, struct file *filp) -{ - struct pi433_instance *instance; - - instance = filp->private_data; - kfree(instance); - filp->private_data = NULL; - - return 0; -} - -/*-------------------------------------------------------------------------*/ - -static int setup_gpio(struct pi433_device *device) -{ - char name[5]; - int retval; - int i; - const irq_handler_t DIO_irq_handler[NUM_DIO] = { - DIO0_irq_handler, - DIO1_irq_handler - }; - - for (i = 0; i < NUM_DIO; i++) { - /* "construct" name and get the gpio descriptor */ - snprintf(name, sizeof(name), "DIO%d", i); - device->gpiod[i] = gpiod_get(&device->spi->dev, name, - 0 /*GPIOD_IN*/); - - if (device->gpiod[i] == ERR_PTR(-ENOENT)) { - dev_dbg(&device->spi->dev, - "Could not find entry for %s. Ignoring.\n", name); - continue; - } - - if (device->gpiod[i] == ERR_PTR(-EBUSY)) - dev_dbg(&device->spi->dev, "%s is busy.\n", name); - - if (IS_ERR(device->gpiod[i])) { - retval = PTR_ERR(device->gpiod[i]); - /* release already allocated gpios */ - for (i--; i >= 0; i--) { - free_irq(device->irq_num[i], device); - gpiod_put(device->gpiod[i]); - } - return retval; - } - - /* configure the pin */ - retval = gpiod_direction_input(device->gpiod[i]); - if (retval) - return retval; - - /* configure irq */ - device->irq_num[i] = gpiod_to_irq(device->gpiod[i]); - if (device->irq_num[i] < 0) { - device->gpiod[i] = ERR_PTR(-EINVAL); - return device->irq_num[i]; - } - retval = request_irq(device->irq_num[i], - DIO_irq_handler[i], - 0, /* flags */ - name, - device); - - if (retval) - return retval; - - dev_dbg(&device->spi->dev, "%s successfully configured\n", name); - } - - return 0; -} - -static void free_gpio(struct pi433_device *device) -{ - int i; - - for (i = 0; i < NUM_DIO; i++) { - /* check if gpiod is valid */ - if (IS_ERR(device->gpiod[i])) - continue; - - free_irq(device->irq_num[i], device); - gpiod_put(device->gpiod[i]); - } -} - -static int pi433_get_minor(struct pi433_device *device) -{ - int retval = -ENOMEM; - - mutex_lock(&minor_lock); - retval = idr_alloc(&pi433_idr, device, 0, N_PI433_MINORS, GFP_KERNEL); - if (retval >= 0) { - device->minor = retval; - retval = 0; - } else if (retval == -ENOSPC) { - dev_err(&device->spi->dev, "too many pi433 devices\n"); - retval = -EINVAL; - } - mutex_unlock(&minor_lock); - return retval; -} - -static void pi433_free_minor(struct pi433_device *dev) -{ - mutex_lock(&minor_lock); - idr_remove(&pi433_idr, dev->minor); - mutex_unlock(&minor_lock); -} - -/*-------------------------------------------------------------------------*/ - -static const struct file_operations pi433_fops = { - .owner = THIS_MODULE, - /* - * REVISIT switch to aio primitives, so that userspace - * gets more complete API coverage. It'll simplify things - * too, except for the locking. - */ - .write = pi433_write, - .read = pi433_read, - .unlocked_ioctl = pi433_ioctl, - .compat_ioctl = compat_ptr_ioctl, - .open = pi433_open, - .release = pi433_release, - .llseek = no_llseek, -}; - -static int pi433_debugfs_regs_show(struct seq_file *m, void *p) -{ - struct pi433_device *dev; - u8 reg_data[114]; - int i; - char *fmt = "0x%02x, 0x%02x\n"; - int ret; - - dev = m->private; - - mutex_lock(&dev->tx_fifo_lock); - mutex_lock(&dev->rx_lock); - - // wait for on-going operations to finish - ret = wait_event_interruptible(dev->rx_wait_queue, !dev->tx_active); - if (ret) - goto out_unlock; - - ret = wait_event_interruptible(dev->tx_wait_queue, !dev->rx_active); - if (ret) - goto out_unlock; - - // skip FIFO register (0x0) otherwise this can affect some of uC ops - for (i = 1; i < 0x50; i++) - reg_data[i] = rf69_read_reg(dev->spi, i); - - reg_data[REG_TESTLNA] = rf69_read_reg(dev->spi, REG_TESTLNA); - reg_data[REG_TESTPA1] = rf69_read_reg(dev->spi, REG_TESTPA1); - reg_data[REG_TESTPA2] = rf69_read_reg(dev->spi, REG_TESTPA2); - reg_data[REG_TESTDAGC] = rf69_read_reg(dev->spi, REG_TESTDAGC); - reg_data[REG_TESTAFC] = rf69_read_reg(dev->spi, REG_TESTAFC); - - seq_puts(m, "# reg, val\n"); - - for (i = 1; i < 0x50; i++) - seq_printf(m, fmt, i, reg_data[i]); - - seq_printf(m, fmt, REG_TESTLNA, reg_data[REG_TESTLNA]); - seq_printf(m, fmt, REG_TESTPA1, reg_data[REG_TESTPA1]); - seq_printf(m, fmt, REG_TESTPA2, reg_data[REG_TESTPA2]); - seq_printf(m, fmt, REG_TESTDAGC, reg_data[REG_TESTDAGC]); - seq_printf(m, fmt, REG_TESTAFC, reg_data[REG_TESTAFC]); - -out_unlock: - mutex_unlock(&dev->rx_lock); - mutex_unlock(&dev->tx_fifo_lock); - - return ret; -} -DEFINE_SHOW_ATTRIBUTE(pi433_debugfs_regs); - -/*-------------------------------------------------------------------------*/ - -static int pi433_probe(struct spi_device *spi) -{ - struct pi433_device *device; - int retval; - struct dentry *entry; - - /* setup spi parameters */ - spi->mode = 0x00; - spi->bits_per_word = 8; - /* - * spi->max_speed_hz = 10000000; - * 1MHz already set by device tree overlay - */ - - retval = spi_setup(spi); - if (retval) { - dev_dbg(&spi->dev, "configuration of SPI interface failed!\n"); - return retval; - } - - dev_dbg(&spi->dev, - "spi interface setup: mode 0x%2x, %d bits per word, %dhz max speed\n", - spi->mode, spi->bits_per_word, spi->max_speed_hz); - - /* read chip version */ - retval = rf69_get_version(spi); - if (retval < 0) - return retval; - - switch (retval) { - case 0x24: - dev_dbg(&spi->dev, "found pi433 (ver. 0x%x)\n", retval); - break; - default: - dev_dbg(&spi->dev, "unknown chip version: 0x%x\n", retval); - return -ENODEV; - } - - /* Allocate driver data */ - device = kzalloc(sizeof(*device), GFP_KERNEL); - if (!device) - return -ENOMEM; - - /* Initialize the driver data */ - device->spi = spi; - device->rx_active = false; - device->tx_active = false; - device->interrupt_rx_allowed = false; - - /* init rx buffer */ - device->rx_buffer = kmalloc(MAX_MSG_SIZE, GFP_KERNEL); - if (!device->rx_buffer) { - retval = -ENOMEM; - goto RX_failed; - } - - /* init wait queues */ - init_waitqueue_head(&device->tx_wait_queue); - init_waitqueue_head(&device->rx_wait_queue); - init_waitqueue_head(&device->fifo_wait_queue); - - /* init fifo */ - INIT_KFIFO(device->tx_fifo); - - /* init mutexes and locks */ - mutex_init(&device->tx_fifo_lock); - mutex_init(&device->rx_lock); - - /* setup GPIO (including irq_handler) for the different DIOs */ - retval = setup_gpio(device); - if (retval) { - dev_dbg(&spi->dev, "setup of GPIOs failed\n"); - goto GPIO_failed; - } - - /* setup the radio module */ - retval = rf69_set_mode(spi, standby); - if (retval < 0) - goto minor_failed; - retval = rf69_set_data_mode(spi, DATAMODUL_MODE_PACKET); - if (retval < 0) - goto minor_failed; - retval = rf69_enable_amplifier(spi, MASK_PALEVEL_PA0); - if (retval < 0) - goto minor_failed; - retval = rf69_disable_amplifier(spi, MASK_PALEVEL_PA1); - if (retval < 0) - goto minor_failed; - retval = rf69_disable_amplifier(spi, MASK_PALEVEL_PA2); - if (retval < 0) - goto minor_failed; - retval = rf69_set_output_power_level(spi, 13); - if (retval < 0) - goto minor_failed; - retval = rf69_set_antenna_impedance(spi, fifty_ohm); - if (retval < 0) - goto minor_failed; - - /* determ minor number */ - retval = pi433_get_minor(device); - if (retval) { - dev_dbg(&spi->dev, "get of minor number failed\n"); - goto minor_failed; - } - - /* create device */ - device->devt = MKDEV(MAJOR(pi433_dev), device->minor); - device->dev = device_create(&pi433_class, - &spi->dev, - device->devt, - device, - "pi433.%d", - device->minor); - if (IS_ERR(device->dev)) { - pr_err("pi433: device register failed\n"); - retval = PTR_ERR(device->dev); - goto device_create_failed; - } else { - dev_dbg(device->dev, - "created device for major %d, minor %d\n", - MAJOR(pi433_dev), - device->minor); - } - - /* start tx thread */ - device->tx_task_struct = kthread_run(pi433_tx_thread, - device, - "pi433.%d_tx_task", - device->minor); - if (IS_ERR(device->tx_task_struct)) { - dev_dbg(device->dev, "start of send thread failed\n"); - retval = PTR_ERR(device->tx_task_struct); - goto send_thread_failed; - } - - /* create cdev */ - device->cdev = cdev_alloc(); - if (!device->cdev) { - dev_dbg(device->dev, "allocation of cdev failed\n"); - retval = -ENOMEM; - goto cdev_failed; - } - device->cdev->owner = THIS_MODULE; - cdev_init(device->cdev, &pi433_fops); - retval = cdev_add(device->cdev, device->devt, 1); - if (retval) { - dev_dbg(device->dev, "register of cdev failed\n"); - goto del_cdev; - } - - /* spi setup */ - spi_set_drvdata(spi, device); - - entry = debugfs_create_dir(dev_name(device->dev), root_dir); - debugfs_create_file("regs", 0400, entry, device, &pi433_debugfs_regs_fops); - - return 0; - -del_cdev: - cdev_del(device->cdev); -cdev_failed: - kthread_stop(device->tx_task_struct); -send_thread_failed: - device_destroy(&pi433_class, device->devt); -device_create_failed: - pi433_free_minor(device); -minor_failed: - free_gpio(device); -GPIO_failed: - kfree(device->rx_buffer); -RX_failed: - kfree(device); - - return retval; -} - -static void pi433_remove(struct spi_device *spi) -{ - struct pi433_device *device = spi_get_drvdata(spi); - - debugfs_lookup_and_remove(dev_name(device->dev), root_dir); - - /* free GPIOs */ - free_gpio(device); - - /* make sure ops on existing fds can abort cleanly */ - device->spi = NULL; - - kthread_stop(device->tx_task_struct); - - device_destroy(&pi433_class, device->devt); - - cdev_del(device->cdev); - - pi433_free_minor(device); - - kfree(device->rx_buffer); - kfree(device); -} - -static const struct of_device_id pi433_dt_ids[] = { - { .compatible = "Smarthome-Wolf,pi433" }, - {}, -}; - -MODULE_DEVICE_TABLE(of, pi433_dt_ids); - -static struct spi_driver pi433_spi_driver = { - .driver = { - .name = "pi433", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(pi433_dt_ids), - }, - .probe = pi433_probe, - .remove = pi433_remove, - - /* - * NOTE: suspend/resume methods are not necessary here. - * We don't do anything except pass the requests to/from - * the underlying controller. The refrigerator handles - * most issues; the controller driver handles the rest. - */ -}; - -/*-------------------------------------------------------------------------*/ - -static int __init pi433_init(void) -{ - int status; - - /* - * If MAX_MSG_SIZE is smaller then FIFO_SIZE, the driver won't - * work stable - risk of buffer overflow - */ - if (MAX_MSG_SIZE < FIFO_SIZE) - return -EINVAL; - - /* - * Claim device numbers. Then register a class - * that will key udev/mdev to add/remove /dev nodes. - * Last, register the driver which manages those device numbers. - */ - status = alloc_chrdev_region(&pi433_dev, 0, N_PI433_MINORS, "pi433"); - if (status < 0) - return status; - - status = class_register(&pi433_class); - if (status) { - unregister_chrdev(MAJOR(pi433_dev), - pi433_spi_driver.driver.name); - return status; - } - - root_dir = debugfs_create_dir(KBUILD_MODNAME, NULL); - - status = spi_register_driver(&pi433_spi_driver); - if (status < 0) { - class_unregister(&pi433_class); - unregister_chrdev(MAJOR(pi433_dev), - pi433_spi_driver.driver.name); - } - - return status; -} - -module_init(pi433_init); - -static void __exit pi433_exit(void) -{ - spi_unregister_driver(&pi433_spi_driver); - class_unregister(&pi433_class); - unregister_chrdev(MAJOR(pi433_dev), pi433_spi_driver.driver.name); - debugfs_remove(root_dir); -} -module_exit(pi433_exit); - -MODULE_AUTHOR("Marcus Wolf, <linux@wolf-entwicklungen.de>"); -MODULE_DESCRIPTION("Driver for Pi433"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:pi433"); diff --git a/drivers/staging/pi433/pi433_if.h b/drivers/staging/pi433/pi433_if.h deleted file mode 100644 index 25ee0b77a32c..000000000000 --- a/drivers/staging/pi433/pi433_if.h +++ /dev/null @@ -1,148 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * userspace interface for pi433 radio module - * - * Pi433 is a 433MHz radio module for the Raspberry Pi. - * It is based on the HopeRf Module RFM69CW. Therefore, inside of this - * driver you'll find an abstraction of the rf69 chip. - * - * If needed this driver could also be extended to support other - * devices based on HopeRf rf69 as well as HopeRf modules with a similar - * interface such as RFM69HCW, RFM12, RFM95 and so on. - * - * Copyright (C) 2016 Wolf-Entwicklungen - * Marcus Wolf <linux@wolf-entwicklungen.de> - */ - -#ifndef PI433_H -#define PI433_H - -#include <linux/types.h> -#include "rf69_enum.h" - -/*---------------------------------------------------------------------------*/ - -enum option_on_off { - OPTION_OFF, - OPTION_ON -}; - -/* IOCTL structs and commands */ - -/** - * struct pi433_tx_cfg - * describes the configuration of the radio module for sending data - * @frequency: - * @bit_rate: - * @modulation: - * @data_mode: - * @preamble_length: - * @sync_pattern: - * @tx_start_condition: - * @payload_length: - * @repetitions: - * - * ATTENTION: - * If the contents of 'pi433_tx_cfg' ever change - * incompatibly, then the ioctl number (see define below) must change. - * - * NOTE: struct layout is the same in 64bit and 32bit userspace. - */ -#define PI433_TX_CFG_IOCTL_NR 0 -struct pi433_tx_cfg { - __u32 frequency; - __u16 bit_rate; - __u32 dev_frequency; - enum modulation modulation; - enum mod_shaping mod_shaping; - - enum pa_ramp pa_ramp; - - enum tx_start_condition tx_start_condition; - - __u16 repetitions; - - /* packet format */ - enum option_on_off enable_preamble; - enum option_on_off enable_sync; - enum option_on_off enable_length_byte; - enum option_on_off enable_address_byte; - enum option_on_off enable_crc; - - __u16 preamble_length; - __u8 sync_length; - __u8 fixed_message_length; - - __u8 sync_pattern[8]; - __u8 address_byte; -}; - -/** - * struct pi433_rx_cfg - * describes the configuration of the radio module for receiving data - * @frequency: - * @bit_rate: - * @modulation: - * @data_mode: - * @preamble_length: - * @sync_pattern: - * @tx_start_condition: - * @payload_length: - * @repetitions: - * - * ATTENTION: - * If the contents of 'pi433_rx_cfg' ever change - * incompatibly, then the ioctl number (see define below) must change - * - * NOTE: struct layout is the same in 64bit and 32bit userspace. - */ -#define PI433_RX_CFG_IOCTL_NR 1 -struct pi433_rx_cfg { - __u32 frequency; - __u16 bit_rate; - __u32 dev_frequency; - - enum modulation modulation; - - __u8 rssi_threshold; - enum threshold_decrement threshold_decrement; - enum antenna_impedance antenna_impedance; - enum lna_gain lna_gain; - enum mantisse bw_mantisse; /* normal: 0x50 */ - __u8 bw_exponent; /* during AFC: 0x8b */ - enum dagc dagc; - - /* packet format */ - enum option_on_off enable_sync; - - /* should be used in combination with sync, only */ - enum option_on_off enable_length_byte; - - /* operational with sync, only */ - enum address_filtering enable_address_filtering; - - /* only operational, if sync on and fixed length or length byte is used */ - enum option_on_off enable_crc; - - __u8 sync_length; - __u8 fixed_message_length; - __u32 bytes_to_drop; - - __u8 sync_pattern[8]; - __u8 node_address; - __u8 broadcast_address; -}; - -#define PI433_IOC_MAGIC 'r' - -#define PI433_IOC_RD_TX_CFG \ - _IOR(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) -#define PI433_IOC_WR_TX_CFG \ - _IOW(PI433_IOC_MAGIC, PI433_TX_CFG_IOCTL_NR, char[sizeof(struct pi433_tx_cfg)]) - -#define PI433_IOC_RD_RX_CFG \ - _IOR(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) -#define PI433_IOC_WR_RX_CFG \ - _IOW(PI433_IOC_MAGIC, PI433_RX_CFG_IOCTL_NR, char[sizeof(struct pi433_rx_cfg)]) - -#endif /* PI433_H */ diff --git a/drivers/staging/pi433/rf69.c b/drivers/staging/pi433/rf69.c deleted file mode 100644 index 5a1c362badb6..000000000000 --- a/drivers/staging/pi433/rf69.c +++ /dev/null @@ -1,832 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * abstraction of the spi interface of HopeRf rf69 radio module - * - * Copyright (C) 2016 Wolf-Entwicklungen - * Marcus Wolf <linux@wolf-entwicklungen.de> - */ - -#include <linux/types.h> -#include <linux/spi/spi.h> -#include <linux/units.h> - -#include "rf69.h" -#include "rf69_registers.h" - -#define F_OSC (32 * HZ_PER_MHZ) - -/*-------------------------------------------------------------------------*/ - -u8 rf69_read_reg(struct spi_device *spi, u8 addr) -{ - return spi_w8r8(spi, addr); -} - -static int rf69_write_reg(struct spi_device *spi, u8 addr, u8 value) -{ - char buffer[2]; - - buffer[0] = addr | WRITE_BIT; - buffer[1] = value; - - return spi_write(spi, &buffer, ARRAY_SIZE(buffer)); -} - -/*-------------------------------------------------------------------------*/ - -static int rf69_set_bit(struct spi_device *spi, u8 reg, u8 mask) -{ - u8 tmp; - - tmp = rf69_read_reg(spi, reg); - tmp = tmp | mask; - return rf69_write_reg(spi, reg, tmp); -} - -static int rf69_clear_bit(struct spi_device *spi, u8 reg, u8 mask) -{ - u8 tmp; - - tmp = rf69_read_reg(spi, reg); - tmp = tmp & ~mask; - return rf69_write_reg(spi, reg, tmp); -} - -static inline int rf69_read_mod_write(struct spi_device *spi, u8 reg, - u8 mask, u8 value) -{ - u8 tmp; - - tmp = rf69_read_reg(spi, reg); - tmp = (tmp & ~mask) | value; - return rf69_write_reg(spi, reg, tmp); -} - -/*-------------------------------------------------------------------------*/ - -int rf69_get_version(struct spi_device *spi) -{ - return rf69_read_reg(spi, REG_VERSION); -} - -int rf69_set_mode(struct spi_device *spi, enum mode mode) -{ - static const u8 mode_map[] = { - [transmit] = OPMODE_MODE_TRANSMIT, - [receive] = OPMODE_MODE_RECEIVE, - [synthesizer] = OPMODE_MODE_SYNTHESIZER, - [standby] = OPMODE_MODE_STANDBY, - [mode_sleep] = OPMODE_MODE_SLEEP, - }; - - if (unlikely(mode >= ARRAY_SIZE(mode_map))) { - dev_dbg(&spi->dev, "set: illegal mode %u\n", mode); - return -EINVAL; - } - - return rf69_read_mod_write(spi, REG_OPMODE, MASK_OPMODE_MODE, - mode_map[mode]); - - /* - * we are using packet mode, so this check is not really needed - * but waiting for mode ready is necessary when going from sleep - * because the FIFO may not be immediately available from previous mode - * while (_mode == RF69_MODE_SLEEP && (READ_REG(REG_IRQFLAGS1) & - RF_IRQFLAGS1_MODEREADY) == 0x00); // Wait for ModeReady - */ -} - -int rf69_set_data_mode(struct spi_device *spi, u8 data_mode) -{ - return rf69_read_mod_write(spi, REG_DATAMODUL, MASK_DATAMODUL_MODE, - data_mode); -} - -int rf69_set_modulation(struct spi_device *spi, enum modulation modulation) -{ - static const u8 modulation_map[] = { - [OOK] = DATAMODUL_MODULATION_TYPE_OOK, - [FSK] = DATAMODUL_MODULATION_TYPE_FSK, - }; - - if (unlikely(modulation >= ARRAY_SIZE(modulation_map))) { - dev_dbg(&spi->dev, "set: illegal modulation %u\n", modulation); - return -EINVAL; - } - - return rf69_read_mod_write(spi, REG_DATAMODUL, - MASK_DATAMODUL_MODULATION_TYPE, - modulation_map[modulation]); -} - -static enum modulation rf69_get_modulation(struct spi_device *spi) -{ - u8 modulation_reg; - - modulation_reg = rf69_read_reg(spi, REG_DATAMODUL); - - switch (modulation_reg & MASK_DATAMODUL_MODULATION_TYPE) { - case DATAMODUL_MODULATION_TYPE_OOK: - return OOK; - case DATAMODUL_MODULATION_TYPE_FSK: - return FSK; - default: - return UNDEF; - } -} - -int rf69_set_modulation_shaping(struct spi_device *spi, - enum mod_shaping mod_shaping) -{ - switch (rf69_get_modulation(spi)) { - case FSK: - switch (mod_shaping) { - case SHAPING_OFF: - return rf69_read_mod_write(spi, REG_DATAMODUL, - MASK_DATAMODUL_MODULATION_SHAPE, - DATAMODUL_MODULATION_SHAPE_NONE); - case SHAPING_1_0: - return rf69_read_mod_write(spi, REG_DATAMODUL, - MASK_DATAMODUL_MODULATION_SHAPE, - DATAMODUL_MODULATION_SHAPE_1_0); - case SHAPING_0_5: - return rf69_read_mod_write(spi, REG_DATAMODUL, - MASK_DATAMODUL_MODULATION_SHAPE, - DATAMODUL_MODULATION_SHAPE_0_5); - case SHAPING_0_3: - return rf69_read_mod_write(spi, REG_DATAMODUL, - MASK_DATAMODUL_MODULATION_SHAPE, - DATAMODUL_MODULATION_SHAPE_0_3); - default: - dev_dbg(&spi->dev, "set: illegal mod shaping for FSK %u\n", mod_shaping); - return -EINVAL; - } - case OOK: - switch (mod_shaping) { - case SHAPING_OFF: - return rf69_read_mod_write(spi, REG_DATAMODUL, - MASK_DATAMODUL_MODULATION_SHAPE, - DATAMODUL_MODULATION_SHAPE_NONE); - case SHAPING_BR: - return rf69_read_mod_write(spi, REG_DATAMODUL, - MASK_DATAMODUL_MODULATION_SHAPE, - DATAMODUL_MODULATION_SHAPE_BR); - case SHAPING_2BR: - return rf69_read_mod_write(spi, REG_DATAMODUL, - MASK_DATAMODUL_MODULATION_SHAPE, - DATAMODUL_MODULATION_SHAPE_2BR); - default: - dev_dbg(&spi->dev, "set: illegal mod shaping for OOK %u\n", mod_shaping); - return -EINVAL; - } - default: - dev_dbg(&spi->dev, "set: modulation undefined\n"); - return -EINVAL; - } -} - -int rf69_set_bit_rate(struct spi_device *spi, u16 bit_rate) -{ - int retval; - u32 bit_rate_reg; - u8 msb; - u8 lsb; - enum modulation mod; - - // check if modulation is configured - mod = rf69_get_modulation(spi); - if (mod == UNDEF) { - dev_dbg(&spi->dev, "setBitRate: modulation is undefined\n"); - return -EINVAL; - } - - // check input value - if (bit_rate < 1200 || (mod == OOK && bit_rate > 32768)) { - dev_dbg(&spi->dev, "setBitRate: illegal input param\n"); - return -EINVAL; - } - - // calculate reg settings - bit_rate_reg = (F_OSC / bit_rate); - - msb = (bit_rate_reg & 0xff00) >> 8; - lsb = (bit_rate_reg & 0xff); - - // transmit to RF 69 - retval = rf69_write_reg(spi, REG_BITRATE_MSB, msb); - if (retval) - return retval; - retval = rf69_write_reg(spi, REG_BITRATE_LSB, lsb); - if (retval) - return retval; - - return 0; -} - -int rf69_set_deviation(struct spi_device *spi, u32 deviation) -{ - int retval; - u64 f_reg; - u64 f_step; - u32 bit_rate_reg; - u32 bit_rate; - u8 msb; - u8 lsb; - u64 factor = 1000000; // to improve precision of calculation - - // calculate bit rate - bit_rate_reg = rf69_read_reg(spi, REG_BITRATE_MSB) << 8; - bit_rate_reg |= rf69_read_reg(spi, REG_BITRATE_LSB); - bit_rate = F_OSC / bit_rate_reg; - - /* - * frequency deviation must exceed 600 Hz but not exceed - * 500kHz when taking bitrate dependency into consideration - * to ensure proper modulation - */ - if (deviation < 600 || (deviation + (bit_rate / 2)) > 500000) { - dev_dbg(&spi->dev, - "set_deviation: illegal input param: %u\n", deviation); - return -EINVAL; - } - - // calculat f step - f_step = F_OSC * factor; - do_div(f_step, 524288); // 524288 = 2^19 - - // calculate register settings - f_reg = deviation * factor; - do_div(f_reg, f_step); - - msb = (f_reg & 0xff00) >> 8; - lsb = (f_reg & 0xff); - - // check msb - if (msb & ~FDEVMASB_MASK) { - dev_dbg(&spi->dev, "set_deviation: err in calc of msb\n"); - return -EINVAL; - } - - // write to chip - retval = rf69_write_reg(spi, REG_FDEV_MSB, msb); - if (retval) - return retval; - retval = rf69_write_reg(spi, REG_FDEV_LSB, lsb); - if (retval) - return retval; - - return 0; -} - -int rf69_set_frequency(struct spi_device *spi, u32 frequency) -{ - int retval; - u32 f_max; - u64 f_reg; - u64 f_step; - u8 msb; - u8 mid; - u8 lsb; - u64 factor = 1000000; // to improve precision of calculation - - // calculat f step - f_step = F_OSC * factor; - do_div(f_step, 524288); // 524288 = 2^19 - - // check input value - f_max = div_u64(f_step * 8388608, factor); - if (frequency > f_max) { - dev_dbg(&spi->dev, "setFrequency: illegal input param\n"); - return -EINVAL; - } - - // calculate reg settings - f_reg = frequency * factor; - do_div(f_reg, f_step); - - msb = (f_reg & 0xff0000) >> 16; - mid = (f_reg & 0xff00) >> 8; - lsb = (f_reg & 0xff); - - // write to chip - retval = rf69_write_reg(spi, REG_FRF_MSB, msb); - if (retval) - return retval; - retval = rf69_write_reg(spi, REG_FRF_MID, mid); - if (retval) - return retval; - retval = rf69_write_reg(spi, REG_FRF_LSB, lsb); - if (retval) - return retval; - - return 0; -} - -int rf69_enable_amplifier(struct spi_device *spi, u8 amplifier_mask) -{ - return rf69_set_bit(spi, REG_PALEVEL, amplifier_mask); -} - -int rf69_disable_amplifier(struct spi_device *spi, u8 amplifier_mask) -{ - return rf69_clear_bit(spi, REG_PALEVEL, amplifier_mask); -} - -int rf69_set_output_power_level(struct spi_device *spi, u8 power_level) -{ - u8 pa_level, ocp, test_pa1, test_pa2; - bool pa0, pa1, pa2, high_power; - u8 min_power_level; - - // check register pa_level - pa_level = rf69_read_reg(spi, REG_PALEVEL); - pa0 = pa_level & MASK_PALEVEL_PA0; - pa1 = pa_level & MASK_PALEVEL_PA1; - pa2 = pa_level & MASK_PALEVEL_PA2; - - // check high power mode - ocp = rf69_read_reg(spi, REG_OCP); - test_pa1 = rf69_read_reg(spi, REG_TESTPA1); - test_pa2 = rf69_read_reg(spi, REG_TESTPA2); - high_power = (ocp == 0x0f) && (test_pa1 == 0x5d) && (test_pa2 == 0x7c); - - if (pa0 && !pa1 && !pa2) { - power_level += 18; - min_power_level = 0; - } else if (!pa0 && pa1 && !pa2) { - power_level += 18; - min_power_level = 16; - } else if (!pa0 && pa1 && pa2) { - if (high_power) - power_level += 11; - else - power_level += 14; - min_power_level = 16; - } else { - goto failed; - } - - // check input value - if (power_level > 0x1f) - goto failed; - - if (power_level < min_power_level) - goto failed; - - // write value - return rf69_read_mod_write(spi, REG_PALEVEL, MASK_PALEVEL_OUTPUT_POWER, - power_level); -failed: - dev_dbg(&spi->dev, "set: illegal power level %u\n", power_level); - return -EINVAL; -} - -int rf69_set_pa_ramp(struct spi_device *spi, enum pa_ramp pa_ramp) -{ - static const u8 pa_ramp_map[] = { - [ramp3400] = PARAMP_3400, - [ramp2000] = PARAMP_2000, - [ramp1000] = PARAMP_1000, - [ramp500] = PARAMP_500, - [ramp250] = PARAMP_250, - [ramp125] = PARAMP_125, - [ramp100] = PARAMP_100, - [ramp62] = PARAMP_62, - [ramp50] = PARAMP_50, - [ramp40] = PARAMP_40, - [ramp31] = PARAMP_31, - [ramp25] = PARAMP_25, - [ramp20] = PARAMP_20, - [ramp15] = PARAMP_15, - [ramp10] = PARAMP_10, - }; - - if (unlikely(pa_ramp >= ARRAY_SIZE(pa_ramp_map))) { - dev_dbg(&spi->dev, "set: illegal pa_ramp %u\n", pa_ramp); - return -EINVAL; - } - - return rf69_write_reg(spi, REG_PARAMP, pa_ramp_map[pa_ramp]); -} - -int rf69_set_antenna_impedance(struct spi_device *spi, - enum antenna_impedance antenna_impedance) -{ - switch (antenna_impedance) { - case fifty_ohm: - return rf69_clear_bit(spi, REG_LNA, MASK_LNA_ZIN); - case two_hundred_ohm: - return rf69_set_bit(spi, REG_LNA, MASK_LNA_ZIN); - default: - dev_dbg(&spi->dev, "set: illegal antenna impedance %u\n", antenna_impedance); - return -EINVAL; - } -} - -int rf69_set_lna_gain(struct spi_device *spi, enum lna_gain lna_gain) -{ - static const u8 lna_gain_map[] = { - [automatic] = LNA_GAIN_AUTO, - [max] = LNA_GAIN_MAX, - [max_minus_6] = LNA_GAIN_MAX_MINUS_6, - [max_minus_12] = LNA_GAIN_MAX_MINUS_12, - [max_minus_24] = LNA_GAIN_MAX_MINUS_24, - [max_minus_36] = LNA_GAIN_MAX_MINUS_36, - [max_minus_48] = LNA_GAIN_MAX_MINUS_48, - }; - - if (unlikely(lna_gain >= ARRAY_SIZE(lna_gain_map))) { - dev_dbg(&spi->dev, "set: illegal lna gain %u\n", lna_gain); - return -EINVAL; - } - - return rf69_read_mod_write(spi, REG_LNA, MASK_LNA_GAIN, - lna_gain_map[lna_gain]); -} - -static int rf69_set_bandwidth_intern(struct spi_device *spi, u8 reg, - enum mantisse mantisse, u8 exponent) -{ - u8 bandwidth; - - // check value for mantisse and exponent - if (exponent > 7) { - dev_dbg(&spi->dev, "set: illegal bandwidth exponent %u\n", exponent); - return -EINVAL; - } - - if (mantisse != mantisse16 && - mantisse != mantisse20 && - mantisse != mantisse24) { - dev_dbg(&spi->dev, "set: illegal bandwidth mantisse %u\n", mantisse); - return -EINVAL; - } - - // read old value - bandwidth = rf69_read_reg(spi, reg); - - // "delete" mantisse and exponent = just keep the DCC setting - bandwidth = bandwidth & MASK_BW_DCC_FREQ; - - // add new mantisse - switch (mantisse) { - case mantisse16: - bandwidth = bandwidth | BW_MANT_16; - break; - case mantisse20: - bandwidth = bandwidth | BW_MANT_20; - break; - case mantisse24: - bandwidth = bandwidth | BW_MANT_24; - break; - } - - // add new exponent - bandwidth = bandwidth | exponent; - - // write back - return rf69_write_reg(spi, reg, bandwidth); -} - -int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, - u8 exponent) -{ - return rf69_set_bandwidth_intern(spi, REG_RXBW, mantisse, exponent); -} - -int rf69_set_bandwidth_during_afc(struct spi_device *spi, - enum mantisse mantisse, - u8 exponent) -{ - return rf69_set_bandwidth_intern(spi, REG_AFCBW, mantisse, exponent); -} - -int rf69_set_ook_threshold_dec(struct spi_device *spi, - enum threshold_decrement threshold_decrement) -{ - static const u8 td_map[] = { - [dec_every8th] = OOKPEAK_THRESHDEC_EVERY_8TH, - [dec_every4th] = OOKPEAK_THRESHDEC_EVERY_4TH, - [dec_every2nd] = OOKPEAK_THRESHDEC_EVERY_2ND, - [dec_once] = OOKPEAK_THRESHDEC_ONCE, - [dec_twice] = OOKPEAK_THRESHDEC_TWICE, - [dec_4times] = OOKPEAK_THRESHDEC_4_TIMES, - [dec_8times] = OOKPEAK_THRESHDEC_8_TIMES, - [dec_16times] = OOKPEAK_THRESHDEC_16_TIMES, - }; - - if (unlikely(threshold_decrement >= ARRAY_SIZE(td_map))) { - dev_dbg(&spi->dev, "set: illegal OOK threshold decrement %u\n", - threshold_decrement); - return -EINVAL; - } - - return rf69_read_mod_write(spi, REG_OOKPEAK, MASK_OOKPEAK_THRESDEC, - td_map[threshold_decrement]); -} - -int rf69_set_dio_mapping(struct spi_device *spi, u8 dio_number, u8 value) -{ - u8 mask; - u8 shift; - u8 dio_addr; - u8 dio_value; - - switch (dio_number) { - case 0: - mask = MASK_DIO0; - shift = SHIFT_DIO0; - dio_addr = REG_DIOMAPPING1; - break; - case 1: - mask = MASK_DIO1; - shift = SHIFT_DIO1; - dio_addr = REG_DIOMAPPING1; - break; - case 2: - mask = MASK_DIO2; - shift = SHIFT_DIO2; - dio_addr = REG_DIOMAPPING1; - break; - case 3: - mask = MASK_DIO3; - shift = SHIFT_DIO3; - dio_addr = REG_DIOMAPPING1; - break; - case 4: - mask = MASK_DIO4; - shift = SHIFT_DIO4; - dio_addr = REG_DIOMAPPING2; - break; - case 5: - mask = MASK_DIO5; - shift = SHIFT_DIO5; - dio_addr = REG_DIOMAPPING2; - break; - default: - dev_dbg(&spi->dev, "set: illegal dio number %u\n", dio_number); - return -EINVAL; - } - - // read reg - dio_value = rf69_read_reg(spi, dio_addr); - // delete old value - dio_value = dio_value & ~mask; - // add new value - dio_value = dio_value | value << shift; - // write back - return rf69_write_reg(spi, dio_addr, dio_value); -} - -int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold) -{ - /* no value check needed - u8 exactly matches register size */ - - return rf69_write_reg(spi, REG_RSSITHRESH, threshold); -} - -int rf69_set_preamble_length(struct spi_device *spi, u16 preamble_length) -{ - int retval; - u8 msb, lsb; - - /* no value check needed - u16 exactly matches register size */ - - /* calculate reg settings */ - msb = (preamble_length & 0xff00) >> 8; - lsb = (preamble_length & 0xff); - - /* transmit to chip */ - retval = rf69_write_reg(spi, REG_PREAMBLE_MSB, msb); - if (retval) - return retval; - return rf69_write_reg(spi, REG_PREAMBLE_LSB, lsb); -} - -int rf69_enable_sync(struct spi_device *spi) -{ - return rf69_set_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_SYNC_ON); -} - -int rf69_disable_sync(struct spi_device *spi) -{ - return rf69_clear_bit(spi, REG_SYNC_CONFIG, MASK_SYNC_CONFIG_SYNC_ON); -} - -int rf69_set_fifo_fill_condition(struct spi_device *spi, - enum fifo_fill_condition fifo_fill_condition) -{ - switch (fifo_fill_condition) { - case always: - return rf69_set_bit(spi, REG_SYNC_CONFIG, - MASK_SYNC_CONFIG_FIFO_FILL_CONDITION); - case after_sync_interrupt: - return rf69_clear_bit(spi, REG_SYNC_CONFIG, - MASK_SYNC_CONFIG_FIFO_FILL_CONDITION); - default: - dev_dbg(&spi->dev, "set: illegal fifo fill condition %u\n", fifo_fill_condition); - return -EINVAL; - } -} - -int rf69_set_sync_size(struct spi_device *spi, u8 sync_size) -{ - // check input value - if (sync_size > 0x07) { - dev_dbg(&spi->dev, "set: illegal sync size %u\n", sync_size); - return -EINVAL; - } - - // write value - return rf69_read_mod_write(spi, REG_SYNC_CONFIG, - MASK_SYNC_CONFIG_SYNC_SIZE, - (sync_size << 3)); -} - -int rf69_set_sync_values(struct spi_device *spi, u8 sync_values[8]) -{ - int retval = 0; - - retval += rf69_write_reg(spi, REG_SYNCVALUE1, sync_values[0]); - retval += rf69_write_reg(spi, REG_SYNCVALUE2, sync_values[1]); - retval += rf69_write_reg(spi, REG_SYNCVALUE3, sync_values[2]); - retval += rf69_write_reg(spi, REG_SYNCVALUE4, sync_values[3]); - retval += rf69_write_reg(spi, REG_SYNCVALUE5, sync_values[4]); - retval += rf69_write_reg(spi, REG_SYNCVALUE6, sync_values[5]); - retval += rf69_write_reg(spi, REG_SYNCVALUE7, sync_values[6]); - retval += rf69_write_reg(spi, REG_SYNCVALUE8, sync_values[7]); - - return retval; -} - -int rf69_set_packet_format(struct spi_device *spi, - enum packet_format packet_format) -{ - switch (packet_format) { - case packet_length_var: - return rf69_set_bit(spi, REG_PACKETCONFIG1, - MASK_PACKETCONFIG1_PACKET_FORMAT_VARIABLE); - case packet_length_fix: - return rf69_clear_bit(spi, REG_PACKETCONFIG1, - MASK_PACKETCONFIG1_PACKET_FORMAT_VARIABLE); - default: - dev_dbg(&spi->dev, "set: illegal packet format %u\n", packet_format); - return -EINVAL; - } -} - -int rf69_enable_crc(struct spi_device *spi) -{ - return rf69_set_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_CRC_ON); -} - -int rf69_disable_crc(struct spi_device *spi) -{ - return rf69_clear_bit(spi, REG_PACKETCONFIG1, MASK_PACKETCONFIG1_CRC_ON); -} - -int rf69_set_address_filtering(struct spi_device *spi, - enum address_filtering address_filtering) -{ - static const u8 af_map[] = { - [filtering_off] = PACKETCONFIG1_ADDRESSFILTERING_OFF, - [node_address] = PACKETCONFIG1_ADDRESSFILTERING_NODE, - [node_or_broadcast_address] = - PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST, - }; - - if (unlikely(address_filtering >= ARRAY_SIZE(af_map))) { - dev_dbg(&spi->dev, "set: illegal address filtering %u\n", address_filtering); - return -EINVAL; - } - - return rf69_read_mod_write(spi, REG_PACKETCONFIG1, - MASK_PACKETCONFIG1_ADDRESSFILTERING, - af_map[address_filtering]); -} - -int rf69_set_payload_length(struct spi_device *spi, u8 payload_length) -{ - return rf69_write_reg(spi, REG_PAYLOAD_LENGTH, payload_length); -} - -int rf69_set_node_address(struct spi_device *spi, u8 node_address) -{ - return rf69_write_reg(spi, REG_NODEADRS, node_address); -} - -int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcast_address) -{ - return rf69_write_reg(spi, REG_BROADCASTADRS, broadcast_address); -} - -int rf69_set_tx_start_condition(struct spi_device *spi, - enum tx_start_condition tx_start_condition) -{ - switch (tx_start_condition) { - case fifo_level: - return rf69_clear_bit(spi, REG_FIFO_THRESH, - MASK_FIFO_THRESH_TXSTART); - case fifo_not_empty: - return rf69_set_bit(spi, REG_FIFO_THRESH, - MASK_FIFO_THRESH_TXSTART); - default: - dev_dbg(&spi->dev, "set: illegal tx start condition %u\n", tx_start_condition); - return -EINVAL; - } -} - -int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold) -{ - int retval; - - /* check input value */ - if (threshold & ~MASK_FIFO_THRESH_VALUE) { - dev_dbg(&spi->dev, "set: illegal fifo threshold %u\n", threshold); - return -EINVAL; - } - - /* write value */ - retval = rf69_read_mod_write(spi, REG_FIFO_THRESH, - MASK_FIFO_THRESH_VALUE, - threshold); - if (retval) - return retval; - - /* - * access the fifo to activate new threshold - * retval (mis-) used as buffer here - */ - return rf69_read_fifo(spi, (u8 *)&retval, 1); -} - -int rf69_set_dagc(struct spi_device *spi, enum dagc dagc) -{ - static const u8 dagc_map[] = { - [normal_mode] = DAGC_NORMAL, - [improve] = DAGC_IMPROVED_LOWBETA0, - [improve_for_low_modulation_index] = DAGC_IMPROVED_LOWBETA1, - }; - - if (unlikely(dagc >= ARRAY_SIZE(dagc_map))) { - dev_dbg(&spi->dev, "set: illegal dagc %u\n", dagc); - return -EINVAL; - } - - return rf69_write_reg(spi, REG_TESTDAGC, dagc_map[dagc]); -} - -/*-------------------------------------------------------------------------*/ - -int rf69_read_fifo(struct spi_device *spi, u8 *buffer, unsigned int size) -{ - int i; - struct spi_transfer transfer; - u8 local_buffer[FIFO_SIZE + 1] = {}; - int retval; - - if (size > FIFO_SIZE) { - dev_dbg(&spi->dev, - "read fifo: passed in buffer bigger then internal buffer\n"); - return -EMSGSIZE; - } - - /* prepare a bidirectional transfer */ - local_buffer[0] = REG_FIFO; - memset(&transfer, 0, sizeof(transfer)); - transfer.tx_buf = local_buffer; - transfer.rx_buf = local_buffer; - transfer.len = size + 1; - - retval = spi_sync_transfer(spi, &transfer, 1); - - /* print content read from fifo for debugging purposes */ - for (i = 0; i < size; i++) - dev_dbg(&spi->dev, "%d - 0x%x\n", i, local_buffer[i + 1]); - - memcpy(buffer, &local_buffer[1], size); - - return retval; -} - -int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size) -{ - int i; - u8 local_buffer[FIFO_SIZE + 1]; - - if (size > FIFO_SIZE) { - dev_dbg(&spi->dev, - "write fifo: passed in buffer bigger then internal buffer\n"); - return -EMSGSIZE; - } - - local_buffer[0] = REG_FIFO | WRITE_BIT; - memcpy(&local_buffer[1], buffer, size); - - /* print content written from fifo for debugging purposes */ - for (i = 0; i < size; i++) - dev_dbg(&spi->dev, "%d - 0x%x\n", i, buffer[i]); - - return spi_write(spi, local_buffer, size + 1); -} - diff --git a/drivers/staging/pi433/rf69.h b/drivers/staging/pi433/rf69.h deleted file mode 100644 index 76f0f9896a52..000000000000 --- a/drivers/staging/pi433/rf69.h +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * hardware abstraction/register access for HopeRf rf69 radio module - * - * Copyright (C) 2016 Wolf-Entwicklungen - * Marcus Wolf <linux@wolf-entwicklungen.de> - */ -#ifndef RF69_H -#define RF69_H - -#include "rf69_enum.h" -#include "rf69_registers.h" - -#define FIFO_SIZE 66 /* bytes */ - -u8 rf69_read_reg(struct spi_device *spi, u8 addr); -int rf69_get_version(struct spi_device *spi); -int rf69_set_mode(struct spi_device *spi, enum mode mode); -int rf69_set_data_mode(struct spi_device *spi, u8 data_mode); -int rf69_set_modulation(struct spi_device *spi, enum modulation modulation); -int rf69_set_modulation_shaping(struct spi_device *spi, - enum mod_shaping mod_shaping); -int rf69_set_bit_rate(struct spi_device *spi, u16 bit_rate); -int rf69_set_deviation(struct spi_device *spi, u32 deviation); -int rf69_set_frequency(struct spi_device *spi, u32 frequency); -int rf69_enable_amplifier(struct spi_device *spi, u8 amplifier_mask); -int rf69_disable_amplifier(struct spi_device *spi, u8 amplifier_mask); -int rf69_set_output_power_level(struct spi_device *spi, u8 power_level); -int rf69_set_pa_ramp(struct spi_device *spi, enum pa_ramp pa_ramp); -int rf69_set_antenna_impedance(struct spi_device *spi, - enum antenna_impedance antenna_impedance); -int rf69_set_lna_gain(struct spi_device *spi, enum lna_gain lna_gain); -int rf69_set_bandwidth(struct spi_device *spi, enum mantisse mantisse, - u8 exponent); -int rf69_set_bandwidth_during_afc(struct spi_device *spi, - enum mantisse mantisse, - u8 exponent); -int rf69_set_ook_threshold_dec(struct spi_device *spi, - enum threshold_decrement threshold_decrement); -int rf69_set_dio_mapping(struct spi_device *spi, u8 dio_number, u8 value); -int rf69_set_rssi_threshold(struct spi_device *spi, u8 threshold); -int rf69_set_preamble_length(struct spi_device *spi, u16 preamble_length); -int rf69_enable_sync(struct spi_device *spi); -int rf69_disable_sync(struct spi_device *spi); -int rf69_set_fifo_fill_condition(struct spi_device *spi, - enum fifo_fill_condition fifo_fill_condition); -int rf69_set_sync_size(struct spi_device *spi, u8 sync_size); -int rf69_set_sync_values(struct spi_device *spi, u8 sync_values[8]); -int rf69_set_packet_format(struct spi_device *spi, - enum packet_format packet_format); -int rf69_enable_crc(struct spi_device *spi); -int rf69_disable_crc(struct spi_device *spi); -int rf69_set_address_filtering(struct spi_device *spi, - enum address_filtering address_filtering); -int rf69_set_payload_length(struct spi_device *spi, u8 payload_length); -int rf69_set_node_address(struct spi_device *spi, u8 node_address); -int rf69_set_broadcast_address(struct spi_device *spi, u8 broadcast_address); -int rf69_set_tx_start_condition(struct spi_device *spi, - enum tx_start_condition tx_start_condition); -int rf69_set_fifo_threshold(struct spi_device *spi, u8 threshold); -int rf69_set_dagc(struct spi_device *spi, enum dagc dagc); - -int rf69_read_fifo(struct spi_device *spi, u8 *buffer, unsigned int size); -int rf69_write_fifo(struct spi_device *spi, u8 *buffer, unsigned int size); - -#endif diff --git a/drivers/staging/pi433/rf69_enum.h b/drivers/staging/pi433/rf69_enum.h deleted file mode 100644 index 9dc906124e98..000000000000 --- a/drivers/staging/pi433/rf69_enum.h +++ /dev/null @@ -1,126 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * enumerations for HopeRf rf69 radio module - * - * Copyright (C) 2016 Wolf-Entwicklungen - * Marcus Wolf <linux@wolf-entwicklungen.de> - */ - -#ifndef RF69_ENUM_H -#define RF69_ENUM_H - -enum mode { - mode_sleep, - standby, - synthesizer, - transmit, - receive -}; - -enum modulation { - OOK, - FSK, - UNDEF -}; - -enum mod_shaping { - SHAPING_OFF, - SHAPING_1_0, - SHAPING_0_5, - SHAPING_0_3, - SHAPING_BR, - SHAPING_2BR -}; - -enum pa_ramp { - ramp3400, - ramp2000, - ramp1000, - ramp500, - ramp250, - ramp125, - ramp100, - ramp62, - ramp50, - ramp40, - ramp31, - ramp25, - ramp20, - ramp15, - ramp12, - ramp10 -}; - -enum antenna_impedance { - fifty_ohm, - two_hundred_ohm -}; - -enum lna_gain { - automatic, - max, - max_minus_6, - max_minus_12, - max_minus_24, - max_minus_36, - max_minus_48, - undefined -}; - -enum mantisse { - mantisse16, - mantisse20, - mantisse24 -}; - -enum threshold_decrement { - dec_every8th, - dec_every4th, - dec_every2nd, - dec_once, - dec_twice, - dec_4times, - dec_8times, - dec_16times -}; - -enum fifo_fill_condition { - after_sync_interrupt, - always -}; - -enum packet_format { - /* - * Used when the size of payload is fixed in advance. This mode of - * operation may be of interest to minimize RF overhead by 1 byte as - * no length byte field is required - */ - packet_length_fix, - /* - * Used when the size of payload isn't known in advance. It requires the - * transmitter to send the length byte in each packet so the receiver - * would know how to operate properly - */ - packet_length_var -}; - -enum tx_start_condition { - /* the number of bytes in the FIFO exceeds FIFO_THRESHOLD */ - fifo_level, - /* at least one byte in the FIFO */ - fifo_not_empty -}; - -enum address_filtering { - filtering_off, - node_address, - node_or_broadcast_address -}; - -enum dagc { - normal_mode, - improve, - improve_for_low_modulation_index -}; - -#endif diff --git a/drivers/staging/pi433/rf69_registers.h b/drivers/staging/pi433/rf69_registers.h deleted file mode 100644 index 0d6737738841..000000000000 --- a/drivers/staging/pi433/rf69_registers.h +++ /dev/null @@ -1,478 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * register description for HopeRf rf69 radio module - * - * Copyright (C) 2016 Wolf-Entwicklungen - * Marcus Wolf <linux@wolf-entwicklungen.de> - */ - -/*******************************************/ -/* RF69 register addresses */ -/*******************************************/ -#define REG_FIFO 0x00 -#define REG_OPMODE 0x01 -#define REG_DATAMODUL 0x02 -#define REG_BITRATE_MSB 0x03 -#define REG_BITRATE_LSB 0x04 -#define REG_FDEV_MSB 0x05 -#define REG_FDEV_LSB 0x06 -#define REG_FRF_MSB 0x07 -#define REG_FRF_MID 0x08 -#define REG_FRF_LSB 0x09 -#define REG_OSC1 0x0A -#define REG_AFCCTRL 0x0B -#define REG_LOWBAT 0x0C -#define REG_LISTEN1 0x0D -#define REG_LISTEN2 0x0E -#define REG_LISTEN3 0x0F -#define REG_VERSION 0x10 -#define REG_PALEVEL 0x11 -#define REG_PARAMP 0x12 -#define REG_OCP 0x13 -#define REG_AGCREF 0x14 /* not available on RF69 */ -#define REG_AGCTHRESH1 0x15 /* not available on RF69 */ -#define REG_AGCTHRESH2 0x16 /* not available on RF69 */ -#define REG_AGCTHRESH3 0x17 /* not available on RF69 */ -#define REG_LNA 0x18 -#define REG_RXBW 0x19 -#define REG_AFCBW 0x1A -#define REG_OOKPEAK 0x1B -#define REG_OOKAVG 0x1C -#define REG_OOKFIX 0x1D -#define REG_AFCFEI 0x1E -#define REG_AFCMSB 0x1F -#define REG_AFCLSB 0x20 -#define REG_FEIMSB 0x21 -#define REG_FEILSB 0x22 -#define REG_RSSICONFIG 0x23 -#define REG_RSSIVALUE 0x24 -#define REG_DIOMAPPING1 0x25 -#define REG_DIOMAPPING2 0x26 -#define REG_IRQFLAGS1 0x27 -#define REG_IRQFLAGS2 0x28 -#define REG_RSSITHRESH 0x29 -#define REG_RXTIMEOUT1 0x2A -#define REG_RXTIMEOUT2 0x2B -#define REG_PREAMBLE_MSB 0x2C -#define REG_PREAMBLE_LSB 0x2D -#define REG_SYNC_CONFIG 0x2E -#define REG_SYNCVALUE1 0x2F -#define REG_SYNCVALUE2 0x30 -#define REG_SYNCVALUE3 0x31 -#define REG_SYNCVALUE4 0x32 -#define REG_SYNCVALUE5 0x33 -#define REG_SYNCVALUE6 0x34 -#define REG_SYNCVALUE7 0x35 -#define REG_SYNCVALUE8 0x36 -#define REG_PACKETCONFIG1 0x37 -#define REG_PAYLOAD_LENGTH 0x38 -#define REG_NODEADRS 0x39 -#define REG_BROADCASTADRS 0x3A -#define REG_AUTOMODES 0x3B -#define REG_FIFO_THRESH 0x3C -#define REG_PACKETCONFIG2 0x3D -#define REG_AESKEY1 0x3E -#define REG_AESKEY2 0x3F -#define REG_AESKEY3 0x40 -#define REG_AESKEY4 0x41 -#define REG_AESKEY5 0x42 -#define REG_AESKEY6 0x43 -#define REG_AESKEY7 0x44 -#define REG_AESKEY8 0x45 -#define REG_AESKEY9 0x46 -#define REG_AESKEY10 0x47 -#define REG_AESKEY11 0x48 -#define REG_AESKEY12 0x49 -#define REG_AESKEY13 0x4A -#define REG_AESKEY14 0x4B -#define REG_AESKEY15 0x4C -#define REG_AESKEY16 0x4D -#define REG_TEMP1 0x4E -#define REG_TEMP2 0x4F -#define REG_TESTLNA 0x58 -#define REG_TESTPA1 0x5A /* only present on RFM69HW */ -#define REG_TESTPA2 0x5C /* only present on RFM69HW */ -#define REG_TESTDAGC 0x6F -#define REG_TESTAFC 0x71 - -/******************************************************/ -/* RF69/SX1231 bit definition */ -/******************************************************/ -/* write bit */ -#define WRITE_BIT 0x80 - -/* RegOpMode */ -#define MASK_OPMODE_SEQUENCER_OFF 0x80 -#define MASK_OPMODE_LISTEN_ON 0x40 -#define MASK_OPMODE_LISTEN_ABORT 0x20 -#define MASK_OPMODE_MODE 0x1C - -#define OPMODE_MODE_SLEEP 0x00 -#define OPMODE_MODE_STANDBY 0x04 /* default */ -#define OPMODE_MODE_SYNTHESIZER 0x08 -#define OPMODE_MODE_TRANSMIT 0x0C -#define OPMODE_MODE_RECEIVE 0x10 - -/* RegDataModul */ -#define MASK_DATAMODUL_MODE 0x06 -#define MASK_DATAMODUL_MODULATION_TYPE 0x18 -#define MASK_DATAMODUL_MODULATION_SHAPE 0x03 - -#define DATAMODUL_MODE_PACKET 0x00 /* default */ -#define DATAMODUL_MODE_CONTINUOUS 0x40 -#define DATAMODUL_MODE_CONTINUOUS_NOSYNC 0x60 - -#define DATAMODUL_MODULATION_TYPE_FSK 0x00 /* default */ -#define DATAMODUL_MODULATION_TYPE_OOK 0x08 - -#define DATAMODUL_MODULATION_SHAPE_NONE 0x00 /* default */ -#define DATAMODUL_MODULATION_SHAPE_1_0 0x01 -#define DATAMODUL_MODULATION_SHAPE_0_5 0x02 -#define DATAMODUL_MODULATION_SHAPE_0_3 0x03 -#define DATAMODUL_MODULATION_SHAPE_BR 0x01 -#define DATAMODUL_MODULATION_SHAPE_2BR 0x02 - -/* RegFDevMsb (0x05)*/ -#define FDEVMASB_MASK 0x3f - -/* - * // RegOsc1 - * #define OSC1_RCCAL_START 0x80 - * #define OSC1_RCCAL_DONE 0x40 - * - * // RegLowBat - * #define LOWBAT_MONITOR 0x10 - * #define LOWBAT_ON 0x08 - * #define LOWBAT_OFF 0x00 // Default - * - * #define LOWBAT_TRIM_1695 0x00 - * #define LOWBAT_TRIM_1764 0x01 - * #define LOWBAT_TRIM_1835 0x02 // Default - * #define LOWBAT_TRIM_1905 0x03 - * #define LOWBAT_TRIM_1976 0x04 - * #define LOWBAT_TRIM_2045 0x05 - * #define LOWBAT_TRIM_2116 0x06 - * #define LOWBAT_TRIM_2185 0x07 - * - * - * // RegListen1 - * #define LISTEN1_RESOL_64 0x50 - * #define LISTEN1_RESOL_4100 0xA0 // Default - * #define LISTEN1_RESOL_262000 0xF0 - * - * #define LISTEN1_CRITERIA_RSSI 0x00 // Default - * #define LISTEN1_CRITERIA_RSSIANDSYNC 0x08 - * - * #define LISTEN1_END_00 0x00 - * #define LISTEN1_END_01 0x02 // Default - * #define LISTEN1_END_10 0x04 - * - * - * // RegListen2 - * #define LISTEN2_COEFIDLE_VALUE 0xF5 // Default - * - * // RegListen3 - * #define LISTEN3_COEFRX_VALUE 0x20 // Default - */ - -// RegPaLevel -#define MASK_PALEVEL_PA0 0x80 -#define MASK_PALEVEL_PA1 0x40 -#define MASK_PALEVEL_PA2 0x20 -#define MASK_PALEVEL_OUTPUT_POWER 0x1F - -// RegPaRamp -#define PARAMP_3400 0x00 -#define PARAMP_2000 0x01 -#define PARAMP_1000 0x02 -#define PARAMP_500 0x03 -#define PARAMP_250 0x04 -#define PARAMP_125 0x05 -#define PARAMP_100 0x06 -#define PARAMP_62 0x07 -#define PARAMP_50 0x08 -#define PARAMP_40 0x09 /* default */ -#define PARAMP_31 0x0A -#define PARAMP_25 0x0B -#define PARAMP_20 0x0C -#define PARAMP_15 0x0D -#define PARAMP_12 0x0E -#define PARAMP_10 0x0F - -#define MASK_PARAMP 0x0F - -/* - * // RegOcp - * #define OCP_OFF 0x0F - * #define OCP_ON 0x1A // Default - * - * #define OCP_TRIM_45 0x00 - * #define OCP_TRIM_50 0x01 - * #define OCP_TRIM_55 0x02 - * #define OCP_TRIM_60 0x03 - * #define OCP_TRIM_65 0x04 - * #define OCP_TRIM_70 0x05 - * #define OCP_TRIM_75 0x06 - * #define OCP_TRIM_80 0x07 - * #define OCP_TRIM_85 0x08 - * #define OCP_TRIM_90 0x09 - * #define OCP_TRIM_95 0x0A - * #define OCP_TRIM_100 0x0B // Default - * #define OCP_TRIM_105 0x0C - * #define OCP_TRIM_110 0x0D - * #define OCP_TRIM_115 0x0E - * #define OCP_TRIM_120 0x0F - */ - -/* RegLna (0x18) */ -#define MASK_LNA_ZIN 0x80 -#define MASK_LNA_CURRENT_GAIN 0x38 -#define MASK_LNA_GAIN 0x07 - -#define LNA_GAIN_AUTO 0x00 /* default */ -#define LNA_GAIN_MAX 0x01 -#define LNA_GAIN_MAX_MINUS_6 0x02 -#define LNA_GAIN_MAX_MINUS_12 0x03 -#define LNA_GAIN_MAX_MINUS_24 0x04 -#define LNA_GAIN_MAX_MINUS_36 0x05 -#define LNA_GAIN_MAX_MINUS_48 0x06 - -/* RegRxBw (0x19) and RegAfcBw (0x1A) */ -#define MASK_BW_DCC_FREQ 0xE0 -#define MASK_BW_MANTISSE 0x18 -#define MASK_BW_EXPONENT 0x07 - -#define BW_DCC_16_PERCENT 0x00 -#define BW_DCC_8_PERCENT 0x20 -#define BW_DCC_4_PERCENT 0x40 /* default */ -#define BW_DCC_2_PERCENT 0x60 -#define BW_DCC_1_PERCENT 0x80 -#define BW_DCC_0_5_PERCENT 0xA0 -#define BW_DCC_0_25_PERCENT 0xC0 -#define BW_DCC_0_125_PERCENT 0xE0 - -#define BW_MANT_16 0x00 -#define BW_MANT_20 0x08 -#define BW_MANT_24 0x10 /* default */ - -/* RegOokPeak (0x1B) */ -#define MASK_OOKPEAK_THRESTYPE 0xc0 -#define MASK_OOKPEAK_THRESSTEP 0x38 -#define MASK_OOKPEAK_THRESDEC 0x07 - -#define OOKPEAK_THRESHTYPE_FIXED 0x00 -#define OOKPEAK_THRESHTYPE_PEAK 0x40 /* default */ -#define OOKPEAK_THRESHTYPE_AVERAGE 0x80 - -#define OOKPEAK_THRESHSTEP_0_5_DB 0x00 /* default */ -#define OOKPEAK_THRESHSTEP_1_0_DB 0x08 -#define OOKPEAK_THRESHSTEP_1_5_DB 0x10 -#define OOKPEAK_THRESHSTEP_2_0_DB 0x18 -#define OOKPEAK_THRESHSTEP_3_0_DB 0x20 -#define OOKPEAK_THRESHSTEP_4_0_DB 0x28 -#define OOKPEAK_THRESHSTEP_5_0_DB 0x30 -#define OOKPEAK_THRESHSTEP_6_0_DB 0x38 - -#define OOKPEAK_THRESHDEC_ONCE 0x00 /* default */ -#define OOKPEAK_THRESHDEC_EVERY_2ND 0x01 -#define OOKPEAK_THRESHDEC_EVERY_4TH 0x02 -#define OOKPEAK_THRESHDEC_EVERY_8TH 0x03 -#define OOKPEAK_THRESHDEC_TWICE 0x04 -#define OOKPEAK_THRESHDEC_4_TIMES 0x05 -#define OOKPEAK_THRESHDEC_8_TIMES 0x06 -#define OOKPEAK_THRESHDEC_16_TIMES 0x07 - -/* - * // RegOokAvg - * #define OOKAVG_AVERAGETHRESHFILT_00 0x00 - * #define OOKAVG_AVERAGETHRESHFILT_01 0x40 - * #define OOKAVG_AVERAGETHRESHFILT_10 0x80 // Default - * #define OOKAVG_AVERAGETHRESHFILT_11 0xC0 - * - * - * // RegAfcFei - * #define AFCFEI_FEI_DONE 0x40 - * #define AFCFEI_FEI_START 0x20 - * #define AFCFEI_AFC_DONE 0x10 - * #define AFCFEI_AFCAUTOCLEAR_ON 0x08 - * #define AFCFEI_AFCAUTOCLEAR_OFF 0x00 // Default - * - * #define AFCFEI_AFCAUTO_ON 0x04 - * #define AFCFEI_AFCAUTO_OFF 0x00 // Default - * - * #define AFCFEI_AFC_CLEAR 0x02 - * #define AFCFEI_AFC_START 0x01 - * - * // RegRssiConfig - * #define RSSI_FASTRX_ON 0x08 - * #define RSSI_FASTRX_OFF 0x00 // Default - * #define RSSI_DONE 0x02 - * #define RSSI_START 0x01 - */ - -/* RegDioMapping1 */ -#define MASK_DIO0 0xC0 -#define MASK_DIO1 0x30 -#define MASK_DIO2 0x0C -#define MASK_DIO3 0x03 -#define SHIFT_DIO0 6 -#define SHIFT_DIO1 4 -#define SHIFT_DIO2 2 -#define SHIFT_DIO3 0 - -/* RegDioMapping2 */ -#define MASK_DIO4 0xC0 -#define MASK_DIO5 0x30 -#define SHIFT_DIO4 6 -#define SHIFT_DIO5 4 - -/* DIO numbers */ -#define DIO0 0 -#define DIO1 1 -#define DIO2 2 -#define DIO3 3 -#define DIO4 4 -#define DIO5 5 - -/* DIO Mapping values (packet mode) */ -#define DIO_MODE_READY_DIO4 0x00 -#define DIO_MODE_READY_DIO5 0x03 -#define DIO_CLK_OUT 0x00 -#define DIO_DATA 0x01 -#define DIO_TIMEOUT_DIO1 0x03 -#define DIO_TIMEOUT_DIO4 0x00 -#define DIO_RSSI_DIO0 0x03 -#define DIO_RSSI_DIO3_4 0x01 -#define DIO_RX_READY 0x02 -#define DIO_PLL_LOCK 0x03 -#define DIO_TX_READY 0x01 -#define DIO_FIFO_FULL_DIO1 0x01 -#define DIO_FIFO_FULL_DIO3 0x00 -#define DIO_SYNC_ADDRESS 0x02 -#define DIO_FIFO_NOT_EMPTY_DIO1 0x02 -#define DIO_FIFO_NOT_EMPTY_FIO2 0x00 -#define DIO_AUTOMODE 0x04 -#define DIO_FIFO_LEVEL 0x00 -#define DIO_CRC_OK 0x00 -#define DIO_PAYLOAD_READY 0x01 -#define DIO_PACKET_SENT 0x00 -#define DIO_DCLK 0x00 - -/* RegDioMapping2 CLK_OUT part */ -#define MASK_DIOMAPPING2_CLK_OUT 0x07 - -#define DIOMAPPING2_CLK_OUT_NO_DIV 0x00 -#define DIOMAPPING2_CLK_OUT_DIV_2 0x01 -#define DIOMAPPING2_CLK_OUT_DIV_4 0x02 -#define DIOMAPPING2_CLK_OUT_DIV_8 0x03 -#define DIOMAPPING2_CLK_OUT_DIV_16 0x04 -#define DIOMAPPING2_CLK_OUT_DIV_32 0x05 -#define DIOMAPPING2_CLK_OUT_RC 0x06 -#define DIOMAPPING2_CLK_OUT_OFF 0x07 /* default */ - -/* RegIrqFlags1 */ -#define MASK_IRQFLAGS1_MODE_READY 0x80 -#define MASK_IRQFLAGS1_RX_READY 0x40 -#define MASK_IRQFLAGS1_TX_READY 0x20 -#define MASK_IRQFLAGS1_PLL_LOCK 0x10 -#define MASK_IRQFLAGS1_RSSI 0x08 -#define MASK_IRQFLAGS1_TIMEOUT 0x04 -#define MASK_IRQFLAGS1_AUTOMODE 0x02 -#define MASK_IRQFLAGS1_SYNC_ADDRESS_MATCH 0x01 - -/* RegIrqFlags2 */ -#define MASK_IRQFLAGS2_FIFO_FULL 0x80 -#define MASK_IRQFLAGS2_FIFO_NOT_EMPTY 0x40 -#define MASK_IRQFLAGS2_FIFO_LEVEL 0x20 -#define MASK_IRQFLAGS2_FIFO_OVERRUN 0x10 -#define MASK_IRQFLAGS2_PACKET_SENT 0x08 -#define MASK_IRQFLAGS2_PAYLOAD_READY 0x04 -#define MASK_IRQFLAGS2_CRC_OK 0x02 -#define MASK_IRQFLAGS2_LOW_BAT 0x01 - -/* RegSyncConfig */ -#define MASK_SYNC_CONFIG_SYNC_ON 0x80 /* default */ -#define MASK_SYNC_CONFIG_FIFO_FILL_CONDITION 0x40 -#define MASK_SYNC_CONFIG_SYNC_SIZE 0x38 -#define MASK_SYNC_CONFIG_SYNC_TOLERANCE 0x07 - -/* RegPacketConfig1 */ -#define MASK_PACKETCONFIG1_PACKET_FORMAT_VARIABLE 0x80 -#define MASK_PACKETCONFIG1_DCFREE 0x60 -#define MASK_PACKETCONFIG1_CRC_ON 0x10 /* default */ -#define MASK_PACKETCONFIG1_CRCAUTOCLEAR_OFF 0x08 -#define MASK_PACKETCONFIG1_ADDRESSFILTERING 0x06 - -#define PACKETCONFIG1_DCFREE_OFF 0x00 /* default */ -#define PACKETCONFIG1_DCFREE_MANCHESTER 0x20 -#define PACKETCONFIG1_DCFREE_WHITENING 0x40 -#define PACKETCONFIG1_ADDRESSFILTERING_OFF 0x00 /* default */ -#define PACKETCONFIG1_ADDRESSFILTERING_NODE 0x02 -#define PACKETCONFIG1_ADDRESSFILTERING_NODEBROADCAST 0x04 - -/* - * // RegAutoModes - * #define AUTOMODES_ENTER_OFF 0x00 // Default - * #define AUTOMODES_ENTER_FIFONOTEMPTY 0x20 - * #define AUTOMODES_ENTER_FIFOLEVEL 0x40 - * #define AUTOMODES_ENTER_CRCOK 0x60 - * #define AUTOMODES_ENTER_PAYLOADREADY 0x80 - * #define AUTOMODES_ENTER_SYNCADRSMATCH 0xA0 - * #define AUTOMODES_ENTER_PACKETSENT 0xC0 - * #define AUTOMODES_ENTER_FIFOEMPTY 0xE0 - * - * #define AUTOMODES_EXIT_OFF 0x00 // Default - * #define AUTOMODES_EXIT_FIFOEMPTY 0x04 - * #define AUTOMODES_EXIT_FIFOLEVEL 0x08 - * #define AUTOMODES_EXIT_CRCOK 0x0C - * #define AUTOMODES_EXIT_PAYLOADREADY 0x10 - * #define AUTOMODES_EXIT_SYNCADRSMATCH 0x14 - * #define AUTOMODES_EXIT_PACKETSENT 0x18 - * #define AUTOMODES_EXIT_RXTIMEOUT 0x1C - * - * #define AUTOMODES_INTERMEDIATE_SLEEP 0x00 // Default - * #define AUTOMODES_INTERMEDIATE_STANDBY 0x01 - * #define AUTOMODES_INTERMEDIATE_RECEIVER 0x02 - * #define AUTOMODES_INTERMEDIATE_TRANSMITTER 0x03 - * - */ -/* RegFifoThresh (0x3c) */ -#define MASK_FIFO_THRESH_TXSTART 0x80 -#define MASK_FIFO_THRESH_VALUE 0x7F - -/* - * - * // RegPacketConfig2 - * #define PACKET2_RXRESTARTDELAY_1BIT 0x00 // Default - * #define PACKET2_RXRESTARTDELAY_2BITS 0x10 - * #define PACKET2_RXRESTARTDELAY_4BITS 0x20 - * #define PACKET2_RXRESTARTDELAY_8BITS 0x30 - * #define PACKET2_RXRESTARTDELAY_16BITS 0x40 - * #define PACKET2_RXRESTARTDELAY_32BITS 0x50 - * #define PACKET2_RXRESTARTDELAY_64BITS 0x60 - * #define PACKET2_RXRESTARTDELAY_128BITS 0x70 - * #define PACKET2_RXRESTARTDELAY_256BITS 0x80 - * #define PACKET2_RXRESTARTDELAY_512BITS 0x90 - * #define PACKET2_RXRESTARTDELAY_1024BITS 0xA0 - * #define PACKET2_RXRESTARTDELAY_2048BITS 0xB0 - * #define PACKET2_RXRESTARTDELAY_NONE 0xC0 - * #define PACKET2_RXRESTART 0x04 - * - * #define PACKET2_AUTORXRESTART_ON 0x02 // Default - * #define PACKET2_AUTORXRESTART_OFF 0x00 - * - * #define PACKET2_AES_ON 0x01 - * #define PACKET2_AES_OFF 0x00 // Default - * - * - * // RegTemp1 - * #define TEMP1_MEAS_START 0x08 - * #define TEMP1_MEAS_RUNNING 0x04 - * #define TEMP1_ADCLOWPOWER_ON 0x01 // Default - * #define TEMP1_ADCLOWPOWER_OFF 0x00 - */ - -// RegTestDagc (0x6F) -#define DAGC_NORMAL 0x00 /* Reset value */ -#define DAGC_IMPROVED_LOWBETA1 0x20 -#define DAGC_IMPROVED_LOWBETA0 0x30 /* Recommended val */ diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c index 7f0c160bc741..e470b49b0ff7 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_cmdpkt.c @@ -11,7 +11,6 @@ bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data, u32 len) { - bool rt_status = true; struct r8192_priv *priv = rtllib_priv(dev); u16 frag_length = 0, frag_offset = 0; struct sk_buff *skb; @@ -37,10 +36,8 @@ bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data, else skb = dev_alloc_skb(frag_length + 4); - if (!skb) { - rt_status = false; - goto Failed; - } + if (!skb) + return false; memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); @@ -77,6 +74,6 @@ bool rtl92e_send_cmd_pkt(struct net_device *dev, u32 type, const void *data, } while (frag_offset < len); rtl92e_writeb(dev, TP_POLL, TP_POLL_CQ); -Failed: - return rt_status; + + return true; } diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c index e3ed709a7674..fdf8fc66939d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.c @@ -130,7 +130,7 @@ void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val) &priv->rtllib->current_network.qos_data.parameters; u1bAIFS = qop->aifs[pAcParam] * - ((mode & (WIRELESS_MODE_G | WIRELESS_MODE_N_24G)) ? 9 : 20) + aSifsTime; + ((mode & (WIRELESS_MODE_G | WIRELESS_MODE_N_24G)) ? 9 : 20) + asifs_time; rtl92e_dm_init_edca_turbo(dev); @@ -702,17 +702,17 @@ void rtl92e_link_change(struct net_device *dev) } } -void rtl92e_set_monitor_mode(struct net_device *dev, bool bAllowAllDA, - bool WriteIntoReg) +void rtl92e_set_monitor_mode(struct net_device *dev, bool allow_all_da, + bool write_into_reg) { struct r8192_priv *priv = rtllib_priv(dev); - if (bAllowAllDA) + if (allow_all_da) priv->receive_config |= RCR_AAP; else priv->receive_config &= ~RCR_AAP; - if (WriteIntoReg) + if (write_into_reg) rtl92e_writel(dev, RCR, priv->receive_config); } @@ -900,7 +900,7 @@ void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc, pTxFwInfo->RtsBandwidth = 0; pTxFwInfo->RtsSubcarrier = cb_desc->RTSSC; pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT == 0) ? - (cb_desc->bRTSUseShortPreamble ? 1 : 0) : + (cb_desc->rts_use_short_preamble ? 1 : 0) : (cb_desc->bRTSUseShortGI ? 1 : 0); if (priv->current_chnl_bw == HT_CHANNEL_WIDTH_20_40) { if (cb_desc->bPacketBW) { @@ -1659,8 +1659,8 @@ bool rtl92e_get_rx_stats(struct net_device *dev, struct rtllib_rx_stats *stats, stats->bFirstMPDU = (pDrvInfo->PartAggr == 1) && (pDrvInfo->FirstAGGR == 1); - stats->TimeStampLow = pDrvInfo->TSFL; - stats->TimeStampHigh = rtl92e_readl(dev, TSFR + 4); + stats->time_stamp_low = pDrvInfo->TSFL; + stats->time_stamp_high = rtl92e_readl(dev, TSFR + 4); _rtl92e_translate_rx_signal_stats(dev, skb, stats, pdesc, pDrvInfo); skb_trim(skb, skb->len - S_CRC_LEN); diff --git a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h index 878c96236824..9d9c5051c7fe 100644 --- a/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h +++ b/drivers/staging/rtl8192e/rtl8192e/r8192E_dev.h @@ -21,8 +21,8 @@ void rtl92e_set_reg(struct net_device *dev, u8 variable, u8 *val); void rtl92e_get_eeprom_size(struct net_device *dev); bool rtl92e_start_adapter(struct net_device *dev); void rtl92e_link_change(struct net_device *dev); -void rtl92e_set_monitor_mode(struct net_device *dev, bool bAllowAllDA, - bool WriteIntoReg); +void rtl92e_set_monitor_mode(struct net_device *dev, bool allow_all_da, + bool write_into_reg); void rtl92e_fill_tx_desc(struct net_device *dev, struct tx_desc *pdesc, struct cb_desc *cb_desc, struct sk_buff *skb); void rtl92e_fill_tx_cmd_desc(struct net_device *dev, struct tx_desc_cmd *entry, diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c index 649b529657ba..08d057ab8f74 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_core.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_core.c @@ -964,7 +964,7 @@ static void _rtl92e_watchdog_wq_cb(void *data) MAC80211_NOLINK) && (ieee->rf_power_state == rf_on) && !ieee->is_set_key && (!ieee->proto_stoppping) && !ieee->wx_set_enc) { - if (ieee->pwr_save_ctrl.ReturnPoint == IPS_CALLBACK_NONE) + if (ieee->pwr_save_ctrl.return_point == IPS_CALLBACK_NONE) rtl92e_ips_enter(dev); } } diff --git a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c index c34087af973c..aebe67f1a46d 100644 --- a/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c +++ b/drivers/staging/rtl8192e/rtl8192e/rtl_dm.c @@ -144,7 +144,7 @@ const u8 dm_cck_tx_bb_gain_ch14[CCK_TX_BB_GAIN_TABLE_LEN][8] = { /*------------------------Define global variable-----------------------------*/ struct dig_t dm_digtable; -struct drx_path_sel dm_rx_path_sel_table; +static struct drx_path_sel dm_rx_path_sel_table; /*------------------------Define global variable-----------------------------*/ @@ -163,7 +163,6 @@ static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev); static void _rtl92e_dm_dig_init(struct net_device *dev); static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev); -static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev); static void _rtl92e_dm_initial_gain(struct net_device *dev); static void _rtl92e_dm_pd_th(struct net_device *dev); static void _rtl92e_dm_cs_ratio(struct net_device *dev); @@ -929,11 +928,6 @@ static void _rtl92e_dm_dig_init(struct net_device *dev) dm_digtable.rx_gain_range_min = DM_DIG_MIN; } -static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev) -{ - _rtl92e_dm_ctrl_initgain_byrssi_driver(dev); -} - /*----------------------------------------------------------------------------- * Function: dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm() * @@ -952,7 +946,7 @@ static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev) * ******************************************************************************/ -static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev) +static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev) { struct r8192_priv *priv = rtllib_priv(dev); u8 i; diff --git a/drivers/staging/rtl8192e/rtl819x_HT.h b/drivers/staging/rtl8192e/rtl819x_HT.h index a4580445305d..a6e0077630c7 100644 --- a/drivers/staging/rtl8192e/rtl819x_HT.h +++ b/drivers/staging/rtl8192e/rtl819x_HT.h @@ -24,28 +24,28 @@ enum ht_extchnl_offset { }; struct ht_capab_ele { - u8 AdvCoding:1; - u8 ChlWidth:1; - u8 MimoPwrSave:2; - u8 GreenField:1; - u8 ShortGI20Mhz:1; - u8 ShortGI40Mhz:1; - u8 TxSTBC:1; - u8 RxSTBC:2; - u8 DelayBA:1; - u8 MaxAMSDUSize:1; - u8 DssCCk:1; + u8 adv_coding:1; + u8 chl_width:1; + u8 mimo_pwr_save:2; + u8 green_field:1; + u8 short_gi_20mhz:1; + u8 short_gi_40mhz:1; + u8 tx_stbc:1; + u8 rx_stbc:2; + u8 delay_ba:1; + u8 max_amsdu_size:1; + u8 dss_cck:1; u8 PSMP:1; u8 Rsvd1:1; - u8 LSigTxopProtect:1; + u8 lsig_txop_protect:1; - u8 MaxRxAMPDUFactor:2; - u8 MPDUDensity:3; + u8 max_rx_ampdu_factor:2; + u8 mpdu_density:3; u8 Rsvd2:3; u8 MCS[16]; - u16 ExtHTCapInfo; + u16 ext_ht_cap_info; u8 TxBFCap[4]; @@ -62,7 +62,7 @@ struct ht_info_ele { u8 PSMPAccessOnly:1; u8 SrvIntGranularity:3; - u8 OptMode:2; + u8 opt_mode:2; u8 NonGFDevPresent:1; u8 Revd1:5; u8 Revd2:8; @@ -104,12 +104,12 @@ struct rt_hi_throughput { u8 ampdu_enable; u8 current_ampdu_enable; u8 ampdu_factor; - u8 CurrentAMPDUFactor; + u8 current_ampdu_factor; u8 current_mpdu_density; u8 forced_ampdu_factor; u8 forced_mpdu_density; u8 current_op_mode; - enum ht_extchnl_offset CurSTAExtChnlOffset; + enum ht_extchnl_offset cur_sta_ext_chnl_offset; u8 cur_tx_bw40mhz; u8 sw_bw_in_progress; u8 current_rt2rt_aggregation; diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c index fa96a2c2c916..9b0a981f6f22 100644 --- a/drivers/staging/rtl8192e/rtl819x_HTProc.c +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -235,7 +235,7 @@ void ht_construct_capability_element(struct rtllib_device *ieee, u8 *pos_ht_cap, if (!pos_ht_cap || !ht) { netdev_warn(ieee->dev, - "%s(): posHTCap and ht_info are null\n", __func__); + "%s(): pos_ht_cap and ht_info are null\n", __func__); return; } memset(pos_ht_cap, 0, *len); @@ -251,39 +251,39 @@ void ht_construct_capability_element(struct rtllib_device *ieee, u8 *pos_ht_cap, *len = 26 + 2; } - cap_ele->AdvCoding = 0; + cap_ele->adv_coding = 0; if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev)) - cap_ele->ChlWidth = 0; + cap_ele->chl_width = 0; else - cap_ele->ChlWidth = 1; - - cap_ele->MimoPwrSave = 3; - cap_ele->GreenField = 0; - cap_ele->ShortGI20Mhz = 1; - cap_ele->ShortGI40Mhz = 1; - - cap_ele->TxSTBC = 1; - cap_ele->RxSTBC = 0; - cap_ele->DelayBA = 0; - cap_ele->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0; - cap_ele->DssCCk = 1; + cap_ele->chl_width = 1; + + cap_ele->mimo_pwr_save = 3; + cap_ele->green_field = 0; + cap_ele->short_gi_20mhz = 1; + cap_ele->short_gi_40mhz = 1; + + cap_ele->tx_stbc = 1; + cap_ele->rx_stbc = 0; + cap_ele->delay_ba = 0; + cap_ele->max_amsdu_size = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0; + cap_ele->dss_cck = 1; cap_ele->PSMP = 0; - cap_ele->LSigTxopProtect = 0; + cap_ele->lsig_txop_protect = 0; netdev_dbg(ieee->dev, - "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", - cap_ele->ChlWidth, cap_ele->MaxAMSDUSize, cap_ele->DssCCk); + "TX HT cap/info ele BW=%d max_amsdu_size:%d dss_cck:%d\n", + cap_ele->chl_width, cap_ele->max_amsdu_size, cap_ele->dss_cck); if (is_encrypt) { - cap_ele->MPDUDensity = 7; - cap_ele->MaxRxAMPDUFactor = 2; + cap_ele->mpdu_density = 7; + cap_ele->max_rx_ampdu_factor = 2; } else { - cap_ele->MaxRxAMPDUFactor = 3; - cap_ele->MPDUDensity = 0; + cap_ele->max_rx_ampdu_factor = 3; + cap_ele->mpdu_density = 0; } memcpy(cap_ele->MCS, ieee->reg_dot11ht_oper_rate_set, 16); - memset(&cap_ele->ExtHTCapInfo, 0, 2); + memset(&cap_ele->ext_ht_cap_info, 0, 2); memset(cap_ele->TxBFCap, 0, 4); cap_ele->ASCap = 0; @@ -299,10 +299,10 @@ void ht_construct_capability_element(struct rtllib_device *ieee, u8 *pos_ht_cap, cap_ele->MCS[1] &= 0x00; if (ht->iot_action & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI) - cap_ele->ShortGI40Mhz = 0; + cap_ele->short_gi_40mhz = 0; if (ieee->get_half_nmode_support_by_aps_handler(ieee->dev)) { - cap_ele->ChlWidth = 0; + cap_ele->chl_width = 0; cap_ele->MCS[1] = 0; } } @@ -452,13 +452,13 @@ void ht_on_assoc_rsp(struct rtllib_device *ieee) print_hex_dump_bytes("%s: ", __func__, DUMP_PREFIX_NONE, pPeerHTCap, sizeof(struct ht_capab_ele)); #endif - ht_set_connect_bw_mode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), + ht_set_connect_bw_mode(ieee, (enum ht_channel_width)(pPeerHTCap->chl_width), (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); ht_info->cur_tx_bw40mhz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? true : false); - ht_info->cur_short_gi_20mhz = ((pPeerHTCap->ShortGI20Mhz == 1) ? true : false); - ht_info->cur_short_gi_40mhz = ((pPeerHTCap->ShortGI40Mhz == 1) ? true : false); + ht_info->cur_short_gi_20mhz = ((pPeerHTCap->short_gi_20mhz == 1) ? true : false); + ht_info->cur_short_gi_40mhz = ((pPeerHTCap->short_gi_40mhz == 1) ? true : false); ht_info->current_ampdu_enable = ht_info->ampdu_enable; if (ieee->rtllib_ap_sec_type && @@ -470,16 +470,16 @@ void ht_on_assoc_rsp(struct rtllib_device *ieee) if (ieee->current_network.bssht.bd_rt2rt_aggregation) { if (ieee->pairwise_key_type != KEY_TYPE_NA) - ht_info->CurrentAMPDUFactor = - pPeerHTCap->MaxRxAMPDUFactor; + ht_info->current_ampdu_factor = + pPeerHTCap->max_rx_ampdu_factor; else - ht_info->CurrentAMPDUFactor = HT_AGG_SIZE_64K; + ht_info->current_ampdu_factor = HT_AGG_SIZE_64K; } else { - ht_info->CurrentAMPDUFactor = min_t(u32, pPeerHTCap->MaxRxAMPDUFactor, - HT_AGG_SIZE_32K); + ht_info->current_ampdu_factor = min_t(u32, pPeerHTCap->max_rx_ampdu_factor, + HT_AGG_SIZE_32K); } - ht_info->current_mpdu_density = pPeerHTCap->MPDUDensity; + ht_info->current_mpdu_density = pPeerHTCap->mpdu_density; if (ht_info->iot_action & HT_IOT_ACT_TX_USE_AMSDU_8K) ht_info->current_ampdu_enable = false; @@ -498,7 +498,7 @@ void ht_on_assoc_rsp(struct rtllib_device *ieee) pMcsFilter); ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; - ht_info->current_op_mode = pPeerHTInfo->OptMode; + ht_info->current_op_mode = pPeerHTInfo->opt_mode; } void ht_initialize_ht_info(struct rtllib_device *ieee) @@ -514,7 +514,7 @@ void ht_initialize_ht_info(struct rtllib_device *ieee) ht_info->cur_short_gi_40mhz = false; ht_info->current_mpdu_density = 0; - ht_info->CurrentAMPDUFactor = ht_info->ampdu_factor; + ht_info->current_ampdu_factor = ht_info->ampdu_factor; memset((void *)(&ht_info->self_ht_cap), 0, sizeof(ht_info->self_ht_cap)); @@ -543,19 +543,19 @@ void ht_initialize_ht_info(struct rtllib_device *ieee) } } -void ht_initialize_bss_desc(struct bss_ht *pBssHT) +void ht_initialize_bss_desc(struct bss_ht *bss_ht) { - pBssHT->bd_support_ht = false; - memset(pBssHT->bd_ht_cap_buf, 0, sizeof(pBssHT->bd_ht_cap_buf)); - pBssHT->bd_ht_cap_len = 0; - memset(pBssHT->bd_ht_info_buf, 0, sizeof(pBssHT->bd_ht_info_buf)); - pBssHT->bd_ht_info_len = 0; + bss_ht->bd_support_ht = false; + memset(bss_ht->bd_ht_cap_buf, 0, sizeof(bss_ht->bd_ht_cap_buf)); + bss_ht->bd_ht_cap_len = 0; + memset(bss_ht->bd_ht_info_buf, 0, sizeof(bss_ht->bd_ht_info_buf)); + bss_ht->bd_ht_info_len = 0; - pBssHT->bd_ht_spec_ver = HT_SPEC_VER_IEEE; + bss_ht->bd_ht_spec_ver = HT_SPEC_VER_IEEE; - pBssHT->bd_rt2rt_aggregation = false; - pBssHT->bd_rt2rt_long_slot_time = false; - pBssHT->rt2rt_ht_mode = (enum rt_ht_capability)0; + bss_ht->bd_rt2rt_aggregation = false; + bss_ht->bd_rt2rt_long_slot_time = false; + bss_ht->rt2rt_ht_mode = (enum rt_ht_capability)0; } void ht_reset_self_and_save_peer_setting(struct rtllib_device *ieee, @@ -617,7 +617,7 @@ void HT_update_self_and_peer_setting(struct rtllib_device *ieee, if (ht_info->current_ht_support) { if (pNetwork->bssht.bd_ht_info_len != 0) - ht_info->current_op_mode = pPeerHTInfo->OptMode; + ht_info->current_op_mode = pPeerHTInfo->opt_mode; } } EXPORT_SYMBOL(HT_update_self_and_peer_setting); @@ -625,7 +625,7 @@ EXPORT_SYMBOL(HT_update_self_and_peer_setting); u8 ht_c_check(struct rtllib_device *ieee, u8 *pFrame) { if (ieee->ht_info->current_ht_support) { - if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { + if ((IsQoSDataFrame(pFrame) && frame_order(pFrame)) == 1) { netdev_dbg(ieee->dev, "HT CONTROL FILED EXIST!!\n"); return true; } @@ -638,10 +638,10 @@ static void ht_set_connect_bw_mode_callback(struct rtllib_device *ieee) struct rt_hi_throughput *ht_info = ieee->ht_info; if (ht_info->cur_bw_40mhz) { - if (ht_info->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) + if (ht_info->cur_sta_ext_chnl_offset == HT_EXTCHNL_OFFSET_UPPER) ieee->set_chan(ieee->dev, ieee->current_network.channel + 2); - else if (ht_info->CurSTAExtChnlOffset == + else if (ht_info->cur_sta_ext_chnl_offset == HT_EXTCHNL_OFFSET_LOWER) ieee->set_chan(ieee->dev, ieee->current_network.channel - 2); @@ -650,7 +650,7 @@ static void ht_set_connect_bw_mode_callback(struct rtllib_device *ieee) ieee->current_network.channel); ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20_40, - ht_info->CurSTAExtChnlOffset); + ht_info->cur_sta_ext_chnl_offset); } else { ieee->set_chan(ieee->dev, ieee->current_network.channel); ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20, @@ -680,14 +680,14 @@ void ht_set_connect_bw_mode(struct rtllib_device *ieee, if (Offset == HT_EXTCHNL_OFFSET_UPPER || Offset == HT_EXTCHNL_OFFSET_LOWER) { ht_info->cur_bw_40mhz = true; - ht_info->CurSTAExtChnlOffset = Offset; + ht_info->cur_sta_ext_chnl_offset = Offset; } else { ht_info->cur_bw_40mhz = false; - ht_info->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; + ht_info->cur_sta_ext_chnl_offset = HT_EXTCHNL_OFFSET_NO_EXT; } } else { ht_info->cur_bw_40mhz = false; - ht_info->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; + ht_info->cur_sta_ext_chnl_offset = HT_EXTCHNL_OFFSET_NO_EXT; } netdev_dbg(ieee->dev, "%s():ht_info->bCurBW40MHz:%x\n", __func__, diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h index 6fbf11ac168f..0809af3fd041 100644 --- a/drivers/staging/rtl8192e/rtllib.h +++ b/drivers/staging/rtl8192e/rtllib.h @@ -121,7 +121,7 @@ struct cb_desc { u8 bRTSBW:1; u8 bPacketBW:1; - u8 bRTSUseShortPreamble:1; + u8 rts_use_short_preamble:1; u8 bRTSUseShortGI:1; u8 multicast:1; u8 bBroadcast:1; @@ -299,7 +299,7 @@ enum rt_op_mode { RT_OP_MODE_NO_LINK, }; -#define aSifsTime \ +#define asifs_time \ ((priv->rtllib->current_network.mode == WIRELESS_MODE_N_24G) ? 16 : 10) #define MGMT_QUEUE_NUM 5 @@ -343,7 +343,7 @@ enum rt_op_mode { #define IsQoSDataFrame(pframe) \ ((*(u16 *)pframe&(IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) == \ (IEEE80211_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) -#define Frame_Order(pframe) (*(u16 *)pframe&IEEE80211_FCTL_ORDER) +#define frame_order(pframe) (*(u16 *)pframe&IEEE80211_FCTL_ORDER) #define SN_LESS(a, b) (((a-b)&0x800) != 0) #define SN_EQUAL(a, b) (a == b) #define MAX_DEV_ADDR_SIZE 8 @@ -482,8 +482,8 @@ struct rtllib_rx_stats { u16 bCRC:1; u16 bICV:1; u16 Decrypted:1; - u32 TimeStampLow; - u32 TimeStampHigh; + u32 time_stamp_low; + u32 time_stamp_high; u8 RxDrvInfoSize; u8 RxBufShift; @@ -1051,7 +1051,7 @@ enum rt_rf_power_state { struct rt_pwr_save_ctrl { bool bSwRfProcessing; enum rt_rf_power_state eInactivePowerState; - enum ips_callback_function ReturnPoint; + enum ips_callback_function return_point; bool bLeisurePs; u8 lps_idle_count; @@ -1477,8 +1477,8 @@ struct rtllib_device { void (*set_hw_reg_handler)(struct net_device *dev, u8 variable, u8 *val); void (*allow_all_dest_addr_handler)(struct net_device *dev, - bool bAllowAllDA, - bool WriteIntoReg); + bool allow_all_da, + bool write_into_reg); void (*rtllib_ips_leave_wq)(struct net_device *dev); void (*rtllib_ips_leave)(struct net_device *dev); @@ -1736,13 +1736,13 @@ void ht_set_connect_bw_mode(struct rtllib_device *ieee, enum ht_extchnl_offset Offset); void ht_update_default_setting(struct rtllib_device *ieee); void ht_construct_capability_element(struct rtllib_device *ieee, - u8 *posHTCap, u8 *len, + u8 *pos_ht_cap, u8 *len, u8 isEncrypt, bool bAssoc); void ht_construct_rt2rt_agg_element(struct rtllib_device *ieee, u8 *posRT2RTAgg, u8 *len); void ht_on_assoc_rsp(struct rtllib_device *ieee); void ht_initialize_ht_info(struct rtllib_device *ieee); -void ht_initialize_bss_desc(struct bss_ht *pBssHT); +void ht_initialize_bss_desc(struct bss_ht *bss_ht); void ht_reset_self_and_save_peer_setting(struct rtllib_device *ieee, struct rtllib_network *pNetwork); void HT_update_self_and_peer_setting(struct rtllib_device *ieee, diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c index ebf8a2fd36d3..ee469c9118b8 100644 --- a/drivers/staging/rtl8192e/rtllib_rx.c +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -1877,7 +1877,7 @@ static void rtllib_parse_mfie_ht_cap(struct rtllib_info_element *info_element, ht->bd_bandwidth = (enum ht_channel_width) (((struct ht_capab_ele *) - (ht->bd_ht_cap_buf))->ChlWidth); + (ht->bd_ht_cap_buf))->chl_width); } else { ht->bd_support_ht = false; ht->bd_ht_1r = false; diff --git a/drivers/staging/rtl8192e/rtllib_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index d6bc74ba9092..11542aea4a20 100644 --- a/drivers/staging/rtl8192e/rtllib_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -319,7 +319,7 @@ void rtllib_wx_sync_scan_wq(void *data) if (ieee->ht_info->current_ht_support && ieee->ht_info->enable_ht && ieee->ht_info->cur_bw_40mhz) { b40M = 1; - chan_offset = ieee->ht_info->CurSTAExtChnlOffset; + chan_offset = ieee->ht_info->cur_sta_ext_chnl_offset; bandwidth = (enum ht_channel_width)ieee->ht_info->cur_bw_40mhz; ieee->set_bw_mode_handler(ieee->dev, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c index 54100dd81505..1aeb207a3fee 100644 --- a/drivers/staging/rtl8192e/rtllib_tx.c +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -313,7 +313,7 @@ static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, } if (ieee->iw_mode == IW_MODE_INFRA) { tcb_desc->ampdu_enable = true; - tcb_desc->ampdu_factor = ht_info->CurrentAMPDUFactor; + tcb_desc->ampdu_factor = ht_info->current_ampdu_factor; tcb_desc->ampdu_density = ht_info->current_mpdu_density; } } diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c index 55a3e4222cd6..fbd4ec824084 100644 --- a/drivers/staging/rtl8192e/rtllib_wx.c +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -129,10 +129,10 @@ static inline char *rtl819x_translate_scan(struct rtllib_device *ieee, else ht_cap = (struct ht_capab_ele *) &network->bssht.bd_ht_cap_buf[0]; - is40M = (ht_cap->ChlWidth) ? 1 : 0; - isShortGI = (ht_cap->ChlWidth) ? - ((ht_cap->ShortGI40Mhz) ? 1 : 0) : - ((ht_cap->ShortGI20Mhz) ? 1 : 0); + is40M = (ht_cap->chl_width) ? 1 : 0; + isShortGI = (ht_cap->chl_width) ? + ((ht_cap->short_gi_40mhz) ? 1 : 0) : + ((ht_cap->short_gi_20mhz) ? 1 : 0); max_mcs = ht_get_highest_mcs_rate(ieee, ht_cap->MCS, MCS_FILTER_ALL); diff --git a/drivers/staging/rtl8712/mlme_linux.c b/drivers/staging/rtl8712/mlme_linux.c index b9f5104f3bf7..436816d14cdf 100644 --- a/drivers/staging/rtl8712/mlme_linux.c +++ b/drivers/staging/rtl8712/mlme_linux.c @@ -84,11 +84,11 @@ void r8712_os_indicate_connect(struct _adapter *adapter) netif_carrier_on(adapter->pnetdev); } -static struct RT_PMKID_LIST backupPMKIDList[NUM_PMKID_CACHE]; +static struct RT_PMKID_LIST backup_PMKID_list[NUM_PMKID_CACHE]; void r8712_os_indicate_disconnect(struct _adapter *adapter) { - u8 backupPMKIDIndex = 0; - u8 backupTKIPCountermeasure = 0x00; + u8 backup_PMKID_index = 0; + u8 backup_TKIP_countermeasure = 0x00; r8712_indicate_wx_disassoc_event(adapter); netif_carrier_off(adapter->pnetdev); @@ -99,11 +99,11 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter) * disconnect with AP for 60 seconds. */ - memcpy(&backupPMKIDList[0], + memcpy(&backup_PMKID_list[0], &adapter->securitypriv.PMKIDList[0], sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); - backupPMKIDIndex = adapter->securitypriv.PMKIDIndex; - backupTKIPCountermeasure = + backup_PMKID_index = adapter->securitypriv.PMKIDIndex; + backup_TKIP_countermeasure = adapter->securitypriv.btkip_countermeasure; memset((unsigned char *)&adapter->securitypriv, 0, sizeof(struct security_priv)); @@ -113,11 +113,11 @@ void r8712_os_indicate_disconnect(struct _adapter *adapter) * for the following connection. */ memcpy(&adapter->securitypriv.PMKIDList[0], - &backupPMKIDList[0], + &backup_PMKID_list[0], sizeof(struct RT_PMKID_LIST) * NUM_PMKID_CACHE); - adapter->securitypriv.PMKIDIndex = backupPMKIDIndex; + adapter->securitypriv.PMKIDIndex = backup_PMKID_index; adapter->securitypriv.btkip_countermeasure = - backupTKIPCountermeasure; + backup_TKIP_countermeasure; } else { /*reset values in securitypriv*/ struct security_priv *sec_priv = &adapter->securitypriv; diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 7554613fe7e1..1b11f8b04e13 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -221,7 +221,8 @@ struct net_device *r8712_init_netdev(void) static u32 start_drv_threads(struct _adapter *padapter) { - padapter->cmd_thread = kthread_run(r8712_cmd_thread, padapter, "%s", padapter->pnetdev->name); + padapter->cmd_thread = kthread_run(r8712_cmd_thread, padapter, "%s", + padapter->pnetdev->name); if (IS_ERR(padapter->cmd_thread)) return _FAIL; return _SUCCESS; diff --git a/drivers/staging/rtl8712/rtl8712_led.c b/drivers/staging/rtl8712/rtl8712_led.c index d5fc9026b036..6d9be5dec4e7 100644 --- a/drivers/staging/rtl8712/rtl8712_led.c +++ b/drivers/staging/rtl8712/rtl8712_led.c @@ -107,7 +107,7 @@ static void DeInitLed871x(struct LED_871x *pLed) */ static void SwLedOn(struct _adapter *padapter, struct LED_871x *pLed) { - u8 LedCfg; + u8 LedCfg; if (padapter->surprise_removed || padapter->driver_stopped) return; diff --git a/drivers/staging/rtl8712/rtl8712_recv.c b/drivers/staging/rtl8712/rtl8712_recv.c index a3c4713c59b3..1fabc5137a4c 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.c +++ b/drivers/staging/rtl8712/rtl8712_recv.c @@ -861,7 +861,7 @@ static void query_rx_phy_status(struct _adapter *padapter, static void process_link_qual(struct _adapter *padapter, union recv_frame *prframe) { - u32 last_evm = 0, tmpVal; + u32 last_evm = 0, avg_val; struct rx_pkt_attrib *pattrib; struct smooth_rssi_data *sqd = &padapter->recvpriv.signal_qual_data; @@ -883,8 +883,8 @@ static void process_link_qual(struct _adapter *padapter, sqd->index = 0; /* <1> Showed on UI for user, in percentage. */ - tmpVal = sqd->total_val / sqd->total_num; - padapter->recvpriv.signal = (u8)tmpVal; + avg_val = sqd->total_val / sqd->total_num; + padapter->recvpriv.signal = (u8)avg_val; } } diff --git a/drivers/staging/rtl8712/rtl8712_recv.h b/drivers/staging/rtl8712/rtl8712_recv.h index f4d20b0efd4e..a1360dcf91ce 100644 --- a/drivers/staging/rtl8712/rtl8712_recv.h +++ b/drivers/staging/rtl8712/rtl8712_recv.h @@ -82,7 +82,7 @@ struct phy_stat { union recvstat { struct recv_stat recv_stat; - unsigned int value[RXDESC_SIZE>>2]; + unsigned int value[RXDESC_SIZE >> 2]; }; struct recv_buf { diff --git a/drivers/staging/rtl8723bs/core/rtw_mlme.c b/drivers/staging/rtl8723bs/core/rtw_mlme.c index bfb27f902753..8c487b7b7a40 100644 --- a/drivers/staging/rtl8723bs/core/rtw_mlme.c +++ b/drivers/staging/rtl8723bs/core/rtw_mlme.c @@ -22,7 +22,6 @@ int rtw_init_mlme_priv(struct adapter *padapter) pmlmepriv->pscanned = NULL; pmlmepriv->fw_state = WIFI_STATION_STATE; /* Must sync with rtw_wdev_alloc() */ - /* wdev->iftype = NL80211_IFTYPE_STATION */ pmlmepriv->cur_network.network.infrastructure_mode = Ndis802_11AutoUnknown; pmlmepriv->scan_mode = SCAN_ACTIVE;/* 1: active, 0: passive. Maybe someday we should rename this varable to "active_mode" (Jeff) */ @@ -109,32 +108,6 @@ void _rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) } } -/* -struct wlan_network *_rtw_dequeue_network(struct __queue *queue) -{ - _irqL irqL; - - struct wlan_network *pnetwork; - - spin_lock_bh(&queue->lock); - - if (list_empty(&queue->queue)) - - pnetwork = NULL; - - else - { - pnetwork = container_of(get_next(&queue->queue), struct wlan_network, list); - - list_del_init(&(pnetwork->list)); - } - - spin_unlock_bh(&queue->lock); - - return pnetwork; -} -*/ - struct wlan_network *rtw_alloc_network(struct mlme_priv *pmlmepriv) { struct wlan_network *pnetwork; @@ -207,13 +180,9 @@ void _rtw_free_network_nolock(struct mlme_priv *pmlmepriv, struct wlan_network * if (pnetwork->fixed) return; - /* spin_lock_irqsave(&free_queue->lock, irqL); */ - list_del_init(&(pnetwork->list)); list_add_tail(&(pnetwork->list), get_list_head(free_queue)); - - /* spin_unlock_irqrestore(&free_queue->lock, irqL); */ } /* @@ -231,8 +200,6 @@ struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr) goto exit; } - /* spin_lock_bh(&scanned_queue->lock); */ - phead = get_list_head(scanned_queue); list_for_each(plist, phead) { pnetwork = list_entry(plist, struct wlan_network, list); @@ -244,8 +211,6 @@ struct wlan_network *_rtw_find_network(struct __queue *scanned_queue, u8 *addr) if (plist == phead) pnetwork = NULL; - /* spin_unlock_bh(&scanned_queue->lock); */ - exit: return pnetwork; } @@ -320,16 +285,6 @@ void rtw_free_mlme_priv(struct mlme_priv *pmlmepriv) _rtw_free_mlme_priv(pmlmepriv); } -/* -static struct wlan_network *rtw_dequeue_network(struct __queue *queue) -{ - struct wlan_network *pnetwork; - - pnetwork = _rtw_dequeue_network(queue); - return pnetwork; -} -*/ - void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork); void rtw_free_network_nolock(struct adapter *padapter, struct wlan_network *pnetwork) { @@ -494,12 +449,9 @@ static void update_current_network(struct adapter *adapter, struct wlan_bssid_ex &(pmlmepriv->cur_network.network)); if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && (is_same_network(&(pmlmepriv->cur_network.network), pnetwork, 0))) { - /* if (pmlmepriv->cur_network.network.ie_length<= pnetwork->ie_length) */ - { - update_network(&(pmlmepriv->cur_network.network), pnetwork, adapter, true); - rtw_update_protection(adapter, (pmlmepriv->cur_network.network.ies) + sizeof(struct ndis_802_11_fix_ie), - pmlmepriv->cur_network.network.ie_length); - } + update_network(&(pmlmepriv->cur_network.network), pnetwork, adapter, true); + rtw_update_protection(adapter, (pmlmepriv->cur_network.network.ies) + sizeof(struct ndis_802_11_fix_ie), + pmlmepriv->cur_network.network.ie_length); } } @@ -540,7 +492,6 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t /* If we didn't find a match, then get a new network slot to initialize * with this beacon's information */ - /* if (phead == plist) { */ if (!target_find) { if (list_empty(&pmlmepriv->free_bss_pool.queue)) { /* If there are no more slots, expire the oldest */ @@ -613,15 +564,8 @@ exit: void rtw_add_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork); void rtw_add_network(struct adapter *adapter, struct wlan_bssid_ex *pnetwork) { - /* struct __queue *queue = &(pmlmepriv->scanned_queue); */ - - /* spin_lock_bh(&queue->lock); */ - update_current_network(adapter, pnetwork); - rtw_update_scanned_network(adapter, pnetwork); - - /* spin_unlock_bh(&queue->lock); */ } /* select the desired network based on the capability of the (i)bss. */ @@ -637,10 +581,7 @@ int rtw_is_desired_network(struct adapter *adapter, struct wlan_network *pnetwor struct mlme_priv *pmlmepriv = &adapter->mlmepriv; u32 desired_encmode; u32 privacy; - - /* u8 wps_ie[512]; */ uint wps_ielen; - int bselected = true; desired_encmode = psecuritypriv->ndisencryptstatus; @@ -1052,9 +993,8 @@ static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, str memset((u8 *)&psta->dot11rxpn, 0, sizeof(union pn48)); } - /* Commented by Albert 2012/07/21 */ - /* When doing the WPS, the wps_ie_len won't equal to 0 */ - /* And the Wi-Fi driver shouldn't allow the data packet to be transmitted. */ + /* When doing the WPS, the wps_ie_len won't equal to 0 */ + /* And the Wi-Fi driver shouldn't allow the data packet to be transmitted. */ if (padapter->securitypriv.wps_ie_len != 0) { psta->ieee8021x_blocked = true; padapter->securitypriv.wps_ie_len = 0; @@ -1064,7 +1004,6 @@ static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, str /* if A-MPDU Rx is enabled, resetting rx_ordering_ctrl wstart_b(indicate_seq) to default value = 0xffff */ /* todo: check if AP can send A-MPDU packets */ for (i = 0; i < 16 ; i++) { - /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */ preorder_ctrl = &psta->recvreorder_ctrl[i]; preorder_ctrl->enable = false; preorder_ctrl->indicate_seq = 0xffff; @@ -1075,7 +1014,6 @@ static struct sta_info *rtw_joinbss_update_stainfo(struct adapter *padapter, str bmc_sta = rtw_get_bcmc_stainfo(padapter); if (bmc_sta) { for (i = 0; i < 16 ; i++) { - /* preorder_ctrl = &precvpriv->recvreorder_ctrl[i]; */ preorder_ctrl = &bmc_sta->recvreorder_ctrl[i]; preorder_ctrl->enable = false; preorder_ctrl->indicate_seq = 0xffff; @@ -1239,8 +1177,6 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) rtw_reset_securitypriv(adapter); _set_timer(&pmlmepriv->assoc_timer, 1); - /* rtw_free_assoc_resources(adapter, 1); */ - if ((check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) == true) _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); @@ -1262,7 +1198,6 @@ void rtw_joinbss_event_prehandle(struct adapter *adapter, u8 *pbuf) #endif _set_timer(&pmlmepriv->assoc_timer, 1); - /* rtw_free_assoc_resources(adapter, 1); */ _clr_fwstate_(pmlmepriv, _FW_UNDER_LINKING); #ifdef REJOIN @@ -1357,7 +1292,6 @@ void rtw_stassoc_event_callback(struct adapter *adapter, u8 *pbuf) /* to do : init sta_info variable */ psta->qos_option = 0; psta->mac_id = (uint)pstassoc->cam_id; - /* psta->aid = (uint)pstassoc->cam_id; */ /* for ad-hoc mode */ rtw_hal_set_odm_var(adapter, HAL_ODM_STA_INFO, psta, true); @@ -1472,10 +1406,8 @@ void rtw_stadel_event_callback(struct adapter *adapter, u8 *pbuf) if (adapter->stapriv.asoc_sta_count == 1) {/* a sta + bc/mc_stainfo (not Ibss_stainfo) */ u8 ret = _SUCCESS; - /* rtw_indicate_disconnect(adapter);removed@20091105 */ spin_lock_bh(&(pmlmepriv->scanned_queue.lock)); /* free old ibss network */ - /* pwlan = rtw_find_network(&pmlmepriv->scanned_queue, pstadel->macaddr); */ pwlan = rtw_find_network(&pmlmepriv->scanned_queue, tgt_network->network.mac_address); if (pwlan) { pwlan->fixed = false; @@ -2088,14 +2020,6 @@ signed int rtw_restruct_sec_ie(struct adapter *adapter, u8 *in_ie, u8 *out_ie, u } else if ((authmode == WLAN_EID_VENDOR_SPECIFIC) || (authmode == WLAN_EID_RSN)) { /* copy RSN or SSN */ memcpy(&out_ie[ielength], &psecuritypriv->supplicant_ie[0], psecuritypriv->supplicant_ie[1]+2); - /* debug for CONFIG_IEEE80211W - { - int jj; - printk("supplicant_ie_length =%d &&&&&&&&&&&&&&&&&&&\n", psecuritypriv->supplicant_ie[1]+2); - for (jj = 0; jj < psecuritypriv->supplicant_ie[1]+2; jj++) - printk(" %02x ", psecuritypriv->supplicant_ie[jj]); - printk("\n"); - }*/ ielength += psecuritypriv->supplicant_ie[1]+2; rtw_report_sec_ie(adapter, authmode, psecuritypriv->supplicant_ie); } @@ -2132,7 +2056,6 @@ void rtw_update_registrypriv_dev_network(struct adapter *adapter) struct wlan_bssid_ex *pdev_network = &pregistrypriv->dev_network; struct security_priv *psecuritypriv = &adapter->securitypriv; struct wlan_network *cur_network = &adapter->mlmepriv.cur_network; - /* struct xmit_priv *pxmitpriv = &adapter->xmitpriv; */ pdev_network->privacy = (psecuritypriv->dot11PrivacyAlgrthm > 0 ? 1 : 0) ; /* adhoc no 802.1x */ @@ -2381,7 +2304,6 @@ unsigned int rtw_restructure_ht_ie(struct adapter *padapter, u8 *in_ie, u8 *out_ rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); - /* rtw_hal_get_def_var(padapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor); */ ht_capie.ampdu_params_info = (max_rx_ampdu_factor&0x03); if (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_) @@ -2411,14 +2333,10 @@ void rtw_update_ht_cap(struct adapter *padapter, u8 *pie, uint ie_len, u8 channe { u8 *p, max_ampdu_sz; int len; - /* struct sta_info *bmc_sta, *psta; */ struct ieee80211_ht_cap *pht_capie; - /* struct recv_reorder_ctrl *preorder_ctrl; */ struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct ht_priv *phtpriv = &pmlmepriv->htpriv; - /* struct recv_priv *precvpriv = &padapter->recvpriv; */ struct registry_priv *pregistrypriv = &padapter->registrypriv; - /* struct wlan_network *pcur_network = &(pmlmepriv->cur_network);; */ struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv; struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); u8 cbw40_enable = 0; diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c index 65a450fcdce7..3fe27ee75b47 100644 --- a/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c +++ b/drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c @@ -884,7 +884,7 @@ static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev, goto addkey_end; } - strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN); + strscpy(param->u.crypt.alg, alg_name); if (!mac_addr || is_broadcast_ether_addr(mac_addr)) param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */ @@ -2143,8 +2143,7 @@ static int rtw_cfg80211_add_monitor_if(struct adapter *padapter, char *name, str } mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP; - strncpy(mon_ndev->name, name, IFNAMSIZ); - mon_ndev->name[IFNAMSIZ - 1] = 0; + strscpy(mon_ndev->name, name); mon_ndev->needs_free_netdev = true; mon_ndev->priv_destructor = rtw_ndev_destructor; diff --git a/drivers/staging/rtl8723bs/os_dep/os_intfs.c b/drivers/staging/rtl8723bs/os_dep/os_intfs.c index 68bba3c0e757..55d0140cd543 100644 --- a/drivers/staging/rtl8723bs/os_dep/os_intfs.c +++ b/drivers/staging/rtl8723bs/os_dep/os_intfs.c @@ -415,7 +415,7 @@ static int rtw_ndev_init(struct net_device *dev) struct adapter *adapter = rtw_netdev_priv(dev); netdev_dbg(dev, FUNC_ADPT_FMT "\n", FUNC_ADPT_ARG(adapter)); - strncpy(adapter->old_ifname, dev->name, IFNAMSIZ); + strscpy(adapter->old_ifname, dev->name); return 0; } diff --git a/drivers/staging/rts5208/rtsx_scsi.c b/drivers/staging/rts5208/rtsx_scsi.c index 08bd768ad34d..c27cffb9ad8f 100644 --- a/drivers/staging/rts5208/rtsx_scsi.c +++ b/drivers/staging/rts5208/rtsx_scsi.c @@ -463,10 +463,10 @@ static unsigned char formatter_inquiry_str[20] = { static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) { unsigned int lun = SCSI_LUN(srb); - char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00 "; - char *inquiry_sdms = (char *)"Generic-SD/MemoryStick 1.00 "; - char *inquiry_sd = (char *)"Generic-SD/MMC 1.00 "; - char *inquiry_ms = (char *)"Generic-MemoryStick 1.00 "; + char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00"; + char *inquiry_sdms = (char *)"Generic-SD/MemoryStick 1.00"; + char *inquiry_sd = (char *)"Generic-SD/MMC 1.00"; + char *inquiry_ms = (char *)"Generic-MemoryStick 1.00"; char *inquiry_string; unsigned char sendbytes; unsigned char *buf; @@ -523,7 +523,7 @@ static int inquiry(struct scsi_cmnd *srb, struct rtsx_chip *chip) if (sendbytes > 8) { memcpy(buf, inquiry_buf, 8); - strncpy(buf + 8, inquiry_string, sendbytes - 8); + memcpy(buf + 8, inquiry_string, min(sendbytes, 36) - 8); if (pro_formatter_flag) { /* Additional Length */ buf[4] = 0x33; diff --git a/drivers/staging/vc04_services/Kconfig b/drivers/staging/vc04_services/Kconfig index 31e58c9d1a11..ccc8e1588648 100644 --- a/drivers/staging/vc04_services/Kconfig +++ b/drivers/staging/vc04_services/Kconfig @@ -16,27 +16,33 @@ config BCM2835_VCHIQ depends on HAS_DMA imply VCHIQ_CDEV help - Broadcom BCM2835 and similar SoCs have a VPU called VideoCore. This config - enables the VCHIQ driver, which implements a messaging interface between - the kernel and the firmware running on VideoCore. Other drivers use this - interface to communicate to the VPU. More specifically, the VCHIQ driver is - used by audio/video and camera drivers as well as for implementing MMAL - API, which is in turn used by several multimedia services on the BCM2835 - family of SoCs. - Defaults to Y when the Broadcom Videocore services are included in - the build, N otherwise. + Broadcom BCM2835 and similar SoCs have a VPU called VideoCore. + This config enables the VCHIQ driver, which implements a + messaging interface between the kernel and the firmware running + on VideoCore. Other drivers use this interface to communicate to + the VPU. More specifically, the VCHIQ driver is used by + audio/video and camera drivers as well as for implementing MMAL + API, which is in turn used by several multimedia services on the + BCM2835 family of SoCs. + + Defaults to Y when the Broadcom Videocore services are included + in the build, N otherwise. if BCM2835_VCHIQ config VCHIQ_CDEV bool "VCHIQ Character Driver" help - Enable the creation of VCHIQ character driver. The cdev exposes ioctls used - by userspace libraries and testing tools to interact with VideoCore, via - the VCHIQ core driver (Check BCM2835_VCHIQ for more info). - This can be set to 'N' if the VideoCore communication is not needed by - userspace but only by other kernel modules (like bcm2835-audio). If not - sure, set this to 'Y'. + Enable the creation of VCHIQ character driver. The cdev exposes + ioctls used by userspace libraries and testing tools to interact + with VideoCore, via the VCHIQ core driver (Check BCM2835_VCHIQ + for more info). + + This can be set to 'N' if the VideoCore communication is not + needed by userspace but only by other kernel modules + (like bcm2835-audio). + + If not sure, set this to 'Y'. endif diff --git a/drivers/staging/vc04_services/Makefile b/drivers/staging/vc04_services/Makefile index e8b897a7b9a6..dad3789522b8 100644 --- a/drivers/staging/vc04_services/Makefile +++ b/drivers/staging/vc04_services/Makefile @@ -6,7 +6,6 @@ vchiq-objs := \ interface/vchiq_arm/vchiq_arm.o \ interface/vchiq_arm/vchiq_bus.o \ interface/vchiq_arm/vchiq_debugfs.o \ - interface/vchiq_arm/vchiq_connected.o \ ifdef CONFIG_VCHIQ_CDEV vchiq-objs += interface/vchiq_arm/vchiq_dev.o diff --git a/drivers/staging/vc04_services/bcm2835-audio/Kconfig b/drivers/staging/vc04_services/bcm2835-audio/Kconfig index 7f22f6c85067..7fbb29d3c34d 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/Kconfig +++ b/drivers/staging/vc04_services/bcm2835-audio/Kconfig @@ -8,4 +8,4 @@ config SND_BCM2835 Say Y or M if you want to support BCM2835 built in audio. This driver handles both 3.5mm and HDMI audio, by leveraging the VCHIQ messaging interface between the kernel and the firmware - running on VideoCore.
\ No newline at end of file + running on VideoCore. diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index d74110ca17ab..133ed15f3dbc 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c @@ -7,6 +7,8 @@ #include "bcm2835.h" #include "vc_vchi_audioserv_defs.h" +#include "../interface/vchiq_arm/vchiq_arm.h" + struct bcm2835_audio_instance { struct device *dev; unsigned int service_handle; @@ -175,10 +177,11 @@ static void vc_vchi_audio_deinit(struct bcm2835_audio_instance *instance) int bcm2835_new_vchi_ctx(struct device *dev, struct bcm2835_vchi_ctx *vchi_ctx) { + struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(dev->parent); int ret; /* Initialize and create a VCHI connection */ - ret = vchiq_initialise(&vchi_ctx->instance); + ret = vchiq_initialise(&mgmt->state, &vchi_ctx->instance); if (ret) { dev_err(dev, "failed to initialise VCHI instance (ret=%d)\n", ret); diff --git a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c index c3ba490e53cb..b3599ec6293a 100644 --- a/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c +++ b/drivers/staging/vc04_services/bcm2835-camera/bcm2835-camera.c @@ -1555,7 +1555,7 @@ static int mmal_init(struct bcm2835_mmal_dev *dev) u32 param_size; struct vchiq_mmal_component *camera; - ret = vchiq_mmal_init(&dev->instance); + ret = vchiq_mmal_init(dev->v4l2_dev.dev, &dev->instance); if (ret < 0) { v4l2_err(&dev->v4l2_dev, "%s: vchiq mmal init failed %d\n", __func__, ret); @@ -1854,7 +1854,7 @@ static int bcm2835_mmal_probe(struct vchiq_device *device) return ret; } - ret = vchiq_mmal_init(&instance); + ret = vchiq_mmal_init(&device->dev, &instance); if (ret < 0) return ret; diff --git a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h index 52e106f117da..6c40d8c1dde6 100644 --- a/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h +++ b/drivers/staging/vc04_services/include/linux/raspberrypi/vchiq.h @@ -48,6 +48,7 @@ struct vchiq_element { }; struct vchiq_instance; +struct vchiq_state; struct vchiq_service_base { int fourcc; @@ -78,7 +79,8 @@ struct vchiq_service_params_kernel { short version_min; /* Update for incompatible changes */ }; -extern int vchiq_initialise(struct vchiq_instance **pinstance); +extern int vchiq_initialise(struct vchiq_state *state, + struct vchiq_instance **pinstance); extern int vchiq_shutdown(struct vchiq_instance *instance); extern int vchiq_connect(struct vchiq_instance *instance); extern int vchiq_open_service(struct vchiq_instance *instance, diff --git a/drivers/staging/vc04_services/interface/TODO b/drivers/staging/vc04_services/interface/TODO index 05eb5140d096..05f129c0c254 100644 --- a/drivers/staging/vc04_services/interface/TODO +++ b/drivers/staging/vc04_services/interface/TODO @@ -28,27 +28,12 @@ variables avoided. A short top-down description of this driver's architecture (function of kthreads, userspace, limitations) could be very helpful for reviewers. -* Review and comment memory barriers - -There is a heavy use of memory barriers in this driver, it would be very -beneficial to go over all of them and, if correct, comment on their merits. -Extra points to whomever confidently reviews the remote_event_*() family of -functions. - * Reformat core code with more sane indentations The code follows the 80 characters limitation yet tends to go 3 or 4 levels of indentation deep making it very unpleasant to read. This is specially relevant in the character driver ioctl code and in the core thread functions. -* Get rid of all non essential global structures and create a proper per -device structure - -The first thing one generally sees in a probe function is a memory allocation -for all the device specific data. This structure is then passed all over the -driver. This is good practice since it makes the driver work regardless of the -number of devices probed. - * Clean up Sparse warnings from __user annotations. See vchiq_irq_queue_bulk_tx_rx(). Ensure that the address of "&waiter->bulk_waiter" is never disclosed to userspace. diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index 1579bd4e5263..297af1d80b12 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -36,7 +36,6 @@ #include "vchiq_arm.h" #include "vchiq_bus.h" #include "vchiq_debugfs.h" -#include "vchiq_connected.h" #include "vchiq_pagelist.h" #define DEVICE_NAME "vchiq" @@ -60,9 +59,6 @@ #define KEEPALIVE_VER 1 #define KEEPALIVE_VER_MIN KEEPALIVE_VER -DEFINE_SPINLOCK(msg_queue_spinlock); -struct vchiq_state g_state; - /* * The devices implemented in the VCHIQ firmware are not discoverable, * so we need to maintain a list of them in order to register them with @@ -71,16 +67,11 @@ struct vchiq_state g_state; static struct vchiq_device *bcm2835_audio; static struct vchiq_device *bcm2835_camera; -struct vchiq_drvdata { - const unsigned int cache_line_size; - struct rpi_firmware *fw; -}; - -static struct vchiq_drvdata bcm2835_drvdata = { +static const struct vchiq_platform_info bcm2835_info = { .cache_line_size = 32, }; -static struct vchiq_drvdata bcm2836_drvdata = { +static const struct vchiq_platform_info bcm2836_info = { .cache_line_size = 64, }; @@ -135,25 +126,6 @@ struct vchiq_pagelist_info { unsigned int scatterlist_mapped; }; -static void __iomem *g_regs; -/* This value is the size of the L2 cache lines as understood by the - * VPU firmware, which determines the required alignment of the - * offsets/sizes in pagelists. - * - * Modern VPU firmware looks for a DT "cache-line-size" property in - * the VCHIQ node and will overwrite it with the actual L2 cache size, - * which the kernel must then respect. That property was rejected - * upstream, so we have to use the VPU firmware's compatibility value - * of 32. - */ -static unsigned int g_cache_line_size = 32; -static unsigned int g_fragments_size; -static char *g_fragments_base; -static char *g_free_fragments; -static struct semaphore g_free_fragments_sema; - -static DEFINE_SEMAPHORE(g_free_fragments_mutex, 1); - static int vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *data, unsigned int size, enum vchiq_bulk_dir dir); @@ -162,11 +134,14 @@ static irqreturn_t vchiq_doorbell_irq(int irq, void *dev_id) { struct vchiq_state *state = dev_id; + struct vchiq_drv_mgmt *mgmt; irqreturn_t ret = IRQ_NONE; unsigned int status; + mgmt = dev_get_drvdata(state->dev); + /* Read (and clear) the doorbell */ - status = readl(g_regs + BELL0); + status = readl(mgmt->regs + BELL0); if (status & ARM_DS_ACTIVE) { /* Was the doorbell rung? */ remote_event_pollall(state); @@ -205,6 +180,56 @@ is_adjacent_block(u32 *addrs, u32 addr, unsigned int k) return tmp == (addr & PAGE_MASK); } +/* + * This function is called by the vchiq stack once it has been connected to + * the videocore and clients can start to use the stack. + */ +static void vchiq_call_connected_callbacks(struct vchiq_drv_mgmt *drv_mgmt) +{ + int i; + + if (mutex_lock_killable(&drv_mgmt->connected_mutex)) + return; + + for (i = 0; i < drv_mgmt->num_deferred_callbacks; i++) + drv_mgmt->deferred_callback[i](); + + drv_mgmt->num_deferred_callbacks = 0; + drv_mgmt->connected = true; + mutex_unlock(&drv_mgmt->connected_mutex); +} + +/* + * This function is used to defer initialization until the vchiq stack is + * initialized. If the stack is already initialized, then the callback will + * be made immediately, otherwise it will be deferred until + * vchiq_call_connected_callbacks is called. + */ +void vchiq_add_connected_callback(struct vchiq_device *device, void (*callback)(void)) +{ + struct vchiq_drv_mgmt *drv_mgmt = device->drv_mgmt; + + if (mutex_lock_killable(&drv_mgmt->connected_mutex)) + return; + + if (drv_mgmt->connected) { + /* We're already connected. Call the callback immediately. */ + callback(); + } else { + if (drv_mgmt->num_deferred_callbacks >= VCHIQ_DRV_MAX_CALLBACKS) { + dev_err(&device->dev, + "core: deferred callbacks(%d) exceeded the maximum limit(%d)\n", + drv_mgmt->num_deferred_callbacks, VCHIQ_DRV_MAX_CALLBACKS); + } else { + drv_mgmt->deferred_callback[drv_mgmt->num_deferred_callbacks] = + callback; + drv_mgmt->num_deferred_callbacks++; + } + } + mutex_unlock(&drv_mgmt->connected_mutex); +} +EXPORT_SYMBOL(vchiq_add_connected_callback); + /* There is a potential problem with partial cache lines (pages?) * at the ends of the block when reading. If the CPU accessed anything in * the same line (page?) then it may have pulled old data into the cache, @@ -217,6 +242,7 @@ static struct vchiq_pagelist_info * create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf, size_t count, unsigned short type) { + struct vchiq_drv_mgmt *drv_mgmt; struct pagelist *pagelist; struct vchiq_pagelist_info *pagelistinfo; struct page **pages; @@ -231,6 +257,8 @@ create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf, if (count >= INT_MAX - PAGE_SIZE) return NULL; + drv_mgmt = dev_get_drvdata(instance->state->dev); + if (buf) offset = (uintptr_t)buf & (PAGE_SIZE - 1); else @@ -373,25 +401,25 @@ create_pagelist(struct vchiq_instance *instance, char *buf, char __user *ubuf, /* Partial cache lines (fragments) require special measures */ if ((type == PAGELIST_READ) && - ((pagelist->offset & (g_cache_line_size - 1)) || + ((pagelist->offset & (drv_mgmt->info->cache_line_size - 1)) || ((pagelist->offset + pagelist->length) & - (g_cache_line_size - 1)))) { + (drv_mgmt->info->cache_line_size - 1)))) { char *fragments; - if (down_interruptible(&g_free_fragments_sema)) { + if (down_interruptible(&drv_mgmt->free_fragments_sema)) { cleanup_pagelistinfo(instance, pagelistinfo); return NULL; } - WARN_ON(!g_free_fragments); + WARN_ON(!drv_mgmt->free_fragments); - down(&g_free_fragments_mutex); - fragments = g_free_fragments; + down(&drv_mgmt->free_fragments_mutex); + fragments = drv_mgmt->free_fragments; WARN_ON(!fragments); - g_free_fragments = *(char **)g_free_fragments; - up(&g_free_fragments_mutex); + drv_mgmt->free_fragments = *(char **)drv_mgmt->free_fragments; + up(&drv_mgmt->free_fragments_mutex); pagelist->type = PAGELIST_READ_WITH_FRAGMENTS + - (fragments - g_fragments_base) / g_fragments_size; + (fragments - drv_mgmt->fragments_base) / drv_mgmt->fragments_size; } return pagelistinfo; @@ -401,12 +429,15 @@ static void free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagelistinfo, int actual) { + struct vchiq_drv_mgmt *drv_mgmt; struct pagelist *pagelist = pagelistinfo->pagelist; struct page **pages = pagelistinfo->pages; unsigned int num_pages = pagelistinfo->num_pages; dev_dbg(instance->state->dev, "arm: %pK, %d\n", pagelistinfo->pagelist, actual); + drv_mgmt = dev_get_drvdata(instance->state->dev); + /* * NOTE: dma_unmap_sg must be called before the * cpu can touch any of the data/pages. @@ -416,16 +447,16 @@ free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagel pagelistinfo->scatterlist_mapped = 0; /* Deal with any partial cache lines (fragments) */ - if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS && g_fragments_base) { - char *fragments = g_fragments_base + + if (pagelist->type >= PAGELIST_READ_WITH_FRAGMENTS && drv_mgmt->fragments_base) { + char *fragments = drv_mgmt->fragments_base + (pagelist->type - PAGELIST_READ_WITH_FRAGMENTS) * - g_fragments_size; + drv_mgmt->fragments_size; int head_bytes, tail_bytes; - head_bytes = (g_cache_line_size - pagelist->offset) & - (g_cache_line_size - 1); + head_bytes = (drv_mgmt->info->cache_line_size - pagelist->offset) & + (drv_mgmt->info->cache_line_size - 1); tail_bytes = (pagelist->offset + actual) & - (g_cache_line_size - 1); + (drv_mgmt->info->cache_line_size - 1); if ((actual >= 0) && (head_bytes != 0)) { if (head_bytes > actual) @@ -440,15 +471,15 @@ free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagel (tail_bytes != 0)) memcpy_to_page(pages[num_pages - 1], (pagelist->offset + actual) & - (PAGE_SIZE - 1) & ~(g_cache_line_size - 1), - fragments + g_cache_line_size, + (PAGE_SIZE - 1) & ~(drv_mgmt->info->cache_line_size - 1), + fragments + drv_mgmt->info->cache_line_size, tail_bytes); - down(&g_free_fragments_mutex); - *(char **)fragments = g_free_fragments; - g_free_fragments = fragments; - up(&g_free_fragments_mutex); - up(&g_free_fragments_sema); + down(&drv_mgmt->free_fragments_mutex); + *(char **)fragments = drv_mgmt->free_fragments; + drv_mgmt->free_fragments = fragments; + up(&drv_mgmt->free_fragments_mutex); + up(&drv_mgmt->free_fragments_sema); } /* Need to mark all the pages dirty. */ @@ -466,8 +497,8 @@ free_pagelist(struct vchiq_instance *instance, struct vchiq_pagelist_info *pagel static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state *state) { struct device *dev = &pdev->dev; - struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev); - struct rpi_firmware *fw = drvdata->fw; + struct vchiq_drv_mgmt *drv_mgmt = platform_get_drvdata(pdev); + struct rpi_firmware *fw = drv_mgmt->fw; struct vchiq_slot_zero *vchiq_slot_zero; void *slot_mem; dma_addr_t slot_phys; @@ -484,12 +515,11 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state if (err < 0) return err; - g_cache_line_size = drvdata->cache_line_size; - g_fragments_size = 2 * g_cache_line_size; + drv_mgmt->fragments_size = 2 * drv_mgmt->info->cache_line_size; /* Allocate space for the channels in coherent memory */ slot_mem_size = PAGE_ALIGN(TOTAL_SLOTS * VCHIQ_SLOT_SIZE); - frag_mem_size = PAGE_ALIGN(g_fragments_size * MAX_FRAGMENTS); + frag_mem_size = PAGE_ALIGN(drv_mgmt->fragments_size * MAX_FRAGMENTS); slot_mem = dmam_alloc_coherent(dev, slot_mem_size + frag_mem_size, &slot_phys, GFP_KERNEL); @@ -509,23 +539,24 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state vchiq_slot_zero->platform_data[VCHIQ_PLATFORM_FRAGMENTS_COUNT_IDX] = MAX_FRAGMENTS; - g_fragments_base = (char *)slot_mem + slot_mem_size; + drv_mgmt->fragments_base = (char *)slot_mem + slot_mem_size; - g_free_fragments = g_fragments_base; + drv_mgmt->free_fragments = drv_mgmt->fragments_base; for (i = 0; i < (MAX_FRAGMENTS - 1); i++) { - *(char **)&g_fragments_base[i * g_fragments_size] = - &g_fragments_base[(i + 1) * g_fragments_size]; + *(char **)&drv_mgmt->fragments_base[i * drv_mgmt->fragments_size] = + &drv_mgmt->fragments_base[(i + 1) * drv_mgmt->fragments_size]; } - *(char **)&g_fragments_base[i * g_fragments_size] = NULL; - sema_init(&g_free_fragments_sema, MAX_FRAGMENTS); + *(char **)&drv_mgmt->fragments_base[i * drv_mgmt->fragments_size] = NULL; + sema_init(&drv_mgmt->free_fragments_sema, MAX_FRAGMENTS); + sema_init(&drv_mgmt->free_fragments_mutex, 1); err = vchiq_init_state(state, vchiq_slot_zero, dev); if (err) return err; - g_regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(g_regs)) - return PTR_ERR(g_regs); + drv_mgmt->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(drv_mgmt->regs)) + return PTR_ERR(drv_mgmt->regs); irq = platform_get_irq(pdev, 0); if (irq <= 0) @@ -556,7 +587,8 @@ static int vchiq_platform_init(struct platform_device *pdev, struct vchiq_state dev_dbg(&pdev->dev, "arm: vchiq_init - done (slots %pK, phys %pad)\n", vchiq_slot_zero, &slot_phys); - vchiq_call_connected_callbacks(); + mutex_init(&drv_mgmt->connected_mutex); + vchiq_call_connected_callbacks(drv_mgmt); return 0; } @@ -607,8 +639,10 @@ static struct vchiq_arm_state *vchiq_platform_get_arm_state(struct vchiq_state * } void -remote_event_signal(struct remote_event *event) +remote_event_signal(struct vchiq_state *state, struct remote_event *event) { + struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(state->dev); + /* * Ensure that all writes to shared data structures have completed * before signalling the peer. @@ -620,7 +654,7 @@ remote_event_signal(struct remote_event *event) dsb(sy); /* data barrier operation */ if (event->armed) - writel(0, g_regs + BELL2); /* trigger vc interrupt */ + writel(0, mgmt->regs + BELL2); /* trigger vc interrupt */ } int @@ -662,9 +696,8 @@ void vchiq_dump_platform_state(struct seq_file *f) } #define VCHIQ_INIT_RETRIES 10 -int vchiq_initialise(struct vchiq_instance **instance_out) +int vchiq_initialise(struct vchiq_state *state, struct vchiq_instance **instance_out) { - struct vchiq_state *state; struct vchiq_instance *instance = NULL; int i, ret; @@ -674,7 +707,6 @@ int vchiq_initialise(struct vchiq_instance **instance_out) * block forever. */ for (i = 0; i < VCHIQ_INIT_RETRIES; i++) { - state = vchiq_get_state(); if (state) break; usleep_range(500, 600); @@ -690,7 +722,6 @@ int vchiq_initialise(struct vchiq_instance **instance_out) instance = kzalloc(sizeof(*instance), GFP_KERNEL); if (!instance) { - dev_err(state->dev, "core: %s: Cannot allocate vchiq instance\n", __func__); ret = -ENOMEM; goto failed; } @@ -949,17 +980,15 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl * This is not a retry of the previous one. * Cancel the signal when the transfer completes. */ - spin_lock(&bulk_waiter_spinlock); + spin_lock(&service->state->bulk_waiter_spinlock); bulk->userdata = NULL; - spin_unlock(&bulk_waiter_spinlock); + spin_unlock(&service->state->bulk_waiter_spinlock); } } } else { waiter = kzalloc(sizeof(*waiter), GFP_KERNEL); - if (!waiter) { - dev_err(service->state->dev, "core: %s: - Out of memory\n", __func__); + if (!waiter) return -ENOMEM; - } } status = vchiq_bulk_transfer(instance, handle, data, NULL, size, @@ -970,9 +999,9 @@ vchiq_blocking_bulk_transfer(struct vchiq_instance *instance, unsigned int handl if (bulk) { /* Cancel the signal when the transfer completes. */ - spin_lock(&bulk_waiter_spinlock); + spin_lock(&service->state->bulk_waiter_spinlock); bulk->userdata = NULL; - spin_unlock(&bulk_waiter_spinlock); + spin_unlock(&service->state->bulk_waiter_spinlock); } kfree(waiter); } else { @@ -993,9 +1022,10 @@ add_completion(struct vchiq_instance *instance, enum vchiq_reason reason, void *bulk_userdata) { struct vchiq_completion_data_kernel *completion; + struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(instance->state->dev); int insert; - DEBUG_INITIALISE(g_state.local); + DEBUG_INITIALISE(mgmt->state.local); insert = instance->completion_insert; while ((insert - instance->completion_remove) >= MAX_COMPLETIONS) { @@ -1058,11 +1088,12 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, * containing the original callback and the user state structure, which * contains a circular buffer for completion records. */ + struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(instance->state->dev); struct user_service *user_service; struct vchiq_service *service; bool skip_completion = false; - DEBUG_INITIALISE(g_state.local); + DEBUG_INITIALISE(mgmt->state.local); DEBUG_TRACE(SERVICE_CALLBACK_LINE); @@ -1075,7 +1106,7 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, user_service = (struct user_service *)service->base.userdata; - if (!instance || instance->closing) { + if (instance->closing) { rcu_read_unlock(); return 0; } @@ -1093,10 +1124,10 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, reason, header, instance, bulk_userdata); if (header && user_service->is_vchi) { - spin_lock(&msg_queue_spinlock); + spin_lock(&service->state->msg_queue_spinlock); while (user_service->msg_insert == (user_service->msg_remove + MSG_QUEUE_SIZE)) { - spin_unlock(&msg_queue_spinlock); + spin_unlock(&service->state->msg_queue_spinlock); DEBUG_TRACE(SERVICE_CALLBACK_LINE); DEBUG_COUNT(MSG_QUEUE_FULL_COUNT); dev_dbg(service->state->dev, "arm: msg queue full\n"); @@ -1133,7 +1164,7 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, return -EINVAL; } DEBUG_TRACE(SERVICE_CALLBACK_LINE); - spin_lock(&msg_queue_spinlock); + spin_lock(&service->state->msg_queue_spinlock); } user_service->msg_queue[user_service->msg_insert & @@ -1152,7 +1183,7 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, skip_completion = true; } - spin_unlock(&msg_queue_spinlock); + spin_unlock(&service->state->msg_queue_spinlock); complete(&user_service->insert_event); header = NULL; @@ -1167,9 +1198,8 @@ service_callback(struct vchiq_instance *instance, enum vchiq_reason reason, bulk_userdata); } -void vchiq_dump_platform_instances(struct seq_file *f) +void vchiq_dump_platform_instances(struct vchiq_state *state, struct seq_file *f) { - struct vchiq_state *state = vchiq_get_state(); int i; if (!state) @@ -1244,23 +1274,6 @@ void vchiq_dump_platform_service_state(struct seq_file *f, seq_puts(f, "\n"); } -struct vchiq_state * -vchiq_get_state(void) -{ - if (!g_state.remote) { - pr_err("%s: g_state.remote == NULL\n", __func__); - return NULL; - } - - if (g_state.remote->initialised != 1) { - pr_notice("%s: g_state.remote->initialised != 1 (%d)\n", - __func__, g_state.remote->initialised); - return NULL; - } - - return &g_state; -} - /* * Autosuspend related functionality */ @@ -1294,7 +1307,7 @@ vchiq_keepalive_thread_func(void *v) .version_min = KEEPALIVE_VER_MIN }; - ret = vchiq_initialise(&instance); + ret = vchiq_initialise(state, &instance); if (ret) { dev_err(state->dev, "suspend: %s: vchiq_initialise failed %d\n", __func__, ret); goto exit; @@ -1317,7 +1330,7 @@ vchiq_keepalive_thread_func(void *v) long rc = 0, uc = 0; if (wait_for_completion_interruptible(&arm_state->ka_evt)) { - dev_err(state->dev, "suspend: %s: interrupted\n", __func__); + dev_dbg(state->dev, "suspend: %s: interrupted\n", __func__); flush_signals(current); continue; } @@ -1706,8 +1719,8 @@ void vchiq_platform_conn_state_changed(struct vchiq_state *state, } static const struct of_device_id vchiq_of_match[] = { - { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata }, - { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata }, + { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_info }, + { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_info }, {}, }; MODULE_DEVICE_TABLE(of, vchiq_of_match); @@ -1715,13 +1728,12 @@ MODULE_DEVICE_TABLE(of, vchiq_of_match); static int vchiq_probe(struct platform_device *pdev) { struct device_node *fw_node; - const struct of_device_id *of_id; - struct vchiq_drvdata *drvdata; + const struct vchiq_platform_info *info; + struct vchiq_drv_mgmt *mgmt; int err; - of_id = of_match_node(vchiq_of_match, pdev->dev.of_node); - drvdata = (struct vchiq_drvdata *)of_id->data; - if (!drvdata) + info = of_device_get_match_data(&pdev->dev); + if (!info) return -EINVAL; fw_node = of_find_compatible_node(NULL, NULL, @@ -1731,14 +1743,19 @@ static int vchiq_probe(struct platform_device *pdev) return -ENOENT; } - drvdata->fw = devm_rpi_firmware_get(&pdev->dev, fw_node); + mgmt = kzalloc(sizeof(*mgmt), GFP_KERNEL); + if (!mgmt) + return -ENOMEM; + + mgmt->fw = devm_rpi_firmware_get(&pdev->dev, fw_node); of_node_put(fw_node); - if (!drvdata->fw) + if (!mgmt->fw) return -EPROBE_DEFER; - platform_set_drvdata(pdev, drvdata); + mgmt->info = info; + platform_set_drvdata(pdev, mgmt); - err = vchiq_platform_init(pdev, &g_state); + err = vchiq_platform_init(pdev, &mgmt->state); if (err) goto failed_platform_init; @@ -1753,7 +1770,7 @@ static int vchiq_probe(struct platform_device *pdev) */ err = vchiq_register_chrdev(&pdev->dev); if (err) { - dev_warn(&pdev->dev, "arm: Failed to initialize vchiq cdev\n"); + dev_err(&pdev->dev, "arm: Failed to initialize vchiq cdev\n"); goto error_exit; } @@ -1763,17 +1780,21 @@ static int vchiq_probe(struct platform_device *pdev) return 0; failed_platform_init: - dev_warn(&pdev->dev, "arm: Could not initialize vchiq platform\n"); + dev_err(&pdev->dev, "arm: Could not initialize vchiq platform\n"); error_exit: return err; } static void vchiq_remove(struct platform_device *pdev) { + struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(&pdev->dev); + vchiq_device_unregister(bcm2835_audio); vchiq_device_unregister(bcm2835_camera); vchiq_debugfs_deinit(); vchiq_deregister_chrdev(); + + kfree(mgmt); } static struct platform_driver vchiq_driver = { diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h index 7844ef765a00..fd1b9d3555ce 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h @@ -20,11 +20,42 @@ #define MAX_ELEMENTS 8 #define MSG_QUEUE_SIZE 128 +#define VCHIQ_DRV_MAX_CALLBACKS 10 + +struct rpi_firmware; +struct vchiq_device; + enum USE_TYPE_E { USE_TYPE_SERVICE, USE_TYPE_VCHIQ }; +struct vchiq_platform_info { + unsigned int cache_line_size; +}; + +struct vchiq_drv_mgmt { + struct rpi_firmware *fw; + const struct vchiq_platform_info *info; + + bool connected; + int num_deferred_callbacks; + /* Protects connected and num_deferred_callbacks */ + struct mutex connected_mutex; + + void (*deferred_callback[VCHIQ_DRV_MAX_CALLBACKS])(void); + + struct semaphore free_fragments_sema; + struct semaphore free_fragments_mutex; + char *fragments_base; + char *free_fragments; + unsigned int fragments_size; + + void __iomem *regs; + + struct vchiq_state state; +}; + struct user_service { struct vchiq_service *service; void __user *userdata; @@ -69,12 +100,6 @@ struct vchiq_instance { struct vchiq_debugfs_node debugfs_node; }; -extern spinlock_t msg_queue_spinlock; -extern struct vchiq_state g_state; - -extern struct vchiq_state * -vchiq_get_state(void); - int vchiq_use_service(struct vchiq_instance *instance, unsigned int handle); @@ -112,6 +137,10 @@ vchiq_instance_get_trace(struct vchiq_instance *instance); extern void vchiq_instance_set_trace(struct vchiq_instance *instance, int trace); +extern void +vchiq_add_connected_callback(struct vchiq_device *device, + void (*callback)(void)); + #if IS_ENABLED(CONFIG_VCHIQ_CDEV) extern void diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c index 68f830d75531..3f87b93c6537 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.c @@ -11,6 +11,7 @@ #include <linux/slab.h> #include <linux/string.h> +#include "vchiq_arm.h" #include "vchiq_bus.h" static int vchiq_bus_type_match(struct device *dev, struct device_driver *drv) @@ -37,11 +38,21 @@ static int vchiq_bus_probe(struct device *dev) return driver->probe(device); } +static void vchiq_bus_remove(struct device *dev) +{ + struct vchiq_device *device = to_vchiq_device(dev); + struct vchiq_driver *driver = to_vchiq_driver(dev->driver); + + if (driver->remove) + driver->remove(device); +} + const struct bus_type vchiq_bus_type = { .name = "vchiq-bus", .match = vchiq_bus_type_match, .uevent = vchiq_bus_uevent, .probe = vchiq_bus_probe, + .remove = vchiq_bus_remove, }; static void vchiq_device_release(struct device *dev) @@ -67,6 +78,8 @@ vchiq_device_register(struct device *parent, const char *name) device->dev.dma_mask = &device->dev.coherent_dma_mask; device->dev.release = vchiq_device_release; + device->drv_mgmt = dev_get_drvdata(parent); + of_dma_configure(&device->dev, parent->of_node, true); ret = device_register(&device->dev); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h index 4db86e76edbd..9de179b39f85 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_bus.h @@ -9,8 +9,11 @@ #include <linux/device.h> #include <linux/mod_devicetable.h> +struct vchiq_drv_mgmt; + struct vchiq_device { struct device dev; + struct vchiq_drv_mgmt *drv_mgmt; }; struct vchiq_driver { diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c deleted file mode 100644 index 3cad13f09e37..000000000000 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.c +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause -/* Copyright (c) 2010-2012 Broadcom. All rights reserved. */ - -#include "vchiq_connected.h" -#include "vchiq_core.h" -#include <linux/module.h> -#include <linux/mutex.h> - -#define MAX_CALLBACKS 10 - -static int g_connected; -static int g_num_deferred_callbacks; -static void (*g_deferred_callback[MAX_CALLBACKS])(void); -static int g_once_init; -static DEFINE_MUTEX(g_connected_mutex); - -/* Function to initialize our lock */ -static void connected_init(void) -{ - if (!g_once_init) - g_once_init = 1; -} - -/* - * This function is used to defer initialization until the vchiq stack is - * initialized. If the stack is already initialized, then the callback will - * be made immediately, otherwise it will be deferred until - * vchiq_call_connected_callbacks is called. - */ -void vchiq_add_connected_callback(struct vchiq_device *device, void (*callback)(void)) -{ - connected_init(); - - if (mutex_lock_killable(&g_connected_mutex)) - return; - - if (g_connected) { - /* We're already connected. Call the callback immediately. */ - callback(); - } else { - if (g_num_deferred_callbacks >= MAX_CALLBACKS) { - dev_err(&device->dev, - "core: There already %d callback registered - please increase MAX_CALLBACKS\n", - g_num_deferred_callbacks); - } else { - g_deferred_callback[g_num_deferred_callbacks] = - callback; - g_num_deferred_callbacks++; - } - } - mutex_unlock(&g_connected_mutex); -} -EXPORT_SYMBOL(vchiq_add_connected_callback); - -/* - * This function is called by the vchiq stack once it has been connected to - * the videocore and clients can start to use the stack. - */ -void vchiq_call_connected_callbacks(void) -{ - int i; - - connected_init(); - - if (mutex_lock_killable(&g_connected_mutex)) - return; - - for (i = 0; i < g_num_deferred_callbacks; i++) - g_deferred_callback[i](); - - g_num_deferred_callbacks = 0; - g_connected = 1; - mutex_unlock(&g_connected_mutex); -} diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.h deleted file mode 100644 index e4ed56446f8a..000000000000 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_connected.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */ -/* Copyright (c) 2010-2012 Broadcom. All rights reserved. */ - -#include "vchiq_bus.h" - -#ifndef VCHIQ_CONNECTED_H -#define VCHIQ_CONNECTED_H - -void vchiq_add_connected_callback(struct vchiq_device *device, void (*callback)(void)); -void vchiq_call_connected_callbacks(void); - -#endif /* VCHIQ_CONNECTED_H */ diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c index 76c27778154a..df3af821f218 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c @@ -43,7 +43,7 @@ (((type) << TYPE_SHIFT) | ((srcport) << 12) | ((dstport) << 0)) #define VCHIQ_MSG_TYPE(msgid) ((unsigned int)(msgid) >> TYPE_SHIFT) #define VCHIQ_MSG_SRCPORT(msgid) \ - (unsigned short)(((unsigned int)(msgid) >> 12) & 0xfff) + ((unsigned short)(((unsigned int)(msgid) >> 12) & 0xfff)) #define VCHIQ_MSG_DSTPORT(msgid) \ ((unsigned short)(msgid) & 0xfff) @@ -149,9 +149,6 @@ static inline void check_sizes(void) BUILD_BUG_ON_NOT_POWER_OF_2(VCHIQ_MAX_SERVICES); } -DEFINE_SPINLOCK(bulk_waiter_spinlock); -static DEFINE_SPINLOCK(quota_spinlock); - static unsigned int handle_seq; static const char *const srvstate_names[] = { @@ -230,6 +227,7 @@ struct vchiq_service *handle_to_service(struct vchiq_instance *instance, unsigne return rcu_dereference(instance->state->services[idx]); } + struct vchiq_service * find_service_by_handle(struct vchiq_instance *instance, unsigned int handle) { @@ -691,7 +689,7 @@ reserve_space(struct vchiq_state *state, size_t space, int is_blocking) /* But first, flush through the last slot. */ state->local_tx_pos = tx_pos; local->tx_pos = tx_pos; - remote_event_signal(&state->remote->trigger); + remote_event_signal(state, &state->remote->trigger); if (!is_blocking || (wait_for_completion_interruptible(&state->slot_available_event))) @@ -700,7 +698,8 @@ reserve_space(struct vchiq_state *state, size_t space, int is_blocking) if (tx_pos == (state->slot_queue_available * VCHIQ_SLOT_SIZE)) { complete(&state->slot_available_event); - pr_warn("%s: invalid tx_pos: %d\n", __func__, tx_pos); + dev_warn(state->dev, "%s: invalid tx_pos: %d\n", + __func__, tx_pos); return NULL; } @@ -724,11 +723,11 @@ process_free_data_message(struct vchiq_state *state, u32 *service_found, struct vchiq_service_quota *quota = &state->service_quotas[port]; int count; - spin_lock("a_spinlock); + spin_lock(&state->quota_spinlock); count = quota->message_use_count; if (count > 0) quota->message_use_count = count - 1; - spin_unlock("a_spinlock); + spin_unlock(&state->quota_spinlock); if (count == quota->message_quota) { /* @@ -747,11 +746,11 @@ process_free_data_message(struct vchiq_state *state, u32 *service_found, /* Set the found bit for this service */ BITSET_SET(service_found, port); - spin_lock("a_spinlock); + spin_lock(&state->quota_spinlock); count = quota->slot_use_count; if (count > 0) quota->slot_use_count = count - 1; - spin_unlock("a_spinlock); + spin_unlock(&state->quota_spinlock); if (count > 0) { /* @@ -837,11 +836,11 @@ process_free_queue(struct vchiq_state *state, u32 *service_found, if (data_found) { int count; - spin_lock("a_spinlock); + spin_lock(&state->quota_spinlock); count = state->data_use_count; if (count > 0) state->data_use_count = count - 1; - spin_unlock("a_spinlock); + spin_unlock(&state->quota_spinlock); if (count == state->data_quota) complete(&state->data_quota_event); } @@ -940,7 +939,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, quota = &state->service_quotas[service->localport]; - spin_lock("a_spinlock); + spin_lock(&state->quota_spinlock); /* * Ensure this service doesn't use more than its quota of @@ -955,14 +954,14 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, while ((tx_end_index != state->previous_data_index) && (state->data_use_count == state->data_quota)) { VCHIQ_STATS_INC(state, data_stalls); - spin_unlock("a_spinlock); + spin_unlock(&state->quota_spinlock); mutex_unlock(&state->slot_mutex); if (wait_for_completion_interruptible(&state->data_quota_event)) return -EAGAIN; mutex_lock(&state->slot_mutex); - spin_lock("a_spinlock); + spin_lock(&state->quota_spinlock); tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos + stride - 1); if ((tx_end_index == state->previous_data_index) || (state->data_use_count < state->data_quota)) { @@ -975,7 +974,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, while ((quota->message_use_count == quota->message_quota) || ((tx_end_index != quota->previous_tx_index) && (quota->slot_use_count == quota->slot_quota))) { - spin_unlock("a_spinlock); + spin_unlock(&state->quota_spinlock); dev_dbg(state->dev, "core: %d: qm:%d %s,%zx - quota stall (msg %d, slot %d)\n", state->id, service->localport, msg_type_str(type), size, @@ -993,11 +992,11 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, mutex_unlock(&state->slot_mutex); return -EHOSTDOWN; } - spin_lock("a_spinlock); + spin_lock(&state->quota_spinlock); tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos + stride - 1); } - spin_unlock("a_spinlock); + spin_unlock(&state->quota_spinlock); } header = reserve_space(state, stride, flags & QMFLAGS_IS_BLOCKING); @@ -1040,7 +1039,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, header->data, min_t(size_t, 16, callback_result)); - spin_lock("a_spinlock); + spin_lock(&state->quota_spinlock); quota->message_use_count++; tx_end_index = @@ -1066,7 +1065,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, slot_use_count = 0; } - spin_unlock("a_spinlock); + spin_unlock(&state->quota_spinlock); if (slot_use_count) dev_dbg(state->dev, "core: %d: qm:%d %s,%zx - slot_use->%d (hdr %p)\n", @@ -1124,7 +1123,7 @@ queue_message(struct vchiq_state *state, struct vchiq_service *service, if (!(flags & QMFLAGS_NO_MUTEX_UNLOCK)) mutex_unlock(&state->slot_mutex); - remote_event_signal(&state->remote->trigger); + remote_event_signal(state, &state->remote->trigger); return 0; } @@ -1192,7 +1191,6 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service, header->size = size; header->msgid = msgid; - svc_fourcc = service ? service->base.fourcc : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); @@ -1202,7 +1200,7 @@ queue_message_sync(struct vchiq_state *state, struct vchiq_service *service, &svc_fourcc, VCHIQ_MSG_SRCPORT(msgid), VCHIQ_MSG_DSTPORT(msgid), size); - remote_event_signal(&state->remote->sync_trigger); + remote_event_signal(state, &state->remote->sync_trigger); if (VCHIQ_MSG_TYPE(msgid) != VCHIQ_MSG_PAUSE) mutex_unlock(&state->sync_mutex); @@ -1260,7 +1258,7 @@ release_slot(struct vchiq_state *state, struct vchiq_slot_info *slot_info, * A write barrier is necessary, but remote_event_signal * contains one. */ - remote_event_signal(&state->remote->recycle); + remote_event_signal(state, &state->remote->recycle); } mutex_unlock(&state->recycle_mutex); @@ -1322,13 +1320,13 @@ notify_bulks(struct vchiq_service *service, struct vchiq_bulk_queue *queue, if (bulk->mode == VCHIQ_BULK_MODE_BLOCKING) { struct bulk_waiter *waiter; - spin_lock(&bulk_waiter_spinlock); + spin_lock(&service->state->bulk_waiter_spinlock); waiter = bulk->userdata; if (waiter) { waiter->actual = bulk->actual; complete(&waiter->event); } - spin_unlock(&bulk_waiter_spinlock); + spin_unlock(&service->state->bulk_waiter_spinlock); } else if (bulk->mode == VCHIQ_BULK_MODE_CALLBACK) { enum vchiq_reason reason = get_bulk_reason(bulk); @@ -1618,7 +1616,6 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) break; } - svc_fourcc = service ? service->base.fourcc : VCHIQ_MAKE_FOURCC('?', '?', '?', '?'); @@ -1735,10 +1732,9 @@ parse_message(struct vchiq_state *state, struct vchiq_header *header) break; } if (queue->process != queue->remote_insert) { - pr_err("%s: p %x != ri %x\n", - __func__, - queue->process, - queue->remote_insert); + dev_err(state->dev, "%s: p %x != ri %x\n", + __func__, queue->process, + queue->remote_insert); mutex_unlock(&service->bulk_mutex); goto bail_not_ready; } @@ -2169,6 +2165,10 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, s mutex_init(&state->sync_mutex); mutex_init(&state->bulk_transfer_mutex); + spin_lock_init(&state->msg_queue_spinlock); + spin_lock_init(&state->bulk_waiter_spinlock); + spin_lock_init(&state->quota_spinlock); + init_completion(&state->slot_available_event); init_completion(&state->slot_remove_event); init_completion(&state->data_quota_event); @@ -2177,6 +2177,7 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero, s for (i = 0; i < VCHIQ_MAX_SERVICES; i++) { struct vchiq_service_quota *quota = &state->service_quotas[i]; + init_completion("a->quota_event); } @@ -3240,7 +3241,7 @@ static void release_message_sync(struct vchiq_state *state, struct vchiq_header *header) { header->msgid = VCHIQ_MSGID_PADDING; - remote_event_signal(&state->remote->sync_release); + remote_event_signal(state, &state->remote->sync_release); } int @@ -3504,7 +3505,7 @@ void vchiq_dump_state(struct seq_file *f, struct vchiq_state *state) vchiq_dump_shared_state(f, state, state->remote, "Remote"); - vchiq_dump_platform_instances(f); + vchiq_dump_platform_instances(state, f); for (i = 0; i < state->unused_service; i++) { struct vchiq_service *service = find_service_by_port(state, i); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h index c8527551b58c..8af209e34fb2 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h @@ -11,6 +11,7 @@ #include <linux/kthread.h> #include <linux/kref.h> #include <linux/rcupdate.h> +#include <linux/spinlock_types.h> #include <linux/wait.h> #include "../../include/linux/raspberrypi/vchiq.h" @@ -348,6 +349,12 @@ struct vchiq_state { struct mutex bulk_transfer_mutex; + spinlock_t msg_queue_spinlock; + + spinlock_t bulk_waiter_spinlock; + + spinlock_t quota_spinlock; + /* * Indicates the byte position within the stream from where the next * message will be read. The least significant bits are an index into @@ -471,12 +478,6 @@ extern void vchiq_dump_state(struct seq_file *f, struct vchiq_state *state); extern void -vchiq_loud_error_header(void); - -extern void -vchiq_loud_error_footer(void); - -extern void request_poll(struct vchiq_state *state, struct vchiq_service *service, int poll_type); @@ -522,11 +523,11 @@ int vchiq_prepare_bulk_data(struct vchiq_instance *instance, struct vchiq_bulk * void vchiq_complete_bulk(struct vchiq_instance *instance, struct vchiq_bulk *bulk); -void remote_event_signal(struct remote_event *event); +void remote_event_signal(struct vchiq_state *state, struct remote_event *event); void vchiq_dump_platform_state(struct seq_file *f); -void vchiq_dump_platform_instances(struct seq_file *f); +void vchiq_dump_platform_instances(struct vchiq_state *state, struct seq_file *f); void vchiq_dump_platform_service_state(struct seq_file *f, struct vchiq_service *service); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c index d833e4e2973a..54e7bf029d9a 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_debugfs.c @@ -42,7 +42,10 @@ static int debugfs_trace_show(struct seq_file *f, void *offset) static int vchiq_dump_show(struct seq_file *f, void *offset) { - vchiq_dump_state(f, &g_state); + struct vchiq_instance *instance = f->private; + + vchiq_dump_state(f, instance->state); + return 0; } DEFINE_SHOW_ATTRIBUTE(vchiq_dump); diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c index 4d9deeeb637a..3c63347d2d08 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_dev.c @@ -208,7 +208,7 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance, struct vchiq_header *header; int ret; - DEBUG_INITIALISE(g_state.local); + DEBUG_INITIALISE(instance->state->local); DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); service = find_service_for_instance(instance, args->handle); if (!service) @@ -220,10 +220,10 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance, goto out; } - spin_lock(&msg_queue_spinlock); + spin_lock(&service->state->msg_queue_spinlock); if (user_service->msg_remove == user_service->msg_insert) { if (!args->blocking) { - spin_unlock(&msg_queue_spinlock); + spin_unlock(&service->state->msg_queue_spinlock); DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); ret = -EWOULDBLOCK; goto out; @@ -231,14 +231,14 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance, user_service->dequeue_pending = 1; ret = 0; do { - spin_unlock(&msg_queue_spinlock); + spin_unlock(&service->state->msg_queue_spinlock); DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); if (wait_for_completion_interruptible(&user_service->insert_event)) { dev_dbg(service->state->dev, "arm: DEQUEUE_MESSAGE interrupted\n"); ret = -EINTR; break; } - spin_lock(&msg_queue_spinlock); + spin_lock(&service->state->msg_queue_spinlock); } while (user_service->msg_remove == user_service->msg_insert); if (ret) @@ -247,7 +247,7 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance, if (WARN_ON_ONCE((int)(user_service->msg_insert - user_service->msg_remove) < 0)) { - spin_unlock(&msg_queue_spinlock); + spin_unlock(&service->state->msg_queue_spinlock); ret = -EINVAL; goto out; } @@ -255,7 +255,7 @@ static int vchiq_ioc_dequeue_message(struct vchiq_instance *instance, header = user_service->msg_queue[user_service->msg_remove & (MSG_QUEUE_SIZE - 1)]; user_service->msg_remove++; - spin_unlock(&msg_queue_spinlock); + spin_unlock(&service->state->msg_queue_spinlock); complete(&user_service->remove_event); if (!header) { @@ -340,9 +340,9 @@ static int vchiq_irq_queue_bulk_tx_rx(struct vchiq_instance *instance, !waiter->bulk_waiter.bulk) { if (waiter->bulk_waiter.bulk) { /* Cancel the signal when the transfer completes. */ - spin_lock(&bulk_waiter_spinlock); + spin_lock(&service->state->bulk_waiter_spinlock); waiter->bulk_waiter.bulk->userdata = NULL; - spin_unlock(&bulk_waiter_spinlock); + spin_unlock(&service->state->bulk_waiter_spinlock); } kfree(waiter); ret = 0; @@ -435,7 +435,7 @@ static int vchiq_ioc_await_completion(struct vchiq_instance *instance, int remove; int ret; - DEBUG_INITIALISE(g_state.local); + DEBUG_INITIALISE(instance->state->local); DEBUG_TRACE(AWAIT_COMPLETION_LINE); if (!instance->connected) @@ -1163,16 +1163,13 @@ vchiq_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) static int vchiq_open(struct inode *inode, struct file *file) { - struct vchiq_state *state = vchiq_get_state(); + struct miscdevice *vchiq_miscdev = file->private_data; + struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(vchiq_miscdev->parent); + struct vchiq_state *state = &mgmt->state; struct vchiq_instance *instance; dev_dbg(state->dev, "arm: vchiq open\n"); - if (!state) { - dev_err(state->dev, "arm: vchiq has no connection to VideoCore\n"); - return -ENOTCONN; - } - instance = kzalloc(sizeof(*instance), GFP_KERNEL); if (!instance) return -ENOMEM; @@ -1196,7 +1193,7 @@ static int vchiq_open(struct inode *inode, struct file *file) static int vchiq_release(struct inode *inode, struct file *file) { struct vchiq_instance *instance = file->private_data; - struct vchiq_state *state = vchiq_get_state(); + struct vchiq_state *state = instance->state; struct vchiq_service *service; int ret = 0; int i; @@ -1246,7 +1243,7 @@ static int vchiq_release(struct inode *inode, struct file *file) break; } - spin_lock(&msg_queue_spinlock); + spin_lock(&service->state->msg_queue_spinlock); while (user_service->msg_remove != user_service->msg_insert) { struct vchiq_header *header; @@ -1254,14 +1251,14 @@ static int vchiq_release(struct inode *inode, struct file *file) header = user_service->msg_queue[m]; user_service->msg_remove++; - spin_unlock(&msg_queue_spinlock); + spin_unlock(&service->state->msg_queue_spinlock); if (header) vchiq_release_message(instance, service->handle, header); - spin_lock(&msg_queue_spinlock); + spin_lock(&service->state->msg_queue_spinlock); } - spin_unlock(&msg_queue_spinlock); + spin_unlock(&service->state->msg_queue_spinlock); vchiq_service_put(service); } diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c index 4c3684dd902e..fca920d41e4f 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.c @@ -26,6 +26,7 @@ #include <media/videobuf2-vmalloc.h> #include "../include/linux/raspberrypi/vchiq.h" +#include "../interface/vchiq_arm/vchiq_arm.h" #include "mmal-common.h" #include "mmal-vchiq.h" #include "mmal-msg.h" @@ -548,9 +549,9 @@ static void bulk_abort_cb(struct vchiq_mmal_instance *instance, } /* incoming event service callback */ -static int service_callback(struct vchiq_instance *vchiq_instance, - enum vchiq_reason reason, struct vchiq_header *header, - unsigned int handle, void *bulk_ctx) +static int mmal_service_callback(struct vchiq_instance *vchiq_instance, + enum vchiq_reason reason, struct vchiq_header *header, + unsigned int handle, void *bulk_ctx) { struct vchiq_mmal_instance *instance = vchiq_get_service_userdata(vchiq_instance, handle); u32 msg_len; @@ -1852,7 +1853,7 @@ int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance) } EXPORT_SYMBOL_GPL(vchiq_mmal_finalise); -int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) +int vchiq_mmal_init(struct device *dev, struct vchiq_mmal_instance **out_instance) { int status; int err = -ENODEV; @@ -1862,9 +1863,10 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) .version = VC_MMAL_VER, .version_min = VC_MMAL_MIN_VER, .fourcc = VCHIQ_MAKE_FOURCC('m', 'm', 'a', 'l'), - .callback = service_callback, + .callback = mmal_service_callback, .userdata = NULL, }; + struct vchiq_drv_mgmt *mgmt = dev_get_drvdata(dev->parent); /* compile time checks to ensure structure size as they are * directly (de)serialised from memory. @@ -1880,7 +1882,7 @@ int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance) BUILD_BUG_ON(sizeof(struct mmal_port) != 64); /* create a vchi instance */ - status = vchiq_initialise(&vchiq_instance); + status = vchiq_initialise(&mgmt->state, &vchiq_instance); if (status) { pr_err("Failed to initialise VCHI instance (status=%d)\n", status); diff --git a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h index 09f030919d4e..97abe4bdcfc5 100644 --- a/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h +++ b/drivers/staging/vc04_services/vchiq-mmal/mmal-vchiq.h @@ -25,6 +25,7 @@ #define MMAL_FORMAT_EXTRADATA_MAX_SIZE 128 struct vchiq_mmal_instance; +struct device; enum vchiq_mmal_es_type { MMAL_ES_TYPE_UNKNOWN, /**< Unknown elementary stream type */ @@ -42,8 +43,7 @@ struct vchiq_mmal_port_buffer { struct vchiq_mmal_port; -typedef void (*vchiq_mmal_buffer_cb)( - struct vchiq_mmal_instance *instance, +typedef void (*vchiq_mmal_buffer_cb)(struct vchiq_mmal_instance *instance, struct vchiq_mmal_port *port, int status, struct mmal_buffer *buffer); @@ -95,37 +95,31 @@ struct vchiq_mmal_component { u32 client_component; /* Used to ref back to client struct */ }; -int vchiq_mmal_init(struct vchiq_mmal_instance **out_instance); +int vchiq_mmal_init(struct device *dev, struct vchiq_mmal_instance **out_instance); int vchiq_mmal_finalise(struct vchiq_mmal_instance *instance); /* Initialise a mmal component and its ports * */ -int vchiq_mmal_component_init( - struct vchiq_mmal_instance *instance, - const char *name, - struct vchiq_mmal_component **component_out); +int vchiq_mmal_component_init(struct vchiq_mmal_instance *instance, + const char *name, struct vchiq_mmal_component **component_out); -int vchiq_mmal_component_finalise( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component); +int vchiq_mmal_component_finalise(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component); -int vchiq_mmal_component_enable( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component); +int vchiq_mmal_component_enable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component); -int vchiq_mmal_component_disable( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_component *component); +int vchiq_mmal_component_disable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_component *component); /* enable a mmal port * * enables a port and if a buffer callback provided enque buffer * headers as appropriate for the port. */ -int vchiq_mmal_port_enable( - struct vchiq_mmal_instance *instance, - struct vchiq_mmal_port *port, +int vchiq_mmal_port_enable(struct vchiq_mmal_instance *instance, + struct vchiq_mmal_port *port, vchiq_mmal_buffer_cb buffer_cb); /* disable a port diff --git a/drivers/staging/vt6655/rf.h b/drivers/staging/vt6655/rf.h index 6f842ac00526..8eef100c7ef2 100644 --- a/drivers/staging/vt6655/rf.h +++ b/drivers/staging/vt6655/rf.h @@ -68,8 +68,4 @@ bool RFbRawSetPower(struct vnt_private *priv, unsigned char byPwr, void RFvRSSITodBm(struct vnt_private *priv, unsigned char byCurrRSSI, long *pldBm); -/* {{ RobertYu: 20050104 */ -bool RFbAL7230SelectChannelPostProcess(struct vnt_private *priv, u16 byOldChannel, u16 byNewChannel); -/* }} RobertYu */ - #endif /* __RF_H__ */ diff --git a/drivers/staging/vt6655/srom.c b/drivers/staging/vt6655/srom.c index 1b89d401a7eb..e80556509c58 100644 --- a/drivers/staging/vt6655/srom.c +++ b/drivers/staging/vt6655/srom.c @@ -64,7 +64,6 @@ unsigned char SROMbyReadEmbedded(void __iomem *iobase, unsigned char byData; unsigned char byOrg; - byData = 0xFF; byOrg = ioread8(iobase + MAC_REG_I2MCFG); /* turn off hardware retry for getting NACK */ iowrite8(byOrg & (~I2MCFG_NORETRY), iobase + MAC_REG_I2MCFG); diff --git a/drivers/staging/wlan-ng/Kconfig b/drivers/staging/wlan-ng/Kconfig deleted file mode 100644 index 082c16a31616..000000000000 --- a/drivers/staging/wlan-ng/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -config PRISM2_USB - tristate "Prism2.5/3 USB driver" - depends on WLAN && USB && CFG80211 - select WIRELESS_EXT - select WEXT_PRIV - select CRC32 - help - This is the wlan-ng prism 2.5/3 USB driver for a wide range of - old USB wireless devices. - - To compile this driver as a module, choose M here: the module - will be called prism2_usb. diff --git a/drivers/staging/wlan-ng/Makefile b/drivers/staging/wlan-ng/Makefile deleted file mode 100644 index 1d24b0f86eee..000000000000 --- a/drivers/staging/wlan-ng/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_PRISM2_USB) += prism2_usb.o - -prism2_usb-y := prism2usb.o \ - p80211conv.o \ - p80211req.o \ - p80211wep.o \ - p80211netdev.o diff --git a/drivers/staging/wlan-ng/README b/drivers/staging/wlan-ng/README deleted file mode 100644 index d0621f827c01..000000000000 --- a/drivers/staging/wlan-ng/README +++ /dev/null @@ -1,8 +0,0 @@ -TODO: - - checkpatch.pl cleanups - - sparse warnings - - move to use the in-kernel wireless stack - -Please send any patches or complaints about this driver to Greg -Kroah-Hartman <greg@kroah.com> and don't bother the upstream wireless -kernel developers about it, they want nothing to do with it. diff --git a/drivers/staging/wlan-ng/TODO b/drivers/staging/wlan-ng/TODO deleted file mode 100644 index ab9d5d145b3b..000000000000 --- a/drivers/staging/wlan-ng/TODO +++ /dev/null @@ -1,16 +0,0 @@ -To-do list: - -* Correct the coding style according to Linux guidelines; please read the document - at https://www.kernel.org/doc/html/latest/process/coding-style.html. -* Remove unnecessary debugging/printing macros; for those that are still needed - use the proper kernel API (pr_debug(), dev_dbg(), netdev_dbg()). -* Remove dead code such as unusued functions, variables, fields, etc.. -* Use in-kernel API and remove unnecessary wrappers where possible. -* Fix bugs due to code that sleeps in atomic context. -* Remove the HAL layer and migrate its functionality into the relevant parts of - the driver. -* Switch to use LIB80211. -* Switch to use MAC80211. -* Switch to use CFG80211. -* Improve the error handling of various functions, particularly those that use - existing kernel APIs. diff --git a/drivers/staging/wlan-ng/cfg80211.c b/drivers/staging/wlan-ng/cfg80211.c deleted file mode 100644 index 471bb310176f..000000000000 --- a/drivers/staging/wlan-ng/cfg80211.c +++ /dev/null @@ -1,718 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* cfg80211 Interface for prism2_usb module */ -#include "hfa384x.h" -#include "prism2mgmt.h" - -/* Prism2 channel/frequency/bitrate declarations */ -static const struct ieee80211_channel prism2_channels[] = { - { .center_freq = 2412 }, - { .center_freq = 2417 }, - { .center_freq = 2422 }, - { .center_freq = 2427 }, - { .center_freq = 2432 }, - { .center_freq = 2437 }, - { .center_freq = 2442 }, - { .center_freq = 2447 }, - { .center_freq = 2452 }, - { .center_freq = 2457 }, - { .center_freq = 2462 }, - { .center_freq = 2467 }, - { .center_freq = 2472 }, - { .center_freq = 2484 }, -}; - -static const struct ieee80211_rate prism2_rates[] = { - { .bitrate = 10 }, - { .bitrate = 20 }, - { .bitrate = 55 }, - { .bitrate = 110 } -}; - -#define PRISM2_NUM_CIPHER_SUITES 2 -static const u32 prism2_cipher_suites[PRISM2_NUM_CIPHER_SUITES] = { - WLAN_CIPHER_SUITE_WEP40, - WLAN_CIPHER_SUITE_WEP104 -}; - -/* prism2 device private data */ -struct prism2_wiphy_private { - struct wlandevice *wlandev; - - struct ieee80211_supported_band band; - struct ieee80211_channel channels[ARRAY_SIZE(prism2_channels)]; - struct ieee80211_rate rates[ARRAY_SIZE(prism2_rates)]; - - struct cfg80211_scan_request *scan_request; -}; - -static const void * const prism2_wiphy_privid = &prism2_wiphy_privid; - -/* Helper Functions */ -static int prism2_result2err(int prism2_result) -{ - int err = 0; - - switch (prism2_result) { - case P80211ENUM_resultcode_invalid_parameters: - err = -EINVAL; - break; - case P80211ENUM_resultcode_implementation_failure: - err = -EIO; - break; - case P80211ENUM_resultcode_not_supported: - err = -EOPNOTSUPP; - break; - default: - err = 0; - break; - } - - return err; -} - -static int prism2_domibset_uint32(struct wlandevice *wlandev, - u32 did, u32 data) -{ - struct p80211msg_dot11req_mibset msg; - struct p80211item_uint32 *mibitem = - (struct p80211item_uint32 *)&msg.mibattribute.data; - - msg.msgcode = DIDMSG_DOT11REQ_MIBSET; - mibitem->did = did; - mibitem->data = data; - - return p80211req_dorequest(wlandev, (u8 *)&msg); -} - -static int prism2_domibset_pstr32(struct wlandevice *wlandev, - u32 did, u8 len, const u8 *data) -{ - struct p80211msg_dot11req_mibset msg; - struct p80211item_pstr32 *mibitem = - (struct p80211item_pstr32 *)&msg.mibattribute.data; - - msg.msgcode = DIDMSG_DOT11REQ_MIBSET; - mibitem->did = did; - mibitem->data.len = len; - memcpy(mibitem->data.data, data, len); - - return p80211req_dorequest(wlandev, (u8 *)&msg); -} - -/* The interface functions, called by the cfg80211 layer */ -static int prism2_change_virtual_intf(struct wiphy *wiphy, - struct net_device *dev, - enum nl80211_iftype type, - struct vif_params *params) -{ - struct wlandevice *wlandev = dev->ml_priv; - u32 data; - int result; - int err = 0; - - switch (type) { - case NL80211_IFTYPE_ADHOC: - if (wlandev->macmode == WLAN_MACMODE_IBSS_STA) - goto exit; - wlandev->macmode = WLAN_MACMODE_IBSS_STA; - data = 0; - break; - case NL80211_IFTYPE_STATION: - if (wlandev->macmode == WLAN_MACMODE_ESS_STA) - goto exit; - wlandev->macmode = WLAN_MACMODE_ESS_STA; - data = 1; - break; - default: - netdev_warn(dev, "Operation mode: %d not support\n", type); - return -EOPNOTSUPP; - } - - /* Set Operation mode to the PORT TYPE RID */ - result = prism2_domibset_uint32(wlandev, - DIDMIB_P2_STATIC_CNFPORTTYPE, - data); - - if (result) - err = -EFAULT; - - dev->ieee80211_ptr->iftype = type; - -exit: - return err; -} - -static int prism2_add_key(struct wiphy *wiphy, struct net_device *dev, - int link_id, u8 key_index, bool pairwise, - const u8 *mac_addr, struct key_params *params) -{ - struct wlandevice *wlandev = dev->ml_priv; - u32 did; - - if (key_index >= NUM_WEPKEYS) - return -EINVAL; - - if (params->cipher != WLAN_CIPHER_SUITE_WEP40 && - params->cipher != WLAN_CIPHER_SUITE_WEP104) { - pr_debug("Unsupported cipher suite\n"); - return -EFAULT; - } - - if (prism2_domibset_uint32(wlandev, - DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID, - key_index)) - return -EFAULT; - - /* send key to driver */ - did = didmib_dot11smt_wepdefaultkeystable_key(key_index + 1); - - if (prism2_domibset_pstr32(wlandev, did, params->key_len, params->key)) - return -EFAULT; - return 0; -} - -static int prism2_get_key(struct wiphy *wiphy, struct net_device *dev, - int link_id, u8 key_index, bool pairwise, - const u8 *mac_addr, void *cookie, - void (*callback)(void *cookie, struct key_params*)) -{ - struct wlandevice *wlandev = dev->ml_priv; - struct key_params params; - int len; - - if (key_index >= NUM_WEPKEYS) - return -EINVAL; - - len = wlandev->wep_keylens[key_index]; - memset(¶ms, 0, sizeof(params)); - - if (len == 13) - params.cipher = WLAN_CIPHER_SUITE_WEP104; - else if (len == 5) - params.cipher = WLAN_CIPHER_SUITE_WEP104; - else - return -ENOENT; - params.key_len = len; - params.key = wlandev->wep_keys[key_index]; - params.seq_len = 0; - - callback(cookie, ¶ms); - - return 0; -} - -static int prism2_del_key(struct wiphy *wiphy, struct net_device *dev, - int link_id, u8 key_index, bool pairwise, - const u8 *mac_addr) -{ - struct wlandevice *wlandev = dev->ml_priv; - u32 did; - int err = 0; - int result = 0; - - /* There is no direct way in the hardware (AFAIK) of removing - * a key, so we will cheat by setting the key to a bogus value - */ - - if (key_index >= NUM_WEPKEYS) - return -EINVAL; - - /* send key to driver */ - did = didmib_dot11smt_wepdefaultkeystable_key(key_index + 1); - result = prism2_domibset_pstr32(wlandev, did, 13, "0000000000000"); - - if (result) - err = -EFAULT; - - return err; -} - -static int prism2_set_default_key(struct wiphy *wiphy, struct net_device *dev, - int link_id, u8 key_index, bool unicast, - bool multicast) -{ - struct wlandevice *wlandev = dev->ml_priv; - - return prism2_domibset_uint32(wlandev, - DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID, - key_index); -} - -static int prism2_get_station(struct wiphy *wiphy, struct net_device *dev, - const u8 *mac, struct station_info *sinfo) -{ - struct wlandevice *wlandev = dev->ml_priv; - struct p80211msg_lnxreq_commsquality quality; - int result; - - memset(sinfo, 0, sizeof(*sinfo)); - - if (!wlandev || (wlandev->msdstate != WLAN_MSD_RUNNING)) - return -EOPNOTSUPP; - - /* build request message */ - quality.msgcode = DIDMSG_LNXREQ_COMMSQUALITY; - quality.dbm.data = P80211ENUM_truth_true; - quality.dbm.status = P80211ENUM_msgitem_status_data_ok; - - /* send message to nsd */ - if (!wlandev->mlmerequest) - return -EOPNOTSUPP; - - result = wlandev->mlmerequest(wlandev, (struct p80211msg *)&quality); - - if (result == 0) { - sinfo->txrate.legacy = quality.txrate.data; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); - sinfo->signal = quality.level.data; - sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL); - } - - return result; -} - -static int prism2_scan(struct wiphy *wiphy, - struct cfg80211_scan_request *request) -{ - struct net_device *dev; - struct prism2_wiphy_private *priv = wiphy_priv(wiphy); - struct wlandevice *wlandev; - struct p80211msg_dot11req_scan msg1; - struct p80211msg_dot11req_scan_results *msg2; - struct cfg80211_bss *bss; - struct cfg80211_scan_info info = {}; - - int result; - int err = 0; - int numbss = 0; - int i = 0; - u8 ie_buf[46]; - int ie_len; - - if (!request) - return -EINVAL; - - dev = request->wdev->netdev; - wlandev = dev->ml_priv; - - if (priv->scan_request && priv->scan_request != request) - return -EBUSY; - - if (wlandev->macmode == WLAN_MACMODE_ESS_AP) { - netdev_err(dev, "Can't scan in AP mode\n"); - return -EOPNOTSUPP; - } - - msg2 = kzalloc(sizeof(*msg2), GFP_KERNEL); - if (!msg2) - return -ENOMEM; - - priv->scan_request = request; - - memset(&msg1, 0x00, sizeof(msg1)); - msg1.msgcode = DIDMSG_DOT11REQ_SCAN; - msg1.bsstype.data = P80211ENUM_bsstype_any; - - memset(&msg1.bssid.data.data, 0xFF, sizeof(msg1.bssid.data.data)); - msg1.bssid.data.len = 6; - - if (request->n_ssids > 0) { - msg1.scantype.data = P80211ENUM_scantype_active; - msg1.ssid.data.len = request->ssids->ssid_len; - memcpy(msg1.ssid.data.data, - request->ssids->ssid, request->ssids->ssid_len); - } else { - msg1.scantype.data = 0; - } - msg1.probedelay.data = 0; - - for (i = 0; - (i < request->n_channels) && i < ARRAY_SIZE(prism2_channels); - i++) - msg1.channellist.data.data[i] = - ieee80211_frequency_to_channel(request->channels[i]->center_freq); - msg1.channellist.data.len = request->n_channels; - - msg1.maxchanneltime.data = 250; - msg1.minchanneltime.data = 200; - - result = p80211req_dorequest(wlandev, (u8 *)&msg1); - if (result) { - err = prism2_result2err(msg1.resultcode.data); - goto exit; - } - /* Now retrieve scan results */ - numbss = msg1.numbss.data; - - for (i = 0; i < numbss; i++) { - int freq; - - msg2->msgcode = DIDMSG_DOT11REQ_SCAN_RESULTS; - msg2->bssindex.data = i; - - result = p80211req_dorequest(wlandev, (u8 *)&msg2); - if ((result != 0) || - (msg2->resultcode.data != P80211ENUM_resultcode_success)) { - break; - } - - ie_buf[0] = WLAN_EID_SSID; - ie_buf[1] = msg2->ssid.data.len; - ie_len = ie_buf[1] + 2; - memcpy(&ie_buf[2], &msg2->ssid.data.data, msg2->ssid.data.len); - freq = ieee80211_channel_to_frequency(msg2->dschannel.data, - NL80211_BAND_2GHZ); - bss = cfg80211_inform_bss(wiphy, - ieee80211_get_channel(wiphy, freq), - CFG80211_BSS_FTYPE_UNKNOWN, - (const u8 *)&msg2->bssid.data.data, - msg2->timestamp.data, msg2->capinfo.data, - msg2->beaconperiod.data, - ie_buf, - ie_len, - (msg2->signal.data - 65536) * 100, /* Conversion to signed type */ - GFP_KERNEL); - - if (!bss) { - err = -ENOMEM; - goto exit; - } - - cfg80211_put_bss(wiphy, bss); - } - - if (result) - err = prism2_result2err(msg2->resultcode.data); - -exit: - info.aborted = !!(err); - cfg80211_scan_done(request, &info); - priv->scan_request = NULL; - kfree(msg2); - return err; -} - -static int prism2_set_wiphy_params(struct wiphy *wiphy, u32 changed) -{ - struct prism2_wiphy_private *priv = wiphy_priv(wiphy); - struct wlandevice *wlandev = priv->wlandev; - u32 data; - int result; - int err = 0; - - if (changed & WIPHY_PARAM_RTS_THRESHOLD) { - if (wiphy->rts_threshold == -1) - data = 2347; - else - data = wiphy->rts_threshold; - - result = prism2_domibset_uint32(wlandev, - DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD, - data); - if (result) { - err = -EFAULT; - goto exit; - } - } - - if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { - if (wiphy->frag_threshold == -1) - data = 2346; - else - data = wiphy->frag_threshold; - - result = prism2_domibset_uint32(wlandev, - DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD, - data); - if (result) { - err = -EFAULT; - goto exit; - } - } - -exit: - return err; -} - -static int prism2_connect(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_connect_params *sme) -{ - struct wlandevice *wlandev = dev->ml_priv; - struct ieee80211_channel *channel = sme->channel; - struct p80211msg_lnxreq_autojoin msg_join; - u32 did; - int length = sme->ssid_len; - int chan = -1; - int is_wep = (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP40) || - (sme->crypto.cipher_group == WLAN_CIPHER_SUITE_WEP104); - int result; - int err = 0; - - /* Set the channel */ - if (channel) { - chan = ieee80211_frequency_to_channel(channel->center_freq); - result = prism2_domibset_uint32(wlandev, - DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL, - chan); - if (result) - goto exit; - } - - /* Set the authorization */ - if ((sme->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) || - ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && !is_wep)) - msg_join.authtype.data = P80211ENUM_authalg_opensystem; - else if ((sme->auth_type == NL80211_AUTHTYPE_SHARED_KEY) || - ((sme->auth_type == NL80211_AUTHTYPE_AUTOMATIC) && is_wep)) - msg_join.authtype.data = P80211ENUM_authalg_sharedkey; - else - netdev_warn(dev, - "Unhandled authorisation type for connect (%d)\n", - sme->auth_type); - - /* Set the encryption - we only support wep */ - if (is_wep) { - if (sme->key) { - if (sme->key_idx >= NUM_WEPKEYS) - return -EINVAL; - - result = prism2_domibset_uint32(wlandev, - DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID, - sme->key_idx); - if (result) - goto exit; - - /* send key to driver */ - did = didmib_dot11smt_wepdefaultkeystable_key(sme->key_idx + 1); - result = prism2_domibset_pstr32(wlandev, - did, sme->key_len, - (u8 *)sme->key); - if (result) - goto exit; - } - - /* Assume we should set privacy invoked and exclude unencrypted - * We could possible use sme->privacy here, but the assumption - * seems reasonable anyways - */ - result = prism2_domibset_uint32(wlandev, - DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED, - P80211ENUM_truth_true); - if (result) - goto exit; - - result = prism2_domibset_uint32(wlandev, - DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED, - P80211ENUM_truth_true); - if (result) - goto exit; - - } else { - /* Assume we should unset privacy invoked - * and exclude unencrypted - */ - result = prism2_domibset_uint32(wlandev, - DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED, - P80211ENUM_truth_false); - if (result) - goto exit; - - result = prism2_domibset_uint32(wlandev, - DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED, - P80211ENUM_truth_false); - if (result) - goto exit; - } - - /* Now do the actual join. Note there is no way that I can - * see to request a specific bssid - */ - msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN; - - memcpy(msg_join.ssid.data.data, sme->ssid, length); - msg_join.ssid.data.len = length; - - result = p80211req_dorequest(wlandev, (u8 *)&msg_join); - -exit: - if (result) - err = -EFAULT; - - return err; -} - -static int prism2_disconnect(struct wiphy *wiphy, struct net_device *dev, - u16 reason_code) -{ - struct wlandevice *wlandev = dev->ml_priv; - struct p80211msg_lnxreq_autojoin msg_join; - int result; - int err = 0; - - /* Do a join, with a bogus ssid. Thats the only way I can think of */ - msg_join.msgcode = DIDMSG_LNXREQ_AUTOJOIN; - - memcpy(msg_join.ssid.data.data, "---", 3); - msg_join.ssid.data.len = 3; - - result = p80211req_dorequest(wlandev, (u8 *)&msg_join); - - if (result) - err = -EFAULT; - - return err; -} - -static int prism2_join_ibss(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_ibss_params *params) -{ - return -EOPNOTSUPP; -} - -static int prism2_leave_ibss(struct wiphy *wiphy, struct net_device *dev) -{ - return -EOPNOTSUPP; -} - -static int prism2_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, - enum nl80211_tx_power_setting type, int mbm) -{ - struct prism2_wiphy_private *priv = wiphy_priv(wiphy); - struct wlandevice *wlandev = priv->wlandev; - u32 data; - int result; - int err = 0; - - if (type == NL80211_TX_POWER_AUTOMATIC) - data = 30; - else - data = MBM_TO_DBM(mbm); - - result = prism2_domibset_uint32(wlandev, - DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL, - data); - - if (result) { - err = -EFAULT; - goto exit; - } - -exit: - return err; -} - -static int prism2_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, - int *dbm) -{ - struct prism2_wiphy_private *priv = wiphy_priv(wiphy); - struct wlandevice *wlandev = priv->wlandev; - struct p80211msg_dot11req_mibget msg; - struct p80211item_uint32 *mibitem; - int result; - int err = 0; - - mibitem = (struct p80211item_uint32 *)&msg.mibattribute.data; - msg.msgcode = DIDMSG_DOT11REQ_MIBGET; - mibitem->did = DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL; - - result = p80211req_dorequest(wlandev, (u8 *)&msg); - - if (result) { - err = -EFAULT; - goto exit; - } - - *dbm = mibitem->data; - -exit: - return err; -} - -/* Interface callback functions, passing data back up to the cfg80211 layer */ -void prism2_connect_result(struct wlandevice *wlandev, u8 failed) -{ - u16 status = failed ? - WLAN_STATUS_UNSPECIFIED_FAILURE : WLAN_STATUS_SUCCESS; - - cfg80211_connect_result(wlandev->netdev, wlandev->bssid, - NULL, 0, NULL, 0, status, GFP_KERNEL); -} - -void prism2_disconnected(struct wlandevice *wlandev) -{ - cfg80211_disconnected(wlandev->netdev, 0, NULL, - 0, false, GFP_KERNEL); -} - -void prism2_roamed(struct wlandevice *wlandev) -{ - struct cfg80211_roam_info roam_info = { - .links[0].bssid = wlandev->bssid, - }; - - cfg80211_roamed(wlandev->netdev, &roam_info, GFP_KERNEL); -} - -/* Structures for declaring wiphy interface */ -static const struct cfg80211_ops prism2_usb_cfg_ops = { - .change_virtual_intf = prism2_change_virtual_intf, - .add_key = prism2_add_key, - .get_key = prism2_get_key, - .del_key = prism2_del_key, - .set_default_key = prism2_set_default_key, - .get_station = prism2_get_station, - .scan = prism2_scan, - .set_wiphy_params = prism2_set_wiphy_params, - .connect = prism2_connect, - .disconnect = prism2_disconnect, - .join_ibss = prism2_join_ibss, - .leave_ibss = prism2_leave_ibss, - .set_tx_power = prism2_set_tx_power, - .get_tx_power = prism2_get_tx_power, -}; - -/* Functions to create/free wiphy interface */ -static struct wiphy *wlan_create_wiphy(struct device *dev, - struct wlandevice *wlandev) -{ - struct wiphy *wiphy; - struct prism2_wiphy_private *priv; - - wiphy = wiphy_new(&prism2_usb_cfg_ops, sizeof(*priv)); - if (!wiphy) - return NULL; - - priv = wiphy_priv(wiphy); - priv->wlandev = wlandev; - memcpy(priv->channels, prism2_channels, sizeof(prism2_channels)); - memcpy(priv->rates, prism2_rates, sizeof(prism2_rates)); - priv->band.channels = priv->channels; - priv->band.n_channels = ARRAY_SIZE(prism2_channels); - priv->band.bitrates = priv->rates; - priv->band.n_bitrates = ARRAY_SIZE(prism2_rates); - priv->band.band = NL80211_BAND_2GHZ; - priv->band.ht_cap.ht_supported = false; - wiphy->bands[NL80211_BAND_2GHZ] = &priv->band; - - set_wiphy_dev(wiphy, dev); - wiphy->privid = prism2_wiphy_privid; - wiphy->max_scan_ssids = 1; - wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) - | BIT(NL80211_IFTYPE_ADHOC); - wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - wiphy->n_cipher_suites = PRISM2_NUM_CIPHER_SUITES; - wiphy->cipher_suites = prism2_cipher_suites; - - if (wiphy_register(wiphy) < 0) { - wiphy_free(wiphy); - return NULL; - } - - return wiphy; -} - -static void wlan_free_wiphy(struct wiphy *wiphy) -{ - wiphy_unregister(wiphy); - wiphy_free(wiphy); -} diff --git a/drivers/staging/wlan-ng/hfa384x.h b/drivers/staging/wlan-ng/hfa384x.h deleted file mode 100644 index a4799589e469..000000000000 --- a/drivers/staging/wlan-ng/hfa384x.h +++ /dev/null @@ -1,1236 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * Defines the constants and data structures for the hfa384x - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * [Implementation and usage notes] - * - * [References] - * CW10 Programmer's Manual v1.5 - * IEEE 802.11 D10.0 - * - * -------------------------------------------------------------------- - */ - -#ifndef _HFA384x_H -#define _HFA384x_H - -#define HFA384x_FIRMWARE_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c)) - -#include <linux/if_ether.h> -#include <linux/usb.h> - -/*--- Mins & Maxs -----------------------------------*/ -#define HFA384x_PORTID_MAX ((u16)7) -#define HFA384x_NUMPORTS_MAX ((u16)(HFA384x_PORTID_MAX + 1)) -#define HFA384x_PDR_LEN_MAX ((u16)512) /* in bytes, from EK */ -#define HFA384x_PDA_RECS_MAX ((u16)200) /* a guess */ -#define HFA384x_PDA_LEN_MAX ((u16)1024) /* in bytes, from EK*/ -#define HFA384x_SCANRESULT_MAX ((u16)31) -#define HFA384x_HSCANRESULT_MAX ((u16)31) -#define HFA384x_CHINFORESULT_MAX ((u16)16) -#define HFA384x_RID_GUESSING_MAXLEN 2048 /* I'm not really sure */ -#define HFA384x_RIDDATA_MAXLEN HFA384x_RID_GUESSING_MAXLEN -#define HFA384x_USB_RWMEM_MAXLEN 2048 - -/*--- Support Constants -----------------------------*/ -#define HFA384x_PORTTYPE_IBSS ((u16)0) -#define HFA384x_PORTTYPE_BSS ((u16)1) -#define HFA384x_PORTTYPE_PSUEDOIBSS ((u16)3) -#define HFA384x_WEPFLAGS_PRIVINVOKED ((u16)BIT(0)) -#define HFA384x_WEPFLAGS_EXCLUDE ((u16)BIT(1)) -#define HFA384x_WEPFLAGS_DISABLE_TXCRYPT ((u16)BIT(4)) -#define HFA384x_WEPFLAGS_DISABLE_RXCRYPT ((u16)BIT(7)) -#define HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM ((u16)3) -#define HFA384x_PORTSTATUS_DISABLED ((u16)1) -#define HFA384x_RATEBIT_1 ((u16)1) -#define HFA384x_RATEBIT_2 ((u16)2) -#define HFA384x_RATEBIT_5dot5 ((u16)4) -#define HFA384x_RATEBIT_11 ((u16)8) - -/*--- MAC Internal memory constants and macros ------*/ -/* masks and macros used to manipulate MAC internal memory addresses. */ -/* MAC internal memory addresses are 23 bit quantities. The MAC uses - * a paged address space where the upper 16 bits are the page number - * and the lower 7 bits are the offset. There are various Host API - * elements that require two 16-bit quantities to specify a MAC - * internal memory address. Unfortunately, some of the API's use a - * page/offset format where the offset value is JUST the lower seven - * bits and the page is the remaining 16 bits. Some of the API's - * assume that the 23 bit address has been split at the 16th bit. We - * refer to these two formats as AUX format and CMD format. The - * macros below help handle some of this. - */ - -/* Mask bits for discarding unwanted pieces in a flat address */ -#define HFA384x_ADDR_FLAT_AUX_PAGE_MASK (0x007fff80) -#define HFA384x_ADDR_FLAT_AUX_OFF_MASK (0x0000007f) -#define HFA384x_ADDR_FLAT_CMD_PAGE_MASK (0xffff0000) -#define HFA384x_ADDR_FLAT_CMD_OFF_MASK (0x0000ffff) - -/* Mask bits for discarding unwanted pieces in AUX format - * 16-bit address parts - */ -#define HFA384x_ADDR_AUX_PAGE_MASK (0xffff) -#define HFA384x_ADDR_AUX_OFF_MASK (0x007f) - -/* Make a 32-bit flat address from AUX format 16-bit page and offset */ -#define HFA384x_ADDR_AUX_MKFLAT(p, o) \ - ((((u32)(((u16)(p)) & HFA384x_ADDR_AUX_PAGE_MASK)) << 7) | \ - ((u32)(((u16)(o)) & HFA384x_ADDR_AUX_OFF_MASK))) - -/* Make CMD format offset and page from a 32-bit flat address */ -#define HFA384x_ADDR_CMD_MKPAGE(f) \ - ((u16)((((u32)(f)) & HFA384x_ADDR_FLAT_CMD_PAGE_MASK) >> 16)) -#define HFA384x_ADDR_CMD_MKOFF(f) \ - ((u16)(((u32)(f)) & HFA384x_ADDR_FLAT_CMD_OFF_MASK)) - -/*--- Controller Memory addresses -------------------*/ -#define HFA3842_PDA_BASE (0x007f0000UL) -#define HFA3841_PDA_BASE (0x003f0000UL) -#define HFA3841_PDA_BOGUS_BASE (0x00390000UL) - -/*--- Driver Download states -----------------------*/ -#define HFA384x_DLSTATE_DISABLED 0 -#define HFA384x_DLSTATE_RAMENABLED 1 -#define HFA384x_DLSTATE_FLASHENABLED 2 - -/*--- Register Field Masks --------------------------*/ -#define HFA384x_CMD_AINFO ((u16)GENMASK(14, 8)) -#define HFA384x_CMD_MACPORT ((u16)GENMASK(10, 8)) -#define HFA384x_CMD_PROGMODE ((u16)GENMASK(9, 8)) -#define HFA384x_CMD_CMDCODE ((u16)GENMASK(5, 0)) -#define HFA384x_STATUS_RESULT ((u16)GENMASK(14, 8)) - -/*--- Command Code Constants --------------------------*/ -/*--- Controller Commands --------------------------*/ -#define HFA384x_CMDCODE_INIT ((u16)0x00) -#define HFA384x_CMDCODE_ENABLE ((u16)0x01) -#define HFA384x_CMDCODE_DISABLE ((u16)0x02) - -/*--- Regulate Commands --------------------------*/ -#define HFA384x_CMDCODE_INQ ((u16)0x11) - -/*--- Configure Commands --------------------------*/ -#define HFA384x_CMDCODE_DOWNLD ((u16)0x22) - -/*--- Debugging Commands -----------------------------*/ -#define HFA384x_CMDCODE_MONITOR ((u16)(0x38)) -#define HFA384x_MONITOR_ENABLE ((u16)(0x0b)) -#define HFA384x_MONITOR_DISABLE ((u16)(0x0f)) - -/*--- Result Codes --------------------------*/ -#define HFA384x_CMD_ERR ((u16)(0x7F)) - -/*--- Programming Modes -------------------------- - * MODE 0: Disable programming - * MODE 1: Enable volatile memory programming - * MODE 2: Enable non-volatile memory programming - * MODE 3: Program non-volatile memory section - *------------------------------------------------- - */ -#define HFA384x_PROGMODE_DISABLE ((u16)0x00) -#define HFA384x_PROGMODE_RAM ((u16)0x01) -#define HFA384x_PROGMODE_NV ((u16)0x02) -#define HFA384x_PROGMODE_NVWRITE ((u16)0x03) - -/*--- Record ID Constants --------------------------*/ -/*-------------------------------------------------------------------- - * Configuration RIDs: Network Parameters, Static Configuration Entities - *-------------------------------------------------------------------- - */ -#define HFA384x_RID_CNFPORTTYPE ((u16)0xFC00) -#define HFA384x_RID_CNFOWNMACADDR ((u16)0xFC01) -#define HFA384x_RID_CNFDESIREDSSID ((u16)0xFC02) -#define HFA384x_RID_CNFOWNCHANNEL ((u16)0xFC03) -#define HFA384x_RID_CNFOWNSSID ((u16)0xFC04) -#define HFA384x_RID_CNFMAXDATALEN ((u16)0xFC07) - -/*-------------------------------------------------------------------- - * Configuration RID lengths: Network Params, Static Config Entities - * This is the length of JUST the DATA part of the RID (does not - * include the len or code fields) - *-------------------------------------------------------------------- - */ -#define HFA384x_RID_CNFOWNMACADDR_LEN ((u16)6) -#define HFA384x_RID_CNFDESIREDSSID_LEN ((u16)34) -#define HFA384x_RID_CNFOWNSSID_LEN ((u16)34) - -/*-------------------------------------------------------------------- - * Configuration RIDs: Network Parameters, Dynamic Configuration Entities - *-------------------------------------------------------------------- - */ -#define HFA384x_RID_CREATEIBSS ((u16)0xFC81) -#define HFA384x_RID_FRAGTHRESH ((u16)0xFC82) -#define HFA384x_RID_RTSTHRESH ((u16)0xFC83) -#define HFA384x_RID_TXRATECNTL ((u16)0xFC84) -#define HFA384x_RID_PROMISCMODE ((u16)0xFC85) - -/*---------------------------------------------------------------------- - * Information RIDs: NIC Information - *---------------------------------------------------------------------- - */ -#define HFA384x_RID_MAXLOADTIME ((u16)0xFD00) -#define HFA384x_RID_DOWNLOADBUFFER ((u16)0xFD01) -#define HFA384x_RID_PRIIDENTITY ((u16)0xFD02) -#define HFA384x_RID_PRISUPRANGE ((u16)0xFD03) -#define HFA384x_RID_PRI_CFIACTRANGES ((u16)0xFD04) -#define HFA384x_RID_NICSERIALNUMBER ((u16)0xFD0A) -#define HFA384x_RID_NICIDENTITY ((u16)0xFD0B) -#define HFA384x_RID_MFISUPRANGE ((u16)0xFD0C) -#define HFA384x_RID_CFISUPRANGE ((u16)0xFD0D) -#define HFA384x_RID_STAIDENTITY ((u16)0xFD20) -#define HFA384x_RID_STASUPRANGE ((u16)0xFD21) -#define HFA384x_RID_STA_MFIACTRANGES ((u16)0xFD22) -#define HFA384x_RID_STA_CFIACTRANGES ((u16)0xFD23) - -/*---------------------------------------------------------------------- - * Information RID Lengths: NIC Information - * This is the length of JUST the DATA part of the RID (does not - * include the len or code fields) - *--------------------------------------------------------------------- - */ -#define HFA384x_RID_NICSERIALNUMBER_LEN ((u16)12) - -/*-------------------------------------------------------------------- - * Information RIDs: MAC Information - *-------------------------------------------------------------------- - */ -#define HFA384x_RID_PORTSTATUS ((u16)0xFD40) -#define HFA384x_RID_CURRENTSSID ((u16)0xFD41) -#define HFA384x_RID_CURRENTBSSID ((u16)0xFD42) -#define HFA384x_RID_CURRENTTXRATE ((u16)0xFD44) -#define HFA384x_RID_SHORTRETRYLIMIT ((u16)0xFD48) -#define HFA384x_RID_LONGRETRYLIMIT ((u16)0xFD49) -#define HFA384x_RID_MAXTXLIFETIME ((u16)0xFD4A) -#define HFA384x_RID_PRIVACYOPTIMP ((u16)0xFD4F) -#define HFA384x_RID_DBMCOMMSQUALITY ((u16)0xFD51) - -/*-------------------------------------------------------------------- - * Information RID Lengths: MAC Information - * This is the length of JUST the DATA part of the RID (does not - * include the len or code fields) - *-------------------------------------------------------------------- - */ -#define HFA384x_RID_DBMCOMMSQUALITY_LEN \ - ((u16)sizeof(struct hfa384x_dbmcommsquality)) -#define HFA384x_RID_JOINREQUEST_LEN \ - ((u16)sizeof(struct hfa384x_join_request_data)) - -/*-------------------------------------------------------------------- - * Information RIDs: Modem Information - *-------------------------------------------------------------------- - */ -#define HFA384x_RID_CURRENTCHANNEL ((u16)0xFDC1) - -/*-------------------------------------------------------------------- - * API ENHANCEMENTS (NOT ALREADY IMPLEMENTED) - *-------------------------------------------------------------------- - */ -#define HFA384x_RID_CNFWEPDEFAULTKEYID ((u16)0xFC23) -#define HFA384x_RID_CNFWEPDEFAULTKEY0 ((u16)0xFC24) -#define HFA384x_RID_CNFWEPDEFAULTKEY1 ((u16)0xFC25) -#define HFA384x_RID_CNFWEPDEFAULTKEY2 ((u16)0xFC26) -#define HFA384x_RID_CNFWEPDEFAULTKEY3 ((u16)0xFC27) -#define HFA384x_RID_CNFWEPFLAGS ((u16)0xFC28) -#define HFA384x_RID_CNFAUTHENTICATION ((u16)0xFC2A) -#define HFA384x_RID_CNFROAMINGMODE ((u16)0xFC2D) -#define HFA384x_RID_CNFAPBCNINT ((u16)0xFC33) -#define HFA384x_RID_CNFDBMADJUST ((u16)0xFC46) -#define HFA384x_RID_CNFWPADATA ((u16)0xFC48) -#define HFA384x_RID_CNFBASICRATES ((u16)0xFCB3) -#define HFA384x_RID_CNFSUPPRATES ((u16)0xFCB4) -#define HFA384x_RID_CNFPASSIVESCANCTRL ((u16)0xFCBA) -#define HFA384x_RID_TXPOWERMAX ((u16)0xFCBE) -#define HFA384x_RID_JOINREQUEST ((u16)0xFCE2) -#define HFA384x_RID_AUTHENTICATESTA ((u16)0xFCE3) -#define HFA384x_RID_HOSTSCAN ((u16)0xFCE5) - -#define HFA384x_RID_CNFWEPDEFAULTKEY_LEN ((u16)6) -#define HFA384x_RID_CNFWEP128DEFAULTKEY_LEN ((u16)14) - -/*-------------------------------------------------------------------- - * PD Record codes - *-------------------------------------------------------------------- - */ -#define HFA384x_PDR_PCB_PARTNUM ((u16)0x0001) -#define HFA384x_PDR_PDAVER ((u16)0x0002) -#define HFA384x_PDR_NIC_SERIAL ((u16)0x0003) -#define HFA384x_PDR_MKK_MEASUREMENTS ((u16)0x0004) -#define HFA384x_PDR_NIC_RAMSIZE ((u16)0x0005) -#define HFA384x_PDR_MFISUPRANGE ((u16)0x0006) -#define HFA384x_PDR_CFISUPRANGE ((u16)0x0007) -#define HFA384x_PDR_NICID ((u16)0x0008) -#define HFA384x_PDR_MAC_ADDRESS ((u16)0x0101) -#define HFA384x_PDR_REGDOMAIN ((u16)0x0103) -#define HFA384x_PDR_ALLOWED_CHANNEL ((u16)0x0104) -#define HFA384x_PDR_DEFAULT_CHANNEL ((u16)0x0105) -#define HFA384x_PDR_TEMPTYPE ((u16)0x0107) -#define HFA384x_PDR_IFR_SETTING ((u16)0x0200) -#define HFA384x_PDR_RFR_SETTING ((u16)0x0201) -#define HFA384x_PDR_HFA3861_BASELINE ((u16)0x0202) -#define HFA384x_PDR_HFA3861_SHADOW ((u16)0x0203) -#define HFA384x_PDR_HFA3861_IFRF ((u16)0x0204) -#define HFA384x_PDR_HFA3861_CHCALSP ((u16)0x0300) -#define HFA384x_PDR_HFA3861_CHCALI ((u16)0x0301) -#define HFA384x_PDR_MAX_TX_POWER ((u16)0x0302) -#define HFA384x_PDR_MASTER_CHAN_LIST ((u16)0x0303) -#define HFA384x_PDR_3842_NIC_CONFIG ((u16)0x0400) -#define HFA384x_PDR_USB_ID ((u16)0x0401) -#define HFA384x_PDR_PCI_ID ((u16)0x0402) -#define HFA384x_PDR_PCI_IFCONF ((u16)0x0403) -#define HFA384x_PDR_PCI_PMCONF ((u16)0x0404) -#define HFA384x_PDR_RFENRGY ((u16)0x0406) -#define HFA384x_PDR_USB_POWER_TYPE ((u16)0x0407) -#define HFA384x_PDR_USB_MAX_POWER ((u16)0x0409) -#define HFA384x_PDR_USB_MANUFACTURER ((u16)0x0410) -#define HFA384x_PDR_USB_PRODUCT ((u16)0x0411) -#define HFA384x_PDR_ANT_DIVERSITY ((u16)0x0412) -#define HFA384x_PDR_HFO_DELAY ((u16)0x0413) -#define HFA384x_PDR_SCALE_THRESH ((u16)0x0414) - -#define HFA384x_PDR_HFA3861_MANF_TESTSP ((u16)0x0900) -#define HFA384x_PDR_HFA3861_MANF_TESTI ((u16)0x0901) -#define HFA384x_PDR_END_OF_PDA ((u16)0x0000) - -/*--- Register Test/Get/Set Field macros ------------------------*/ - -#define HFA384x_CMD_AINFO_SET(value) ((u16)((u16)(value) << 8)) -#define HFA384x_CMD_MACPORT_SET(value) \ - ((u16)HFA384x_CMD_AINFO_SET(value)) -#define HFA384x_CMD_PROGMODE_SET(value) \ - ((u16)HFA384x_CMD_AINFO_SET((u16)value)) -#define HFA384x_CMD_CMDCODE_SET(value) ((u16)(value)) - -#define HFA384x_STATUS_RESULT_SET(value) (((u16)(value)) << 8) - -/* Host Maintained State Info */ -#define HFA384x_STATE_PREINIT 0 -#define HFA384x_STATE_INIT 1 -#define HFA384x_STATE_RUNNING 2 - -/*-------------------------------------------------------------*/ -/* Commonly used basic types */ -struct hfa384x_bytestr { - __le16 len; - u8 data[]; -} __packed; - -struct hfa384x_bytestr32 { - __le16 len; - u8 data[32]; -} __packed; - -/*-------------------------------------------------------------------- - * Configuration Record Structures: - * Network Parameters, Static Configuration Entities - *-------------------------------------------------------------------- - */ - -/*-- Hardware/Firmware Component Information ----------*/ -struct hfa384x_compident { - u16 id; - u16 variant; - u16 major; - u16 minor; -} __packed; - -struct hfa384x_caplevel { - u16 role; - u16 id; - u16 variant; - u16 bottom; - u16 top; -} __packed; - -/*-- Configuration Record: cnfAuthentication --*/ -#define HFA384x_CNFAUTHENTICATION_OPENSYSTEM 0x0001 -#define HFA384x_CNFAUTHENTICATION_SHAREDKEY 0x0002 -#define HFA384x_CNFAUTHENTICATION_LEAP 0x0004 - -/*-------------------------------------------------------------------- - * Configuration Record Structures: - * Network Parameters, Dynamic Configuration Entities - *-------------------------------------------------------------------- - */ - -#define HFA384x_CREATEIBSS_JOINCREATEIBSS 0 - -/*-- Configuration Record: HostScanRequest (data portion only) --*/ -struct hfa384x_host_scan_request_data { - __le16 channel_list; - __le16 tx_rate; - struct hfa384x_bytestr32 ssid; -} __packed; - -/*-- Configuration Record: JoinRequest (data portion only) --*/ -struct hfa384x_join_request_data { - u8 bssid[WLAN_BSSID_LEN]; - u16 channel; -} __packed; - -/*-- Configuration Record: authenticateStation (data portion only) --*/ -struct hfa384x_authenticate_station_data { - u8 address[ETH_ALEN]; - __le16 status; - __le16 algorithm; -} __packed; - -/*-- Configuration Record: WPAData (data portion only) --*/ -struct hfa384x_wpa_data { - __le16 datalen; - u8 data[]; /* max 80 */ -} __packed; - -/*-------------------------------------------------------------------- - * Information Record Structures: NIC Information - *-------------------------------------------------------------------- - */ - -/*-- Information Record: DownLoadBuffer --*/ -/* NOTE: The page and offset are in AUX format */ -struct hfa384x_downloadbuffer { - u16 page; - u16 offset; - u16 len; -} __packed; - -/*-------------------------------------------------------------------- - * Information Record Structures: NIC Information - *-------------------------------------------------------------------- - */ - -#define HFA384x_PSTATUS_CONN_IBSS ((u16)3) - -/*-- Information Record: commsquality --*/ -struct hfa384x_commsquality { - __le16 cq_curr_bss; - __le16 asl_curr_bss; - __le16 anl_curr_fc; -} __packed; - -/*-- Information Record: dmbcommsquality --*/ -struct hfa384x_dbmcommsquality { - u16 cq_dbm_curr_bss; - u16 asl_dbm_curr_bss; - u16 anl_dbm_curr_fc; -} __packed; - -/*-------------------------------------------------------------------- - * FRAME STRUCTURES: Communication Frames - *-------------------------------------------------------------------- - * Communication Frames: Transmit Frames - *-------------------------------------------------------------------- - */ -/*-- Communication Frame: Transmit Frame Structure --*/ -struct hfa384x_tx_frame { - u16 status; - u16 reserved1; - u16 reserved2; - u32 sw_support; - u8 tx_retrycount; - u8 tx_rate; - u16 tx_control; - - /*-- 802.11 Header Information --*/ - struct p80211_hdr hdr; - __le16 data_len; /* little endian format */ - - /*-- 802.3 Header Information --*/ - - u8 dest_addr[6]; - u8 src_addr[6]; - u16 data_length; /* big endian format */ -} __packed; -/*-------------------------------------------------------------------- - * Communication Frames: Field Masks for Transmit Frames - *-------------------------------------------------------------------- - */ -/*-- Status Field --*/ -#define HFA384x_TXSTATUS_ACKERR ((u16)BIT(5)) -#define HFA384x_TXSTATUS_FORMERR ((u16)BIT(3)) -#define HFA384x_TXSTATUS_DISCON ((u16)BIT(2)) -#define HFA384x_TXSTATUS_AGEDERR ((u16)BIT(1)) -#define HFA384x_TXSTATUS_RETRYERR ((u16)BIT(0)) -/*-- Transmit Control Field --*/ -#define HFA384x_TX_MACPORT ((u16)GENMASK(10, 8)) -#define HFA384x_TX_STRUCTYPE ((u16)GENMASK(4, 3)) -#define HFA384x_TX_TXEX ((u16)BIT(2)) -#define HFA384x_TX_TXOK ((u16)BIT(1)) -/*-------------------------------------------------------------------- - * Communication Frames: Test/Get/Set Field Values for Transmit Frames - *-------------------------------------------------------------------- - */ -/*-- Status Field --*/ -#define HFA384x_TXSTATUS_ISERROR(v) \ - (((u16)(v)) & \ - (HFA384x_TXSTATUS_ACKERR | HFA384x_TXSTATUS_FORMERR | \ - HFA384x_TXSTATUS_DISCON | HFA384x_TXSTATUS_AGEDERR | \ - HFA384x_TXSTATUS_RETRYERR)) - -#define HFA384x_TX_SET(v, m, s) ((((u16)(v)) << ((u16)(s))) & ((u16)(m))) - -#define HFA384x_TX_MACPORT_SET(v) HFA384x_TX_SET(v, HFA384x_TX_MACPORT, 8) -#define HFA384x_TX_STRUCTYPE_SET(v) HFA384x_TX_SET(v, \ - HFA384x_TX_STRUCTYPE, 3) -#define HFA384x_TX_TXEX_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXEX, 2) -#define HFA384x_TX_TXOK_SET(v) HFA384x_TX_SET(v, HFA384x_TX_TXOK, 1) -/*-------------------------------------------------------------------- - * Communication Frames: Receive Frames - *-------------------------------------------------------------------- - */ -/*-- Communication Frame: Receive Frame Structure --*/ -struct hfa384x_rx_frame { - /*-- MAC rx descriptor (hfa384x byte order) --*/ - u16 status; - u32 time; - u8 silence; - u8 signal; - u8 rate; - u8 rx_flow; - u16 reserved1; - u16 reserved2; - - /*-- 802.11 Header Information (802.11 byte order) --*/ - struct p80211_hdr hdr; - __le16 data_len; /* hfa384x (little endian) format */ - - /*-- 802.3 Header Information --*/ - u8 dest_addr[6]; - u8 src_addr[6]; - u16 data_length; /* IEEE? (big endian) format */ -} __packed; -/*-------------------------------------------------------------------- - * Communication Frames: Field Masks for Receive Frames - *-------------------------------------------------------------------- - */ - -/*-- Status Fields --*/ -#define HFA384x_RXSTATUS_MACPORT ((u16)GENMASK(10, 8)) -#define HFA384x_RXSTATUS_FCSERR ((u16)BIT(0)) -/*-------------------------------------------------------------------- - * Communication Frames: Test/Get/Set Field Values for Receive Frames - *-------------------------------------------------------------------- - */ -#define HFA384x_RXSTATUS_MACPORT_GET(value) ((u16)((((u16)(value)) \ - & HFA384x_RXSTATUS_MACPORT) >> 8)) -#define HFA384x_RXSTATUS_ISFCSERR(value) ((u16)(((u16)(value)) \ - & HFA384x_RXSTATUS_FCSERR)) -/*-------------------------------------------------------------------- - * FRAME STRUCTURES: Information Types and Information Frame Structures - *-------------------------------------------------------------------- - * Information Types - *-------------------------------------------------------------------- - */ -#define HFA384x_IT_HANDOVERADDR ((u16)0xF000UL) -#define HFA384x_IT_COMMTALLIES ((u16)0xF100UL) -#define HFA384x_IT_SCANRESULTS ((u16)0xF101UL) -#define HFA384x_IT_CHINFORESULTS ((u16)0xF102UL) -#define HFA384x_IT_HOSTSCANRESULTS ((u16)0xF103UL) -#define HFA384x_IT_LINKSTATUS ((u16)0xF200UL) -#define HFA384x_IT_ASSOCSTATUS ((u16)0xF201UL) -#define HFA384x_IT_AUTHREQ ((u16)0xF202UL) -#define HFA384x_IT_PSUSERCNT ((u16)0xF203UL) -#define HFA384x_IT_KEYIDCHANGED ((u16)0xF204UL) -#define HFA384x_IT_ASSOCREQ ((u16)0xF205UL) -#define HFA384x_IT_MICFAILURE ((u16)0xF206UL) - -/*-------------------------------------------------------------------- - * Information Frames Structures - *-------------------------------------------------------------------- - * Information Frames: Notification Frame Structures - *-------------------------------------------------------------------- - */ - -/*-- Inquiry Frame, Diagnose: Communication Tallies --*/ -struct hfa384x_comm_tallies_16 { - __le16 txunicastframes; - __le16 txmulticastframes; - __le16 txfragments; - __le16 txunicastoctets; - __le16 txmulticastoctets; - __le16 txdeferredtrans; - __le16 txsingleretryframes; - __le16 txmultipleretryframes; - __le16 txretrylimitexceeded; - __le16 txdiscards; - __le16 rxunicastframes; - __le16 rxmulticastframes; - __le16 rxfragments; - __le16 rxunicastoctets; - __le16 rxmulticastoctets; - __le16 rxfcserrors; - __le16 rxdiscardsnobuffer; - __le16 txdiscardswrongsa; - __le16 rxdiscardswepundecr; - __le16 rxmsginmsgfrag; - __le16 rxmsginbadmsgfrag; -} __packed; - -struct hfa384x_comm_tallies_32 { - __le32 txunicastframes; - __le32 txmulticastframes; - __le32 txfragments; - __le32 txunicastoctets; - __le32 txmulticastoctets; - __le32 txdeferredtrans; - __le32 txsingleretryframes; - __le32 txmultipleretryframes; - __le32 txretrylimitexceeded; - __le32 txdiscards; - __le32 rxunicastframes; - __le32 rxmulticastframes; - __le32 rxfragments; - __le32 rxunicastoctets; - __le32 rxmulticastoctets; - __le32 rxfcserrors; - __le32 rxdiscardsnobuffer; - __le32 txdiscardswrongsa; - __le32 rxdiscardswepundecr; - __le32 rxmsginmsgfrag; - __le32 rxmsginbadmsgfrag; -} __packed; - -/*-- Inquiry Frame, Diagnose: Scan Results & Subfields--*/ -struct hfa384x_scan_result_sub { - u16 chid; - u16 anl; - u16 sl; - u8 bssid[WLAN_BSSID_LEN]; - u16 bcnint; - u16 capinfo; - struct hfa384x_bytestr32 ssid; - u8 supprates[10]; /* 802.11 info element */ - u16 proberesp_rate; -} __packed; - -struct hfa384x_scan_result { - u16 rsvd; - u16 scanreason; - struct hfa384x_scan_result_sub result[HFA384x_SCANRESULT_MAX]; -} __packed; - -/*-- Inquiry Frame, Diagnose: ChInfo Results & Subfields--*/ -struct hfa384x_ch_info_result_sub { - u16 chid; - u16 anl; - u16 pnl; - u16 active; -} __packed; - -#define HFA384x_CHINFORESULT_BSSACTIVE BIT(0) -#define HFA384x_CHINFORESULT_PCFACTIVE BIT(1) - -struct hfa384x_ch_info_result { - u16 scanchannels; - struct hfa384x_ch_info_result_sub result[HFA384x_CHINFORESULT_MAX]; -} __packed; - -/*-- Inquiry Frame, Diagnose: Host Scan Results & Subfields--*/ -struct hfa384x_hscan_result_sub { - __le16 chid; - __le16 anl; - __le16 sl; - u8 bssid[WLAN_BSSID_LEN]; - __le16 bcnint; - __le16 capinfo; - struct hfa384x_bytestr32 ssid; - u8 supprates[10]; /* 802.11 info element */ - u16 proberesp_rate; - __le16 atim; -} __packed; - -struct hfa384x_hscan_result { - u16 nresult; - u16 rsvd; - struct hfa384x_hscan_result_sub result[HFA384x_HSCANRESULT_MAX]; -} __packed; - -/*-- Unsolicited Frame, MAC Mgmt: LinkStatus --*/ - -#define HFA384x_LINK_NOTCONNECTED ((u16)0) -#define HFA384x_LINK_CONNECTED ((u16)1) -#define HFA384x_LINK_DISCONNECTED ((u16)2) -#define HFA384x_LINK_AP_CHANGE ((u16)3) -#define HFA384x_LINK_AP_OUTOFRANGE ((u16)4) -#define HFA384x_LINK_AP_INRANGE ((u16)5) -#define HFA384x_LINK_ASSOCFAIL ((u16)6) - -struct hfa384x_link_status { - __le16 linkstatus; -} __packed; - -/*-- Unsolicited Frame, MAC Mgmt: AssociationStatus (--*/ - -#define HFA384x_ASSOCSTATUS_STAASSOC ((u16)1) -#define HFA384x_ASSOCSTATUS_REASSOC ((u16)2) -#define HFA384x_ASSOCSTATUS_AUTHFAIL ((u16)5) - -struct hfa384x_assoc_status { - u16 assocstatus; - u8 sta_addr[ETH_ALEN]; - /* old_ap_addr is only valid if assocstatus == 2 */ - u8 old_ap_addr[ETH_ALEN]; - u16 reason; - u16 reserved; -} __packed; - -/*-- Unsolicited Frame, MAC Mgmt: AuthRequest (AP Only) --*/ - -struct hfa384x_auth_request { - u8 sta_addr[ETH_ALEN]; - __le16 algorithm; -} __packed; - -/*-- Unsolicited Frame, MAC Mgmt: PSUserCount (AP Only) --*/ - -struct hfa384x_ps_user_count { - __le16 usercnt; -} __packed; - -struct hfa384x_key_id_changed { - u8 sta_addr[ETH_ALEN]; - u16 keyid; -} __packed; - -/*-- Collection of all Inf frames ---------------*/ -union hfa384x_infodata { - struct hfa384x_comm_tallies_16 commtallies16; - struct hfa384x_comm_tallies_32 commtallies32; - struct hfa384x_scan_result scanresult; - struct hfa384x_ch_info_result chinforesult; - struct hfa384x_hscan_result hscanresult; - struct hfa384x_link_status linkstatus; - struct hfa384x_assoc_status assocstatus; - struct hfa384x_auth_request authreq; - struct hfa384x_ps_user_count psusercnt; - struct hfa384x_key_id_changed keyidchanged; -} __packed; - -struct hfa384x_inf_frame { - u16 framelen; - u16 infotype; - union hfa384x_infodata info; -} __packed; - -/*-------------------------------------------------------------------- - * USB Packet structures and constants. - *-------------------------------------------------------------------- - */ - -/* Should be sent to the bulkout endpoint */ -#define HFA384x_USB_TXFRM 0 -#define HFA384x_USB_CMDREQ 1 -#define HFA384x_USB_WRIDREQ 2 -#define HFA384x_USB_RRIDREQ 3 -#define HFA384x_USB_WMEMREQ 4 -#define HFA384x_USB_RMEMREQ 5 - -/* Received from the bulkin endpoint */ -#define HFA384x_USB_ISTXFRM(a) (((a) & 0x9000) == 0x1000) -#define HFA384x_USB_ISRXFRM(a) (!((a) & 0x9000)) -#define HFA384x_USB_INFOFRM 0x8000 -#define HFA384x_USB_CMDRESP 0x8001 -#define HFA384x_USB_WRIDRESP 0x8002 -#define HFA384x_USB_RRIDRESP 0x8003 -#define HFA384x_USB_WMEMRESP 0x8004 -#define HFA384x_USB_RMEMRESP 0x8005 -#define HFA384x_USB_BUFAVAIL 0x8006 -#define HFA384x_USB_ERROR 0x8007 - -/*------------------------------------*/ -/* Request (bulk OUT) packet contents */ - -struct hfa384x_usb_txfrm { - struct hfa384x_tx_frame desc; - u8 data[WLAN_DATA_MAXLEN]; -} __packed; - -struct hfa384x_usb_cmdreq { - __le16 type; - __le16 cmd; - __le16 parm0; - __le16 parm1; - __le16 parm2; - u8 pad[54]; -} __packed; - -struct hfa384x_usb_wridreq { - __le16 type; - __le16 frmlen; - __le16 rid; - u8 data[HFA384x_RIDDATA_MAXLEN]; -} __packed; - -struct hfa384x_usb_rridreq { - __le16 type; - __le16 frmlen; - __le16 rid; - u8 pad[58]; -} __packed; - -struct hfa384x_usb_wmemreq { - __le16 type; - __le16 frmlen; - __le16 offset; - __le16 page; - u8 data[HFA384x_USB_RWMEM_MAXLEN]; -} __packed; - -struct hfa384x_usb_rmemreq { - __le16 type; - __le16 frmlen; - __le16 offset; - __le16 page; - u8 pad[56]; -} __packed; - -/*------------------------------------*/ -/* Response (bulk IN) packet contents */ - -struct hfa384x_usb_rxfrm { - struct hfa384x_rx_frame desc; - u8 data[WLAN_DATA_MAXLEN]; -} __packed; - -struct hfa384x_usb_infofrm { - u16 type; - struct hfa384x_inf_frame info; -} __packed; - -struct hfa384x_usb_statusresp { - u16 type; - __le16 status; - __le16 resp0; - __le16 resp1; - __le16 resp2; -} __packed; - -struct hfa384x_usb_rridresp { - u16 type; - __le16 frmlen; - __le16 rid; - u8 data[HFA384x_RIDDATA_MAXLEN]; -} __packed; - -struct hfa384x_usb_rmemresp { - u16 type; - u16 frmlen; - u8 data[HFA384x_USB_RWMEM_MAXLEN]; -} __packed; - -struct hfa384x_usb_bufavail { - u16 type; - u16 frmlen; -} __packed; - -struct hfa384x_usb_error { - u16 type; - u16 errortype; -} __packed; - -/*----------------------------------------------------------*/ -/* Unions for packaging all the known packet types together */ - -union hfa384x_usbout { - __le16 type; - struct hfa384x_usb_txfrm txfrm; - struct hfa384x_usb_cmdreq cmdreq; - struct hfa384x_usb_wridreq wridreq; - struct hfa384x_usb_rridreq rridreq; - struct hfa384x_usb_wmemreq wmemreq; - struct hfa384x_usb_rmemreq rmemreq; -} __packed; - -union hfa384x_usbin { - __le16 type; - struct hfa384x_usb_rxfrm rxfrm; - struct hfa384x_usb_txfrm txfrm; - struct hfa384x_usb_infofrm infofrm; - struct hfa384x_usb_statusresp cmdresp; - struct hfa384x_usb_statusresp wridresp; - struct hfa384x_usb_rridresp rridresp; - struct hfa384x_usb_statusresp wmemresp; - struct hfa384x_usb_rmemresp rmemresp; - struct hfa384x_usb_bufavail bufavail; - struct hfa384x_usb_error usberror; - u8 boguspad[3000]; -} __packed; - -/*-------------------------------------------------------------------- - * PD record structures. - *-------------------------------------------------------------------- - */ - -struct hfa384x_pdr_mfisuprange { - u16 id; - u16 variant; - u16 bottom; - u16 top; -} __packed; - -struct hfa384x_pdr_cfisuprange { - u16 id; - u16 variant; - u16 bottom; - u16 top; -} __packed; - -struct hfa384x_pdr_nicid { - u16 id; - u16 variant; - u16 major; - u16 minor; -} __packed; - -struct hfa384x_pdrec { - __le16 len; /* in words */ - __le16 code; - union pdr { - struct hfa384x_pdr_mfisuprange mfisuprange; - struct hfa384x_pdr_cfisuprange cfisuprange; - struct hfa384x_pdr_nicid nicid; - - } data; -} __packed; - -#ifdef __KERNEL__ -/*-------------------------------------------------------------------- - * --- MAC state structure, argument to all functions -- - * --- Also, a collection of support types -- - *-------------------------------------------------------------------- - */ -struct hfa384x_cmdresult { - u16 status; - u16 resp0; - u16 resp1; - u16 resp2; -}; - -/* USB Control Exchange (CTLX): - * A queue of the structure below is maintained for all of the - * Request/Response type USB packets supported by Prism2. - */ -/* The following hfa384x_* structures are arguments to - * the usercb() for the different CTLX types. - */ -struct hfa384x_rridresult { - u16 rid; - const void *riddata; - unsigned int riddata_len; -}; - -enum ctlx_state { - CTLX_START = 0, /* Start state, not queued */ - - CTLX_COMPLETE, /* CTLX successfully completed */ - CTLX_REQ_FAILED, /* OUT URB completed w/ error */ - - CTLX_PENDING, /* Queued, data valid */ - CTLX_REQ_SUBMITTED, /* OUT URB submitted */ - CTLX_REQ_COMPLETE, /* OUT URB complete */ - CTLX_RESP_COMPLETE /* IN URB received */ -}; - -struct hfa384x_usbctlx; -struct hfa384x; - -typedef void (*ctlx_cmdcb_t) (struct hfa384x *, const struct hfa384x_usbctlx *); - -typedef void (*ctlx_usercb_t) (struct hfa384x *hw, - void *ctlxresult, void *usercb_data); - -struct hfa384x_usbctlx { - struct list_head list; - - size_t outbufsize; - union hfa384x_usbout outbuf; /* pkt buf for OUT */ - union hfa384x_usbin inbuf; /* pkt buf for IN(a copy) */ - - enum ctlx_state state; /* Tracks running state */ - - struct completion done; - int reapable; /* Food for the reaper task */ - - ctlx_cmdcb_t cmdcb; /* Async command callback */ - ctlx_usercb_t usercb; /* Async user callback, */ - void *usercb_data; /* at CTLX completion */ -}; - -struct hfa384x_usbctlxq { - spinlock_t lock; - struct list_head pending; - struct list_head active; - struct list_head completing; - struct list_head reapable; -}; - -struct hfa384x_metacmd { - u16 cmd; - - u16 parm0; - u16 parm1; - u16 parm2; - - struct hfa384x_cmdresult result; -}; - -#define MAX_GRP_ADDR 32 -#define WLAN_COMMENT_MAX 80 /* Max. length of user comment string. */ - -#define WLAN_AUTH_MAX 60 /* Max. # of authenticated stations. */ -#define WLAN_ACCESS_MAX 60 /* Max. # of stations in an access list. */ -#define WLAN_ACCESS_NONE 0 /* No stations may be authenticated. */ -#define WLAN_ACCESS_ALL 1 /* All stations may be authenticated. */ -#define WLAN_ACCESS_ALLOW 2 /* Authenticate only "allowed" stations. */ -#define WLAN_ACCESS_DENY 3 /* Do not authenticate "denied" stations. */ - -/* XXX These are going away ASAP */ -struct prism2sta_authlist { - unsigned int cnt; - u8 addr[WLAN_AUTH_MAX][ETH_ALEN]; - u8 assoc[WLAN_AUTH_MAX]; -}; - -struct prism2sta_accesslist { - unsigned int modify; - unsigned int cnt; - u8 addr[WLAN_ACCESS_MAX][ETH_ALEN]; - unsigned int cnt1; - u8 addr1[WLAN_ACCESS_MAX][ETH_ALEN]; -}; - -struct hfa384x { - /* USB support data */ - struct usb_device *usb; - struct urb rx_urb; - struct sk_buff *rx_urb_skb; - struct urb tx_urb; - struct urb ctlx_urb; - union hfa384x_usbout txbuff; - struct hfa384x_usbctlxq ctlxq; - struct timer_list reqtimer; - struct timer_list resptimer; - - struct timer_list throttle; - - struct work_struct reaper_bh; - struct work_struct completion_bh; - - struct work_struct usb_work; - - unsigned long usb_flags; -#define THROTTLE_RX 0 -#define THROTTLE_TX 1 -#define WORK_RX_HALT 2 -#define WORK_TX_HALT 3 -#define WORK_RX_RESUME 4 -#define WORK_TX_RESUME 5 - - unsigned short req_timer_done:1; - unsigned short resp_timer_done:1; - - int endp_in; - int endp_out; - - int sniff_fcs; - int sniff_channel; - int sniff_truncate; - int sniffhdr; - - wait_queue_head_t cmdq; /* wait queue itself */ - - /* Controller state */ - u32 state; - u32 isap; - u8 port_enabled[HFA384x_NUMPORTS_MAX]; - - /* Download support */ - unsigned int dlstate; - struct hfa384x_downloadbuffer bufinfo; - u16 dltimeout; - - int scanflag; /* to signal scan complete */ - int join_ap; /* are we joined to a specific ap */ - int join_retries; /* number of join retries till we fail */ - struct hfa384x_join_request_data joinreq;/* join request saved data */ - - struct wlandevice *wlandev; - /* Timer to allow for the deferred processing of linkstatus messages */ - struct work_struct link_bh; - - struct work_struct commsqual_bh; - struct hfa384x_commsquality qual; - struct timer_list commsqual_timer; - - u16 link_status; - u16 link_status_new; - struct sk_buff_head authq; - - u32 txrate; - - /* And here we have stuff that used to be in priv */ - - /* State variables */ - unsigned int presniff_port_type; - u16 presniff_wepflags; - u32 dot11_desired_bss_type; - - int dbmadjust; - - /* Group Addresses - right now, there are up to a total - * of MAX_GRP_ADDR group addresses - */ - u8 dot11_grp_addr[MAX_GRP_ADDR][ETH_ALEN]; - unsigned int dot11_grpcnt; - - /* Component Identities */ - struct hfa384x_compident ident_nic; - struct hfa384x_compident ident_pri_fw; - struct hfa384x_compident ident_sta_fw; - struct hfa384x_compident ident_ap_fw; - u16 mm_mods; - - /* Supplier compatibility ranges */ - struct hfa384x_caplevel cap_sup_mfi; - struct hfa384x_caplevel cap_sup_cfi; - struct hfa384x_caplevel cap_sup_pri; - struct hfa384x_caplevel cap_sup_sta; - struct hfa384x_caplevel cap_sup_ap; - - /* Actor compatibility ranges */ - struct hfa384x_caplevel cap_act_pri_cfi; /* - * pri f/w to controller - * interface - */ - - struct hfa384x_caplevel cap_act_sta_cfi; /* - * sta f/w to controller - * interface - */ - - struct hfa384x_caplevel cap_act_sta_mfi; /* - * sta f/w to modem interface - */ - - struct hfa384x_caplevel cap_act_ap_cfi; /* - * ap f/w to controller - * interface - */ - - struct hfa384x_caplevel cap_act_ap_mfi; /* ap f/w to modem interface */ - - u32 psusercount; /* Power save user count. */ - struct hfa384x_comm_tallies_32 tallies; /* Communication tallies. */ - u8 comment[WLAN_COMMENT_MAX + 1]; /* User comment */ - - /* Channel Info request results (AP only) */ - struct { - atomic_t done; - u8 count; - struct hfa384x_ch_info_result results; - } channel_info; - - struct hfa384x_inf_frame *scanresults; - - struct prism2sta_authlist authlist; /* - * Authenticated station list. - */ - unsigned int accessmode; /* Access mode. */ - struct prism2sta_accesslist allow; /* Allowed station list. */ - struct prism2sta_accesslist deny; /* Denied station list. */ - -}; - -void hfa384x_create(struct hfa384x *hw, struct usb_device *usb); -void hfa384x_destroy(struct hfa384x *hw); - -int hfa384x_corereset(struct hfa384x *hw, int holdtime, int settletime, - int genesis); -int hfa384x_drvr_disable(struct hfa384x *hw, u16 macport); -int hfa384x_drvr_enable(struct hfa384x *hw, u16 macport); -int hfa384x_drvr_flashdl_enable(struct hfa384x *hw); -int hfa384x_drvr_flashdl_disable(struct hfa384x *hw); -int hfa384x_drvr_flashdl_write(struct hfa384x *hw, u32 daddr, void *buf, - u32 len); -int hfa384x_drvr_getconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len); -int hfa384x_drvr_ramdl_enable(struct hfa384x *hw, u32 exeaddr); -int hfa384x_drvr_ramdl_disable(struct hfa384x *hw); -int hfa384x_drvr_ramdl_write(struct hfa384x *hw, u32 daddr, void *buf, u32 len); -int hfa384x_drvr_readpda(struct hfa384x *hw, void *buf, unsigned int len); -int hfa384x_drvr_setconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len); - -static inline int -hfa384x_drvr_getconfig16(struct hfa384x *hw, u16 rid, void *val) -{ - int result = 0; - - result = hfa384x_drvr_getconfig(hw, rid, val, sizeof(u16)); - if (result == 0) - le16_to_cpus(val); - return result; -} - -static inline int hfa384x_drvr_setconfig16(struct hfa384x *hw, u16 rid, u16 val) -{ - __le16 value = cpu_to_le16(val); - - return hfa384x_drvr_setconfig(hw, rid, &value, sizeof(value)); -} - -int -hfa384x_drvr_setconfig_async(struct hfa384x *hw, - u16 rid, - void *buf, - u16 len, ctlx_usercb_t usercb, void *usercb_data); - -static inline int -hfa384x_drvr_setconfig16_async(struct hfa384x *hw, u16 rid, u16 val) -{ - __le16 value = cpu_to_le16(val); - - return hfa384x_drvr_setconfig_async(hw, rid, &value, sizeof(value), - NULL, NULL); -} - -int hfa384x_drvr_start(struct hfa384x *hw); -int hfa384x_drvr_stop(struct hfa384x *hw); -int -hfa384x_drvr_txframe(struct hfa384x *hw, struct sk_buff *skb, - struct p80211_hdr *p80211_hdr, - struct p80211_metawep *p80211_wep); -void hfa384x_tx_timeout(struct wlandevice *wlandev); - -int hfa384x_cmd_initialize(struct hfa384x *hw); -int hfa384x_cmd_enable(struct hfa384x *hw, u16 macport); -int hfa384x_cmd_disable(struct hfa384x *hw, u16 macport); -int hfa384x_cmd_allocate(struct hfa384x *hw, u16 len); -int hfa384x_cmd_monitor(struct hfa384x *hw, u16 enable); -int -hfa384x_cmd_download(struct hfa384x *hw, - u16 mode, u16 lowaddr, u16 highaddr, u16 codelen); - -#endif /*__KERNEL__ */ - -#endif /*_HFA384x_H */ diff --git a/drivers/staging/wlan-ng/hfa384x_usb.c b/drivers/staging/wlan-ng/hfa384x_usb.c deleted file mode 100644 index 35650f911ebc..000000000000 --- a/drivers/staging/wlan-ng/hfa384x_usb.c +++ /dev/null @@ -1,3880 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) -/* - * - * Functions that talk to the USB variant of the Intersil hfa384x MAC - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file implements functions that correspond to the prism2/hfa384x - * 802.11 MAC hardware and firmware host interface. - * - * The functions can be considered to represent several levels of - * abstraction. The lowest level functions are simply C-callable wrappers - * around the register accesses. The next higher level represents C-callable - * prism2 API functions that match the Intersil documentation as closely - * as is reasonable. The next higher layer implements common sequences - * of invocations of the API layer (e.g. write to bap, followed by cmd). - * - * Common sequences: - * hfa384x_drvr_xxx Highest level abstractions provided by the - * hfa384x code. They are driver defined wrappers - * for common sequences. These functions generally - * use the services of the lower levels. - * - * hfa384x_drvr_xxxconfig An example of the drvr level abstraction. These - * functions are wrappers for the RID get/set - * sequence. They call copy_[to|from]_bap() and - * cmd_access(). These functions operate on the - * RIDs and buffers without validation. The caller - * is responsible for that. - * - * API wrapper functions: - * hfa384x_cmd_xxx functions that provide access to the f/w commands. - * The function arguments correspond to each command - * argument, even command arguments that get packed - * into single registers. These functions _just_ - * issue the command by setting the cmd/parm regs - * & reading the status/resp regs. Additional - * activities required to fully use a command - * (read/write from/to bap, get/set int status etc.) - * are implemented separately. Think of these as - * C-callable prism2 commands. - * - * Lowest Layer Functions: - * hfa384x_docmd_xxx These functions implement the sequence required - * to issue any prism2 command. Primarily used by the - * hfa384x_cmd_xxx functions. - * - * hfa384x_bap_xxx BAP read/write access functions. - * Note: we usually use BAP0 for non-interrupt context - * and BAP1 for interrupt context. - * - * hfa384x_dl_xxx download related functions. - * - * Driver State Issues: - * Note that there are two pairs of functions that manage the - * 'initialized' and 'running' states of the hw/MAC combo. The four - * functions are create(), destroy(), start(), and stop(). create() - * sets up the data structures required to support the hfa384x_* - * functions and destroy() cleans them up. The start() function gets - * the actual hardware running and enables the interrupts. The stop() - * function shuts the hardware down. The sequence should be: - * create() - * start() - * . - * . Do interesting things w/ the hardware - * . - * stop() - * destroy() - * - * Note that destroy() can be called without calling stop() first. - * -------------------------------------------------------------------- - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/wireless.h> -#include <linux/netdevice.h> -#include <linux/timer.h> -#include <linux/io.h> -#include <linux/delay.h> -#include <asm/byteorder.h> -#include <linux/bitops.h> -#include <linux/list.h> -#include <linux/usb.h> -#include <linux/byteorder/generic.h> - -#include "p80211types.h" -#include "p80211hdr.h" -#include "p80211mgmt.h" -#include "p80211conv.h" -#include "p80211msg.h" -#include "p80211netdev.h" -#include "p80211req.h" -#include "p80211metadef.h" -#include "p80211metastruct.h" -#include "hfa384x.h" -#include "prism2mgmt.h" - -enum cmd_mode { - DOWAIT = 0, - DOASYNC -}; - -#define THROTTLE_JIFFIES (HZ / 8) -#define URB_ASYNC_UNLINK 0 -#define USB_QUEUE_BULK 0 - -#define ROUNDUP64(a) (((a) + 63) & ~63) - -#ifdef DEBUG_USB -static void dbprint_urb(struct urb *urb); -#endif - -static void hfa384x_int_rxmonitor(struct wlandevice *wlandev, - struct hfa384x_usb_rxfrm *rxfrm); - -static void hfa384x_usb_defer(struct work_struct *data); - -static int submit_rx_urb(struct hfa384x *hw, gfp_t flags); - -static int submit_tx_urb(struct hfa384x *hw, struct urb *tx_urb, gfp_t flags); - -/*---------------------------------------------------*/ -/* Callbacks */ -static void hfa384x_usbout_callback(struct urb *urb); -static void hfa384x_ctlxout_callback(struct urb *urb); -static void hfa384x_usbin_callback(struct urb *urb); - -static void -hfa384x_usbin_txcompl(struct wlandevice *wlandev, union hfa384x_usbin *usbin); - -static void hfa384x_usbin_rx(struct wlandevice *wlandev, struct sk_buff *skb); - -static void hfa384x_usbin_info(struct wlandevice *wlandev, - union hfa384x_usbin *usbin); - -static void hfa384x_usbin_ctlx(struct hfa384x *hw, union hfa384x_usbin *usbin, - int urb_status); - -/*---------------------------------------------------*/ -/* Functions to support the prism2 usb command queue */ - -static void hfa384x_usbctlxq_run(struct hfa384x *hw); - -static void hfa384x_usbctlx_reqtimerfn(struct timer_list *t); - -static void hfa384x_usbctlx_resptimerfn(struct timer_list *t); - -static void hfa384x_usb_throttlefn(struct timer_list *t); - -static void hfa384x_usbctlx_completion_task(struct work_struct *work); - -static void hfa384x_usbctlx_reaper_task(struct work_struct *work); - -static int hfa384x_usbctlx_submit(struct hfa384x *hw, - struct hfa384x_usbctlx *ctlx); - -static void unlocked_usbctlx_complete(struct hfa384x *hw, - struct hfa384x_usbctlx *ctlx); - -struct usbctlx_completor { - int (*complete)(struct usbctlx_completor *completor); -}; - -static int -hfa384x_usbctlx_complete_sync(struct hfa384x *hw, - struct hfa384x_usbctlx *ctlx, - struct usbctlx_completor *completor); - -static int -unlocked_usbctlx_cancel_async(struct hfa384x *hw, struct hfa384x_usbctlx *ctlx); - -static void hfa384x_cb_status(struct hfa384x *hw, - const struct hfa384x_usbctlx *ctlx); - -static int -usbctlx_get_status(const struct hfa384x_usb_statusresp *cmdresp, - struct hfa384x_cmdresult *result); - -static void -usbctlx_get_rridresult(const struct hfa384x_usb_rridresp *rridresp, - struct hfa384x_rridresult *result); - -/*---------------------------------------------------*/ -/* Low level req/resp CTLX formatters and submitters */ -static inline int -hfa384x_docmd(struct hfa384x *hw, - struct hfa384x_metacmd *cmd); - -static int -hfa384x_dorrid(struct hfa384x *hw, - enum cmd_mode mode, - u16 rid, - void *riddata, - unsigned int riddatalen, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data); - -static int -hfa384x_dowrid(struct hfa384x *hw, - enum cmd_mode mode, - u16 rid, - void *riddata, - unsigned int riddatalen, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data); - -static int -hfa384x_dormem(struct hfa384x *hw, - u16 page, - u16 offset, - void *data, - unsigned int len); - -static int -hfa384x_dowmem(struct hfa384x *hw, - u16 page, - u16 offset, - void *data, - unsigned int len); - -static int hfa384x_isgood_pdrcode(u16 pdrcode); - -static inline const char *ctlxstr(enum ctlx_state s) -{ - static const char * const ctlx_str[] = { - "Initial state", - "Complete", - "Request failed", - "Request pending", - "Request packet submitted", - "Request packet completed", - "Response packet completed" - }; - - return ctlx_str[s]; -}; - -static inline struct hfa384x_usbctlx *get_active_ctlx(struct hfa384x *hw) -{ - return list_entry(hw->ctlxq.active.next, struct hfa384x_usbctlx, list); -} - -#ifdef DEBUG_USB -void dbprint_urb(struct urb *urb) -{ - pr_debug("urb->pipe=0x%08x\n", urb->pipe); - pr_debug("urb->status=0x%08x\n", urb->status); - pr_debug("urb->transfer_flags=0x%08x\n", urb->transfer_flags); - pr_debug("urb->transfer_buffer=0x%08x\n", - (unsigned int)urb->transfer_buffer); - pr_debug("urb->transfer_buffer_length=0x%08x\n", - urb->transfer_buffer_length); - pr_debug("urb->actual_length=0x%08x\n", urb->actual_length); - pr_debug("urb->setup_packet(ctl)=0x%08x\n", - (unsigned int)urb->setup_packet); - pr_debug("urb->start_frame(iso/irq)=0x%08x\n", urb->start_frame); - pr_debug("urb->interval(irq)=0x%08x\n", urb->interval); - pr_debug("urb->error_count(iso)=0x%08x\n", urb->error_count); - pr_debug("urb->context=0x%08x\n", (unsigned int)urb->context); - pr_debug("urb->complete=0x%08x\n", (unsigned int)urb->complete); -} -#endif - -/*---------------------------------------------------------------- - * submit_rx_urb - * - * Listen for input data on the BULK-IN pipe. If the pipe has - * stalled then schedule it to be reset. - * - * Arguments: - * hw device struct - * memflags memory allocation flags - * - * Returns: - * error code from submission - * - * Call context: - * Any - *---------------------------------------------------------------- - */ -static int submit_rx_urb(struct hfa384x *hw, gfp_t memflags) -{ - struct sk_buff *skb; - int result; - - skb = dev_alloc_skb(sizeof(union hfa384x_usbin)); - if (!skb) { - result = -ENOMEM; - goto done; - } - - /* Post the IN urb */ - usb_fill_bulk_urb(&hw->rx_urb, hw->usb, - hw->endp_in, - skb->data, sizeof(union hfa384x_usbin), - hfa384x_usbin_callback, hw->wlandev); - - hw->rx_urb_skb = skb; - - result = -ENOLINK; - if (!hw->wlandev->hwremoved && - !test_bit(WORK_RX_HALT, &hw->usb_flags)) { - result = usb_submit_urb(&hw->rx_urb, memflags); - - /* Check whether we need to reset the RX pipe */ - if (result == -EPIPE) { - netdev_warn(hw->wlandev->netdev, - "%s rx pipe stalled: requesting reset\n", - hw->wlandev->netdev->name); - if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags)) - schedule_work(&hw->usb_work); - } - } - - /* Don't leak memory if anything should go wrong */ - if (result != 0) { - dev_kfree_skb(skb); - hw->rx_urb_skb = NULL; - } - -done: - return result; -} - -/*---------------------------------------------------------------- - * submit_tx_urb - * - * Prepares and submits the URB of transmitted data. If the - * submission fails then it will schedule the output pipe to - * be reset. - * - * Arguments: - * hw device struct - * tx_urb URB of data for transmission - * memflags memory allocation flags - * - * Returns: - * error code from submission - * - * Call context: - * Any - *---------------------------------------------------------------- - */ -static int submit_tx_urb(struct hfa384x *hw, struct urb *tx_urb, gfp_t memflags) -{ - struct net_device *netdev = hw->wlandev->netdev; - int result; - - result = -ENOLINK; - if (netif_running(netdev)) { - if (!hw->wlandev->hwremoved && - !test_bit(WORK_TX_HALT, &hw->usb_flags)) { - result = usb_submit_urb(tx_urb, memflags); - - /* Test whether we need to reset the TX pipe */ - if (result == -EPIPE) { - netdev_warn(hw->wlandev->netdev, - "%s tx pipe stalled: requesting reset\n", - netdev->name); - set_bit(WORK_TX_HALT, &hw->usb_flags); - schedule_work(&hw->usb_work); - } else if (result == 0) { - netif_stop_queue(netdev); - } - } - } - - return result; -} - -/*---------------------------------------------------------------- - * hfa394x_usb_defer - * - * There are some things that the USB stack cannot do while - * in interrupt context, so we arrange this function to run - * in process context. - * - * Arguments: - * hw device structure - * - * Returns: - * nothing - * - * Call context: - * process (by design) - *---------------------------------------------------------------- - */ -static void hfa384x_usb_defer(struct work_struct *data) -{ - struct hfa384x *hw = container_of(data, struct hfa384x, usb_work); - struct net_device *netdev = hw->wlandev->netdev; - - /* Don't bother trying to reset anything if the plug - * has been pulled ... - */ - if (hw->wlandev->hwremoved) - return; - - /* Reception has stopped: try to reset the input pipe */ - if (test_bit(WORK_RX_HALT, &hw->usb_flags)) { - int ret; - - usb_kill_urb(&hw->rx_urb); /* Cannot be holding spinlock! */ - - ret = usb_clear_halt(hw->usb, hw->endp_in); - if (ret != 0) { - netdev_err(hw->wlandev->netdev, - "Failed to clear rx pipe for %s: err=%d\n", - netdev->name, ret); - } else { - netdev_info(hw->wlandev->netdev, "%s rx pipe reset complete.\n", - netdev->name); - clear_bit(WORK_RX_HALT, &hw->usb_flags); - set_bit(WORK_RX_RESUME, &hw->usb_flags); - } - } - - /* Resume receiving data back from the device. */ - if (test_bit(WORK_RX_RESUME, &hw->usb_flags)) { - int ret; - - ret = submit_rx_urb(hw, GFP_KERNEL); - if (ret != 0) { - netdev_err(hw->wlandev->netdev, - "Failed to resume %s rx pipe.\n", - netdev->name); - } else { - clear_bit(WORK_RX_RESUME, &hw->usb_flags); - } - } - - /* Transmission has stopped: try to reset the output pipe */ - if (test_bit(WORK_TX_HALT, &hw->usb_flags)) { - int ret; - - usb_kill_urb(&hw->tx_urb); - ret = usb_clear_halt(hw->usb, hw->endp_out); - if (ret != 0) { - netdev_err(hw->wlandev->netdev, - "Failed to clear tx pipe for %s: err=%d\n", - netdev->name, ret); - } else { - netdev_info(hw->wlandev->netdev, "%s tx pipe reset complete.\n", - netdev->name); - clear_bit(WORK_TX_HALT, &hw->usb_flags); - set_bit(WORK_TX_RESUME, &hw->usb_flags); - - /* Stopping the BULK-OUT pipe also blocked - * us from sending any more CTLX URBs, so - * we need to re-run our queue ... - */ - hfa384x_usbctlxq_run(hw); - } - } - - /* Resume transmitting. */ - if (test_and_clear_bit(WORK_TX_RESUME, &hw->usb_flags)) - netif_wake_queue(hw->wlandev->netdev); -} - -/*---------------------------------------------------------------- - * hfa384x_create - * - * Sets up the struct hfa384x data structure for use. Note this - * does _not_ initialize the actual hardware, just the data structures - * we use to keep track of its state. - * - * Arguments: - * hw device structure - * irq device irq number - * iobase i/o base address for register access - * membase memory base address for register access - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -void hfa384x_create(struct hfa384x *hw, struct usb_device *usb) -{ - hw->usb = usb; - - /* Set up the waitq */ - init_waitqueue_head(&hw->cmdq); - - /* Initialize the command queue */ - spin_lock_init(&hw->ctlxq.lock); - INIT_LIST_HEAD(&hw->ctlxq.pending); - INIT_LIST_HEAD(&hw->ctlxq.active); - INIT_LIST_HEAD(&hw->ctlxq.completing); - INIT_LIST_HEAD(&hw->ctlxq.reapable); - - /* Initialize the authentication queue */ - skb_queue_head_init(&hw->authq); - - INIT_WORK(&hw->reaper_bh, hfa384x_usbctlx_reaper_task); - INIT_WORK(&hw->completion_bh, hfa384x_usbctlx_completion_task); - INIT_WORK(&hw->link_bh, prism2sta_processing_defer); - INIT_WORK(&hw->usb_work, hfa384x_usb_defer); - - timer_setup(&hw->throttle, hfa384x_usb_throttlefn, 0); - - timer_setup(&hw->resptimer, hfa384x_usbctlx_resptimerfn, 0); - - timer_setup(&hw->reqtimer, hfa384x_usbctlx_reqtimerfn, 0); - - usb_init_urb(&hw->rx_urb); - usb_init_urb(&hw->tx_urb); - usb_init_urb(&hw->ctlx_urb); - - hw->link_status = HFA384x_LINK_NOTCONNECTED; - hw->state = HFA384x_STATE_INIT; - - INIT_WORK(&hw->commsqual_bh, prism2sta_commsqual_defer); - timer_setup(&hw->commsqual_timer, prism2sta_commsqual_timer, 0); -} - -/*---------------------------------------------------------------- - * hfa384x_destroy - * - * Partner to hfa384x_create(). This function cleans up the hw - * structure so that it can be freed by the caller using a simple - * kfree. Currently, this function is just a placeholder. If, at some - * point in the future, an hw in the 'shutdown' state requires a 'deep' - * kfree, this is where it should be done. Note that if this function - * is called on a _running_ hw structure, the drvr_stop() function is - * called. - * - * Arguments: - * hw device structure - * - * Returns: - * nothing, this function is not allowed to fail. - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -void hfa384x_destroy(struct hfa384x *hw) -{ - struct sk_buff *skb; - - if (hw->state == HFA384x_STATE_RUNNING) - hfa384x_drvr_stop(hw); - hw->state = HFA384x_STATE_PREINIT; - - kfree(hw->scanresults); - hw->scanresults = NULL; - - /* Now to clean out the auth queue */ - while ((skb = skb_dequeue(&hw->authq))) - dev_kfree_skb(skb); -} - -static struct hfa384x_usbctlx *usbctlx_alloc(void) -{ - struct hfa384x_usbctlx *ctlx; - - ctlx = kzalloc(sizeof(*ctlx), - in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); - if (ctlx) - init_completion(&ctlx->done); - - return ctlx; -} - -static int -usbctlx_get_status(const struct hfa384x_usb_statusresp *cmdresp, - struct hfa384x_cmdresult *result) -{ - result->status = le16_to_cpu(cmdresp->status); - result->resp0 = le16_to_cpu(cmdresp->resp0); - result->resp1 = le16_to_cpu(cmdresp->resp1); - result->resp2 = le16_to_cpu(cmdresp->resp2); - - pr_debug("cmdresult:status=0x%04x resp0=0x%04x resp1=0x%04x resp2=0x%04x\n", - result->status, result->resp0, result->resp1, result->resp2); - - return result->status & HFA384x_STATUS_RESULT; -} - -static void -usbctlx_get_rridresult(const struct hfa384x_usb_rridresp *rridresp, - struct hfa384x_rridresult *result) -{ - result->rid = le16_to_cpu(rridresp->rid); - result->riddata = rridresp->data; - result->riddata_len = ((le16_to_cpu(rridresp->frmlen) - 1) * 2); -} - -/*---------------------------------------------------------------- - * Completor object: - * This completor must be passed to hfa384x_usbctlx_complete_sync() - * when processing a CTLX that returns a struct hfa384x_cmdresult structure. - *---------------------------------------------------------------- - */ -struct usbctlx_cmd_completor { - struct usbctlx_completor head; - - const struct hfa384x_usb_statusresp *cmdresp; - struct hfa384x_cmdresult *result; -}; - -static inline int usbctlx_cmd_completor_fn(struct usbctlx_completor *head) -{ - struct usbctlx_cmd_completor *complete; - - complete = (struct usbctlx_cmd_completor *)head; - return usbctlx_get_status(complete->cmdresp, complete->result); -} - -static inline struct usbctlx_completor * -init_cmd_completor(struct usbctlx_cmd_completor *completor, - const struct hfa384x_usb_statusresp *cmdresp, - struct hfa384x_cmdresult *result) -{ - completor->head.complete = usbctlx_cmd_completor_fn; - completor->cmdresp = cmdresp; - completor->result = result; - return &completor->head; -} - -/*---------------------------------------------------------------- - * Completor object: - * This completor must be passed to hfa384x_usbctlx_complete_sync() - * when processing a CTLX that reads a RID. - *---------------------------------------------------------------- - */ -struct usbctlx_rrid_completor { - struct usbctlx_completor head; - - const struct hfa384x_usb_rridresp *rridresp; - void *riddata; - unsigned int riddatalen; -}; - -static int usbctlx_rrid_completor_fn(struct usbctlx_completor *head) -{ - struct usbctlx_rrid_completor *complete; - struct hfa384x_rridresult rridresult; - - complete = (struct usbctlx_rrid_completor *)head; - usbctlx_get_rridresult(complete->rridresp, &rridresult); - - /* Validate the length, note body len calculation in bytes */ - if (rridresult.riddata_len != complete->riddatalen) { - pr_warn("RID len mismatch, rid=0x%04x hlen=%d fwlen=%d\n", - rridresult.rid, - complete->riddatalen, rridresult.riddata_len); - return -ENODATA; - } - - memcpy(complete->riddata, rridresult.riddata, complete->riddatalen); - return 0; -} - -static inline struct usbctlx_completor * -init_rrid_completor(struct usbctlx_rrid_completor *completor, - const struct hfa384x_usb_rridresp *rridresp, - void *riddata, - unsigned int riddatalen) -{ - completor->head.complete = usbctlx_rrid_completor_fn; - completor->rridresp = rridresp; - completor->riddata = riddata; - completor->riddatalen = riddatalen; - return &completor->head; -} - -/*---------------------------------------------------------------- - * Completor object: - * Interprets the results of a synchronous RID-write - *---------------------------------------------------------------- - */ -#define init_wrid_completor init_cmd_completor - -/*---------------------------------------------------------------- - * Completor object: - * Interprets the results of a synchronous memory-write - *---------------------------------------------------------------- - */ -#define init_wmem_completor init_cmd_completor - -/*---------------------------------------------------------------- - * Completor object: - * Interprets the results of a synchronous memory-read - *---------------------------------------------------------------- - */ -struct usbctlx_rmem_completor { - struct usbctlx_completor head; - - const struct hfa384x_usb_rmemresp *rmemresp; - void *data; - unsigned int len; -}; - -static int usbctlx_rmem_completor_fn(struct usbctlx_completor *head) -{ - struct usbctlx_rmem_completor *complete = - (struct usbctlx_rmem_completor *)head; - - pr_debug("rmemresp:len=%d\n", complete->rmemresp->frmlen); - memcpy(complete->data, complete->rmemresp->data, complete->len); - return 0; -} - -static inline struct usbctlx_completor * -init_rmem_completor(struct usbctlx_rmem_completor *completor, - struct hfa384x_usb_rmemresp *rmemresp, - void *data, - unsigned int len) -{ - completor->head.complete = usbctlx_rmem_completor_fn; - completor->rmemresp = rmemresp; - completor->data = data; - completor->len = len; - return &completor->head; -} - -/*---------------------------------------------------------------- - * hfa384x_cb_status - * - * Ctlx_complete handler for async CMD type control exchanges. - * mark the hw struct as such. - * - * Note: If the handling is changed here, it should probably be - * changed in docmd as well. - * - * Arguments: - * hw hw struct - * ctlx completed CTLX - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_cb_status(struct hfa384x *hw, - const struct hfa384x_usbctlx *ctlx) -{ - if (ctlx->usercb) { - struct hfa384x_cmdresult cmdresult; - - if (ctlx->state != CTLX_COMPLETE) { - memset(&cmdresult, 0, sizeof(cmdresult)); - cmdresult.status = - HFA384x_STATUS_RESULT_SET(HFA384x_CMD_ERR); - } else { - usbctlx_get_status(&ctlx->inbuf.cmdresp, &cmdresult); - } - - ctlx->usercb(hw, &cmdresult, ctlx->usercb_data); - } -} - -/*---------------------------------------------------------------- - * hfa384x_cmd_initialize - * - * Issues the initialize command and sets the hw->state based - * on the result. - * - * Arguments: - * hw device structure - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_cmd_initialize(struct hfa384x *hw) -{ - int result = 0; - int i; - struct hfa384x_metacmd cmd; - - cmd.cmd = HFA384x_CMDCODE_INIT; - cmd.parm0 = 0; - cmd.parm1 = 0; - cmd.parm2 = 0; - - result = hfa384x_docmd(hw, &cmd); - - pr_debug("cmdresp.init: status=0x%04x, resp0=0x%04x, resp1=0x%04x, resp2=0x%04x\n", - cmd.result.status, - cmd.result.resp0, cmd.result.resp1, cmd.result.resp2); - if (result == 0) { - for (i = 0; i < HFA384x_NUMPORTS_MAX; i++) - hw->port_enabled[i] = 0; - } - - hw->link_status = HFA384x_LINK_NOTCONNECTED; - - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_cmd_disable - * - * Issues the disable command to stop communications on one of - * the MACs 'ports'. - * - * Arguments: - * hw device structure - * macport MAC port number (host order) - * - * Returns: - * 0 success - * >0 f/w reported failure - f/w status code - * <0 driver reported error (timeout|bad arg) - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_cmd_disable(struct hfa384x *hw, u16 macport) -{ - struct hfa384x_metacmd cmd; - - cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DISABLE) | - HFA384x_CMD_MACPORT_SET(macport); - cmd.parm0 = 0; - cmd.parm1 = 0; - cmd.parm2 = 0; - - return hfa384x_docmd(hw, &cmd); -} - -/*---------------------------------------------------------------- - * hfa384x_cmd_enable - * - * Issues the enable command to enable communications on one of - * the MACs 'ports'. - * - * Arguments: - * hw device structure - * macport MAC port number - * - * Returns: - * 0 success - * >0 f/w reported failure - f/w status code - * <0 driver reported error (timeout|bad arg) - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_cmd_enable(struct hfa384x *hw, u16 macport) -{ - struct hfa384x_metacmd cmd; - - cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ENABLE) | - HFA384x_CMD_MACPORT_SET(macport); - cmd.parm0 = 0; - cmd.parm1 = 0; - cmd.parm2 = 0; - - return hfa384x_docmd(hw, &cmd); -} - -/*---------------------------------------------------------------- - * hfa384x_cmd_monitor - * - * Enables the 'monitor mode' of the MAC. Here's the description of - * monitor mode that I've received thus far: - * - * "The "monitor mode" of operation is that the MAC passes all - * frames for which the PLCP checks are correct. All received - * MPDUs are passed to the host with MAC Port = 7, with a - * receive status of good, FCS error, or undecryptable. Passing - * certain MPDUs is a violation of the 802.11 standard, but useful - * for a debugging tool." Normal communication is not possible - * while monitor mode is enabled. - * - * Arguments: - * hw device structure - * enable a code (0x0b|0x0f) that enables/disables - * monitor mode. (host order) - * - * Returns: - * 0 success - * >0 f/w reported failure - f/w status code - * <0 driver reported error (timeout|bad arg) - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_cmd_monitor(struct hfa384x *hw, u16 enable) -{ - struct hfa384x_metacmd cmd; - - cmd.cmd = HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_MONITOR) | - HFA384x_CMD_AINFO_SET(enable); - cmd.parm0 = 0; - cmd.parm1 = 0; - cmd.parm2 = 0; - - return hfa384x_docmd(hw, &cmd); -} - -/*---------------------------------------------------------------- - * hfa384x_cmd_download - * - * Sets the controls for the MAC controller code/data download - * process. The arguments set the mode and address associated - * with a download. Note that the aux registers should be enabled - * prior to setting one of the download enable modes. - * - * Arguments: - * hw device structure - * mode 0 - Disable programming and begin code exec - * 1 - Enable volatile mem programming - * 2 - Enable non-volatile mem programming - * 3 - Program non-volatile section from NV download - * buffer. - * (host order) - * lowaddr - * highaddr For mode 1, sets the high & low order bits of - * the "destination address". This address will be - * the execution start address when download is - * subsequently disabled. - * For mode 2, sets the high & low order bits of - * the destination in NV ram. - * For modes 0 & 3, should be zero. (host order) - * NOTE: these are CMD format. - * codelen Length of the data to write in mode 2, - * zero otherwise. (host order) - * - * Returns: - * 0 success - * >0 f/w reported failure - f/w status code - * <0 driver reported error (timeout|bad arg) - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_cmd_download(struct hfa384x *hw, u16 mode, u16 lowaddr, - u16 highaddr, u16 codelen) -{ - struct hfa384x_metacmd cmd; - - pr_debug("mode=%d, lowaddr=0x%04x, highaddr=0x%04x, codelen=%d\n", - mode, lowaddr, highaddr, codelen); - - cmd.cmd = (HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_DOWNLD) | - HFA384x_CMD_PROGMODE_SET(mode)); - - cmd.parm0 = lowaddr; - cmd.parm1 = highaddr; - cmd.parm2 = codelen; - - return hfa384x_docmd(hw, &cmd); -} - -/*---------------------------------------------------------------- - * hfa384x_corereset - * - * Perform a reset of the hfa38xx MAC core. We assume that the hw - * structure is in its "created" state. That is, it is initialized - * with proper values. Note that if a reset is done after the - * device has been active for awhile, the caller might have to clean - * up some leftover cruft in the hw structure. - * - * Arguments: - * hw device structure - * holdtime how long (in ms) to hold the reset - * settletime how long (in ms) to wait after releasing - * the reset - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_corereset(struct hfa384x *hw, int holdtime, - int settletime, int genesis) -{ - int result; - - result = usb_reset_device(hw->usb); - if (result < 0) { - netdev_err(hw->wlandev->netdev, "usb_reset_device() failed, result=%d.\n", - result); - } - - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_usbctlx_complete_sync - * - * Waits for a synchronous CTLX object to complete, - * and then handles the response. - * - * Arguments: - * hw device structure - * ctlx CTLX ptr - * completor functor object to decide what to - * do with the CTLX's result. - * - * Returns: - * 0 Success - * -ERESTARTSYS Interrupted by a signal - * -EIO CTLX failed - * -ENODEV Adapter was unplugged - * ??? Result from completor - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -static int hfa384x_usbctlx_complete_sync(struct hfa384x *hw, - struct hfa384x_usbctlx *ctlx, - struct usbctlx_completor *completor) -{ - unsigned long flags; - int result; - - result = wait_for_completion_interruptible(&ctlx->done); - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - /* - * We can only handle the CTLX if the USB disconnect - * function has not run yet ... - */ -cleanup: - if (hw->wlandev->hwremoved) { - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - result = -ENODEV; - } else if (result != 0) { - int runqueue = 0; - - /* - * We were probably interrupted, so delete - * this CTLX asynchronously, kill the timers - * and the URB, and then start the next - * pending CTLX. - * - * NOTE: We can only delete the timers and - * the URB if this CTLX is active. - */ - if (ctlx == get_active_ctlx(hw)) { - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - - del_timer_sync(&hw->reqtimer); - del_timer_sync(&hw->resptimer); - hw->req_timer_done = 1; - hw->resp_timer_done = 1; - usb_kill_urb(&hw->ctlx_urb); - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - runqueue = 1; - - /* - * This scenario is so unlikely that I'm - * happy with a grubby "goto" solution ... - */ - if (hw->wlandev->hwremoved) - goto cleanup; - } - - /* - * The completion task will send this CTLX - * to the reaper the next time it runs. We - * are no longer in a hurry. - */ - ctlx->reapable = 1; - ctlx->state = CTLX_REQ_FAILED; - list_move_tail(&ctlx->list, &hw->ctlxq.completing); - - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - - if (runqueue) - hfa384x_usbctlxq_run(hw); - } else { - if (ctlx->state == CTLX_COMPLETE) { - result = completor->complete(completor); - } else { - netdev_warn(hw->wlandev->netdev, "CTLX[%d] error: state(%s)\n", - le16_to_cpu(ctlx->outbuf.type), - ctlxstr(ctlx->state)); - result = -EIO; - } - - list_del(&ctlx->list); - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - kfree(ctlx); - } - - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_docmd - * - * Constructs a command CTLX and submits it. - * - * NOTE: Any changes to the 'post-submit' code in this function - * need to be carried over to hfa384x_cbcmd() since the handling - * is virtually identical. - * - * Arguments: - * hw device structure - * cmd cmd structure. Includes all arguments and result - * data points. All in host order. in host order - * - * Returns: - * 0 success - * -EIO CTLX failure - * -ERESTARTSYS Awakened on signal - * >0 command indicated error, Status and Resp0-2 are - * in hw structure. - * - * Side effects: - * - * - * Call context: - * process - *---------------------------------------------------------------- - */ -static inline int -hfa384x_docmd(struct hfa384x *hw, - struct hfa384x_metacmd *cmd) -{ - int result; - struct hfa384x_usbctlx *ctlx; - - ctlx = usbctlx_alloc(); - if (!ctlx) { - result = -ENOMEM; - goto done; - } - - /* Initialize the command */ - ctlx->outbuf.cmdreq.type = cpu_to_le16(HFA384x_USB_CMDREQ); - ctlx->outbuf.cmdreq.cmd = cpu_to_le16(cmd->cmd); - ctlx->outbuf.cmdreq.parm0 = cpu_to_le16(cmd->parm0); - ctlx->outbuf.cmdreq.parm1 = cpu_to_le16(cmd->parm1); - ctlx->outbuf.cmdreq.parm2 = cpu_to_le16(cmd->parm2); - - ctlx->outbufsize = sizeof(ctlx->outbuf.cmdreq); - - pr_debug("cmdreq: cmd=0x%04x parm0=0x%04x parm1=0x%04x parm2=0x%04x\n", - cmd->cmd, cmd->parm0, cmd->parm1, cmd->parm2); - - ctlx->reapable = DOWAIT; - ctlx->cmdcb = NULL; - ctlx->usercb = NULL; - ctlx->usercb_data = NULL; - - result = hfa384x_usbctlx_submit(hw, ctlx); - if (result != 0) { - kfree(ctlx); - } else { - struct usbctlx_cmd_completor cmd_completor; - struct usbctlx_completor *completor; - - completor = init_cmd_completor(&cmd_completor, - &ctlx->inbuf.cmdresp, - &cmd->result); - - result = hfa384x_usbctlx_complete_sync(hw, ctlx, completor); - } - -done: - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_dorrid - * - * Constructs a read rid CTLX and issues it. - * - * NOTE: Any changes to the 'post-submit' code in this function - * need to be carried over to hfa384x_cbrrid() since the handling - * is virtually identical. - * - * Arguments: - * hw device structure - * mode DOWAIT or DOASYNC - * rid Read RID number (host order) - * riddata Caller supplied buffer that MAC formatted RID.data - * record will be written to for DOWAIT calls. Should - * be NULL for DOASYNC calls. - * riddatalen Buffer length for DOWAIT calls. Zero for DOASYNC calls. - * cmdcb command callback for async calls, NULL for DOWAIT calls - * usercb user callback for async calls, NULL for DOWAIT calls - * usercb_data user supplied data pointer for async calls, NULL - * for DOWAIT calls - * - * Returns: - * 0 success - * -EIO CTLX failure - * -ERESTARTSYS Awakened on signal - * -ENODATA riddatalen != macdatalen - * >0 command indicated error, Status and Resp0-2 are - * in hw structure. - * - * Side effects: - * - * Call context: - * interrupt (DOASYNC) - * process (DOWAIT or DOASYNC) - *---------------------------------------------------------------- - */ -static int -hfa384x_dorrid(struct hfa384x *hw, - enum cmd_mode mode, - u16 rid, - void *riddata, - unsigned int riddatalen, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data) -{ - int result; - struct hfa384x_usbctlx *ctlx; - - ctlx = usbctlx_alloc(); - if (!ctlx) { - result = -ENOMEM; - goto done; - } - - /* Initialize the command */ - ctlx->outbuf.rridreq.type = cpu_to_le16(HFA384x_USB_RRIDREQ); - ctlx->outbuf.rridreq.frmlen = - cpu_to_le16(sizeof(ctlx->outbuf.rridreq.rid)); - ctlx->outbuf.rridreq.rid = cpu_to_le16(rid); - - ctlx->outbufsize = sizeof(ctlx->outbuf.rridreq); - - ctlx->reapable = mode; - ctlx->cmdcb = cmdcb; - ctlx->usercb = usercb; - ctlx->usercb_data = usercb_data; - - /* Submit the CTLX */ - result = hfa384x_usbctlx_submit(hw, ctlx); - if (result != 0) { - kfree(ctlx); - } else if (mode == DOWAIT) { - struct usbctlx_rrid_completor completor; - - result = - hfa384x_usbctlx_complete_sync(hw, ctlx, - init_rrid_completor - (&completor, - &ctlx->inbuf.rridresp, - riddata, riddatalen)); - } - -done: - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_dowrid - * - * Constructs a write rid CTLX and issues it. - * - * NOTE: Any changes to the 'post-submit' code in this function - * need to be carried over to hfa384x_cbwrid() since the handling - * is virtually identical. - * - * Arguments: - * hw device structure - * enum cmd_mode DOWAIT or DOASYNC - * rid RID code - * riddata Data portion of RID formatted for MAC - * riddatalen Length of the data portion in bytes - * cmdcb command callback for async calls, NULL for DOWAIT calls - * usercb user callback for async calls, NULL for DOWAIT calls - * usercb_data user supplied data pointer for async calls - * - * Returns: - * 0 success - * -ETIMEDOUT timed out waiting for register ready or - * command completion - * >0 command indicated error, Status and Resp0-2 are - * in hw structure. - * - * Side effects: - * - * Call context: - * interrupt (DOASYNC) - * process (DOWAIT or DOASYNC) - *---------------------------------------------------------------- - */ -static int -hfa384x_dowrid(struct hfa384x *hw, - enum cmd_mode mode, - u16 rid, - void *riddata, - unsigned int riddatalen, - ctlx_cmdcb_t cmdcb, ctlx_usercb_t usercb, void *usercb_data) -{ - int result; - struct hfa384x_usbctlx *ctlx; - - ctlx = usbctlx_alloc(); - if (!ctlx) { - result = -ENOMEM; - goto done; - } - - /* Initialize the command */ - ctlx->outbuf.wridreq.type = cpu_to_le16(HFA384x_USB_WRIDREQ); - ctlx->outbuf.wridreq.frmlen = cpu_to_le16((sizeof - (ctlx->outbuf.wridreq.rid) + - riddatalen + 1) / 2); - ctlx->outbuf.wridreq.rid = cpu_to_le16(rid); - memcpy(ctlx->outbuf.wridreq.data, riddata, riddatalen); - - ctlx->outbufsize = sizeof(ctlx->outbuf.wridreq.type) + - sizeof(ctlx->outbuf.wridreq.frmlen) + - sizeof(ctlx->outbuf.wridreq.rid) + riddatalen; - - ctlx->reapable = mode; - ctlx->cmdcb = cmdcb; - ctlx->usercb = usercb; - ctlx->usercb_data = usercb_data; - - /* Submit the CTLX */ - result = hfa384x_usbctlx_submit(hw, ctlx); - if (result != 0) { - kfree(ctlx); - } else if (mode == DOWAIT) { - struct usbctlx_cmd_completor completor; - struct hfa384x_cmdresult wridresult; - - result = hfa384x_usbctlx_complete_sync(hw, - ctlx, - init_wrid_completor - (&completor, - &ctlx->inbuf.wridresp, - &wridresult)); - } - -done: - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_dormem - * - * Constructs a readmem CTLX and issues it. - * - * NOTE: Any changes to the 'post-submit' code in this function - * need to be carried over to hfa384x_cbrmem() since the handling - * is virtually identical. - * - * Arguments: - * hw device structure - * page MAC address space page (CMD format) - * offset MAC address space offset - * data Ptr to data buffer to receive read - * len Length of the data to read (max == 2048) - * - * Returns: - * 0 success - * -ETIMEDOUT timed out waiting for register ready or - * command completion - * >0 command indicated error, Status and Resp0-2 are - * in hw structure. - * - * Side effects: - * - * Call context: - * process (DOWAIT) - *---------------------------------------------------------------- - */ -static int -hfa384x_dormem(struct hfa384x *hw, - u16 page, - u16 offset, - void *data, - unsigned int len) -{ - int result; - struct hfa384x_usbctlx *ctlx; - - ctlx = usbctlx_alloc(); - if (!ctlx) { - result = -ENOMEM; - goto done; - } - - /* Initialize the command */ - ctlx->outbuf.rmemreq.type = cpu_to_le16(HFA384x_USB_RMEMREQ); - ctlx->outbuf.rmemreq.frmlen = - cpu_to_le16(sizeof(ctlx->outbuf.rmemreq.offset) + - sizeof(ctlx->outbuf.rmemreq.page) + len); - ctlx->outbuf.rmemreq.offset = cpu_to_le16(offset); - ctlx->outbuf.rmemreq.page = cpu_to_le16(page); - - ctlx->outbufsize = sizeof(ctlx->outbuf.rmemreq); - - pr_debug("type=0x%04x frmlen=%d offset=0x%04x page=0x%04x\n", - ctlx->outbuf.rmemreq.type, - ctlx->outbuf.rmemreq.frmlen, - ctlx->outbuf.rmemreq.offset, ctlx->outbuf.rmemreq.page); - - pr_debug("pktsize=%zd\n", ROUNDUP64(sizeof(ctlx->outbuf.rmemreq))); - - ctlx->reapable = DOWAIT; - ctlx->cmdcb = NULL; - ctlx->usercb = NULL; - ctlx->usercb_data = NULL; - - result = hfa384x_usbctlx_submit(hw, ctlx); - if (result != 0) { - kfree(ctlx); - } else { - struct usbctlx_rmem_completor completor; - - result = - hfa384x_usbctlx_complete_sync(hw, ctlx, - init_rmem_completor - (&completor, - &ctlx->inbuf.rmemresp, data, - len)); - } - -done: - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_dowmem - * - * Constructs a writemem CTLX and issues it. - * - * NOTE: Any changes to the 'post-submit' code in this function - * need to be carried over to hfa384x_cbwmem() since the handling - * is virtually identical. - * - * Arguments: - * hw device structure - * page MAC address space page (CMD format) - * offset MAC address space offset - * data Ptr to data buffer containing write data - * len Length of the data to read (max == 2048) - * - * Returns: - * 0 success - * -ETIMEDOUT timed out waiting for register ready or - * command completion - * >0 command indicated error, Status and Resp0-2 are - * in hw structure. - * - * Side effects: - * - * Call context: - * interrupt (DOWAIT) - * process (DOWAIT) - *---------------------------------------------------------------- - */ -static int -hfa384x_dowmem(struct hfa384x *hw, - u16 page, - u16 offset, - void *data, - unsigned int len) -{ - int result; - struct hfa384x_usbctlx *ctlx; - - pr_debug("page=0x%04x offset=0x%04x len=%d\n", page, offset, len); - - ctlx = usbctlx_alloc(); - if (!ctlx) { - result = -ENOMEM; - goto done; - } - - /* Initialize the command */ - ctlx->outbuf.wmemreq.type = cpu_to_le16(HFA384x_USB_WMEMREQ); - ctlx->outbuf.wmemreq.frmlen = - cpu_to_le16(sizeof(ctlx->outbuf.wmemreq.offset) + - sizeof(ctlx->outbuf.wmemreq.page) + len); - ctlx->outbuf.wmemreq.offset = cpu_to_le16(offset); - ctlx->outbuf.wmemreq.page = cpu_to_le16(page); - memcpy(ctlx->outbuf.wmemreq.data, data, len); - - ctlx->outbufsize = sizeof(ctlx->outbuf.wmemreq.type) + - sizeof(ctlx->outbuf.wmemreq.frmlen) + - sizeof(ctlx->outbuf.wmemreq.offset) + - sizeof(ctlx->outbuf.wmemreq.page) + len; - - ctlx->reapable = DOWAIT; - ctlx->cmdcb = NULL; - ctlx->usercb = NULL; - ctlx->usercb_data = NULL; - - result = hfa384x_usbctlx_submit(hw, ctlx); - if (result != 0) { - kfree(ctlx); - } else { - struct usbctlx_cmd_completor completor; - struct hfa384x_cmdresult wmemresult; - - result = hfa384x_usbctlx_complete_sync(hw, - ctlx, - init_wmem_completor - (&completor, - &ctlx->inbuf.wmemresp, - &wmemresult)); - } - -done: - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_disable - * - * Issues the disable command to stop communications on one of - * the MACs 'ports'. Only macport 0 is valid for stations. - * APs may also disable macports 1-6. Only ports that have been - * previously enabled may be disabled. - * - * Arguments: - * hw device structure - * macport MAC port number (host order) - * - * Returns: - * 0 success - * >0 f/w reported failure - f/w status code - * <0 driver reported error (timeout|bad arg) - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_disable(struct hfa384x *hw, u16 macport) -{ - int result = 0; - - if ((!hw->isap && macport != 0) || - (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || - !(hw->port_enabled[macport])) { - result = -EINVAL; - } else { - result = hfa384x_cmd_disable(hw, macport); - if (result == 0) - hw->port_enabled[macport] = 0; - } - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_enable - * - * Issues the enable command to enable communications on one of - * the MACs 'ports'. Only macport 0 is valid for stations. - * APs may also enable macports 1-6. Only ports that are currently - * disabled may be enabled. - * - * Arguments: - * hw device structure - * macport MAC port number - * - * Returns: - * 0 success - * >0 f/w reported failure - f/w status code - * <0 driver reported error (timeout|bad arg) - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_enable(struct hfa384x *hw, u16 macport) -{ - int result = 0; - - if ((!hw->isap && macport != 0) || - (hw->isap && !(macport <= HFA384x_PORTID_MAX)) || - (hw->port_enabled[macport])) { - result = -EINVAL; - } else { - result = hfa384x_cmd_enable(hw, macport); - if (result == 0) - hw->port_enabled[macport] = 1; - } - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_flashdl_enable - * - * Begins the flash download state. Checks to see that we're not - * already in a download state and that a port isn't enabled. - * Sets the download state and retrieves the flash download - * buffer location, buffer size, and timeout length. - * - * Arguments: - * hw device structure - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_flashdl_enable(struct hfa384x *hw) -{ - int result = 0; - int i; - - /* Check that a port isn't active */ - for (i = 0; i < HFA384x_PORTID_MAX; i++) { - if (hw->port_enabled[i]) { - pr_debug("called when port enabled.\n"); - return -EINVAL; - } - } - - /* Check that we're not already in a download state */ - if (hw->dlstate != HFA384x_DLSTATE_DISABLED) - return -EINVAL; - - /* Retrieve the buffer loc&size and timeout */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DOWNLOADBUFFER, - &hw->bufinfo, sizeof(hw->bufinfo)); - if (result) - return result; - - le16_to_cpus(&hw->bufinfo.page); - le16_to_cpus(&hw->bufinfo.offset); - le16_to_cpus(&hw->bufinfo.len); - result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_MAXLOADTIME, - &hw->dltimeout); - if (result) - return result; - - le16_to_cpus(&hw->dltimeout); - - pr_debug("flashdl_enable\n"); - - hw->dlstate = HFA384x_DLSTATE_FLASHENABLED; - - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_flashdl_disable - * - * Ends the flash download state. Note that this will cause the MAC - * firmware to restart. - * - * Arguments: - * hw device structure - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_flashdl_disable(struct hfa384x *hw) -{ - /* Check that we're already in the download state */ - if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED) - return -EINVAL; - - pr_debug("flashdl_enable\n"); - - /* There isn't much we can do at this point, so I don't */ - /* bother w/ the return value */ - hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0); - hw->dlstate = HFA384x_DLSTATE_DISABLED; - - return 0; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_flashdl_write - * - * Performs a FLASH download of a chunk of data. First checks to see - * that we're in the FLASH download state, then sets the download - * mode, uses the aux functions to 1) copy the data to the flash - * buffer, 2) sets the download 'write flash' mode, 3) readback and - * compare. Lather rinse, repeat as many times an necessary to get - * all the given data into flash. - * When all data has been written using this function (possibly - * repeatedly), call drvr_flashdl_disable() to end the download state - * and restart the MAC. - * - * Arguments: - * hw device structure - * daddr Card address to write to. (host order) - * buf Ptr to data to write. - * len Length of data (host order). - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_flashdl_write(struct hfa384x *hw, u32 daddr, - void *buf, u32 len) -{ - int result = 0; - u32 dlbufaddr; - int nburns; - u32 burnlen; - u32 burndaddr; - u16 burnlo; - u16 burnhi; - int nwrites; - u8 *writebuf; - u16 writepage; - u16 writeoffset; - u32 writelen; - int i; - int j; - - pr_debug("daddr=0x%08x len=%d\n", daddr, len); - - /* Check that we're in the flash download state */ - if (hw->dlstate != HFA384x_DLSTATE_FLASHENABLED) - return -EINVAL; - - netdev_info(hw->wlandev->netdev, - "Download %d bytes to flash @0x%06x\n", len, daddr); - - /* Convert to flat address for arithmetic */ - /* NOTE: dlbuffer RID stores the address in AUX format */ - dlbufaddr = - HFA384x_ADDR_AUX_MKFLAT(hw->bufinfo.page, hw->bufinfo.offset); - pr_debug("dlbuf.page=0x%04x dlbuf.offset=0x%04x dlbufaddr=0x%08x\n", - hw->bufinfo.page, hw->bufinfo.offset, dlbufaddr); - /* Calculations to determine how many fills of the dlbuffer to do - * and how many USB wmemreq's to do for each fill. At this point - * in time, the dlbuffer size and the wmemreq size are the same. - * Therefore, nwrites should always be 1. The extra complexity - * here is a hedge against future changes. - */ - - /* Figure out how many times to do the flash programming */ - nburns = len / hw->bufinfo.len; - nburns += (len % hw->bufinfo.len) ? 1 : 0; - - /* For each flash program cycle, how many USB wmemreq's are needed? */ - nwrites = hw->bufinfo.len / HFA384x_USB_RWMEM_MAXLEN; - nwrites += (hw->bufinfo.len % HFA384x_USB_RWMEM_MAXLEN) ? 1 : 0; - - /* For each burn */ - for (i = 0; i < nburns; i++) { - /* Get the dest address and len */ - burnlen = (len - (hw->bufinfo.len * i)) > hw->bufinfo.len ? - hw->bufinfo.len : (len - (hw->bufinfo.len * i)); - burndaddr = daddr + (hw->bufinfo.len * i); - burnlo = HFA384x_ADDR_CMD_MKOFF(burndaddr); - burnhi = HFA384x_ADDR_CMD_MKPAGE(burndaddr); - - netdev_info(hw->wlandev->netdev, "Writing %d bytes to flash @0x%06x\n", - burnlen, burndaddr); - - /* Set the download mode */ - result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_NV, - burnlo, burnhi, burnlen); - if (result) { - netdev_err(hw->wlandev->netdev, - "download(NV,lo=%x,hi=%x,len=%x) cmd failed, result=%d. Aborting d/l\n", - burnlo, burnhi, burnlen, result); - goto exit_proc; - } - - /* copy the data to the flash download buffer */ - for (j = 0; j < nwrites; j++) { - writebuf = buf + - (i * hw->bufinfo.len) + - (j * HFA384x_USB_RWMEM_MAXLEN); - - writepage = HFA384x_ADDR_CMD_MKPAGE(dlbufaddr + - (j * HFA384x_USB_RWMEM_MAXLEN)); - writeoffset = HFA384x_ADDR_CMD_MKOFF(dlbufaddr + - (j * HFA384x_USB_RWMEM_MAXLEN)); - - writelen = burnlen - (j * HFA384x_USB_RWMEM_MAXLEN); - writelen = writelen > HFA384x_USB_RWMEM_MAXLEN ? - HFA384x_USB_RWMEM_MAXLEN : writelen; - - result = hfa384x_dowmem(hw, - writepage, - writeoffset, - writebuf, writelen); - } - - /* set the download 'write flash' mode */ - result = hfa384x_cmd_download(hw, - HFA384x_PROGMODE_NVWRITE, - 0, 0, 0); - if (result) { - netdev_err(hw->wlandev->netdev, - "download(NVWRITE,lo=%x,hi=%x,len=%x) cmd failed, result=%d. Aborting d/l\n", - burnlo, burnhi, burnlen, result); - goto exit_proc; - } - - /* TODO: We really should do a readback and compare. */ - } - -exit_proc: - - /* Leave the firmware in the 'post-prog' mode. flashdl_disable will */ - /* actually disable programming mode. Remember, that will cause the */ - /* the firmware to effectively reset itself. */ - - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_getconfig - * - * Performs the sequence necessary to read a config/info item. - * - * Arguments: - * hw device structure - * rid config/info record id (host order) - * buf host side record buffer. Upon return it will - * contain the body portion of the record (minus the - * RID and len). - * len buffer length (in bytes, should match record length) - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * -ENODATA length mismatch between argument and retrieved - * record. - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_getconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len) -{ - return hfa384x_dorrid(hw, DOWAIT, rid, buf, len, NULL, NULL, NULL); -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_setconfig_async - * - * Performs the sequence necessary to write a config/info item. - * - * Arguments: - * hw device structure - * rid config/info record id (in host order) - * buf host side record buffer - * len buffer length (in bytes) - * usercb completion callback - * usercb_data completion callback argument - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int -hfa384x_drvr_setconfig_async(struct hfa384x *hw, - u16 rid, - void *buf, - u16 len, ctlx_usercb_t usercb, void *usercb_data) -{ - return hfa384x_dowrid(hw, DOASYNC, rid, buf, len, hfa384x_cb_status, - usercb, usercb_data); -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_ramdl_disable - * - * Ends the ram download state. - * - * Arguments: - * hw device structure - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_ramdl_disable(struct hfa384x *hw) -{ - /* Check that we're already in the download state */ - if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED) - return -EINVAL; - - pr_debug("ramdl_disable()\n"); - - /* There isn't much we can do at this point, so I don't */ - /* bother w/ the return value */ - hfa384x_cmd_download(hw, HFA384x_PROGMODE_DISABLE, 0, 0, 0); - hw->dlstate = HFA384x_DLSTATE_DISABLED; - - return 0; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_ramdl_enable - * - * Begins the ram download state. Checks to see that we're not - * already in a download state and that a port isn't enabled. - * Sets the download state and calls cmd_download with the - * ENABLE_VOLATILE subcommand and the exeaddr argument. - * - * Arguments: - * hw device structure - * exeaddr the card execution address that will be - * jumped to when ramdl_disable() is called - * (host order). - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_ramdl_enable(struct hfa384x *hw, u32 exeaddr) -{ - int result = 0; - u16 lowaddr; - u16 hiaddr; - int i; - - /* Check that a port isn't active */ - for (i = 0; i < HFA384x_PORTID_MAX; i++) { - if (hw->port_enabled[i]) { - netdev_err(hw->wlandev->netdev, - "Can't download with a macport enabled.\n"); - return -EINVAL; - } - } - - /* Check that we're not already in a download state */ - if (hw->dlstate != HFA384x_DLSTATE_DISABLED) { - netdev_err(hw->wlandev->netdev, - "Download state not disabled.\n"); - return -EINVAL; - } - - pr_debug("ramdl_enable, exeaddr=0x%08x\n", exeaddr); - - /* Call the download(1,addr) function */ - lowaddr = HFA384x_ADDR_CMD_MKOFF(exeaddr); - hiaddr = HFA384x_ADDR_CMD_MKPAGE(exeaddr); - - result = hfa384x_cmd_download(hw, HFA384x_PROGMODE_RAM, - lowaddr, hiaddr, 0); - - if (result == 0) { - /* Set the download state */ - hw->dlstate = HFA384x_DLSTATE_RAMENABLED; - } else { - pr_debug("cmd_download(0x%04x, 0x%04x) failed, result=%d.\n", - lowaddr, hiaddr, result); - } - - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_ramdl_write - * - * Performs a RAM download of a chunk of data. First checks to see - * that we're in the RAM download state, then uses the [read|write]mem USB - * commands to 1) copy the data, 2) readback and compare. The download - * state is unaffected. When all data has been written using - * this function, call drvr_ramdl_disable() to end the download state - * and restart the MAC. - * - * Arguments: - * hw device structure - * daddr Card address to write to. (host order) - * buf Ptr to data to write. - * len Length of data (host order). - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_ramdl_write(struct hfa384x *hw, u32 daddr, void *buf, u32 len) -{ - int result = 0; - int nwrites; - u8 *data = buf; - int i; - u32 curraddr; - u16 currpage; - u16 curroffset; - u16 currlen; - - /* Check that we're in the ram download state */ - if (hw->dlstate != HFA384x_DLSTATE_RAMENABLED) - return -EINVAL; - - netdev_info(hw->wlandev->netdev, "Writing %d bytes to ram @0x%06x\n", - len, daddr); - - /* How many dowmem calls? */ - nwrites = len / HFA384x_USB_RWMEM_MAXLEN; - nwrites += len % HFA384x_USB_RWMEM_MAXLEN ? 1 : 0; - - /* Do blocking wmem's */ - for (i = 0; i < nwrites; i++) { - /* make address args */ - curraddr = daddr + (i * HFA384x_USB_RWMEM_MAXLEN); - currpage = HFA384x_ADDR_CMD_MKPAGE(curraddr); - curroffset = HFA384x_ADDR_CMD_MKOFF(curraddr); - currlen = len - (i * HFA384x_USB_RWMEM_MAXLEN); - if (currlen > HFA384x_USB_RWMEM_MAXLEN) - currlen = HFA384x_USB_RWMEM_MAXLEN; - - /* Do blocking ctlx */ - result = hfa384x_dowmem(hw, - currpage, - curroffset, - data + (i * HFA384x_USB_RWMEM_MAXLEN), - currlen); - - if (result) - break; - - /* TODO: We really should have a readback. */ - } - - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_readpda - * - * Performs the sequence to read the PDA space. Note there is no - * drvr_writepda() function. Writing a PDA is - * generally implemented by a calling component via calls to - * cmd_download and writing to the flash download buffer via the - * aux regs. - * - * Arguments: - * hw device structure - * buf buffer to store PDA in - * len buffer length - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * -ETIMEDOUT timeout waiting for the cmd regs to become - * available, or waiting for the control reg - * to indicate the Aux port is enabled. - * -ENODATA the buffer does NOT contain a valid PDA. - * Either the card PDA is bad, or the auxdata - * reads are giving us garbage. - * - * - * Side effects: - * - * Call context: - * process or non-card interrupt. - *---------------------------------------------------------------- - */ -int hfa384x_drvr_readpda(struct hfa384x *hw, void *buf, unsigned int len) -{ - int result = 0; - __le16 *pda = buf; - int pdaok = 0; - int morepdrs = 1; - int currpdr = 0; /* word offset of the current pdr */ - size_t i; - u16 pdrlen; /* pdr length in bytes, host order */ - u16 pdrcode; /* pdr code, host order */ - u16 currpage; - u16 curroffset; - struct pdaloc { - u32 cardaddr; - u16 auxctl; - } pdaloc[] = { - { - HFA3842_PDA_BASE, 0}, { - HFA3841_PDA_BASE, 0}, { - HFA3841_PDA_BOGUS_BASE, 0} - }; - - /* Read the pda from each known address. */ - for (i = 0; i < ARRAY_SIZE(pdaloc); i++) { - /* Make address */ - currpage = HFA384x_ADDR_CMD_MKPAGE(pdaloc[i].cardaddr); - curroffset = HFA384x_ADDR_CMD_MKOFF(pdaloc[i].cardaddr); - - /* units of bytes */ - result = hfa384x_dormem(hw, currpage, curroffset, buf, - len); - - if (result) { - netdev_warn(hw->wlandev->netdev, - "Read from index %zd failed, continuing\n", - i); - continue; - } - - /* Test for garbage */ - pdaok = 1; /* initially assume good */ - morepdrs = 1; - while (pdaok && morepdrs) { - pdrlen = le16_to_cpu(pda[currpdr]) * 2; - pdrcode = le16_to_cpu(pda[currpdr + 1]); - /* Test the record length */ - if (pdrlen > HFA384x_PDR_LEN_MAX || pdrlen == 0) { - netdev_err(hw->wlandev->netdev, - "pdrlen invalid=%d\n", pdrlen); - pdaok = 0; - break; - } - /* Test the code */ - if (!hfa384x_isgood_pdrcode(pdrcode)) { - netdev_err(hw->wlandev->netdev, "pdrcode invalid=%d\n", - pdrcode); - pdaok = 0; - break; - } - /* Test for completion */ - if (pdrcode == HFA384x_PDR_END_OF_PDA) - morepdrs = 0; - - /* Move to the next pdr (if necessary) */ - if (morepdrs) { - /* note the access to pda[], need words here */ - currpdr += le16_to_cpu(pda[currpdr]) + 1; - } - } - if (pdaok) { - netdev_info(hw->wlandev->netdev, - "PDA Read from 0x%08x in %s space.\n", - pdaloc[i].cardaddr, - pdaloc[i].auxctl == 0 ? "EXTDS" : - pdaloc[i].auxctl == 1 ? "NV" : - pdaloc[i].auxctl == 2 ? "PHY" : - pdaloc[i].auxctl == 3 ? "ICSRAM" : - "<bogus auxctl>"); - break; - } - } - result = pdaok ? 0 : -ENODATA; - - if (result) - pr_debug("Failure: pda is not okay\n"); - - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_setconfig - * - * Performs the sequence necessary to write a config/info item. - * - * Arguments: - * hw device structure - * rid config/info record id (in host order) - * buf host side record buffer - * len buffer length (in bytes) - * - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_setconfig(struct hfa384x *hw, u16 rid, void *buf, u16 len) -{ - return hfa384x_dowrid(hw, DOWAIT, rid, buf, len, NULL, NULL, NULL); -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_start - * - * Issues the MAC initialize command, sets up some data structures, - * and enables the interrupts. After this function completes, the - * low-level stuff should be ready for any/all commands. - * - * Arguments: - * hw device structure - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_start(struct hfa384x *hw) -{ - int result, result1, result2; - u16 status; - - might_sleep(); - - /* Clear endpoint stalls - but only do this if the endpoint - * is showing a stall status. Some prism2 cards seem to behave - * badly if a clear_halt is called when the endpoint is already - * ok - */ - result = - usb_get_std_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_in, - &status); - if (result < 0) { - netdev_err(hw->wlandev->netdev, "Cannot get bulk in endpoint status.\n"); - goto done; - } - if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_in)) - netdev_err(hw->wlandev->netdev, "Failed to reset bulk in endpoint.\n"); - - result = - usb_get_std_status(hw->usb, USB_RECIP_ENDPOINT, hw->endp_out, - &status); - if (result < 0) { - netdev_err(hw->wlandev->netdev, "Cannot get bulk out endpoint status.\n"); - goto done; - } - if ((status == 1) && usb_clear_halt(hw->usb, hw->endp_out)) - netdev_err(hw->wlandev->netdev, "Failed to reset bulk out endpoint.\n"); - - /* Synchronous unlink, in case we're trying to restart the driver */ - usb_kill_urb(&hw->rx_urb); - - /* Post the IN urb */ - result = submit_rx_urb(hw, GFP_KERNEL); - if (result != 0) { - netdev_err(hw->wlandev->netdev, - "Fatal, failed to submit RX URB, result=%d\n", - result); - goto done; - } - - /* Call initialize twice, with a 1 second sleep in between. - * This is a nasty work-around since many prism2 cards seem to - * need time to settle after an init from cold. The second - * call to initialize in theory is not necessary - but we call - * it anyway as a double insurance policy: - * 1) If the first init should fail, the second may well succeed - * and the card can still be used - * 2) It helps ensures all is well with the card after the first - * init and settle time. - */ - result1 = hfa384x_cmd_initialize(hw); - msleep(1000); - result = hfa384x_cmd_initialize(hw); - result2 = result; - if (result1 != 0) { - if (result2 != 0) { - netdev_err(hw->wlandev->netdev, - "cmd_initialize() failed on two attempts, results %d and %d\n", - result1, result2); - usb_kill_urb(&hw->rx_urb); - goto done; - } else { - pr_debug("First cmd_initialize() failed (result %d),\n", - result1); - pr_debug("but second attempt succeeded. All should be ok\n"); - } - } else if (result2 != 0) { - netdev_warn(hw->wlandev->netdev, "First cmd_initialize() succeeded, but second attempt failed (result=%d)\n", - result2); - netdev_warn(hw->wlandev->netdev, - "Most likely the card will be functional\n"); - goto done; - } - - hw->state = HFA384x_STATE_RUNNING; - -done: - return result; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_stop - * - * Shuts down the MAC to the point where it is safe to unload the - * driver. Any subsystem that may be holding a data or function - * ptr into the driver must be cleared/deinitialized. - * - * Arguments: - * hw device structure - * Returns: - * 0 success - * >0 f/w reported error - f/w status code - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process - *---------------------------------------------------------------- - */ -int hfa384x_drvr_stop(struct hfa384x *hw) -{ - int i; - - might_sleep(); - - /* There's no need for spinlocks here. The USB "disconnect" - * function sets this "removed" flag and then calls us. - */ - if (!hw->wlandev->hwremoved) { - /* Call initialize to leave the MAC in its 'reset' state */ - hfa384x_cmd_initialize(hw); - - /* Cancel the rxurb */ - usb_kill_urb(&hw->rx_urb); - } - - hw->link_status = HFA384x_LINK_NOTCONNECTED; - hw->state = HFA384x_STATE_INIT; - - del_timer_sync(&hw->commsqual_timer); - - /* Clear all the port status */ - for (i = 0; i < HFA384x_NUMPORTS_MAX; i++) - hw->port_enabled[i] = 0; - - return 0; -} - -/*---------------------------------------------------------------- - * hfa384x_drvr_txframe - * - * Takes a frame from prism2sta and queues it for transmission. - * - * Arguments: - * hw device structure - * skb packet buffer struct. Contains an 802.11 - * data frame. - * p80211_hdr points to the 802.11 header for the packet. - * Returns: - * 0 Success and more buffs available - * 1 Success but no more buffs - * 2 Allocation failure - * 4 Buffer full or queue busy - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -int hfa384x_drvr_txframe(struct hfa384x *hw, struct sk_buff *skb, - struct p80211_hdr *p80211_hdr, - struct p80211_metawep *p80211_wep) -{ - int usbpktlen = sizeof(struct hfa384x_tx_frame); - int result; - int ret; - char *ptr; - - if (hw->tx_urb.status == -EINPROGRESS) { - netdev_warn(hw->wlandev->netdev, "TX URB already in use\n"); - result = 3; - goto exit; - } - - /* Build Tx frame structure */ - /* Set up the control field */ - memset(&hw->txbuff.txfrm.desc, 0, sizeof(hw->txbuff.txfrm.desc)); - - /* Setup the usb type field */ - hw->txbuff.type = cpu_to_le16(HFA384x_USB_TXFRM); - - /* Set up the sw_support field to identify this frame */ - hw->txbuff.txfrm.desc.sw_support = 0x0123; - -/* Tx complete and Tx exception disable per dleach. Might be causing - * buf depletion - */ -/* #define DOEXC SLP -- doboth breaks horribly under load, doexc less so. */ -#if defined(DOBOTH) - hw->txbuff.txfrm.desc.tx_control = - HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | - HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1); -#elif defined(DOEXC) - hw->txbuff.txfrm.desc.tx_control = - HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | - HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(0); -#else - hw->txbuff.txfrm.desc.tx_control = - HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | - HFA384x_TX_TXEX_SET(0) | HFA384x_TX_TXOK_SET(0); -#endif - cpu_to_le16s(&hw->txbuff.txfrm.desc.tx_control); - - /* copy the header over to the txdesc */ - hw->txbuff.txfrm.desc.hdr = *p80211_hdr; - - /* if we're using host WEP, increase size by IV+ICV */ - if (p80211_wep->data) { - hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len + 8); - usbpktlen += 8; - } else { - hw->txbuff.txfrm.desc.data_len = cpu_to_le16(skb->len); - } - - usbpktlen += skb->len; - - /* copy over the WEP IV if we are using host WEP */ - ptr = hw->txbuff.txfrm.data; - if (p80211_wep->data) { - memcpy(ptr, p80211_wep->iv, sizeof(p80211_wep->iv)); - ptr += sizeof(p80211_wep->iv); - memcpy(ptr, p80211_wep->data, skb->len); - } else { - memcpy(ptr, skb->data, skb->len); - } - /* copy over the packet data */ - ptr += skb->len; - - /* copy over the WEP ICV if we are using host WEP */ - if (p80211_wep->data) - memcpy(ptr, p80211_wep->icv, sizeof(p80211_wep->icv)); - - /* Send the USB packet */ - usb_fill_bulk_urb(&hw->tx_urb, hw->usb, - hw->endp_out, - &hw->txbuff, ROUNDUP64(usbpktlen), - hfa384x_usbout_callback, hw->wlandev); - hw->tx_urb.transfer_flags |= USB_QUEUE_BULK; - - result = 1; - ret = submit_tx_urb(hw, &hw->tx_urb, GFP_ATOMIC); - if (ret != 0) { - netdev_err(hw->wlandev->netdev, - "submit_tx_urb() failed, error=%d\n", ret); - result = 3; - } - -exit: - return result; -} - -void hfa384x_tx_timeout(struct wlandevice *wlandev) -{ - struct hfa384x *hw = wlandev->priv; - unsigned long flags; - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - if (!hw->wlandev->hwremoved) { - int sched; - - sched = !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags); - sched |= !test_and_set_bit(WORK_RX_HALT, &hw->usb_flags); - if (sched) - schedule_work(&hw->usb_work); - } - - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); -} - -/*---------------------------------------------------------------- - * hfa384x_usbctlx_reaper_task - * - * Deferred work callback to delete dead CTLX objects - * - * Arguments: - * work contains ptr to a struct hfa384x - * - * Returns: - * - * Call context: - * Task - *---------------------------------------------------------------- - */ -static void hfa384x_usbctlx_reaper_task(struct work_struct *work) -{ - struct hfa384x *hw = container_of(work, struct hfa384x, reaper_bh); - struct hfa384x_usbctlx *ctlx, *temp; - unsigned long flags; - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - /* This list is guaranteed to be empty if someone - * has unplugged the adapter. - */ - list_for_each_entry_safe(ctlx, temp, &hw->ctlxq.reapable, list) { - list_del(&ctlx->list); - kfree(ctlx); - } - - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); -} - -/*---------------------------------------------------------------- - * hfa384x_usbctlx_completion_task - * - * Deferred work callback to call completion handlers for returned CTLXs - * - * Arguments: - * work contains ptr to a struct hfa384x - * - * Returns: - * Nothing - * - * Call context: - * Task - *---------------------------------------------------------------- - */ -static void hfa384x_usbctlx_completion_task(struct work_struct *work) -{ - struct hfa384x *hw = container_of(work, struct hfa384x, completion_bh); - struct hfa384x_usbctlx *ctlx, *temp; - unsigned long flags; - - int reap = 0; - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - /* This list is guaranteed to be empty if someone - * has unplugged the adapter ... - */ - list_for_each_entry_safe(ctlx, temp, &hw->ctlxq.completing, list) { - /* Call the completion function that this - * command was assigned, assuming it has one. - */ - if (ctlx->cmdcb) { - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - ctlx->cmdcb(hw, ctlx); - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - /* Make sure we don't try and complete - * this CTLX more than once! - */ - ctlx->cmdcb = NULL; - - /* Did someone yank the adapter out - * while our list was (briefly) unlocked? - */ - if (hw->wlandev->hwremoved) { - reap = 0; - break; - } - } - - /* - * "Reapable" CTLXs are ones which don't have any - * threads waiting for them to die. Hence they must - * be delivered to The Reaper! - */ - if (ctlx->reapable) { - /* Move the CTLX off the "completing" list (hopefully) - * on to the "reapable" list where the reaper task - * can find it. And "reapable" means that this CTLX - * isn't sitting on a wait-queue somewhere. - */ - list_move_tail(&ctlx->list, &hw->ctlxq.reapable); - reap = 1; - } - - complete(&ctlx->done); - } - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - - if (reap) - schedule_work(&hw->reaper_bh); -} - -/*---------------------------------------------------------------- - * unlocked_usbctlx_cancel_async - * - * Mark the CTLX dead asynchronously, and ensure that the - * next command on the queue is run afterwards. - * - * Arguments: - * hw ptr to the struct hfa384x structure - * ctlx ptr to a CTLX structure - * - * Returns: - * 0 the CTLX's URB is inactive - * -EINPROGRESS the URB is currently being unlinked - * - * Call context: - * Either process or interrupt, but presumably interrupt - *---------------------------------------------------------------- - */ -static int unlocked_usbctlx_cancel_async(struct hfa384x *hw, - struct hfa384x_usbctlx *ctlx) -{ - int ret; - - /* - * Try to delete the URB containing our request packet. - * If we succeed, then its completion handler will be - * called with a status of -ECONNRESET. - */ - hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK; - ret = usb_unlink_urb(&hw->ctlx_urb); - - if (ret != -EINPROGRESS) { - /* - * The OUT URB had either already completed - * or was still in the pending queue, so the - * URB's completion function will not be called. - * We will have to complete the CTLX ourselves. - */ - ctlx->state = CTLX_REQ_FAILED; - unlocked_usbctlx_complete(hw, ctlx); - ret = 0; - } - - return ret; -} - -/*---------------------------------------------------------------- - * unlocked_usbctlx_complete - * - * A CTLX has completed. It may have been successful, it may not - * have been. At this point, the CTLX should be quiescent. The URBs - * aren't active and the timers should have been stopped. - * - * The CTLX is migrated to the "completing" queue, and the completing - * work is scheduled. - * - * Arguments: - * hw ptr to a struct hfa384x structure - * ctlx ptr to a ctlx structure - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * Either, assume interrupt - *---------------------------------------------------------------- - */ -static void unlocked_usbctlx_complete(struct hfa384x *hw, - struct hfa384x_usbctlx *ctlx) -{ - /* Timers have been stopped, and ctlx should be in - * a terminal state. Retire it from the "active" - * queue. - */ - list_move_tail(&ctlx->list, &hw->ctlxq.completing); - schedule_work(&hw->completion_bh); - - switch (ctlx->state) { - case CTLX_COMPLETE: - case CTLX_REQ_FAILED: - /* This are the correct terminating states. */ - break; - - default: - netdev_err(hw->wlandev->netdev, "CTLX[%d] not in a terminating state(%s)\n", - le16_to_cpu(ctlx->outbuf.type), - ctlxstr(ctlx->state)); - break; - } /* switch */ -} - -/*---------------------------------------------------------------- - * hfa384x_usbctlxq_run - * - * Checks to see if the head item is running. If not, starts it. - * - * Arguments: - * hw ptr to struct hfa384x - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * any - *---------------------------------------------------------------- - */ -static void hfa384x_usbctlxq_run(struct hfa384x *hw) -{ - unsigned long flags; - - /* acquire lock */ - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - /* Only one active CTLX at any one time, because there's no - * other (reliable) way to match the response URB to the - * correct CTLX. - * - * Don't touch any of these CTLXs if the hardware - * has been removed or the USB subsystem is stalled. - */ - if (!list_empty(&hw->ctlxq.active) || - test_bit(WORK_TX_HALT, &hw->usb_flags) || hw->wlandev->hwremoved) - goto unlock; - - while (!list_empty(&hw->ctlxq.pending)) { - struct hfa384x_usbctlx *head; - int result; - - /* This is the first pending command */ - head = list_entry(hw->ctlxq.pending.next, - struct hfa384x_usbctlx, list); - - /* We need to split this off to avoid a race condition */ - list_move_tail(&head->list, &hw->ctlxq.active); - - /* Fill the out packet */ - usb_fill_bulk_urb(&hw->ctlx_urb, hw->usb, - hw->endp_out, - &head->outbuf, ROUNDUP64(head->outbufsize), - hfa384x_ctlxout_callback, hw); - hw->ctlx_urb.transfer_flags |= USB_QUEUE_BULK; - - /* Now submit the URB and update the CTLX's state */ - result = usb_submit_urb(&hw->ctlx_urb, GFP_ATOMIC); - if (result == 0) { - /* This CTLX is now running on the active queue */ - head->state = CTLX_REQ_SUBMITTED; - - /* Start the OUT wait timer */ - hw->req_timer_done = 0; - hw->reqtimer.expires = jiffies + HZ; - add_timer(&hw->reqtimer); - - /* Start the IN wait timer */ - hw->resp_timer_done = 0; - hw->resptimer.expires = jiffies + 2 * HZ; - add_timer(&hw->resptimer); - - break; - } - - if (result == -EPIPE) { - /* The OUT pipe needs resetting, so put - * this CTLX back in the "pending" queue - * and schedule a reset ... - */ - netdev_warn(hw->wlandev->netdev, - "%s tx pipe stalled: requesting reset\n", - hw->wlandev->netdev->name); - list_move(&head->list, &hw->ctlxq.pending); - set_bit(WORK_TX_HALT, &hw->usb_flags); - schedule_work(&hw->usb_work); - break; - } - - if (result == -ESHUTDOWN) { - netdev_warn(hw->wlandev->netdev, "%s urb shutdown!\n", - hw->wlandev->netdev->name); - break; - } - - netdev_err(hw->wlandev->netdev, "Failed to submit CTLX[%d]: error=%d\n", - le16_to_cpu(head->outbuf.type), result); - unlocked_usbctlx_complete(hw, head); - } /* while */ - -unlock: - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); -} - -/*---------------------------------------------------------------- - * hfa384x_usbin_callback - * - * Callback for URBs on the BULKIN endpoint. - * - * Arguments: - * urb ptr to the completed urb - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_usbin_callback(struct urb *urb) -{ - struct wlandevice *wlandev = urb->context; - struct hfa384x *hw; - union hfa384x_usbin *usbin; - struct sk_buff *skb = NULL; - int result; - int urb_status; - u16 type; - - enum USBIN_ACTION { - HANDLE, - RESUBMIT, - ABORT - } action; - - if (!wlandev || !wlandev->netdev || wlandev->hwremoved) - goto exit; - - hw = wlandev->priv; - if (!hw) - goto exit; - - skb = hw->rx_urb_skb; - if (!skb || (skb->data != urb->transfer_buffer)) { - WARN_ON(1); - return; - } - - hw->rx_urb_skb = NULL; - - /* Check for error conditions within the URB */ - switch (urb->status) { - case 0: - action = HANDLE; - - /* Check for short packet */ - if (urb->actual_length == 0) { - wlandev->netdev->stats.rx_errors++; - wlandev->netdev->stats.rx_length_errors++; - action = RESUBMIT; - } - break; - - case -EPIPE: - netdev_warn(hw->wlandev->netdev, "%s rx pipe stalled: requesting reset\n", - wlandev->netdev->name); - if (!test_and_set_bit(WORK_RX_HALT, &hw->usb_flags)) - schedule_work(&hw->usb_work); - wlandev->netdev->stats.rx_errors++; - action = ABORT; - break; - - case -EILSEQ: - case -ETIMEDOUT: - case -EPROTO: - if (!test_and_set_bit(THROTTLE_RX, &hw->usb_flags) && - !timer_pending(&hw->throttle)) { - mod_timer(&hw->throttle, jiffies + THROTTLE_JIFFIES); - } - wlandev->netdev->stats.rx_errors++; - action = ABORT; - break; - - case -EOVERFLOW: - wlandev->netdev->stats.rx_over_errors++; - action = RESUBMIT; - break; - - case -ENODEV: - case -ESHUTDOWN: - pr_debug("status=%d, device removed.\n", urb->status); - action = ABORT; - break; - - case -ENOENT: - case -ECONNRESET: - pr_debug("status=%d, urb explicitly unlinked.\n", urb->status); - action = ABORT; - break; - - default: - pr_debug("urb status=%d, transfer flags=0x%x\n", - urb->status, urb->transfer_flags); - wlandev->netdev->stats.rx_errors++; - action = RESUBMIT; - break; - } - - /* Save values from the RX URB before reposting overwrites it. */ - urb_status = urb->status; - usbin = (union hfa384x_usbin *)urb->transfer_buffer; - - if (action != ABORT) { - /* Repost the RX URB */ - result = submit_rx_urb(hw, GFP_ATOMIC); - - if (result != 0) { - netdev_err(hw->wlandev->netdev, - "Fatal, failed to resubmit rx_urb. error=%d\n", - result); - } - } - - /* Handle any USB-IN packet */ - /* Note: the check of the sw_support field, the type field doesn't - * have bit 12 set like the docs suggest. - */ - type = le16_to_cpu(usbin->type); - if (HFA384x_USB_ISRXFRM(type)) { - if (action == HANDLE) { - if (usbin->txfrm.desc.sw_support == 0x0123) { - hfa384x_usbin_txcompl(wlandev, usbin); - } else { - skb_put(skb, sizeof(*usbin)); - hfa384x_usbin_rx(wlandev, skb); - skb = NULL; - } - } - goto exit; - } - if (HFA384x_USB_ISTXFRM(type)) { - if (action == HANDLE) - hfa384x_usbin_txcompl(wlandev, usbin); - goto exit; - } - switch (type) { - case HFA384x_USB_INFOFRM: - if (action == ABORT) - goto exit; - if (action == HANDLE) - hfa384x_usbin_info(wlandev, usbin); - break; - - case HFA384x_USB_CMDRESP: - case HFA384x_USB_WRIDRESP: - case HFA384x_USB_RRIDRESP: - case HFA384x_USB_WMEMRESP: - case HFA384x_USB_RMEMRESP: - /* ALWAYS, ALWAYS, ALWAYS handle this CTLX!!!! */ - hfa384x_usbin_ctlx(hw, usbin, urb_status); - break; - - case HFA384x_USB_BUFAVAIL: - pr_debug("Received BUFAVAIL packet, frmlen=%d\n", - usbin->bufavail.frmlen); - break; - - case HFA384x_USB_ERROR: - pr_debug("Received USB_ERROR packet, errortype=%d\n", - usbin->usberror.errortype); - break; - - default: - pr_debug("Unrecognized USBIN packet, type=%x, status=%d\n", - usbin->type, urb_status); - break; - } /* switch */ - -exit: - - if (skb) - dev_kfree_skb(skb); -} - -/*---------------------------------------------------------------- - * hfa384x_usbin_ctlx - * - * We've received a URB containing a Prism2 "response" message. - * This message needs to be matched up with a CTLX on the active - * queue and our state updated accordingly. - * - * Arguments: - * hw ptr to struct hfa384x - * usbin ptr to USB IN packet - * urb_status status of this Bulk-In URB - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_usbin_ctlx(struct hfa384x *hw, union hfa384x_usbin *usbin, - int urb_status) -{ - struct hfa384x_usbctlx *ctlx; - int run_queue = 0; - unsigned long flags; - -retry: - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - /* There can be only one CTLX on the active queue - * at any one time, and this is the CTLX that the - * timers are waiting for. - */ - if (list_empty(&hw->ctlxq.active)) - goto unlock; - - /* Remove the "response timeout". It's possible that - * we are already too late, and that the timeout is - * already running. And that's just too bad for us, - * because we could lose our CTLX from the active - * queue here ... - */ - if (del_timer(&hw->resptimer) == 0) { - if (hw->resp_timer_done == 0) { - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - goto retry; - } - } else { - hw->resp_timer_done = 1; - } - - ctlx = get_active_ctlx(hw); - - if (urb_status != 0) { - /* - * Bad CTLX, so get rid of it. But we only - * remove it from the active queue if we're no - * longer expecting the OUT URB to complete. - */ - if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) - run_queue = 1; - } else { - const __le16 intype = (usbin->type & ~cpu_to_le16(0x8000)); - - /* - * Check that our message is what we're expecting ... - */ - if (ctlx->outbuf.type != intype) { - netdev_warn(hw->wlandev->netdev, - "Expected IN[%d], received IN[%d] - ignored.\n", - le16_to_cpu(ctlx->outbuf.type), - le16_to_cpu(intype)); - goto unlock; - } - - /* This URB has succeeded, so grab the data ... */ - memcpy(&ctlx->inbuf, usbin, sizeof(ctlx->inbuf)); - - switch (ctlx->state) { - case CTLX_REQ_SUBMITTED: - /* - * We have received our response URB before - * our request has been acknowledged. Odd, - * but our OUT URB is still alive... - */ - pr_debug("Causality violation: please reboot Universe\n"); - ctlx->state = CTLX_RESP_COMPLETE; - break; - - case CTLX_REQ_COMPLETE: - /* - * This is the usual path: our request - * has already been acknowledged, and - * now we have received the reply too. - */ - ctlx->state = CTLX_COMPLETE; - unlocked_usbctlx_complete(hw, ctlx); - run_queue = 1; - break; - - default: - /* - * Throw this CTLX away ... - */ - netdev_err(hw->wlandev->netdev, - "Matched IN URB, CTLX[%d] in invalid state(%s). Discarded.\n", - le16_to_cpu(ctlx->outbuf.type), - ctlxstr(ctlx->state)); - if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) - run_queue = 1; - break; - } /* switch */ - } - -unlock: - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - - if (run_queue) - hfa384x_usbctlxq_run(hw); -} - -/*---------------------------------------------------------------- - * hfa384x_usbin_txcompl - * - * At this point we have the results of a previous transmit. - * - * Arguments: - * wlandev wlan device - * usbin ptr to the usb transfer buffer - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_usbin_txcompl(struct wlandevice *wlandev, - union hfa384x_usbin *usbin) -{ - u16 status; - - status = le16_to_cpu(usbin->type); /* yeah I know it says type... */ - - /* Was there an error? */ - if (HFA384x_TXSTATUS_ISERROR(status)) - netdev_dbg(wlandev->netdev, "TxExc status=0x%x.\n", status); - else - prism2sta_ev_tx(wlandev, status); -} - -/*---------------------------------------------------------------- - * hfa384x_usbin_rx - * - * At this point we have a successful received a rx frame packet. - * - * Arguments: - * wlandev wlan device - * usbin ptr to the usb transfer buffer - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_usbin_rx(struct wlandevice *wlandev, struct sk_buff *skb) -{ - union hfa384x_usbin *usbin = (union hfa384x_usbin *)skb->data; - struct hfa384x *hw = wlandev->priv; - int hdrlen; - struct p80211_rxmeta *rxmeta; - u16 data_len; - u16 fc; - u16 status; - - /* Byte order convert once up front. */ - le16_to_cpus(&usbin->rxfrm.desc.status); - le32_to_cpus(&usbin->rxfrm.desc.time); - - /* Now handle frame based on port# */ - status = HFA384x_RXSTATUS_MACPORT_GET(usbin->rxfrm.desc.status); - - switch (status) { - case 0: - fc = le16_to_cpu(usbin->rxfrm.desc.hdr.frame_control); - - /* If exclude and we receive an unencrypted, drop it */ - if ((wlandev->hostwep & HOSTWEP_EXCLUDEUNENCRYPTED) && - !WLAN_GET_FC_ISWEP(fc)) { - break; - } - - data_len = le16_to_cpu(usbin->rxfrm.desc.data_len); - - /* How much header data do we have? */ - hdrlen = p80211_headerlen(fc); - - /* Pull off the descriptor */ - skb_pull(skb, sizeof(struct hfa384x_rx_frame)); - - /* Now shunt the header block up against the data block - * with an "overlapping" copy - */ - memmove(skb_push(skb, hdrlen), - &usbin->rxfrm.desc.hdr, hdrlen); - - skb->dev = wlandev->netdev; - - /* And set the frame length properly */ - skb_trim(skb, data_len + hdrlen); - - /* The prism2 series does not return the CRC */ - memset(skb_put(skb, WLAN_CRC_LEN), 0xff, WLAN_CRC_LEN); - - skb_reset_mac_header(skb); - - /* Attach the rxmeta, set some stuff */ - p80211skb_rxmeta_attach(wlandev, skb); - rxmeta = p80211skb_rxmeta(skb); - rxmeta->mactime = usbin->rxfrm.desc.time; - rxmeta->rxrate = usbin->rxfrm.desc.rate; - rxmeta->signal = usbin->rxfrm.desc.signal - hw->dbmadjust; - rxmeta->noise = usbin->rxfrm.desc.silence - hw->dbmadjust; - - p80211netdev_rx(wlandev, skb); - - break; - - case 7: - if (!HFA384x_RXSTATUS_ISFCSERR(usbin->rxfrm.desc.status)) { - /* Copy to wlansnif skb */ - hfa384x_int_rxmonitor(wlandev, &usbin->rxfrm); - dev_kfree_skb(skb); - } else { - pr_debug("Received monitor frame: FCSerr set\n"); - } - break; - - default: - netdev_warn(hw->wlandev->netdev, - "Received frame on unsupported port=%d\n", - status); - break; - } -} - -/*---------------------------------------------------------------- - * hfa384x_int_rxmonitor - * - * Helper function for int_rx. Handles monitor frames. - * Note that this function allocates space for the FCS and sets it - * to 0xffffffff. The hfa384x doesn't give us the FCS value but the - * higher layers expect it. 0xffffffff is used as a flag to indicate - * the FCS is bogus. - * - * Arguments: - * wlandev wlan device structure - * rxfrm rx descriptor read from card in int_rx - * - * Returns: - * nothing - * - * Side effects: - * Allocates an skb and passes it up via the PF_PACKET interface. - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_int_rxmonitor(struct wlandevice *wlandev, - struct hfa384x_usb_rxfrm *rxfrm) -{ - struct hfa384x_rx_frame *rxdesc = &rxfrm->desc; - unsigned int hdrlen = 0; - unsigned int datalen = 0; - unsigned int skblen = 0; - u8 *datap; - u16 fc; - struct sk_buff *skb; - struct hfa384x *hw = wlandev->priv; - - /* Remember the status, time, and data_len fields are in host order */ - /* Figure out how big the frame is */ - fc = le16_to_cpu(rxdesc->hdr.frame_control); - hdrlen = p80211_headerlen(fc); - datalen = le16_to_cpu(rxdesc->data_len); - - /* Allocate an ind message+framesize skb */ - skblen = sizeof(struct p80211_caphdr) + hdrlen + datalen + WLAN_CRC_LEN; - - /* sanity check the length */ - if (skblen > - (sizeof(struct p80211_caphdr) + - WLAN_HDR_A4_LEN + WLAN_DATA_MAXLEN + WLAN_CRC_LEN)) { - pr_debug("overlen frm: len=%zd\n", - skblen - sizeof(struct p80211_caphdr)); - - return; - } - - skb = dev_alloc_skb(skblen); - if (!skb) - return; - - /* only prepend the prism header if in the right mode */ - if ((wlandev->netdev->type == ARPHRD_IEEE80211_PRISM) && - (hw->sniffhdr != 0)) { - struct p80211_caphdr *caphdr; - /* The NEW header format! */ - datap = skb_put(skb, sizeof(struct p80211_caphdr)); - caphdr = (struct p80211_caphdr *)datap; - - caphdr->version = htonl(P80211CAPTURE_VERSION); - caphdr->length = htonl(sizeof(struct p80211_caphdr)); - caphdr->mactime = __cpu_to_be64(rxdesc->time * 1000); - caphdr->hosttime = __cpu_to_be64(jiffies); - caphdr->phytype = htonl(4); /* dss_dot11_b */ - caphdr->channel = htonl(hw->sniff_channel); - caphdr->datarate = htonl(rxdesc->rate); - caphdr->antenna = htonl(0); /* unknown */ - caphdr->priority = htonl(0); /* unknown */ - caphdr->ssi_type = htonl(3); /* rssi_raw */ - caphdr->ssi_signal = htonl(rxdesc->signal); - caphdr->ssi_noise = htonl(rxdesc->silence); - caphdr->preamble = htonl(0); /* unknown */ - caphdr->encoding = htonl(1); /* cck */ - } - - /* Copy the 802.11 header to the skb - * (ctl frames may be less than a full header) - */ - skb_put_data(skb, &rxdesc->hdr.frame_control, hdrlen); - - /* If any, copy the data from the card to the skb */ - if (datalen > 0) { - datap = skb_put_data(skb, rxfrm->data, datalen); - - /* check for unencrypted stuff if WEP bit set. */ - if (*(datap - hdrlen + 1) & 0x40) /* wep set */ - if ((*(datap) == 0xaa) && (*(datap + 1) == 0xaa)) - /* clear wep; it's the 802.2 header! */ - *(datap - hdrlen + 1) &= 0xbf; - } - - if (hw->sniff_fcs) { - /* Set the FCS */ - datap = skb_put(skb, WLAN_CRC_LEN); - memset(datap, 0xff, WLAN_CRC_LEN); - } - - /* pass it back up */ - p80211netdev_rx(wlandev, skb); -} - -/*---------------------------------------------------------------- - * hfa384x_usbin_info - * - * At this point we have a successful received a Prism2 info frame. - * - * Arguments: - * wlandev wlan device - * usbin ptr to the usb transfer buffer - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_usbin_info(struct wlandevice *wlandev, - union hfa384x_usbin *usbin) -{ - le16_to_cpus(&usbin->infofrm.info.framelen); - prism2sta_ev_info(wlandev, &usbin->infofrm.info); -} - -/*---------------------------------------------------------------- - * hfa384x_usbout_callback - * - * Callback for URBs on the BULKOUT endpoint. - * - * Arguments: - * urb ptr to the completed urb - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_usbout_callback(struct urb *urb) -{ - struct wlandevice *wlandev = urb->context; - -#ifdef DEBUG_USB - dbprint_urb(urb); -#endif - - if (wlandev && wlandev->netdev) { - switch (urb->status) { - case 0: - prism2sta_ev_alloc(wlandev); - break; - - case -EPIPE: { - struct hfa384x *hw = wlandev->priv; - - netdev_warn(hw->wlandev->netdev, - "%s tx pipe stalled: requesting reset\n", - wlandev->netdev->name); - if (!test_and_set_bit(WORK_TX_HALT, &hw->usb_flags)) - schedule_work(&hw->usb_work); - wlandev->netdev->stats.tx_errors++; - break; - } - - case -EPROTO: - case -ETIMEDOUT: - case -EILSEQ: { - struct hfa384x *hw = wlandev->priv; - - if (!test_and_set_bit(THROTTLE_TX, &hw->usb_flags) && - !timer_pending(&hw->throttle)) { - mod_timer(&hw->throttle, - jiffies + THROTTLE_JIFFIES); - } - wlandev->netdev->stats.tx_errors++; - netif_stop_queue(wlandev->netdev); - break; - } - - case -ENOENT: - case -ESHUTDOWN: - /* Ignorable errors */ - break; - - default: - netdev_info(wlandev->netdev, "unknown urb->status=%d\n", - urb->status); - wlandev->netdev->stats.tx_errors++; - break; - } /* switch */ - } -} - -/*---------------------------------------------------------------- - * hfa384x_ctlxout_callback - * - * Callback for control data on the BULKOUT endpoint. - * - * Arguments: - * urb ptr to the completed urb - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_ctlxout_callback(struct urb *urb) -{ - struct hfa384x *hw = urb->context; - int delete_resptimer = 0; - int timer_ok = 1; - int run_queue = 0; - struct hfa384x_usbctlx *ctlx; - unsigned long flags; - - pr_debug("urb->status=%d\n", urb->status); -#ifdef DEBUG_USB - dbprint_urb(urb); -#endif - if ((urb->status == -ESHUTDOWN) || - (urb->status == -ENODEV) || !hw) - return; - -retry: - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - /* - * Only one CTLX at a time on the "active" list, and - * none at all if we are unplugged. However, we can - * rely on the disconnect function to clean everything - * up if someone unplugged the adapter. - */ - if (list_empty(&hw->ctlxq.active)) { - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - return; - } - - /* - * Having something on the "active" queue means - * that we have timers to worry about ... - */ - if (del_timer(&hw->reqtimer) == 0) { - if (hw->req_timer_done == 0) { - /* - * This timer was actually running while we - * were trying to delete it. Let it terminate - * gracefully instead. - */ - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - goto retry; - } - } else { - hw->req_timer_done = 1; - } - - ctlx = get_active_ctlx(hw); - - if (urb->status == 0) { - /* Request portion of a CTLX is successful */ - switch (ctlx->state) { - case CTLX_REQ_SUBMITTED: - /* This OUT-ACK received before IN */ - ctlx->state = CTLX_REQ_COMPLETE; - break; - - case CTLX_RESP_COMPLETE: - /* IN already received before this OUT-ACK, - * so this command must now be complete. - */ - ctlx->state = CTLX_COMPLETE; - unlocked_usbctlx_complete(hw, ctlx); - run_queue = 1; - break; - - default: - /* This is NOT a valid CTLX "success" state! */ - netdev_err(hw->wlandev->netdev, - "Illegal CTLX[%d] success state(%s, %d) in OUT URB\n", - le16_to_cpu(ctlx->outbuf.type), - ctlxstr(ctlx->state), urb->status); - break; - } /* switch */ - } else { - /* If the pipe has stalled then we need to reset it */ - if ((urb->status == -EPIPE) && - !test_and_set_bit(WORK_TX_HALT, &hw->usb_flags)) { - netdev_warn(hw->wlandev->netdev, - "%s tx pipe stalled: requesting reset\n", - hw->wlandev->netdev->name); - schedule_work(&hw->usb_work); - } - - /* If someone cancels the OUT URB then its status - * should be either -ECONNRESET or -ENOENT. - */ - ctlx->state = CTLX_REQ_FAILED; - unlocked_usbctlx_complete(hw, ctlx); - delete_resptimer = 1; - run_queue = 1; - } - -delresp: - if (delete_resptimer) { - timer_ok = del_timer(&hw->resptimer); - if (timer_ok != 0) - hw->resp_timer_done = 1; - } - - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - - if (!timer_ok && (hw->resp_timer_done == 0)) { - spin_lock_irqsave(&hw->ctlxq.lock, flags); - goto delresp; - } - - if (run_queue) - hfa384x_usbctlxq_run(hw); -} - -/*---------------------------------------------------------------- - * hfa384x_usbctlx_reqtimerfn - * - * Timer response function for CTLX request timeouts. If this - * function is called, it means that the callback for the OUT - * URB containing a Prism2.x XXX_Request was never called. - * - * Arguments: - * data a ptr to the struct hfa384x - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_usbctlx_reqtimerfn(struct timer_list *t) -{ - struct hfa384x *hw = from_timer(hw, t, reqtimer); - unsigned long flags; - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - hw->req_timer_done = 1; - - /* Removing the hardware automatically empties - * the active list ... - */ - if (!list_empty(&hw->ctlxq.active)) { - /* - * We must ensure that our URB is removed from - * the system, if it hasn't already expired. - */ - hw->ctlx_urb.transfer_flags |= URB_ASYNC_UNLINK; - if (usb_unlink_urb(&hw->ctlx_urb) == -EINPROGRESS) { - struct hfa384x_usbctlx *ctlx = get_active_ctlx(hw); - - ctlx->state = CTLX_REQ_FAILED; - - /* This URB was active, but has now been - * cancelled. It will now have a status of - * -ECONNRESET in the callback function. - * - * We are cancelling this CTLX, so we're - * not going to need to wait for a response. - * The URB's callback function will check - * that this timer is truly dead. - */ - if (del_timer(&hw->resptimer) != 0) - hw->resp_timer_done = 1; - } - } - - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); -} - -/*---------------------------------------------------------------- - * hfa384x_usbctlx_resptimerfn - * - * Timer response function for CTLX response timeouts. If this - * function is called, it means that the callback for the IN - * URB containing a Prism2.x XXX_Response was never called. - * - * Arguments: - * data a ptr to the struct hfa384x - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_usbctlx_resptimerfn(struct timer_list *t) -{ - struct hfa384x *hw = from_timer(hw, t, resptimer); - unsigned long flags; - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - hw->resp_timer_done = 1; - - /* The active list will be empty if the - * adapter has been unplugged ... - */ - if (!list_empty(&hw->ctlxq.active)) { - struct hfa384x_usbctlx *ctlx = get_active_ctlx(hw); - - if (unlocked_usbctlx_cancel_async(hw, ctlx) == 0) { - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - hfa384x_usbctlxq_run(hw); - return; - } - } - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); -} - -/*---------------------------------------------------------------- - * hfa384x_usb_throttlefn - * - * - * Arguments: - * data ptr to hw - * - * Returns: - * Nothing - * - * Side effects: - * - * Call context: - * Interrupt - *---------------------------------------------------------------- - */ -static void hfa384x_usb_throttlefn(struct timer_list *t) -{ - struct hfa384x *hw = from_timer(hw, t, throttle); - unsigned long flags; - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - pr_debug("flags=0x%lx\n", hw->usb_flags); - if (!hw->wlandev->hwremoved) { - bool rx_throttle = test_and_clear_bit(THROTTLE_RX, &hw->usb_flags) && - !test_and_set_bit(WORK_RX_RESUME, &hw->usb_flags); - bool tx_throttle = test_and_clear_bit(THROTTLE_TX, &hw->usb_flags) && - !test_and_set_bit(WORK_TX_RESUME, &hw->usb_flags); - /* - * We need to check BOTH the RX and the TX throttle controls, - * so we use the bitwise OR instead of the logical OR. - */ - if (rx_throttle | tx_throttle) - schedule_work(&hw->usb_work); - } - - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); -} - -/*---------------------------------------------------------------- - * hfa384x_usbctlx_submit - * - * Called from the doxxx functions to submit a CTLX to the queue - * - * Arguments: - * hw ptr to the hw struct - * ctlx ctlx structure to enqueue - * - * Returns: - * -ENODEV if the adapter is unplugged - * 0 - * - * Side effects: - * - * Call context: - * process or interrupt - *---------------------------------------------------------------- - */ -static int hfa384x_usbctlx_submit(struct hfa384x *hw, - struct hfa384x_usbctlx *ctlx) -{ - unsigned long flags; - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - if (hw->wlandev->hwremoved) { - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - return -ENODEV; - } - - ctlx->state = CTLX_PENDING; - list_add_tail(&ctlx->list, &hw->ctlxq.pending); - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - hfa384x_usbctlxq_run(hw); - - return 0; -} - -/*---------------------------------------------------------------- - * hfa384x_isgood_pdrcore - * - * Quick check of PDR codes. - * - * Arguments: - * pdrcode PDR code number (host order) - * - * Returns: - * zero not good. - * one is good. - * - * Side effects: - * - * Call context: - *---------------------------------------------------------------- - */ -static int hfa384x_isgood_pdrcode(u16 pdrcode) -{ - switch (pdrcode) { - case HFA384x_PDR_END_OF_PDA: - case HFA384x_PDR_PCB_PARTNUM: - case HFA384x_PDR_PDAVER: - case HFA384x_PDR_NIC_SERIAL: - case HFA384x_PDR_MKK_MEASUREMENTS: - case HFA384x_PDR_NIC_RAMSIZE: - case HFA384x_PDR_MFISUPRANGE: - case HFA384x_PDR_CFISUPRANGE: - case HFA384x_PDR_NICID: - case HFA384x_PDR_MAC_ADDRESS: - case HFA384x_PDR_REGDOMAIN: - case HFA384x_PDR_ALLOWED_CHANNEL: - case HFA384x_PDR_DEFAULT_CHANNEL: - case HFA384x_PDR_TEMPTYPE: - case HFA384x_PDR_IFR_SETTING: - case HFA384x_PDR_RFR_SETTING: - case HFA384x_PDR_HFA3861_BASELINE: - case HFA384x_PDR_HFA3861_SHADOW: - case HFA384x_PDR_HFA3861_IFRF: - case HFA384x_PDR_HFA3861_CHCALSP: - case HFA384x_PDR_HFA3861_CHCALI: - case HFA384x_PDR_3842_NIC_CONFIG: - case HFA384x_PDR_USB_ID: - case HFA384x_PDR_PCI_ID: - case HFA384x_PDR_PCI_IFCONF: - case HFA384x_PDR_PCI_PMCONF: - case HFA384x_PDR_RFENRGY: - case HFA384x_PDR_HFA3861_MANF_TESTSP: - case HFA384x_PDR_HFA3861_MANF_TESTI: - /* code is OK */ - return 1; - default: - if (pdrcode < 0x1000) { - /* code is OK, but we don't know exactly what it is */ - pr_debug("Encountered unknown PDR#=0x%04x, assuming it's ok.\n", - pdrcode); - return 1; - } - break; - } - /* bad code */ - pr_debug("Encountered unknown PDR#=0x%04x, (>=0x1000), assuming it's bad.\n", - pdrcode); - return 0; -} diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c deleted file mode 100644 index 8336435eccc2..000000000000 --- a/drivers/staging/wlan-ng/p80211conv.c +++ /dev/null @@ -1,643 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) -/* - * - * Ether/802.11 conversions and packet buffer routines - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file defines the functions that perform Ethernet to/from - * 802.11 frame conversions. - * - * -------------------------------------------------------------------- - * - *================================================================ - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/skbuff.h> -#include <linux/slab.h> -#include <linux/wireless.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/if_ether.h> -#include <linux/byteorder/generic.h> - -#include <asm/byteorder.h> - -#include "p80211types.h" -#include "p80211hdr.h" -#include "p80211conv.h" -#include "p80211mgmt.h" -#include "p80211msg.h" -#include "p80211netdev.h" -#include "p80211ioctl.h" -#include "p80211req.h" - -static const u8 oui_rfc1042[] = { 0x00, 0x00, 0x00 }; -static const u8 oui_8021h[] = { 0x00, 0x00, 0xf8 }; - -/*---------------------------------------------------------------- - * p80211pb_ether_to_80211 - * - * Uses the contents of the ether frame and the etherconv setting - * to build the elements of the 802.11 frame. - * - * We don't actually set - * up the frame header here. That's the MAC's job. We're only handling - * conversion of DIXII or 802.3+LLC frames to something that works - * with 802.11. - * - * Note -- 802.11 header is NOT part of the skb. Likewise, the 802.11 - * FCS is also not present and will need to be added elsewhere. - * - * Arguments: - * ethconv Conversion type to perform - * skb skbuff containing the ether frame - * p80211_hdr 802.11 header - * - * Returns: - * 0 on success, non-zero otherwise - * - * Call context: - * May be called in interrupt or non-interrupt context - *---------------------------------------------------------------- - */ -int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv, - struct sk_buff *skb, struct p80211_hdr *p80211_hdr, - struct p80211_metawep *p80211_wep) -{ - __le16 fc; - u16 proto; - struct wlan_ethhdr e_hdr; - struct wlan_llc *e_llc; - struct wlan_snap *e_snap; - int foo; - - memcpy(&e_hdr, skb->data, sizeof(e_hdr)); - - if (skb->len <= 0) { - pr_debug("zero-length skb!\n"); - return 1; - } - - if (ethconv == WLAN_ETHCONV_ENCAP) { /* simplest case */ - pr_debug("ENCAP len: %d\n", skb->len); - /* here, we don't care what kind of ether frm. Just stick it */ - /* in the 80211 payload */ - /* which is to say, leave the skb alone. */ - } else { - /* step 1: classify ether frame, DIX or 802.3? */ - proto = ntohs(e_hdr.type); - if (proto <= ETH_DATA_LEN) { - pr_debug("802.3 len: %d\n", skb->len); - /* codes <= 1500 reserved for 802.3 lengths */ - /* it's 802.3, pass ether payload unchanged, */ - - /* trim off ethernet header */ - skb_pull(skb, ETH_HLEN); - - /* leave off any PAD octets. */ - skb_trim(skb, proto); - } else { - pr_debug("DIXII len: %d\n", skb->len); - /* it's DIXII, time for some conversion */ - - /* trim off ethernet header */ - skb_pull(skb, ETH_HLEN); - - /* tack on SNAP */ - e_snap = skb_push(skb, sizeof(struct wlan_snap)); - e_snap->type = htons(proto); - if (ethconv == WLAN_ETHCONV_8021h && - p80211_stt_findproto(proto)) { - memcpy(e_snap->oui, oui_8021h, - WLAN_IEEE_OUI_LEN); - } else { - memcpy(e_snap->oui, oui_rfc1042, - WLAN_IEEE_OUI_LEN); - } - - /* tack on llc */ - e_llc = skb_push(skb, sizeof(struct wlan_llc)); - e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */ - e_llc->ssap = 0xAA; - e_llc->ctl = 0x03; - } - } - - /* Set up the 802.11 header */ - /* It's a data frame */ - fc = cpu_to_le16(WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY)); - - switch (wlandev->macmode) { - case WLAN_MACMODE_IBSS_STA: - memcpy(p80211_hdr->address1, &e_hdr.daddr, ETH_ALEN); - memcpy(p80211_hdr->address2, wlandev->netdev->dev_addr, ETH_ALEN); - memcpy(p80211_hdr->address3, wlandev->bssid, ETH_ALEN); - break; - case WLAN_MACMODE_ESS_STA: - fc |= cpu_to_le16(WLAN_SET_FC_TODS(1)); - memcpy(p80211_hdr->address1, wlandev->bssid, ETH_ALEN); - memcpy(p80211_hdr->address2, wlandev->netdev->dev_addr, ETH_ALEN); - memcpy(p80211_hdr->address3, &e_hdr.daddr, ETH_ALEN); - break; - case WLAN_MACMODE_ESS_AP: - fc |= cpu_to_le16(WLAN_SET_FC_FROMDS(1)); - memcpy(p80211_hdr->address1, &e_hdr.daddr, ETH_ALEN); - memcpy(p80211_hdr->address2, wlandev->bssid, ETH_ALEN); - memcpy(p80211_hdr->address3, &e_hdr.saddr, ETH_ALEN); - break; - default: - netdev_err(wlandev->netdev, - "Error: Converting eth to wlan in unknown mode.\n"); - return 1; - } - - p80211_wep->data = NULL; - - if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && - (wlandev->hostwep & HOSTWEP_ENCRYPT)) { - /* XXXX need to pick keynum other than default? */ - - p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC); - if (!p80211_wep->data) - return -ENOMEM; - foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, - skb->len, - wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK, - p80211_wep->iv, p80211_wep->icv); - if (foo) { - netdev_warn(wlandev->netdev, - "Host en-WEP failed, dropping frame (%d).\n", - foo); - kfree(p80211_wep->data); - return 2; - } - fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1)); - } - - /* skb->nh.raw = skb->data; */ - - p80211_hdr->frame_control = fc; - p80211_hdr->duration_id = 0; - p80211_hdr->sequence_control = 0; - - return 0; -} - -/* jkriegl: from orinoco, modified */ -static void orinoco_spy_gather(struct wlandevice *wlandev, char *mac, - struct p80211_rxmeta *rxmeta) -{ - int i; - - /* Gather wireless spy statistics: for each packet, compare the - * source address with out list, and if match, get the stats... - */ - - for (i = 0; i < wlandev->spy_number; i++) { - if (!memcmp(wlandev->spy_address[i], mac, ETH_ALEN)) { - wlandev->spy_stat[i].level = rxmeta->signal; - wlandev->spy_stat[i].noise = rxmeta->noise; - wlandev->spy_stat[i].qual = - (rxmeta->signal > - rxmeta->noise) ? (rxmeta->signal - - rxmeta->noise) : 0; - wlandev->spy_stat[i].updated = 0x7; - } - } -} - -/*---------------------------------------------------------------- - * p80211pb_80211_to_ether - * - * Uses the contents of a received 802.11 frame and the etherconv - * setting to build an ether frame. - * - * This function extracts the src and dest address from the 802.11 - * frame to use in the construction of the eth frame. - * - * Arguments: - * ethconv Conversion type to perform - * skb Packet buffer containing the 802.11 frame - * - * Returns: - * 0 on success, non-zero otherwise - * - * Call context: - * May be called in interrupt or non-interrupt context - *---------------------------------------------------------------- - */ -int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, - struct sk_buff *skb) -{ - struct net_device *netdev = wlandev->netdev; - u16 fc; - unsigned int payload_length; - unsigned int payload_offset; - u8 daddr[ETH_ALEN]; - u8 saddr[ETH_ALEN]; - struct p80211_hdr *w_hdr; - struct wlan_ethhdr *e_hdr; - struct wlan_llc *e_llc; - struct wlan_snap *e_snap; - - int foo; - - payload_length = skb->len - WLAN_HDR_A3_LEN - WLAN_CRC_LEN; - payload_offset = WLAN_HDR_A3_LEN; - - w_hdr = (struct p80211_hdr *)skb->data; - - /* setup some vars for convenience */ - fc = le16_to_cpu(w_hdr->frame_control); - if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0)) { - ether_addr_copy(daddr, w_hdr->address1); - ether_addr_copy(saddr, w_hdr->address2); - } else if ((WLAN_GET_FC_TODS(fc) == 0) && - (WLAN_GET_FC_FROMDS(fc) == 1)) { - ether_addr_copy(daddr, w_hdr->address1); - ether_addr_copy(saddr, w_hdr->address3); - } else if ((WLAN_GET_FC_TODS(fc) == 1) && - (WLAN_GET_FC_FROMDS(fc) == 0)) { - ether_addr_copy(daddr, w_hdr->address3); - ether_addr_copy(saddr, w_hdr->address2); - } else { - payload_offset = WLAN_HDR_A4_LEN; - if (payload_length < WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN) { - netdev_err(netdev, "A4 frame too short!\n"); - return 1; - } - payload_length -= (WLAN_HDR_A4_LEN - WLAN_HDR_A3_LEN); - ether_addr_copy(daddr, w_hdr->address3); - ether_addr_copy(saddr, w_hdr->address4); - } - - /* perform de-wep if necessary.. */ - if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && - WLAN_GET_FC_ISWEP(fc) && - (wlandev->hostwep & HOSTWEP_DECRYPT)) { - if (payload_length <= 8) { - netdev_err(netdev, - "WEP frame too short (%u).\n", skb->len); - return 1; - } - foo = wep_decrypt(wlandev, skb->data + payload_offset + 4, - payload_length - 8, -1, - skb->data + payload_offset, - skb->data + payload_offset + - payload_length - 4); - if (foo) { - /* de-wep failed, drop skb. */ - netdev_dbg(netdev, "Host de-WEP failed, dropping frame (%d).\n", - foo); - wlandev->rx.decrypt_err++; - return 2; - } - - /* subtract the IV+ICV length off the payload */ - payload_length -= 8; - /* chop off the IV */ - skb_pull(skb, 4); - /* chop off the ICV. */ - skb_trim(skb, skb->len - 4); - - wlandev->rx.decrypt++; - } - - e_hdr = (struct wlan_ethhdr *)(skb->data + payload_offset); - - e_llc = (struct wlan_llc *)(skb->data + payload_offset); - e_snap = - (struct wlan_snap *)(skb->data + payload_offset + - sizeof(struct wlan_llc)); - - /* Test for the various encodings */ - if ((payload_length >= sizeof(struct wlan_ethhdr)) && - (e_llc->dsap != 0xaa || e_llc->ssap != 0xaa) && - ((!ether_addr_equal_unaligned(daddr, e_hdr->daddr)) || - (!ether_addr_equal_unaligned(saddr, e_hdr->saddr)))) { - netdev_dbg(netdev, "802.3 ENCAP len: %d\n", payload_length); - /* 802.3 Encapsulated */ - /* Test for an overlength frame */ - if (payload_length > (netdev->mtu + ETH_HLEN)) { - /* A bogus length ethfrm has been encap'd. */ - /* Is someone trying an oflow attack? */ - netdev_err(netdev, "ENCAP frame too large (%d > %d)\n", - payload_length, netdev->mtu + ETH_HLEN); - return 1; - } - - /* Chop off the 802.11 header. it's already sane. */ - skb_pull(skb, payload_offset); - /* chop off the 802.11 CRC */ - skb_trim(skb, skb->len - WLAN_CRC_LEN); - - } else if ((payload_length >= sizeof(struct wlan_llc) + - sizeof(struct wlan_snap)) && - (e_llc->dsap == 0xaa) && - (e_llc->ssap == 0xaa) && - (e_llc->ctl == 0x03) && - (((memcmp(e_snap->oui, oui_rfc1042, - WLAN_IEEE_OUI_LEN) == 0) && - (ethconv == WLAN_ETHCONV_8021h) && - (p80211_stt_findproto(be16_to_cpu(e_snap->type)))) || - (memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) != - 0))) { - netdev_dbg(netdev, "SNAP+RFC1042 len: %d\n", payload_length); - /* it's a SNAP + RFC1042 frame && protocol is in STT */ - /* build 802.3 + RFC1042 */ - - /* Test for an overlength frame */ - if (payload_length > netdev->mtu) { - /* A bogus length ethfrm has been sent. */ - /* Is someone trying an oflow attack? */ - netdev_err(netdev, "SNAP frame too large (%d > %d)\n", - payload_length, netdev->mtu); - return 1; - } - - /* chop 802.11 header from skb. */ - skb_pull(skb, payload_offset); - - /* create 802.3 header at beginning of skb. */ - e_hdr = skb_push(skb, ETH_HLEN); - ether_addr_copy(e_hdr->daddr, daddr); - ether_addr_copy(e_hdr->saddr, saddr); - e_hdr->type = htons(payload_length); - - /* chop off the 802.11 CRC */ - skb_trim(skb, skb->len - WLAN_CRC_LEN); - - } else if ((payload_length >= sizeof(struct wlan_llc) + - sizeof(struct wlan_snap)) && - (e_llc->dsap == 0xaa) && - (e_llc->ssap == 0xaa) && - (e_llc->ctl == 0x03)) { - netdev_dbg(netdev, "802.1h/RFC1042 len: %d\n", payload_length); - /* it's an 802.1h frame || (an RFC1042 && protocol not in STT) - * build a DIXII + RFC894 - */ - - /* Test for an overlength frame */ - if ((payload_length - sizeof(struct wlan_llc) - - sizeof(struct wlan_snap)) - > netdev->mtu) { - /* A bogus length ethfrm has been sent. */ - /* Is someone trying an oflow attack? */ - netdev_err(netdev, "DIXII frame too large (%ld > %d)\n", - (long)(payload_length - - sizeof(struct wlan_llc) - - sizeof(struct wlan_snap)), netdev->mtu); - return 1; - } - - /* chop 802.11 header from skb. */ - skb_pull(skb, payload_offset); - - /* chop llc header from skb. */ - skb_pull(skb, sizeof(struct wlan_llc)); - - /* chop snap header from skb. */ - skb_pull(skb, sizeof(struct wlan_snap)); - - /* create 802.3 header at beginning of skb. */ - e_hdr = skb_push(skb, ETH_HLEN); - e_hdr->type = e_snap->type; - ether_addr_copy(e_hdr->daddr, daddr); - ether_addr_copy(e_hdr->saddr, saddr); - - /* chop off the 802.11 CRC */ - skb_trim(skb, skb->len - WLAN_CRC_LEN); - } else { - netdev_dbg(netdev, "NON-ENCAP len: %d\n", payload_length); - /* any NON-ENCAP */ - /* it's a generic 80211+LLC or IPX 'Raw 802.3' */ - /* build an 802.3 frame */ - /* allocate space and setup hostbuf */ - - /* Test for an overlength frame */ - if (payload_length > netdev->mtu) { - /* A bogus length ethfrm has been sent. */ - /* Is someone trying an oflow attack? */ - netdev_err(netdev, "OTHER frame too large (%d > %d)\n", - payload_length, netdev->mtu); - return 1; - } - - /* Chop off the 802.11 header. */ - skb_pull(skb, payload_offset); - - /* create 802.3 header at beginning of skb. */ - e_hdr = skb_push(skb, ETH_HLEN); - ether_addr_copy(e_hdr->daddr, daddr); - ether_addr_copy(e_hdr->saddr, saddr); - e_hdr->type = htons(payload_length); - - /* chop off the 802.11 CRC */ - skb_trim(skb, skb->len - WLAN_CRC_LEN); - } - - /* - * Note that eth_type_trans() expects an skb w/ skb->data pointing - * at the MAC header, it then sets the following skb members: - * skb->mac_header, - * skb->data, and - * skb->pkt_type. - * It then _returns_ the value that _we're_ supposed to stuff in - * skb->protocol. This is nuts. - */ - skb->protocol = eth_type_trans(skb, netdev); - - /* jkriegl: process signal and noise as set in hfa384x_int_rx() */ - /* jkriegl: only process signal/noise if requested by iwspy */ - if (wlandev->spy_number) - orinoco_spy_gather(wlandev, eth_hdr(skb)->h_source, - p80211skb_rxmeta(skb)); - - /* Free the metadata */ - p80211skb_rxmeta_detach(skb); - - return 0; -} - -/*---------------------------------------------------------------- - * p80211_stt_findproto - * - * Searches the 802.1h Selective Translation Table for a given - * protocol. - * - * Arguments: - * proto protocol number (in host order) to search for. - * - * Returns: - * 1 - if the table is empty or a match is found. - * 0 - if the table is non-empty and a match is not found. - * - * Call context: - * May be called in interrupt or non-interrupt context - *---------------------------------------------------------------- - */ -int p80211_stt_findproto(u16 proto) -{ - /* Always return found for now. This is the behavior used by the */ - /* Zoom Win95 driver when 802.1h mode is selected */ - /* TODO: If necessary, add an actual search we'll probably - * need this to match the CMAC's way of doing things. - * Need to do some testing to confirm. - */ - - if (proto == ETH_P_AARP) /* APPLETALK */ - return 1; - - return 0; -} - -/*---------------------------------------------------------------- - * p80211skb_rxmeta_detach - * - * Disconnects the frmmeta and rxmeta from an skb. - * - * Arguments: - * wlandev The wlandev this skb belongs to. - * skb The skb we're attaching to. - * - * Returns: - * 0 on success, non-zero otherwise - * - * Call context: - * May be called in interrupt or non-interrupt context - *---------------------------------------------------------------- - */ -void p80211skb_rxmeta_detach(struct sk_buff *skb) -{ - struct p80211_rxmeta *rxmeta; - struct p80211_frmmeta *frmmeta; - - /* Sanity checks */ - if (!skb) { /* bad skb */ - pr_debug("Called w/ null skb.\n"); - return; - } - frmmeta = p80211skb_frmmeta(skb); - if (!frmmeta) { /* no magic */ - pr_debug("Called w/ bad frmmeta magic.\n"); - return; - } - rxmeta = frmmeta->rx; - if (!rxmeta) { /* bad meta ptr */ - pr_debug("Called w/ bad rxmeta ptr.\n"); - return; - } - - /* Free rxmeta */ - kfree(rxmeta); - - /* Clear skb->cb */ - memset(skb->cb, 0, sizeof(skb->cb)); -} - -/*---------------------------------------------------------------- - * p80211skb_rxmeta_attach - * - * Allocates a p80211rxmeta structure, initializes it, and attaches - * it to an skb. - * - * Arguments: - * wlandev The wlandev this skb belongs to. - * skb The skb we're attaching to. - * - * Returns: - * 0 on success, non-zero otherwise - * - * Call context: - * May be called in interrupt or non-interrupt context - *---------------------------------------------------------------- - */ -int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb) -{ - int result = 0; - struct p80211_rxmeta *rxmeta; - struct p80211_frmmeta *frmmeta; - - /* If these already have metadata, we error out! */ - if (p80211skb_rxmeta(skb)) { - netdev_err(wlandev->netdev, - "%s: RXmeta already attached!\n", wlandev->name); - result = 0; - goto exit; - } - - /* Allocate the rxmeta */ - rxmeta = kzalloc(sizeof(*rxmeta), GFP_ATOMIC); - - if (!rxmeta) { - result = 1; - goto exit; - } - - /* Initialize the rxmeta */ - rxmeta->wlandev = wlandev; - rxmeta->hosttime = jiffies; - - /* Overlay a frmmeta_t onto skb->cb */ - memset(skb->cb, 0, sizeof(struct p80211_frmmeta)); - frmmeta = (struct p80211_frmmeta *)(skb->cb); - frmmeta->magic = P80211_FRMMETA_MAGIC; - frmmeta->rx = rxmeta; -exit: - return result; -} - -/*---------------------------------------------------------------- - * p80211skb_free - * - * Frees an entire p80211skb by checking and freeing the meta struct - * and then freeing the skb. - * - * Arguments: - * wlandev The wlandev this skb belongs to. - * skb The skb we're attaching to. - * - * Returns: - * 0 on success, non-zero otherwise - * - * Call context: - * May be called in interrupt or non-interrupt context - *---------------------------------------------------------------- - */ -void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb) -{ - struct p80211_frmmeta *meta; - - meta = p80211skb_frmmeta(skb); - if (meta && meta->rx) - p80211skb_rxmeta_detach(skb); - else - netdev_err(wlandev->netdev, - "Freeing an skb (%p) w/ no frmmeta.\n", skb); - dev_kfree_skb(skb); -} diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h deleted file mode 100644 index 45234769f45d..000000000000 --- a/drivers/staging/wlan-ng/p80211conv.h +++ /dev/null @@ -1,141 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * Ether/802.11 conversions and packet buffer routines - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file declares the functions, types and macros that perform - * Ethernet to/from 802.11 frame conversions. - * - * -------------------------------------------------------------------- - */ - -#ifndef _LINUX_P80211CONV_H -#define _LINUX_P80211CONV_H - -#define WLAN_IEEE_OUI_LEN 3 - -#define WLAN_ETHCONV_ENCAP 1 -#define WLAN_ETHCONV_8021h 3 - -#define P80211CAPTURE_VERSION 0x80211001 - -#define P80211_FRMMETA_MAGIC 0x802110 - -struct p80211_rxmeta { - struct wlandevice *wlandev; - - u64 mactime; /* Hi-rez MAC-supplied time value */ - u64 hosttime; /* Best-rez host supplied time value */ - - unsigned int rxrate; /* Receive data rate in 100kbps */ - unsigned int priority; /* 0-15, 0=contention, 6=CF */ - int signal; /* An SSI, see p80211netdev.h */ - int noise; /* An SSI, see p80211netdev.h */ - unsigned int channel; /* Receive channel (mostly for snifs) */ - unsigned int preamble; /* P80211ENUM_preambletype_* */ - unsigned int encoding; /* P80211ENUM_encoding_* */ - -}; - -struct p80211_frmmeta { - unsigned int magic; - struct p80211_rxmeta *rx; -}; - -void p80211skb_free(struct wlandevice *wlandev, struct sk_buff *skb); -int p80211skb_rxmeta_attach(struct wlandevice *wlandev, struct sk_buff *skb); -void p80211skb_rxmeta_detach(struct sk_buff *skb); - -static inline struct p80211_frmmeta *p80211skb_frmmeta(struct sk_buff *skb) -{ - struct p80211_frmmeta *frmmeta = (struct p80211_frmmeta *)skb->cb; - - return frmmeta->magic == P80211_FRMMETA_MAGIC ? frmmeta : NULL; -} - -static inline struct p80211_rxmeta *p80211skb_rxmeta(struct sk_buff *skb) -{ - struct p80211_frmmeta *frmmeta = p80211skb_frmmeta(skb); - - return frmmeta ? frmmeta->rx : NULL; -} - -/* - * Frame capture header. (See doc/capturefrm.txt) - */ -struct p80211_caphdr { - __be32 version; - __be32 length; - __be64 mactime; - __be64 hosttime; - __be32 phytype; - __be32 channel; - __be32 datarate; - __be32 antenna; - __be32 priority; - __be32 ssi_type; - __be32 ssi_signal; - __be32 ssi_noise; - __be32 preamble; - __be32 encoding; -}; - -struct p80211_metawep { - void *data; - u8 iv[4]; - u8 icv[4]; -}; - -/* local ether header type */ -struct wlan_ethhdr { - u8 daddr[ETH_ALEN]; - u8 saddr[ETH_ALEN]; - __be16 type; -} __packed; - -/* local llc header type */ -struct wlan_llc { - u8 dsap; - u8 ssap; - u8 ctl; -} __packed; - -/* local snap header type */ -struct wlan_snap { - u8 oui[WLAN_IEEE_OUI_LEN]; - __be16 type; -} __packed; - -/* Circular include trick */ -struct wlandevice; - -int skb_p80211_to_ether(struct wlandevice *wlandev, u32 ethconv, - struct sk_buff *skb); -int skb_ether_to_p80211(struct wlandevice *wlandev, u32 ethconv, - struct sk_buff *skb, struct p80211_hdr *p80211_hdr, - struct p80211_metawep *p80211_wep); - -int p80211_stt_findproto(u16 proto); - -#endif diff --git a/drivers/staging/wlan-ng/p80211hdr.h b/drivers/staging/wlan-ng/p80211hdr.h deleted file mode 100644 index 7ea1c8ec05ed..000000000000 --- a/drivers/staging/wlan-ng/p80211hdr.h +++ /dev/null @@ -1,189 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * Macros, types, and functions for handling 802.11 MAC headers - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file declares the constants and types used in the interface - * between a wlan driver and the user mode utilities. - * - * Note: - * - Constant values are always in HOST byte order. To assign - * values to multi-byte fields they _must_ be converted to - * ieee byte order. To retrieve multi-byte values from incoming - * frames, they must be converted to host order. - * - * All functions declared here are implemented in p80211.c - * -------------------------------------------------------------------- - */ - -#ifndef _P80211HDR_H -#define _P80211HDR_H - -#include <linux/if_ether.h> - -/*--- Sizes -----------------------------------------------*/ -#define WLAN_CRC_LEN 4 -#define WLAN_BSSID_LEN 6 -#define WLAN_HDR_A3_LEN 24 -#define WLAN_HDR_A4_LEN 30 -#define WLAN_SSID_MAXLEN 32 -#define WLAN_DATA_MAXLEN 2312 -#define WLAN_WEP_IV_LEN 4 -#define WLAN_WEP_ICV_LEN 4 - -/*--- Frame Control Field -------------------------------------*/ -/* Frame Types */ -#define WLAN_FTYPE_MGMT 0x00 -#define WLAN_FTYPE_CTL 0x01 -#define WLAN_FTYPE_DATA 0x02 - -/* Frame subtypes */ -/* Management */ -#define WLAN_FSTYPE_ASSOCREQ 0x00 -#define WLAN_FSTYPE_ASSOCRESP 0x01 -#define WLAN_FSTYPE_REASSOCREQ 0x02 -#define WLAN_FSTYPE_REASSOCRESP 0x03 -#define WLAN_FSTYPE_PROBEREQ 0x04 -#define WLAN_FSTYPE_PROBERESP 0x05 -#define WLAN_FSTYPE_BEACON 0x08 -#define WLAN_FSTYPE_ATIM 0x09 -#define WLAN_FSTYPE_DISASSOC 0x0a -#define WLAN_FSTYPE_AUTHEN 0x0b -#define WLAN_FSTYPE_DEAUTHEN 0x0c - -/* Control */ -#define WLAN_FSTYPE_BLOCKACKREQ 0x8 -#define WLAN_FSTYPE_BLOCKACK 0x9 -#define WLAN_FSTYPE_PSPOLL 0x0a -#define WLAN_FSTYPE_RTS 0x0b -#define WLAN_FSTYPE_CTS 0x0c -#define WLAN_FSTYPE_ACK 0x0d -#define WLAN_FSTYPE_CFEND 0x0e -#define WLAN_FSTYPE_CFENDCFACK 0x0f - -/* Data */ -#define WLAN_FSTYPE_DATAONLY 0x00 -#define WLAN_FSTYPE_DATA_CFACK 0x01 -#define WLAN_FSTYPE_DATA_CFPOLL 0x02 -#define WLAN_FSTYPE_DATA_CFACK_CFPOLL 0x03 -#define WLAN_FSTYPE_NULL 0x04 -#define WLAN_FSTYPE_CFACK 0x05 -#define WLAN_FSTYPE_CFPOLL 0x06 -#define WLAN_FSTYPE_CFACK_CFPOLL 0x07 - -/*--- FC Macros ----------------------------------------------*/ -/* Macros to get/set the bitfields of the Frame Control Field */ -/* GET_FC_??? - takes the host byte-order value of an FC */ -/* and retrieves the value of one of the */ -/* bitfields and moves that value so its lsb is */ -/* in bit 0. */ -/* SET_FC_??? - takes a host order value for one of the FC */ -/* bitfields and moves it to the proper bit */ -/* location for ORing into a host order FC. */ -/* To send the FC produced from SET_FC_???, */ -/* one must put the bytes in IEEE order. */ -/* e.g. */ -/* printf("the frame subtype is %x", */ -/* GET_FC_FTYPE( ieee2host( rx.fc ))) */ -/* */ -/* tx.fc = host2ieee( SET_FC_FTYPE(WLAN_FTYP_CTL) | */ -/* SET_FC_FSTYPE(WLAN_FSTYPE_RTS) ); */ -/*------------------------------------------------------------*/ - -#define WLAN_GET_FC_FTYPE(n) ((((u16)(n)) & GENMASK(3, 2)) >> 2) -#define WLAN_GET_FC_FSTYPE(n) ((((u16)(n)) & GENMASK(7, 4)) >> 4) -#define WLAN_GET_FC_TODS(n) ((((u16)(n)) & (BIT(8))) >> 8) -#define WLAN_GET_FC_FROMDS(n) ((((u16)(n)) & (BIT(9))) >> 9) -#define WLAN_GET_FC_ISWEP(n) ((((u16)(n)) & (BIT(14))) >> 14) - -#define WLAN_SET_FC_FTYPE(n) (((u16)(n)) << 2) -#define WLAN_SET_FC_FSTYPE(n) (((u16)(n)) << 4) -#define WLAN_SET_FC_TODS(n) (((u16)(n)) << 8) -#define WLAN_SET_FC_FROMDS(n) (((u16)(n)) << 9) -#define WLAN_SET_FC_ISWEP(n) (((u16)(n)) << 14) - -#define DOT11_RATE5_ISBASIC_GET(r) (((u8)(r)) & BIT(7)) - -/* Generic 802.11 Header types */ - -struct p80211_hdr { - __le16 frame_control; - u16 duration_id; - u8 address1[ETH_ALEN]; - u8 address2[ETH_ALEN]; - u8 address3[ETH_ALEN]; - u16 sequence_control; - u8 address4[ETH_ALEN]; -} __packed; - -/* Frame and header length macros */ - -static inline u16 wlan_ctl_framelen(u16 fstype) -{ - switch (fstype) { - case WLAN_FSTYPE_BLOCKACKREQ: - return 24; - case WLAN_FSTYPE_BLOCKACK: - return 152; - case WLAN_FSTYPE_PSPOLL: - case WLAN_FSTYPE_RTS: - case WLAN_FSTYPE_CFEND: - case WLAN_FSTYPE_CFENDCFACK: - return 20; - case WLAN_FSTYPE_CTS: - case WLAN_FSTYPE_ACK: - return 14; - default: - return 4; - } -} - -#define WLAN_FCS_LEN 4 - -/* ftcl in HOST order */ -static inline u16 p80211_headerlen(u16 fctl) -{ - u16 hdrlen = 0; - - switch (WLAN_GET_FC_FTYPE(fctl)) { - case WLAN_FTYPE_MGMT: - hdrlen = WLAN_HDR_A3_LEN; - break; - case WLAN_FTYPE_DATA: - hdrlen = WLAN_HDR_A3_LEN; - if (WLAN_GET_FC_TODS(fctl) && WLAN_GET_FC_FROMDS(fctl)) - hdrlen += ETH_ALEN; - break; - case WLAN_FTYPE_CTL: - hdrlen = wlan_ctl_framelen(WLAN_GET_FC_FSTYPE(fctl)) - - WLAN_FCS_LEN; - break; - default: - hdrlen = WLAN_HDR_A3_LEN; - } - - return hdrlen; -} - -#endif /* _P80211HDR_H */ diff --git a/drivers/staging/wlan-ng/p80211ioctl.h b/drivers/staging/wlan-ng/p80211ioctl.h deleted file mode 100644 index 176e327a45bc..000000000000 --- a/drivers/staging/wlan-ng/p80211ioctl.h +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * Declares constants and types for the p80211 ioctls - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * While this file is called 'ioctl' is purpose goes a little beyond - * that. This file defines the types and contants used to implement - * the p80211 request/confirm/indicate interfaces on Linux. The - * request/confirm interface is, in fact, normally implemented as an - * ioctl. The indicate interface on the other hand, is implemented - * using the Linux 'netlink' interface. - * - * The reason I say that request/confirm is 'normally' implemented - * via ioctl is that we're reserving the right to be able to send - * request commands via the netlink interface. This will be necessary - * if we ever need to send request messages when there aren't any - * wlan network devices present (i.e. sending a message that only p80211 - * cares about. - * -------------------------------------------------------------------- - */ - -#ifndef _P80211IOCTL_H -#define _P80211IOCTL_H - -/* p80211 ioctl "request" codes. See argument 2 of ioctl(2). */ - -#define P80211_IFTEST (SIOCDEVPRIVATE + 0) -#define P80211_IFREQ (SIOCDEVPRIVATE + 1) - -/*----------------------------------------------------------------*/ -/* Magic number, a quick test to see we're getting the desired struct */ - -#define P80211_IOCTL_MAGIC (0x4a2d464dUL) - -/*----------------------------------------------------------------*/ -/* A ptr to the following structure type is passed as the third */ -/* argument to the ioctl system call when issuing a request to */ -/* the p80211 module. */ - -struct p80211ioctl_req { - char name[WLAN_DEVNAMELEN_MAX]; - char __user *data; - u32 magic; - u16 len; - u32 result; -} __packed; - -#endif /* _P80211IOCTL_H */ diff --git a/drivers/staging/wlan-ng/p80211metadef.h b/drivers/staging/wlan-ng/p80211metadef.h deleted file mode 100644 index 1cbb4b67a9a6..000000000000 --- a/drivers/staging/wlan-ng/p80211metadef.h +++ /dev/null @@ -1,227 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* -------------------------------------------------------------------- - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - */ - -#ifndef _P80211MKMETADEF_H -#define _P80211MKMETADEF_H - -#define DIDMSG_DOT11REQ_MIBGET \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(1)) -#define DIDMSG_DOT11REQ_MIBGET_MIBATTRIBUTE \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(1) | 0x00000000) -#define DIDMSG_DOT11REQ_MIBGET_RESULTCODE \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(2) | 0x00000000) -#define DIDMSG_DOT11REQ_MIBSET \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(2)) -#define DIDMSG_DOT11REQ_MIBSET_MIBATTRIBUTE \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(2) | \ - P80211DID_MKITEM(1) | 0x00000000) -#define DIDMSG_DOT11REQ_MIBSET_RESULTCODE \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(2) | \ - P80211DID_MKITEM(2) | 0x00000000) -#define DIDMSG_DOT11REQ_SCAN \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(4)) -#define DIDMSG_DOT11REQ_SCAN_RESULTS \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(5)) -#define DIDMSG_DOT11REQ_START \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(13)) -#define DIDMSG_DOT11IND_AUTHENTICATE \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1)) -#define DIDMSG_DOT11IND_ASSOCIATE \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(3)) -#define DIDMSG_LNXREQ_IFSTATE \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(1)) -#define DIDMSG_LNXREQ_WLANSNIFF \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(2)) -#define DIDMSG_LNXREQ_HOSTWEP \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(3)) -#define DIDMSG_LNXREQ_COMMSQUALITY \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(4)) -#define DIDMSG_LNXREQ_AUTOJOIN \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(5)) -#define DIDMSG_P2REQ_READPDA \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(2)) -#define DIDMSG_P2REQ_READPDA_PDA \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(2) | \ - P80211DID_MKITEM(1) | 0x00000000) -#define DIDMSG_P2REQ_READPDA_RESULTCODE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(2) | \ - P80211DID_MKITEM(2) | 0x00000000) -#define DIDMSG_P2REQ_RAMDL_STATE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(11)) -#define DIDMSG_P2REQ_RAMDL_STATE_ENABLE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(11) | \ - P80211DID_MKITEM(1) | 0x00000000) -#define DIDMSG_P2REQ_RAMDL_STATE_EXEADDR \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(11) | \ - P80211DID_MKITEM(2) | 0x00000000) -#define DIDMSG_P2REQ_RAMDL_STATE_RESULTCODE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(11) | \ - P80211DID_MKITEM(3) | 0x00000000) -#define DIDMSG_P2REQ_RAMDL_WRITE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(12)) -#define DIDMSG_P2REQ_RAMDL_WRITE_ADDR \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(12) | \ - P80211DID_MKITEM(1) | 0x00000000) -#define DIDMSG_P2REQ_RAMDL_WRITE_LEN \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(12) | \ - P80211DID_MKITEM(2) | 0x00000000) -#define DIDMSG_P2REQ_RAMDL_WRITE_DATA \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(12) | \ - P80211DID_MKITEM(3) | 0x00000000) -#define DIDMSG_P2REQ_RAMDL_WRITE_RESULTCODE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(12) | \ - P80211DID_MKITEM(4) | 0x00000000) -#define DIDMSG_P2REQ_FLASHDL_STATE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(13)) -#define DIDMSG_P2REQ_FLASHDL_WRITE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(14)) -#define DIDMIB_CAT_DOT11SMT \ - P80211DID_MKSECTION(1) -#define DIDMIB_DOT11SMT_WEPDEFAULTKEYSTABLE \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(4)) -#define didmib_dot11smt_wepdefaultkeystable_key(_i) \ - (DIDMIB_DOT11SMT_WEPDEFAULTKEYSTABLE | \ - P80211DID_MKITEM(_i) | 0x0c000000) -#define DIDMIB_DOT11SMT_PRIVACYTABLE \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(6)) -#define DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(6) | \ - P80211DID_MKITEM(1) | 0x18000000) -#define DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(6) | \ - P80211DID_MKITEM(2) | 0x18000000) -#define DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED \ - (P80211DID_MKSECTION(1) | \ - P80211DID_MKGROUP(6) | \ - P80211DID_MKITEM(4) | 0x18000000) -#define DIDMIB_DOT11MAC_OPERATIONTABLE \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1)) -#define DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(1) | 0x18000000) -#define DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(2) | 0x18000000) -#define DIDMIB_DOT11MAC_OPERATIONTABLE_SHORTRETRYLIMIT \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(3) | 0x10000000) -#define DIDMIB_DOT11MAC_OPERATIONTABLE_LONGRETRYLIMIT \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(4) | 0x10000000) -#define DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(5) | 0x18000000) -#define DIDMIB_DOT11MAC_OPERATIONTABLE_MAXTRANSMITMSDULIFETIME \ - (P80211DID_MKSECTION(2) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(6) | 0x10000000) -#define DIDMIB_CAT_DOT11PHY \ - P80211DID_MKSECTION(3) -#define DIDMIB_DOT11PHY_OPERATIONTABLE \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(1)) -#define DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(3) | \ - P80211DID_MKITEM(10) | 0x18000000) -#define DIDMIB_DOT11PHY_DSSSTABLE \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(5)) -#define DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL \ - (P80211DID_MKSECTION(3) | \ - P80211DID_MKGROUP(5) | \ - P80211DID_MKITEM(1) | 0x10000000) -#define DIDMIB_CAT_LNX \ - P80211DID_MKSECTION(4) -#define DIDMIB_LNX_CONFIGTABLE \ - (P80211DID_MKSECTION(4) | \ - P80211DID_MKGROUP(1)) -#define DIDMIB_LNX_CONFIGTABLE_RSNAIE \ - (P80211DID_MKSECTION(4) | \ - P80211DID_MKGROUP(1) | \ - P80211DID_MKITEM(1) | 0x18000000) -#define DIDMIB_CAT_P2 \ - P80211DID_MKSECTION(5) -#define DIDMIB_P2_STATIC \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(2)) -#define DIDMIB_P2_STATIC_CNFPORTTYPE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(2) | \ - P80211DID_MKITEM(1) | 0x18000000) -#define DIDMIB_P2_NIC_PRISUPRANGE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(5) | \ - P80211DID_MKITEM(6) | 0x10000000) -#define DIDMIB_P2_MAC \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(6)) -#define DIDMIB_P2_MAC_CURRENTTXRATE \ - (P80211DID_MKSECTION(5) | \ - P80211DID_MKGROUP(6) | \ - P80211DID_MKITEM(12) | 0x10000000) -#endif diff --git a/drivers/staging/wlan-ng/p80211metastruct.h b/drivers/staging/wlan-ng/p80211metastruct.h deleted file mode 100644 index a52217c9b953..000000000000 --- a/drivers/staging/wlan-ng/p80211metastruct.h +++ /dev/null @@ -1,236 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* -------------------------------------------------------------------- - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - */ - -#ifndef _P80211MKMETASTRUCT_H -#define _P80211MKMETASTRUCT_H - -struct p80211msg_dot11req_mibget { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_unk392 mibattribute; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_dot11req_mibset { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_unk392 mibattribute; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_dot11req_scan { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 bsstype; - struct p80211item_pstr6 bssid; - u8 pad_0C[1]; - struct p80211item_pstr32 ssid; - u8 pad_1D[3]; - struct p80211item_uint32 scantype; - struct p80211item_uint32 probedelay; - struct p80211item_pstr14 channellist; - u8 pad_2C[1]; - struct p80211item_uint32 minchanneltime; - struct p80211item_uint32 maxchanneltime; - struct p80211item_uint32 resultcode; - struct p80211item_uint32 numbss; - struct p80211item_uint32 append; -} __packed; - -struct p80211msg_dot11req_scan_results { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 bssindex; - struct p80211item_uint32 resultcode; - struct p80211item_uint32 signal; - struct p80211item_uint32 noise; - struct p80211item_pstr6 bssid; - u8 pad_3C[1]; - struct p80211item_pstr32 ssid; - u8 pad_4D[3]; - struct p80211item_uint32 bsstype; - struct p80211item_uint32 beaconperiod; - struct p80211item_uint32 dtimperiod; - struct p80211item_uint32 timestamp; - struct p80211item_uint32 localtime; - struct p80211item_uint32 fhdwelltime; - struct p80211item_uint32 fhhopset; - struct p80211item_uint32 fhhoppattern; - struct p80211item_uint32 fhhopindex; - struct p80211item_uint32 dschannel; - struct p80211item_uint32 cfpcount; - struct p80211item_uint32 cfpperiod; - struct p80211item_uint32 cfpmaxduration; - struct p80211item_uint32 cfpdurremaining; - struct p80211item_uint32 ibssatimwindow; - struct p80211item_uint32 cfpollable; - struct p80211item_uint32 cfpollreq; - struct p80211item_uint32 privacy; - struct p80211item_uint32 capinfo; - struct p80211item_uint32 basicrate[8]; - struct p80211item_uint32 supprate[8]; -} __packed; - -struct p80211msg_dot11req_start { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_pstr32 ssid; - u8 pad_12D[3]; - struct p80211item_uint32 bsstype; - struct p80211item_uint32 beaconperiod; - struct p80211item_uint32 dtimperiod; - struct p80211item_uint32 cfpperiod; - struct p80211item_uint32 cfpmaxduration; - struct p80211item_uint32 fhdwelltime; - struct p80211item_uint32 fhhopset; - struct p80211item_uint32 fhhoppattern; - struct p80211item_uint32 dschannel; - struct p80211item_uint32 ibssatimwindow; - struct p80211item_uint32 probedelay; - struct p80211item_uint32 cfpollable; - struct p80211item_uint32 cfpollreq; - struct p80211item_uint32 basicrate1; - struct p80211item_uint32 basicrate2; - struct p80211item_uint32 basicrate3; - struct p80211item_uint32 basicrate4; - struct p80211item_uint32 basicrate5; - struct p80211item_uint32 basicrate6; - struct p80211item_uint32 basicrate7; - struct p80211item_uint32 basicrate8; - struct p80211item_uint32 operationalrate1; - struct p80211item_uint32 operationalrate2; - struct p80211item_uint32 operationalrate3; - struct p80211item_uint32 operationalrate4; - struct p80211item_uint32 operationalrate5; - struct p80211item_uint32 operationalrate6; - struct p80211item_uint32 operationalrate7; - struct p80211item_uint32 operationalrate8; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_lnxreq_ifstate { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 ifstate; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_lnxreq_wlansniff { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 enable; - struct p80211item_uint32 channel; - struct p80211item_uint32 prismheader; - struct p80211item_uint32 wlanheader; - struct p80211item_uint32 keepwepflags; - struct p80211item_uint32 stripfcs; - struct p80211item_uint32 packet_trunc; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_lnxreq_hostwep { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 resultcode; - struct p80211item_uint32 decrypt; - struct p80211item_uint32 encrypt; -} __packed; - -struct p80211msg_lnxreq_commsquality { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 resultcode; - struct p80211item_uint32 dbm; - struct p80211item_uint32 link; - struct p80211item_uint32 level; - struct p80211item_uint32 noise; - struct p80211item_uint32 txrate; -} __packed; - -struct p80211msg_lnxreq_autojoin { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_pstr32 ssid; - u8 pad_19D[3]; - struct p80211item_uint32 authtype; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_p2req_readpda { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_unk1024 pda; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_p2req_ramdl_state { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 enable; - struct p80211item_uint32 exeaddr; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_p2req_ramdl_write { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 addr; - struct p80211item_uint32 len; - struct p80211item_unk4096 data; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_p2req_flashdl_state { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 enable; - struct p80211item_uint32 resultcode; -} __packed; - -struct p80211msg_p2req_flashdl_write { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; - struct p80211item_uint32 addr; - struct p80211item_uint32 len; - struct p80211item_unk4096 data; - struct p80211item_uint32 resultcode; -} __packed; - -#endif diff --git a/drivers/staging/wlan-ng/p80211mgmt.h b/drivers/staging/wlan-ng/p80211mgmt.h deleted file mode 100644 index 7ffc202d9007..000000000000 --- a/drivers/staging/wlan-ng/p80211mgmt.h +++ /dev/null @@ -1,199 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * Macros, types, and functions to handle 802.11 mgmt frames - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file declares the constants and types used in the interface - * between a wlan driver and the user mode utilities. - * - * Notes: - * - Constant values are always in HOST byte order. To assign - * values to multi-byte fields they _must_ be converted to - * ieee byte order. To retrieve multi-byte values from incoming - * frames, they must be converted to host order. - * - * - The len member of the frame structure does NOT!!! include - * the MAC CRC. Therefore, the len field on rx'd frames should - * have 4 subtracted from it. - * - * All functions declared here are implemented in p80211.c - * - * The types, macros, and functions defined here are primarily - * used for encoding and decoding management frames. They are - * designed to follow these patterns of use: - * - * DECODE: - * 1) a frame of length len is received into buffer b - * 2) using the hdr structure and macros, we determine the type - * 3) an appropriate mgmt frame structure, mf, is allocated and zeroed - * 4) mf.hdr = b - * mf.buf = b - * mf.len = len - * 5) call mgmt_decode( mf ) - * 6) the frame field pointers in mf are now set. Note that any - * multi-byte frame field values accessed using the frame field - * pointers are in ieee byte order and will have to be converted - * to host order. - * - * ENCODE: - * 1) Library client allocates buffer space for maximum length - * frame of the desired type - * 2) Library client allocates a mgmt frame structure, called mf, - * of the desired type - * 3) Set the following: - * mf.type = <desired type> - * mf.buf = <allocated buffer address> - * 4) call mgmt_encode( mf ) - * 5) all of the fixed field pointers and fixed length information element - * pointers in mf are now set to their respective locations in the - * allocated space (fortunately, all variable length information elements - * fall at the end of their respective frames). - * 5a) The length field is set to include the last of the fixed and fixed - * length fields. It may have to be updated for optional or variable - * length information elements. - * 6) Optional and variable length information elements are special cases - * and must be handled individually by the client code. - * -------------------------------------------------------------------- - */ - -#ifndef _P80211MGMT_H -#define _P80211MGMT_H - -#ifndef _P80211HDR_H -#include "p80211hdr.h" -#endif - -/*-- Information Element IDs --------------------*/ -#define WLAN_EID_SSID 0 -#define WLAN_EID_SUPP_RATES 1 -#define WLAN_EID_FH_PARMS 2 -#define WLAN_EID_DS_PARMS 3 -#define WLAN_EID_CF_PARMS 4 -#define WLAN_EID_TIM 5 -#define WLAN_EID_IBSS_PARMS 6 -/*-- values 7-15 reserved --*/ -#define WLAN_EID_CHALLENGE 16 -/*-- values 17-31 reserved for challenge text extension --*/ -/*-- values 32-255 reserved --*/ - -/*-- Reason Codes -------------------------------*/ -#define WLAN_MGMT_REASON_RSVD 0 -#define WLAN_MGMT_REASON_UNSPEC 1 -#define WLAN_MGMT_REASON_PRIOR_AUTH_INVALID 2 -#define WLAN_MGMT_REASON_DEAUTH_LEAVING 3 -#define WLAN_MGMT_REASON_DISASSOC_INACTIVE 4 -#define WLAN_MGMT_REASON_DISASSOC_AP_BUSY 5 -#define WLAN_MGMT_REASON_CLASS2_NONAUTH 6 -#define WLAN_MGMT_REASON_CLASS3_NONASSOC 7 -#define WLAN_MGMT_REASON_DISASSOC_STA_HASLEFT 8 -#define WLAN_MGMT_REASON_CANT_ASSOC_NONAUTH 9 - -/*-- Status Codes -------------------------------*/ -#define WLAN_MGMT_STATUS_SUCCESS 0 -#define WLAN_MGMT_STATUS_UNSPEC_FAILURE 1 -#define WLAN_MGMT_STATUS_CAPS_UNSUPPORTED 10 -#define WLAN_MGMT_STATUS_REASSOC_NO_ASSOC 11 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_UNSPEC 12 -#define WLAN_MGMT_STATUS_UNSUPPORTED_AUTHALG 13 -#define WLAN_MGMT_STATUS_RX_AUTH_NOSEQ 14 -#define WLAN_MGMT_STATUS_CHALLENGE_FAIL 15 -#define WLAN_MGMT_STATUS_AUTH_TIMEOUT 16 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_BUSY 17 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_RATES 18 - /* p80211b additions */ -#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOSHORT 19 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOPBCC 20 -#define WLAN_MGMT_STATUS_ASSOC_DENIED_NOAGILITY 21 - -/*-- Auth Algorithm Field ---------------------------*/ -#define WLAN_AUTH_ALG_OPENSYSTEM 0 -#define WLAN_AUTH_ALG_SHAREDKEY 1 - -/*-- Management Frame Field Offsets -------------*/ -/* Note: Not all fields are listed because of variable lengths, */ -/* see the code in p80211.c to see how we search for fields */ -/* Note: These offsets are from the start of the frame data */ - -#define WLAN_BEACON_OFF_TS 0 -#define WLAN_BEACON_OFF_BCN_int 8 -#define WLAN_BEACON_OFF_CAPINFO 10 -#define WLAN_BEACON_OFF_SSID 12 - -#define WLAN_DISASSOC_OFF_REASON 0 - -#define WLAN_ASSOCREQ_OFF_CAP_INFO 0 -#define WLAN_ASSOCREQ_OFF_LISTEN_int 2 -#define WLAN_ASSOCREQ_OFF_SSID 4 - -#define WLAN_ASSOCRESP_OFF_CAP_INFO 0 -#define WLAN_ASSOCRESP_OFF_STATUS 2 -#define WLAN_ASSOCRESP_OFF_AID 4 -#define WLAN_ASSOCRESP_OFF_SUPP_RATES 6 - -#define WLAN_REASSOCREQ_OFF_CAP_INFO 0 -#define WLAN_REASSOCREQ_OFF_LISTEN_int 2 -#define WLAN_REASSOCREQ_OFF_CURR_AP 4 -#define WLAN_REASSOCREQ_OFF_SSID 10 - -#define WLAN_REASSOCRESP_OFF_CAP_INFO 0 -#define WLAN_REASSOCRESP_OFF_STATUS 2 -#define WLAN_REASSOCRESP_OFF_AID 4 -#define WLAN_REASSOCRESP_OFF_SUPP_RATES 6 - -#define WLAN_PROBEREQ_OFF_SSID 0 - -#define WLAN_PROBERESP_OFF_TS 0 -#define WLAN_PROBERESP_OFF_BCN_int 8 -#define WLAN_PROBERESP_OFF_CAP_INFO 10 -#define WLAN_PROBERESP_OFF_SSID 12 - -#define WLAN_AUTHEN_OFF_AUTH_ALG 0 -#define WLAN_AUTHEN_OFF_AUTH_SEQ 2 -#define WLAN_AUTHEN_OFF_STATUS 4 -#define WLAN_AUTHEN_OFF_CHALLENGE 6 - -#define WLAN_DEAUTHEN_OFF_REASON 0 - -/*-- Capability Field ---------------------------*/ -#define WLAN_GET_MGMT_CAP_INFO_ESS(n) ((n) & BIT(0)) -#define WLAN_GET_MGMT_CAP_INFO_IBSS(n) (((n) & BIT(1)) >> 1) -#define WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(n) (((n) & BIT(2)) >> 2) -#define WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(n) (((n) & BIT(3)) >> 3) -#define WLAN_GET_MGMT_CAP_INFO_PRIVACY(n) (((n) & BIT(4)) >> 4) - /* p80211b additions */ -#define WLAN_GET_MGMT_CAP_INFO_SHORT(n) (((n) & BIT(5)) >> 5) -#define WLAN_GET_MGMT_CAP_INFO_PBCC(n) (((n) & BIT(6)) >> 6) -#define WLAN_GET_MGMT_CAP_INFO_AGILITY(n) (((n) & BIT(7)) >> 7) - -#define WLAN_SET_MGMT_CAP_INFO_ESS(n) (n) -#define WLAN_SET_MGMT_CAP_INFO_IBSS(n) ((n) << 1) -#define WLAN_SET_MGMT_CAP_INFO_CFPOLLABLE(n) ((n) << 2) -#define WLAN_SET_MGMT_CAP_INFO_CFPOLLREQ(n) ((n) << 3) -#define WLAN_SET_MGMT_CAP_INFO_PRIVACY(n) ((n) << 4) - /* p80211b additions */ -#define WLAN_SET_MGMT_CAP_INFO_SHORT(n) ((n) << 5) -#define WLAN_SET_MGMT_CAP_INFO_PBCC(n) ((n) << 6) -#define WLAN_SET_MGMT_CAP_INFO_AGILITY(n) ((n) << 7) - -#endif /* _P80211MGMT_H */ diff --git a/drivers/staging/wlan-ng/p80211msg.h b/drivers/staging/wlan-ng/p80211msg.h deleted file mode 100644 index d56bc6079ed4..000000000000 --- a/drivers/staging/wlan-ng/p80211msg.h +++ /dev/null @@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * Macros, constants, types, and funcs for req and ind messages - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - */ - -#ifndef _P80211MSG_H -#define _P80211MSG_H - -#define WLAN_DEVNAMELEN_MAX 16 - -struct p80211msg { - u32 msgcode; - u32 msglen; - u8 devname[WLAN_DEVNAMELEN_MAX]; -} __packed; - -#endif /* _P80211MSG_H */ diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c deleted file mode 100644 index 8634fc89a6c2..000000000000 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ /dev/null @@ -1,988 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) -/* - * - * Linux Kernel net device interface - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * The functions required for a Linux network device are defined here. - * - * -------------------------------------------------------------------- - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/skbuff.h> -#include <linux/slab.h> -#include <linux/proc_fs.h> -#include <linux/interrupt.h> -#include <linux/netdevice.h> -#include <linux/kmod.h> -#include <linux/if_arp.h> -#include <linux/wireless.h> -#include <linux/sockios.h> -#include <linux/etherdevice.h> -#include <linux/if_ether.h> -#include <linux/byteorder/generic.h> -#include <linux/bitops.h> -#include <linux/uaccess.h> -#include <asm/byteorder.h> - -#ifdef SIOCETHTOOL -#include <linux/ethtool.h> -#endif - -#include <net/iw_handler.h> -#include <net/net_namespace.h> -#include <net/cfg80211.h> - -#include "p80211types.h" -#include "p80211hdr.h" -#include "p80211conv.h" -#include "p80211mgmt.h" -#include "p80211msg.h" -#include "p80211netdev.h" -#include "p80211ioctl.h" -#include "p80211req.h" -#include "p80211metastruct.h" -#include "p80211metadef.h" - -#include "cfg80211.c" - -/* netdevice method functions */ -static int p80211knetdev_init(struct net_device *netdev); -static int p80211knetdev_open(struct net_device *netdev); -static int p80211knetdev_stop(struct net_device *netdev); -static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb, - struct net_device *netdev); -static void p80211knetdev_set_multicast_list(struct net_device *dev); -static int p80211knetdev_siocdevprivate(struct net_device *dev, struct ifreq *ifr, - void __user *data, int cmd); -static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr); -static void p80211knetdev_tx_timeout(struct net_device *netdev, unsigned int txqueue); -static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc); - -int wlan_watchdog = 5000; -module_param(wlan_watchdog, int, 0644); -MODULE_PARM_DESC(wlan_watchdog, "transmit timeout in milliseconds"); - -int wlan_wext_write = 1; -module_param(wlan_wext_write, int, 0644); -MODULE_PARM_DESC(wlan_wext_write, "enable write wireless extensions"); - -/*---------------------------------------------------------------- - * p80211knetdev_init - * - * Init method for a Linux netdevice. Called in response to - * register_netdev. - * - * Arguments: - * none - * - * Returns: - * nothing - *---------------------------------------------------------------- - */ -static int p80211knetdev_init(struct net_device *netdev) -{ - /* Called in response to register_netdev */ - /* This is usually the probe function, but the probe has */ - /* already been done by the MSD and the create_kdev */ - /* function. All we do here is return success */ - return 0; -} - -/*---------------------------------------------------------------- - * p80211knetdev_open - * - * Linux netdevice open method. Following a successful call here, - * the device is supposed to be ready for tx and rx. In our - * situation that may not be entirely true due to the state of the - * MAC below. - * - * Arguments: - * netdev Linux network device structure - * - * Returns: - * zero on success, non-zero otherwise - *---------------------------------------------------------------- - */ -static int p80211knetdev_open(struct net_device *netdev) -{ - int result = 0; /* success */ - struct wlandevice *wlandev = netdev->ml_priv; - - /* Check to make sure the MSD is running */ - if (wlandev->msdstate != WLAN_MSD_RUNNING) - return -ENODEV; - - /* Tell the MSD to open */ - if (wlandev->open) { - result = wlandev->open(wlandev); - if (result == 0) { - netif_start_queue(wlandev->netdev); - wlandev->state = WLAN_DEVICE_OPEN; - } - } else { - result = -EAGAIN; - } - - return result; -} - -/*---------------------------------------------------------------- - * p80211knetdev_stop - * - * Linux netdevice stop (close) method. Following this call, - * no frames should go up or down through this interface. - * - * Arguments: - * netdev Linux network device structure - * - * Returns: - * zero on success, non-zero otherwise - *---------------------------------------------------------------- - */ -static int p80211knetdev_stop(struct net_device *netdev) -{ - int result = 0; - struct wlandevice *wlandev = netdev->ml_priv; - - if (wlandev->close) - result = wlandev->close(wlandev); - - netif_stop_queue(wlandev->netdev); - wlandev->state = WLAN_DEVICE_CLOSED; - - return result; -} - -/*---------------------------------------------------------------- - * p80211netdev_rx - * - * Frame receive function called by the mac specific driver. - * - * Arguments: - * wlandev WLAN network device structure - * skb skbuff containing a full 802.11 frame. - * Returns: - * nothing - * Side effects: - * - *---------------------------------------------------------------- - */ -void p80211netdev_rx(struct wlandevice *wlandev, struct sk_buff *skb) -{ - /* Enqueue for post-irq processing */ - skb_queue_tail(&wlandev->nsd_rxq, skb); - tasklet_schedule(&wlandev->rx_bh); -} - -#define CONV_TO_ETHER_SKIPPED 0x01 -#define CONV_TO_ETHER_FAILED 0x02 - -/** - * p80211_convert_to_ether - conversion from 802.11 frame to ethernet frame - * @wlandev: pointer to WLAN device - * @skb: pointer to socket buffer - * - * Returns: 0 if conversion succeeded - * CONV_TO_ETHER_FAILED if conversion failed - * CONV_TO_ETHER_SKIPPED if frame is ignored - */ -static int p80211_convert_to_ether(struct wlandevice *wlandev, - struct sk_buff *skb) -{ - struct p80211_hdr *hdr; - - hdr = (struct p80211_hdr *)skb->data; - if (p80211_rx_typedrop(wlandev, le16_to_cpu(hdr->frame_control))) - return CONV_TO_ETHER_SKIPPED; - - /* perform mcast filtering: allow my local address through but reject - * anything else that isn't multicast - */ - if (wlandev->netdev->flags & IFF_ALLMULTI) { - if (!ether_addr_equal_unaligned(wlandev->netdev->dev_addr, - hdr->address1)) { - if (!is_multicast_ether_addr(hdr->address1)) - return CONV_TO_ETHER_SKIPPED; - } - } - - if (skb_p80211_to_ether(wlandev, wlandev->ethconv, skb) == 0) { - wlandev->netdev->stats.rx_packets++; - wlandev->netdev->stats.rx_bytes += skb->len; - netif_rx(skb); - return 0; - } - - netdev_dbg(wlandev->netdev, "%s failed.\n", __func__); - return CONV_TO_ETHER_FAILED; -} - -/** - * p80211netdev_rx_bh - deferred processing of all received frames - * - * @t: pointer to the tasklet associated with this handler - */ -static void p80211netdev_rx_bh(struct tasklet_struct *t) -{ - struct wlandevice *wlandev = from_tasklet(wlandev, t, rx_bh); - struct sk_buff *skb = NULL; - struct net_device *dev = wlandev->netdev; - - /* Let's empty our queue */ - while ((skb = skb_dequeue(&wlandev->nsd_rxq))) { - if (wlandev->state == WLAN_DEVICE_OPEN) { - if (dev->type != ARPHRD_ETHER) { - /* RAW frame; we shouldn't convert it */ - /* XXX Append the Prism Header here instead. */ - - /* set up various data fields */ - skb->dev = dev; - skb_reset_mac_header(skb); - skb->ip_summed = CHECKSUM_NONE; - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = htons(ETH_P_80211_RAW); - - dev->stats.rx_packets++; - dev->stats.rx_bytes += skb->len; - netif_rx(skb); - continue; - } else { - if (!p80211_convert_to_ether(wlandev, skb)) - continue; - } - } - dev_kfree_skb(skb); - } -} - -/*---------------------------------------------------------------- - * p80211knetdev_hard_start_xmit - * - * Linux netdevice method for transmitting a frame. - * - * Arguments: - * skb Linux sk_buff containing the frame. - * netdev Linux netdevice. - * - * Side effects: - * If the lower layers report that buffers are full. netdev->tbusy - * will be set to prevent higher layers from sending more traffic. - * - * Note: If this function returns non-zero, higher layers retain - * ownership of the skb. - * - * Returns: - * zero on success, non-zero on failure. - *---------------------------------------------------------------- - */ -static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb, - struct net_device *netdev) -{ - int result = 0; - int txresult; - struct wlandevice *wlandev = netdev->ml_priv; - struct p80211_hdr p80211_hdr; - struct p80211_metawep p80211_wep; - - p80211_wep.data = NULL; - - if (!skb) - return NETDEV_TX_OK; - - if (wlandev->state != WLAN_DEVICE_OPEN) { - result = 1; - goto failed; - } - - memset(&p80211_hdr, 0, sizeof(p80211_hdr)); - memset(&p80211_wep, 0, sizeof(p80211_wep)); - - if (netif_queue_stopped(netdev)) { - netdev_dbg(netdev, "called when queue stopped.\n"); - result = 1; - goto failed; - } - - netif_stop_queue(netdev); - - /* Check to see that a valid mode is set */ - switch (wlandev->macmode) { - case WLAN_MACMODE_IBSS_STA: - case WLAN_MACMODE_ESS_STA: - case WLAN_MACMODE_ESS_AP: - break; - default: - /* Mode isn't set yet, just drop the frame - * and return success . - * TODO: we need a saner way to handle this - */ - if (be16_to_cpu(skb->protocol) != ETH_P_80211_RAW) { - netif_start_queue(wlandev->netdev); - netdev_notice(netdev, "Tx attempt prior to association, frame dropped.\n"); - netdev->stats.tx_dropped++; - result = 0; - goto failed; - } - break; - } - - /* Check for raw transmits */ - if (be16_to_cpu(skb->protocol) == ETH_P_80211_RAW) { - if (!capable(CAP_NET_ADMIN)) { - result = 1; - goto failed; - } - /* move the header over */ - memcpy(&p80211_hdr, skb->data, sizeof(p80211_hdr)); - skb_pull(skb, sizeof(p80211_hdr)); - } else { - if (skb_ether_to_p80211 - (wlandev, wlandev->ethconv, skb, &p80211_hdr, - &p80211_wep) != 0) { - /* convert failed */ - netdev_dbg(netdev, "ether_to_80211(%d) failed.\n", - wlandev->ethconv); - result = 1; - goto failed; - } - } - if (!wlandev->txframe) { - result = 1; - goto failed; - } - - netif_trans_update(netdev); - - netdev->stats.tx_packets++; - /* count only the packet payload */ - netdev->stats.tx_bytes += skb->len; - - txresult = wlandev->txframe(wlandev, skb, &p80211_hdr, &p80211_wep); - - if (txresult == 0) { - /* success and more buf */ - /* avail, re: hw_txdata */ - netif_wake_queue(wlandev->netdev); - result = NETDEV_TX_OK; - } else if (txresult == 1) { - /* success, no more avail */ - netdev_dbg(netdev, "txframe success, no more bufs\n"); - /* netdev->tbusy = 1; don't set here, irqhdlr */ - /* may have already cleared it */ - result = NETDEV_TX_OK; - } else if (txresult == 2) { - /* alloc failure, drop frame */ - netdev_dbg(netdev, "txframe returned alloc_fail\n"); - result = NETDEV_TX_BUSY; - } else { - /* buffer full or queue busy, drop frame. */ - netdev_dbg(netdev, "txframe returned full or busy\n"); - result = NETDEV_TX_BUSY; - } - -failed: - /* Free up the WEP buffer if it's not the same as the skb */ - if ((p80211_wep.data) && (p80211_wep.data != skb->data)) - kfree_sensitive(p80211_wep.data); - - /* we always free the skb here, never in a lower level. */ - if (!result) - dev_kfree_skb(skb); - - return result; -} - -/*---------------------------------------------------------------- - * p80211knetdev_set_multicast_list - * - * Called from higher layers whenever there's a need to set/clear - * promiscuous mode or rewrite the multicast list. - * - * Arguments: - * none - * - * Returns: - * nothing - *---------------------------------------------------------------- - */ -static void p80211knetdev_set_multicast_list(struct net_device *dev) -{ - struct wlandevice *wlandev = dev->ml_priv; - - /* TODO: real multicast support as well */ - - if (wlandev->set_multicast_list) - wlandev->set_multicast_list(wlandev, dev); -} - -/*---------------------------------------------------------------- - * p80211knetdev_siocdevprivate - * - * Handle an ioctl call on one of our devices. Everything Linux - * ioctl specific is done here. Then we pass the contents of the - * ifr->data to the request message handler. - * - * Arguments: - * dev Linux kernel netdevice - * ifr Our private ioctl request structure, typed for the - * generic struct ifreq so we can use ptr to func - * w/o cast. - * - * Returns: - * zero on success, a negative errno on failure. Possible values: - * -ENETDOWN Device isn't up. - * -EBUSY cmd already in progress - * -ETIME p80211 cmd timed out (MSD may have its own timers) - * -EFAULT memory fault copying msg from user buffer - * -ENOMEM unable to allocate kernel msg buffer - * -EINVAL bad magic, it the cmd really for us? - * -EintR sleeping on cmd, awakened by signal, cmd cancelled. - * - * Call Context: - * Process thread (ioctl caller). TODO: SMP support may require - * locks. - *---------------------------------------------------------------- - */ -static int p80211knetdev_siocdevprivate(struct net_device *dev, - struct ifreq *ifr, - void __user *data, int cmd) -{ - int result = 0; - struct p80211ioctl_req *req = (struct p80211ioctl_req *)ifr; - struct wlandevice *wlandev = dev->ml_priv; - u8 *msgbuf; - - netdev_dbg(dev, "rx'd ioctl, cmd=%d, len=%d\n", cmd, req->len); - - if (in_compat_syscall()) - return -EOPNOTSUPP; - - /* Test the magic, assume ifr is good if it's there */ - if (req->magic != P80211_IOCTL_MAGIC) { - result = -EINVAL; - goto bail; - } - - if (cmd == P80211_IFTEST) { - result = 0; - goto bail; - } else if (cmd != P80211_IFREQ) { - result = -EINVAL; - goto bail; - } - - msgbuf = memdup_user(data, req->len); - if (IS_ERR(msgbuf)) { - result = PTR_ERR(msgbuf); - goto bail; - } - - result = p80211req_dorequest(wlandev, msgbuf); - - if (result == 0) { - if (copy_to_user(data, msgbuf, req->len)) - result = -EFAULT; - } - kfree(msgbuf); - -bail: - /* If allocate,copyfrom or copyto fails, return errno */ - return result; -} - -/*---------------------------------------------------------------- - * p80211knetdev_set_mac_address - * - * Handles the ioctl for changing the MACAddress of a netdevice - * - * references: linux/netdevice.h and drivers/net/net_init.c - * - * NOTE: [MSM] We only prevent address changes when the netdev is - * up. We don't control anything based on dot11 state. If the - * address is changed on a STA that's currently associated, you - * will probably lose the ability to send and receive data frames. - * Just be aware. Therefore, this should usually only be done - * prior to scan/join/auth/assoc. - * - * Arguments: - * dev netdevice struct - * addr the new MACAddress (a struct) - * - * Returns: - * zero on success, a negative errno on failure. Possible values: - * -EBUSY device is bussy (cmd not possible) - * -and errors returned by: p80211req_dorequest(..) - * - * by: Collin R. Mulliner <collin@mulliner.org> - *---------------------------------------------------------------- - */ -static int p80211knetdev_set_mac_address(struct net_device *dev, void *addr) -{ - struct sockaddr *new_addr = addr; - struct p80211msg_dot11req_mibset dot11req; - struct p80211item_unk392 *mibattr; - struct p80211item_pstr6 *macaddr; - struct p80211item_uint32 *resultcode; - int result; - - /* If we're running, we don't allow MAC address changes */ - if (netif_running(dev)) - return -EBUSY; - - /* Set up some convenience pointers. */ - mibattr = &dot11req.mibattribute; - macaddr = (struct p80211item_pstr6 *)&mibattr->data; - resultcode = &dot11req.resultcode; - - /* Set up a dot11req_mibset */ - memset(&dot11req, 0, sizeof(dot11req)); - dot11req.msgcode = DIDMSG_DOT11REQ_MIBSET; - dot11req.msglen = sizeof(dot11req); - memcpy(dot11req.devname, - ((struct wlandevice *)dev->ml_priv)->name, - WLAN_DEVNAMELEN_MAX - 1); - - /* Set up the mibattribute argument */ - mibattr->did = DIDMSG_DOT11REQ_MIBSET_MIBATTRIBUTE; - mibattr->status = P80211ENUM_msgitem_status_data_ok; - mibattr->len = sizeof(mibattr->data); - - macaddr->did = DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS; - macaddr->status = P80211ENUM_msgitem_status_data_ok; - macaddr->len = sizeof(macaddr->data); - macaddr->data.len = ETH_ALEN; - memcpy(&macaddr->data.data, new_addr->sa_data, ETH_ALEN); - - /* Set up the resultcode argument */ - resultcode->did = DIDMSG_DOT11REQ_MIBSET_RESULTCODE; - resultcode->status = P80211ENUM_msgitem_status_no_value; - resultcode->len = sizeof(resultcode->data); - resultcode->data = 0; - - /* now fire the request */ - result = p80211req_dorequest(dev->ml_priv, (u8 *)&dot11req); - - /* If the request wasn't successful, report an error and don't - * change the netdev address - */ - if (result != 0 || resultcode->data != P80211ENUM_resultcode_success) { - netdev_err(dev, "Low-level driver failed dot11req_mibset(dot11MACAddress).\n"); - result = -EADDRNOTAVAIL; - } else { - /* everything's ok, change the addr in netdev */ - eth_hw_addr_set(dev, new_addr->sa_data); - } - - return result; -} - -static const struct net_device_ops p80211_netdev_ops = { - .ndo_init = p80211knetdev_init, - .ndo_open = p80211knetdev_open, - .ndo_stop = p80211knetdev_stop, - .ndo_start_xmit = p80211knetdev_hard_start_xmit, - .ndo_set_rx_mode = p80211knetdev_set_multicast_list, - .ndo_siocdevprivate = p80211knetdev_siocdevprivate, - .ndo_set_mac_address = p80211knetdev_set_mac_address, - .ndo_tx_timeout = p80211knetdev_tx_timeout, - .ndo_validate_addr = eth_validate_addr, -}; - -/*---------------------------------------------------------------- - * wlan_setup - * - * Roughly matches the functionality of ether_setup. Here - * we set up any members of the wlandevice structure that are common - * to all devices. Additionally, we allocate a linux 'struct device' - * and perform the same setup as ether_setup. - * - * Note: It's important that the caller have setup the wlandev->name - * ptr prior to calling this function. - * - * Arguments: - * wlandev ptr to the wlandev structure for the - * interface. - * physdev ptr to usb device - * Returns: - * zero on success, non-zero otherwise. - * Call Context: - * Should be process thread. We'll assume it might be - * interrupt though. When we add support for statically - * compiled drivers, this function will be called in the - * context of the kernel startup code. - *---------------------------------------------------------------- - */ -int wlan_setup(struct wlandevice *wlandev, struct device *physdev) -{ - int result = 0; - struct net_device *netdev; - struct wiphy *wiphy; - struct wireless_dev *wdev; - - /* Set up the wlandev */ - wlandev->state = WLAN_DEVICE_CLOSED; - wlandev->ethconv = WLAN_ETHCONV_8021h; - wlandev->macmode = WLAN_MACMODE_NONE; - - /* Set up the rx queue */ - skb_queue_head_init(&wlandev->nsd_rxq); - tasklet_setup(&wlandev->rx_bh, p80211netdev_rx_bh); - - /* Allocate and initialize the wiphy struct */ - wiphy = wlan_create_wiphy(physdev, wlandev); - if (!wiphy) { - dev_err(physdev, "Failed to alloc wiphy.\n"); - return 1; - } - - /* Allocate and initialize the struct device */ - netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", - NET_NAME_UNKNOWN, ether_setup); - if (!netdev) { - dev_err(physdev, "Failed to alloc netdev.\n"); - wlan_free_wiphy(wiphy); - result = 1; - } else { - wlandev->netdev = netdev; - netdev->ml_priv = wlandev; - netdev->netdev_ops = &p80211_netdev_ops; - wdev = netdev_priv(netdev); - wdev->wiphy = wiphy; - wdev->iftype = NL80211_IFTYPE_STATION; - netdev->ieee80211_ptr = wdev; - netdev->min_mtu = 68; - /* 2312 is max 802.11 payload, 20 is overhead, - * (ether + llc + snap) and another 8 for wep. - */ - netdev->max_mtu = (2312 - 20 - 8); - - netif_stop_queue(netdev); - netif_carrier_off(netdev); - } - - return result; -} - -/*---------------------------------------------------------------- - * wlan_unsetup - * - * This function is paired with the wlan_setup routine. It should - * be called after unregister_wlandev. Basically, all it does is - * free the 'struct device' that's associated with the wlandev. - * We do it here because the 'struct device' isn't allocated - * explicitly in the driver code, it's done in wlan_setup. To - * do the free in the driver might seem like 'magic'. - * - * Arguments: - * wlandev ptr to the wlandev structure for the - * interface. - * Call Context: - * Should be process thread. We'll assume it might be - * interrupt though. When we add support for statically - * compiled drivers, this function will be called in the - * context of the kernel startup code. - *---------------------------------------------------------------- - */ -void wlan_unsetup(struct wlandevice *wlandev) -{ - struct wireless_dev *wdev; - - tasklet_kill(&wlandev->rx_bh); - - if (wlandev->netdev) { - wdev = netdev_priv(wlandev->netdev); - if (wdev->wiphy) - wlan_free_wiphy(wdev->wiphy); - free_netdev(wlandev->netdev); - wlandev->netdev = NULL; - } -} - -/*---------------------------------------------------------------- - * register_wlandev - * - * Roughly matches the functionality of register_netdev. This function - * is called after the driver has successfully probed and set up the - * resources for the device. It's now ready to become a named device - * in the Linux system. - * - * First we allocate a name for the device (if not already set), then - * we call the Linux function register_netdevice. - * - * Arguments: - * wlandev ptr to the wlandev structure for the - * interface. - * Returns: - * zero on success, non-zero otherwise. - * Call Context: - * Can be either interrupt or not. - *---------------------------------------------------------------- - */ -int register_wlandev(struct wlandevice *wlandev) -{ - return register_netdev(wlandev->netdev); -} - -/*---------------------------------------------------------------- - * unregister_wlandev - * - * Roughly matches the functionality of unregister_netdev. This - * function is called to remove a named device from the system. - * - * First we tell linux that the device should no longer exist. - * Then we remove it from the list of known wlan devices. - * - * Arguments: - * wlandev ptr to the wlandev structure for the - * interface. - * Returns: - * zero on success, non-zero otherwise. - * Call Context: - * Can be either interrupt or not. - *---------------------------------------------------------------- - */ -int unregister_wlandev(struct wlandevice *wlandev) -{ - struct sk_buff *skb; - - unregister_netdev(wlandev->netdev); - - /* Now to clean out the rx queue */ - while ((skb = skb_dequeue(&wlandev->nsd_rxq))) - dev_kfree_skb(skb); - - return 0; -} - -/*---------------------------------------------------------------- - * p80211netdev_hwremoved - * - * Hardware removed notification. This function should be called - * immediately after an MSD has detected that the underlying hardware - * has been yanked out from under us. The primary things we need - * to do are: - * - Mark the wlandev - * - Prevent any further traffic from the knetdev i/f - * - Prevent any further requests from mgmt i/f - * - If there are any waitq'd mgmt requests or mgmt-frame exchanges, - * shut them down. - * - Call the MSD hwremoved function. - * - * The remainder of the cleanup will be handled by unregister(). - * Our primary goal here is to prevent as much tickling of the MSD - * as possible since the MSD is already in a 'wounded' state. - * - * TODO: As new features are added, this function should be - * updated. - * - * Arguments: - * wlandev WLAN network device structure - * Returns: - * nothing - * Side effects: - * - * Call context: - * Usually interrupt. - *---------------------------------------------------------------- - */ -void p80211netdev_hwremoved(struct wlandevice *wlandev) -{ - wlandev->hwremoved = 1; - if (wlandev->state == WLAN_DEVICE_OPEN) - netif_stop_queue(wlandev->netdev); - - netif_device_detach(wlandev->netdev); -} - -/*---------------------------------------------------------------- - * p80211_rx_typedrop - * - * Classifies the frame, increments the appropriate counter, and - * returns 0|1|2 indicating whether the driver should handle, ignore, or - * drop the frame - * - * Arguments: - * wlandev wlan device structure - * fc frame control field - * - * Returns: - * zero if the frame should be handled by the driver, - * one if the frame should be ignored - * anything else means we drop it. - * - * Side effects: - * - * Call context: - * interrupt - *---------------------------------------------------------------- - */ -static int p80211_rx_typedrop(struct wlandevice *wlandev, u16 fc) -{ - u16 ftype; - u16 fstype; - int drop = 0; - /* Classify frame, increment counter */ - ftype = WLAN_GET_FC_FTYPE(fc); - fstype = WLAN_GET_FC_FSTYPE(fc); - switch (ftype) { - case WLAN_FTYPE_MGMT: - if ((wlandev->netdev->flags & IFF_PROMISC) || - (wlandev->netdev->flags & IFF_ALLMULTI)) { - drop = 1; - break; - } - netdev_dbg(wlandev->netdev, "rx'd mgmt:\n"); - wlandev->rx.mgmt++; - switch (fstype) { - case WLAN_FSTYPE_ASSOCREQ: - wlandev->rx.assocreq++; - break; - case WLAN_FSTYPE_ASSOCRESP: - wlandev->rx.assocresp++; - break; - case WLAN_FSTYPE_REASSOCREQ: - wlandev->rx.reassocreq++; - break; - case WLAN_FSTYPE_REASSOCRESP: - wlandev->rx.reassocresp++; - break; - case WLAN_FSTYPE_PROBEREQ: - wlandev->rx.probereq++; - break; - case WLAN_FSTYPE_PROBERESP: - wlandev->rx.proberesp++; - break; - case WLAN_FSTYPE_BEACON: - wlandev->rx.beacon++; - break; - case WLAN_FSTYPE_ATIM: - wlandev->rx.atim++; - break; - case WLAN_FSTYPE_DISASSOC: - wlandev->rx.disassoc++; - break; - case WLAN_FSTYPE_AUTHEN: - wlandev->rx.authen++; - break; - case WLAN_FSTYPE_DEAUTHEN: - wlandev->rx.deauthen++; - break; - default: - wlandev->rx.mgmt_unknown++; - break; - } - drop = 2; - break; - - case WLAN_FTYPE_CTL: - if ((wlandev->netdev->flags & IFF_PROMISC) || - (wlandev->netdev->flags & IFF_ALLMULTI)) { - drop = 1; - break; - } - netdev_dbg(wlandev->netdev, "rx'd ctl:\n"); - wlandev->rx.ctl++; - switch (fstype) { - case WLAN_FSTYPE_PSPOLL: - wlandev->rx.pspoll++; - break; - case WLAN_FSTYPE_RTS: - wlandev->rx.rts++; - break; - case WLAN_FSTYPE_CTS: - wlandev->rx.cts++; - break; - case WLAN_FSTYPE_ACK: - wlandev->rx.ack++; - break; - case WLAN_FSTYPE_CFEND: - wlandev->rx.cfend++; - break; - case WLAN_FSTYPE_CFENDCFACK: - wlandev->rx.cfendcfack++; - break; - default: - wlandev->rx.ctl_unknown++; - break; - } - drop = 2; - break; - - case WLAN_FTYPE_DATA: - wlandev->rx.data++; - switch (fstype) { - case WLAN_FSTYPE_DATAONLY: - wlandev->rx.dataonly++; - break; - case WLAN_FSTYPE_DATA_CFACK: - wlandev->rx.data_cfack++; - break; - case WLAN_FSTYPE_DATA_CFPOLL: - wlandev->rx.data_cfpoll++; - break; - case WLAN_FSTYPE_DATA_CFACK_CFPOLL: - wlandev->rx.data__cfack_cfpoll++; - break; - case WLAN_FSTYPE_NULL: - netdev_dbg(wlandev->netdev, "rx'd data:null\n"); - wlandev->rx.null++; - break; - case WLAN_FSTYPE_CFACK: - netdev_dbg(wlandev->netdev, "rx'd data:cfack\n"); - wlandev->rx.cfack++; - break; - case WLAN_FSTYPE_CFPOLL: - netdev_dbg(wlandev->netdev, "rx'd data:cfpoll\n"); - wlandev->rx.cfpoll++; - break; - case WLAN_FSTYPE_CFACK_CFPOLL: - netdev_dbg(wlandev->netdev, "rx'd data:cfack_cfpoll\n"); - wlandev->rx.cfack_cfpoll++; - break; - default: - wlandev->rx.data_unknown++; - break; - } - - break; - } - return drop; -} - -static void p80211knetdev_tx_timeout(struct net_device *netdev, unsigned int txqueue) -{ - struct wlandevice *wlandev = netdev->ml_priv; - - if (wlandev->tx_timeout) { - wlandev->tx_timeout(wlandev); - } else { - netdev_warn(netdev, "Implement tx_timeout for %s\n", - wlandev->nsdname); - netif_wake_queue(wlandev->netdev); - } -} diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h deleted file mode 100644 index 485f2c697f5f..000000000000 --- a/drivers/staging/wlan-ng/p80211netdev.h +++ /dev/null @@ -1,212 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * WLAN net device structure and functions - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file declares the structure type that represents each wlan - * interface. - * - * -------------------------------------------------------------------- - */ - -#ifndef _LINUX_P80211NETDEV_H -#define _LINUX_P80211NETDEV_H - -#include <linux/interrupt.h> -#include <linux/wireless.h> -#include <linux/netdevice.h> - -#define WLAN_RELEASE "0.3.0-staging" - -#define WLAN_DEVICE_CLOSED 0 -#define WLAN_DEVICE_OPEN 1 - -#define WLAN_MACMODE_NONE 0 -#define WLAN_MACMODE_IBSS_STA 1 -#define WLAN_MACMODE_ESS_STA 2 -#define WLAN_MACMODE_ESS_AP 3 - -/* MSD States */ -#define WLAN_MSD_HWPRESENT_PENDING 1 -#define WLAN_MSD_HWFAIL 2 -#define WLAN_MSD_HWPRESENT 3 -#define WLAN_MSD_FWLOAD_PENDING 4 -#define WLAN_MSD_FWLOAD 5 -#define WLAN_MSD_RUNNING_PENDING 6 -#define WLAN_MSD_RUNNING 7 - -#ifndef ETH_P_ECONET -#define ETH_P_ECONET 0x0018 /* needed for 2.2.x kernels */ -#endif - -#define ETH_P_80211_RAW (ETH_P_ECONET + 1) - -#ifndef ARPHRD_IEEE80211 -#define ARPHRD_IEEE80211 801 /* kernel 2.4.6 */ -#endif - -#ifndef ARPHRD_IEEE80211_PRISM /* kernel 2.4.18 */ -#define ARPHRD_IEEE80211_PRISM 802 -#endif - -/*--- NSD Capabilities Flags ------------------------------*/ -#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */ -#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */ -#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */ -#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */ -#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */ - -/* Received frame statistics */ -struct p80211_frmrx { - u32 mgmt; - u32 assocreq; - u32 assocresp; - u32 reassocreq; - u32 reassocresp; - u32 probereq; - u32 proberesp; - u32 beacon; - u32 atim; - u32 disassoc; - u32 authen; - u32 deauthen; - u32 mgmt_unknown; - u32 ctl; - u32 pspoll; - u32 rts; - u32 cts; - u32 ack; - u32 cfend; - u32 cfendcfack; - u32 ctl_unknown; - u32 data; - u32 dataonly; - u32 data_cfack; - u32 data_cfpoll; - u32 data__cfack_cfpoll; - u32 null; - u32 cfack; - u32 cfpoll; - u32 cfack_cfpoll; - u32 data_unknown; - u32 decrypt; - u32 decrypt_err; -}; - -/* WEP stuff */ -#define NUM_WEPKEYS 4 -#define MAX_KEYLEN 32 - -#define HOSTWEP_DEFAULTKEY_MASK GENMASK(1, 0) -#define HOSTWEP_SHAREDKEY BIT(3) -#define HOSTWEP_DECRYPT BIT(4) -#define HOSTWEP_ENCRYPT BIT(5) -#define HOSTWEP_PRIVACYINVOKED BIT(6) -#define HOSTWEP_EXCLUDEUNENCRYPTED BIT(7) - -extern int wlan_watchdog; -extern int wlan_wext_write; - -/* WLAN device type */ -struct wlandevice { - void *priv; /* private data for MSD */ - - /* Subsystem State */ - char name[WLAN_DEVNAMELEN_MAX]; /* Dev name, from register_wlandev() */ - char *nsdname; - - u32 state; /* Device I/F state (open/closed) */ - u32 msdstate; /* state of underlying driver */ - u32 hwremoved; /* Has the hw been yanked out? */ - - /* Hardware config */ - unsigned int irq; - unsigned int iobase; - unsigned int membase; - u32 nsdcaps; /* NSD Capabilities flags */ - - /* Config vars */ - unsigned int ethconv; - - /* device methods (init by MSD, used by p80211 */ - int (*open)(struct wlandevice *wlandev); - int (*close)(struct wlandevice *wlandev); - void (*reset)(struct wlandevice *wlandev); - int (*txframe)(struct wlandevice *wlandev, struct sk_buff *skb, - struct p80211_hdr *p80211_hdr, - struct p80211_metawep *p80211_wep); - int (*mlmerequest)(struct wlandevice *wlandev, struct p80211msg *msg); - int (*set_multicast_list)(struct wlandevice *wlandev, - struct net_device *dev); - void (*tx_timeout)(struct wlandevice *wlandev); - - /* 802.11 State */ - u8 bssid[WLAN_BSSID_LEN]; - struct p80211pstr32 ssid; - u32 macmode; - int linkstatus; - - /* WEP State */ - u8 wep_keys[NUM_WEPKEYS][MAX_KEYLEN]; - u8 wep_keylens[NUM_WEPKEYS]; - int hostwep; - - /* Request/Confirm i/f state (used by p80211) */ - unsigned long request_pending; /* flag, access atomically */ - - /* netlink socket */ - /* queue for indications waiting for cmd completion */ - /* Linux netdevice and support */ - struct net_device *netdev; /* ptr to linux netdevice */ - - /* Rx bottom half */ - struct tasklet_struct rx_bh; - - struct sk_buff_head nsd_rxq; - - /* 802.11 device statistics */ - struct p80211_frmrx rx; - - struct iw_statistics wstats; - - /* jkriegl: iwspy fields */ - u8 spy_number; - char spy_address[IW_MAX_SPY][ETH_ALEN]; - struct iw_quality spy_stat[IW_MAX_SPY]; -}; - -/* WEP stuff */ -int wep_change_key(struct wlandevice *wlandev, int keynum, u8 *key, int keylen); -int wep_decrypt(struct wlandevice *wlandev, u8 *buf, u32 len, int key_override, - u8 *iv, u8 *icv); -int wep_encrypt(struct wlandevice *wlandev, u8 *buf, u8 *dst, u32 len, - int keynum, u8 *iv, u8 *icv); - -int wlan_setup(struct wlandevice *wlandev, struct device *physdev); -void wlan_unsetup(struct wlandevice *wlandev); -int register_wlandev(struct wlandevice *wlandev); -int unregister_wlandev(struct wlandevice *wlandev); -void p80211netdev_rx(struct wlandevice *wlandev, struct sk_buff *skb); -void p80211netdev_hwremoved(struct wlandevice *wlandev); -#endif diff --git a/drivers/staging/wlan-ng/p80211req.c b/drivers/staging/wlan-ng/p80211req.c deleted file mode 100644 index 6ec559ffd2f9..000000000000 --- a/drivers/staging/wlan-ng/p80211req.c +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) -/* - * - * Request/Indication/MacMgmt interface handling functions - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file contains the functions, types, and macros to support the - * MLME request interface that's implemented via the device ioctls. - * - * -------------------------------------------------------------------- - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/skbuff.h> -#include <linux/wireless.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <net/sock.h> -#include <linux/netlink.h> - -#include "p80211types.h" -#include "p80211hdr.h" -#include "p80211mgmt.h" -#include "p80211conv.h" -#include "p80211msg.h" -#include "p80211netdev.h" -#include "p80211ioctl.h" -#include "p80211metadef.h" -#include "p80211metastruct.h" -#include "p80211req.h" - -static void p80211req_handlemsg(struct wlandevice *wlandev, - struct p80211msg *msg); -static void p80211req_mibset_mibget(struct wlandevice *wlandev, - struct p80211msg_dot11req_mibget *mib_msg, - int isget); - -static void p80211req_handle_action(struct wlandevice *wlandev, u32 *data, - int isget, u32 flag) -{ - if (isget) { - if (wlandev->hostwep & flag) - *data = P80211ENUM_truth_true; - else - *data = P80211ENUM_truth_false; - } else { - wlandev->hostwep &= ~flag; - if (*data == P80211ENUM_truth_true) - wlandev->hostwep |= flag; - } -} - -/*---------------------------------------------------------------- - * p80211req_dorequest - * - * Handles an MLME request/confirm message. - * - * Arguments: - * wlandev WLAN device struct - * msgbuf Buffer containing a request message - * - * Returns: - * 0 on success, an errno otherwise - * - * Call context: - * Potentially blocks the caller, so it's a good idea to - * not call this function from an interrupt context. - *---------------------------------------------------------------- - */ -int p80211req_dorequest(struct wlandevice *wlandev, u8 *msgbuf) -{ - struct p80211msg *msg = (struct p80211msg *)msgbuf; - - /* Check to make sure the MSD is running */ - if (!((wlandev->msdstate == WLAN_MSD_HWPRESENT && - msg->msgcode == DIDMSG_LNXREQ_IFSTATE) || - wlandev->msdstate == WLAN_MSD_RUNNING || - wlandev->msdstate == WLAN_MSD_FWLOAD)) { - return -ENODEV; - } - - /* Check Permissions */ - if (!capable(CAP_NET_ADMIN) && - (msg->msgcode != DIDMSG_DOT11REQ_MIBGET)) { - netdev_err(wlandev->netdev, - "%s: only dot11req_mibget allowed for non-root.\n", - wlandev->name); - return -EPERM; - } - - /* Check for busy status */ - if (test_and_set_bit(1, &wlandev->request_pending)) - return -EBUSY; - - /* Allow p80211 to look at msg and handle if desired. */ - /* So far, all p80211 msgs are immediate, no waitq/timer necessary */ - /* This may change. */ - p80211req_handlemsg(wlandev, msg); - - /* Pass it down to wlandev via wlandev->mlmerequest */ - if (wlandev->mlmerequest) - wlandev->mlmerequest(wlandev, msg); - - clear_bit(1, &wlandev->request_pending); - return 0; /* if result==0, msg->status still may contain an err */ -} - -/*---------------------------------------------------------------- - * p80211req_handlemsg - * - * p80211 message handler. Primarily looks for messages that - * belong to p80211 and then dispatches the appropriate response. - * TODO: we don't do anything yet. Once the linuxMIB is better - * defined we'll need a get/set handler. - * - * Arguments: - * wlandev WLAN device struct - * msg message structure - * - * Returns: - * nothing (any results are set in the status field of the msg) - * - * Call context: - * Process thread - *---------------------------------------------------------------- - */ -static void p80211req_handlemsg(struct wlandevice *wlandev, - struct p80211msg *msg) -{ - switch (msg->msgcode) { - case DIDMSG_LNXREQ_HOSTWEP: { - struct p80211msg_lnxreq_hostwep *req = - (struct p80211msg_lnxreq_hostwep *)msg; - wlandev->hostwep &= - ~(HOSTWEP_DECRYPT | HOSTWEP_ENCRYPT); - if (req->decrypt.data == P80211ENUM_truth_true) - wlandev->hostwep |= HOSTWEP_DECRYPT; - if (req->encrypt.data == P80211ENUM_truth_true) - wlandev->hostwep |= HOSTWEP_ENCRYPT; - - break; - } - case DIDMSG_DOT11REQ_MIBGET: - case DIDMSG_DOT11REQ_MIBSET: { - int isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET); - struct p80211msg_dot11req_mibget *mib_msg = - (struct p80211msg_dot11req_mibget *)msg; - p80211req_mibset_mibget(wlandev, mib_msg, isget); - break; - } - } /* switch msg->msgcode */ -} - -static void p80211req_mibset_mibget(struct wlandevice *wlandev, - struct p80211msg_dot11req_mibget *mib_msg, - int isget) -{ - struct p80211itemd *mibitem = - (struct p80211itemd *)mib_msg->mibattribute.data; - struct p80211pstrd *pstr = (struct p80211pstrd *)mibitem->data; - u8 *key = mibitem->data + sizeof(struct p80211pstrd); - - switch (mibitem->did) { - case didmib_dot11smt_wepdefaultkeystable_key(1): - case didmib_dot11smt_wepdefaultkeystable_key(2): - case didmib_dot11smt_wepdefaultkeystable_key(3): - case didmib_dot11smt_wepdefaultkeystable_key(4): - if (!isget) - wep_change_key(wlandev, - P80211DID_ITEM(mibitem->did) - 1, - key, pstr->len); - break; - - case DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID: { - u32 *data = (u32 *)mibitem->data; - - if (isget) { - *data = wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK; - } else { - wlandev->hostwep &= ~(HOSTWEP_DEFAULTKEY_MASK); - wlandev->hostwep |= (*data & HOSTWEP_DEFAULTKEY_MASK); - } - break; - } - case DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED: { - u32 *data = (u32 *)mibitem->data; - - p80211req_handle_action(wlandev, data, isget, - HOSTWEP_PRIVACYINVOKED); - break; - } - case DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED: { - u32 *data = (u32 *)mibitem->data; - - p80211req_handle_action(wlandev, data, isget, - HOSTWEP_EXCLUDEUNENCRYPTED); - break; - } - } -} diff --git a/drivers/staging/wlan-ng/p80211req.h b/drivers/staging/wlan-ng/p80211req.h deleted file mode 100644 index 39213f73913c..000000000000 --- a/drivers/staging/wlan-ng/p80211req.h +++ /dev/null @@ -1,33 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * Request handling functions - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - */ - -#ifndef _LINUX_P80211REQ_H -#define _LINUX_P80211REQ_H - -int p80211req_dorequest(struct wlandevice *wlandev, u8 *msgbuf); - -#endif diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h deleted file mode 100644 index 5e4ea5f92058..000000000000 --- a/drivers/staging/wlan-ng/p80211types.h +++ /dev/null @@ -1,292 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * - * Macros, constants, types, and funcs for p80211 data types - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file declares some of the constants and types used in various - * parts of the linux-wlan system. - * - * Notes: - * - Constant values are always in HOST byte order. - * - * All functions and statics declared here are implemented in p80211types.c - * -------------------------------------------------------------------- - */ - -#ifndef _P80211TYPES_H -#define _P80211TYPES_H - -/*----------------------------------------------------------------*/ -/* The following constants are indexes into the Mib Category List */ -/* and the Message Category List */ - -/* Mib Category List */ -#define P80211_MIB_CAT_DOT11SMT 1 -#define P80211_MIB_CAT_DOT11MAC 2 -#define P80211_MIB_CAT_DOT11PHY 3 - -#define P80211SEC_DOT11SMT P80211_MIB_CAT_DOT11SMT -#define P80211SEC_DOT11MAC P80211_MIB_CAT_DOT11MAC -#define P80211SEC_DOT11PHY P80211_MIB_CAT_DOT11PHY - -/* Message Category List */ -#define P80211_MSG_CAT_DOT11REQ 1 -#define P80211_MSG_CAT_DOT11IND 2 - -/*----------------------------------------------------------------*/ -/* p80211 enumeration constants. The value to text mappings for */ -/* these is in p80211types.c. These defines were generated */ -/* from the mappings. */ - -/* error codes for lookups */ - -#define P80211ENUM_truth_false 0 -#define P80211ENUM_truth_true 1 -#define P80211ENUM_ifstate_disable 0 -#define P80211ENUM_ifstate_fwload 1 -#define P80211ENUM_ifstate_enable 2 -#define P80211ENUM_bsstype_infrastructure 1 -#define P80211ENUM_bsstype_independent 2 -#define P80211ENUM_bsstype_any 3 -#define P80211ENUM_authalg_opensystem 1 -#define P80211ENUM_authalg_sharedkey 2 -#define P80211ENUM_scantype_active 1 -#define P80211ENUM_resultcode_success 1 -#define P80211ENUM_resultcode_invalid_parameters 2 -#define P80211ENUM_resultcode_not_supported 3 -#define P80211ENUM_resultcode_refused 6 -#define P80211ENUM_resultcode_cant_set_readonly_mib 10 -#define P80211ENUM_resultcode_implementation_failure 11 -#define P80211ENUM_resultcode_cant_get_writeonly_mib 12 -#define P80211ENUM_status_successful 0 -#define P80211ENUM_status_unspec_failure 1 -#define P80211ENUM_status_ap_full 17 -#define P80211ENUM_msgitem_status_data_ok 0 -#define P80211ENUM_msgitem_status_no_value 1 - -/*----------------------------------------------------------------*/ -/* p80211 max length constants for the different pascal strings. */ - -#define MAXLEN_PSTR6 (6) /* pascal array of 6 bytes */ -#define MAXLEN_PSTR14 (14) /* pascal array of 14 bytes */ -#define MAXLEN_PSTR32 (32) /* pascal array of 32 bytes */ -#define MAXLEN_PSTR255 (255) /* pascal array of 255 bytes */ -#define MAXLEN_MIBATTRIBUTE (392) /* maximum mibattribute */ - /* where the size of the DATA itself */ - /* is a DID-LEN-DATA triple */ - /* with a max size of 4+4+384 */ - -/*---------------------------------------------------------------- - * The following constants and macros are used to construct and - * deconstruct the Data ID codes. The coding is as follows: - * - * ...rwtnnnnnnnniiiiiiggggggssssss s - Section - * g - Group - * i - Item - * n - Index - * t - Table flag - * w - Write flag - * r - Read flag - * . - Unused - */ - -#define P80211DID_LSB_SECTION (0) -#define P80211DID_LSB_GROUP (6) -#define P80211DID_LSB_ITEM (12) -#define P80211DID_LSB_INDEX (18) -#define P80211DID_LSB_ISTABLE (26) -#define P80211DID_LSB_ACCESS (27) - -#define P80211DID_MASK_SECTION (0x0000003fUL) -#define P80211DID_MASK_GROUP (0x0000003fUL) -#define P80211DID_MASK_ITEM (0x0000003fUL) -#define P80211DID_MASK_INDEX (0x000000ffUL) -#define P80211DID_MASK_ISTABLE (0x00000001UL) -#define P80211DID_MASK_ACCESS (0x00000003UL) - -#define P80211DID_MK(a, m, l) ((((u32)(a)) & (m)) << (l)) - -#define P80211DID_MKSECTION(a) P80211DID_MK(a, \ - P80211DID_MASK_SECTION, \ - P80211DID_LSB_SECTION) -#define P80211DID_MKGROUP(a) P80211DID_MK(a, \ - P80211DID_MASK_GROUP, \ - P80211DID_LSB_GROUP) -#define P80211DID_MKITEM(a) P80211DID_MK(a, \ - P80211DID_MASK_ITEM, \ - P80211DID_LSB_ITEM) -#define P80211DID_MKINDEX(a) P80211DID_MK(a, \ - P80211DID_MASK_INDEX, \ - P80211DID_LSB_INDEX) -#define P80211DID_MKISTABLE(a) P80211DID_MK(a, \ - P80211DID_MASK_ISTABLE, \ - P80211DID_LSB_ISTABLE) - -#define P80211DID_MKID(s, g, i, n, t, a) (P80211DID_MKSECTION(s) | \ - P80211DID_MKGROUP(g) | \ - P80211DID_MKITEM(i) | \ - P80211DID_MKINDEX(n) | \ - P80211DID_MKISTABLE(t) | \ - (a)) - -#define P80211DID_GET(a, m, l) ((((u32)(a)) >> (l)) & (m)) - -#define P80211DID_SECTION(a) P80211DID_GET(a, \ - P80211DID_MASK_SECTION, \ - P80211DID_LSB_SECTION) -#define P80211DID_GROUP(a) P80211DID_GET(a, \ - P80211DID_MASK_GROUP, \ - P80211DID_LSB_GROUP) -#define P80211DID_ITEM(a) P80211DID_GET(a, \ - P80211DID_MASK_ITEM, \ - P80211DID_LSB_ITEM) -#define P80211DID_INDEX(a) P80211DID_GET(a, \ - P80211DID_MASK_INDEX, \ - P80211DID_LSB_INDEX) -#define P80211DID_ISTABLE(a) P80211DID_GET(a, \ - P80211DID_MASK_ISTABLE, \ - P80211DID_LSB_ISTABLE) -#define P80211DID_ACCESS(a) P80211DID_GET(a, \ - P80211DID_MASK_ACCESS, \ - P80211DID_LSB_ACCESS) - -/*----------------------------------------------------------------*/ -/* The following structure types are used to store data items in */ -/* messages. */ - -/* Template pascal string */ -struct p80211pstr { - u8 len; -} __packed; - -struct p80211pstrd { - u8 len; - u8 data[]; -} __packed; - -/* Maximum pascal string */ -struct p80211pstr255 { - u8 len; - u8 data[MAXLEN_PSTR255]; -} __packed; - -/* pascal string for macaddress and bssid */ -struct p80211pstr6 { - u8 len; - u8 data[MAXLEN_PSTR6]; -} __packed; - -/* pascal string for channel list */ -struct p80211pstr14 { - u8 len; - u8 data[MAXLEN_PSTR14]; -} __packed; - -/* pascal string for ssid */ -struct p80211pstr32 { - u8 len; - u8 data[MAXLEN_PSTR32]; -} __packed; - -/* prototype template */ -struct p80211item { - u32 did; - u16 status; - u16 len; -} __packed; - -/* prototype template w/ data item */ -struct p80211itemd { - u32 did; - u16 status; - u16 len; - u8 data[]; -} __packed; - -/* message data item for int, BOUNDEDINT, ENUMINT */ -struct p80211item_uint32 { - u32 did; - u16 status; - u16 len; - u32 data; -} __packed; - -/* message data item for OCTETSTR, DISPLAYSTR */ -struct p80211item_pstr6 { - u32 did; - u16 status; - u16 len; - struct p80211pstr6 data; -} __packed; - -/* message data item for OCTETSTR, DISPLAYSTR */ -struct p80211item_pstr14 { - u32 did; - u16 status; - u16 len; - struct p80211pstr14 data; -} __packed; - -/* message data item for OCTETSTR, DISPLAYSTR */ -struct p80211item_pstr32 { - u32 did; - u16 status; - u16 len; - struct p80211pstr32 data; -} __packed; - -/* message data item for OCTETSTR, DISPLAYSTR */ -struct p80211item_pstr255 { - u32 did; - u16 status; - u16 len; - struct p80211pstr255 data; -} __packed; - -/* message data item for UNK 392, namely mib items */ -struct p80211item_unk392 { - u32 did; - u16 status; - u16 len; - u8 data[MAXLEN_MIBATTRIBUTE]; -} __packed; - -/* message data item for UNK 1025, namely p2 pdas */ -struct p80211item_unk1024 { - u32 did; - u16 status; - u16 len; - u8 data[1024]; -} __packed; - -/* message data item for UNK 4096, namely p2 download chunks */ -struct p80211item_unk4096 { - u32 did; - u16 status; - u16 len; - u8 data[4096]; -} __packed; - -#endif /* _P80211TYPES_H */ diff --git a/drivers/staging/wlan-ng/p80211wep.c b/drivers/staging/wlan-ng/p80211wep.c deleted file mode 100644 index e7b26b057124..000000000000 --- a/drivers/staging/wlan-ng/p80211wep.c +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) -/* - * - * WEP encode/decode for P80211. - * - * Copyright (C) 2002 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - */ - -/*================================================================*/ -/* System Includes */ - -#include <linux/crc32.h> -#include <linux/netdevice.h> -#include <linux/wireless.h> -#include <linux/random.h> -#include <linux/kernel.h> -#include "p80211hdr.h" -#include "p80211types.h" -#include "p80211msg.h" -#include "p80211conv.h" -#include "p80211netdev.h" - -#define WEP_KEY(x) (((x) & 0xC0) >> 6) - -/* keylen in bytes! */ - -int wep_change_key(struct wlandevice *wlandev, int keynum, u8 *key, int keylen) -{ - if (keylen < 0) - return -1; - if (keylen >= MAX_KEYLEN) - return -1; - if (!key) - return -1; - if (keynum < 0) - return -1; - if (keynum >= NUM_WEPKEYS) - return -1; - - wlandev->wep_keylens[keynum] = keylen; - memcpy(wlandev->wep_keys[keynum], key, keylen); - - return 0; -} - -/* - * 4-byte IV at start of buffer, 4-byte ICV at end of buffer. - * if successful, buf start is payload begin, length -= 8; - */ -int wep_decrypt(struct wlandevice *wlandev, u8 *buf, u32 len, int key_override, - u8 *iv, u8 *icv) -{ - u32 i, j, k, crc, keylen; - u8 s[256], key[64], c_crc[4]; - u8 keyidx; - - /* Needs to be at least 8 bytes of payload */ - if (len <= 0) - return -1; - - /* initialize the first bytes of the key from the IV */ - key[0] = iv[0]; - key[1] = iv[1]; - key[2] = iv[2]; - keyidx = WEP_KEY(iv[3]); - - if (key_override >= 0) - keyidx = key_override; - - if (keyidx >= NUM_WEPKEYS) - return -2; - - keylen = wlandev->wep_keylens[keyidx]; - - if (keylen == 0) - return -3; - - /* copy the rest of the key over from the designated key */ - memcpy(key + 3, wlandev->wep_keys[keyidx], keylen); - - keylen += 3; /* add in IV bytes */ - - /* set up the RC4 state */ - for (i = 0; i < 256; i++) - s[i] = i; - j = 0; - for (i = 0; i < 256; i++) { - j = (j + s[i] + key[i % keylen]) & 0xff; - swap(i, j); - } - - /* Apply the RC4 to the data, update the CRC32 */ - i = 0; - j = 0; - for (k = 0; k < len; k++) { - i = (i + 1) & 0xff; - j = (j + s[i]) & 0xff; - swap(i, j); - buf[k] ^= s[(s[i] + s[j]) & 0xff]; - } - crc = ~crc32_le(~0, buf, len); - - /* now let's check the crc */ - c_crc[0] = crc; - c_crc[1] = crc >> 8; - c_crc[2] = crc >> 16; - c_crc[3] = crc >> 24; - - for (k = 0; k < 4; k++) { - i = (i + 1) & 0xff; - j = (j + s[i]) & 0xff; - swap(i, j); - if ((c_crc[k] ^ s[(s[i] + s[j]) & 0xff]) != icv[k]) - return -(4 | (k << 4)); /* ICV mismatch */ - } - - return 0; -} - -/* encrypts in-place. */ -int wep_encrypt(struct wlandevice *wlandev, u8 *buf, - u8 *dst, u32 len, int keynum, u8 *iv, u8 *icv) -{ - u32 i, j, k, crc, keylen; - u8 s[256], key[64]; - - /* no point in WEPping an empty frame */ - if (len <= 0) - return -1; - - /* we need to have a real key.. */ - if (keynum >= NUM_WEPKEYS) - return -2; - keylen = wlandev->wep_keylens[keynum]; - if (keylen <= 0) - return -3; - - /* use a random IV. And skip known weak ones. */ - get_random_bytes(iv, 3); - while ((iv[1] == 0xff) && (iv[0] >= 3) && (iv[0] < keylen)) - get_random_bytes(iv, 3); - - iv[3] = (keynum & 0x03) << 6; - - key[0] = iv[0]; - key[1] = iv[1]; - key[2] = iv[2]; - - /* copy the rest of the key over from the designated key */ - memcpy(key + 3, wlandev->wep_keys[keynum], keylen); - - keylen += 3; /* add in IV bytes */ - - /* set up the RC4 state */ - for (i = 0; i < 256; i++) - s[i] = i; - j = 0; - for (i = 0; i < 256; i++) { - j = (j + s[i] + key[i % keylen]) & 0xff; - swap(i, j); - } - - /* Update CRC32 then apply RC4 to the data */ - i = 0; - j = 0; - for (k = 0; k < len; k++) { - i = (i + 1) & 0xff; - j = (j + s[i]) & 0xff; - swap(i, j); - dst[k] = buf[k] ^ s[(s[i] + s[j]) & 0xff]; - } - crc = ~crc32_le(~0, buf, len); - - /* now let's encrypt the crc */ - icv[0] = crc; - icv[1] = crc >> 8; - icv[2] = crc >> 16; - icv[3] = crc >> 24; - - for (k = 0; k < 4; k++) { - i = (i + 1) & 0xff; - j = (j + s[i]) & 0xff; - swap(i, j); - icv[k] ^= s[(s[i] + s[j]) & 0xff]; - } - - return 0; -} diff --git a/drivers/staging/wlan-ng/prism2fw.c b/drivers/staging/wlan-ng/prism2fw.c deleted file mode 100644 index 3ccd11041646..000000000000 --- a/drivers/staging/wlan-ng/prism2fw.c +++ /dev/null @@ -1,1213 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) -/* from src/prism2/download/prism2dl.c - * - * utility for downloading prism2 images moved into kernelspace - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - */ - -/*================================================================*/ -/* System Includes */ -#include <linux/ihex.h> -#include <linux/slab.h> - -/*================================================================*/ -/* Local Constants */ - -#define PRISM2_USB_FWFILE "prism2_ru.fw" -MODULE_FIRMWARE(PRISM2_USB_FWFILE); - -#define S3DATA_MAX 5000 -#define S3PLUG_MAX 200 -#define S3CRC_MAX 200 -#define S3INFO_MAX 50 - -#define S3ADDR_PLUG (0xff000000UL) -#define S3ADDR_CRC (0xff100000UL) -#define S3ADDR_INFO (0xff200000UL) -#define S3ADDR_START (0xff400000UL) - -#define CHUNKS_MAX 100 - -#define WRITESIZE_MAX 4096 - -/*================================================================*/ -/* Local Types */ - -struct s3datarec { - u32 len; - u32 addr; - u8 checksum; - u8 *data; -}; - -struct s3plugrec { - u32 itemcode; - u32 addr; - u32 len; -}; - -struct s3crcrec { - u32 addr; - u32 len; - unsigned int dowrite; -}; - -struct s3inforec { - u16 len; - u16 type; - union { - struct hfa384x_compident version; - struct hfa384x_caplevel compat; - u16 buildseq; - struct hfa384x_compident platform; - } info; -}; - -struct pda { - u8 buf[HFA384x_PDA_LEN_MAX]; - struct hfa384x_pdrec *rec[HFA384x_PDA_RECS_MAX]; - unsigned int nrec; -}; - -struct imgchunk { - u32 addr; /* start address */ - u32 len; /* in bytes */ - u16 crc; /* CRC value (if it falls at a chunk boundary) */ - u8 *data; -}; - -/*================================================================*/ -/* Local Static Definitions */ - -/*----------------------------------------------------------------*/ -/* s-record image processing */ - -/* Data records */ -static unsigned int ns3data; -static struct s3datarec *s3data; - -/* Plug records */ -static unsigned int ns3plug; -static struct s3plugrec s3plug[S3PLUG_MAX]; - -/* CRC records */ -static unsigned int ns3crc; -static struct s3crcrec s3crc[S3CRC_MAX]; - -/* Info records */ -static unsigned int ns3info; -static struct s3inforec s3info[S3INFO_MAX]; - -/* S7 record (there _better_ be only one) */ -static u32 startaddr; - -/* Load image chunks */ -static unsigned int nfchunks; -static struct imgchunk fchunk[CHUNKS_MAX]; - -/* Note that for the following pdrec_t arrays, the len and code */ -/* fields are stored in HOST byte order. The mkpdrlist() function */ -/* does the conversion. */ -/*----------------------------------------------------------------*/ -/* PDA, built from [card|newfile]+[addfile1+addfile2...] */ - -static struct pda pda; -static struct hfa384x_compident nicid; -static struct hfa384x_caplevel rfid; -static struct hfa384x_caplevel macid; -static struct hfa384x_caplevel priid; - -/*================================================================*/ -/* Local Function Declarations */ - -static int prism2_fwapply(const struct ihex_binrec *rfptr, - struct wlandevice *wlandev); - -static int read_fwfile(const struct ihex_binrec *rfptr); - -static int mkimage(struct imgchunk *clist, unsigned int *ccnt); - -static int read_cardpda(struct pda *pda, struct wlandevice *wlandev); - -static int mkpdrlist(struct pda *pda); - -static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, - struct s3plugrec *s3plug, unsigned int ns3plug, - struct pda *pda); - -static int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, - struct s3crcrec *s3crc, unsigned int ns3crc); - -static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, - unsigned int nfchunks); - -static void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks); - -static void free_srecs(void); - -static int validate_identity(void); - -/*================================================================*/ -/* Function Definitions */ - -/*---------------------------------------------------------------- - * prism2_fwtry - * - * Try and get firmware into memory - * - * Arguments: - * udev usb device structure - * wlandev wlan device structure - * - * Returns: - * 0 - success - * ~0 - failure - *---------------------------------------------------------------- - */ -static int prism2_fwtry(struct usb_device *udev, struct wlandevice *wlandev) -{ - const struct firmware *fw_entry = NULL; - - netdev_info(wlandev->netdev, "prism2_usb: Checking for firmware %s\n", - PRISM2_USB_FWFILE); - if (request_ihex_firmware(&fw_entry, - PRISM2_USB_FWFILE, &udev->dev) != 0) { - netdev_info(wlandev->netdev, - "prism2_usb: Firmware not available, but not essential\n"); - netdev_info(wlandev->netdev, - "prism2_usb: can continue to use card anyway.\n"); - return 1; - } - - netdev_info(wlandev->netdev, - "prism2_usb: %s will be processed, size %zu\n", - PRISM2_USB_FWFILE, fw_entry->size); - prism2_fwapply((const struct ihex_binrec *)fw_entry->data, wlandev); - - release_firmware(fw_entry); - return 0; -} - -/*---------------------------------------------------------------- - * prism2_fwapply - * - * Apply the firmware loaded into memory - * - * Arguments: - * rfptr firmware image in kernel memory - * wlandev device - * - * Returns: - * 0 - success - * ~0 - failure - *---------------------------------------------------------------- - */ -static int prism2_fwapply(const struct ihex_binrec *rfptr, - struct wlandevice *wlandev) -{ - signed int result = 0; - struct p80211msg_dot11req_mibget getmsg; - struct p80211itemd *item; - u32 *data; - - /* Initialize the data structures */ - ns3data = 0; - s3data = kcalloc(S3DATA_MAX, sizeof(*s3data), GFP_KERNEL); - if (!s3data) { - result = -ENOMEM; - goto out; - } - - ns3plug = 0; - memset(s3plug, 0, sizeof(s3plug)); - ns3crc = 0; - memset(s3crc, 0, sizeof(s3crc)); - ns3info = 0; - memset(s3info, 0, sizeof(s3info)); - startaddr = 0; - - nfchunks = 0; - memset(fchunk, 0, sizeof(fchunk)); - memset(&nicid, 0, sizeof(nicid)); - memset(&rfid, 0, sizeof(rfid)); - memset(&macid, 0, sizeof(macid)); - memset(&priid, 0, sizeof(priid)); - - /* clear the pda and add an initial END record */ - memset(&pda, 0, sizeof(pda)); - pda.rec[0] = (struct hfa384x_pdrec *)pda.buf; - pda.rec[0]->len = cpu_to_le16(2); /* len in words */ - pda.rec[0]->code = cpu_to_le16(HFA384x_PDR_END_OF_PDA); - pda.nrec = 1; - - /*-----------------------------------------------------*/ - /* Put card into fwload state */ - prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload); - - /* Build the PDA we're going to use. */ - if (read_cardpda(&pda, wlandev)) { - netdev_err(wlandev->netdev, "load_cardpda failed, exiting.\n"); - result = 1; - goto out; - } - - /* read the card's PRI-SUP */ - memset(&getmsg, 0, sizeof(getmsg)); - getmsg.msgcode = DIDMSG_DOT11REQ_MIBGET; - getmsg.msglen = sizeof(getmsg); - strscpy(getmsg.devname, wlandev->name, sizeof(getmsg.devname)); - - getmsg.mibattribute.did = DIDMSG_DOT11REQ_MIBGET_MIBATTRIBUTE; - getmsg.mibattribute.status = P80211ENUM_msgitem_status_data_ok; - getmsg.resultcode.did = DIDMSG_DOT11REQ_MIBGET_RESULTCODE; - getmsg.resultcode.status = P80211ENUM_msgitem_status_no_value; - - item = (struct p80211itemd *)getmsg.mibattribute.data; - item->did = DIDMIB_P2_NIC_PRISUPRANGE; - item->status = P80211ENUM_msgitem_status_no_value; - - data = (u32 *)item->data; - - /* DIDmsg_dot11req_mibget */ - prism2mgmt_mibset_mibget(wlandev, &getmsg); - if (getmsg.resultcode.data != P80211ENUM_resultcode_success) - netdev_err(wlandev->netdev, "Couldn't fetch PRI-SUP info\n"); - - /* Already in host order */ - priid.role = *data++; - priid.id = *data++; - priid.variant = *data++; - priid.bottom = *data++; - priid.top = *data++; - - /* Read the S3 file */ - result = read_fwfile(rfptr); - if (result) { - netdev_err(wlandev->netdev, - "Failed to read the data exiting.\n"); - goto out; - } - - result = validate_identity(); - if (result) { - netdev_err(wlandev->netdev, "Incompatible firmware image.\n"); - goto out; - } - - if (startaddr == 0x00000000) { - netdev_err(wlandev->netdev, - "Can't RAM download a Flash image!\n"); - result = 1; - goto out; - } - - /* Make the image chunks */ - result = mkimage(fchunk, &nfchunks); - if (result) { - netdev_err(wlandev->netdev, "Failed to make image chunk.\n"); - goto free_chunks; - } - - /* Do any plugging */ - result = plugimage(fchunk, nfchunks, s3plug, ns3plug, &pda); - if (result) { - netdev_err(wlandev->netdev, "Failed to plug data.\n"); - goto free_chunks; - } - - /* Insert any CRCs */ - result = crcimage(fchunk, nfchunks, s3crc, ns3crc); - if (result) { - netdev_err(wlandev->netdev, "Failed to insert all CRCs\n"); - goto free_chunks; - } - - /* Write the image */ - result = writeimage(wlandev, fchunk, nfchunks); - if (result) { - netdev_err(wlandev->netdev, "Failed to ramwrite image data.\n"); - goto free_chunks; - } - - netdev_info(wlandev->netdev, "prism2_usb: firmware loading finished.\n"); - -free_chunks: - /* clear any allocated memory */ - free_chunks(fchunk, &nfchunks); - free_srecs(); - -out: - return result; -} - -/*---------------------------------------------------------------- - * crcimage - * - * Adds a CRC16 in the two bytes prior to each block identified by - * an S3 CRC record. Currently, we don't actually do a CRC we just - * insert the value 0xC0DE in hfa384x order. - * - * Arguments: - * fchunk Array of image chunks - * nfchunks Number of image chunks - * s3crc Array of crc records - * ns3crc Number of crc records - * - * Returns: - * 0 success - * ~0 failure - *---------------------------------------------------------------- - */ -static int crcimage(struct imgchunk *fchunk, unsigned int nfchunks, - struct s3crcrec *s3crc, unsigned int ns3crc) -{ - int result = 0; - int i; - int c; - u32 crcstart; - u32 cstart = 0; - u32 cend; - u8 *dest; - u32 chunkoff; - - for (i = 0; i < ns3crc; i++) { - if (!s3crc[i].dowrite) - continue; - crcstart = s3crc[i].addr; - /* Find chunk */ - for (c = 0; c < nfchunks; c++) { - cstart = fchunk[c].addr; - cend = fchunk[c].addr + fchunk[c].len; - /* the line below does an address & len match search */ - /* unfortunately, I've found that the len fields of */ - /* some crc records don't match with the length of */ - /* the actual data, so we're not checking right now */ - /* if (crcstart-2 >= cstart && crcend <= cend) break; */ - - /* note the -2 below, it's to make sure the chunk has */ - /* space for the CRC value */ - if (crcstart - 2 >= cstart && crcstart < cend) - break; - } - if (c >= nfchunks) { - pr_err("Failed to find chunk for crcrec[%d], addr=0x%06x len=%d , aborting crc.\n", - i, s3crc[i].addr, s3crc[i].len); - return 1; - } - - /* Insert crc */ - pr_debug("Adding crc @ 0x%06x\n", s3crc[i].addr - 2); - chunkoff = crcstart - cstart - 2; - dest = fchunk[c].data + chunkoff; - *dest = 0xde; - *(dest + 1) = 0xc0; - } - return result; -} - -/*---------------------------------------------------------------- - * free_chunks - * - * Clears the chunklist data structures in preparation for a new file. - * - * Arguments: - * none - * - * Returns: - * nothing - *---------------------------------------------------------------- - */ -static void free_chunks(struct imgchunk *fchunk, unsigned int *nfchunks) -{ - int i; - - for (i = 0; i < *nfchunks; i++) - kfree(fchunk[i].data); - - *nfchunks = 0; - memset(fchunk, 0, sizeof(*fchunk)); -} - -/*---------------------------------------------------------------- - * free_srecs - * - * Clears the srec data structures in preparation for a new file. - * - * Arguments: - * none - * - * Returns: - * nothing - *---------------------------------------------------------------- - */ -static void free_srecs(void) -{ - ns3data = 0; - kfree(s3data); - ns3plug = 0; - memset(s3plug, 0, sizeof(s3plug)); - ns3crc = 0; - memset(s3crc, 0, sizeof(s3crc)); - ns3info = 0; - memset(s3info, 0, sizeof(s3info)); - startaddr = 0; -} - -/*---------------------------------------------------------------- - * mkimage - * - * Scans the currently loaded set of S records for data residing - * in contiguous memory regions. Each contiguous region is then - * made into a 'chunk'. This function assumes that we're building - * a new chunk list. Assumes the s3data items are in sorted order. - * - * Arguments: none - * - * Returns: - * 0 - success - * ~0 - failure (probably an errno) - *---------------------------------------------------------------- - */ -static int mkimage(struct imgchunk *clist, unsigned int *ccnt) -{ - int result = 0; - int i; - int j; - int currchunk = 0; - u32 nextaddr = 0; - u32 s3start; - u32 s3end; - u32 cstart = 0; - u32 cend; - u32 coffset; - - /* There may already be data in the chunklist */ - *ccnt = 0; - - /* Establish the location and size of each chunk */ - for (i = 0; i < ns3data; i++) { - if (s3data[i].addr == nextaddr) { - /* existing chunk, grow it */ - clist[currchunk].len += s3data[i].len; - nextaddr += s3data[i].len; - } else { - /* New chunk */ - (*ccnt)++; - currchunk = *ccnt - 1; - clist[currchunk].addr = s3data[i].addr; - clist[currchunk].len = s3data[i].len; - nextaddr = s3data[i].addr + s3data[i].len; - /* Expand the chunk if there is a CRC record at */ - /* their beginning bound */ - for (j = 0; j < ns3crc; j++) { - if (s3crc[j].dowrite && - s3crc[j].addr == clist[currchunk].addr) { - clist[currchunk].addr -= 2; - clist[currchunk].len += 2; - } - } - } - } - - /* We're currently assuming there aren't any overlapping chunks */ - /* if this proves false, we'll need to add code to coalesce. */ - - /* Allocate buffer space for chunks */ - for (i = 0; i < *ccnt; i++) { - clist[i].data = kzalloc(clist[i].len, GFP_KERNEL); - if (!clist[i].data) - return 1; - - pr_debug("chunk[%d]: addr=0x%06x len=%d\n", - i, clist[i].addr, clist[i].len); - } - - /* Copy srec data to chunks */ - for (i = 0; i < ns3data; i++) { - s3start = s3data[i].addr; - s3end = s3start + s3data[i].len - 1; - for (j = 0; j < *ccnt; j++) { - cstart = clist[j].addr; - cend = cstart + clist[j].len - 1; - if (s3start >= cstart && s3end <= cend) - break; - } - if (((unsigned int)j) >= (*ccnt)) { - pr_err("s3rec(a=0x%06x,l=%d), no chunk match, exiting.\n", - s3start, s3data[i].len); - return 1; - } - coffset = s3start - cstart; - memcpy(clist[j].data + coffset, s3data[i].data, s3data[i].len); - } - - return result; -} - -/*---------------------------------------------------------------- - * mkpdrlist - * - * Reads a raw PDA and builds an array of pdrec_t structures. - * - * Arguments: - * pda buffer containing raw PDA bytes - * pdrec ptr to an array of pdrec_t's. Will be filled on exit. - * nrec ptr to a variable that will contain the count of PDRs - * - * Returns: - * 0 - success - * ~0 - failure (probably an errno) - *---------------------------------------------------------------- - */ -static int mkpdrlist(struct pda *pda) -{ - __le16 *pda16 = (__le16 *)pda->buf; - int curroff; /* in 'words' */ - - pda->nrec = 0; - curroff = 0; - while (curroff < (HFA384x_PDA_LEN_MAX / 2 - 1) && - le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) { - pda->rec[pda->nrec] = (struct hfa384x_pdrec *)&pda16[curroff]; - - if (le16_to_cpu(pda->rec[pda->nrec]->code) == - HFA384x_PDR_NICID) { - memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid, - sizeof(nicid)); - le16_to_cpus(&nicid.id); - le16_to_cpus(&nicid.variant); - le16_to_cpus(&nicid.major); - le16_to_cpus(&nicid.minor); - } - if (le16_to_cpu(pda->rec[pda->nrec]->code) == - HFA384x_PDR_MFISUPRANGE) { - memcpy(&rfid, &pda->rec[pda->nrec]->data.mfisuprange, - sizeof(rfid)); - le16_to_cpus(&rfid.id); - le16_to_cpus(&rfid.variant); - le16_to_cpus(&rfid.bottom); - le16_to_cpus(&rfid.top); - } - if (le16_to_cpu(pda->rec[pda->nrec]->code) == - HFA384x_PDR_CFISUPRANGE) { - memcpy(&macid, &pda->rec[pda->nrec]->data.cfisuprange, - sizeof(macid)); - le16_to_cpus(&macid.id); - le16_to_cpus(&macid.variant); - le16_to_cpus(&macid.bottom); - le16_to_cpus(&macid.top); - } - - (pda->nrec)++; - curroff += le16_to_cpu(pda16[curroff]) + 1; - } - if (curroff >= (HFA384x_PDA_LEN_MAX / 2 - 1)) { - pr_err("no end record found or invalid lengths in PDR data, exiting. %x %d\n", - curroff, pda->nrec); - return 1; - } - pda->rec[pda->nrec] = (struct hfa384x_pdrec *)&pda16[curroff]; - (pda->nrec)++; - return 0; -} - -/*---------------------------------------------------------------- - * plugimage - * - * Plugs the given image using the given plug records from the given - * PDA and filename. - * - * Arguments: - * fchunk Array of image chunks - * nfchunks Number of image chunks - * s3plug Array of plug records - * ns3plug Number of plug records - * pda Current pda data - * - * Returns: - * 0 success - * ~0 failure - *---------------------------------------------------------------- - */ -static int plugimage(struct imgchunk *fchunk, unsigned int nfchunks, - struct s3plugrec *s3plug, unsigned int ns3plug, - struct pda *pda) -{ - int result = 0; - int i; /* plug index */ - int j; /* index of PDR or -1 if fname plug */ - int c; /* chunk index */ - u32 pstart; - u32 pend; - u32 cstart = 0; - u32 cend; - u32 chunkoff; - u8 *dest; - - /* for each plug record */ - for (i = 0; i < ns3plug; i++) { - pstart = s3plug[i].addr; - pend = s3plug[i].addr + s3plug[i].len; - j = -1; - /* find the matching PDR (or filename) */ - if (s3plug[i].itemcode != 0xffffffffUL) { /* not filename */ - for (j = 0; j < pda->nrec; j++) { - if (s3plug[i].itemcode == - le16_to_cpu(pda->rec[j]->code)) - break; - } - } - if (j >= pda->nrec && j != -1) { /* if no matching PDR, fail */ - pr_warn("warning: Failed to find PDR for plugrec 0x%04x.\n", - s3plug[i].itemcode); - continue; /* and move on to the next PDR */ - - /* MSM: They swear that unless it's the MAC address, - * the serial number, or the TX calibration records, - * then there's reasonable defaults in the f/w - * image. Therefore, missing PDRs in the card - * should only be a warning, not fatal. - * TODO: add fatals for the PDRs mentioned above. - */ - } - - /* Validate plug len against PDR len */ - if (j != -1 && s3plug[i].len < le16_to_cpu(pda->rec[j]->len)) { - pr_err("error: Plug vs. PDR len mismatch for plugrec 0x%04x, abort plugging.\n", - s3plug[i].itemcode); - result = 1; - continue; - } - - /* - * Validate plug address against - * chunk data and identify chunk - */ - for (c = 0; c < nfchunks; c++) { - cstart = fchunk[c].addr; - cend = fchunk[c].addr + fchunk[c].len; - if (pstart >= cstart && pend <= cend) - break; - } - if (c >= nfchunks) { - pr_err("error: Failed to find image chunk for plugrec 0x%04x.\n", - s3plug[i].itemcode); - result = 1; - continue; - } - - /* Plug data */ - chunkoff = pstart - cstart; - dest = fchunk[c].data + chunkoff; - pr_debug("Plugging item 0x%04x @ 0x%06x, len=%d, cnum=%d coff=0x%06x\n", - s3plug[i].itemcode, pstart, s3plug[i].len, - c, chunkoff); - - if (j == -1) { /* plug the filename */ - memset(dest, 0, s3plug[i].len); - strscpy(dest, PRISM2_USB_FWFILE, s3plug[i].len); - } else { /* plug a PDR */ - memcpy(dest, &pda->rec[j]->data, s3plug[i].len); - } - } - return result; -} - -/*---------------------------------------------------------------- - * read_cardpda - * - * Sends the command for the driver to read the pda from the card - * named in the device variable. Upon success, the card pda is - * stored in the "cardpda" variables. Note that the pda structure - * is considered 'well formed' after this function. That means - * that the nrecs is valid, the rec array has been set up, and there's - * a valid PDAEND record in the raw PDA data. - * - * Arguments: - * pda pda structure - * wlandev device - * - * Returns: - * 0 - success - * ~0 - failure (probably an errno) - *---------------------------------------------------------------- - */ -static int read_cardpda(struct pda *pda, struct wlandevice *wlandev) -{ - int result = 0; - struct p80211msg_p2req_readpda *msg; - - msg = kzalloc(sizeof(*msg), GFP_KERNEL); - if (!msg) - return -ENOMEM; - - /* set up the msg */ - msg->msgcode = DIDMSG_P2REQ_READPDA; - msg->msglen = sizeof(msg); - strscpy(msg->devname, wlandev->name, sizeof(msg->devname)); - msg->pda.did = DIDMSG_P2REQ_READPDA_PDA; - msg->pda.len = HFA384x_PDA_LEN_MAX; - msg->pda.status = P80211ENUM_msgitem_status_no_value; - msg->resultcode.did = DIDMSG_P2REQ_READPDA_RESULTCODE; - msg->resultcode.len = sizeof(u32); - msg->resultcode.status = P80211ENUM_msgitem_status_no_value; - - if (prism2mgmt_readpda(wlandev, msg) != 0) { - /* prism2mgmt_readpda prints an errno if appropriate */ - result = -1; - } else if (msg->resultcode.data == P80211ENUM_resultcode_success) { - memcpy(pda->buf, msg->pda.data, HFA384x_PDA_LEN_MAX); - result = mkpdrlist(pda); - } else { - /* resultcode must've been something other than success */ - result = -1; - } - - kfree(msg); - return result; -} - -/*---------------------------------------------------------------- - * read_fwfile - * - * Reads the given fw file which should have been compiled from an srec - * file. Each record in the fw file will either be a plain data record, - * a start address record, or other records used for plugging. - * - * Note that data records are expected to be sorted into - * ascending address order in the fw file. - * - * Note also that the start address record, originally an S7 record in - * the srec file, is expected in the fw file to be like a data record but - * with a certain address to make it identifiable. - * - * Here's the SREC format that the fw should have come from: - * S[37]nnaaaaaaaaddd...dddcc - * - * nn - number of bytes starting with the address field - * aaaaaaaa - address in readable (or big endian) format - * dd....dd - 0-245 data bytes (two chars per byte) - * cc - checksum - * - * The S7 record's (there should be only one) address value gets - * converted to an S3 record with address of 0xff400000, with the - * start address being stored as a 4 byte data word. That address is - * the start execution address used for RAM downloads. - * - * The S3 records have a collection of subformats indicated by the - * value of aaaaaaaa: - * 0xff000000 - Plug record, data field format: - * xxxxxxxxaaaaaaaassssssss - * x - PDR code number (little endian) - * a - Address in load image to plug (little endian) - * s - Length of plug data area (little endian) - * - * 0xff100000 - CRC16 generation record, data field format: - * aaaaaaaassssssssbbbbbbbb - * a - Start address for CRC calculation (little endian) - * s - Length of data to calculate over (little endian) - * b - Boolean, true=write crc, false=don't write - * - * 0xff200000 - Info record, data field format: - * ssssttttdd..dd - * s - Size in words (little endian) - * t - Info type (little endian), see #defines and - * struct s3inforec for details about types. - * d - (s - 1) little endian words giving the contents of - * the given info type. - * - * 0xff400000 - Start address record, data field format: - * aaaaaaaa - * a - Address in load image to plug (little endian) - * - * Arguments: - * record firmware image (ihex record structure) in kernel memory - * - * Returns: - * 0 - success - * ~0 - failure (probably an errno) - *---------------------------------------------------------------- - */ -static int read_fwfile(const struct ihex_binrec *record) -{ - int i; - int rcnt = 0; - u16 *tmpinfo; - u16 *ptr16; - u32 *ptr32, len, addr; - - pr_debug("Reading fw file ...\n"); - - while (record) { - rcnt++; - - len = be16_to_cpu(record->len); - addr = be32_to_cpu(record->addr); - - /* Point into data for different word lengths */ - ptr32 = (u32 *)record->data; - ptr16 = (u16 *)record->data; - - /* parse what was an S3 srec and put it in the right array */ - switch (addr) { - case S3ADDR_START: - startaddr = *ptr32; - pr_debug(" S7 start addr, record=%d addr=0x%08x\n", - rcnt, - startaddr); - break; - case S3ADDR_PLUG: - s3plug[ns3plug].itemcode = *ptr32; - s3plug[ns3plug].addr = *(ptr32 + 1); - s3plug[ns3plug].len = *(ptr32 + 2); - - pr_debug(" S3 plugrec, record=%d itemcode=0x%08x addr=0x%08x len=%d\n", - rcnt, - s3plug[ns3plug].itemcode, - s3plug[ns3plug].addr, - s3plug[ns3plug].len); - - ns3plug++; - if (ns3plug == S3PLUG_MAX) { - pr_err("S3 plugrec limit reached - aborting\n"); - return 1; - } - break; - case S3ADDR_CRC: - s3crc[ns3crc].addr = *ptr32; - s3crc[ns3crc].len = *(ptr32 + 1); - s3crc[ns3crc].dowrite = *(ptr32 + 2); - - pr_debug(" S3 crcrec, record=%d addr=0x%08x len=%d write=0x%08x\n", - rcnt, - s3crc[ns3crc].addr, - s3crc[ns3crc].len, - s3crc[ns3crc].dowrite); - ns3crc++; - if (ns3crc == S3CRC_MAX) { - pr_err("S3 crcrec limit reached - aborting\n"); - return 1; - } - break; - case S3ADDR_INFO: - s3info[ns3info].len = *ptr16; - s3info[ns3info].type = *(ptr16 + 1); - - pr_debug(" S3 inforec, record=%d len=0x%04x type=0x%04x\n", - rcnt, - s3info[ns3info].len, - s3info[ns3info].type); - if (((s3info[ns3info].len - 1) * sizeof(u16)) > - sizeof(s3info[ns3info].info)) { - pr_err("S3 inforec length too long - aborting\n"); - return 1; - } - - tmpinfo = (u16 *)&s3info[ns3info].info.version; - pr_debug(" info="); - for (i = 0; i < s3info[ns3info].len - 1; i++) { - tmpinfo[i] = *(ptr16 + 2 + i); - pr_debug("%04x ", tmpinfo[i]); - } - pr_debug("\n"); - - ns3info++; - if (ns3info == S3INFO_MAX) { - pr_err("S3 inforec limit reached - aborting\n"); - return 1; - } - break; - default: /* Data record */ - s3data[ns3data].addr = addr; - s3data[ns3data].len = len; - s3data[ns3data].data = (uint8_t *)record->data; - ns3data++; - if (ns3data == S3DATA_MAX) { - pr_err("S3 datarec limit reached - aborting\n"); - return 1; - } - break; - } - record = ihex_next_binrec(record); - } - return 0; -} - -/*---------------------------------------------------------------- - * writeimage - * - * Takes the chunks, builds p80211 messages and sends them down - * to the driver for writing to the card. - * - * Arguments: - * wlandev device - * fchunk Array of image chunks - * nfchunks Number of image chunks - * - * Returns: - * 0 success - * ~0 failure - *---------------------------------------------------------------- - */ -static int writeimage(struct wlandevice *wlandev, struct imgchunk *fchunk, - unsigned int nfchunks) -{ - int result = 0; - struct p80211msg_p2req_ramdl_state *rstmsg; - struct p80211msg_p2req_ramdl_write *rwrmsg; - u32 resultcode; - int i; - int j; - unsigned int nwrites; - u32 curroff; - u32 currlen; - u32 currdaddr; - - rstmsg = kzalloc(sizeof(*rstmsg), GFP_KERNEL); - rwrmsg = kzalloc(sizeof(*rwrmsg), GFP_KERNEL); - if (!rstmsg || !rwrmsg) { - netdev_err(wlandev->netdev, - "%s: no memory for firmware download, aborting download\n", - __func__); - result = -ENOMEM; - goto free_result; - } - - /* Initialize the messages */ - strscpy(rstmsg->devname, wlandev->name, sizeof(rstmsg->devname)); - rstmsg->msgcode = DIDMSG_P2REQ_RAMDL_STATE; - rstmsg->msglen = sizeof(*rstmsg); - rstmsg->enable.did = DIDMSG_P2REQ_RAMDL_STATE_ENABLE; - rstmsg->exeaddr.did = DIDMSG_P2REQ_RAMDL_STATE_EXEADDR; - rstmsg->resultcode.did = DIDMSG_P2REQ_RAMDL_STATE_RESULTCODE; - rstmsg->enable.status = P80211ENUM_msgitem_status_data_ok; - rstmsg->exeaddr.status = P80211ENUM_msgitem_status_data_ok; - rstmsg->resultcode.status = P80211ENUM_msgitem_status_no_value; - rstmsg->enable.len = sizeof(u32); - rstmsg->exeaddr.len = sizeof(u32); - rstmsg->resultcode.len = sizeof(u32); - - strscpy(rwrmsg->devname, wlandev->name, sizeof(rwrmsg->devname)); - rwrmsg->msgcode = DIDMSG_P2REQ_RAMDL_WRITE; - rwrmsg->msglen = sizeof(*rwrmsg); - rwrmsg->addr.did = DIDMSG_P2REQ_RAMDL_WRITE_ADDR; - rwrmsg->len.did = DIDMSG_P2REQ_RAMDL_WRITE_LEN; - rwrmsg->data.did = DIDMSG_P2REQ_RAMDL_WRITE_DATA; - rwrmsg->resultcode.did = DIDMSG_P2REQ_RAMDL_WRITE_RESULTCODE; - rwrmsg->addr.status = P80211ENUM_msgitem_status_data_ok; - rwrmsg->len.status = P80211ENUM_msgitem_status_data_ok; - rwrmsg->data.status = P80211ENUM_msgitem_status_data_ok; - rwrmsg->resultcode.status = P80211ENUM_msgitem_status_no_value; - rwrmsg->addr.len = sizeof(u32); - rwrmsg->len.len = sizeof(u32); - rwrmsg->data.len = WRITESIZE_MAX; - rwrmsg->resultcode.len = sizeof(u32); - - /* Send xxx_state(enable) */ - pr_debug("Sending dl_state(enable) message.\n"); - rstmsg->enable.data = P80211ENUM_truth_true; - rstmsg->exeaddr.data = startaddr; - - result = prism2mgmt_ramdl_state(wlandev, rstmsg); - if (result) { - netdev_err(wlandev->netdev, - "%s state enable failed w/ result=%d, aborting download\n", - __func__, result); - goto free_result; - } - resultcode = rstmsg->resultcode.data; - if (resultcode != P80211ENUM_resultcode_success) { - netdev_err(wlandev->netdev, - "%s()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", - __func__, resultcode); - result = 1; - goto free_result; - } - - /* Now, loop through the data chunks and send WRITESIZE_MAX data */ - for (i = 0; i < nfchunks; i++) { - nwrites = fchunk[i].len / WRITESIZE_MAX; - nwrites += (fchunk[i].len % WRITESIZE_MAX) ? 1 : 0; - curroff = 0; - for (j = 0; j < nwrites; j++) { - /* TODO Move this to a separate function */ - int lenleft = fchunk[i].len - (WRITESIZE_MAX * j); - - if (fchunk[i].len > WRITESIZE_MAX) - currlen = WRITESIZE_MAX; - else - currlen = lenleft; - curroff = j * WRITESIZE_MAX; - currdaddr = fchunk[i].addr + curroff; - /* Setup the message */ - rwrmsg->addr.data = currdaddr; - rwrmsg->len.data = currlen; - memcpy(rwrmsg->data.data, - fchunk[i].data + curroff, currlen); - - /* Send flashdl_write(pda) */ - pr_debug - ("Sending xxxdl_write message addr=%06x len=%d.\n", - currdaddr, currlen); - - result = prism2mgmt_ramdl_write(wlandev, rwrmsg); - - /* Check the results */ - if (result) { - netdev_err(wlandev->netdev, - "%s chunk write failed w/ result=%d, aborting download\n", - __func__, result); - goto free_result; - } - resultcode = rstmsg->resultcode.data; - if (resultcode != P80211ENUM_resultcode_success) { - pr_err("%s()->xxxdl_write msg indicates failure, w/ resultcode=%d, aborting download.\n", - __func__, resultcode); - result = 1; - goto free_result; - } - } - } - - /* Send xxx_state(disable) */ - pr_debug("Sending dl_state(disable) message.\n"); - rstmsg->enable.data = P80211ENUM_truth_false; - rstmsg->exeaddr.data = 0; - - result = prism2mgmt_ramdl_state(wlandev, rstmsg); - if (result) { - netdev_err(wlandev->netdev, - "%s state disable failed w/ result=%d, aborting download\n", - __func__, result); - goto free_result; - } - resultcode = rstmsg->resultcode.data; - if (resultcode != P80211ENUM_resultcode_success) { - netdev_err(wlandev->netdev, - "%s()->xxxdl_state msg indicates failure, w/ resultcode=%d, aborting download.\n", - __func__, resultcode); - result = 1; - goto free_result; - } - -free_result: - kfree(rstmsg); - kfree(rwrmsg); - return result; -} - -static int validate_identity(void) -{ - int i; - int result = 1; - int trump = 0; - - pr_debug("NIC ID: %#x v%d.%d.%d\n", - nicid.id, nicid.major, nicid.minor, nicid.variant); - pr_debug("MFI ID: %#x v%d %d->%d\n", - rfid.id, rfid.variant, rfid.bottom, rfid.top); - pr_debug("CFI ID: %#x v%d %d->%d\n", - macid.id, macid.variant, macid.bottom, macid.top); - pr_debug("PRI ID: %#x v%d %d->%d\n", - priid.id, priid.variant, priid.bottom, priid.top); - - for (i = 0; i < ns3info; i++) { - switch (s3info[i].type) { - case 1: - pr_debug("Version: ID %#x %d.%d.%d\n", - s3info[i].info.version.id, - s3info[i].info.version.major, - s3info[i].info.version.minor, - s3info[i].info.version.variant); - break; - case 2: - pr_debug("Compat: Role %#x Id %#x v%d %d->%d\n", - s3info[i].info.compat.role, - s3info[i].info.compat.id, - s3info[i].info.compat.variant, - s3info[i].info.compat.bottom, - s3info[i].info.compat.top); - - /* MAC compat range */ - if ((s3info[i].info.compat.role == 1) && - (s3info[i].info.compat.id == 2)) { - if (s3info[i].info.compat.variant != - macid.variant) { - result = 2; - } - } - - /* PRI compat range */ - if ((s3info[i].info.compat.role == 1) && - (s3info[i].info.compat.id == 3)) { - if ((s3info[i].info.compat.bottom > - priid.top) || - (s3info[i].info.compat.top < - priid.bottom)) { - result = 3; - } - } - /* SEC compat range */ - if ((s3info[i].info.compat.role == 1) && - (s3info[i].info.compat.id == 4)) { - /* FIXME: isn't something missing here? */ - } - - break; - case 3: - pr_debug("Seq: %#x\n", s3info[i].info.buildseq); - - break; - case 4: - pr_debug("Platform: ID %#x %d.%d.%d\n", - s3info[i].info.version.id, - s3info[i].info.version.major, - s3info[i].info.version.minor, - s3info[i].info.version.variant); - - if (nicid.id != s3info[i].info.version.id) - continue; - if (nicid.major != s3info[i].info.version.major) - continue; - if (nicid.minor != s3info[i].info.version.minor) - continue; - if ((nicid.variant != s3info[i].info.version.variant) && - (nicid.id != 0x8008)) - continue; - - trump = 1; - break; - case 0x8001: - pr_debug("name inforec len %d\n", s3info[i].len); - - break; - default: - pr_debug("Unknown inforec type %d\n", s3info[i].type); - } - } - /* walk through */ - - if (trump && (result != 2)) - result = 0; - return result; -} diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c deleted file mode 100644 index d5737166564e..000000000000 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ /dev/null @@ -1,1315 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) -/* - * - * Management request handler functions. - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * The functions in this file handle management requests sent from - * user mode. - * - * Most of these functions have two separate blocks of code that are - * conditional on whether this is a station or an AP. This is used - * to separate out the STA and AP responses to these management primitives. - * It's a choice (good, bad, indifferent?) to have the code in the same - * place so it's clear that the same primitive is implemented in both - * cases but has different behavior. - * - * -------------------------------------------------------------------- - */ - -#include <linux/if_arp.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/wait.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/wireless.h> -#include <linux/netdevice.h> -#include <linux/delay.h> -#include <linux/io.h> -#include <asm/byteorder.h> -#include <linux/random.h> -#include <linux/usb.h> -#include <linux/bitops.h> - -#include "p80211types.h" -#include "p80211hdr.h" -#include "p80211mgmt.h" -#include "p80211conv.h" -#include "p80211msg.h" -#include "p80211netdev.h" -#include "p80211metadef.h" -#include "p80211metastruct.h" -#include "hfa384x.h" -#include "prism2mgmt.h" - -/* Converts 802.11 format rate specifications to prism2 */ -static inline u16 p80211rate_to_p2bit(u32 rate) -{ - switch (rate & ~BIT(7)) { - case 2: - return BIT(0); - case 4: - return BIT(1); - case 11: - return BIT(2); - case 22: - return BIT(3); - default: - return 0; - } -} - -/*---------------------------------------------------------------- - * prism2mgmt_scan - * - * Initiate a scan for BSSs. - * - * This function corresponds to MLME-scan.request and part of - * MLME-scan.confirm. As far as I can tell in the standard, there - * are no restrictions on when a scan.request may be issued. We have - * to handle in whatever state the driver/MAC happen to be. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - * interrupt - *---------------------------------------------------------------- - */ -int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp) -{ - int result = 0; - struct hfa384x *hw = wlandev->priv; - struct p80211msg_dot11req_scan *msg = msgp; - u16 roamingmode, word; - int i, timeout; - int istmpenable = 0; - - struct hfa384x_host_scan_request_data scanreq; - - /* gatekeeper check */ - if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, - hw->ident_sta_fw.minor, - hw->ident_sta_fw.variant) < - HFA384x_FIRMWARE_VERSION(1, 3, 2)) { - netdev_err(wlandev->netdev, - "HostScan not supported with current firmware (<1.3.2).\n"); - result = 1; - msg->resultcode.data = P80211ENUM_resultcode_not_supported; - goto exit; - } - - memset(&scanreq, 0, sizeof(scanreq)); - - /* save current roaming mode */ - result = hfa384x_drvr_getconfig16(hw, - HFA384x_RID_CNFROAMINGMODE, - &roamingmode); - if (result) { - netdev_err(wlandev->netdev, - "getconfig(ROAMMODE) failed. result=%d\n", result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - - /* drop into mode 3 for the scan */ - result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFROAMINGMODE, - HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); - if (result) { - netdev_err(wlandev->netdev, - "setconfig(ROAMINGMODE) failed. result=%d\n", - result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - - /* active or passive? */ - if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, - hw->ident_sta_fw.minor, - hw->ident_sta_fw.variant) > - HFA384x_FIRMWARE_VERSION(1, 5, 0)) { - if (msg->scantype.data != P80211ENUM_scantype_active) - word = msg->maxchanneltime.data; - else - word = 0; - - result = - hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPASSIVESCANCTRL, - word); - if (result) { - netdev_warn(wlandev->netdev, - "Passive scan not supported with current firmware. (<1.5.1)\n"); - } - } - - /* set up the txrate to be 2MBPS. Should be fastest basicrate... */ - word = HFA384x_RATEBIT_2; - scanreq.tx_rate = cpu_to_le16(word); - - /* set up the channel list */ - word = 0; - for (i = 0; i < msg->channellist.data.len; i++) { - u8 channel = msg->channellist.data.data[i]; - - if (channel > 14) - continue; - /* channel 1 is BIT 0 ... channel 14 is BIT 13 */ - word |= (1 << (channel - 1)); - } - scanreq.channel_list = cpu_to_le16(word); - - /* set up the ssid, if present. */ - scanreq.ssid.len = cpu_to_le16(msg->ssid.data.len); - memcpy(scanreq.ssid.data, msg->ssid.data.data, msg->ssid.data.len); - - /* Enable the MAC port if it's not already enabled */ - result = hfa384x_drvr_getconfig16(hw, HFA384x_RID_PORTSTATUS, &word); - if (result) { - netdev_err(wlandev->netdev, - "getconfig(PORTSTATUS) failed. result=%d\n", result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - if (word == HFA384x_PORTSTATUS_DISABLED) { - __le16 wordbuf[17]; - - result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFROAMINGMODE, - HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); - if (result) { - netdev_err(wlandev->netdev, - "setconfig(ROAMINGMODE) failed. result=%d\n", - result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - /* Construct a bogus SSID and assign it to OwnSSID and - * DesiredSSID - */ - wordbuf[0] = cpu_to_le16(WLAN_SSID_MAXLEN); - get_random_bytes(&wordbuf[1], WLAN_SSID_MAXLEN); - result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID, - wordbuf, - HFA384x_RID_CNFOWNSSID_LEN); - if (result) { - netdev_err(wlandev->netdev, "Failed to set OwnSSID.\n"); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, - wordbuf, - HFA384x_RID_CNFDESIREDSSID_LEN); - if (result) { - netdev_err(wlandev->netdev, - "Failed to set DesiredSSID.\n"); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - /* bsstype */ - result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - HFA384x_PORTTYPE_IBSS); - if (result) { - netdev_err(wlandev->netdev, - "Failed to set CNFPORTTYPE.\n"); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - /* ibss options */ - result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CREATEIBSS, - HFA384x_CREATEIBSS_JOINCREATEIBSS); - if (result) { - netdev_err(wlandev->netdev, - "Failed to set CREATEIBSS.\n"); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - result = hfa384x_drvr_enable(hw, 0); - if (result) { - netdev_err(wlandev->netdev, - "drvr_enable(0) failed. result=%d\n", - result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - istmpenable = 1; - } - - /* Figure out our timeout first Kus, then HZ */ - timeout = msg->channellist.data.len * msg->maxchanneltime.data; - timeout = (timeout * HZ) / 1000; - - /* Issue the scan request */ - hw->scanflag = 0; - - result = hfa384x_drvr_setconfig(hw, - HFA384x_RID_HOSTSCAN, &scanreq, - sizeof(scanreq)); - if (result) { - netdev_err(wlandev->netdev, - "setconfig(SCANREQUEST) failed. result=%d\n", - result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - - /* sleep until info frame arrives */ - wait_event_interruptible_timeout(hw->cmdq, hw->scanflag, timeout); - - msg->numbss.status = P80211ENUM_msgitem_status_data_ok; - if (hw->scanflag == -1) - hw->scanflag = 0; - - msg->numbss.data = hw->scanflag; - - hw->scanflag = 0; - - /* Disable port if we temporarily enabled it. */ - if (istmpenable) { - result = hfa384x_drvr_disable(hw, 0); - if (result) { - netdev_err(wlandev->netdev, - "drvr_disable(0) failed. result=%d\n", - result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - } - - /* restore original roaming mode */ - result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFROAMINGMODE, - roamingmode); - if (result) { - netdev_err(wlandev->netdev, - "setconfig(ROAMMODE) failed. result=%d\n", result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - goto exit; - } - - result = 0; - msg->resultcode.data = P80211ENUM_resultcode_success; - -exit: - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - - return result; -} - -/*---------------------------------------------------------------- - * prism2mgmt_scan_results - * - * Retrieve the BSS description for one of the BSSs identified in - * a scan. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - * interrupt - *---------------------------------------------------------------- - */ -int prism2mgmt_scan_results(struct wlandevice *wlandev, void *msgp) -{ - int result = 0; - struct p80211msg_dot11req_scan_results *req; - struct hfa384x *hw = wlandev->priv; - struct hfa384x_hscan_result_sub *item = NULL; - - int count; - - req = msgp; - - req->resultcode.status = P80211ENUM_msgitem_status_data_ok; - - if (!hw->scanresults) { - netdev_err(wlandev->netdev, - "dot11req_scan_results can only be used after a successful dot11req_scan.\n"); - result = 2; - req->resultcode.data = P80211ENUM_resultcode_invalid_parameters; - goto exit; - } - - count = (hw->scanresults->framelen - 3) / 32; - if (count > HFA384x_SCANRESULT_MAX) - count = HFA384x_SCANRESULT_MAX; - - if (req->bssindex.data >= count) { - netdev_dbg(wlandev->netdev, - "requested index (%d) out of range (%d)\n", - req->bssindex.data, count); - result = 2; - req->resultcode.data = P80211ENUM_resultcode_invalid_parameters; - goto exit; - } - - item = &hw->scanresults->info.hscanresult.result[req->bssindex.data]; - /* signal and noise */ - req->signal.status = P80211ENUM_msgitem_status_data_ok; - req->noise.status = P80211ENUM_msgitem_status_data_ok; - req->signal.data = le16_to_cpu(item->sl); - req->noise.data = le16_to_cpu(item->anl); - - /* BSSID */ - req->bssid.status = P80211ENUM_msgitem_status_data_ok; - req->bssid.data.len = WLAN_BSSID_LEN; - memcpy(req->bssid.data.data, item->bssid, WLAN_BSSID_LEN); - - /* SSID */ - req->ssid.status = P80211ENUM_msgitem_status_data_ok; - req->ssid.data.len = le16_to_cpu(item->ssid.len); - req->ssid.data.len = min_t(u16, req->ssid.data.len, WLAN_SSID_MAXLEN); - memcpy(req->ssid.data.data, item->ssid.data, req->ssid.data.len); - - /* supported rates */ - for (count = 0; count < 10; count++) - if (item->supprates[count] == 0) - break; - - for (int i = 0; i < 8; i++) { - if (count > i && - DOT11_RATE5_ISBASIC_GET(item->supprates[i])) { - req->basicrate[i].data = item->supprates[i]; - req->basicrate[i].status = - P80211ENUM_msgitem_status_data_ok; - } - } - - for (int i = 0; i < 8; i++) { - if (count > i) { - req->supprate[i].data = item->supprates[i]; - req->supprate[i].status = - P80211ENUM_msgitem_status_data_ok; - } - } - - /* beacon period */ - req->beaconperiod.status = P80211ENUM_msgitem_status_data_ok; - req->beaconperiod.data = le16_to_cpu(item->bcnint); - - /* timestamps */ - req->timestamp.status = P80211ENUM_msgitem_status_data_ok; - req->timestamp.data = jiffies; - req->localtime.status = P80211ENUM_msgitem_status_data_ok; - req->localtime.data = jiffies; - - /* atim window */ - req->ibssatimwindow.status = P80211ENUM_msgitem_status_data_ok; - req->ibssatimwindow.data = le16_to_cpu(item->atim); - - /* Channel */ - req->dschannel.status = P80211ENUM_msgitem_status_data_ok; - req->dschannel.data = le16_to_cpu(item->chid); - - /* capinfo bits */ - count = le16_to_cpu(item->capinfo); - req->capinfo.status = P80211ENUM_msgitem_status_data_ok; - req->capinfo.data = count; - - /* privacy flag */ - req->privacy.status = P80211ENUM_msgitem_status_data_ok; - req->privacy.data = WLAN_GET_MGMT_CAP_INFO_PRIVACY(count); - - /* cfpollable */ - req->cfpollable.status = P80211ENUM_msgitem_status_data_ok; - req->cfpollable.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLABLE(count); - - /* cfpollreq */ - req->cfpollreq.status = P80211ENUM_msgitem_status_data_ok; - req->cfpollreq.data = WLAN_GET_MGMT_CAP_INFO_CFPOLLREQ(count); - - /* bsstype */ - req->bsstype.status = P80211ENUM_msgitem_status_data_ok; - req->bsstype.data = (WLAN_GET_MGMT_CAP_INFO_ESS(count)) ? - P80211ENUM_bsstype_infrastructure : P80211ENUM_bsstype_independent; - - result = 0; - req->resultcode.data = P80211ENUM_resultcode_success; - -exit: - return result; -} - -/*---------------------------------------------------------------- - * prism2mgmt_start - * - * Start a BSS. Any station can do this for IBSS, only AP for ESS. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - * interrupt - *---------------------------------------------------------------- - */ -int prism2mgmt_start(struct wlandevice *wlandev, void *msgp) -{ - int result = 0; - struct hfa384x *hw = wlandev->priv; - struct p80211msg_dot11req_start *msg = msgp; - - struct p80211pstrd *pstr; - u8 bytebuf[80]; - struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *)bytebuf; - u16 word; - - wlandev->macmode = WLAN_MACMODE_NONE; - - /* Set the SSID */ - memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data)); - - /*** ADHOC IBSS ***/ - /* see if current f/w is less than 8c3 */ - if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, - hw->ident_sta_fw.minor, - hw->ident_sta_fw.variant) < - HFA384x_FIRMWARE_VERSION(0, 8, 3)) { - /* Ad-Hoc not quite supported on Prism2 */ - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - msg->resultcode.data = P80211ENUM_resultcode_not_supported; - goto done; - } - - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - - /*** STATION ***/ - /* Set the REQUIRED config items */ - /* SSID */ - pstr = (struct p80211pstrd *)&msg->ssid.data; - prism2mgmt_pstr2bytestr(p2bytestr, pstr); - result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFOWNSSID, - bytebuf, HFA384x_RID_CNFOWNSSID_LEN); - if (result) { - netdev_err(wlandev->netdev, "Failed to set CnfOwnSSID\n"); - goto failed; - } - result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, - bytebuf, - HFA384x_RID_CNFDESIREDSSID_LEN); - if (result) { - netdev_err(wlandev->netdev, "Failed to set CnfDesiredSSID\n"); - goto failed; - } - - /* bsstype - we use the default in the ap firmware */ - /* IBSS port */ - hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, 0); - - /* beacon period */ - word = msg->beaconperiod.data; - result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAPBCNINT, word); - if (result) { - netdev_err(wlandev->netdev, - "Failed to set beacon period=%d.\n", word); - goto failed; - } - - /* dschannel */ - word = msg->dschannel.data; - result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFOWNCHANNEL, word); - if (result) { - netdev_err(wlandev->netdev, - "Failed to set channel=%d.\n", word); - goto failed; - } - /* Basic rates */ - word = p80211rate_to_p2bit(msg->basicrate1.data); - if (msg->basicrate2.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->basicrate2.data); - - if (msg->basicrate3.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->basicrate3.data); - - if (msg->basicrate4.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->basicrate4.data); - - if (msg->basicrate5.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->basicrate5.data); - - if (msg->basicrate6.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->basicrate6.data); - - if (msg->basicrate7.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->basicrate7.data); - - if (msg->basicrate8.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->basicrate8.data); - - result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFBASICRATES, word); - if (result) { - netdev_err(wlandev->netdev, - "Failed to set basicrates=%d.\n", word); - goto failed; - } - - /* Operational rates (supprates and txratecontrol) */ - word = p80211rate_to_p2bit(msg->operationalrate1.data); - if (msg->operationalrate2.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->operationalrate2.data); - - if (msg->operationalrate3.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->operationalrate3.data); - - if (msg->operationalrate4.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->operationalrate4.data); - - if (msg->operationalrate5.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->operationalrate5.data); - - if (msg->operationalrate6.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->operationalrate6.data); - - if (msg->operationalrate7.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->operationalrate7.data); - - if (msg->operationalrate8.status == P80211ENUM_msgitem_status_data_ok) - word |= p80211rate_to_p2bit(msg->operationalrate8.data); - - result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFSUPPRATES, word); - if (result) { - netdev_err(wlandev->netdev, - "Failed to set supprates=%d.\n", word); - goto failed; - } - - result = hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, word); - if (result) { - netdev_err(wlandev->netdev, "Failed to set txrates=%d.\n", - word); - goto failed; - } - - /* Set the macmode so the frame setup code knows what to do */ - if (msg->bsstype.data == P80211ENUM_bsstype_independent) { - wlandev->macmode = WLAN_MACMODE_IBSS_STA; - /* lets extend the data length a bit */ - hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, 2304); - } - - /* Enable the Port */ - result = hfa384x_drvr_enable(hw, 0); - if (result) { - netdev_err(wlandev->netdev, - "Enable macport failed, result=%d.\n", result); - goto failed; - } - - msg->resultcode.data = P80211ENUM_resultcode_success; - - goto done; -failed: - netdev_dbg(wlandev->netdev, - "Failed to set a config option, result=%d\n", result); - msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; - -done: - return 0; -} - -/*---------------------------------------------------------------- - * prism2mgmt_readpda - * - * Collect the PDA data and put it in the message. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - *---------------------------------------------------------------- - */ -int prism2mgmt_readpda(struct wlandevice *wlandev, void *msgp) -{ - struct hfa384x *hw = wlandev->priv; - struct p80211msg_p2req_readpda *msg = msgp; - int result; - - /* We only support collecting the PDA when in the FWLOAD - * state. - */ - if (wlandev->msdstate != WLAN_MSD_FWLOAD) { - netdev_err(wlandev->netdev, - "PDA may only be read in the fwload state.\n"); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - } else { - /* Call drvr_readpda(), it handles the auxport enable - * and validating the returned PDA. - */ - result = hfa384x_drvr_readpda(hw, - msg->pda.data, - HFA384x_PDA_LEN_MAX); - if (result) { - netdev_err(wlandev->netdev, - "hfa384x_drvr_readpda() failed, result=%d\n", - result); - - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - msg->resultcode.status = - P80211ENUM_msgitem_status_data_ok; - return 0; - } - msg->pda.status = P80211ENUM_msgitem_status_data_ok; - msg->resultcode.data = P80211ENUM_resultcode_success; - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - } - - return 0; -} - -/*---------------------------------------------------------------- - * prism2mgmt_ramdl_state - * - * Establishes the beginning/end of a card RAM download session. - * - * It is expected that the ramdl_write() function will be called - * one or more times between the 'enable' and 'disable' calls to - * this function. - * - * Note: This function should not be called when a mac comm port - * is active. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - *---------------------------------------------------------------- - */ -int prism2mgmt_ramdl_state(struct wlandevice *wlandev, void *msgp) -{ - struct hfa384x *hw = wlandev->priv; - struct p80211msg_p2req_ramdl_state *msg = msgp; - - if (wlandev->msdstate != WLAN_MSD_FWLOAD) { - netdev_err(wlandev->netdev, - "ramdl_state(): may only be called in the fwload state.\n"); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - return 0; - } - - /* - ** Note: Interrupts are locked out if this is an AP and are NOT - ** locked out if this is a station. - */ - - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - if (msg->enable.data == P80211ENUM_truth_true) { - if (hfa384x_drvr_ramdl_enable(hw, msg->exeaddr.data)) { - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - } else { - msg->resultcode.data = P80211ENUM_resultcode_success; - } - } else { - hfa384x_drvr_ramdl_disable(hw); - msg->resultcode.data = P80211ENUM_resultcode_success; - } - - return 0; -} - -/*---------------------------------------------------------------- - * prism2mgmt_ramdl_write - * - * Writes a buffer to the card RAM using the download state. This - * is for writing code to card RAM. To just read or write raw data - * use the aux functions. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - *---------------------------------------------------------------- - */ -int prism2mgmt_ramdl_write(struct wlandevice *wlandev, void *msgp) -{ - struct hfa384x *hw = wlandev->priv; - struct p80211msg_p2req_ramdl_write *msg = msgp; - u32 addr; - u32 len; - u8 *buf; - - if (wlandev->msdstate != WLAN_MSD_FWLOAD) { - netdev_err(wlandev->netdev, - "ramdl_write(): may only be called in the fwload state.\n"); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - return 0; - } - - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - /* first validate the length */ - if (msg->len.data > sizeof(msg->data.data)) { - msg->resultcode.status = - P80211ENUM_resultcode_invalid_parameters; - return 0; - } - /* call the hfa384x function to do the write */ - addr = msg->addr.data; - len = msg->len.data; - buf = msg->data.data; - if (hfa384x_drvr_ramdl_write(hw, addr, buf, len)) - msg->resultcode.data = P80211ENUM_resultcode_refused; - - msg->resultcode.data = P80211ENUM_resultcode_success; - - return 0; -} - -/*---------------------------------------------------------------- - * prism2mgmt_flashdl_state - * - * Establishes the beginning/end of a card Flash download session. - * - * It is expected that the flashdl_write() function will be called - * one or more times between the 'enable' and 'disable' calls to - * this function. - * - * Note: This function should not be called when a mac comm port - * is active. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - *---------------------------------------------------------------- - */ -int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp) -{ - int result = 0; - struct hfa384x *hw = wlandev->priv; - struct p80211msg_p2req_flashdl_state *msg = msgp; - - if (wlandev->msdstate != WLAN_MSD_FWLOAD) { - netdev_err(wlandev->netdev, - "flashdl_state(): may only be called in the fwload state.\n"); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - return 0; - } - - /* - ** Note: Interrupts are locked out if this is an AP and are NOT - ** locked out if this is a station. - */ - - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - if (msg->enable.data == P80211ENUM_truth_true) { - if (hfa384x_drvr_flashdl_enable(hw)) { - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - } else { - msg->resultcode.data = P80211ENUM_resultcode_success; - } - } else { - hfa384x_drvr_flashdl_disable(hw); - msg->resultcode.data = P80211ENUM_resultcode_success; - /* NOTE: At this point, the MAC is in the post-reset - * state and the driver is in the fwload state. - * We need to get the MAC back into the fwload - * state. To do this, we set the nsdstate to HWPRESENT - * and then call the ifstate function to redo everything - * that got us into the fwload state. - */ - wlandev->msdstate = WLAN_MSD_HWPRESENT; - result = prism2sta_ifstate(wlandev, P80211ENUM_ifstate_fwload); - if (result != P80211ENUM_resultcode_success) { - netdev_err(wlandev->netdev, - "prism2sta_ifstate(fwload) failed, P80211ENUM_resultcode=%d\n", - result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - result = -1; - } - } - - return result; -} - -/*---------------------------------------------------------------- - * prism2mgmt_flashdl_write - * - * - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - *---------------------------------------------------------------- - */ -int prism2mgmt_flashdl_write(struct wlandevice *wlandev, void *msgp) -{ - struct hfa384x *hw = wlandev->priv; - struct p80211msg_p2req_flashdl_write *msg = msgp; - u32 addr; - u32 len; - u8 *buf; - - if (wlandev->msdstate != WLAN_MSD_FWLOAD) { - netdev_err(wlandev->netdev, - "flashdl_write(): may only be called in the fwload state.\n"); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - return 0; - } - - /* - ** Note: Interrupts are locked out if this is an AP and are NOT - ** locked out if this is a station. - */ - - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - /* first validate the length */ - if (msg->len.data > sizeof(msg->data.data)) { - msg->resultcode.status = - P80211ENUM_resultcode_invalid_parameters; - return 0; - } - /* call the hfa384x function to do the write */ - addr = msg->addr.data; - len = msg->len.data; - buf = msg->data.data; - if (hfa384x_drvr_flashdl_write(hw, addr, buf, len)) - msg->resultcode.data = P80211ENUM_resultcode_refused; - - msg->resultcode.data = P80211ENUM_resultcode_success; - - return 0; -} - -/*---------------------------------------------------------------- - * prism2mgmt_autojoin - * - * Associate with an ESS. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - * interrupt - *---------------------------------------------------------------- - */ -int prism2mgmt_autojoin(struct wlandevice *wlandev, void *msgp) -{ - struct hfa384x *hw = wlandev->priv; - int result = 0; - u16 reg; - u16 port_type; - struct p80211msg_lnxreq_autojoin *msg = msgp; - struct p80211pstrd *pstr; - u8 bytebuf[256]; - struct hfa384x_bytestr *p2bytestr = (struct hfa384x_bytestr *)bytebuf; - - wlandev->macmode = WLAN_MACMODE_NONE; - - /* Set the SSID */ - memcpy(&wlandev->ssid, &msg->ssid.data, sizeof(msg->ssid.data)); - - /* Disable the Port */ - hfa384x_drvr_disable(hw, 0); - - /*** STATION ***/ - /* Set the TxRates */ - hfa384x_drvr_setconfig16(hw, HFA384x_RID_TXRATECNTL, 0x000f); - - /* Set the auth type */ - if (msg->authtype.data == P80211ENUM_authalg_sharedkey) - reg = HFA384x_CNFAUTHENTICATION_SHAREDKEY; - else - reg = HFA384x_CNFAUTHENTICATION_OPENSYSTEM; - - hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFAUTHENTICATION, reg); - - /* Set the ssid */ - memset(bytebuf, 0, 256); - pstr = (struct p80211pstrd *)&msg->ssid.data; - prism2mgmt_pstr2bytestr(p2bytestr, pstr); - result = hfa384x_drvr_setconfig(hw, HFA384x_RID_CNFDESIREDSSID, - bytebuf, - HFA384x_RID_CNFDESIREDSSID_LEN); - port_type = HFA384x_PORTTYPE_BSS; - /* Set the PortType */ - hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFPORTTYPE, port_type); - - /* Enable the Port */ - hfa384x_drvr_enable(hw, 0); - - /* Set the resultcode */ - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - msg->resultcode.data = P80211ENUM_resultcode_success; - - return result; -} - -/*---------------------------------------------------------------- - * prism2mgmt_wlansniff - * - * Start or stop sniffing. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - * interrupt - *---------------------------------------------------------------- - */ -int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp) -{ - int result = 0; - struct p80211msg_lnxreq_wlansniff *msg = msgp; - - struct hfa384x *hw = wlandev->priv; - u16 word; - - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - switch (msg->enable.data) { - case P80211ENUM_truth_false: - /* Confirm that we're in monitor mode */ - if (wlandev->netdev->type == ARPHRD_ETHER) { - msg->resultcode.data = - P80211ENUM_resultcode_invalid_parameters; - return 0; - } - /* Disable monitor mode */ - result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_DISABLE); - if (result) { - netdev_dbg(wlandev->netdev, - "failed to disable monitor mode, result=%d\n", - result); - goto failed; - } - /* Disable port 0 */ - result = hfa384x_drvr_disable(hw, 0); - if (result) { - netdev_dbg - (wlandev->netdev, - "failed to disable port 0 after sniffing, result=%d\n", - result); - goto failed; - } - /* Clear the driver state */ - wlandev->netdev->type = ARPHRD_ETHER; - - /* Restore the wepflags */ - result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFWEPFLAGS, - hw->presniff_wepflags); - if (result) { - netdev_dbg - (wlandev->netdev, - "failed to restore wepflags=0x%04x, result=%d\n", - hw->presniff_wepflags, result); - goto failed; - } - - /* Set the port to its prior type and enable (if necessary) */ - if (hw->presniff_port_type != 0) { - word = hw->presniff_port_type; - result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - word); - if (result) { - netdev_dbg - (wlandev->netdev, - "failed to restore porttype, result=%d\n", - result); - goto failed; - } - - /* Enable the port */ - result = hfa384x_drvr_enable(hw, 0); - if (result) { - netdev_dbg(wlandev->netdev, - "failed to enable port to presniff setting, result=%d\n", - result); - goto failed; - } - } else { - result = hfa384x_drvr_disable(hw, 0); - } - - netdev_info(wlandev->netdev, "monitor mode disabled\n"); - msg->resultcode.data = P80211ENUM_resultcode_success; - return 0; - case P80211ENUM_truth_true: - /* Disable the port (if enabled), only check Port 0 */ - if (hw->port_enabled[0]) { - if (wlandev->netdev->type == ARPHRD_ETHER) { - /* Save macport 0 state */ - result = hfa384x_drvr_getconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - &hw->presniff_port_type); - if (result) { - netdev_dbg - (wlandev->netdev, - "failed to read porttype, result=%d\n", - result); - goto failed; - } - /* Save the wepflags state */ - result = hfa384x_drvr_getconfig16(hw, - HFA384x_RID_CNFWEPFLAGS, - &hw->presniff_wepflags); - if (result) { - netdev_dbg - (wlandev->netdev, - "failed to read wepflags, result=%d\n", - result); - goto failed; - } - hfa384x_drvr_stop(hw); - result = hfa384x_drvr_start(hw); - if (result) { - netdev_dbg(wlandev->netdev, - "failed to restart the card for sniffing, result=%d\n", - result); - goto failed; - } - } else { - /* Disable the port */ - result = hfa384x_drvr_disable(hw, 0); - if (result) { - netdev_dbg(wlandev->netdev, - "failed to enable port for sniffing, result=%d\n", - result); - goto failed; - } - } - } else { - hw->presniff_port_type = 0; - } - - /* Set the channel we wish to sniff */ - word = msg->channel.data; - result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFOWNCHANNEL, - word); - hw->sniff_channel = word; - - if (result) { - netdev_dbg(wlandev->netdev, - "failed to set channel %d, result=%d\n", - word, result); - goto failed; - } - - /* Now if we're already sniffing, we can skip the rest */ - if (wlandev->netdev->type != ARPHRD_ETHER) { - /* Set the port type to pIbss */ - word = HFA384x_PORTTYPE_PSUEDOIBSS; - result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFPORTTYPE, - word); - if (result) { - netdev_dbg - (wlandev->netdev, - "failed to set porttype %d, result=%d\n", - word, result); - goto failed; - } - if ((msg->keepwepflags.status == - P80211ENUM_msgitem_status_data_ok) && - (msg->keepwepflags.data != P80211ENUM_truth_true)) { - /* Set the wepflags for no decryption */ - word = HFA384x_WEPFLAGS_DISABLE_TXCRYPT | - HFA384x_WEPFLAGS_DISABLE_RXCRYPT; - result = - hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFWEPFLAGS, - word); - } - - if (result) { - netdev_dbg - (wlandev->netdev, - "failed to set wepflags=0x%04x, result=%d\n", - word, result); - goto failed; - } - } - - /* Do we want to strip the FCS in monitor mode? */ - if ((msg->stripfcs.status == - P80211ENUM_msgitem_status_data_ok) && - (msg->stripfcs.data == P80211ENUM_truth_true)) { - hw->sniff_fcs = 0; - } else { - hw->sniff_fcs = 1; - } - - /* Do we want to truncate the packets? */ - if (msg->packet_trunc.status == - P80211ENUM_msgitem_status_data_ok) { - hw->sniff_truncate = msg->packet_trunc.data; - } else { - hw->sniff_truncate = 0; - } - - /* Enable the port */ - result = hfa384x_drvr_enable(hw, 0); - if (result) { - netdev_dbg - (wlandev->netdev, - "failed to enable port for sniffing, result=%d\n", - result); - goto failed; - } - /* Enable monitor mode */ - result = hfa384x_cmd_monitor(hw, HFA384x_MONITOR_ENABLE); - if (result) { - netdev_dbg(wlandev->netdev, - "failed to enable monitor mode, result=%d\n", - result); - goto failed; - } - - if (wlandev->netdev->type == ARPHRD_ETHER) - netdev_info(wlandev->netdev, "monitor mode enabled\n"); - - /* Set the driver state */ - /* Do we want the prism2 header? */ - if ((msg->prismheader.status == - P80211ENUM_msgitem_status_data_ok) && - (msg->prismheader.data == P80211ENUM_truth_true)) { - hw->sniffhdr = 0; - wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; - } else if ((msg->wlanheader.status == - P80211ENUM_msgitem_status_data_ok) && - (msg->wlanheader.data == P80211ENUM_truth_true)) { - hw->sniffhdr = 1; - wlandev->netdev->type = ARPHRD_IEEE80211_PRISM; - } else { - wlandev->netdev->type = ARPHRD_IEEE80211; - } - - msg->resultcode.data = P80211ENUM_resultcode_success; - return 0; - default: - msg->resultcode.data = P80211ENUM_resultcode_invalid_parameters; - return 0; - } - -failed: - msg->resultcode.data = P80211ENUM_resultcode_refused; - return 0; -} diff --git a/drivers/staging/wlan-ng/prism2mgmt.h b/drivers/staging/wlan-ng/prism2mgmt.h deleted file mode 100644 index 17222516e85e..000000000000 --- a/drivers/staging/wlan-ng/prism2mgmt.h +++ /dev/null @@ -1,89 +0,0 @@ -/* SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) */ -/* - * - * Declares the mgmt command handler functions - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file contains the constants and data structures for interaction - * with the hfa384x Wireless LAN (WLAN) Media Access Controller (MAC). - * The hfa384x is a portion of the Harris PRISM(tm) WLAN chipset. - * - * [Implementation and usage notes] - * - * [References] - * CW10 Programmer's Manual v1.5 - * IEEE 802.11 D10.0 - * - * -------------------------------------------------------------------- - */ - -#ifndef _PRISM2MGMT_H -#define _PRISM2MGMT_H - -extern int prism2_reset_holdtime; -extern int prism2_reset_settletime; - -u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate); - -void prism2sta_ev_info(struct wlandevice *wlandev, struct hfa384x_inf_frame *inf); -void prism2sta_ev_tx(struct wlandevice *wlandev, u16 status); -void prism2sta_ev_alloc(struct wlandevice *wlandev); - -int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_scan(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_scan_results(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_start(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_wlansniff(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_readpda(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_ramdl_state(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_ramdl_write(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_flashdl_state(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_flashdl_write(struct wlandevice *wlandev, void *msgp); -int prism2mgmt_autojoin(struct wlandevice *wlandev, void *msgp); - -/*--------------------------------------------------------------- - * conversion functions going between wlan message data types and - * Prism2 data types - *--------------------------------------------------------------- - */ - -/* byte area conversion functions*/ -void prism2mgmt_bytearea2pstr(u8 *bytearea, struct p80211pstrd *pstr, int len); - -/* byte string conversion functions*/ -void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr, - struct p80211pstrd *pstr); -void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr, - struct p80211pstrd *pstr); - -void prism2sta_processing_defer(struct work_struct *data); - -void prism2sta_commsqual_defer(struct work_struct *data); -void prism2sta_commsqual_timer(struct timer_list *t); - -/* Interface callback functions, passing data back up to the cfg80211 layer */ -void prism2_connect_result(struct wlandevice *wlandev, u8 failed); -void prism2_disconnected(struct wlandevice *wlandev); -void prism2_roamed(struct wlandevice *wlandev); - -#endif diff --git a/drivers/staging/wlan-ng/prism2mib.c b/drivers/staging/wlan-ng/prism2mib.c deleted file mode 100644 index 4346b90c1a77..000000000000 --- a/drivers/staging/wlan-ng/prism2mib.c +++ /dev/null @@ -1,742 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) -/* - * - * Management request for mibset/mibget - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * The functions in this file handle the mibset/mibget management - * functions. - * - * -------------------------------------------------------------------- - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/wireless.h> -#include <linux/netdevice.h> -#include <linux/io.h> -#include <linux/delay.h> -#include <asm/byteorder.h> -#include <linux/usb.h> -#include <linux/bitops.h> - -#include "p80211types.h" -#include "p80211hdr.h" -#include "p80211mgmt.h" -#include "p80211conv.h" -#include "p80211msg.h" -#include "p80211netdev.h" -#include "p80211metadef.h" -#include "p80211metastruct.h" -#include "hfa384x.h" -#include "prism2mgmt.h" - -#define MIB_TMP_MAXLEN 200 /* Max length of RID record (in bytes). */ - -#define F_STA 0x1 /* MIB is supported on stations. */ -#define F_READ 0x2 /* MIB may be read. */ -#define F_WRITE 0x4 /* MIB may be written. */ - -struct mibrec { - u32 did; - u16 flag; - u16 parm1; - u16 parm2; - u16 parm3; - int (*func)(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, void *data); -}; - -static int prism2mib_bytearea2pstr(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data); - -static int prism2mib_uint32(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, void *data); - -static int prism2mib_flag(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, void *data); - -static int prism2mib_wepdefaultkey(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data); - -static int prism2mib_privacyinvoked(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data); - -static int -prism2mib_fragmentationthreshold(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data); - -static int prism2mib_priv(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, void *data); - -static struct mibrec mibtab[] = { - /* dot11smt MIB's */ - {didmib_dot11smt_wepdefaultkeystable_key(1), - F_STA | F_WRITE, - HFA384x_RID_CNFWEPDEFAULTKEY0, 0, 0, - prism2mib_wepdefaultkey}, - {didmib_dot11smt_wepdefaultkeystable_key(2), - F_STA | F_WRITE, - HFA384x_RID_CNFWEPDEFAULTKEY1, 0, 0, - prism2mib_wepdefaultkey}, - {didmib_dot11smt_wepdefaultkeystable_key(3), - F_STA | F_WRITE, - HFA384x_RID_CNFWEPDEFAULTKEY2, 0, 0, - prism2mib_wepdefaultkey}, - {didmib_dot11smt_wepdefaultkeystable_key(4), - F_STA | F_WRITE, - HFA384x_RID_CNFWEPDEFAULTKEY3, 0, 0, - prism2mib_wepdefaultkey}, - {DIDMIB_DOT11SMT_PRIVACYTABLE_PRIVACYINVOKED, - F_STA | F_READ | F_WRITE, - HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_PRIVINVOKED, 0, - prism2mib_privacyinvoked}, - {DIDMIB_DOT11SMT_PRIVACYTABLE_WEPDEFAULTKEYID, - F_STA | F_READ | F_WRITE, - HFA384x_RID_CNFWEPDEFAULTKEYID, 0, 0, - prism2mib_uint32}, - {DIDMIB_DOT11SMT_PRIVACYTABLE_EXCLUDEUNENCRYPTED, - F_STA | F_READ | F_WRITE, - HFA384x_RID_CNFWEPFLAGS, HFA384x_WEPFLAGS_EXCLUDE, 0, - prism2mib_flag}, - - /* dot11mac MIB's */ - - {DIDMIB_DOT11MAC_OPERATIONTABLE_MACADDRESS, - F_STA | F_READ | F_WRITE, - HFA384x_RID_CNFOWNMACADDR, HFA384x_RID_CNFOWNMACADDR_LEN, 0, - prism2mib_bytearea2pstr}, - {DIDMIB_DOT11MAC_OPERATIONTABLE_RTSTHRESHOLD, - F_STA | F_READ | F_WRITE, - HFA384x_RID_RTSTHRESH, 0, 0, - prism2mib_uint32}, - {DIDMIB_DOT11MAC_OPERATIONTABLE_SHORTRETRYLIMIT, - F_STA | F_READ, - HFA384x_RID_SHORTRETRYLIMIT, 0, 0, - prism2mib_uint32}, - {DIDMIB_DOT11MAC_OPERATIONTABLE_LONGRETRYLIMIT, - F_STA | F_READ, - HFA384x_RID_LONGRETRYLIMIT, 0, 0, - prism2mib_uint32}, - {DIDMIB_DOT11MAC_OPERATIONTABLE_FRAGMENTATIONTHRESHOLD, - F_STA | F_READ | F_WRITE, - HFA384x_RID_FRAGTHRESH, 0, 0, - prism2mib_fragmentationthreshold}, - {DIDMIB_DOT11MAC_OPERATIONTABLE_MAXTRANSMITMSDULIFETIME, - F_STA | F_READ, - HFA384x_RID_MAXTXLIFETIME, 0, 0, - prism2mib_uint32}, - - /* dot11phy MIB's */ - - {DIDMIB_DOT11PHY_DSSSTABLE_CURRENTCHANNEL, - F_STA | F_READ, - HFA384x_RID_CURRENTCHANNEL, 0, 0, - prism2mib_uint32}, - {DIDMIB_DOT11PHY_TXPOWERTABLE_CURRENTTXPOWERLEVEL, - F_STA | F_READ | F_WRITE, - HFA384x_RID_TXPOWERMAX, 0, 0, - prism2mib_uint32}, - - /* p2Static MIB's */ - - {DIDMIB_P2_STATIC_CNFPORTTYPE, - F_STA | F_READ | F_WRITE, - HFA384x_RID_CNFPORTTYPE, 0, 0, - prism2mib_uint32}, - - /* p2MAC MIB's */ - - {DIDMIB_P2_MAC_CURRENTTXRATE, - F_STA | F_READ, - HFA384x_RID_CURRENTTXRATE, 0, 0, - prism2mib_uint32}, - - /* And finally, lnx mibs */ - {DIDMIB_LNX_CONFIGTABLE_RSNAIE, - F_STA | F_READ | F_WRITE, - HFA384x_RID_CNFWPADATA, 0, 0, - prism2mib_priv}, - {0, 0, 0, 0, 0, NULL} -}; - -/* - * prism2mgmt_mibset_mibget - * - * Set the value of a mib item. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * 0 success and done - * <0 success, but we're waiting for something to finish. - * >0 an error occurred while handling the message. - * Side effects: - * - * Call context: - * process thread (usually) - * interrupt - */ - -int prism2mgmt_mibset_mibget(struct wlandevice *wlandev, void *msgp) -{ - struct hfa384x *hw = wlandev->priv; - int result, isget; - struct mibrec *mib; - - u16 which; - - struct p80211msg_dot11req_mibset *msg = msgp; - struct p80211itemd *mibitem; - - msg->resultcode.status = P80211ENUM_msgitem_status_data_ok; - msg->resultcode.data = P80211ENUM_resultcode_success; - - /* - ** Determine if this is an Access Point or a station. - */ - - which = F_STA; - - /* - ** Find the MIB in the MIB table. Note that a MIB may be in the - ** table twice...once for an AP and once for a station. Make sure - ** to get the correct one. Note that DID=0 marks the end of the - ** MIB table. - */ - - mibitem = (struct p80211itemd *)msg->mibattribute.data; - - for (mib = mibtab; mib->did != 0; mib++) - if (mib->did == mibitem->did && (mib->flag & which)) - break; - - if (mib->did == 0) { - msg->resultcode.data = P80211ENUM_resultcode_not_supported; - goto done; - } - - /* - ** Determine if this is a "mibget" or a "mibset". If this is a - ** "mibget", then make sure that the MIB may be read. Otherwise, - ** this is a "mibset" so make sure that the MIB may be written. - */ - - isget = (msg->msgcode == DIDMSG_DOT11REQ_MIBGET); - - if (isget) { - if (!(mib->flag & F_READ)) { - msg->resultcode.data = - P80211ENUM_resultcode_cant_get_writeonly_mib; - goto done; - } - } else { - if (!(mib->flag & F_WRITE)) { - msg->resultcode.data = - P80211ENUM_resultcode_cant_set_readonly_mib; - goto done; - } - } - - /* - ** Execute the MIB function. If things worked okay, then make - ** sure that the MIB function also worked okay. If so, and this - ** is a "mibget", then the status value must be set for both the - ** "mibattribute" parameter and the mib item within the data - ** portion of the "mibattribute". - */ - - result = mib->func(mib, isget, wlandev, hw, msg, (void *)mibitem->data); - - if (msg->resultcode.data == P80211ENUM_resultcode_success) { - if (result != 0) { - pr_debug("get/set failure, result=%d\n", result); - msg->resultcode.data = - P80211ENUM_resultcode_implementation_failure; - } else { - if (isget) { - msg->mibattribute.status = - P80211ENUM_msgitem_status_data_ok; - mibitem->status = - P80211ENUM_msgitem_status_data_ok; - } - } - } - -done: - return 0; -} - -/* - * prism2mib_bytearea2pstr - * - * Get/set pstr data to/from a byte area. - * - * MIB record parameters: - * parm1 Prism2 RID value. - * parm2 Number of bytes of RID data. - * parm3 Not used. - * - * Arguments: - * mib MIB record. - * isget MIBGET/MIBSET flag. - * wlandev wlan device structure. - * priv "priv" structure. - * hw "hw" structure. - * msg Message structure. - * data Data buffer. - * - * Returns: - * 0 - Success. - * ~0 - Error. - * - */ - -static int prism2mib_bytearea2pstr(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data) -{ - int result; - struct p80211pstrd *pstr = data; - u8 bytebuf[MIB_TMP_MAXLEN]; - - if (isget) { - result = - hfa384x_drvr_getconfig(hw, mib->parm1, bytebuf, mib->parm2); - prism2mgmt_bytearea2pstr(bytebuf, pstr, mib->parm2); - } else { - memset(bytebuf, 0, mib->parm2); - memcpy(bytebuf, pstr->data, pstr->len); - result = - hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, mib->parm2); - } - - return result; -} - -/* - * prism2mib_uint32 - * - * Get/set uint32 data. - * - * MIB record parameters: - * parm1 Prism2 RID value. - * parm2 Not used. - * parm3 Not used. - * - * Arguments: - * mib MIB record. - * isget MIBGET/MIBSET flag. - * wlandev wlan device structure. - * priv "priv" structure. - * hw "hw" structure. - * msg Message structure. - * data Data buffer. - * - * Returns: - * 0 - Success. - * ~0 - Error. - * - */ - -static int prism2mib_uint32(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, void *data) -{ - int result; - u32 *uint32 = data; - u8 bytebuf[MIB_TMP_MAXLEN]; - u16 *wordbuf = (u16 *)bytebuf; - - if (isget) { - result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); - *uint32 = *wordbuf; - } else { - *wordbuf = *uint32; - result = hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); - } - - return result; -} - -/* - * prism2mib_flag - * - * Get/set a flag. - * - * MIB record parameters: - * parm1 Prism2 RID value. - * parm2 Bit to get/set. - * parm3 Not used. - * - * Arguments: - * mib MIB record. - * isget MIBGET/MIBSET flag. - * wlandev wlan device structure. - * priv "priv" structure. - * hw "hw" structure. - * msg Message structure. - * data Data buffer. - * - * Returns: - * 0 - Success. - * ~0 - Error. - * - */ - -static int prism2mib_flag(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, void *data) -{ - int result; - u32 *uint32 = data; - u8 bytebuf[MIB_TMP_MAXLEN]; - u16 *wordbuf = (u16 *)bytebuf; - u32 flags; - - result = hfa384x_drvr_getconfig16(hw, mib->parm1, wordbuf); - if (result == 0) { - flags = *wordbuf; - if (isget) { - *uint32 = (flags & mib->parm2) ? - P80211ENUM_truth_true : P80211ENUM_truth_false; - } else { - if ((*uint32) == P80211ENUM_truth_true) - flags |= mib->parm2; - else - flags &= ~mib->parm2; - *wordbuf = flags; - result = - hfa384x_drvr_setconfig16(hw, mib->parm1, *wordbuf); - } - } - - return result; -} - -/* - * prism2mib_wepdefaultkey - * - * Get/set WEP default keys. - * - * MIB record parameters: - * parm1 Prism2 RID value. - * parm2 Number of bytes of RID data. - * parm3 Not used. - * - * Arguments: - * mib MIB record. - * isget MIBGET/MIBSET flag. - * wlandev wlan device structure. - * priv "priv" structure. - * hw "hw" structure. - * msg Message structure. - * data Data buffer. - * - * Returns: - * 0 - Success. - * ~0 - Error. - * - */ - -static int prism2mib_wepdefaultkey(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data) -{ - int result; - struct p80211pstrd *pstr = data; - u8 bytebuf[MIB_TMP_MAXLEN]; - u16 len; - - if (isget) { - result = 0; /* Should never happen. */ - } else { - len = (pstr->len > 5) ? HFA384x_RID_CNFWEP128DEFAULTKEY_LEN : - HFA384x_RID_CNFWEPDEFAULTKEY_LEN; - memset(bytebuf, 0, len); - memcpy(bytebuf, pstr->data, pstr->len); - result = hfa384x_drvr_setconfig(hw, mib->parm1, bytebuf, len); - } - - return result; -} - -/* - * prism2mib_privacyinvoked - * - * Get/set the dot11PrivacyInvoked value. - * - * MIB record parameters: - * parm1 Prism2 RID value. - * parm2 Bit value for PrivacyInvoked flag. - * parm3 Not used. - * - * Arguments: - * mib MIB record. - * isget MIBGET/MIBSET flag. - * wlandev wlan device structure. - * priv "priv" structure. - * hw "hw" structure. - * msg Message structure. - * data Data buffer. - * - * Returns: - * 0 - Success. - * ~0 - Error. - * - */ - -static int prism2mib_privacyinvoked(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data) -{ - if (wlandev->hostwep & HOSTWEP_DECRYPT) { - if (wlandev->hostwep & HOSTWEP_DECRYPT) - mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_RXCRYPT; - if (wlandev->hostwep & HOSTWEP_ENCRYPT) - mib->parm2 |= HFA384x_WEPFLAGS_DISABLE_TXCRYPT; - } - - return prism2mib_flag(mib, isget, wlandev, hw, msg, data); -} - -/* - * prism2mib_fragmentationthreshold - * - * Get/set the fragmentation threshold. - * - * MIB record parameters: - * parm1 Prism2 RID value. - * parm2 Not used. - * parm3 Not used. - * - * Arguments: - * mib MIB record. - * isget MIBGET/MIBSET flag. - * wlandev wlan device structure. - * priv "priv" structure. - * hw "hw" structure. - * msg Message structure. - * data Data buffer. - * - * Returns: - * 0 - Success. - * ~0 - Error. - * - */ - -static int -prism2mib_fragmentationthreshold(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, - void *data) -{ - u32 *uint32 = data; - - if (!isget) - if ((*uint32) % 2) { - netdev_warn(wlandev->netdev, - "Attempt to set odd number FragmentationThreshold\n"); - msg->resultcode.data = - P80211ENUM_resultcode_not_supported; - return 0; - } - - return prism2mib_uint32(mib, isget, wlandev, hw, msg, data); -} - -/* - * prism2mib_priv - * - * Get/set values in the "priv" data structure. - * - * MIB record parameters: - * parm1 Not used. - * parm2 Not used. - * parm3 Not used. - * - * Arguments: - * mib MIB record. - * isget MIBGET/MIBSET flag. - * wlandev wlan device structure. - * priv "priv" structure. - * hw "hw" structure. - * msg Message structure. - * data Data buffer. - * - * Returns: - * 0 - Success. - * ~0 - Error. - * - */ - -static int prism2mib_priv(struct mibrec *mib, - int isget, - struct wlandevice *wlandev, - struct hfa384x *hw, - struct p80211msg_dot11req_mibset *msg, void *data) -{ - struct p80211pstrd *pstr = data; - - switch (mib->did) { - case DIDMIB_LNX_CONFIGTABLE_RSNAIE: { - /* - * This can never work: wpa is on the stack - * and has no bytes allocated in wpa.data. - */ - struct hfa384x_wpa_data wpa; - - if (isget) { - hfa384x_drvr_getconfig(hw, - HFA384x_RID_CNFWPADATA, - (u8 *)&wpa, - sizeof(wpa)); - pstr->len = 0; - } else { - wpa.datalen = 0; - - hfa384x_drvr_setconfig(hw, - HFA384x_RID_CNFWPADATA, - (u8 *)&wpa, - sizeof(wpa)); - } - break; - } - default: - netdev_err(wlandev->netdev, "Unhandled DID 0x%08x\n", mib->did); - } - - return 0; -} - -/* - * prism2mgmt_pstr2bytestr - * - * Convert the pstr data in the WLAN message structure into an hfa384x - * byte string format. - * - * Arguments: - * bytestr hfa384x byte string data type - * pstr wlan message data - * - * Returns: - * Nothing - * - */ - -void prism2mgmt_pstr2bytestr(struct hfa384x_bytestr *bytestr, - struct p80211pstrd *pstr) -{ - bytestr->len = cpu_to_le16((u16)(pstr->len)); - memcpy(bytestr->data, pstr->data, pstr->len); -} - -/* - * prism2mgmt_bytestr2pstr - * - * Convert the data in an hfa384x byte string format into a - * pstr in the WLAN message. - * - * Arguments: - * bytestr hfa384x byte string data type - * msg wlan message - * - * Returns: - * Nothing - * - */ - -void prism2mgmt_bytestr2pstr(struct hfa384x_bytestr *bytestr, - struct p80211pstrd *pstr) -{ - pstr->len = (u8)(le16_to_cpu(bytestr->len)); - memcpy(pstr->data, bytestr->data, pstr->len); -} - -/* - * prism2mgmt_bytearea2pstr - * - * Convert the data in an hfa384x byte area format into a pstr - * in the WLAN message. - * - * Arguments: - * bytearea hfa384x byte area data type - * msg wlan message - * - * Returns: - * Nothing - * - */ - -void prism2mgmt_bytearea2pstr(u8 *bytearea, struct p80211pstrd *pstr, int len) -{ - pstr->len = (u8)len; - memcpy(pstr->data, bytearea, len); -} diff --git a/drivers/staging/wlan-ng/prism2sta.c b/drivers/staging/wlan-ng/prism2sta.c deleted file mode 100644 index cb6c7a9fb8f3..000000000000 --- a/drivers/staging/wlan-ng/prism2sta.c +++ /dev/null @@ -1,1945 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0 OR MPL-1.1) -/* - * - * Implements the station functionality for prism2 - * - * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved. - * -------------------------------------------------------------------- - * - * linux-wlan - * - * -------------------------------------------------------------------- - * - * Inquiries regarding the linux-wlan Open Source project can be - * made directly to: - * - * AbsoluteValue Systems Inc. - * info@linux-wlan.com - * http://www.linux-wlan.com - * - * -------------------------------------------------------------------- - * - * Portions of the development of this software were funded by - * Intersil Corporation as part of PRISM(R) chipset product development. - * - * -------------------------------------------------------------------- - * - * This file implements the module and linux pcmcia routines for the - * prism2 driver. - * - * -------------------------------------------------------------------- - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/wireless.h> -#include <linux/netdevice.h> -#include <linux/workqueue.h> -#include <linux/byteorder/generic.h> -#include <linux/etherdevice.h> - -#include <linux/io.h> -#include <linux/delay.h> -#include <asm/byteorder.h> -#include <linux/if_arp.h> -#include <linux/if_ether.h> -#include <linux/bitops.h> - -#include "p80211types.h" -#include "p80211hdr.h" -#include "p80211mgmt.h" -#include "p80211conv.h" -#include "p80211msg.h" -#include "p80211netdev.h" -#include "p80211req.h" -#include "p80211metadef.h" -#include "p80211metastruct.h" -#include "hfa384x.h" -#include "prism2mgmt.h" - -static char *dev_info = "prism2_usb"; -static struct wlandevice *create_wlan(void); - -int prism2_reset_holdtime = 30; /* Reset hold time in ms */ -int prism2_reset_settletime = 100; /* Reset settle time in ms */ - -static int prism2_doreset; /* Do a reset at init? */ - -module_param(prism2_doreset, int, 0644); -MODULE_PARM_DESC(prism2_doreset, "Issue a reset on initialization"); - -module_param(prism2_reset_holdtime, int, 0644); -MODULE_PARM_DESC(prism2_reset_holdtime, "reset hold time in ms"); -module_param(prism2_reset_settletime, int, 0644); -MODULE_PARM_DESC(prism2_reset_settletime, "reset settle time in ms"); - -MODULE_LICENSE("Dual MPL/GPL"); - -static int prism2sta_open(struct wlandevice *wlandev); -static int prism2sta_close(struct wlandevice *wlandev); -static void prism2sta_reset(struct wlandevice *wlandev); -static int prism2sta_txframe(struct wlandevice *wlandev, struct sk_buff *skb, - struct p80211_hdr *p80211_hdr, - struct p80211_metawep *p80211_wep); -static int prism2sta_mlmerequest(struct wlandevice *wlandev, - struct p80211msg *msg); -static int prism2sta_getcardinfo(struct wlandevice *wlandev); -static int prism2sta_globalsetup(struct wlandevice *wlandev); -static int prism2sta_setmulticast(struct wlandevice *wlandev, - struct net_device *dev); -static void prism2sta_inf_tallies(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); -static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); -static void prism2sta_inf_scanresults(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); -static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); -static void prism2sta_inf_linkstatus(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); -static void prism2sta_inf_assocstatus(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); -static void prism2sta_inf_authreq(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); -static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); -static void prism2sta_inf_psusercnt(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf); - -/* - * prism2sta_open - * - * WLAN device open method. Called from p80211netdev when kernel - * device open (start) method is called in response to the - * SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP - * from clear to set. - * - * Arguments: - * wlandev wlan device structure - * - * Returns: - * 0 success - * >0 f/w reported error - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process thread - */ -static int prism2sta_open(struct wlandevice *wlandev) -{ - /* We don't currently have to do anything else. - * The setup of the MAC should be subsequently completed via - * the mlme commands. - * Higher layers know we're ready from dev->start==1 and - * dev->tbusy==0. Our rx path knows to pass up received/ - * frames because of dev->flags&IFF_UP is true. - */ - - return 0; -} - -/* - * prism2sta_close - * - * WLAN device close method. Called from p80211netdev when kernel - * device close method is called in response to the - * SIOCSIIFFLAGS ioctl changing the flags bit IFF_UP - * from set to clear. - * - * Arguments: - * wlandev wlan device structure - * - * Returns: - * 0 success - * >0 f/w reported error - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process thread - */ -static int prism2sta_close(struct wlandevice *wlandev) -{ - /* We don't currently have to do anything else. - * Higher layers know we're not ready from dev->start==0 and - * dev->tbusy==1. Our rx path knows to not pass up received - * frames because of dev->flags&IFF_UP is false. - */ - - return 0; -} - -/* - * prism2sta_reset - * - * Currently not implemented. - * - * Arguments: - * wlandev wlan device structure - * none - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * process thread - */ -static void prism2sta_reset(struct wlandevice *wlandev) -{ -} - -/* - * prism2sta_txframe - * - * Takes a frame from p80211 and queues it for transmission. - * - * Arguments: - * wlandev wlan device structure - * pb packet buffer struct. Contains an 802.11 - * data frame. - * p80211_hdr points to the 802.11 header for the packet. - * Returns: - * 0 Success and more buffs available - * 1 Success but no more buffs - * 2 Allocation failure - * 4 Buffer full or queue busy - * - * Side effects: - * - * Call context: - * process thread - */ -static int prism2sta_txframe(struct wlandevice *wlandev, struct sk_buff *skb, - struct p80211_hdr *p80211_hdr, - struct p80211_metawep *p80211_wep) -{ - struct hfa384x *hw = wlandev->priv; - - /* If necessary, set the 802.11 WEP bit */ - if ((wlandev->hostwep & (HOSTWEP_PRIVACYINVOKED | HOSTWEP_ENCRYPT)) == - HOSTWEP_PRIVACYINVOKED) { - p80211_hdr->frame_control |= cpu_to_le16(WLAN_SET_FC_ISWEP(1)); - } - - return hfa384x_drvr_txframe(hw, skb, p80211_hdr, p80211_wep); -} - -/* - * prism2sta_mlmerequest - * - * wlan command message handler. All we do here is pass the message - * over to the prism2sta_mgmt_handler. - * - * Arguments: - * wlandev wlan device structure - * msg wlan command message - * Returns: - * 0 success - * <0 successful acceptance of message, but we're - * waiting for an async process to finish before - * we're done with the msg. When the asynch - * process is done, we'll call the p80211 - * function p80211req_confirm() . - * >0 An error occurred while we were handling - * the message. - * - * Side effects: - * - * Call context: - * process thread - */ -static int prism2sta_mlmerequest(struct wlandevice *wlandev, - struct p80211msg *msg) -{ - struct hfa384x *hw = wlandev->priv; - - int result = 0; - - switch (msg->msgcode) { - case DIDMSG_DOT11REQ_MIBGET: - netdev_dbg(wlandev->netdev, "Received mibget request\n"); - result = prism2mgmt_mibset_mibget(wlandev, msg); - break; - case DIDMSG_DOT11REQ_MIBSET: - netdev_dbg(wlandev->netdev, "Received mibset request\n"); - result = prism2mgmt_mibset_mibget(wlandev, msg); - break; - case DIDMSG_DOT11REQ_SCAN: - netdev_dbg(wlandev->netdev, "Received scan request\n"); - result = prism2mgmt_scan(wlandev, msg); - break; - case DIDMSG_DOT11REQ_SCAN_RESULTS: - netdev_dbg(wlandev->netdev, "Received scan_results request\n"); - result = prism2mgmt_scan_results(wlandev, msg); - break; - case DIDMSG_DOT11REQ_START: - netdev_dbg(wlandev->netdev, "Received mlme start request\n"); - result = prism2mgmt_start(wlandev, msg); - break; - /* - * Prism2 specific messages - */ - case DIDMSG_P2REQ_READPDA: - netdev_dbg(wlandev->netdev, "Received mlme readpda request\n"); - result = prism2mgmt_readpda(wlandev, msg); - break; - case DIDMSG_P2REQ_RAMDL_STATE: - netdev_dbg(wlandev->netdev, - "Received mlme ramdl_state request\n"); - result = prism2mgmt_ramdl_state(wlandev, msg); - break; - case DIDMSG_P2REQ_RAMDL_WRITE: - netdev_dbg(wlandev->netdev, - "Received mlme ramdl_write request\n"); - result = prism2mgmt_ramdl_write(wlandev, msg); - break; - case DIDMSG_P2REQ_FLASHDL_STATE: - netdev_dbg(wlandev->netdev, - "Received mlme flashdl_state request\n"); - result = prism2mgmt_flashdl_state(wlandev, msg); - break; - case DIDMSG_P2REQ_FLASHDL_WRITE: - netdev_dbg(wlandev->netdev, - "Received mlme flashdl_write request\n"); - result = prism2mgmt_flashdl_write(wlandev, msg); - break; - /* - * Linux specific messages - */ - case DIDMSG_LNXREQ_HOSTWEP: - break; /* ignore me. */ - case DIDMSG_LNXREQ_IFSTATE: { - struct p80211msg_lnxreq_ifstate *ifstatemsg; - - netdev_dbg(wlandev->netdev, "Received mlme ifstate request\n"); - ifstatemsg = (struct p80211msg_lnxreq_ifstate *)msg; - result = prism2sta_ifstate(wlandev, - ifstatemsg->ifstate.data); - ifstatemsg->resultcode.status = - P80211ENUM_msgitem_status_data_ok; - ifstatemsg->resultcode.data = result; - result = 0; - break; - } - case DIDMSG_LNXREQ_WLANSNIFF: - netdev_dbg(wlandev->netdev, - "Received mlme wlansniff request\n"); - result = prism2mgmt_wlansniff(wlandev, msg); - break; - case DIDMSG_LNXREQ_AUTOJOIN: - netdev_dbg(wlandev->netdev, "Received mlme autojoin request\n"); - result = prism2mgmt_autojoin(wlandev, msg); - break; - case DIDMSG_LNXREQ_COMMSQUALITY: { - struct p80211msg_lnxreq_commsquality *qualmsg; - - netdev_dbg(wlandev->netdev, "Received commsquality request\n"); - - qualmsg = (struct p80211msg_lnxreq_commsquality *)msg; - - qualmsg->link.status = P80211ENUM_msgitem_status_data_ok; - qualmsg->level.status = P80211ENUM_msgitem_status_data_ok; - qualmsg->noise.status = P80211ENUM_msgitem_status_data_ok; - - qualmsg->link.data = le16_to_cpu(hw->qual.cq_curr_bss); - qualmsg->level.data = le16_to_cpu(hw->qual.asl_curr_bss); - qualmsg->noise.data = le16_to_cpu(hw->qual.anl_curr_fc); - qualmsg->txrate.data = hw->txrate; - - break; - } - default: - netdev_warn(wlandev->netdev, - "Unknown mgmt request message 0x%08x", - msg->msgcode); - break; - } - - return result; -} - -/* - * prism2sta_ifstate - * - * Interface state. This is the primary WLAN interface enable/disable - * handler. Following the driver/load/deviceprobe sequence, this - * function must be called with a state of "enable" before any other - * commands will be accepted. - * - * Arguments: - * wlandev wlan device structure - * msgp ptr to msg buffer - * - * Returns: - * A p80211 message resultcode value. - * - * Side effects: - * - * Call context: - * process thread (usually) - * interrupt - */ -u32 prism2sta_ifstate(struct wlandevice *wlandev, u32 ifstate) -{ - struct hfa384x *hw = wlandev->priv; - u32 result; - - result = P80211ENUM_resultcode_implementation_failure; - - netdev_dbg(wlandev->netdev, "Current MSD state(%d), requesting(%d)\n", - wlandev->msdstate, ifstate); - switch (ifstate) { - case P80211ENUM_ifstate_fwload: - switch (wlandev->msdstate) { - case WLAN_MSD_HWPRESENT: - wlandev->msdstate = WLAN_MSD_FWLOAD_PENDING; - /* - * Initialize the device+driver sufficiently - * for firmware loading. - */ - result = hfa384x_drvr_start(hw); - if (result) { - netdev_err(wlandev->netdev, - "hfa384x_drvr_start() failed,result=%d\n", - (int)result); - result = - P80211ENUM_resultcode_implementation_failure; - wlandev->msdstate = WLAN_MSD_HWPRESENT; - break; - } - wlandev->msdstate = WLAN_MSD_FWLOAD; - result = P80211ENUM_resultcode_success; - break; - case WLAN_MSD_FWLOAD: - hfa384x_cmd_initialize(hw); - result = P80211ENUM_resultcode_success; - break; - case WLAN_MSD_RUNNING: - netdev_warn(wlandev->netdev, - "Cannot enter fwload state from enable state, you must disable first.\n"); - result = P80211ENUM_resultcode_invalid_parameters; - break; - case WLAN_MSD_HWFAIL: - default: - /* probe() had a problem or the msdstate contains - * an unrecognized value, there's nothing we can do. - */ - result = P80211ENUM_resultcode_implementation_failure; - break; - } - break; - case P80211ENUM_ifstate_enable: - switch (wlandev->msdstate) { - case WLAN_MSD_HWPRESENT: - case WLAN_MSD_FWLOAD: - wlandev->msdstate = WLAN_MSD_RUNNING_PENDING; - /* Initialize the device+driver for full - * operation. Note that this might me an FWLOAD - * to RUNNING transition so we must not do a chip - * or board level reset. Note that on failure, - * the MSD state is set to HWPRESENT because we - * can't make any assumptions about the state - * of the hardware or a previous firmware load. - */ - result = hfa384x_drvr_start(hw); - if (result) { - netdev_err(wlandev->netdev, - "hfa384x_drvr_start() failed,result=%d\n", - (int)result); - result = - P80211ENUM_resultcode_implementation_failure; - wlandev->msdstate = WLAN_MSD_HWPRESENT; - break; - } - - result = prism2sta_getcardinfo(wlandev); - if (result) { - netdev_err(wlandev->netdev, - "prism2sta_getcardinfo() failed,result=%d\n", - (int)result); - result = - P80211ENUM_resultcode_implementation_failure; - hfa384x_drvr_stop(hw); - wlandev->msdstate = WLAN_MSD_HWPRESENT; - break; - } - result = prism2sta_globalsetup(wlandev); - if (result) { - netdev_err(wlandev->netdev, - "prism2sta_globalsetup() failed,result=%d\n", - (int)result); - result = - P80211ENUM_resultcode_implementation_failure; - hfa384x_drvr_stop(hw); - wlandev->msdstate = WLAN_MSD_HWPRESENT; - break; - } - wlandev->msdstate = WLAN_MSD_RUNNING; - hw->join_ap = 0; - hw->join_retries = 60; - result = P80211ENUM_resultcode_success; - break; - case WLAN_MSD_RUNNING: - /* Do nothing, we're already in this state. */ - result = P80211ENUM_resultcode_success; - break; - case WLAN_MSD_HWFAIL: - default: - /* probe() had a problem or the msdstate contains - * an unrecognized value, there's nothing we can do. - */ - result = P80211ENUM_resultcode_implementation_failure; - break; - } - break; - case P80211ENUM_ifstate_disable: - switch (wlandev->msdstate) { - case WLAN_MSD_HWPRESENT: - /* Do nothing, we're already in this state. */ - result = P80211ENUM_resultcode_success; - break; - case WLAN_MSD_FWLOAD: - case WLAN_MSD_RUNNING: - wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING; - /* - * TODO: Shut down the MAC completely. Here a chip - * or board level reset is probably called for. - * After a "disable" _all_ results are lost, even - * those from a fwload. - */ - if (!wlandev->hwremoved) - netif_carrier_off(wlandev->netdev); - - hfa384x_drvr_stop(hw); - - wlandev->macmode = WLAN_MACMODE_NONE; - wlandev->msdstate = WLAN_MSD_HWPRESENT; - result = P80211ENUM_resultcode_success; - break; - case WLAN_MSD_HWFAIL: - default: - /* probe() had a problem or the msdstate contains - * an unrecognized value, there's nothing we can do. - */ - result = P80211ENUM_resultcode_implementation_failure; - break; - } - break; - default: - result = P80211ENUM_resultcode_invalid_parameters; - break; - } - - return result; -} - -/* - * prism2sta_getcardinfo - * - * Collect the NICID, firmware version and any other identifiers - * we'd like to have in host-side data structures. - * - * Arguments: - * wlandev wlan device structure - * - * Returns: - * 0 success - * >0 f/w reported error - * <0 driver reported error - * - * Side effects: - * - * Call context: - * Either. - */ -static int prism2sta_getcardinfo(struct wlandevice *wlandev) -{ - int result = 0; - struct hfa384x *hw = wlandev->priv; - u16 temp; - u8 snum[HFA384x_RID_NICSERIALNUMBER_LEN]; - u8 addr[ETH_ALEN]; - - /* Collect version and compatibility info */ - /* Some are critical, some are not */ - /* NIC identity */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICIDENTITY, - &hw->ident_nic, - sizeof(struct hfa384x_compident)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve NICIDENTITY\n"); - goto failed; - } - - /* get all the nic id fields in host byte order */ - le16_to_cpus(&hw->ident_nic.id); - le16_to_cpus(&hw->ident_nic.variant); - le16_to_cpus(&hw->ident_nic.major); - le16_to_cpus(&hw->ident_nic.minor); - - netdev_info(wlandev->netdev, "ident: nic h/w: id=0x%02x %d.%d.%d\n", - hw->ident_nic.id, hw->ident_nic.major, - hw->ident_nic.minor, hw->ident_nic.variant); - - /* Primary f/w identity */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRIIDENTITY, - &hw->ident_pri_fw, - sizeof(struct hfa384x_compident)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve PRIIDENTITY\n"); - goto failed; - } - - /* get all the private fw id fields in host byte order */ - le16_to_cpus(&hw->ident_pri_fw.id); - le16_to_cpus(&hw->ident_pri_fw.variant); - le16_to_cpus(&hw->ident_pri_fw.major); - le16_to_cpus(&hw->ident_pri_fw.minor); - - netdev_info(wlandev->netdev, "ident: pri f/w: id=0x%02x %d.%d.%d\n", - hw->ident_pri_fw.id, hw->ident_pri_fw.major, - hw->ident_pri_fw.minor, hw->ident_pri_fw.variant); - - /* Station (Secondary?) f/w identity */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STAIDENTITY, - &hw->ident_sta_fw, - sizeof(struct hfa384x_compident)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve STAIDENTITY\n"); - goto failed; - } - - if (hw->ident_nic.id < 0x8000) { - netdev_err(wlandev->netdev, - "FATAL: Card is not an Intersil Prism2/2.5/3\n"); - result = -1; - goto failed; - } - - /* get all the station fw id fields in host byte order */ - le16_to_cpus(&hw->ident_sta_fw.id); - le16_to_cpus(&hw->ident_sta_fw.variant); - le16_to_cpus(&hw->ident_sta_fw.major); - le16_to_cpus(&hw->ident_sta_fw.minor); - - /* strip out the 'special' variant bits */ - hw->mm_mods = hw->ident_sta_fw.variant & GENMASK(15, 14); - hw->ident_sta_fw.variant &= ~((u16)GENMASK(15, 14)); - - if (hw->ident_sta_fw.id == 0x1f) { - netdev_info(wlandev->netdev, - "ident: sta f/w: id=0x%02x %d.%d.%d\n", - hw->ident_sta_fw.id, hw->ident_sta_fw.major, - hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); - } else { - netdev_info(wlandev->netdev, - "ident: ap f/w: id=0x%02x %d.%d.%d\n", - hw->ident_sta_fw.id, hw->ident_sta_fw.major, - hw->ident_sta_fw.minor, hw->ident_sta_fw.variant); - netdev_err(wlandev->netdev, "Unsupported Tertiary AP firmware loaded!\n"); - goto failed; - } - - /* Compatibility range, Modem supplier */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_MFISUPRANGE, - &hw->cap_sup_mfi, - sizeof(struct hfa384x_caplevel)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve MFISUPRANGE\n"); - goto failed; - } - - /* get all the Compatibility range, modem interface supplier - * fields in byte order - */ - le16_to_cpus(&hw->cap_sup_mfi.role); - le16_to_cpus(&hw->cap_sup_mfi.id); - le16_to_cpus(&hw->cap_sup_mfi.variant); - le16_to_cpus(&hw->cap_sup_mfi.bottom); - le16_to_cpus(&hw->cap_sup_mfi.top); - - netdev_info(wlandev->netdev, - "MFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", - hw->cap_sup_mfi.role, hw->cap_sup_mfi.id, - hw->cap_sup_mfi.variant, hw->cap_sup_mfi.bottom, - hw->cap_sup_mfi.top); - - /* Compatibility range, Controller supplier */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CFISUPRANGE, - &hw->cap_sup_cfi, - sizeof(struct hfa384x_caplevel)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve CFISUPRANGE\n"); - goto failed; - } - - /* get all the Compatibility range, controller interface supplier - * fields in byte order - */ - le16_to_cpus(&hw->cap_sup_cfi.role); - le16_to_cpus(&hw->cap_sup_cfi.id); - le16_to_cpus(&hw->cap_sup_cfi.variant); - le16_to_cpus(&hw->cap_sup_cfi.bottom); - le16_to_cpus(&hw->cap_sup_cfi.top); - - netdev_info(wlandev->netdev, - "CFI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", - hw->cap_sup_cfi.role, hw->cap_sup_cfi.id, - hw->cap_sup_cfi.variant, hw->cap_sup_cfi.bottom, - hw->cap_sup_cfi.top); - - /* Compatibility range, Primary f/w supplier */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRISUPRANGE, - &hw->cap_sup_pri, - sizeof(struct hfa384x_caplevel)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve PRISUPRANGE\n"); - goto failed; - } - - /* get all the Compatibility range, primary firmware supplier - * fields in byte order - */ - le16_to_cpus(&hw->cap_sup_pri.role); - le16_to_cpus(&hw->cap_sup_pri.id); - le16_to_cpus(&hw->cap_sup_pri.variant); - le16_to_cpus(&hw->cap_sup_pri.bottom); - le16_to_cpus(&hw->cap_sup_pri.top); - - netdev_info(wlandev->netdev, - "PRI:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", - hw->cap_sup_pri.role, hw->cap_sup_pri.id, - hw->cap_sup_pri.variant, hw->cap_sup_pri.bottom, - hw->cap_sup_pri.top); - - /* Compatibility range, Station f/w supplier */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STASUPRANGE, - &hw->cap_sup_sta, - sizeof(struct hfa384x_caplevel)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve STASUPRANGE\n"); - goto failed; - } - - /* get all the Compatibility range, station firmware supplier - * fields in byte order - */ - le16_to_cpus(&hw->cap_sup_sta.role); - le16_to_cpus(&hw->cap_sup_sta.id); - le16_to_cpus(&hw->cap_sup_sta.variant); - le16_to_cpus(&hw->cap_sup_sta.bottom); - le16_to_cpus(&hw->cap_sup_sta.top); - - if (hw->cap_sup_sta.id == 0x04) { - netdev_info(wlandev->netdev, - "STA:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", - hw->cap_sup_sta.role, hw->cap_sup_sta.id, - hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, - hw->cap_sup_sta.top); - } else { - netdev_info(wlandev->netdev, - "AP:SUP:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", - hw->cap_sup_sta.role, hw->cap_sup_sta.id, - hw->cap_sup_sta.variant, hw->cap_sup_sta.bottom, - hw->cap_sup_sta.top); - } - - /* Compatibility range, primary f/w actor, CFI supplier */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_PRI_CFIACTRANGES, - &hw->cap_act_pri_cfi, - sizeof(struct hfa384x_caplevel)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve PRI_CFIACTRANGES\n"); - goto failed; - } - - /* get all the Compatibility range, primary f/w actor, CFI supplier - * fields in byte order - */ - le16_to_cpus(&hw->cap_act_pri_cfi.role); - le16_to_cpus(&hw->cap_act_pri_cfi.id); - le16_to_cpus(&hw->cap_act_pri_cfi.variant); - le16_to_cpus(&hw->cap_act_pri_cfi.bottom); - le16_to_cpus(&hw->cap_act_pri_cfi.top); - - netdev_info(wlandev->netdev, - "PRI-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", - hw->cap_act_pri_cfi.role, hw->cap_act_pri_cfi.id, - hw->cap_act_pri_cfi.variant, hw->cap_act_pri_cfi.bottom, - hw->cap_act_pri_cfi.top); - - /* Compatibility range, sta f/w actor, CFI supplier */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_CFIACTRANGES, - &hw->cap_act_sta_cfi, - sizeof(struct hfa384x_caplevel)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve STA_CFIACTRANGES\n"); - goto failed; - } - - /* get all the Compatibility range, station f/w actor, CFI supplier - * fields in byte order - */ - le16_to_cpus(&hw->cap_act_sta_cfi.role); - le16_to_cpus(&hw->cap_act_sta_cfi.id); - le16_to_cpus(&hw->cap_act_sta_cfi.variant); - le16_to_cpus(&hw->cap_act_sta_cfi.bottom); - le16_to_cpus(&hw->cap_act_sta_cfi.top); - - netdev_info(wlandev->netdev, - "STA-CFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", - hw->cap_act_sta_cfi.role, hw->cap_act_sta_cfi.id, - hw->cap_act_sta_cfi.variant, hw->cap_act_sta_cfi.bottom, - hw->cap_act_sta_cfi.top); - - /* Compatibility range, sta f/w actor, MFI supplier */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_STA_MFIACTRANGES, - &hw->cap_act_sta_mfi, - sizeof(struct hfa384x_caplevel)); - if (result) { - netdev_err(wlandev->netdev, "Failed to retrieve STA_MFIACTRANGES\n"); - goto failed; - } - - /* get all the Compatibility range, station f/w actor, MFI supplier - * fields in byte order - */ - le16_to_cpus(&hw->cap_act_sta_mfi.role); - le16_to_cpus(&hw->cap_act_sta_mfi.id); - le16_to_cpus(&hw->cap_act_sta_mfi.variant); - le16_to_cpus(&hw->cap_act_sta_mfi.bottom); - le16_to_cpus(&hw->cap_act_sta_mfi.top); - - netdev_info(wlandev->netdev, - "STA-MFI:ACT:role=0x%02x:id=0x%02x:var=0x%02x:b/t=%d/%d\n", - hw->cap_act_sta_mfi.role, hw->cap_act_sta_mfi.id, - hw->cap_act_sta_mfi.variant, hw->cap_act_sta_mfi.bottom, - hw->cap_act_sta_mfi.top); - - /* Serial Number */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_NICSERIALNUMBER, - snum, HFA384x_RID_NICSERIALNUMBER_LEN); - if (!result) { - netdev_info(wlandev->netdev, "Prism2 card SN: %*pE\n", - HFA384x_RID_NICSERIALNUMBER_LEN, snum); - } else { - netdev_err(wlandev->netdev, "Failed to retrieve Prism2 Card SN\n"); - goto failed; - } - - /* Collect the MAC address */ - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_CNFOWNMACADDR, - addr, ETH_ALEN); - if (result != 0) { - netdev_err(wlandev->netdev, "Failed to retrieve mac address\n"); - goto failed; - } - eth_hw_addr_set(wlandev->netdev, addr); - - /* short preamble is always implemented */ - wlandev->nsdcaps |= P80211_NSDCAP_SHORT_PREAMBLE; - - /* find out if hardware wep is implemented */ - hfa384x_drvr_getconfig16(hw, HFA384x_RID_PRIVACYOPTIMP, &temp); - if (temp) - wlandev->nsdcaps |= P80211_NSDCAP_HARDWAREWEP; - - /* get the dBm Scaling constant */ - hfa384x_drvr_getconfig16(hw, HFA384x_RID_CNFDBMADJUST, &temp); - hw->dbmadjust = temp; - - /* Only enable scan by default on newer firmware */ - if (HFA384x_FIRMWARE_VERSION(hw->ident_sta_fw.major, - hw->ident_sta_fw.minor, - hw->ident_sta_fw.variant) < - HFA384x_FIRMWARE_VERSION(1, 5, 5)) { - wlandev->nsdcaps |= P80211_NSDCAP_NOSCAN; - } - - /* TODO: Set any internally managed config items */ - - goto done; -failed: - netdev_err(wlandev->netdev, "Failed, result=%d\n", result); -done: - return result; -} - -/* - * prism2sta_globalsetup - * - * Set any global RIDs that we want to set at device activation. - * - * Arguments: - * wlandev wlan device structure - * - * Returns: - * 0 success - * >0 f/w reported error - * <0 driver reported error - * - * Side effects: - * - * Call context: - * process thread - */ -static int prism2sta_globalsetup(struct wlandevice *wlandev) -{ - struct hfa384x *hw = wlandev->priv; - - /* Set the maximum frame size */ - return hfa384x_drvr_setconfig16(hw, HFA384x_RID_CNFMAXDATALEN, - WLAN_DATA_MAXLEN); -} - -static int prism2sta_setmulticast(struct wlandevice *wlandev, - struct net_device *dev) -{ - int result = 0; - struct hfa384x *hw = wlandev->priv; - - u16 promisc; - - /* If we're not ready, what's the point? */ - if (hw->state != HFA384x_STATE_RUNNING) - goto exit; - - if ((dev->flags & (IFF_PROMISC | IFF_ALLMULTI)) != 0) - promisc = P80211ENUM_truth_true; - else - promisc = P80211ENUM_truth_false; - - result = - hfa384x_drvr_setconfig16_async(hw, HFA384x_RID_PROMISCMODE, - promisc); -exit: - return result; -} - -/* - * prism2sta_inf_tallies - * - * Handles the receipt of a CommTallies info frame. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to info frame (contents in hfa384x order) - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -static void prism2sta_inf_tallies(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - struct hfa384x *hw = wlandev->priv; - __le16 *src16; - u32 *dst; - __le32 *src32; - int i; - int cnt; - - /* - * Determine if these are 16-bit or 32-bit tallies, based on the - * record length of the info record. - */ - - cnt = sizeof(struct hfa384x_comm_tallies_32) / sizeof(u32); - if (inf->framelen > 22) { - dst = (u32 *)&hw->tallies; - src32 = (__le32 *)&inf->info.commtallies32; - for (i = 0; i < cnt; i++, dst++, src32++) - *dst += le32_to_cpu(*src32); - } else { - dst = (u32 *)&hw->tallies; - src16 = (__le16 *)&inf->info.commtallies16; - for (i = 0; i < cnt; i++, dst++, src16++) - *dst += le16_to_cpu(*src16); - } -} - -/* - * prism2sta_inf_scanresults - * - * Handles the receipt of a Scan Results info frame. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to info frame (contents in hfa384x order) - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -static void prism2sta_inf_scanresults(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - struct hfa384x *hw = wlandev->priv; - int nbss; - struct hfa384x_scan_result *sr = &inf->info.scanresult; - int i; - struct hfa384x_join_request_data joinreq; - int result; - - /* Get the number of results, first in bytes, then in results */ - nbss = (inf->framelen * sizeof(u16)) - - sizeof(inf->infotype) - sizeof(inf->info.scanresult.scanreason); - nbss /= sizeof(struct hfa384x_scan_result_sub); - - /* Print em */ - netdev_dbg(wlandev->netdev, "rx scanresults, reason=%d, nbss=%d:\n", - inf->info.scanresult.scanreason, nbss); - for (i = 0; i < nbss; i++) { - netdev_dbg(wlandev->netdev, "chid=%d anl=%d sl=%d bcnint=%d\n", - sr->result[i].chid, sr->result[i].anl, - sr->result[i].sl, sr->result[i].bcnint); - netdev_dbg(wlandev->netdev, - " capinfo=0x%04x proberesp_rate=%d\n", - sr->result[i].capinfo, sr->result[i].proberesp_rate); - } - /* issue a join request */ - joinreq.channel = sr->result[0].chid; - memcpy(joinreq.bssid, sr->result[0].bssid, WLAN_BSSID_LEN); - result = hfa384x_drvr_setconfig(hw, - HFA384x_RID_JOINREQUEST, - &joinreq, HFA384x_RID_JOINREQUEST_LEN); - if (result) { - netdev_err(wlandev->netdev, "setconfig(joinreq) failed, result=%d\n", - result); - } -} - -/* - * prism2sta_inf_hostscanresults - * - * Handles the receipt of a Scan Results info frame. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to info frame (contents in hfa384x order) - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -static void prism2sta_inf_hostscanresults(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - struct hfa384x *hw = wlandev->priv; - int nbss; - - nbss = (inf->framelen - 3) / 32; - netdev_dbg(wlandev->netdev, "Received %d hostscan results\n", nbss); - - if (nbss > 32) - nbss = 32; - - kfree(hw->scanresults); - - hw->scanresults = kmemdup(inf, sizeof(*inf), GFP_ATOMIC); - - if (nbss == 0) - nbss = -1; - - /* Notify/wake the sleeping caller. */ - hw->scanflag = nbss; - wake_up_interruptible(&hw->cmdq); -}; - -/* - * prism2sta_inf_chinforesults - * - * Handles the receipt of a Channel Info Results info frame. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to info frame (contents in hfa384x order) - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -static void prism2sta_inf_chinforesults(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - struct hfa384x *hw = wlandev->priv; - unsigned int i, n; - - hw->channel_info.results.scanchannels = - inf->info.chinforesult.scanchannels; - - for (i = 0, n = 0; i < HFA384x_CHINFORESULT_MAX; i++) { - struct hfa384x_ch_info_result_sub *result; - struct hfa384x_ch_info_result_sub *chinforesult; - int chan; - - if (!(hw->channel_info.results.scanchannels & (1 << i))) - continue; - - result = &inf->info.chinforesult.result[n]; - chan = result->chid - 1; - - if (chan < 0 || chan >= HFA384x_CHINFORESULT_MAX) - continue; - - chinforesult = &hw->channel_info.results.result[chan]; - chinforesult->chid = chan; - chinforesult->anl = result->anl; - chinforesult->pnl = result->pnl; - chinforesult->active = result->active; - - netdev_dbg(wlandev->netdev, - "chinfo: channel %d, %s level (avg/peak)=%d/%d dB, pcf %d\n", - chan + 1, - (chinforesult->active & HFA384x_CHINFORESULT_BSSACTIVE) ? - "signal" : "noise", - chinforesult->anl, - chinforesult->pnl, - (chinforesult->active & HFA384x_CHINFORESULT_PCFACTIVE) ? 1 : 0); - n++; - } - atomic_set(&hw->channel_info.done, 2); - - hw->channel_info.count = n; -} - -void prism2sta_processing_defer(struct work_struct *data) -{ - struct hfa384x *hw = container_of(data, struct hfa384x, link_bh); - struct wlandevice *wlandev = hw->wlandev; - struct hfa384x_bytestr32 ssid; - int result; - - /* First let's process the auth frames */ - { - struct sk_buff *skb; - struct hfa384x_inf_frame *inf; - - while ((skb = skb_dequeue(&hw->authq))) { - inf = (struct hfa384x_inf_frame *)skb->data; - prism2sta_inf_authreq_defer(wlandev, inf); - } - } - - /* Now let's handle the linkstatus stuff */ - if (hw->link_status == hw->link_status_new) - return; - - hw->link_status = hw->link_status_new; - - switch (hw->link_status) { - case HFA384x_LINK_NOTCONNECTED: - /* I'm currently assuming that this is the initial link - * state. It should only be possible immediately - * following an Enable command. - * Response: - * Block Transmits, Ignore receives of data frames - */ - netif_carrier_off(wlandev->netdev); - - netdev_info(wlandev->netdev, "linkstatus=NOTCONNECTED (unhandled)\n"); - break; - - case HFA384x_LINK_CONNECTED: - /* This one indicates a successful scan/join/auth/assoc. - * When we have the full MLME complement, this event will - * signify successful completion of both mlme_authenticate - * and mlme_associate. State management will get a little - * ugly here. - * Response: - * Indicate authentication and/or association - * Enable Transmits, Receives and pass up data frames - */ - - netif_carrier_on(wlandev->netdev); - - /* If we are joining a specific AP, set our - * state and reset retries - */ - if (hw->join_ap == 1) - hw->join_ap = 2; - hw->join_retries = 60; - - /* Don't call this in monitor mode */ - if (wlandev->netdev->type == ARPHRD_ETHER) { - u16 portstatus; - - netdev_info(wlandev->netdev, "linkstatus=CONNECTED\n"); - - /* For non-usb devices, we can use the sync versions */ - /* Collect the BSSID, and set state to allow tx */ - - result = hfa384x_drvr_getconfig(hw, - HFA384x_RID_CURRENTBSSID, - wlandev->bssid, - WLAN_BSSID_LEN); - if (result) { - netdev_dbg(wlandev->netdev, - "getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTBSSID, result); - return; - } - - result = hfa384x_drvr_getconfig(hw, - HFA384x_RID_CURRENTSSID, - &ssid, sizeof(ssid)); - if (result) { - netdev_dbg(wlandev->netdev, - "getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTSSID, result); - return; - } - prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid, - (struct p80211pstrd *)&wlandev->ssid); - - /* Collect the port status */ - result = hfa384x_drvr_getconfig16(hw, - HFA384x_RID_PORTSTATUS, - &portstatus); - if (result) { - netdev_dbg(wlandev->netdev, - "getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_PORTSTATUS, result); - return; - } - wlandev->macmode = - (portstatus == HFA384x_PSTATUS_CONN_IBSS) ? - WLAN_MACMODE_IBSS_STA : WLAN_MACMODE_ESS_STA; - - /* signal back up to cfg80211 layer */ - prism2_connect_result(wlandev, P80211ENUM_truth_false); - - /* Get the ball rolling on the comms quality stuff */ - prism2sta_commsqual_defer(&hw->commsqual_bh); - } - break; - - case HFA384x_LINK_DISCONNECTED: - /* This one indicates that our association is gone. We've - * lost connection with the AP and/or been disassociated. - * This indicates that the MAC has completely cleared it's - * associated state. We * should send a deauth indication - * (implying disassoc) up * to the MLME. - * Response: - * Indicate Deauthentication - * Block Transmits, Ignore receives of data frames - */ - if (wlandev->netdev->type == ARPHRD_ETHER) - netdev_info(wlandev->netdev, - "linkstatus=DISCONNECTED (unhandled)\n"); - wlandev->macmode = WLAN_MACMODE_NONE; - - netif_carrier_off(wlandev->netdev); - - /* signal back up to cfg80211 layer */ - prism2_disconnected(wlandev); - - break; - - case HFA384x_LINK_AP_CHANGE: - /* This one indicates that the MAC has decided to and - * successfully completed a change to another AP. We - * should probably implement a reassociation indication - * in response to this one. I'm thinking that the - * p80211 layer needs to be notified in case of - * buffering/queueing issues. User mode also needs to be - * notified so that any BSS dependent elements can be - * updated. - * associated state. We * should send a deauth indication - * (implying disassoc) up * to the MLME. - * Response: - * Indicate Reassociation - * Enable Transmits, Receives and pass up data frames - */ - netdev_info(wlandev->netdev, "linkstatus=AP_CHANGE\n"); - - result = hfa384x_drvr_getconfig(hw, - HFA384x_RID_CURRENTBSSID, - wlandev->bssid, WLAN_BSSID_LEN); - if (result) { - netdev_dbg(wlandev->netdev, - "getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTBSSID, result); - return; - } - - result = hfa384x_drvr_getconfig(hw, - HFA384x_RID_CURRENTSSID, - &ssid, sizeof(ssid)); - if (result) { - netdev_dbg(wlandev->netdev, - "getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTSSID, result); - return; - } - prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid, - (struct p80211pstrd *)&wlandev->ssid); - - hw->link_status = HFA384x_LINK_CONNECTED; - netif_carrier_on(wlandev->netdev); - - /* signal back up to cfg80211 layer */ - prism2_roamed(wlandev); - - break; - - case HFA384x_LINK_AP_OUTOFRANGE: - /* This one indicates that the MAC has decided that the - * AP is out of range, but hasn't found a better candidate - * so the MAC maintains its "associated" state in case - * we get back in range. We should block transmits and - * receives in this state. Do we need an indication here? - * Probably not since a polling user-mode element would - * get this status from p2PortStatus(FD40). What about - * p80211? - * Response: - * Block Transmits, Ignore receives of data frames - */ - netdev_info(wlandev->netdev, "linkstatus=AP_OUTOFRANGE (unhandled)\n"); - - netif_carrier_off(wlandev->netdev); - - break; - - case HFA384x_LINK_AP_INRANGE: - /* This one indicates that the MAC has decided that the - * AP is back in range. We continue working with our - * existing association. - * Response: - * Enable Transmits, Receives and pass up data frames - */ - netdev_info(wlandev->netdev, "linkstatus=AP_INRANGE\n"); - - hw->link_status = HFA384x_LINK_CONNECTED; - netif_carrier_on(wlandev->netdev); - - break; - - case HFA384x_LINK_ASSOCFAIL: - /* This one is actually a peer to CONNECTED. We've - * requested a join for a given SSID and optionally BSSID. - * We can use this one to indicate authentication and - * association failures. The trick is going to be - * 1) identifying the failure, and 2) state management. - * Response: - * Disable Transmits, Ignore receives of data frames - */ - if (hw->join_ap && --hw->join_retries > 0) { - struct hfa384x_join_request_data joinreq; - - joinreq = hw->joinreq; - /* Send the join request */ - hfa384x_drvr_setconfig(hw, - HFA384x_RID_JOINREQUEST, - &joinreq, - HFA384x_RID_JOINREQUEST_LEN); - netdev_info(wlandev->netdev, - "linkstatus=ASSOCFAIL (re-submitting join)\n"); - } else { - netdev_info(wlandev->netdev, "linkstatus=ASSOCFAIL (unhandled)\n"); - } - - netif_carrier_off(wlandev->netdev); - - /* signal back up to cfg80211 layer */ - prism2_connect_result(wlandev, P80211ENUM_truth_true); - - break; - - default: - /* This is bad, IO port problems? */ - netdev_warn(wlandev->netdev, - "unknown linkstatus=0x%02x\n", hw->link_status); - return; - } - - wlandev->linkstatus = (hw->link_status == HFA384x_LINK_CONNECTED); -} - -/* - * prism2sta_inf_linkstatus - * - * Handles the receipt of a Link Status info frame. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to info frame (contents in hfa384x order) - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -static void prism2sta_inf_linkstatus(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - struct hfa384x *hw = wlandev->priv; - - hw->link_status_new = le16_to_cpu(inf->info.linkstatus.linkstatus); - - schedule_work(&hw->link_bh); -} - -/* - * prism2sta_inf_assocstatus - * - * Handles the receipt of an Association Status info frame. Should - * be present in APs only. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to info frame (contents in hfa384x order) - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -static void prism2sta_inf_assocstatus(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - struct hfa384x *hw = wlandev->priv; - struct hfa384x_assoc_status rec; - int i; - - memcpy(&rec, &inf->info.assocstatus, sizeof(rec)); - le16_to_cpus(&rec.assocstatus); - le16_to_cpus(&rec.reason); - - /* - * Find the address in the list of authenticated stations. - * If it wasn't found, then this address has not been previously - * authenticated and something weird has happened if this is - * anything other than an "authentication failed" message. - * If the address was found, then set the "associated" flag for - * that station, based on whether the station is associating or - * losing its association. Something weird has also happened - * if we find the address in the list of authenticated stations - * but we are getting an "authentication failed" message. - */ - - for (i = 0; i < hw->authlist.cnt; i++) - if (ether_addr_equal(rec.sta_addr, hw->authlist.addr[i])) - break; - - if (i >= hw->authlist.cnt) { - if (rec.assocstatus != HFA384x_ASSOCSTATUS_AUTHFAIL) - netdev_warn(wlandev->netdev, - "assocstatus info frame received for non-authenticated station.\n"); - } else { - hw->authlist.assoc[i] = - (rec.assocstatus == HFA384x_ASSOCSTATUS_STAASSOC || - rec.assocstatus == HFA384x_ASSOCSTATUS_REASSOC); - - if (rec.assocstatus == HFA384x_ASSOCSTATUS_AUTHFAIL) - netdev_warn(wlandev->netdev, - "authfail assocstatus info frame received for authenticated station.\n"); - } -} - -/* - * prism2sta_inf_authreq - * - * Handles the receipt of an Authentication Request info frame. Should - * be present in APs only. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to info frame (contents in hfa384x order) - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - * - */ -static void prism2sta_inf_authreq(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - struct hfa384x *hw = wlandev->priv; - struct sk_buff *skb; - - skb = dev_alloc_skb(sizeof(*inf)); - if (skb) { - skb_put(skb, sizeof(*inf)); - memcpy(skb->data, inf, sizeof(*inf)); - skb_queue_tail(&hw->authq, skb); - schedule_work(&hw->link_bh); - } -} - -static void prism2sta_inf_authreq_defer(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - struct hfa384x *hw = wlandev->priv; - struct hfa384x_authenticate_station_data rec; - - int i, added, result, cnt; - u8 *addr; - - /* - * Build the AuthenticateStation record. Initialize it for denying - * authentication. - */ - - ether_addr_copy(rec.address, inf->info.authreq.sta_addr); - rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure); - - /* - * Authenticate based on the access mode. - */ - - switch (hw->accessmode) { - case WLAN_ACCESS_NONE: - - /* - * Deny all new authentications. However, if a station - * is ALREADY authenticated, then accept it. - */ - - for (i = 0; i < hw->authlist.cnt; i++) - if (ether_addr_equal(rec.address, - hw->authlist.addr[i])) { - rec.status = cpu_to_le16(P80211ENUM_status_successful); - break; - } - - break; - - case WLAN_ACCESS_ALL: - - /* - * Allow all authentications. - */ - - rec.status = cpu_to_le16(P80211ENUM_status_successful); - break; - - case WLAN_ACCESS_ALLOW: - - /* - * Only allow the authentication if the MAC address - * is in the list of allowed addresses. - * - * Since this is the interrupt handler, we may be here - * while the access list is in the middle of being - * updated. Choose the list which is currently okay. - * See "prism2mib_priv_accessallow()" for details. - */ - - if (hw->allow.modify == 0) { - cnt = hw->allow.cnt; - addr = hw->allow.addr[0]; - } else { - cnt = hw->allow.cnt1; - addr = hw->allow.addr1[0]; - } - - for (i = 0; i < cnt; i++, addr += ETH_ALEN) - if (ether_addr_equal(rec.address, addr)) { - rec.status = cpu_to_le16(P80211ENUM_status_successful); - break; - } - - break; - - case WLAN_ACCESS_DENY: - - /* - * Allow the authentication UNLESS the MAC address is - * in the list of denied addresses. - * - * Since this is the interrupt handler, we may be here - * while the access list is in the middle of being - * updated. Choose the list which is currently okay. - * See "prism2mib_priv_accessdeny()" for details. - */ - - if (hw->deny.modify == 0) { - cnt = hw->deny.cnt; - addr = hw->deny.addr[0]; - } else { - cnt = hw->deny.cnt1; - addr = hw->deny.addr1[0]; - } - - rec.status = cpu_to_le16(P80211ENUM_status_successful); - - for (i = 0; i < cnt; i++, addr += ETH_ALEN) - if (ether_addr_equal(rec.address, addr)) { - rec.status = cpu_to_le16(P80211ENUM_status_unspec_failure); - break; - } - - break; - } - - /* - * If the authentication is okay, then add the MAC address to the - * list of authenticated stations. Don't add the address if it - * is already in the list. (802.11b does not seem to disallow - * a station from issuing an authentication request when the - * station is already authenticated. Does this sort of thing - * ever happen? We might as well do the check just in case.) - */ - - added = 0; - - if (rec.status == cpu_to_le16(P80211ENUM_status_successful)) { - for (i = 0; i < hw->authlist.cnt; i++) - if (ether_addr_equal(rec.address, - hw->authlist.addr[i])) - break; - - if (i >= hw->authlist.cnt) { - if (hw->authlist.cnt >= WLAN_AUTH_MAX) { - rec.status = cpu_to_le16(P80211ENUM_status_ap_full); - } else { - ether_addr_copy(hw->authlist.addr[hw->authlist.cnt], - rec.address); - hw->authlist.cnt++; - added = 1; - } - } - } - - /* - * Send back the results of the authentication. If this doesn't work, - * then make sure to remove the address from the authenticated list if - * it was added. - */ - - rec.algorithm = inf->info.authreq.algorithm; - - result = hfa384x_drvr_setconfig(hw, HFA384x_RID_AUTHENTICATESTA, - &rec, sizeof(rec)); - if (result) { - if (added) - hw->authlist.cnt--; - netdev_err(wlandev->netdev, - "setconfig(authenticatestation) failed, result=%d\n", - result); - } -} - -/* - * prism2sta_inf_psusercnt - * - * Handles the receipt of a PowerSaveUserCount info frame. Should - * be present in APs only. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to info frame (contents in hfa384x order) - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -static void prism2sta_inf_psusercnt(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - struct hfa384x *hw = wlandev->priv; - - hw->psusercount = le16_to_cpu(inf->info.psusercnt.usercnt); -} - -/* - * prism2sta_ev_info - * - * Handles the Info event. - * - * Arguments: - * wlandev wlan device structure - * inf ptr to a generic info frame - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -void prism2sta_ev_info(struct wlandevice *wlandev, - struct hfa384x_inf_frame *inf) -{ - le16_to_cpus(&inf->infotype); - /* Dispatch */ - switch (inf->infotype) { - case HFA384x_IT_HANDOVERADDR: - netdev_dbg(wlandev->netdev, - "received infoframe:HANDOVER (unhandled)\n"); - break; - case HFA384x_IT_COMMTALLIES: - prism2sta_inf_tallies(wlandev, inf); - break; - case HFA384x_IT_HOSTSCANRESULTS: - prism2sta_inf_hostscanresults(wlandev, inf); - break; - case HFA384x_IT_SCANRESULTS: - prism2sta_inf_scanresults(wlandev, inf); - break; - case HFA384x_IT_CHINFORESULTS: - prism2sta_inf_chinforesults(wlandev, inf); - break; - case HFA384x_IT_LINKSTATUS: - prism2sta_inf_linkstatus(wlandev, inf); - break; - case HFA384x_IT_ASSOCSTATUS: - prism2sta_inf_assocstatus(wlandev, inf); - break; - case HFA384x_IT_AUTHREQ: - prism2sta_inf_authreq(wlandev, inf); - break; - case HFA384x_IT_PSUSERCNT: - prism2sta_inf_psusercnt(wlandev, inf); - break; - case HFA384x_IT_KEYIDCHANGED: - netdev_warn(wlandev->netdev, "Unhandled IT_KEYIDCHANGED\n"); - break; - case HFA384x_IT_ASSOCREQ: - netdev_warn(wlandev->netdev, "Unhandled IT_ASSOCREQ\n"); - break; - case HFA384x_IT_MICFAILURE: - netdev_warn(wlandev->netdev, "Unhandled IT_MICFAILURE\n"); - break; - default: - netdev_warn(wlandev->netdev, - "Unknown info type=0x%02x\n", inf->infotype); - break; - } -} - -/* - * prism2sta_ev_tx - * - * Handles the Tx event. - * - * Arguments: - * wlandev wlan device structure - * status tx frame status word - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -void prism2sta_ev_tx(struct wlandevice *wlandev, u16 status) -{ - netdev_dbg(wlandev->netdev, "Tx Complete, status=0x%04x\n", status); - /* update linux network stats */ - wlandev->netdev->stats.tx_packets++; -} - -/* - * prism2sta_ev_alloc - * - * Handles the Alloc event. - * - * Arguments: - * wlandev wlan device structure - * - * Returns: - * nothing - * - * Side effects: - * - * Call context: - * interrupt - */ -void prism2sta_ev_alloc(struct wlandevice *wlandev) -{ - netif_wake_queue(wlandev->netdev); -} - -/* - * create_wlan - * - * Called at module init time. This creates the struct wlandevice structure - * and initializes it with relevant bits. - * - * Arguments: - * none - * - * Returns: - * the created struct wlandevice structure. - * - * Side effects: - * also allocates the priv/hw structures. - * - * Call context: - * process thread - * - */ -static struct wlandevice *create_wlan(void) -{ - struct wlandevice *wlandev = NULL; - struct hfa384x *hw = NULL; - - /* Alloc our structures */ - wlandev = kzalloc(sizeof(*wlandev), GFP_KERNEL); - hw = kzalloc(sizeof(*hw), GFP_KERNEL); - - if (!wlandev || !hw) { - kfree(wlandev); - kfree(hw); - return NULL; - } - - /* Initialize the network device object. */ - wlandev->nsdname = dev_info; - wlandev->msdstate = WLAN_MSD_HWPRESENT_PENDING; - wlandev->priv = hw; - wlandev->open = prism2sta_open; - wlandev->close = prism2sta_close; - wlandev->reset = prism2sta_reset; - wlandev->txframe = prism2sta_txframe; - wlandev->mlmerequest = prism2sta_mlmerequest; - wlandev->set_multicast_list = prism2sta_setmulticast; - wlandev->tx_timeout = hfa384x_tx_timeout; - - wlandev->nsdcaps = P80211_NSDCAP_HWFRAGMENT | P80211_NSDCAP_AUTOJOIN; - - /* Initialize the device private data structure. */ - hw->dot11_desired_bss_type = 1; - - return wlandev; -} - -void prism2sta_commsqual_defer(struct work_struct *data) -{ - struct hfa384x *hw = container_of(data, struct hfa384x, commsqual_bh); - struct wlandevice *wlandev = hw->wlandev; - struct hfa384x_bytestr32 ssid; - struct p80211msg_dot11req_mibget msg; - struct p80211item_uint32 *mibitem = (struct p80211item_uint32 *) - &msg.mibattribute.data; - int result = 0; - - if (hw->wlandev->hwremoved) - return; - - /* we don't care if we're in AP mode */ - if ((wlandev->macmode == WLAN_MACMODE_NONE) || - (wlandev->macmode == WLAN_MACMODE_ESS_AP)) { - return; - } - - /* It only makes sense to poll these in non-IBSS */ - if (wlandev->macmode != WLAN_MACMODE_IBSS_STA) { - result = hfa384x_drvr_getconfig(hw, HFA384x_RID_DBMCOMMSQUALITY, - &hw->qual, HFA384x_RID_DBMCOMMSQUALITY_LEN); - - if (result) { - netdev_err(wlandev->netdev, "error fetching commsqual\n"); - return; - } - - netdev_dbg(wlandev->netdev, "commsqual %d %d %d\n", - le16_to_cpu(hw->qual.cq_curr_bss), - le16_to_cpu(hw->qual.asl_curr_bss), - le16_to_cpu(hw->qual.anl_curr_fc)); - } - - /* Get the signal rate */ - msg.msgcode = DIDMSG_DOT11REQ_MIBGET; - mibitem->did = DIDMIB_P2_MAC_CURRENTTXRATE; - result = p80211req_dorequest(wlandev, (u8 *)&msg); - - if (result) { - netdev_dbg(wlandev->netdev, - "get signal rate failed, result = %d\n", result); - return; - } - - switch (mibitem->data) { - case HFA384x_RATEBIT_1: - hw->txrate = 10; - break; - case HFA384x_RATEBIT_2: - hw->txrate = 20; - break; - case HFA384x_RATEBIT_5dot5: - hw->txrate = 55; - break; - case HFA384x_RATEBIT_11: - hw->txrate = 110; - break; - default: - netdev_dbg(wlandev->netdev, "Bad ratebit (%d)\n", - mibitem->data); - } - - /* Lastly, we need to make sure the BSSID didn't change on us */ - result = hfa384x_drvr_getconfig(hw, - HFA384x_RID_CURRENTBSSID, - wlandev->bssid, WLAN_BSSID_LEN); - if (result) { - netdev_dbg(wlandev->netdev, - "getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTBSSID, result); - return; - } - - result = hfa384x_drvr_getconfig(hw, - HFA384x_RID_CURRENTSSID, - &ssid, sizeof(ssid)); - if (result) { - netdev_dbg(wlandev->netdev, - "getconfig(0x%02x) failed, result = %d\n", - HFA384x_RID_CURRENTSSID, result); - return; - } - prism2mgmt_bytestr2pstr((struct hfa384x_bytestr *)&ssid, - (struct p80211pstrd *)&wlandev->ssid); - - /* Reschedule timer */ - mod_timer(&hw->commsqual_timer, jiffies + HZ); -} - -void prism2sta_commsqual_timer(struct timer_list *t) -{ - struct hfa384x *hw = from_timer(hw, t, commsqual_timer); - - schedule_work(&hw->commsqual_bh); -} diff --git a/drivers/staging/wlan-ng/prism2usb.c b/drivers/staging/wlan-ng/prism2usb.c deleted file mode 100644 index 0e0ccef4871e..000000000000 --- a/drivers/staging/wlan-ng/prism2usb.c +++ /dev/null @@ -1,299 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include "hfa384x_usb.c" -#include "prism2mgmt.c" -#include "prism2mib.c" -#include "prism2sta.c" -#include "prism2fw.c" - -#define PRISM_DEV(vid, pid, name) \ - { USB_DEVICE(vid, pid), \ - .driver_info = (unsigned long)name } - -static const struct usb_device_id usb_prism_tbl[] = { - PRISM_DEV(0x04bb, 0x0922, "IOData AirPort WN-B11/USBS"), - PRISM_DEV(0x07aa, 0x0012, "Corega USB Wireless LAN Stick-11"), - PRISM_DEV(0x09aa, 0x3642, "Prism2.x 11Mbps USB WLAN Adapter"), - PRISM_DEV(0x1668, 0x0408, "Actiontec Prism2.5 11Mbps USB WLAN Adapter"), - PRISM_DEV(0x1668, 0x0421, "Actiontec Prism2.5 11Mbps USB WLAN Adapter"), - PRISM_DEV(0x1915, 0x2236, "Linksys WUSB11v3.0 11Mbps USB WLAN Adapter"), - PRISM_DEV(0x066b, 0x2212, "Linksys WUSB11v2.5 11Mbps USB WLAN Adapter"), - PRISM_DEV(0x066b, 0x2213, "Linksys WUSB12v1.1 11Mbps USB WLAN Adapter"), - PRISM_DEV(0x0411, 0x0016, "Melco WLI-USB-S11 11Mbps WLAN Adapter"), - PRISM_DEV(0x08de, 0x7a01, "PRISM25 USB IEEE 802.11 Mini Adapter"), - PRISM_DEV(0x8086, 0x1111, "Intel PRO/Wireless 2011B USB LAN Adapter"), - PRISM_DEV(0x0d8e, 0x7a01, "PRISM25 IEEE 802.11 Mini USB Adapter"), - PRISM_DEV(0x045e, 0x006e, "Microsoft MN510 USB Wireless Adapter"), - PRISM_DEV(0x0967, 0x0204, "Acer Warplink USB Adapter"), - PRISM_DEV(0x0cde, 0x0002, "Z-Com 725/726 Prism2.5 USB/USB Integrated"), - PRISM_DEV(0x0cde, 0x0005, "Z-Com Xl735 USB Wireless 802.11b Adapter"), - PRISM_DEV(0x413c, 0x8100, "Dell TrueMobile 1180 USB Wireless Adapter"), - PRISM_DEV(0x0b3b, 0x1601, "ALLNET 0193 11Mbps USB WLAN Adapter"), - PRISM_DEV(0x0b3b, 0x1602, "ZyXEL ZyAIR B200 USB Wireless Adapter"), - PRISM_DEV(0x0baf, 0x00eb, "USRobotics USR1120 USB Wireless Adapter"), - PRISM_DEV(0x0411, 0x0027, "Melco WLI-USB-KS11G 11Mbps WLAN Adapter"), - PRISM_DEV(0x04f1, 0x3009, "JVC MP-XP7250 Builtin USB WLAN Adapter"), - PRISM_DEV(0x0846, 0x4110, "NetGear MA111"), - PRISM_DEV(0x03f3, 0x0020, "Adaptec AWN-8020 USB WLAN Adapter"), - PRISM_DEV(0x2821, 0x3300, "ASUS-WL140 / Hawking HighDB USB Wireless Adapter"), - PRISM_DEV(0x2001, 0x3700, "DWL-122 USB Wireless Adapter"), - PRISM_DEV(0x2001, 0x3702, "DWL-120 Rev F USB Wireless Adapter"), - PRISM_DEV(0x50c2, 0x4013, "Averatec USB WLAN Adapter"), - PRISM_DEV(0x2c02, 0x14ea, "Planex GW-US11H USB WLAN Adapter"), - PRISM_DEV(0x124a, 0x168b, "Airvast PRISM3 USB WLAN Adapter"), - PRISM_DEV(0x083a, 0x3503, "T-Sinus 111 USB WLAN Adapter"), - PRISM_DEV(0x0411, 0x0044, "Melco WLI-USB-KB11 11Mbps WLAN Adapter"), - PRISM_DEV(0x1668, 0x6106, "ROPEX FreeLan USB 802.11b Adapter"), - PRISM_DEV(0x124a, 0x4017, "Pheenet WL-503IA USB 802.11b Adapter"), - PRISM_DEV(0x0bb2, 0x0302, "Ambit Microsystems Corp."), - PRISM_DEV(0x9016, 0x182d, "Sitecom WL-022 USB 802.11b Adapter"), - PRISM_DEV(0x0543, 0x0f01, - "ViewSonic Airsync USB Adapter 11Mbps (Prism2.5)"), - PRISM_DEV(0x067c, 0x1022, - "Siemens SpeedStream 1022 11Mbps USB WLAN Adapter"), - PRISM_DEV(0x049f, 0x0033, - "Compaq/Intel W100 PRO/Wireless 11Mbps multiport WLAN Adapter"), - { } /* terminator */ -}; -MODULE_DEVICE_TABLE(usb, usb_prism_tbl); - -static int prism2sta_probe_usb(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct usb_device *dev; - struct usb_endpoint_descriptor *bulk_in, *bulk_out; - struct usb_host_interface *iface_desc = interface->cur_altsetting; - struct wlandevice *wlandev = NULL; - struct hfa384x *hw = NULL; - int result = 0; - - result = usb_find_common_endpoints(iface_desc, &bulk_in, &bulk_out, NULL, NULL); - if (result) - goto failed; - - dev = interface_to_usbdev(interface); - wlandev = create_wlan(); - if (!wlandev) { - dev_err(&interface->dev, "Memory allocation failure.\n"); - result = -EIO; - goto failed; - } - hw = wlandev->priv; - - if (wlan_setup(wlandev, &interface->dev) != 0) { - dev_err(&interface->dev, "wlan_setup() failed.\n"); - result = -EIO; - goto failed; - } - - /* Initialize the hw data */ - hw->endp_in = usb_rcvbulkpipe(dev, bulk_in->bEndpointAddress); - hw->endp_out = usb_sndbulkpipe(dev, bulk_out->bEndpointAddress); - hfa384x_create(hw, dev); - hw->wlandev = wlandev; - - /* Register the wlandev, this gets us a name and registers the - * linux netdevice. - */ - SET_NETDEV_DEV(wlandev->netdev, &interface->dev); - - /* Do a chip-level reset on the MAC */ - if (prism2_doreset) { - result = hfa384x_corereset(hw, - prism2_reset_holdtime, - prism2_reset_settletime, 0); - if (result != 0) { - result = -EIO; - dev_err(&interface->dev, - "hfa384x_corereset() failed.\n"); - goto failed_reset; - } - } - - usb_get_dev(dev); - - wlandev->msdstate = WLAN_MSD_HWPRESENT; - - /* Try and load firmware, then enable card before we register */ - prism2_fwtry(dev, wlandev); - prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable); - - if (register_wlandev(wlandev) != 0) { - dev_err(&interface->dev, "register_wlandev() failed.\n"); - result = -EIO; - goto failed_register; - } - - goto done; - -failed_register: - usb_put_dev(dev); -failed_reset: - wlan_unsetup(wlandev); -failed: - kfree(wlandev); - kfree(hw); - wlandev = NULL; - -done: - usb_set_intfdata(interface, wlandev); - return result; -} - -static void prism2sta_disconnect_usb(struct usb_interface *interface) -{ - struct wlandevice *wlandev; - - wlandev = usb_get_intfdata(interface); - if (wlandev) { - LIST_HEAD(cleanlist); - struct hfa384x_usbctlx *ctlx, *temp; - unsigned long flags; - - struct hfa384x *hw = wlandev->priv; - - if (!hw) - goto exit; - - spin_lock_irqsave(&hw->ctlxq.lock, flags); - - p80211netdev_hwremoved(wlandev); - list_splice_init(&hw->ctlxq.reapable, &cleanlist); - list_splice_init(&hw->ctlxq.completing, &cleanlist); - list_splice_init(&hw->ctlxq.pending, &cleanlist); - list_splice_init(&hw->ctlxq.active, &cleanlist); - - spin_unlock_irqrestore(&hw->ctlxq.lock, flags); - - /* There's no hardware to shutdown, but the driver - * might have some tasks that must be stopped before - * we can tear everything down. - */ - prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable); - - timer_shutdown_sync(&hw->throttle); - timer_shutdown_sync(&hw->reqtimer); - timer_shutdown_sync(&hw->resptimer); - - /* Unlink all the URBs. This "removes the wheels" - * from the entire CTLX handling mechanism. - */ - usb_kill_urb(&hw->rx_urb); - usb_kill_urb(&hw->tx_urb); - usb_kill_urb(&hw->ctlx_urb); - - cancel_work_sync(&hw->completion_bh); - cancel_work_sync(&hw->reaper_bh); - - cancel_work_sync(&hw->link_bh); - cancel_work_sync(&hw->commsqual_bh); - cancel_work_sync(&hw->usb_work); - - /* Now we complete any outstanding commands - * and tell everyone who is waiting for their - * responses that we have shut down. - */ - list_for_each_entry(ctlx, &cleanlist, list) - complete(&ctlx->done); - - /* Give any outstanding synchronous commands - * a chance to complete. All they need to do - * is "wake up", so that's easy. - * (I'd like a better way to do this, really.) - */ - msleep(100); - - /* Now delete the CTLXs, because no-one else can now. */ - list_for_each_entry_safe(ctlx, temp, &cleanlist, list) - kfree(ctlx); - - /* Unhook the wlandev */ - unregister_wlandev(wlandev); - wlan_unsetup(wlandev); - - usb_put_dev(hw->usb); - - hfa384x_destroy(hw); - kfree(hw); - - kfree(wlandev); - } - -exit: - usb_set_intfdata(interface, NULL); -} - -#ifdef CONFIG_PM -static int prism2sta_suspend(struct usb_interface *interface, - pm_message_t message) -{ - struct hfa384x *hw = NULL; - struct wlandevice *wlandev; - - wlandev = usb_get_intfdata(interface); - if (!wlandev) - return -ENODEV; - - hw = wlandev->priv; - if (!hw) - return -ENODEV; - - prism2sta_ifstate(wlandev, P80211ENUM_ifstate_disable); - - usb_kill_urb(&hw->rx_urb); - usb_kill_urb(&hw->tx_urb); - usb_kill_urb(&hw->ctlx_urb); - - return 0; -} - -static int prism2sta_resume(struct usb_interface *interface) -{ - int result = 0; - struct hfa384x *hw = NULL; - struct wlandevice *wlandev; - - wlandev = usb_get_intfdata(interface); - if (!wlandev) - return -ENODEV; - - hw = wlandev->priv; - if (!hw) - return -ENODEV; - - /* Do a chip-level reset on the MAC */ - if (prism2_doreset) { - result = hfa384x_corereset(hw, - prism2_reset_holdtime, - prism2_reset_settletime, 0); - if (result != 0) { - unregister_wlandev(wlandev); - hfa384x_destroy(hw); - dev_err(&interface->dev, "hfa384x_corereset() failed.\n"); - kfree(wlandev); - kfree(hw); - wlandev = NULL; - return -ENODEV; - } - } - - prism2sta_ifstate(wlandev, P80211ENUM_ifstate_enable); - - return 0; -} -#else -#define prism2sta_suspend NULL -#define prism2sta_resume NULL -#endif /* CONFIG_PM */ - -static struct usb_driver prism2_usb_driver = { - .name = "prism2_usb", - .probe = prism2sta_probe_usb, - .disconnect = prism2sta_disconnect_usb, - .id_table = usb_prism_tbl, - .suspend = prism2sta_suspend, - .resume = prism2sta_resume, - .reset_resume = prism2sta_resume, - /* fops, minor? */ -}; - -module_usb_driver(prism2_usb_driver); |