Commit b9217266 authored by David S. Miller's avatar David S. Miller

Merge tag 'master-2014-11-04' of...

Merge tag 'master-2014-11-04' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next

John W. Linville says:

====================
pull request: wireless-next 2014-11-07

Please pull this batch of updates intended for the 3.19 stream!

For the mac80211 bits, Johannes says:

"This relatively large batch of changes is comprised of the following:
 * large mac80211-hwsim changes from Ben, Jukka and a bit myself
 * OCB/WAVE/11p support from Rostislav on behalf of the Czech Technical
   University in Prague and Volkswagen Group Research
 * minstrel VHT work from Karl
 * more CSA work from Luca
 * WMM admission control support in mac80211 (myself)
 * various smaller fixes, spelling corrections, and minor API additions"

For the Bluetooth bits, Johan says:

"Here's the first bluetooth-next pull request for 3.19. The vast majority
of patches are for ieee802154 from Alexander Aring with various fixes
and cleanups. There are also several LE/SMP fixes as well as improved
support for handling LE devices that have lost their pairing information
(the patches from Alfonso). Jukka provides a couple of stability fixes
for 6lowpan and Szymon conformance fixes for RFCOMM. For the HCI drivers
we have one new USB ID for an Acer controller as well as a reset
handling fix for H5."

For the Atheros bits, Kalle says:

"Major changes are:

o ethtool support (Ben)

o print dev string prefix with debug hex buffers dump (Michal)

o debugfs file to read calibration data from the firmware verification
  purposes (me)

o fix fw_stats debugfs file, now results are more reliable (Michal)

o firmware crash counters via debugfs (Ben&me)

o various tracing points to debug firmware (Rajkumar)

o make it possible to provide firmware calibration data via a file (me)

And we have quite a lot of smaller fixes and clean up."

For the iwlwifi bits, Emmanuel says:

"The big new thing here is netdetect which allows the
firmware to wake up the platform when a specific network
is detected. Along with that I have fixes for d3 operation.
The usual amount of rate scaling stuff - we now support STBC.
The other commit that stands out is Johannes's work on
devcoredump. He basically starts to use the standard
infrastructure he built."

Along with that are the usual sort of updates and such for ath9k,
brcmfmac, wil6210, and a handful of other bits here and there...

Please let me know if there are problems!
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e344458f bf515fb1
...@@ -2306,6 +2306,14 @@ F: security/capability.c ...@@ -2306,6 +2306,14 @@ F: security/capability.c
F: security/commoncap.c F: security/commoncap.c
F: kernel/capability.c F: kernel/capability.c
CC2520 IEEE-802.15.4 RADIO DRIVER
M: Varka Bhadram <varkabhadram@gmail.com>
L: linux-wpan@vger.kernel.org
S: Maintained
F: drivers/net/ieee802154/cc2520.c
F: include/linux/spi/cc2520.h
F: Documentation/devicetree/bindings/net/ieee802154/cc2520.txt
CELL BROADBAND ENGINE ARCHITECTURE CELL BROADBAND ENGINE ARCHITECTURE
M: Arnd Bergmann <arnd@arndb.de> M: Arnd Bergmann <arnd@arndb.de>
L: linuxppc-dev@lists.ozlabs.org L: linuxppc-dev@lists.ozlabs.org
...@@ -4693,6 +4701,13 @@ S: Maintained ...@@ -4693,6 +4701,13 @@ S: Maintained
F: net/ieee802154/ F: net/ieee802154/
F: net/mac802154/ F: net/mac802154/
F: drivers/net/ieee802154/ F: drivers/net/ieee802154/
F: include/linux/nl802154.h
F: include/linux/ieee802154.h
F: include/net/nl802154.h
F: include/net/mac802154.h
F: include/net/af_ieee802154.h
F: include/net/cfg802154.h
F: include/net/ieee802154_netdev.h
F: Documentation/networking/ieee802154.txt F: Documentation/networking/ieee802154.txt
IGUANAWORKS USB IR TRANSCEIVER IGUANAWORKS USB IR TRANSCEIVER
......
...@@ -24,6 +24,7 @@ struct bcma_bus; ...@@ -24,6 +24,7 @@ struct bcma_bus;
/* main.c */ /* main.c */
bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value,
int timeout); int timeout);
void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core);
int bcma_bus_register(struct bcma_bus *bus); int bcma_bus_register(struct bcma_bus *bus);
void bcma_bus_unregister(struct bcma_bus *bus); void bcma_bus_unregister(struct bcma_bus *bus);
int __init bcma_bus_early_register(struct bcma_bus *bus, int __init bcma_bus_early_register(struct bcma_bus *bus,
......
...@@ -169,10 +169,8 @@ static void bcma_of_fill_device(struct platform_device *parent, ...@@ -169,10 +169,8 @@ static void bcma_of_fill_device(struct platform_device *parent,
} }
#endif /* CONFIG_OF */ #endif /* CONFIG_OF */
static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
{ {
int err;
core->dev.release = bcma_release_core_dev; core->dev.release = bcma_release_core_dev;
core->dev.bus = &bcma_bus_type; core->dev.bus = &bcma_bus_type;
dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index); dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
...@@ -196,6 +194,11 @@ static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core) ...@@ -196,6 +194,11 @@ static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
case BCMA_HOSTTYPE_SDIO: case BCMA_HOSTTYPE_SDIO:
break; break;
} }
}
static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
{
int err;
err = device_register(&core->dev); err = device_register(&core->dev);
if (err) { if (err) {
......
...@@ -505,6 +505,7 @@ int bcma_bus_scan(struct bcma_bus *bus) ...@@ -505,6 +505,7 @@ int bcma_bus_scan(struct bcma_bus *bus)
bus->nr_cores++; bus->nr_cores++;
other_core = bcma_find_core_reverse(bus, core->id.id); other_core = bcma_find_core_reverse(bus, core->id.id);
core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1; core->core_unit = (other_core == NULL) ? 0 : other_core->core_unit + 1;
bcma_prepare_core(bus, core);
bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n", bcma_info(bus, "Core %d found: %s (manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
core->core_index, bcma_device_name(&core->id), core->core_index, bcma_device_name(&core->id),
......
...@@ -79,6 +79,7 @@ static const struct usb_device_id ath3k_table[] = { ...@@ -79,6 +79,7 @@ static const struct usb_device_id ath3k_table[] = {
{ USB_DEVICE(0x0489, 0xe057) }, { USB_DEVICE(0x0489, 0xe057) },
{ USB_DEVICE(0x0489, 0xe056) }, { USB_DEVICE(0x0489, 0xe056) },
{ USB_DEVICE(0x0489, 0xe05f) }, { USB_DEVICE(0x0489, 0xe05f) },
{ USB_DEVICE(0x0489, 0xe078) },
{ USB_DEVICE(0x04c5, 0x1330) }, { USB_DEVICE(0x04c5, 0x1330) },
{ USB_DEVICE(0x04CA, 0x3004) }, { USB_DEVICE(0x04CA, 0x3004) },
{ USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x04CA, 0x3005) },
...@@ -130,6 +131,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { ...@@ -130,6 +131,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = {
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
......
...@@ -156,6 +156,7 @@ static const struct usb_device_id blacklist_table[] = { ...@@ -156,6 +156,7 @@ static const struct usb_device_id blacklist_table[] = {
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0489, 0xe05f), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x0489, 0xe078), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04c5, 0x1330), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 },
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
......
...@@ -168,6 +168,36 @@ static void h5_timed_event(unsigned long arg) ...@@ -168,6 +168,36 @@ static void h5_timed_event(unsigned long arg)
hci_uart_tx_wakeup(hu); hci_uart_tx_wakeup(hu);
} }
static void h5_peer_reset(struct hci_uart *hu)
{
struct h5 *h5 = hu->priv;
struct sk_buff *skb;
const unsigned char hard_err[] = { 0x10, 0x01, 0x00 };
BT_ERR("Peer device has reset");
h5->state = H5_UNINITIALIZED;
del_timer(&h5->timer);
skb_queue_purge(&h5->rel);
skb_queue_purge(&h5->unrel);
skb_queue_purge(&h5->unack);
h5->tx_seq = 0;
h5->tx_ack = 0;
skb = bt_skb_alloc(3, GFP_ATOMIC);
if (!skb)
return;
bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
memcpy(skb_put(skb, 3), hard_err, 3);
/* Send Hardware Error to upper stack */
hci_recv_frame(hu->hdev, skb);
}
static int h5_open(struct hci_uart *hu) static int h5_open(struct hci_uart *hu)
{ {
struct h5 *h5; struct h5 *h5;
...@@ -283,8 +313,12 @@ static void h5_handle_internal_rx(struct hci_uart *hu) ...@@ -283,8 +313,12 @@ static void h5_handle_internal_rx(struct hci_uart *hu)
conf_req[2] = h5_cfg_field(h5); conf_req[2] = h5_cfg_field(h5);
if (memcmp(data, sync_req, 2) == 0) { if (memcmp(data, sync_req, 2) == 0) {
if (h5->state == H5_ACTIVE)
h5_peer_reset(hu);
h5_link_control(hu, sync_rsp, 2); h5_link_control(hu, sync_rsp, 2);
} else if (memcmp(data, sync_rsp, 2) == 0) { } else if (memcmp(data, sync_rsp, 2) == 0) {
if (h5->state == H5_ACTIVE)
h5_peer_reset(hu);
h5->state = H5_INITIALIZED; h5->state = H5_INITIALIZED;
h5_link_control(hu, conf_req, 3); h5_link_control(hu, conf_req, 3);
} else if (memcmp(data, conf_req, 2) == 0) { } else if (memcmp(data, conf_req, 2) == 0) {
......
...@@ -10,16 +10,6 @@ menuconfig IEEE802154_DRIVERS ...@@ -10,16 +10,6 @@ menuconfig IEEE802154_DRIVERS
If you say N, all options in this submenu will be skipped and If you say N, all options in this submenu will be skipped and
disabled. disabled.
config IEEE802154_FAKEHARD
tristate "Fake LR-WPAN driver with several interconnected devices"
depends on IEEE802154_DRIVERS
---help---
Say Y here to enable the fake driver that serves as an example
of HardMAC device driver.
This driver can also be built as a module. To do so say M here.
The module will be called 'fakehard'.
config IEEE802154_FAKELB config IEEE802154_FAKELB
depends on IEEE802154_DRIVERS && MAC802154 depends on IEEE802154_DRIVERS && MAC802154
tristate "IEEE 802.15.4 loopback driver" tristate "IEEE 802.15.4 loopback driver"
......
obj-$(CONFIG_IEEE802154_FAKEHARD) += fakehard.o
obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o obj-$(CONFIG_IEEE802154_FAKELB) += fakelb.o
obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o obj-$(CONFIG_IEEE802154_AT86RF230) += at86rf230.o
obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o obj-$(CONFIG_IEEE802154_MRF24J40) += mrf24j40.o
......
This diff is collapsed.
...@@ -21,10 +21,10 @@ ...@@ -21,10 +21,10 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/pinctrl/consumer.h> #include <linux/pinctrl/consumer.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/ieee802154.h>
#include <net/mac802154.h> #include <net/mac802154.h>
#include <net/wpan-phy.h> #include <net/cfg802154.h>
#include <net/ieee802154.h>
#define SPI_COMMAND_BUFFER 3 #define SPI_COMMAND_BUFFER 3
#define HIGH 1 #define HIGH 1
...@@ -193,7 +193,7 @@ ...@@ -193,7 +193,7 @@
/* Driver private information */ /* Driver private information */
struct cc2520_private { struct cc2520_private {
struct spi_device *spi; /* SPI device structure */ struct spi_device *spi; /* SPI device structure */
struct ieee802154_dev *dev; /* IEEE-802.15.4 device */ struct ieee802154_hw *hw; /* IEEE-802.15.4 device */
u8 *buf; /* SPI TX/Rx data buffer */ u8 *buf; /* SPI TX/Rx data buffer */
struct mutex buffer_mutex; /* SPI buffer mutex */ struct mutex buffer_mutex; /* SPI buffer mutex */
bool is_tx; /* Flag for sync b/w Tx and Rx */ bool is_tx; /* Flag for sync b/w Tx and Rx */
...@@ -453,20 +453,20 @@ cc2520_read_rxfifo(struct cc2520_private *priv, u8 *data, u8 len, u8 *lqi) ...@@ -453,20 +453,20 @@ cc2520_read_rxfifo(struct cc2520_private *priv, u8 *data, u8 len, u8 *lqi)
return status; return status;
} }
static int cc2520_start(struct ieee802154_dev *dev) static int cc2520_start(struct ieee802154_hw *hw)
{ {
return cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRXON); return cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRXON);
} }
static void cc2520_stop(struct ieee802154_dev *dev) static void cc2520_stop(struct ieee802154_hw *hw)
{ {
cc2520_cmd_strobe(dev->priv, CC2520_CMD_SRFOFF); cc2520_cmd_strobe(hw->priv, CC2520_CMD_SRFOFF);
} }
static int static int
cc2520_tx(struct ieee802154_dev *dev, struct sk_buff *skb) cc2520_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
{ {
struct cc2520_private *priv = dev->priv; struct cc2520_private *priv = hw->priv;
unsigned long flags; unsigned long flags;
int rc; int rc;
u8 status = 0; u8 status = 0;
...@@ -524,7 +524,7 @@ static int cc2520_rx(struct cc2520_private *priv) ...@@ -524,7 +524,7 @@ static int cc2520_rx(struct cc2520_private *priv)
if (len < 2 || len > IEEE802154_MTU) if (len < 2 || len > IEEE802154_MTU)
return -EINVAL; return -EINVAL;
skb = alloc_skb(len, GFP_KERNEL); skb = dev_alloc_skb(len);
if (!skb) if (!skb)
return -ENOMEM; return -ENOMEM;
...@@ -536,7 +536,7 @@ static int cc2520_rx(struct cc2520_private *priv) ...@@ -536,7 +536,7 @@ static int cc2520_rx(struct cc2520_private *priv)
skb_trim(skb, skb->len - 2); skb_trim(skb, skb->len - 2);
ieee802154_rx_irqsafe(priv->dev, skb, lqi); ieee802154_rx_irqsafe(priv->hw, skb, lqi);
dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi); dev_vdbg(&priv->spi->dev, "RXFIFO: %x %x\n", len, lqi);
...@@ -544,9 +544,9 @@ static int cc2520_rx(struct cc2520_private *priv) ...@@ -544,9 +544,9 @@ static int cc2520_rx(struct cc2520_private *priv)
} }
static int static int
cc2520_ed(struct ieee802154_dev *dev, u8 *level) cc2520_ed(struct ieee802154_hw *hw, u8 *level)
{ {
struct cc2520_private *priv = dev->priv; struct cc2520_private *priv = hw->priv;
u8 status = 0xff; u8 status = 0xff;
u8 rssi; u8 rssi;
int ret; int ret;
...@@ -569,12 +569,11 @@ cc2520_ed(struct ieee802154_dev *dev, u8 *level) ...@@ -569,12 +569,11 @@ cc2520_ed(struct ieee802154_dev *dev, u8 *level)
} }
static int static int
cc2520_set_channel(struct ieee802154_dev *dev, int page, int channel) cc2520_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
{ {
struct cc2520_private *priv = dev->priv; struct cc2520_private *priv = hw->priv;
int ret; int ret;
might_sleep();
dev_dbg(&priv->spi->dev, "trying to set channel\n"); dev_dbg(&priv->spi->dev, "trying to set channel\n");
BUG_ON(page != 0); BUG_ON(page != 0);
...@@ -588,12 +587,12 @@ cc2520_set_channel(struct ieee802154_dev *dev, int page, int channel) ...@@ -588,12 +587,12 @@ cc2520_set_channel(struct ieee802154_dev *dev, int page, int channel)
} }
static int static int
cc2520_filter(struct ieee802154_dev *dev, cc2520_filter(struct ieee802154_hw *hw,
struct ieee802154_hw_addr_filt *filt, unsigned long changed) struct ieee802154_hw_addr_filt *filt, unsigned long changed)
{ {
struct cc2520_private *priv = dev->priv; struct cc2520_private *priv = hw->priv;
if (changed & IEEE802515_AFILT_PANID_CHANGED) { if (changed & IEEE802154_AFILT_PANID_CHANGED) {
u16 panid = le16_to_cpu(filt->pan_id); u16 panid = le16_to_cpu(filt->pan_id);
dev_vdbg(&priv->spi->dev, dev_vdbg(&priv->spi->dev,
...@@ -602,7 +601,7 @@ cc2520_filter(struct ieee802154_dev *dev, ...@@ -602,7 +601,7 @@ cc2520_filter(struct ieee802154_dev *dev,
sizeof(panid), (u8 *)&panid); sizeof(panid), (u8 *)&panid);
} }
if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
dev_vdbg(&priv->spi->dev, dev_vdbg(&priv->spi->dev,
"cc2520_filter called for IEEE addr\n"); "cc2520_filter called for IEEE addr\n");
cc2520_write_ram(priv, CC2520RAM_IEEEADDR, cc2520_write_ram(priv, CC2520RAM_IEEEADDR,
...@@ -610,7 +609,7 @@ cc2520_filter(struct ieee802154_dev *dev, ...@@ -610,7 +609,7 @@ cc2520_filter(struct ieee802154_dev *dev,
(u8 *)&filt->ieee_addr); (u8 *)&filt->ieee_addr);
} }
if (changed & IEEE802515_AFILT_SADDR_CHANGED) { if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
u16 addr = le16_to_cpu(filt->short_addr); u16 addr = le16_to_cpu(filt->short_addr);
dev_vdbg(&priv->spi->dev, dev_vdbg(&priv->spi->dev,
...@@ -619,7 +618,7 @@ cc2520_filter(struct ieee802154_dev *dev, ...@@ -619,7 +618,7 @@ cc2520_filter(struct ieee802154_dev *dev,
sizeof(addr), (u8 *)&addr); sizeof(addr), (u8 *)&addr);
} }
if (changed & IEEE802515_AFILT_PANC_CHANGED) { if (changed & IEEE802154_AFILT_PANC_CHANGED) {
dev_vdbg(&priv->spi->dev, dev_vdbg(&priv->spi->dev,
"cc2520_filter called for panc change\n"); "cc2520_filter called for panc change\n");
if (filt->pan_coord) if (filt->pan_coord)
...@@ -631,11 +630,11 @@ cc2520_filter(struct ieee802154_dev *dev, ...@@ -631,11 +630,11 @@ cc2520_filter(struct ieee802154_dev *dev,
return 0; return 0;
} }
static struct ieee802154_ops cc2520_ops = { static const struct ieee802154_ops cc2520_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.start = cc2520_start, .start = cc2520_start,
.stop = cc2520_stop, .stop = cc2520_stop,
.xmit = cc2520_tx, .xmit_sync = cc2520_tx,
.ed = cc2520_ed, .ed = cc2520_ed,
.set_channel = cc2520_set_channel, .set_channel = cc2520_set_channel,
.set_hw_addr_filt = cc2520_filter, .set_hw_addr_filt = cc2520_filter,
...@@ -645,27 +644,28 @@ static int cc2520_register(struct cc2520_private *priv) ...@@ -645,27 +644,28 @@ static int cc2520_register(struct cc2520_private *priv)
{ {
int ret = -ENOMEM; int ret = -ENOMEM;
priv->dev = ieee802154_alloc_device(sizeof(*priv), &cc2520_ops); priv->hw = ieee802154_alloc_hw(sizeof(*priv), &cc2520_ops);
if (!priv->dev) if (!priv->hw)
goto err_ret; goto err_ret;
priv->dev->priv = priv; priv->hw->priv = priv;
priv->dev->parent = &priv->spi->dev; priv->hw->parent = &priv->spi->dev;
priv->dev->extra_tx_headroom = 0; priv->hw->extra_tx_headroom = 0;
/* We do support only 2.4 Ghz */ /* We do support only 2.4 Ghz */
priv->dev->phy->channels_supported[0] = 0x7FFF800; priv->hw->phy->channels_supported[0] = 0x7FFF800;
priv->dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK; priv->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
IEEE802154_HW_AFILT;
dev_vdbg(&priv->spi->dev, "registered cc2520\n"); dev_vdbg(&priv->spi->dev, "registered cc2520\n");
ret = ieee802154_register_device(priv->dev); ret = ieee802154_register_hw(priv->hw);
if (ret) if (ret)
goto err_free_device; goto err_free_device;
return 0; return 0;
err_free_device: err_free_device:
ieee802154_free_device(priv->dev); ieee802154_free_hw(priv->hw);
err_ret: err_ret:
return ret; return ret;
} }
...@@ -1002,8 +1002,8 @@ static int cc2520_remove(struct spi_device *spi) ...@@ -1002,8 +1002,8 @@ static int cc2520_remove(struct spi_device *spi)
mutex_destroy(&priv->buffer_mutex); mutex_destroy(&priv->buffer_mutex);
flush_work(&priv->fifop_irqwork); flush_work(&priv->fifop_irqwork);
ieee802154_unregister_device(priv->dev); ieee802154_unregister_hw(priv->hw);
ieee802154_free_device(priv->dev); ieee802154_free_hw(priv->hw);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -12,10 +12,6 @@ ...@@ -12,10 +12,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Written by: * Written by:
* Sergey Lapin <slapin@ossfans.org> * Sergey Lapin <slapin@ossfans.org>
* Dmitry Eremin-Solenikov <dbaryshkov@gmail.com> * Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
...@@ -29,12 +25,12 @@ ...@@ -29,12 +25,12 @@
#include <linux/device.h> #include <linux/device.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <net/mac802154.h> #include <net/mac802154.h>
#include <net/wpan-phy.h> #include <net/cfg802154.h>
static int numlbs = 1; static int numlbs = 1;
struct fakelb_dev_priv { struct fakelb_dev_priv {
struct ieee802154_dev *dev; struct ieee802154_hw *hw;
struct list_head list; struct list_head list;
struct fakelb_priv *fake; struct fakelb_priv *fake;
...@@ -49,9 +45,8 @@ struct fakelb_priv { ...@@ -49,9 +45,8 @@ struct fakelb_priv {
}; };
static int static int
fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level) fakelb_hw_ed(struct ieee802154_hw *hw, u8 *level)
{ {
might_sleep();
BUG_ON(!level); BUG_ON(!level);
*level = 0xbe; *level = 0xbe;
...@@ -59,13 +54,12 @@ fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level) ...@@ -59,13 +54,12 @@ fakelb_hw_ed(struct ieee802154_dev *dev, u8 *level)
} }
static int static int
fakelb_hw_channel(struct ieee802154_dev *dev, int page, int channel) fakelb_hw_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
{ {
pr_debug("set channel to %d\n", channel); pr_debug("set channel to %d\n", channel);
might_sleep(); hw->phy->current_page = page;
dev->phy->current_page = page; hw->phy->current_channel = channel;
dev->phy->current_channel = channel;
return 0; return 0;
} }
...@@ -78,19 +72,17 @@ fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb) ...@@ -78,19 +72,17 @@ fakelb_hw_deliver(struct fakelb_dev_priv *priv, struct sk_buff *skb)
spin_lock(&priv->lock); spin_lock(&priv->lock);
if (priv->working) { if (priv->working) {
newskb = pskb_copy(skb, GFP_ATOMIC); newskb = pskb_copy(skb, GFP_ATOMIC);
ieee802154_rx_irqsafe(priv->dev, newskb, 0xcc); ieee802154_rx_irqsafe(priv->hw, newskb, 0xcc);
} }
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
} }
static int static int
fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) fakelb_hw_xmit(struct ieee802154_hw *hw, struct sk_buff *skb)
{ {
struct fakelb_dev_priv *priv = dev->priv; struct fakelb_dev_priv *priv = hw->priv;
struct fakelb_priv *fake = priv->fake; struct fakelb_priv *fake = priv->fake;
might_sleep();
read_lock_bh(&fake->lock); read_lock_bh(&fake->lock);
if (priv->list.next == priv->list.prev) { if (priv->list.next == priv->list.prev) {
/* we are the only one device */ /* we are the only one device */
...@@ -99,8 +91,8 @@ fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) ...@@ -99,8 +91,8 @@ fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
struct fakelb_dev_priv *dp; struct fakelb_dev_priv *dp;
list_for_each_entry(dp, &priv->fake->list, list) { list_for_each_entry(dp, &priv->fake->list, list) {
if (dp != priv && if (dp != priv &&
(dp->dev->phy->current_channel == (dp->hw->phy->current_channel ==
priv->dev->phy->current_channel)) priv->hw->phy->current_channel))
fakelb_hw_deliver(dp, skb); fakelb_hw_deliver(dp, skb);
} }
} }
...@@ -110,8 +102,8 @@ fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb) ...@@ -110,8 +102,8 @@ fakelb_hw_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
} }
static int static int
fakelb_hw_start(struct ieee802154_dev *dev) { fakelb_hw_start(struct ieee802154_hw *hw) {
struct fakelb_dev_priv *priv = dev->priv; struct fakelb_dev_priv *priv = hw->priv;
int ret = 0; int ret = 0;
spin_lock(&priv->lock); spin_lock(&priv->lock);
...@@ -125,17 +117,17 @@ fakelb_hw_start(struct ieee802154_dev *dev) { ...@@ -125,17 +117,17 @@ fakelb_hw_start(struct ieee802154_dev *dev) {
} }
static void static void
fakelb_hw_stop(struct ieee802154_dev *dev) { fakelb_hw_stop(struct ieee802154_hw *hw) {
struct fakelb_dev_priv *priv = dev->priv; struct fakelb_dev_priv *priv = hw->priv;
spin_lock(&priv->lock); spin_lock(&priv->lock);
priv->working = 0; priv->working = 0;
spin_unlock(&priv->lock); spin_unlock(&priv->lock);
} }
static struct ieee802154_ops fakelb_ops = { static const struct ieee802154_ops fakelb_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.xmit = fakelb_hw_xmit, .xmit_sync = fakelb_hw_xmit,
.ed = fakelb_hw_ed, .ed = fakelb_hw_ed,
.set_channel = fakelb_hw_channel, .set_channel = fakelb_hw_channel,
.start = fakelb_hw_start, .start = fakelb_hw_start,
...@@ -150,54 +142,54 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) ...@@ -150,54 +142,54 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
{ {
struct fakelb_dev_priv *priv; struct fakelb_dev_priv *priv;
int err; int err;
struct ieee802154_dev *ieee; struct ieee802154_hw *hw;
ieee = ieee802154_alloc_device(sizeof(*priv), &fakelb_ops); hw = ieee802154_alloc_hw(sizeof(*priv), &fakelb_ops);
if (!ieee) if (!hw)
return -ENOMEM; return -ENOMEM;
priv = ieee->priv; priv = hw->priv;
priv->dev = ieee; priv->hw = hw;
/* 868 MHz BPSK 802.15.4-2003 */ /* 868 MHz BPSK 802.15.4-2003 */
ieee->phy->channels_supported[0] |= 1; hw->phy->channels_supported[0] |= 1;
/* 915 MHz BPSK 802.15.4-2003 */ /* 915 MHz BPSK 802.15.4-2003 */
ieee->phy->channels_supported[0] |= 0x7fe; hw->phy->channels_supported[0] |= 0x7fe;
/* 2.4 GHz O-QPSK 802.15.4-2003 */ /* 2.4 GHz O-QPSK 802.15.4-2003 */
ieee->phy->channels_supported[0] |= 0x7FFF800; hw->phy->channels_supported[0] |= 0x7FFF800;
/* 868 MHz ASK 802.15.4-2006 */ /* 868 MHz ASK 802.15.4-2006 */
ieee->phy->channels_supported[1] |= 1; hw->phy->channels_supported[1] |= 1;
/* 915 MHz ASK 802.15.4-2006 */ /* 915 MHz ASK 802.15.4-2006 */
ieee->phy->channels_supported[1] |= 0x7fe; hw->phy->channels_supported[1] |= 0x7fe;
/* 868 MHz O-QPSK 802.15.4-2006 */ /* 868 MHz O-QPSK 802.15.4-2006 */
ieee->phy->channels_supported[2] |= 1; hw->phy->channels_supported[2] |= 1;
/* 915 MHz O-QPSK 802.15.4-2006 */ /* 915 MHz O-QPSK 802.15.4-2006 */
ieee->phy->channels_supported[2] |= 0x7fe; hw->phy->channels_supported[2] |= 0x7fe;
/* 2.4 GHz CSS 802.15.4a-2007 */ /* 2.4 GHz CSS 802.15.4a-2007 */
ieee->phy->channels_supported[3] |= 0x3fff; hw->phy->channels_supported[3] |= 0x3fff;
/* UWB Sub-gigahertz 802.15.4a-2007 */ /* UWB Sub-gigahertz 802.15.4a-2007 */
ieee->phy->channels_supported[4] |= 1; hw->phy->channels_supported[4] |= 1;
/* UWB Low band 802.15.4a-2007 */ /* UWB Low band 802.15.4a-2007 */
ieee->phy->channels_supported[4] |= 0x1e; hw->phy->channels_supported[4] |= 0x1e;
/* UWB High band 802.15.4a-2007 */ /* UWB High band 802.15.4a-2007 */
ieee->phy->channels_supported[4] |= 0xffe0; hw->phy->channels_supported[4] |= 0xffe0;
/* 750 MHz O-QPSK 802.15.4c-2009 */ /* 750 MHz O-QPSK 802.15.4c-2009 */
ieee->phy->channels_supported[5] |= 0xf; hw->phy->channels_supported[5] |= 0xf;
/* 750 MHz MPSK 802.15.4c-2009 */ /* 750 MHz MPSK 802.15.4c-2009 */
ieee->phy->channels_supported[5] |= 0xf0; hw->phy->channels_supported[5] |= 0xf0;
/* 950 MHz BPSK 802.15.4d-2009 */ /* 950 MHz BPSK 802.15.4d-2009 */
ieee->phy->channels_supported[6] |= 0x3ff; hw->phy->channels_supported[6] |= 0x3ff;
/* 950 MHz GFSK 802.15.4d-2009 */ /* 950 MHz GFSK 802.15.4d-2009 */
ieee->phy->channels_supported[6] |= 0x3ffc00; hw->phy->channels_supported[6] |= 0x3ffc00;
INIT_LIST_HEAD(&priv->list); INIT_LIST_HEAD(&priv->list);
priv->fake = fake; priv->fake = fake;
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
ieee->parent = dev; hw->parent = dev;
err = ieee802154_register_device(ieee); err = ieee802154_register_hw(hw);
if (err) if (err)
goto err_reg; goto err_reg;
...@@ -208,7 +200,7 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake) ...@@ -208,7 +200,7 @@ static int fakelb_add_one(struct device *dev, struct fakelb_priv *fake)
return 0; return 0;
err_reg: err_reg:
ieee802154_free_device(priv->dev); ieee802154_free_hw(priv->hw);
return err; return err;
} }
...@@ -218,8 +210,8 @@ static void fakelb_del(struct fakelb_dev_priv *priv) ...@@ -218,8 +210,8 @@ static void fakelb_del(struct fakelb_dev_priv *priv)
list_del(&priv->list); list_del(&priv->list);
write_unlock_bh(&priv->fake->lock); write_unlock_bh(&priv->fake->lock);
ieee802154_unregister_device(priv->dev); ieee802154_unregister_hw(priv->hw);
ieee802154_free_device(priv->dev); ieee802154_free_hw(priv->hw);
} }
static int fakelb_probe(struct platform_device *pdev) static int fakelb_probe(struct platform_device *pdev)
......
...@@ -13,18 +13,14 @@ ...@@ -13,18 +13,14 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/wpan-phy.h> #include <linux/ieee802154.h>
#include <net/cfg802154.h>
#include <net/mac802154.h> #include <net/mac802154.h>
#include <net/ieee802154.h>
/* MRF24J40 Short Address Registers */ /* MRF24J40 Short Address Registers */
#define REG_RXMCR 0x00 /* Receive MAC control */ #define REG_RXMCR 0x00 /* Receive MAC control */
...@@ -43,6 +39,8 @@ ...@@ -43,6 +39,8 @@
#define REG_TXSTBL 0x2E /* TX Stabilization */ #define REG_TXSTBL 0x2E /* TX Stabilization */
#define REG_INTSTAT 0x31 /* Interrupt Status */ #define REG_INTSTAT 0x31 /* Interrupt Status */
#define REG_INTCON 0x32 /* Interrupt Control */ #define REG_INTCON 0x32 /* Interrupt Control */
#define REG_GPIO 0x33 /* GPIO */
#define REG_TRISGPIO 0x34 /* GPIO direction */
#define REG_RFCTL 0x36 /* RF Control Mode Register */ #define REG_RFCTL 0x36 /* RF Control Mode Register */
#define REG_BBREG1 0x39 /* Baseband Registers */ #define REG_BBREG1 0x39 /* Baseband Registers */
#define REG_BBREG2 0x3A /* */ #define REG_BBREG2 0x3A /* */
...@@ -63,6 +61,7 @@ ...@@ -63,6 +61,7 @@
#define REG_SLPCON1 0x220 #define REG_SLPCON1 0x220
#define REG_WAKETIMEL 0x222 /* Wake-up Time Match Value Low */ #define REG_WAKETIMEL 0x222 /* Wake-up Time Match Value Low */
#define REG_WAKETIMEH 0x223 /* Wake-up Time Match Value High */ #define REG_WAKETIMEH 0x223 /* Wake-up Time Match Value High */
#define REG_TESTMODE 0x22F /* Test mode */
#define REG_RX_FIFO 0x300 /* Receive FIFO */ #define REG_RX_FIFO 0x300 /* Receive FIFO */
/* Device configuration: Only channels 11-26 on page 0 are supported. */ /* Device configuration: Only channels 11-26 on page 0 are supported. */
...@@ -75,10 +74,12 @@ ...@@ -75,10 +74,12 @@
#define RX_FIFO_SIZE 144 /* From datasheet */ #define RX_FIFO_SIZE 144 /* From datasheet */
#define SET_CHANNEL_DELAY_US 192 /* From datasheet */ #define SET_CHANNEL_DELAY_US 192 /* From datasheet */
enum mrf24j40_modules { MRF24J40, MRF24J40MA, MRF24J40MC };
/* Device Private Data */ /* Device Private Data */
struct mrf24j40 { struct mrf24j40 {
struct spi_device *spi; struct spi_device *spi;
struct ieee802154_dev *dev; struct ieee802154_hw *hw;
struct mutex buffer_mutex; /* only used to protect buf */ struct mutex buffer_mutex; /* only used to protect buf */
struct completion tx_complete; struct completion tx_complete;
...@@ -331,9 +332,9 @@ static int mrf24j40_read_rx_buf(struct mrf24j40 *devrec, ...@@ -331,9 +332,9 @@ static int mrf24j40_read_rx_buf(struct mrf24j40 *devrec,
return ret; return ret;
} }
static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb) static int mrf24j40_tx(struct ieee802154_hw *hw, struct sk_buff *skb)
{ {
struct mrf24j40 *devrec = dev->priv; struct mrf24j40 *devrec = hw->priv;
u8 val; u8 val;
int ret = 0; int ret = 0;
...@@ -382,7 +383,7 @@ static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb) ...@@ -382,7 +383,7 @@ static int mrf24j40_tx(struct ieee802154_dev *dev, struct sk_buff *skb)
return ret; return ret;
} }
static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level) static int mrf24j40_ed(struct ieee802154_hw *hw, u8 *level)
{ {
/* TODO: */ /* TODO: */
pr_warn("mrf24j40: ed not implemented\n"); pr_warn("mrf24j40: ed not implemented\n");
...@@ -390,9 +391,9 @@ static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level) ...@@ -390,9 +391,9 @@ static int mrf24j40_ed(struct ieee802154_dev *dev, u8 *level)
return 0; return 0;
} }
static int mrf24j40_start(struct ieee802154_dev *dev) static int mrf24j40_start(struct ieee802154_hw *hw)
{ {
struct mrf24j40 *devrec = dev->priv; struct mrf24j40 *devrec = hw->priv;
u8 val; u8 val;
int ret; int ret;
...@@ -407,9 +408,9 @@ static int mrf24j40_start(struct ieee802154_dev *dev) ...@@ -407,9 +408,9 @@ static int mrf24j40_start(struct ieee802154_dev *dev)
return 0; return 0;
} }
static void mrf24j40_stop(struct ieee802154_dev *dev) static void mrf24j40_stop(struct ieee802154_hw *hw)
{ {
struct mrf24j40 *devrec = dev->priv; struct mrf24j40 *devrec = hw->priv;
u8 val; u8 val;
int ret; int ret;
...@@ -422,10 +423,9 @@ static void mrf24j40_stop(struct ieee802154_dev *dev) ...@@ -422,10 +423,9 @@ static void mrf24j40_stop(struct ieee802154_dev *dev)
write_short_reg(devrec, REG_INTCON, val); write_short_reg(devrec, REG_INTCON, val);
} }
static int mrf24j40_set_channel(struct ieee802154_dev *dev, static int mrf24j40_set_channel(struct ieee802154_hw *hw, u8 page, u8 channel)
int page, int channel)
{ {
struct mrf24j40 *devrec = dev->priv; struct mrf24j40 *devrec = hw->priv;
u8 val; u8 val;
int ret; int ret;
...@@ -453,15 +453,15 @@ static int mrf24j40_set_channel(struct ieee802154_dev *dev, ...@@ -453,15 +453,15 @@ static int mrf24j40_set_channel(struct ieee802154_dev *dev,
return 0; return 0;
} }
static int mrf24j40_filter(struct ieee802154_dev *dev, static int mrf24j40_filter(struct ieee802154_hw *hw,
struct ieee802154_hw_addr_filt *filt, struct ieee802154_hw_addr_filt *filt,
unsigned long changed) unsigned long changed)
{ {
struct mrf24j40 *devrec = dev->priv; struct mrf24j40 *devrec = hw->priv;
dev_dbg(printdev(devrec), "filter\n"); dev_dbg(printdev(devrec), "filter\n");
if (changed & IEEE802515_AFILT_SADDR_CHANGED) { if (changed & IEEE802154_AFILT_SADDR_CHANGED) {
/* Short Addr */ /* Short Addr */
u8 addrh, addrl; u8 addrh, addrl;
...@@ -474,7 +474,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, ...@@ -474,7 +474,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev,
"Set short addr to %04hx\n", filt->short_addr); "Set short addr to %04hx\n", filt->short_addr);
} }
if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { if (changed & IEEE802154_AFILT_IEEEADDR_CHANGED) {
/* Device Address */ /* Device Address */
u8 i, addr[8]; u8 i, addr[8];
...@@ -490,7 +490,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, ...@@ -490,7 +490,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev,
#endif #endif
} }
if (changed & IEEE802515_AFILT_PANID_CHANGED) { if (changed & IEEE802154_AFILT_PANID_CHANGED) {
/* PAN ID */ /* PAN ID */
u8 panidl, panidh; u8 panidl, panidh;
...@@ -502,7 +502,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev, ...@@ -502,7 +502,7 @@ static int mrf24j40_filter(struct ieee802154_dev *dev,
dev_dbg(printdev(devrec), "Set PANID to %04hx\n", filt->pan_id); dev_dbg(printdev(devrec), "Set PANID to %04hx\n", filt->pan_id);
} }
if (changed & IEEE802515_AFILT_PANC_CHANGED) { if (changed & IEEE802154_AFILT_PANC_CHANGED) {
/* Pan Coordinator */ /* Pan Coordinator */
u8 val; u8 val;
int ret; int ret;
...@@ -543,7 +543,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) ...@@ -543,7 +543,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
val |= 4; /* SET RXDECINV */ val |= 4; /* SET RXDECINV */
write_short_reg(devrec, REG_BBREG1, val); write_short_reg(devrec, REG_BBREG1, val);
skb = alloc_skb(len, GFP_KERNEL); skb = dev_alloc_skb(len);
if (!skb) { if (!skb) {
ret = -ENOMEM; ret = -ENOMEM;
goto out; goto out;
...@@ -563,7 +563,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) ...@@ -563,7 +563,7 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
/* TODO: Other drivers call ieee20154_rx_irqsafe() here (eg: cc2040, /* TODO: Other drivers call ieee20154_rx_irqsafe() here (eg: cc2040,
* also from a workqueue). I think irqsafe is not necessary here. * also from a workqueue). I think irqsafe is not necessary here.
* Can someone confirm? */ * Can someone confirm? */
ieee802154_rx_irqsafe(devrec->dev, skb, lqi); ieee802154_rx_irqsafe(devrec->hw, skb, lqi);
dev_dbg(printdev(devrec), "RX Handled\n"); dev_dbg(printdev(devrec), "RX Handled\n");
...@@ -578,9 +578,9 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec) ...@@ -578,9 +578,9 @@ static int mrf24j40_handle_rx(struct mrf24j40 *devrec)
return ret; return ret;
} }
static struct ieee802154_ops mrf24j40_ops = { static const struct ieee802154_ops mrf24j40_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.xmit = mrf24j40_tx, .xmit_sync = mrf24j40_tx,
.ed = mrf24j40_ed, .ed = mrf24j40_ed,
.start = mrf24j40_start, .start = mrf24j40_start,
.stop = mrf24j40_stop, .stop = mrf24j40_stop,
...@@ -691,6 +691,28 @@ static int mrf24j40_hw_init(struct mrf24j40 *devrec) ...@@ -691,6 +691,28 @@ static int mrf24j40_hw_init(struct mrf24j40 *devrec)
if (ret) if (ret)
goto err_ret; goto err_ret;
if (spi_get_device_id(devrec->spi)->driver_data == MRF24J40MC) {
/* Enable external amplifier.
* From MRF24J40MC datasheet section 1.3: Operation.
*/
read_long_reg(devrec, REG_TESTMODE, &val);
val |= 0x7; /* Configure GPIO 0-2 to control amplifier */
write_long_reg(devrec, REG_TESTMODE, val);
read_short_reg(devrec, REG_TRISGPIO, &val);
val |= 0x8; /* Set GPIO3 as output. */
write_short_reg(devrec, REG_TRISGPIO, val);
read_short_reg(devrec, REG_GPIO, &val);
val |= 0x8; /* Set GPIO3 HIGH to enable U5 voltage regulator */
write_short_reg(devrec, REG_GPIO, val);
/* Reduce TX pwr to meet FCC requirements.
* From MRF24J40MC datasheet section 3.1.1
*/
write_long_reg(devrec, REG_RFCON3, 0x28);
}
return 0; return 0;
err_ret: err_ret:
...@@ -722,17 +744,18 @@ static int mrf24j40_probe(struct spi_device *spi) ...@@ -722,17 +744,18 @@ static int mrf24j40_probe(struct spi_device *spi)
/* Register with the 802154 subsystem */ /* Register with the 802154 subsystem */
devrec->dev = ieee802154_alloc_device(0, &mrf24j40_ops); devrec->hw = ieee802154_alloc_hw(0, &mrf24j40_ops);
if (!devrec->dev) if (!devrec->hw)
goto err_ret; goto err_ret;
devrec->dev->priv = devrec; devrec->hw->priv = devrec;
devrec->dev->parent = &devrec->spi->dev; devrec->hw->parent = &devrec->spi->dev;
devrec->dev->phy->channels_supported[0] = CHANNEL_MASK; devrec->hw->phy->channels_supported[0] = CHANNEL_MASK;
devrec->dev->flags = IEEE802154_HW_OMIT_CKSUM|IEEE802154_HW_AACK; devrec->hw->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK |
IEEE802154_HW_AFILT;
dev_dbg(printdev(devrec), "registered mrf24j40\n"); dev_dbg(printdev(devrec), "registered mrf24j40\n");
ret = ieee802154_register_device(devrec->dev); ret = ieee802154_register_hw(devrec->hw);
if (ret) if (ret)
goto err_register_device; goto err_register_device;
...@@ -757,9 +780,9 @@ static int mrf24j40_probe(struct spi_device *spi) ...@@ -757,9 +780,9 @@ static int mrf24j40_probe(struct spi_device *spi)
err_irq: err_irq:
err_hw_init: err_hw_init:
ieee802154_unregister_device(devrec->dev); ieee802154_unregister_hw(devrec->hw);
err_register_device: err_register_device:
ieee802154_free_device(devrec->dev); ieee802154_free_hw(devrec->hw);
err_ret: err_ret:
return ret; return ret;
} }
...@@ -770,8 +793,8 @@ static int mrf24j40_remove(struct spi_device *spi) ...@@ -770,8 +793,8 @@ static int mrf24j40_remove(struct spi_device *spi)
dev_dbg(printdev(devrec), "remove\n"); dev_dbg(printdev(devrec), "remove\n");
ieee802154_unregister_device(devrec->dev); ieee802154_unregister_hw(devrec->hw);
ieee802154_free_device(devrec->dev); ieee802154_free_hw(devrec->hw);
/* TODO: Will ieee802154_free_device() wait until ->xmit() is /* TODO: Will ieee802154_free_device() wait until ->xmit() is
* complete? */ * complete? */
...@@ -779,8 +802,9 @@ static int mrf24j40_remove(struct spi_device *spi) ...@@ -779,8 +802,9 @@ static int mrf24j40_remove(struct spi_device *spi)
} }
static const struct spi_device_id mrf24j40_ids[] = { static const struct spi_device_id mrf24j40_ids[] = {
{ "mrf24j40", 0 }, { "mrf24j40", MRF24J40 },
{ "mrf24j40ma", 0 }, { "mrf24j40ma", MRF24J40MA },
{ "mrf24j40mc", MRF24J40MC },
{ }, { },
}; };
MODULE_DEVICE_TABLE(spi, mrf24j40_ids); MODULE_DEVICE_TABLE(spi, mrf24j40_ids);
......
...@@ -148,7 +148,7 @@ struct ath_common { ...@@ -148,7 +148,7 @@ struct ath_common {
u16 cachelsz; u16 cachelsz;
u16 curaid; u16 curaid;
u8 macaddr[ETH_ALEN]; u8 macaddr[ETH_ALEN];
u8 curbssid[ETH_ALEN]; u8 curbssid[ETH_ALEN] __aligned(2);
u8 bssidmask[ETH_ALEN]; u8 bssidmask[ETH_ALEN];
u32 rx_bufsize; u32 rx_bufsize;
......
...@@ -443,12 +443,12 @@ int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr) ...@@ -443,12 +443,12 @@ int ath10k_ce_rx_post_buf(struct ath10k_ce_pipe *pipe, void *ctx, u32 paddr)
* Guts of ath10k_ce_completed_recv_next. * Guts of ath10k_ce_completed_recv_next.
* The caller takes responsibility for any necessary locking. * The caller takes responsibility for any necessary locking.
*/ */
static int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state, int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp, void **per_transfer_contextp,
u32 *bufferp, u32 *bufferp,
unsigned int *nbytesp, unsigned int *nbytesp,
unsigned int *transfer_idp, unsigned int *transfer_idp,
unsigned int *flagsp) unsigned int *flagsp)
{ {
struct ath10k_ce_ring *dest_ring = ce_state->dest_ring; struct ath10k_ce_ring *dest_ring = ce_state->dest_ring;
unsigned int nentries_mask = dest_ring->nentries_mask; unsigned int nentries_mask = dest_ring->nentries_mask;
...@@ -576,11 +576,11 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, ...@@ -576,11 +576,11 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
* Guts of ath10k_ce_completed_send_next. * Guts of ath10k_ce_completed_send_next.
* The caller takes responsibility for any necessary locking. * The caller takes responsibility for any necessary locking.
*/ */
static int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state, int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp, void **per_transfer_contextp,
u32 *bufferp, u32 *bufferp,
unsigned int *nbytesp, unsigned int *nbytesp,
unsigned int *transfer_idp) unsigned int *transfer_idp)
{ {
struct ath10k_ce_ring *src_ring = ce_state->src_ring; struct ath10k_ce_ring *src_ring = ce_state->src_ring;
u32 ctrl_addr = ce_state->ctrl_addr; u32 ctrl_addr = ce_state->ctrl_addr;
...@@ -817,7 +817,10 @@ void ath10k_ce_enable_interrupts(struct ath10k *ar) ...@@ -817,7 +817,10 @@ void ath10k_ce_enable_interrupts(struct ath10k *ar)
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
int ce_id; int ce_id;
for (ce_id = 0; ce_id < CE_COUNT; ce_id++) /* Skip the last copy engine, CE7 the diagnostic window, as that
* uses polling and isn't initialized for interrupts.
*/
for (ce_id = 0; ce_id < CE_COUNT - 1; ce_id++)
ath10k_ce_per_engine_handler_adjust(&ar_pci->ce_states[ce_id]); ath10k_ce_per_engine_handler_adjust(&ar_pci->ce_states[ce_id]);
} }
...@@ -1020,37 +1023,10 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id, ...@@ -1020,37 +1023,10 @@ ath10k_ce_alloc_dest_ring(struct ath10k *ar, unsigned int ce_id,
* initialized by software/firmware. * initialized by software/firmware.
*/ */
int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
const struct ce_attr *attr, const struct ce_attr *attr)
void (*send_cb)(struct ath10k_ce_pipe *),
void (*recv_cb)(struct ath10k_ce_pipe *))
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
int ret; int ret;
/*
* Make sure there's enough CE ringbuffer entries for HTT TX to avoid
* additional TX locking checks.
*
* For the lack of a better place do the check here.
*/
BUILD_BUG_ON(2*TARGET_NUM_MSDU_DESC >
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC >
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
spin_lock_bh(&ar_pci->ce_lock);
ce_state->ar = ar;
ce_state->id = ce_id;
ce_state->ctrl_addr = ath10k_ce_base_address(ce_id);
ce_state->attr_flags = attr->flags;
ce_state->src_sz_max = attr->src_sz_max;
if (attr->src_nentries)
ce_state->send_cb = send_cb;
if (attr->dest_nentries)
ce_state->recv_cb = recv_cb;
spin_unlock_bh(&ar_pci->ce_lock);
if (attr->src_nentries) { if (attr->src_nentries) {
ret = ath10k_ce_init_src_ring(ar, ce_id, attr); ret = ath10k_ce_init_src_ring(ar, ce_id, attr);
if (ret) { if (ret) {
...@@ -1098,12 +1074,37 @@ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id) ...@@ -1098,12 +1074,37 @@ void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id)
} }
int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
const struct ce_attr *attr) const struct ce_attr *attr,
void (*send_cb)(struct ath10k_ce_pipe *),
void (*recv_cb)(struct ath10k_ce_pipe *))
{ {
struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id];
int ret; int ret;
/*
* Make sure there's enough CE ringbuffer entries for HTT TX to avoid
* additional TX locking checks.
*
* For the lack of a better place do the check here.
*/
BUILD_BUG_ON(2*TARGET_NUM_MSDU_DESC >
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC >
(CE_HTT_H2T_MSG_SRC_NENTRIES - 1));
ce_state->ar = ar;
ce_state->id = ce_id;
ce_state->ctrl_addr = ath10k_ce_base_address(ce_id);
ce_state->attr_flags = attr->flags;
ce_state->src_sz_max = attr->src_sz_max;
if (attr->src_nentries)
ce_state->send_cb = send_cb;
if (attr->dest_nentries)
ce_state->recv_cb = recv_cb;
if (attr->src_nentries) { if (attr->src_nentries) {
ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr); ce_state->src_ring = ath10k_ce_alloc_src_ring(ar, ce_id, attr);
if (IS_ERR(ce_state->src_ring)) { if (IS_ERR(ce_state->src_ring)) {
......
...@@ -192,15 +192,21 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state, ...@@ -192,15 +192,21 @@ int ath10k_ce_completed_send_next(struct ath10k_ce_pipe *ce_state,
unsigned int *nbytesp, unsigned int *nbytesp,
unsigned int *transfer_idp); unsigned int *transfer_idp);
int ath10k_ce_completed_send_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp);
/*==================CE Engine Initialization=======================*/ /*==================CE Engine Initialization=======================*/
int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id,
const struct ce_attr *attr, const struct ce_attr *attr);
void (*send_cb)(struct ath10k_ce_pipe *),
void (*recv_cb)(struct ath10k_ce_pipe *));
void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id); void ath10k_ce_deinit_pipe(struct ath10k *ar, unsigned int ce_id);
int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id, int ath10k_ce_alloc_pipe(struct ath10k *ar, int ce_id,
const struct ce_attr *attr); const struct ce_attr *attr,
void (*send_cb)(struct ath10k_ce_pipe *),
void (*recv_cb)(struct ath10k_ce_pipe *));
void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id); void ath10k_ce_free_pipe(struct ath10k *ar, int ce_id);
/*==================CE Engine Shutdown=======================*/ /*==================CE Engine Shutdown=======================*/
...@@ -213,6 +219,13 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state, ...@@ -213,6 +219,13 @@ int ath10k_ce_revoke_recv_next(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp, void **per_transfer_contextp,
u32 *bufferp); u32 *bufferp);
int ath10k_ce_completed_recv_next_nolock(struct ath10k_ce_pipe *ce_state,
void **per_transfer_contextp,
u32 *bufferp,
unsigned int *nbytesp,
unsigned int *transfer_idp,
unsigned int *flagsp);
/* /*
* Support clean shutdown by allowing the caller to cancel * Support clean shutdown by allowing the caller to cancel
* pending sends. Target DMA must be stopped before using * pending sends. Target DMA must be stopped before using
......
...@@ -138,7 +138,8 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar, ...@@ -138,7 +138,8 @@ static const struct firmware *ath10k_fetch_fw_file(struct ath10k *ar,
return fw; return fw;
} }
static int ath10k_push_board_ext_data(struct ath10k *ar) static int ath10k_push_board_ext_data(struct ath10k *ar, const void *data,
size_t data_len)
{ {
u32 board_data_size = QCA988X_BOARD_DATA_SZ; u32 board_data_size = QCA988X_BOARD_DATA_SZ;
u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ; u32 board_ext_data_size = QCA988X_BOARD_EXT_DATA_SZ;
...@@ -159,14 +160,14 @@ static int ath10k_push_board_ext_data(struct ath10k *ar) ...@@ -159,14 +160,14 @@ static int ath10k_push_board_ext_data(struct ath10k *ar)
if (board_ext_data_addr == 0) if (board_ext_data_addr == 0)
return 0; return 0;
if (ar->board_len != (board_data_size + board_ext_data_size)) { if (data_len != (board_data_size + board_ext_data_size)) {
ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n", ath10k_err(ar, "invalid board (ext) data sizes %zu != %d+%d\n",
ar->board_len, board_data_size, board_ext_data_size); data_len, board_data_size, board_ext_data_size);
return -EINVAL; return -EINVAL;
} }
ret = ath10k_bmi_write_memory(ar, board_ext_data_addr, ret = ath10k_bmi_write_memory(ar, board_ext_data_addr,
ar->board_data + board_data_size, data + board_data_size,
board_ext_data_size); board_ext_data_size);
if (ret) { if (ret) {
ath10k_err(ar, "could not write board ext data (%d)\n", ret); ath10k_err(ar, "could not write board ext data (%d)\n", ret);
...@@ -184,13 +185,14 @@ static int ath10k_push_board_ext_data(struct ath10k *ar) ...@@ -184,13 +185,14 @@ static int ath10k_push_board_ext_data(struct ath10k *ar)
return 0; return 0;
} }
static int ath10k_download_board_data(struct ath10k *ar) static int ath10k_download_board_data(struct ath10k *ar, const void *data,
size_t data_len)
{ {
u32 board_data_size = QCA988X_BOARD_DATA_SZ; u32 board_data_size = QCA988X_BOARD_DATA_SZ;
u32 address; u32 address;
int ret; int ret;
ret = ath10k_push_board_ext_data(ar); ret = ath10k_push_board_ext_data(ar, data, data_len);
if (ret) { if (ret) {
ath10k_err(ar, "could not push board ext data (%d)\n", ret); ath10k_err(ar, "could not push board ext data (%d)\n", ret);
goto exit; goto exit;
...@@ -202,9 +204,9 @@ static int ath10k_download_board_data(struct ath10k *ar) ...@@ -202,9 +204,9 @@ static int ath10k_download_board_data(struct ath10k *ar)
goto exit; goto exit;
} }
ret = ath10k_bmi_write_memory(ar, address, ar->board_data, ret = ath10k_bmi_write_memory(ar, address, data,
min_t(u32, board_data_size, min_t(u32, board_data_size,
ar->board_len)); data_len));
if (ret) { if (ret) {
ath10k_err(ar, "could not write board data (%d)\n", ret); ath10k_err(ar, "could not write board data (%d)\n", ret);
goto exit; goto exit;
...@@ -220,11 +222,39 @@ static int ath10k_download_board_data(struct ath10k *ar) ...@@ -220,11 +222,39 @@ static int ath10k_download_board_data(struct ath10k *ar)
return ret; return ret;
} }
static int ath10k_download_cal_file(struct ath10k *ar)
{
int ret;
if (!ar->cal_file)
return -ENOENT;
if (IS_ERR(ar->cal_file))
return PTR_ERR(ar->cal_file);
ret = ath10k_download_board_data(ar, ar->cal_file->data,
ar->cal_file->size);
if (ret) {
ath10k_err(ar, "failed to download cal_file data: %d\n", ret);
return ret;
}
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cal file downloaded\n");
return 0;
}
static int ath10k_download_and_run_otp(struct ath10k *ar) static int ath10k_download_and_run_otp(struct ath10k *ar)
{ {
u32 result, address = ar->hw_params.patch_load_addr; u32 result, address = ar->hw_params.patch_load_addr;
int ret; int ret;
ret = ath10k_download_board_data(ar, ar->board_data, ar->board_len);
if (ret) {
ath10k_err(ar, "failed to download board data: %d\n", ret);
return ret;
}
/* OTP is optional */ /* OTP is optional */
if (!ar->otp_data || !ar->otp_len) { if (!ar->otp_data || !ar->otp_len) {
...@@ -308,6 +338,9 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar) ...@@ -308,6 +338,9 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar)
if (ar->firmware && !IS_ERR(ar->firmware)) if (ar->firmware && !IS_ERR(ar->firmware))
release_firmware(ar->firmware); release_firmware(ar->firmware);
if (ar->cal_file && !IS_ERR(ar->cal_file))
release_firmware(ar->cal_file);
ar->board = NULL; ar->board = NULL;
ar->board_data = NULL; ar->board_data = NULL;
ar->board_len = 0; ar->board_len = 0;
...@@ -319,6 +352,27 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar) ...@@ -319,6 +352,27 @@ static void ath10k_core_free_firmware_files(struct ath10k *ar)
ar->firmware = NULL; ar->firmware = NULL;
ar->firmware_data = NULL; ar->firmware_data = NULL;
ar->firmware_len = 0; ar->firmware_len = 0;
ar->cal_file = NULL;
}
static int ath10k_fetch_cal_file(struct ath10k *ar)
{
char filename[100];
/* cal-<bus>-<id>.bin */
scnprintf(filename, sizeof(filename), "cal-%s-%s.bin",
ath10k_bus_str(ar->hif.bus), dev_name(ar->dev));
ar->cal_file = ath10k_fetch_fw_file(ar, ATH10K_FW_DIR, filename);
if (IS_ERR(ar->cal_file))
/* calibration file is optional, don't print any warnings */
return PTR_ERR(ar->cal_file);
ath10k_dbg(ar, ATH10K_DBG_BOOT, "found calibration file %s/%s\n",
ATH10K_FW_DIR, filename);
return 0;
} }
static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar) static int ath10k_core_fetch_firmware_api_1(struct ath10k *ar)
...@@ -562,6 +616,9 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar) ...@@ -562,6 +616,9 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
{ {
int ret; int ret;
/* calibration file is optional, don't check for any errors */
ath10k_fetch_cal_file(ar);
ar->fw_api = 3; ar->fw_api = 3;
ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api); ath10k_dbg(ar, ATH10K_DBG_BOOT, "trying fw api %d\n", ar->fw_api);
...@@ -589,30 +646,32 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar) ...@@ -589,30 +646,32 @@ static int ath10k_core_fetch_firmware_files(struct ath10k *ar)
return 0; return 0;
} }
static int ath10k_init_download_firmware(struct ath10k *ar, static int ath10k_download_cal_data(struct ath10k *ar)
enum ath10k_firmware_mode mode)
{ {
int ret; int ret;
ret = ath10k_download_board_data(ar); ret = ath10k_download_cal_file(ar);
if (ret) { if (ret == 0) {
ath10k_err(ar, "failed to download board data: %d\n", ret); ar->cal_mode = ATH10K_CAL_MODE_FILE;
return ret; goto done;
} }
ath10k_dbg(ar, ATH10K_DBG_BOOT,
"boot did not find a calibration file, try OTP next: %d\n",
ret);
ret = ath10k_download_and_run_otp(ar); ret = ath10k_download_and_run_otp(ar);
if (ret) { if (ret) {
ath10k_err(ar, "failed to run otp: %d\n", ret); ath10k_err(ar, "failed to run otp: %d\n", ret);
return ret; return ret;
} }
ret = ath10k_download_fw(ar, mode); ar->cal_mode = ATH10K_CAL_MODE_OTP;
if (ret) {
ath10k_err(ar, "failed to download firmware: %d\n", ret);
return ret;
}
return ret; done:
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot using calibration mode %s\n",
ath10k_cal_mode_str(ar->cal_mode));
return 0;
} }
static int ath10k_init_uart(struct ath10k *ar) static int ath10k_init_uart(struct ath10k *ar)
...@@ -729,7 +788,11 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) ...@@ -729,7 +788,11 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
goto err; goto err;
} }
status = ath10k_init_download_firmware(ar, mode); status = ath10k_download_cal_data(ar);
if (status)
goto err;
status = ath10k_download_fw(ar, mode);
if (status) if (status)
goto err; goto err;
...@@ -846,9 +909,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode) ...@@ -846,9 +909,9 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
goto err_hif_stop; goto err_hif_stop;
if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features))
ar->free_vdev_map = (1 << TARGET_10X_NUM_VDEVS) - 1; ar->free_vdev_map = (1LL << TARGET_10X_NUM_VDEVS) - 1;
else else
ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; ar->free_vdev_map = (1LL << TARGET_NUM_VDEVS) - 1;
INIT_LIST_HEAD(&ar->arvifs); INIT_LIST_HEAD(&ar->arvifs);
...@@ -1084,6 +1147,7 @@ void ath10k_core_unregister(struct ath10k *ar) ...@@ -1084,6 +1147,7 @@ void ath10k_core_unregister(struct ath10k *ar)
EXPORT_SYMBOL(ath10k_core_unregister); EXPORT_SYMBOL(ath10k_core_unregister);
struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
enum ath10k_bus bus,
const struct ath10k_hif_ops *hif_ops) const struct ath10k_hif_ops *hif_ops)
{ {
struct ath10k *ar; struct ath10k *ar;
...@@ -1100,6 +1164,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, ...@@ -1100,6 +1164,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
ar->dev = dev; ar->dev = dev;
ar->hif.ops = hif_ops; ar->hif.ops = hif_ops;
ar->hif.bus = bus;
init_completion(&ar->scan.started); init_completion(&ar->scan.started);
init_completion(&ar->scan.completed); init_completion(&ar->scan.completed);
......
...@@ -63,6 +63,20 @@ ...@@ -63,6 +63,20 @@
struct ath10k; struct ath10k;
enum ath10k_bus {
ATH10K_BUS_PCI,
};
static inline const char *ath10k_bus_str(enum ath10k_bus bus)
{
switch (bus) {
case ATH10K_BUS_PCI:
return "pci";
}
return "unknown";
}
struct ath10k_skb_cb { struct ath10k_skb_cb {
dma_addr_t paddr; dma_addr_t paddr;
u8 vdev_id; u8 vdev_id;
...@@ -96,8 +110,6 @@ struct ath10k_bmi { ...@@ -96,8 +110,6 @@ struct ath10k_bmi {
bool done_sent; bool done_sent;
}; };
#define ATH10K_MAX_MEM_REQS 16
struct ath10k_mem_chunk { struct ath10k_mem_chunk {
void *vaddr; void *vaddr;
dma_addr_t paddr; dma_addr_t paddr;
...@@ -115,17 +127,21 @@ struct ath10k_wmi { ...@@ -115,17 +127,21 @@ struct ath10k_wmi {
struct wmi_pdev_param_map *pdev_param; struct wmi_pdev_param_map *pdev_param;
u32 num_mem_chunks; u32 num_mem_chunks;
struct ath10k_mem_chunk mem_chunks[ATH10K_MAX_MEM_REQS]; struct ath10k_mem_chunk mem_chunks[WMI_MAX_MEM_REQS];
}; };
struct ath10k_peer_stat { struct ath10k_fw_stats_peer {
struct list_head list;
u8 peer_macaddr[ETH_ALEN]; u8 peer_macaddr[ETH_ALEN];
u32 peer_rssi; u32 peer_rssi;
u32 peer_tx_rate; u32 peer_tx_rate;
u32 peer_rx_rate; /* 10x only */ u32 peer_rx_rate; /* 10x only */
}; };
struct ath10k_target_stats { struct ath10k_fw_stats_pdev {
struct list_head list;
/* PDEV stats */ /* PDEV stats */
s32 ch_noise_floor; s32 ch_noise_floor;
u32 tx_frame_count; u32 tx_frame_count;
...@@ -180,15 +196,11 @@ struct ath10k_target_stats { ...@@ -180,15 +196,11 @@ struct ath10k_target_stats {
s32 phy_errs; s32 phy_errs;
s32 phy_err_drop; s32 phy_err_drop;
s32 mpdu_errs; s32 mpdu_errs;
};
/* VDEV STATS */ struct ath10k_fw_stats {
struct list_head pdevs;
/* PEER STATS */ struct list_head peers;
u8 peers;
struct ath10k_peer_stat peer_stat[TARGET_NUM_PEERS];
/* TODO: Beacon filter stats */
}; };
struct ath10k_dfs_stats { struct ath10k_dfs_stats {
...@@ -234,6 +246,8 @@ struct ath10k_vif { ...@@ -234,6 +246,8 @@ struct ath10k_vif {
struct sk_buff *beacon; struct sk_buff *beacon;
/* protected by data_lock */ /* protected by data_lock */
bool beacon_sent; bool beacon_sent;
void *beacon_buf;
dma_addr_t beacon_paddr;
struct ath10k *ar; struct ath10k *ar;
struct ieee80211_vif *vif; struct ieee80211_vif *vif;
...@@ -273,6 +287,7 @@ struct ath10k_vif { ...@@ -273,6 +287,7 @@ struct ath10k_vif {
u8 force_sgi; u8 force_sgi;
bool use_cts_prot; bool use_cts_prot;
int num_legacy_stations; int num_legacy_stations;
int txpower;
}; };
struct ath10k_vif_iter { struct ath10k_vif_iter {
...@@ -292,17 +307,19 @@ struct ath10k_fw_crash_data { ...@@ -292,17 +307,19 @@ struct ath10k_fw_crash_data {
struct ath10k_debug { struct ath10k_debug {
struct dentry *debugfs_phy; struct dentry *debugfs_phy;
struct ath10k_target_stats target_stats; struct ath10k_fw_stats fw_stats;
struct completion fw_stats_complete;
bool fw_stats_done;
DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX); DECLARE_BITMAP(wmi_service_bitmap, WMI_SERVICE_MAX);
struct completion event_stats_compl;
unsigned long htt_stats_mask; unsigned long htt_stats_mask;
struct delayed_work htt_stats_dwork; struct delayed_work htt_stats_dwork;
struct ath10k_dfs_stats dfs_stats; struct ath10k_dfs_stats dfs_stats;
struct ath_dfs_pool_stats dfs_pool_stats; struct ath_dfs_pool_stats dfs_pool_stats;
/* protected by conf_mutex */
u32 fw_dbglog_mask; u32 fw_dbglog_mask;
u32 pktlog_filter;
u8 htt_max_amsdu; u8 htt_max_amsdu;
u8 htt_max_ampdu; u8 htt_max_ampdu;
...@@ -321,7 +338,7 @@ enum ath10k_state { ...@@ -321,7 +338,7 @@ enum ath10k_state {
* stopped in ath10k_core_restart() work holding conf_mutex. The state * stopped in ath10k_core_restart() work holding conf_mutex. The state
* RESTARTED means that the device is up and mac80211 has started hw * RESTARTED means that the device is up and mac80211 has started hw
* reconfiguration. Once mac80211 is done with the reconfiguration we * reconfiguration. Once mac80211 is done with the reconfiguration we
* set the state to STATE_ON in restart_complete(). */ * set the state to STATE_ON in reconfig_complete(). */
ATH10K_STATE_RESTARTING, ATH10K_STATE_RESTARTING,
ATH10K_STATE_RESTARTED, ATH10K_STATE_RESTARTED,
...@@ -371,6 +388,23 @@ enum ath10k_dev_flags { ...@@ -371,6 +388,23 @@ enum ath10k_dev_flags {
ATH10K_FLAG_CORE_REGISTERED, ATH10K_FLAG_CORE_REGISTERED,
}; };
enum ath10k_cal_mode {
ATH10K_CAL_MODE_FILE,
ATH10K_CAL_MODE_OTP,
};
static inline const char *ath10k_cal_mode_str(enum ath10k_cal_mode mode)
{
switch (mode) {
case ATH10K_CAL_MODE_FILE:
return "file";
case ATH10K_CAL_MODE_OTP:
return "otp";
}
return "unknown";
}
enum ath10k_scan_state { enum ath10k_scan_state {
ATH10K_SCAN_IDLE, ATH10K_SCAN_IDLE,
ATH10K_SCAN_STARTING, ATH10K_SCAN_STARTING,
...@@ -421,6 +455,7 @@ struct ath10k { ...@@ -421,6 +455,7 @@ struct ath10k {
bool p2p; bool p2p;
struct { struct {
enum ath10k_bus bus;
const struct ath10k_hif_ops *ops; const struct ath10k_hif_ops *ops;
} hif; } hif;
...@@ -456,7 +491,10 @@ struct ath10k { ...@@ -456,7 +491,10 @@ struct ath10k {
const void *firmware_data; const void *firmware_data;
size_t firmware_len; size_t firmware_len;
const struct firmware *cal_file;
int fw_api; int fw_api;
enum ath10k_cal_mode cal_mode;
struct { struct {
struct completion started; struct completion started;
...@@ -482,7 +520,7 @@ struct ath10k { ...@@ -482,7 +520,7 @@ struct ath10k {
/* current operating channel definition */ /* current operating channel definition */
struct cfg80211_chan_def chandef; struct cfg80211_chan_def chandef;
int free_vdev_map; unsigned long long free_vdev_map;
bool monitor; bool monitor;
int monitor_vdev_id; int monitor_vdev_id;
bool monitor_started; bool monitor_started;
...@@ -563,11 +601,19 @@ struct ath10k { ...@@ -563,11 +601,19 @@ struct ath10k {
bool utf_monitor; bool utf_monitor;
} testmode; } testmode;
struct {
/* protected by data_lock */
u32 fw_crash_counter;
u32 fw_warm_reset_counter;
u32 fw_cold_reset_counter;
} stats;
/* must be last */ /* must be last */
u8 drv_priv[0] __aligned(sizeof(void *)); u8 drv_priv[0] __aligned(sizeof(void *));
}; };
struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev,
enum ath10k_bus bus,
const struct ath10k_hif_ops *hif_ops); const struct ath10k_hif_ops *hif_ops);
void ath10k_core_destroy(struct ath10k *ar); void ath10k_core_destroy(struct ath10k *ar);
......
This diff is collapsed.
...@@ -38,11 +38,20 @@ enum ath10k_debug_mask { ...@@ -38,11 +38,20 @@ enum ath10k_debug_mask {
ATH10K_DBG_ANY = 0xffffffff, ATH10K_DBG_ANY = 0xffffffff,
}; };
enum ath10k_pktlog_filter {
ATH10K_PKTLOG_RX = 0x000000001,
ATH10K_PKTLOG_TX = 0x000000002,
ATH10K_PKTLOG_RCFIND = 0x000000004,
ATH10K_PKTLOG_RCUPDATE = 0x000000008,
ATH10K_PKTLOG_DBG_PRINT = 0x000000010,
ATH10K_PKTLOG_ANY = 0x00000001f,
};
extern unsigned int ath10k_debug_mask; extern unsigned int ath10k_debug_mask;
__printf(2, 3) int ath10k_info(struct ath10k *ar, const char *fmt, ...); __printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...);
__printf(2, 3) int ath10k_err(struct ath10k *ar, const char *fmt, ...); __printf(2, 3) void ath10k_err(struct ath10k *ar, const char *fmt, ...);
__printf(2, 3) int ath10k_warn(struct ath10k *ar, const char *fmt, ...); __printf(2, 3) void ath10k_warn(struct ath10k *ar, const char *fmt, ...);
void ath10k_print_driver_info(struct ath10k *ar); void ath10k_print_driver_info(struct ath10k *ar);
#ifdef CONFIG_ATH10K_DEBUGFS #ifdef CONFIG_ATH10K_DEBUGFS
...@@ -53,17 +62,24 @@ void ath10k_debug_destroy(struct ath10k *ar); ...@@ -53,17 +62,24 @@ void ath10k_debug_destroy(struct ath10k *ar);
int ath10k_debug_register(struct ath10k *ar); int ath10k_debug_register(struct ath10k *ar);
void ath10k_debug_unregister(struct ath10k *ar); void ath10k_debug_unregister(struct ath10k *ar);
void ath10k_debug_read_service_map(struct ath10k *ar, void ath10k_debug_read_service_map(struct ath10k *ar,
void *service_map, const void *service_map,
size_t map_size); size_t map_size);
void ath10k_debug_read_target_stats(struct ath10k *ar, void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb);
struct wmi_stats_event *ev);
struct ath10k_fw_crash_data * struct ath10k_fw_crash_data *
ath10k_debug_get_new_fw_crash_data(struct ath10k *ar); ath10k_debug_get_new_fw_crash_data(struct ath10k *ar);
void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len); void ath10k_debug_dbglog_add(struct ath10k *ar, u8 *buffer, int len);
#define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++) #define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++)
void ath10k_debug_get_et_strings(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
u32 sset, u8 *data);
int ath10k_debug_get_et_sset_count(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, int sset);
void ath10k_debug_get_et_stats(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ethtool_stats *stats, u64 *data);
#else #else
static inline int ath10k_debug_start(struct ath10k *ar) static inline int ath10k_debug_start(struct ath10k *ar)
{ {
...@@ -93,13 +109,13 @@ static inline void ath10k_debug_unregister(struct ath10k *ar) ...@@ -93,13 +109,13 @@ static inline void ath10k_debug_unregister(struct ath10k *ar)
} }
static inline void ath10k_debug_read_service_map(struct ath10k *ar, static inline void ath10k_debug_read_service_map(struct ath10k *ar,
void *service_map, const void *service_map,
size_t map_size) size_t map_size)
{ {
} }
static inline void ath10k_debug_read_target_stats(struct ath10k *ar, static inline void ath10k_debug_fw_stats_process(struct ath10k *ar,
struct wmi_stats_event *ev) struct sk_buff *skb)
{ {
} }
...@@ -116,6 +132,10 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar) ...@@ -116,6 +132,10 @@ ath10k_debug_get_new_fw_crash_data(struct ath10k *ar)
#define ATH10K_DFS_STAT_INC(ar, c) do { } while (0) #define ATH10K_DFS_STAT_INC(ar, c) do { } while (0)
#define ath10k_debug_get_et_strings NULL
#define ath10k_debug_get_et_sset_count NULL
#define ath10k_debug_get_et_stats NULL
#endif /* CONFIG_ATH10K_DEBUGFS */ #endif /* CONFIG_ATH10K_DEBUGFS */
#ifdef CONFIG_ATH10K_DEBUG #ifdef CONFIG_ATH10K_DEBUG
......
...@@ -43,6 +43,10 @@ struct ath10k_hif_ops { ...@@ -43,6 +43,10 @@ struct ath10k_hif_ops {
int (*tx_sg)(struct ath10k *ar, u8 pipe_id, int (*tx_sg)(struct ath10k *ar, u8 pipe_id,
struct ath10k_hif_sg_item *items, int n_items); struct ath10k_hif_sg_item *items, int n_items);
/* read firmware memory through the diagnose interface */
int (*diag_read)(struct ath10k *ar, u32 address, void *buf,
size_t buf_len);
/* /*
* API to handle HIF-specific BMI message exchanges, this API is * API to handle HIF-specific BMI message exchanges, this API is
* synchronous and only allowed to be called from a context that * synchronous and only allowed to be called from a context that
...@@ -98,6 +102,12 @@ static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id, ...@@ -98,6 +102,12 @@ static inline int ath10k_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
return ar->hif.ops->tx_sg(ar, pipe_id, items, n_items); return ar->hif.ops->tx_sg(ar, pipe_id, items, n_items);
} }
static inline int ath10k_hif_diag_read(struct ath10k *ar, u32 address, void *buf,
size_t buf_len)
{
return ar->hif.ops->diag_read(ar, address, buf, buf_len);
}
static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar, static inline int ath10k_hif_exchange_bmi_msg(struct ath10k *ar,
void *request, u32 request_len, void *request, u32 request_len,
void *response, u32 *response_len) void *response, u32 *response_len)
......
...@@ -725,7 +725,7 @@ static inline u8 *htt_rx_test_get_chars(struct htt_rx_test *rx_test) ...@@ -725,7 +725,7 @@ static inline u8 *htt_rx_test_get_chars(struct htt_rx_test *rx_test)
*/ */
struct htt_pktlog_msg { struct htt_pktlog_msg {
u8 pad[3]; u8 pad[3];
__le32 payload[1 /* or more */]; u8 payload[0];
} __packed; } __packed;
struct htt_dbg_stats_rx_reorder_stats { struct htt_dbg_stats_rx_reorder_stats {
......
...@@ -291,6 +291,9 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt) ...@@ -291,6 +291,9 @@ static inline struct sk_buff *ath10k_htt_rx_netbuf_pop(struct ath10k_htt *htt)
htt->rx_ring.sw_rd_idx.msdu_payld = idx; htt->rx_ring.sw_rd_idx.msdu_payld = idx;
htt->rx_ring.fill_cnt--; htt->rx_ring.fill_cnt--;
trace_ath10k_htt_rx_pop_msdu(ar, msdu->data, msdu->len +
skb_tailroom(msdu));
return msdu; return msdu;
} }
...@@ -316,6 +319,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, ...@@ -316,6 +319,7 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
int msdu_len, msdu_chaining = 0; int msdu_len, msdu_chaining = 0;
struct sk_buff *msdu, *next; struct sk_buff *msdu, *next;
struct htt_rx_desc *rx_desc; struct htt_rx_desc *rx_desc;
u32 tsf;
lockdep_assert_held(&htt->rx_ring.lock); lockdep_assert_held(&htt->rx_ring.lock);
...@@ -447,6 +451,9 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt, ...@@ -447,6 +451,9 @@ static int ath10k_htt_rx_amsdu_pop(struct ath10k_htt *htt,
last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) & last_msdu = __le32_to_cpu(rx_desc->msdu_end.info0) &
RX_MSDU_END_INFO0_LAST_MSDU; RX_MSDU_END_INFO0_LAST_MSDU;
tsf = __le32_to_cpu(rx_desc->ppdu_end.tsf_timestamp);
trace_ath10k_htt_rx_desc(ar, tsf, &rx_desc->attention,
sizeof(*rx_desc) - sizeof(u32));
if (last_msdu) { if (last_msdu) {
msdu->next = NULL; msdu->next = NULL;
break; break;
...@@ -1674,6 +1681,15 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) ...@@ -1674,6 +1681,15 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
case HTT_T2H_MSG_TYPE_RX_DELBA: case HTT_T2H_MSG_TYPE_RX_DELBA:
ath10k_htt_rx_delba(ar, resp); ath10k_htt_rx_delba(ar, resp);
break; break;
case HTT_T2H_MSG_TYPE_PKTLOG: {
struct ath10k_pktlog_hdr *hdr =
(struct ath10k_pktlog_hdr *)resp->pktlog_msg.payload;
trace_ath10k_htt_pktlog(ar, resp->pktlog_msg.payload,
sizeof(*hdr) +
__le16_to_cpu(hdr->size));
break;
}
case HTT_T2H_MSG_TYPE_RX_FLUSH: { case HTT_T2H_MSG_TYPE_RX_FLUSH: {
/* Ignore this event because mac80211 takes care of Rx /* Ignore this event because mac80211 takes care of Rx
* aggregation reordering. * aggregation reordering.
...@@ -1681,8 +1697,8 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb) ...@@ -1681,8 +1697,8 @@ void ath10k_htt_t2h_msg_handler(struct ath10k *ar, struct sk_buff *skb)
break; break;
} }
default: default:
ath10k_dbg(ar, ATH10K_DBG_HTT, "htt event (%d) not handled\n", ath10k_warn(ar, "htt event (%d) not handled\n",
resp->hdr.msg_type); resp->hdr.msg_type);
ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ", ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt event: ",
skb->data, skb->len); skb->data, skb->len);
break; break;
......
...@@ -557,12 +557,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu) ...@@ -557,12 +557,14 @@ int ath10k_htt_tx(struct ath10k_htt *htt, struct sk_buff *msdu)
skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr); skb_cb->htt.txbuf->cmd_tx.frags_paddr = __cpu_to_le32(frags_paddr);
skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le32(HTT_INVALID_PEERID); skb_cb->htt.txbuf->cmd_tx.peerid = __cpu_to_le32(HTT_INVALID_PEERID);
trace_ath10k_htt_tx(ar, msdu_id, msdu->len, vdev_id, tid);
ath10k_dbg(ar, ATH10K_DBG_HTT, ath10k_dbg(ar, ATH10K_DBG_HTT,
"htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu\n", "htt tx flags0 %hhu flags1 %hu len %d id %hu frags_paddr %08x, msdu_paddr %08x vdev %hhu tid %hhu\n",
flags0, flags1, msdu->len, msdu_id, frags_paddr, flags0, flags1, msdu->len, msdu_id, frags_paddr,
(u32)skb_cb->paddr, vdev_id, tid); (u32)skb_cb->paddr, vdev_id, tid);
ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ", ath10k_dbg_dump(ar, ATH10K_DBG_HTT_DUMP, NULL, "htt tx msdu: ",
msdu->data, msdu->len); msdu->data, msdu->len);
trace_ath10k_htt_tx_msdu(ar, msdu->data, msdu->len);
sg_items[0].transfer_id = 0; sg_items[0].transfer_id = 0;
sg_items[0].transfer_context = NULL; sg_items[0].transfer_context = NULL;
......
...@@ -20,15 +20,16 @@ ...@@ -20,15 +20,16 @@
#include "targaddrs.h" #include "targaddrs.h"
#define ATH10K_FW_DIR "ath10k"
/* QCA988X 1.0 definitions (unsupported) */ /* QCA988X 1.0 definitions (unsupported) */
#define QCA988X_HW_1_0_CHIP_ID_REV 0x0 #define QCA988X_HW_1_0_CHIP_ID_REV 0x0
/* QCA988X 2.0 definitions */ /* QCA988X 2.0 definitions */
#define QCA988X_HW_2_0_VERSION 0x4100016c #define QCA988X_HW_2_0_VERSION 0x4100016c
#define QCA988X_HW_2_0_CHIP_ID_REV 0x2 #define QCA988X_HW_2_0_CHIP_ID_REV 0x2
#define QCA988X_HW_2_0_FW_DIR "ath10k/QCA988X/hw2.0" #define QCA988X_HW_2_0_FW_DIR ATH10K_FW_DIR "/QCA988X/hw2.0"
#define QCA988X_HW_2_0_FW_FILE "firmware.bin" #define QCA988X_HW_2_0_FW_FILE "firmware.bin"
#define QCA988X_HW_2_0_FW_3_FILE "firmware-3.bin"
#define QCA988X_HW_2_0_OTP_FILE "otp.bin" #define QCA988X_HW_2_0_OTP_FILE "otp.bin"
#define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin" #define QCA988X_HW_2_0_BOARD_DATA_FILE "board.bin"
#define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234 #define QCA988X_HW_2_0_PATCH_LOAD_ADDR 0x1234
...@@ -43,6 +44,8 @@ ...@@ -43,6 +44,8 @@
#define REG_DUMP_COUNT_QCA988X 60 #define REG_DUMP_COUNT_QCA988X 60
#define QCA988X_CAL_DATA_LEN 2116
struct ath10k_fw_ie { struct ath10k_fw_ie {
__le32 id; __le32 id;
__le32 len; __le32 len;
...@@ -78,6 +81,15 @@ enum ath10k_mcast2ucast_mode { ...@@ -78,6 +81,15 @@ enum ath10k_mcast2ucast_mode {
ATH10K_MCAST2UCAST_ENABLED = 1, ATH10K_MCAST2UCAST_ENABLED = 1,
}; };
struct ath10k_pktlog_hdr {
__le16 flags;
__le16 missed_cnt;
__le16 log_type;
__le16 size;
__le32 timestamp;
u8 payload[0];
} __packed;
/* Target specific defines for MAIN firmware */ /* Target specific defines for MAIN firmware */
#define TARGET_NUM_VDEVS 8 #define TARGET_NUM_VDEVS 8
#define TARGET_NUM_PEER_AST 2 #define TARGET_NUM_PEER_AST 2
...@@ -279,6 +291,7 @@ enum ath10k_mcast2ucast_mode { ...@@ -279,6 +291,7 @@ enum ath10k_mcast2ucast_mode {
#define SI_RX_DATA1_OFFSET 0x00000014 #define SI_RX_DATA1_OFFSET 0x00000014
#define CORE_CTRL_CPU_INTR_MASK 0x00002000 #define CORE_CTRL_CPU_INTR_MASK 0x00002000
#define CORE_CTRL_PCIE_REG_31_MASK 0x00000800
#define CORE_CTRL_ADDRESS 0x0000 #define CORE_CTRL_ADDRESS 0x0000
#define PCIE_INTR_ENABLE_ADDRESS 0x0008 #define PCIE_INTR_ENABLE_ADDRESS 0x0008
#define PCIE_INTR_CAUSE_ADDRESS 0x000c #define PCIE_INTR_CAUSE_ADDRESS 0x000c
......
This diff is collapsed.
...@@ -39,6 +39,7 @@ void ath10k_offchan_tx_work(struct work_struct *work); ...@@ -39,6 +39,7 @@ void ath10k_offchan_tx_work(struct work_struct *work);
void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar); void ath10k_mgmt_over_wmi_tx_purge(struct ath10k *ar);
void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work); void ath10k_mgmt_over_wmi_tx_work(struct work_struct *work);
void ath10k_halt(struct ath10k *ar); void ath10k_halt(struct ath10k *ar);
void ath10k_mac_vif_beacon_free(struct ath10k_vif *arvif);
static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif) static inline struct ath10k_vif *ath10k_vif_to_arvif(struct ieee80211_vif *vif)
{ {
......
This diff is collapsed.
...@@ -56,14 +56,14 @@ static uint8_t get_max_exp(s8 max_index, u16 max_magnitude, size_t bin_len, ...@@ -56,14 +56,14 @@ static uint8_t get_max_exp(s8 max_index, u16 max_magnitude, size_t bin_len,
} }
int ath10k_spectral_process_fft(struct ath10k *ar, int ath10k_spectral_process_fft(struct ath10k *ar,
struct wmi_single_phyerr_rx_event *event, const struct wmi_phyerr *phyerr,
struct phyerr_fft_report *fftr, const struct phyerr_fft_report *fftr,
size_t bin_len, u64 tsf) size_t bin_len, u64 tsf)
{ {
struct fft_sample_ath10k *fft_sample; struct fft_sample_ath10k *fft_sample;
u8 buf[sizeof(*fft_sample) + SPECTRAL_ATH10K_MAX_NUM_BINS]; u8 buf[sizeof(*fft_sample) + SPECTRAL_ATH10K_MAX_NUM_BINS];
u16 freq1, freq2, total_gain_db, base_pwr_db, length, peak_mag; u16 freq1, freq2, total_gain_db, base_pwr_db, length, peak_mag;
u32 reg0, reg1, nf_list1, nf_list2; u32 reg0, reg1;
u8 chain_idx, *bins; u8 chain_idx, *bins;
int dc_pos; int dc_pos;
...@@ -82,7 +82,7 @@ int ath10k_spectral_process_fft(struct ath10k *ar, ...@@ -82,7 +82,7 @@ int ath10k_spectral_process_fft(struct ath10k *ar,
/* TODO: there might be a reason why the hardware reports 20/40/80 MHz, /* TODO: there might be a reason why the hardware reports 20/40/80 MHz,
* but the results/plots suggest that its actually 22/44/88 MHz. * but the results/plots suggest that its actually 22/44/88 MHz.
*/ */
switch (event->hdr.chan_width_mhz) { switch (phyerr->chan_width_mhz) {
case 20: case 20:
fft_sample->chan_width_mhz = 22; fft_sample->chan_width_mhz = 22;
break; break;
...@@ -101,7 +101,7 @@ int ath10k_spectral_process_fft(struct ath10k *ar, ...@@ -101,7 +101,7 @@ int ath10k_spectral_process_fft(struct ath10k *ar,
fft_sample->chan_width_mhz = 88; fft_sample->chan_width_mhz = 88;
break; break;
default: default:
fft_sample->chan_width_mhz = event->hdr.chan_width_mhz; fft_sample->chan_width_mhz = phyerr->chan_width_mhz;
} }
fft_sample->relpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB); fft_sample->relpwr_db = MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB);
...@@ -110,36 +110,22 @@ int ath10k_spectral_process_fft(struct ath10k *ar, ...@@ -110,36 +110,22 @@ int ath10k_spectral_process_fft(struct ath10k *ar,
peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG); peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG);
fft_sample->max_magnitude = __cpu_to_be16(peak_mag); fft_sample->max_magnitude = __cpu_to_be16(peak_mag);
fft_sample->max_index = MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX); fft_sample->max_index = MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX);
fft_sample->rssi = event->hdr.rssi_combined; fft_sample->rssi = phyerr->rssi_combined;
total_gain_db = MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB); total_gain_db = MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB);
base_pwr_db = MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB); base_pwr_db = MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB);
fft_sample->total_gain_db = __cpu_to_be16(total_gain_db); fft_sample->total_gain_db = __cpu_to_be16(total_gain_db);
fft_sample->base_pwr_db = __cpu_to_be16(base_pwr_db); fft_sample->base_pwr_db = __cpu_to_be16(base_pwr_db);
freq1 = __le16_to_cpu(event->hdr.freq1); freq1 = __le16_to_cpu(phyerr->freq1);
freq2 = __le16_to_cpu(event->hdr.freq2); freq2 = __le16_to_cpu(phyerr->freq2);
fft_sample->freq1 = __cpu_to_be16(freq1); fft_sample->freq1 = __cpu_to_be16(freq1);
fft_sample->freq2 = __cpu_to_be16(freq2); fft_sample->freq2 = __cpu_to_be16(freq2);
nf_list1 = __le32_to_cpu(event->hdr.nf_list_1);
nf_list2 = __le32_to_cpu(event->hdr.nf_list_2);
chain_idx = MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX); chain_idx = MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX);
switch (chain_idx) { fft_sample->noise = __cpu_to_be16(
case 0: __le16_to_cpu(phyerr->nf_chains[chain_idx]));
fft_sample->noise = __cpu_to_be16(nf_list1 & 0xffffu);
break;
case 1:
fft_sample->noise = __cpu_to_be16((nf_list1 >> 16) & 0xffffu);
break;
case 2:
fft_sample->noise = __cpu_to_be16(nf_list2 & 0xffffu);
break;
case 3:
fft_sample->noise = __cpu_to_be16((nf_list2 >> 16) & 0xffffu);
break;
}
bins = (u8 *)fftr; bins = (u8 *)fftr;
bins += sizeof(*fftr); bins += sizeof(*fftr);
......
...@@ -47,8 +47,8 @@ enum ath10k_spectral_mode { ...@@ -47,8 +47,8 @@ enum ath10k_spectral_mode {
#ifdef CONFIG_ATH10K_DEBUGFS #ifdef CONFIG_ATH10K_DEBUGFS
int ath10k_spectral_process_fft(struct ath10k *ar, int ath10k_spectral_process_fft(struct ath10k *ar,
struct wmi_single_phyerr_rx_event *event, const struct wmi_phyerr *phyerr,
struct phyerr_fft_report *fftr, const struct phyerr_fft_report *fftr,
size_t bin_len, u64 tsf); size_t bin_len, u64 tsf);
int ath10k_spectral_start(struct ath10k *ar); int ath10k_spectral_start(struct ath10k *ar);
int ath10k_spectral_vif_stop(struct ath10k_vif *arvif); int ath10k_spectral_vif_stop(struct ath10k_vif *arvif);
...@@ -59,8 +59,8 @@ void ath10k_spectral_destroy(struct ath10k *ar); ...@@ -59,8 +59,8 @@ void ath10k_spectral_destroy(struct ath10k *ar);
static inline int static inline int
ath10k_spectral_process_fft(struct ath10k *ar, ath10k_spectral_process_fft(struct ath10k *ar,
struct wmi_single_phyerr_rx_event *event, const struct wmi_phyerr *phyerr,
struct phyerr_fft_report *fftr, const struct phyerr_fft_report *fftr,
size_t bin_len, u64 tsf) size_t bin_len, u64 tsf)
{ {
return 0; return 0;
......
This diff is collapsed.
...@@ -78,6 +78,7 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt, ...@@ -78,6 +78,7 @@ void ath10k_txrx_tx_unref(struct ath10k_htt *htt,
info = IEEE80211_SKB_CB(msdu); info = IEEE80211_SKB_CB(msdu);
memset(&info->status, 0, sizeof(info->status)); memset(&info->status, 0, sizeof(info->status));
trace_ath10k_txrx_tx_unref(ar, tx_done->msdu_id);
if (tx_done->discard) { if (tx_done->discard) {
ieee80211_free_txskb(htt->ar->hw, msdu); ieee80211_free_txskb(htt->ar->hw, msdu);
......
This diff is collapsed.
This diff is collapsed.
...@@ -2976,11 +2976,11 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev) ...@@ -2976,11 +2976,11 @@ static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev, static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
const u8 *mac) struct station_del_parameters *params)
{ {
struct ath6kl *ar = ath6kl_priv(dev); struct ath6kl *ar = ath6kl_priv(dev);
struct ath6kl_vif *vif = netdev_priv(dev); struct ath6kl_vif *vif = netdev_priv(dev);
const u8 *addr = mac ? mac : bcast_addr; const u8 *addr = params->mac ? params->mac : bcast_addr;
return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH, return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
addr, WLAN_REASON_PREV_AUTH_NOT_VALID); addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#define ATH6KL_MAX_IE 256 #define ATH6KL_MAX_IE 256
__printf(2, 3) int ath6kl_printk(const char *level, const char *fmt, ...); __printf(2, 3) void ath6kl_printk(const char *level, const char *fmt, ...);
/* /*
* Reflects the version of binary interface exposed by ATH6KL target * Reflects the version of binary interface exposed by ATH6KL target
......
This diff is collapsed.
This diff is collapsed.
...@@ -148,6 +148,11 @@ config ATH9K_CHANNEL_CONTEXT ...@@ -148,6 +148,11 @@ config ATH9K_CHANNEL_CONTEXT
for multi-channel concurrency. Enable this if P2P PowerSave support for multi-channel concurrency. Enable this if P2P PowerSave support
is required. is required.
config ATH9K_PCOEM
bool "Atheros ath9k support for PC OEM cards" if EXPERT
depends on ATH9K
default y
config ATH9K_HTC config ATH9K_HTC
tristate "Atheros HTC based wireless cards support" tristate "Atheros HTC based wireless cards support"
depends on USB && MAC80211 depends on USB && MAC80211
......
This diff is collapsed.
This diff is collapsed.
...@@ -670,9 +670,6 @@ static void ar9003_tx_gain_table_mode5(struct ath_hw *ah) ...@@ -670,9 +670,6 @@ static void ar9003_tx_gain_table_mode5(struct ath_hw *ah)
if (AR_SREV_9485_11_OR_LATER(ah)) if (AR_SREV_9485_11_OR_LATER(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain, INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9485Modes_green_ob_db_tx_gain_1_1); ar9485Modes_green_ob_db_tx_gain_1_1);
else if (AR_SREV_9340(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9340Modes_ub124_tx_gain_table_1p0);
else if (AR_SREV_9580(ah)) else if (AR_SREV_9580(ah))
INIT_INI_ARRAY(&ah->iniModesTxGain, INIT_INI_ARRAY(&ah->iniModesTxGain,
ar9580_1p0_type5_tx_gain_table); ar9580_1p0_type5_tx_gain_table);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment