Staging driver changes for 6.10-rc1

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.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 
 iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCZk4A+Q8cZ3JlZ0Brcm9h
 aC5jb20ACgkQMUfUDdst+yn80gCffliMWrtWk55FBGs21J9o1OqgS5IAoLUD00hc
 ooGXzYDfwLk6/6wXnvZq
 =JLeh
 -----END PGP SIGNATURE-----

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
  ...
This commit is contained in:
Linus Torvalds 2024-05-22 12:11:48 -07:00
commit be81389c82
98 changed files with 531 additions and 19331 deletions

View file

@ -21241,7 +21241,7 @@ S: Maintained
F: drivers/staging/sm750fb/
STAGING - VIA VT665X DRIVERS
M: Forest Bond <forest@alittletooquiet.net>
M: Philipp Hortmann <philipp.g.hortmann@gmail.com>
S: Odd Fixes
F: drivers/staging/vt665?/

View file

@ -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"

View file

@ -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/

View file

@ -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) {

View file

@ -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"

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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 */

View file

@ -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");

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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>;
};
};

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -1,4 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_PI433) += pi433.o
pi433-objs := pi433_if.o rf69.o

View file

@ -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.

File diff suppressed because it is too large Load diff

View file

@ -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 */

View file

@ -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);
}

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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;
}

View file

@ -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);

View file

@ -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,

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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->chl_width = 1;
cap_ele->MimoPwrSave = 3;
cap_ele->GreenField = 0;
cap_ele->ShortGI20Mhz = 1;
cap_ele->ShortGI40Mhz = 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->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->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__,

View file

@ -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,

View file

@ -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;

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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 {

View file

@ -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 @@ void rtw_update_scanned_network(struct adapter *adapter, struct wlan_bssid_ex *t
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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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.
running on VideoCore.

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -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.

View file

@ -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 = {

View file

@ -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

View file

@ -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);

View file

@ -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 {

View file

@ -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);
}

View file

@ -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 */

View file

@ -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(&quota_spinlock);
spin_lock(&state->quota_spinlock);
count = quota->message_use_count;
if (count > 0)
quota->message_use_count = count - 1;
spin_unlock(&quota_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(&quota_spinlock);
spin_lock(&state->quota_spinlock);
count = quota->slot_use_count;
if (count > 0)
quota->slot_use_count = count - 1;
spin_unlock(&quota_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(&quota_spinlock);
spin_lock(&state->quota_spinlock);
count = state->data_use_count;
if (count > 0)
state->data_use_count = count - 1;
spin_unlock(&quota_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(&quota_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(&quota_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(&quota_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(&quota_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(&quota_spinlock);
spin_lock(&state->quota_spinlock);
tx_end_index = SLOT_QUEUE_INDEX_FROM_POS(state->local_tx_pos + stride - 1);
}
spin_unlock(&quota_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(&quota_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(&quota_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(&quota->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);

View file

@ -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
@ -470,12 +477,6 @@ vchiq_bulk_transfer(struct vchiq_instance *instance, unsigned int handle, void *
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);

View file

@ -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);

View file

@ -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);
}

View file

@ -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);

View file

@ -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

View file

@ -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__ */

View file

@ -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);

View file

@ -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.

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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(&params, 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, &params);
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);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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);
}

View file

@ -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

View file

@ -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 */

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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 */

View file

@ -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);
}
}

View file

@ -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

View file

@ -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;
}
}
}

View file

@ -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

View file

@ -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 */

View file

@ -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;
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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);
}

File diff suppressed because it is too large Load diff

View file

@ -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);