Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (94 commits) genetlink: fix netns vs. netlink table locking (2) 3c59x: Get rid of "Trying to free already-free IRQ" tunnel: eliminate recursion field ems_pci: fix size of CAN controllers BAR mapping for CPC-PCI v2 net: fix htmldocs sunrpc, clnt.c Phonet: error on broadcast sending (unimplemented) Phonet: fix race for port number in concurrent bind() pktgen: better scheduler friendliness pktgen: T_TERMINATE flag is unused ipv4: check optlen for IP_MULTICAST_IF option ath9k: Initialize txgain and rxgain for newer AR9287 chipsets. iwlagn: fix panic in iwl{5000,4965}_rx_reply_tx ath9k: Fix RFKILL bugs drivers/net/wireless: Use usb_endpoint_dir_out cfg80211: don't overwrite privacy setting wl12xx: fix kconfig/link errors rt2x00: fix the definition of rt2x00crypto_rx_insert_iv iwlwifi: reduce noise when skb allocation fails iwlwifi: do not send sync command while holding spinlock mac80211: fix DTIM setting ...
This commit is contained in:
@@ -813,10 +813,10 @@ static int vortex_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
if (netif_running(dev)) {
|
||||
netif_device_detach(dev);
|
||||
vortex_down(dev, 1);
|
||||
disable_irq(dev->irq);
|
||||
}
|
||||
pci_save_state(pdev);
|
||||
pci_enable_wake(pdev, pci_choose_state(pdev, state), 0);
|
||||
free_irq(dev->irq, dev);
|
||||
pci_disable_device(pdev);
|
||||
pci_set_power_state(pdev, pci_choose_state(pdev, state));
|
||||
}
|
||||
@@ -839,18 +839,12 @@ static int vortex_resume(struct pci_dev *pdev)
|
||||
return err;
|
||||
}
|
||||
pci_set_master(pdev);
|
||||
if (request_irq(dev->irq, vp->full_bus_master_rx ?
|
||||
&boomerang_interrupt : &vortex_interrupt, IRQF_SHARED, dev->name, dev)) {
|
||||
pr_warning("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
|
||||
pci_disable_device(pdev);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (netif_running(dev)) {
|
||||
err = vortex_up(dev);
|
||||
if (err)
|
||||
return err;
|
||||
else
|
||||
netif_device_attach(dev);
|
||||
enable_irq(dev->irq);
|
||||
netif_device_attach(dev);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@@ -87,7 +87,7 @@
|
||||
|
||||
/* These identify the driver base version and may not be removed. */
|
||||
static char version[] =
|
||||
KERN_INFO DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
|
||||
DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
|
||||
|
||||
MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
|
||||
MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver");
|
||||
|
@@ -1875,7 +1875,7 @@ config 68360_ENET
|
||||
|
||||
config FEC
|
||||
bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
|
||||
depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35
|
||||
depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35 || ARCH_MX25
|
||||
help
|
||||
Say Y here if you want to use the built-in 10/100 Fast ethernet
|
||||
controller on some Motorola ColdFire and Freescale i.MX processors.
|
||||
|
@@ -2296,7 +2296,7 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
u32 ctrl;
|
||||
u32 mac_ctrl_data;
|
||||
u32 master_ctrl_data;
|
||||
u32 wol_ctrl_data;
|
||||
u32 wol_ctrl_data = 0;
|
||||
u16 mii_bmsr_data;
|
||||
u16 save_autoneg_advertised;
|
||||
u16 mii_intr_status_data;
|
||||
|
@@ -75,6 +75,13 @@ config CAN_EMS_PCI
|
||||
CPC-PCIe and CPC-104P cards from EMS Dr. Thomas Wuensche
|
||||
(http://www.ems-wuensche.de).
|
||||
|
||||
config CAN_EMS_USB
|
||||
tristate "EMS CPC-USB/ARM7 CAN/USB interface"
|
||||
depends on USB && CAN_DEV
|
||||
---help---
|
||||
This driver is for the one channel CPC-USB/ARM7 CAN/USB interface
|
||||
from from EMS Dr. Thomas Wuensche (http://www.ems-wuensche.de).
|
||||
|
||||
config CAN_KVASER_PCI
|
||||
tristate "Kvaser PCIcanx and Kvaser PCIcan PCI Cards"
|
||||
depends on PCI && CAN_SJA1000
|
||||
@@ -82,6 +89,12 @@ config CAN_KVASER_PCI
|
||||
This driver is for the the PCIcanx and PCIcan cards (1, 2 or
|
||||
4 channel) from Kvaser (http://www.kvaser.com).
|
||||
|
||||
config CAN_AT91
|
||||
tristate "Atmel AT91 onchip CAN controller"
|
||||
depends on CAN && CAN_DEV && ARCH_AT91SAM9263
|
||||
---help---
|
||||
This is a driver for the SoC CAN controller in Atmel's AT91SAM9263.
|
||||
|
||||
config CAN_DEBUG_DEVICES
|
||||
bool "CAN devices debugging messages"
|
||||
depends on CAN
|
||||
|
@@ -7,6 +7,9 @@ obj-$(CONFIG_CAN_VCAN) += vcan.o
|
||||
obj-$(CONFIG_CAN_DEV) += can-dev.o
|
||||
can-dev-y := dev.o
|
||||
|
||||
obj-y += usb/
|
||||
|
||||
obj-$(CONFIG_CAN_SJA1000) += sja1000/
|
||||
obj-$(CONFIG_CAN_AT91) += at91_can.o
|
||||
|
||||
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
|
||||
|
@@ -94,12 +94,14 @@ struct ems_pci_card {
|
||||
#define EMS_PCI_CDR (CDR_CBP | CDR_CLKOUT_MASK)
|
||||
|
||||
#define EMS_PCI_V1_BASE_BAR 1
|
||||
#define EMS_PCI_V1_MEM_SIZE 4096
|
||||
#define EMS_PCI_V1_CONF_SIZE 4096 /* size of PITA control area */
|
||||
#define EMS_PCI_V2_BASE_BAR 2
|
||||
#define EMS_PCI_V2_MEM_SIZE 128
|
||||
#define EMS_PCI_V2_CONF_SIZE 128 /* size of PLX control area */
|
||||
#define EMS_PCI_CAN_BASE_OFFSET 0x400 /* offset where the controllers starts */
|
||||
#define EMS_PCI_CAN_CTRL_SIZE 0x200 /* memory size for each controller */
|
||||
|
||||
#define EMS_PCI_BASE_SIZE 4096 /* size of controller area */
|
||||
|
||||
static struct pci_device_id ems_pci_tbl[] = {
|
||||
/* CPC-PCI v1 */
|
||||
{PCI_VENDOR_ID_SIEMENS, 0x2104, PCI_ANY_ID, PCI_ANY_ID,},
|
||||
@@ -224,7 +226,7 @@ static int __devinit ems_pci_add_card(struct pci_dev *pdev,
|
||||
struct sja1000_priv *priv;
|
||||
struct net_device *dev;
|
||||
struct ems_pci_card *card;
|
||||
int max_chan, mem_size, base_bar;
|
||||
int max_chan, conf_size, base_bar;
|
||||
int err, i;
|
||||
|
||||
/* Enabling PCI device */
|
||||
@@ -251,22 +253,22 @@ static int __devinit ems_pci_add_card(struct pci_dev *pdev,
|
||||
card->version = 2; /* CPC-PCI v2 */
|
||||
max_chan = EMS_PCI_V2_MAX_CHAN;
|
||||
base_bar = EMS_PCI_V2_BASE_BAR;
|
||||
mem_size = EMS_PCI_V2_MEM_SIZE;
|
||||
conf_size = EMS_PCI_V2_CONF_SIZE;
|
||||
} else {
|
||||
card->version = 1; /* CPC-PCI v1 */
|
||||
max_chan = EMS_PCI_V1_MAX_CHAN;
|
||||
base_bar = EMS_PCI_V1_BASE_BAR;
|
||||
mem_size = EMS_PCI_V1_MEM_SIZE;
|
||||
conf_size = EMS_PCI_V1_CONF_SIZE;
|
||||
}
|
||||
|
||||
/* Remap configuration space and controller memory area */
|
||||
card->conf_addr = pci_iomap(pdev, 0, mem_size);
|
||||
card->conf_addr = pci_iomap(pdev, 0, conf_size);
|
||||
if (card->conf_addr == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto failure_cleanup;
|
||||
}
|
||||
|
||||
card->base_addr = pci_iomap(pdev, base_bar, mem_size);
|
||||
card->base_addr = pci_iomap(pdev, base_bar, EMS_PCI_BASE_SIZE);
|
||||
if (card->base_addr == NULL) {
|
||||
err = -ENOMEM;
|
||||
goto failure_cleanup;
|
||||
|
5
drivers/net/can/usb/Makefile
Normal file
5
drivers/net/can/usb/Makefile
Normal file
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# Makefile for the Linux Controller Area Network USB drivers.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o
|
1155
drivers/net/can/usb/ems_usb.c
Normal file
1155
drivers/net/can/usb/ems_usb.c
Normal file
File diff suppressed because it is too large
Load Diff
@@ -85,8 +85,6 @@ static int cnic_uio_open(struct uio_info *uinfo, struct inode *inode)
|
||||
|
||||
cp->uio_dev = iminor(inode);
|
||||
|
||||
cnic_shutdown_bnx2_rx_ring(dev);
|
||||
|
||||
cnic_init_bnx2_tx_ring(dev);
|
||||
cnic_init_bnx2_rx_ring(dev);
|
||||
|
||||
@@ -98,6 +96,8 @@ static int cnic_uio_close(struct uio_info *uinfo, struct inode *inode)
|
||||
struct cnic_dev *dev = uinfo->priv;
|
||||
struct cnic_local *cp = dev->cnic_priv;
|
||||
|
||||
cnic_shutdown_bnx2_rx_ring(dev);
|
||||
|
||||
cp->uio_dev = -1;
|
||||
return 0;
|
||||
}
|
||||
|
@@ -1109,7 +1109,7 @@ static int external_switch;
|
||||
static int __devinit cpmac_probe(struct platform_device *pdev)
|
||||
{
|
||||
int rc, phy_id;
|
||||
char mdio_bus_id[BUS_ID_SIZE];
|
||||
char mdio_bus_id[MII_BUS_ID_SIZE];
|
||||
struct resource *mem;
|
||||
struct cpmac_priv *priv;
|
||||
struct net_device *dev;
|
||||
@@ -1118,7 +1118,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
|
||||
pdata = pdev->dev.platform_data;
|
||||
|
||||
if (external_switch || dumb_switch) {
|
||||
strncpy(mdio_bus_id, "0", BUS_ID_SIZE); /* fixed phys bus */
|
||||
strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */
|
||||
phy_id = pdev->id;
|
||||
} else {
|
||||
for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
|
||||
@@ -1126,7 +1126,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
|
||||
continue;
|
||||
if (!cpmac_mii->phy_map[phy_id])
|
||||
continue;
|
||||
strncpy(mdio_bus_id, cpmac_mii->id, BUS_ID_SIZE);
|
||||
strncpy(mdio_bus_id, cpmac_mii->id, MII_BUS_ID_SIZE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1167,7 +1167,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
|
||||
priv->msg_enable = netif_msg_init(debug_level, 0xff);
|
||||
memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
|
||||
|
||||
snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
|
||||
snprintf(priv->phy_name, MII_BUS_ID_SIZE, PHY_ID_FMT, mdio_bus_id, phy_id);
|
||||
|
||||
priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0,
|
||||
PHY_INTERFACE_MODE_MII);
|
||||
|
@@ -3083,7 +3083,6 @@ static const struct net_device_ops ehea_netdev_ops = {
|
||||
.ndo_poll_controller = ehea_netpoll,
|
||||
#endif
|
||||
.ndo_get_stats = ehea_get_stats,
|
||||
.ndo_change_mtu = eth_change_mtu,
|
||||
.ndo_set_mac_address = ehea_set_mac_addr,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_set_multicast_list = ehea_set_multicast_list,
|
||||
|
@@ -285,41 +285,6 @@ void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
|
||||
wrfl();
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_update_mc_addr_list - Update Multicast addresses
|
||||
* @hw: pointer to the HW structure
|
||||
* @mc_addr_list: array of multicast addresses to program
|
||||
* @mc_addr_count: number of multicast addresses to program
|
||||
*
|
||||
* Updates entire Multicast Table Array.
|
||||
* The caller must have a packed mc_addr_list of multicast addresses.
|
||||
**/
|
||||
void igb_update_mc_addr_list(struct e1000_hw *hw,
|
||||
u8 *mc_addr_list, u32 mc_addr_count)
|
||||
{
|
||||
u32 hash_value, hash_bit, hash_reg;
|
||||
int i;
|
||||
|
||||
/* clear mta_shadow */
|
||||
memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
|
||||
|
||||
/* update mta_shadow from mc_addr_list */
|
||||
for (i = 0; (u32) i < mc_addr_count; i++) {
|
||||
hash_value = igb_hash_mc_addr(hw, mc_addr_list);
|
||||
|
||||
hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
|
||||
hash_bit = hash_value & 0x1F;
|
||||
|
||||
hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
|
||||
mc_addr_list += (ETH_ALEN);
|
||||
}
|
||||
|
||||
/* replace the entire MTA table */
|
||||
for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
|
||||
array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);
|
||||
wrfl();
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_hash_mc_addr - Generate a multicast hash value
|
||||
* @hw: pointer to the HW structure
|
||||
@@ -329,7 +294,7 @@ void igb_update_mc_addr_list(struct e1000_hw *hw,
|
||||
* the multicast filter table array address and new table value. See
|
||||
* igb_mta_set()
|
||||
**/
|
||||
u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
|
||||
static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
|
||||
{
|
||||
u32 hash_value, hash_mask;
|
||||
u8 bit_shift = 0;
|
||||
@@ -391,6 +356,41 @@ u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
|
||||
return hash_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_update_mc_addr_list - Update Multicast addresses
|
||||
* @hw: pointer to the HW structure
|
||||
* @mc_addr_list: array of multicast addresses to program
|
||||
* @mc_addr_count: number of multicast addresses to program
|
||||
*
|
||||
* Updates entire Multicast Table Array.
|
||||
* The caller must have a packed mc_addr_list of multicast addresses.
|
||||
**/
|
||||
void igb_update_mc_addr_list(struct e1000_hw *hw,
|
||||
u8 *mc_addr_list, u32 mc_addr_count)
|
||||
{
|
||||
u32 hash_value, hash_bit, hash_reg;
|
||||
int i;
|
||||
|
||||
/* clear mta_shadow */
|
||||
memset(&hw->mac.mta_shadow, 0, sizeof(hw->mac.mta_shadow));
|
||||
|
||||
/* update mta_shadow from mc_addr_list */
|
||||
for (i = 0; (u32) i < mc_addr_count; i++) {
|
||||
hash_value = igb_hash_mc_addr(hw, mc_addr_list);
|
||||
|
||||
hash_reg = (hash_value >> 5) & (hw->mac.mta_reg_count - 1);
|
||||
hash_bit = hash_value & 0x1F;
|
||||
|
||||
hw->mac.mta_shadow[hash_reg] |= (1 << hash_bit);
|
||||
mc_addr_list += (ETH_ALEN);
|
||||
}
|
||||
|
||||
/* replace the entire MTA table */
|
||||
for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
|
||||
array_wr32(E1000_MTA, i, hw->mac.mta_shadow[i]);
|
||||
wrfl();
|
||||
}
|
||||
|
||||
/**
|
||||
* igb_clear_hw_cntrs_base - Clear base hardware counters
|
||||
* @hw: pointer to the HW structure
|
||||
|
@@ -88,6 +88,5 @@ enum e1000_mng_mode {
|
||||
#define E1000_MNG_DHCP_COOKIE_STATUS_VLAN 0x2
|
||||
|
||||
extern void e1000_init_function_pointers_82575(struct e1000_hw *hw);
|
||||
extern u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr);
|
||||
|
||||
#endif
|
||||
|
@@ -267,7 +267,8 @@ struct ixgbe_adapter {
|
||||
enum ixgbe_fc_mode last_lfc_mode;
|
||||
|
||||
/* Interrupt Throttle Rate */
|
||||
u32 itr_setting;
|
||||
u32 rx_itr_setting;
|
||||
u32 tx_itr_setting;
|
||||
u16 eitr_low;
|
||||
u16 eitr_high;
|
||||
|
||||
@@ -351,7 +352,8 @@ struct ixgbe_adapter {
|
||||
struct ixgbe_hw_stats stats;
|
||||
|
||||
/* Interrupt Throttle Rate */
|
||||
u32 eitr_param;
|
||||
u32 rx_eitr_param;
|
||||
u32 tx_eitr_param;
|
||||
|
||||
unsigned long state;
|
||||
u64 tx_busy;
|
||||
|
@@ -1929,7 +1929,7 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
|
||||
ec->tx_max_coalesced_frames_irq = adapter->tx_ring[0].work_limit;
|
||||
|
||||
/* only valid if in constant ITR mode */
|
||||
switch (adapter->itr_setting) {
|
||||
switch (adapter->rx_itr_setting) {
|
||||
case 0:
|
||||
/* throttling disabled */
|
||||
ec->rx_coalesce_usecs = 0;
|
||||
@@ -1940,9 +1940,25 @@ static int ixgbe_get_coalesce(struct net_device *netdev,
|
||||
break;
|
||||
default:
|
||||
/* fixed interrupt rate mode */
|
||||
ec->rx_coalesce_usecs = 1000000/adapter->eitr_param;
|
||||
ec->rx_coalesce_usecs = 1000000/adapter->rx_eitr_param;
|
||||
break;
|
||||
}
|
||||
|
||||
/* only valid if in constant ITR mode */
|
||||
switch (adapter->tx_itr_setting) {
|
||||
case 0:
|
||||
/* throttling disabled */
|
||||
ec->tx_coalesce_usecs = 0;
|
||||
break;
|
||||
case 1:
|
||||
/* dynamic ITR mode */
|
||||
ec->tx_coalesce_usecs = 1;
|
||||
break;
|
||||
default:
|
||||
ec->tx_coalesce_usecs = 1000000/adapter->tx_eitr_param;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1953,6 +1969,14 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
|
||||
struct ixgbe_q_vector *q_vector;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* don't accept tx specific changes if we've got mixed RxTx vectors
|
||||
* test and jump out here if needed before changing the rx numbers
|
||||
*/
|
||||
if ((1000000/ec->tx_coalesce_usecs) != adapter->tx_eitr_param &&
|
||||
adapter->q_vector[0]->txr_count && adapter->q_vector[0]->rxr_count)
|
||||
return -EINVAL;
|
||||
|
||||
if (ec->tx_max_coalesced_frames_irq)
|
||||
adapter->tx_ring[0].work_limit = ec->tx_max_coalesced_frames_irq;
|
||||
|
||||
@@ -1963,26 +1987,49 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
|
||||
return -EINVAL;
|
||||
|
||||
/* store the value in ints/second */
|
||||
adapter->eitr_param = 1000000/ec->rx_coalesce_usecs;
|
||||
adapter->rx_eitr_param = 1000000/ec->rx_coalesce_usecs;
|
||||
|
||||
/* static value of interrupt rate */
|
||||
adapter->itr_setting = adapter->eitr_param;
|
||||
adapter->rx_itr_setting = adapter->rx_eitr_param;
|
||||
/* clear the lower bit as its used for dynamic state */
|
||||
adapter->itr_setting &= ~1;
|
||||
adapter->rx_itr_setting &= ~1;
|
||||
} else if (ec->rx_coalesce_usecs == 1) {
|
||||
/* 1 means dynamic mode */
|
||||
adapter->eitr_param = 20000;
|
||||
adapter->itr_setting = 1;
|
||||
adapter->rx_eitr_param = 20000;
|
||||
adapter->rx_itr_setting = 1;
|
||||
} else {
|
||||
/*
|
||||
* any other value means disable eitr, which is best
|
||||
* served by setting the interrupt rate very high
|
||||
*/
|
||||
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
|
||||
adapter->eitr_param = IXGBE_MAX_RSC_INT_RATE;
|
||||
adapter->rx_eitr_param = IXGBE_MAX_RSC_INT_RATE;
|
||||
else
|
||||
adapter->eitr_param = IXGBE_MAX_INT_RATE;
|
||||
adapter->itr_setting = 0;
|
||||
adapter->rx_eitr_param = IXGBE_MAX_INT_RATE;
|
||||
adapter->rx_itr_setting = 0;
|
||||
}
|
||||
|
||||
if (ec->tx_coalesce_usecs > 1) {
|
||||
/* check the limits */
|
||||
if ((1000000/ec->tx_coalesce_usecs > IXGBE_MAX_INT_RATE) ||
|
||||
(1000000/ec->tx_coalesce_usecs < IXGBE_MIN_INT_RATE))
|
||||
return -EINVAL;
|
||||
|
||||
/* store the value in ints/second */
|
||||
adapter->tx_eitr_param = 1000000/ec->tx_coalesce_usecs;
|
||||
|
||||
/* static value of interrupt rate */
|
||||
adapter->tx_itr_setting = adapter->tx_eitr_param;
|
||||
|
||||
/* clear the lower bit as its used for dynamic state */
|
||||
adapter->tx_itr_setting &= ~1;
|
||||
} else if (ec->tx_coalesce_usecs == 1) {
|
||||
/* 1 means dynamic mode */
|
||||
adapter->tx_eitr_param = 10000;
|
||||
adapter->tx_itr_setting = 1;
|
||||
} else {
|
||||
adapter->tx_eitr_param = IXGBE_MAX_INT_RATE;
|
||||
adapter->tx_itr_setting = 0;
|
||||
}
|
||||
|
||||
/* MSI/MSIx Interrupt Mode */
|
||||
@@ -1992,17 +2039,17 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
|
||||
for (i = 0; i < num_vectors; i++) {
|
||||
q_vector = adapter->q_vector[i];
|
||||
if (q_vector->txr_count && !q_vector->rxr_count)
|
||||
/* tx vector gets half the rate */
|
||||
q_vector->eitr = (adapter->eitr_param >> 1);
|
||||
/* tx only */
|
||||
q_vector->eitr = adapter->tx_eitr_param;
|
||||
else
|
||||
/* rx only or mixed */
|
||||
q_vector->eitr = adapter->eitr_param;
|
||||
q_vector->eitr = adapter->rx_eitr_param;
|
||||
ixgbe_write_eitr(q_vector);
|
||||
}
|
||||
/* Legacy Interrupt Mode */
|
||||
} else {
|
||||
q_vector = adapter->q_vector[0];
|
||||
q_vector->eitr = adapter->eitr_param;
|
||||
q_vector->eitr = adapter->rx_eitr_param;
|
||||
ixgbe_write_eitr(q_vector);
|
||||
}
|
||||
|
||||
|
@@ -926,12 +926,12 @@ static void ixgbe_configure_msix(struct ixgbe_adapter *adapter)
|
||||
r_idx + 1);
|
||||
}
|
||||
|
||||
/* if this is a tx only vector halve the interrupt rate */
|
||||
if (q_vector->txr_count && !q_vector->rxr_count)
|
||||
q_vector->eitr = (adapter->eitr_param >> 1);
|
||||
/* tx only */
|
||||
q_vector->eitr = adapter->tx_eitr_param;
|
||||
else if (q_vector->rxr_count)
|
||||
/* rx only */
|
||||
q_vector->eitr = adapter->eitr_param;
|
||||
/* rx or mixed */
|
||||
q_vector->eitr = adapter->rx_eitr_param;
|
||||
|
||||
ixgbe_write_eitr(q_vector);
|
||||
}
|
||||
@@ -1359,7 +1359,7 @@ static int ixgbe_clean_rxonly(struct napi_struct *napi, int budget)
|
||||
/* If all Rx work done, exit the polling mode */
|
||||
if (work_done < budget) {
|
||||
napi_complete(napi);
|
||||
if (adapter->itr_setting & 1)
|
||||
if (adapter->rx_itr_setting & 1)
|
||||
ixgbe_set_itr_msix(q_vector);
|
||||
if (!test_bit(__IXGBE_DOWN, &adapter->state))
|
||||
ixgbe_irq_enable_queues(adapter,
|
||||
@@ -1420,7 +1420,7 @@ static int ixgbe_clean_rxtx_many(struct napi_struct *napi, int budget)
|
||||
/* If all Rx work done, exit the polling mode */
|
||||
if (work_done < budget) {
|
||||
napi_complete(napi);
|
||||
if (adapter->itr_setting & 1)
|
||||
if (adapter->rx_itr_setting & 1)
|
||||
ixgbe_set_itr_msix(q_vector);
|
||||
if (!test_bit(__IXGBE_DOWN, &adapter->state))
|
||||
ixgbe_irq_enable_queues(adapter,
|
||||
@@ -1458,10 +1458,10 @@ static int ixgbe_clean_txonly(struct napi_struct *napi, int budget)
|
||||
if (!ixgbe_clean_tx_irq(q_vector, tx_ring))
|
||||
work_done = budget;
|
||||
|
||||
/* If all Rx work done, exit the polling mode */
|
||||
/* If all Tx work done, exit the polling mode */
|
||||
if (work_done < budget) {
|
||||
napi_complete(napi);
|
||||
if (adapter->itr_setting & 1)
|
||||
if (adapter->tx_itr_setting & 1)
|
||||
ixgbe_set_itr_msix(q_vector);
|
||||
if (!test_bit(__IXGBE_DOWN, &adapter->state))
|
||||
ixgbe_irq_enable_queues(adapter, ((u64)1 << q_vector->v_idx));
|
||||
@@ -1848,7 +1848,7 @@ static void ixgbe_configure_msi_and_legacy(struct ixgbe_adapter *adapter)
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
|
||||
IXGBE_WRITE_REG(hw, IXGBE_EITR(0),
|
||||
EITR_INTS_PER_SEC_TO_REG(adapter->eitr_param));
|
||||
EITR_INTS_PER_SEC_TO_REG(adapter->rx_eitr_param));
|
||||
|
||||
ixgbe_set_ivar(adapter, 0, 0, 0);
|
||||
ixgbe_set_ivar(adapter, 1, 0, 0);
|
||||
@@ -1969,6 +1969,50 @@ static u32 ixgbe_setup_mrqc(struct ixgbe_adapter *adapter)
|
||||
return mrqc;
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_configure_rscctl - enable RSC for the indicated ring
|
||||
* @adapter: address of board private structure
|
||||
* @index: index of ring to set
|
||||
* @rx_buf_len: rx buffer length
|
||||
**/
|
||||
static void ixgbe_configure_rscctl(struct ixgbe_adapter *adapter, int index,
|
||||
int rx_buf_len)
|
||||
{
|
||||
struct ixgbe_ring *rx_ring;
|
||||
struct ixgbe_hw *hw = &adapter->hw;
|
||||
int j;
|
||||
u32 rscctrl;
|
||||
|
||||
rx_ring = &adapter->rx_ring[index];
|
||||
j = rx_ring->reg_idx;
|
||||
rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
|
||||
rscctrl |= IXGBE_RSCCTL_RSCEN;
|
||||
/*
|
||||
* we must limit the number of descriptors so that the
|
||||
* total size of max desc * buf_len is not greater
|
||||
* than 65535
|
||||
*/
|
||||
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
|
||||
#if (MAX_SKB_FRAGS > 16)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
|
||||
#elif (MAX_SKB_FRAGS > 8)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
|
||||
#elif (MAX_SKB_FRAGS > 4)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
|
||||
#else
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_1;
|
||||
#endif
|
||||
} else {
|
||||
if (rx_buf_len < IXGBE_RXBUFFER_4096)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
|
||||
else if (rx_buf_len < IXGBE_RXBUFFER_8192)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
|
||||
else
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
|
||||
}
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* ixgbe_configure_rx - Configure 8259x Receive Unit after Reset
|
||||
* @adapter: board private structure
|
||||
@@ -1990,7 +2034,6 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
|
||||
u32 fctrl, hlreg0;
|
||||
u32 reta = 0, mrqc = 0;
|
||||
u32 rdrxctl;
|
||||
u32 rscctrl;
|
||||
int rx_buf_len;
|
||||
|
||||
/* Decide whether to use packet split mode or not */
|
||||
@@ -2148,36 +2191,9 @@ static void ixgbe_configure_rx(struct ixgbe_adapter *adapter)
|
||||
|
||||
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED) {
|
||||
/* Enable 82599 HW-RSC */
|
||||
for (i = 0; i < adapter->num_rx_queues; i++) {
|
||||
rx_ring = &adapter->rx_ring[i];
|
||||
j = rx_ring->reg_idx;
|
||||
rscctrl = IXGBE_READ_REG(hw, IXGBE_RSCCTL(j));
|
||||
rscctrl |= IXGBE_RSCCTL_RSCEN;
|
||||
/*
|
||||
* we must limit the number of descriptors so that the
|
||||
* total size of max desc * buf_len is not greater
|
||||
* than 65535
|
||||
*/
|
||||
if (rx_ring->flags & IXGBE_RING_RX_PS_ENABLED) {
|
||||
#if (MAX_SKB_FRAGS > 16)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
|
||||
#elif (MAX_SKB_FRAGS > 8)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
|
||||
#elif (MAX_SKB_FRAGS > 4)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
|
||||
#else
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_1;
|
||||
#endif
|
||||
} else {
|
||||
if (rx_buf_len < IXGBE_RXBUFFER_4096)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_16;
|
||||
else if (rx_buf_len < IXGBE_RXBUFFER_8192)
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_8;
|
||||
else
|
||||
rscctrl |= IXGBE_RSCCTL_MAXDESC_4;
|
||||
}
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RSCCTL(j), rscctrl);
|
||||
}
|
||||
for (i = 0; i < adapter->num_rx_queues; i++)
|
||||
ixgbe_configure_rscctl(adapter, i, rx_buf_len);
|
||||
|
||||
/* Disable RSC for ACK packets */
|
||||
IXGBE_WRITE_REG(hw, IXGBE_RSCDBU,
|
||||
(IXGBE_RSCDBU_RSCACKDIS | IXGBE_READ_REG(hw, IXGBE_RSCDBU)));
|
||||
@@ -2926,6 +2942,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
|
||||
|
||||
ixgbe_napi_disable_all(adapter);
|
||||
|
||||
clear_bit(__IXGBE_SFP_MODULE_NOT_FOUND, &adapter->state);
|
||||
del_timer_sync(&adapter->sfp_timer);
|
||||
del_timer_sync(&adapter->watchdog_timer);
|
||||
cancel_work_sync(&adapter->watchdog_task);
|
||||
|
||||
@@ -2989,7 +3007,7 @@ static int ixgbe_poll(struct napi_struct *napi, int budget)
|
||||
/* If budget not fully consumed, exit the polling mode */
|
||||
if (work_done < budget) {
|
||||
napi_complete(napi);
|
||||
if (adapter->itr_setting & 1)
|
||||
if (adapter->rx_itr_setting & 1)
|
||||
ixgbe_set_itr(adapter);
|
||||
if (!test_bit(__IXGBE_DOWN, &adapter->state))
|
||||
ixgbe_irq_enable_queues(adapter, IXGBE_EIMS_RTX_QUEUE);
|
||||
@@ -3599,7 +3617,10 @@ static int ixgbe_alloc_q_vectors(struct ixgbe_adapter *adapter)
|
||||
if (!q_vector)
|
||||
goto err_out;
|
||||
q_vector->adapter = adapter;
|
||||
q_vector->eitr = adapter->eitr_param;
|
||||
if (q_vector->txr_count && !q_vector->rxr_count)
|
||||
q_vector->eitr = adapter->tx_eitr_param;
|
||||
else
|
||||
q_vector->eitr = adapter->rx_eitr_param;
|
||||
q_vector->v_idx = q_idx;
|
||||
netif_napi_add(adapter->netdev, &q_vector->napi, (*poll), 64);
|
||||
adapter->q_vector[q_idx] = q_vector;
|
||||
@@ -3868,8 +3889,10 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
|
||||
hw->fc.disable_fc_autoneg = false;
|
||||
|
||||
/* enable itr by default in dynamic mode */
|
||||
adapter->itr_setting = 1;
|
||||
adapter->eitr_param = 20000;
|
||||
adapter->rx_itr_setting = 1;
|
||||
adapter->rx_eitr_param = 20000;
|
||||
adapter->tx_itr_setting = 1;
|
||||
adapter->tx_eitr_param = 10000;
|
||||
|
||||
/* set defaults for eitr in MegaBytes */
|
||||
adapter->eitr_low = 10;
|
||||
|
@@ -1469,6 +1469,7 @@ netxen_nic_resume(struct pci_dev *pdev)
|
||||
}
|
||||
|
||||
netxen_schedule_work(adapter, netxen_fw_poll_work, FW_POLL_DELAY);
|
||||
return 0;
|
||||
|
||||
err_out_detach:
|
||||
netxen_nic_detach(adapter);
|
||||
@@ -1903,12 +1904,13 @@ static void netxen_tx_timeout_task(struct work_struct *work)
|
||||
|
||||
netif_wake_queue(adapter->netdev);
|
||||
|
||||
goto done;
|
||||
clear_bit(__NX_RESETTING, &adapter->state);
|
||||
|
||||
} else {
|
||||
clear_bit(__NX_RESETTING, &adapter->state);
|
||||
if (!netxen_nic_reset_context(adapter)) {
|
||||
adapter->netdev->trans_start = jiffies;
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
|
||||
/* context reset failed, fall through for fw reset */
|
||||
@@ -1916,8 +1918,6 @@ static void netxen_tx_timeout_task(struct work_struct *work)
|
||||
|
||||
request_reset:
|
||||
adapter->need_fw_reset = 1;
|
||||
done:
|
||||
clear_bit(__NX_RESETTING, &adapter->state);
|
||||
}
|
||||
|
||||
struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
|
||||
|
@@ -340,12 +340,11 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
|
||||
base = &virt[hw_info[i].offset & (req.Size-1)];
|
||||
if ((readb(base+0) == hw_info[i].a0) &&
|
||||
(readb(base+2) == hw_info[i].a1) &&
|
||||
(readb(base+4) == hw_info[i].a2))
|
||||
break;
|
||||
}
|
||||
if (i < NR_INFO) {
|
||||
for (j = 0; j < 6; j++)
|
||||
dev->dev_addr[j] = readb(base + (j<<1));
|
||||
(readb(base+4) == hw_info[i].a2)) {
|
||||
for (j = 0; j < 6; j++)
|
||||
dev->dev_addr[j] = readb(base + (j<<1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
iounmap(virt);
|
||||
|
@@ -1497,7 +1497,6 @@ static int sky2_up(struct net_device *dev)
|
||||
if (ramsize > 0) {
|
||||
u32 rxspace;
|
||||
|
||||
hw->flags |= SKY2_HW_RAM_BUFFER;
|
||||
pr_debug(PFX "%s: ram buffer %dK\n", dev->name, ramsize);
|
||||
if (ramsize < 16)
|
||||
rxspace = ramsize / 2;
|
||||
@@ -2926,6 +2925,9 @@ static int __devinit sky2_init(struct sky2_hw *hw)
|
||||
++hw->ports;
|
||||
}
|
||||
|
||||
if (sky2_read8(hw, B2_E_0))
|
||||
hw->flags |= SKY2_HW_RAM_BUFFER;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1016,7 +1016,6 @@ static const struct net_device_ops vnet_ops = {
|
||||
.ndo_open = vnet_open,
|
||||
.ndo_stop = vnet_close,
|
||||
.ndo_set_multicast_list = vnet_set_rx_mode,
|
||||
.ndo_change_mtu = eth_change_mtu,
|
||||
.ndo_set_mac_address = vnet_set_mac_addr,
|
||||
.ndo_validate_addr = eth_validate_addr,
|
||||
.ndo_tx_timeout = vnet_tx_timeout,
|
||||
|
@@ -946,8 +946,6 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
|
||||
char *name;
|
||||
unsigned long flags = 0;
|
||||
|
||||
err = -EINVAL;
|
||||
|
||||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
err = security_tun_dev_create();
|
||||
@@ -964,7 +962,7 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
|
||||
flags |= TUN_TAP_DEV;
|
||||
name = "tap%d";
|
||||
} else
|
||||
goto failed;
|
||||
return -EINVAL;
|
||||
|
||||
if (*ifr->ifr_name)
|
||||
name = ifr->ifr_name;
|
||||
|
@@ -263,6 +263,7 @@ static int kaweth_control(struct kaweth_device *kaweth,
|
||||
int timeout)
|
||||
{
|
||||
struct usb_ctrlrequest *dr;
|
||||
int retval;
|
||||
|
||||
dbg("kaweth_control()");
|
||||
|
||||
@@ -278,18 +279,21 @@ static int kaweth_control(struct kaweth_device *kaweth,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dr->bRequestType= requesttype;
|
||||
dr->bRequestType = requesttype;
|
||||
dr->bRequest = request;
|
||||
dr->wValue = cpu_to_le16(value);
|
||||
dr->wIndex = cpu_to_le16(index);
|
||||
dr->wLength = cpu_to_le16(size);
|
||||
|
||||
return kaweth_internal_control_msg(kaweth->dev,
|
||||
pipe,
|
||||
dr,
|
||||
data,
|
||||
size,
|
||||
timeout);
|
||||
retval = kaweth_internal_control_msg(kaweth->dev,
|
||||
pipe,
|
||||
dr,
|
||||
data,
|
||||
size,
|
||||
timeout);
|
||||
|
||||
kfree(dr);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
|
@@ -1227,7 +1227,7 @@ static const struct driver_info smsc95xx_info = {
|
||||
.rx_fixup = smsc95xx_rx_fixup,
|
||||
.tx_fixup = smsc95xx_tx_fixup,
|
||||
.status = smsc95xx_status,
|
||||
.flags = FLAG_ETHER,
|
||||
.flags = FLAG_ETHER | FLAG_SEND_ZLP,
|
||||
};
|
||||
|
||||
static const struct usb_device_id products[] = {
|
||||
@@ -1236,11 +1236,76 @@ static const struct usb_device_id products[] = {
|
||||
USB_DEVICE(0x0424, 0x9500),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9505 USB Ethernet Device */
|
||||
USB_DEVICE(0x0424, 0x9505),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9500A USB Ethernet Device */
|
||||
USB_DEVICE(0x0424, 0x9E00),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9505A USB Ethernet Device */
|
||||
USB_DEVICE(0x0424, 0x9E01),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9512/9514 USB Hub & Ethernet Device */
|
||||
USB_DEVICE(0x0424, 0xec00),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9500 USB Ethernet Device (SAL10) */
|
||||
USB_DEVICE(0x0424, 0x9900),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9505 USB Ethernet Device (SAL10) */
|
||||
USB_DEVICE(0x0424, 0x9901),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9500A USB Ethernet Device (SAL10) */
|
||||
USB_DEVICE(0x0424, 0x9902),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9505A USB Ethernet Device (SAL10) */
|
||||
USB_DEVICE(0x0424, 0x9903),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9512/9514 USB Hub & Ethernet Device (SAL10) */
|
||||
USB_DEVICE(0x0424, 0x9904),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9500A USB Ethernet Device (HAL) */
|
||||
USB_DEVICE(0x0424, 0x9905),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9505A USB Ethernet Device (HAL) */
|
||||
USB_DEVICE(0x0424, 0x9906),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9500 USB Ethernet Device (Alternate ID) */
|
||||
USB_DEVICE(0x0424, 0x9907),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9500A USB Ethernet Device (Alternate ID) */
|
||||
USB_DEVICE(0x0424, 0x9908),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{
|
||||
/* SMSC9512/9514 USB Hub & Ethernet Device (Alternate ID) */
|
||||
USB_DEVICE(0x0424, 0x9909),
|
||||
.driver_info = (unsigned long) &smsc95xx_info,
|
||||
},
|
||||
{ }, /* END */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(usb, products);
|
||||
|
@@ -1049,7 +1049,7 @@ netdev_tx_t usbnet_start_xmit (struct sk_buff *skb,
|
||||
* NOTE: strictly conforming cdc-ether devices should expect
|
||||
* the ZLP here, but ignore the one-byte packet.
|
||||
*/
|
||||
if ((length % dev->maxpacket) == 0) {
|
||||
if (!(info->flags & FLAG_SEND_ZLP) && (length % dev->maxpacket) == 0) {
|
||||
urb->transfer_buffer_length++;
|
||||
if (skb_tailroom(skb)) {
|
||||
skb->data[skb->len] = 0;
|
||||
|
@@ -64,6 +64,8 @@ static struct usb_device_id ar9170_usb_ids[] = {
|
||||
{ USB_DEVICE(0x0cf3, 0x9170) },
|
||||
/* Atheros TG121N */
|
||||
{ USB_DEVICE(0x0cf3, 0x1001) },
|
||||
/* TP-Link TL-WN821N v2 */
|
||||
{ USB_DEVICE(0x0cf3, 0x1002) },
|
||||
/* Cace Airpcap NX */
|
||||
{ USB_DEVICE(0xcace, 0x0300) },
|
||||
/* D-Link DWA 160A */
|
||||
|
@@ -609,14 +609,24 @@ void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
|
||||
AR_PHY_CH1_EXT_CCA,
|
||||
AR_PHY_CH2_EXT_CCA
|
||||
};
|
||||
u8 chainmask;
|
||||
u8 chainmask, rx_chain_status;
|
||||
|
||||
rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
|
||||
if (AR_SREV_9285(ah))
|
||||
chainmask = 0x9;
|
||||
else if (AR_SREV_9280(ah) || AR_SREV_9287(ah))
|
||||
chainmask = 0x1B;
|
||||
else
|
||||
chainmask = 0x3F;
|
||||
else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
|
||||
if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
|
||||
chainmask = 0x1B;
|
||||
else
|
||||
chainmask = 0x09;
|
||||
} else {
|
||||
if (rx_chain_status & 0x4)
|
||||
chainmask = 0x3F;
|
||||
else if (rx_chain_status & 0x2)
|
||||
chainmask = 0x1B;
|
||||
else
|
||||
chainmask = 0x09;
|
||||
}
|
||||
|
||||
h = ah->nfCalHist;
|
||||
|
||||
@@ -697,6 +707,8 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
|
||||
noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
|
||||
else if (AR_SREV_9285(ah))
|
||||
noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
|
||||
else if (AR_SREV_9287(ah))
|
||||
noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
|
||||
else
|
||||
noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
|
||||
|
||||
@@ -924,6 +936,7 @@ static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah, bool is_reset)
|
||||
regVal |= (1 << (19 + i));
|
||||
REG_WRITE(ah, 0x7834, regVal);
|
||||
udelay(1);
|
||||
regVal = REG_READ(ah, 0x7834);
|
||||
regVal &= (~(0x1 << (19 + i)));
|
||||
reg_field = MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9);
|
||||
regVal |= (reg_field << (19 + i));
|
||||
|
@@ -28,6 +28,7 @@ extern const struct ath9k_percal_data adc_init_dc_cal;
|
||||
#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85
|
||||
#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112
|
||||
#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118
|
||||
#define AR_PHY_CCA_MAX_AR9287_GOOD_VALUE -118
|
||||
#define AR_PHY_CCA_MAX_HIGH_VALUE -62
|
||||
#define AR_PHY_CCA_MIN_BAD_VALUE -140
|
||||
#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
|
||||
|
@@ -509,6 +509,8 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
|
||||
REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE,
|
||||
eep->baseEepHeader.dacLpMode);
|
||||
|
||||
udelay(100);
|
||||
|
||||
REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP,
|
||||
pModal->miscBits >> 2);
|
||||
|
||||
@@ -902,7 +904,7 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah,
|
||||
u16 powerLimit)
|
||||
{
|
||||
#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
|
||||
#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 10 /* 10*log10(3)*2 */
|
||||
#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
|
||||
|
||||
struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
|
||||
struct ar5416_eeprom_def *pEepData = &ah->eeprom.def;
|
||||
|
@@ -842,7 +842,7 @@ static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
|
||||
|
||||
static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
|
||||
{
|
||||
if (AR_SREV_9287_11(ah))
|
||||
if (AR_SREV_9287_11_OR_LATER(ah))
|
||||
INIT_INI_ARRAY(&ah->iniModesRxGain,
|
||||
ar9287Modes_rx_gain_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
|
||||
@@ -853,7 +853,7 @@ static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
|
||||
else if (AR_SREV_9280_20(ah))
|
||||
ath9k_hw_init_rxgain_ini(ah);
|
||||
|
||||
if (AR_SREV_9287_11(ah)) {
|
||||
if (AR_SREV_9287_11_OR_LATER(ah)) {
|
||||
INIT_INI_ARRAY(&ah->iniModesTxGain,
|
||||
ar9287Modes_tx_gain_9287_1_1,
|
||||
ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
|
||||
@@ -965,7 +965,7 @@ int ath9k_hw_init(struct ath_hw *ah)
|
||||
ath9k_hw_init_mode_regs(ah);
|
||||
|
||||
if (ah->is_pciexpress)
|
||||
ath9k_hw_configpcipowersave(ah, 0);
|
||||
ath9k_hw_configpcipowersave(ah, 0, 0);
|
||||
else
|
||||
ath9k_hw_disablepcie(ah);
|
||||
|
||||
@@ -1273,6 +1273,15 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
|
||||
*/
|
||||
REG_SET_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
|
||||
|
||||
if (AR_SREV_9280_10_OR_LATER(ah)) {
|
||||
val = REG_READ(ah, AR_PCU_MISC_MODE2) &
|
||||
(~AR_PCU_MISC_MODE2_HWWAR1);
|
||||
|
||||
if (AR_SREV_9287_10_OR_LATER(ah))
|
||||
val = val & (~AR_PCU_MISC_MODE2_HWWAR2);
|
||||
|
||||
REG_WRITE(ah, AR_PCU_MISC_MODE2, val);
|
||||
}
|
||||
|
||||
if (!AR_SREV_5416_20_OR_LATER(ah) ||
|
||||
AR_SREV_9280_10_OR_LATER(ah))
|
||||
@@ -1784,7 +1793,7 @@ static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
static bool ath9k_hw_chip_reset(struct ath_hw *ah,
|
||||
struct ath9k_channel *chan)
|
||||
{
|
||||
if (OLC_FOR_AR9280_20_LATER) {
|
||||
if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) {
|
||||
if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON))
|
||||
return false;
|
||||
} else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
|
||||
@@ -2338,6 +2347,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
struct ath9k_channel *curchan = ah->curchan;
|
||||
u32 saveDefAntenna;
|
||||
u32 macStaId1;
|
||||
u64 tsf = 0;
|
||||
int i, rx_chainmask, r;
|
||||
|
||||
ah->extprotspacing = sc->ht_extprotspacing;
|
||||
@@ -2347,7 +2357,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
|
||||
return -EIO;
|
||||
|
||||
if (curchan)
|
||||
if (curchan && !ah->chip_fullsleep)
|
||||
ath9k_hw_getnf(ah, curchan);
|
||||
|
||||
if (bChannelChange &&
|
||||
@@ -2356,8 +2366,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
(chan->channel != ah->curchan->channel) &&
|
||||
((chan->channelFlags & CHANNEL_ALL) ==
|
||||
(ah->curchan->channelFlags & CHANNEL_ALL)) &&
|
||||
(!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
|
||||
!IS_CHAN_A_5MHZ_SPACED(ah->curchan)))) {
|
||||
!(AR_SREV_9280(ah) || IS_CHAN_A_5MHZ_SPACED(chan) ||
|
||||
IS_CHAN_A_5MHZ_SPACED(ah->curchan))) {
|
||||
|
||||
if (ath9k_hw_channel_change(ah, chan, sc->tx_chan_width)) {
|
||||
ath9k_hw_loadnf(ah, ah->curchan);
|
||||
@@ -2372,6 +2382,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
|
||||
macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
|
||||
|
||||
/* For chips on which RTC reset is done, save TSF before it gets cleared */
|
||||
if (AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
|
||||
tsf = ath9k_hw_gettsf64(ah);
|
||||
|
||||
saveLedState = REG_READ(ah, AR_CFG_LED) &
|
||||
(AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
|
||||
AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
|
||||
@@ -2398,6 +2412,10 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
|
||||
udelay(50);
|
||||
}
|
||||
|
||||
/* Restore TSF */
|
||||
if (tsf && AR_SREV_9280(ah) && ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
|
||||
ath9k_hw_settsf64(ah, tsf);
|
||||
|
||||
if (AR_SREV_9280_10_OR_LATER(ah))
|
||||
REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
|
||||
|
||||
@@ -3005,9 +3023,10 @@ void ath9k_ps_restore(struct ath_softc *sc)
|
||||
* Programming the SerDes must go through the same 288 bit serial shift
|
||||
* register as the other analog registers. Hence the 9 writes.
|
||||
*/
|
||||
void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
|
||||
void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off)
|
||||
{
|
||||
u8 i;
|
||||
u32 val;
|
||||
|
||||
if (ah->is_pciexpress != true)
|
||||
return;
|
||||
@@ -3017,84 +3036,113 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
|
||||
return;
|
||||
|
||||
/* Nothing to do on restore for 11N */
|
||||
if (restore)
|
||||
return;
|
||||
if (!restore) {
|
||||
if (AR_SREV_9280_20_OR_LATER(ah)) {
|
||||
/*
|
||||
* AR9280 2.0 or later chips use SerDes values from the
|
||||
* initvals.h initialized depending on chipset during
|
||||
* ath9k_hw_init()
|
||||
*/
|
||||
for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
|
||||
REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
|
||||
INI_RA(&ah->iniPcieSerdes, i, 1));
|
||||
}
|
||||
} else if (AR_SREV_9280(ah) &&
|
||||
(ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
|
||||
|
||||
if (AR_SREV_9280_20_OR_LATER(ah)) {
|
||||
/*
|
||||
* AR9280 2.0 or later chips use SerDes values from the
|
||||
* initvals.h initialized depending on chipset during
|
||||
* ath9k_hw_init()
|
||||
*/
|
||||
for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
|
||||
REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
|
||||
INI_RA(&ah->iniPcieSerdes, i, 1));
|
||||
/* RX shut off when elecidle is asserted */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
|
||||
|
||||
/* Shut off CLKREQ active in L1 */
|
||||
if (ah->config.pcie_clock_req)
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
|
||||
else
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
|
||||
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
|
||||
|
||||
/* Load the new settings */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
|
||||
|
||||
} else {
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
|
||||
|
||||
/* RX shut off when elecidle is asserted */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
|
||||
|
||||
/*
|
||||
* Ignore ah->ah_config.pcie_clock_req setting for
|
||||
* pre-AR9280 11n
|
||||
*/
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
|
||||
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
|
||||
|
||||
/* Load the new settings */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
|
||||
}
|
||||
} else if (AR_SREV_9280(ah) &&
|
||||
(ah->hw_version.macRev == AR_SREV_REVISION_9280_10)) {
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
|
||||
|
||||
/* RX shut off when elecidle is asserted */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
|
||||
udelay(1000);
|
||||
|
||||
/* Shut off CLKREQ active in L1 */
|
||||
if (ah->config.pcie_clock_req)
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
|
||||
else
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
|
||||
/* set bit 19 to allow forcing of pcie core into L1 state */
|
||||
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
|
||||
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
|
||||
/* Several PCIe massages to ensure proper behaviour */
|
||||
if (ah->config.pcie_waen) {
|
||||
val = ah->config.pcie_waen;
|
||||
if (!power_off)
|
||||
val &= (~AR_WA_D3_L1_DISABLE);
|
||||
} else {
|
||||
if (AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
|
||||
AR_SREV_9287(ah)) {
|
||||
val = AR9285_WA_DEFAULT;
|
||||
if (!power_off)
|
||||
val &= (~AR_WA_D3_L1_DISABLE);
|
||||
} else if (AR_SREV_9280(ah)) {
|
||||
/*
|
||||
* On AR9280 chips bit 22 of 0x4004 needs to be
|
||||
* set otherwise card may disappear.
|
||||
*/
|
||||
val = AR9280_WA_DEFAULT;
|
||||
if (!power_off)
|
||||
val &= (~AR_WA_D3_L1_DISABLE);
|
||||
} else
|
||||
val = AR_WA_DEFAULT;
|
||||
}
|
||||
|
||||
/* Load the new settings */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
|
||||
|
||||
} else {
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
|
||||
|
||||
/* RX shut off when elecidle is asserted */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
|
||||
|
||||
/*
|
||||
* Ignore ah->ah_config.pcie_clock_req setting for
|
||||
* pre-AR9280 11n
|
||||
*/
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
|
||||
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
|
||||
REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
|
||||
|
||||
/* Load the new settings */
|
||||
REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
|
||||
REG_WRITE(ah, AR_WA, val);
|
||||
}
|
||||
|
||||
udelay(1000);
|
||||
|
||||
/* set bit 19 to allow forcing of pcie core into L1 state */
|
||||
REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
|
||||
|
||||
/* Several PCIe massages to ensure proper behaviour */
|
||||
if (ah->config.pcie_waen) {
|
||||
REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
|
||||
} else {
|
||||
if (AR_SREV_9285(ah) || AR_SREV_9271(ah) || AR_SREV_9287(ah))
|
||||
REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
|
||||
if (power_off) {
|
||||
/*
|
||||
* On AR9280 chips bit 22 of 0x4004 needs to be set to
|
||||
* otherwise card may disappear.
|
||||
* Set PCIe workaround bits
|
||||
* bit 14 in WA register (disable L1) should only
|
||||
* be set when device enters D3 and be cleared
|
||||
* when device comes back to D0.
|
||||
*/
|
||||
else if (AR_SREV_9280(ah))
|
||||
REG_WRITE(ah, AR_WA, AR9280_WA_DEFAULT);
|
||||
else
|
||||
REG_WRITE(ah, AR_WA, AR_WA_DEFAULT);
|
||||
if (ah->config.pcie_waen) {
|
||||
if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
|
||||
REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
|
||||
} else {
|
||||
if (((AR_SREV_9285(ah) || AR_SREV_9271(ah) ||
|
||||
AR_SREV_9287(ah)) &&
|
||||
(AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
|
||||
(AR_SREV_9280(ah) &&
|
||||
(AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
|
||||
REG_SET_BIT(ah, AR_WA, AR_WA_D3_L1_DISABLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3652,15 +3700,7 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) ||
|
||||
(ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCIE) ||
|
||||
(ah->hw_version.macVersion == AR_SREV_VERSION_9160) ||
|
||||
(ah->hw_version.macVersion == AR_SREV_VERSION_9100) ||
|
||||
(ah->hw_version.macVersion == AR_SREV_VERSION_9280) ||
|
||||
(ah->hw_version.macVersion == AR_SREV_VERSION_9285))
|
||||
pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
|
||||
else
|
||||
pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
|
||||
pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
|
||||
|
||||
if (AR_SREV_9280(ah) || AR_SREV_9285(ah))
|
||||
pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
|
||||
|
@@ -106,7 +106,7 @@
|
||||
#define AH_TSF_WRITE_TIMEOUT 100 /* (us) */
|
||||
#define AH_TIME_QUANTUM 10
|
||||
#define AR_KEYTABLE_SIZE 128
|
||||
#define POWER_UP_TIME 200000
|
||||
#define POWER_UP_TIME 10000
|
||||
#define SPUR_RSSI_THRESH 40
|
||||
|
||||
#define CAB_TIMEOUT_VAL 10
|
||||
@@ -650,7 +650,7 @@ void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
|
||||
const struct ath9k_beacon_state *bs);
|
||||
bool ath9k_hw_setpower(struct ath_hw *ah,
|
||||
enum ath9k_power_mode mode);
|
||||
void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
|
||||
void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore, int power_off);
|
||||
|
||||
/* Interrupt Handling */
|
||||
bool ath9k_hw_intrpend(struct ath_hw *ah);
|
||||
|
@@ -1131,7 +1131,7 @@ void ath_radio_enable(struct ath_softc *sc)
|
||||
int r;
|
||||
|
||||
ath9k_ps_wakeup(sc);
|
||||
ath9k_hw_configpcipowersave(ah, 0);
|
||||
ath9k_hw_configpcipowersave(ah, 0, 0);
|
||||
|
||||
if (!ah->curchan)
|
||||
ah->curchan = ath_get_curchannel(sc, sc->hw);
|
||||
@@ -1202,7 +1202,7 @@ void ath_radio_disable(struct ath_softc *sc)
|
||||
spin_unlock_bh(&sc->sc_resetlock);
|
||||
|
||||
ath9k_hw_phy_disable(ah);
|
||||
ath9k_hw_configpcipowersave(ah, 1);
|
||||
ath9k_hw_configpcipowersave(ah, 1, 1);
|
||||
ath9k_ps_restore(sc);
|
||||
ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
|
||||
}
|
||||
@@ -1226,11 +1226,6 @@ static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
|
||||
bool blocked = !!ath_is_rfkill_set(sc);
|
||||
|
||||
wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
|
||||
|
||||
if (blocked)
|
||||
ath_radio_disable(sc);
|
||||
else
|
||||
ath_radio_enable(sc);
|
||||
}
|
||||
|
||||
static void ath_start_rfkill_poll(struct ath_softc *sc)
|
||||
@@ -1260,6 +1255,7 @@ void ath_detach(struct ath_softc *sc)
|
||||
DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
|
||||
|
||||
ath_deinit_leds(sc);
|
||||
wiphy_rfkill_stop_polling(sc->hw->wiphy);
|
||||
|
||||
for (i = 0; i < sc->num_sec_wiphy; i++) {
|
||||
struct ath_wiphy *aphy = sc->sec_wiphy[i];
|
||||
@@ -1942,7 +1938,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
|
||||
init_channel = ath_get_curchannel(sc, hw);
|
||||
|
||||
/* Reset SERDES registers */
|
||||
ath9k_hw_configpcipowersave(sc->sc_ah, 0);
|
||||
ath9k_hw_configpcipowersave(sc->sc_ah, 0, 0);
|
||||
|
||||
/*
|
||||
* The basic interface to setting the hardware in a good
|
||||
@@ -2166,11 +2162,9 @@ static void ath9k_stop(struct ieee80211_hw *hw)
|
||||
} else
|
||||
sc->rx.rxlink = NULL;
|
||||
|
||||
wiphy_rfkill_stop_polling(sc->hw->wiphy);
|
||||
|
||||
/* disable HAL and put h/w to sleep */
|
||||
ath9k_hw_disable(sc->sc_ah);
|
||||
ath9k_hw_configpcipowersave(sc->sc_ah, 1);
|
||||
ath9k_hw_configpcipowersave(sc->sc_ah, 1, 1);
|
||||
ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP);
|
||||
|
||||
sc->sc_flags |= SC_OP_INVALID;
|
||||
|
@@ -676,8 +676,9 @@
|
||||
#define AR_RC_HOSTIF 0x00000100
|
||||
|
||||
#define AR_WA 0x4004
|
||||
#define AR_WA_D3_L1_DISABLE (1 << 14)
|
||||
#define AR9285_WA_DEFAULT 0x004a05cb
|
||||
#define AR9280_WA_DEFAULT 0x0040073f
|
||||
#define AR9280_WA_DEFAULT 0x0040073b
|
||||
#define AR_WA_DEFAULT 0x0000073f
|
||||
|
||||
|
||||
|
@@ -61,11 +61,28 @@ config B43_PCMCIA
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config B43_SDIO
|
||||
bool "Broadcom 43xx SDIO device support (EXPERIMENTAL)"
|
||||
depends on B43 && SSB_SDIOHOST_POSSIBLE && EXPERIMENTAL
|
||||
select SSB_SDIOHOST
|
||||
---help---
|
||||
Broadcom 43xx device support for Soft-MAC SDIO devices.
|
||||
|
||||
With this config option you can drive Soft-MAC b43 cards with a
|
||||
Secure Digital I/O interface.
|
||||
This includes the WLAN daughter card found on the Nintendo Wii
|
||||
video game console.
|
||||
Note that this does not support Broadcom 43xx Full-MAC devices.
|
||||
|
||||
It's safe to select Y here, even if you don't have a B43 SDIO device.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
# Data transfers to the device via PIO
|
||||
# This is only needed on PCMCIA devices. All others can do DMA properly.
|
||||
# This is only needed on PCMCIA and SDIO devices. All others can do DMA properly.
|
||||
config B43_PIO
|
||||
bool
|
||||
depends on B43 && (B43_PCMCIA || B43_FORCE_PIO)
|
||||
depends on B43 && (B43_SDIO || B43_PCMCIA || B43_FORCE_PIO)
|
||||
select SSB_BLOCKIO
|
||||
default y
|
||||
|
||||
|
@@ -16,6 +16,7 @@ b43-$(CONFIG_B43_PIO) += pio.o
|
||||
b43-y += rfkill.o
|
||||
b43-$(CONFIG_B43_LEDS) += leds.o
|
||||
b43-$(CONFIG_B43_PCMCIA) += pcmcia.o
|
||||
b43-$(CONFIG_B43_SDIO) += sdio.o
|
||||
b43-$(CONFIG_B43_DEBUG) += debugfs.o
|
||||
|
||||
obj-$(CONFIG_B43) += b43.o
|
||||
|
@@ -629,13 +629,6 @@ struct b43_wl {
|
||||
* from the mac80211 subsystem. */
|
||||
u16 mac80211_initially_registered_queues;
|
||||
|
||||
/* R/W lock for data transmission.
|
||||
* Transmissions on 2+ queues can run concurrently, but somebody else
|
||||
* might sync with TX by write_lock_irqsave()'ing. */
|
||||
rwlock_t tx_lock;
|
||||
/* Lock for LEDs access. */
|
||||
spinlock_t leds_lock;
|
||||
|
||||
/* We can only have one operating interface (802.11 core)
|
||||
* at a time. General information about this interface follows.
|
||||
*/
|
||||
@@ -686,6 +679,9 @@ struct b43_wl {
|
||||
struct work_struct tx_work;
|
||||
/* Queue of packets to be transmitted. */
|
||||
struct sk_buff_head tx_queue;
|
||||
|
||||
/* The device LEDs. */
|
||||
struct b43_leds leds;
|
||||
};
|
||||
|
||||
/* The type of the firmware file. */
|
||||
@@ -768,13 +764,10 @@ struct b43_wldev {
|
||||
/* The device initialization status.
|
||||
* Use b43_status() to query. */
|
||||
atomic_t __init_status;
|
||||
/* Saved init status for handling suspend. */
|
||||
int suspend_init_status;
|
||||
|
||||
bool bad_frames_preempt; /* Use "Bad Frames Preemption" (default off) */
|
||||
bool dfq_valid; /* Directed frame queue valid (IBSS PS mode, ATIM) */
|
||||
bool radio_hw_enable; /* saved state of radio hardware enabled state */
|
||||
bool suspend_in_progress; /* TRUE, if we are in a suspend/resume cycle */
|
||||
bool qos_enabled; /* TRUE, if QoS is used. */
|
||||
bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */
|
||||
|
||||
@@ -794,12 +787,6 @@ struct b43_wldev {
|
||||
/* Various statistics about the physical device. */
|
||||
struct b43_stats stats;
|
||||
|
||||
/* The device LEDs. */
|
||||
struct b43_led led_tx;
|
||||
struct b43_led led_rx;
|
||||
struct b43_led led_assoc;
|
||||
struct b43_led led_radio;
|
||||
|
||||
/* Reason code of the last interrupt. */
|
||||
u32 irq_reason;
|
||||
u32 dma_reason[6];
|
||||
@@ -830,6 +817,10 @@ struct b43_wldev {
|
||||
/* Debugging stuff follows. */
|
||||
#ifdef CONFIG_B43_DEBUG
|
||||
struct b43_dfsentry *dfsentry;
|
||||
unsigned int irq_count;
|
||||
unsigned int irq_bit_count[32];
|
||||
unsigned int tx_count;
|
||||
unsigned int rx_count;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@@ -689,6 +689,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev)
|
||||
add_dyn_dbg("debug_lo", B43_DBG_LO, 0);
|
||||
add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0);
|
||||
add_dyn_dbg("debug_keys", B43_DBG_KEYS, 0);
|
||||
add_dyn_dbg("debug_verbose_stats", B43_DBG_VERBOSESTATS, 0);
|
||||
|
||||
#undef add_dyn_dbg
|
||||
}
|
||||
|
@@ -13,6 +13,7 @@ enum b43_dyndbg { /* Dynamic debugging features */
|
||||
B43_DBG_LO,
|
||||
B43_DBG_FIRMWARE,
|
||||
B43_DBG_KEYS,
|
||||
B43_DBG_VERBOSESTATS,
|
||||
__B43_NR_DYNDBG,
|
||||
};
|
||||
|
||||
|
@@ -1428,9 +1428,9 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
|
||||
ring->nr_failed_tx_packets++;
|
||||
ring->nr_total_packet_tries += status->frame_count;
|
||||
#endif /* DEBUG */
|
||||
ieee80211_tx_status_irqsafe(dev->wl->hw, meta->skb);
|
||||
ieee80211_tx_status(dev->wl->hw, meta->skb);
|
||||
|
||||
/* skb is freed by ieee80211_tx_status_irqsafe() */
|
||||
/* skb is freed by ieee80211_tx_status() */
|
||||
meta->skb = NULL;
|
||||
} else {
|
||||
/* No need to call free_descriptor_buffer here, as
|
||||
|
@@ -34,35 +34,75 @@
|
||||
static void b43_led_turn_on(struct b43_wldev *dev, u8 led_index,
|
||||
bool activelow)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
unsigned long flags;
|
||||
u16 ctl;
|
||||
|
||||
spin_lock_irqsave(&wl->leds_lock, flags);
|
||||
ctl = b43_read16(dev, B43_MMIO_GPIO_CONTROL);
|
||||
if (activelow)
|
||||
ctl &= ~(1 << led_index);
|
||||
else
|
||||
ctl |= (1 << led_index);
|
||||
b43_write16(dev, B43_MMIO_GPIO_CONTROL, ctl);
|
||||
spin_unlock_irqrestore(&wl->leds_lock, flags);
|
||||
}
|
||||
|
||||
static void b43_led_turn_off(struct b43_wldev *dev, u8 led_index,
|
||||
bool activelow)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
unsigned long flags;
|
||||
u16 ctl;
|
||||
|
||||
spin_lock_irqsave(&wl->leds_lock, flags);
|
||||
ctl = b43_read16(dev, B43_MMIO_GPIO_CONTROL);
|
||||
if (activelow)
|
||||
ctl |= (1 << led_index);
|
||||
else
|
||||
ctl &= ~(1 << led_index);
|
||||
b43_write16(dev, B43_MMIO_GPIO_CONTROL, ctl);
|
||||
spin_unlock_irqrestore(&wl->leds_lock, flags);
|
||||
}
|
||||
|
||||
static void b43_led_update(struct b43_wldev *dev,
|
||||
struct b43_led *led)
|
||||
{
|
||||
bool radio_enabled;
|
||||
bool turn_on;
|
||||
|
||||
if (!led->wl)
|
||||
return;
|
||||
|
||||
radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable);
|
||||
|
||||
/* The led->state read is racy, but we don't care. In case we raced
|
||||
* with the brightness_set handler, we will be called again soon
|
||||
* to fixup our state. */
|
||||
if (radio_enabled)
|
||||
turn_on = atomic_read(&led->state) != LED_OFF;
|
||||
else
|
||||
turn_on = 0;
|
||||
if (turn_on == led->hw_state)
|
||||
return;
|
||||
led->hw_state = turn_on;
|
||||
|
||||
if (turn_on)
|
||||
b43_led_turn_on(dev, led->index, led->activelow);
|
||||
else
|
||||
b43_led_turn_off(dev, led->index, led->activelow);
|
||||
}
|
||||
|
||||
static void b43_leds_work(struct work_struct *work)
|
||||
{
|
||||
struct b43_leds *leds = container_of(work, struct b43_leds, work);
|
||||
struct b43_wl *wl = container_of(leds, struct b43_wl, leds);
|
||||
struct b43_wldev *dev;
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
dev = wl->current_dev;
|
||||
if (unlikely(!dev || b43_status(dev) < B43_STAT_STARTED))
|
||||
goto out_unlock;
|
||||
|
||||
b43_led_update(dev, &wl->leds.led_tx);
|
||||
b43_led_update(dev, &wl->leds.led_rx);
|
||||
b43_led_update(dev, &wl->leds.led_radio);
|
||||
b43_led_update(dev, &wl->leds.led_assoc);
|
||||
|
||||
out_unlock:
|
||||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
/* Callback from the LED subsystem. */
|
||||
@@ -70,21 +110,12 @@ static void b43_led_brightness_set(struct led_classdev *led_dev,
|
||||
enum led_brightness brightness)
|
||||
{
|
||||
struct b43_led *led = container_of(led_dev, struct b43_led, led_dev);
|
||||
struct b43_wldev *dev = led->dev;
|
||||
bool radio_enabled;
|
||||
struct b43_wl *wl = led->wl;
|
||||
|
||||
if (unlikely(b43_status(dev) < B43_STAT_INITIALIZED))
|
||||
return;
|
||||
|
||||
/* Checking the radio-enabled status here is slightly racy,
|
||||
* but we want to avoid the locking overhead and we don't care
|
||||
* whether the LED has the wrong state for a second. */
|
||||
radio_enabled = (dev->phy.radio_on && dev->radio_hw_enable);
|
||||
|
||||
if (brightness == LED_OFF || !radio_enabled)
|
||||
b43_led_turn_off(dev, led->index, led->activelow);
|
||||
else
|
||||
b43_led_turn_on(dev, led->index, led->activelow);
|
||||
if (likely(!wl->leds.stop)) {
|
||||
atomic_set(&led->state, brightness);
|
||||
ieee80211_queue_work(wl->hw, &wl->leds.work);
|
||||
}
|
||||
}
|
||||
|
||||
static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
|
||||
@@ -93,15 +124,15 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
|
||||
{
|
||||
int err;
|
||||
|
||||
b43_led_turn_off(dev, led_index, activelow);
|
||||
if (led->dev)
|
||||
if (led->wl)
|
||||
return -EEXIST;
|
||||
if (!default_trigger)
|
||||
return -EINVAL;
|
||||
led->dev = dev;
|
||||
led->wl = dev->wl;
|
||||
led->index = led_index;
|
||||
led->activelow = activelow;
|
||||
strncpy(led->name, name, sizeof(led->name));
|
||||
atomic_set(&led->state, 0);
|
||||
|
||||
led->led_dev.name = led->name;
|
||||
led->led_dev.default_trigger = default_trigger;
|
||||
@@ -110,19 +141,19 @@ static int b43_register_led(struct b43_wldev *dev, struct b43_led *led,
|
||||
err = led_classdev_register(dev->dev->dev, &led->led_dev);
|
||||
if (err) {
|
||||
b43warn(dev->wl, "LEDs: Failed to register %s\n", name);
|
||||
led->dev = NULL;
|
||||
led->wl = NULL;
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void b43_unregister_led(struct b43_led *led)
|
||||
{
|
||||
if (!led->dev)
|
||||
if (!led->wl)
|
||||
return;
|
||||
led_classdev_unregister(&led->led_dev);
|
||||
b43_led_turn_off(led->dev, led->index, led->activelow);
|
||||
led->dev = NULL;
|
||||
led->wl = NULL;
|
||||
}
|
||||
|
||||
static void b43_map_led(struct b43_wldev *dev,
|
||||
@@ -137,24 +168,20 @@ static void b43_map_led(struct b43_wldev *dev,
|
||||
* generic LED triggers. */
|
||||
switch (behaviour) {
|
||||
case B43_LED_INACTIVE:
|
||||
break;
|
||||
case B43_LED_OFF:
|
||||
b43_led_turn_off(dev, led_index, activelow);
|
||||
break;
|
||||
case B43_LED_ON:
|
||||
b43_led_turn_on(dev, led_index, activelow);
|
||||
break;
|
||||
case B43_LED_ACTIVITY:
|
||||
case B43_LED_TRANSFER:
|
||||
case B43_LED_APTRANSFER:
|
||||
snprintf(name, sizeof(name),
|
||||
"b43-%s::tx", wiphy_name(hw->wiphy));
|
||||
b43_register_led(dev, &dev->led_tx, name,
|
||||
b43_register_led(dev, &dev->wl->leds.led_tx, name,
|
||||
ieee80211_get_tx_led_name(hw),
|
||||
led_index, activelow);
|
||||
snprintf(name, sizeof(name),
|
||||
"b43-%s::rx", wiphy_name(hw->wiphy));
|
||||
b43_register_led(dev, &dev->led_rx, name,
|
||||
b43_register_led(dev, &dev->wl->leds.led_rx, name,
|
||||
ieee80211_get_rx_led_name(hw),
|
||||
led_index, activelow);
|
||||
break;
|
||||
@@ -164,18 +191,15 @@ static void b43_map_led(struct b43_wldev *dev,
|
||||
case B43_LED_MODE_BG:
|
||||
snprintf(name, sizeof(name),
|
||||
"b43-%s::radio", wiphy_name(hw->wiphy));
|
||||
b43_register_led(dev, &dev->led_radio, name,
|
||||
b43_register_led(dev, &dev->wl->leds.led_radio, name,
|
||||
ieee80211_get_radio_led_name(hw),
|
||||
led_index, activelow);
|
||||
/* Sync the RF-kill LED state with radio and switch states. */
|
||||
if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev))
|
||||
b43_led_turn_on(dev, led_index, activelow);
|
||||
break;
|
||||
case B43_LED_WEIRD:
|
||||
case B43_LED_ASSOC:
|
||||
snprintf(name, sizeof(name),
|
||||
"b43-%s::assoc", wiphy_name(hw->wiphy));
|
||||
b43_register_led(dev, &dev->led_assoc, name,
|
||||
b43_register_led(dev, &dev->wl->leds.led_assoc, name,
|
||||
ieee80211_get_assoc_led_name(hw),
|
||||
led_index, activelow);
|
||||
break;
|
||||
@@ -186,58 +210,150 @@ static void b43_map_led(struct b43_wldev *dev,
|
||||
}
|
||||
}
|
||||
|
||||
void b43_leds_init(struct b43_wldev *dev)
|
||||
static void b43_led_get_sprominfo(struct b43_wldev *dev,
|
||||
unsigned int led_index,
|
||||
enum b43_led_behaviour *behaviour,
|
||||
bool *activelow)
|
||||
{
|
||||
struct ssb_bus *bus = dev->dev->bus;
|
||||
u8 sprom[4];
|
||||
int i;
|
||||
enum b43_led_behaviour behaviour;
|
||||
bool activelow;
|
||||
|
||||
sprom[0] = bus->sprom.gpio0;
|
||||
sprom[1] = bus->sprom.gpio1;
|
||||
sprom[2] = bus->sprom.gpio2;
|
||||
sprom[3] = bus->sprom.gpio3;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (sprom[i] == 0xFF) {
|
||||
/* There is no LED information in the SPROM
|
||||
* for this LED. Hardcode it here. */
|
||||
activelow = 0;
|
||||
switch (i) {
|
||||
case 0:
|
||||
behaviour = B43_LED_ACTIVITY;
|
||||
activelow = 1;
|
||||
if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
|
||||
behaviour = B43_LED_RADIO_ALL;
|
||||
break;
|
||||
case 1:
|
||||
behaviour = B43_LED_RADIO_B;
|
||||
if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK)
|
||||
behaviour = B43_LED_ASSOC;
|
||||
break;
|
||||
case 2:
|
||||
behaviour = B43_LED_RADIO_A;
|
||||
break;
|
||||
case 3:
|
||||
behaviour = B43_LED_OFF;
|
||||
break;
|
||||
default:
|
||||
B43_WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
behaviour = sprom[i] & B43_LED_BEHAVIOUR;
|
||||
activelow = !!(sprom[i] & B43_LED_ACTIVELOW);
|
||||
if (sprom[led_index] == 0xFF) {
|
||||
/* There is no LED information in the SPROM
|
||||
* for this LED. Hardcode it here. */
|
||||
*activelow = 0;
|
||||
switch (led_index) {
|
||||
case 0:
|
||||
*behaviour = B43_LED_ACTIVITY;
|
||||
*activelow = 1;
|
||||
if (bus->boardinfo.vendor == PCI_VENDOR_ID_COMPAQ)
|
||||
*behaviour = B43_LED_RADIO_ALL;
|
||||
break;
|
||||
case 1:
|
||||
*behaviour = B43_LED_RADIO_B;
|
||||
if (bus->boardinfo.vendor == PCI_VENDOR_ID_ASUSTEK)
|
||||
*behaviour = B43_LED_ASSOC;
|
||||
break;
|
||||
case 2:
|
||||
*behaviour = B43_LED_RADIO_A;
|
||||
break;
|
||||
case 3:
|
||||
*behaviour = B43_LED_OFF;
|
||||
break;
|
||||
default:
|
||||
B43_WARN_ON(1);
|
||||
return;
|
||||
}
|
||||
b43_map_led(dev, i, behaviour, activelow);
|
||||
} else {
|
||||
*behaviour = sprom[led_index] & B43_LED_BEHAVIOUR;
|
||||
*activelow = !!(sprom[led_index] & B43_LED_ACTIVELOW);
|
||||
}
|
||||
}
|
||||
|
||||
void b43_leds_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_led *led;
|
||||
unsigned int i;
|
||||
enum b43_led_behaviour behaviour;
|
||||
bool activelow;
|
||||
|
||||
/* Sync the RF-kill LED state (if we have one) with radio and switch states. */
|
||||
led = &dev->wl->leds.led_radio;
|
||||
if (led->wl) {
|
||||
if (dev->phy.radio_on && b43_is_hw_radio_enabled(dev)) {
|
||||
b43_led_turn_on(dev, led->index, led->activelow);
|
||||
led->hw_state = 1;
|
||||
atomic_set(&led->state, 1);
|
||||
} else {
|
||||
b43_led_turn_off(dev, led->index, led->activelow);
|
||||
led->hw_state = 0;
|
||||
atomic_set(&led->state, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize TX/RX/ASSOC leds */
|
||||
led = &dev->wl->leds.led_tx;
|
||||
if (led->wl) {
|
||||
b43_led_turn_off(dev, led->index, led->activelow);
|
||||
led->hw_state = 0;
|
||||
atomic_set(&led->state, 0);
|
||||
}
|
||||
led = &dev->wl->leds.led_rx;
|
||||
if (led->wl) {
|
||||
b43_led_turn_off(dev, led->index, led->activelow);
|
||||
led->hw_state = 0;
|
||||
atomic_set(&led->state, 0);
|
||||
}
|
||||
led = &dev->wl->leds.led_assoc;
|
||||
if (led->wl) {
|
||||
b43_led_turn_off(dev, led->index, led->activelow);
|
||||
led->hw_state = 0;
|
||||
atomic_set(&led->state, 0);
|
||||
}
|
||||
|
||||
/* Initialize other LED states. */
|
||||
for (i = 0; i < B43_MAX_NR_LEDS; i++) {
|
||||
b43_led_get_sprominfo(dev, i, &behaviour, &activelow);
|
||||
switch (behaviour) {
|
||||
case B43_LED_OFF:
|
||||
b43_led_turn_off(dev, i, activelow);
|
||||
break;
|
||||
case B43_LED_ON:
|
||||
b43_led_turn_on(dev, i, activelow);
|
||||
break;
|
||||
default:
|
||||
/* Leave others as-is. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dev->wl->leds.stop = 0;
|
||||
}
|
||||
|
||||
void b43_leds_exit(struct b43_wldev *dev)
|
||||
{
|
||||
b43_unregister_led(&dev->led_tx);
|
||||
b43_unregister_led(&dev->led_rx);
|
||||
b43_unregister_led(&dev->led_assoc);
|
||||
b43_unregister_led(&dev->led_radio);
|
||||
struct b43_leds *leds = &dev->wl->leds;
|
||||
|
||||
b43_led_turn_off(dev, leds->led_tx.index, leds->led_tx.activelow);
|
||||
b43_led_turn_off(dev, leds->led_rx.index, leds->led_rx.activelow);
|
||||
b43_led_turn_off(dev, leds->led_assoc.index, leds->led_assoc.activelow);
|
||||
b43_led_turn_off(dev, leds->led_radio.index, leds->led_radio.activelow);
|
||||
}
|
||||
|
||||
void b43_leds_stop(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_leds *leds = &dev->wl->leds;
|
||||
|
||||
leds->stop = 1;
|
||||
cancel_work_sync(&leds->work);
|
||||
}
|
||||
|
||||
void b43_leds_register(struct b43_wldev *dev)
|
||||
{
|
||||
unsigned int i;
|
||||
enum b43_led_behaviour behaviour;
|
||||
bool activelow;
|
||||
|
||||
INIT_WORK(&dev->wl->leds.work, b43_leds_work);
|
||||
|
||||
/* Register the LEDs to the LED subsystem. */
|
||||
for (i = 0; i < B43_MAX_NR_LEDS; i++) {
|
||||
b43_led_get_sprominfo(dev, i, &behaviour, &activelow);
|
||||
b43_map_led(dev, i, behaviour, activelow);
|
||||
}
|
||||
}
|
||||
|
||||
void b43_leds_unregister(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_leds *leds = &dev->wl->leds;
|
||||
|
||||
b43_unregister_led(&leds->led_tx);
|
||||
b43_unregister_led(&leds->led_rx);
|
||||
b43_unregister_led(&leds->led_assoc);
|
||||
b43_unregister_led(&leds->led_radio);
|
||||
}
|
||||
|
@@ -7,12 +7,13 @@ struct b43_wldev;
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
|
||||
#define B43_LED_MAX_NAME_LEN 31
|
||||
|
||||
struct b43_led {
|
||||
struct b43_wldev *dev;
|
||||
struct b43_wl *wl;
|
||||
/* The LED class device */
|
||||
struct led_classdev led_dev;
|
||||
/* The index number of the LED. */
|
||||
@@ -22,8 +23,24 @@ struct b43_led {
|
||||
bool activelow;
|
||||
/* The unique name string for this LED device. */
|
||||
char name[B43_LED_MAX_NAME_LEN + 1];
|
||||
/* The current status of the LED. This is updated locklessly. */
|
||||
atomic_t state;
|
||||
/* The active state in hardware. */
|
||||
bool hw_state;
|
||||
};
|
||||
|
||||
struct b43_leds {
|
||||
struct b43_led led_tx;
|
||||
struct b43_led led_rx;
|
||||
struct b43_led led_radio;
|
||||
struct b43_led led_assoc;
|
||||
|
||||
bool stop;
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
#define B43_MAX_NR_LEDS 4
|
||||
|
||||
#define B43_LED_BEHAVIOUR 0x7F
|
||||
#define B43_LED_ACTIVELOW 0x80
|
||||
/* LED behaviour values */
|
||||
@@ -42,23 +59,35 @@ enum b43_led_behaviour {
|
||||
B43_LED_INACTIVE,
|
||||
};
|
||||
|
||||
void b43_leds_register(struct b43_wldev *dev);
|
||||
void b43_leds_unregister(struct b43_wldev *dev);
|
||||
void b43_leds_init(struct b43_wldev *dev);
|
||||
void b43_leds_exit(struct b43_wldev *dev);
|
||||
void b43_leds_stop(struct b43_wldev *dev);
|
||||
|
||||
|
||||
#else /* CONFIG_B43_LEDS */
|
||||
/* LED support disabled */
|
||||
|
||||
struct b43_led {
|
||||
struct b43_leds {
|
||||
/* empty */
|
||||
};
|
||||
|
||||
static inline void b43_leds_register(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
static inline void b43_leds_unregister(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
static inline void b43_leds_init(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
static inline void b43_leds_exit(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
static inline void b43_leds_stop(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_B43_LEDS */
|
||||
|
||||
#endif /* B43_LEDS_H_ */
|
||||
|
@@ -8,6 +8,9 @@
|
||||
Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
|
||||
Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
|
||||
|
||||
SDIO support
|
||||
Copyright (c) 2009 Albert Herranz <albert_herranz@yahoo.es>
|
||||
|
||||
Some parts of the code in this file are derived from the ipw2200
|
||||
driver Copyright(c) 2003 - 2004 Intel Corporation.
|
||||
|
||||
@@ -53,6 +56,8 @@
|
||||
#include "xmit.h"
|
||||
#include "lo.h"
|
||||
#include "pcmcia.h"
|
||||
#include "sdio.h"
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
|
||||
MODULE_DESCRIPTION("Broadcom B43 wireless driver");
|
||||
MODULE_AUTHOR("Martin Langer");
|
||||
@@ -1587,7 +1592,7 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
|
||||
mutex_lock(&wl->mutex);
|
||||
dev = wl->current_dev;
|
||||
if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
|
||||
if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
|
||||
if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
|
||||
/* wl->mutex is enough. */
|
||||
b43_do_beacon_update_trigger_work(dev);
|
||||
mmiowb();
|
||||
@@ -1825,6 +1830,16 @@ static void b43_do_interrupt_thread(struct b43_wldev *dev)
|
||||
|
||||
/* Re-enable interrupts on the device by restoring the current interrupt mask. */
|
||||
b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
|
||||
|
||||
#if B43_DEBUG
|
||||
if (b43_debug(dev, B43_DBG_VERBOSESTATS)) {
|
||||
dev->irq_count++;
|
||||
for (i = 0; i < ARRAY_SIZE(dev->irq_bit_count); i++) {
|
||||
if (reason & (1 << i))
|
||||
dev->irq_bit_count[i]++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Interrupt thread handler. Handles device interrupts in thread context. */
|
||||
@@ -1905,6 +1920,21 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* SDIO interrupt handler. This runs in process context. */
|
||||
static void b43_sdio_interrupt_handler(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
irqreturn_t ret;
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
|
||||
ret = b43_do_interrupt(dev);
|
||||
if (ret == IRQ_WAKE_THREAD)
|
||||
b43_do_interrupt_thread(dev);
|
||||
|
||||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
void b43_do_release_fw(struct b43_firmware_file *fw)
|
||||
{
|
||||
release_firmware(fw->data);
|
||||
@@ -2645,6 +2675,20 @@ static void b43_adjust_opmode(struct b43_wldev *dev)
|
||||
cfp_pretbtt = 50;
|
||||
}
|
||||
b43_write16(dev, 0x612, cfp_pretbtt);
|
||||
|
||||
/* FIXME: We don't currently implement the PMQ mechanism,
|
||||
* so always disable it. If we want to implement PMQ,
|
||||
* we need to enable it here (clear DISCPMQ) in AP mode.
|
||||
*/
|
||||
if (0 /* ctl & B43_MACCTL_AP */) {
|
||||
b43_write32(dev, B43_MMIO_MACCTL,
|
||||
b43_read32(dev, B43_MMIO_MACCTL)
|
||||
& ~B43_MACCTL_DISCPMQ);
|
||||
} else {
|
||||
b43_write32(dev, B43_MMIO_MACCTL,
|
||||
b43_read32(dev, B43_MMIO_MACCTL)
|
||||
| B43_MACCTL_DISCPMQ);
|
||||
}
|
||||
}
|
||||
|
||||
static void b43_rate_memory_write(struct b43_wldev *dev, u16 rate, int is_ofdm)
|
||||
@@ -2873,6 +2917,27 @@ static void b43_periodic_every15sec(struct b43_wldev *dev)
|
||||
|
||||
atomic_set(&phy->txerr_cnt, B43_PHY_TX_BADNESS_LIMIT);
|
||||
wmb();
|
||||
|
||||
#if B43_DEBUG
|
||||
if (b43_debug(dev, B43_DBG_VERBOSESTATS)) {
|
||||
unsigned int i;
|
||||
|
||||
b43dbg(dev->wl, "Stats: %7u IRQs/sec, %7u TX/sec, %7u RX/sec\n",
|
||||
dev->irq_count / 15,
|
||||
dev->tx_count / 15,
|
||||
dev->rx_count / 15);
|
||||
dev->irq_count = 0;
|
||||
dev->tx_count = 0;
|
||||
dev->rx_count = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(dev->irq_bit_count); i++) {
|
||||
if (dev->irq_bit_count[i]) {
|
||||
b43dbg(dev->wl, "Stats: %7u IRQ-%02u/sec (0x%08X)\n",
|
||||
dev->irq_bit_count[i] / 15, i, (1 << i));
|
||||
dev->irq_bit_count[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void do_periodic_work(struct b43_wldev *dev)
|
||||
@@ -3002,14 +3067,18 @@ static void b43_security_init(struct b43_wldev *dev)
|
||||
static int b43_rng_read(struct hwrng *rng, u32 *data)
|
||||
{
|
||||
struct b43_wl *wl = (struct b43_wl *)rng->priv;
|
||||
struct b43_wldev *dev;
|
||||
int count = -ENODEV;
|
||||
|
||||
/* FIXME: We need to take wl->mutex here to make sure the device
|
||||
* is not going away from under our ass. However it could deadlock
|
||||
* with hwrng internal locking. */
|
||||
mutex_lock(&wl->mutex);
|
||||
dev = wl->current_dev;
|
||||
if (likely(dev && b43_status(dev) >= B43_STAT_INITIALIZED)) {
|
||||
*data = b43_read16(dev, B43_MMIO_RNG);
|
||||
count = sizeof(u16);
|
||||
}
|
||||
mutex_unlock(&wl->mutex);
|
||||
|
||||
*data = b43_read16(wl->current_dev, B43_MMIO_RNG);
|
||||
|
||||
return (sizeof(u16));
|
||||
return count;
|
||||
}
|
||||
#endif /* CONFIG_B43_HWRNG */
|
||||
|
||||
@@ -3068,6 +3137,9 @@ static void b43_tx_work(struct work_struct *work)
|
||||
dev_kfree_skb(skb); /* Drop it */
|
||||
}
|
||||
|
||||
#if B43_DEBUG
|
||||
dev->tx_count++;
|
||||
#endif
|
||||
mutex_unlock(&wl->mutex);
|
||||
}
|
||||
|
||||
@@ -3820,7 +3892,7 @@ redo:
|
||||
|
||||
/* Disable interrupts on the device. */
|
||||
b43_set_status(dev, B43_STAT_INITIALIZED);
|
||||
if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
|
||||
if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
|
||||
/* wl->mutex is locked. That is enough. */
|
||||
b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
|
||||
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
|
||||
@@ -3830,10 +3902,15 @@ redo:
|
||||
b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
|
||||
spin_unlock_irq(&wl->hardirq_lock);
|
||||
}
|
||||
/* Synchronize the interrupt handlers. Unlock to avoid deadlocks. */
|
||||
/* Synchronize and free the interrupt handlers. Unlock to avoid deadlocks. */
|
||||
orig_dev = dev;
|
||||
mutex_unlock(&wl->mutex);
|
||||
synchronize_irq(dev->dev->irq);
|
||||
if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
|
||||
b43_sdio_free_irq(dev);
|
||||
} else {
|
||||
synchronize_irq(dev->dev->irq);
|
||||
free_irq(dev->dev->irq, dev);
|
||||
}
|
||||
mutex_lock(&wl->mutex);
|
||||
dev = wl->current_dev;
|
||||
if (!dev)
|
||||
@@ -3850,7 +3927,7 @@ redo:
|
||||
dev_kfree_skb(skb_dequeue(&wl->tx_queue));
|
||||
|
||||
b43_mac_suspend(dev);
|
||||
free_irq(dev->dev->irq, dev);
|
||||
b43_leds_exit(dev);
|
||||
b43dbg(wl, "Wireless interface stopped\n");
|
||||
|
||||
return dev;
|
||||
@@ -3864,12 +3941,20 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
|
||||
B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
|
||||
|
||||
drain_txstatus_queue(dev);
|
||||
err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
|
||||
b43_interrupt_thread_handler,
|
||||
IRQF_SHARED, KBUILD_MODNAME, dev);
|
||||
if (err) {
|
||||
b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
|
||||
goto out;
|
||||
if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
|
||||
err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);
|
||||
if (err) {
|
||||
b43err(dev->wl, "Cannot request SDIO IRQ\n");
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
|
||||
b43_interrupt_thread_handler,
|
||||
IRQF_SHARED, KBUILD_MODNAME, dev);
|
||||
if (err) {
|
||||
b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* We are ready to run. */
|
||||
@@ -3882,8 +3967,10 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
|
||||
/* Start maintainance work */
|
||||
b43_periodic_tasks_setup(dev);
|
||||
|
||||
b43_leds_init(dev);
|
||||
|
||||
b43dbg(dev->wl, "Wireless interface started\n");
|
||||
out:
|
||||
out:
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -4160,10 +4247,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
|
||||
macctl |= B43_MACCTL_PSM_JMP0;
|
||||
b43_write32(dev, B43_MMIO_MACCTL, macctl);
|
||||
|
||||
if (!dev->suspend_in_progress) {
|
||||
b43_leds_exit(dev);
|
||||
b43_rng_exit(dev->wl);
|
||||
}
|
||||
b43_dma_free(dev);
|
||||
b43_pio_free(dev);
|
||||
b43_chip_exit(dev);
|
||||
@@ -4180,7 +4263,6 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
|
||||
/* Initialize a wireless core */
|
||||
static int b43_wireless_core_init(struct b43_wldev *dev)
|
||||
{
|
||||
struct b43_wl *wl = dev->wl;
|
||||
struct ssb_bus *bus = dev->dev->bus;
|
||||
struct ssb_sprom *sprom = &bus->sprom;
|
||||
struct b43_phy *phy = &dev->phy;
|
||||
@@ -4264,7 +4346,9 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
|
||||
/* Maximum Contention Window */
|
||||
b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
|
||||
|
||||
if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || B43_FORCE_PIO) {
|
||||
if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
|
||||
(dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
|
||||
B43_FORCE_PIO) {
|
||||
dev->__using_pio_transfers = 1;
|
||||
err = b43_pio_init(dev);
|
||||
} else {
|
||||
@@ -4280,15 +4364,13 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
|
||||
ssb_bus_powerup(bus, !(sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW));
|
||||
b43_upload_card_macaddress(dev);
|
||||
b43_security_init(dev);
|
||||
if (!dev->suspend_in_progress)
|
||||
b43_rng_init(wl);
|
||||
|
||||
ieee80211_wake_queues(dev->wl->hw);
|
||||
|
||||
ieee80211_wake_queues(dev->wl->hw);
|
||||
|
||||
b43_set_status(dev, B43_STAT_INITIALIZED);
|
||||
|
||||
if (!dev->suspend_in_progress)
|
||||
b43_leds_init(dev);
|
||||
out:
|
||||
return err;
|
||||
|
||||
@@ -4837,7 +4919,6 @@ static int b43_wireless_init(struct ssb_device *dev)
|
||||
|
||||
/* Initialize struct b43_wl */
|
||||
wl->hw = hw;
|
||||
spin_lock_init(&wl->leds_lock);
|
||||
mutex_init(&wl->mutex);
|
||||
spin_lock_init(&wl->hardirq_lock);
|
||||
INIT_LIST_HEAD(&wl->devlist);
|
||||
@@ -4878,6 +4959,8 @@ static int b43_probe(struct ssb_device *dev, const struct ssb_device_id *id)
|
||||
err = ieee80211_register_hw(wl->hw);
|
||||
if (err)
|
||||
goto err_one_core_detach;
|
||||
b43_leds_register(wl->current_dev);
|
||||
b43_rng_init(wl);
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -4906,12 +4989,15 @@ static void b43_remove(struct ssb_device *dev)
|
||||
* might have modified it. Restoring is important, so the networking
|
||||
* stack can properly free resources. */
|
||||
wl->hw->queues = wl->mac80211_initially_registered_queues;
|
||||
b43_leds_stop(wldev);
|
||||
ieee80211_unregister_hw(wl->hw);
|
||||
}
|
||||
|
||||
b43_one_core_detach(dev);
|
||||
|
||||
if (list_empty(&wl->devlist)) {
|
||||
b43_rng_exit(wl);
|
||||
b43_leds_unregister(wldev);
|
||||
/* Last core on the chip unregistered.
|
||||
* We can destroy common struct b43_wl.
|
||||
*/
|
||||
@@ -4929,80 +5015,17 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason)
|
||||
ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int b43_suspend(struct ssb_device *dev, pm_message_t state)
|
||||
{
|
||||
struct b43_wldev *wldev = ssb_get_drvdata(dev);
|
||||
struct b43_wl *wl = wldev->wl;
|
||||
|
||||
b43dbg(wl, "Suspending...\n");
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
wldev->suspend_in_progress = true;
|
||||
wldev->suspend_init_status = b43_status(wldev);
|
||||
if (wldev->suspend_init_status >= B43_STAT_STARTED)
|
||||
wldev = b43_wireless_core_stop(wldev);
|
||||
if (wldev && wldev->suspend_init_status >= B43_STAT_INITIALIZED)
|
||||
b43_wireless_core_exit(wldev);
|
||||
mutex_unlock(&wl->mutex);
|
||||
|
||||
b43dbg(wl, "Device suspended.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int b43_resume(struct ssb_device *dev)
|
||||
{
|
||||
struct b43_wldev *wldev = ssb_get_drvdata(dev);
|
||||
struct b43_wl *wl = wldev->wl;
|
||||
int err = 0;
|
||||
|
||||
b43dbg(wl, "Resuming...\n");
|
||||
|
||||
mutex_lock(&wl->mutex);
|
||||
if (wldev->suspend_init_status >= B43_STAT_INITIALIZED) {
|
||||
err = b43_wireless_core_init(wldev);
|
||||
if (err) {
|
||||
b43err(wl, "Resume failed at core init\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
if (wldev->suspend_init_status >= B43_STAT_STARTED) {
|
||||
err = b43_wireless_core_start(wldev);
|
||||
if (err) {
|
||||
b43_leds_exit(wldev);
|
||||
b43_rng_exit(wldev->wl);
|
||||
b43_wireless_core_exit(wldev);
|
||||
b43err(wl, "Resume failed at core start\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
b43dbg(wl, "Device resumed.\n");
|
||||
out:
|
||||
wldev->suspend_in_progress = false;
|
||||
mutex_unlock(&wl->mutex);
|
||||
return err;
|
||||
}
|
||||
|
||||
#else /* CONFIG_PM */
|
||||
# define b43_suspend NULL
|
||||
# define b43_resume NULL
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct ssb_driver b43_ssb_driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = b43_ssb_tbl,
|
||||
.probe = b43_probe,
|
||||
.remove = b43_remove,
|
||||
.suspend = b43_suspend,
|
||||
.resume = b43_resume,
|
||||
};
|
||||
|
||||
static void b43_print_driverinfo(void)
|
||||
{
|
||||
const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "",
|
||||
*feat_leds = "";
|
||||
*feat_leds = "", *feat_sdio = "";
|
||||
|
||||
#ifdef CONFIG_B43_PCI_AUTOSELECT
|
||||
feat_pci = "P";
|
||||
@@ -5015,12 +5038,15 @@ static void b43_print_driverinfo(void)
|
||||
#endif
|
||||
#ifdef CONFIG_B43_LEDS
|
||||
feat_leds = "L";
|
||||
#endif
|
||||
#ifdef CONFIG_B43_SDIO
|
||||
feat_sdio = "S";
|
||||
#endif
|
||||
printk(KERN_INFO "Broadcom 43xx driver loaded "
|
||||
"[ Features: %s%s%s%s, Firmware-ID: "
|
||||
"[ Features: %s%s%s%s%s, Firmware-ID: "
|
||||
B43_SUPPORTED_FIRMWARE_ID " ]\n",
|
||||
feat_pci, feat_pcmcia, feat_nphy,
|
||||
feat_leds);
|
||||
feat_leds, feat_sdio);
|
||||
}
|
||||
|
||||
static int __init b43_init(void)
|
||||
@@ -5031,13 +5057,18 @@ static int __init b43_init(void)
|
||||
err = b43_pcmcia_init();
|
||||
if (err)
|
||||
goto err_dfs_exit;
|
||||
err = ssb_driver_register(&b43_ssb_driver);
|
||||
err = b43_sdio_init();
|
||||
if (err)
|
||||
goto err_pcmcia_exit;
|
||||
err = ssb_driver_register(&b43_ssb_driver);
|
||||
if (err)
|
||||
goto err_sdio_exit;
|
||||
b43_print_driverinfo();
|
||||
|
||||
return err;
|
||||
|
||||
err_sdio_exit:
|
||||
b43_sdio_exit();
|
||||
err_pcmcia_exit:
|
||||
b43_pcmcia_exit();
|
||||
err_dfs_exit:
|
||||
@@ -5048,6 +5079,7 @@ err_dfs_exit:
|
||||
static void __exit b43_exit(void)
|
||||
{
|
||||
ssb_driver_unregister(&b43_ssb_driver);
|
||||
b43_sdio_exit();
|
||||
b43_pcmcia_exit();
|
||||
b43_debugfs_exit();
|
||||
}
|
||||
|
@@ -2228,6 +2228,16 @@ static enum b43_txpwr_result b43_lpphy_op_recalc_txpower(struct b43_wldev *dev,
|
||||
return B43_TXPWR_RES_DONE;
|
||||
}
|
||||
|
||||
void b43_lpphy_op_switch_analog(struct b43_wldev *dev, bool on)
|
||||
{
|
||||
if (on) {
|
||||
b43_phy_mask(dev, B43_LPPHY_AFE_CTL_OVR, 0xfff8);
|
||||
} else {
|
||||
b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVRVAL, 0x0007);
|
||||
b43_phy_set(dev, B43_LPPHY_AFE_CTL_OVR, 0x0007);
|
||||
}
|
||||
}
|
||||
|
||||
const struct b43_phy_operations b43_phyops_lp = {
|
||||
.allocate = b43_lpphy_op_allocate,
|
||||
.free = b43_lpphy_op_free,
|
||||
@@ -2239,7 +2249,7 @@ const struct b43_phy_operations b43_phyops_lp = {
|
||||
.radio_read = b43_lpphy_op_radio_read,
|
||||
.radio_write = b43_lpphy_op_radio_write,
|
||||
.software_rfkill = b43_lpphy_op_software_rfkill,
|
||||
.switch_analog = b43_phyop_switch_analog_generic,
|
||||
.switch_analog = b43_lpphy_op_switch_analog,
|
||||
.switch_channel = b43_lpphy_op_switch_channel,
|
||||
.get_default_chan = b43_lpphy_op_get_default_chan,
|
||||
.set_rx_antenna = b43_lpphy_op_set_rx_antenna,
|
||||
|
@@ -574,7 +574,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev,
|
||||
q->buffer_used -= total_len;
|
||||
q->free_packet_slots += 1;
|
||||
|
||||
ieee80211_tx_status_irqsafe(dev->wl->hw, pack->skb);
|
||||
ieee80211_tx_status(dev->wl->hw, pack->skb);
|
||||
pack->skb = NULL;
|
||||
list_add(&pack->list, &q->packets_list);
|
||||
|
||||
|
@@ -28,7 +28,7 @@
|
||||
/* Returns TRUE, if the radio is enabled in hardware. */
|
||||
bool b43_is_hw_radio_enabled(struct b43_wldev *dev)
|
||||
{
|
||||
if (dev->phy.rev >= 3) {
|
||||
if (dev->phy.rev >= 3 || dev->phy.type == B43_PHYTYPE_LP) {
|
||||
if (!(b43_read32(dev, B43_MMIO_RADIO_HWENABLED_HI)
|
||||
& B43_MMIO_RADIO_HWENABLED_HI_MASK))
|
||||
return 1;
|
||||
|
202
drivers/net/wireless/b43/sdio.c
Normal file
202
drivers/net/wireless/b43/sdio.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Broadcom B43 wireless driver
|
||||
*
|
||||
* SDIO over Sonics Silicon Backplane bus glue for b43.
|
||||
*
|
||||
* Copyright (C) 2009 Albert Herranz
|
||||
* Copyright (C) 2009 Michael Buesch <mb@bu3sch.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or (at
|
||||
* your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/sdio_func.h>
|
||||
#include <linux/mmc/sdio_ids.h>
|
||||
#include <linux/ssb/ssb.h>
|
||||
|
||||
#include "sdio.h"
|
||||
#include "b43.h"
|
||||
|
||||
|
||||
#define HNBU_CHIPID 0x01 /* vendor & device id */
|
||||
|
||||
#define B43_SDIO_BLOCK_SIZE 64 /* rx fifo max size in bytes */
|
||||
|
||||
|
||||
static const struct b43_sdio_quirk {
|
||||
u16 vendor;
|
||||
u16 device;
|
||||
unsigned int quirks;
|
||||
} b43_sdio_quirks[] = {
|
||||
{ 0x14E4, 0x4318, SSB_QUIRK_SDIO_READ_AFTER_WRITE32, },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
||||
static unsigned int b43_sdio_get_quirks(u16 vendor, u16 device)
|
||||
{
|
||||
const struct b43_sdio_quirk *q;
|
||||
|
||||
for (q = b43_sdio_quirks; q->quirks; q++) {
|
||||
if (vendor == q->vendor && device == q->device)
|
||||
return q->quirks;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void b43_sdio_interrupt_dispatcher(struct sdio_func *func)
|
||||
{
|
||||
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
||||
struct b43_wldev *dev = sdio->irq_handler_opaque;
|
||||
|
||||
if (unlikely(b43_status(dev) < B43_STAT_STARTED))
|
||||
return;
|
||||
|
||||
sdio_release_host(func);
|
||||
sdio->irq_handler(dev);
|
||||
sdio_claim_host(func);
|
||||
}
|
||||
|
||||
int b43_sdio_request_irq(struct b43_wldev *dev,
|
||||
void (*handler)(struct b43_wldev *dev))
|
||||
{
|
||||
struct ssb_bus *bus = dev->dev->bus;
|
||||
struct sdio_func *func = bus->host_sdio;
|
||||
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
||||
int err;
|
||||
|
||||
sdio->irq_handler_opaque = dev;
|
||||
sdio->irq_handler = handler;
|
||||
sdio_claim_host(func);
|
||||
err = sdio_claim_irq(func, b43_sdio_interrupt_dispatcher);
|
||||
sdio_release_host(func);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void b43_sdio_free_irq(struct b43_wldev *dev)
|
||||
{
|
||||
struct ssb_bus *bus = dev->dev->bus;
|
||||
struct sdio_func *func = bus->host_sdio;
|
||||
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
||||
|
||||
sdio_claim_host(func);
|
||||
sdio_release_irq(func);
|
||||
sdio_release_host(func);
|
||||
sdio->irq_handler_opaque = NULL;
|
||||
sdio->irq_handler = NULL;
|
||||
}
|
||||
|
||||
static int b43_sdio_probe(struct sdio_func *func,
|
||||
const struct sdio_device_id *id)
|
||||
{
|
||||
struct b43_sdio *sdio;
|
||||
struct sdio_func_tuple *tuple;
|
||||
u16 vendor = 0, device = 0;
|
||||
int error;
|
||||
|
||||
/* Look for the card chip identifier. */
|
||||
tuple = func->tuples;
|
||||
while (tuple) {
|
||||
switch (tuple->code) {
|
||||
case 0x80:
|
||||
switch (tuple->data[0]) {
|
||||
case HNBU_CHIPID:
|
||||
if (tuple->size != 5)
|
||||
break;
|
||||
vendor = tuple->data[1] | (tuple->data[2]<<8);
|
||||
device = tuple->data[3] | (tuple->data[4]<<8);
|
||||
dev_info(&func->dev, "Chip ID %04x:%04x\n",
|
||||
vendor, device);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
tuple = tuple->next;
|
||||
}
|
||||
if (!vendor || !device) {
|
||||
error = -ENODEV;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sdio_claim_host(func);
|
||||
error = sdio_set_block_size(func, B43_SDIO_BLOCK_SIZE);
|
||||
if (error) {
|
||||
dev_err(&func->dev, "failed to set block size to %u bytes,"
|
||||
" error %d\n", B43_SDIO_BLOCK_SIZE, error);
|
||||
goto err_release_host;
|
||||
}
|
||||
error = sdio_enable_func(func);
|
||||
if (error) {
|
||||
dev_err(&func->dev, "failed to enable func, error %d\n", error);
|
||||
goto err_release_host;
|
||||
}
|
||||
sdio_release_host(func);
|
||||
|
||||
sdio = kzalloc(sizeof(*sdio), GFP_KERNEL);
|
||||
if (!sdio) {
|
||||
error = -ENOMEM;
|
||||
dev_err(&func->dev, "failed to allocate ssb bus\n");
|
||||
goto err_disable_func;
|
||||
}
|
||||
error = ssb_bus_sdiobus_register(&sdio->ssb, func,
|
||||
b43_sdio_get_quirks(vendor, device));
|
||||
if (error) {
|
||||
dev_err(&func->dev, "failed to register ssb sdio bus,"
|
||||
" error %d\n", error);
|
||||
goto err_free_ssb;
|
||||
}
|
||||
sdio_set_drvdata(func, sdio);
|
||||
|
||||
return 0;
|
||||
|
||||
err_free_ssb:
|
||||
kfree(sdio);
|
||||
err_disable_func:
|
||||
sdio_disable_func(func);
|
||||
err_release_host:
|
||||
sdio_release_host(func);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
static void b43_sdio_remove(struct sdio_func *func)
|
||||
{
|
||||
struct b43_sdio *sdio = sdio_get_drvdata(func);
|
||||
|
||||
ssb_bus_unregister(&sdio->ssb);
|
||||
sdio_disable_func(func);
|
||||
kfree(sdio);
|
||||
sdio_set_drvdata(func, NULL);
|
||||
}
|
||||
|
||||
static const struct sdio_device_id b43_sdio_ids[] = {
|
||||
{ SDIO_DEVICE(0x02d0, 0x044b) }, /* Nintendo Wii WLAN daughter card */
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct sdio_driver b43_sdio_driver = {
|
||||
.name = "b43-sdio",
|
||||
.id_table = b43_sdio_ids,
|
||||
.probe = b43_sdio_probe,
|
||||
.remove = b43_sdio_remove,
|
||||
};
|
||||
|
||||
int b43_sdio_init(void)
|
||||
{
|
||||
return sdio_register_driver(&b43_sdio_driver);
|
||||
}
|
||||
|
||||
void b43_sdio_exit(void)
|
||||
{
|
||||
sdio_unregister_driver(&b43_sdio_driver);
|
||||
}
|
45
drivers/net/wireless/b43/sdio.h
Normal file
45
drivers/net/wireless/b43/sdio.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef B43_SDIO_H_
|
||||
#define B43_SDIO_H_
|
||||
|
||||
#include <linux/ssb/ssb.h>
|
||||
|
||||
struct b43_wldev;
|
||||
|
||||
|
||||
#ifdef CONFIG_B43_SDIO
|
||||
|
||||
struct b43_sdio {
|
||||
struct ssb_bus ssb;
|
||||
void *irq_handler_opaque;
|
||||
void (*irq_handler)(struct b43_wldev *dev);
|
||||
};
|
||||
|
||||
int b43_sdio_request_irq(struct b43_wldev *dev,
|
||||
void (*handler)(struct b43_wldev *dev));
|
||||
void b43_sdio_free_irq(struct b43_wldev *dev);
|
||||
|
||||
int b43_sdio_init(void);
|
||||
void b43_sdio_exit(void);
|
||||
|
||||
|
||||
#else /* CONFIG_B43_SDIO */
|
||||
|
||||
|
||||
int b43_sdio_request_irq(struct b43_wldev *dev,
|
||||
void (*handler)(struct b43_wldev *dev))
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
void b43_sdio_free_irq(struct b43_wldev *dev)
|
||||
{
|
||||
}
|
||||
static inline int b43_sdio_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline void b43_sdio_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_B43_SDIO */
|
||||
#endif /* B43_SDIO_H_ */
|
@@ -690,8 +690,11 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
|
||||
}
|
||||
|
||||
memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status));
|
||||
ieee80211_rx_irqsafe(dev->wl->hw, skb);
|
||||
ieee80211_rx(dev->wl->hw, skb);
|
||||
|
||||
#if B43_DEBUG
|
||||
dev->rx_count++;
|
||||
#endif
|
||||
return;
|
||||
drop:
|
||||
b43dbg(dev->wl, "RX: Packet dropped\n");
|
||||
|
@@ -2021,6 +2021,12 @@ static int iwl4965_tx_status_reply_tx(struct iwl_priv *priv,
|
||||
agg->frame_count, txq_id, idx);
|
||||
|
||||
hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
|
||||
if (!hdr) {
|
||||
IWL_ERR(priv,
|
||||
"BUG_ON idx doesn't point to valid skb"
|
||||
" idx=%d, txq_id=%d\n", idx, txq_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sc = le16_to_cpu(hdr->seq_ctrl);
|
||||
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
|
||||
|
@@ -1163,6 +1163,12 @@ static int iwl5000_tx_status_reply_tx(struct iwl_priv *priv,
|
||||
agg->frame_count, txq_id, idx);
|
||||
|
||||
hdr = iwl_tx_queue_get_hdr(priv, txq_id, idx);
|
||||
if (!hdr) {
|
||||
IWL_ERR(priv,
|
||||
"BUG_ON idx doesn't point to valid skb"
|
||||
" idx=%d, txq_id=%d\n", idx, txq_id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
sc = le16_to_cpu(hdr->seq_ctrl);
|
||||
if (idx != (SEQ_TO_SN(sc) & 0xff)) {
|
||||
|
@@ -250,12 +250,20 @@ void iwl_rx_allocate(struct iwl_priv *priv, gfp_t priority)
|
||||
}
|
||||
spin_unlock_irqrestore(&rxq->lock, flags);
|
||||
|
||||
if (rxq->free_count > RX_LOW_WATERMARK)
|
||||
priority |= __GFP_NOWARN;
|
||||
/* Alloc a new receive buffer */
|
||||
skb = alloc_skb(priv->hw_params.rx_buf_size + 256,
|
||||
priority);
|
||||
|
||||
if (!skb) {
|
||||
IWL_CRIT(priv, "Can not allocate SKB buffers\n");
|
||||
if (net_ratelimit())
|
||||
IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n");
|
||||
if ((rxq->free_count <= RX_LOW_WATERMARK) &&
|
||||
net_ratelimit())
|
||||
IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n",
|
||||
priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL",
|
||||
rxq->free_count);
|
||||
/* We don't reschedule replenish work here -- we will
|
||||
* call the restock method and if it still needs
|
||||
* more buffers it will schedule replenish */
|
||||
|
@@ -520,7 +520,7 @@ int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
|
||||
struct iwl_host_cmd cmd = {
|
||||
.id = REPLY_WEPKEY,
|
||||
.data = wep_cmd,
|
||||
.flags = CMD_SYNC,
|
||||
.flags = CMD_ASYNC,
|
||||
};
|
||||
|
||||
memset(wep_cmd, 0, cmd_size +
|
||||
|
@@ -1146,11 +1146,18 @@ static void iwl3945_rx_allocate(struct iwl_priv *priv, gfp_t priority)
|
||||
}
|
||||
spin_unlock_irqrestore(&rxq->lock, flags);
|
||||
|
||||
if (rxq->free_count > RX_LOW_WATERMARK)
|
||||
priority |= __GFP_NOWARN;
|
||||
/* Alloc a new receive buffer */
|
||||
skb = alloc_skb(priv->hw_params.rx_buf_size, priority);
|
||||
if (!skb) {
|
||||
if (net_ratelimit())
|
||||
IWL_CRIT(priv, ": Can not allocate SKB buffers\n");
|
||||
IWL_DEBUG_INFO(priv, "Failed to allocate SKB buffer.\n");
|
||||
if ((rxq->free_count <= RX_LOW_WATERMARK) &&
|
||||
net_ratelimit())
|
||||
IWL_CRIT(priv, "Failed to allocate SKB buffer with %s. Only %u free buffers remaining.\n",
|
||||
priority == GFP_ATOMIC ? "GFP_ATOMIC" : "GFP_KERNEL",
|
||||
rxq->free_count);
|
||||
/* We don't reschedule replenish work here -- we will
|
||||
* call the restock method and if it still needs
|
||||
* more buffers it will schedule replenish */
|
||||
|
@@ -380,7 +380,7 @@ static inline void rt2x00crypto_tx_insert_iv(struct sk_buff *skb,
|
||||
{
|
||||
}
|
||||
|
||||
static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb, bool l2pad,
|
||||
static inline void rt2x00crypto_rx_insert_iv(struct sk_buff *skb,
|
||||
unsigned int header_length,
|
||||
struct rxdone_entry_desc *rxdesc)
|
||||
{
|
||||
|
@@ -1,5 +1,5 @@
|
||||
menuconfig WL12XX
|
||||
boolean "TI wl12xx driver support"
|
||||
tristate "TI wl12xx driver support"
|
||||
depends on MAC80211 && WLAN_80211 && EXPERIMENTAL
|
||||
---help---
|
||||
This will enable TI wl12xx driver support. The drivers make
|
||||
|
@@ -1070,7 +1070,7 @@ static int eject_installer(struct usb_interface *intf)
|
||||
|
||||
/* Find bulk out endpoint */
|
||||
endpoint = &iface_desc->endpoint[1].desc;
|
||||
if ((endpoint->bEndpointAddress & USB_TYPE_MASK) == USB_DIR_OUT &&
|
||||
if (usb_endpoint_dir_out(endpoint) &&
|
||||
usb_endpoint_xfer_bulk(endpoint)) {
|
||||
bulk_out_ep = endpoint->bEndpointAddress;
|
||||
} else {
|
||||
|
@@ -134,18 +134,15 @@ static void xemaclite_enable_interrupts(struct net_local *drvdata)
|
||||
}
|
||||
|
||||
/* Enable the Rx interrupts for the first buffer */
|
||||
reg_data = in_be32(drvdata->base_addr + XEL_RSR_OFFSET);
|
||||
out_be32(drvdata->base_addr + XEL_RSR_OFFSET,
|
||||
reg_data | XEL_RSR_RECV_IE_MASK);
|
||||
XEL_RSR_RECV_IE_MASK);
|
||||
|
||||
/* Enable the Rx interrupts for the second Buffer if
|
||||
* configured in HW */
|
||||
if (drvdata->rx_ping_pong != 0) {
|
||||
reg_data = in_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
|
||||
XEL_RSR_OFFSET);
|
||||
out_be32(drvdata->base_addr + XEL_BUFFER_OFFSET +
|
||||
XEL_RSR_OFFSET,
|
||||
reg_data | XEL_RSR_RECV_IE_MASK);
|
||||
XEL_RSR_RECV_IE_MASK);
|
||||
}
|
||||
|
||||
/* Enable the Global Interrupt Enable */
|
||||
|
Reference in New Issue
Block a user