mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-29 23:24:11 +08:00
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
This commit is contained in:
commit
ae3568adf4
20
MAINTAINERS
20
MAINTAINERS
@ -3671,7 +3671,7 @@ F: include/linux/mv643xx.h
|
||||
MARVELL MWL8K WIRELESS DRIVER
|
||||
M: Lennert Buytenhek <buytenh@wantstofly.org>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Odd Fixes
|
||||
F: drivers/net/wireless/mwl8k.c
|
||||
|
||||
MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER
|
||||
@ -4522,7 +4522,7 @@ PRISM54 WIRELESS DRIVER
|
||||
M: "Luis R. Rodriguez" <mcgrof@gmail.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://prism54.org
|
||||
S: Maintained
|
||||
S: Obsolete
|
||||
F: drivers/net/wireless/prism54/
|
||||
|
||||
PROMISE DC4030 CACHING DISK CONTROLLER DRIVER
|
||||
@ -4712,9 +4712,8 @@ S: Maintained
|
||||
F: drivers/rapidio/
|
||||
|
||||
RAYLINK/WEBGEAR 802.11 WIRELESS LAN DRIVER
|
||||
M: Corey Thomas <coreythomas@charter.net>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/ray*
|
||||
|
||||
RCUTORTURE MODULE
|
||||
@ -6037,10 +6036,9 @@ F: Documentation/video4linux/zc0301.txt
|
||||
F: drivers/media/video/zc0301/
|
||||
|
||||
USB ZD1201 DRIVER
|
||||
M: Jeroen Vreeken <pe1rxq@amsat.org>
|
||||
L: linux-usb@vger.kernel.org
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://linux-lc100020.sourceforge.net
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: drivers/net/wireless/zd1201.*
|
||||
|
||||
USB ZR364XX DRIVER
|
||||
@ -6226,14 +6224,6 @@ F: Documentation/watchdog/
|
||||
F: drivers/watchdog/
|
||||
F: include/linux/watchdog.h
|
||||
|
||||
WAVELAN NETWORK DRIVER & WIRELESS EXTENSIONS
|
||||
M: Jean Tourrilhes <jt@hpl.hp.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
W: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/
|
||||
S: Maintained
|
||||
F: Documentation/networking/wavelan.txt
|
||||
F: drivers/staging/wavelan/
|
||||
|
||||
WD7000 SCSI DRIVER
|
||||
M: Miroslav Zagorac <zaga@fly.cc.fer.hr>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
|
@ -58,6 +58,18 @@ config BT_HCIUART_BCSP
|
||||
|
||||
Say Y here to compile support for HCI BCSP protocol.
|
||||
|
||||
config BT_HCIUART_ATH3K
|
||||
bool "Atheros AR300x serial support"
|
||||
depends on BT_HCIUART
|
||||
help
|
||||
HCIATH3K (HCI Atheros AR300x) is a serial protocol for
|
||||
communication between host and Atheros AR300x Bluetooth devices.
|
||||
This protocol enables AR300x chips to be enabled with
|
||||
power management support.
|
||||
Enable this if you have Atheros AR300x serial Bluetooth device.
|
||||
|
||||
Say Y here to compile support for HCI UART ATH3K protocol.
|
||||
|
||||
config BT_HCIUART_LL
|
||||
bool "HCILL protocol support"
|
||||
depends on BT_HCIUART
|
||||
|
@ -26,4 +26,5 @@ hci_uart-y := hci_ldisc.o
|
||||
hci_uart-$(CONFIG_BT_HCIUART_H4) += hci_h4.o
|
||||
hci_uart-$(CONFIG_BT_HCIUART_BCSP) += hci_bcsp.o
|
||||
hci_uart-$(CONFIG_BT_HCIUART_LL) += hci_ll.o
|
||||
hci_uart-$(CONFIG_BT_HCIUART_ATH3K) += hci_ath.o
|
||||
hci_uart-objs := $(hci_uart-y)
|
||||
|
@ -224,7 +224,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
|
||||
BT_DBG("firmware data %p size %zu", firmware->data, firmware->size);
|
||||
|
||||
data->fw_data = kmalloc(firmware->size, GFP_KERNEL);
|
||||
data->fw_data = kmemdup(firmware->data, firmware->size, GFP_KERNEL);
|
||||
if (!data->fw_data) {
|
||||
BT_ERR("Can't allocate memory for firmware image");
|
||||
release_firmware(firmware);
|
||||
@ -234,7 +234,6 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memcpy(data->fw_data, firmware->data, firmware->size);
|
||||
data->fw_size = firmware->size;
|
||||
data->fw_sent = 0;
|
||||
|
||||
|
@ -62,7 +62,7 @@ struct hci_vendor_hdr {
|
||||
__u8 type;
|
||||
__le16 snum;
|
||||
__le16 dlen;
|
||||
} __attribute__ ((packed));
|
||||
} __packed;
|
||||
|
||||
static int bpa10x_recv(struct hci_dev *hdev, int queue, void *buf, int count)
|
||||
{
|
||||
|
@ -216,7 +216,7 @@ static const struct file_operations btmrvl_gpiogap_fops = {
|
||||
static ssize_t btmrvl_hscmd_write(struct file *file, const char __user *ubuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct btmrvl_private *priv = (struct btmrvl_private *) file->private_data;
|
||||
struct btmrvl_private *priv = file->private_data;
|
||||
char buf[16];
|
||||
long result, ret;
|
||||
|
||||
|
@ -76,6 +76,7 @@ struct btmrvl_private {
|
||||
int (*hw_host_to_card) (struct btmrvl_private *priv,
|
||||
u8 *payload, u16 nb);
|
||||
int (*hw_wakeup_firmware) (struct btmrvl_private *priv);
|
||||
int (*hw_process_int_status) (struct btmrvl_private *priv);
|
||||
spinlock_t driver_lock; /* spinlock used by driver */
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
void *debugfs_data;
|
||||
@ -118,13 +119,13 @@ struct btmrvl_cmd {
|
||||
__le16 ocf_ogf;
|
||||
u8 length;
|
||||
u8 data[4];
|
||||
} __attribute__ ((packed));
|
||||
} __packed;
|
||||
|
||||
struct btmrvl_event {
|
||||
u8 ec; /* event counter */
|
||||
u8 length;
|
||||
u8 data[4];
|
||||
} __attribute__ ((packed));
|
||||
} __packed;
|
||||
|
||||
/* Prototype of global function */
|
||||
|
||||
|
@ -502,14 +502,17 @@ static int btmrvl_service_main_thread(void *data)
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
if (adapter->int_count) {
|
||||
adapter->int_count = 0;
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
priv->hw_process_int_status(priv);
|
||||
} else if (adapter->ps_state == PS_SLEEP &&
|
||||
!skb_queue_empty(&adapter->tx_queue)) {
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
adapter->wakeup_tries++;
|
||||
priv->hw_wakeup_firmware(priv);
|
||||
continue;
|
||||
} else {
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
|
||||
if (adapter->ps_state == PS_SLEEP)
|
||||
continue;
|
||||
|
@ -47,6 +47,7 @@
|
||||
* module_exit function is called.
|
||||
*/
|
||||
static u8 user_rmmod;
|
||||
static u8 sdio_ireg;
|
||||
|
||||
static const struct btmrvl_sdio_device btmrvl_sdio_sd6888 = {
|
||||
.helper = "sd8688_helper.bin",
|
||||
@ -83,10 +84,10 @@ static int btmrvl_sdio_read_fw_status(struct btmrvl_sdio_card *card, u16 *dat)
|
||||
*dat = 0;
|
||||
|
||||
fws0 = sdio_readb(card->func, CARD_FW_STATUS0_REG, &ret);
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
if (!ret)
|
||||
fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret);
|
||||
|
||||
fws1 = sdio_readb(card->func, CARD_FW_STATUS1_REG, &ret);
|
||||
if (ret)
|
||||
return -EIO;
|
||||
|
||||
@ -216,7 +217,7 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
|
||||
|
||||
tmphlprbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
|
||||
|
||||
tmphlprbuf = kmalloc(tmphlprbufsz, GFP_KERNEL);
|
||||
tmphlprbuf = kzalloc(tmphlprbufsz, GFP_KERNEL);
|
||||
if (!tmphlprbuf) {
|
||||
BT_ERR("Unable to allocate buffer for helper."
|
||||
" Terminating download");
|
||||
@ -224,8 +225,6 @@ static int btmrvl_sdio_download_helper(struct btmrvl_sdio_card *card)
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(tmphlprbuf, 0, tmphlprbufsz);
|
||||
|
||||
helperbuf = (u8 *) ALIGN_ADDR(tmphlprbuf, BTSDIO_DMA_ALIGN);
|
||||
|
||||
/* Perform helper data transfer */
|
||||
@ -318,7 +317,7 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
|
||||
BT_DBG("Downloading FW image (%d bytes)", firmwarelen);
|
||||
|
||||
tmpfwbufsz = ALIGN_SZ(BTM_UPLD_SIZE, BTSDIO_DMA_ALIGN);
|
||||
tmpfwbuf = kmalloc(tmpfwbufsz, GFP_KERNEL);
|
||||
tmpfwbuf = kzalloc(tmpfwbufsz, GFP_KERNEL);
|
||||
if (!tmpfwbuf) {
|
||||
BT_ERR("Unable to allocate buffer for firmware."
|
||||
" Terminating download");
|
||||
@ -326,8 +325,6 @@ static int btmrvl_sdio_download_fw_w_helper(struct btmrvl_sdio_card *card)
|
||||
goto done;
|
||||
}
|
||||
|
||||
memset(tmpfwbuf, 0, tmpfwbufsz);
|
||||
|
||||
/* Ensure aligned firmware buffer */
|
||||
fwbuf = (u8 *) ALIGN_ADDR(tmpfwbuf, BTSDIO_DMA_ALIGN);
|
||||
|
||||
@ -555,78 +552,79 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int btmrvl_sdio_get_int_status(struct btmrvl_private *priv, u8 * ireg)
|
||||
static int btmrvl_sdio_process_int_status(struct btmrvl_private *priv)
|
||||
{
|
||||
int ret;
|
||||
u8 sdio_ireg = 0;
|
||||
ulong flags;
|
||||
u8 ireg;
|
||||
struct btmrvl_sdio_card *card = priv->btmrvl_dev.card;
|
||||
|
||||
*ireg = 0;
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
ireg = sdio_ireg;
|
||||
sdio_ireg = 0;
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
|
||||
sdio_ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
|
||||
if (ret) {
|
||||
BT_ERR("sdio_readb: read int status register failed");
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (sdio_ireg != 0) {
|
||||
/*
|
||||
* DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
|
||||
* Clear the interrupt status register and re-enable the
|
||||
* interrupt.
|
||||
*/
|
||||
BT_DBG("sdio_ireg = 0x%x", sdio_ireg);
|
||||
|
||||
sdio_writeb(card->func, ~(sdio_ireg) & (DN_LD_HOST_INT_STATUS |
|
||||
UP_LD_HOST_INT_STATUS),
|
||||
HOST_INTSTATUS_REG, &ret);
|
||||
if (ret) {
|
||||
BT_ERR("sdio_writeb: clear int status register "
|
||||
"failed");
|
||||
ret = -EIO;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
if (sdio_ireg & DN_LD_HOST_INT_STATUS) {
|
||||
sdio_claim_host(card->func);
|
||||
if (ireg & DN_LD_HOST_INT_STATUS) {
|
||||
if (priv->btmrvl_dev.tx_dnld_rdy)
|
||||
BT_DBG("tx_done already received: "
|
||||
" int_status=0x%x", sdio_ireg);
|
||||
" int_status=0x%x", ireg);
|
||||
else
|
||||
priv->btmrvl_dev.tx_dnld_rdy = true;
|
||||
}
|
||||
|
||||
if (sdio_ireg & UP_LD_HOST_INT_STATUS)
|
||||
if (ireg & UP_LD_HOST_INT_STATUS)
|
||||
btmrvl_sdio_card_to_host(priv);
|
||||
|
||||
*ireg = sdio_ireg;
|
||||
sdio_release_host(card->func);
|
||||
|
||||
ret = 0;
|
||||
|
||||
done:
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void btmrvl_sdio_interrupt(struct sdio_func *func)
|
||||
{
|
||||
struct btmrvl_private *priv;
|
||||
struct hci_dev *hcidev;
|
||||
struct btmrvl_sdio_card *card;
|
||||
ulong flags;
|
||||
u8 ireg = 0;
|
||||
int ret;
|
||||
|
||||
card = sdio_get_drvdata(func);
|
||||
if (card && card->priv) {
|
||||
priv = card->priv;
|
||||
hcidev = priv->btmrvl_dev.hcidev;
|
||||
|
||||
if (btmrvl_sdio_get_int_status(priv, &ireg))
|
||||
BT_ERR("reading HOST_INT_STATUS_REG failed");
|
||||
else
|
||||
BT_DBG("HOST_INT_STATUS_REG %#x", ireg);
|
||||
|
||||
btmrvl_interrupt(priv);
|
||||
if (!card || !card->priv) {
|
||||
BT_ERR("sbi_interrupt(%p) card or priv is "
|
||||
"NULL, card=%p\n", func, card);
|
||||
return;
|
||||
}
|
||||
|
||||
priv = card->priv;
|
||||
|
||||
ireg = sdio_readb(card->func, HOST_INTSTATUS_REG, &ret);
|
||||
if (ret) {
|
||||
BT_ERR("sdio_readb: read int status register failed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ireg != 0) {
|
||||
/*
|
||||
* DN_LD_HOST_INT_STATUS and/or UP_LD_HOST_INT_STATUS
|
||||
* Clear the interrupt status register and re-enable the
|
||||
* interrupt.
|
||||
*/
|
||||
BT_DBG("ireg = 0x%x", ireg);
|
||||
|
||||
sdio_writeb(card->func, ~(ireg) & (DN_LD_HOST_INT_STATUS |
|
||||
UP_LD_HOST_INT_STATUS),
|
||||
HOST_INTSTATUS_REG, &ret);
|
||||
if (ret) {
|
||||
BT_ERR("sdio_writeb: clear int status register failed");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
sdio_ireg |= ireg;
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
|
||||
btmrvl_interrupt(priv);
|
||||
}
|
||||
|
||||
static int btmrvl_sdio_register_dev(struct btmrvl_sdio_card *card)
|
||||
@ -930,6 +928,7 @@ static int btmrvl_sdio_probe(struct sdio_func *func,
|
||||
/* Initialize the interface specific function pointers */
|
||||
priv->hw_host_to_card = btmrvl_sdio_host_to_card;
|
||||
priv->hw_wakeup_firmware = btmrvl_sdio_wakeup_fw;
|
||||
priv->hw_process_int_status = btmrvl_sdio_process_int_status;
|
||||
|
||||
if (btmrvl_register_hdev(priv)) {
|
||||
BT_ERR("Register hdev failed!");
|
||||
|
@ -59,6 +59,9 @@ static struct usb_device_id btusb_table[] = {
|
||||
/* Generic Bluetooth USB device */
|
||||
{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
|
||||
|
||||
/* Apple iMac11,1 */
|
||||
{ USB_DEVICE(0x05ac, 0x8215) },
|
||||
|
||||
/* AVM BlueFRITZ! USB v2.0 */
|
||||
{ USB_DEVICE(0x057c, 0x3800) },
|
||||
|
||||
@ -146,6 +149,7 @@ static struct usb_device_id blacklist_table[] = {
|
||||
#define BTUSB_BULK_RUNNING 1
|
||||
#define BTUSB_ISOC_RUNNING 2
|
||||
#define BTUSB_SUSPENDING 3
|
||||
#define BTUSB_DID_ISO_RESUME 4
|
||||
|
||||
struct btusb_data {
|
||||
struct hci_dev *hdev;
|
||||
@ -179,7 +183,6 @@ struct btusb_data {
|
||||
unsigned int sco_num;
|
||||
int isoc_altsetting;
|
||||
int suspend_count;
|
||||
int did_iso_resume:1;
|
||||
};
|
||||
|
||||
static int inc_tx(struct btusb_data *data)
|
||||
@ -807,7 +810,7 @@ static void btusb_work(struct work_struct *work)
|
||||
int err;
|
||||
|
||||
if (hdev->conn_hash.sco_num > 0) {
|
||||
if (!data->did_iso_resume) {
|
||||
if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) {
|
||||
err = usb_autopm_get_interface(data->isoc);
|
||||
if (err < 0) {
|
||||
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
|
||||
@ -815,7 +818,7 @@ static void btusb_work(struct work_struct *work)
|
||||
return;
|
||||
}
|
||||
|
||||
data->did_iso_resume = 1;
|
||||
set_bit(BTUSB_DID_ISO_RESUME, &data->flags);
|
||||
}
|
||||
if (data->isoc_altsetting != 2) {
|
||||
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
|
||||
@ -836,10 +839,8 @@ static void btusb_work(struct work_struct *work)
|
||||
usb_kill_anchored_urbs(&data->isoc_anchor);
|
||||
|
||||
__set_isoc_interface(hdev, 0);
|
||||
if (data->did_iso_resume) {
|
||||
data->did_iso_resume = 0;
|
||||
if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags))
|
||||
usb_autopm_put_interface(data->isoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ typedef struct {
|
||||
u8 type;
|
||||
u8 zero;
|
||||
u16 len;
|
||||
} __attribute__ ((packed)) nsh_t; /* Nokia Specific Header */
|
||||
} __packed nsh_t; /* Nokia Specific Header */
|
||||
|
||||
#define NSHL 4 /* Nokia Specific Header Length */
|
||||
|
||||
|
235
drivers/bluetooth/hci_ath.c
Normal file
235
drivers/bluetooth/hci_ath.c
Normal file
@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Atheros Communication Bluetooth HCIATH3K UART protocol
|
||||
*
|
||||
* HCIATH3K (HCI Atheros AR300x Protocol) is a Atheros Communication's
|
||||
* power management protocol extension to H4 to support AR300x Bluetooth Chip.
|
||||
*
|
||||
* Copyright (c) 2009-2010 Atheros Communications Inc.
|
||||
*
|
||||
* Acknowledgements:
|
||||
* This file is based on hci_h4.c, which was written
|
||||
* by Maxim Krasnyansky and Marcel Holtmann.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
|
||||
#include "hci_uart.h"
|
||||
|
||||
struct ath_struct {
|
||||
struct hci_uart *hu;
|
||||
unsigned int cur_sleep;
|
||||
|
||||
struct sk_buff_head txq;
|
||||
struct work_struct ctxtsw;
|
||||
};
|
||||
|
||||
static int ath_wakeup_ar3k(struct tty_struct *tty)
|
||||
{
|
||||
struct termios settings;
|
||||
int status = tty->driver->ops->tiocmget(tty, NULL);
|
||||
|
||||
if (status & TIOCM_CTS)
|
||||
return status;
|
||||
|
||||
/* Disable Automatic RTSCTS */
|
||||
n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings);
|
||||
settings.c_cflag &= ~CRTSCTS;
|
||||
n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings);
|
||||
|
||||
/* Clear RTS first */
|
||||
status = tty->driver->ops->tiocmget(tty, NULL);
|
||||
tty->driver->ops->tiocmset(tty, NULL, 0x00, TIOCM_RTS);
|
||||
mdelay(20);
|
||||
|
||||
/* Set RTS, wake up board */
|
||||
status = tty->driver->ops->tiocmget(tty, NULL);
|
||||
tty->driver->ops->tiocmset(tty, NULL, TIOCM_RTS, 0x00);
|
||||
mdelay(20);
|
||||
|
||||
status = tty->driver->ops->tiocmget(tty, NULL);
|
||||
|
||||
n_tty_ioctl_helper(tty, NULL, TCGETS, (unsigned long)&settings);
|
||||
settings.c_cflag |= CRTSCTS;
|
||||
n_tty_ioctl_helper(tty, NULL, TCSETS, (unsigned long)&settings);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void ath_hci_uart_work(struct work_struct *work)
|
||||
{
|
||||
int status;
|
||||
struct ath_struct *ath;
|
||||
struct hci_uart *hu;
|
||||
struct tty_struct *tty;
|
||||
|
||||
ath = container_of(work, struct ath_struct, ctxtsw);
|
||||
|
||||
hu = ath->hu;
|
||||
tty = hu->tty;
|
||||
|
||||
/* verify and wake up controller */
|
||||
if (ath->cur_sleep) {
|
||||
status = ath_wakeup_ar3k(tty);
|
||||
if (!(status & TIOCM_CTS))
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ready to send Data */
|
||||
clear_bit(HCI_UART_SENDING, &hu->tx_state);
|
||||
hci_uart_tx_wakeup(hu);
|
||||
}
|
||||
|
||||
/* Initialize protocol */
|
||||
static int ath_open(struct hci_uart *hu)
|
||||
{
|
||||
struct ath_struct *ath;
|
||||
|
||||
BT_DBG("hu %p", hu);
|
||||
|
||||
ath = kzalloc(sizeof(*ath), GFP_ATOMIC);
|
||||
if (!ath)
|
||||
return -ENOMEM;
|
||||
|
||||
skb_queue_head_init(&ath->txq);
|
||||
|
||||
hu->priv = ath;
|
||||
ath->hu = hu;
|
||||
|
||||
INIT_WORK(&ath->ctxtsw, ath_hci_uart_work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Flush protocol data */
|
||||
static int ath_flush(struct hci_uart *hu)
|
||||
{
|
||||
struct ath_struct *ath = hu->priv;
|
||||
|
||||
BT_DBG("hu %p", hu);
|
||||
|
||||
skb_queue_purge(&ath->txq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Close protocol */
|
||||
static int ath_close(struct hci_uart *hu)
|
||||
{
|
||||
struct ath_struct *ath = hu->priv;
|
||||
|
||||
BT_DBG("hu %p", hu);
|
||||
|
||||
skb_queue_purge(&ath->txq);
|
||||
|
||||
cancel_work_sync(&ath->ctxtsw);
|
||||
|
||||
hu->priv = NULL;
|
||||
kfree(ath);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define HCI_OP_ATH_SLEEP 0xFC04
|
||||
|
||||
/* Enqueue frame for transmittion */
|
||||
static int ath_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
||||
{
|
||||
struct ath_struct *ath = hu->priv;
|
||||
|
||||
if (bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) {
|
||||
kfree_skb(skb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update power management enable flag with parameters of
|
||||
* HCI sleep enable vendor specific HCI command.
|
||||
*/
|
||||
if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) {
|
||||
struct hci_command_hdr *hdr = (void *)skb->data;
|
||||
|
||||
if (__le16_to_cpu(hdr->opcode) == HCI_OP_ATH_SLEEP)
|
||||
ath->cur_sleep = skb->data[HCI_COMMAND_HDR_SIZE];
|
||||
}
|
||||
|
||||
BT_DBG("hu %p skb %p", hu, skb);
|
||||
|
||||
/* Prepend skb with frame type */
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
|
||||
skb_queue_tail(&ath->txq, skb);
|
||||
set_bit(HCI_UART_SENDING, &hu->tx_state);
|
||||
|
||||
schedule_work(&ath->ctxtsw);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sk_buff *ath_dequeue(struct hci_uart *hu)
|
||||
{
|
||||
struct ath_struct *ath = hu->priv;
|
||||
|
||||
return skb_dequeue(&ath->txq);
|
||||
}
|
||||
|
||||
/* Recv data */
|
||||
static int ath_recv(struct hci_uart *hu, void *data, int count)
|
||||
{
|
||||
if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
|
||||
BT_ERR("Frame Reassembly Failed");
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct hci_uart_proto athp = {
|
||||
.id = HCI_UART_ATH3K,
|
||||
.open = ath_open,
|
||||
.close = ath_close,
|
||||
.recv = ath_recv,
|
||||
.enqueue = ath_enqueue,
|
||||
.dequeue = ath_dequeue,
|
||||
.flush = ath_flush,
|
||||
};
|
||||
|
||||
int __init ath_init(void)
|
||||
{
|
||||
int err = hci_uart_register_proto(&athp);
|
||||
|
||||
if (!err)
|
||||
BT_INFO("HCIATH3K protocol initialized");
|
||||
else
|
||||
BT_ERR("HCIATH3K protocol registration failed");
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int __exit ath_deinit(void)
|
||||
{
|
||||
return hci_uart_unregister_proto(&athp);
|
||||
}
|
@ -739,7 +739,7 @@ static struct hci_uart_proto bcsp = {
|
||||
.flush = bcsp_flush
|
||||
};
|
||||
|
||||
int bcsp_init(void)
|
||||
int __init bcsp_init(void)
|
||||
{
|
||||
int err = hci_uart_register_proto(&bcsp);
|
||||
|
||||
@ -751,7 +751,7 @@ int bcsp_init(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
int bcsp_deinit(void)
|
||||
int __exit bcsp_deinit(void)
|
||||
{
|
||||
return hci_uart_unregister_proto(&bcsp);
|
||||
}
|
||||
|
@ -151,107 +151,8 @@ static inline int h4_check_data_len(struct h4_struct *h4, int len)
|
||||
/* Recv data */
|
||||
static int h4_recv(struct hci_uart *hu, void *data, int count)
|
||||
{
|
||||
struct h4_struct *h4 = hu->priv;
|
||||
register char *ptr;
|
||||
struct hci_event_hdr *eh;
|
||||
struct hci_acl_hdr *ah;
|
||||
struct hci_sco_hdr *sh;
|
||||
register int len, type, dlen;
|
||||
|
||||
BT_DBG("hu %p count %d rx_state %ld rx_count %ld",
|
||||
hu, count, h4->rx_state, h4->rx_count);
|
||||
|
||||
ptr = data;
|
||||
while (count) {
|
||||
if (h4->rx_count) {
|
||||
len = min_t(unsigned int, h4->rx_count, count);
|
||||
memcpy(skb_put(h4->rx_skb, len), ptr, len);
|
||||
h4->rx_count -= len; count -= len; ptr += len;
|
||||
|
||||
if (h4->rx_count)
|
||||
continue;
|
||||
|
||||
switch (h4->rx_state) {
|
||||
case H4_W4_DATA:
|
||||
BT_DBG("Complete data");
|
||||
|
||||
hci_recv_frame(h4->rx_skb);
|
||||
|
||||
h4->rx_state = H4_W4_PACKET_TYPE;
|
||||
h4->rx_skb = NULL;
|
||||
continue;
|
||||
|
||||
case H4_W4_EVENT_HDR:
|
||||
eh = hci_event_hdr(h4->rx_skb);
|
||||
|
||||
BT_DBG("Event header: evt 0x%2.2x plen %d", eh->evt, eh->plen);
|
||||
|
||||
h4_check_data_len(h4, eh->plen);
|
||||
continue;
|
||||
|
||||
case H4_W4_ACL_HDR:
|
||||
ah = hci_acl_hdr(h4->rx_skb);
|
||||
dlen = __le16_to_cpu(ah->dlen);
|
||||
|
||||
BT_DBG("ACL header: dlen %d", dlen);
|
||||
|
||||
h4_check_data_len(h4, dlen);
|
||||
continue;
|
||||
|
||||
case H4_W4_SCO_HDR:
|
||||
sh = hci_sco_hdr(h4->rx_skb);
|
||||
|
||||
BT_DBG("SCO header: dlen %d", sh->dlen);
|
||||
|
||||
h4_check_data_len(h4, sh->dlen);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* H4_W4_PACKET_TYPE */
|
||||
switch (*ptr) {
|
||||
case HCI_EVENT_PKT:
|
||||
BT_DBG("Event packet");
|
||||
h4->rx_state = H4_W4_EVENT_HDR;
|
||||
h4->rx_count = HCI_EVENT_HDR_SIZE;
|
||||
type = HCI_EVENT_PKT;
|
||||
break;
|
||||
|
||||
case HCI_ACLDATA_PKT:
|
||||
BT_DBG("ACL packet");
|
||||
h4->rx_state = H4_W4_ACL_HDR;
|
||||
h4->rx_count = HCI_ACL_HDR_SIZE;
|
||||
type = HCI_ACLDATA_PKT;
|
||||
break;
|
||||
|
||||
case HCI_SCODATA_PKT:
|
||||
BT_DBG("SCO packet");
|
||||
h4->rx_state = H4_W4_SCO_HDR;
|
||||
h4->rx_count = HCI_SCO_HDR_SIZE;
|
||||
type = HCI_SCODATA_PKT;
|
||||
break;
|
||||
|
||||
default:
|
||||
BT_ERR("Unknown HCI packet type %2.2x", (__u8)*ptr);
|
||||
hu->hdev->stat.err_rx++;
|
||||
ptr++; count--;
|
||||
continue;
|
||||
};
|
||||
|
||||
ptr++; count--;
|
||||
|
||||
/* Allocate packet */
|
||||
h4->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
|
||||
if (!h4->rx_skb) {
|
||||
BT_ERR("Can't allocate mem for new packet");
|
||||
h4->rx_state = H4_W4_PACKET_TYPE;
|
||||
h4->rx_count = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
h4->rx_skb->dev = (void *) hu->hdev;
|
||||
bt_cb(h4->rx_skb)->pkt_type = type;
|
||||
}
|
||||
if (hci_recv_stream_fragment(hu->hdev, data, count) < 0)
|
||||
BT_ERR("Frame Reassembly Failed");
|
||||
|
||||
return count;
|
||||
}
|
||||
@ -272,7 +173,7 @@ static struct hci_uart_proto h4p = {
|
||||
.flush = h4_flush,
|
||||
};
|
||||
|
||||
int h4_init(void)
|
||||
int __init h4_init(void)
|
||||
{
|
||||
int err = hci_uart_register_proto(&h4p);
|
||||
|
||||
@ -284,7 +185,7 @@ int h4_init(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
int h4_deinit(void)
|
||||
int __exit h4_deinit(void)
|
||||
{
|
||||
return hci_uart_unregister_proto(&h4p);
|
||||
}
|
||||
|
@ -210,7 +210,6 @@ static int hci_uart_close(struct hci_dev *hdev)
|
||||
static int hci_uart_send_frame(struct sk_buff *skb)
|
||||
{
|
||||
struct hci_dev* hdev = (struct hci_dev *) skb->dev;
|
||||
struct tty_struct *tty;
|
||||
struct hci_uart *hu;
|
||||
|
||||
if (!hdev) {
|
||||
@ -222,7 +221,6 @@ static int hci_uart_send_frame(struct sk_buff *skb)
|
||||
return -EBUSY;
|
||||
|
||||
hu = (struct hci_uart *) hdev->driver_data;
|
||||
tty = hu->tty;
|
||||
|
||||
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
|
||||
|
||||
@ -397,6 +395,9 @@ static int hci_uart_register_dev(struct hci_uart *hu)
|
||||
if (!reset)
|
||||
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
|
||||
|
||||
if (test_bit(HCI_UART_RAW_DEVICE, &hu->hdev_flags))
|
||||
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
|
||||
|
||||
if (hci_register_dev(hdev) < 0) {
|
||||
BT_ERR("Can't register HCI device");
|
||||
hci_free_dev(hdev);
|
||||
@ -477,6 +478,15 @@ static int hci_uart_tty_ioctl(struct tty_struct *tty, struct file * file,
|
||||
return hu->hdev->id;
|
||||
return -EUNATCH;
|
||||
|
||||
case HCIUARTSETFLAGS:
|
||||
if (test_bit(HCI_UART_PROTO_SET, &hu->flags))
|
||||
return -EBUSY;
|
||||
hu->hdev_flags = arg;
|
||||
break;
|
||||
|
||||
case HCIUARTGETFLAGS:
|
||||
return hu->hdev_flags;
|
||||
|
||||
default:
|
||||
err = n_tty_ioctl_helper(tty, file, cmd, arg);
|
||||
break;
|
||||
@ -542,6 +552,9 @@ static int __init hci_uart_init(void)
|
||||
#ifdef CONFIG_BT_HCIUART_LL
|
||||
ll_init();
|
||||
#endif
|
||||
#ifdef CONFIG_BT_HCIUART_ATH3K
|
||||
ath_init();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -559,6 +572,9 @@ static void __exit hci_uart_exit(void)
|
||||
#ifdef CONFIG_BT_HCIUART_LL
|
||||
ll_deinit();
|
||||
#endif
|
||||
#ifdef CONFIG_BT_HCIUART_ATH3K
|
||||
ath_deinit();
|
||||
#endif
|
||||
|
||||
/* Release tty registration of line discipline */
|
||||
if ((err = tty_unregister_ldisc(N_HCI)))
|
||||
|
@ -74,7 +74,7 @@ enum hcill_states_e {
|
||||
|
||||
struct hcill_cmd {
|
||||
u8 cmd;
|
||||
} __attribute__((packed));
|
||||
} __packed;
|
||||
|
||||
struct ll_struct {
|
||||
unsigned long rx_state;
|
||||
@ -517,7 +517,7 @@ static struct hci_uart_proto llp = {
|
||||
.flush = ll_flush,
|
||||
};
|
||||
|
||||
int ll_init(void)
|
||||
int __init ll_init(void)
|
||||
{
|
||||
int err = hci_uart_register_proto(&llp);
|
||||
|
||||
@ -529,7 +529,7 @@ int ll_init(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
int ll_deinit(void)
|
||||
int __exit ll_deinit(void)
|
||||
{
|
||||
return hci_uart_unregister_proto(&llp);
|
||||
}
|
||||
|
@ -31,15 +31,20 @@
|
||||
#define HCIUARTSETPROTO _IOW('U', 200, int)
|
||||
#define HCIUARTGETPROTO _IOR('U', 201, int)
|
||||
#define HCIUARTGETDEVICE _IOR('U', 202, int)
|
||||
#define HCIUARTSETFLAGS _IOW('U', 203, int)
|
||||
#define HCIUARTGETFLAGS _IOR('U', 204, int)
|
||||
|
||||
/* UART protocols */
|
||||
#define HCI_UART_MAX_PROTO 5
|
||||
#define HCI_UART_MAX_PROTO 6
|
||||
|
||||
#define HCI_UART_H4 0
|
||||
#define HCI_UART_BCSP 1
|
||||
#define HCI_UART_3WIRE 2
|
||||
#define HCI_UART_H4DS 3
|
||||
#define HCI_UART_LL 4
|
||||
#define HCI_UART_ATH3K 5
|
||||
|
||||
#define HCI_UART_RAW_DEVICE 0
|
||||
|
||||
struct hci_uart;
|
||||
|
||||
@ -57,6 +62,7 @@ struct hci_uart {
|
||||
struct tty_struct *tty;
|
||||
struct hci_dev *hdev;
|
||||
unsigned long flags;
|
||||
unsigned long hdev_flags;
|
||||
|
||||
struct hci_uart_proto *proto;
|
||||
void *priv;
|
||||
@ -66,7 +72,7 @@ struct hci_uart {
|
||||
spinlock_t rx_lock;
|
||||
};
|
||||
|
||||
/* HCI_UART flag bits */
|
||||
/* HCI_UART proto flag bits */
|
||||
#define HCI_UART_PROTO_SET 0
|
||||
|
||||
/* TX states */
|
||||
@ -91,3 +97,8 @@ int bcsp_deinit(void);
|
||||
int ll_init(void);
|
||||
int ll_deinit(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BT_HCIUART_ATH3K
|
||||
int ath_init(void);
|
||||
int ath_deinit(void);
|
||||
#endif
|
||||
|
@ -373,8 +373,8 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
|
||||
pktlen = status & RDES0_STATUS_FL;
|
||||
if (pktlen > RX_PKT_SIZE) {
|
||||
if (net_ratelimit())
|
||||
printk(KERN_DEBUG "%s: frame too long (%d)\n",
|
||||
wiphy_name(dev->wiphy), pktlen);
|
||||
wiphy_debug(dev->wiphy, "frame too long (%d)\n",
|
||||
pktlen);
|
||||
pktlen = RX_PKT_SIZE;
|
||||
}
|
||||
|
||||
@ -454,10 +454,10 @@ static void adm8211_interrupt_rci(struct ieee80211_hw *dev)
|
||||
|
||||
static irqreturn_t adm8211_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
#define ADM8211_INT(x) \
|
||||
do { \
|
||||
if (unlikely(stsr & ADM8211_STSR_ ## x)) \
|
||||
printk(KERN_DEBUG "%s: " #x "\n", wiphy_name(dev->wiphy)); \
|
||||
#define ADM8211_INT(x) \
|
||||
do { \
|
||||
if (unlikely(stsr & ADM8211_STSR_ ## x)) \
|
||||
wiphy_debug(dev->wiphy, "%s\n", #x); \
|
||||
} while (0)
|
||||
|
||||
struct ieee80211_hw *dev = dev_id;
|
||||
@ -570,9 +570,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data)
|
||||
}
|
||||
|
||||
if (timeout == 0) {
|
||||
printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed"
|
||||
" prewrite (reg=0x%08x)\n",
|
||||
wiphy_name(dev->wiphy), addr, data, reg);
|
||||
wiphy_debug(dev->wiphy,
|
||||
"adm8211_write_bbp(%d,%d) failed prewrite (reg=0x%08x)\n",
|
||||
addr, data, reg);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -605,9 +605,9 @@ static int adm8211_write_bbp(struct ieee80211_hw *dev, u8 addr, u8 data)
|
||||
if (timeout == 0) {
|
||||
ADM8211_CSR_WRITE(BBPCTL, ADM8211_CSR_READ(BBPCTL) &
|
||||
~ADM8211_BBPCTL_WR);
|
||||
printk(KERN_DEBUG "%s: adm8211_write_bbp(%d,%d) failed"
|
||||
" postwrite (reg=0x%08x)\n",
|
||||
wiphy_name(dev->wiphy), addr, data, reg);
|
||||
wiphy_debug(dev->wiphy,
|
||||
"adm8211_write_bbp(%d,%d) failed postwrite (reg=0x%08x)\n",
|
||||
addr, data, reg);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -675,8 +675,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan)
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_DEBUG "%s: unsupported transceiver type %d\n",
|
||||
wiphy_name(dev->wiphy), priv->transceiver_type);
|
||||
wiphy_debug(dev->wiphy, "unsupported transceiver type %d\n",
|
||||
priv->transceiver_type);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -732,8 +732,8 @@ static int adm8211_rf_set_channel(struct ieee80211_hw *dev, unsigned int chan)
|
||||
|
||||
/* Nothing to do for ADMtek BBP */
|
||||
} else if (priv->bbp_type != ADM8211_TYPE_ADMTEK)
|
||||
printk(KERN_DEBUG "%s: unsupported BBP type %d\n",
|
||||
wiphy_name(dev->wiphy), priv->bbp_type);
|
||||
wiphy_debug(dev->wiphy, "unsupported bbp type %d\n",
|
||||
priv->bbp_type);
|
||||
|
||||
ADM8211_RESTORE();
|
||||
|
||||
@ -1027,13 +1027,12 @@ static int adm8211_hw_init_bbp(struct ieee80211_hw *dev)
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_DEBUG "%s: unsupported transceiver %d\n",
|
||||
wiphy_name(dev->wiphy), priv->transceiver_type);
|
||||
wiphy_debug(dev->wiphy, "unsupported transceiver %d\n",
|
||||
priv->transceiver_type);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
printk(KERN_DEBUG "%s: unsupported BBP %d\n",
|
||||
wiphy_name(dev->wiphy), priv->bbp_type);
|
||||
wiphy_debug(dev->wiphy, "unsupported bbp %d\n", priv->bbp_type);
|
||||
|
||||
ADM8211_CSR_WRITE(SYNRF, 0);
|
||||
|
||||
@ -1509,15 +1508,13 @@ static int adm8211_start(struct ieee80211_hw *dev)
|
||||
/* Power up MAC and RF chips */
|
||||
retval = adm8211_hw_reset(dev);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "%s: hardware reset failed\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "hardware reset failed\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
retval = adm8211_init_rings(dev);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "%s: failed to initialize rings\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "failed to initialize rings\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1528,8 +1525,7 @@ static int adm8211_start(struct ieee80211_hw *dev)
|
||||
retval = request_irq(priv->pdev->irq, adm8211_interrupt,
|
||||
IRQF_SHARED, "adm8211", dev);
|
||||
if (retval) {
|
||||
printk(KERN_ERR "%s: failed to register IRQ handler\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "failed to register irq handler\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1906,9 +1902,8 @@ static int __devinit adm8211_probe(struct pci_dev *pdev,
|
||||
goto err_free_eeprom;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s: hwaddr %pM, Rev 0x%02x\n",
|
||||
wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
|
||||
pdev->revision);
|
||||
wiphy_info(dev->wiphy, "hwaddr %pm, rev 0x%02x\n",
|
||||
dev->wiphy->perm_addr, pdev->revision);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -89,22 +89,19 @@
|
||||
#define DBG_DEFAULTS 0
|
||||
|
||||
/* Use our own dbg macro */
|
||||
#define at76_dbg(bits, format, arg...) \
|
||||
do { \
|
||||
if (at76_debug & (bits)) \
|
||||
printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
|
||||
## arg); \
|
||||
} while (0)
|
||||
#define at76_dbg(bits, format, arg...) \
|
||||
do { \
|
||||
if (at76_debug & (bits)) \
|
||||
printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg); \
|
||||
} while (0)
|
||||
|
||||
#define at76_dbg_dump(bits, buf, len, format, arg...) \
|
||||
do { \
|
||||
if (at76_debug & (bits)) { \
|
||||
printk(KERN_DEBUG DRIVER_NAME ": " format "\n" , \
|
||||
## arg); \
|
||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, \
|
||||
buf, len); \
|
||||
} \
|
||||
} while (0)
|
||||
#define at76_dbg_dump(bits, buf, len, format, arg...) \
|
||||
do { \
|
||||
if (at76_debug & (bits)) { \
|
||||
printk(KERN_DEBUG DRIVER_NAME ": " format "\n", ##arg); \
|
||||
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static uint at76_debug = DBG_DEFAULTS;
|
||||
|
||||
@ -658,8 +655,8 @@ static int at76_get_hw_config(struct at76_priv *priv)
|
||||
exit:
|
||||
kfree(hwcfg);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "%s: cannot get HW Config (error %d)\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy, "cannot get hw config (error %d)\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -794,8 +791,9 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
|
||||
do {
|
||||
status = at76_get_cmd_status(priv->udev, cmd);
|
||||
if (status < 0) {
|
||||
printk(KERN_ERR "%s: at76_get_cmd_status failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), status);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"at76_get_cmd_status failed: %d\n",
|
||||
status);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -810,9 +808,8 @@ static int at76_wait_completion(struct at76_priv *priv, int cmd)
|
||||
|
||||
schedule_timeout_interruptible(HZ / 10); /* 100 ms */
|
||||
if (time_after(jiffies, timeout)) {
|
||||
printk(KERN_ERR
|
||||
"%s: completion timeout for command %d\n",
|
||||
wiphy_name(priv->hw->wiphy), cmd);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"completion timeout for command %d\n", cmd);
|
||||
status = -ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
@ -833,9 +830,9 @@ static int at76_set_mib(struct at76_priv *priv, struct set_mib_buffer *buf)
|
||||
|
||||
ret = at76_wait_completion(priv, CMD_SET_MIB);
|
||||
if (ret != CMD_STATUS_COMPLETE) {
|
||||
printk(KERN_INFO
|
||||
"%s: set_mib: at76_wait_completion failed "
|
||||
"with %d\n", wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_info(priv->hw->wiphy,
|
||||
"set_mib: at76_wait_completion failed with %d\n",
|
||||
ret);
|
||||
ret = -EIO;
|
||||
}
|
||||
|
||||
@ -855,8 +852,8 @@ static int at76_set_radio(struct at76_priv *priv, int enable)
|
||||
|
||||
ret = at76_set_card_command(priv->udev, cmd, NULL, 0);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "%s: at76_set_card_command(%d) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), cmd, ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"at76_set_card_command(%d) failed: %d\n", cmd, ret);
|
||||
else
|
||||
ret = 1;
|
||||
|
||||
@ -876,8 +873,8 @@ static int at76_set_pm_mode(struct at76_priv *priv)
|
||||
|
||||
ret = at76_set_mib(priv, &priv->mib_buf);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "%s: set_mib (pm_mode) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy, "set_mib (pm_mode) failed: %d\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -893,8 +890,8 @@ static int at76_set_preamble(struct at76_priv *priv, u8 type)
|
||||
|
||||
ret = at76_set_mib(priv, &priv->mib_buf);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "%s: set_mib (preamble) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy, "set_mib (preamble) failed: %d\n",
|
||||
ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -910,8 +907,8 @@ static int at76_set_frag(struct at76_priv *priv, u16 size)
|
||||
|
||||
ret = at76_set_mib(priv, &priv->mib_buf);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "%s: set_mib (frag threshold) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"set_mib (frag threshold) failed: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -927,8 +924,7 @@ static int at76_set_rts(struct at76_priv *priv, u16 size)
|
||||
|
||||
ret = at76_set_mib(priv, &priv->mib_buf);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "%s: set_mib (rts) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy, "set_mib (rts) failed: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -944,8 +940,8 @@ static int at76_set_autorate_fallback(struct at76_priv *priv, int onoff)
|
||||
|
||||
ret = at76_set_mib(priv, &priv->mib_buf);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "%s: set_mib (autorate fallback) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"set_mib (autorate fallback) failed: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -963,8 +959,8 @@ static void at76_dump_mib_mac_addr(struct at76_priv *priv)
|
||||
ret = at76_get_mib(priv->udev, MIB_MAC_ADDR, m,
|
||||
sizeof(struct mib_mac_addr));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: at76_get_mib (MAC_ADDR) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"at76_get_mib (mac_addr) failed: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -992,8 +988,8 @@ static void at76_dump_mib_mac_wep(struct at76_priv *priv)
|
||||
ret = at76_get_mib(priv->udev, MIB_MAC_WEP, m,
|
||||
sizeof(struct mib_mac_wep));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: at76_get_mib (MAC_WEP) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"at76_get_mib (mac_wep) failed: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -1029,8 +1025,8 @@ static void at76_dump_mib_mac_mgmt(struct at76_priv *priv)
|
||||
ret = at76_get_mib(priv->udev, MIB_MAC_MGMT, m,
|
||||
sizeof(struct mib_mac_mgmt));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: at76_get_mib (MAC_MGMT) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"at76_get_mib (mac_mgmt) failed: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -1065,8 +1061,8 @@ static void at76_dump_mib_mac(struct at76_priv *priv)
|
||||
|
||||
ret = at76_get_mib(priv->udev, MIB_MAC, m, sizeof(struct mib_mac));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: at76_get_mib (MAC) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"at76_get_mib (mac) failed: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -1102,8 +1098,8 @@ static void at76_dump_mib_phy(struct at76_priv *priv)
|
||||
|
||||
ret = at76_get_mib(priv->udev, MIB_PHY, m, sizeof(struct mib_phy));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: at76_get_mib (PHY) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"at76_get_mib (phy) failed: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -1135,8 +1131,8 @@ static void at76_dump_mib_local(struct at76_priv *priv)
|
||||
|
||||
ret = at76_get_mib(priv->udev, MIB_LOCAL, m, sizeof(struct mib_local));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: at76_get_mib (LOCAL) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"at76_get_mib (local) failed: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -1161,8 +1157,8 @@ static void at76_dump_mib_mdomain(struct at76_priv *priv)
|
||||
ret = at76_get_mib(priv->udev, MIB_MDOMAIN, m,
|
||||
sizeof(struct mib_mdomain));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: at76_get_mib (MDOMAIN) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"at76_get_mib (mdomain) failed: %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
@ -1233,16 +1229,16 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
|
||||
struct sk_buff *skb = priv->rx_skb;
|
||||
|
||||
if (!priv->rx_urb) {
|
||||
printk(KERN_ERR "%s: %s: priv->rx_urb is NULL\n",
|
||||
wiphy_name(priv->hw->wiphy), __func__);
|
||||
wiphy_err(priv->hw->wiphy, "%s: priv->rx_urb is null\n",
|
||||
__func__);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (!skb) {
|
||||
skb = dev_alloc_skb(sizeof(struct at76_rx_buffer));
|
||||
if (!skb) {
|
||||
printk(KERN_ERR "%s: cannot allocate rx skbuff\n",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"cannot allocate rx skbuff\n");
|
||||
ret = -ENOMEM;
|
||||
goto exit;
|
||||
}
|
||||
@ -1261,15 +1257,14 @@ static int at76_submit_rx_urb(struct at76_priv *priv)
|
||||
at76_dbg(DBG_DEVSTART,
|
||||
"usb_submit_urb returned -ENODEV");
|
||||
else
|
||||
printk(KERN_ERR "%s: rx, usb_submit_urb failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"rx, usb_submit_urb failed: %d\n", ret);
|
||||
}
|
||||
|
||||
exit:
|
||||
if (ret < 0 && ret != -ENODEV)
|
||||
printk(KERN_ERR "%s: cannot submit rx urb - please unload the "
|
||||
"driver and/or power cycle the device\n",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"cannot submit rx urb - please unload the driver and/or power cycle the device\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1438,8 +1433,8 @@ static int at76_startup_device(struct at76_priv *priv)
|
||||
ret = at76_set_card_command(priv->udev, CMD_STARTUP, &priv->card_config,
|
||||
sizeof(struct at76_card_config));
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1504,8 +1499,8 @@ static void at76_work_set_promisc(struct work_struct *work)
|
||||
|
||||
ret = at76_set_mib(priv, &priv->mib_buf);
|
||||
if (ret < 0)
|
||||
printk(KERN_ERR "%s: set_mib (promiscuous_mode) failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"set_mib (promiscuous_mode) failed: %d\n", ret);
|
||||
|
||||
mutex_unlock(&priv->mtx);
|
||||
}
|
||||
@ -1668,16 +1663,16 @@ static int at76_join(struct at76_priv *priv)
|
||||
sizeof(struct at76_req_join));
|
||||
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: at76_set_card_command failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy, "at76_set_card_command failed: %d\n",
|
||||
ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = at76_wait_completion(priv, CMD_JOIN);
|
||||
at76_dbg(DBG_MAC80211, "%s: CMD_JOIN returned: 0x%02x", __func__, ret);
|
||||
if (ret != CMD_STATUS_COMPLETE) {
|
||||
printk(KERN_ERR "%s: at76_wait_completion failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy, "at76_wait_completion failed: %d\n",
|
||||
ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1745,8 +1740,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
at76_dbg(DBG_MAC80211, "%s()", __func__);
|
||||
|
||||
if (priv->tx_urb->status == -EINPROGRESS) {
|
||||
printk(KERN_ERR "%s: %s called while tx urb is pending\n",
|
||||
wiphy_name(priv->hw->wiphy), __func__);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"%s called while tx urb is pending\n", __func__);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
@ -1794,13 +1789,12 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
submit_len, at76_mac80211_tx_callback, priv);
|
||||
ret = usb_submit_urb(priv->tx_urb, GFP_ATOMIC);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: error in tx submit urb: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy, "error in tx submit urb: %d\n", ret);
|
||||
if (ret == -EINVAL)
|
||||
printk(KERN_ERR
|
||||
"%s: -EINVAL: tx urb %p hcpriv %p complete %p\n",
|
||||
wiphy_name(priv->hw->wiphy), priv->tx_urb,
|
||||
priv->tx_urb->hcpriv, priv->tx_urb->complete);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"-einval: tx urb %p hcpriv %p complete %p\n",
|
||||
priv->tx_urb,
|
||||
priv->tx_urb->hcpriv, priv->tx_urb->complete);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1817,8 +1811,8 @@ static int at76_mac80211_start(struct ieee80211_hw *hw)
|
||||
|
||||
ret = at76_submit_rx_urb(priv);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "%s: open: submit_rx_urb failed: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), ret);
|
||||
wiphy_err(priv->hw->wiphy, "open: submit_rx_urb failed: %d\n",
|
||||
ret);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -2316,14 +2310,12 @@ static int at76_init_new_device(struct at76_priv *priv,
|
||||
|
||||
priv->mac80211_registered = 1;
|
||||
|
||||
printk(KERN_INFO "%s: USB %s, MAC %pM, firmware %d.%d.%d-%d\n",
|
||||
wiphy_name(priv->hw->wiphy),
|
||||
dev_name(&interface->dev), priv->mac_addr,
|
||||
priv->fw_version.major, priv->fw_version.minor,
|
||||
priv->fw_version.patch, priv->fw_version.build);
|
||||
printk(KERN_INFO "%s: regulatory domain 0x%02x: %s\n",
|
||||
wiphy_name(priv->hw->wiphy),
|
||||
priv->regulatory_domain, priv->domain->name);
|
||||
wiphy_info(priv->hw->wiphy, "usb %s, mac %pm, firmware %d.%d.%d-%d\n",
|
||||
dev_name(&interface->dev), priv->mac_addr,
|
||||
priv->fw_version.major, priv->fw_version.minor,
|
||||
priv->fw_version.patch, priv->fw_version.build);
|
||||
wiphy_info(priv->hw->wiphy, "regulatory domain 0x%02x: %s\n",
|
||||
priv->regulatory_domain, priv->domain->name);
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
@ -2485,7 +2477,7 @@ static void at76_disconnect(struct usb_interface *interface)
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
printk(KERN_INFO "%s: disconnecting\n", wiphy_name(priv->hw->wiphy));
|
||||
wiphy_info(priv->hw->wiphy, "disconnecting\n");
|
||||
at76_delete_device(priv);
|
||||
dev_printk(KERN_INFO, &interface->dev, "disconnected\n");
|
||||
}
|
||||
|
@ -48,8 +48,7 @@ int ar9170_write_mem(struct ar9170 *ar, const __le32 *data, size_t len)
|
||||
|
||||
err = ar->exec_cmd(ar, AR9170_CMD_WMEM, len, (u8 *) data, 0, NULL);
|
||||
if (err)
|
||||
printk(KERN_DEBUG "%s: writing memory failed\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_debug(ar->hw->wiphy, "writing memory failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -67,8 +66,8 @@ int ar9170_write_reg(struct ar9170 *ar, const u32 reg, const u32 val)
|
||||
err = ar->exec_cmd(ar, AR9170_CMD_WREG, sizeof(buf),
|
||||
(u8 *) buf, 0, NULL);
|
||||
if (err)
|
||||
printk(KERN_DEBUG "%s: writing reg %#x (val %#x) failed\n",
|
||||
wiphy_name(ar->hw->wiphy), reg, val);
|
||||
wiphy_debug(ar->hw->wiphy, "writing reg %#x (val %#x) failed\n",
|
||||
reg, val);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -133,8 +133,8 @@ static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
|
||||
err = led_classdev_register(wiphy_dev(ar->hw->wiphy),
|
||||
&ar->leds[i].l);
|
||||
if (err)
|
||||
printk(KERN_ERR "%s: failed to register %s LED (%d).\n",
|
||||
wiphy_name(ar->hw->wiphy), ar->leds[i].name, err);
|
||||
wiphy_err(ar->hw->wiphy, "failed to register %s LED (%d).\n",
|
||||
ar->leds[i].name, err);
|
||||
else
|
||||
ar->leds[i].registered = true;
|
||||
|
||||
|
@ -198,12 +198,13 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
|
||||
struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
|
||||
struct ieee80211_hdr *hdr = (void *) txc->frame_data;
|
||||
|
||||
printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
|
||||
"mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
|
||||
wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
|
||||
ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
|
||||
le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
|
||||
jiffies_to_msecs(arinfo->timeout - jiffies));
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"=> FRAME [skb:%p, q:%d, DA:[%pM] s:%d "
|
||||
"mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
|
||||
skb, skb_get_queue_mapping(skb),
|
||||
ieee80211_get_DA(hdr), ar9170_get_seq_h(hdr),
|
||||
le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
|
||||
jiffies_to_msecs(arinfo->timeout - jiffies));
|
||||
}
|
||||
|
||||
static void __ar9170_dump_txqueue(struct ar9170 *ar,
|
||||
@ -213,8 +214,8 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar,
|
||||
int i = 0;
|
||||
|
||||
printk(KERN_DEBUG "---[ cut here ]---\n");
|
||||
printk(KERN_DEBUG "%s: %d entries in queue.\n",
|
||||
wiphy_name(ar->hw->wiphy), skb_queue_len(queue));
|
||||
wiphy_debug(ar->hw->wiphy, "%d entries in queue.\n",
|
||||
skb_queue_len(queue));
|
||||
|
||||
skb_queue_walk(queue, skb) {
|
||||
printk(KERN_DEBUG "index:%d =>\n", i++);
|
||||
@ -244,15 +245,14 @@ static void __ar9170_dump_txstats(struct ar9170 *ar)
|
||||
{
|
||||
int i;
|
||||
|
||||
printk(KERN_DEBUG "%s: QoS queue stats\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_debug(ar->hw->wiphy, "qos queue stats\n");
|
||||
|
||||
for (i = 0; i < __AR9170_NUM_TXQ; i++)
|
||||
printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d "
|
||||
" stopped:%d\n", wiphy_name(ar->hw->wiphy), i,
|
||||
ar->tx_stats[i].limit, ar->tx_stats[i].len,
|
||||
skb_queue_len(&ar->tx_status[i]),
|
||||
ieee80211_queue_stopped(ar->hw, i));
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"queue:%d limit:%d len:%d waitack:%d stopped:%d\n",
|
||||
i, ar->tx_stats[i].limit, ar->tx_stats[i].len,
|
||||
skb_queue_len(&ar->tx_status[i]),
|
||||
ieee80211_queue_stopped(ar->hw, i));
|
||||
}
|
||||
#endif /* AR9170_QUEUE_STOP_DEBUG */
|
||||
|
||||
@ -274,9 +274,9 @@ static void ar9170_recycle_expired(struct ar9170 *ar,
|
||||
|
||||
if (time_is_before_jiffies(arinfo->timeout)) {
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: [%ld > %ld] frame expired => "
|
||||
"recycle\n", wiphy_name(ar->hw->wiphy),
|
||||
jiffies, arinfo->timeout);
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"[%ld > %ld] frame expired => recycle\n",
|
||||
jiffies, arinfo->timeout);
|
||||
ar9170_print_txheader(ar, skb);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
__skb_unlink(skb, queue);
|
||||
@ -317,8 +317,8 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "%s: invalid tx_status response (%x).\n",
|
||||
wiphy_name(ar->hw->wiphy), tx_status);
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"invalid tx_status response (%x)\n", tx_status);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -339,8 +339,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
|
||||
|
||||
if (ar->tx_stats[queue].len < AR9170_NUM_TX_LIMIT_SOFT) {
|
||||
#ifdef AR9170_QUEUE_STOP_DEBUG
|
||||
printk(KERN_DEBUG "%s: wake queue %d\n",
|
||||
wiphy_name(ar->hw->wiphy), queue);
|
||||
wiphy_debug(ar->hw->wiphy, "wake queue %d\n", queue);
|
||||
__ar9170_dump_txstats(ar);
|
||||
#endif /* AR9170_QUEUE_STOP_DEBUG */
|
||||
ieee80211_wake_queue(ar->hw, queue);
|
||||
@ -387,9 +386,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
|
||||
|
||||
if (mac && compare_ether_addr(ieee80211_get_DA(hdr), mac)) {
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: skip frame => DA %pM != %pM\n",
|
||||
wiphy_name(ar->hw->wiphy), mac,
|
||||
ieee80211_get_DA(hdr));
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"skip frame => da %pm != %pm\n",
|
||||
mac, ieee80211_get_DA(hdr));
|
||||
ar9170_print_txheader(ar, skb);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
continue;
|
||||
@ -400,8 +399,8 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
|
||||
|
||||
if ((rate != AR9170_TX_INVALID_RATE) && (r != rate)) {
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: skip frame => rate %d != %d\n",
|
||||
wiphy_name(ar->hw->wiphy), rate, r);
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"skip frame => rate %d != %d\n", rate, r);
|
||||
ar9170_print_txheader(ar, skb);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
continue;
|
||||
@ -413,9 +412,9 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
|
||||
}
|
||||
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_ERR "%s: ESS:[%pM] does not have any "
|
||||
"outstanding frames in queue.\n",
|
||||
wiphy_name(ar->hw->wiphy), mac);
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"ESS:[%pM] does not have any outstanding frames in queue.\n",
|
||||
mac);
|
||||
__ar9170_dump_txqueue(ar, queue);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
spin_unlock_irqrestore(&queue->lock, flags);
|
||||
@ -444,8 +443,8 @@ static void ar9170_tx_janitor(struct work_struct *work)
|
||||
|
||||
for (i = 0; i < __AR9170_NUM_TXQ; i++) {
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: garbage collector scans queue:%d\n",
|
||||
wiphy_name(ar->hw->wiphy), i);
|
||||
wiphy_debug(ar->hw->wiphy, "garbage collector scans queue:%d\n",
|
||||
i);
|
||||
ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
|
||||
ar9170_dump_txqueue(ar, &ar->tx_status[i]);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
@ -495,8 +494,9 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
|
||||
u32 q = (phy & AR9170_TX_PHY_QOS_MASK) >>
|
||||
AR9170_TX_PHY_QOS_SHIFT;
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: recv tx_status for %pM, p:%08x, q:%d\n",
|
||||
wiphy_name(ar->hw->wiphy), cmd->tx_status.dst, phy, q);
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"recv tx_status for %pm, p:%08x, q:%d\n",
|
||||
cmd->tx_status.dst, phy, q);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
|
||||
skb = ar9170_get_queued_skb(ar, cmd->tx_status.dst,
|
||||
@ -582,7 +582,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_INFO "received unhandled event %x\n", cmd->type);
|
||||
pr_info("received unhandled event %x\n", cmd->type);
|
||||
print_hex_dump_bytes("dump:", DUMP_PREFIX_NONE, buf, len);
|
||||
break;
|
||||
}
|
||||
@ -675,9 +675,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar,
|
||||
/* TODO: update netdevice's RX dropped/errors statistics */
|
||||
|
||||
if (ar9170_nag_limiter(ar))
|
||||
printk(KERN_DEBUG "%s: received frame with "
|
||||
"suspicious error code (%#x).\n",
|
||||
wiphy_name(ar->hw->wiphy), error);
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"received frame with suspicious error code (%#x).\n",
|
||||
error);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -704,9 +704,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar,
|
||||
break;
|
||||
default:
|
||||
if (ar9170_nag_limiter(ar))
|
||||
printk(KERN_ERR "%s: invalid plcp cck rate "
|
||||
"(%x).\n", wiphy_name(ar->hw->wiphy),
|
||||
head->plcp[0]);
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"invalid plcp cck rate (%x).\n",
|
||||
head->plcp[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
@ -740,9 +740,9 @@ static int ar9170_rx_mac_status(struct ar9170 *ar,
|
||||
break;
|
||||
default:
|
||||
if (ar9170_nag_limiter(ar))
|
||||
printk(KERN_ERR "%s: invalid plcp ofdm rate "
|
||||
"(%x).\n", wiphy_name(ar->hw->wiphy),
|
||||
head->plcp[0]);
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"invalid plcp ofdm rate (%x).\n",
|
||||
head->plcp[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (status->band == IEEE80211_BAND_2GHZ)
|
||||
@ -761,8 +761,7 @@ static int ar9170_rx_mac_status(struct ar9170 *ar,
|
||||
|
||||
default:
|
||||
if (ar9170_nag_limiter(ar))
|
||||
printk(KERN_ERR "%s: invalid modulation\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy, "invalid modulation\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -863,8 +862,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
|
||||
ar->rx_mpdu.has_plcp = true;
|
||||
} else {
|
||||
if (ar9170_nag_limiter(ar))
|
||||
printk(KERN_ERR "%s: plcp info is clipped.\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"plcp info is clipped.\n");
|
||||
return ;
|
||||
}
|
||||
break;
|
||||
@ -877,8 +876,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
|
||||
phy = (void *)(buf + mpdu_len);
|
||||
} else {
|
||||
if (ar9170_nag_limiter(ar))
|
||||
printk(KERN_ERR "%s: frame tail is clipped.\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"frame tail is clipped.\n");
|
||||
return ;
|
||||
}
|
||||
|
||||
@ -888,9 +887,8 @@ static void ar9170_handle_mpdu(struct ar9170 *ar, u8 *buf, int len)
|
||||
if (!ar9170_nag_limiter(ar))
|
||||
return ;
|
||||
|
||||
printk(KERN_ERR "%s: rx stream did not start "
|
||||
"with a first_mpdu frame tag.\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"rx stream did not start with a first_mpdu frame tag.\n");
|
||||
|
||||
return ;
|
||||
}
|
||||
@ -954,8 +952,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
|
||||
if (!ar->rx_failover_missing) {
|
||||
/* this is no "short read". */
|
||||
if (ar9170_nag_limiter(ar)) {
|
||||
printk(KERN_ERR "%s: missing tag!\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"missing tag!\n");
|
||||
goto err_telluser;
|
||||
} else
|
||||
goto err_silent;
|
||||
@ -963,9 +961,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
|
||||
|
||||
if (ar->rx_failover_missing > tlen) {
|
||||
if (ar9170_nag_limiter(ar)) {
|
||||
printk(KERN_ERR "%s: possible multi "
|
||||
"stream corruption!\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"possible multi stream corruption!\n");
|
||||
goto err_telluser;
|
||||
} else
|
||||
goto err_silent;
|
||||
@ -997,9 +994,8 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
|
||||
if (ar->rx_failover_missing) {
|
||||
/* TODO: handle double stream corruption. */
|
||||
if (ar9170_nag_limiter(ar)) {
|
||||
printk(KERN_ERR "%s: double rx stream "
|
||||
"corruption!\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"double rx stream corruption!\n");
|
||||
goto err_telluser;
|
||||
} else
|
||||
goto err_silent;
|
||||
@ -1042,9 +1038,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
|
||||
|
||||
if (tlen) {
|
||||
if (net_ratelimit())
|
||||
printk(KERN_ERR "%s: %d bytes of unprocessed "
|
||||
"data left in rx stream!\n",
|
||||
wiphy_name(ar->hw->wiphy), tlen);
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"%d bytes of unprocessed data left in rx stream!\n",
|
||||
tlen);
|
||||
|
||||
goto err_telluser;
|
||||
}
|
||||
@ -1052,10 +1048,9 @@ void ar9170_rx(struct ar9170 *ar, struct sk_buff *skb)
|
||||
return ;
|
||||
|
||||
err_telluser:
|
||||
printk(KERN_ERR "%s: damaged RX stream data [want:%d, "
|
||||
"data:%d, rx:%d, pending:%d ]\n",
|
||||
wiphy_name(ar->hw->wiphy), clen, wlen, tlen,
|
||||
ar->rx_failover_missing);
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"damaged RX stream data [want:%d, data:%d, rx:%d, pending:%d ]\n",
|
||||
clen, wlen, tlen, ar->rx_failover_missing);
|
||||
|
||||
if (ar->rx_failover_missing)
|
||||
print_hex_dump_bytes("rxbuf:", DUMP_PREFIX_OFFSET,
|
||||
@ -1065,9 +1060,8 @@ err_telluser:
|
||||
print_hex_dump_bytes("stream:", DUMP_PREFIX_OFFSET,
|
||||
skb->data, skb->len);
|
||||
|
||||
printk(KERN_ERR "%s: please check your hardware and cables, if "
|
||||
"you see this message frequently.\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"If you see this message frequently, please check your hardware and cables.\n");
|
||||
|
||||
err_silent:
|
||||
if (ar->rx_failover_missing) {
|
||||
@ -1384,10 +1378,10 @@ static void ar9170_tx(struct ar9170 *ar)
|
||||
|
||||
if (remaining_space < frames) {
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: tx quota reached queue:%d, "
|
||||
"remaining slots:%d, needed:%d\n",
|
||||
wiphy_name(ar->hw->wiphy), i, remaining_space,
|
||||
frames);
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"tx quota reached queue:%d, "
|
||||
"remaining slots:%d, needed:%d\n",
|
||||
i, remaining_space, frames);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
frames = remaining_space;
|
||||
}
|
||||
@ -1396,18 +1390,14 @@ static void ar9170_tx(struct ar9170 *ar)
|
||||
ar->tx_stats[i].count += frames;
|
||||
if (ar->tx_stats[i].len >= ar->tx_stats[i].limit) {
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: queue %d full\n",
|
||||
wiphy_name(ar->hw->wiphy), i);
|
||||
|
||||
printk(KERN_DEBUG "%s: stuck frames: ===>\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_debug(ar->hw->wiphy, "queue %d full\n", i);
|
||||
wiphy_debug(ar->hw->wiphy, "stuck frames: ===>\n");
|
||||
ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
|
||||
ar9170_dump_txqueue(ar, &ar->tx_status[i]);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
|
||||
#ifdef AR9170_QUEUE_STOP_DEBUG
|
||||
printk(KERN_DEBUG "%s: stop queue %d\n",
|
||||
wiphy_name(ar->hw->wiphy), i);
|
||||
wiphy_debug(ar->hw->wiphy, "stop queue %d\n", i);
|
||||
__ar9170_dump_txstats(ar);
|
||||
#endif /* AR9170_QUEUE_STOP_DEBUG */
|
||||
ieee80211_stop_queue(ar->hw, i);
|
||||
@ -1435,8 +1425,7 @@ static void ar9170_tx(struct ar9170 *ar)
|
||||
msecs_to_jiffies(AR9170_TX_TIMEOUT);
|
||||
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: send frame q:%d =>\n",
|
||||
wiphy_name(ar->hw->wiphy), i);
|
||||
wiphy_debug(ar->hw->wiphy, "send frame q:%d =>\n", i);
|
||||
ar9170_print_txheader(ar, skb);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
|
||||
@ -1453,26 +1442,25 @@ static void ar9170_tx(struct ar9170 *ar)
|
||||
}
|
||||
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: ar9170_tx report for queue %d\n",
|
||||
wiphy_name(ar->hw->wiphy), i);
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"ar9170_tx report for queue %d\n", i);
|
||||
|
||||
printk(KERN_DEBUG "%s: unprocessed pending frames left:\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"unprocessed pending frames left:\n");
|
||||
ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
|
||||
if (unlikely(frames_failed)) {
|
||||
#ifdef AR9170_QUEUE_DEBUG
|
||||
printk(KERN_DEBUG "%s: frames failed %d =>\n",
|
||||
wiphy_name(ar->hw->wiphy), frames_failed);
|
||||
wiphy_debug(ar->hw->wiphy,
|
||||
"frames failed %d =>\n", frames_failed);
|
||||
#endif /* AR9170_QUEUE_DEBUG */
|
||||
|
||||
spin_lock_irqsave(&ar->tx_stats_lock, flags);
|
||||
ar->tx_stats[i].len -= frames_failed;
|
||||
ar->tx_stats[i].count -= frames_failed;
|
||||
#ifdef AR9170_QUEUE_STOP_DEBUG
|
||||
printk(KERN_DEBUG "%s: wake queue %d\n",
|
||||
wiphy_name(ar->hw->wiphy), i);
|
||||
wiphy_debug(ar->hw->wiphy, "wake queue %d\n", i);
|
||||
__ar9170_dump_txstats(ar);
|
||||
#endif /* AR9170_QUEUE_STOP_DEBUG */
|
||||
ieee80211_wake_queue(ar->hw, i);
|
||||
@ -1917,6 +1905,24 @@ static int ar9170_get_stats(struct ieee80211_hw *hw,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar9170_get_survey(struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey)
|
||||
{
|
||||
struct ar9170 *ar = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
|
||||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
|
||||
/* TODO: update noise value, e.g. call ar9170_set_channel */
|
||||
|
||||
survey->channel = conf->channel;
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = ar->noise[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ar9170_conf_tx(struct ieee80211_hw *hw, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *param)
|
||||
{
|
||||
@ -1969,6 +1975,7 @@ static const struct ieee80211_ops ar9170_ops = {
|
||||
.get_tsf = ar9170_op_get_tsf,
|
||||
.set_key = ar9170_set_key,
|
||||
.get_stats = ar9170_get_stats,
|
||||
.get_survey = ar9170_get_survey,
|
||||
.ampdu_action = ar9170_ampdu_action,
|
||||
};
|
||||
|
||||
|
@ -670,8 +670,7 @@ static int ar9170_init_rf_banks_0_7(struct ar9170 *ar, bool band5ghz)
|
||||
ar9170_regwrite_finish();
|
||||
err = ar9170_regwrite_result();
|
||||
if (err)
|
||||
printk(KERN_ERR "%s: rf init failed\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy, "rf init failed\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -1702,9 +1701,8 @@ int ar9170_set_channel(struct ar9170 *ar, struct ieee80211_channel *channel,
|
||||
0x200 | ar->phy_heavy_clip);
|
||||
if (err) {
|
||||
if (ar9170_nag_limiter(ar))
|
||||
printk(KERN_ERR "%s: failed to set "
|
||||
"heavy clip\n",
|
||||
wiphy_name(ar->hw->wiphy));
|
||||
wiphy_err(ar->hw->wiphy,
|
||||
"failed to set heavy clip\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -239,6 +239,9 @@ static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
|
||||
"TSF\t\t0x%016llx\tTU: %08x\n",
|
||||
(unsigned long long)tsf, TSF_TO_TU(tsf));
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
@ -334,6 +337,9 @@ static ssize_t read_file_debug(struct file *file, char __user *user_buf,
|
||||
sc->debug.level == dbg_info[i].level ? '+' : ' ',
|
||||
dbg_info[i].level, dbg_info[i].desc);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
@ -433,6 +439,9 @@ static ssize_t read_file_antenna(struct file *file, char __user *user_buf,
|
||||
len += snprintf(buf+len, sizeof(buf)-len,
|
||||
"AR5K_PHY_ANT_SWITCH_TABLE_1\t0x%08x\n", v);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
@ -542,6 +551,9 @@ static ssize_t read_file_frameerrors(struct file *file, char __user *user_buf,
|
||||
len += snprintf(buf+len, sizeof(buf)-len, "[TX all\t%d]\n",
|
||||
st->tx_all_count);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
@ -681,6 +693,9 @@ static ssize_t read_file_ani(struct file *file, char __user *user_buf,
|
||||
ATH5K_ANI_CCK_TRIG_HIGH - (ATH5K_PHYERR_CNT_MAX -
|
||||
ath5k_hw_reg_read(sc->ah, AR5K_PHYERR_CNT2)));
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
@ -766,6 +781,9 @@ static ssize_t read_file_queue(struct file *file, char __user *user_buf,
|
||||
len += snprintf(buf+len, sizeof(buf)-len, " len: %d\n", n);
|
||||
}
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
|
@ -131,11 +131,8 @@ static int ath_ahb_probe(struct platform_device *pdev)
|
||||
|
||||
ah = sc->sc_ah;
|
||||
ath9k_hw_name(ah, hw_name, sizeof(hw_name));
|
||||
printk(KERN_INFO
|
||||
"%s: %s mem=0x%lx, irq=%d\n",
|
||||
wiphy_name(hw->wiphy),
|
||||
hw_name,
|
||||
(unsigned long)mem, irq);
|
||||
wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
|
||||
hw_name, (unsigned long)mem, irq);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -1506,6 +1506,9 @@ static void ar5008_hw_do_getnf(struct ath_hw *ah,
|
||||
nf = MS(REG_READ(ah, AR_PHY_CH2_CCA), AR_PHY_CH2_MINCCA_PWR);
|
||||
nfarray[2] = sign_extend(nf, 9);
|
||||
|
||||
if (!IS_CHAN_HT40(ah->curchan))
|
||||
return;
|
||||
|
||||
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
|
||||
nfarray[3] = sign_extend(nf, 9);
|
||||
|
||||
|
@ -477,7 +477,8 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah,
|
||||
nfarray[0] = sign_extend(nf, 9);
|
||||
|
||||
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
|
||||
nfarray[3] = sign_extend(nf, 9);
|
||||
if (IS_CHAN_HT40(ah->curchan))
|
||||
nfarray[3] = sign_extend(nf, 9);
|
||||
|
||||
if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
|
||||
return;
|
||||
@ -486,7 +487,8 @@ static void ar9002_hw_do_getnf(struct ath_hw *ah,
|
||||
nfarray[1] = sign_extend(nf, 9);
|
||||
|
||||
nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
|
||||
nfarray[4] = sign_extend(nf, 9);
|
||||
if (IS_CHAN_HT40(ah->curchan))
|
||||
nfarray[4] = sign_extend(nf, 9);
|
||||
}
|
||||
|
||||
static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
|
||||
|
@ -1029,6 +1029,9 @@ static void ar9003_hw_do_getnf(struct ath_hw *ah,
|
||||
nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
|
||||
nfarray[2] = sign_extend(nf, 9);
|
||||
|
||||
if (!IS_CHAN_HT40(ah->curchan))
|
||||
return;
|
||||
|
||||
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
|
||||
nfarray[3] = sign_extend(nf, 9);
|
||||
|
||||
|
@ -687,7 +687,7 @@ bool ath9k_all_wiphys_idle(struct ath_softc *sc);
|
||||
void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
|
||||
|
||||
void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
|
||||
void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
|
||||
bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
|
||||
|
||||
void ath_start_rfkill_poll(struct ath_softc *sc);
|
||||
extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
|
||||
|
@ -172,26 +172,9 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
struct ath9k_nfcal_hist *h;
|
||||
unsigned i, j;
|
||||
int32_t val;
|
||||
u8 chainmask;
|
||||
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
if (AR_SREV_9300_20_OR_LATER(ah))
|
||||
chainmask = 0x3F;
|
||||
else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
|
||||
chainmask = 0x9;
|
||||
else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
|
||||
if ((ah->rxchainmask & 0x2) || (ah->rxchainmask & 0x4))
|
||||
chainmask = 0x1B;
|
||||
else
|
||||
chainmask = 0x09;
|
||||
} else {
|
||||
if (ah->rxchainmask & 0x4)
|
||||
chainmask = 0x3F;
|
||||
else if (ah->rxchainmask & 0x2)
|
||||
chainmask = 0x1B;
|
||||
else
|
||||
chainmask = 0x09;
|
||||
}
|
||||
h = ah->nfCalHist;
|
||||
|
||||
for (i = 0; i < NUM_NF_READINGS; i++) {
|
||||
@ -278,7 +261,7 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
|
||||
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
"NF calibrated [%s] [chain %d] is %d\n",
|
||||
(i > 3 ? "ext" : "ctl"), i % 3, nf[i]);
|
||||
(i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
|
||||
|
||||
if (nf[i] > limit->max) {
|
||||
ath_print(common, ATH_DBG_CALIBRATE,
|
||||
|
@ -524,6 +524,9 @@ static ssize_t read_file_tgt_stats(struct file *file, char __user *user_buf,
|
||||
len += snprintf(buf + len, sizeof(buf) - len,
|
||||
"%19s : %10u\n", "TX Rate", priv->debug.txrate);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
@ -569,6 +572,9 @@ static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
|
||||
"%20s : %10u\n", "VO queued",
|
||||
priv->debug.tx_stats.queue_stats[WME_AC_VO]);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
@ -595,6 +601,9 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
|
||||
"%20s : %10u\n", "SKBs Dropped",
|
||||
priv->debug.rx_stats.skb_dropped);
|
||||
|
||||
if (len > sizeof(buf))
|
||||
len = sizeof(buf);
|
||||
|
||||
return simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
}
|
||||
|
||||
|
@ -532,7 +532,8 @@ static int __ath9k_hw_init(struct ath_hw *ah)
|
||||
|
||||
if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
|
||||
if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
|
||||
(AR_SREV_9280(ah) && !ah->is_pciexpress)) {
|
||||
((AR_SREV_9160(ah) || AR_SREV_9280(ah)) &&
|
||||
!ah->is_pciexpress)) {
|
||||
ah->config.serialize_regmode =
|
||||
SER_REG_MODE_ON;
|
||||
} else {
|
||||
|
@ -1994,11 +1994,12 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
|
||||
|
||||
mutex_lock(&sc->mutex);
|
||||
if (ath9k_wiphy_scanning(sc)) {
|
||||
printk(KERN_DEBUG "ath9k: Two wiphys trying to scan at the "
|
||||
"same time\n");
|
||||
/*
|
||||
* Do not allow the concurrent scanning state for now. This
|
||||
* could be improved with scanning control moved into ath9k.
|
||||
* There is a race here in mac80211 but fixing it requires
|
||||
* we revisit how we handle the scan complete callback.
|
||||
* After mac80211 fixes we will not have configured hardware
|
||||
* to the home channel nor would we have configured the RX
|
||||
* filter yet.
|
||||
*/
|
||||
mutex_unlock(&sc->mutex);
|
||||
return;
|
||||
@ -2014,6 +2015,10 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
|
||||
mutex_unlock(&sc->mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: this requires a revisit after the driver
|
||||
* scan_complete gets moved to another place/removed in mac80211.
|
||||
*/
|
||||
static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct ath_wiphy *aphy = hw->priv;
|
||||
|
@ -209,11 +209,8 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
}
|
||||
|
||||
ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
|
||||
printk(KERN_INFO
|
||||
"%s: %s mem=0x%lx, irq=%d\n",
|
||||
wiphy_name(hw->wiphy),
|
||||
hw_name,
|
||||
(unsigned long)mem, pdev->irq);
|
||||
wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
|
||||
hw_name, (unsigned long)mem, pdev->irq);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -20,95 +20,145 @@
|
||||
#include "ath9k.h"
|
||||
|
||||
static const struct ath_rate_table ar5416_11na_ratetable = {
|
||||
43,
|
||||
68,
|
||||
8, /* MCS start */
|
||||
{
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
|
||||
5400, 0, 12, 0, 0, 0, 0, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
|
||||
7800, 1, 18, 0, 1, 1, 1, 1 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
|
||||
10000, 2, 24, 2, 2, 2, 2, 2 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
|
||||
13900, 3, 36, 2, 3, 3, 3, 3 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
|
||||
17300, 4, 48, 4, 4, 4, 4, 4 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
|
||||
23000, 5, 72, 4, 5, 5, 5, 5 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
|
||||
27400, 6, 96, 4, 6, 6, 6, 6 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
|
||||
29300, 7, 108, 4, 7, 7, 7, 7 },
|
||||
{ VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
|
||||
6400, 0, 0, 0, 8, 25, 8, 25 },
|
||||
{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
|
||||
12700, 1, 1, 2, 9, 26, 9, 26 },
|
||||
{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
|
||||
18800, 2, 2, 2, 10, 27, 10, 27 },
|
||||
{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
|
||||
25000, 3, 3, 4, 11, 28, 11, 28 },
|
||||
{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
|
||||
36700, 4, 4, 4, 12, 29, 12, 29 },
|
||||
{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
|
||||
48100, 5, 5, 4, 13, 30, 13, 30 },
|
||||
{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
|
||||
53500, 6, 6, 4, 14, 31, 14, 31 },
|
||||
{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
|
||||
59000, 7, 7, 4, 15, 32, 15, 33 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
|
||||
12700, 8, 8, 3, 16, 34, 16, 34 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
|
||||
24800, 9, 9, 2, 17, 35, 17, 35 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
|
||||
36600, 10, 10, 2, 18, 36, 18, 36 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
|
||||
48100, 11, 11, 4, 19, 37, 19, 37 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
|
||||
69500, 12, 12, 4, 20, 38, 20, 38 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
|
||||
89500, 13, 13, 4, 21, 39, 21, 39 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
|
||||
98900, 14, 14, 4, 22, 40, 22, 40 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
|
||||
108300, 15, 15, 4, 23, 41, 24, 42 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 144.4 Mb */
|
||||
12000, 15, 15, 4, 23, 41, 24, 42 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
|
||||
13200, 0, 0, 0, 8, 25, 25, 25 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
|
||||
25900, 1, 1, 2, 9, 26, 26, 26 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
|
||||
38600, 2, 2, 2, 10, 27, 27, 27 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
|
||||
49800, 3, 3, 4, 11, 28, 28, 28 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
|
||||
72200, 4, 4, 4, 12, 29, 29, 29 },
|
||||
{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
|
||||
92900, 5, 5, 4, 13, 30, 30, 30 },
|
||||
{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
|
||||
102700, 6, 6, 4, 14, 31, 31, 31 },
|
||||
{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
|
||||
112000, 7, 7, 4, 15, 32, 33, 33 },
|
||||
{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
|
||||
122000, 7, 7, 4, 15, 32, 33, 33 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
|
||||
25800, 8, 8, 0, 16, 34, 34, 34 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
|
||||
49800, 9, 9, 2, 17, 35, 35, 35 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
|
||||
71900, 10, 10, 2, 18, 36, 36, 36 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
|
||||
92500, 11, 11, 4, 19, 37, 37, 37 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
|
||||
130300, 12, 12, 4, 20, 38, 38, 38 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
|
||||
162800, 13, 13, 4, 21, 39, 39, 39 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
|
||||
178200, 14, 14, 4, 22, 40, 40, 40 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
|
||||
192100, 15, 15, 4, 23, 41, 42, 42 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
|
||||
207000, 15, 15, 4, 23, 41, 42, 42 },
|
||||
[0] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 6000,
|
||||
5400, 0, 12, 0, 0, 0, 0 }, /* 6 Mb */
|
||||
[1] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 9000,
|
||||
7800, 1, 18, 0, 1, 1, 1 }, /* 9 Mb */
|
||||
[2] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
|
||||
10000, 2, 24, 2, 2, 2, 2 }, /* 12 Mb */
|
||||
[3] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
|
||||
13900, 3, 36, 2, 3, 3, 3 }, /* 18 Mb */
|
||||
[4] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
|
||||
17300, 4, 48, 4, 4, 4, 4 }, /* 24 Mb */
|
||||
[5] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
|
||||
23000, 5, 72, 4, 5, 5, 5 }, /* 36 Mb */
|
||||
[6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
|
||||
27400, 6, 96, 4, 6, 6, 6 }, /* 48 Mb */
|
||||
[7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
|
||||
29300, 7, 108, 4, 7, 7, 7 }, /* 54 Mb */
|
||||
[8] = { RC_HT_SDT_2040, WLAN_RC_PHY_HT_20_SS, 6500,
|
||||
6400, 0, 0, 0, 38, 8, 38 }, /* 6.5 Mb */
|
||||
[9] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
|
||||
12700, 1, 1, 2, 39, 9, 39 }, /* 13 Mb */
|
||||
[10] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
|
||||
18800, 2, 2, 2, 40, 10, 40 }, /* 19.5 Mb */
|
||||
[11] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
|
||||
25000, 3, 3, 4, 41, 11, 41 }, /* 26 Mb */
|
||||
[12] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
|
||||
36700, 4, 4, 4, 42, 12, 42 }, /* 39 Mb */
|
||||
[13] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
|
||||
48100, 5, 5, 4, 43, 13, 43 }, /* 52 Mb */
|
||||
[14] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
|
||||
53500, 6, 6, 4, 44, 14, 44 }, /* 58.5 Mb */
|
||||
[15] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
|
||||
59000, 7, 7, 4, 45, 16, 46 }, /* 65 Mb */
|
||||
[16] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
|
||||
65400, 7, 7, 4, 45, 16, 46 }, /* 75 Mb */
|
||||
[17] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
|
||||
12700, 8, 8, 0, 47, 17, 47 }, /* 13 Mb */
|
||||
[18] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
|
||||
24800, 9, 9, 2, 48, 18, 48 }, /* 26 Mb */
|
||||
[19] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
|
||||
36600, 10, 10, 2, 49, 19, 49 }, /* 39 Mb */
|
||||
[20] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
|
||||
48100, 11, 11, 4, 50, 20, 50 }, /* 52 Mb */
|
||||
[21] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
|
||||
69500, 12, 12, 4, 51, 21, 51 }, /* 78 Mb */
|
||||
[22] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
|
||||
89500, 13, 13, 4, 52, 22, 52 }, /* 104 Mb */
|
||||
[23] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
|
||||
98900, 14, 14, 4, 53, 23, 53 }, /* 117 Mb */
|
||||
[24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
|
||||
108300, 15, 15, 4, 54, 25, 55 }, /* 130 Mb */
|
||||
[25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
|
||||
120000, 15, 15, 4, 54, 25, 55 }, /* 144.4 Mb */
|
||||
[26] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
|
||||
17400, 16, 16, 0, 56, 26, 56 }, /* 19.5 Mb */
|
||||
[27] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
|
||||
35100, 17, 17, 2, 57, 27, 57 }, /* 39 Mb */
|
||||
[28] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
|
||||
52600, 18, 18, 2, 58, 28, 58 }, /* 58.5 Mb */
|
||||
[29] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
|
||||
70400, 19, 19, 4, 59, 29, 59 }, /* 78 Mb */
|
||||
[30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
|
||||
104900, 20, 20, 4, 60, 31, 61 }, /* 117 Mb */
|
||||
[31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
|
||||
115800, 20, 20, 4, 60, 31, 61 }, /* 130 Mb*/
|
||||
[32] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
|
||||
137200, 21, 21, 4, 62, 33, 63 }, /* 156 Mb */
|
||||
[33] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
|
||||
151100, 21, 21, 4, 62, 33, 63 }, /* 173.3 Mb */
|
||||
[34] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
|
||||
152800, 22, 22, 4, 64, 35, 65 }, /* 175.5 Mb */
|
||||
[35] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
|
||||
168400, 22, 22, 4, 64, 35, 65 }, /* 195 Mb*/
|
||||
[36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
|
||||
168400, 23, 23, 4, 66, 37, 67 }, /* 195 Mb */
|
||||
[37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
|
||||
185000, 23, 23, 4, 66, 37, 67 }, /* 216.7 Mb */
|
||||
[38] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
|
||||
13200, 0, 0, 0, 38, 38, 38 }, /* 13.5 Mb*/
|
||||
[39] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
|
||||
25900, 1, 1, 2, 39, 39, 39 }, /* 27.0 Mb*/
|
||||
[40] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
|
||||
38600, 2, 2, 2, 40, 40, 40 }, /* 40.5 Mb*/
|
||||
[41] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
|
||||
49800, 3, 3, 4, 41, 41, 41 }, /* 54 Mb */
|
||||
[42] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
|
||||
72200, 4, 4, 4, 42, 42, 42 }, /* 81 Mb */
|
||||
[43] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 108000,
|
||||
92900, 5, 5, 4, 43, 43, 43 }, /* 108 Mb */
|
||||
[44] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
|
||||
102700, 6, 6, 4, 44, 44, 44 }, /* 121.5 Mb*/
|
||||
[45] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
|
||||
112000, 7, 7, 4, 45, 46, 46 }, /* 135 Mb */
|
||||
[46] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
|
||||
122000, 7, 7, 4, 45, 46, 46 }, /* 150 Mb */
|
||||
[47] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
|
||||
25800, 8, 8, 0, 47, 47, 47 }, /* 27 Mb */
|
||||
[48] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
|
||||
49800, 9, 9, 2, 48, 48, 48 }, /* 54 Mb */
|
||||
[49] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
|
||||
71900, 10, 10, 2, 49, 49, 49 }, /* 81 Mb */
|
||||
[50] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
|
||||
92500, 11, 11, 4, 50, 50, 50 }, /* 108 Mb */
|
||||
[51] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
|
||||
130300, 12, 12, 4, 51, 51, 51 }, /* 162 Mb */
|
||||
[52] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
|
||||
162800, 13, 13, 4, 52, 52, 52 }, /* 216 Mb */
|
||||
[53] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
|
||||
178200, 14, 14, 4, 53, 53, 53 }, /* 243 Mb */
|
||||
[54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
|
||||
192100, 15, 15, 4, 54, 55, 55 }, /* 270 Mb */
|
||||
[55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
|
||||
207000, 15, 15, 4, 54, 55, 55 }, /* 300 Mb */
|
||||
[56] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
|
||||
36100, 16, 16, 0, 56, 56, 56 }, /* 40.5 Mb */
|
||||
[57] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
|
||||
72900, 17, 17, 2, 57, 57, 57 }, /* 81 Mb */
|
||||
[58] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
|
||||
108300, 18, 18, 2, 58, 58, 58 }, /* 121.5 Mb */
|
||||
[59] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
|
||||
142000, 19, 19, 4, 59, 59, 59 }, /* 162 Mb */
|
||||
[60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
|
||||
205100, 20, 20, 4, 60, 61, 61 }, /* 243 Mb */
|
||||
[61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
|
||||
224700, 20, 20, 4, 60, 61, 61 }, /* 270 Mb */
|
||||
[62] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
|
||||
263100, 21, 21, 4, 62, 63, 63 }, /* 324 Mb */
|
||||
[63] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
|
||||
288000, 21, 21, 4, 62, 63, 63 }, /* 360 Mb */
|
||||
[64] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
|
||||
290700, 22, 22, 4, 64, 65, 65 }, /* 364.5 Mb */
|
||||
[65] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
|
||||
317200, 22, 22, 4, 64, 65, 65 }, /* 405 Mb */
|
||||
[66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
|
||||
317200, 23, 23, 4, 66, 67, 67 }, /* 405 Mb */
|
||||
[67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
|
||||
346400, 23, 23, 4, 66, 67, 67 }, /* 450 Mb */
|
||||
},
|
||||
50, /* probe interval */
|
||||
WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
|
||||
@ -118,103 +168,153 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
|
||||
* for HT are the 64K max aggregate limit */
|
||||
|
||||
static const struct ath_rate_table ar5416_11ng_ratetable = {
|
||||
47,
|
||||
72,
|
||||
12, /* MCS start */
|
||||
{
|
||||
{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
|
||||
900, 0, 2, 0, 0, 0, 0, 0 },
|
||||
{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
|
||||
1900, 1, 4, 1, 1, 1, 1, 1 },
|
||||
{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
|
||||
4900, 2, 11, 2, 2, 2, 2, 2 },
|
||||
{ VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
|
||||
8100, 3, 22, 3, 3, 3, 3, 3 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
|
||||
5400, 4, 12, 4, 4, 4, 4, 4 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
|
||||
7800, 5, 18, 4, 5, 5, 5, 5 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
|
||||
10100, 6, 24, 6, 6, 6, 6, 6 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
|
||||
14100, 7, 36, 6, 7, 7, 7, 7 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
|
||||
17700, 8, 48, 8, 8, 8, 8, 8 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
|
||||
23700, 9, 72, 8, 9, 9, 9, 9 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
|
||||
27400, 10, 96, 8, 10, 10, 10, 10 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
|
||||
30900, 11, 108, 8, 11, 11, 11, 11 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
|
||||
6400, 0, 0, 4, 12, 29, 12, 29 },
|
||||
{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
|
||||
12700, 1, 1, 6, 13, 30, 13, 30 },
|
||||
{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
|
||||
18800, 2, 2, 6, 14, 31, 14, 31 },
|
||||
{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
|
||||
25000, 3, 3, 8, 15, 32, 15, 32 },
|
||||
{ VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
|
||||
36700, 4, 4, 8, 16, 33, 16, 33 },
|
||||
{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
|
||||
48100, 5, 5, 8, 17, 34, 17, 34 },
|
||||
{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
|
||||
53500, 6, 6, 8, 18, 35, 18, 35 },
|
||||
{ INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
|
||||
59000, 7, 7, 8, 19, 36, 19, 37 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
|
||||
12700, 8, 8, 4, 20, 38, 20, 38 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
|
||||
24800, 9, 9, 6, 21, 39, 21, 39 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
|
||||
36600, 10, 10, 6, 22, 40, 22, 40 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
|
||||
48100, 11, 11, 8, 23, 41, 23, 41 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
|
||||
69500, 12, 12, 8, 24, 42, 24, 42 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
|
||||
89500, 13, 13, 8, 25, 43, 25, 43 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
|
||||
98900, 14, 14, 8, 26, 44, 26, 44 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
|
||||
108300, 15, 15, 8, 27, 45, 28, 46 },
|
||||
{ VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS_HGI, 144400, /* 130 Mb */
|
||||
120000, 15, 15, 8, 27, 45, 28, 46 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
|
||||
13200, 0, 0, 8, 12, 29, 29, 29 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
|
||||
25900, 1, 1, 8, 13, 30, 30, 30 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
|
||||
38600, 2, 2, 8, 14, 31, 31, 31 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
|
||||
49800, 3, 3, 8, 15, 32, 32, 32 },
|
||||
{ VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
|
||||
72200, 4, 4, 8, 16, 33, 33, 33 },
|
||||
{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
|
||||
92900, 5, 5, 8, 17, 34, 34, 34 },
|
||||
{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
|
||||
102700, 6, 6, 8, 18, 35, 35, 35 },
|
||||
{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
|
||||
112000, 7, 7, 8, 19, 36, 37, 37 },
|
||||
{ INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
|
||||
122000, 7, 7, 8, 19, 36, 37, 37 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
|
||||
25800, 8, 8, 8, 20, 38, 38, 38 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
|
||||
49800, 9, 9, 8, 21, 39, 39, 39 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
|
||||
71900, 10, 10, 8, 22, 40, 40, 40 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
|
||||
92500, 11, 11, 8, 23, 41, 41, 41 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
|
||||
130300, 12, 12, 8, 24, 42, 42, 42 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
|
||||
162800, 13, 13, 8, 25, 43, 43, 43 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
|
||||
178200, 14, 14, 8, 26, 44, 44, 44 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
|
||||
192100, 15, 15, 8, 27, 45, 46, 46 },
|
||||
{ VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
|
||||
207000, 15, 15, 8, 27, 45, 46, 46 },
|
||||
[0] = { RC_ALL, WLAN_RC_PHY_CCK, 1000,
|
||||
900, 0, 2, 0, 0, 0, 0 }, /* 1 Mb */
|
||||
[1] = { RC_ALL, WLAN_RC_PHY_CCK, 2000,
|
||||
1900, 1, 4, 1, 1, 1, 1 }, /* 2 Mb */
|
||||
[2] = { RC_ALL, WLAN_RC_PHY_CCK, 5500,
|
||||
4900, 2, 11, 2, 2, 2, 2 }, /* 5.5 Mb */
|
||||
[3] = { RC_ALL, WLAN_RC_PHY_CCK, 11000,
|
||||
8100, 3, 22, 3, 3, 3, 3 }, /* 11 Mb */
|
||||
[4] = { RC_INVALID, WLAN_RC_PHY_OFDM, 6000,
|
||||
5400, 4, 12, 4, 4, 4, 4 }, /* 6 Mb */
|
||||
[5] = { RC_INVALID, WLAN_RC_PHY_OFDM, 9000,
|
||||
7800, 5, 18, 4, 5, 5, 5 }, /* 9 Mb */
|
||||
[6] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 12000,
|
||||
10100, 6, 24, 6, 6, 6, 6 }, /* 12 Mb */
|
||||
[7] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 18000,
|
||||
14100, 7, 36, 6, 7, 7, 7 }, /* 18 Mb */
|
||||
[8] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 24000,
|
||||
17700, 8, 48, 8, 8, 8, 8 }, /* 24 Mb */
|
||||
[9] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 36000,
|
||||
23700, 9, 72, 8, 9, 9, 9 }, /* 36 Mb */
|
||||
[10] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 48000,
|
||||
27400, 10, 96, 8, 10, 10, 10 }, /* 48 Mb */
|
||||
[11] = { RC_L_SDT, WLAN_RC_PHY_OFDM, 54000,
|
||||
30900, 11, 108, 8, 11, 11, 11 }, /* 54 Mb */
|
||||
[12] = { RC_INVALID, WLAN_RC_PHY_HT_20_SS, 6500,
|
||||
6400, 0, 0, 4, 42, 12, 42 }, /* 6.5 Mb */
|
||||
[13] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 13000,
|
||||
12700, 1, 1, 6, 43, 13, 43 }, /* 13 Mb */
|
||||
[14] = { RC_HT_SDT_20, WLAN_RC_PHY_HT_20_SS, 19500,
|
||||
18800, 2, 2, 6, 44, 14, 44 }, /* 19.5 Mb*/
|
||||
[15] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 26000,
|
||||
25000, 3, 3, 8, 45, 15, 45 }, /* 26 Mb */
|
||||
[16] = { RC_HT_SD_20, WLAN_RC_PHY_HT_20_SS, 39000,
|
||||
36700, 4, 4, 8, 46, 16, 46 }, /* 39 Mb */
|
||||
[17] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 52000,
|
||||
48100, 5, 5, 8, 47, 17, 47 }, /* 52 Mb */
|
||||
[18] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 58500,
|
||||
53500, 6, 6, 8, 48, 18, 48 }, /* 58.5 Mb */
|
||||
[19] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS, 65000,
|
||||
59000, 7, 7, 8, 49, 20, 50 }, /* 65 Mb */
|
||||
[20] = { RC_HT_S_20, WLAN_RC_PHY_HT_20_SS_HGI, 72200,
|
||||
65400, 7, 7, 8, 49, 20, 50 }, /* 65 Mb*/
|
||||
[21] = { RC_INVALID, WLAN_RC_PHY_HT_20_DS, 13000,
|
||||
12700, 8, 8, 4, 51, 21, 51 }, /* 13 Mb */
|
||||
[22] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 26000,
|
||||
24800, 9, 9, 6, 52, 22, 52 }, /* 26 Mb */
|
||||
[23] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_DS, 39000,
|
||||
36600, 10, 10, 6, 53, 23, 53 }, /* 39 Mb */
|
||||
[24] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 52000,
|
||||
48100, 11, 11, 8, 54, 24, 54 }, /* 52 Mb */
|
||||
[25] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 78000,
|
||||
69500, 12, 12, 8, 55, 25, 55 }, /* 78 Mb */
|
||||
[26] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 104000,
|
||||
89500, 13, 13, 8, 56, 26, 56 }, /* 104 Mb */
|
||||
[27] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 117000,
|
||||
98900, 14, 14, 8, 57, 27, 57 }, /* 117 Mb */
|
||||
[28] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS, 130000,
|
||||
108300, 15, 15, 8, 58, 29, 59 }, /* 130 Mb */
|
||||
[29] = { RC_HT_DT_20, WLAN_RC_PHY_HT_20_DS_HGI, 144400,
|
||||
120000, 15, 15, 8, 58, 29, 59 }, /* 144.4 Mb */
|
||||
[30] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 19500,
|
||||
17400, 16, 16, 4, 60, 30, 60 }, /* 19.5 Mb */
|
||||
[31] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 39000,
|
||||
35100, 17, 17, 6, 61, 31, 61 }, /* 39 Mb */
|
||||
[32] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 58500,
|
||||
52600, 18, 18, 6, 62, 32, 62 }, /* 58.5 Mb */
|
||||
[33] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 78000,
|
||||
70400, 19, 19, 8, 63, 33, 63 }, /* 78 Mb */
|
||||
[34] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS, 117000,
|
||||
104900, 20, 20, 8, 64, 35, 65 }, /* 117 Mb */
|
||||
[35] = { RC_INVALID, WLAN_RC_PHY_HT_20_TS_HGI, 130000,
|
||||
115800, 20, 20, 8, 64, 35, 65 }, /* 130 Mb */
|
||||
[36] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 156000,
|
||||
137200, 21, 21, 8, 66, 37, 67 }, /* 156 Mb */
|
||||
[37] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 173300,
|
||||
151100, 21, 21, 8, 66, 37, 67 }, /* 173.3 Mb */
|
||||
[38] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 175500,
|
||||
152800, 22, 22, 8, 68, 39, 69 }, /* 175.5 Mb */
|
||||
[39] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 195000,
|
||||
168400, 22, 22, 8, 68, 39, 69 }, /* 195 Mb */
|
||||
[40] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS, 195000,
|
||||
168400, 23, 23, 8, 70, 41, 71 }, /* 195 Mb */
|
||||
[41] = { RC_HT_T_20, WLAN_RC_PHY_HT_20_TS_HGI, 216700,
|
||||
185000, 23, 23, 8, 70, 41, 71 }, /* 216.7 Mb */
|
||||
[42] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 13500,
|
||||
13200, 0, 0, 8, 42, 42, 42 }, /* 13.5 Mb */
|
||||
[43] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 27500,
|
||||
25900, 1, 1, 8, 43, 43, 43 }, /* 27.0 Mb */
|
||||
[44] = { RC_HT_SDT_40, WLAN_RC_PHY_HT_40_SS, 40500,
|
||||
38600, 2, 2, 8, 44, 44, 44 }, /* 40.5 Mb */
|
||||
[45] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 54000,
|
||||
49800, 3, 3, 8, 45, 45, 45 }, /* 54 Mb */
|
||||
[46] = { RC_HT_SD_40, WLAN_RC_PHY_HT_40_SS, 81500,
|
||||
72200, 4, 4, 8, 46, 46, 46 }, /* 81 Mb */
|
||||
[47] = { RC_HT_S_40 , WLAN_RC_PHY_HT_40_SS, 108000,
|
||||
92900, 5, 5, 8, 47, 47, 47 }, /* 108 Mb */
|
||||
[48] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 121500,
|
||||
102700, 6, 6, 8, 48, 48, 48 }, /* 121.5 Mb */
|
||||
[49] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS, 135000,
|
||||
112000, 7, 7, 8, 49, 50, 50 }, /* 135 Mb */
|
||||
[50] = { RC_HT_S_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000,
|
||||
122000, 7, 7, 8, 49, 50, 50 }, /* 150 Mb */
|
||||
[51] = { RC_INVALID, WLAN_RC_PHY_HT_40_DS, 27000,
|
||||
25800, 8, 8, 8, 51, 51, 51 }, /* 27 Mb */
|
||||
[52] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 54000,
|
||||
49800, 9, 9, 8, 52, 52, 52 }, /* 54 Mb */
|
||||
[53] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_DS, 81000,
|
||||
71900, 10, 10, 8, 53, 53, 53 }, /* 81 Mb */
|
||||
[54] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 108000,
|
||||
92500, 11, 11, 8, 54, 54, 54 }, /* 108 Mb */
|
||||
[55] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 162000,
|
||||
130300, 12, 12, 8, 55, 55, 55 }, /* 162 Mb */
|
||||
[56] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 216000,
|
||||
162800, 13, 13, 8, 56, 56, 56 }, /* 216 Mb */
|
||||
[57] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 243000,
|
||||
178200, 14, 14, 8, 57, 57, 57 }, /* 243 Mb */
|
||||
[58] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS, 270000,
|
||||
192100, 15, 15, 8, 58, 59, 59 }, /* 270 Mb */
|
||||
[59] = { RC_HT_DT_40, WLAN_RC_PHY_HT_40_DS_HGI, 300000,
|
||||
207000, 15, 15, 8, 58, 59, 59 }, /* 300 Mb */
|
||||
[60] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 40500,
|
||||
36100, 16, 16, 8, 60, 60, 60 }, /* 40.5 Mb */
|
||||
[61] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 81000,
|
||||
72900, 17, 17, 8, 61, 61, 61 }, /* 81 Mb */
|
||||
[62] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 121500,
|
||||
108300, 18, 18, 8, 62, 62, 62 }, /* 121.5 Mb */
|
||||
[63] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 162000,
|
||||
142000, 19, 19, 8, 63, 63, 63 }, /* 162 Mb */
|
||||
[64] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS, 243000,
|
||||
205100, 20, 20, 8, 64, 65, 65 }, /* 243 Mb */
|
||||
[65] = { RC_INVALID, WLAN_RC_PHY_HT_40_TS_HGI, 270000,
|
||||
224700, 20, 20, 8, 64, 65, 65 }, /* 170 Mb */
|
||||
[66] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 324000,
|
||||
263100, 21, 21, 8, 66, 67, 67 }, /* 324 Mb */
|
||||
[67] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 360000,
|
||||
288000, 21, 21, 8, 66, 67, 67 }, /* 360 Mb */
|
||||
[68] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 364500,
|
||||
290700, 22, 22, 8, 68, 69, 69 }, /* 364.5 Mb */
|
||||
[69] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 405000,
|
||||
317200, 22, 22, 8, 68, 69, 69 }, /* 405 Mb */
|
||||
[70] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS, 405000,
|
||||
317200, 23, 23, 8, 70, 71, 71 }, /* 405 Mb */
|
||||
[71] = { RC_HT_T_40, WLAN_RC_PHY_HT_40_TS_HGI, 450000,
|
||||
346400, 23, 23, 8, 70, 71, 71 }, /* 450 Mb */
|
||||
},
|
||||
50, /* probe interval */
|
||||
WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
|
||||
@ -224,22 +324,22 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
|
||||
8,
|
||||
0,
|
||||
{
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
|
||||
5400, 0, 12, 0, 0, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
|
||||
7800, 1, 18, 0, 1, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
|
||||
10000, 2, 24, 2, 2, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
|
||||
13900, 3, 36, 2, 3, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
|
||||
17300, 4, 48, 4, 4, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
|
||||
23000, 5, 72, 4, 5, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
|
||||
27400, 6, 96, 4, 6, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
|
||||
29300, 7, 108, 4, 7, 0 },
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
|
||||
5400, 0, 12, 0},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
|
||||
7800, 1, 18, 0},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
|
||||
10000, 2, 24, 2},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
|
||||
13900, 3, 36, 2},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
|
||||
17300, 4, 48, 4},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
|
||||
23000, 5, 72, 4},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
|
||||
27400, 6, 96, 4},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
|
||||
29300, 7, 108, 4},
|
||||
},
|
||||
50, /* probe interval */
|
||||
0, /* Phy rates allowed initially */
|
||||
@ -249,30 +349,30 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
|
||||
12,
|
||||
0,
|
||||
{
|
||||
{ VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
|
||||
900, 0, 2, 0, 0, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
|
||||
1900, 1, 4, 1, 1, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
|
||||
4900, 2, 11, 2, 2, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
|
||||
8100, 3, 22, 3, 3, 0 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
|
||||
5400, 4, 12, 4, 4, 0 },
|
||||
{ INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
|
||||
7800, 5, 18, 4, 5, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
|
||||
10000, 6, 24, 6, 6, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
|
||||
13900, 7, 36, 6, 7, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
|
||||
17300, 8, 48, 8, 8, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
|
||||
23000, 9, 72, 8, 9, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
|
||||
27400, 10, 96, 8, 10, 0 },
|
||||
{ VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
|
||||
29300, 11, 108, 8, 11, 0 },
|
||||
{ RC_L_SDT, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
|
||||
900, 0, 2, 0},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
|
||||
1900, 1, 4, 1},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
|
||||
4900, 2, 11, 2},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
|
||||
8100, 3, 22, 3},
|
||||
{ RC_INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
|
||||
5400, 4, 12, 4},
|
||||
{ RC_INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
|
||||
7800, 5, 18, 4},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
|
||||
10000, 6, 24, 6},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
|
||||
13900, 7, 36, 6},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
|
||||
17300, 8, 48, 8},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
|
||||
23000, 9, 72, 8},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
|
||||
27400, 10, 96, 8},
|
||||
{ RC_L_SDT, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
|
||||
29300, 11, 108, 8},
|
||||
},
|
||||
50, /* probe interval */
|
||||
0, /* Phy rates allowed initially */
|
||||
@ -342,7 +442,7 @@ static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
|
||||
u8 index, int valid_tx_rate)
|
||||
{
|
||||
BUG_ON(index > ath_rc_priv->rate_table_size);
|
||||
ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
|
||||
ath_rc_priv->valid_rate_index[index] = !!valid_tx_rate;
|
||||
}
|
||||
|
||||
static inline
|
||||
@ -374,6 +474,8 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
|
||||
return 0;
|
||||
if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
|
||||
return 0;
|
||||
if (WLAN_RC_PHY_TS(phy) && !(capflag & WLAN_RC_TS_FLAG))
|
||||
return 0;
|
||||
if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
|
||||
return 0;
|
||||
if (!ignore_cw && WLAN_RC_PHY_HT(phy))
|
||||
@ -404,13 +506,9 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
|
||||
u32 capflag)
|
||||
{
|
||||
u8 i, hi = 0;
|
||||
u32 valid;
|
||||
|
||||
for (i = 0; i < rate_table->rate_cnt; i++) {
|
||||
valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
|
||||
rate_table->info[i].valid_single_stream :
|
||||
rate_table->info[i].valid);
|
||||
if (valid == 1) {
|
||||
if (rate_table->info[i].rate_flags & RC_LEGACY) {
|
||||
u32 phy = rate_table->info[i].phy;
|
||||
u8 valid_rate_count = 0;
|
||||
|
||||
@ -422,7 +520,7 @@ static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
|
||||
ath_rc_priv->valid_phy_rateidx[phy][valid_rate_count] = i;
|
||||
ath_rc_priv->valid_phy_ratecnt[phy] += 1;
|
||||
ath_rc_set_valid_txmask(ath_rc_priv, i, 1);
|
||||
hi = A_MAX(hi, i);
|
||||
hi = i;
|
||||
}
|
||||
}
|
||||
|
||||
@ -440,9 +538,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
|
||||
for (i = 0; i < rateset->rs_nrates; i++) {
|
||||
for (j = 0; j < rate_table->rate_cnt; j++) {
|
||||
u32 phy = rate_table->info[j].phy;
|
||||
u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
|
||||
rate_table->info[j].valid_single_stream :
|
||||
rate_table->info[j].valid);
|
||||
u16 rate_flags = rate_table->info[i].rate_flags;
|
||||
u8 rate = rateset->rs_rates[i];
|
||||
u8 dot11rate = rate_table->info[j].dot11rate;
|
||||
|
||||
@ -451,8 +547,9 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
|
||||
* (VALID/VALID_20/VALID_40) flags */
|
||||
|
||||
if ((rate == dot11rate) &&
|
||||
((valid & WLAN_RC_CAP_MODE(capflag)) ==
|
||||
WLAN_RC_CAP_MODE(capflag)) &&
|
||||
(rate_flags & WLAN_RC_CAP_MODE(capflag)) ==
|
||||
WLAN_RC_CAP_MODE(capflag) &&
|
||||
(rate_flags & WLAN_RC_CAP_STREAM(capflag)) &&
|
||||
!WLAN_RC_PHY_HT(phy)) {
|
||||
u8 valid_rate_count = 0;
|
||||
|
||||
@ -486,14 +583,13 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
|
||||
for (i = 0; i < rateset->rs_nrates; i++) {
|
||||
for (j = 0; j < rate_table->rate_cnt; j++) {
|
||||
u32 phy = rate_table->info[j].phy;
|
||||
u32 valid = (!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG) ?
|
||||
rate_table->info[j].valid_single_stream :
|
||||
rate_table->info[j].valid);
|
||||
u16 rate_flags = rate_table->info[j].rate_flags;
|
||||
u8 rate = rateset->rs_rates[i];
|
||||
u8 dot11rate = rate_table->info[j].dot11rate;
|
||||
|
||||
if ((rate != dot11rate) || !WLAN_RC_PHY_HT(phy) ||
|
||||
!WLAN_RC_PHY_HT_VALID(valid, capflag))
|
||||
!(rate_flags & WLAN_RC_CAP_STREAM(capflag)) ||
|
||||
!WLAN_RC_PHY_HT_VALID(rate_flags, capflag))
|
||||
continue;
|
||||
|
||||
if (!ath_rc_valid_phyrate(phy, capflag, 0))
|
||||
@ -589,12 +685,15 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
|
||||
if (rate > (ath_rc_priv->rate_table_size - 1))
|
||||
rate = ath_rc_priv->rate_table_size - 1;
|
||||
|
||||
if (rate_table->info[rate].valid &&
|
||||
(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
|
||||
if (RC_TS_ONLY(rate_table->info[rate].rate_flags) &&
|
||||
(ath_rc_priv->ht_cap & WLAN_RC_TS_FLAG))
|
||||
return rate;
|
||||
|
||||
if (rate_table->info[rate].valid_single_stream &&
|
||||
!(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
|
||||
if (RC_DS_OR_LATER(rate_table->info[rate].rate_flags) &&
|
||||
(ath_rc_priv->ht_cap & (WLAN_RC_DS_FLAG | WLAN_RC_TS_FLAG)))
|
||||
return rate;
|
||||
|
||||
if (RC_SS_OR_LEGACY(rate_table->info[rate].rate_flags))
|
||||
return rate;
|
||||
|
||||
/* This should not happen */
|
||||
@ -1007,12 +1106,19 @@ static void ath_rc_update_ht(struct ath_softc *sc,
|
||||
static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
|
||||
struct ieee80211_tx_rate *rate)
|
||||
{
|
||||
int rix;
|
||||
int rix = 0, i = 0;
|
||||
int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
|
||||
|
||||
if (!(rate->flags & IEEE80211_TX_RC_MCS))
|
||||
return rate->idx;
|
||||
|
||||
rix = rate->idx + rate_table->mcs_start;
|
||||
while (rate->idx > mcs_rix_off[i] &&
|
||||
i < sizeof(mcs_rix_off)/sizeof(int)) {
|
||||
rix++; i++;
|
||||
}
|
||||
|
||||
rix += rate->idx + rate_table->mcs_start;
|
||||
|
||||
if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
|
||||
(rate->flags & IEEE80211_TX_RC_SHORT_GI))
|
||||
rix = rate_table->info[rix].ht_index;
|
||||
@ -1020,8 +1126,6 @@ static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
|
||||
rix = rate_table->info[rix].sgi_index;
|
||||
else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
|
||||
rix = rate_table->info[rix].cw40index;
|
||||
else
|
||||
rix = rate_table->info[rix].base_index;
|
||||
|
||||
return rix;
|
||||
}
|
||||
@ -1203,13 +1307,14 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
|
||||
|
||||
if (sta->ht_cap.ht_supported) {
|
||||
caps = WLAN_RC_HT_FLAG;
|
||||
if (sta->ht_cap.mcs.rx_mask[1])
|
||||
if (sta->ht_cap.mcs.rx_mask[1] && sta->ht_cap.mcs.rx_mask[2])
|
||||
caps |= WLAN_RC_TS_FLAG | WLAN_RC_DS_FLAG;
|
||||
else if (sta->ht_cap.mcs.rx_mask[1])
|
||||
caps |= WLAN_RC_DS_FLAG;
|
||||
if (is_cw40)
|
||||
caps |= WLAN_RC_40_FLAG;
|
||||
if (is_sgi)
|
||||
caps |= WLAN_RC_SGI_FLAG;
|
||||
|
||||
}
|
||||
|
||||
return caps;
|
||||
|
@ -24,32 +24,63 @@
|
||||
struct ath_softc;
|
||||
|
||||
#define ATH_RATE_MAX 30
|
||||
#define RATE_TABLE_SIZE 64
|
||||
#define RATE_TABLE_SIZE 72
|
||||
#define MAX_TX_RATE_PHY 48
|
||||
|
||||
/* VALID_ALL - valid for 20/40/Legacy,
|
||||
* VALID - Legacy only,
|
||||
* VALID_20 - HT 20 only,
|
||||
* VALID_40 - HT 40 only */
|
||||
|
||||
#define INVALID 0x0
|
||||
#define VALID 0x1
|
||||
#define VALID_20 0x2
|
||||
#define VALID_40 0x4
|
||||
#define VALID_2040 (VALID_20|VALID_40)
|
||||
#define VALID_ALL (VALID_2040|VALID)
|
||||
#define RC_INVALID 0x0000
|
||||
#define RC_LEGACY 0x0001
|
||||
#define RC_SS 0x0002
|
||||
#define RC_DS 0x0004
|
||||
#define RC_TS 0x0008
|
||||
#define RC_HT_20 0x0010
|
||||
#define RC_HT_40 0x0020
|
||||
|
||||
#define RC_STREAM_MASK 0xe
|
||||
#define RC_DS_OR_LATER(f) ((((f) & RC_STREAM_MASK) == RC_DS) || \
|
||||
(((f) & RC_STREAM_MASK) == (RC_DS | RC_TS)))
|
||||
#define RC_TS_ONLY(f) (((f) & RC_STREAM_MASK) == RC_TS)
|
||||
#define RC_SS_OR_LEGACY(f) ((f) & (RC_SS | RC_LEGACY))
|
||||
|
||||
#define RC_HT_2040 (RC_HT_20 | RC_HT_40)
|
||||
#define RC_ALL_STREAM (RC_SS | RC_DS | RC_TS)
|
||||
#define RC_L_SD (RC_LEGACY | RC_SS | RC_DS)
|
||||
#define RC_L_SDT (RC_LEGACY | RC_SS | RC_DS | RC_TS)
|
||||
#define RC_HT_S_20 (RC_HT_20 | RC_SS)
|
||||
#define RC_HT_D_20 (RC_HT_20 | RC_DS)
|
||||
#define RC_HT_T_20 (RC_HT_20 | RC_TS)
|
||||
#define RC_HT_S_40 (RC_HT_40 | RC_SS)
|
||||
#define RC_HT_D_40 (RC_HT_40 | RC_DS)
|
||||
#define RC_HT_T_40 (RC_HT_40 | RC_TS)
|
||||
|
||||
#define RC_HT_SD_20 (RC_HT_20 | RC_SS | RC_DS)
|
||||
#define RC_HT_DT_20 (RC_HT_20 | RC_DS | RC_TS)
|
||||
#define RC_HT_SD_40 (RC_HT_40 | RC_SS | RC_DS)
|
||||
#define RC_HT_DT_40 (RC_HT_40 | RC_DS | RC_TS)
|
||||
|
||||
#define RC_HT_SD_2040 (RC_HT_2040 | RC_SS | RC_DS)
|
||||
#define RC_HT_SDT_2040 (RC_HT_2040 | RC_SS | RC_DS | RC_TS)
|
||||
|
||||
#define RC_HT_SDT_20 (RC_HT_20 | RC_SS | RC_DS | RC_TS)
|
||||
#define RC_HT_SDT_40 (RC_HT_40 | RC_SS | RC_DS | RC_TS)
|
||||
|
||||
#define RC_ALL (RC_LEGACY | RC_HT_2040 | RC_ALL_STREAM)
|
||||
|
||||
enum {
|
||||
WLAN_RC_PHY_OFDM,
|
||||
WLAN_RC_PHY_CCK,
|
||||
WLAN_RC_PHY_HT_20_SS,
|
||||
WLAN_RC_PHY_HT_20_DS,
|
||||
WLAN_RC_PHY_HT_20_TS,
|
||||
WLAN_RC_PHY_HT_40_SS,
|
||||
WLAN_RC_PHY_HT_40_DS,
|
||||
WLAN_RC_PHY_HT_40_TS,
|
||||
WLAN_RC_PHY_HT_20_SS_HGI,
|
||||
WLAN_RC_PHY_HT_20_DS_HGI,
|
||||
WLAN_RC_PHY_HT_20_TS_HGI,
|
||||
WLAN_RC_PHY_HT_40_SS_HGI,
|
||||
WLAN_RC_PHY_HT_40_DS_HGI,
|
||||
WLAN_RC_PHY_HT_40_TS_HGI,
|
||||
WLAN_RC_PHY_MAX
|
||||
};
|
||||
|
||||
@ -57,36 +88,50 @@ enum {
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_DS) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
|
||||
#define WLAN_RC_PHY_TS(_phy) ((_phy == WLAN_RC_PHY_HT_20_TS) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_TS) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
|
||||
#define WLAN_RC_PHY_20(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_DS) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_TS) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI))
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI))
|
||||
#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_DS) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_TS) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
|
||||
#define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_20_TS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_DS_HGI) \
|
||||
|| (_phy == WLAN_RC_PHY_HT_40_TS_HGI))
|
||||
|
||||
#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS)
|
||||
|
||||
#define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \
|
||||
(capflag & WLAN_RC_40_FLAG) ? VALID_40 : VALID_20 : VALID))
|
||||
((capflag & WLAN_RC_40_FLAG) ? RC_HT_40 : RC_HT_20) : RC_LEGACY))
|
||||
|
||||
#define WLAN_RC_CAP_STREAM(capflag) (((capflag & WLAN_RC_TS_FLAG) ? \
|
||||
(RC_TS) : ((capflag & WLAN_RC_DS_FLAG) ? RC_DS : RC_SS)))
|
||||
|
||||
/* Return TRUE if flag supports HT20 && client supports HT20 or
|
||||
* return TRUE if flag supports HT40 && client supports HT40.
|
||||
* This is used becos some rates overlap between HT20/HT40.
|
||||
*/
|
||||
#define WLAN_RC_PHY_HT_VALID(flag, capflag) \
|
||||
(((flag & VALID_20) && !(capflag & WLAN_RC_40_FLAG)) || \
|
||||
((flag & VALID_40) && (capflag & WLAN_RC_40_FLAG)))
|
||||
(((flag & RC_HT_20) && !(capflag & WLAN_RC_40_FLAG)) || \
|
||||
((flag & RC_HT_40) && (capflag & WLAN_RC_40_FLAG)))
|
||||
|
||||
#define WLAN_RC_DS_FLAG (0x01)
|
||||
#define WLAN_RC_40_FLAG (0x02)
|
||||
#define WLAN_RC_SGI_FLAG (0x04)
|
||||
#define WLAN_RC_HT_FLAG (0x08)
|
||||
#define WLAN_RC_TS_FLAG (0x02)
|
||||
#define WLAN_RC_40_FLAG (0x04)
|
||||
#define WLAN_RC_SGI_FLAG (0x08)
|
||||
#define WLAN_RC_HT_FLAG (0x10)
|
||||
|
||||
/**
|
||||
* struct ath_rate_table - Rate Control table
|
||||
@ -110,15 +155,13 @@ struct ath_rate_table {
|
||||
int rate_cnt;
|
||||
int mcs_start;
|
||||
struct {
|
||||
u8 valid;
|
||||
u8 valid_single_stream;
|
||||
u16 rate_flags;
|
||||
u8 phy;
|
||||
u32 ratekbps;
|
||||
u32 user_ratekbps;
|
||||
u8 ratecode;
|
||||
u8 dot11rate;
|
||||
u8 ctrl_rate;
|
||||
u8 base_index;
|
||||
u8 cw40index;
|
||||
u8 sgi_index;
|
||||
u8 ht_index;
|
||||
|
@ -695,16 +695,18 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
|
||||
idle ? "idle" : "not-idle");
|
||||
}
|
||||
/* Only bother starting a queue on an active virtual wiphy */
|
||||
void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
|
||||
bool ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
|
||||
{
|
||||
struct ieee80211_hw *hw = sc->pri_wiphy->hw;
|
||||
unsigned int i;
|
||||
bool txq_started = false;
|
||||
|
||||
spin_lock_bh(&sc->wiphy_lock);
|
||||
|
||||
/* Start the primary wiphy */
|
||||
if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) {
|
||||
ieee80211_wake_queue(hw, skb_queue);
|
||||
txq_started = true;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
@ -718,11 +720,13 @@ void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
|
||||
|
||||
hw = aphy->hw;
|
||||
ieee80211_wake_queue(hw, skb_queue);
|
||||
txq_started = true;
|
||||
break;
|
||||
}
|
||||
|
||||
unlock:
|
||||
spin_unlock_bh(&sc->wiphy_lock);
|
||||
return txq_started;
|
||||
}
|
||||
|
||||
/* Go ahead and propagate information to all virtual wiphys, it won't hurt */
|
||||
|
@ -518,6 +518,14 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
bf = bf_next;
|
||||
}
|
||||
|
||||
/* prepend un-acked frames to the beginning of the pending frame queue */
|
||||
if (!list_empty(&bf_pending)) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
list_splice(&bf_pending, &tid->buf_q);
|
||||
ath_tx_queue_tid(txq, tid);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
||||
if (tid->state & AGGR_CLEANUP) {
|
||||
if (tid->baw_head == tid->baw_tail) {
|
||||
tid->state &= ~AGGR_ADDBA_COMPLETE;
|
||||
@ -530,14 +538,6 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
|
||||
return;
|
||||
}
|
||||
|
||||
/* prepend un-acked frames to the beginning of the pending frame queue */
|
||||
if (!list_empty(&bf_pending)) {
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
list_splice(&bf_pending, &tid->buf_q);
|
||||
ath_tx_queue_tid(txq, tid);
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
||||
rcu_read_unlock();
|
||||
|
||||
if (needreset)
|
||||
@ -2077,8 +2077,8 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
|
||||
|
||||
spin_lock_bh(&txq->axq_lock);
|
||||
if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
|
||||
ath_mac80211_start_queue(sc, qnum);
|
||||
txq->stopped = 0;
|
||||
if (ath_mac80211_start_queue(sc, qnum))
|
||||
txq->stopped = 0;
|
||||
}
|
||||
spin_unlock_bh(&txq->axq_lock);
|
||||
}
|
||||
|
@ -828,7 +828,6 @@ struct libipw_device {
|
||||
int host_strip_iv_icv;
|
||||
|
||||
int host_open_frag;
|
||||
int host_build_iv;
|
||||
int ieee802_1x; /* is IEEE 802.1X used */
|
||||
|
||||
/* WPA data */
|
||||
|
@ -260,7 +260,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size,
|
||||
rts_required;
|
||||
unsigned long flags;
|
||||
int encrypt, host_encrypt, host_encrypt_msdu, host_build_iv;
|
||||
int encrypt, host_encrypt, host_encrypt_msdu;
|
||||
__be16 ether_type;
|
||||
int bytes, fc, hdr_len;
|
||||
struct sk_buff *skb_frag;
|
||||
@ -301,7 +301,6 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
|
||||
host_encrypt = ieee->host_encrypt && encrypt && crypt;
|
||||
host_encrypt_msdu = ieee->host_encrypt_msdu && encrypt && crypt;
|
||||
host_build_iv = ieee->host_build_iv && encrypt && crypt;
|
||||
|
||||
if (!encrypt && ieee->ieee802_1x &&
|
||||
ieee->drop_unencrypted && ether_type != htons(ETH_P_PAE)) {
|
||||
@ -313,7 +312,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
skb_copy_from_linear_data(skb, dest, ETH_ALEN);
|
||||
skb_copy_from_linear_data_offset(skb, ETH_ALEN, src, ETH_ALEN);
|
||||
|
||||
if (host_encrypt || host_build_iv)
|
||||
if (host_encrypt)
|
||||
fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
|
||||
IEEE80211_FCTL_PROTECTED;
|
||||
else
|
||||
@ -467,7 +466,7 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
for (; i < nr_frags; i++) {
|
||||
skb_frag = txb->fragments[i];
|
||||
|
||||
if (host_encrypt || host_build_iv)
|
||||
if (host_encrypt)
|
||||
skb_reserve(skb_frag,
|
||||
crypt->ops->extra_mpdu_prefix_len);
|
||||
|
||||
@ -502,15 +501,6 @@ netdev_tx_t libipw_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
* to insert the IV between the header and the payload */
|
||||
if (host_encrypt)
|
||||
libipw_encrypt_fragment(ieee, skb_frag, hdr_len);
|
||||
else if (host_build_iv) {
|
||||
atomic_inc(&crypt->refcnt);
|
||||
if (crypt->ops->build_iv)
|
||||
crypt->ops->build_iv(skb_frag, hdr_len,
|
||||
ieee->sec.keys[ieee->sec.active_key],
|
||||
ieee->sec.key_sizes[ieee->sec.active_key],
|
||||
crypt->priv);
|
||||
atomic_dec(&crypt->refcnt);
|
||||
}
|
||||
|
||||
if (ieee->config &
|
||||
(CFG_LIBIPW_COMPUTE_FCS | CFG_LIBIPW_RESERVE_FCS))
|
||||
|
@ -320,7 +320,7 @@ int libipw_wx_set_encode(struct libipw_device *ieee,
|
||||
};
|
||||
int i, key, key_provided, len;
|
||||
struct lib80211_crypt_data **crypt;
|
||||
int host_crypto = ieee->host_encrypt || ieee->host_decrypt || ieee->host_build_iv;
|
||||
int host_crypto = ieee->host_encrypt || ieee->host_decrypt;
|
||||
DECLARE_SSID_BUF(ssid);
|
||||
|
||||
LIBIPW_DEBUG_WX("SET_ENCODE\n");
|
||||
|
@ -222,6 +222,7 @@ static struct iwl_lib_ops iwl1000_lib = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
},
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
|
@ -1605,8 +1605,8 @@ static int iwl4965_hw_get_temperature(struct iwl_priv *priv)
|
||||
if (!test_bit(STATUS_TEMPERATURE, &priv->status))
|
||||
vt = sign_extend(R4, 23);
|
||||
else
|
||||
vt = sign_extend(le32_to_cpu(
|
||||
priv->_agn.statistics.general.temperature), 23);
|
||||
vt = sign_extend(le32_to_cpu(priv->_agn.statistics.
|
||||
general.common.temperature), 23);
|
||||
|
||||
IWL_DEBUG_TEMP(priv, "Calib values R[1-3]: %d %d %d R4: %d\n", R1, R2, R3, vt);
|
||||
|
||||
@ -2285,6 +2285,7 @@ static struct iwl_lib_ops iwl4965_lib = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
},
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
|
@ -265,7 +265,7 @@ static void iwl5150_temperature(struct iwl_priv *priv)
|
||||
u32 vt = 0;
|
||||
s32 offset = iwl_temp_calib_to_offset(priv);
|
||||
|
||||
vt = le32_to_cpu(priv->_agn.statistics.general.temperature);
|
||||
vt = le32_to_cpu(priv->_agn.statistics.general.common.temperature);
|
||||
vt = vt / IWL_5150_VOLTAGE_TO_TEMPERATURE_COEFF + offset;
|
||||
/* now vt hold the temperature in Kelvin */
|
||||
priv->temperature = KELVIN_TO_CELSIUS(vt);
|
||||
@ -398,6 +398,7 @@ static struct iwl_lib_ops iwl5000_lib = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
},
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
|
@ -323,6 +323,7 @@ static struct iwl_lib_ops iwl6000_lib = {
|
||||
.rx_stats_read = iwl_ucode_rx_stats_read,
|
||||
.tx_stats_read = iwl_ucode_tx_stats_read,
|
||||
.general_stats_read = iwl_ucode_general_stats_read,
|
||||
.bt_stats_read = iwl_ucode_bt_stats_read,
|
||||
},
|
||||
.recover_from_tx_stall = iwl_bg_monitor_recover,
|
||||
.check_plcp_health = iwl_good_plcp_health,
|
||||
@ -500,6 +501,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = {
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2abg_cfg = {
|
||||
@ -535,6 +537,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = {
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2bgn_cfg = {
|
||||
@ -572,6 +575,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = {
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_2bg_cfg = {
|
||||
@ -607,6 +611,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = {
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_bgn_cfg = {
|
||||
@ -644,6 +649,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = {
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
};
|
||||
|
||||
struct iwl_cfg iwl6000g2b_bg_cfg = {
|
||||
@ -679,6 +685,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = {
|
||||
.sensitivity_calib_by_driver = true,
|
||||
.chain_noise_calib_by_driver = true,
|
||||
.need_dc_calib = true,
|
||||
.bt_statistics = true,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -605,8 +605,7 @@ void iwl_init_sensitivity(struct iwl_priv *priv)
|
||||
IWL_DEBUG_CALIB(priv, "<<return 0x%X\n", ret);
|
||||
}
|
||||
|
||||
void iwl_sensitivity_calibration(struct iwl_priv *priv,
|
||||
struct iwl_notif_statistics *resp)
|
||||
void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
|
||||
{
|
||||
u32 rx_enable_time;
|
||||
u32 fa_cck;
|
||||
@ -616,8 +615,8 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
|
||||
u32 norm_fa_ofdm;
|
||||
u32 norm_fa_cck;
|
||||
struct iwl_sensitivity_data *data = NULL;
|
||||
struct statistics_rx_non_phy *rx_info = &(resp->rx.general);
|
||||
struct statistics_rx *statistics = &(resp->rx);
|
||||
struct statistics_rx_non_phy *rx_info;
|
||||
struct statistics_rx_phy *ofdm, *cck;
|
||||
unsigned long flags;
|
||||
struct statistics_general_data statis;
|
||||
|
||||
@ -632,6 +631,16 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
if (priv->cfg->bt_statistics) {
|
||||
rx_info = &(((struct iwl_bt_notif_statistics *)resp)->
|
||||
rx.general.common);
|
||||
ofdm = &(((struct iwl_bt_notif_statistics *)resp)->rx.ofdm);
|
||||
cck = &(((struct iwl_bt_notif_statistics *)resp)->rx.cck);
|
||||
} else {
|
||||
rx_info = &(((struct iwl_notif_statistics *)resp)->rx.general);
|
||||
ofdm = &(((struct iwl_notif_statistics *)resp)->rx.ofdm);
|
||||
cck = &(((struct iwl_notif_statistics *)resp)->rx.cck);
|
||||
}
|
||||
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
|
||||
IWL_DEBUG_CALIB(priv, "<< invalid data.\n");
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
@ -640,23 +649,23 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv,
|
||||
|
||||
/* Extract Statistics: */
|
||||
rx_enable_time = le32_to_cpu(rx_info->channel_load);
|
||||
fa_cck = le32_to_cpu(statistics->cck.false_alarm_cnt);
|
||||
fa_ofdm = le32_to_cpu(statistics->ofdm.false_alarm_cnt);
|
||||
bad_plcp_cck = le32_to_cpu(statistics->cck.plcp_err);
|
||||
bad_plcp_ofdm = le32_to_cpu(statistics->ofdm.plcp_err);
|
||||
fa_cck = le32_to_cpu(cck->false_alarm_cnt);
|
||||
fa_ofdm = le32_to_cpu(ofdm->false_alarm_cnt);
|
||||
bad_plcp_cck = le32_to_cpu(cck->plcp_err);
|
||||
bad_plcp_ofdm = le32_to_cpu(ofdm->plcp_err);
|
||||
|
||||
statis.beacon_silence_rssi_a =
|
||||
le32_to_cpu(statistics->general.beacon_silence_rssi_a);
|
||||
le32_to_cpu(rx_info->beacon_silence_rssi_a);
|
||||
statis.beacon_silence_rssi_b =
|
||||
le32_to_cpu(statistics->general.beacon_silence_rssi_b);
|
||||
le32_to_cpu(rx_info->beacon_silence_rssi_b);
|
||||
statis.beacon_silence_rssi_c =
|
||||
le32_to_cpu(statistics->general.beacon_silence_rssi_c);
|
||||
le32_to_cpu(rx_info->beacon_silence_rssi_c);
|
||||
statis.beacon_energy_a =
|
||||
le32_to_cpu(statistics->general.beacon_energy_a);
|
||||
le32_to_cpu(rx_info->beacon_energy_a);
|
||||
statis.beacon_energy_b =
|
||||
le32_to_cpu(statistics->general.beacon_energy_b);
|
||||
le32_to_cpu(rx_info->beacon_energy_b);
|
||||
statis.beacon_energy_c =
|
||||
le32_to_cpu(statistics->general.beacon_energy_c);
|
||||
le32_to_cpu(rx_info->beacon_energy_c);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
@ -728,8 +737,7 @@ static inline u8 find_first_chain(u8 mask)
|
||||
* 1) Which antennas are connected.
|
||||
* 2) Differential rx gain settings to balance the 3 receivers.
|
||||
*/
|
||||
void iwl_chain_noise_calibration(struct iwl_priv *priv,
|
||||
struct iwl_notif_statistics *stat_resp)
|
||||
void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
|
||||
{
|
||||
struct iwl_chain_noise_data *data = NULL;
|
||||
|
||||
@ -753,7 +761,7 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
|
||||
u32 active_chains = 0;
|
||||
u8 num_tx_chains;
|
||||
unsigned long flags;
|
||||
struct statistics_rx_non_phy *rx_info = &(stat_resp->rx.general);
|
||||
struct statistics_rx_non_phy *rx_info;
|
||||
u8 first_chain;
|
||||
|
||||
if (priv->disable_chain_noise_cal)
|
||||
@ -772,6 +780,13 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
if (priv->cfg->bt_statistics) {
|
||||
rx_info = &(((struct iwl_bt_notif_statistics *)stat_resp)->
|
||||
rx.general.common);
|
||||
} else {
|
||||
rx_info = &(((struct iwl_notif_statistics *)stat_resp)->
|
||||
rx.general);
|
||||
}
|
||||
if (rx_info->interference_data_flag != INTERFERENCE_DATA_AVAILABLE) {
|
||||
IWL_DEBUG_CALIB(priv, " << Interference data unavailable\n");
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
@ -780,8 +795,19 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv,
|
||||
|
||||
rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK);
|
||||
rxon_chnum = le16_to_cpu(priv->staging_rxon.channel);
|
||||
stat_band24 = !!(stat_resp->flag & STATISTICS_REPLY_FLG_BAND_24G_MSK);
|
||||
stat_chnum = le32_to_cpu(stat_resp->flag) >> 16;
|
||||
if (priv->cfg->bt_statistics) {
|
||||
stat_band24 = !!(((struct iwl_bt_notif_statistics *)
|
||||
stat_resp)->flag &
|
||||
STATISTICS_REPLY_FLG_BAND_24G_MSK);
|
||||
stat_chnum = le32_to_cpu(((struct iwl_bt_notif_statistics *)
|
||||
stat_resp)->flag) >> 16;
|
||||
} else {
|
||||
stat_band24 = !!(((struct iwl_notif_statistics *)
|
||||
stat_resp)->flag &
|
||||
STATISTICS_REPLY_FLG_BAND_24G_MSK);
|
||||
stat_chnum = le32_to_cpu(((struct iwl_notif_statistics *)
|
||||
stat_resp)->flag) >> 16;
|
||||
}
|
||||
|
||||
/* Make sure we accumulate data for just the associated channel
|
||||
* (even if scanning). */
|
||||
|
@ -31,21 +31,24 @@
|
||||
static int iwl_statistics_flag(struct iwl_priv *priv, char *buf, int bufsz)
|
||||
{
|
||||
int p = 0;
|
||||
u32 flag;
|
||||
|
||||
p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n",
|
||||
le32_to_cpu(priv->_agn.statistics.flag));
|
||||
if (le32_to_cpu(priv->_agn.statistics.flag) &
|
||||
UCODE_STATISTICS_CLEAR_MSK)
|
||||
if (priv->cfg->bt_statistics)
|
||||
flag = le32_to_cpu(priv->_agn.statistics_bt.flag);
|
||||
else
|
||||
flag = le32_to_cpu(priv->_agn.statistics.flag);
|
||||
|
||||
p += scnprintf(buf + p, bufsz - p, "Statistics Flag(0x%X):\n", flag);
|
||||
if (flag & UCODE_STATISTICS_CLEAR_MSK)
|
||||
p += scnprintf(buf + p, bufsz - p,
|
||||
"\tStatistics have been cleared\n");
|
||||
"\tStatistics have been cleared\n");
|
||||
p += scnprintf(buf + p, bufsz - p, "\tOperational Frequency: %s\n",
|
||||
(le32_to_cpu(priv->_agn.statistics.flag) &
|
||||
UCODE_STATISTICS_FREQUENCY_MSK)
|
||||
? "2.4 GHz" : "5.2 GHz");
|
||||
(flag & UCODE_STATISTICS_FREQUENCY_MSK)
|
||||
? "2.4 GHz" : "5.2 GHz");
|
||||
p += scnprintf(buf + p, bufsz - p, "\tTGj Narrow Band: %s\n",
|
||||
(le32_to_cpu(priv->_agn.statistics.flag) &
|
||||
UCODE_STATISTICS_NARROW_BAND_MSK)
|
||||
? "enabled" : "disabled");
|
||||
(flag & UCODE_STATISTICS_NARROW_BAND_MSK)
|
||||
? "enabled" : "disabled");
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
@ -79,22 +82,43 @@ ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
ofdm = &priv->_agn.statistics.rx.ofdm;
|
||||
cck = &priv->_agn.statistics.rx.cck;
|
||||
general = &priv->_agn.statistics.rx.general;
|
||||
ht = &priv->_agn.statistics.rx.ofdm_ht;
|
||||
accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
|
||||
accum_cck = &priv->_agn.accum_statistics.rx.cck;
|
||||
accum_general = &priv->_agn.accum_statistics.rx.general;
|
||||
accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
|
||||
delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
|
||||
delta_cck = &priv->_agn.delta_statistics.rx.cck;
|
||||
delta_general = &priv->_agn.delta_statistics.rx.general;
|
||||
delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
|
||||
max_ofdm = &priv->_agn.max_delta.rx.ofdm;
|
||||
max_cck = &priv->_agn.max_delta.rx.cck;
|
||||
max_general = &priv->_agn.max_delta.rx.general;
|
||||
max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
|
||||
if (priv->cfg->bt_statistics) {
|
||||
ofdm = &priv->_agn.statistics_bt.rx.ofdm;
|
||||
cck = &priv->_agn.statistics_bt.rx.cck;
|
||||
general = &priv->_agn.statistics_bt.rx.general.common;
|
||||
ht = &priv->_agn.statistics_bt.rx.ofdm_ht;
|
||||
accum_ofdm = &priv->_agn.accum_statistics_bt.rx.ofdm;
|
||||
accum_cck = &priv->_agn.accum_statistics_bt.rx.cck;
|
||||
accum_general =
|
||||
&priv->_agn.accum_statistics_bt.rx.general.common;
|
||||
accum_ht = &priv->_agn.accum_statistics_bt.rx.ofdm_ht;
|
||||
delta_ofdm = &priv->_agn.delta_statistics_bt.rx.ofdm;
|
||||
delta_cck = &priv->_agn.delta_statistics_bt.rx.cck;
|
||||
delta_general =
|
||||
&priv->_agn.delta_statistics_bt.rx.general.common;
|
||||
delta_ht = &priv->_agn.delta_statistics_bt.rx.ofdm_ht;
|
||||
max_ofdm = &priv->_agn.max_delta_bt.rx.ofdm;
|
||||
max_cck = &priv->_agn.max_delta_bt.rx.cck;
|
||||
max_general = &priv->_agn.max_delta_bt.rx.general.common;
|
||||
max_ht = &priv->_agn.max_delta_bt.rx.ofdm_ht;
|
||||
} else {
|
||||
ofdm = &priv->_agn.statistics.rx.ofdm;
|
||||
cck = &priv->_agn.statistics.rx.cck;
|
||||
general = &priv->_agn.statistics.rx.general;
|
||||
ht = &priv->_agn.statistics.rx.ofdm_ht;
|
||||
accum_ofdm = &priv->_agn.accum_statistics.rx.ofdm;
|
||||
accum_cck = &priv->_agn.accum_statistics.rx.cck;
|
||||
accum_general = &priv->_agn.accum_statistics.rx.general;
|
||||
accum_ht = &priv->_agn.accum_statistics.rx.ofdm_ht;
|
||||
delta_ofdm = &priv->_agn.delta_statistics.rx.ofdm;
|
||||
delta_cck = &priv->_agn.delta_statistics.rx.cck;
|
||||
delta_general = &priv->_agn.delta_statistics.rx.general;
|
||||
delta_ht = &priv->_agn.delta_statistics.rx.ofdm_ht;
|
||||
max_ofdm = &priv->_agn.max_delta.rx.ofdm;
|
||||
max_cck = &priv->_agn.max_delta.rx.cck;
|
||||
max_general = &priv->_agn.max_delta.rx.general;
|
||||
max_ht = &priv->_agn.max_delta.rx.ofdm_ht;
|
||||
}
|
||||
|
||||
pos += iwl_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
|
||||
@ -560,10 +584,18 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file,
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
tx = &priv->_agn.statistics.tx;
|
||||
accum_tx = &priv->_agn.accum_statistics.tx;
|
||||
delta_tx = &priv->_agn.delta_statistics.tx;
|
||||
max_tx = &priv->_agn.max_delta.tx;
|
||||
if (priv->cfg->bt_statistics) {
|
||||
tx = &priv->_agn.statistics_bt.tx;
|
||||
accum_tx = &priv->_agn.accum_statistics_bt.tx;
|
||||
delta_tx = &priv->_agn.delta_statistics_bt.tx;
|
||||
max_tx = &priv->_agn.max_delta_bt.tx;
|
||||
} else {
|
||||
tx = &priv->_agn.statistics.tx;
|
||||
accum_tx = &priv->_agn.accum_statistics.tx;
|
||||
delta_tx = &priv->_agn.delta_statistics.tx;
|
||||
max_tx = &priv->_agn.max_delta.tx;
|
||||
}
|
||||
|
||||
pos += iwl_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
|
||||
"acumulative delta max\n",
|
||||
@ -759,8 +791,8 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
char *buf;
|
||||
int bufsz = sizeof(struct statistics_general) * 10 + 300;
|
||||
ssize_t ret;
|
||||
struct statistics_general *general, *accum_general;
|
||||
struct statistics_general *delta_general, *max_general;
|
||||
struct statistics_general_common *general, *accum_general;
|
||||
struct statistics_general_common *delta_general, *max_general;
|
||||
struct statistics_dbg *dbg, *accum_dbg, *delta_dbg, *max_dbg;
|
||||
struct statistics_div *div, *accum_div, *delta_div, *max_div;
|
||||
|
||||
@ -777,18 +809,34 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
general = &priv->_agn.statistics.general;
|
||||
dbg = &priv->_agn.statistics.general.dbg;
|
||||
div = &priv->_agn.statistics.general.div;
|
||||
accum_general = &priv->_agn.accum_statistics.general;
|
||||
delta_general = &priv->_agn.delta_statistics.general;
|
||||
max_general = &priv->_agn.max_delta.general;
|
||||
accum_dbg = &priv->_agn.accum_statistics.general.dbg;
|
||||
delta_dbg = &priv->_agn.delta_statistics.general.dbg;
|
||||
max_dbg = &priv->_agn.max_delta.general.dbg;
|
||||
accum_div = &priv->_agn.accum_statistics.general.div;
|
||||
delta_div = &priv->_agn.delta_statistics.general.div;
|
||||
max_div = &priv->_agn.max_delta.general.div;
|
||||
if (priv->cfg->bt_statistics) {
|
||||
general = &priv->_agn.statistics_bt.general.common;
|
||||
dbg = &priv->_agn.statistics_bt.general.common.dbg;
|
||||
div = &priv->_agn.statistics_bt.general.common.div;
|
||||
accum_general = &priv->_agn.accum_statistics_bt.general.common;
|
||||
accum_dbg = &priv->_agn.accum_statistics_bt.general.common.dbg;
|
||||
accum_div = &priv->_agn.accum_statistics_bt.general.common.div;
|
||||
delta_general = &priv->_agn.delta_statistics_bt.general.common;
|
||||
max_general = &priv->_agn.max_delta_bt.general.common;
|
||||
delta_dbg = &priv->_agn.delta_statistics_bt.general.common.dbg;
|
||||
max_dbg = &priv->_agn.max_delta_bt.general.common.dbg;
|
||||
delta_div = &priv->_agn.delta_statistics_bt.general.common.div;
|
||||
max_div = &priv->_agn.max_delta_bt.general.common.div;
|
||||
} else {
|
||||
general = &priv->_agn.statistics.general.common;
|
||||
dbg = &priv->_agn.statistics.general.common.dbg;
|
||||
div = &priv->_agn.statistics.general.common.div;
|
||||
accum_general = &priv->_agn.accum_statistics.general.common;
|
||||
accum_dbg = &priv->_agn.accum_statistics.general.common.dbg;
|
||||
accum_div = &priv->_agn.accum_statistics.general.common.div;
|
||||
delta_general = &priv->_agn.delta_statistics.general.common;
|
||||
max_general = &priv->_agn.max_delta.general.common;
|
||||
delta_dbg = &priv->_agn.delta_statistics.general.common.dbg;
|
||||
max_dbg = &priv->_agn.max_delta.general.common.dbg;
|
||||
delta_div = &priv->_agn.delta_statistics.general.common.div;
|
||||
max_div = &priv->_agn.max_delta.general.common.div;
|
||||
}
|
||||
|
||||
pos += iwl_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "%-32s current"
|
||||
"acumulative delta max\n",
|
||||
@ -876,3 +924,90 @@ ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t iwl_ucode_bt_stats_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
|
||||
int pos = 0;
|
||||
char *buf;
|
||||
int bufsz = (sizeof(struct statistics_bt_activity) * 24) + 200;
|
||||
ssize_t ret;
|
||||
struct statistics_bt_activity *bt, *accum_bt;
|
||||
|
||||
if (!iwl_is_alive(priv))
|
||||
return -EAGAIN;
|
||||
|
||||
/* make request to uCode to retrieve statistics information */
|
||||
mutex_lock(&priv->mutex);
|
||||
ret = iwl_send_statistics_request(priv, CMD_SYNC, false);
|
||||
mutex_unlock(&priv->mutex);
|
||||
|
||||
if (ret) {
|
||||
IWL_ERR(priv,
|
||||
"Error sending statistics request: %zd\n", ret);
|
||||
return -EAGAIN;
|
||||
}
|
||||
buf = kzalloc(bufsz, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
IWL_ERR(priv, "Can not allocate Buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
* the statistic information display here is based on
|
||||
* the last statistics notification from uCode
|
||||
* might not reflect the current uCode activity
|
||||
*/
|
||||
bt = &priv->_agn.statistics_bt.general.activity;
|
||||
accum_bt = &priv->_agn.accum_statistics_bt.general.activity;
|
||||
|
||||
pos += iwl_statistics_flag(priv, buf, bufsz);
|
||||
pos += scnprintf(buf + pos, bufsz - pos, "Statistics_BT:\n");
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"\t\t\tcurrent\t\t\taccumulative\n");
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"hi_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
|
||||
le32_to_cpu(bt->hi_priority_tx_req_cnt),
|
||||
accum_bt->hi_priority_tx_req_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"hi_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
|
||||
le32_to_cpu(bt->hi_priority_tx_denied_cnt),
|
||||
accum_bt->hi_priority_tx_denied_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"lo_priority_tx_req_cnt:\t\t%u\t\t\t%u\n",
|
||||
le32_to_cpu(bt->lo_priority_tx_req_cnt),
|
||||
accum_bt->lo_priority_tx_req_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
|
||||
le32_to_cpu(bt->lo_priority_tx_denied_cnt),
|
||||
accum_bt->lo_priority_tx_denied_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"hi_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
|
||||
le32_to_cpu(bt->hi_priority_rx_req_cnt),
|
||||
accum_bt->hi_priority_rx_req_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"hi_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
|
||||
le32_to_cpu(bt->hi_priority_rx_denied_cnt),
|
||||
accum_bt->hi_priority_rx_denied_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"lo_priority_rx_req_cnt:\t\t%u\t\t\t%u\n",
|
||||
le32_to_cpu(bt->lo_priority_rx_req_cnt),
|
||||
accum_bt->lo_priority_rx_req_cnt);
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
|
||||
le32_to_cpu(bt->lo_priority_rx_denied_cnt),
|
||||
accum_bt->lo_priority_rx_denied_cnt);
|
||||
|
||||
pos += scnprintf(buf + pos, bufsz - pos,
|
||||
"(rx)num_bt_kills:\t\t%u\t\t\t%u\n",
|
||||
le32_to_cpu(priv->_agn.statistics_bt.rx.
|
||||
general.num_bt_kills),
|
||||
priv->_agn.accum_statistics_bt.rx.
|
||||
general.num_bt_kills);
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ ssize_t iwl_ucode_tx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
#else
|
||||
static ssize_t iwl_ucode_rx_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
@ -53,4 +55,9 @@ static ssize_t iwl_ucode_general_stats_read(struct file *file, char __user *user
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static ssize_t iwl_ucode_bt_stats_read(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -164,7 +164,7 @@ static void iwlagn_gain_computation(struct iwl_priv *priv,
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
|
||||
cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD;
|
||||
cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_gain_cmd;
|
||||
cmd.hdr.first_group = 0;
|
||||
cmd.hdr.groups_num = 1;
|
||||
cmd.hdr.data_valid = 1;
|
||||
@ -197,7 +197,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
|
||||
data->beacon_count = 0;
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.op_code = IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD;
|
||||
cmd.hdr.op_code = priv->_agn.phy_calib_chain_noise_reset_cmd;
|
||||
cmd.hdr.first_group = 0;
|
||||
cmd.hdr.groups_num = 1;
|
||||
cmd.hdr.data_valid = 1;
|
||||
|
@ -364,7 +364,7 @@ void iwlagn_temperature(struct iwl_priv *priv)
|
||||
{
|
||||
/* store temperature from statistics (in Celsius) */
|
||||
priv->temperature =
|
||||
le32_to_cpu(priv->_agn.statistics.general.temperature);
|
||||
le32_to_cpu(priv->_agn.statistics.general.common.temperature);
|
||||
iwl_tt_handler(priv);
|
||||
}
|
||||
|
||||
@ -1234,7 +1234,10 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
|
||||
IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
interval = vif ? vif->bss_conf.beacon_int : 0;
|
||||
if (priv->is_internal_short_scan)
|
||||
interval = 0;
|
||||
else
|
||||
interval = vif->bss_conf.beacon_int;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
scan->suspend_time = 0;
|
||||
|
@ -67,18 +67,23 @@ void iwl_rx_missed_beacon_notif(struct iwl_priv *priv,
|
||||
* exactly when to expect beacons, therefore only when we're associated. */
|
||||
static void iwl_rx_calc_noise(struct iwl_priv *priv)
|
||||
{
|
||||
struct statistics_rx_non_phy *rx_info
|
||||
= &(priv->_agn.statistics.rx.general);
|
||||
struct statistics_rx_non_phy *rx_info;
|
||||
int num_active_rx = 0;
|
||||
int total_silence = 0;
|
||||
int bcn_silence_a =
|
||||
le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
|
||||
int bcn_silence_b =
|
||||
le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
|
||||
int bcn_silence_c =
|
||||
le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
|
||||
int bcn_silence_a, bcn_silence_b, bcn_silence_c;
|
||||
int last_rx_noise;
|
||||
|
||||
if (priv->cfg->bt_statistics)
|
||||
rx_info = &(priv->_agn.statistics_bt.rx.general.common);
|
||||
else
|
||||
rx_info = &(priv->_agn.statistics.rx.general);
|
||||
bcn_silence_a =
|
||||
le32_to_cpu(rx_info->beacon_silence_rssi_a) & IN_BAND_FILTER;
|
||||
bcn_silence_b =
|
||||
le32_to_cpu(rx_info->beacon_silence_rssi_b) & IN_BAND_FILTER;
|
||||
bcn_silence_c =
|
||||
le32_to_cpu(rx_info->beacon_silence_rssi_c) & IN_BAND_FILTER;
|
||||
|
||||
if (bcn_silence_a) {
|
||||
total_silence += bcn_silence_a;
|
||||
num_active_rx++;
|
||||
@ -112,17 +117,35 @@ static void iwl_rx_calc_noise(struct iwl_priv *priv)
|
||||
static void iwl_accumulative_statistics(struct iwl_priv *priv,
|
||||
__le32 *stats)
|
||||
{
|
||||
int i;
|
||||
int i, size;
|
||||
__le32 *prev_stats;
|
||||
u32 *accum_stats;
|
||||
u32 *delta, *max_delta;
|
||||
struct statistics_general_common *general, *accum_general;
|
||||
struct statistics_tx *tx, *accum_tx;
|
||||
|
||||
prev_stats = (__le32 *)&priv->_agn.statistics;
|
||||
accum_stats = (u32 *)&priv->_agn.accum_statistics;
|
||||
delta = (u32 *)&priv->_agn.delta_statistics;
|
||||
max_delta = (u32 *)&priv->_agn.max_delta;
|
||||
|
||||
for (i = sizeof(__le32); i < sizeof(struct iwl_notif_statistics);
|
||||
if (priv->cfg->bt_statistics) {
|
||||
prev_stats = (__le32 *)&priv->_agn.statistics_bt;
|
||||
accum_stats = (u32 *)&priv->_agn.accum_statistics_bt;
|
||||
size = sizeof(struct iwl_bt_notif_statistics);
|
||||
general = &priv->_agn.statistics_bt.general.common;
|
||||
accum_general = &priv->_agn.accum_statistics_bt.general.common;
|
||||
tx = &priv->_agn.statistics_bt.tx;
|
||||
accum_tx = &priv->_agn.accum_statistics_bt.tx;
|
||||
delta = (u32 *)&priv->_agn.delta_statistics_bt;
|
||||
max_delta = (u32 *)&priv->_agn.max_delta_bt;
|
||||
} else {
|
||||
prev_stats = (__le32 *)&priv->_agn.statistics;
|
||||
accum_stats = (u32 *)&priv->_agn.accum_statistics;
|
||||
size = sizeof(struct iwl_notif_statistics);
|
||||
general = &priv->_agn.statistics.general.common;
|
||||
accum_general = &priv->_agn.accum_statistics.general.common;
|
||||
tx = &priv->_agn.statistics.tx;
|
||||
accum_tx = &priv->_agn.accum_statistics.tx;
|
||||
delta = (u32 *)&priv->_agn.delta_statistics;
|
||||
max_delta = (u32 *)&priv->_agn.max_delta;
|
||||
}
|
||||
for (i = sizeof(__le32); i < size;
|
||||
i += sizeof(__le32), stats++, prev_stats++, delta++,
|
||||
max_delta++, accum_stats++) {
|
||||
if (le32_to_cpu(*stats) > le32_to_cpu(*prev_stats)) {
|
||||
@ -135,18 +158,12 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
|
||||
}
|
||||
|
||||
/* reset accumulative statistics for "no-counter" type statistics */
|
||||
priv->_agn.accum_statistics.general.temperature =
|
||||
priv->_agn.statistics.general.temperature;
|
||||
priv->_agn.accum_statistics.general.temperature_m =
|
||||
priv->_agn.statistics.general.temperature_m;
|
||||
priv->_agn.accum_statistics.general.ttl_timestamp =
|
||||
priv->_agn.statistics.general.ttl_timestamp;
|
||||
priv->_agn.accum_statistics.tx.tx_power.ant_a =
|
||||
priv->_agn.statistics.tx.tx_power.ant_a;
|
||||
priv->_agn.accum_statistics.tx.tx_power.ant_b =
|
||||
priv->_agn.statistics.tx.tx_power.ant_b;
|
||||
priv->_agn.accum_statistics.tx.tx_power.ant_c =
|
||||
priv->_agn.statistics.tx.tx_power.ant_c;
|
||||
accum_general->temperature = general->temperature;
|
||||
accum_general->temperature_m = general->temperature_m;
|
||||
accum_general->ttl_timestamp = general->ttl_timestamp;
|
||||
accum_tx->tx_power.ant_a = tx->tx_power.ant_a;
|
||||
accum_tx->tx_power.ant_b = tx->tx_power.ant_b;
|
||||
accum_tx->tx_power.ant_c = tx->tx_power.ant_c;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -185,11 +202,30 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
|
||||
* by zero.
|
||||
*/
|
||||
if (plcp_msec) {
|
||||
combined_plcp_delta =
|
||||
(le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err) -
|
||||
le32_to_cpu(priv->_agn.statistics.rx.ofdm.plcp_err)) +
|
||||
(le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err) -
|
||||
le32_to_cpu(priv->_agn.statistics.rx.ofdm_ht.plcp_err));
|
||||
struct statistics_rx_phy *ofdm;
|
||||
struct statistics_rx_ht_phy *ofdm_ht;
|
||||
|
||||
if (priv->cfg->bt_statistics) {
|
||||
ofdm = &pkt->u.stats_bt.rx.ofdm;
|
||||
ofdm_ht = &pkt->u.stats_bt.rx.ofdm_ht;
|
||||
combined_plcp_delta =
|
||||
(le32_to_cpu(ofdm->plcp_err) -
|
||||
le32_to_cpu(priv->_agn.statistics_bt.
|
||||
rx.ofdm.plcp_err)) +
|
||||
(le32_to_cpu(ofdm_ht->plcp_err) -
|
||||
le32_to_cpu(priv->_agn.statistics_bt.
|
||||
rx.ofdm_ht.plcp_err));
|
||||
} else {
|
||||
ofdm = &pkt->u.stats.rx.ofdm;
|
||||
ofdm_ht = &pkt->u.stats.rx.ofdm_ht;
|
||||
combined_plcp_delta =
|
||||
(le32_to_cpu(ofdm->plcp_err) -
|
||||
le32_to_cpu(priv->_agn.statistics.
|
||||
rx.ofdm.plcp_err)) +
|
||||
(le32_to_cpu(ofdm_ht->plcp_err) -
|
||||
le32_to_cpu(priv->_agn.statistics.
|
||||
rx.ofdm_ht.plcp_err));
|
||||
}
|
||||
|
||||
if ((combined_plcp_delta > 0) &&
|
||||
((combined_plcp_delta * 100) / plcp_msec) >
|
||||
@ -206,15 +242,14 @@ bool iwl_good_plcp_health(struct iwl_priv *priv,
|
||||
* plcp_msec
|
||||
*/
|
||||
IWL_DEBUG_RADIO(priv, "plcp_err exceeded %u, "
|
||||
"%u, %u, %u, %u, %d, %u mSecs\n",
|
||||
priv->cfg->plcp_delta_threshold,
|
||||
le32_to_cpu(pkt->u.stats.rx.ofdm.plcp_err),
|
||||
le32_to_cpu(
|
||||
priv->_agn.statistics.rx.ofdm.plcp_err),
|
||||
le32_to_cpu(pkt->u.stats.rx.ofdm_ht.plcp_err),
|
||||
le32_to_cpu(
|
||||
priv->_agn.statistics.rx.ofdm_ht.plcp_err),
|
||||
combined_plcp_delta, plcp_msec);
|
||||
"%u, %u, %u, %u, %d, %u mSecs\n",
|
||||
priv->cfg->plcp_delta_threshold,
|
||||
le32_to_cpu(ofdm->plcp_err),
|
||||
le32_to_cpu(ofdm->plcp_err),
|
||||
le32_to_cpu(ofdm_ht->plcp_err),
|
||||
le32_to_cpu(ofdm_ht->plcp_err),
|
||||
combined_plcp_delta, plcp_msec);
|
||||
|
||||
rc = false;
|
||||
}
|
||||
}
|
||||
@ -227,24 +262,50 @@ void iwl_rx_statistics(struct iwl_priv *priv,
|
||||
int change;
|
||||
struct iwl_rx_packet *pkt = rxb_addr(rxb);
|
||||
|
||||
if (priv->cfg->bt_statistics) {
|
||||
IWL_DEBUG_RX(priv,
|
||||
"Statistics notification received (%d vs %d).\n",
|
||||
(int)sizeof(struct iwl_bt_notif_statistics),
|
||||
le32_to_cpu(pkt->len_n_flags) &
|
||||
FH_RSCSR_FRAME_SIZE_MSK);
|
||||
|
||||
IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
|
||||
(int)sizeof(priv->_agn.statistics),
|
||||
le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK);
|
||||
|
||||
change = ((priv->_agn.statistics.general.temperature !=
|
||||
pkt->u.stats.general.temperature) ||
|
||||
((priv->_agn.statistics.flag &
|
||||
STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
|
||||
(pkt->u.stats.flag & STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
|
||||
|
||||
change = ((priv->_agn.statistics_bt.general.common.temperature !=
|
||||
pkt->u.stats_bt.general.common.temperature) ||
|
||||
((priv->_agn.statistics_bt.flag &
|
||||
STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
|
||||
(pkt->u.stats_bt.flag &
|
||||
STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
|
||||
iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats_bt);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
IWL_DEBUG_RX(priv,
|
||||
"Statistics notification received (%d vs %d).\n",
|
||||
(int)sizeof(struct iwl_notif_statistics),
|
||||
le32_to_cpu(pkt->len_n_flags) &
|
||||
FH_RSCSR_FRAME_SIZE_MSK);
|
||||
|
||||
change = ((priv->_agn.statistics.general.common.temperature !=
|
||||
pkt->u.stats.general.common.temperature) ||
|
||||
((priv->_agn.statistics.flag &
|
||||
STATISTICS_REPLY_FLG_HT40_MODE_MSK) !=
|
||||
(pkt->u.stats.flag &
|
||||
STATISTICS_REPLY_FLG_HT40_MODE_MSK)));
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
iwl_recover_from_statistics(priv, pkt);
|
||||
|
||||
memcpy(&priv->_agn.statistics, &pkt->u.stats,
|
||||
sizeof(priv->_agn.statistics));
|
||||
if (priv->cfg->bt_statistics)
|
||||
memcpy(&priv->_agn.statistics_bt, &pkt->u.stats_bt,
|
||||
sizeof(priv->_agn.statistics_bt));
|
||||
else
|
||||
memcpy(&priv->_agn.statistics, &pkt->u.stats,
|
||||
sizeof(priv->_agn.statistics));
|
||||
|
||||
set_bit(STATUS_STATISTICS, &priv->status);
|
||||
|
||||
@ -277,6 +338,12 @@ void iwl_reply_statistics(struct iwl_priv *priv,
|
||||
sizeof(struct iwl_notif_statistics));
|
||||
memset(&priv->_agn.max_delta, 0,
|
||||
sizeof(struct iwl_notif_statistics));
|
||||
memset(&priv->_agn.accum_statistics_bt, 0,
|
||||
sizeof(struct iwl_bt_notif_statistics));
|
||||
memset(&priv->_agn.delta_statistics_bt, 0,
|
||||
sizeof(struct iwl_bt_notif_statistics));
|
||||
memset(&priv->_agn.max_delta_bt, 0,
|
||||
sizeof(struct iwl_bt_notif_statistics));
|
||||
#endif
|
||||
IWL_DEBUG_RX(priv, "Statistics have been cleared\n");
|
||||
}
|
||||
|
@ -27,6 +27,8 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
@ -292,9 +294,7 @@ static u32 iwl_fill_beacon_frame(struct iwl_priv *priv,
|
||||
struct ieee80211_hdr *hdr,
|
||||
int left)
|
||||
{
|
||||
if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
|
||||
((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
|
||||
(priv->iw_mode != NL80211_IFTYPE_AP)))
|
||||
if (!priv->ibss_beacon)
|
||||
return 0;
|
||||
|
||||
if (priv->ibss_beacon->len > left)
|
||||
@ -1692,6 +1692,7 @@ static void iwl_nic_start(struct iwl_priv *priv)
|
||||
|
||||
struct iwlagn_ucode_capabilities {
|
||||
u32 max_probe_length;
|
||||
u32 standard_phy_calibration_size;
|
||||
};
|
||||
|
||||
static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context);
|
||||
@ -1827,7 +1828,6 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
||||
u32 tlv_len;
|
||||
enum iwl_ucode_tlv_type tlv_type;
|
||||
const u8 *tlv_data;
|
||||
int ret = 0;
|
||||
|
||||
if (len < sizeof(*ucode)) {
|
||||
IWL_ERR(priv, "uCode has invalid length: %zd\n", len);
|
||||
@ -1863,9 +1863,8 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
||||
|
||||
len -= sizeof(*ucode);
|
||||
|
||||
while (len >= sizeof(*tlv) && !ret) {
|
||||
while (len >= sizeof(*tlv)) {
|
||||
u16 tlv_alt;
|
||||
u32 fixed_tlv_size = 4;
|
||||
|
||||
len -= sizeof(*tlv);
|
||||
tlv = (void *)data;
|
||||
@ -1913,59 +1912,57 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
||||
pieces->boot_size = tlv_len;
|
||||
break;
|
||||
case IWL_UCODE_TLV_PROBE_MAX_LEN:
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
capa->max_probe_length =
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
capa->max_probe_length =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT_EVTLOG_PTR:
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->init_evtlog_ptr =
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
pieces->init_evtlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT_EVTLOG_SIZE:
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->init_evtlog_size =
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
pieces->init_evtlog_size =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_INIT_ERRLOG_PTR:
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->init_errlog_ptr =
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
pieces->init_errlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_RUNT_EVTLOG_PTR:
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->inst_evtlog_ptr =
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
pieces->inst_evtlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_RUNT_EVTLOG_SIZE:
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->inst_evtlog_size =
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
pieces->inst_evtlog_size =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_RUNT_ERRLOG_PTR:
|
||||
if (tlv_len != fixed_tlv_size)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
pieces->inst_errlog_ptr =
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
pieces->inst_errlog_ptr =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
case IWL_UCODE_TLV_ENHANCE_SENS_TBL:
|
||||
if (tlv_len)
|
||||
ret = -EINVAL;
|
||||
else
|
||||
priv->enhance_sensitivity_table = true;
|
||||
goto invalid_tlv_len;
|
||||
priv->enhance_sensitivity_table = true;
|
||||
break;
|
||||
case IWL_UCODE_TLV_PHY_CALIBRATION_SIZE:
|
||||
if (tlv_len != sizeof(u32))
|
||||
goto invalid_tlv_len;
|
||||
capa->standard_phy_calibration_size =
|
||||
le32_to_cpup((__le32 *)tlv_data);
|
||||
break;
|
||||
default:
|
||||
IWL_WARN(priv, "unknown TLV: %d\n", tlv_type);
|
||||
@ -1976,14 +1973,16 @@ static int iwlagn_load_firmware(struct iwl_priv *priv,
|
||||
if (len) {
|
||||
IWL_ERR(priv, "invalid TLV after parsing: %zd\n", len);
|
||||
iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)data, len);
|
||||
ret = -EINVAL;
|
||||
} else if (ret) {
|
||||
IWL_ERR(priv, "TLV %d has invalid size: %u\n",
|
||||
tlv_type, tlv_len);
|
||||
iwl_print_hex_dump(priv, IWL_DL_FW, (u8 *)tlv_data, tlv_len);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
|
||||
invalid_tlv_len:
|
||||
IWL_ERR(priv, "TLV %d has invalid size: %u\n", tlv_type, tlv_len);
|
||||
iwl_print_hex_dump(priv, IWL_DL_FW, tlv_data, tlv_len);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2005,6 +2004,8 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
u32 build;
|
||||
struct iwlagn_ucode_capabilities ucode_capa = {
|
||||
.max_probe_length = 200,
|
||||
.standard_phy_calibration_size =
|
||||
IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE,
|
||||
};
|
||||
|
||||
memset(&pieces, 0, sizeof(pieces));
|
||||
@ -2226,6 +2227,20 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
|
||||
pieces.boot_size);
|
||||
memcpy(priv->ucode_boot.v_addr, pieces.boot, pieces.boot_size);
|
||||
|
||||
/*
|
||||
* figure out the offset of chain noise reset and gain commands
|
||||
* base on the size of standard phy calibration commands table size
|
||||
*/
|
||||
if (ucode_capa.standard_phy_calibration_size >
|
||||
IWL_MAX_PHY_CALIBRATE_TBL_SIZE)
|
||||
ucode_capa.standard_phy_calibration_size =
|
||||
IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE;
|
||||
|
||||
priv->_agn.phy_calib_chain_noise_reset_cmd =
|
||||
ucode_capa.standard_phy_calibration_size;
|
||||
priv->_agn.phy_calib_chain_noise_gain_cmd =
|
||||
ucode_capa.standard_phy_calibration_size + 1;
|
||||
|
||||
/**************************************************
|
||||
* This is still part of probe() in a sense...
|
||||
*
|
||||
@ -3008,9 +3023,17 @@ static void iwl_bg_run_time_calib_work(struct work_struct *work)
|
||||
}
|
||||
|
||||
if (priv->start_calib) {
|
||||
iwl_chain_noise_calibration(priv, &priv->_agn.statistics);
|
||||
|
||||
iwl_sensitivity_calibration(priv, &priv->_agn.statistics);
|
||||
if (priv->cfg->bt_statistics) {
|
||||
iwl_chain_noise_calibration(priv,
|
||||
(void *)&priv->_agn.statistics_bt);
|
||||
iwl_sensitivity_calibration(priv,
|
||||
(void *)&priv->_agn.statistics_bt);
|
||||
} else {
|
||||
iwl_chain_noise_calibration(priv,
|
||||
(void *)&priv->_agn.statistics);
|
||||
iwl_sensitivity_calibration(priv,
|
||||
(void *)&priv->_agn.statistics);
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&priv->mutex);
|
||||
@ -3909,8 +3932,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
struct ieee80211_hw *hw;
|
||||
struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
|
||||
unsigned long flags;
|
||||
u16 pci_cmd;
|
||||
u8 perm_addr[ETH_ALEN];
|
||||
u16 pci_cmd, num_mac;
|
||||
|
||||
/************************
|
||||
* 1. Allocating HW data
|
||||
@ -4028,9 +4050,17 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
goto out_free_eeprom;
|
||||
|
||||
/* extract MAC Address */
|
||||
iwl_eeprom_get_mac(priv, perm_addr);
|
||||
IWL_DEBUG_INFO(priv, "MAC address: %pM\n", perm_addr);
|
||||
SET_IEEE80211_PERM_ADDR(priv->hw, perm_addr);
|
||||
iwl_eeprom_get_mac(priv, priv->addresses[0].addr);
|
||||
IWL_DEBUG_INFO(priv, "MAC address: %pM\n", priv->addresses[0].addr);
|
||||
priv->hw->wiphy->addresses = priv->addresses;
|
||||
priv->hw->wiphy->n_addresses = 1;
|
||||
num_mac = iwl_eeprom_query16(priv, EEPROM_NUM_MAC_ADDRESS);
|
||||
if (num_mac > 1) {
|
||||
memcpy(priv->addresses[1].addr, priv->addresses[0].addr,
|
||||
ETH_ALEN);
|
||||
priv->addresses[1].addr[5]++;
|
||||
priv->hw->wiphy->n_addresses++;
|
||||
}
|
||||
|
||||
/************************
|
||||
* 5. Setup HW constants
|
||||
@ -4389,19 +4419,18 @@ static int __init iwl_init(void)
|
||||
{
|
||||
|
||||
int ret;
|
||||
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
|
||||
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
|
||||
pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
|
||||
pr_info(DRV_COPYRIGHT "\n");
|
||||
|
||||
ret = iwlagn_rate_control_register();
|
||||
if (ret) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
"Unable to register rate control algorithm: %d\n", ret);
|
||||
pr_err("Unable to register rate control algorithm: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = pci_register_driver(&iwl_driver);
|
||||
if (ret) {
|
||||
printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
|
||||
pr_err("Unable to initialize PCI module\n");
|
||||
goto error_register;
|
||||
}
|
||||
|
||||
|
@ -66,10 +66,8 @@
|
||||
#include "iwl-core.h"
|
||||
#include "iwl-commands.h"
|
||||
|
||||
void iwl_chain_noise_calibration(struct iwl_priv *priv,
|
||||
struct iwl_notif_statistics *stat_resp);
|
||||
void iwl_sensitivity_calibration(struct iwl_priv *priv,
|
||||
struct iwl_notif_statistics *resp);
|
||||
void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp);
|
||||
void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp);
|
||||
|
||||
void iwl_init_sensitivity(struct iwl_priv *priv);
|
||||
void iwl_reset_run_time_calib(struct iwl_priv *priv);
|
||||
|
@ -964,8 +964,8 @@ struct iwl_qosparam_cmd {
|
||||
#define IWL_STATION_COUNT 32 /* MAX(3945,4965)*/
|
||||
#define IWL_INVALID_STATION 255
|
||||
|
||||
#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2);
|
||||
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8);
|
||||
#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
|
||||
#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8)
|
||||
#define STA_FLG_RTS_MIMO_PROT_MSK cpu_to_le32(1 << 17)
|
||||
#define STA_FLG_AGG_MPDU_8US_MSK cpu_to_le32(1 << 18)
|
||||
#define STA_FLG_MAX_AGG_SIZE_POS (19)
|
||||
@ -3127,6 +3127,13 @@ struct statistics_rx_non_phy {
|
||||
__le32 beacon_energy_c;
|
||||
} __packed;
|
||||
|
||||
struct statistics_rx_non_phy_bt {
|
||||
struct statistics_rx_non_phy common;
|
||||
/* additional stats for bt */
|
||||
__le32 num_bt_kills;
|
||||
__le32 reserved[2];
|
||||
} __packed;
|
||||
|
||||
struct statistics_rx {
|
||||
struct statistics_rx_phy ofdm;
|
||||
struct statistics_rx_phy cck;
|
||||
@ -3134,6 +3141,13 @@ struct statistics_rx {
|
||||
struct statistics_rx_ht_phy ofdm_ht;
|
||||
} __packed;
|
||||
|
||||
struct statistics_rx_bt {
|
||||
struct statistics_rx_phy ofdm;
|
||||
struct statistics_rx_phy cck;
|
||||
struct statistics_rx_non_phy_bt general;
|
||||
struct statistics_rx_ht_phy ofdm_ht;
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* struct statistics_tx_power - current tx power
|
||||
*
|
||||
@ -3196,7 +3210,7 @@ struct statistics_div {
|
||||
__le32 reserved2;
|
||||
} __packed;
|
||||
|
||||
struct statistics_general {
|
||||
struct statistics_general_common {
|
||||
__le32 temperature; /* radio temperature */
|
||||
__le32 temperature_m; /* for 5000 and up, this is radio voltage */
|
||||
struct statistics_dbg dbg;
|
||||
@ -3212,6 +3226,30 @@ struct statistics_general {
|
||||
* in order to get out of bad PHY status
|
||||
*/
|
||||
__le32 num_of_sos_states;
|
||||
} __packed;
|
||||
|
||||
struct statistics_bt_activity {
|
||||
/* Tx statistics */
|
||||
__le32 hi_priority_tx_req_cnt;
|
||||
__le32 hi_priority_tx_denied_cnt;
|
||||
__le32 lo_priority_tx_req_cnt;
|
||||
__le32 lo_priority_tx_denied_cnt;
|
||||
/* Rx statistics */
|
||||
__le32 hi_priority_rx_req_cnt;
|
||||
__le32 hi_priority_rx_denied_cnt;
|
||||
__le32 lo_priority_rx_req_cnt;
|
||||
__le32 lo_priority_rx_denied_cnt;
|
||||
} __packed;
|
||||
|
||||
struct statistics_general {
|
||||
struct statistics_general_common common;
|
||||
__le32 reserved2;
|
||||
__le32 reserved3;
|
||||
} __packed;
|
||||
|
||||
struct statistics_general_bt {
|
||||
struct statistics_general_common common;
|
||||
struct statistics_bt_activity activity;
|
||||
__le32 reserved2;
|
||||
__le32 reserved3;
|
||||
} __packed;
|
||||
@ -3273,6 +3311,12 @@ struct iwl_notif_statistics {
|
||||
struct statistics_general general;
|
||||
} __packed;
|
||||
|
||||
struct iwl_bt_notif_statistics {
|
||||
__le32 flag;
|
||||
struct statistics_rx_bt rx;
|
||||
struct statistics_tx tx;
|
||||
struct statistics_general_bt general;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* MISSED_BEACONS_NOTIFICATION = 0xa2 (notification only, not a command)
|
||||
@ -3616,10 +3660,10 @@ enum {
|
||||
IWL_PHY_CALIBRATE_CRYSTAL_FRQ_CMD = 15,
|
||||
IWL_PHY_CALIBRATE_BASE_BAND_CMD = 16,
|
||||
IWL_PHY_CALIBRATE_TX_IQ_PERD_CMD = 17,
|
||||
IWL_PHY_CALIBRATE_CHAIN_NOISE_RESET_CMD = 18,
|
||||
IWL_PHY_CALIBRATE_CHAIN_NOISE_GAIN_CMD = 19,
|
||||
IWL_MAX_STANDARD_PHY_CALIBRATE_TBL_SIZE = 18,
|
||||
};
|
||||
|
||||
#define IWL_MAX_PHY_CALIBRATE_TBL_SIZE (253)
|
||||
|
||||
#define IWL_CALIB_INIT_CFG_ALL cpu_to_le32(0xffffffff)
|
||||
|
||||
@ -3944,6 +3988,7 @@ struct iwl_rx_packet {
|
||||
struct iwl_sleep_notification sleep_notif;
|
||||
struct iwl_spectrum_resp spectrum;
|
||||
struct iwl_notif_statistics stats;
|
||||
struct iwl_bt_notif_statistics stats_bt;
|
||||
struct iwl_compressed_ba_resp compressed_ba;
|
||||
struct iwl_missed_beacon_notif missed_beacon;
|
||||
struct iwl_coex_medium_notification coex_medium_notif;
|
||||
|
@ -170,7 +170,7 @@ struct ieee80211_hw *iwl_alloc_all(struct iwl_cfg *cfg,
|
||||
struct ieee80211_hw *hw =
|
||||
ieee80211_alloc_hw(sizeof(struct iwl_priv), hw_ops);
|
||||
if (hw == NULL) {
|
||||
printk(KERN_ERR "%s: Can not allocate network device\n",
|
||||
pr_err("%s: Can not allocate network device\n",
|
||||
cfg->name);
|
||||
goto out;
|
||||
}
|
||||
@ -1748,6 +1748,37 @@ static inline void iwl_set_no_assoc(struct iwl_priv *priv)
|
||||
iwlcore_commit_rxon(priv);
|
||||
}
|
||||
|
||||
static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
unsigned long flags;
|
||||
__le64 timestamp;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
|
||||
if (!iwl_is_ready_rf(priv)) {
|
||||
IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
if (priv->ibss_beacon)
|
||||
dev_kfree_skb(priv->ibss_beacon);
|
||||
|
||||
priv->ibss_beacon = skb;
|
||||
|
||||
timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
|
||||
priv->timestamp = le64_to_cpu(timestamp);
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
priv->cfg->ops->lib->post_associate(priv, priv->vif);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iwl_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
@ -1914,38 +1945,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_bss_info_changed);
|
||||
|
||||
int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
{
|
||||
struct iwl_priv *priv = hw->priv;
|
||||
unsigned long flags;
|
||||
__le64 timestamp;
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "enter\n");
|
||||
|
||||
if (!iwl_is_ready_rf(priv)) {
|
||||
IWL_DEBUG_MAC80211(priv, "leave - RF not ready\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
|
||||
if (priv->ibss_beacon)
|
||||
dev_kfree_skb(priv->ibss_beacon);
|
||||
|
||||
priv->ibss_beacon = skb;
|
||||
|
||||
timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
|
||||
priv->timestamp = le64_to_cpu(timestamp);
|
||||
|
||||
IWL_DEBUG_MAC80211(priv, "leave\n");
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
priv->cfg->ops->lib->post_associate(priv, priv->vif);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_mac_beacon_update);
|
||||
|
||||
static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
{
|
||||
iwl_connection_init_rx_config(priv, vif);
|
||||
|
@ -125,6 +125,8 @@ struct iwl_debugfs_ops {
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t (*general_stats_read)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
ssize_t (*bt_stats_read)(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos);
|
||||
};
|
||||
|
||||
struct iwl_temp_ops {
|
||||
@ -335,6 +337,7 @@ struct iwl_cfg {
|
||||
u8 scan_rx_antennas[IEEE80211_NUM_BANDS];
|
||||
u8 scan_tx_antennas[IEEE80211_NUM_BANDS];
|
||||
const bool need_dc_calib;
|
||||
const bool bt_statistics;
|
||||
};
|
||||
|
||||
/***************************
|
||||
@ -377,7 +380,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_bss_conf *bss_conf,
|
||||
u32 changes);
|
||||
int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb);
|
||||
int iwl_commit_rxon(struct iwl_priv *priv);
|
||||
int iwl_mac_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif);
|
||||
|
@ -1519,6 +1519,16 @@ static ssize_t iwl_dbgfs_txfifo_flush_write(struct file *file,
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t iwl_dbgfs_ucode_bt_stats_read(struct file *file,
|
||||
char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
|
||||
|
||||
return priv->cfg->ops->lib->debugfs_ops.bt_stats_read(file,
|
||||
user_buf, count, ppos);
|
||||
}
|
||||
|
||||
DEBUGFS_READ_FILE_OPS(rx_statistics);
|
||||
DEBUGFS_READ_FILE_OPS(tx_statistics);
|
||||
DEBUGFS_READ_WRITE_FILE_OPS(traffic_log);
|
||||
@ -1541,6 +1551,7 @@ DEBUGFS_READ_WRITE_FILE_OPS(force_reset);
|
||||
DEBUGFS_READ_FILE_OPS(rxon_flags);
|
||||
DEBUGFS_READ_FILE_OPS(rxon_filter_flags);
|
||||
DEBUGFS_WRITE_FILE_OPS(txfifo_flush);
|
||||
DEBUGFS_READ_FILE_OPS(ucode_bt_stats);
|
||||
|
||||
/*
|
||||
* Create the debugfs files and directories
|
||||
@ -1608,6 +1619,8 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
|
||||
DEBUGFS_ADD_FILE(chain_noise, dir_debug, S_IRUSR);
|
||||
if (priv->cfg->ucode_tracing)
|
||||
DEBUGFS_ADD_FILE(ucode_tracing, dir_debug, S_IWUSR | S_IRUSR);
|
||||
if (priv->cfg->bt_statistics)
|
||||
DEBUGFS_ADD_FILE(ucode_bt_stats, dir_debug, S_IRUSR);
|
||||
DEBUGFS_ADD_FILE(rxon_flags, dir_debug, S_IWUSR);
|
||||
DEBUGFS_ADD_FILE(rxon_filter_flags, dir_debug, S_IWUSR);
|
||||
if (priv->cfg->sensitivity_calib_by_driver)
|
||||
|
@ -571,6 +571,7 @@ enum iwl_ucode_tlv_type {
|
||||
IWL_UCODE_TLV_INIT_EVTLOG_SIZE = 12,
|
||||
IWL_UCODE_TLV_INIT_ERRLOG_PTR = 13,
|
||||
IWL_UCODE_TLV_ENHANCE_SENS_TBL = 14,
|
||||
IWL_UCODE_TLV_PHY_CALIBRATION_SIZE = 15,
|
||||
};
|
||||
|
||||
struct iwl_ucode_tlv {
|
||||
@ -1153,6 +1154,9 @@ struct iwl_priv {
|
||||
u32 hw_wa_rev;
|
||||
u8 rev_id;
|
||||
|
||||
/* EEPROM MAC addresses */
|
||||
struct mac_address addresses[2];
|
||||
|
||||
/* uCode images, save to reload in case of failure */
|
||||
int fw_index; /* firmware we're trying to load */
|
||||
u32 ucode_ver; /* version of ucode, copy of
|
||||
@ -1321,11 +1325,23 @@ struct iwl_priv {
|
||||
u32 init_evtlog_ptr, init_evtlog_size, init_errlog_ptr;
|
||||
u32 inst_evtlog_ptr, inst_evtlog_size, inst_errlog_ptr;
|
||||
|
||||
/*
|
||||
* chain noise reset and gain commands are the
|
||||
* two extra calibration commands follows the standard
|
||||
* phy calibration commands
|
||||
*/
|
||||
u8 phy_calib_chain_noise_reset_cmd;
|
||||
u8 phy_calib_chain_noise_gain_cmd;
|
||||
|
||||
struct iwl_notif_statistics statistics;
|
||||
struct iwl_bt_notif_statistics statistics_bt;
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
struct iwl_notif_statistics accum_statistics;
|
||||
struct iwl_notif_statistics delta_statistics;
|
||||
struct iwl_notif_statistics max_delta;
|
||||
struct iwl_bt_notif_statistics accum_statistics_bt;
|
||||
struct iwl_bt_notif_statistics delta_statistics_bt;
|
||||
struct iwl_bt_notif_statistics max_delta_bt;
|
||||
#endif
|
||||
} _agn;
|
||||
#endif
|
||||
|
@ -402,6 +402,7 @@ struct iwl_eeprom_calib_info {
|
||||
#define EEPROM_WOWLAN_MODE (2*0x47) /* 2 bytes */
|
||||
#define EEPROM_RADIO_CONFIG (2*0x48) /* 2 bytes */
|
||||
#define EEPROM_3945_M_VERSION (2*0x4A) /* 1 bytes */
|
||||
#define EEPROM_NUM_MAC_ADDRESS (2*0x4C) /* 2 bytes */
|
||||
|
||||
/* The following masks are to be applied on EEPROM_RADIO_CONFIG */
|
||||
#define EEPROM_RF_CFG_TYPE_MSK(x) (x & 0x3) /* bits 0-1 */
|
||||
|
@ -429,11 +429,10 @@ void iwl_bg_scan_check(struct work_struct *data)
|
||||
return;
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
if (test_bit(STATUS_SCANNING, &priv->status) ||
|
||||
test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
|
||||
IWL_DEBUG_SCAN(priv, "Scan completion watchdog resetting "
|
||||
"adapter (%dms)\n",
|
||||
jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
|
||||
if (test_bit(STATUS_SCANNING, &priv->status) &&
|
||||
!test_bit(STATUS_SCAN_ABORTING, &priv->status)) {
|
||||
IWL_DEBUG_SCAN(priv, "Scan completion watchdog (%dms)\n",
|
||||
jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
|
||||
|
||||
if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
|
||||
iwl_send_scan_abort(priv);
|
||||
@ -498,12 +497,11 @@ void iwl_bg_abort_scan(struct work_struct *work)
|
||||
!test_bit(STATUS_GEO_CONFIGURED, &priv->status))
|
||||
return;
|
||||
|
||||
cancel_delayed_work(&priv->scan_check);
|
||||
|
||||
mutex_lock(&priv->mutex);
|
||||
|
||||
cancel_delayed_work_sync(&priv->scan_check);
|
||||
set_bit(STATUS_SCAN_ABORTING, &priv->status);
|
||||
iwl_send_scan_abort(priv);
|
||||
|
||||
if (test_bit(STATUS_SCAN_ABORTING, &priv->status))
|
||||
iwl_send_scan_abort(priv);
|
||||
mutex_unlock(&priv->mutex);
|
||||
}
|
||||
EXPORT_SYMBOL(iwl_bg_abort_scan);
|
||||
|
@ -27,6 +27,8 @@
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
@ -311,9 +313,7 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
|
||||
int left)
|
||||
{
|
||||
|
||||
if (!iwl_is_associated(priv) || !priv->ibss_beacon ||
|
||||
((priv->iw_mode != NL80211_IFTYPE_ADHOC) &&
|
||||
(priv->iw_mode != NL80211_IFTYPE_AP)))
|
||||
if (!iwl_is_associated(priv) || !priv->ibss_beacon)
|
||||
return 0;
|
||||
|
||||
if (priv->ibss_beacon->len > left)
|
||||
@ -2883,7 +2883,10 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
|
||||
IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
interval = vif ? vif->bss_conf.beacon_int : 0;
|
||||
if (priv->is_internal_short_scan)
|
||||
interval = 0;
|
||||
else
|
||||
interval = vif->bss_conf.beacon_int;
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
|
||||
scan->suspend_time = 0;
|
||||
@ -3932,7 +3935,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
|
||||
* space for this driver's private structure */
|
||||
hw = iwl_alloc_all(cfg, &iwl3945_hw_ops);
|
||||
if (hw == NULL) {
|
||||
printk(KERN_ERR DRV_NAME "Can not allocate network device\n");
|
||||
pr_err("Can not allocate network device\n");
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@ -4224,19 +4227,18 @@ static int __init iwl3945_init(void)
|
||||
{
|
||||
|
||||
int ret;
|
||||
printk(KERN_INFO DRV_NAME ": " DRV_DESCRIPTION ", " DRV_VERSION "\n");
|
||||
printk(KERN_INFO DRV_NAME ": " DRV_COPYRIGHT "\n");
|
||||
pr_info(DRV_DESCRIPTION ", " DRV_VERSION "\n");
|
||||
pr_info(DRV_COPYRIGHT "\n");
|
||||
|
||||
ret = iwl3945_rate_control_register();
|
||||
if (ret) {
|
||||
printk(KERN_ERR DRV_NAME
|
||||
"Unable to register rate control algorithm: %d\n", ret);
|
||||
pr_err("Unable to register rate control algorithm: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = pci_register_driver(&iwl3945_driver);
|
||||
if (ret) {
|
||||
printk(KERN_ERR DRV_NAME "Unable to initialize PCI module\n");
|
||||
pr_err("Unable to initialize PCI module\n");
|
||||
goto error_register;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/if_arp.h>
|
||||
#include <linux/ieee80211.h>
|
||||
#include <net/cfg80211.h>
|
||||
#include <asm/unaligned.h>
|
||||
@ -1383,93 +1382,10 @@ static int lbs_cfg_del_key(struct wiphy *wiphy, struct net_device *netdev,
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Monitor mode
|
||||
*/
|
||||
|
||||
/* like "struct cmd_ds_802_11_monitor_mode", but with cmd_header. Once we
|
||||
* get rid of WEXT, this should go into host.h */
|
||||
struct cmd_monitor_mode {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le16 mode;
|
||||
} __packed;
|
||||
|
||||
static int lbs_enable_monitor_mode(struct lbs_private *priv, int mode)
|
||||
{
|
||||
struct cmd_monitor_mode cmd;
|
||||
int ret;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CFG80211);
|
||||
|
||||
/*
|
||||
* cmd 98 00
|
||||
* size 0c 00
|
||||
* sequence xx xx
|
||||
* result 00 00
|
||||
* action 01 00 ACT_SET
|
||||
* enable 01 00
|
||||
*/
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(CMD_ACT_SET);
|
||||
cmd.mode = cpu_to_le16(mode);
|
||||
|
||||
ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd);
|
||||
|
||||
if (ret == 0)
|
||||
priv->dev->type = ARPHRD_IEEE80211_RADIOTAP;
|
||||
else
|
||||
priv->dev->type = ARPHRD_ETHER;
|
||||
|
||||
lbs_deb_leave(LBS_DEB_CFG80211);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* Get station
|
||||
*/
|
||||
|
||||
/*
|
||||
* Returns the signal or 0 in case of an error.
|
||||
*/
|
||||
|
||||
/* like "struct cmd_ds_802_11_rssi", but with cmd_header. Once we get rid
|
||||
* of WEXT, this should go into host.h */
|
||||
struct cmd_rssi {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 n_or_snr;
|
||||
__le16 nf;
|
||||
__le16 avg_snr;
|
||||
__le16 avg_nf;
|
||||
} __packed;
|
||||
|
||||
static int lbs_get_signal(struct lbs_private *priv, s8 *signal, s8 *noise)
|
||||
{
|
||||
struct cmd_rssi cmd;
|
||||
int ret;
|
||||
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.n_or_snr = cpu_to_le16(DEFAULT_BCN_AVG_FACTOR);
|
||||
ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
|
||||
|
||||
if (ret == 0) {
|
||||
*signal = CAL_RSSI(le16_to_cpu(cmd.n_or_snr),
|
||||
le16_to_cpu(cmd.nf));
|
||||
*noise = CAL_NF(le16_to_cpu(cmd.nf));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
u8 *mac, struct station_info *sinfo)
|
||||
{
|
||||
@ -1490,7 +1406,7 @@ static int lbs_cfg_get_station(struct wiphy *wiphy, struct net_device *dev,
|
||||
sinfo->rx_packets = priv->dev->stats.rx_packets;
|
||||
|
||||
/* Get current RSSI */
|
||||
ret = lbs_get_signal(priv, &signal, &noise);
|
||||
ret = lbs_get_rssi(priv, &signal, &noise);
|
||||
if (ret == 0) {
|
||||
sinfo->signal = signal;
|
||||
sinfo->filled |= STATION_INFO_SIGNAL;
|
||||
@ -1530,7 +1446,7 @@ static int lbs_get_survey(struct wiphy *wiphy, struct net_device *dev,
|
||||
survey->channel = ieee80211_get_channel(wiphy,
|
||||
ieee80211_channel_to_frequency(priv->channel));
|
||||
|
||||
ret = lbs_get_signal(priv, &signal, &noise);
|
||||
ret = lbs_get_rssi(priv, &signal, &noise);
|
||||
if (ret == 0) {
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = noise;
|
||||
@ -1558,17 +1474,17 @@ static int lbs_change_intf(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
switch (type) {
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
ret = lbs_enable_monitor_mode(priv, 1);
|
||||
ret = lbs_set_monitor_mode(priv, 1);
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
|
||||
ret = lbs_enable_monitor_mode(priv, 0);
|
||||
ret = lbs_set_monitor_mode(priv, 0);
|
||||
if (!ret)
|
||||
ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 1);
|
||||
break;
|
||||
case NL80211_IFTYPE_ADHOC:
|
||||
if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR)
|
||||
ret = lbs_enable_monitor_mode(priv, 0);
|
||||
ret = lbs_set_monitor_mode(priv, 0);
|
||||
if (!ret)
|
||||
ret = lbs_set_snmp_mib(priv, SNMP_MIB_OID_BSS_TYPE, 2);
|
||||
break;
|
||||
@ -2063,113 +1979,20 @@ int lbs_cfg_register(struct lbs_private *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sets DOMAIN INFO to FW
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @return 0; -1
|
||||
*/
|
||||
static int lbs_11d_set_domain_info(struct lbs_private *priv)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = lbs_prepare_and_send_command(priv, CMD_802_11D_DOMAIN_INFO,
|
||||
CMD_ACT_SET,
|
||||
CMD_OPTION_WAITFORRSP, 0, NULL);
|
||||
if (ret)
|
||||
lbs_deb_11d("fail to dnld domain info\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lbs_send_domain_info_cmd_fw(struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
u8 no_of_triplet = 0;
|
||||
u8 no_of_parsed_chan = 0;
|
||||
u8 first_channel = 0, next_chan = 0, max_pwr = 0;
|
||||
u8 i, flag = 0;
|
||||
enum ieee80211_band band;
|
||||
struct ieee80211_supported_band *sband;
|
||||
struct ieee80211_channel *ch;
|
||||
struct lbs_private *priv = wiphy_priv(wiphy);
|
||||
struct lbs_802_11d_domain_reg *domain_info = &priv->domain_reg;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CFG80211);
|
||||
|
||||
/* Set country code */
|
||||
domain_info->country_code[0] = request->alpha2[0];
|
||||
domain_info->country_code[1] = request->alpha2[1];
|
||||
domain_info->country_code[2] = ' ';
|
||||
|
||||
for (band = 0; band < IEEE80211_NUM_BANDS ; band++) {
|
||||
|
||||
if (!wiphy->bands[band])
|
||||
continue;
|
||||
|
||||
sband = wiphy->bands[band];
|
||||
|
||||
for (i = 0; i < sband->n_channels ; i++) {
|
||||
ch = &sband->channels[i];
|
||||
if (ch->flags & IEEE80211_CHAN_DISABLED)
|
||||
continue;
|
||||
|
||||
if (!flag) {
|
||||
flag = 1;
|
||||
next_chan = first_channel = (u32) ch->hw_value;
|
||||
max_pwr = ch->max_power;
|
||||
no_of_parsed_chan = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ch->hw_value == next_chan + 1 &&
|
||||
ch->max_power == max_pwr) {
|
||||
next_chan++;
|
||||
no_of_parsed_chan++;
|
||||
} else {
|
||||
domain_info->triplet[no_of_triplet]
|
||||
.chans.first_channel = first_channel;
|
||||
domain_info->triplet[no_of_triplet]
|
||||
.chans.num_channels = no_of_parsed_chan;
|
||||
domain_info->triplet[no_of_triplet]
|
||||
.chans.max_power = max_pwr;
|
||||
no_of_triplet++;
|
||||
flag = 0;
|
||||
}
|
||||
}
|
||||
if (flag) {
|
||||
domain_info->triplet[no_of_triplet]
|
||||
.chans.first_channel = first_channel;
|
||||
domain_info->triplet[no_of_triplet]
|
||||
.chans.num_channels = no_of_parsed_chan;
|
||||
domain_info->triplet[no_of_triplet]
|
||||
.chans.max_power = max_pwr;
|
||||
no_of_triplet++;
|
||||
}
|
||||
}
|
||||
|
||||
domain_info->no_triplet = no_of_triplet;
|
||||
|
||||
/* Set domain info */
|
||||
ret = lbs_11d_set_domain_info(priv);
|
||||
if (ret)
|
||||
lbs_pr_err("11D: error setting domain info in FW\n");
|
||||
|
||||
lbs_deb_leave(LBS_DEB_CFG80211);
|
||||
}
|
||||
|
||||
int lbs_reg_notifier(struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct lbs_private *priv = wiphy_priv(wiphy);
|
||||
int ret;
|
||||
|
||||
lbs_deb_enter_args(LBS_DEB_CFG80211, "cfg80211 regulatory domain "
|
||||
"callback for domain %c%c\n", request->alpha2[0],
|
||||
request->alpha2[1]);
|
||||
|
||||
lbs_send_domain_info_cmd_fw(wiphy, request);
|
||||
ret = lbs_set_11d_domain_info(priv, request, wiphy->bands);
|
||||
|
||||
lbs_deb_leave(LBS_DEB_CFG80211);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void lbs_scan_deinit(struct lbs_private *priv)
|
||||
|
@ -13,12 +13,6 @@ void lbs_cfg_free(struct lbs_private *priv);
|
||||
int lbs_reg_notifier(struct wiphy *wiphy,
|
||||
struct regulatory_request *request);
|
||||
|
||||
/* All of those are TODOs: */
|
||||
#define lbs_cmd_802_11_rssi(priv, cmdptr) (0)
|
||||
#define lbs_ret_802_11_rssi(priv, resp) (0)
|
||||
#define lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action) (0)
|
||||
#define lbs_ret_802_11_bcn_ctrl(priv, resp) (0)
|
||||
|
||||
void lbs_send_disconnect_notification(struct lbs_private *priv);
|
||||
void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
|
||||
|
||||
|
@ -6,13 +6,14 @@
|
||||
#include <linux/kfifo.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/if_arp.h>
|
||||
|
||||
#include "decl.h"
|
||||
#include "cfg.h"
|
||||
#include "cmd.h"
|
||||
|
||||
|
||||
static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv);
|
||||
#define CAL_NF(nf) ((s32)(-(s32)(nf)))
|
||||
#define CAL_RSSI(snr, nf) ((s32)((s32)(snr) + CAL_NF(nf)))
|
||||
|
||||
/**
|
||||
* @brief Simple callback that copies response back into command
|
||||
@ -73,30 +74,6 @@ static u8 is_command_allowed_in_ps(u16 cmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function checks if the command is allowed.
|
||||
*
|
||||
* @param priv A pointer to lbs_private structure
|
||||
* @return allowed or not allowed.
|
||||
*/
|
||||
|
||||
static int lbs_is_cmd_allowed(struct lbs_private *priv)
|
||||
{
|
||||
int ret = 1;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
if (!priv->is_auto_deep_sleep_enabled) {
|
||||
if (priv->is_deep_sleep) {
|
||||
lbs_deb_cmd("command not allowed in deep sleep\n");
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Updates the hardware details like MAC address and regulatory region
|
||||
*
|
||||
@ -227,42 +204,49 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(lbs_host_sleep_cfg);
|
||||
|
||||
static int lbs_cmd_802_11_ps_mode(struct cmd_ds_command *cmd,
|
||||
u16 cmd_action)
|
||||
/**
|
||||
* @brief Sets the Power Save mode
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param cmd_action The Power Save operation (PS_MODE_ACTION_ENTER_PS or
|
||||
* PS_MODE_ACTION_EXIT_PS)
|
||||
* @param block Whether to block on a response or not
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
*/
|
||||
int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block)
|
||||
{
|
||||
struct cmd_ds_802_11_ps_mode *psm = &cmd->params.psmode;
|
||||
struct cmd_ds_802_11_ps_mode cmd;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
cmd->command = cpu_to_le16(CMD_802_11_PS_MODE);
|
||||
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_ps_mode) +
|
||||
sizeof(struct cmd_header));
|
||||
psm->action = cpu_to_le16(cmd_action);
|
||||
psm->multipledtim = 0;
|
||||
switch (cmd_action) {
|
||||
case CMD_SUBCMD_ENTER_PS:
|
||||
lbs_deb_cmd("PS command:" "SubCode- Enter PS\n");
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(cmd_action);
|
||||
|
||||
psm->locallisteninterval = 0;
|
||||
psm->nullpktinterval = 0;
|
||||
psm->multipledtim =
|
||||
cpu_to_le16(MRVDRV_DEFAULT_MULTIPLE_DTIM);
|
||||
break;
|
||||
|
||||
case CMD_SUBCMD_EXIT_PS:
|
||||
lbs_deb_cmd("PS command:" "SubCode- Exit PS\n");
|
||||
break;
|
||||
|
||||
case CMD_SUBCMD_SLEEP_CONFIRMED:
|
||||
lbs_deb_cmd("PS command: SubCode- sleep confirm\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
if (cmd_action == PS_MODE_ACTION_ENTER_PS) {
|
||||
lbs_deb_cmd("PS_MODE: action ENTER_PS\n");
|
||||
cmd.multipledtim = cpu_to_le16(1); /* Default DTIM multiple */
|
||||
} else if (cmd_action == PS_MODE_ACTION_EXIT_PS) {
|
||||
lbs_deb_cmd("PS_MODE: action EXIT_PS\n");
|
||||
} else {
|
||||
/* We don't handle CONFIRM_SLEEP here because it needs to
|
||||
* be fastpathed to the firmware.
|
||||
*/
|
||||
lbs_deb_cmd("PS_MODE: unknown action 0x%X\n", cmd_action);
|
||||
ret = -EOPNOTSUPP;
|
||||
goto out;
|
||||
}
|
||||
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
return 0;
|
||||
if (block)
|
||||
ret = lbs_cmd_with_response(priv, CMD_802_11_PS_MODE, &cmd);
|
||||
else
|
||||
lbs_cmd_async(priv, CMD_802_11_PS_MODE, &cmd.hdr, sizeof (cmd));
|
||||
|
||||
out:
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
|
||||
@ -576,23 +560,35 @@ int lbs_set_tx_power(struct lbs_private *priv, s16 dbm)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lbs_cmd_802_11_monitor_mode(struct cmd_ds_command *cmd,
|
||||
u16 cmd_action, void *pdata_buf)
|
||||
/**
|
||||
* @brief Enable or disable monitor mode (only implemented on OLPC usb8388 FW)
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param enable 1 to enable monitor mode, 0 to disable
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
*/
|
||||
int lbs_set_monitor_mode(struct lbs_private *priv, int enable)
|
||||
{
|
||||
struct cmd_ds_802_11_monitor_mode *monitor = &cmd->params.monitor;
|
||||
struct cmd_ds_802_11_monitor_mode cmd;
|
||||
int ret;
|
||||
|
||||
cmd->command = cpu_to_le16(CMD_802_11_MONITOR_MODE);
|
||||
cmd->size =
|
||||
cpu_to_le16(sizeof(struct cmd_ds_802_11_monitor_mode) +
|
||||
sizeof(struct cmd_header));
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(CMD_ACT_SET);
|
||||
if (enable)
|
||||
cmd.mode = cpu_to_le16(0x1);
|
||||
|
||||
monitor->action = cpu_to_le16(cmd_action);
|
||||
if (cmd_action == CMD_ACT_SET) {
|
||||
monitor->mode =
|
||||
cpu_to_le16((u16) (*(u32 *) pdata_buf));
|
||||
lbs_deb_cmd("SET_MONITOR_MODE: %d\n", enable);
|
||||
|
||||
ret = lbs_cmd_with_response(priv, CMD_802_11_MONITOR_MODE, &cmd);
|
||||
if (ret == 0) {
|
||||
priv->dev->type = enable ? ARPHRD_IEEE80211_RADIOTAP :
|
||||
ARPHRD_ETHER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -677,78 +673,242 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lbs_cmd_reg_access(struct cmd_ds_command *cmdptr,
|
||||
u8 cmd_action, void *pdata_buf)
|
||||
/**
|
||||
* @brief Get current RSSI and noise floor
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param rssi On successful return, signal level in mBm
|
||||
*
|
||||
* @return The channel on success, error on failure
|
||||
*/
|
||||
int lbs_get_rssi(struct lbs_private *priv, s8 *rssi, s8 *nf)
|
||||
{
|
||||
struct lbs_offset_value *offval;
|
||||
struct cmd_ds_802_11_rssi cmd;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
offval = (struct lbs_offset_value *)pdata_buf;
|
||||
BUG_ON(rssi == NULL);
|
||||
BUG_ON(nf == NULL);
|
||||
|
||||
switch (le16_to_cpu(cmdptr->command)) {
|
||||
case CMD_MAC_REG_ACCESS:
|
||||
{
|
||||
struct cmd_ds_mac_reg_access *macreg;
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
/* Average SNR over last 8 beacons */
|
||||
cmd.n_or_snr = cpu_to_le16(8);
|
||||
|
||||
cmdptr->size =
|
||||
cpu_to_le16(sizeof (struct cmd_ds_mac_reg_access)
|
||||
+ sizeof(struct cmd_header));
|
||||
macreg =
|
||||
(struct cmd_ds_mac_reg_access *)&cmdptr->params.
|
||||
macreg;
|
||||
|
||||
macreg->action = cpu_to_le16(cmd_action);
|
||||
macreg->offset = cpu_to_le16((u16) offval->offset);
|
||||
macreg->value = cpu_to_le32(offval->value);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_BBP_REG_ACCESS:
|
||||
{
|
||||
struct cmd_ds_bbp_reg_access *bbpreg;
|
||||
|
||||
cmdptr->size =
|
||||
cpu_to_le16(sizeof
|
||||
(struct cmd_ds_bbp_reg_access)
|
||||
+ sizeof(struct cmd_header));
|
||||
bbpreg =
|
||||
(struct cmd_ds_bbp_reg_access *)&cmdptr->params.
|
||||
bbpreg;
|
||||
|
||||
bbpreg->action = cpu_to_le16(cmd_action);
|
||||
bbpreg->offset = cpu_to_le16((u16) offval->offset);
|
||||
bbpreg->value = (u8) offval->value;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_RF_REG_ACCESS:
|
||||
{
|
||||
struct cmd_ds_rf_reg_access *rfreg;
|
||||
|
||||
cmdptr->size =
|
||||
cpu_to_le16(sizeof
|
||||
(struct cmd_ds_rf_reg_access) +
|
||||
sizeof(struct cmd_header));
|
||||
rfreg =
|
||||
(struct cmd_ds_rf_reg_access *)&cmdptr->params.
|
||||
rfreg;
|
||||
|
||||
rfreg->action = cpu_to_le16(cmd_action);
|
||||
rfreg->offset = cpu_to_le16((u16) offval->offset);
|
||||
rfreg->value = (u8) offval->value;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
ret = lbs_cmd_with_response(priv, CMD_802_11_RSSI, &cmd);
|
||||
if (ret == 0) {
|
||||
*nf = CAL_NF(le16_to_cpu(cmd.nf));
|
||||
*rssi = CAL_RSSI(le16_to_cpu(cmd.n_or_snr), le16_to_cpu(cmd.nf));
|
||||
}
|
||||
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
return 0;
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Send regulatory and 802.11d domain information to the firmware
|
||||
*
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @param request cfg80211 regulatory request structure
|
||||
* @param bands the device's supported bands and channels
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
*/
|
||||
int lbs_set_11d_domain_info(struct lbs_private *priv,
|
||||
struct regulatory_request *request,
|
||||
struct ieee80211_supported_band **bands)
|
||||
{
|
||||
struct cmd_ds_802_11d_domain_info cmd;
|
||||
struct mrvl_ie_domain_param_set *domain = &cmd.domain;
|
||||
struct ieee80211_country_ie_triplet *t;
|
||||
enum ieee80211_band band;
|
||||
struct ieee80211_channel *ch;
|
||||
u8 num_triplet = 0;
|
||||
u8 num_parsed_chan = 0;
|
||||
u8 first_channel = 0, next_chan = 0, max_pwr = 0;
|
||||
u8 i, flag = 0;
|
||||
size_t triplet_size;
|
||||
int ret;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_11D);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(CMD_ACT_SET);
|
||||
|
||||
lbs_deb_11d("Setting country code '%c%c'\n",
|
||||
request->alpha2[0], request->alpha2[1]);
|
||||
|
||||
domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
|
||||
|
||||
/* Set country code */
|
||||
domain->country_code[0] = request->alpha2[0];
|
||||
domain->country_code[1] = request->alpha2[1];
|
||||
domain->country_code[2] = ' ';
|
||||
|
||||
/* Now set up the channel triplets; firmware is somewhat picky here
|
||||
* and doesn't validate channel numbers and spans; hence it would
|
||||
* interpret a triplet of (36, 4, 20) as channels 36, 37, 38, 39. Since
|
||||
* the last 3 aren't valid channels, the driver is responsible for
|
||||
* splitting that up into 4 triplet pairs of (36, 1, 20) + (40, 1, 20)
|
||||
* etc.
|
||||
*/
|
||||
for (band = 0;
|
||||
(band < IEEE80211_NUM_BANDS) && (num_triplet < MAX_11D_TRIPLETS);
|
||||
band++) {
|
||||
|
||||
if (!bands[band])
|
||||
continue;
|
||||
|
||||
for (i = 0;
|
||||
(i < bands[band]->n_channels) && (num_triplet < MAX_11D_TRIPLETS);
|
||||
i++) {
|
||||
ch = &bands[band]->channels[i];
|
||||
if (ch->flags & IEEE80211_CHAN_DISABLED)
|
||||
continue;
|
||||
|
||||
if (!flag) {
|
||||
flag = 1;
|
||||
next_chan = first_channel = (u32) ch->hw_value;
|
||||
max_pwr = ch->max_power;
|
||||
num_parsed_chan = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((ch->hw_value == next_chan + 1) &&
|
||||
(ch->max_power == max_pwr)) {
|
||||
/* Consolidate adjacent channels */
|
||||
next_chan++;
|
||||
num_parsed_chan++;
|
||||
} else {
|
||||
/* Add this triplet */
|
||||
lbs_deb_11d("11D triplet (%d, %d, %d)\n",
|
||||
first_channel, num_parsed_chan,
|
||||
max_pwr);
|
||||
t = &domain->triplet[num_triplet];
|
||||
t->chans.first_channel = first_channel;
|
||||
t->chans.num_channels = num_parsed_chan;
|
||||
t->chans.max_power = max_pwr;
|
||||
num_triplet++;
|
||||
flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
/* Add last triplet */
|
||||
lbs_deb_11d("11D triplet (%d, %d, %d)\n", first_channel,
|
||||
num_parsed_chan, max_pwr);
|
||||
t = &domain->triplet[num_triplet];
|
||||
t->chans.first_channel = first_channel;
|
||||
t->chans.num_channels = num_parsed_chan;
|
||||
t->chans.max_power = max_pwr;
|
||||
num_triplet++;
|
||||
}
|
||||
}
|
||||
|
||||
lbs_deb_11d("# triplets %d\n", num_triplet);
|
||||
|
||||
/* Set command header sizes */
|
||||
triplet_size = num_triplet * sizeof(struct ieee80211_country_ie_triplet);
|
||||
domain->header.len = cpu_to_le16(sizeof(domain->country_code) +
|
||||
triplet_size);
|
||||
|
||||
lbs_deb_hex(LBS_DEB_11D, "802.11D domain param set",
|
||||
(u8 *) &cmd.domain.country_code,
|
||||
le16_to_cpu(domain->header.len));
|
||||
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd.hdr) +
|
||||
sizeof(cmd.action) +
|
||||
sizeof(cmd.domain.header) +
|
||||
sizeof(cmd.domain.country_code) +
|
||||
triplet_size);
|
||||
|
||||
ret = lbs_cmd_with_response(priv, CMD_802_11D_DOMAIN_INFO, &cmd);
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a MAC, Baseband, or RF register
|
||||
*
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @param cmd register command, one of CMD_MAC_REG_ACCESS,
|
||||
* CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
|
||||
* @param offset byte offset of the register to get
|
||||
* @param value on success, the value of the register at 'offset'
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
*/
|
||||
int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value)
|
||||
{
|
||||
struct cmd_ds_reg_access cmd;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
BUG_ON(value == NULL);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(CMD_ACT_GET);
|
||||
|
||||
if (reg != CMD_MAC_REG_ACCESS &&
|
||||
reg != CMD_BBP_REG_ACCESS &&
|
||||
reg != CMD_RF_REG_ACCESS) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = lbs_cmd_with_response(priv, reg, &cmd);
|
||||
if (ret) {
|
||||
if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
|
||||
*value = cmd.value.bbp_rf;
|
||||
else if (reg == CMD_MAC_REG_ACCESS)
|
||||
*value = le32_to_cpu(cmd.value.mac);
|
||||
}
|
||||
|
||||
out:
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Write a MAC, Baseband, or RF register
|
||||
*
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @param cmd register command, one of CMD_MAC_REG_ACCESS,
|
||||
* CMD_BBP_REG_ACCESS, or CMD_RF_REG_ACCESS
|
||||
* @param offset byte offset of the register to set
|
||||
* @param value the value to write to the register at 'offset'
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
*/
|
||||
int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value)
|
||||
{
|
||||
struct cmd_ds_reg_access cmd;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(CMD_ACT_SET);
|
||||
|
||||
if (reg == CMD_BBP_REG_ACCESS || reg == CMD_RF_REG_ACCESS)
|
||||
cmd.value.bbp_rf = (u8) (value & 0xFF);
|
||||
else if (reg == CMD_MAC_REG_ACCESS)
|
||||
cmd.value.mac = cpu_to_le32(value);
|
||||
else {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = lbs_cmd_with_response(priv, reg, &cmd);
|
||||
|
||||
out:
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void lbs_queue_cmd(struct lbs_private *priv,
|
||||
@ -771,16 +931,15 @@ static void lbs_queue_cmd(struct lbs_private *priv,
|
||||
|
||||
/* Exit_PS command needs to be queued in the header always. */
|
||||
if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_PS_MODE) {
|
||||
struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf[1];
|
||||
struct cmd_ds_802_11_ps_mode *psm = (void *) &cmdnode->cmdbuf;
|
||||
|
||||
if (psm->action == cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
|
||||
if (psm->action == cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
|
||||
if (priv->psstate != PS_STATE_FULL_POWER)
|
||||
addtail = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (le16_to_cpu(cmdnode->cmdbuf->command) ==
|
||||
CMD_802_11_WAKEUP_CONFIRM)
|
||||
if (le16_to_cpu(cmdnode->cmdbuf->command) == CMD_802_11_WAKEUP_CONFIRM)
|
||||
addtail = 0;
|
||||
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
@ -815,7 +974,6 @@ static void lbs_submit_command(struct lbs_private *priv,
|
||||
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
priv->cur_cmd = cmdnode;
|
||||
priv->cur_cmd_retcode = 0;
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
|
||||
cmdsize = le16_to_cpu(cmd->size);
|
||||
@ -888,9 +1046,6 @@ static void lbs_cleanup_and_insert_cmd(struct lbs_private *priv,
|
||||
void lbs_complete_command(struct lbs_private *priv, struct cmd_ctrl_node *cmd,
|
||||
int result)
|
||||
{
|
||||
if (cmd == priv->cur_cmd)
|
||||
priv->cur_cmd_retcode = result;
|
||||
|
||||
cmd->result = result;
|
||||
cmd->cmdwaitqwoken = 1;
|
||||
wake_up_interruptible(&cmd->cmdwait_q);
|
||||
@ -957,240 +1112,6 @@ void lbs_set_mac_control(struct lbs_private *priv)
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function implements command CMD_802_11D_DOMAIN_INFO
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @param cmd pointer to cmd buffer
|
||||
* @param cmdno cmd ID
|
||||
* @param cmdOption cmd action
|
||||
* @return 0
|
||||
*/
|
||||
int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
|
||||
struct cmd_ds_command *cmd,
|
||||
u16 cmdoption)
|
||||
{
|
||||
struct cmd_ds_802_11d_domain_info *pdomaininfo =
|
||||
&cmd->params.domaininfo;
|
||||
struct mrvl_ie_domain_param_set *domain = &pdomaininfo->domain;
|
||||
u8 nr_triplet = priv->domain_reg.no_triplet;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_11D);
|
||||
|
||||
lbs_deb_11d("nr_triplet=%x\n", nr_triplet);
|
||||
|
||||
pdomaininfo->action = cpu_to_le16(cmdoption);
|
||||
if (cmdoption == CMD_ACT_GET) {
|
||||
cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
|
||||
sizeof(struct cmd_header));
|
||||
lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
|
||||
le16_to_cpu(cmd->size));
|
||||
goto done;
|
||||
}
|
||||
|
||||
domain->header.type = cpu_to_le16(TLV_TYPE_DOMAIN);
|
||||
memcpy(domain->countrycode, priv->domain_reg.country_code,
|
||||
sizeof(domain->countrycode));
|
||||
|
||||
domain->header.len = cpu_to_le16(nr_triplet
|
||||
* sizeof(struct ieee80211_country_ie_triplet)
|
||||
+ sizeof(domain->countrycode));
|
||||
|
||||
if (nr_triplet) {
|
||||
memcpy(domain->triplet, priv->domain_reg.triplet,
|
||||
nr_triplet *
|
||||
sizeof(struct ieee80211_country_ie_triplet));
|
||||
|
||||
cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
|
||||
le16_to_cpu(domain->header.len) +
|
||||
sizeof(struct mrvl_ie_header) +
|
||||
sizeof(struct cmd_header));
|
||||
} else {
|
||||
cmd->size = cpu_to_le16(sizeof(pdomaininfo->action) +
|
||||
sizeof(struct cmd_header));
|
||||
}
|
||||
|
||||
lbs_deb_hex(LBS_DEB_11D, "802_11D_DOMAIN_INFO", (u8 *) cmd,
|
||||
le16_to_cpu(cmd->size));
|
||||
|
||||
done:
|
||||
lbs_deb_enter(LBS_DEB_11D);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function prepare the command before send to firmware.
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param cmd_no command number
|
||||
* @param cmd_action command action: GET or SET
|
||||
* @param wait_option wait option: wait response or not
|
||||
* @param cmd_oid cmd oid: treated as sub command
|
||||
* @param pdata_buf A pointer to informaion buffer
|
||||
* @return 0 or -1
|
||||
*/
|
||||
int lbs_prepare_and_send_command(struct lbs_private *priv,
|
||||
u16 cmd_no,
|
||||
u16 cmd_action,
|
||||
u16 wait_option, u32 cmd_oid, void *pdata_buf)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cmd_ctrl_node *cmdnode;
|
||||
struct cmd_ds_command *cmdptr;
|
||||
unsigned long flags;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_HOST);
|
||||
|
||||
if (!priv) {
|
||||
lbs_deb_host("PREP_CMD: priv is NULL\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (priv->surpriseremoved) {
|
||||
lbs_deb_host("PREP_CMD: card removed\n");
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!lbs_is_cmd_allowed(priv)) {
|
||||
ret = -EBUSY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
cmdnode = lbs_get_cmd_ctrl_node(priv);
|
||||
|
||||
if (cmdnode == NULL) {
|
||||
lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
|
||||
|
||||
/* Wake up main thread to execute next command */
|
||||
wake_up_interruptible(&priv->waitq);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
cmdnode->callback = NULL;
|
||||
cmdnode->callback_arg = (unsigned long)pdata_buf;
|
||||
|
||||
cmdptr = (struct cmd_ds_command *)cmdnode->cmdbuf;
|
||||
|
||||
lbs_deb_host("PREP_CMD: command 0x%04x\n", cmd_no);
|
||||
|
||||
/* Set sequence number, command and INT option */
|
||||
priv->seqnum++;
|
||||
cmdptr->seqnum = cpu_to_le16(priv->seqnum);
|
||||
|
||||
cmdptr->command = cpu_to_le16(cmd_no);
|
||||
cmdptr->result = 0;
|
||||
|
||||
switch (cmd_no) {
|
||||
case CMD_802_11_PS_MODE:
|
||||
ret = lbs_cmd_802_11_ps_mode(cmdptr, cmd_action);
|
||||
break;
|
||||
|
||||
case CMD_MAC_REG_ACCESS:
|
||||
case CMD_BBP_REG_ACCESS:
|
||||
case CMD_RF_REG_ACCESS:
|
||||
ret = lbs_cmd_reg_access(cmdptr, cmd_action, pdata_buf);
|
||||
break;
|
||||
|
||||
case CMD_802_11_MONITOR_MODE:
|
||||
ret = lbs_cmd_802_11_monitor_mode(cmdptr,
|
||||
cmd_action, pdata_buf);
|
||||
break;
|
||||
|
||||
case CMD_802_11_RSSI:
|
||||
ret = lbs_cmd_802_11_rssi(priv, cmdptr);
|
||||
break;
|
||||
|
||||
case CMD_802_11_SET_AFC:
|
||||
case CMD_802_11_GET_AFC:
|
||||
|
||||
cmdptr->command = cpu_to_le16(cmd_no);
|
||||
cmdptr->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_afc) +
|
||||
sizeof(struct cmd_header));
|
||||
|
||||
memmove(&cmdptr->params.afc,
|
||||
pdata_buf, sizeof(struct cmd_ds_802_11_afc));
|
||||
|
||||
ret = 0;
|
||||
goto done;
|
||||
|
||||
case CMD_802_11D_DOMAIN_INFO:
|
||||
cmdptr->command = cpu_to_le16(cmd_no);
|
||||
ret = lbs_cmd_802_11d_domain_info(priv, cmdptr, cmd_action);
|
||||
break;
|
||||
|
||||
case CMD_802_11_TPC_CFG:
|
||||
cmdptr->command = cpu_to_le16(CMD_802_11_TPC_CFG);
|
||||
cmdptr->size =
|
||||
cpu_to_le16(sizeof(struct cmd_ds_802_11_tpc_cfg) +
|
||||
sizeof(struct cmd_header));
|
||||
|
||||
memmove(&cmdptr->params.tpccfg,
|
||||
pdata_buf, sizeof(struct cmd_ds_802_11_tpc_cfg));
|
||||
|
||||
ret = 0;
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_LIBERTAS_MESH
|
||||
|
||||
case CMD_BT_ACCESS:
|
||||
ret = lbs_cmd_bt_access(cmdptr, cmd_action, pdata_buf);
|
||||
break;
|
||||
|
||||
case CMD_FWT_ACCESS:
|
||||
ret = lbs_cmd_fwt_access(cmdptr, cmd_action, pdata_buf);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
case CMD_802_11_BEACON_CTRL:
|
||||
ret = lbs_cmd_bcn_ctrl(priv, cmdptr, cmd_action);
|
||||
break;
|
||||
case CMD_802_11_DEEP_SLEEP:
|
||||
cmdptr->command = cpu_to_le16(CMD_802_11_DEEP_SLEEP);
|
||||
cmdptr->size = cpu_to_le16(sizeof(struct cmd_header));
|
||||
break;
|
||||
default:
|
||||
lbs_pr_err("PREP_CMD: unknown command 0x%04x\n", cmd_no);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* return error, since the command preparation failed */
|
||||
if (ret != 0) {
|
||||
lbs_deb_host("PREP_CMD: command preparation failed\n");
|
||||
lbs_cleanup_and_insert_cmd(priv, cmdnode);
|
||||
ret = -1;
|
||||
goto done;
|
||||
}
|
||||
|
||||
cmdnode->cmdwaitqwoken = 0;
|
||||
|
||||
lbs_queue_cmd(priv, cmdnode);
|
||||
wake_up_interruptible(&priv->waitq);
|
||||
|
||||
if (wait_option & CMD_OPTION_WAITFORRSP) {
|
||||
lbs_deb_host("PREP_CMD: wait for response\n");
|
||||
might_sleep();
|
||||
wait_event_interruptible(cmdnode->cmdwait_q,
|
||||
cmdnode->cmdwaitqwoken);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
if (priv->cur_cmd_retcode) {
|
||||
lbs_deb_host("PREP_CMD: command failed with return code %d\n",
|
||||
priv->cur_cmd_retcode);
|
||||
priv->cur_cmd_retcode = 0;
|
||||
ret = -1;
|
||||
}
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
|
||||
done:
|
||||
lbs_deb_leave_args(LBS_DEB_HOST, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function allocates the command buffer and link
|
||||
* it to command free queue.
|
||||
@ -1284,7 +1205,7 @@ done:
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @return cmd_ctrl_node A pointer to cmd_ctrl_node structure or NULL
|
||||
*/
|
||||
static struct cmd_ctrl_node *lbs_get_cmd_ctrl_node(struct lbs_private *priv)
|
||||
static struct cmd_ctrl_node *lbs_get_free_cmd_node(struct lbs_private *priv)
|
||||
{
|
||||
struct cmd_ctrl_node *tempnode;
|
||||
unsigned long flags;
|
||||
@ -1367,10 +1288,10 @@ int lbs_execute_next_command(struct lbs_private *priv)
|
||||
/*
|
||||
* 1. Non-PS command:
|
||||
* Queue it. set needtowakeup to TRUE if current state
|
||||
* is SLEEP, otherwise call lbs_ps_wakeup to send Exit_PS.
|
||||
* 2. PS command but not Exit_PS:
|
||||
* is SLEEP, otherwise call send EXIT_PS.
|
||||
* 2. PS command but not EXIT_PS:
|
||||
* Ignore it.
|
||||
* 3. PS command Exit_PS:
|
||||
* 3. PS command EXIT_PS:
|
||||
* Set needtowakeup to TRUE if current state is SLEEP,
|
||||
* otherwise send this command down to firmware
|
||||
* immediately.
|
||||
@ -1384,8 +1305,11 @@ int lbs_execute_next_command(struct lbs_private *priv)
|
||||
/* w/ new scheme, it will not reach here.
|
||||
since it is blocked in main_thread. */
|
||||
priv->needtowakeup = 1;
|
||||
} else
|
||||
lbs_ps_wakeup(priv, 0);
|
||||
} else {
|
||||
lbs_set_ps_mode(priv,
|
||||
PS_MODE_ACTION_EXIT_PS,
|
||||
false);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
goto done;
|
||||
@ -1400,7 +1324,7 @@ int lbs_execute_next_command(struct lbs_private *priv)
|
||||
"EXEC_NEXT_CMD: PS cmd, action 0x%02x\n",
|
||||
psm->action);
|
||||
if (psm->action !=
|
||||
cpu_to_le16(CMD_SUBCMD_EXIT_PS)) {
|
||||
cpu_to_le16(PS_MODE_ACTION_EXIT_PS)) {
|
||||
lbs_deb_host(
|
||||
"EXEC_NEXT_CMD: ignore ENTER_PS cmd\n");
|
||||
list_del(&cmdnode->list);
|
||||
@ -1460,13 +1384,16 @@ int lbs_execute_next_command(struct lbs_private *priv)
|
||||
lbs_deb_host(
|
||||
"EXEC_NEXT_CMD: WPA enabled and GTK_SET"
|
||||
" go back to PS_SLEEP");
|
||||
lbs_ps_sleep(priv, 0);
|
||||
lbs_set_ps_mode(priv,
|
||||
PS_MODE_ACTION_ENTER_PS,
|
||||
false);
|
||||
}
|
||||
} else {
|
||||
lbs_deb_host(
|
||||
"EXEC_NEXT_CMD: cmdpendingq empty, "
|
||||
"go back to PS_SLEEP");
|
||||
lbs_ps_sleep(priv, 0);
|
||||
lbs_set_ps_mode(priv, PS_MODE_ACTION_ENTER_PS,
|
||||
false);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -1514,43 +1441,6 @@ out:
|
||||
lbs_deb_leave(LBS_DEB_HOST);
|
||||
}
|
||||
|
||||
void lbs_ps_sleep(struct lbs_private *priv, int wait_option)
|
||||
{
|
||||
lbs_deb_enter(LBS_DEB_HOST);
|
||||
|
||||
/*
|
||||
* PS is currently supported only in Infrastructure mode
|
||||
* Remove this check if it is to be supported in IBSS mode also
|
||||
*/
|
||||
|
||||
lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
|
||||
CMD_SUBCMD_ENTER_PS, wait_option, 0, NULL);
|
||||
|
||||
lbs_deb_leave(LBS_DEB_HOST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function sends Exit_PS command to firmware.
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param wait_option wait response or not
|
||||
* @return n/a
|
||||
*/
|
||||
void lbs_ps_wakeup(struct lbs_private *priv, int wait_option)
|
||||
{
|
||||
__le32 Localpsmode;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_HOST);
|
||||
|
||||
Localpsmode = cpu_to_le32(LBS802_11POWERMODECAM);
|
||||
|
||||
lbs_prepare_and_send_command(priv, CMD_802_11_PS_MODE,
|
||||
CMD_SUBCMD_EXIT_PS,
|
||||
wait_option, 0, &Localpsmode);
|
||||
|
||||
lbs_deb_leave(LBS_DEB_HOST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function checks condition and prepares to
|
||||
* send sleep confirm command to firmware if ok.
|
||||
@ -1675,12 +1565,18 @@ struct cmd_ctrl_node *__lbs_cmd_async(struct lbs_private *priv,
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!lbs_is_cmd_allowed(priv)) {
|
||||
cmdnode = ERR_PTR(-EBUSY);
|
||||
goto done;
|
||||
/* No commands are allowed in Deep Sleep until we toggle the GPIO
|
||||
* to wake up the card and it has signaled that it's ready.
|
||||
*/
|
||||
if (!priv->is_auto_deep_sleep_enabled) {
|
||||
if (priv->is_deep_sleep) {
|
||||
lbs_deb_cmd("command not allowed in deep sleep\n");
|
||||
cmdnode = ERR_PTR(-EBUSY);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
cmdnode = lbs_get_cmd_ctrl_node(priv);
|
||||
cmdnode = lbs_get_free_cmd_node(priv);
|
||||
if (cmdnode == NULL) {
|
||||
lbs_deb_host("PREP_CMD: cmdnode is NULL\n");
|
||||
|
||||
|
@ -3,6 +3,8 @@
|
||||
#ifndef _LBS_CMD_H_
|
||||
#define _LBS_CMD_H_
|
||||
|
||||
#include <net/cfg80211.h>
|
||||
|
||||
#include "host.h"
|
||||
#include "dev.h"
|
||||
|
||||
@ -37,11 +39,6 @@ struct cmd_ctrl_node {
|
||||
#define lbs_cmd_with_response(priv, cmdnr, cmd) \
|
||||
lbs_cmd(priv, cmdnr, cmd, lbs_cmd_copyback, (unsigned long) (cmd))
|
||||
|
||||
int lbs_prepare_and_send_command(struct lbs_private *priv,
|
||||
u16 cmd_no,
|
||||
u16 cmd_action,
|
||||
u16 wait_option, u32 cmd_oid, void *pdata_buf);
|
||||
|
||||
void lbs_cmd_async(struct lbs_private *priv, uint16_t command,
|
||||
struct cmd_header *in_cmd, int in_cmd_size);
|
||||
|
||||
@ -92,10 +89,6 @@ int lbs_host_sleep_cfg(struct lbs_private *priv, uint32_t criteria,
|
||||
int lbs_cmd_802_11_sleep_params(struct lbs_private *priv, uint16_t cmd_action,
|
||||
struct sleep_params *sp);
|
||||
|
||||
void lbs_ps_sleep(struct lbs_private *priv, int wait_option);
|
||||
|
||||
void lbs_ps_wakeup(struct lbs_private *priv, int wait_option);
|
||||
|
||||
void lbs_ps_confirm_sleep(struct lbs_private *priv);
|
||||
|
||||
int lbs_set_radio(struct lbs_private *priv, u8 preamble, u8 radio_on);
|
||||
@ -129,4 +122,18 @@ int lbs_set_deep_sleep(struct lbs_private *priv, int deep_sleep);
|
||||
|
||||
int lbs_set_host_sleep(struct lbs_private *priv, int host_sleep);
|
||||
|
||||
int lbs_set_monitor_mode(struct lbs_private *priv, int enable);
|
||||
|
||||
int lbs_get_rssi(struct lbs_private *priv, s8 *snr, s8 *nf);
|
||||
|
||||
int lbs_set_11d_domain_info(struct lbs_private *priv,
|
||||
struct regulatory_request *request,
|
||||
struct ieee80211_supported_band **bands);
|
||||
|
||||
int lbs_get_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 *value);
|
||||
|
||||
int lbs_set_reg(struct lbs_private *priv, u16 reg, u16 offset, u32 value);
|
||||
|
||||
int lbs_set_ps_mode(struct lbs_private *priv, u16 cmd_action, bool block);
|
||||
|
||||
#endif /* _LBS_CMD_H */
|
||||
|
@ -49,171 +49,11 @@ void lbs_mac_event_disconnected(struct lbs_private *priv)
|
||||
if (priv->psstate != PS_STATE_FULL_POWER) {
|
||||
/* make firmware to exit PS mode */
|
||||
lbs_deb_cmd("disconnected, so exit PS mode\n");
|
||||
lbs_ps_wakeup(priv, 0);
|
||||
lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
|
||||
}
|
||||
lbs_deb_leave(LBS_DEB_ASSOC);
|
||||
}
|
||||
|
||||
static int lbs_ret_reg_access(struct lbs_private *priv,
|
||||
u16 type, struct cmd_ds_command *resp)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
switch (type) {
|
||||
case CMD_RET(CMD_MAC_REG_ACCESS):
|
||||
{
|
||||
struct cmd_ds_mac_reg_access *reg = &resp->params.macreg;
|
||||
|
||||
priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
|
||||
priv->offsetvalue.value = le32_to_cpu(reg->value);
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_RET(CMD_BBP_REG_ACCESS):
|
||||
{
|
||||
struct cmd_ds_bbp_reg_access *reg = &resp->params.bbpreg;
|
||||
|
||||
priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
|
||||
priv->offsetvalue.value = reg->value;
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_RET(CMD_RF_REG_ACCESS):
|
||||
{
|
||||
struct cmd_ds_rf_reg_access *reg = &resp->params.rfreg;
|
||||
|
||||
priv->offsetvalue.offset = (u32)le16_to_cpu(reg->offset);
|
||||
priv->offsetvalue.value = reg->value;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function parses countryinfo from AP and download country info to FW
|
||||
* @param priv pointer to struct lbs_private
|
||||
* @param resp pointer to command response buffer
|
||||
* @return 0; -1
|
||||
*/
|
||||
static int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp)
|
||||
{
|
||||
struct cmd_ds_802_11d_domain_info *domaininfo =
|
||||
&resp->params.domaininforesp;
|
||||
struct mrvl_ie_domain_param_set *domain = &domaininfo->domain;
|
||||
u16 action = le16_to_cpu(domaininfo->action);
|
||||
s16 ret = 0;
|
||||
u8 nr_triplet = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_11D);
|
||||
|
||||
lbs_deb_hex(LBS_DEB_11D, "domain info resp", (u8 *) resp,
|
||||
(int)le16_to_cpu(resp->size));
|
||||
|
||||
nr_triplet = (le16_to_cpu(domain->header.len) - COUNTRY_CODE_LEN) /
|
||||
sizeof(struct ieee80211_country_ie_triplet);
|
||||
|
||||
lbs_deb_11d("domain info resp: nr_triplet %d\n", nr_triplet);
|
||||
|
||||
if (nr_triplet > MRVDRV_MAX_TRIPLET_802_11D) {
|
||||
lbs_deb_11d("invalid number of triplets returned!!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case CMD_ACT_SET: /*Proc set action */
|
||||
break;
|
||||
|
||||
case CMD_ACT_GET:
|
||||
break;
|
||||
default:
|
||||
lbs_deb_11d("invalid action:%d\n", domaininfo->action);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_11D, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int handle_cmd_response(struct lbs_private *priv,
|
||||
struct cmd_header *cmd_response)
|
||||
{
|
||||
struct cmd_ds_command *resp = (struct cmd_ds_command *) cmd_response;
|
||||
int ret = 0;
|
||||
unsigned long flags;
|
||||
uint16_t respcmd = le16_to_cpu(resp->command);
|
||||
|
||||
lbs_deb_enter(LBS_DEB_HOST);
|
||||
|
||||
switch (respcmd) {
|
||||
case CMD_RET(CMD_MAC_REG_ACCESS):
|
||||
case CMD_RET(CMD_BBP_REG_ACCESS):
|
||||
case CMD_RET(CMD_RF_REG_ACCESS):
|
||||
ret = lbs_ret_reg_access(priv, respcmd, resp);
|
||||
break;
|
||||
|
||||
case CMD_RET(CMD_802_11_SET_AFC):
|
||||
case CMD_RET(CMD_802_11_GET_AFC):
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
memmove((void *)priv->cur_cmd->callback_arg, &resp->params.afc,
|
||||
sizeof(struct cmd_ds_802_11_afc));
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
|
||||
break;
|
||||
|
||||
case CMD_RET(CMD_802_11_BEACON_STOP):
|
||||
break;
|
||||
|
||||
case CMD_RET(CMD_802_11_RSSI):
|
||||
ret = lbs_ret_802_11_rssi(priv, resp);
|
||||
break;
|
||||
|
||||
case CMD_RET(CMD_802_11D_DOMAIN_INFO):
|
||||
ret = lbs_ret_802_11d_domain_info(resp);
|
||||
break;
|
||||
|
||||
case CMD_RET(CMD_802_11_TPC_CFG):
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
memmove((void *)priv->cur_cmd->callback_arg, &resp->params.tpccfg,
|
||||
sizeof(struct cmd_ds_802_11_tpc_cfg));
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
break;
|
||||
|
||||
case CMD_RET(CMD_BT_ACCESS):
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
if (priv->cur_cmd->callback_arg)
|
||||
memcpy((void *)priv->cur_cmd->callback_arg,
|
||||
&resp->params.bt.addr1, 2 * ETH_ALEN);
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
break;
|
||||
case CMD_RET(CMD_FWT_ACCESS):
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
if (priv->cur_cmd->callback_arg)
|
||||
memcpy((void *)priv->cur_cmd->callback_arg, &resp->params.fwt,
|
||||
sizeof(resp->params.fwt));
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
break;
|
||||
case CMD_RET(CMD_802_11_BEACON_CTRL):
|
||||
ret = lbs_ret_802_11_bcn_ctrl(priv, resp);
|
||||
break;
|
||||
|
||||
default:
|
||||
lbs_pr_err("CMD_RESP: unknown cmd response 0x%04x\n",
|
||||
le16_to_cpu(resp->command));
|
||||
break;
|
||||
}
|
||||
lbs_deb_leave(LBS_DEB_HOST);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
|
||||
{
|
||||
uint16_t respcmd, curcmd;
|
||||
@ -272,9 +112,6 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
|
||||
del_timer(&priv->command_timer);
|
||||
priv->cmd_timed_out = 0;
|
||||
|
||||
/* Store the response code to cur_cmd_retcode. */
|
||||
priv->cur_cmd_retcode = result;
|
||||
|
||||
if (respcmd == CMD_RET(CMD_802_11_PS_MODE)) {
|
||||
struct cmd_ds_802_11_ps_mode *psmode = (void *) &resp[1];
|
||||
u16 action = le16_to_cpu(psmode->action);
|
||||
@ -292,9 +129,9 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
|
||||
* lbs_execute_next_command().
|
||||
*/
|
||||
if (priv->wdev->iftype == NL80211_IFTYPE_MONITOR &&
|
||||
action == CMD_SUBCMD_ENTER_PS)
|
||||
action == PS_MODE_ACTION_ENTER_PS)
|
||||
priv->psmode = LBS802_11POWERMODECAM;
|
||||
} else if (action == CMD_SUBCMD_ENTER_PS) {
|
||||
} else if (action == PS_MODE_ACTION_ENTER_PS) {
|
||||
priv->needtowakeup = 0;
|
||||
priv->psstate = PS_STATE_AWAKE;
|
||||
|
||||
@ -309,11 +146,12 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
|
||||
|
||||
spin_unlock_irqrestore(&priv->driver_lock, flags);
|
||||
mutex_unlock(&priv->lock);
|
||||
lbs_ps_wakeup(priv, 0);
|
||||
lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS,
|
||||
false);
|
||||
mutex_lock(&priv->lock);
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
}
|
||||
} else if (action == CMD_SUBCMD_EXIT_PS) {
|
||||
} else if (action == PS_MODE_ACTION_EXIT_PS) {
|
||||
priv->needtowakeup = 0;
|
||||
priv->psstate = PS_STATE_FULL_POWER;
|
||||
lbs_deb_host("CMD_RESP: EXIT_PS command response\n");
|
||||
@ -354,8 +192,7 @@ int lbs_process_command_response(struct lbs_private *priv, u8 *data, u32 len)
|
||||
if (priv->cur_cmd && priv->cur_cmd->callback) {
|
||||
ret = priv->cur_cmd->callback(priv, priv->cur_cmd->callback_arg,
|
||||
resp);
|
||||
} else
|
||||
ret = handle_cmd_response(priv, resp);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&priv->driver_lock, flags);
|
||||
|
||||
@ -452,7 +289,7 @@ int lbs_process_event(struct lbs_private *priv, u32 event)
|
||||
* in lbs_ps_wakeup()
|
||||
*/
|
||||
lbs_deb_cmd("waking up ...\n");
|
||||
lbs_ps_wakeup(priv, 0);
|
||||
lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, false);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -446,30 +446,24 @@ static ssize_t lbs_bcnmiss_write(struct file *file, const char __user *userbuf,
|
||||
}
|
||||
|
||||
|
||||
|
||||
static ssize_t lbs_rdmac_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct lbs_private *priv = file->private_data;
|
||||
struct lbs_offset_value offval;
|
||||
ssize_t pos = 0;
|
||||
int ret;
|
||||
unsigned long addr = get_zeroed_page(GFP_KERNEL);
|
||||
char *buf = (char *)addr;
|
||||
u32 val = 0;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
offval.offset = priv->mac_offset;
|
||||
offval.value = 0;
|
||||
|
||||
ret = lbs_prepare_and_send_command(priv,
|
||||
CMD_MAC_REG_ACCESS, 0,
|
||||
CMD_OPTION_WAITFORRSP, 0, &offval);
|
||||
ret = lbs_get_reg(priv, CMD_MAC_REG_ACCESS, priv->mac_offset, &val);
|
||||
mdelay(10);
|
||||
if (!ret) {
|
||||
pos += snprintf(buf+pos, len-pos, "MAC[0x%x] = 0x%08x\n",
|
||||
priv->mac_offset, priv->offsetvalue.value);
|
||||
|
||||
pos = snprintf(buf, len, "MAC[0x%x] = 0x%08x\n",
|
||||
priv->mac_offset, val);
|
||||
ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
|
||||
}
|
||||
free_page(addr);
|
||||
@ -507,7 +501,6 @@ static ssize_t lbs_wrmac_write(struct file *file,
|
||||
struct lbs_private *priv = file->private_data;
|
||||
ssize_t res, buf_size;
|
||||
u32 offset, value;
|
||||
struct lbs_offset_value offval;
|
||||
unsigned long addr = get_zeroed_page(GFP_KERNEL);
|
||||
char *buf = (char *)addr;
|
||||
if (!buf)
|
||||
@ -524,11 +517,7 @@ static ssize_t lbs_wrmac_write(struct file *file,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
offval.offset = offset;
|
||||
offval.value = value;
|
||||
res = lbs_prepare_and_send_command(priv,
|
||||
CMD_MAC_REG_ACCESS, 1,
|
||||
CMD_OPTION_WAITFORRSP, 0, &offval);
|
||||
res = lbs_set_reg(priv, CMD_MAC_REG_ACCESS, offset, value);
|
||||
mdelay(10);
|
||||
|
||||
if (!res)
|
||||
@ -542,25 +531,20 @@ static ssize_t lbs_rdbbp_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct lbs_private *priv = file->private_data;
|
||||
struct lbs_offset_value offval;
|
||||
ssize_t pos = 0;
|
||||
int ret;
|
||||
unsigned long addr = get_zeroed_page(GFP_KERNEL);
|
||||
char *buf = (char *)addr;
|
||||
u32 val;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
offval.offset = priv->bbp_offset;
|
||||
offval.value = 0;
|
||||
|
||||
ret = lbs_prepare_and_send_command(priv,
|
||||
CMD_BBP_REG_ACCESS, 0,
|
||||
CMD_OPTION_WAITFORRSP, 0, &offval);
|
||||
ret = lbs_get_reg(priv, CMD_BBP_REG_ACCESS, priv->bbp_offset, &val);
|
||||
mdelay(10);
|
||||
if (!ret) {
|
||||
pos += snprintf(buf+pos, len-pos, "BBP[0x%x] = 0x%08x\n",
|
||||
priv->bbp_offset, priv->offsetvalue.value);
|
||||
|
||||
pos = snprintf(buf, len, "BBP[0x%x] = 0x%08x\n",
|
||||
priv->bbp_offset, val);
|
||||
ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
|
||||
}
|
||||
free_page(addr);
|
||||
@ -599,7 +583,6 @@ static ssize_t lbs_wrbbp_write(struct file *file,
|
||||
struct lbs_private *priv = file->private_data;
|
||||
ssize_t res, buf_size;
|
||||
u32 offset, value;
|
||||
struct lbs_offset_value offval;
|
||||
unsigned long addr = get_zeroed_page(GFP_KERNEL);
|
||||
char *buf = (char *)addr;
|
||||
if (!buf)
|
||||
@ -616,11 +599,7 @@ static ssize_t lbs_wrbbp_write(struct file *file,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
offval.offset = offset;
|
||||
offval.value = value;
|
||||
res = lbs_prepare_and_send_command(priv,
|
||||
CMD_BBP_REG_ACCESS, 1,
|
||||
CMD_OPTION_WAITFORRSP, 0, &offval);
|
||||
res = lbs_set_reg(priv, CMD_BBP_REG_ACCESS, offset, value);
|
||||
mdelay(10);
|
||||
|
||||
if (!res)
|
||||
@ -634,25 +613,20 @@ static ssize_t lbs_rdrf_read(struct file *file, char __user *userbuf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct lbs_private *priv = file->private_data;
|
||||
struct lbs_offset_value offval;
|
||||
ssize_t pos = 0;
|
||||
int ret;
|
||||
unsigned long addr = get_zeroed_page(GFP_KERNEL);
|
||||
char *buf = (char *)addr;
|
||||
u32 val;
|
||||
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
offval.offset = priv->rf_offset;
|
||||
offval.value = 0;
|
||||
|
||||
ret = lbs_prepare_and_send_command(priv,
|
||||
CMD_RF_REG_ACCESS, 0,
|
||||
CMD_OPTION_WAITFORRSP, 0, &offval);
|
||||
ret = lbs_get_reg(priv, CMD_RF_REG_ACCESS, priv->rf_offset, &val);
|
||||
mdelay(10);
|
||||
if (!ret) {
|
||||
pos += snprintf(buf+pos, len-pos, "RF[0x%x] = 0x%08x\n",
|
||||
priv->rf_offset, priv->offsetvalue.value);
|
||||
|
||||
pos = snprintf(buf, len, "RF[0x%x] = 0x%08x\n",
|
||||
priv->rf_offset, val);
|
||||
ret = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
|
||||
}
|
||||
free_page(addr);
|
||||
@ -691,7 +665,6 @@ static ssize_t lbs_wrrf_write(struct file *file,
|
||||
struct lbs_private *priv = file->private_data;
|
||||
ssize_t res, buf_size;
|
||||
u32 offset, value;
|
||||
struct lbs_offset_value offval;
|
||||
unsigned long addr = get_zeroed_page(GFP_KERNEL);
|
||||
char *buf = (char *)addr;
|
||||
if (!buf)
|
||||
@ -708,11 +681,7 @@ static ssize_t lbs_wrrf_write(struct file *file,
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
offval.offset = offset;
|
||||
offval.value = value;
|
||||
res = lbs_prepare_and_send_command(priv,
|
||||
CMD_RF_REG_ACCESS, 1,
|
||||
CMD_OPTION_WAITFORRSP, 0, &offval);
|
||||
res = lbs_set_reg(priv, CMD_RF_REG_ACCESS, offset, value);
|
||||
mdelay(10);
|
||||
|
||||
if (!res)
|
||||
|
@ -53,9 +53,4 @@ int lbs_exit_auto_deep_sleep(struct lbs_private *priv);
|
||||
u32 lbs_fw_index_to_data_rate(u8 index);
|
||||
u8 lbs_data_rate_to_fw_index(u32 rate);
|
||||
|
||||
int lbs_cmd_802_11d_domain_info(struct lbs_private *priv,
|
||||
struct cmd_ds_command *cmd, u16 cmdoption);
|
||||
|
||||
int lbs_ret_802_11d_domain_info(struct cmd_ds_command *resp);
|
||||
|
||||
#endif
|
||||
|
@ -172,11 +172,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
||||
#define MRVDRV_MAX_BSS_DESCRIPTS 16
|
||||
#define MRVDRV_MAX_REGION_CODE 6
|
||||
|
||||
#define MRVDRV_IGNORE_MULTIPLE_DTIM 0xfffe
|
||||
#define MRVDRV_MIN_MULTIPLE_DTIM 1
|
||||
#define MRVDRV_MAX_MULTIPLE_DTIM 5
|
||||
#define MRVDRV_DEFAULT_MULTIPLE_DTIM 1
|
||||
|
||||
#define MRVDRV_DEFAULT_LISTEN_INTERVAL 10
|
||||
|
||||
#define MRVDRV_CHANNELS_PER_SCAN 4
|
||||
@ -301,19 +296,6 @@ static inline void lbs_deb_hex(unsigned int grp, const char *prompt, u8 *buf, in
|
||||
#define BAND_G (0x02)
|
||||
#define ALL_802_11_BANDS (BAND_B | BAND_G)
|
||||
|
||||
/** MACRO DEFINITIONS */
|
||||
#define CAL_NF(NF) ((s32)(-(s32)(NF)))
|
||||
#define CAL_RSSI(SNR, NF) ((s32)((s32)(SNR) + CAL_NF(NF)))
|
||||
#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI)))
|
||||
|
||||
#define DEFAULT_BCN_AVG_FACTOR 8
|
||||
#define DEFAULT_DATA_AVG_FACTOR 8
|
||||
#define AVG_SCALE 100
|
||||
#define CAL_AVG_SNR_NF(AVG, SNRNF, N) \
|
||||
(((AVG) == 0) ? ((u16)(SNRNF) * AVG_SCALE) : \
|
||||
((((int)(AVG) * (N -1)) + ((u16)(SNRNF) * \
|
||||
AVG_SCALE)) / N))
|
||||
|
||||
#define MAX_RATES 14
|
||||
|
||||
#define MAX_LEDS 8
|
||||
|
@ -60,14 +60,10 @@ struct lbs_private {
|
||||
struct dentry *regs_dir;
|
||||
struct dentry *debugfs_regs_files[6];
|
||||
|
||||
/** 11D and domain regulatory data */
|
||||
struct lbs_802_11d_domain_reg domain_reg;
|
||||
|
||||
/* Hardware debugging */
|
||||
u32 mac_offset;
|
||||
u32 bbp_offset;
|
||||
u32 rf_offset;
|
||||
struct lbs_offset_value offsetvalue;
|
||||
|
||||
/* Power management */
|
||||
u16 psmode;
|
||||
@ -115,12 +111,10 @@ struct lbs_private {
|
||||
struct cmd_ctrl_node *cur_cmd;
|
||||
struct list_head cmdfreeq; /* free command buffers */
|
||||
struct list_head cmdpendingq; /* pending command buffers */
|
||||
wait_queue_head_t cmd_pending;
|
||||
struct timer_list command_timer;
|
||||
int cmd_timed_out;
|
||||
|
||||
/* Command responses sent from the hardware to the driver */
|
||||
int cur_cmd_retcode;
|
||||
u8 resp_idx;
|
||||
u8 resp_buf[2][LBS_UPLD_SIZE];
|
||||
u32 resp_len[2];
|
||||
|
@ -94,11 +94,9 @@
|
||||
#define CMD_802_11_BEACON_CTRL 0x00b0
|
||||
|
||||
/* For the IEEE Power Save */
|
||||
#define CMD_SUBCMD_ENTER_PS 0x0030
|
||||
#define CMD_SUBCMD_EXIT_PS 0x0031
|
||||
#define CMD_SUBCMD_SLEEP_CONFIRMED 0x0034
|
||||
#define CMD_SUBCMD_FULL_POWERDOWN 0x0035
|
||||
#define CMD_SUBCMD_FULL_POWERUP 0x0036
|
||||
#define PS_MODE_ACTION_ENTER_PS 0x0030
|
||||
#define PS_MODE_ACTION_EXIT_PS 0x0031
|
||||
#define PS_MODE_ACTION_SLEEP_CONFIRMED 0x0034
|
||||
|
||||
#define CMD_ENABLE_RSN 0x0001
|
||||
#define CMD_DISABLE_RSN 0x0000
|
||||
@ -163,11 +161,6 @@
|
||||
#define CMD_ACT_SET_TX_FIX_RATE 0x0001
|
||||
#define CMD_ACT_GET_TX_RATE 0x0002
|
||||
|
||||
/* Define action or option for CMD_802_11_PS_MODE */
|
||||
#define CMD_TYPE_CAM 0x0000
|
||||
#define CMD_TYPE_MAX_PSP 0x0001
|
||||
#define CMD_TYPE_FAST_PSP 0x0002
|
||||
|
||||
/* Options for CMD_802_11_FW_WAKE_METHOD */
|
||||
#define CMD_WAKE_METHOD_UNCHANGED 0x0000
|
||||
#define CMD_WAKE_METHOD_COMMAND_INT 0x0001
|
||||
@ -389,30 +382,22 @@ struct lbs_offset_value {
|
||||
u32 value;
|
||||
} __packed;
|
||||
|
||||
#define MRVDRV_MAX_TRIPLET_802_11D 83
|
||||
|
||||
#define COUNTRY_CODE_LEN 3
|
||||
#define MAX_11D_TRIPLETS 83
|
||||
|
||||
struct mrvl_ie_domain_param_set {
|
||||
struct mrvl_ie_header header;
|
||||
|
||||
u8 countrycode[COUNTRY_CODE_LEN];
|
||||
struct ieee80211_country_ie_triplet triplet[1];
|
||||
u8 country_code[3];
|
||||
struct ieee80211_country_ie_triplet triplet[MAX_11D_TRIPLETS];
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_802_11d_domain_info {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
struct mrvl_ie_domain_param_set domain;
|
||||
} __packed;
|
||||
|
||||
struct lbs_802_11d_domain_reg {
|
||||
/** Country code*/
|
||||
u8 country_code[COUNTRY_CODE_LEN];
|
||||
/** No. of triplet*/
|
||||
u8 no_triplet;
|
||||
struct ieee80211_country_ie_triplet triplet[MRVDRV_MAX_TRIPLET_802_11D];
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Define data structure for CMD_GET_HW_SPEC
|
||||
* This structure defines the response for the GET_HW_SPEC command
|
||||
@ -575,24 +560,15 @@ struct cmd_ds_802_11_snmp_mib {
|
||||
u8 value[128];
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_mac_reg_access {
|
||||
__le16 action;
|
||||
__le16 offset;
|
||||
__le32 value;
|
||||
} __packed;
|
||||
struct cmd_ds_reg_access {
|
||||
struct cmd_header hdr;
|
||||
|
||||
struct cmd_ds_bbp_reg_access {
|
||||
__le16 action;
|
||||
__le16 offset;
|
||||
u8 value;
|
||||
u8 reserved[3];
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_rf_reg_access {
|
||||
__le16 action;
|
||||
__le16 offset;
|
||||
u8 value;
|
||||
u8 reserved[3];
|
||||
union {
|
||||
u8 bbp_rf; /* for BBP and RF registers */
|
||||
__le32 mac; /* for MAC registers */
|
||||
} value;
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_802_11_radio_control {
|
||||
@ -603,6 +579,8 @@ struct cmd_ds_802_11_radio_control {
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_802_11_beacon_control {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le16 beacon_enable;
|
||||
__le16 beacon_period;
|
||||
@ -644,19 +622,19 @@ struct cmd_ds_802_11_rf_channel {
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_802_11_rssi {
|
||||
/* weighting factor */
|
||||
__le16 N;
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 reserved_0;
|
||||
__le16 reserved_1;
|
||||
__le16 reserved_2;
|
||||
} __packed;
|
||||
/* request: number of beacons (N) to average the SNR and NF over
|
||||
* response: SNR of most recent beacon
|
||||
*/
|
||||
__le16 n_or_snr;
|
||||
|
||||
struct cmd_ds_802_11_rssi_rsp {
|
||||
__le16 SNR;
|
||||
__le16 noisefloor;
|
||||
__le16 avgSNR;
|
||||
__le16 avgnoisefloor;
|
||||
/* The following fields are only set in the response.
|
||||
* In the request these are reserved and should be set to 0.
|
||||
*/
|
||||
__le16 nf; /* most recent beacon noise floor */
|
||||
__le16 avg_snr; /* average SNR weighted by N from request */
|
||||
__le16 avg_nf; /* average noise floor weighted by N from request */
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_802_11_mac_address {
|
||||
@ -675,7 +653,10 @@ struct cmd_ds_802_11_rf_tx_power {
|
||||
s8 minlevel;
|
||||
} __packed;
|
||||
|
||||
/* MONITOR_MODE only exists in OLPC v5 firmware */
|
||||
struct cmd_ds_802_11_monitor_mode {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le16 mode;
|
||||
} __packed;
|
||||
@ -695,11 +676,35 @@ struct cmd_ds_802_11_fw_wake_method {
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_802_11_ps_mode {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
|
||||
/* Interval for keepalive in PS mode:
|
||||
* 0x0000 = don't change
|
||||
* 0x001E = firmware default
|
||||
* 0xFFFF = disable
|
||||
*/
|
||||
__le16 nullpktinterval;
|
||||
|
||||
/* Number of DTIM intervals to wake up for:
|
||||
* 0 = don't change
|
||||
* 1 = firmware default
|
||||
* 5 = max
|
||||
*/
|
||||
__le16 multipledtim;
|
||||
|
||||
__le16 reserved;
|
||||
__le16 locallisteninterval;
|
||||
|
||||
/* AdHoc awake period (FW v9+ only):
|
||||
* 0 = don't change
|
||||
* 1 = always awake (IEEE standard behavior)
|
||||
* 2 - 31 = sleep for (n - 1) periods and awake for 1 period
|
||||
* 32 - 254 = invalid
|
||||
* 255 = sleep at each ATIM
|
||||
*/
|
||||
__le16 adhoc_awake_period;
|
||||
} __packed;
|
||||
|
||||
struct cmd_confirm_sleep {
|
||||
@ -882,12 +887,17 @@ struct cmd_ds_802_11_pa_cfg {
|
||||
|
||||
|
||||
struct cmd_ds_802_11_led_ctrl {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le16 numled;
|
||||
u8 data[256];
|
||||
} __packed;
|
||||
|
||||
/* Automatic Frequency Control */
|
||||
struct cmd_ds_802_11_afc {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 afc_auto;
|
||||
union {
|
||||
struct {
|
||||
@ -910,6 +920,8 @@ struct cmd_ds_get_tsf {
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_bt_access {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le32 id;
|
||||
u8 addr1[ETH_ALEN];
|
||||
@ -917,6 +929,8 @@ struct cmd_ds_bt_access {
|
||||
} __packed;
|
||||
|
||||
struct cmd_ds_fwt_access {
|
||||
struct cmd_header hdr;
|
||||
|
||||
__le16 action;
|
||||
__le32 id;
|
||||
u8 valid;
|
||||
@ -955,34 +969,4 @@ struct cmd_ds_mesh_access {
|
||||
|
||||
/* Number of stats counters returned by the firmware */
|
||||
#define MESH_STATS_NUM 8
|
||||
|
||||
struct cmd_ds_command {
|
||||
/* command header */
|
||||
__le16 command;
|
||||
__le16 size;
|
||||
__le16 seqnum;
|
||||
__le16 result;
|
||||
|
||||
/* command Body */
|
||||
union {
|
||||
struct cmd_ds_802_11_ps_mode psmode;
|
||||
struct cmd_ds_802_11_monitor_mode monitor;
|
||||
struct cmd_ds_802_11_rssi rssi;
|
||||
struct cmd_ds_802_11_rssi_rsp rssirsp;
|
||||
struct cmd_ds_mac_reg_access macreg;
|
||||
struct cmd_ds_bbp_reg_access bbpreg;
|
||||
struct cmd_ds_rf_reg_access rfreg;
|
||||
|
||||
struct cmd_ds_802_11d_domain_info domaininfo;
|
||||
struct cmd_ds_802_11d_domain_info domaininforesp;
|
||||
|
||||
struct cmd_ds_802_11_tpc_cfg tpccfg;
|
||||
struct cmd_ds_802_11_afc afc;
|
||||
struct cmd_ds_802_11_led_ctrl ledgpio;
|
||||
|
||||
struct cmd_ds_bt_access bt;
|
||||
struct cmd_ds_fwt_access fwt;
|
||||
struct cmd_ds_802_11_beacon_control bcn_ctrl;
|
||||
} params;
|
||||
} __packed;
|
||||
#endif
|
||||
|
@ -433,7 +433,7 @@ static int if_usb_send_fw_pkt(struct if_usb_card *cardp)
|
||||
|
||||
static int if_usb_reset_device(struct if_usb_card *cardp)
|
||||
{
|
||||
struct cmd_ds_command *cmd = cardp->ep_out_buf + 4;
|
||||
struct cmd_header *cmd = cardp->ep_out_buf + 4;
|
||||
int ret;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_USB);
|
||||
@ -441,7 +441,7 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
|
||||
*(__le32 *)cardp->ep_out_buf = cpu_to_le32(CMD_TYPE_REQUEST);
|
||||
|
||||
cmd->command = cpu_to_le16(CMD_802_11_RESET);
|
||||
cmd->size = cpu_to_le16(sizeof(struct cmd_header));
|
||||
cmd->size = cpu_to_le16(sizeof(cmd));
|
||||
cmd->result = cpu_to_le16(0);
|
||||
cmd->seqnum = cpu_to_le16(0x5a5a);
|
||||
usb_tx_block(cardp, cardp->ep_out_buf, 4 + sizeof(struct cmd_header));
|
||||
|
@ -157,12 +157,7 @@ static void lbs_tx_timeout(struct net_device *dev)
|
||||
to kick it somehow? */
|
||||
lbs_host_to_card_done(priv);
|
||||
|
||||
/* More often than not, this actually happens because the
|
||||
firmware has crapped itself -- rather than just a very
|
||||
busy medium. So send a harmless command, and if/when
|
||||
_that_ times out, we'll kick it in the head. */
|
||||
lbs_prepare_and_send_command(priv, CMD_802_11_RSSI, 0,
|
||||
0, 0, NULL);
|
||||
/* FIXME: reset the card */
|
||||
|
||||
lbs_deb_leave(LBS_DEB_TX);
|
||||
}
|
||||
@ -507,12 +502,6 @@ static int lbs_thread(void *data)
|
||||
if (!priv->dnld_sent && !priv->cur_cmd)
|
||||
lbs_execute_next_command(priv);
|
||||
|
||||
/* Wake-up command waiters which can't sleep in
|
||||
* lbs_prepare_and_send_command
|
||||
*/
|
||||
if (!list_empty(&priv->cmdpendingq))
|
||||
wake_up_all(&priv->cmd_pending);
|
||||
|
||||
spin_lock_irq(&priv->driver_lock);
|
||||
if (!priv->dnld_sent && priv->tx_pending_len > 0) {
|
||||
int ret = priv->hw_host_to_card(priv, MVMS_DAT,
|
||||
@ -538,7 +527,6 @@ static int lbs_thread(void *data)
|
||||
|
||||
del_timer(&priv->command_timer);
|
||||
del_timer(&priv->auto_deepsleep_timer);
|
||||
wake_up_all(&priv->cmd_pending);
|
||||
|
||||
lbs_deb_leave(LBS_DEB_THREAD);
|
||||
return 0;
|
||||
@ -663,7 +651,6 @@ out:
|
||||
static void auto_deepsleep_timer_fn(unsigned long data)
|
||||
{
|
||||
struct lbs_private *priv = (struct lbs_private *)data;
|
||||
int ret;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
@ -671,14 +658,15 @@ static void auto_deepsleep_timer_fn(unsigned long data)
|
||||
priv->is_activity_detected = 0;
|
||||
} else {
|
||||
if (priv->is_auto_deep_sleep_enabled &&
|
||||
(!priv->wakeup_dev_required) &&
|
||||
(priv->connect_status != LBS_CONNECTED)) {
|
||||
(!priv->wakeup_dev_required) &&
|
||||
(priv->connect_status != LBS_CONNECTED)) {
|
||||
struct cmd_header cmd;
|
||||
|
||||
lbs_deb_main("Entering auto deep sleep mode...\n");
|
||||
ret = lbs_prepare_and_send_command(priv,
|
||||
CMD_802_11_DEEP_SLEEP, 0,
|
||||
0, 0, NULL);
|
||||
if (ret)
|
||||
lbs_pr_err("Enter Deep Sleep command failed\n");
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.size = cpu_to_le16(sizeof(cmd));
|
||||
lbs_cmd_async(priv, CMD_802_11_DEEP_SLEEP, &cmd,
|
||||
sizeof(cmd));
|
||||
}
|
||||
}
|
||||
mod_timer(&priv->auto_deepsleep_timer , jiffies +
|
||||
@ -746,7 +734,6 @@ static int lbs_init_adapter(struct lbs_private *priv)
|
||||
INIT_LIST_HEAD(&priv->cmdpendingq);
|
||||
|
||||
spin_lock_init(&priv->driver_lock);
|
||||
init_waitqueue_head(&priv->cmd_pending);
|
||||
|
||||
/* Allocate the command buffers */
|
||||
if (lbs_allocate_cmd_buffer(priv)) {
|
||||
@ -902,7 +889,7 @@ void lbs_remove_card(struct lbs_private *priv)
|
||||
|
||||
if (priv->psmode == LBS802_11POWERMODEMAX_PSP) {
|
||||
priv->psmode = LBS802_11POWERMODECAM;
|
||||
lbs_ps_wakeup(priv, CMD_OPTION_WAITFORRSP);
|
||||
lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true);
|
||||
}
|
||||
|
||||
if (priv->is_deep_sleep) {
|
||||
@ -1065,7 +1052,7 @@ static int __init lbs_init_module(void)
|
||||
memset(&confirm_sleep, 0, sizeof(confirm_sleep));
|
||||
confirm_sleep.hdr.command = cpu_to_le16(CMD_802_11_PS_MODE);
|
||||
confirm_sleep.hdr.size = cpu_to_le16(sizeof(confirm_sleep));
|
||||
confirm_sleep.action = cpu_to_le16(CMD_SUBCMD_SLEEP_CONFIRMED);
|
||||
confirm_sleep.action = cpu_to_le16(PS_MODE_ACTION_SLEEP_CONFIRMED);
|
||||
lbs_debugfs_init();
|
||||
lbs_deb_leave(LBS_DEB_MAIN);
|
||||
return 0;
|
||||
|
@ -455,65 +455,189 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
|
||||
* Mesh command handling
|
||||
*/
|
||||
|
||||
int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
|
||||
u16 cmd_action, void *pdata_buf)
|
||||
/**
|
||||
* @brief Add or delete Mesh Blinding Table entries
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param add TRUE to add the entry, FALSE to delete it
|
||||
* @param addr1 Destination address to blind or unblind
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1)
|
||||
{
|
||||
struct cmd_ds_bt_access *bt_access = &cmd->params.bt;
|
||||
lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
|
||||
struct cmd_ds_bt_access cmd;
|
||||
int ret = 0;
|
||||
|
||||
cmd->command = cpu_to_le16(CMD_BT_ACCESS);
|
||||
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_bt_access) +
|
||||
sizeof(struct cmd_header));
|
||||
cmd->result = 0;
|
||||
bt_access->action = cpu_to_le16(cmd_action);
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
switch (cmd_action) {
|
||||
case CMD_ACT_BT_ACCESS_ADD:
|
||||
memcpy(bt_access->addr1, pdata_buf, 2 * ETH_ALEN);
|
||||
BUG_ON(addr1 == NULL);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
memcpy(cmd.addr1, addr1, ETH_ALEN);
|
||||
if (add) {
|
||||
cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_ADD);
|
||||
lbs_deb_hex(LBS_DEB_MESH, "BT_ADD: blinded MAC addr",
|
||||
bt_access->addr1, 6);
|
||||
break;
|
||||
case CMD_ACT_BT_ACCESS_DEL:
|
||||
memcpy(bt_access->addr1, pdata_buf, 1 * ETH_ALEN);
|
||||
addr1, ETH_ALEN);
|
||||
} else {
|
||||
cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_DEL);
|
||||
lbs_deb_hex(LBS_DEB_MESH, "BT_DEL: blinded MAC addr",
|
||||
bt_access->addr1, 6);
|
||||
break;
|
||||
case CMD_ACT_BT_ACCESS_LIST:
|
||||
bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
|
||||
break;
|
||||
case CMD_ACT_BT_ACCESS_RESET:
|
||||
break;
|
||||
case CMD_ACT_BT_ACCESS_SET_INVERT:
|
||||
bt_access->id = cpu_to_le32(*(u32 *) pdata_buf);
|
||||
break;
|
||||
case CMD_ACT_BT_ACCESS_GET_INVERT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
addr1, ETH_ALEN);
|
||||
}
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
return 0;
|
||||
|
||||
ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
|
||||
u16 cmd_action, void *pdata_buf)
|
||||
/**
|
||||
* @brief Reset/clear the mesh blinding table
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_reset(struct lbs_private *priv)
|
||||
{
|
||||
struct cmd_ds_fwt_access *fwt_access = &cmd->params.fwt;
|
||||
struct cmd_ds_bt_access cmd;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_RESET);
|
||||
|
||||
ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Gets the inverted status of the mesh blinding table
|
||||
*
|
||||
* Normally the firmware "blinds" or ignores traffic from mesh nodes in the
|
||||
* table, but an inverted table allows *only* traffic from nodes listed in
|
||||
* the table.
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param invert On success, TRUE if the blinding table is inverted,
|
||||
* FALSE if it is not inverted
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted)
|
||||
{
|
||||
struct cmd_ds_bt_access cmd;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
BUG_ON(inverted == NULL);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_GET_INVERT);
|
||||
|
||||
ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
|
||||
if (ret == 0)
|
||||
*inverted = !!cmd.id;
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sets the inverted status of the mesh blinding table
|
||||
*
|
||||
* Normally the firmware "blinds" or ignores traffic from mesh nodes in the
|
||||
* table, but an inverted table allows *only* traffic from nodes listed in
|
||||
* the table.
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param invert TRUE to invert the blinding table (only traffic from
|
||||
* listed nodes allowed), FALSE to return it
|
||||
* to normal state (listed nodes ignored)
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted)
|
||||
{
|
||||
struct cmd_ds_bt_access cmd;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT);
|
||||
cmd.id = !!inverted;
|
||||
|
||||
ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief List an entry in the mesh blinding table
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param id The ID of the entry to list
|
||||
* @param addr1 MAC address associated with the table entry
|
||||
*
|
||||
* @return 0 on success, error on failure
|
||||
*/
|
||||
int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1)
|
||||
{
|
||||
struct cmd_ds_bt_access cmd;
|
||||
int ret = 0;
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CMD);
|
||||
|
||||
BUG_ON(addr1 == NULL);
|
||||
|
||||
memset(&cmd, 0, sizeof(cmd));
|
||||
cmd.hdr.size = cpu_to_le16(sizeof(cmd));
|
||||
cmd.action = cpu_to_le16(CMD_ACT_BT_ACCESS_SET_INVERT);
|
||||
cmd.id = cpu_to_le32(id);
|
||||
|
||||
ret = lbs_cmd_with_response(priv, CMD_BT_ACCESS, &cmd);
|
||||
if (ret == 0)
|
||||
memcpy(addr1, cmd.addr1, sizeof(cmd.addr1));
|
||||
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Access the mesh forwarding table
|
||||
*
|
||||
* @param priv A pointer to struct lbs_private structure
|
||||
* @param cmd_action The forwarding table action to perform
|
||||
* @param cmd The pre-filled FWT_ACCESS command
|
||||
*
|
||||
* @return 0 on success and 'cmd' will be filled with the
|
||||
* firmware's response
|
||||
*/
|
||||
int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action,
|
||||
struct cmd_ds_fwt_access *cmd)
|
||||
{
|
||||
int ret;
|
||||
|
||||
lbs_deb_enter_args(LBS_DEB_CMD, "action %d", cmd_action);
|
||||
|
||||
cmd->command = cpu_to_le16(CMD_FWT_ACCESS);
|
||||
cmd->size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access) +
|
||||
sizeof(struct cmd_header));
|
||||
cmd->result = 0;
|
||||
cmd->hdr.command = cpu_to_le16(CMD_FWT_ACCESS);
|
||||
cmd->hdr.size = cpu_to_le16(sizeof(struct cmd_ds_fwt_access));
|
||||
cmd->hdr.result = 0;
|
||||
cmd->action = cpu_to_le16(cmd_action);
|
||||
|
||||
if (pdata_buf)
|
||||
memcpy(fwt_access, pdata_buf, sizeof(*fwt_access));
|
||||
else
|
||||
memset(fwt_access, 0, sizeof(*fwt_access));
|
||||
ret = lbs_cmd_with_response(priv, CMD_FWT_ACCESS, cmd);
|
||||
|
||||
fwt_access->action = cpu_to_le16(cmd_action);
|
||||
|
||||
lbs_deb_leave(LBS_DEB_CMD);
|
||||
lbs_deb_leave_args(LBS_DEB_CMD, "ret %d", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <net/iw_handler.h>
|
||||
#include <net/lib80211.h>
|
||||
|
||||
#include "host.h"
|
||||
|
||||
#ifdef CONFIG_LIBERTAS_MESH
|
||||
|
||||
@ -51,10 +52,15 @@ struct cmd_ds_command;
|
||||
struct cmd_ds_mesh_access;
|
||||
struct cmd_ds_mesh_config;
|
||||
|
||||
int lbs_cmd_bt_access(struct cmd_ds_command *cmd,
|
||||
u16 cmd_action, void *pdata_buf);
|
||||
int lbs_cmd_fwt_access(struct cmd_ds_command *cmd,
|
||||
u16 cmd_action, void *pdata_buf);
|
||||
int lbs_mesh_bt_add_del(struct lbs_private *priv, bool add, u8 *addr1);
|
||||
int lbs_mesh_bt_reset(struct lbs_private *priv);
|
||||
int lbs_mesh_bt_get_inverted(struct lbs_private *priv, bool *inverted);
|
||||
int lbs_mesh_bt_set_inverted(struct lbs_private *priv, bool inverted);
|
||||
int lbs_mesh_bt_get_entry(struct lbs_private *priv, u32 id, u8 *addr1);
|
||||
|
||||
int lbs_cmd_fwt_access(struct lbs_private *priv, u16 cmd_action,
|
||||
struct cmd_ds_fwt_access *cmd);
|
||||
|
||||
int lbs_mesh_access(struct lbs_private *priv, uint16_t cmd_action,
|
||||
struct cmd_ds_mesh_access *cmd);
|
||||
int lbs_mesh_config_send(struct lbs_private *priv,
|
||||
|
@ -180,7 +180,7 @@ void lbs_send_tx_feedback(struct lbs_private *priv, u32 try_count)
|
||||
{
|
||||
struct tx_radiotap_hdr *radiotap_hdr;
|
||||
|
||||
if (!priv->wdev->iftype == NL80211_IFTYPE_MONITOR ||
|
||||
if (priv->wdev->iftype != NL80211_IFTYPE_MONITOR ||
|
||||
priv->currenttxskb == NULL)
|
||||
return;
|
||||
|
||||
|
@ -253,6 +253,9 @@ struct lbtf_private {
|
||||
u8 fw_ready;
|
||||
u8 surpriseremoved;
|
||||
struct sk_buff_head bc_ps_buf;
|
||||
|
||||
/* Most recently reported noise in dBm */
|
||||
s8 noise;
|
||||
};
|
||||
|
||||
/* 802.11-related definitions */
|
||||
|
@ -525,6 +525,22 @@ static void lbtf_op_bss_info_changed(struct ieee80211_hw *hw,
|
||||
lbtf_deb_leave(LBTF_DEB_MACOPS);
|
||||
}
|
||||
|
||||
static int lbtf_op_get_survey(struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey)
|
||||
{
|
||||
struct lbtf_private *priv = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
|
||||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
|
||||
survey->channel = conf->channel;
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = priv->noise;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops lbtf_ops = {
|
||||
.tx = lbtf_op_tx,
|
||||
.start = lbtf_op_start,
|
||||
@ -535,6 +551,7 @@ static const struct ieee80211_ops lbtf_ops = {
|
||||
.prepare_multicast = lbtf_op_prepare_multicast,
|
||||
.configure_filter = lbtf_op_configure_filter,
|
||||
.bss_info_changed = lbtf_op_bss_info_changed,
|
||||
.get_survey = lbtf_op_get_survey,
|
||||
};
|
||||
|
||||
int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
|
||||
@ -555,6 +572,7 @@ int lbtf_rx(struct lbtf_private *priv, struct sk_buff *skb)
|
||||
stats.freq = priv->cur_freq;
|
||||
stats.band = IEEE80211_BAND_2GHZ;
|
||||
stats.signal = prxpd->snr;
|
||||
priv->noise = prxpd->nf;
|
||||
/* Marvell rate index has a hole at value 4 */
|
||||
if (prxpd->rx_rate > 4)
|
||||
--prxpd->rx_rate;
|
||||
|
@ -486,8 +486,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
|
||||
struct ieee80211_rx_status rx_status;
|
||||
|
||||
if (data->idle) {
|
||||
printk(KERN_DEBUG "%s: Trying to TX when idle - reject\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_debug(hw->wiphy, "trying to tx when idle - reject\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -576,7 +575,7 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
static int mac80211_hwsim_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct mac80211_hwsim_data *data = hw->priv;
|
||||
printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
|
||||
wiphy_debug(hw->wiphy, "%s\n", __func__);
|
||||
data->started = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -587,16 +586,15 @@ static void mac80211_hwsim_stop(struct ieee80211_hw *hw)
|
||||
struct mac80211_hwsim_data *data = hw->priv;
|
||||
data->started = 0;
|
||||
del_timer(&data->beacon_timer);
|
||||
printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
|
||||
wiphy_debug(hw->wiphy, "%s\n", __func__);
|
||||
}
|
||||
|
||||
|
||||
static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
|
||||
wiphy_name(hw->wiphy), __func__, vif->type,
|
||||
vif->addr);
|
||||
wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
|
||||
__func__, vif->type, vif->addr);
|
||||
hwsim_set_magic(vif);
|
||||
return 0;
|
||||
}
|
||||
@ -605,9 +603,8 @@ static int mac80211_hwsim_add_interface(struct ieee80211_hw *hw,
|
||||
static void mac80211_hwsim_remove_interface(
|
||||
struct ieee80211_hw *hw, struct ieee80211_vif *vif)
|
||||
{
|
||||
printk(KERN_DEBUG "%s:%s (type=%d mac_addr=%pM)\n",
|
||||
wiphy_name(hw->wiphy), __func__, vif->type,
|
||||
vif->addr);
|
||||
wiphy_debug(hw->wiphy, "%s (type=%d mac_addr=%pM)\n",
|
||||
__func__, vif->type, vif->addr);
|
||||
hwsim_check_magic(vif);
|
||||
hwsim_clear_magic(vif);
|
||||
}
|
||||
@ -670,13 +667,14 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
|
||||
[IEEE80211_SMPS_DYNAMIC] = "dynamic",
|
||||
};
|
||||
|
||||
printk(KERN_DEBUG "%s:%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
|
||||
wiphy_name(hw->wiphy), __func__,
|
||||
conf->channel->center_freq,
|
||||
hwsim_chantypes[conf->channel_type],
|
||||
!!(conf->flags & IEEE80211_CONF_IDLE),
|
||||
!!(conf->flags & IEEE80211_CONF_PS),
|
||||
smps_modes[conf->smps_mode]);
|
||||
wiphy_debug(hw->wiphy,
|
||||
"%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
|
||||
__func__,
|
||||
conf->channel->center_freq,
|
||||
hwsim_chantypes[conf->channel_type],
|
||||
!!(conf->flags & IEEE80211_CONF_IDLE),
|
||||
!!(conf->flags & IEEE80211_CONF_PS),
|
||||
smps_modes[conf->smps_mode]);
|
||||
|
||||
data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
|
||||
|
||||
@ -696,7 +694,7 @@ static void mac80211_hwsim_configure_filter(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct mac80211_hwsim_data *data = hw->priv;
|
||||
|
||||
printk(KERN_DEBUG "%s:%s\n", wiphy_name(hw->wiphy), __func__);
|
||||
wiphy_debug(hw->wiphy, "%s\n", __func__);
|
||||
|
||||
data->rx_filter = 0;
|
||||
if (*total_flags & FIF_PROMISC_IN_BSS)
|
||||
@ -717,26 +715,23 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
|
||||
|
||||
hwsim_check_magic(vif);
|
||||
|
||||
printk(KERN_DEBUG "%s:%s(changed=0x%x)\n",
|
||||
wiphy_name(hw->wiphy), __func__, changed);
|
||||
wiphy_debug(hw->wiphy, "%s(changed=0x%x)\n", __func__, changed);
|
||||
|
||||
if (changed & BSS_CHANGED_BSSID) {
|
||||
printk(KERN_DEBUG "%s:%s: BSSID changed: %pM\n",
|
||||
wiphy_name(hw->wiphy), __func__,
|
||||
info->bssid);
|
||||
wiphy_debug(hw->wiphy, "%s: BSSID changed: %pM\n",
|
||||
__func__, info->bssid);
|
||||
memcpy(vp->bssid, info->bssid, ETH_ALEN);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ASSOC) {
|
||||
printk(KERN_DEBUG " %s: ASSOC: assoc=%d aid=%d\n",
|
||||
wiphy_name(hw->wiphy), info->assoc, info->aid);
|
||||
wiphy_debug(hw->wiphy, " ASSOC: assoc=%d aid=%d\n",
|
||||
info->assoc, info->aid);
|
||||
vp->assoc = info->assoc;
|
||||
vp->aid = info->aid;
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BEACON_INT) {
|
||||
printk(KERN_DEBUG " %s: BCNINT: %d\n",
|
||||
wiphy_name(hw->wiphy), info->beacon_int);
|
||||
wiphy_debug(hw->wiphy, " BCNINT: %d\n", info->beacon_int);
|
||||
data->beacon_int = 1024 * info->beacon_int / 1000 * HZ / 1000;
|
||||
if (WARN_ON(!data->beacon_int))
|
||||
data->beacon_int = 1;
|
||||
@ -746,31 +741,28 @@ static void mac80211_hwsim_bss_info_changed(struct ieee80211_hw *hw,
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_CTS_PROT) {
|
||||
printk(KERN_DEBUG " %s: ERP_CTS_PROT: %d\n",
|
||||
wiphy_name(hw->wiphy), info->use_cts_prot);
|
||||
wiphy_debug(hw->wiphy, " ERP_CTS_PROT: %d\n",
|
||||
info->use_cts_prot);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_PREAMBLE) {
|
||||
printk(KERN_DEBUG " %s: ERP_PREAMBLE: %d\n",
|
||||
wiphy_name(hw->wiphy), info->use_short_preamble);
|
||||
wiphy_debug(hw->wiphy, " ERP_PREAMBLE: %d\n",
|
||||
info->use_short_preamble);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_ERP_SLOT) {
|
||||
printk(KERN_DEBUG " %s: ERP_SLOT: %d\n",
|
||||
wiphy_name(hw->wiphy), info->use_short_slot);
|
||||
wiphy_debug(hw->wiphy, " ERP_SLOT: %d\n", info->use_short_slot);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_HT) {
|
||||
printk(KERN_DEBUG " %s: HT: op_mode=0x%x, chantype=%s\n",
|
||||
wiphy_name(hw->wiphy),
|
||||
info->ht_operation_mode,
|
||||
hwsim_chantypes[info->channel_type]);
|
||||
wiphy_debug(hw->wiphy, " HT: op_mode=0x%x, chantype=%s\n",
|
||||
info->ht_operation_mode,
|
||||
hwsim_chantypes[info->channel_type]);
|
||||
}
|
||||
|
||||
if (changed & BSS_CHANGED_BASIC_RATES) {
|
||||
printk(KERN_DEBUG " %s: BASIC_RATES: 0x%llx\n",
|
||||
wiphy_name(hw->wiphy),
|
||||
(unsigned long long) info->basic_rates);
|
||||
wiphy_debug(hw->wiphy, " BASIC_RATES: 0x%llx\n",
|
||||
(unsigned long long) info->basic_rates);
|
||||
}
|
||||
}
|
||||
|
||||
@ -824,10 +816,11 @@ static int mac80211_hwsim_conf_tx(
|
||||
struct ieee80211_hw *hw, u16 queue,
|
||||
const struct ieee80211_tx_queue_params *params)
|
||||
{
|
||||
printk(KERN_DEBUG "%s:%s (queue=%d txop=%d cw_min=%d cw_max=%d "
|
||||
"aifs=%d)\n",
|
||||
wiphy_name(hw->wiphy), __func__, queue,
|
||||
params->txop, params->cw_min, params->cw_max, params->aifs);
|
||||
wiphy_debug(hw->wiphy,
|
||||
"%s (queue=%d txop=%d cw_min=%d cw_max=%d aifs=%d)\n",
|
||||
__func__, queue,
|
||||
params->txop, params->cw_min,
|
||||
params->cw_max, params->aifs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -837,8 +830,7 @@ static int mac80211_hwsim_get_survey(
|
||||
{
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
|
||||
printk(KERN_DEBUG "%s:%s (idx=%d)\n",
|
||||
wiphy_name(hw->wiphy), __func__, idx);
|
||||
wiphy_debug(hw->wiphy, "%s (idx=%d)\n", __func__, idx);
|
||||
|
||||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
@ -1108,8 +1100,9 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
|
||||
if (!vp->assoc)
|
||||
return;
|
||||
|
||||
printk(KERN_DEBUG "%s:%s: send PS-Poll to %pM for aid %d\n",
|
||||
wiphy_name(data->hw->wiphy), __func__, vp->bssid, vp->aid);
|
||||
wiphy_debug(data->hw->wiphy,
|
||||
"%s: send PS-Poll to %pM for aid %d\n",
|
||||
__func__, vp->bssid, vp->aid);
|
||||
|
||||
skb = dev_alloc_skb(sizeof(*pspoll));
|
||||
if (!skb)
|
||||
@ -1137,8 +1130,9 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
|
||||
if (!vp->assoc)
|
||||
return;
|
||||
|
||||
printk(KERN_DEBUG "%s:%s: send data::nullfunc to %pM ps=%d\n",
|
||||
wiphy_name(data->hw->wiphy), __func__, vp->bssid, ps);
|
||||
wiphy_debug(data->hw->wiphy,
|
||||
"%s: send data::nullfunc to %pM ps=%d\n",
|
||||
__func__, vp->bssid, ps);
|
||||
|
||||
skb = dev_alloc_skb(sizeof(*hdr));
|
||||
if (!skb)
|
||||
@ -1473,9 +1467,8 @@ static int __init init_mac80211_hwsim(void)
|
||||
break;
|
||||
}
|
||||
|
||||
printk(KERN_DEBUG "%s: hwaddr %pM registered\n",
|
||||
wiphy_name(hw->wiphy),
|
||||
hw->wiphy->perm_addr);
|
||||
wiphy_debug(hw->wiphy, "hwaddr %pm registered\n",
|
||||
hw->wiphy->perm_addr);
|
||||
|
||||
data->debugfs = debugfs_create_dir("hwsim",
|
||||
hw->wiphy->debugfsdir);
|
||||
|
@ -86,7 +86,7 @@ struct rxd_ops {
|
||||
void (*rxd_init)(void *rxd, dma_addr_t next_dma_addr);
|
||||
void (*rxd_refill)(void *rxd, dma_addr_t addr, int len);
|
||||
int (*rxd_process)(void *rxd, struct ieee80211_rx_status *status,
|
||||
__le16 *qos);
|
||||
__le16 *qos, s8 *noise);
|
||||
};
|
||||
|
||||
struct mwl8k_device_info {
|
||||
@ -207,6 +207,9 @@ struct mwl8k_priv {
|
||||
|
||||
/* Tasklet to perform RX. */
|
||||
struct tasklet_struct poll_rx_task;
|
||||
|
||||
/* Most recently reported noise in dBm */
|
||||
s8 noise;
|
||||
};
|
||||
|
||||
/* Per interface specific private data */
|
||||
@ -741,7 +744,7 @@ static void mwl8k_rxd_8366_ap_refill(void *_rxd, dma_addr_t addr, int len)
|
||||
|
||||
static int
|
||||
mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
|
||||
__le16 *qos)
|
||||
__le16 *qos, s8 *noise)
|
||||
{
|
||||
struct mwl8k_rxd_8366_ap *rxd = _rxd;
|
||||
|
||||
@ -752,6 +755,7 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
|
||||
memset(status, 0, sizeof(*status));
|
||||
|
||||
status->signal = -rxd->rssi;
|
||||
*noise = -rxd->noise_floor;
|
||||
|
||||
if (rxd->rate & MWL8K_8366_AP_RATE_INFO_MCS_FORMAT) {
|
||||
status->flag |= RX_FLAG_HT;
|
||||
@ -839,7 +843,7 @@ static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len)
|
||||
|
||||
static int
|
||||
mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
|
||||
__le16 *qos)
|
||||
__le16 *qos, s8 *noise)
|
||||
{
|
||||
struct mwl8k_rxd_sta *rxd = _rxd;
|
||||
u16 rate_info;
|
||||
@ -853,6 +857,7 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
|
||||
memset(status, 0, sizeof(*status));
|
||||
|
||||
status->signal = -rxd->rssi;
|
||||
*noise = -rxd->noise_level;
|
||||
status->antenna = MWL8K_STA_RATE_INFO_ANTSELECT(rate_info);
|
||||
status->rate_idx = MWL8K_STA_RATE_INFO_RATEID(rate_info);
|
||||
|
||||
@ -905,16 +910,14 @@ static int mwl8k_rxq_init(struct ieee80211_hw *hw, int index)
|
||||
|
||||
rxq->rxd = pci_alloc_consistent(priv->pdev, size, &rxq->rxd_dma);
|
||||
if (rxq->rxd == NULL) {
|
||||
printk(KERN_ERR "%s: failed to alloc RX descriptors\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "failed to alloc rx descriptors\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(rxq->rxd, 0, size);
|
||||
|
||||
rxq->buf = kmalloc(MWL8K_RX_DESCS * sizeof(*rxq->buf), GFP_KERNEL);
|
||||
if (rxq->buf == NULL) {
|
||||
printk(KERN_ERR "%s: failed to alloc RX skbuff list\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "failed to alloc rx skbuff list\n");
|
||||
pci_free_consistent(priv->pdev, size, rxq->rxd, rxq->rxd_dma);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -1055,7 +1058,8 @@ static int rxq_process(struct ieee80211_hw *hw, int index, int limit)
|
||||
|
||||
rxd = rxq->rxd + (rxq->head * priv->rxd_ops->rxd_size);
|
||||
|
||||
pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos);
|
||||
pkt_len = priv->rxd_ops->rxd_process(rxd, &status, &qos,
|
||||
&priv->noise);
|
||||
if (pkt_len < 0)
|
||||
break;
|
||||
|
||||
@ -1141,16 +1145,14 @@ static int mwl8k_txq_init(struct ieee80211_hw *hw, int index)
|
||||
|
||||
txq->txd = pci_alloc_consistent(priv->pdev, size, &txq->txd_dma);
|
||||
if (txq->txd == NULL) {
|
||||
printk(KERN_ERR "%s: failed to alloc TX descriptors\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "failed to alloc tx descriptors\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
memset(txq->txd, 0, size);
|
||||
|
||||
txq->skb = kmalloc(MWL8K_TX_DESCS * sizeof(*txq->skb), GFP_KERNEL);
|
||||
if (txq->skb == NULL) {
|
||||
printk(KERN_ERR "%s: failed to alloc TX skbuff list\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "failed to alloc tx skbuff list\n");
|
||||
pci_free_consistent(priv->pdev, size, txq->txd, txq->txd_dma);
|
||||
return -ENOMEM;
|
||||
}
|
||||
@ -1206,11 +1208,12 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
|
||||
unused++;
|
||||
}
|
||||
|
||||
printk(KERN_ERR "%s: txq[%d] len=%d head=%d tail=%d "
|
||||
"fw_owned=%d drv_owned=%d unused=%d\n",
|
||||
wiphy_name(hw->wiphy), i,
|
||||
txq->len, txq->head, txq->tail,
|
||||
fw_owned, drv_owned, unused);
|
||||
wiphy_err(hw->wiphy,
|
||||
"txq[%d] len=%d head=%d tail=%d "
|
||||
"fw_owned=%d drv_owned=%d unused=%d\n",
|
||||
i,
|
||||
txq->len, txq->head, txq->tail,
|
||||
fw_owned, drv_owned, unused);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1254,25 +1257,23 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
|
||||
if (timeout) {
|
||||
WARN_ON(priv->pending_tx_pkts);
|
||||
if (retry) {
|
||||
printk(KERN_NOTICE "%s: tx rings drained\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_notice(hw->wiphy, "tx rings drained\n");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (priv->pending_tx_pkts < oldcount) {
|
||||
printk(KERN_NOTICE "%s: waiting for tx rings "
|
||||
"to drain (%d -> %d pkts)\n",
|
||||
wiphy_name(hw->wiphy), oldcount,
|
||||
priv->pending_tx_pkts);
|
||||
wiphy_notice(hw->wiphy,
|
||||
"waiting for tx rings to drain (%d -> %d pkts)\n",
|
||||
oldcount, priv->pending_tx_pkts);
|
||||
retry = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
priv->tx_wait = NULL;
|
||||
|
||||
printk(KERN_ERR "%s: tx rings stuck for %d ms\n",
|
||||
wiphy_name(hw->wiphy), MWL8K_TX_WAIT_TIMEOUT_MS);
|
||||
wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n",
|
||||
MWL8K_TX_WAIT_TIMEOUT_MS);
|
||||
mwl8k_dump_tx_rings(hw);
|
||||
|
||||
rc = -ETIMEDOUT;
|
||||
@ -1423,8 +1424,8 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
|
||||
skb->len, PCI_DMA_TODEVICE);
|
||||
|
||||
if (pci_dma_mapping_error(priv->pdev, dma)) {
|
||||
printk(KERN_DEBUG "%s: failed to dma map skb, "
|
||||
"dropping TX frame.\n", wiphy_name(hw->wiphy));
|
||||
wiphy_debug(hw->wiphy,
|
||||
"failed to dma map skb, dropping TX frame.\n");
|
||||
dev_kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
@ -1572,10 +1573,9 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
|
||||
PCI_DMA_BIDIRECTIONAL);
|
||||
|
||||
if (!timeout) {
|
||||
printk(KERN_ERR "%s: Command %s timeout after %u ms\n",
|
||||
wiphy_name(hw->wiphy),
|
||||
mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
|
||||
MWL8K_CMD_TIMEOUT_MS);
|
||||
wiphy_err(hw->wiphy, "command %s timeout after %u ms\n",
|
||||
mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
|
||||
MWL8K_CMD_TIMEOUT_MS);
|
||||
rc = -ETIMEDOUT;
|
||||
} else {
|
||||
int ms;
|
||||
@ -1584,15 +1584,14 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
|
||||
|
||||
rc = cmd->result ? -EINVAL : 0;
|
||||
if (rc)
|
||||
printk(KERN_ERR "%s: Command %s error 0x%x\n",
|
||||
wiphy_name(hw->wiphy),
|
||||
mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
|
||||
le16_to_cpu(cmd->result));
|
||||
wiphy_err(hw->wiphy, "command %s error 0x%x\n",
|
||||
mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
|
||||
le16_to_cpu(cmd->result));
|
||||
else if (ms > 2000)
|
||||
printk(KERN_NOTICE "%s: Command %s took %d ms\n",
|
||||
wiphy_name(hw->wiphy),
|
||||
mwl8k_cmd_name(cmd->code, buf, sizeof(buf)),
|
||||
ms);
|
||||
wiphy_notice(hw->wiphy, "command %s took %d ms\n",
|
||||
mwl8k_cmd_name(cmd->code,
|
||||
buf, sizeof(buf)),
|
||||
ms);
|
||||
}
|
||||
|
||||
return rc;
|
||||
@ -3192,8 +3191,8 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
|
||||
int rc;
|
||||
|
||||
if (!priv->radio_on) {
|
||||
printk(KERN_DEBUG "%s: dropped TX frame since radio "
|
||||
"disabled\n", wiphy_name(hw->wiphy));
|
||||
wiphy_debug(hw->wiphy,
|
||||
"dropped TX frame since radio disabled\n");
|
||||
dev_kfree_skb(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
@ -3211,8 +3210,7 @@ static int mwl8k_start(struct ieee80211_hw *hw)
|
||||
rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
|
||||
IRQF_SHARED, MWL8K_NAME, hw);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: failed to register IRQ handler\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "failed to register irq handler\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
@ -3299,9 +3297,8 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
|
||||
* mode. (Sniffer mode is only used on STA firmware.)
|
||||
*/
|
||||
if (priv->sniffer_enabled) {
|
||||
printk(KERN_INFO "%s: unable to create STA "
|
||||
"interface due to sniffer mode being enabled\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_info(hw->wiphy,
|
||||
"unable to create STA interface because sniffer mode is enabled\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -3583,9 +3580,8 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
|
||||
*/
|
||||
if (!list_empty(&priv->vif_list)) {
|
||||
if (net_ratelimit())
|
||||
printk(KERN_INFO "%s: not enabling sniffer "
|
||||
"mode because STA interface is active\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_info(hw->wiphy,
|
||||
"not enabling sniffer mode because STA interface is active\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3765,6 +3761,22 @@ static int mwl8k_get_stats(struct ieee80211_hw *hw,
|
||||
return mwl8k_cmd_get_stat(hw, stats);
|
||||
}
|
||||
|
||||
static int mwl8k_get_survey(struct ieee80211_hw *hw, int idx,
|
||||
struct survey_info *survey)
|
||||
{
|
||||
struct mwl8k_priv *priv = hw->priv;
|
||||
struct ieee80211_conf *conf = &hw->conf;
|
||||
|
||||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
|
||||
survey->channel = conf->channel;
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = priv->noise;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
|
||||
enum ieee80211_ampdu_mlme_action action,
|
||||
@ -3796,6 +3808,7 @@ static const struct ieee80211_ops mwl8k_ops = {
|
||||
.sta_remove = mwl8k_sta_remove,
|
||||
.conf_tx = mwl8k_conf_tx,
|
||||
.get_stats = mwl8k_get_stats,
|
||||
.get_survey = mwl8k_get_survey,
|
||||
.ampdu_action = mwl8k_ampdu_action,
|
||||
};
|
||||
|
||||
@ -3913,8 +3926,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||
|
||||
priv->sram = pci_iomap(pdev, 0, 0x10000);
|
||||
if (priv->sram == NULL) {
|
||||
printk(KERN_ERR "%s: Cannot map device SRAM\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "cannot map device sram\n");
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
@ -3926,8 +3938,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||
if (priv->regs == NULL) {
|
||||
priv->regs = pci_iomap(pdev, 2, 0x10000);
|
||||
if (priv->regs == NULL) {
|
||||
printk(KERN_ERR "%s: Cannot map device registers\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "cannot map device registers\n");
|
||||
goto err_iounmap;
|
||||
}
|
||||
}
|
||||
@ -3939,16 +3950,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||
/* Ask userland hotplug daemon for the device firmware */
|
||||
rc = mwl8k_request_firmware(priv);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Firmware files not found\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "firmware files not found\n");
|
||||
goto err_stop_firmware;
|
||||
}
|
||||
|
||||
/* Load firmware into hardware */
|
||||
rc = mwl8k_load_firmware(hw);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Cannot start firmware\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "cannot start firmware\n");
|
||||
goto err_stop_firmware;
|
||||
}
|
||||
|
||||
@ -3959,9 +3968,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||
if (priv->ap_fw) {
|
||||
priv->rxd_ops = priv->device_info->ap_rxd_ops;
|
||||
if (priv->rxd_ops == NULL) {
|
||||
printk(KERN_ERR "%s: Driver does not have AP "
|
||||
"firmware image support for this hardware\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy,
|
||||
"Driver does not have AP firmware image support for this hardware\n");
|
||||
goto err_stop_firmware;
|
||||
}
|
||||
} else {
|
||||
@ -4039,8 +4047,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||
rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
|
||||
IRQF_SHARED, MWL8K_NAME, hw);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: failed to register IRQ handler\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "failed to register irq handler\n");
|
||||
goto err_free_queues;
|
||||
}
|
||||
|
||||
@ -4060,8 +4067,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||
rc = mwl8k_cmd_get_hw_spec_sta(hw);
|
||||
}
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Cannot initialise firmware\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "cannot initialise firmware\n");
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
@ -4075,15 +4081,14 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||
/* Turn radio off */
|
||||
rc = mwl8k_cmd_radio_disable(hw);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Cannot disable\n", wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "cannot disable\n");
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
/* Clear MAC address */
|
||||
rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Cannot clear MAC address\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "cannot clear mac address\n");
|
||||
goto err_free_irq;
|
||||
}
|
||||
|
||||
@ -4093,17 +4098,16 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
|
||||
|
||||
rc = ieee80211_register_hw(hw);
|
||||
if (rc) {
|
||||
printk(KERN_ERR "%s: Cannot register device\n",
|
||||
wiphy_name(hw->wiphy));
|
||||
wiphy_err(hw->wiphy, "cannot register device\n");
|
||||
goto err_free_queues;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n",
|
||||
wiphy_name(hw->wiphy), priv->device_info->part_name,
|
||||
priv->hw_rev, hw->wiphy->perm_addr,
|
||||
priv->ap_fw ? "AP" : "STA",
|
||||
(priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
|
||||
(priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
|
||||
wiphy_info(hw->wiphy, "%s v%d, %pm, %s firmware %u.%u.%u.%u\n",
|
||||
priv->device_info->part_name,
|
||||
priv->hw_rev, hw->wiphy->perm_addr,
|
||||
priv->ap_fw ? "AP" : "STA",
|
||||
(priv->fw_rev >> 24) & 0xff, (priv->fw_rev >> 16) & 0xff,
|
||||
(priv->fw_rev >> 8) & 0xff, priv->fw_rev & 0xff);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -117,9 +117,8 @@ static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
case NL80211_IFTYPE_MONITOR:
|
||||
if (priv->broken_monitor && !force_monitor) {
|
||||
printk(KERN_WARNING "%s: Monitor mode support is "
|
||||
"buggy in this firmware, not enabling\n",
|
||||
wiphy_name(wiphy));
|
||||
wiphy_warn(wiphy,
|
||||
"Monitor mode support is buggy in this firmware, not enabling\n");
|
||||
err = -EINVAL;
|
||||
}
|
||||
break;
|
||||
|
@ -149,16 +149,15 @@ static int p54_generate_band(struct ieee80211_hw *dev,
|
||||
continue;
|
||||
|
||||
if (list->channels[i].data != CHAN_HAS_ALL) {
|
||||
printk(KERN_ERR "%s:%s%s%s is/are missing for "
|
||||
"channel:%d [%d MHz].\n",
|
||||
wiphy_name(dev->wiphy),
|
||||
(list->channels[i].data & CHAN_HAS_CAL ? "" :
|
||||
" [iqauto calibration data]"),
|
||||
(list->channels[i].data & CHAN_HAS_LIMIT ? "" :
|
||||
" [output power limits]"),
|
||||
(list->channels[i].data & CHAN_HAS_CURVE ? "" :
|
||||
" [curve data]"),
|
||||
list->channels[i].index, list->channels[i].freq);
|
||||
wiphy_err(dev->wiphy,
|
||||
"%s%s%s is/are missing for channel:%d [%d MHz].\n",
|
||||
(list->channels[i].data & CHAN_HAS_CAL ? "" :
|
||||
" [iqauto calibration data]"),
|
||||
(list->channels[i].data & CHAN_HAS_LIMIT ? "" :
|
||||
" [output power limits]"),
|
||||
(list->channels[i].data & CHAN_HAS_CURVE ? "" :
|
||||
" [curve data]"),
|
||||
list->channels[i].index, list->channels[i].freq);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -168,9 +167,8 @@ static int p54_generate_band(struct ieee80211_hw *dev,
|
||||
}
|
||||
|
||||
if (j == 0) {
|
||||
printk(KERN_ERR "%s: Disabling totally damaged %s band.\n",
|
||||
wiphy_name(dev->wiphy), (band == IEEE80211_BAND_2GHZ) ?
|
||||
"2 GHz" : "5 GHz");
|
||||
wiphy_err(dev->wiphy, "disabling totally damaged %d GHz band\n",
|
||||
(band == IEEE80211_BAND_2GHZ) ? 2 : 5);
|
||||
|
||||
ret = -ENODATA;
|
||||
goto err_out;
|
||||
@ -244,9 +242,9 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
|
||||
|
||||
if ((priv->iq_autocal_len != priv->curve_data->entries) ||
|
||||
(priv->iq_autocal_len != priv->output_limit->entries))
|
||||
printk(KERN_ERR "%s: Unsupported or damaged EEPROM detected. "
|
||||
"You may not be able to use all channels.\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy,
|
||||
"Unsupported or damaged EEPROM detected. "
|
||||
"You may not be able to use all channels.\n");
|
||||
|
||||
max_channel_num = max_t(unsigned int, priv->output_limit->entries,
|
||||
priv->iq_autocal_len);
|
||||
@ -419,15 +417,14 @@ static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len,
|
||||
int i;
|
||||
|
||||
if (len != (entry_size * num_entries)) {
|
||||
printk(KERN_ERR "%s: unknown rssi calibration data packing "
|
||||
" type:(%x) len:%d.\n",
|
||||
wiphy_name(dev->wiphy), type, len);
|
||||
wiphy_err(dev->wiphy,
|
||||
"unknown rssi calibration data packing type:(%x) len:%d.\n",
|
||||
type, len);
|
||||
|
||||
print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE,
|
||||
data, len);
|
||||
|
||||
printk(KERN_ERR "%s: please report this issue.\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "please report this issue.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -445,15 +442,14 @@ static void p54_parse_default_country(struct ieee80211_hw *dev,
|
||||
struct pda_country *country;
|
||||
|
||||
if (len != sizeof(*country)) {
|
||||
printk(KERN_ERR "%s: found possible invalid default country "
|
||||
"eeprom entry. (entry size: %d)\n",
|
||||
wiphy_name(dev->wiphy), len);
|
||||
wiphy_err(dev->wiphy,
|
||||
"found possible invalid default country eeprom entry. (entry size: %d)\n",
|
||||
len);
|
||||
|
||||
print_hex_dump_bytes("country:", DUMP_PREFIX_NONE,
|
||||
data, len);
|
||||
|
||||
printk(KERN_ERR "%s: please report this issue.\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "please report this issue.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -478,8 +474,8 @@ static int p54_convert_output_limits(struct ieee80211_hw *dev,
|
||||
return -EINVAL;
|
||||
|
||||
if (data[0] != 0) {
|
||||
printk(KERN_ERR "%s: unknown output power db revision:%x\n",
|
||||
wiphy_name(dev->wiphy), data[0]);
|
||||
wiphy_err(dev->wiphy, "unknown output power db revision:%x\n",
|
||||
data[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -587,10 +583,9 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
|
||||
err = p54_convert_rev1(dev, curve_data);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "%s: unknown curve data "
|
||||
"revision %d\n",
|
||||
wiphy_name(dev->wiphy),
|
||||
curve_data->cal_method_rev);
|
||||
wiphy_err(dev->wiphy,
|
||||
"unknown curve data revision %d\n",
|
||||
curve_data->cal_method_rev);
|
||||
err = -ENODEV;
|
||||
break;
|
||||
}
|
||||
@ -672,8 +667,8 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
|
||||
|
||||
if (!synth || !priv->iq_autocal || !priv->output_limit ||
|
||||
!priv->curve_data) {
|
||||
printk(KERN_ERR "%s: not all required entries found in eeprom!\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy,
|
||||
"not all required entries found in eeprom!\n");
|
||||
err = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
@ -699,15 +694,15 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
|
||||
if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
|
||||
u8 perm_addr[ETH_ALEN];
|
||||
|
||||
printk(KERN_WARNING "%s: Invalid hwaddr! Using randomly generated MAC addr\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_warn(dev->wiphy,
|
||||
"invalid hwaddr! using randomly generated mac addr\n");
|
||||
random_ether_addr(perm_addr);
|
||||
SET_IEEE80211_PERM_ADDR(dev, perm_addr);
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s: hwaddr %pM, MAC:isl38%02x RF:%s\n",
|
||||
wiphy_name(dev->wiphy), dev->wiphy->perm_addr, priv->version,
|
||||
p54_rf_chips[priv->rxhw]);
|
||||
wiphy_info(dev->wiphy, "hwaddr %pm, mac:isl38%02x rf:%s\n",
|
||||
dev->wiphy->perm_addr, priv->version,
|
||||
p54_rf_chips[priv->rxhw]);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -719,8 +714,7 @@ err:
|
||||
priv->output_limit = NULL;
|
||||
priv->curve_data = NULL;
|
||||
|
||||
printk(KERN_ERR "%s: eeprom parse failed!\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "eeprom parse failed!\n");
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(p54_parse_eeprom);
|
||||
|
@ -62,16 +62,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
|
||||
case FW_LM20:
|
||||
case FW_LM87: {
|
||||
char *iftype = (char *)bootrec->data;
|
||||
printk(KERN_INFO "%s: p54 detected a LM%c%c "
|
||||
"firmware\n",
|
||||
wiphy_name(priv->hw->wiphy),
|
||||
iftype[2], iftype[3]);
|
||||
wiphy_info(priv->hw->wiphy,
|
||||
"p54 detected a LM%c%c firmware\n",
|
||||
iftype[2], iftype[3]);
|
||||
break;
|
||||
}
|
||||
case FW_FMAC:
|
||||
default:
|
||||
printk(KERN_ERR "%s: unsupported firmware\n",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"unsupported firmware\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
break;
|
||||
@ -125,15 +124,15 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
|
||||
}
|
||||
|
||||
if (fw_version)
|
||||
printk(KERN_INFO "%s: FW rev %s - Softmac protocol %x.%x\n",
|
||||
wiphy_name(priv->hw->wiphy), fw_version,
|
||||
priv->fw_var >> 8, priv->fw_var & 0xff);
|
||||
wiphy_info(priv->hw->wiphy,
|
||||
"fw rev %s - softmac protocol %x.%x\n",
|
||||
fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
|
||||
|
||||
if (priv->fw_var < 0x500)
|
||||
printk(KERN_INFO "%s: you are using an obsolete firmware. "
|
||||
"visit http://wireless.kernel.org/en/users/Drivers/p54 "
|
||||
"and grab one for \"kernel >= 2.6.28\"!\n",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
wiphy_info(priv->hw->wiphy,
|
||||
"you are using an obsolete firmware. "
|
||||
"visit http://wireless.kernel.org/en/users/Drivers/p54 "
|
||||
"and grab one for \"kernel >= 2.6.28\"!\n");
|
||||
|
||||
if (priv->fw_var >= 0x300) {
|
||||
/* Firmware supports QoS, use it! */
|
||||
@ -152,13 +151,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
|
||||
priv->hw->queues = P54_QUEUE_AC_NUM;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s: cryptographic accelerator "
|
||||
"WEP:%s, TKIP:%s, CCMP:%s\n", wiphy_name(priv->hw->wiphy),
|
||||
(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" :
|
||||
"no", (priv->privacy_caps & (BR_DESC_PRIV_CAP_TKIP |
|
||||
BR_DESC_PRIV_CAP_MICHAEL)) ? "YES" : "no",
|
||||
(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP) ?
|
||||
"YES" : "no");
|
||||
wiphy_info(priv->hw->wiphy,
|
||||
"cryptographic accelerator WEP:%s, TKIP:%s, CCMP:%s\n",
|
||||
(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP) ? "YES" : "no",
|
||||
(priv->privacy_caps &
|
||||
(BR_DESC_PRIV_CAP_TKIP | BR_DESC_PRIV_CAP_MICHAEL))
|
||||
? "YES" : "no",
|
||||
(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)
|
||||
? "YES" : "no");
|
||||
|
||||
if (priv->rx_keycache_size) {
|
||||
/*
|
||||
@ -247,8 +247,7 @@ int p54_download_eeprom(struct p54_common *priv, void *buf,
|
||||
|
||||
if (!wait_for_completion_interruptible_timeout(
|
||||
&priv->eeprom_comp, HZ)) {
|
||||
printk(KERN_ERR "%s: device does not respond!\n",
|
||||
wiphy_name(priv->hw->wiphy));
|
||||
wiphy_err(priv->hw->wiphy, "device does not respond!\n");
|
||||
ret = -EBUSY;
|
||||
}
|
||||
priv->eeprom = NULL;
|
||||
@ -523,9 +522,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
|
||||
return 0;
|
||||
|
||||
err:
|
||||
printk(KERN_ERR "%s: frequency change to channel %d failed.\n",
|
||||
wiphy_name(priv->hw->wiphy), ieee80211_frequency_to_channel(
|
||||
priv->hw->conf.channel->center_freq));
|
||||
wiphy_err(priv->hw->wiphy, "frequency change to channel %d failed.\n",
|
||||
ieee80211_frequency_to_channel(
|
||||
priv->hw->conf.channel->center_freq));
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
return -EINVAL;
|
||||
@ -676,8 +675,8 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len,
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(KERN_ERR "%s: invalid cryptographic algorithm: %d\n",
|
||||
wiphy_name(priv->hw->wiphy), algo);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"invalid cryptographic algorithm: %d\n", algo);
|
||||
dev_kfree_skb(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -57,8 +57,8 @@ static void p54_update_leds(struct work_struct *work)
|
||||
|
||||
err = p54_set_leds(priv);
|
||||
if (err && net_ratelimit())
|
||||
printk(KERN_ERR "%s: failed to update LEDs (%d).\n",
|
||||
wiphy_name(priv->hw->wiphy), err);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"failed to update leds (%d).\n", err);
|
||||
|
||||
if (rerun)
|
||||
ieee80211_queue_delayed_work(priv->hw, &priv->led_work,
|
||||
@ -102,8 +102,8 @@ static int p54_register_led(struct p54_common *priv,
|
||||
|
||||
err = led_classdev_register(wiphy_dev(priv->hw->wiphy), &led->led_dev);
|
||||
if (err)
|
||||
printk(KERN_ERR "%s: Failed to register %s LED.\n",
|
||||
wiphy_name(priv->hw->wiphy), name);
|
||||
wiphy_err(priv->hw->wiphy,
|
||||
"failed to register %s led.\n", name);
|
||||
else
|
||||
led->registered = 1;
|
||||
|
||||
|
@ -507,6 +507,22 @@ out_unlock:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int p54_get_survey(struct ieee80211_hw *dev, int idx,
|
||||
struct survey_info *survey)
|
||||
{
|
||||
struct p54_common *priv = dev->priv;
|
||||
struct ieee80211_conf *conf = &dev->conf;
|
||||
|
||||
if (idx != 0)
|
||||
return -ENOENT;
|
||||
|
||||
survey->channel = conf->channel;
|
||||
survey->filled = SURVEY_INFO_NOISE_DBM;
|
||||
survey->noise = clamp_t(s8, priv->noise, -128, 127);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct ieee80211_ops p54_ops = {
|
||||
.tx = p54_tx_80211,
|
||||
.start = p54_start,
|
||||
@ -523,6 +539,7 @@ static const struct ieee80211_ops p54_ops = {
|
||||
.configure_filter = p54_configure_filter,
|
||||
.conf_tx = p54_conf_tx,
|
||||
.get_stats = p54_get_stats,
|
||||
.get_survey = p54_get_survey,
|
||||
};
|
||||
|
||||
struct ieee80211_hw *p54_init_common(size_t priv_data_len)
|
||||
|
@ -466,8 +466,7 @@ static int p54p_open(struct ieee80211_hw *dev)
|
||||
P54P_READ(dev_int);
|
||||
|
||||
if (!wait_for_completion_interruptible_timeout(&priv->boot_comp, HZ)) {
|
||||
printk(KERN_ERR "%s: Cannot boot firmware!\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "cannot boot firmware!\n");
|
||||
p54p_stop(dev);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
@ -38,8 +38,8 @@ static void p54_dump_tx_queue(struct p54_common *priv)
|
||||
u32 largest_hole = 0, free;
|
||||
|
||||
spin_lock_irqsave(&priv->tx_queue.lock, flags);
|
||||
printk(KERN_DEBUG "%s: / --- tx queue dump (%d entries) ---\n",
|
||||
wiphy_name(priv->hw->wiphy), skb_queue_len(&priv->tx_queue));
|
||||
wiphy_debug(priv->hw->wiphy, "/ --- tx queue dump (%d entries) ---\n",
|
||||
skb_queue_len(&priv->tx_queue));
|
||||
|
||||
prev_addr = priv->rx_start;
|
||||
skb_queue_walk(&priv->tx_queue, skb) {
|
||||
@ -48,21 +48,23 @@ static void p54_dump_tx_queue(struct p54_common *priv)
|
||||
hdr = (void *) skb->data;
|
||||
|
||||
free = range->start_addr - prev_addr;
|
||||
printk(KERN_DEBUG "%s: | [%02d] => [skb:%p skb_len:0x%04x "
|
||||
"hdr:{flags:%02x len:%04x req_id:%04x type:%02x} "
|
||||
"mem:{start:%04x end:%04x, free:%d}]\n",
|
||||
wiphy_name(priv->hw->wiphy), i++, skb, skb->len,
|
||||
le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len),
|
||||
le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type),
|
||||
range->start_addr, range->end_addr, free);
|
||||
wiphy_debug(priv->hw->wiphy,
|
||||
"| [%02d] => [skb:%p skb_len:0x%04x "
|
||||
"hdr:{flags:%02x len:%04x req_id:%04x type:%02x} "
|
||||
"mem:{start:%04x end:%04x, free:%d}]\n",
|
||||
i++, skb, skb->len,
|
||||
le16_to_cpu(hdr->flags), le16_to_cpu(hdr->len),
|
||||
le32_to_cpu(hdr->req_id), le16_to_cpu(hdr->type),
|
||||
range->start_addr, range->end_addr, free);
|
||||
|
||||
prev_addr = range->end_addr;
|
||||
largest_hole = max(largest_hole, free);
|
||||
}
|
||||
free = priv->rx_end - prev_addr;
|
||||
largest_hole = max(largest_hole, free);
|
||||
printk(KERN_DEBUG "%s: \\ --- [free: %d], largest free block: %d ---\n",
|
||||
wiphy_name(priv->hw->wiphy), free, largest_hole);
|
||||
wiphy_debug(priv->hw->wiphy,
|
||||
"\\ --- [free: %d], largest free block: %d ---\n",
|
||||
free, largest_hole);
|
||||
spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
|
||||
}
|
||||
#endif /* P54_MM_DEBUG */
|
||||
@ -538,8 +540,7 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
|
||||
case P54_TRAP_BEACON_TX:
|
||||
break;
|
||||
case P54_TRAP_RADAR:
|
||||
printk(KERN_INFO "%s: radar (freq:%d MHz)\n",
|
||||
wiphy_name(priv->hw->wiphy), freq);
|
||||
wiphy_info(priv->hw->wiphy, "radar (freq:%d mhz)\n", freq);
|
||||
break;
|
||||
case P54_TRAP_NO_BEACON:
|
||||
if (priv->vif)
|
||||
@ -558,8 +559,8 @@ static void p54_rx_trap(struct p54_common *priv, struct sk_buff *skb)
|
||||
wiphy_rfkill_set_hw_state(priv->hw->wiphy, false);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_INFO "%s: received event:%x freq:%d\n",
|
||||
wiphy_name(priv->hw->wiphy), event, freq);
|
||||
wiphy_info(priv->hw->wiphy, "received event:%x freq:%d\n",
|
||||
event, freq);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -584,8 +585,9 @@ static int p54_rx_control(struct p54_common *priv, struct sk_buff *skb)
|
||||
p54_rx_eeprom_readback(priv, skb);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_DEBUG "%s: not handling 0x%02x type control frame\n",
|
||||
wiphy_name(priv->hw->wiphy), le16_to_cpu(hdr->type));
|
||||
wiphy_debug(priv->hw->wiphy,
|
||||
"not handling 0x%02x type control frame\n",
|
||||
le16_to_cpu(hdr->type));
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
|
@ -350,6 +350,14 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
|
||||
enum cipher curr_cipher;
|
||||
|
||||
if (crypto->cmd == SET_KEY) {
|
||||
/*
|
||||
* Disallow to set WEP key other than with index 0,
|
||||
* it is known that not work at least on some hardware.
|
||||
* SW crypto will be used in that case.
|
||||
*/
|
||||
if (key->alg == ALG_WEP && key->keyidx != 0)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/*
|
||||
* Pairwise key will always be entry 0, but this
|
||||
* could collide with a shared key on the same
|
||||
@ -376,7 +384,7 @@ static int rt2500usb_config_key(struct rt2x00_dev *rt2x00dev,
|
||||
if (key->hw_key_idx > 0 && crypto->cipher != curr_cipher)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
rt2500usb_register_multiwrite(rt2x00dev, reg,
|
||||
rt2500usb_register_multiwrite(rt2x00dev, KEY_ENTRY(key->hw_key_idx),
|
||||
crypto->key, sizeof(crypto->key));
|
||||
|
||||
/*
|
||||
@ -817,6 +825,7 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
|
||||
rt2500usb_register_write(rt2x00dev, MAC_CSR8, reg);
|
||||
|
||||
rt2500usb_register_read(rt2x00dev, TXRX_CSR0, ®);
|
||||
rt2x00_set_field16(®, TXRX_CSR0_ALGORITHM, CIPHER_NONE);
|
||||
rt2x00_set_field16(®, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER);
|
||||
rt2x00_set_field16(®, TXRX_CSR0_KEY_ID, 0);
|
||||
rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg);
|
||||
|
@ -273,17 +273,24 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
|
||||
mutex_init(&intf->beacon_skb_mutex);
|
||||
intf->beacon = entry;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_AP)
|
||||
memcpy(&intf->bssid, vif->addr, ETH_ALEN);
|
||||
memcpy(&intf->mac, vif->addr, ETH_ALEN);
|
||||
|
||||
/*
|
||||
* The MAC adddress must be configured after the device
|
||||
* has been initialized. Otherwise the device can reset
|
||||
* the MAC registers.
|
||||
* The BSSID address must only be configured in AP mode,
|
||||
* however we should not send an empty BSSID address for
|
||||
* STA interfaces at this time, since this can cause
|
||||
* invalid behavior in the device.
|
||||
*/
|
||||
rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
|
||||
intf->mac, intf->bssid);
|
||||
memcpy(&intf->mac, vif->addr, ETH_ALEN);
|
||||
if (vif->type == NL80211_IFTYPE_AP) {
|
||||
memcpy(&intf->bssid, vif->addr, ETH_ALEN);
|
||||
rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
|
||||
intf->mac, intf->bssid);
|
||||
} else {
|
||||
rt2x00lib_config_intf(rt2x00dev, intf, vif->type,
|
||||
intf->mac, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some filters depend on the current working mode. We can force
|
||||
|
@ -103,7 +103,7 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
|
||||
{
|
||||
struct rtl8180_priv *priv = dev->priv;
|
||||
unsigned int count = 32;
|
||||
u8 signal;
|
||||
u8 signal, agc, sq;
|
||||
|
||||
while (count--) {
|
||||
struct rtl8180_rx_desc *entry = &priv->rx_ring[priv->rx_idx];
|
||||
@ -132,12 +132,16 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
|
||||
|
||||
rx_status.antenna = (flags2 >> 15) & 1;
|
||||
rx_status.rate_idx = (flags >> 20) & 0xF;
|
||||
/* TODO: improve signal/rssi reporting for !rtl8185 */
|
||||
signal = (flags2 >> 17) & 0x7F;
|
||||
if (rx_status.rate_idx > 3)
|
||||
signal = 90 - clamp_t(u8, signal, 25, 90);
|
||||
else
|
||||
signal = 95 - clamp_t(u8, signal, 30, 95);
|
||||
agc = (flags2 >> 17) & 0x7F;
|
||||
if (priv->r8185) {
|
||||
if (rx_status.rate_idx > 3)
|
||||
signal = 90 - clamp_t(u8, agc, 25, 90);
|
||||
else
|
||||
signal = 95 - clamp_t(u8, agc, 30, 95);
|
||||
} else {
|
||||
sq = flags2 & 0xff;
|
||||
signal = priv->rf->calc_rssi(agc, sq);
|
||||
}
|
||||
rx_status.signal = signal;
|
||||
rx_status.freq = dev->conf.channel->center_freq;
|
||||
rx_status.band = dev->conf.channel->band;
|
||||
@ -357,7 +361,7 @@ static int rtl8180_init_hw(struct ieee80211_hw *dev)
|
||||
|
||||
/* check success of reset */
|
||||
if (rtl818x_ioread8(priv, &priv->map->CMD) & RTL818X_CMD_RESET) {
|
||||
printk(KERN_ERR "%s: reset timeout!\n", wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "reset timeout!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -441,8 +445,7 @@ static int rtl8180_init_rx_ring(struct ieee80211_hw *dev)
|
||||
&priv->rx_ring_dma);
|
||||
|
||||
if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) {
|
||||
printk(KERN_ERR "%s: Cannot allocate RX ring\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "cannot allocate rx ring\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -499,8 +502,8 @@ static int rtl8180_init_tx_ring(struct ieee80211_hw *dev,
|
||||
|
||||
ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma);
|
||||
if (!ring || (unsigned long)ring & 0xFF) {
|
||||
printk(KERN_ERR "%s: Cannot allocate TX ring (prio = %d)\n",
|
||||
wiphy_name(dev->wiphy), prio);
|
||||
wiphy_err(dev->wiphy, "cannot allocate tx ring (prio = %d)\n",
|
||||
prio);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
@ -565,8 +568,7 @@ static int rtl8180_start(struct ieee80211_hw *dev)
|
||||
ret = request_irq(priv->pdev->irq, rtl8180_interrupt,
|
||||
IRQF_SHARED, KBUILD_MODNAME, dev);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s: failed to register IRQ handler\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "failed to register irq handler\n");
|
||||
goto err_free_rings;
|
||||
}
|
||||
|
||||
@ -1103,9 +1105,8 @@ static int __devinit rtl8180_probe(struct pci_dev *pdev,
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n",
|
||||
wiphy_name(dev->wiphy), mac_addr,
|
||||
chip_name, priv->rf->name);
|
||||
wiphy_info(dev->wiphy, "hwaddr %pm, %s + %s\n",
|
||||
mac_addr, chip_name, priv->rf->name);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -69,6 +69,15 @@ static void grf5101_write_phy_antenna(struct ieee80211_hw *dev, short chan)
|
||||
rtl8180_write_phy(dev, 0x10, ant);
|
||||
}
|
||||
|
||||
static u8 grf5101_rf_calc_rssi(u8 agc, u8 sq)
|
||||
{
|
||||
if (agc > 60)
|
||||
return 65;
|
||||
|
||||
/* TODO(?): just return agc (or agc + 5) to avoid mult / div */
|
||||
return 65 * agc / 60;
|
||||
}
|
||||
|
||||
static void grf5101_rf_set_channel(struct ieee80211_hw *dev,
|
||||
struct ieee80211_conf *conf)
|
||||
{
|
||||
@ -176,5 +185,6 @@ const struct rtl818x_rf_ops grf5101_rf_ops = {
|
||||
.name = "GCT",
|
||||
.init = grf5101_rf_init,
|
||||
.stop = grf5101_rf_stop,
|
||||
.set_chan = grf5101_rf_set_channel
|
||||
.set_chan = grf5101_rf_set_channel,
|
||||
.calc_rssi = grf5101_rf_calc_rssi,
|
||||
};
|
||||
|
@ -74,6 +74,22 @@ static void max2820_write_phy_antenna(struct ieee80211_hw *dev, short chan)
|
||||
rtl8180_write_phy(dev, 0x10, ant);
|
||||
}
|
||||
|
||||
static u8 max2820_rf_calc_rssi(u8 agc, u8 sq)
|
||||
{
|
||||
bool odd;
|
||||
|
||||
odd = !!(agc & 1);
|
||||
|
||||
agc >>= 1;
|
||||
if (odd)
|
||||
agc += 76;
|
||||
else
|
||||
agc += 66;
|
||||
|
||||
/* TODO: change addends above to avoid mult / div below */
|
||||
return 65 * agc / 100;
|
||||
}
|
||||
|
||||
static void max2820_rf_set_channel(struct ieee80211_hw *dev,
|
||||
struct ieee80211_conf *conf)
|
||||
{
|
||||
@ -148,5 +164,6 @@ const struct rtl818x_rf_ops max2820_rf_ops = {
|
||||
.name = "Maxim",
|
||||
.init = max2820_rf_init,
|
||||
.stop = max2820_rf_stop,
|
||||
.set_chan = max2820_rf_set_channel
|
||||
.set_chan = max2820_rf_set_channel,
|
||||
.calc_rssi = max2820_rf_calc_rssi,
|
||||
};
|
||||
|
@ -50,7 +50,10 @@ static void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
|
||||
udelay(10);
|
||||
|
||||
for (i = 15; i >= 0; i--) {
|
||||
u16 reg = reg80 | !!(bangdata & (1 << i));
|
||||
u16 reg = reg80;
|
||||
|
||||
if (bangdata & (1 << i))
|
||||
reg |= 1;
|
||||
|
||||
if (i & 1)
|
||||
rtl818x_iowrite16(priv, &priv->map->RFPinsOutput, reg);
|
||||
|
@ -76,6 +76,31 @@ static void sa2400_write_phy_antenna(struct ieee80211_hw *dev, short chan)
|
||||
|
||||
}
|
||||
|
||||
static u8 sa2400_rf_rssi_map[] = {
|
||||
0x64, 0x64, 0x63, 0x62, 0x61, 0x60, 0x5f, 0x5e,
|
||||
0x5d, 0x5c, 0x5b, 0x5a, 0x57, 0x54, 0x52, 0x50,
|
||||
0x4e, 0x4c, 0x4a, 0x48, 0x46, 0x44, 0x41, 0x3f,
|
||||
0x3c, 0x3a, 0x37, 0x36, 0x36, 0x1c, 0x1c, 0x1b,
|
||||
0x1b, 0x1a, 0x1a, 0x19, 0x19, 0x18, 0x18, 0x17,
|
||||
0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13,
|
||||
0x13, 0x12, 0x12, 0x11, 0x11, 0x10, 0x10, 0x0f,
|
||||
0x0f, 0x0e, 0x0e, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
|
||||
0x0b, 0x0a, 0x0a, 0x09, 0x09, 0x08, 0x08, 0x07,
|
||||
0x07, 0x06, 0x06, 0x05, 0x04, 0x03, 0x02,
|
||||
};
|
||||
|
||||
static u8 sa2400_rf_calc_rssi(u8 agc, u8 sq)
|
||||
{
|
||||
if (sq == 0x80)
|
||||
return 1;
|
||||
|
||||
if (sq > 78)
|
||||
return 32;
|
||||
|
||||
/* TODO: recalc sa2400_rf_rssi_map to avoid mult / div */
|
||||
return 65 * sa2400_rf_rssi_map[sq] / 100;
|
||||
}
|
||||
|
||||
static void sa2400_rf_set_channel(struct ieee80211_hw *dev,
|
||||
struct ieee80211_conf *conf)
|
||||
{
|
||||
@ -198,5 +223,6 @@ const struct rtl818x_rf_ops sa2400_rf_ops = {
|
||||
.name = "Philips",
|
||||
.init = sa2400_rf_init,
|
||||
.stop = sa2400_rf_stop,
|
||||
.set_chan = sa2400_rf_set_channel
|
||||
.set_chan = sa2400_rf_set_channel,
|
||||
.calc_rssi = sa2400_rf_calc_rssi,
|
||||
};
|
||||
|
@ -573,7 +573,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
|
||||
} while (--i);
|
||||
|
||||
if (!i) {
|
||||
printk(KERN_ERR "%s: Reset timeout!\n", wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "reset timeout!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -589,8 +589,7 @@ static int rtl8187_cmd_reset(struct ieee80211_hw *dev)
|
||||
} while (--i);
|
||||
|
||||
if (!i) {
|
||||
printk(KERN_ERR "%s: eeprom reset timeout!\n",
|
||||
wiphy_name(dev->wiphy));
|
||||
wiphy_err(dev->wiphy, "eeprom reset timeout!\n");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -1527,9 +1526,9 @@ static int __devinit rtl8187_probe(struct usb_interface *intf,
|
||||
mutex_init(&priv->conf_mutex);
|
||||
skb_queue_head_init(&priv->b_tx_status.queue);
|
||||
|
||||
printk(KERN_INFO "%s: hwaddr %pM, %s V%d + %s, rfkill mask %d\n",
|
||||
wiphy_name(dev->wiphy), mac_addr,
|
||||
chip_name, priv->asic_rev, priv->rf->name, priv->rfkill_mask);
|
||||
wiphy_info(dev->wiphy, "hwaddr %pm, %s v%d + %s, rfkill mask %d\n",
|
||||
mac_addr, chip_name, priv->asic_rev, priv->rf->name,
|
||||
priv->rfkill_mask);
|
||||
|
||||
#ifdef CONFIG_RTL8187_LEDS
|
||||
eeprom_93cx6_read(&eeprom, 0x3F, ®);
|
||||
|
@ -366,8 +366,8 @@ static void rtl8225_rf_init(struct ieee80211_hw *dev)
|
||||
rtl8225_write(dev, 0x02, 0x044d);
|
||||
msleep(100);
|
||||
if (!(rtl8225_read(dev, 6) & (1 << 7)))
|
||||
printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
|
||||
wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
|
||||
wiphy_warn(dev->wiphy, "rf calibration failed! %x\n",
|
||||
rtl8225_read(dev, 6));
|
||||
}
|
||||
|
||||
rtl8225_write(dev, 0x0, 0x127);
|
||||
@ -735,8 +735,8 @@ static void rtl8225z2_rf_init(struct ieee80211_hw *dev)
|
||||
rtl8225_write(dev, 0x02, 0x044D);
|
||||
msleep(100);
|
||||
if (!(rtl8225_read(dev, 6) & (1 << 7)))
|
||||
printk(KERN_WARNING "%s: RF Calibration Failed! %x\n",
|
||||
wiphy_name(dev->wiphy), rtl8225_read(dev, 6));
|
||||
wiphy_warn(dev->wiphy, "rf calibration failed! %x\n",
|
||||
rtl8225_read(dev, 6));
|
||||
}
|
||||
|
||||
msleep(200);
|
||||
|
@ -193,6 +193,7 @@ struct rtl818x_rf_ops {
|
||||
void (*stop)(struct ieee80211_hw *);
|
||||
void (*set_chan)(struct ieee80211_hw *, struct ieee80211_conf *);
|
||||
void (*conf_erp)(struct ieee80211_hw *, struct ieee80211_bss_conf *);
|
||||
u8 (*calc_rssi)(u8 agc, u8 sq);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -381,6 +381,9 @@ struct wl1251 {
|
||||
|
||||
u32 chip_id;
|
||||
char fw_ver[21];
|
||||
|
||||
/* Most recently reported noise in dBm */
|
||||
s8 noise;
|
||||
};
|
||||
|
||||
int wl1251_plt_start(struct wl1251 *wl);
|
||||
|
@ -225,7 +225,7 @@ static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag)
|
||||
int wl1251_boot_run_firmware(struct wl1251 *wl)
|
||||
{
|
||||
int loop, ret;
|
||||
u32 chip_id, interrupt;
|
||||
u32 chip_id, acx_intr;
|
||||
|
||||
wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
|
||||
|
||||
@ -242,15 +242,15 @@ int wl1251_boot_run_firmware(struct wl1251 *wl)
|
||||
loop = 0;
|
||||
while (loop++ < INIT_LOOP) {
|
||||
udelay(INIT_LOOP_DELAY);
|
||||
interrupt = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
|
||||
acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
|
||||
|
||||
if (interrupt == 0xffffffff) {
|
||||
if (acx_intr == 0xffffffff) {
|
||||
wl1251_error("error reading hardware complete "
|
||||
"init indication");
|
||||
return -EIO;
|
||||
}
|
||||
/* check that ACX_INTR_INIT_COMPLETE is enabled */
|
||||
else if (interrupt & WL1251_ACX_INTR_INIT_COMPLETE) {
|
||||
else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) {
|
||||
wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
|
||||
WL1251_ACX_INTR_INIT_COMPLETE);
|
||||
break;
|
||||
|
@ -175,8 +175,8 @@ struct cmd_read_write_memory {
|
||||
#define WL1251_SCAN_NUM_PROBES 3
|
||||
|
||||
struct wl1251_scan_parameters {
|
||||
u32 rx_config_options;
|
||||
u32 rx_filter_options;
|
||||
__le32 rx_config_options;
|
||||
__le32 rx_filter_options;
|
||||
|
||||
/*
|
||||
* Scan options:
|
||||
@ -186,7 +186,7 @@ struct wl1251_scan_parameters {
|
||||
* bit 2: voice mode, 0 for normal scan.
|
||||
* bit 3: scan priority, 1 for high priority.
|
||||
*/
|
||||
u16 scan_options;
|
||||
__le16 scan_options;
|
||||
|
||||
/* Number of channels to scan */
|
||||
u8 num_channels;
|
||||
@ -195,7 +195,7 @@ struct wl1251_scan_parameters {
|
||||
u8 num_probe_requests;
|
||||
|
||||
/* Rate and modulation for probe requests */
|
||||
u16 tx_rate;
|
||||
__le16 tx_rate;
|
||||
|
||||
u8 tid_trigger;
|
||||
u8 ssid_len;
|
||||
@ -204,8 +204,8 @@ struct wl1251_scan_parameters {
|
||||
} __packed;
|
||||
|
||||
struct wl1251_scan_ch_parameters {
|
||||
u32 min_duration; /* in TU */
|
||||
u32 max_duration; /* in TU */
|
||||
__le32 min_duration; /* in TU */
|
||||
__le32 max_duration; /* in TU */
|
||||
u32 bssid_lsb;
|
||||
u16 bssid_msb;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user