mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
Merge remote-tracking branch 'wireless-next/master' into iwlwifi-next
This commit is contained in:
@@ -17,10 +17,12 @@ HCI
|
||||
HCI registers as an nfc device with NFC Core. Requests coming from userspace are
|
||||
routed through netlink sockets to NFC Core and then to HCI. From this point,
|
||||
they are translated in a sequence of HCI commands sent to the HCI layer in the
|
||||
host controller (the chip). The sending context blocks while waiting for the
|
||||
response to arrive.
|
||||
host controller (the chip). Commands can be executed synchronously (the sending
|
||||
context blocks waiting for response) or asynchronously (the response is returned
|
||||
from HCI Rx context).
|
||||
HCI events can also be received from the host controller. They will be handled
|
||||
and a translation will be forwarded to NFC Core as needed.
|
||||
and a translation will be forwarded to NFC Core as needed. There are hooks to
|
||||
let the HCI driver handle proprietary events or override standard behavior.
|
||||
HCI uses 2 execution contexts:
|
||||
- one for executing commands : nfc_hci_msg_tx_work(). Only one command
|
||||
can be executing at any given moment.
|
||||
@@ -33,6 +35,8 @@ The Session initialization is an HCI standard which must unfortunately
|
||||
support proprietary gates. This is the reason why the driver will pass a list
|
||||
of proprietary gates that must be part of the session. HCI will ensure all
|
||||
those gates have pipes connected when the hci device is set up.
|
||||
In case the chip supports pre-opened gates and pseudo-static pipes, the driver
|
||||
can pass that information to HCI core.
|
||||
|
||||
HCI Gates and Pipes
|
||||
-------------------
|
||||
@@ -46,6 +50,13 @@ without knowing the pipe connected to it.
|
||||
Driver interface
|
||||
----------------
|
||||
|
||||
A driver is generally written in two parts : the physical link management and
|
||||
the HCI management. This makes it easier to maintain a driver for a chip that
|
||||
can be connected using various phy (i2c, spi, ...)
|
||||
|
||||
HCI Management
|
||||
--------------
|
||||
|
||||
A driver would normally register itself with HCI and provide the following
|
||||
entry points:
|
||||
|
||||
@@ -53,58 +64,113 @@ struct nfc_hci_ops {
|
||||
int (*open)(struct nfc_hci_dev *hdev);
|
||||
void (*close)(struct nfc_hci_dev *hdev);
|
||||
int (*hci_ready) (struct nfc_hci_dev *hdev);
|
||||
int (*xmit)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
|
||||
int (*start_poll)(struct nfc_hci_dev *hdev, u32 protocols);
|
||||
int (*target_from_gate)(struct nfc_hci_dev *hdev, u8 gate,
|
||||
struct nfc_target *target);
|
||||
int (*xmit) (struct nfc_hci_dev *hdev, struct sk_buff *skb);
|
||||
int (*start_poll) (struct nfc_hci_dev *hdev,
|
||||
u32 im_protocols, u32 tm_protocols);
|
||||
int (*dep_link_up)(struct nfc_hci_dev *hdev, struct nfc_target *target,
|
||||
u8 comm_mode, u8 *gb, size_t gb_len);
|
||||
int (*dep_link_down)(struct nfc_hci_dev *hdev);
|
||||
int (*target_from_gate) (struct nfc_hci_dev *hdev, u8 gate,
|
||||
struct nfc_target *target);
|
||||
int (*complete_target_discovered) (struct nfc_hci_dev *hdev, u8 gate,
|
||||
struct nfc_target *target);
|
||||
int (*data_exchange) (struct nfc_hci_dev *hdev,
|
||||
struct nfc_target *target,
|
||||
struct sk_buff *skb, struct sk_buff **res_skb);
|
||||
int (*im_transceive) (struct nfc_hci_dev *hdev,
|
||||
struct nfc_target *target, struct sk_buff *skb,
|
||||
data_exchange_cb_t cb, void *cb_context);
|
||||
int (*tm_send)(struct nfc_hci_dev *hdev, struct sk_buff *skb);
|
||||
int (*check_presence)(struct nfc_hci_dev *hdev,
|
||||
struct nfc_target *target);
|
||||
int (*event_received)(struct nfc_hci_dev *hdev, u8 gate, u8 event,
|
||||
struct sk_buff *skb);
|
||||
};
|
||||
|
||||
- open() and close() shall turn the hardware on and off.
|
||||
- hci_ready() is an optional entry point that is called right after the hci
|
||||
session has been set up. The driver can use it to do additional initialization
|
||||
that must be performed using HCI commands.
|
||||
- xmit() shall simply write a frame to the chip.
|
||||
- xmit() shall simply write a frame to the physical link.
|
||||
- start_poll() is an optional entrypoint that shall set the hardware in polling
|
||||
mode. This must be implemented only if the hardware uses proprietary gates or a
|
||||
mechanism slightly different from the HCI standard.
|
||||
- dep_link_up() is called after a p2p target has been detected, to finish
|
||||
the p2p connection setup with hardware parameters that need to be passed back
|
||||
to nfc core.
|
||||
- dep_link_down() is called to bring the p2p link down.
|
||||
- target_from_gate() is an optional entrypoint to return the nfc protocols
|
||||
corresponding to a proprietary gate.
|
||||
- complete_target_discovered() is an optional entry point to let the driver
|
||||
perform additional proprietary processing necessary to auto activate the
|
||||
discovered target.
|
||||
- data_exchange() must be implemented by the driver if proprietary HCI commands
|
||||
- im_transceive() must be implemented by the driver if proprietary HCI commands
|
||||
are required to send data to the tag. Some tag types will require custom
|
||||
commands, others can be written to using the standard HCI commands. The driver
|
||||
can check the tag type and either do proprietary processing, or return 1 to ask
|
||||
for standard processing.
|
||||
for standard processing. The data exchange command itself must be sent
|
||||
asynchronously.
|
||||
- tm_send() is called to send data in the case of a p2p connection
|
||||
- check_presence() is an optional entry point that will be called regularly
|
||||
by the core to check that an activated tag is still in the field. If this is
|
||||
not implemented, the core will not be able to push tag_lost events to the user
|
||||
space
|
||||
- event_received() is called to handle an event coming from the chip. Driver
|
||||
can handle the event or return 1 to let HCI attempt standard processing.
|
||||
|
||||
On the rx path, the driver is responsible to push incoming HCP frames to HCI
|
||||
using nfc_hci_recv_frame(). HCI will take care of re-aggregation and handling
|
||||
This must be done from a context that can sleep.
|
||||
|
||||
SHDLC
|
||||
-----
|
||||
PHY Management
|
||||
--------------
|
||||
|
||||
Most chips use shdlc to ensure integrity and delivery ordering of the HCP
|
||||
frames between the host controller (the chip) and hosts (entities connected
|
||||
to the chip, like the cpu). In order to simplify writing the driver, an shdlc
|
||||
layer is available for use by the driver.
|
||||
When used, the driver actually registers with shdlc, and shdlc will register
|
||||
with HCI. HCI sees shdlc as the driver and thus send its HCP frames
|
||||
through shdlc->xmit.
|
||||
SHDLC adds a new execution context (nfc_shdlc_sm_work()) to run its state
|
||||
machine and handle both its rx and tx path.
|
||||
The physical link (i2c, ...) management is defined by the following struture:
|
||||
|
||||
struct nfc_phy_ops {
|
||||
int (*write)(void *dev_id, struct sk_buff *skb);
|
||||
int (*enable)(void *dev_id);
|
||||
void (*disable)(void *dev_id);
|
||||
};
|
||||
|
||||
enable(): turn the phy on (power on), make it ready to transfer data
|
||||
disable(): turn the phy off
|
||||
write(): Send a data frame to the chip. Note that to enable higher
|
||||
layers such as an llc to store the frame for re-emission, this function must
|
||||
not alter the skb. It must also not return a positive result (return 0 for
|
||||
success, negative for failure).
|
||||
|
||||
Data coming from the chip shall be sent directly to nfc_hci_recv_frame().
|
||||
|
||||
LLC
|
||||
---
|
||||
|
||||
Communication between the CPU and the chip often requires some link layer
|
||||
protocol. Those are isolated as modules managed by the HCI layer. There are
|
||||
currently two modules : nop (raw transfert) and shdlc.
|
||||
A new llc must implement the following functions:
|
||||
|
||||
struct nfc_llc_ops {
|
||||
void *(*init) (struct nfc_hci_dev *hdev, xmit_to_drv_t xmit_to_drv,
|
||||
rcv_to_hci_t rcv_to_hci, int tx_headroom,
|
||||
int tx_tailroom, int *rx_headroom, int *rx_tailroom,
|
||||
llc_failure_t llc_failure);
|
||||
void (*deinit) (struct nfc_llc *llc);
|
||||
int (*start) (struct nfc_llc *llc);
|
||||
int (*stop) (struct nfc_llc *llc);
|
||||
void (*rcv_from_drv) (struct nfc_llc *llc, struct sk_buff *skb);
|
||||
int (*xmit_from_hci) (struct nfc_llc *llc, struct sk_buff *skb);
|
||||
};
|
||||
|
||||
- init() : allocate and init your private storage
|
||||
- deinit() : cleanup
|
||||
- start() : establish the logical connection
|
||||
- stop () : terminate the logical connection
|
||||
- rcv_from_drv() : handle data coming from the chip, going to HCI
|
||||
- xmit_from_hci() : handle data sent by HCI, going to the chip
|
||||
|
||||
The llc must be registered with nfc before it can be used. Do that by
|
||||
calling nfc_llc_register(const char *name, struct nfc_llc_ops *ops);
|
||||
|
||||
Again, note that the llc does not handle the physical link. It is thus very
|
||||
easy to mix any physical link with any llc for a given chip driver.
|
||||
|
||||
Included Drivers
|
||||
----------------
|
||||
@@ -117,10 +183,12 @@ Execution Contexts
|
||||
|
||||
The execution contexts are the following:
|
||||
- IRQ handler (IRQH):
|
||||
fast, cannot sleep. stores incoming frames into an shdlc rx queue
|
||||
fast, cannot sleep. sends incoming frames to HCI where they are passed to
|
||||
the current llc. In case of shdlc, the frame is queued in shdlc rx queue.
|
||||
|
||||
- SHDLC State Machine worker (SMW)
|
||||
handles shdlc rx & tx queues. Dispatches HCI cmd responses.
|
||||
Only when llc_shdlc is used: handles shdlc rx & tx queues.
|
||||
Dispatches HCI cmd responses.
|
||||
|
||||
- HCI Tx Cmd worker (MSGTXWQ)
|
||||
Serializes execution of HCI commands. Completes execution in case of response
|
||||
@@ -166,6 +234,15 @@ waiting command execution. Response processing involves invoking the completion
|
||||
callback that was provided by nfc_hci_msg_tx_work() when it sent the command.
|
||||
The completion callback will then wake the syscall context.
|
||||
|
||||
It is also possible to execute the command asynchronously using this API:
|
||||
|
||||
static int nfc_hci_execute_cmd_async(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
|
||||
const u8 *param, size_t param_len,
|
||||
data_exchange_cb_t cb, void *cb_context)
|
||||
|
||||
The workflow is the same, except that the API call returns immediately, and
|
||||
the callback will be called with the result from the SMW context.
|
||||
|
||||
Workflow receiving an HCI event or command
|
||||
------------------------------------------
|
||||
|
||||
|
||||
@@ -1,32 +1,15 @@
|
||||
Kernel driver for the NXP Semiconductors PN544 Near Field
|
||||
Communication chip
|
||||
|
||||
Author: Jari Vanhala
|
||||
Contact: Matti Aaltonen (matti.j.aaltonen at nokia.com)
|
||||
|
||||
General
|
||||
-------
|
||||
|
||||
The PN544 is an integrated transmission module for contactless
|
||||
communication. The driver goes under drives/nfc/ and is compiled as a
|
||||
module named "pn544". It registers a misc device and creates a device
|
||||
file named "/dev/pn544".
|
||||
module named "pn544".
|
||||
|
||||
Host Interfaces: I2C, SPI and HSU, this driver supports currently only I2C.
|
||||
|
||||
The Interface
|
||||
-------------
|
||||
|
||||
The driver offers a sysfs interface for a hardware test and an IOCTL
|
||||
interface for selecting between two operating modes. There are read,
|
||||
write and poll functions for transferring messages. The two operating
|
||||
modes are the normal (HCI) mode and the firmware update mode.
|
||||
|
||||
PN544 is controlled by sending messages from the userspace to the
|
||||
chip. The main function of the driver is just to pass those messages
|
||||
without caring about the message content.
|
||||
|
||||
|
||||
Protocols
|
||||
---------
|
||||
|
||||
@@ -47,68 +30,3 @@ and third (LSB) bytes of the message. The maximum FW message length is
|
||||
|
||||
For the ETSI HCI specification see
|
||||
http://www.etsi.org/WebSite/Technologies/ProtocolSpecification.aspx
|
||||
|
||||
The Hardware Test
|
||||
-----------------
|
||||
|
||||
The idea of the test is that it can performed by reading from the
|
||||
corresponding sysfs file. The test is implemented in the board file
|
||||
and it should test that PN544 can be put into the firmware update
|
||||
mode. If the test is not implemented the sysfs file does not get
|
||||
created.
|
||||
|
||||
Example:
|
||||
> cat /sys/module/pn544/drivers/i2c\:pn544/3-002b/nfc_test
|
||||
1
|
||||
|
||||
Normal Operation
|
||||
----------------
|
||||
|
||||
PN544 is powered up when the device file is opened, otherwise it's
|
||||
turned off. Only one instance can use the device at a time.
|
||||
|
||||
Userspace applications control PN544 with HCI messages. The hardware
|
||||
sends an interrupt when data is available for reading. Data is
|
||||
physically read when the read function is called by a userspace
|
||||
application. Poll() checks the read interrupt state. Configuration and
|
||||
self testing are also done from the userspace using read and write.
|
||||
|
||||
Example platform data:
|
||||
|
||||
static int rx71_pn544_nfc_request_resources(struct i2c_client *client)
|
||||
{
|
||||
/* Get and setup the HW resources for the device */
|
||||
}
|
||||
|
||||
static void rx71_pn544_nfc_free_resources(void)
|
||||
{
|
||||
/* Release the HW resources */
|
||||
}
|
||||
|
||||
static void rx71_pn544_nfc_enable(int fw)
|
||||
{
|
||||
/* Turn the device on */
|
||||
}
|
||||
|
||||
static int rx71_pn544_nfc_test(void)
|
||||
{
|
||||
/*
|
||||
* Put the device into the FW update mode
|
||||
* and then back to the normal mode.
|
||||
* Check the behavior and return one on success,
|
||||
* zero on failure.
|
||||
*/
|
||||
}
|
||||
|
||||
static void rx71_pn544_nfc_disable(void)
|
||||
{
|
||||
/* turn the power off */
|
||||
}
|
||||
|
||||
static struct pn544_nfc_platform_data rx71_nfc_data = {
|
||||
.request_resources = rx71_pn544_nfc_request_resources,
|
||||
.free_resources = rx71_pn544_nfc_free_resources,
|
||||
.enable = rx71_pn544_nfc_enable,
|
||||
.test = rx71_pn544_nfc_test,
|
||||
.disable = rx71_pn544_nfc_disable,
|
||||
};
|
||||
|
||||
@@ -1353,6 +1353,14 @@ W: http://wireless.kernel.org/en/users/Drivers/ath9k
|
||||
S: Supported
|
||||
F: drivers/net/wireless/ath/ath9k/
|
||||
|
||||
WILOCITY WIL6210 WIRELESS DRIVER
|
||||
M: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
L: wil6210@qca.qualcomm.com
|
||||
S: Supported
|
||||
W: http://wireless.kernel.org/en/users/Drivers/wil6210
|
||||
F: drivers/net/wireless/ath/wil6210/
|
||||
|
||||
CARL9170 LINUX COMMUNITY WIRELESS DRIVER
|
||||
M: Christian Lamparter <chunkeey@googlemail.com>
|
||||
L: linux-wireless@vger.kernel.org
|
||||
|
||||
@@ -62,7 +62,7 @@ static int __init uart8250_init_bcma(void)
|
||||
|
||||
p->mapbase = (unsigned int) bcma_port->regs;
|
||||
p->membase = (void *) bcma_port->regs;
|
||||
p->irq = bcma_port->irq + 2;
|
||||
p->irq = bcma_port->irq;
|
||||
p->uartclk = bcma_port->baud_base;
|
||||
p->regshift = bcma_port->reg_shift;
|
||||
p->iotype = UPIO_MEM;
|
||||
|
||||
@@ -67,8 +67,7 @@ config BCMA_DRIVER_GMAC_CMN
|
||||
|
||||
config BCMA_DRIVER_GPIO
|
||||
bool "BCMA GPIO driver"
|
||||
depends on BCMA
|
||||
select GPIOLIB
|
||||
depends on BCMA && GPIOLIB
|
||||
help
|
||||
Driver to provide access to the GPIO pins of the bcma bus.
|
||||
|
||||
|
||||
@@ -31,6 +31,8 @@ int __init bcma_bus_early_register(struct bcma_bus *bus,
|
||||
int bcma_bus_suspend(struct bcma_bus *bus);
|
||||
int bcma_bus_resume(struct bcma_bus *bus);
|
||||
#endif
|
||||
struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
|
||||
u8 unit);
|
||||
|
||||
/* scan.c */
|
||||
int bcma_bus_scan(struct bcma_bus *bus);
|
||||
@@ -45,6 +47,7 @@ int bcma_sprom_get(struct bcma_bus *bus);
|
||||
/* driver_chipcommon.c */
|
||||
#ifdef CONFIG_BCMA_DRIVER_MIPS
|
||||
void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
|
||||
extern struct platform_device bcma_pflash_dev;
|
||||
#endif /* CONFIG_BCMA_DRIVER_MIPS */
|
||||
|
||||
/* driver_chipcommon_pmu.c */
|
||||
|
||||
@@ -329,7 +329,7 @@ void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
|
||||
return;
|
||||
}
|
||||
|
||||
irq = bcma_core_mips_irq(cc->core);
|
||||
irq = bcma_core_irq(cc->core);
|
||||
|
||||
/* Determine the registers of the UARTs */
|
||||
cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
|
||||
|
||||
@@ -35,7 +35,7 @@ static struct bcma_sflash_tbl_e bcma_sflash_st_tbl[] = {
|
||||
{ "M25P40", 0x12, 0x10000, 8, },
|
||||
|
||||
{ "M25P16", 0x14, 0x10000, 32, },
|
||||
{ "M25P32", 0x14, 0x10000, 64, },
|
||||
{ "M25P32", 0x15, 0x10000, 64, },
|
||||
{ "M25P64", 0x16, 0x10000, 128, },
|
||||
{ "M25FL128", 0x17, 0x10000, 256, },
|
||||
{ 0 },
|
||||
|
||||
@@ -73,6 +73,16 @@ static void bcma_gpio_free(struct gpio_chip *chip, unsigned gpio)
|
||||
bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
|
||||
}
|
||||
|
||||
static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
|
||||
{
|
||||
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
|
||||
|
||||
if (cc->core->bus->hosttype == BCMA_HOSTTYPE_SOC)
|
||||
return bcma_core_irq(cc->core);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int bcma_gpio_init(struct bcma_drv_cc *cc)
|
||||
{
|
||||
struct gpio_chip *chip = &cc->gpio;
|
||||
@@ -85,6 +95,7 @@ int bcma_gpio_init(struct bcma_drv_cc *cc)
|
||||
chip->set = bcma_gpio_set_value;
|
||||
chip->direction_input = bcma_gpio_direction_input;
|
||||
chip->direction_output = bcma_gpio_direction_output;
|
||||
chip->to_irq = bcma_gpio_to_irq;
|
||||
chip->ngpio = 16;
|
||||
/* There is just one SoC in one device and its GPIO addresses should be
|
||||
* deterministic to address them more easily. The other buses could get
|
||||
|
||||
@@ -14,11 +14,33 @@
|
||||
|
||||
#include <linux/bcma/bcma.h>
|
||||
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/serial_reg.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
static const char *part_probes[] = { "bcm47xxpart", NULL };
|
||||
|
||||
static struct physmap_flash_data bcma_pflash_data = {
|
||||
.part_probe_types = part_probes,
|
||||
};
|
||||
|
||||
static struct resource bcma_pflash_resource = {
|
||||
.name = "bcma_pflash",
|
||||
.flags = IORESOURCE_MEM,
|
||||
};
|
||||
|
||||
struct platform_device bcma_pflash_dev = {
|
||||
.name = "physmap-flash",
|
||||
.dev = {
|
||||
.platform_data = &bcma_pflash_data,
|
||||
},
|
||||
.resource = &bcma_pflash_resource,
|
||||
.num_resources = 1,
|
||||
};
|
||||
|
||||
/* The 47162a0 hangs when reading MIPS DMP registers registers */
|
||||
static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
|
||||
{
|
||||
@@ -74,28 +96,41 @@ static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
|
||||
return dev->core_index;
|
||||
flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
|
||||
|
||||
return flag & 0x1F;
|
||||
if (flag)
|
||||
return flag & 0x1F;
|
||||
else
|
||||
return 0x3f;
|
||||
}
|
||||
|
||||
/* Get the MIPS IRQ assignment for a specified device.
|
||||
* If unassigned, 0 is returned.
|
||||
* If disabled, 5 is returned.
|
||||
* If not supported, 6 is returned.
|
||||
*/
|
||||
unsigned int bcma_core_mips_irq(struct bcma_device *dev)
|
||||
static unsigned int bcma_core_mips_irq(struct bcma_device *dev)
|
||||
{
|
||||
struct bcma_device *mdev = dev->bus->drv_mips.core;
|
||||
u32 irqflag;
|
||||
unsigned int irq;
|
||||
|
||||
irqflag = bcma_core_mips_irqflag(dev);
|
||||
if (irqflag == 0x3f)
|
||||
return 6;
|
||||
|
||||
for (irq = 1; irq <= 4; irq++)
|
||||
for (irq = 0; irq <= 4; irq++)
|
||||
if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
|
||||
(1 << irqflag))
|
||||
return irq;
|
||||
|
||||
return 0;
|
||||
return 5;
|
||||
}
|
||||
EXPORT_SYMBOL(bcma_core_mips_irq);
|
||||
|
||||
unsigned int bcma_core_irq(struct bcma_device *dev)
|
||||
{
|
||||
unsigned int mips_irq = bcma_core_mips_irq(dev);
|
||||
return mips_irq <= 4 ? mips_irq + 2 : 0;
|
||||
}
|
||||
EXPORT_SYMBOL(bcma_core_irq);
|
||||
|
||||
static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
|
||||
{
|
||||
@@ -114,7 +149,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
|
||||
bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
|
||||
bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
|
||||
~(1 << irqflag));
|
||||
else
|
||||
else if (oldirq != 5)
|
||||
bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(oldirq), 0);
|
||||
|
||||
/* assign the new one */
|
||||
@@ -123,9 +158,9 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
|
||||
bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
|
||||
(1 << irqflag));
|
||||
} else {
|
||||
u32 oldirqflag = bcma_read32(mdev,
|
||||
BCMA_MIPS_MIPS74K_INTMASK(irq));
|
||||
if (oldirqflag) {
|
||||
u32 irqinitmask = bcma_read32(mdev,
|
||||
BCMA_MIPS_MIPS74K_INTMASK(irq));
|
||||
if (irqinitmask) {
|
||||
struct bcma_device *core;
|
||||
|
||||
/* backplane irq line is in use, find out who uses
|
||||
@@ -133,7 +168,7 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
|
||||
*/
|
||||
list_for_each_entry(core, &bus->cores, list) {
|
||||
if ((1 << bcma_core_mips_irqflag(core)) ==
|
||||
oldirqflag) {
|
||||
irqinitmask) {
|
||||
bcma_core_mips_set_irq(core, 0);
|
||||
break;
|
||||
}
|
||||
@@ -143,15 +178,31 @@ static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
|
||||
1 << irqflag);
|
||||
}
|
||||
|
||||
bcma_info(bus, "set_irq: core 0x%04x, irq %d => %d\n",
|
||||
dev->id.id, oldirq + 2, irq + 2);
|
||||
bcma_debug(bus, "set_irq: core 0x%04x, irq %d => %d\n",
|
||||
dev->id.id, oldirq <= 4 ? oldirq + 2 : 0, irq + 2);
|
||||
}
|
||||
|
||||
static void bcma_core_mips_set_irq_name(struct bcma_bus *bus, unsigned int irq,
|
||||
u16 coreid, u8 unit)
|
||||
{
|
||||
struct bcma_device *core;
|
||||
|
||||
core = bcma_find_core_unit(bus, coreid, unit);
|
||||
if (!core) {
|
||||
bcma_warn(bus,
|
||||
"Can not find core (id: 0x%x, unit %i) for IRQ configuration.\n",
|
||||
coreid, unit);
|
||||
return;
|
||||
}
|
||||
|
||||
bcma_core_mips_set_irq(core, irq);
|
||||
}
|
||||
|
||||
static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
|
||||
{
|
||||
int i;
|
||||
static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
|
||||
printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
|
||||
printk(KERN_DEBUG KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
|
||||
for (i = 0; i <= 6; i++)
|
||||
printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
|
||||
printk("\n");
|
||||
@@ -182,6 +233,7 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
|
||||
{
|
||||
struct bcma_bus *bus = mcore->core->bus;
|
||||
struct bcma_drv_cc *cc = &bus->drv_cc;
|
||||
struct bcma_pflash *pflash = &cc->pflash;
|
||||
|
||||
switch (cc->capabilities & BCMA_CC_CAP_FLASHT) {
|
||||
case BCMA_CC_FLASHT_STSER:
|
||||
@@ -191,15 +243,20 @@ static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
|
||||
break;
|
||||
case BCMA_CC_FLASHT_PARA:
|
||||
bcma_debug(bus, "Found parallel flash\n");
|
||||
cc->pflash.present = true;
|
||||
cc->pflash.window = BCMA_SOC_FLASH2;
|
||||
cc->pflash.window_size = BCMA_SOC_FLASH2_SZ;
|
||||
pflash->present = true;
|
||||
pflash->window = BCMA_SOC_FLASH2;
|
||||
pflash->window_size = BCMA_SOC_FLASH2_SZ;
|
||||
|
||||
if ((bcma_read32(cc->core, BCMA_CC_FLASH_CFG) &
|
||||
BCMA_CC_FLASH_CFG_DS) == 0)
|
||||
cc->pflash.buswidth = 1;
|
||||
pflash->buswidth = 1;
|
||||
else
|
||||
cc->pflash.buswidth = 2;
|
||||
pflash->buswidth = 2;
|
||||
|
||||
bcma_pflash_data.width = pflash->buswidth;
|
||||
bcma_pflash_resource.start = pflash->window;
|
||||
bcma_pflash_resource.end = pflash->window + pflash->window_size;
|
||||
|
||||
break;
|
||||
default:
|
||||
bcma_err(bus, "Flash type not supported\n");
|
||||
@@ -227,6 +284,32 @@ void bcma_core_mips_early_init(struct bcma_drv_mips *mcore)
|
||||
mcore->early_setup_done = true;
|
||||
}
|
||||
|
||||
static void bcma_fix_i2s_irqflag(struct bcma_bus *bus)
|
||||
{
|
||||
struct bcma_device *cpu, *pcie, *i2s;
|
||||
|
||||
/* Fixup the interrupts in 4716/4748 for i2s core (2010 Broadcom SDK)
|
||||
* (IRQ flags > 7 are ignored when setting the interrupt masks)
|
||||
*/
|
||||
if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4716 &&
|
||||
bus->chipinfo.id != BCMA_CHIP_ID_BCM4748)
|
||||
return;
|
||||
|
||||
cpu = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
|
||||
pcie = bcma_find_core(bus, BCMA_CORE_PCIE);
|
||||
i2s = bcma_find_core(bus, BCMA_CORE_I2S);
|
||||
if (cpu && pcie && i2s &&
|
||||
bcma_aread32(cpu, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
|
||||
bcma_aread32(pcie, BCMA_MIPS_OOBSELINA74) == 0x08060504 &&
|
||||
bcma_aread32(i2s, BCMA_MIPS_OOBSELOUTA30) == 0x88) {
|
||||
bcma_awrite32(cpu, BCMA_MIPS_OOBSELINA74, 0x07060504);
|
||||
bcma_awrite32(pcie, BCMA_MIPS_OOBSELINA74, 0x07060504);
|
||||
bcma_awrite32(i2s, BCMA_MIPS_OOBSELOUTA30, 0x87);
|
||||
bcma_debug(bus,
|
||||
"Moved i2s interrupt to oob line 7 instead of 8\n");
|
||||
}
|
||||
}
|
||||
|
||||
void bcma_core_mips_init(struct bcma_drv_mips *mcore)
|
||||
{
|
||||
struct bcma_bus *bus;
|
||||
@@ -236,43 +319,55 @@ void bcma_core_mips_init(struct bcma_drv_mips *mcore)
|
||||
if (mcore->setup_done)
|
||||
return;
|
||||
|
||||
bcma_info(bus, "Initializing MIPS core...\n");
|
||||
bcma_debug(bus, "Initializing MIPS core...\n");
|
||||
|
||||
bcma_core_mips_early_init(mcore);
|
||||
|
||||
mcore->assigned_irqs = 1;
|
||||
bcma_fix_i2s_irqflag(bus);
|
||||
|
||||
/* Assign IRQs to all cores on the bus */
|
||||
list_for_each_entry(core, &bus->cores, list) {
|
||||
int mips_irq;
|
||||
if (core->irq)
|
||||
continue;
|
||||
|
||||
mips_irq = bcma_core_mips_irq(core);
|
||||
if (mips_irq > 4)
|
||||
core->irq = 0;
|
||||
else
|
||||
core->irq = mips_irq + 2;
|
||||
if (core->irq > 5)
|
||||
continue;
|
||||
switch (core->id.id) {
|
||||
case BCMA_CORE_PCI:
|
||||
case BCMA_CORE_PCIE:
|
||||
case BCMA_CORE_ETHERNET:
|
||||
case BCMA_CORE_ETHERNET_GBIT:
|
||||
case BCMA_CORE_MAC_GBIT:
|
||||
case BCMA_CORE_80211:
|
||||
case BCMA_CORE_USB20_HOST:
|
||||
/* These devices get their own IRQ line if available,
|
||||
* the rest goes on IRQ0
|
||||
*/
|
||||
if (mcore->assigned_irqs <= 4)
|
||||
bcma_core_mips_set_irq(core,
|
||||
mcore->assigned_irqs++);
|
||||
break;
|
||||
switch (bus->chipinfo.id) {
|
||||
case BCMA_CHIP_ID_BCM4716:
|
||||
case BCMA_CHIP_ID_BCM4748:
|
||||
bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_PCIE, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
|
||||
break;
|
||||
case BCMA_CHIP_ID_BCM5356:
|
||||
case BCMA_CHIP_ID_BCM47162:
|
||||
case BCMA_CHIP_ID_BCM53572:
|
||||
bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
|
||||
break;
|
||||
case BCMA_CHIP_ID_BCM5357:
|
||||
case BCMA_CHIP_ID_BCM4749:
|
||||
bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_80211, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_MAC_GBIT, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_USB20_HOST, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_CHIPCOMMON, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_I2S, 0);
|
||||
break;
|
||||
case BCMA_CHIP_ID_BCM4706:
|
||||
bcma_core_mips_set_irq_name(bus, 1, BCMA_CORE_PCIE, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 2, BCMA_CORE_4706_MAC_GBIT,
|
||||
0);
|
||||
bcma_core_mips_set_irq_name(bus, 3, BCMA_CORE_PCIE, 1);
|
||||
bcma_core_mips_set_irq_name(bus, 4, BCMA_CORE_USB20_HOST, 0);
|
||||
bcma_core_mips_set_irq_name(bus, 0, BCMA_CORE_4706_CHIPCOMMON,
|
||||
0);
|
||||
break;
|
||||
default:
|
||||
list_for_each_entry(core, &bus->cores, list) {
|
||||
core->irq = bcma_core_irq(core);
|
||||
}
|
||||
bcma_err(bus,
|
||||
"Unknown device (0x%x) found, can not configure IRQs\n",
|
||||
bus->chipinfo.id);
|
||||
}
|
||||
bcma_info(bus, "IRQ reconfiguration done\n");
|
||||
bcma_debug(bus, "IRQ reconfiguration done\n");
|
||||
bcma_core_mips_dump_irq(bus);
|
||||
|
||||
mcore->setup_done = true;
|
||||
|
||||
@@ -94,19 +94,19 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||
if (dev == 0) {
|
||||
/* we support only two functions on device 0 */
|
||||
if (func > 1)
|
||||
return -EINVAL;
|
||||
goto out;
|
||||
|
||||
/* accesses to config registers with offsets >= 256
|
||||
* requires indirect access.
|
||||
*/
|
||||
if (off >= PCI_CONFIG_SPACE_SIZE) {
|
||||
addr = (func << 12);
|
||||
addr |= (off & 0x0FFF);
|
||||
addr |= (off & 0x0FFC);
|
||||
val = bcma_pcie_read_config(pc, addr);
|
||||
} else {
|
||||
addr = BCMA_CORE_PCI_PCICFG0;
|
||||
addr |= (func << 8);
|
||||
addr |= (off & 0xfc);
|
||||
addr |= (off & 0xFC);
|
||||
val = pcicore_read32(pc, addr);
|
||||
}
|
||||
} else {
|
||||
@@ -119,11 +119,9 @@ static int bcma_extpci_read_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||
goto out;
|
||||
|
||||
if (mips_busprobe32(val, mmio)) {
|
||||
val = 0xffffffff;
|
||||
val = 0xFFFFFFFF;
|
||||
goto unmap;
|
||||
}
|
||||
|
||||
val = readl(mmio);
|
||||
}
|
||||
val >>= (8 * (off & 3));
|
||||
|
||||
@@ -151,7 +149,7 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||
const void *buf, int len)
|
||||
{
|
||||
int err = -EINVAL;
|
||||
u32 addr = 0, val = 0;
|
||||
u32 addr, val;
|
||||
void __iomem *mmio = 0;
|
||||
u16 chipid = pc->core->bus->chipinfo.id;
|
||||
|
||||
@@ -159,16 +157,22 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||
if (unlikely(len != 1 && len != 2 && len != 4))
|
||||
goto out;
|
||||
if (dev == 0) {
|
||||
/* we support only two functions on device 0 */
|
||||
if (func > 1)
|
||||
goto out;
|
||||
|
||||
/* accesses to config registers with offsets >= 256
|
||||
* requires indirect access.
|
||||
*/
|
||||
if (off < PCI_CONFIG_SPACE_SIZE) {
|
||||
addr = pc->core->addr + BCMA_CORE_PCI_PCICFG0;
|
||||
if (off >= PCI_CONFIG_SPACE_SIZE) {
|
||||
addr = (func << 12);
|
||||
addr |= (off & 0x0FFC);
|
||||
val = bcma_pcie_read_config(pc, addr);
|
||||
} else {
|
||||
addr = BCMA_CORE_PCI_PCICFG0;
|
||||
addr |= (func << 8);
|
||||
addr |= (off & 0xfc);
|
||||
mmio = ioremap_nocache(addr, sizeof(val));
|
||||
if (!mmio)
|
||||
goto out;
|
||||
addr |= (off & 0xFC);
|
||||
val = pcicore_read32(pc, addr);
|
||||
}
|
||||
} else {
|
||||
addr = bcma_get_cfgspace_addr(pc, dev, func, off);
|
||||
@@ -180,19 +184,17 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||
goto out;
|
||||
|
||||
if (mips_busprobe32(val, mmio)) {
|
||||
val = 0xffffffff;
|
||||
val = 0xFFFFFFFF;
|
||||
goto unmap;
|
||||
}
|
||||
}
|
||||
|
||||
switch (len) {
|
||||
case 1:
|
||||
val = readl(mmio);
|
||||
val &= ~(0xFF << (8 * (off & 3)));
|
||||
val |= *((const u8 *)buf) << (8 * (off & 3));
|
||||
break;
|
||||
case 2:
|
||||
val = readl(mmio);
|
||||
val &= ~(0xFFFF << (8 * (off & 3)));
|
||||
val |= *((const u16 *)buf) << (8 * (off & 3));
|
||||
break;
|
||||
@@ -200,13 +202,14 @@ static int bcma_extpci_write_config(struct bcma_drv_pci *pc, unsigned int dev,
|
||||
val = *((const u32 *)buf);
|
||||
break;
|
||||
}
|
||||
if (dev == 0 && !addr) {
|
||||
if (dev == 0) {
|
||||
/* accesses to config registers with offsets >= 256
|
||||
* requires indirect access.
|
||||
*/
|
||||
addr = (func << 12);
|
||||
addr |= (off & 0x0FFF);
|
||||
bcma_pcie_write_config(pc, addr, val);
|
||||
if (off >= PCI_CONFIG_SPACE_SIZE)
|
||||
bcma_pcie_write_config(pc, addr, val);
|
||||
else
|
||||
pcicore_write32(pc, addr, val);
|
||||
} else {
|
||||
writel(val, mmio);
|
||||
|
||||
@@ -277,7 +280,7 @@ static u8 __devinit bcma_find_pci_capability(struct bcma_drv_pci *pc,
|
||||
/* check for Header type 0 */
|
||||
bcma_extpci_read_config(pc, dev, func, PCI_HEADER_TYPE, &byte_val,
|
||||
sizeof(u8));
|
||||
if ((byte_val & 0x7f) != PCI_HEADER_TYPE_NORMAL)
|
||||
if ((byte_val & 0x7F) != PCI_HEADER_TYPE_NORMAL)
|
||||
return cap_ptr;
|
||||
|
||||
/* check if the capability pointer field exists */
|
||||
@@ -427,7 +430,7 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
|
||||
/* Reset RC */
|
||||
usleep_range(3000, 5000);
|
||||
pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST_OE);
|
||||
usleep_range(1000, 2000);
|
||||
msleep(50);
|
||||
pcicore_write32(pc, BCMA_CORE_PCI_CTL, BCMA_CORE_PCI_CTL_RST |
|
||||
BCMA_CORE_PCI_CTL_RST_OE);
|
||||
|
||||
@@ -489,6 +492,17 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc)
|
||||
|
||||
bcma_core_pci_enable_crs(pc);
|
||||
|
||||
if (bus->chipinfo.id == BCMA_CHIP_ID_BCM4706 ||
|
||||
bus->chipinfo.id == BCMA_CHIP_ID_BCM4716) {
|
||||
u16 val16;
|
||||
bcma_extpci_read_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
|
||||
&val16, sizeof(val16));
|
||||
val16 |= (2 << 5); /* Max payload size of 512 */
|
||||
val16 |= (2 << 12); /* MRRS 512 */
|
||||
bcma_extpci_write_config(pc, 0, 0, BCMA_CORE_PCI_CFG_DEVCTRL,
|
||||
&val16, sizeof(val16));
|
||||
}
|
||||
|
||||
/* Enable PCI bridge BAR0 memory & master access */
|
||||
tmp = PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
|
||||
bcma_extpci_write_config(pc, 0, 0, PCI_COMMAND, &tmp, sizeof(tmp));
|
||||
@@ -577,7 +591,7 @@ int bcma_core_pci_plat_dev_init(struct pci_dev *dev)
|
||||
pr_info("PCI: Fixing up device %s\n", pci_name(dev));
|
||||
|
||||
/* Fix up interrupt lines */
|
||||
dev->irq = bcma_core_mips_irq(pc_host->pdev->core) + 2;
|
||||
dev->irq = bcma_core_irq(pc_host->pdev->core);
|
||||
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
|
||||
|
||||
return 0;
|
||||
@@ -596,6 +610,6 @@ int bcma_core_pci_pcibios_map_irq(const struct pci_dev *dev)
|
||||
|
||||
pc_host = container_of(dev->bus->ops, struct bcma_drv_pci_host,
|
||||
pci_ops);
|
||||
return bcma_core_mips_irq(pc_host->pdev->core) + 2;
|
||||
return bcma_core_irq(pc_host->pdev->core);
|
||||
}
|
||||
EXPORT_SYMBOL(bcma_core_pci_pcibios_map_irq);
|
||||
|
||||
@@ -81,8 +81,8 @@ struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(bcma_find_core);
|
||||
|
||||
static struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
|
||||
u8 unit)
|
||||
struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid,
|
||||
u8 unit)
|
||||
{
|
||||
struct bcma_device *core;
|
||||
|
||||
@@ -149,6 +149,14 @@ static int bcma_register_cores(struct bcma_bus *bus)
|
||||
dev_id++;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BCMA_DRIVER_MIPS
|
||||
if (bus->drv_cc.pflash.present) {
|
||||
err = platform_device_register(&bcma_pflash_dev);
|
||||
if (err)
|
||||
bcma_err(bus, "Error registering parallel flash\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_BCMA_SFLASH
|
||||
if (bus->drv_cc.sflash.present) {
|
||||
err = platform_device_register(&bcma_sflash_dev);
|
||||
|
||||
@@ -77,10 +77,15 @@ static struct usb_device_id ath3k_table[] = {
|
||||
{ USB_DEVICE(0x0CF3, 0x311D) },
|
||||
{ USB_DEVICE(0x13d3, 0x3375) },
|
||||
{ USB_DEVICE(0x04CA, 0x3005) },
|
||||
{ USB_DEVICE(0x04CA, 0x3006) },
|
||||
{ USB_DEVICE(0x04CA, 0x3008) },
|
||||
{ USB_DEVICE(0x13d3, 0x3362) },
|
||||
{ USB_DEVICE(0x0CF3, 0xE004) },
|
||||
{ USB_DEVICE(0x0930, 0x0219) },
|
||||
{ USB_DEVICE(0x0489, 0xe057) },
|
||||
{ USB_DEVICE(0x13d3, 0x3393) },
|
||||
{ USB_DEVICE(0x0489, 0xe04e) },
|
||||
{ USB_DEVICE(0x0489, 0xe056) },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE02C) },
|
||||
@@ -104,10 +109,15 @@ static struct usb_device_id ath3k_blist_tbl[] = {
|
||||
{ USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Atheros AR5BBU22 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
@@ -135,10 +135,15 @@ static struct usb_device_id blacklist_table[] = {
|
||||
{ USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x13d3, 0x3393), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe04e), .driver_info = BTUSB_ATH3012 },
|
||||
{ USB_DEVICE(0x0489, 0xe056), .driver_info = BTUSB_ATH3012 },
|
||||
|
||||
/* Atheros AR5BBU12 with sflash firmware */
|
||||
{ USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE },
|
||||
|
||||
@@ -30,5 +30,6 @@ source "drivers/net/wireless/ath/ath9k/Kconfig"
|
||||
source "drivers/net/wireless/ath/carl9170/Kconfig"
|
||||
source "drivers/net/wireless/ath/ath6kl/Kconfig"
|
||||
source "drivers/net/wireless/ath/ar5523/Kconfig"
|
||||
source "drivers/net/wireless/ath/wil6210/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
@@ -3,6 +3,7 @@ obj-$(CONFIG_ATH9K_HW) += ath9k/
|
||||
obj-$(CONFIG_CARL9170) += carl9170/
|
||||
obj-$(CONFIG_ATH6KL) += ath6kl/
|
||||
obj-$(CONFIG_AR5523) += ar5523/
|
||||
obj-$(CONFIG_WIL6210) += wil6210/
|
||||
|
||||
obj-$(CONFIG_ATH_COMMON) += ath.o
|
||||
|
||||
|
||||
@@ -240,13 +240,14 @@ static const struct ath_ops ath5k_common_ops = {
|
||||
* Driver Initialization *
|
||||
\***********************/
|
||||
|
||||
static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
|
||||
static void ath5k_reg_notifier(struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
|
||||
struct ath5k_hw *ah = hw->priv;
|
||||
struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
|
||||
|
||||
return ath_reg_notifier_apply(wiphy, request, regulatory);
|
||||
ath_reg_notifier_apply(wiphy, request, regulatory);
|
||||
}
|
||||
|
||||
/********************\
|
||||
|
||||
@@ -3492,8 +3492,8 @@ void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
|
||||
ath6kl_cfg80211_stop(vif);
|
||||
}
|
||||
|
||||
static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
|
||||
struct regulatory_request *request)
|
||||
{
|
||||
struct ath6kl *ar = wiphy_priv(wiphy);
|
||||
u32 rates[IEEE80211_NUM_BANDS];
|
||||
@@ -3506,17 +3506,13 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
|
||||
request->processed ? " processed" : "",
|
||||
request->initiator, request->user_reg_hint_type);
|
||||
|
||||
/*
|
||||
* As firmware is not able intersect regdoms, we can only listen to
|
||||
* cellular hints.
|
||||
*/
|
||||
if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
|
||||
return -EOPNOTSUPP;
|
||||
return;
|
||||
|
||||
ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
|
||||
if (ret) {
|
||||
ath6kl_err("failed to set regdomain: %d\n", ret);
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3536,10 +3532,8 @@ static int ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
|
||||
if (ret) {
|
||||
ath6kl_err("failed to start scan for a regdomain change: %d\n",
|
||||
ret);
|
||||
return ret;
|
||||
return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
|
||||
|
||||
@@ -2,6 +2,7 @@ config ATH9K_HW
|
||||
tristate
|
||||
config ATH9K_COMMON
|
||||
tristate
|
||||
select ATH_COMMON
|
||||
config ATH9K_DFS_DEBUGFS
|
||||
def_bool y
|
||||
depends on ATH9K_DEBUGFS && ATH9K_DFS_CERTIFIED
|
||||
@@ -17,7 +18,6 @@ config ATH9K_BTCOEX_SUPPORT
|
||||
config ATH9K
|
||||
tristate "Atheros 802.11n wireless cards support"
|
||||
depends on MAC80211
|
||||
select ATH_COMMON
|
||||
select ATH9K_HW
|
||||
select MAC80211_LEDS
|
||||
select LEDS_CLASS
|
||||
@@ -56,7 +56,8 @@ config ATH9K_AHB
|
||||
|
||||
config ATH9K_DEBUGFS
|
||||
bool "Atheros ath9k debugging"
|
||||
depends on ATH9K && DEBUG_FS
|
||||
depends on ATH9K
|
||||
select MAC80211_DEBUGFS
|
||||
---help---
|
||||
Say Y, if you need access to ath9k's statistics for
|
||||
interrupts, rate control, etc.
|
||||
|
||||
@@ -86,29 +86,25 @@ static int ath_ahb_probe(struct platform_device *pdev)
|
||||
|
||||
if (!pdev->dev.platform_data) {
|
||||
dev_err(&pdev->dev, "no platform data specified\n");
|
||||
ret = -EINVAL;
|
||||
goto err_out;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no memory resource found\n");
|
||||
ret = -ENXIO;
|
||||
goto err_out;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
mem = ioremap_nocache(res->start, resource_size(res));
|
||||
mem = devm_ioremap_nocache(&pdev->dev, res->start, resource_size(res));
|
||||
if (mem == NULL) {
|
||||
dev_err(&pdev->dev, "ioremap failed\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_out;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
|
||||
if (res == NULL) {
|
||||
dev_err(&pdev->dev, "no IRQ resource found\n");
|
||||
ret = -ENXIO;
|
||||
goto err_iounmap;
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
irq = res->start;
|
||||
@@ -116,8 +112,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
|
||||
hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
|
||||
if (hw == NULL) {
|
||||
dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
|
||||
ret = -ENOMEM;
|
||||
goto err_iounmap;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
SET_IEEE80211_DEV(hw, &pdev->dev);
|
||||
@@ -156,9 +151,6 @@ static int ath_ahb_probe(struct platform_device *pdev)
|
||||
err_free_hw:
|
||||
ieee80211_free_hw(hw);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
err_iounmap:
|
||||
iounmap(mem);
|
||||
err_out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -168,12 +160,10 @@ static int ath_ahb_remove(struct platform_device *pdev)
|
||||
|
||||
if (hw) {
|
||||
struct ath_softc *sc = hw->priv;
|
||||
void __iomem *mem = sc->mem;
|
||||
|
||||
ath9k_deinit_device(sc);
|
||||
free_irq(sc->irq, sc);
|
||||
ieee80211_free_hw(sc->hw);
|
||||
iounmap(mem);
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user