diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-22 12:11:48 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-05-22 12:11:48 -0700 |
commit | be81389c82e2c1ed0997629cb3d910f584666e33 (patch) | |
tree | f5e7e34d3d13ae9b1c70c562bfb1f2eba7bd1684 /drivers/staging | |
parent | f6b8e86b7a65495d3947a1d1fc22183c52f786f6 (diff) | |
parent | eb563dc752d33b0a5d4952964af15ca892f59524 (diff) |
Merge tag 'staging-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging driver updates from Greg KH:
"Here is the big set of staging driver changes for 6.10-rc1. Not a lot
of cleanups happening this kernel release, intern applications must be
out of sync at the moment. But we did delete two drivers, wlan-ng and
pi433, as they are no longer in use and the developers involved wanted
them just gone entirely, allowing us to drop 19k lines from the tree.
Other than the normal coding style cleanups here, there has been a lot
of work on the vc04_services code, with the intent to finally get that
out of staging hopefully soon. It's getting closer, which is nice to
see.
All of these have been in linux-next for a while with no reported
issues"
* tag 'staging-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: (98 commits)
staging: pi433: Remove unused driver
staging: vchiq_core: Add missing blank lines
staging: vchiq_core: Drop unnecessary blank lines
staging: vchiq_core: Add parentheses to VCHIQ_MSG_SRCPORT
staging: vchiq_core: Use printk messages for devices
staging: vchiq_arm: Drop unnecessary NULL check
staging: vc04_services: Delete unnecessary NULL check
staging: vc04_services: vchiq_arm: Fix NULL ptr dereferences
Staging: rtl8192e: Rename variable DssCCk
Staging: rtl8192e: Rename variable ExtHTCapInfo
Staging: rtl8192e: Rename variable MPDUDensity
Staging: rtl8192e: Rename variable MaxRxAMPDUFactor
Staging: rtl8192e: Rename variable MaxAMSDUSize
Staging: rtl8192e: Rename variable DelayBA
Staging: rtl8192e: Rename variable RxSTBC
Staging: rtl8192e: Rename variable TxSTBC
Staging: rtl8192e: Rename variable GreenField
Staging: rtl8192e: Rename variable ShortGI20Mhz
Staging: rtl8192e: Rename variable ShortGI40Mhz
Staging: rtl8192e: Rename variable MimoPwrSave
...
Diffstat (limited to 'drivers/staging')
97 files changed, 532 insertions, 19332 deletions
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); |