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:
John W. Linville 2010-07-29 14:47:07 -04:00
commit ae3568adf4
145 changed files with 3891 additions and 2859 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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,
};
/*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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, &reg);
rt2x00_set_field16(&reg, TXRX_CSR0_ALGORITHM, CIPHER_NONE);
rt2x00_set_field16(&reg, TXRX_CSR0_IV_OFFSET, IEEE80211_HEADER);
rt2x00_set_field16(&reg, TXRX_CSR0_KEY_ID, 0);
rt2500usb_register_write(rt2x00dev, TXRX_CSR0, reg);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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, &reg);

View File

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

View File

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

View File

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

View File

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

View File

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