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:
Linus Torvalds 2009-09-25 07:22:11 -07:00
commit 5c3cc2084d
93 changed files with 2620 additions and 2919 deletions

View file

@ -757,6 +757,42 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data)
void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
#endif
/* --------------------------------------------------------------------
* CAN Controller
* -------------------------------------------------------------------- */
#if defined(CONFIG_CAN_AT91) || defined(CONFIG_CAN_AT91_MODULE)
static struct resource can_resources[] = {
[0] = {
.start = AT91SAM9263_BASE_CAN,
.end = AT91SAM9263_BASE_CAN + SZ_16K - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
.start = AT91SAM9263_ID_CAN,
.end = AT91SAM9263_ID_CAN,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device at91sam9263_can_device = {
.name = "at91_can",
.id = -1,
.resource = can_resources,
.num_resources = ARRAY_SIZE(can_resources),
};
void __init at91_add_device_can(struct at91_can_data *data)
{
at91_set_A_periph(AT91_PIN_PA13, 0); /* CANTX */
at91_set_A_periph(AT91_PIN_PA14, 0); /* CANRX */
at91sam9263_can_device.dev.platform_data = data;
platform_device_register(&at91sam9263_can_device);
}
#else
void __init at91_add_device_can(struct at91_can_data *data) {}
#endif
/* --------------------------------------------------------------------
* LCD Controller

View file

@ -400,6 +400,23 @@ static struct gpio_led ek_pwm_led[] = {
}
};
/*
* CAN
*/
static void sam9263ek_transceiver_switch(int on)
{
if (on) {
at91_set_gpio_output(AT91_PIN_PA18, 1); /* CANRXEN */
at91_set_gpio_output(AT91_PIN_PA19, 0); /* CANRS */
} else {
at91_set_gpio_output(AT91_PIN_PA18, 0); /* CANRXEN */
at91_set_gpio_output(AT91_PIN_PA19, 1); /* CANRS */
}
}
static struct at91_can_data ek_can_data = {
.transceiver_switch = sam9263ek_transceiver_switch,
};
static void __init ek_board_init(void)
{
@ -431,6 +448,8 @@ static void __init ek_board_init(void)
/* LEDs */
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
/* CAN */
at91_add_device_can(&ek_can_data);
}
MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")

View file

@ -188,6 +188,12 @@ extern void __init at91_add_device_isi(void);
/* Touchscreen Controller */
extern void __init at91_add_device_tsadcc(void);
/* CAN */
struct at91_can_data {
void (*transceiver_switch)(int on);
};
extern void __init at91_add_device_can(struct at91_can_data *data);
/* LEDs */
extern void __init at91_init_leds(u8 cpu_led, u8 timer_led);
extern void __init at91_gpio_leds(struct gpio_led *leds, int nr);

View file

@ -790,11 +790,15 @@ he_init_group(struct he_dev *he_dev, int group)
he_dev->rbps_base = pci_alloc_consistent(he_dev->pci_dev,
CONFIG_RBPS_SIZE * sizeof(struct he_rbp), &he_dev->rbps_phys);
if (he_dev->rbps_base == NULL) {
hprintk("failed to alloc rbps\n");
return -ENOMEM;
hprintk("failed to alloc rbps_base\n");
goto out_destroy_rbps_pool;
}
memset(he_dev->rbps_base, 0, CONFIG_RBPS_SIZE * sizeof(struct he_rbp));
he_dev->rbps_virt = kmalloc(CONFIG_RBPS_SIZE * sizeof(struct he_virt), GFP_KERNEL);
if (he_dev->rbps_virt == NULL) {
hprintk("failed to alloc rbps_virt\n");
goto out_free_rbps_base;
}
for (i = 0; i < CONFIG_RBPS_SIZE; ++i) {
dma_addr_t dma_handle;
@ -802,7 +806,7 @@ he_init_group(struct he_dev *he_dev, int group)
cpuaddr = pci_pool_alloc(he_dev->rbps_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
if (cpuaddr == NULL)
return -ENOMEM;
goto out_free_rbps_virt;
he_dev->rbps_virt[i].virt = cpuaddr;
he_dev->rbps_base[i].status = RBP_LOANED | RBP_SMALLBUF | (i << RBP_INDEX_OFF);
@ -827,17 +831,21 @@ he_init_group(struct he_dev *he_dev, int group)
CONFIG_RBPL_BUFSIZE, 8, 0);
if (he_dev->rbpl_pool == NULL) {
hprintk("unable to create rbpl pool\n");
return -ENOMEM;
goto out_free_rbps_virt;
}
he_dev->rbpl_base = pci_alloc_consistent(he_dev->pci_dev,
CONFIG_RBPL_SIZE * sizeof(struct he_rbp), &he_dev->rbpl_phys);
if (he_dev->rbpl_base == NULL) {
hprintk("failed to alloc rbpl\n");
return -ENOMEM;
hprintk("failed to alloc rbpl_base\n");
goto out_destroy_rbpl_pool;
}
memset(he_dev->rbpl_base, 0, CONFIG_RBPL_SIZE * sizeof(struct he_rbp));
he_dev->rbpl_virt = kmalloc(CONFIG_RBPL_SIZE * sizeof(struct he_virt), GFP_KERNEL);
if (he_dev->rbpl_virt == NULL) {
hprintk("failed to alloc rbpl_virt\n");
goto out_free_rbpl_base;
}
for (i = 0; i < CONFIG_RBPL_SIZE; ++i) {
dma_addr_t dma_handle;
@ -845,7 +853,7 @@ he_init_group(struct he_dev *he_dev, int group)
cpuaddr = pci_pool_alloc(he_dev->rbpl_pool, GFP_KERNEL|GFP_DMA, &dma_handle);
if (cpuaddr == NULL)
return -ENOMEM;
goto out_free_rbpl_virt;
he_dev->rbpl_virt[i].virt = cpuaddr;
he_dev->rbpl_base[i].status = RBP_LOANED | (i << RBP_INDEX_OFF);
@ -870,7 +878,7 @@ he_init_group(struct he_dev *he_dev, int group)
CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq), &he_dev->rbrq_phys);
if (he_dev->rbrq_base == NULL) {
hprintk("failed to allocate rbrq\n");
return -ENOMEM;
goto out_free_rbpl_virt;
}
memset(he_dev->rbrq_base, 0, CONFIG_RBRQ_SIZE * sizeof(struct he_rbrq));
@ -894,7 +902,7 @@ he_init_group(struct he_dev *he_dev, int group)
CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq), &he_dev->tbrq_phys);
if (he_dev->tbrq_base == NULL) {
hprintk("failed to allocate tbrq\n");
return -ENOMEM;
goto out_free_rbpq_base;
}
memset(he_dev->tbrq_base, 0, CONFIG_TBRQ_SIZE * sizeof(struct he_tbrq));
@ -906,6 +914,39 @@ he_init_group(struct he_dev *he_dev, int group)
he_writel(he_dev, CONFIG_TBRQ_THRESH, G0_TBRQ_THRESH + (group * 16));
return 0;
out_free_rbpq_base:
pci_free_consistent(he_dev->pci_dev, CONFIG_RBRQ_SIZE *
sizeof(struct he_rbrq), he_dev->rbrq_base,
he_dev->rbrq_phys);
i = CONFIG_RBPL_SIZE;
out_free_rbpl_virt:
while (--i)
pci_pool_free(he_dev->rbps_pool, he_dev->rbpl_virt[i].virt,
he_dev->rbps_base[i].phys);
kfree(he_dev->rbpl_virt);
out_free_rbpl_base:
pci_free_consistent(he_dev->pci_dev, CONFIG_RBPL_SIZE *
sizeof(struct he_rbp), he_dev->rbpl_base,
he_dev->rbpl_phys);
out_destroy_rbpl_pool:
pci_pool_destroy(he_dev->rbpl_pool);
i = CONFIG_RBPL_SIZE;
out_free_rbps_virt:
while (--i)
pci_pool_free(he_dev->rbpl_pool, he_dev->rbps_virt[i].virt,
he_dev->rbpl_base[i].phys);
kfree(he_dev->rbps_virt);
out_free_rbps_base:
pci_free_consistent(he_dev->pci_dev, CONFIG_RBPS_SIZE *
sizeof(struct he_rbp), he_dev->rbps_base,
he_dev->rbps_phys);
out_destroy_rbps_pool:
pci_pool_destroy(he_dev->rbps_pool);
return -ENOMEM;
}
static int __devinit

View file

@ -25,6 +25,10 @@ SOLOS_ATTR_RO(RSCorrectedErrorsUp)
SOLOS_ATTR_RO(RSUnCorrectedErrorsUp)
SOLOS_ATTR_RO(InterleaveRDn)
SOLOS_ATTR_RO(InterleaveRUp)
SOLOS_ATTR_RO(BisRDn)
SOLOS_ATTR_RO(BisRUp)
SOLOS_ATTR_RO(INPdown)
SOLOS_ATTR_RO(INPup)
SOLOS_ATTR_RO(ShowtimeStart)
SOLOS_ATTR_RO(ATURVendor)
SOLOS_ATTR_RO(ATUCCountry)
@ -62,6 +66,13 @@ SOLOS_ATTR_RW(Defaults)
SOLOS_ATTR_RW(LineMode)
SOLOS_ATTR_RW(Profile)
SOLOS_ATTR_RW(DetectNoise)
SOLOS_ATTR_RW(BisAForceSNRMarginDn)
SOLOS_ATTR_RW(BisMForceSNRMarginDn)
SOLOS_ATTR_RW(BisAMaxMargin)
SOLOS_ATTR_RW(BisMMaxMargin)
SOLOS_ATTR_RW(AnnexAForceSNRMarginDn)
SOLOS_ATTR_RW(AnnexAMaxMargin)
SOLOS_ATTR_RW(AnnexMMaxMargin)
SOLOS_ATTR_RO(SupportedAnnexes)
SOLOS_ATTR_RO(Status)
SOLOS_ATTR_RO(TotalStart)

View file

@ -59,21 +59,29 @@
#define RX_DMA_ADDR(port) (0x30 + (4 * (port)))
#define DATA_RAM_SIZE 32768
#define BUF_SIZE 4096
#define BUF_SIZE 2048
#define OLD_BUF_SIZE 4096 /* For FPGA versions <= 2*/
#define FPGA_PAGE 528 /* FPGA flash page size*/
#define SOLOS_PAGE 512 /* Solos flash page size*/
#define FPGA_BLOCK (FPGA_PAGE * 8) /* FPGA flash block size*/
#define SOLOS_BLOCK (SOLOS_PAGE * 8) /* Solos flash block size*/
#define RX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2)
#define TX_BUF(card, nr) ((card->buffers) + (nr)*BUF_SIZE*2 + BUF_SIZE)
#define RX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2)
#define TX_BUF(card, nr) ((card->buffers) + (nr)*(card->buffer_size)*2 + (card->buffer_size))
#define FLASH_BUF ((card->buffers) + 4*(card->buffer_size)*2)
#define RX_DMA_SIZE 2048
#define FPGA_VERSION(a,b) (((a) << 8) + (b))
#define LEGACY_BUFFERS 2
#define DMA_SUPPORTED 4
static int reset = 0;
static int atmdebug = 0;
static int firmware_upgrade = 0;
static int fpga_upgrade = 0;
static int db_firmware_upgrade = 0;
static int db_fpga_upgrade = 0;
struct pkt_hdr {
__le16 size;
@ -116,6 +124,8 @@ struct solos_card {
wait_queue_head_t param_wq;
wait_queue_head_t fw_wq;
int using_dma;
int fpga_version;
int buffer_size;
};
@ -136,10 +146,14 @@ MODULE_PARM_DESC(reset, "Reset Solos chips on startup");
MODULE_PARM_DESC(atmdebug, "Print ATM data");
MODULE_PARM_DESC(firmware_upgrade, "Initiate Solos firmware upgrade");
MODULE_PARM_DESC(fpga_upgrade, "Initiate FPGA upgrade");
MODULE_PARM_DESC(db_firmware_upgrade, "Initiate daughter board Solos firmware upgrade");
MODULE_PARM_DESC(db_fpga_upgrade, "Initiate daughter board FPGA upgrade");
module_param(reset, int, 0444);
module_param(atmdebug, int, 0644);
module_param(firmware_upgrade, int, 0444);
module_param(fpga_upgrade, int, 0444);
module_param(db_firmware_upgrade, int, 0444);
module_param(db_fpga_upgrade, int, 0444);
static void fpga_queue(struct solos_card *card, int port, struct sk_buff *skb,
struct atm_vcc *vcc);
@ -517,10 +531,32 @@ static int flash_upgrade(struct solos_card *card, int chip)
if (chip == 0) {
fw_name = "solos-FPGA.bin";
blocksize = FPGA_BLOCK;
} else {
}
if (chip == 1) {
fw_name = "solos-Firmware.bin";
blocksize = SOLOS_BLOCK;
}
if (chip == 2){
if (card->fpga_version > LEGACY_BUFFERS){
fw_name = "solos-db-FPGA.bin";
blocksize = FPGA_BLOCK;
} else {
dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n");
return -EPERM;
}
}
if (chip == 3){
if (card->fpga_version > LEGACY_BUFFERS){
fw_name = "solos-Firmware.bin";
blocksize = SOLOS_BLOCK;
} else {
dev_info(&card->dev->dev, "FPGA version doesn't support daughter board upgrades\n");
return -EPERM;
}
}
if (request_firmware(&fw, fw_name, &card->dev->dev))
return -ENOENT;
@ -536,8 +572,10 @@ static int flash_upgrade(struct solos_card *card, int chip)
data32 = ioread32(card->config_regs + FPGA_MODE);
/* Set mode to Chip Erase */
dev_info(&card->dev->dev, "Set FPGA Flash mode to %s Chip Erase\n",
chip?"Solos":"FPGA");
if(chip == 0 || chip == 2)
dev_info(&card->dev->dev, "Set FPGA Flash mode to FPGA Chip Erase\n");
if(chip == 1 || chip == 3)
dev_info(&card->dev->dev, "Set FPGA Flash mode to Solos Chip Erase\n");
iowrite32((chip * 2), card->config_regs + FLASH_MODE);
@ -557,7 +595,10 @@ static int flash_upgrade(struct solos_card *card, int chip)
/* Copy block to buffer, swapping each 16 bits */
for(i = 0; i < blocksize; i += 4) {
uint32_t word = swahb32p((uint32_t *)(fw->data + offset + i));
iowrite32(word, RX_BUF(card, 3) + i);
if(card->fpga_version > LEGACY_BUFFERS)
iowrite32(word, FLASH_BUF + i);
else
iowrite32(word, RX_BUF(card, 3) + i);
}
/* Specify block number and then trigger flash write */
@ -630,6 +671,10 @@ void solos_bh(unsigned long card_arg)
memcpy_fromio(header, RX_BUF(card, port), sizeof(*header));
size = le16_to_cpu(header->size);
if (size > (card->buffer_size - sizeof(*header))){
dev_warn(&card->dev->dev, "Invalid buffer size\n");
continue;
}
skb = alloc_skb(size + 1, GFP_ATOMIC);
if (!skb) {
@ -1094,12 +1139,18 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
fpga_ver = (data32 & 0x0000FFFF);
major_ver = ((data32 & 0xFF000000) >> 24);
minor_ver = ((data32 & 0x00FF0000) >> 16);
card->fpga_version = FPGA_VERSION(major_ver,minor_ver);
if (card->fpga_version > LEGACY_BUFFERS)
card->buffer_size = BUF_SIZE;
else
card->buffer_size = OLD_BUF_SIZE;
dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n",
major_ver, minor_ver, fpga_ver);
if (0 && fpga_ver > 27)
if (card->fpga_version >= DMA_SUPPORTED){
card->using_dma = 1;
else {
} else {
card->using_dma = 0;
/* Set RX empty flag for all ports */
iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
}
@ -1131,6 +1182,12 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
if (firmware_upgrade)
flash_upgrade(card, 1);
if (db_fpga_upgrade)
flash_upgrade(card, 2);
if (db_firmware_upgrade)
flash_upgrade(card, 3);
err = atm_init(card);
if (err)
goto out_free_irq;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1,5 @@
#
# Makefile for the Linux Controller Area Network USB drivers.
#
obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

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

View 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_ */

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -117,8 +117,6 @@ source "drivers/staging/vt6655/Kconfig"
source "drivers/staging/vt6656/Kconfig"
source "drivers/staging/cpc-usb/Kconfig"
source "drivers/staging/udlfb/Kconfig"
source "drivers/staging/hv/Kconfig"

View file

@ -40,7 +40,6 @@ obj-$(CONFIG_USB_SERIAL_QUATECH_USB2) += quatech_usb2/
obj-$(CONFIG_OCTEON_ETHERNET) += octeon/
obj-$(CONFIG_VT6655) += vt6655/
obj-$(CONFIG_VT6656) += vt6656/
obj-$(CONFIG_USB_CPC) += cpc-usb/
obj-$(CONFIG_FB_UDL) += udlfb/
obj-$(CONFIG_HYPERV) += hv/
obj-$(CONFIG_VME_BUS) += vme/

View file

@ -1,4 +0,0 @@
config USB_CPC
tristate "CPC CAN USB driver"
depends on USB && PROC_FS
default n

View file

@ -1,3 +0,0 @@
obj-$(CONFIG_USB_CPC) += cpc-usb.o
cpc-usb-y := cpc-usb_drv.o sja2m16c_2.o

View file

@ -1,10 +0,0 @@
Things to do for this driver to get merged into the main portion of the
kernel:
- checkpatch cleanups
- sparse clean
- remove proc code
- tie into CAN socket interfaces if possible
- figure out sane userspace api
- use linux's error codes
Send patches to Greg Kroah-Hartman <greg@kroah.com>

File diff suppressed because it is too large Load diff

View file

@ -1,417 +0,0 @@
/*
* CPC CAN Interface Definitions
*
* Copyright (C) 2000-2008 EMS Dr. Thomas Wuensche
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef CPC_HEADER
#define CPC_HEADER
/*
* the maximum length of the union members within a CPC_MSG
* this value can be defined by the customer, but has to be
* >= 64 bytes
* however, if not defined before, we set a length of 64 byte
*/
#if !defined(CPC_MSG_LEN) || (CPC_MSG_LEN < 64)
#undef CPC_MSG_LEN
#define CPC_MSG_LEN 64
#endif
/*
* Transmission of events from CPC interfaces to PC can be individually
* controlled per event type. Default state is: don't transmit
* Control values are constructed by bit-or of Subject and Action
* and passed to CPC_Control()
*/
/* Control-Values for CPC_Control() Command Subject Selection */
#define CONTR_CAN_Message 0x04
#define CONTR_Busload 0x08
#define CONTR_CAN_State 0x0C
#define CONTR_SendAck 0x10
#define CONTR_Filter 0x14
#define CONTR_CmdQueue 0x18 /* reserved, do not use */
#define CONTR_BusError 0x1C
/* Control Command Actions */
#define CONTR_CONT_OFF 0
#define CONTR_CONT_ON 1
#define CONTR_SING_ON 2
/*
* CONTR_SING_ON doesn't change CONTR_CONT_ON state, so it should be
* read as: transmit at least once
*/
/* defines for confirmed request */
#define DO_NOT_CONFIRM 0
#define DO_CONFIRM 1
/* event flags */
#define EVENT_READ 0x01
#define EVENT_WRITE 0x02
/*
* Messages from CPC to PC contain a message object type field.
* The following message types are sent by CPC and can be used in
* handlers, others should be ignored.
*/
#define CPC_MSG_T_RESYNC 0 /* Normally to be ignored */
#define CPC_MSG_T_CAN 1 /* CAN data frame */
#define CPC_MSG_T_BUSLOAD 2 /* Busload message */
#define CPC_MSG_T_STRING 3 /* Normally to be ignored */
#define CPC_MSG_T_CONTI 4 /* Normally to be ignored */
#define CPC_MSG_T_MEM 7 /* Normally not to be handled */
#define CPC_MSG_T_RTR 8 /* CAN remote frame */
#define CPC_MSG_T_TXACK 9 /* Send acknowledge */
#define CPC_MSG_T_POWERUP 10 /* Power-up message */
#define CPC_MSG_T_CMD_NO 11 /* Normally to be ignored */
#define CPC_MSG_T_CAN_PRMS 12 /* Actual CAN parameters */
#define CPC_MSG_T_ABORTED 13 /* Command aborted message */
#define CPC_MSG_T_CANSTATE 14 /* CAN state message */
#define CPC_MSG_T_RESET 15 /* used to reset CAN-Controller */
#define CPC_MSG_T_XCAN 16 /* XCAN data frame */
#define CPC_MSG_T_XRTR 17 /* XCAN remote frame */
#define CPC_MSG_T_INFO 18 /* information strings */
#define CPC_MSG_T_CONTROL 19 /* used for control of interface/driver behaviour */
#define CPC_MSG_T_CONFIRM 20 /* response type for confirmed requests */
#define CPC_MSG_T_OVERRUN 21 /* response type for overrun conditions */
#define CPC_MSG_T_KEEPALIVE 22 /* response type for keep alive conditions */
#define CPC_MSG_T_CANERROR 23 /* response type for bus error conditions */
#define CPC_MSG_T_DISCONNECTED 24 /* response type for a disconnected interface */
#define CPC_MSG_T_ERR_COUNTER 25 /* RX/TX error counter of CAN controller */
#define CPC_MSG_T_FIRMWARE 100 /* response type for USB firmware download */
/*
* Messages from the PC to the CPC interface contain a command field
* Most of the command types are wrapped by the library functions and have therefore
* normally not to be used.
* However, programmers who wish to circumvent the library and talk directly
* to the drivers (mainly Linux programmers) can use the following
* command types:
*/
#define CPC_CMD_T_CAN 1 /* CAN data frame */
#define CPC_CMD_T_CONTROL 3 /* used for control of interface/driver behaviour */
#define CPC_CMD_T_CAN_PRMS 6 /* set CAN parameters */
#define CPC_CMD_T_CLEARBUF 8 /* clears input queue; this is depricated, use CPC_CMD_T_CLEAR_MSG_QUEUE instead */
#define CPC_CMD_T_INQ_CAN_PARMS 11 /* inquire actual CAN parameters */
#define CPC_CMD_T_FILTER_PRMS 12 /* set filter parameter */
#define CPC_CMD_T_RTR 13 /* CAN remote frame */
#define CPC_CMD_T_CANSTATE 14 /* CAN state message */
#define CPC_CMD_T_XCAN 15 /* XCAN data frame */
#define CPC_CMD_T_XRTR 16 /* XCAN remote frame */
#define CPC_CMD_T_RESET 17 /* used to reset CAN-Controller */
#define CPC_CMD_T_INQ_INFO 18 /* miscellanous information strings */
#define CPC_CMD_T_OPEN_CHAN 19 /* open a channel */
#define CPC_CMD_T_CLOSE_CHAN 20 /* close a channel */
#define CPC_CMD_T_CNTBUF 21 /* this is depricated, use CPC_CMD_T_INQ_MSG_QUEUE_CNT instead */
#define CPC_CMD_T_CAN_EXIT 200 /* exit the CAN (disable interrupts; reset bootrate; reset output_cntr; mode = 1) */
#define CPC_CMD_T_INQ_MSG_QUEUE_CNT CPC_CMD_T_CNTBUF /* inquires the count of elements in the message queue */
#define CPC_CMD_T_INQ_ERR_COUNTER 25 /* request the CAN controllers error counter */
#define CPC_CMD_T_CLEAR_MSG_QUEUE CPC_CMD_T_CLEARBUF /* clear CPC_MSG queue */
#define CPC_CMD_T_CLEAR_CMD_QUEUE 28 /* clear CPC_CMD queue */
#define CPC_CMD_T_FIRMWARE 100 /* reserved, must not be used */
#define CPC_CMD_T_USB_RESET 101 /* reserved, must not be used */
#define CPC_CMD_T_WAIT_NOTIFY 102 /* reserved, must not be used */
#define CPC_CMD_T_WAIT_SETUP 103 /* reserved, must not be used */
#define CPC_CMD_T_ABORT 255 /* Normally not to be used */
/* definitions for CPC_MSG_T_INFO information sources */
#define CPC_INFOMSG_T_UNKNOWN_SOURCE 0
#define CPC_INFOMSG_T_INTERFACE 1
#define CPC_INFOMSG_T_DRIVER 2
#define CPC_INFOMSG_T_LIBRARY 3
/* information types */
#define CPC_INFOMSG_T_UNKNOWN_TYPE 0
#define CPC_INFOMSG_T_VERSION 1
#define CPC_INFOMSG_T_SERIAL 2
/* definitions for controller types */
#define PCA82C200 1 /* Philips basic CAN controller, replaced by SJA1000 */
#define SJA1000 2 /* Philips basic CAN controller */
#define AN82527 3 /* Intel full CAN controller */
#define M16C_BASIC 4 /* M16C controller running in basic CAN (not full CAN) mode */
/* channel open error codes */
#define CPC_ERR_NO_FREE_CHANNEL -1 /* no more free space within the channel array */
#define CPC_ERR_CHANNEL_ALREADY_OPEN -2 /* the channel is already open */
#define CPC_ERR_CHANNEL_NOT_ACTIVE -3 /* access to a channel not active failed */
#define CPC_ERR_NO_DRIVER_PRESENT -4 /* no driver at the location searched by the library */
#define CPC_ERR_NO_INIFILE_PRESENT -5 /* the library could not find the inifile */
#define CPC_ERR_WRONG_PARAMETERS -6 /* wrong parameters in the inifile */
#define CPC_ERR_NO_INTERFACE_PRESENT -7 /* 1. The specified interface is not connected */
/* 2. The interface (mostly CPC-USB) was disconnected upon operation */
#define CPC_ERR_NO_MATCHING_CHANNEL -8 /* the driver couldn't find a matching channel */
#define CPC_ERR_NO_BUFFER_AVAILABLE -9 /* the driver couldn't allocate buffer for messages */
#define CPC_ERR_NO_INTERRUPT -10 /* the requested interrupt couldn't be claimed */
#define CPC_ERR_NO_MATCHING_INTERFACE -11 /* no interface type related to this channel was found */
#define CPC_ERR_NO_RESOURCES -12 /* the requested resources could not be claimed */
#define CPC_ERR_SOCKET -13 /* error concerning TCP sockets */
/* init error codes */
#define CPC_ERR_WRONG_CONTROLLER_TYPE -14 /* wrong CAN controller type within initialization */
#define CPC_ERR_NO_RESET_MODE -15 /* the controller could not be set into reset mode */
#define CPC_ERR_NO_CAN_ACCESS -16 /* the CAN controller could not be accessed */
/* transmit error codes */
#define CPC_ERR_CAN_WRONG_ID -20 /* the provided CAN id is too big */
#define CPC_ERR_CAN_WRONG_LENGTH -21 /* the provided CAN length is too long */
#define CPC_ERR_CAN_NO_TRANSMIT_BUF -22 /* the transmit buffer was occupied */
#define CPC_ERR_CAN_TRANSMIT_TIMEOUT -23 /* The message could not be sent within a */
/* specified time */
/* other error codes */
#define CPC_ERR_SERVICE_NOT_SUPPORTED -30 /* the requested service is not supported by the interface */
#define CPC_ERR_IO_TRANSFER -31 /* a transmission error down to the driver occurred */
#define CPC_ERR_TRANSMISSION_FAILED -32 /* a transmission error down to the interface occurred */
#define CPC_ERR_TRANSMISSION_TIMEOUT -33 /* a timeout occurred within transmission to the interface */
#define CPC_ERR_OP_SYS_NOT_SUPPORTED -35 /* the operating system is not supported */
#define CPC_ERR_UNKNOWN -40 /* an unknown error ocurred (mostly IOCTL errors) */
#define CPC_ERR_LOADING_DLL -50 /* the library 'cpcwin.dll' could not be loaded */
#define CPC_ERR_ASSIGNING_FUNCTION -51 /* the specified function could not be assigned */
#define CPC_ERR_DLL_INITIALIZATION -52 /* the DLL was not initialized correctly */
#define CPC_ERR_MISSING_LICFILE -55 /* the file containing the licenses does not exist */
#define CPC_ERR_MISSING_LICENSE -56 /* a required license was not found */
/* CAN state bit values. Ignore any bits not listed */
#define CPC_CAN_STATE_BUSOFF 0x80
#define CPC_CAN_STATE_ERROR 0x40
/* Mask to help ignore undefined bits */
#define CPC_CAN_STATE_MASK 0xc0
/*
* CAN-Message representation in a CPC_MS
* Message object type is CPC_MSG_T_CAN or CPC_MSG_T_RTR
* or CPC_MSG_T_XCAN or CPC_MSG_T_XRTR
*/
typedef struct CPC_CAN_MSG {
u32 id;
u8 length;
u8 msg[8];
} CPC_CAN_MSG_T;
/* representation of the CAN parameters for the PCA82C200 controller */
typedef struct CPC_PCA82C200_PARAMS {
u8 acc_code; /* Acceptance-code for receive, Standard: 0 */
u8 acc_mask; /* Acceptance-mask for receive, Standard: 0xff (everything) */
u8 btr0; /* Bus-timing register 0 */
u8 btr1; /* Bus-timing register 1 */
u8 outp_contr; /* Output-control register */
} CPC_PCA82C200_PARAMS_T;
/* representation of the CAN parameters for the SJA1000 controller */
typedef struct CPC_SJA1000_PARAMS {
u8 mode; /* enables single or dual acceptance filtering */
u8 acc_code0; /* Acceptance-code for receive, Standard: 0 */
u8 acc_code1;
u8 acc_code2;
u8 acc_code3;
u8 acc_mask0; /* Acceptance-mask for receive, Standard: 0xff (everything) */
u8 acc_mask1;
u8 acc_mask2;
u8 acc_mask3;
u8 btr0; /* Bus-timing register 0 */
u8 btr1; /* Bus-timing register 1 */
u8 outp_contr; /* Output-control register */
} CPC_SJA1000_PARAMS_T;
/*
* representation of the CAN parameters for the M16C controller
* in basic CAN mode (means no full CAN)
*/
typedef struct CPC_M16C_BASIC_PARAMS {
u8 con0;
u8 con1;
u8 ctlr0;
u8 ctlr1;
u8 clk;
u8 acc_std_code0;
u8 acc_std_code1;
u8 acc_ext_code0;
u8 acc_ext_code1;
u8 acc_ext_code2;
u8 acc_ext_code3;
u8 acc_std_mask0;
u8 acc_std_mask1;
u8 acc_ext_mask0;
u8 acc_ext_mask1;
u8 acc_ext_mask2;
u8 acc_ext_mask3;
} CPC_M16C_BASIC_PARAMS_T;
/* CAN params message representation */
typedef struct CPC_CAN_PARAMS {
u8 cc_type; /* represents the controller type */
union {
CPC_M16C_BASIC_PARAMS_T m16c_basic;
CPC_SJA1000_PARAMS_T sja1000;
CPC_PCA82C200_PARAMS_T pca82c200;
} cc_params;
} CPC_CAN_PARAMS_T;
/* CHAN init params representation */
typedef struct CPC_CHAN_PARAMS {
int fd;
} CPC_CHAN_PARAMS_T;
/* CAN init params message representation */
typedef struct CPC_INIT_PARAMS {
CPC_CHAN_PARAMS_T chanparams;
CPC_CAN_PARAMS_T canparams;
} CPC_INIT_PARAMS_T;
/* structure for confirmed message handling */
typedef struct CPC_CONFIRM {
u8 result; /* error code */
} CPC_CONFIRM_T;
/* structure for information requests */
typedef struct CPC_INFO {
u8 source; /* interface, driver or library */
u8 type; /* version or serial number */
char msg[CPC_MSG_LEN - 2]; /* string holding the requested information */
} CPC_INFO_T;
/*
* OVERRUN
* In general two types of overrun may occur.
* A hardware overrun, where the CAN controller
* lost a message, because the interrupt was
* not handled before the next messgae comes in.
* Or a software overrun, where i.e. a received
* message could not be stored in the CPC_MSG
* buffer.
*/
/* After a software overrun has occurred
* we wait until we have CPC_OVR_GAP slots
* free in the CPC_MSG buffer.
*/
#define CPC_OVR_GAP 10
/*
* Two types of software overrun may occur.
* A received CAN message or a CAN state event
* can cause an overrun.
* Note: A CPC_CMD which would normally store
* its result immediately in the CPC_MSG
* queue may fail, because the message queue is full.
* This will not generate an overrun message, but
* will halt command execution, until this command
* is able to store its message in the message queue.
*/
#define CPC_OVR_EVENT_CAN 0x01
#define CPC_OVR_EVENT_CANSTATE 0x02
#define CPC_OVR_EVENT_BUSERROR 0x04
/*
* If the CAN controller lost a message
* we indicate it with the highest bit
* set in the count field.
*/
#define CPC_OVR_HW 0x80
/* structure for overrun conditions */
typedef struct {
u8 event;
u8 count;
} CPC_OVERRUN_T;
/*
* CAN errors
* Each CAN controller type has different
* registers to record errors.
* Therefor a structure containing the specific
* errors is set up for each controller here
*/
/*
* SJA1000 error structure
* see the SJA1000 datasheet for detailed
* explanation of the registers
*/
typedef struct CPC_SJA1000_CAN_ERROR {
u8 ecc; /* error capture code register */
u8 rxerr; /* RX error counter register */
u8 txerr; /* TX error counter register */
} CPC_SJA1000_CAN_ERROR_T;
/*
* M16C error structure
* see the M16C datasheet for detailed
* explanation of the registers
*/
typedef struct CPC_M16C_CAN_ERROR {
u8 tbd; /* to be defined */
} CPC_M16C_CAN_ERROR_T;
/* structure for CAN error conditions */
#define CPC_CAN_ECODE_ERRFRAME 0x01
typedef struct CPC_CAN_ERROR {
u8 ecode;
struct {
u8 cc_type; /* CAN controller type */
union {
CPC_SJA1000_CAN_ERROR_T sja1000;
CPC_M16C_CAN_ERROR_T m16c;
} regs;
} cc;
} CPC_CAN_ERROR_T;
/*
* Structure containing RX/TX error counter.
* This structure is used to request the
* values of the CAN controllers TX and RX
* error counter.
*/
typedef struct CPC_CAN_ERR_COUNTER {
u8 rx;
u8 tx;
} CPC_CAN_ERR_COUNTER_T;
/* If this flag is set, transmissions from PC to CPC are protected against loss */
#define CPC_SECURE_TO_CPC 0x01
/* If this flag is set, transmissions from CPC to PC are protected against loss */
#define CPC_SECURE_TO_PC 0x02
/* If this flag is set, the CAN-transmit buffer is checked to be free before sending a message */
#define CPC_SECURE_SEND 0x04
/*
* If this flag is set, the transmission complete flag is checked
* after sending a message
* THIS IS CURRENTLY ONLY IMPLEMENTED IN THE PASSIVE INTERFACE DRIVERS
*/
#define CPC_SECURE_TRANSMIT 0x08
/* main message type used between library and application */
typedef struct CPC_MSG {
u8 type; /* type of message */
u8 length; /* length of data within union 'msg' */
u8 msgid; /* confirmation handle */
u32 ts_sec; /* timestamp in seconds */
u32 ts_nsec; /* timestamp in nano seconds */
union {
u8 generic[CPC_MSG_LEN];
CPC_CAN_MSG_T canmsg;
CPC_CAN_PARAMS_T canparams;
CPC_CONFIRM_T confirmation;
CPC_INFO_T info;
CPC_OVERRUN_T overrun;
CPC_CAN_ERROR_T error;
CPC_CAN_ERR_COUNTER_T err_counter;
u8 busload;
u8 canstate;
} msg;
} CPC_MSG_T;
#endif /* CPC_HEADER */

View file

@ -1,83 +0,0 @@
/*
* CPCLIB
*
* Copyright (C) 2000-2008 EMS Dr. Thomas Wuensche
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
*/
#ifndef CPC_INT_H
#define CPC_INT_H
#include <linux/wait.h>
#define CPC_MSG_BUF_CNT 1500
#define CPC_PROC_DIR "driver/"
#undef dbg
#undef err
#undef info
/* Use our own dbg macro */
#define dbg(format, arg...) do { if (debug) printk( KERN_INFO format "\n" , ## arg); } while (0)
#define err(format, arg...) do { printk( KERN_INFO "ERROR " format "\n" , ## arg); } while (0)
#define info(format, arg...) do { printk( KERN_INFO format "\n" , ## arg); } while (0)
/* Macros help using of our buffers */
#define IsBufferFull(x) (!(x)->WnR) && ((x)->iidx == (x)->oidx)
#define IsBufferEmpty(x) ((x)->WnR) && ((x)->iidx == (x)->oidx)
#define IsBufferNotEmpty(x) (!(x)->WnR) || ((x)->iidx != (x)->oidx)
#define ResetBuffer(x) do { (x)->oidx = (x)->iidx=0; (x)->WnR = 1; } while(0);
#define CPC_BufWriteAllowed ((chan->oidx != chan->iidx) || chan->WnR)
typedef void (*chan_write_byte_t) (void *chan, unsigned int reg,
unsigned char val);
typedef unsigned char (*chan_read_byte_t) (void *chan, unsigned int reg);
typedef struct CPC_CHAN {
void __iomem * canBase; /* base address of SJA1000 */
chan_read_byte_t read_byte; /* CAN controller read access routine */
chan_write_byte_t write_byte; /* CAN controller write access routine */
CPC_MSG_T *buf; /* buffer for CPC msg */
unsigned int iidx;
unsigned int oidx;
unsigned int WnR;
unsigned int minor;
unsigned int locked;
unsigned int irqDisabled;
unsigned char cpcCtrlCANMessage;
unsigned char cpcCtrlCANState;
unsigned char cpcCtrlBUSState;
unsigned char controllerType;
unsigned long ovrTimeSec;
unsigned long ovrTimeNSec;
unsigned long ovrLockedBuffer;
CPC_OVERRUN_T ovr;
/* for debugging only */
unsigned int handledIrqs;
unsigned int lostMessages;
unsigned int sentStdCan;
unsigned int sentExtCan;
unsigned int sentStdRtr;
unsigned int sentExtRtr;
unsigned int recvStdCan;
unsigned int recvExtCan;
unsigned int recvStdRtr;
unsigned int recvExtRtr;
wait_queue_head_t *CPCWait_q;
void *private;
} CPC_CHAN_T;
#endif

View file

@ -1,86 +0,0 @@
/* Header for CPC-USB Driver ********************
* Copyright 1999, 2000, 2001
*
* Company: EMS Dr. Thomas Wuensche
* Sonnenhang 3
* 85304 Ilmmuenster
* Phone: +49-8441-490260
* Fax: +49-8441-81860
* email: support@ems-wuensche.com
* WWW: www.ems-wuensche.com
*/
#ifndef CPCUSB_H
#define CPCUSB_H
#undef err
#undef dbg
#undef info
/* Use our own dbg macro */
#define dbg(format, arg...) do { if (debug) printk(KERN_INFO "CPC-USB: " format "\n" , ## arg); } while (0)
#define info(format, arg...) do { printk(KERN_INFO "CPC-USB: " format "\n" , ## arg); } while (0)
#define err(format, arg...) do { printk(KERN_INFO "CPC-USB(ERROR): " format "\n" , ## arg); } while (0)
#define CPC_USB_CARD_CNT 4
typedef struct CPC_USB_READ_URB {
unsigned char *buffer; /* the buffer to send data */
size_t size; /* the size of the send buffer */
struct urb *urb; /* the urb used to send data */
} CPC_USB_READ_URB_T;
typedef struct CPC_USB_WRITE_URB {
unsigned char *buffer; /* the buffer to send data */
size_t size; /* the size of the send buffer */
struct urb *urb; /* the urb used to send data */
atomic_t busy; /* true if write urb is busy */
struct completion finished; /* wait for the write to finish */
} CPC_USB_WRITE_URB_T;
#define CPC_USB_URB_CNT 10
typedef struct CPC_USB {
struct usb_device *udev; /* save off the usb device pointer */
struct usb_interface *interface; /* the interface for this device */
unsigned char minor; /* the starting minor number for this device */
unsigned char num_ports; /* the number of ports this device has */
int num_intr_in; /* number of interrupt in endpoints we have */
int num_bulk_in; /* number of bulk in endpoints we have */
int num_bulk_out; /* number of bulk out endpoints we have */
CPC_USB_READ_URB_T urbs[CPC_USB_URB_CNT];
unsigned char intr_in_buffer[4]; /* interrupt transfer buffer */
struct urb *intr_in_urb; /* interrupt transfer urb */
CPC_USB_WRITE_URB_T wrUrbs[CPC_USB_URB_CNT];
int open; /* if the port is open or not */
int present; /* if the device is not disconnected */
struct semaphore sem; /* locks this structure */
int free_slots; /* free send slots of CPC-USB */
int idx;
spinlock_t slock;
char serialNumber[128]; /* serial number */
int productId; /* product id to differ between M16C and LPC2119 */
CPC_CHAN_T *chan;
} CPC_USB_T;
#define CPCTable CPCUSB_Table
#define CPC_DRIVER_VERSION "0.724"
#define CPC_DRIVER_SERIAL "not applicable"
#define OBUF_SIZE 255 /* 4096 */
/* read timeouts -- RD_NAK_TIMEOUT * RD_EXPIRE = Number of seconds */
#define RD_NAK_TIMEOUT (10*HZ) /* Default number of X seconds to wait */
#define RD_EXPIRE 12 /* Number of attempts to wait X seconds */
#define CPC_USB_BASE_MNR 0 /* CPC-USB start at minor 0 */
#endif

View file

@ -1,41 +0,0 @@
#ifndef _SJA2M16C_H
#define _SJA2M16C_H
#include "cpc.h"
#define BAUDRATE_TOLERANCE_PERCENT 1
#define SAMPLEPOINT_TOLERANCE_PERCENT 5
#define SAMPLEPOINT_UPPER_LIMIT 88
/* M16C parameters */
struct FIELD_C0CONR {
unsigned int brp:4;
unsigned int sam:1;
unsigned int pr:3;
unsigned int dummy:8;
};
struct FIELD_C1CONR {
unsigned int ph1:3;
unsigned int ph2:3;
unsigned int sjw:2;
unsigned int dummy:8;
};
typedef union C0CONR {
unsigned char c0con;
struct FIELD_C0CONR bc0con;
} C0CONR_T;
typedef union C1CONR {
unsigned char c1con;
struct FIELD_C1CONR bc1con;
} C1CONR_T;
#define SJA_TSEG1 ((pParams->btr1 & 0x0f)+1)
#define SJA_TSEG2 (((pParams->btr1 & 0x70)>>4)+1)
#define SJA_BRP ((pParams->btr0 & 0x3f)+1)
#define SJA_SJW ((pParams->btr0 & 0xc0)>>6)
#define SJA_SAM ((pParams->btr1 & 0x80)>>7)
int baudrate_m16c(int clk, int brp, int pr, int ph1, int ph2);
int samplepoint_m16c(int brp, int pr, int ph1, int ph2);
int SJA1000_TO_M16C_BASIC_Params(CPC_MSG_T *pMsg);
#endif

View file

@ -1,452 +0,0 @@
/****************************************************************************
*
* Copyright (c) 2003,2004 by EMS Dr. Thomas Wuensche
*
* - All rights reserved -
*
* This code is provided "as is" without warranty of any kind, either
* expressed or implied, including but not limited to the liability
* concerning the freedom from material defects, the fitness for parti-
* cular purposes or the freedom of proprietary rights of third parties.
*
*****************************************************************************
* Module name.: cpcusb
*****************************************************************************
* Include file: cpc.h
*****************************************************************************
* Project.....: Windows Driver Development Kit
* Filename....: sja2m16c.cpp
* Authors.....: (GU) Gerhard Uttenthaler
* (CS) Christian Schoett
*****************************************************************************
* Short descr.: converts baudrate between SJA1000 and M16C
*****************************************************************************
* Description.: handles the baudrate conversion from SJA1000 parameters to
* M16C parameters
*****************************************************************************
* Address : EMS Dr. Thomas Wuensche
* Sonnenhang 3
* D-85304 Ilmmuenster
* Tel. : +49-8441-490260
* Fax. : +49-8441-81860
* email: support@ems-wuensche.com
*****************************************************************************
* History
*****************************************************************************
* Version Date Auth Remark
*
* 01.00 ?? GU - initial release
* 01.10 ?????????? CS - adapted to fit into the USB Windows driver
* 02.00 18.08.2004 GU - improved the baudrate calculating algorithm
* - implemented acceptance filtering
* 02.10 10.09.2004 CS - adapted to fit into the USB Windows driver
*****************************************************************************
* ToDo's
*****************************************************************************
*/
/****************************************************************************/
/* I N C L U D E S
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/module.h>
#include <linux/poll.h>
#include <linux/smp_lock.h>
#include <linux/completion.h>
#include <asm/uaccess.h>
#include <linux/usb.h>
#include "cpc.h"
#include "cpc_int.h"
#include "cpcusb.h"
#include "sja2m16c.h"
/*********************************************************************/
int baudrate_m16c(int clk, int brp, int pr, int ph1, int ph2)
{
return (16000000 / (1 << clk)) / 2 / (brp + 1) / (1 + pr + 1 +
ph1 + 1 + ph2 +
1);
}
/*********************************************************************/
int samplepoint_m16c(int brp, int pr, int ph1, int ph2)
{
return (100 * (1 + pr + 1 + ph1 + 1)) / (1 + pr + 1 + ph1 + 1 +
ph2 + 1);
}
/****************************************************************************
* Function.....: SJA1000_TO_M16C_BASIC_Params
*
* Task.........: This routine converts SJA1000 CAN btr parameters into M16C
* parameters based on the sample point and the error. In
* addition it converts the acceptance filter parameters to
* suit the M16C parameters
*
* Parameters...: None
*
* Return values: None
*
* Comments.....:
*****************************************************************************
* History
*****************************************************************************
* 19.01.2005 CS - modifed the conversion of SJA1000 filter params into
* M16C params. Due to compatibility reasons with the
* older 82C200 CAN controller the SJA1000
****************************************************************************/
int SJA1000_TO_M16C_BASIC_Params(CPC_MSG_T * in)
{
int sjaBaudrate;
int sjaSamplepoint;
int *baudrate_error; // BRP[0..15], PR[0..7], PH1[0..7], PH2[0..7]
int *samplepoint_error; // BRP[0..15], PR[0..7], PH1[0..7], PH2[0..7]
int baudrate_error_merk;
int clk, brp, pr, ph1, ph2;
int clk_merk, brp_merk, pr_merk, ph1_merk, ph2_merk;
int index;
unsigned char acc_code0, acc_code1, acc_code2, acc_code3;
unsigned char acc_mask0, acc_mask1, acc_mask2, acc_mask3;
CPC_MSG_T * out;
C0CONR_T c0con;
C1CONR_T c1con;
int tmpAccCode;
int tmpAccMask;
// we have to convert the parameters into M16C parameters
CPC_SJA1000_PARAMS_T * pParams;
// check if the type is CAN parameters and if we have to convert the given params
if (in->type != CPC_CMD_T_CAN_PRMS
|| in->msg.canparams.cc_type != SJA1000)
return 0;
pParams =
(CPC_SJA1000_PARAMS_T *) & in->msg.canparams.cc_params.sja1000;
acc_code0 = pParams->acc_code0;
acc_code1 = pParams->acc_code1;
acc_code2 = pParams->acc_code2;
acc_code3 = pParams->acc_code3;
acc_mask0 = pParams->acc_mask0;
acc_mask1 = pParams->acc_mask1;
acc_mask2 = pParams->acc_mask2;
acc_mask3 = pParams->acc_mask3;
#ifdef _DEBUG_OUTPUT_CAN_PARAMS
info("acc_code0: %2.2Xh\n", acc_code0);
info("acc_code1: %2.2Xh\n", acc_code1);
info("acc_code2: %2.2Xh\n", acc_code2);
info("acc_code3: %2.2Xh\n", acc_code3);
info("acc_mask0: %2.2Xh\n", acc_mask0);
info("acc_mask1: %2.2Xh\n", acc_mask1);
info("acc_mask2: %2.2Xh\n", acc_mask2);
info("acc_mask3: %2.2Xh\n", acc_mask3);
#endif /* */
if (!
(baudrate_error =
(int *) vmalloc(sizeof(int) * 16 * 8 * 8 * 8 * 5))) {
err("Could not allocate memory\n");
return -3;
}
if (!
(samplepoint_error =
(int *) vmalloc(sizeof(int) * 16 * 8 * 8 * 8 * 5))) {
err("Could not allocate memory\n");
vfree(baudrate_error);
return -3;
}
memset(baudrate_error, 0xff, sizeof(baudrate_error));
memset(samplepoint_error, 0xff, sizeof(baudrate_error));
sjaBaudrate =
16000000 / 2 / SJA_BRP / (1 + SJA_TSEG1 + SJA_TSEG2);
sjaSamplepoint =
100 * (1 + SJA_TSEG1) / (1 + SJA_TSEG1 + SJA_TSEG2);
if (sjaBaudrate == 0) {
vfree(baudrate_error);
vfree(samplepoint_error);
return -2;
}
#ifdef _DEBUG_OUTPUT_CAN_PARAMS
info("\nStarting SJA CAN params\n");
info("-------------------------\n");
info("TS1 : %2.2Xh TS2 : %2.2Xh\n", SJA_TSEG1, SJA_TSEG2);
info("BTR0 : %2.2Xh BTR1: %2.2Xh\n", pParams->btr0,
pParams->btr1);
info("Baudrate: %d.%dkBaud\n", sjaBaudrate / 1000,
sjaBaudrate % 1000);
info("Sample P: 0.%d\n", sjaSamplepoint);
info("\n");
#endif /* */
c0con.bc0con.sam = SJA_SAM;
c1con.bc1con.sjw = SJA_SJW;
// calculate errors for all baudrates
index = 0;
for (clk = 0; clk < 5; clk++) {
for (brp = 0; brp < 16; brp++) {
for (pr = 0; pr < 8; pr++) {
for (ph1 = 0; ph1 < 8; ph1++) {
for (ph2 = 0; ph2 < 8; ph2++) {
baudrate_error[index] =
100 *
abs(baudrate_m16c
(clk, brp, pr, ph1,
ph2) -
sjaBaudrate) /
sjaBaudrate;
samplepoint_error[index] =
abs(samplepoint_m16c
(brp, pr, ph1,
ph2) -
sjaSamplepoint);
#if 0
info
("Baudrate : %d kBaud\n",
baudrate_m16c(clk,
brp, pr,
ph1,
ph2));
info
("Baudrate Error: %d\n",
baudrate_error
[index]);
info
("Sample P Error: %d\n",
samplepoint_error
[index]);
info
("clk : %d\n",
clk);
#endif /* */
index++;
}
}
}
}
}
// mark all baudrate_error entries which are outer limits
index = 0;
for (clk = 0; clk < 5; clk++) {
for (brp = 0; brp < 16; brp++) {
for (pr = 0; pr < 8; pr++) {
for (ph1 = 0; ph1 < 8; ph1++) {
for (ph2 = 0; ph2 < 8; ph2++) {
if ((baudrate_error[index]
>
BAUDRATE_TOLERANCE_PERCENT)
||
(samplepoint_error
[index] >
SAMPLEPOINT_TOLERANCE_PERCENT)
||
(samplepoint_m16c
(brp, pr, ph1,
ph2) >
SAMPLEPOINT_UPPER_LIMIT))
{
baudrate_error
[index] = -1;
} else
if (((1 + pr + 1 +
ph1 + 1 + ph2 +
1) < 8)
||
((1 + pr + 1 +
ph1 + 1 + ph2 +
1) > 25)) {
baudrate_error
[index] = -1;
}
#if 0
else {
info
("Baudrate : %d kBaud\n",
baudrate_m16c
(clk, brp, pr,
ph1, ph2));
info
("Baudrate Error: %d\n",
baudrate_error
[index]);
info
("Sample P Error: %d\n",
samplepoint_error
[index]);
}
#endif /* */
index++;
}
}
}
}
}
// find list of minimum of baudrate_error within unmarked entries
clk_merk = brp_merk = pr_merk = ph1_merk = ph2_merk = 0;
baudrate_error_merk = 100;
index = 0;
for (clk = 0; clk < 5; clk++) {
for (brp = 0; brp < 16; brp++) {
for (pr = 0; pr < 8; pr++) {
for (ph1 = 0; ph1 < 8; ph1++) {
for (ph2 = 0; ph2 < 8; ph2++) {
if (baudrate_error[index]
!= -1) {
if (baudrate_error
[index] <
baudrate_error_merk)
{
baudrate_error_merk
=
baudrate_error
[index];
brp_merk =
brp;
pr_merk =
pr;
ph1_merk =
ph1;
ph2_merk =
ph2;
clk_merk =
clk;
#if 0
info
("brp: %2.2Xh pr: %2.2Xh ph1: %2.2Xh ph2: %2.2Xh\n",
brp,
pr,
ph1,
ph2);
info
("Baudrate : %d kBaud\n",
baudrate_m16c
(clk,
brp,
pr,
ph1,
ph2));
info
("Baudrate Error: %d\n",
baudrate_error
[index]);
info
("Sample P Error: %d\n",
samplepoint_error
[index]);
#endif /* */
}
}
index++;
}
}
}
}
}
if (baudrate_error_merk == 100) {
info("ERROR: Could not convert CAN init parameter\n");
vfree(baudrate_error);
vfree(samplepoint_error);
return -1;
}
// setting m16c CAN parameter
c0con.bc0con.brp = brp_merk;
c0con.bc0con.pr = pr_merk;
c1con.bc1con.ph1 = ph1_merk;
c1con.bc1con.ph2 = ph2_merk;
#ifdef _DEBUG_OUTPUT_CAN_PARAMS
info("\nResulting M16C CAN params\n");
info("-------------------------\n");
info("clk : %2.2Xh\n", clk_merk);
info("ph1 : %2.2Xh ph2: %2.2Xh\n", c1con.bc1con.ph1 + 1,
c1con.bc1con.ph2 + 1);
info("pr : %2.2Xh brp: %2.2Xh\n", c0con.bc0con.pr + 1,
c0con.bc0con.brp + 1);
info("sjw : %2.2Xh sam: %2.2Xh\n", c1con.bc1con.sjw,
c0con.bc0con.sam);
info("co1 : %2.2Xh co0: %2.2Xh\n", c1con.c1con, c0con.c0con);
info("Baudrate: %d.%dBaud\n",
baudrate_m16c(clk_merk, c0con.bc0con.brp, c0con.bc0con.pr,
c1con.bc1con.ph1, c1con.bc1con.ph2) / 1000,
baudrate_m16c(clk_merk, c0con.bc0con.brp, c0con.bc0con.pr,
c1con.bc1con.ph1, c1con.bc1con.ph2) % 1000);
info("Sample P: 0.%d\n",
samplepoint_m16c(c0con.bc0con.brp, c0con.bc0con.pr,
c1con.bc1con.ph1, c1con.bc1con.ph2));
info("\n");
#endif /* */
out = in;
out->type = 6;
out->length = sizeof(CPC_M16C_BASIC_PARAMS_T) + 1;
out->msg.canparams.cc_type = M16C_BASIC;
out->msg.canparams.cc_params.m16c_basic.con0 = c0con.c0con;
out->msg.canparams.cc_params.m16c_basic.con1 = c1con.c1con;
out->msg.canparams.cc_params.m16c_basic.ctlr0 = 0x4C;
out->msg.canparams.cc_params.m16c_basic.ctlr1 = 0x00;
out->msg.canparams.cc_params.m16c_basic.clk = clk_merk;
out->msg.canparams.cc_params.m16c_basic.acc_std_code0 =
acc_code0;
out->msg.canparams.cc_params.m16c_basic.acc_std_code1 = acc_code1;
// info("code0: 0x%2.2X, code1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_code0, out->msg.canparams.cc_params.m16c_basic.acc_std_code1);
tmpAccCode = (acc_code1 >> 5) + (acc_code0 << 3);
out->msg.canparams.cc_params.m16c_basic.acc_std_code0 =
(unsigned char) tmpAccCode;
out->msg.canparams.cc_params.m16c_basic.acc_std_code1 =
(unsigned char) (tmpAccCode >> 8);
// info("code0: 0x%2.2X, code1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_code0, out->msg.canparams.cc_params.m16c_basic.acc_std_code1);
out->msg.canparams.cc_params.m16c_basic.acc_std_mask0 =
~acc_mask0;
out->msg.canparams.cc_params.m16c_basic.acc_std_mask1 =
~acc_mask1;
// info("mask0: 0x%2.2X, mask1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_mask0, out->msg.canparams.cc_params.m16c_basic.acc_std_mask1);
tmpAccMask = ((acc_mask1) >> 5) + ((acc_mask0) << 3);
// info("tmpAccMask: 0x%4.4X\n", tmpAccMask);
out->msg.canparams.cc_params.m16c_basic.acc_std_mask0 =
(unsigned char) ~tmpAccMask;
out->msg.canparams.cc_params.m16c_basic.acc_std_mask1 =
(unsigned char) ~(tmpAccMask >> 8);
// info("mask0: 0x%2.2X, mask1: 0x%2.2X\n", out->msg.canparams.cc_params.m16c_basic.acc_std_mask0, out->msg.canparams.cc_params.m16c_basic.acc_std_mask1);
out->msg.canparams.cc_params.m16c_basic.acc_ext_code0 =
(unsigned char) tmpAccCode;
out->msg.canparams.cc_params.m16c_basic.acc_ext_code1 =
(unsigned char) (tmpAccCode >> 8);
out->msg.canparams.cc_params.m16c_basic.acc_ext_code2 = acc_code2;
out->msg.canparams.cc_params.m16c_basic.acc_ext_code3 = acc_code3;
out->msg.canparams.cc_params.m16c_basic.acc_ext_mask0 =
(unsigned char) ~tmpAccMask;
out->msg.canparams.cc_params.m16c_basic.acc_ext_mask1 =
(unsigned char) ~(tmpAccMask >> 8);
out->msg.canparams.cc_params.m16c_basic.acc_ext_mask2 =
~acc_mask2;
out->msg.canparams.cc_params.m16c_basic.acc_ext_mask3 =
~acc_mask3;
vfree(baudrate_error);
vfree(samplepoint_error);
return 0;
}

View file

@ -187,6 +187,7 @@ extern struct sock *netlink_kernel_create(struct net *net,
extern void netlink_kernel_release(struct sock *sk);
extern int __netlink_change_ngroups(struct sock *sk, unsigned int groups);
extern int netlink_change_ngroups(struct sock *sk, unsigned int groups);
extern void __netlink_clear_multicast_users(struct sock *sk, unsigned int group);
extern void netlink_clear_multicast_users(struct sock *sk, unsigned int group);
extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err);
extern int netlink_has_listeners(struct sock *sk, unsigned int group);

View file

@ -38,6 +38,7 @@
#define PNPIPE_IFINDEX 2
#define PNADDR_ANY 0
#define PNADDR_BROADCAST 0xFC
#define PNPORT_RESOURCE_ROUTING 0
/* Values for PNPIPE_ENCAP option */

View file

@ -89,6 +89,7 @@ struct driver_info {
#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
#define FLAG_WLAN 0x0080 /* use "wlan%d" names */
#define FLAG_AVOID_UNLINK_URBS 0x0100 /* don't unlink urbs at usbnet_stop() */
#define FLAG_SEND_ZLP 0x0200 /* hw requires ZLPs are sent */
/* init device ... can sleep, or cause probe() failure */

View file

@ -12,7 +12,6 @@ struct ip_tunnel
struct ip_tunnel *next;
struct net_device *dev;
int recursion; /* Depth of hard_start_xmit recursion */
int err_count; /* Number of arrived ICMP errors */
unsigned long err_time; /* Time when the last ICMP error arrived */

View file

@ -49,6 +49,7 @@ cond_syscall(sys_sendmsg);
cond_syscall(compat_sys_sendmsg);
cond_syscall(sys_recvmsg);
cond_syscall(compat_sys_recvmsg);
cond_syscall(compat_sys_recvfrom);
cond_syscall(sys_socketcall);
cond_syscall(sys_futex);
cond_syscall(compat_sys_futex);

View file

@ -671,7 +671,7 @@ static char *ip4_string(char *p, const u8 *addr, bool leading_zeros)
return p;
}
static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
static char *ip6_compressed_string(char *p, const char *addr)
{
int i;
int j;
@ -683,7 +683,12 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
u8 hi;
u8 lo;
bool needcolon = false;
bool useIPv4 = ipv6_addr_v4mapped(addr) || ipv6_addr_is_isatap(addr);
bool useIPv4;
struct in6_addr in6;
memcpy(&in6, addr, sizeof(struct in6_addr));
useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
memset(zerolength, 0, sizeof(zerolength));
@ -695,7 +700,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
/* find position of longest 0 run */
for (i = 0; i < range; i++) {
for (j = i; j < range; j++) {
if (addr->s6_addr16[j] != 0)
if (in6.s6_addr16[j] != 0)
break;
zerolength[i]++;
}
@ -722,7 +727,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
needcolon = false;
}
/* hex u16 without leading 0s */
word = ntohs(addr->s6_addr16[i]);
word = ntohs(in6.s6_addr16[i]);
hi = word >> 8;
lo = word & 0xff;
if (hi) {
@ -741,19 +746,19 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
if (useIPv4) {
if (needcolon)
*p++ = ':';
p = ip4_string(p, &addr->s6_addr[12], false);
p = ip4_string(p, &in6.s6_addr[12], false);
}
*p = '\0';
return p;
}
static char *ip6_string(char *p, const struct in6_addr *addr, const char *fmt)
static char *ip6_string(char *p, const char *addr, const char *fmt)
{
int i;
for (i = 0; i < 8; i++) {
p = pack_hex_byte(p, addr->s6_addr[2 * i]);
p = pack_hex_byte(p, addr->s6_addr[2 * i + 1]);
p = pack_hex_byte(p, *addr++);
p = pack_hex_byte(p, *addr++);
if (fmt[0] == 'I' && i != 7)
*p++ = ':';
}
@ -768,9 +773,9 @@ static char *ip6_addr_string(char *buf, char *end, const u8 *addr,
char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
if (fmt[0] == 'I' && fmt[2] == 'c')
ip6_compressed_string(ip6_addr, (const struct in6_addr *)addr);
ip6_compressed_string(ip6_addr, addr);
else
ip6_string(ip6_addr, (const struct in6_addr *)addr, fmt);
ip6_string(ip6_addr, addr, fmt);
return string(buf, end, ip6_addr, spec);
}

View file

@ -1781,8 +1781,8 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
ax25_info.idletimer = ax25_display_timer(&ax25->idletimer) / (60 * HZ);
ax25_info.n2count = ax25->n2count;
ax25_info.state = ax25->state;
ax25_info.rcv_q = sk_wmem_alloc_get(sk);
ax25_info.snd_q = sk_rmem_alloc_get(sk);
ax25_info.rcv_q = sk_rmem_alloc_get(sk);
ax25_info.snd_q = sk_wmem_alloc_get(sk);
ax25_info.vs = ax25->vs;
ax25_info.vr = ax25->vr;
ax25_info.va = ax25->va;

View file

@ -192,11 +192,10 @@
#define F_QUEUE_MAP_CPU (1<<14) /* queue map mirrors smp_processor_id() */
/* Thread control flag bits */
#define T_TERMINATE (1<<0)
#define T_STOP (1<<1) /* Stop run */
#define T_RUN (1<<2) /* Start run */
#define T_REMDEVALL (1<<3) /* Remove all devs */
#define T_REMDEV (1<<4) /* Remove one dev */
#define T_STOP (1<<0) /* Stop run */
#define T_RUN (1<<1) /* Start run */
#define T_REMDEVALL (1<<2) /* Remove all devs */
#define T_REMDEV (1<<3) /* Remove one dev */
/* If lock -- can be removed after some work */
#define if_lock(t) spin_lock(&(t->if_lock));
@ -2105,7 +2104,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev)
static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
{
ktime_t start;
ktime_t start_time, end_time;
s32 remaining;
struct hrtimer_sleeper t;
@ -2116,7 +2115,7 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
if (remaining <= 0)
return;
start = ktime_now();
start_time = ktime_now();
if (remaining < 100)
udelay(remaining); /* really small just spin */
else {
@ -2135,7 +2134,10 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)
} while (t.task && pkt_dev->running && !signal_pending(current));
__set_current_state(TASK_RUNNING);
}
pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), start));
end_time = ktime_now();
pkt_dev->idle_acc += ktime_to_ns(ktime_sub(end_time, start_time));
pkt_dev->next_tx = ktime_add_ns(end_time, pkt_dev->delay);
}
static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
@ -3365,18 +3367,28 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
mutex_unlock(&pktgen_thread_lock);
}
static void idle(struct pktgen_dev *pkt_dev)
static void pktgen_resched(struct pktgen_dev *pkt_dev)
{
ktime_t idle_start = ktime_now();
if (need_resched())
schedule();
else
cpu_relax();
schedule();
pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), idle_start));
}
static void pktgen_wait_for_skb(struct pktgen_dev *pkt_dev)
{
ktime_t idle_start = ktime_now();
while (atomic_read(&(pkt_dev->skb->users)) != 1) {
if (signal_pending(current))
break;
if (need_resched())
pktgen_resched(pkt_dev);
else
cpu_relax();
}
pkt_dev->idle_acc += ktime_to_ns(ktime_sub(ktime_now(), idle_start));
}
static void pktgen_xmit(struct pktgen_dev *pkt_dev)
{
@ -3387,36 +3399,21 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
u16 queue_map;
int ret;
if (pkt_dev->delay) {
spin(pkt_dev, pkt_dev->next_tx);
/* This is max DELAY, this has special meaning of
* "never transmit"
*/
if (pkt_dev->delay == ULLONG_MAX) {
pkt_dev->next_tx = ktime_add_ns(ktime_now(), ULONG_MAX);
return;
}
}
if (!pkt_dev->skb) {
set_cur_queue_map(pkt_dev);
queue_map = pkt_dev->cur_queue_map;
} else {
queue_map = skb_get_queue_mapping(pkt_dev->skb);
}
txq = netdev_get_tx_queue(odev, queue_map);
/* Did we saturate the queue already? */
if (netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq)) {
/* If device is down, then all queues are permnantly frozen */
if (netif_running(odev))
idle(pkt_dev);
else
pktgen_stop_device(pkt_dev);
/* If device is offline, then don't send */
if (unlikely(!netif_running(odev) || !netif_carrier_ok(odev))) {
pktgen_stop_device(pkt_dev);
return;
}
/* This is max DELAY, this has special meaning of
* "never transmit"
*/
if (unlikely(pkt_dev->delay == ULLONG_MAX)) {
pkt_dev->next_tx = ktime_add_ns(ktime_now(), ULONG_MAX);
return;
}
/* If no skb or clone count exhausted then get new one */
if (!pkt_dev->skb || (pkt_dev->last_ok &&
++pkt_dev->clone_count >= pkt_dev->clone_skb)) {
/* build a new pkt */
@ -3435,54 +3432,45 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
pkt_dev->clone_count = 0; /* reset counter */
}
/* fill_packet() might have changed the queue */
if (pkt_dev->delay && pkt_dev->last_ok)
spin(pkt_dev, pkt_dev->next_tx);
queue_map = skb_get_queue_mapping(pkt_dev->skb);
txq = netdev_get_tx_queue(odev, queue_map);
__netif_tx_lock_bh(txq);
atomic_inc(&(pkt_dev->skb->users));
if (unlikely(netif_tx_queue_stopped(txq) || netif_tx_queue_frozen(txq)))
pkt_dev->last_ok = 0;
else {
atomic_inc(&(pkt_dev->skb->users));
retry_now:
ret = NETDEV_TX_BUSY;
else
ret = (*xmit)(pkt_dev->skb, odev);
switch (ret) {
case NETDEV_TX_OK:
txq_trans_update(txq);
pkt_dev->last_ok = 1;
pkt_dev->sofar++;
pkt_dev->seq_num++;
pkt_dev->tx_bytes += pkt_dev->cur_pkt_size;
break;
case NETDEV_TX_LOCKED:
cpu_relax();
goto retry_now;
default: /* Drivers are not supposed to return other values! */
if (net_ratelimit())
pr_info("pktgen: %s xmit error: %d\n",
odev->name, ret);
pkt_dev->errors++;
/* fallthru */
case NETDEV_TX_BUSY:
/* Retry it next time */
atomic_dec(&(pkt_dev->skb->users));
pkt_dev->last_ok = 0;
}
if (pkt_dev->delay)
pkt_dev->next_tx = ktime_add_ns(ktime_now(),
pkt_dev->delay);
switch (ret) {
case NETDEV_TX_OK:
txq_trans_update(txq);
pkt_dev->last_ok = 1;
pkt_dev->sofar++;
pkt_dev->seq_num++;
pkt_dev->tx_bytes += pkt_dev->cur_pkt_size;
break;
default: /* Drivers are not supposed to return other values! */
if (net_ratelimit())
pr_info("pktgen: %s xmit error: %d\n",
odev->name, ret);
pkt_dev->errors++;
/* fallthru */
case NETDEV_TX_LOCKED:
case NETDEV_TX_BUSY:
/* Retry it next time */
atomic_dec(&(pkt_dev->skb->users));
pkt_dev->last_ok = 0;
}
__netif_tx_unlock_bh(txq);
/* If pkt_dev->count is zero, then run forever */
if ((pkt_dev->count != 0) && (pkt_dev->sofar >= pkt_dev->count)) {
while (atomic_read(&(pkt_dev->skb->users)) != 1) {
if (signal_pending(current))
break;
idle(pkt_dev);
}
pktgen_wait_for_skb(pkt_dev);
/* Done with this */
pktgen_stop_device(pkt_dev);
@ -3515,20 +3503,24 @@ static int pktgen_thread_worker(void *arg)
while (!kthread_should_stop()) {
pkt_dev = next_to_run(t);
if (!pkt_dev &&
(t->control & (T_STOP | T_RUN | T_REMDEVALL | T_REMDEV))
== 0) {
prepare_to_wait(&(t->queue), &wait,
TASK_INTERRUPTIBLE);
schedule_timeout(HZ / 10);
finish_wait(&(t->queue), &wait);
if (unlikely(!pkt_dev && t->control == 0)) {
wait_event_interruptible_timeout(t->queue,
t->control != 0,
HZ/10);
continue;
}
__set_current_state(TASK_RUNNING);
if (pkt_dev)
if (likely(pkt_dev)) {
pktgen_xmit(pkt_dev);
if (need_resched())
pktgen_resched(pkt_dev);
else
cpu_relax();
}
if (t->control & T_STOP) {
pktgen_stop(t);
t->control &= ~(T_STOP);

View file

@ -66,10 +66,7 @@
solution, but it supposes maintaing new variable in ALL
skb, even if no tunneling is used.
Current solution: t->recursion lock breaks dead loops. It looks
like dev->tbusy flag, but I preferred new variable, because
the semantics is different. One day, when hard_start_xmit
will be multithreaded we will have to use skb->encapsulation.
Current solution: HARD_TX_LOCK lock breaks dead loops.
@ -678,11 +675,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
__be32 dst;
int mtu;
if (tunnel->recursion++) {
stats->collisions++;
goto tx_error;
}
if (dev->type == ARPHRD_ETHER)
IPCB(skb)->flags = 0;
@ -820,7 +812,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
ip_rt_put(rt);
stats->tx_dropped++;
dev_kfree_skb(skb);
tunnel->recursion--;
return NETDEV_TX_OK;
}
if (skb->sk)
@ -888,7 +879,6 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev
nf_reset(skb);
IPTUNNEL_XMIT();
tunnel->recursion--;
return NETDEV_TX_OK;
tx_error_icmp:
@ -897,7 +887,6 @@ tx_error_icmp:
tx_error:
stats->tx_errors++;
dev_kfree_skb(skb);
tunnel->recursion--;
return NETDEV_TX_OK;
}

View file

@ -611,6 +611,9 @@ static int do_ip_setsockopt(struct sock *sk, int level,
* Check the arguments are allowable
*/
if (optlen < sizeof(struct in_addr))
goto e_inval;
err = -EFAULT;
if (optlen >= sizeof(struct ip_mreqn)) {
if (copy_from_user(&mreq, optval, sizeof(mreq)))

View file

@ -402,11 +402,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
__be32 dst = tiph->daddr;
int mtu;
if (tunnel->recursion++) {
stats->collisions++;
goto tx_error;
}
if (skb->protocol != htons(ETH_P_IP))
goto tx_error;
@ -485,7 +480,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
ip_rt_put(rt);
stats->tx_dropped++;
dev_kfree_skb(skb);
tunnel->recursion--;
return NETDEV_TX_OK;
}
if (skb->sk)
@ -523,7 +517,6 @@ static netdev_tx_t ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
nf_reset(skb);
IPTUNNEL_XMIT();
tunnel->recursion--;
return NETDEV_TX_OK;
tx_error_icmp:
@ -531,7 +524,6 @@ tx_error_icmp:
tx_error:
stats->tx_errors++;
dev_kfree_skb(skb);
tunnel->recursion--;
return NETDEV_TX_OK;
}

View file

@ -1043,11 +1043,6 @@ ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
struct net_device_stats *stats = &t->dev->stats;
int ret;
if (t->recursion++) {
stats->collisions++;
goto tx_err;
}
switch (skb->protocol) {
case htons(ETH_P_IP):
ret = ip4ip6_tnl_xmit(skb, dev);
@ -1062,14 +1057,12 @@ ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
if (ret < 0)
goto tx_err;
t->recursion--;
return NETDEV_TX_OK;
tx_err:
stats->tx_errors++;
stats->tx_dropped++;
kfree_skb(skb);
t->recursion--;
return NETDEV_TX_OK;
}

View file

@ -626,11 +626,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct in6_addr *addr6;
int addr_type;
if (tunnel->recursion++) {
stats->collisions++;
goto tx_error;
}
if (skb->protocol != htons(ETH_P_IPV6))
goto tx_error;
@ -753,7 +748,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
ip_rt_put(rt);
stats->tx_dropped++;
dev_kfree_skb(skb);
tunnel->recursion--;
return NETDEV_TX_OK;
}
if (skb->sk)
@ -794,7 +788,6 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
nf_reset(skb);
IPTUNNEL_XMIT();
tunnel->recursion--;
return NETDEV_TX_OK;
tx_error_icmp:
@ -802,7 +795,6 @@ tx_error_icmp:
tx_error:
stats->tx_errors++;
dev_kfree_skb(skb);
tunnel->recursion--;
return NETDEV_TX_OK;
}

View file

@ -90,8 +90,8 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
bss->dtim_period = tim_ie->dtim_period;
}
/* set default value for buggy APs */
if (!elems->tim || bss->dtim_period == 0)
/* set default value for buggy AP/no TIM element */
if (bss->dtim_period == 0)
bss->dtim_period = 1;
bss->supp_rates_len = 0;

View file

@ -1609,6 +1609,16 @@ int netlink_change_ngroups(struct sock *sk, unsigned int groups)
return err;
}
void __netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
{
struct sock *sk;
struct hlist_node *node;
struct netlink_table *tbl = &nl_table[ksk->sk_protocol];
sk_for_each_bound(sk, node, &tbl->mc_list)
netlink_update_socket_mc(nlk_sk(sk), group, 0);
}
/**
* netlink_clear_multicast_users - kick off multicast listeners
*
@ -1619,15 +1629,8 @@ int netlink_change_ngroups(struct sock *sk, unsigned int groups)
*/
void netlink_clear_multicast_users(struct sock *ksk, unsigned int group)
{
struct sock *sk;
struct hlist_node *node;
struct netlink_table *tbl = &nl_table[ksk->sk_protocol];
netlink_table_grab();
sk_for_each_bound(sk, node, &tbl->mc_list)
netlink_update_socket_mc(nlk_sk(sk), group, 0);
__netlink_clear_multicast_users(ksk, group);
netlink_table_ungrab();
}

View file

@ -220,10 +220,12 @@ static void __genl_unregister_mc_group(struct genl_family *family,
struct net *net;
BUG_ON(grp->family != family);
netlink_table_grab();
rcu_read_lock();
for_each_net_rcu(net)
netlink_clear_multicast_users(net->genl_sock, grp->id);
__netlink_clear_multicast_users(net->genl_sock, grp->id);
rcu_read_unlock();
netlink_table_ungrab();
clear_bit(grp->id, mc_groups);
list_del(&grp->list);

View file

@ -168,6 +168,12 @@ static int pn_send(struct sk_buff *skb, struct net_device *dev,
goto drop;
}
/* Broadcast sending is not implemented */
if (pn_addr(dst) == PNADDR_BROADCAST) {
err = -EOPNOTSUPP;
goto drop;
}
skb_reset_transport_header(skb);
WARN_ON(skb_headroom(skb) & 1); /* HW assumes word alignment */
skb_push(skb, sizeof(struct phonethdr));

View file

@ -113,6 +113,8 @@ void pn_sock_unhash(struct sock *sk)
}
EXPORT_SYMBOL(pn_sock_unhash);
static DEFINE_MUTEX(port_mutex);
static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
{
struct sock *sk = sock->sk;
@ -140,9 +142,11 @@ static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
err = -EINVAL; /* attempt to rebind */
goto out;
}
WARN_ON(sk_hashed(sk));
mutex_lock(&port_mutex);
err = sk->sk_prot->get_port(sk, pn_port(handle));
if (err)
goto out;
goto out_port;
/* get_port() sets the port, bind() sets the address if applicable */
pn->sobject = pn_object(saddr, pn_port(pn->sobject));
@ -150,6 +154,8 @@ static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
/* Enable RX on the socket */
sk->sk_prot->hash(sk);
out_port:
mutex_unlock(&port_mutex);
out:
release_sock(sk);
return err;
@ -357,8 +363,6 @@ const struct proto_ops phonet_stream_ops = {
};
EXPORT_SYMBOL(phonet_stream_ops);
static DEFINE_MUTEX(port_mutex);
/* allocate port for a socket */
int pn_sock_get_port(struct sock *sk, unsigned short sport)
{
@ -370,9 +374,7 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport)
memset(&try_sa, 0, sizeof(struct sockaddr_pn));
try_sa.spn_family = AF_PHONET;
mutex_lock(&port_mutex);
WARN_ON(!mutex_is_locked(&port_mutex));
if (!sport) {
/* search free port */
int port, pmin, pmax;
@ -401,8 +403,6 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport)
else
sock_put(tmpsk);
}
mutex_unlock(&port_mutex);
/* the port must be in use already */
return -EADDRINUSE;

View file

@ -26,11 +26,11 @@ int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
wdev->wext.connect.ie = wdev->wext.ie;
wdev->wext.connect.ie_len = wdev->wext.ie_len;
wdev->wext.connect.privacy = wdev->wext.default_key != -1;
if (wdev->wext.keys) {
wdev->wext.keys->def = wdev->wext.default_key;
wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key;
wdev->wext.connect.privacy = true;
}
if (!wdev->wext.connect.ssid_len)