aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJiri Kosina <jkosina@suse.cz>2010-08-10 13:22:08 +0200
committerJiri Kosina <jkosina@suse.cz>2010-08-10 13:22:08 +0200
commitfb8231a8b139035476f2a8aaac837d0099b66dad (patch)
tree2875806beb96ea0cdab292146767a5085721dc6a /drivers/net
parent426d31071ac476ea62c62656b242930c17b58c00 (diff)
parentf6cec0ae58c17522a7bc4e2f39dae19f199ab534 (diff)
downloadkernel_samsung_smdk4412-fb8231a8b139035476f2a8aaac837d0099b66dad.tar.gz
kernel_samsung_smdk4412-fb8231a8b139035476f2a8aaac837d0099b66dad.tar.bz2
kernel_samsung_smdk4412-fb8231a8b139035476f2a8aaac837d0099b66dad.zip
Merge branch 'master' into for-next
Conflicts: arch/arm/mach-omap1/board-nokia770.c
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig4
-rw-r--r--drivers/net/au1000_eth.c31
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c25
-rw-r--r--drivers/net/cxgb4vf/cxgb4vf_main.c31
-rw-r--r--drivers/net/davinci_emac.c2
-rw-r--r--drivers/net/e100.c2
-rw-r--r--drivers/net/e1000/e1000_main.c3
-rw-r--r--drivers/net/e1000e/netdev.c20
-rw-r--r--drivers/net/enic/enic_main.c17
-rw-r--r--drivers/net/fsl_pq_mdio.c1
-rw-r--r--drivers/net/ibm_newemac/core.c4
-rw-r--r--drivers/net/igb/igb_main.c2
-rw-r--r--drivers/net/igbvf/netdev.c2
-rw-r--r--drivers/net/ixgb/ixgb_main.c2
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c15
-rw-r--r--drivers/net/ixgbevf/ixgbevf_main.c2
-rw-r--r--drivers/net/myri_sbus.c6
-rw-r--r--drivers/net/netxen/netxen_nic_main.c15
-rw-r--r--drivers/net/niu.c15
-rw-r--r--drivers/net/niu.h4
-rw-r--r--drivers/net/pcmcia/3c574_cs.c14
-rw-r--r--drivers/net/pcmcia/3c589_cs.c14
-rw-r--r--drivers/net/pcmcia/axnet_cs.c48
-rw-r--r--drivers/net/pcmcia/com20020_cs.c22
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c48
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c29
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c32
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c63
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c71
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c60
-rw-r--r--drivers/net/ppp_async.c6
-rw-r--r--drivers/net/ppp_synctty.c6
-rw-r--r--drivers/net/pppoe.c4
-rw-r--r--drivers/net/r8169.c16
-rw-r--r--drivers/net/smc91x.h37
-rw-r--r--drivers/net/sunbmac.c6
-rw-r--r--drivers/net/sunhme.c10
-rw-r--r--drivers/net/sunlance.c6
-rw-r--r--drivers/net/sunqe.c10
-rw-r--r--drivers/net/usb/usbnet.c1
-rw-r--r--drivers/net/via-velocity.c4
-rw-r--r--drivers/net/virtio_net.c14
-rw-r--r--drivers/net/wireless/airo_cs.c74
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c43
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_calib.c18
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c388
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_paprd.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c118
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h25
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c104
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c10
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c36
-rw-r--r--drivers/net/wireless/atmel_cs.c25
-rw-r--r--drivers/net/wireless/b43/pcmcia.c13
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c136
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-devtrace.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c6
-rw-r--r--drivers/net/wireless/libertas/cfg.c214
-rw-r--r--drivers/net/wireless/libertas/dev.h5
-rw-r--r--drivers/net/wireless/libertas/if_cs.c16
-rw-r--r--drivers/net/wireless/libertas/main.c1
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c30
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c62
-rw-r--r--drivers/net/wireless/p54/p54pci.c2
-rw-r--r--drivers/net/wireless/ray_cs.c27
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00pci.c21
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180_dev.c2
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c3
-rw-r--r--drivers/net/wireless/wl3501_cs.c24
-rw-r--r--drivers/net/xilinx_emaclite.c2
84 files changed, 1286 insertions, 956 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ebe68395ecf..5a6895320b4 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -484,7 +484,7 @@ config XTENSA_XT2000_SONIC
config MIPS_AU1X00_ENET
tristate "MIPS AU1000 Ethernet support"
- depends on SOC_AU1X00
+ depends on MIPS_ALCHEMY
select PHYLIB
select CRC32
help
@@ -914,7 +914,7 @@ config SMC91X
tristate "SMC 91C9x/91C1xxx support"
select CRC32
select MII
- depends on ARM || REDWOOD_5 || REDWOOD_6 || M32R || SUPERH || \
+ depends on ARM || M32R || SUPERH || \
MIPS || BLACKFIN || MN10300 || COLDFIRE
help
This is a driver for SMC's 91x series of Ethernet chipsets,
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 386d4feec65..15ae6df2ff0 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -104,14 +104,6 @@ MODULE_VERSION(DRV_VERSION);
* complete immediately.
*/
-/* These addresses are only used if yamon doesn't tell us what
- * the mac address is, and the mac address is not passed on the
- * command line.
- */
-static unsigned char au1000_mac_addr[6] __devinitdata = {
- 0x00, 0x50, 0xc2, 0x0c, 0x30, 0x00
-};
-
struct au1000_private *au_macs[NUM_ETH_INTERFACES];
/*
@@ -1002,7 +994,6 @@ static int __devinit au1000_probe(struct platform_device *pdev)
db_dest_t *pDB, *pDBfree;
int irq, i, err = 0;
struct resource *base, *macen;
- char ethaddr[6];
base = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!base) {
@@ -1079,24 +1070,13 @@ static int __devinit au1000_probe(struct platform_device *pdev)
}
aup->mac_id = pdev->id;
- if (pdev->id == 0) {
- if (prom_get_ethernet_addr(ethaddr) == 0)
- memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
- else {
- netdev_info(dev, "No MAC address found\n");
- /* Use the hard coded MAC addresses */
- }
-
+ if (pdev->id == 0)
au1000_setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
- } else if (pdev->id == 1)
+ else if (pdev->id == 1)
au1000_setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
- /*
- * Assign to the Ethernet ports two consecutive MAC addresses
- * to match those that are printed on their stickers
- */
- memcpy(dev->dev_addr, au1000_mac_addr, sizeof(au1000_mac_addr));
- dev->dev_addr[5] += pdev->id;
+ /* set a random MAC now in case platform_data doesn't provide one */
+ random_ether_addr(dev->dev_addr);
*aup->enable = 0;
aup->mac_enabled = 0;
@@ -1106,6 +1086,9 @@ static int __devinit au1000_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "no platform_data passed, PHY search on MAC0\n");
aup->phy1_search_mac0 = 1;
} else {
+ if (is_valid_ether_addr(pd->mac))
+ memcpy(dev->dev_addr, pd->mac, 6);
+
aup->phy_static_config = pd->phy_static_config;
aup->phy_search_highest_addr = pd->phy_search_highest_addr;
aup->phy1_search_mac0 = pd->phy1_search_mac0;
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 066fd5b09fd..ad19585d960 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -3198,17 +3198,17 @@ static int __devinit init_one(struct pci_dev *pdev,
}
}
- err = pci_request_regions(pdev, DRV_NAME);
+ err = pci_enable_device(pdev);
if (err) {
- /* Just info, some other driver may have claimed the device. */
- dev_info(&pdev->dev, "cannot obtain PCI resources\n");
- return err;
+ dev_err(&pdev->dev, "cannot enable PCI device\n");
+ goto out;
}
- err = pci_enable_device(pdev);
+ err = pci_request_regions(pdev, DRV_NAME);
if (err) {
- dev_err(&pdev->dev, "cannot enable PCI device\n");
- goto out_release_regions;
+ /* Just info, some other driver may have claimed the device. */
+ dev_info(&pdev->dev, "cannot obtain PCI resources\n");
+ goto out_disable_device;
}
if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
@@ -3217,11 +3217,11 @@ static int __devinit init_one(struct pci_dev *pdev,
if (err) {
dev_err(&pdev->dev, "unable to obtain 64-bit DMA for "
"coherent allocations\n");
- goto out_disable_device;
+ goto out_release_regions;
}
} else if ((err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) != 0) {
dev_err(&pdev->dev, "no usable DMA configuration\n");
- goto out_disable_device;
+ goto out_release_regions;
}
pci_set_master(pdev);
@@ -3234,7 +3234,7 @@ static int __devinit init_one(struct pci_dev *pdev,
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
err = -ENOMEM;
- goto out_disable_device;
+ goto out_release_regions;
}
adapter->nofail_skb =
@@ -3370,11 +3370,12 @@ out_free_dev:
out_free_adapter:
kfree(adapter);
-out_disable_device:
- pci_disable_device(pdev);
out_release_regions:
pci_release_regions(pdev);
+out_disable_device:
+ pci_disable_device(pdev);
pci_set_drvdata(pdev, NULL);
+out:
return err;
}
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c
index a16563219ac..7b6d07f50c7 100644
--- a/drivers/net/cxgb4vf/cxgb4vf_main.c
+++ b/drivers/net/cxgb4vf/cxgb4vf_main.c
@@ -2462,23 +2462,24 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
version_printed = 1;
}
+
/*
- * Reserve PCI resources for the device. If we can't get them some
- * other driver may have already claimed the device ...
+ * Initialize generic PCI device state.
*/
- err = pci_request_regions(pdev, KBUILD_MODNAME);
+ err = pci_enable_device(pdev);
if (err) {
- dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+ dev_err(&pdev->dev, "cannot enable PCI device\n");
return err;
}
/*
- * Initialize generic PCI device state.
+ * Reserve PCI resources for the device. If we can't get them some
+ * other driver may have already claimed the device ...
*/
- err = pci_enable_device(pdev);
+ err = pci_request_regions(pdev, KBUILD_MODNAME);
if (err) {
- dev_err(&pdev->dev, "cannot enable PCI device\n");
- goto err_release_regions;
+ dev_err(&pdev->dev, "cannot obtain PCI resources\n");
+ goto err_disable_device;
}
/*
@@ -2491,14 +2492,14 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
if (err) {
dev_err(&pdev->dev, "unable to obtain 64-bit DMA for"
" coherent allocations\n");
- goto err_disable_device;
+ goto err_release_regions;
}
pci_using_dac = 1;
} else {
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err != 0) {
dev_err(&pdev->dev, "no usable DMA configuration\n");
- goto err_disable_device;
+ goto err_release_regions;
}
pci_using_dac = 0;
}
@@ -2514,7 +2515,7 @@ static int __devinit cxgb4vf_pci_probe(struct pci_dev *pdev,
adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
if (!adapter) {
err = -ENOMEM;
- goto err_disable_device;
+ goto err_release_regions;
}
pci_set_drvdata(pdev, adapter);
adapter->pdev = pdev;
@@ -2750,13 +2751,13 @@ err_free_adapter:
kfree(adapter);
pci_set_drvdata(pdev, NULL);
-err_disable_device:
- pci_disable_device(pdev);
- pci_clear_master(pdev);
-
err_release_regions:
pci_release_regions(pdev);
pci_set_drvdata(pdev, NULL);
+ pci_clear_master(pdev);
+
+err_disable_device:
+ pci_disable_device(pdev);
err_out:
return err;
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index d0824e32206..7fbd052ddb0 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -2944,8 +2944,8 @@ static int __devexit davinci_emac_remove(struct platform_device *pdev)
release_mem_region(res->start, res->end - res->start + 1);
unregister_netdev(ndev);
- free_netdev(ndev);
iounmap(priv->remap_addr);
+ free_netdev(ndev);
clk_disable(emac_clk);
clk_put(emac_clk);
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index b194bad29ac..8e2eab4e7c7 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1779,6 +1779,7 @@ static int e100_tx_clean(struct nic *nic)
for (cb = nic->cb_to_clean;
cb->status & cpu_to_le16(cb_complete);
cb = nic->cb_to_clean = cb->next) {
+ rmb(); /* read skb after status */
netif_printk(nic, tx_done, KERN_DEBUG, nic->netdev,
"cb[%d]->status = 0x%04X\n",
(int)(((void*)cb - (void*)nic->cbs)/sizeof(struct cb)),
@@ -1927,6 +1928,7 @@ static int e100_rx_indicate(struct nic *nic, struct rx *rx,
netif_printk(nic, rx_status, KERN_DEBUG, nic->netdev,
"status=0x%04X\n", rfd_status);
+ rmb(); /* read size after status bit */
/* If data isn't ready, nothing to indicate */
if (unlikely(!(rfd_status & cb_complete))) {
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 02833af8a0b..5cc39ed289c 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3454,6 +3454,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
(count < tx_ring->count)) {
bool cleaned = false;
+ rmb(); /* read buffer_info after eop_desc */
for ( ; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
@@ -3643,6 +3644,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
if (*work_done >= work_to_do)
break;
(*work_done)++;
+ rmb(); /* read descriptor and rx_buffer_info after status DD */
status = rx_desc->status;
skb = buffer_info->skb;
@@ -3849,6 +3851,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
if (*work_done >= work_to_do)
break;
(*work_done)++;
+ rmb(); /* read descriptor and rx_buffer_info after status DD */
status = rx_desc->status;
skb = buffer_info->skb;
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 36d31a41632..2b8ef44bd2b 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -781,6 +781,7 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
if (*work_done >= work_to_do)
break;
(*work_done)++;
+ rmb(); /* read descriptor and rx_buffer_info after status DD */
status = rx_desc->status;
skb = buffer_info->skb;
@@ -991,6 +992,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
(count < tx_ring->count)) {
bool cleaned = false;
+ rmb(); /* read buffer_info after eop_desc */
for (; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
@@ -1087,6 +1089,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
break;
(*work_done)++;
skb = buffer_info->skb;
+ rmb(); /* read descriptor and rx_buffer_info after status DD */
/* in the packet split case this is header only */
prefetch(skb->data - NET_IP_ALIGN);
@@ -1286,6 +1289,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
if (*work_done >= work_to_do)
break;
(*work_done)++;
+ rmb(); /* read descriptor and rx_buffer_info after status DD */
status = rx_desc->status;
skb = buffer_info->skb;
@@ -5825,11 +5829,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
e1000_print_device_info(adapter);
- if (pci_dev_run_wake(pdev)) {
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
- }
- pm_schedule_suspend(&pdev->dev, MSEC_PER_SEC);
+ if (pci_dev_run_wake(pdev))
+ pm_runtime_put_noidle(&pdev->dev);
return 0;
@@ -5875,8 +5876,6 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
struct e1000_adapter *adapter = netdev_priv(netdev);
bool down = test_bit(__E1000_DOWN, &adapter->state);
- pm_runtime_get_sync(&pdev->dev);
-
/*
* flush_scheduled work may reschedule our watchdog task, so
* explicitly disable watchdog tasks from being rescheduled
@@ -5901,11 +5900,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
clear_bit(__E1000_DOWN, &adapter->state);
unregister_netdev(netdev);
- if (pci_dev_run_wake(pdev)) {
- pm_runtime_disable(&pdev->dev);
- pm_runtime_set_suspended(&pdev->dev);
- }
- pm_runtime_put_noidle(&pdev->dev);
+ if (pci_dev_run_wake(pdev))
+ pm_runtime_get_noresume(&pdev->dev);
/*
* Release control of h/w to f/w. If f/w is AMT enabled, this
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 77a7f87d498..9aab85366d2 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1087,10 +1087,7 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac)
{
struct vic_provinfo *vp;
u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
- u8 *uuid;
char uuid_str[38];
- static char *uuid_fmt = "%02X%02X%02X%02X-%02X%02X-%02X%02X-"
- "%02X%02X-%02X%02X%02X%02X%0X%02X";
int err;
err = enic_vnic_dev_deinit(enic);
@@ -1121,24 +1118,14 @@ static int enic_set_port_profile(struct enic *enic, u8 *mac)
ETH_ALEN, mac);
if (enic->pp.set & ENIC_SET_INSTANCE) {
- uuid = enic->pp.instance_uuid;
- sprintf(uuid_str, uuid_fmt,
- uuid[0], uuid[1], uuid[2], uuid[3],
- uuid[4], uuid[5], uuid[6], uuid[7],
- uuid[8], uuid[9], uuid[10], uuid[11],
- uuid[12], uuid[13], uuid[14], uuid[15]);
+ sprintf(uuid_str, "%pUB", enic->pp.instance_uuid);
vic_provinfo_add_tlv(vp,
VIC_LINUX_PROV_TLV_CLIENT_UUID_STR,
sizeof(uuid_str), uuid_str);
}
if (enic->pp.set & ENIC_SET_HOST) {
- uuid = enic->pp.host_uuid;
- sprintf(uuid_str, uuid_fmt,
- uuid[0], uuid[1], uuid[2], uuid[3],
- uuid[4], uuid[5], uuid[6], uuid[7],
- uuid[8], uuid[9], uuid[10], uuid[11],
- uuid[12], uuid[13], uuid[14], uuid[15]);
+ sprintf(uuid_str, "%pUB", enic->pp.host_uuid);
vic_provinfo_add_tlv(vp,
VIC_LINUX_PROV_TLV_HOST_UUID_STR,
sizeof(uuid_str), uuid_str);
diff --git a/drivers/net/fsl_pq_mdio.c b/drivers/net/fsl_pq_mdio.c
index b4c41d72c42..f53f850b641 100644
--- a/drivers/net/fsl_pq_mdio.c
+++ b/drivers/net/fsl_pq_mdio.c
@@ -35,6 +35,7 @@
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/of.h>
+#include <linux/of_address.h>
#include <linux/of_mdio.h>
#include <linux/of_platform.h>
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 0f1d4e96cf8..eeec7bc2ce7 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2339,11 +2339,11 @@ static int __devinit emac_wait_deps(struct emac_instance *dev)
deps[EMAC_DEP_MDIO_IDX].phandle = dev->mdio_ph;
if (dev->blist && dev->blist > emac_boot_list)
deps[EMAC_DEP_PREV_IDX].phandle = 0xffffffffu;
- bus_register_notifier(&of_platform_bus_type, &emac_of_bus_notifier);
+ bus_register_notifier(&platform_bus_type, &emac_of_bus_notifier);
wait_event_timeout(emac_probe_wait,
emac_check_deps(dev, deps),
EMAC_PROBE_DEP_TIMEOUT);
- bus_unregister_notifier(&of_platform_bus_type, &emac_of_bus_notifier);
+ bus_unregister_notifier(&platform_bus_type, &emac_of_bus_notifier);
err = emac_check_deps(dev, deps) ? 0 : -ENODEV;
for (i = 0; i < EMAC_DEP_COUNT; i++) {
if (deps[i].node)
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index f0f82dc7c5d..aaf506c56cc 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -5353,6 +5353,7 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
(count < tx_ring->count)) {
+ rmb(); /* read buffer_info after eop_desc status */
for (cleaned = false; !cleaned; count++) {
tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
@@ -5558,6 +5559,7 @@ static bool igb_clean_rx_irq_adv(struct igb_q_vector *q_vector,
if (*work_done >= budget)
break;
(*work_done)++;
+ rmb(); /* read descriptor and rx_buffer_info after status DD */
skb = buffer_info->skb;
prefetch(skb->data - NET_IP_ALIGN);
diff --git a/drivers/net/igbvf/netdev.c b/drivers/net/igbvf/netdev.c
index ec808fa8dc2..c539f7c9c3e 100644
--- a/drivers/net/igbvf/netdev.c
+++ b/drivers/net/igbvf/netdev.c
@@ -248,6 +248,7 @@ static bool igbvf_clean_rx_irq(struct igbvf_adapter *adapter,
if (*work_done >= work_to_do)
break;
(*work_done)++;
+ rmb(); /* read descriptor and rx_buffer_info after status DD */
buffer_info = &rx_ring->buffer_info[i];
@@ -780,6 +781,7 @@ static bool igbvf_clean_tx_irq(struct igbvf_ring *tx_ring)
while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
(count < tx_ring->count)) {
+ rmb(); /* read buffer_info after eop_desc status */
for (cleaned = false; !cleaned; count++) {
tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index c6b75c83100..45fc89b9ba6 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -1816,6 +1816,7 @@ ixgb_clean_tx_irq(struct ixgb_adapter *adapter)
while (eop_desc->status & IXGB_TX_DESC_STATUS_DD) {
+ rmb(); /* read buffer_info after eop_desc */
for (cleaned = false; !cleaned; ) {
tx_desc = IXGB_TX_DESC(*tx_ring, i);
buffer_info = &tx_ring->buffer_info[i];
@@ -1976,6 +1977,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *adapter, int *work_done, int work_to_do)
break;
(*work_done)++;
+ rmb(); /* read descriptor and rx_buffer_info after status DD */
status = rx_desc->status;
skb = buffer_info->skb;
buffer_info->skb = NULL;
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 7d6a415bcf8..e32af434cc9 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -748,6 +748,7 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_q_vector *q_vector,
while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
(count < tx_ring->work_limit)) {
bool cleaned = false;
+ rmb(); /* read buffer_info after eop_desc */
for ( ; !cleaned; count++) {
struct sk_buff *skb;
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
@@ -6155,9 +6156,11 @@ static u16 ixgbe_select_queue(struct net_device *dev, struct sk_buff *skb)
txq &= (adapter->ring_feature[RING_F_FCOE].indices - 1);
txq += adapter->ring_feature[RING_F_FCOE].mask;
return txq;
+#ifdef CONFIG_IXGBE_DCB
} else if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
txq = adapter->fcoe.up;
return txq;
+#endif
}
}
#endif
@@ -6216,10 +6219,14 @@ static netdev_tx_t ixgbe_xmit_frame(struct sk_buff *skb,
if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED &&
(skb->protocol == htons(ETH_P_FCOE) ||
skb->protocol == htons(ETH_P_FIP))) {
- tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
- << IXGBE_TX_FLAGS_VLAN_SHIFT);
- tx_flags |= ((adapter->fcoe.up << 13)
- << IXGBE_TX_FLAGS_VLAN_SHIFT);
+#ifdef CONFIG_IXGBE_DCB
+ if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
+ tx_flags &= ~(IXGBE_TX_FLAGS_VLAN_PRIO_MASK
+ << IXGBE_TX_FLAGS_VLAN_SHIFT);
+ tx_flags |= ((adapter->fcoe.up << 13)
+ << IXGBE_TX_FLAGS_VLAN_SHIFT);
+ }
+#endif
/* flag for FCoE offloads */
if (skb->protocol == htons(ETH_P_FCOE))
tx_flags |= IXGBE_TX_FLAGS_FCOE;
diff --git a/drivers/net/ixgbevf/ixgbevf_main.c b/drivers/net/ixgbevf/ixgbevf_main.c
index 3e291ccc629..918c00359b0 100644
--- a/drivers/net/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ixgbevf/ixgbevf_main.c
@@ -231,6 +231,7 @@ static bool ixgbevf_clean_tx_irq(struct ixgbevf_adapter *adapter,
while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
(count < tx_ring->work_limit)) {
bool cleaned = false;
+ rmb(); /* read buffer_info after eop_desc */
for ( ; !cleaned; count++) {
struct sk_buff *skb;
tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
@@ -518,6 +519,7 @@ static bool ixgbevf_clean_rx_irq(struct ixgbevf_q_vector *q_vector,
break;
(*work_done)++;
+ rmb(); /* read descriptor and rx_buffer_info after status DD */
if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
hdr_info = le16_to_cpu(ixgbevf_get_hdr_info(rx_desc));
len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index 1a57c3da1f4..04e552aa14e 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -1079,7 +1079,7 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
mp->dev = dev;
dev->watchdog_timeo = 5*HZ;
- dev->irq = op->irqs[0];
+ dev->irq = op->archdata.irqs[0];
dev->netdev_ops = &myri_ops;
/* Register interrupt handler now. */
@@ -1172,12 +1172,12 @@ static struct of_platform_driver myri_sbus_driver = {
static int __init myri_sbus_init(void)
{
- return of_register_driver(&myri_sbus_driver, &of_bus_type);
+ return of_register_platform_driver(&myri_sbus_driver);
}
static void __exit myri_sbus_exit(void)
{
- of_unregister_driver(&myri_sbus_driver);
+ of_unregister_platform_driver(&myri_sbus_driver);
}
module_init(myri_sbus_init);
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 6ce6ce1df6d..fd86e18604e 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -2001,27 +2001,26 @@ static void netxen_tx_timeout_task(struct work_struct *work)
if (++adapter->tx_timeo_cnt >= NX_MAX_TX_TIMEOUTS)
goto request_reset;
+ rtnl_lock();
if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
/* try to scrub interrupt */
netxen_napi_disable(adapter);
- adapter->netdev->trans_start = jiffies;
-
netxen_napi_enable(adapter);
netif_wake_queue(adapter->netdev);
clear_bit(__NX_RESETTING, &adapter->state);
- return;
} else {
clear_bit(__NX_RESETTING, &adapter->state);
- if (!netxen_nic_reset_context(adapter)) {
- adapter->netdev->trans_start = jiffies;
- return;
+ if (netxen_nic_reset_context(adapter)) {
+ rtnl_unlock();
+ goto request_reset;
}
-
- /* context reset failed, fall through for fw reset */
}
+ adapter->netdev->trans_start = jiffies;
+ rtnl_unlock();
+ return;
request_reset:
adapter->need_fw_reset = 1;
diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index b9b950845b0..404f2d55288 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -28,10 +28,7 @@
#include <linux/slab.h>
#include <linux/io.h>
-
-#ifdef CONFIG_SPARC64
#include <linux/of_device.h>
-#endif
#include "niu.h"
@@ -9114,12 +9111,12 @@ static int __devinit niu_n2_irq_init(struct niu *np, u8 *ldg_num_map)
if (!int_prop)
return -ENODEV;
- for (i = 0; i < op->num_irqs; i++) {
+ for (i = 0; i < op->archdata.num_irqs; i++) {
ldg_num_map[i] = int_prop[i];
- np->ldg[i].irq = op->irqs[i];
+ np->ldg[i].irq = op->archdata.irqs[i];
}
- np->num_ldg = op->num_irqs;
+ np->num_ldg = op->archdata.num_irqs;
return 0;
#else
@@ -10249,14 +10246,14 @@ static int __init niu_init(void)
niu_debug = netif_msg_init(debug, NIU_MSG_DEFAULT);
#ifdef CONFIG_SPARC64
- err = of_register_driver(&niu_of_driver, &of_bus_type);
+ err = of_register_platform_driver(&niu_of_driver);
#endif
if (!err) {
err = pci_register_driver(&niu_pci_driver);
#ifdef CONFIG_SPARC64
if (err)
- of_unregister_driver(&niu_of_driver);
+ of_unregister_platform_driver(&niu_of_driver);
#endif
}
@@ -10267,7 +10264,7 @@ static void __exit niu_exit(void)
{
pci_unregister_driver(&niu_pci_driver);
#ifdef CONFIG_SPARC64
- of_unregister_driver(&niu_of_driver);
+ of_unregister_platform_driver(&niu_of_driver);
#endif
}
diff --git a/drivers/net/niu.h b/drivers/net/niu.h
index d6715465f35..a41fa8ebe05 100644
--- a/drivers/net/niu.h
+++ b/drivers/net/niu.h
@@ -3236,7 +3236,7 @@ struct niu_phy_ops {
int (*link_status)(struct niu *np, int *);
};
-struct of_device;
+struct platform_device;
struct niu {
void __iomem *regs;
struct net_device *dev;
@@ -3297,7 +3297,7 @@ struct niu {
struct niu_vpd vpd;
u32 eeprom_len;
- struct of_device *op;
+ struct platform_device *op;
void __iomem *vir_regs_1;
void __iomem *vir_regs_2;
};
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 10ee106a161..c683f77c6f4 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -87,7 +87,6 @@ earlier 3Com products.
#include <linux/bitops.h>
#include <linux/mii.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -279,8 +278,8 @@ static int tc574_probe(struct pcmcia_device *link)
lp->p_dev = link;
spin_lock_init(&lp->window_lock);
- link->io.NumPorts1 = 32;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ link->resource[0]->end = 32;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
@@ -338,10 +337,11 @@ static int tc574_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "3c574_config()\n");
- link->io.IOAddrLines = 16;
+ link->io_lines = 16;
+
for (i = j = 0; j < 0x400; j += 0x20) {
- link->io.BasePort1 = j ^ 0x300;
- i = pcmcia_request_io(link, &link->io);
+ link->resource[0]->start = j ^ 0x300;
+ i = pcmcia_request_io(link);
if (i == 0)
break;
}
@@ -357,7 +357,7 @@ static int tc574_config(struct pcmcia_device *link)
goto failed;
dev->irq = link->irq;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
ioaddr = dev->base_addr;
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index ce63c3773b4..61f9cf2100f 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -41,7 +41,6 @@
#include <linux/bitops.h>
#include <linux/jiffies.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -214,8 +213,8 @@ static int tc589_probe(struct pcmcia_device *link)
lp->p_dev = link;
spin_lock_init(&lp->lock);
- link->io.NumPorts1 = 16;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ link->resource[0]->end = 16;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -278,12 +277,13 @@ static int tc589_config(struct pcmcia_device *link)
"3Com card??\n");
multi = (link->card_id == PRODID_3COM_3C562);
+ link->io_lines = 16;
+
/* For the 3c562, the base address must be xx00-xx7f */
- link->io.IOAddrLines = 16;
for (i = j = 0; j < 0x400; j += 0x10) {
if (multi && (j & 0x80)) continue;
- link->io.BasePort1 = j ^ 0x300;
- i = pcmcia_request_io(link, &link->io);
+ link->resource[0]->start = j ^ 0x300;
+ i = pcmcia_request_io(link);
if (i == 0)
break;
}
@@ -299,7 +299,7 @@ static int tc589_config(struct pcmcia_device *link)
goto failed;
dev->irq = link->irq;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
ioaddr = dev->base_addr;
EL3WINDOW(0);
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 33525bf2a3d..5f05ffb240c 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -39,7 +39,6 @@
#include <linux/mii.h>
#include "../8390.h"
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
@@ -260,28 +259,30 @@ static int get_prom(struct pcmcia_device *link)
static int try_io_port(struct pcmcia_device *link)
{
int j, ret;
- if (link->io.NumPorts1 == 32) {
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+ link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
+ if (link->resource[0]->end == 32) {
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
/* for master/slave multifunction cards */
- if (link->io.NumPorts2 > 0)
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+ if (link->resource[1]->end > 0)
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
} else {
/* This should be two 16-port windows */
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
}
- if (link->io.BasePort1 == 0) {
- link->io.IOAddrLines = 16;
+ if (link->resource[0]->start == 0) {
for (j = 0; j < 0x400; j += 0x20) {
- link->io.BasePort1 = j ^ 0x300;
- link->io.BasePort2 = (j ^ 0x300) + 0x10;
- ret = pcmcia_request_io(link, &link->io);
+ link->resource[0]->start = j ^ 0x300;
+ link->resource[1]->start = (j ^ 0x300) + 0x10;
+ link->io_lines = 16;
+ ret = pcmcia_request_io(link);
if (ret == 0)
return ret;
}
return ret;
} else {
- return pcmcia_request_io(link, &link->io);
+ return pcmcia_request_io(link);
}
}
@@ -302,15 +303,15 @@ static int axnet_configcheck(struct pcmcia_device *p_dev,
network function with window 0, and serial with window 1 */
if (io->nwin > 1) {
i = (io->win[1].len > io->win[0].len);
- p_dev->io.BasePort2 = io->win[1-i].base;
- p_dev->io.NumPorts2 = io->win[1-i].len;
+ p_dev->resource[1]->start = io->win[1-i].base;
+ p_dev->resource[1]->end = io->win[1-i].len;
} else {
- i = p_dev->io.NumPorts2 = 0;
+ i = p_dev->resource[1]->end = 0;
}
- p_dev->io.BasePort1 = io->win[i].base;
- p_dev->io.NumPorts1 = io->win[i].len;
- p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
+ p_dev->resource[0]->start = io->win[i].base;
+ p_dev->resource[0]->end = io->win[i].len;
+ p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+ if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32)
return try_io_port(p_dev);
return -ENODEV;
@@ -333,7 +334,7 @@ static int axnet_config(struct pcmcia_device *link)
if (!link->irq)
goto failed;
- if (link->io.NumPorts2 == 8) {
+ if (resource_size(link->resource[1]) == 8) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
}
@@ -343,7 +344,7 @@ static int axnet_config(struct pcmcia_device *link)
goto failed;
dev->irq = link->irq;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
if (!get_prom(link)) {
printk(KERN_NOTICE "axnet_cs: this is not an AX88190 card!\n");
@@ -379,8 +380,7 @@ static int axnet_config(struct pcmcia_device *link)
/* Maybe PHY is in power down mode. (PPD_SET = 1)
Bit 2 of CCSR is active low. */
if (i == 32) {
- conf_reg_t reg = { 0, CS_WRITE, CISREG_CCSR, 0x04 };
- pcmcia_access_configuration_register(link, &reg);
+ pcmcia_write_config_byte(link, CISREG_CCSR, 0x04);
for (i = 0; i < 32; i++) {
j = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 1);
j2 = mdio_read(dev->base_addr + AXNET_MII_EEP, i, 2);
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index 5643f94541b..3c400cfa82a 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -43,7 +43,6 @@
#include <linux/arcdevice.h>
#include <linux/com20020.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
@@ -159,9 +158,8 @@ static int com20020_probe(struct pcmcia_device *p_dev)
/* fill in our module parameters as defaults */
dev->dev_addr[0] = node;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.NumPorts1 = 16;
- p_dev->io.IOAddrLines = 16;
+ p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ p_dev->resource[0]->end = 16;
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
p_dev->conf.IntType = INT_MEMORY_AND_IO;
@@ -246,20 +244,24 @@ static int com20020_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "com20020_config\n");
- dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1);
+ dev_dbg(&link->dev, "baseport1 is %Xh\n",
+ (unsigned int) link->resource[0]->start);
+
i = -ENODEV;
- if (!link->io.BasePort1)
+ link->io_lines = 16;
+
+ if (!link->resource[0]->start)
{
for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x10)
{
- link->io.BasePort1 = ioaddr;
- i = pcmcia_request_io(link, &link->io);
+ link->resource[0]->start = ioaddr;
+ i = pcmcia_request_io(link);
if (i == 0)
break;
}
}
else
- i = pcmcia_request_io(link, &link->io);
+ i = pcmcia_request_io(link);
if (i != 0)
{
@@ -267,7 +269,7 @@ static int com20020_config(struct pcmcia_device *link)
goto failed;
}
- ioaddr = dev->base_addr = link->io.BasePort1;
+ ioaddr = dev->base_addr = link->resource[0]->start;
dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
dev_dbg(&link->dev, "request IRQ %d\n",
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 7c27c50211a..98fffb03ecd 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -49,7 +49,6 @@
#include <linux/ioport.h>
#include <linux/crc32.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
@@ -249,9 +248,8 @@ static int fmvj18x_probe(struct pcmcia_device *link)
lp->base = NULL;
/* The io structure describes IO port mapping */
- link->io.NumPorts1 = 32;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- link->io.IOAddrLines = 5;
+ link->resource[0]->end = 32;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
/* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ;
@@ -289,13 +287,13 @@ static int mfc_try_io_port(struct pcmcia_device *link)
{ 0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x0 };
for (i = 0; i < 5; i++) {
- link->io.BasePort2 = serial_base[i];
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- if (link->io.BasePort2 == 0) {
- link->io.NumPorts2 = 0;
+ link->resource[1]->start = serial_base[i];
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
+ if (link->resource[1]->start == 0) {
+ link->resource[1]->end = 0;
printk(KERN_NOTICE "fmvj18x_cs: out of resource for serial\n");
}
- ret = pcmcia_request_io(link, &link->io);
+ ret = pcmcia_request_io(link);
if (ret == 0)
return ret;
}
@@ -311,12 +309,12 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
0x380,0x3c0 only for ioport.
*/
for (ioaddr = 0x300; ioaddr < 0x3e0; ioaddr += 0x20) {
- link->io.BasePort1 = ioaddr;
- ret = pcmcia_request_io(link, &link->io);
+ link->resource[0]->start = ioaddr;
+ ret = pcmcia_request_io(link);
if (ret == 0) {
/* calculate ConfigIndex value */
link->conf.ConfigIndex =
- ((link->io.BasePort1 & 0x0f0) >> 3) | 0x22;
+ ((link->resource[0]->start & 0x0f0) >> 3) | 0x22;
return ret;
}
}
@@ -346,6 +344,8 @@ static int fmvj18x_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "fmvj18x_config\n");
+ link->io_lines = 5;
+
len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
kfree(buf);
@@ -364,20 +364,20 @@ static int fmvj18x_config(struct pcmcia_device *link)
/* MultiFunction Card */
link->conf.ConfigBase = 0x800;
link->conf.ConfigIndex = 0x47;
- link->io.NumPorts2 = 8;
+ link->resource[1]->end = 8;
}
break;
case MANFID_NEC:
cardtype = NEC; /* MultiFunction Card */
link->conf.ConfigBase = 0x800;
link->conf.ConfigIndex = 0x47;
- link->io.NumPorts2 = 8;
+ link->resource[1]->end = 8;
break;
case MANFID_KME:
cardtype = KME; /* MultiFunction Card */
link->conf.ConfigBase = 0x800;
link->conf.ConfigIndex = 0x47;
- link->io.NumPorts2 = 8;
+ link->resource[1]->end = 8;
break;
case MANFID_CONTEC:
cardtype = CONTEC;
@@ -418,14 +418,14 @@ static int fmvj18x_config(struct pcmcia_device *link)
}
}
- if (link->io.NumPorts2 != 0) {
+ if (link->resource[1]->end != 0) {
ret = mfc_try_io_port(link);
if (ret != 0) goto failed;
} else if (cardtype == UNGERMANN) {
ret = ungermann_try_io_port(link);
if (ret != 0) goto failed;
} else {
- ret = pcmcia_request_io(link, &link->io);
+ ret = pcmcia_request_io(link);
if (ret)
goto failed;
}
@@ -437,9 +437,9 @@ static int fmvj18x_config(struct pcmcia_device *link)
goto failed;
dev->irq = link->irq;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
- if (link->io.BasePort2 != 0) {
+ if (resource_size(link->resource[1]) != 0) {
ret = fmvj18x_setup_mfc(link);
if (ret != 0) goto failed;
}
@@ -545,7 +545,6 @@ failed:
static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
{
win_req_t req;
- memreq_t mem;
u_char __iomem *base;
int i, j;
@@ -558,9 +557,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
return -1;
base = ioremap(req.Base, req.Size);
- mem.Page = 0;
- mem.CardOffset = 0;
- pcmcia_map_mem_page(link, link->win, &mem);
+ pcmcia_map_mem_page(link, link->win, 0);
/*
* MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
@@ -594,7 +591,6 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
static int fmvj18x_setup_mfc(struct pcmcia_device *link)
{
win_req_t req;
- memreq_t mem;
int i;
struct net_device *dev = link->priv;
unsigned int ioaddr;
@@ -614,9 +610,7 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
return -1;
}
- mem.Page = 0;
- mem.CardOffset = 0;
- i = pcmcia_map_mem_page(link, link->win, &mem);
+ i = pcmcia_map_mem_page(link, link->win, 0);
if (i != 0) {
iounmap(lp->base);
lp->base = NULL;
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index 67ee9851a8e..b0d06a3d962 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -57,7 +57,6 @@
#include <linux/trdevice.h>
#include <linux/ibmtr.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
@@ -152,9 +151,8 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
link->priv = info;
info->ti = netdev_priv(dev);
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.NumPorts1 = 4;
- link->io.IOAddrLines = 16;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[0]->end = 4;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.Present = PRESENT_OPTION;
@@ -213,26 +211,26 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
struct net_device *dev = info->dev;
struct tok_info *ti = netdev_priv(dev);
win_req_t req;
- memreq_t mem;
int i, ret;
dev_dbg(&link->dev, "ibmtr_config\n");
link->conf.ConfigIndex = 0x61;
+ link->io_lines = 16;
/* Determine if this is PRIMARY or ALTERNATE. */
/* Try PRIMARY card at 0xA20-0xA23 */
- link->io.BasePort1 = 0xA20;
- i = pcmcia_request_io(link, &link->io);
+ link->resource[0]->start = 0xA20;
+ i = pcmcia_request_io(link);
if (i != 0) {
/* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
- link->io.BasePort1 = 0xA24;
- ret = pcmcia_request_io(link, &link->io);
+ link->resource[0]->start = 0xA24;
+ ret = pcmcia_request_io(link);
if (ret)
goto failed;
}
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
ret = pcmcia_request_exclusive_irq(link, ibmtr_interrupt);
if (ret)
@@ -251,9 +249,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
if (ret)
goto failed;
- mem.CardOffset = mmiobase;
- mem.Page = 0;
- ret = pcmcia_map_mem_page(link, link->win, &mem);
+ ret = pcmcia_map_mem_page(link, link->win, mmiobase);
if (ret)
goto failed;
ti->mmio = ioremap(req.Base, req.Size);
@@ -268,13 +264,11 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
if (ret)
goto failed;
- mem.CardOffset = srambase;
- mem.Page = 0;
- ret = pcmcia_map_mem_page(link, info->sram_win_handle, &mem);
+ ret = pcmcia_map_mem_page(link, info->sram_win_handle, srambase);
if (ret)
goto failed;
- ti->sram_base = mem.CardOffset >> 12;
+ ti->sram_base = srambase >> 12;
ti->sram_virt = ioremap(req.Base, req.Size);
ti->sram_phys = req.Base;
@@ -325,7 +319,6 @@ static void ibmtr_release(struct pcmcia_device *link)
if (link->win) {
struct tok_info *ti = netdev_priv(dev);
iounmap(ti->mmio);
- pcmcia_release_window(link, info->sram_win_handle);
}
pcmcia_disable_device(link);
}
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 9b63dec549c..68f2deeb3ad 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -146,7 +146,6 @@ Include Files
#include <linux/ioport.h>
#include <linux/bitops.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/cistpl.h>
@@ -459,9 +458,8 @@ static int nmclan_probe(struct pcmcia_device *link)
link->priv = dev;
spin_lock_init(&lp->bank_lock);
- link->io.NumPorts1 = 32;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- link->io.IOAddrLines = 5;
+ link->resource[0]->end = 32;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
@@ -645,7 +643,8 @@ static int nmclan_config(struct pcmcia_device *link)
dev_dbg(&link->dev, "nmclan_config\n");
- ret = pcmcia_request_io(link, &link->io);
+ link->io_lines = 5;
+ ret = pcmcia_request_io(link);
if (ret)
goto failed;
ret = pcmcia_request_exclusive_irq(link, mace_interrupt);
@@ -656,7 +655,7 @@ static int nmclan_config(struct pcmcia_device *link)
goto failed;
dev->irq = link->irq;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
ioaddr = dev->base_addr;
@@ -758,29 +757,20 @@ static void nmclan_reset(struct net_device *dev)
#if RESET_XILINX
struct pcmcia_device *link = &lp->link;
- conf_reg_t reg;
- u_long OrigCorValue;
+ u8 OrigCorValue;
/* Save original COR value */
- reg.Function = 0;
- reg.Action = CS_READ;
- reg.Offset = CISREG_COR;
- reg.Value = 0;
- pcmcia_access_configuration_register(link, &reg);
- OrigCorValue = reg.Value;
+ pcmcia_read_config_byte(link, CISREG_COR, &OrigCorValue);
/* Reset Xilinx */
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_COR;
- dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
+ dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%x, resetting...\n",
OrigCorValue);
- reg.Value = COR_SOFT_RESET;
- pcmcia_access_configuration_register(link, &reg);
+ pcmcia_write_config_byte(link, CISREG_COR, COR_SOFT_RESET);
/* Need to wait for 20 ms for PCMCIA to finish reset. */
/* Restore original COR configuration index */
- reg.Value = COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK);
- pcmcia_access_configuration_register(link, &reg);
+ pcmcia_write_config_byte(link, CISREG_COR,
+ (COR_LEVEL_REQ | (OrigCorValue & COR_CONFIG_MASK)));
/* Xilinx is now completely reset along with the MACE chip. */
lp->tx_free_frames=AM2150_MAX_TX_FRAMES;
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index bfdef72c5d5..c3edfe4c265 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -42,7 +42,6 @@
#include <linux/mii.h>
#include "../8390.h"
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
@@ -113,8 +112,6 @@ static int setup_dma_config(struct pcmcia_device *link, int start_pg,
static void pcnet_detach(struct pcmcia_device *p_dev);
-static dev_info_t dev_info = "pcnet_cs";
-
/*====================================================================*/
typedef struct hw_info_t {
@@ -304,7 +301,6 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
win_req_t req;
- memreq_t mem;
u_char __iomem *base, *virt;
int i, j;
@@ -317,10 +313,8 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
return NULL;
virt = ioremap(req.Base, req.Size);
- mem.Page = 0;
for (i = 0; i < NR_INFO; i++) {
- mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
- pcmcia_map_mem_page(link, link->win, &mem);
+ pcmcia_map_mem_page(link, link->win, hw_info[i].offset & ~(req.Size-1));
base = &virt[hw_info[i].offset & (req.Size-1)];
if ((readb(base+0) == hw_info[i].a0) &&
(readb(base+2) == hw_info[i].a1) &&
@@ -480,29 +474,31 @@ static hw_info_t *get_hwired(struct pcmcia_device *link)
static int try_io_port(struct pcmcia_device *link)
{
int j, ret;
- if (link->io.NumPorts1 == 32) {
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (link->io.NumPorts2 > 0) {
+ link->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ link->resource[1]->flags &= ~IO_DATA_PATH_WIDTH;
+ if (link->resource[0]->end == 32) {
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+ if (link->resource[1]->end > 0) {
/* for master/slave multifunction cards */
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
}
} else {
/* This should be two 16-port windows */
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_16;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_16;
}
- if (link->io.BasePort1 == 0) {
- link->io.IOAddrLines = 16;
+ if (link->resource[0]->start == 0) {
for (j = 0; j < 0x400; j += 0x20) {
- link->io.BasePort1 = j ^ 0x300;
- link->io.BasePort2 = (j ^ 0x300) + 0x10;
- ret = pcmcia_request_io(link, &link->io);
+ link->resource[0]->start = j ^ 0x300;
+ link->resource[1]->start = (j ^ 0x300) + 0x10;
+ link->io_lines = 16;
+ ret = pcmcia_request_io(link);
if (ret == 0)
return ret;
}
return ret;
} else {
- return pcmcia_request_io(link, &link->io);
+ return pcmcia_request_io(link);
}
}
@@ -523,18 +519,18 @@ static int pcnet_confcheck(struct pcmcia_device *p_dev,
network function with window 0, and serial with window 1 */
if (io->nwin > 1) {
i = (io->win[1].len > io->win[0].len);
- p_dev->io.BasePort2 = io->win[1-i].base;
- p_dev->io.NumPorts2 = io->win[1-i].len;
+ p_dev->resource[1]->start = io->win[1-i].base;
+ p_dev->resource[1]->end = io->win[1-i].len;
} else {
- i = p_dev->io.NumPorts2 = 0;
+ i = p_dev->resource[1]->end = 0;
}
*has_shmem = ((cfg->mem.nwin == 1) &&
(cfg->mem.win[0].len >= 0x4000));
- p_dev->io.BasePort1 = io->win[i].base;
- p_dev->io.NumPorts1 = io->win[i].len;
- p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- if (p_dev->io.NumPorts1 + p_dev->io.NumPorts2 >= 32)
+ p_dev->resource[0]->start = io->win[i].base;
+ p_dev->resource[0]->end = io->win[i].len;
+ p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+ if (p_dev->resource[0]->end + p_dev->resource[1]->end >= 32)
return try_io_port(p_dev);
return 0;
@@ -557,7 +553,7 @@ static int pcnet_config(struct pcmcia_device *link)
if (!link->irq)
goto failed;
- if (link->io.NumPorts2 == 8) {
+ if (resource_size(link->resource[1]) == 8) {
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
}
@@ -569,7 +565,7 @@ static int pcnet_config(struct pcmcia_device *link)
if (ret)
goto failed;
dev->irq = link->irq;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
if (info->flags & HAS_MISC_REG) {
if ((if_port == 1) || (if_port == 2))
dev->if_port = if_port;
@@ -956,7 +952,7 @@ static int pcnet_open(struct net_device *dev)
set_misc_reg(dev);
outb_p(0xFF, nic_base + EN0_ISR); /* Clear bogus intr. */
- ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev_info, dev);
+ ret = request_irq(dev->irq, ei_irq_wrapper, IRQF_SHARED, dev->name, dev);
if (ret)
return ret;
@@ -1464,7 +1460,6 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
struct net_device *dev = link->priv;
pcnet_dev_t *info = PRIV(dev);
win_req_t req;
- memreq_t mem;
int i, window_size, offset, ret;
window_size = (stop_pg - start_pg) << 8;
@@ -1483,11 +1478,9 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
if (ret)
goto failed;
- mem.CardOffset = (start_pg << 8) + cm_offset;
- offset = mem.CardOffset % window_size;
- mem.CardOffset -= offset;
- mem.Page = 0;
- ret = pcmcia_map_mem_page(link, link->win, &mem);
+ offset = (start_pg << 8) + cm_offset;
+ offset -= offset % window_size;
+ ret = pcmcia_map_mem_page(link, link->win, offset);
if (ret)
goto failed;
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 307cd1721e9..377367d03b4 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -44,7 +44,6 @@
#include <linux/jiffies.h>
#include <linux/firmware.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -325,9 +324,8 @@ static int smc91c92_probe(struct pcmcia_device *link)
link->priv = dev;
spin_lock_init(&smc->lock);
- link->io.NumPorts1 = 16;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- link->io.IOAddrLines = 4;
+ link->resource[0]->end = 16;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.IntType = INT_MEMORY_AND_IO;
@@ -428,12 +426,13 @@ static int mhz_mfc_config_check(struct pcmcia_device *p_dev,
void *priv_data)
{
int k;
- p_dev->io.BasePort2 = cf->io.win[0].base;
+ p_dev->resource[1]->start = cf->io.win[0].base;
for (k = 0; k < 0x400; k += 0x10) {
if (k & 0x80)
continue;
- p_dev->io.BasePort1 = k ^ 0x300;
- if (!pcmcia_request_io(p_dev, &p_dev->io))
+ p_dev->resource[0]->start = k ^ 0x300;
+ p_dev->io_lines = 16;
+ if (!pcmcia_request_io(p_dev))
return 0;
}
return -ENODEV;
@@ -444,21 +443,20 @@ static int mhz_mfc_config(struct pcmcia_device *link)
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
win_req_t req;
- memreq_t mem;
+ unsigned int offset;
int i;
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
- link->io.IOAddrLines = 16;
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->io.NumPorts2 = 8;
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[1]->end = 8;
/* The Megahertz combo cards have modem-like CIS entries, so
we have to explicitly try a bunch of port combinations. */
if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
return -ENODEV;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
/* Allocate a memory window, for accessing the ISR */
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
@@ -469,11 +467,8 @@ static int mhz_mfc_config(struct pcmcia_device *link)
return -ENODEV;
smc->base = ioremap(req.Base, req.Size);
- mem.CardOffset = mem.Page = 0;
- if (smc->manfid == MANFID_MOTOROLA)
- mem.CardOffset = link->conf.ConfigBase;
- i = pcmcia_map_mem_page(link, link->win, &mem);
-
+ offset = (smc->manfid == MANFID_MOTOROLA) ? link->conf.ConfigBase : 0;
+ i = pcmcia_map_mem_page(link, link->win, offset);
if ((i == 0) &&
(smc->manfid == MANFID_MEGAHERTZ) &&
(smc->cardid == PRODID_MEGAHERTZ_EM3288))
@@ -546,7 +541,7 @@ static void mot_config(struct pcmcia_device *link)
struct net_device *dev = link->priv;
struct smc_private *smc = netdev_priv(dev);
unsigned int ioaddr = dev->base_addr;
- unsigned int iouart = link->io.BasePort2;
+ unsigned int iouart = link->resource[1]->start;
/* Set UART base address and force map with COR bit 1 */
writeb(iouart & 0xff, smc->base + MOT_UART + CISREG_IOBASE_0);
@@ -602,9 +597,9 @@ static int smc_configcheck(struct pcmcia_device *p_dev,
unsigned int vcc,
void *priv_data)
{
- p_dev->io.BasePort1 = cf->io.win[0].base;
- p_dev->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;
- return pcmcia_request_io(p_dev, &p_dev->io);
+ p_dev->resource[0]->start = cf->io.win[0].base;
+ p_dev->io_lines = cf->io.flags & CISTPL_IO_LINES_MASK;
+ return pcmcia_request_io(p_dev);
}
static int smc_config(struct pcmcia_device *link)
@@ -612,10 +607,10 @@ static int smc_config(struct pcmcia_device *link)
struct net_device *dev = link->priv;
int i;
- link->io.NumPorts1 = 16;
+ link->resource[0]->end = 16;
i = pcmcia_loop_config(link, smc_configcheck, NULL);
if (!i)
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
return i;
}
@@ -647,27 +642,27 @@ static int osi_config(struct pcmcia_device *link)
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status = CCSR_AUDIO_ENA;
- link->io.NumPorts1 = 64;
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
- link->io.NumPorts2 = 8;
- link->io.IOAddrLines = 16;
+ link->resource[0]->end = 64;
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
+ link->resource[1]->end = 8;
/* Enable Hard Decode, LAN, Modem */
link->conf.ConfigIndex = 0x23;
+ link->io_lines = 16;
for (i = j = 0; j < 4; j++) {
- link->io.BasePort2 = com[j];
- i = pcmcia_request_io(link, &link->io);
+ link->resource[1]->start = com[j];
+ i = pcmcia_request_io(link);
if (i == 0)
break;
}
if (i != 0) {
/* Fallback: turn off hard decode */
link->conf.ConfigIndex = 0x03;
- link->io.NumPorts2 = 0;
- i = pcmcia_request_io(link, &link->io);
+ link->resource[1]->end = 0;
+ i = pcmcia_request_io(link);
}
- dev->base_addr = link->io.BasePort1 + 0x10;
+ dev->base_addr = link->resource[0]->start + 0x10;
return i;
}
@@ -684,7 +679,7 @@ static int osi_load_firmware(struct pcmcia_device *link)
/* Download the Seven of Diamonds firmware */
for (i = 0; i < fw->size; i++) {
- outb(fw->data[i], link->io.BasePort1 + 2);
+ outb(fw->data[i], link->resource[0]->start + 2);
udelay(50);
}
release_firmware(fw);
@@ -726,12 +721,12 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
return rc;
} else if (manfid == MANFID_OSITECH) {
/* Make sure both functions are powered up */
- set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
+ set_bits(0x300, link->resource[0]->start + OSITECH_AUI_PWR);
/* Now, turn on the interrupt for both card functions */
- set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
+ set_bits(0x300, link->resource[0]->start + OSITECH_RESET_ISR);
dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
- inw(link->io.BasePort1 + OSITECH_AUI_PWR),
- inw(link->io.BasePort1 + OSITECH_RESET_ISR));
+ inw(link->resource[0]->start + OSITECH_AUI_PWR),
+ inw(link->resource[0]->start + OSITECH_RESET_ISR));
}
return 0;
}
@@ -804,7 +799,7 @@ static int check_sig(struct pcmcia_device *link)
}
/* Try setting bus width */
- width = (link->io.Attributes1 == IO_DATA_PATH_WIDTH_AUTO);
+ width = (link->resource[0]->flags == IO_DATA_PATH_WIDTH_AUTO);
s = inb(ioaddr + CONFIG);
if (width)
s |= CFG_16BIT;
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index b6c3644888c..4eb6f986703 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -82,7 +82,6 @@
#include <linux/bitops.h>
#include <linux/mii.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -678,9 +677,9 @@ xirc2ps_config_modem(struct pcmcia_device *p_dev,
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
- p_dev->io.BasePort2 = cf->io.win[0].base;
- p_dev->io.BasePort1 = ioaddr;
- if (!pcmcia_request_io(p_dev, &p_dev->io))
+ p_dev->resource[1]->start = cf->io.win[0].base;
+ p_dev->resource[0]->start = ioaddr;
+ if (!pcmcia_request_io(p_dev))
return 0;
}
}
@@ -697,11 +696,11 @@ xirc2ps_config_check(struct pcmcia_device *p_dev,
int *pass = priv_data;
if (cf->io.nwin > 0 && (cf->io.win[0].base & 0xf) == 8) {
- p_dev->io.BasePort2 = cf->io.win[0].base;
- p_dev->io.BasePort1 = p_dev->io.BasePort2
+ p_dev->resource[1]->start = cf->io.win[0].base;
+ p_dev->resource[0]->start = p_dev->resource[1]->start
+ (*pass ? (cf->index & 0x20 ? -24:8)
: (cf->index & 0x20 ? 8:-24));
- if (!pcmcia_request_io(p_dev, &p_dev->io))
+ if (!pcmcia_request_io(p_dev))
return 0;
}
return -ENODEV;
@@ -808,8 +807,7 @@ xirc2ps_config(struct pcmcia_device * link)
goto failure;
}
- link->io.IOAddrLines =10;
- link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+ link->resource[0]->flags |= IO_DATA_PATH_WIDTH_16;
if (local->modem) {
int pass;
@@ -817,16 +815,16 @@ xirc2ps_config(struct pcmcia_device * link)
link->conf.Attributes |= CONF_ENABLE_SPKR;
link->conf.Status |= CCSR_AUDIO_ENA;
}
- link->io.NumPorts2 = 8;
- link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+ link->resource[1]->end = 8;
+ link->resource[1]->flags |= IO_DATA_PATH_WIDTH_8;
if (local->dingo) {
/* Take the Modem IO port from the CIS and scan for a free
* Ethernet port */
- link->io.NumPorts1 = 16; /* no Mako stuff anymore */
+ link->resource[0]->end = 16; /* no Mako stuff anymore */
if (!pcmcia_loop_config(link, xirc2ps_config_modem, NULL))
goto port_found;
} else {
- link->io.NumPorts1 = 18;
+ link->resource[0]->end = 18;
/* We do 2 passes here: The first one uses the regular mapping and
* the second tries again, thereby considering that the 32 ports are
* mirrored every 32 bytes. Actually we use a mirrored port for
@@ -841,14 +839,15 @@ xirc2ps_config(struct pcmcia_device * link)
}
printk(KNOT_XIRC "no ports available\n");
} else {
- link->io.NumPorts1 = 16;
+ link->io_lines = 10;
+ link->resource[0]->end = 16;
for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
- link->io.BasePort1 = ioaddr;
- if (!(err=pcmcia_request_io(link, &link->io)))
+ link->resource[0]->start = ioaddr;
+ if (!(err = pcmcia_request_io(link)))
goto port_found;
}
- link->io.BasePort1 = 0; /* let CS decide */
- if ((err=pcmcia_request_io(link, &link->io)))
+ link->resource[0]->start = 0; /* let CS decide */
+ if ((err = pcmcia_request_io(link)))
goto config_error;
}
port_found:
@@ -870,24 +869,21 @@ xirc2ps_config(struct pcmcia_device * link)
goto config_error;
if (local->dingo) {
- conf_reg_t reg;
win_req_t req;
- memreq_t mem;
/* Reset the modem's BAR to the correct value
* This is necessary because in the RequestConfiguration call,
* the base address of the ethernet port (BasePort1) is written
* to the BAR registers of the modem.
*/
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_IOBASE_0;
- reg.Value = link->io.BasePort2 & 0xff;
- if ((err = pcmcia_access_configuration_register(link, &reg)))
+ err = pcmcia_write_config_byte(link, CISREG_IOBASE_0, (u8)
+ link->resource[1]->start & 0xff);
+ if (err)
goto config_error;
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_IOBASE_1;
- reg.Value = (link->io.BasePort2 >> 8) & 0xff;
- if ((err = pcmcia_access_configuration_register(link, &reg)))
+
+ err = pcmcia_write_config_byte(link, CISREG_IOBASE_1,
+ (link->resource[1]->start >> 8) & 0xff);
+ if (err)
goto config_error;
/* There is no config entry for the Ethernet part which
@@ -901,16 +897,14 @@ xirc2ps_config(struct pcmcia_device * link)
goto config_error;
local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
- mem.CardOffset = 0x0;
- mem.Page = 0;
- if ((err = pcmcia_map_mem_page(link, link->win, &mem)))
+ if ((err = pcmcia_map_mem_page(link, link->win, 0)))
goto config_error;
/* Setup the CCRs; there are no infos in the CIS about the Ethernet
* part.
*/
writeb(0x47, local->dingo_ccr + CISREG_COR);
- ioaddr = link->io.BasePort1;
+ ioaddr = link->resource[0]->start;
writeb(ioaddr & 0xff , local->dingo_ccr + CISREG_IOBASE_0);
writeb((ioaddr >> 8)&0xff , local->dingo_ccr + CISREG_IOBASE_1);
@@ -957,7 +951,7 @@ xirc2ps_config(struct pcmcia_device * link)
/* we can now register the device with the net subsystem */
dev->irq = link->irq;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
if (local->dingo)
do_reset(dev, 1); /* a kludge to make the cem56 work */
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 6c2e8fa0ca3..af50a530dae 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -108,9 +108,9 @@ static void ppp_async_process(unsigned long arg);
static void async_lcp_peek(struct asyncppp *ap, unsigned char *data,
int len, int inbound);
-static struct ppp_channel_ops async_ops = {
- ppp_async_send,
- ppp_async_ioctl
+static const struct ppp_channel_ops async_ops = {
+ .start_xmit = ppp_async_send,
+ .ioctl = ppp_async_ioctl,
};
/*
diff --git a/drivers/net/ppp_synctty.c b/drivers/net/ppp_synctty.c
index 52938da1e54..4c95ec3fb8d 100644
--- a/drivers/net/ppp_synctty.c
+++ b/drivers/net/ppp_synctty.c
@@ -97,9 +97,9 @@ static void ppp_sync_flush_output(struct syncppp *ap);
static void ppp_sync_input(struct syncppp *ap, const unsigned char *buf,
char *flags, int count);
-static struct ppp_channel_ops sync_ops = {
- ppp_sync_send,
- ppp_sync_ioctl
+static const struct ppp_channel_ops sync_ops = {
+ .start_xmit = ppp_sync_send,
+ .ioctl = ppp_sync_ioctl,
};
/*
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c
index 344ef330e12..c07de359dc0 100644
--- a/drivers/net/pppoe.c
+++ b/drivers/net/pppoe.c
@@ -92,7 +92,7 @@
static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
static const struct proto_ops pppoe_ops;
-static struct ppp_channel_ops pppoe_chan_ops;
+static const struct ppp_channel_ops pppoe_chan_ops;
/* per-net private data for this module */
static int pppoe_net_id __read_mostly;
@@ -963,7 +963,7 @@ static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb)
return __pppoe_xmit(sk, skb);
}
-static struct ppp_channel_ops pppoe_chan_ops = {
+static const struct ppp_channel_ops pppoe_chan_ops = {
.start_xmit = pppoe_xmit,
};
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 35540411990..078bbf4e6f1 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3219,11 +3219,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
- if (pci_dev_run_wake(pdev)) {
- pm_runtime_set_active(&pdev->dev);
- pm_runtime_enable(&pdev->dev);
- }
- pm_runtime_idle(&pdev->dev);
+ if (pci_dev_run_wake(pdev))
+ pm_runtime_put_noidle(&pdev->dev);
out:
return rc;
@@ -3246,17 +3243,12 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
- pm_runtime_get_sync(&pdev->dev);
-
flush_scheduled_work();
unregister_netdev(dev);
- if (pci_dev_run_wake(pdev)) {
- pm_runtime_disable(&pdev->dev);
- pm_runtime_set_suspended(&pdev->dev);
- }
- pm_runtime_put_noidle(&pdev->dev);
+ if (pci_dev_run_wake(pdev))
+ pm_runtime_get_noresume(&pdev->dev);
/* restore original MAC address */
rtl_rar_set(tp, dev->perm_addr);
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 8d2772cc42f..ee747919a76 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -83,43 +83,6 @@ static inline void SMC_outw(u16 val, void __iomem *ioaddr, int reg)
}
}
-#elif defined(CONFIG_REDWOOD_5) || defined(CONFIG_REDWOOD_6)
-
-/* We can only do 16-bit reads and writes in the static memory space. */
-#define SMC_CAN_USE_8BIT 0
-#define SMC_CAN_USE_16BIT 1
-#define SMC_CAN_USE_32BIT 0
-#define SMC_NOWAIT 1
-
-#define SMC_IO_SHIFT 0
-
-#define SMC_inw(a, r) in_be16((volatile u16 *)((a) + (r)))
-#define SMC_outw(v, a, r) out_be16((volatile u16 *)((a) + (r)), v)
-#define SMC_insw(a, r, p, l) \
- do { \
- unsigned long __port = (a) + (r); \
- u16 *__p = (u16 *)(p); \
- int __l = (l); \
- insw(__port, __p, __l); \
- while (__l > 0) { \
- *__p = swab16(*__p); \
- __p++; \
- __l--; \
- } \
- } while (0)
-#define SMC_outsw(a, r, p, l) \
- do { \
- unsigned long __port = (a) + (r); \
- u16 *__p = (u16 *)(p); \
- int __l = (l); \
- while (__l > 0) { \
- /* Believe it or not, the swab isn't needed. */ \
- outw( /* swab16 */ (*__p++), __port); \
- __l--; \
- } \
- } while (0)
-#define SMC_IRQ_FLAGS (0)
-
#elif defined(CONFIG_SA1100_PLEB)
/* We can only do 16-bit reads and writes in the static memory space. */
#define SMC_CAN_USE_8BIT 1
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index 367e96f317d..09c071bd6ad 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -1201,7 +1201,7 @@ static int __devinit bigmac_ether_init(struct of_device *op,
dev->watchdog_timeo = 5*HZ;
/* Finish net device registration. */
- dev->irq = bp->bigmac_op->irqs[0];
+ dev->irq = bp->bigmac_op->archdata.irqs[0];
dev->dma = 0;
if (register_netdev(dev)) {
@@ -1301,12 +1301,12 @@ static struct of_platform_driver bigmac_sbus_driver = {
static int __init bigmac_init(void)
{
- return of_register_driver(&bigmac_sbus_driver, &of_bus_type);
+ return of_register_platform_driver(&bigmac_sbus_driver);
}
static void __exit bigmac_exit(void)
{
- of_unregister_driver(&bigmac_sbus_driver);
+ of_unregister_platform_driver(&bigmac_sbus_driver);
}
module_init(bigmac_init);
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 3d9650b8d38..eec443f6407 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2561,7 +2561,7 @@ static int __init quattro_sbus_register_irqs(void)
if (skip)
continue;
- err = request_irq(op->irqs[0],
+ err = request_irq(op->archdata.irqs[0],
quattro_sbus_interrupt,
IRQF_SHARED, "Quattro",
qp);
@@ -2590,7 +2590,7 @@ static void quattro_sbus_free_irqs(void)
if (skip)
continue;
- free_irq(op->irqs[0], qp);
+ free_irq(op->archdata.irqs[0], qp);
}
}
#endif /* CONFIG_SBUS */
@@ -2790,7 +2790,7 @@ static int __devinit happy_meal_sbus_probe_one(struct of_device *op, int is_qfe)
/* Happy Meal can do it all... */
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
- dev->irq = op->irqs[0];
+ dev->irq = op->archdata.irqs[0];
#if defined(CONFIG_SBUS) && defined(CONFIG_PCI)
/* Hook up SBUS register/descriptor accessors. */
@@ -3304,7 +3304,7 @@ static int __init happy_meal_sbus_init(void)
{
int err;
- err = of_register_driver(&hme_sbus_driver, &of_bus_type);
+ err = of_register_platform_driver(&hme_sbus_driver);
if (!err)
err = quattro_sbus_register_irqs();
@@ -3313,7 +3313,7 @@ static int __init happy_meal_sbus_init(void)
static void happy_meal_sbus_exit(void)
{
- of_unregister_driver(&hme_sbus_driver);
+ of_unregister_platform_driver(&hme_sbus_driver);
quattro_sbus_free_irqs();
while (qfe_sbus_list) {
diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c
index 7d9c33dd9d1..ee364fa7563 100644
--- a/drivers/net/sunlance.c
+++ b/drivers/net/sunlance.c
@@ -1474,7 +1474,7 @@ no_link_test:
dev->ethtool_ops = &sparc_lance_ethtool_ops;
dev->netdev_ops = &sparc_lance_ops;
- dev->irq = op->irqs[0];
+ dev->irq = op->archdata.irqs[0];
/* We cannot sleep if the chip is busy during a
* multicast list update event, because such events
@@ -1558,12 +1558,12 @@ static struct of_platform_driver sunlance_sbus_driver = {
/* Find all the lance cards on the system and initialize them */
static int __init sparc_lance_init(void)
{
- return of_register_driver(&sunlance_sbus_driver, &of_bus_type);
+ return of_register_platform_driver(&sunlance_sbus_driver);
}
static void __exit sparc_lance_exit(void)
{
- of_unregister_driver(&sunlance_sbus_driver);
+ of_unregister_platform_driver(&sunlance_sbus_driver);
}
module_init(sparc_lance_init);
diff --git a/drivers/net/sunqe.c b/drivers/net/sunqe.c
index 72b579c8d81..5f84a5daded 100644
--- a/drivers/net/sunqe.c
+++ b/drivers/net/sunqe.c
@@ -803,7 +803,7 @@ static struct sunqec * __devinit get_qec(struct of_device *child)
qec_init_once(qecp, op);
- if (request_irq(op->irqs[0], qec_interrupt,
+ if (request_irq(op->archdata.irqs[0], qec_interrupt,
IRQF_SHARED, "qec", (void *) qecp)) {
printk(KERN_ERR "qec: Can't register irq.\n");
goto fail;
@@ -901,7 +901,7 @@ static int __devinit qec_ether_init(struct of_device *op)
SET_NETDEV_DEV(dev, &op->dev);
dev->watchdog_timeo = 5*HZ;
- dev->irq = op->irqs[0];
+ dev->irq = op->archdata.irqs[0];
dev->dma = 0;
dev->ethtool_ops = &qe_ethtool_ops;
dev->netdev_ops = &qec_ops;
@@ -988,18 +988,18 @@ static struct of_platform_driver qec_sbus_driver = {
static int __init qec_init(void)
{
- return of_register_driver(&qec_sbus_driver, &of_bus_type);
+ return of_register_platform_driver(&qec_sbus_driver);
}
static void __exit qec_exit(void)
{
- of_unregister_driver(&qec_sbus_driver);
+ of_unregister_platform_driver(&qec_sbus_driver);
while (root_qec_dev) {
struct sunqec *next = root_qec_dev->next_module;
struct of_device *op = root_qec_dev->op;
- free_irq(op->irqs[0], (void *) root_qec_dev);
+ free_irq(op->archdata.irqs[0], (void *) root_qec_dev);
of_iounmap(&op->resource[0], root_qec_dev->gregs,
GLOB_REG_SIZE);
kfree(root_qec_dev);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 3b03794ac3f..7f62e2dea28 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1457,7 +1457,6 @@ int usbnet_resume (struct usb_interface *intf)
spin_lock_irq(&dev->txq.lock);
while ((res = usb_get_from_anchor(&dev->deferred))) {
- printk(KERN_INFO"%s has delayed data\n", __func__);
skb = (struct sk_buff *)res->context;
retval = usb_submit_urb(res, GFP_ATOMIC);
if (retval < 0) {
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 42dffd3e579..fd69095ef6e 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -2763,12 +2763,12 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
vptr->dev = dev;
- dev->irq = pdev->irq;
-
ret = pci_enable_device(pdev);
if (ret < 0)
goto err_free_dev;
+ dev->irq = pdev->irq;
+
ret = velocity_get_pci_info(vptr, pdev);
if (ret < 0) {
/* error message already printed */
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index bb6b67f6b0c..4598e9d2608 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -705,6 +705,19 @@ static int virtnet_close(struct net_device *dev)
return 0;
}
+static void virtnet_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *drvinfo)
+{
+ struct virtnet_info *vi = netdev_priv(dev);
+ struct virtio_device *vdev = vi->vdev;
+
+ strncpy(drvinfo->driver, KBUILD_MODNAME, ARRAY_SIZE(drvinfo->driver));
+ strncpy(drvinfo->version, "N/A", ARRAY_SIZE(drvinfo->version));
+ strncpy(drvinfo->fw_version, "N/A", ARRAY_SIZE(drvinfo->fw_version));
+ strncpy(drvinfo->bus_info, dev_name(&vdev->dev),
+ ARRAY_SIZE(drvinfo->bus_info));
+}
+
static int virtnet_set_tx_csum(struct net_device *dev, u32 data)
{
struct virtnet_info *vi = netdev_priv(dev);
@@ -817,6 +830,7 @@ static void virtnet_vlan_rx_kill_vid(struct net_device *dev, u16 vid)
}
static const struct ethtool_ops virtnet_ethtool_ops = {
+ .get_drvinfo = virtnet_get_drvinfo,
.set_tx_csum = virtnet_set_tx_csum,
.set_sg = ethtool_op_set_sg,
.set_tso = ethtool_op_set_tso,
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index 33bdc6a84e8..9a121a5b787 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -32,7 +32,6 @@
#include <linux/timer.h>
#include <linux/netdevice.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -155,8 +154,6 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
unsigned int vcc,
void *priv_data)
{
- win_req_t *req = priv_data;
-
if (cfg->index == 0)
return -ENODEV;
@@ -176,52 +173,25 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
- p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.BasePort1 = io->win[0].base;
- p_dev->io.NumPorts1 = io->win[0].len;
+ p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ p_dev->resource[0]->flags |=
+ pcmcia_io_cfg_data_width(io->flags);
+ p_dev->resource[0]->start = io->win[0].base;
+ p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
- p_dev->io.Attributes2 = p_dev->io.Attributes1;
- p_dev->io.BasePort2 = io->win[1].base;
- p_dev->io.NumPorts2 = io->win[1].len;
+ p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+ p_dev->resource[1]->start = io->win[1].base;
+ p_dev->resource[1]->end = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+ if (pcmcia_request_io(p_dev) != 0)
return -ENODEV;
- /*
- Now set up a common memory window, if needed. There is room
- in the struct pcmcia_device structure for one memory window handle,
- but if the base addresses need to be saved, or if multiple
- windows are needed, the info should go in the private data
- structure for this device.
-
- Note that the memory window base is a physical address, and
- needs to be mapped to virtual space with ioremap() before it
- is used.
- */
- if ((cfg->mem.nwin > 0) || (dflt->mem.nwin > 0)) {
- cistpl_mem_t *mem = (cfg->mem.nwin) ? &cfg->mem : &dflt->mem;
- memreq_t map;
- req->Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
- req->Base = mem->win[0].host_addr;
- req->Size = mem->win[0].len;
- req->AccessSpeed = 0;
- if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
- return -ENODEV;
- map.Page = 0;
- map.CardOffset = mem->win[0].card_addr;
- if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
- return -ENODEV;
- }
/* If we got this far, we're cool! */
return 0;
}
@@ -230,17 +200,12 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
static int airo_config(struct pcmcia_device *link)
{
local_info_t *dev;
- win_req_t *req;
int ret;
dev = link->priv;
dev_dbg(&link->dev, "airo_config\n");
- req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
- if (!req)
- return -ENOMEM;
-
/*
* In this loop, we scan the CIS for configuration table
* entries, each of which describes a valid card
@@ -255,7 +220,7 @@ static int airo_config(struct pcmcia_device *link)
* and most client drivers will only use the CIS to fill in
* implementation-defined details.
*/
- ret = pcmcia_loop_config(link, airo_cs_config_check, req);
+ ret = pcmcia_loop_config(link, airo_cs_config_check, NULL);
if (ret)
goto failed;
@@ -272,7 +237,7 @@ static int airo_config(struct pcmcia_device *link)
goto failed;
((local_info_t *)link->priv)->eth_dev =
init_airo_card(link->irq,
- link->io.BasePort1, 1, &link->dev);
+ link->resource[0]->start, 1, &link->dev);
if (!((local_info_t *)link->priv)->eth_dev)
goto failed;
@@ -282,22 +247,15 @@ static int airo_config(struct pcmcia_device *link)
if (link->conf.Vpp)
printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
printk(", irq %d", link->irq);
- if (link->io.NumPorts1)
- printk(", io 0x%04x-0x%04x", link->io.BasePort1,
- link->io.BasePort1+link->io.NumPorts1-1);
- if (link->io.NumPorts2)
- printk(" & 0x%04x-0x%04x", link->io.BasePort2,
- link->io.BasePort2+link->io.NumPorts2-1);
- if (link->win)
- printk(", mem 0x%06lx-0x%06lx", req->Base,
- req->Base+req->Size-1);
+ if (link->resource[0])
+ printk(" & %pR", link->resource[0]);
+ if (link->resource[1])
+ printk(" & %pR", link->resource[1]);
printk("\n");
- kfree(req);
return 0;
failed:
airo_release(link);
- kfree(req);
return -ENODEV;
} /* airo_config */
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index dabafb874c3..fe7418aefc4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -63,6 +63,7 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah,
u8 rxchainmask,
struct ath9k_cal_list *currCal)
{
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
bool iscaldone = false;
if (currCal->calState == CAL_RUNNING) {
@@ -81,14 +82,14 @@ static bool ar9002_hw_per_calibration(struct ath_hw *ah,
}
currCal->calData->calPostProc(ah, numChains);
- ichan->CalValid |= currCal->calData->calType;
+ caldata->CalValid |= currCal->calData->calType;
currCal->calState = CAL_DONE;
iscaldone = true;
} else {
ar9002_hw_setup_calibration(ah, currCal);
}
}
- } else if (!(ichan->CalValid & currCal->calData->calType)) {
+ } else if (!(caldata->CalValid & currCal->calData->calType)) {
ath9k_hw_reset_calibration(ah, currCal);
}
@@ -686,8 +687,13 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
{
bool iscaldone = true;
struct ath9k_cal_list *currCal = ah->cal_list_curr;
+ bool nfcal, nfcal_pending = false;
- if (currCal &&
+ nfcal = !!(REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF);
+ if (ah->caldata)
+ nfcal_pending = ah->caldata->nfcal_pending;
+
+ if (currCal && !nfcal &&
(currCal->calState == CAL_RUNNING ||
currCal->calState == CAL_WAITING)) {
iscaldone = ar9002_hw_per_calibration(ah, chan,
@@ -703,7 +709,7 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
}
/* Do NF cal only at longer intervals */
- if (longcal) {
+ if (longcal || nfcal_pending) {
/* Do periodic PAOffset Cal */
ar9002_hw_pa_cal(ah, false);
ar9002_hw_olc_temp_compensation(ah);
@@ -712,16 +718,18 @@ static bool ar9002_hw_calibrate(struct ath_hw *ah,
* Get the value from the previous NF cal and update
* history buffer.
*/
- ath9k_hw_getnf(ah, chan);
-
- /*
- * Load the NF from history buffer of the current channel.
- * NF is slow time-variant, so it is OK to use a historical
- * value.
- */
- ath9k_hw_loadnf(ah, ah->curchan);
+ if (ath9k_hw_getnf(ah, chan)) {
+ /*
+ * Load the NF from history buffer of the current
+ * channel.
+ * NF is slow time-variant, so it is OK to use a
+ * historical value.
+ */
+ ath9k_hw_loadnf(ah, ah->curchan);
+ }
- ath9k_hw_start_nfcal(ah);
+ if (longcal)
+ ath9k_hw_start_nfcal(ah, false);
}
return iscaldone;
@@ -869,8 +877,10 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
ar9002_hw_pa_cal(ah, true);
/* Do NF Calibration after DC offset and other calibrations */
- REG_WRITE(ah, AR_PHY_AGC_CONTROL,
- REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF);
+ ath9k_hw_start_nfcal(ah, true);
+
+ if (ah->caldata)
+ ah->caldata->nfcal_pending = true;
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
@@ -901,7 +911,8 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
}
- chan->CalValid = 0;
+ if (ah->caldata)
+ ah->caldata->CalValid = 0;
return true;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 5a065039913..4674ea8c9c9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -68,6 +68,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah,
u8 rxchainmask,
struct ath9k_cal_list *currCal)
{
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
/* Cal is assumed not done until explicitly set below */
bool iscaldone = false;
@@ -95,7 +96,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah,
currCal->calData->calPostProc(ah, numChains);
/* Calibration has finished. */
- ichan->CalValid |= currCal->calData->calType;
+ caldata->CalValid |= currCal->calData->calType;
currCal->calState = CAL_DONE;
iscaldone = true;
} else {
@@ -106,7 +107,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah,
ar9003_hw_setup_calibration(ah, currCal);
}
}
- } else if (!(ichan->CalValid & currCal->calData->calType)) {
+ } else if (!(caldata->CalValid & currCal->calData->calType)) {
/* If current cal is marked invalid in channel, kick it off */
ath9k_hw_reset_calibration(ah, currCal);
}
@@ -149,6 +150,12 @@ static bool ar9003_hw_calibrate(struct ath_hw *ah,
/* Do NF cal only at longer intervals */
if (longcal) {
/*
+ * Get the value from the previous NF cal and update
+ * history buffer.
+ */
+ ath9k_hw_getnf(ah, chan);
+
+ /*
* Load the NF from history buffer of the current channel.
* NF is slow time-variant, so it is OK to use a historical
* value.
@@ -156,7 +163,7 @@ static bool ar9003_hw_calibrate(struct ath_hw *ah,
ath9k_hw_loadnf(ah, ah->curchan);
/* start NF calibration, without updating BB NF register */
- ath9k_hw_start_nfcal(ah);
+ ath9k_hw_start_nfcal(ah, false);
}
return iscaldone;
@@ -762,6 +769,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
/* Revert chainmasks to their original values before NF cal */
ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
+ ath9k_hw_start_nfcal(ah, true);
+
/* Initialize list pointers */
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
@@ -785,7 +794,8 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah,
if (ah->cal_list_curr)
ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
- chan->CalValid = 0;
+ if (ah->caldata)
+ ah->caldata->CalValid = 0;
return true;
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index ace8d2678b1..b883b174385 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -41,6 +41,20 @@
#define LE16(x) __constant_cpu_to_le16(x)
#define LE32(x) __constant_cpu_to_le32(x)
+/* Local defines to distinguish between extension and control CTL's */
+#define EXT_ADDITIVE (0x8000)
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
+#define REDUCE_SCALED_POWER_BY_TWO_CHAIN 6 /* 10*log10(2)*2 */
+#define REDUCE_SCALED_POWER_BY_THREE_CHAIN 9 /* 10*log10(3)*2 */
+#define PWRINCR_3_TO_1_CHAIN 9 /* 10*log(3)*2 */
+#define PWRINCR_3_TO_2_CHAIN 3 /* floor(10*log(3/2)*2) */
+#define PWRINCR_2_TO_1_CHAIN 6 /* 10*log(2)*2 */
+
+#define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */
+#define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */
+
static const struct ar9300_eeprom ar9300_default = {
.eepromVersion = 2,
.templateVersion = 2,
@@ -609,6 +623,14 @@ static const struct ar9300_eeprom ar9300_default = {
}
};
+static u16 ath9k_hw_fbin2freq(u8 fbin, bool is2GHz)
+{
+ if (fbin == AR9300_BCHAN_UNUSED)
+ return fbin;
+
+ return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
+}
+
static int ath9k_hw_ar9300_check_eeprom(struct ath_hw *ah)
{
return 0;
@@ -1417,9 +1439,9 @@ static int ar9003_hw_tx_power_regwrite(struct ath_hw *ah, u8 * pPwrArray)
#undef POW_SM
}
-static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq)
+static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq,
+ u8 *targetPowerValT2)
{
- u8 targetPowerValT2[ar9300RateSize];
/* XXX: hard code for now, need to get from eeprom struct */
u8 ht40PowerIncForPdadc = 0;
bool is2GHz = false;
@@ -1553,9 +1575,6 @@ static void ar9003_hw_set_target_power_eeprom(struct ath_hw *ah, u16 freq)
"TPC[%02d] 0x%08x\n", i, targetPowerValT2[i]);
i++;
}
-
- /* Write target power array to registers */
- ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
}
static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
@@ -1799,14 +1818,369 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
return 0;
}
+static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep,
+ int idx,
+ int edge,
+ bool is2GHz)
+{
+ struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
+ struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
+
+ if (is2GHz)
+ return ctl_2g[idx].ctlEdges[edge].tPower;
+ else
+ return ctl_5g[idx].ctlEdges[edge].tPower;
+}
+
+static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep,
+ int idx,
+ unsigned int edge,
+ u16 freq,
+ bool is2GHz)
+{
+ struct cal_ctl_data_2g *ctl_2g = eep->ctlPowerData_2G;
+ struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G;
+
+ u8 *ctl_freqbin = is2GHz ?
+ &eep->ctl_freqbin_2G[idx][0] :
+ &eep->ctl_freqbin_5G[idx][0];
+
+ if (is2GHz) {
+ if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq &&
+ ctl_2g[idx].ctlEdges[edge - 1].flag)
+ return ctl_2g[idx].ctlEdges[edge - 1].tPower;
+ } else {
+ if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq &&
+ ctl_5g[idx].ctlEdges[edge - 1].flag)
+ return ctl_5g[idx].ctlEdges[edge - 1].tPower;
+ }
+
+ return AR9300_MAX_RATE_POWER;
+}
+
+/*
+ * Find the maximum conformance test limit for the given channel and CTL info
+ */
+static u16 ar9003_hw_get_max_edge_power(struct ar9300_eeprom *eep,
+ u16 freq, int idx, bool is2GHz)
+{
+ u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
+ u8 *ctl_freqbin = is2GHz ?
+ &eep->ctl_freqbin_2G[idx][0] :
+ &eep->ctl_freqbin_5G[idx][0];
+ u16 num_edges = is2GHz ?
+ AR9300_NUM_BAND_EDGES_2G : AR9300_NUM_BAND_EDGES_5G;
+ unsigned int edge;
+
+ /* Get the edge power */
+ for (edge = 0;
+ (edge < num_edges) && (ctl_freqbin[edge] != AR9300_BCHAN_UNUSED);
+ edge++) {
+ /*
+ * If there's an exact channel match or an inband flag set
+ * on the lower channel use the given rdEdgePower
+ */
+ if (freq == ath9k_hw_fbin2freq(ctl_freqbin[edge], is2GHz)) {
+ twiceMaxEdgePower =
+ ar9003_hw_get_direct_edge_power(eep, idx,
+ edge, is2GHz);
+ break;
+ } else if ((edge > 0) &&
+ (freq < ath9k_hw_fbin2freq(ctl_freqbin[edge],
+ is2GHz))) {
+ twiceMaxEdgePower =
+ ar9003_hw_get_indirect_edge_power(eep, idx,
+ edge, freq,
+ is2GHz);
+ /*
+ * Leave loop - no more affecting edges possible in
+ * this monotonic increasing list
+ */
+ break;
+ }
+ }
+ return twiceMaxEdgePower;
+}
+
+static void ar9003_hw_set_power_per_rate_table(struct ath_hw *ah,
+ struct ath9k_channel *chan,
+ u8 *pPwrArray, u16 cfgCtl,
+ u8 twiceAntennaReduction,
+ u8 twiceMaxRegulatoryPower,
+ u16 powerLimit)
+{
+ struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ar9300_eeprom *pEepData = &ah->eeprom.ar9300_eep;
+ u16 twiceMaxEdgePower = AR9300_MAX_RATE_POWER;
+ static const u16 tpScaleReductionTable[5] = {
+ 0, 3, 6, 9, AR9300_MAX_RATE_POWER
+ };
+ int i;
+ int16_t twiceLargestAntenna;
+ u16 scaledPower = 0, minCtlPower, maxRegAllowedPower;
+ u16 ctlModesFor11a[] = {
+ CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40
+ };
+ u16 ctlModesFor11g[] = {
+ CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT,
+ CTL_11G_EXT, CTL_2GHT40
+ };
+ u16 numCtlModes, *pCtlMode, ctlMode, freq;
+ struct chan_centers centers;
+ u8 *ctlIndex;
+ u8 ctlNum;
+ u16 twiceMinEdgePower;
+ bool is2ghz = IS_CHAN_2GHZ(chan);
+
+ ath9k_hw_get_channel_centers(ah, chan, &centers);
+
+ /* Compute TxPower reduction due to Antenna Gain */
+ if (is2ghz)
+ twiceLargestAntenna = pEepData->modalHeader2G.antennaGain;
+ else
+ twiceLargestAntenna = pEepData->modalHeader5G.antennaGain;
+
+ twiceLargestAntenna = (int16_t)min((twiceAntennaReduction) -
+ twiceLargestAntenna, 0);
+
+ /*
+ * scaledPower is the minimum of the user input power level
+ * and the regulatory allowed power level
+ */
+ maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
+
+ if (regulatory->tp_scale != ATH9K_TP_SCALE_MAX) {
+ maxRegAllowedPower -=
+ (tpScaleReductionTable[(regulatory->tp_scale)] * 2);
+ }
+
+ scaledPower = min(powerLimit, maxRegAllowedPower);
+
+ /*
+ * Reduce scaled Power by number of chains active to get
+ * to per chain tx power level
+ */
+ switch (ar5416_get_ntxchains(ah->txchainmask)) {
+ case 1:
+ break;
+ case 2:
+ scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN;
+ break;
+ case 3:
+ scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN;
+ break;
+ }
+
+ scaledPower = max((u16)0, scaledPower);
+
+ /*
+ * Get target powers from EEPROM - our baseline for TX Power
+ */
+ if (is2ghz) {
+ /* Setup for CTL modes */
+ /* CTL_11B, CTL_11G, CTL_2GHT20 */
+ numCtlModes =
+ ARRAY_SIZE(ctlModesFor11g) -
+ SUB_NUM_CTL_MODES_AT_2G_40;
+ pCtlMode = ctlModesFor11g;
+ if (IS_CHAN_HT40(chan))
+ /* All 2G CTL's */
+ numCtlModes = ARRAY_SIZE(ctlModesFor11g);
+ } else {
+ /* Setup for CTL modes */
+ /* CTL_11A, CTL_5GHT20 */
+ numCtlModes = ARRAY_SIZE(ctlModesFor11a) -
+ SUB_NUM_CTL_MODES_AT_5G_40;
+ pCtlMode = ctlModesFor11a;
+ if (IS_CHAN_HT40(chan))
+ /* All 5G CTL's */
+ numCtlModes = ARRAY_SIZE(ctlModesFor11a);
+ }
+
+ /*
+ * For MIMO, need to apply regulatory caps individually across
+ * dynamically running modes: CCK, OFDM, HT20, HT40
+ *
+ * The outer loop walks through each possible applicable runtime mode.
+ * The inner loop walks through each ctlIndex entry in EEPROM.
+ * The ctl value is encoded as [7:4] == test group, [3:0] == test mode.
+ */
+ for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
+ bool isHt40CtlMode = (pCtlMode[ctlMode] == CTL_5GHT40) ||
+ (pCtlMode[ctlMode] == CTL_2GHT40);
+ if (isHt40CtlMode)
+ freq = centers.synth_center;
+ else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
+ freq = centers.ext_center;
+ else
+ freq = centers.ctl_center;
+
+ ath_print(common, ATH_DBG_REGULATORY,
+ "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
+ "EXT_ADDITIVE %d\n",
+ ctlMode, numCtlModes, isHt40CtlMode,
+ (pCtlMode[ctlMode] & EXT_ADDITIVE));
+
+ /* walk through each CTL index stored in EEPROM */
+ if (is2ghz) {
+ ctlIndex = pEepData->ctlIndex_2G;
+ ctlNum = AR9300_NUM_CTLS_2G;
+ } else {
+ ctlIndex = pEepData->ctlIndex_5G;
+ ctlNum = AR9300_NUM_CTLS_5G;
+ }
+
+ for (i = 0; (i < ctlNum) && ctlIndex[i]; i++) {
+ ath_print(common, ATH_DBG_REGULATORY,
+ "LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
+ "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
+ "chan %dn",
+ i, cfgCtl, pCtlMode[ctlMode], ctlIndex[i],
+ chan->channel);
+
+ /*
+ * compare test group from regulatory
+ * channel list with test mode from pCtlMode
+ * list
+ */
+ if ((((cfgCtl & ~CTL_MODE_M) |
+ (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ ctlIndex[i]) ||
+ (((cfgCtl & ~CTL_MODE_M) |
+ (pCtlMode[ctlMode] & CTL_MODE_M)) ==
+ ((ctlIndex[i] & CTL_MODE_M) |
+ SD_NO_CTL))) {
+ twiceMinEdgePower =
+ ar9003_hw_get_max_edge_power(pEepData,
+ freq, i,
+ is2ghz);
+
+ if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL)
+ /*
+ * Find the minimum of all CTL
+ * edge powers that apply to
+ * this channel
+ */
+ twiceMaxEdgePower =
+ min(twiceMaxEdgePower,
+ twiceMinEdgePower);
+ else {
+ /* specific */
+ twiceMaxEdgePower =
+ twiceMinEdgePower;
+ break;
+ }
+ }
+ }
+
+ minCtlPower = (u8)min(twiceMaxEdgePower, scaledPower);
+
+ ath_print(common, ATH_DBG_REGULATORY,
+ "SEL-Min ctlMode %d pCtlMode %d 2xMaxEdge %d "
+ "sP %d minCtlPwr %d\n",
+ ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
+ scaledPower, minCtlPower);
+
+ /* Apply ctl mode to correct target power set */
+ switch (pCtlMode[ctlMode]) {
+ case CTL_11B:
+ for (i = ALL_TARGET_LEGACY_1L_5L;
+ i <= ALL_TARGET_LEGACY_11S; i++)
+ pPwrArray[i] =
+ (u8)min((u16)pPwrArray[i],
+ minCtlPower);
+ break;
+ case CTL_11A:
+ case CTL_11G:
+ for (i = ALL_TARGET_LEGACY_6_24;
+ i <= ALL_TARGET_LEGACY_54; i++)
+ pPwrArray[i] =
+ (u8)min((u16)pPwrArray[i],
+ minCtlPower);
+ break;
+ case CTL_5GHT20:
+ case CTL_2GHT20:
+ for (i = ALL_TARGET_HT20_0_8_16;
+ i <= ALL_TARGET_HT20_21; i++)
+ pPwrArray[i] =
+ (u8)min((u16)pPwrArray[i],
+ minCtlPower);
+ pPwrArray[ALL_TARGET_HT20_22] =
+ (u8)min((u16)pPwrArray[ALL_TARGET_HT20_22],
+ minCtlPower);
+ pPwrArray[ALL_TARGET_HT20_23] =
+ (u8)min((u16)pPwrArray[ALL_TARGET_HT20_23],
+ minCtlPower);
+ break;
+ case CTL_5GHT40:
+ case CTL_2GHT40:
+ for (i = ALL_TARGET_HT40_0_8_16;
+ i <= ALL_TARGET_HT40_23; i++)
+ pPwrArray[i] =
+ (u8)min((u16)pPwrArray[i],
+ minCtlPower);
+ break;
+ default:
+ break;
+ }
+ } /* end ctl mode checking */
+}
+
static void ath9k_hw_ar9300_set_txpower(struct ath_hw *ah,
struct ath9k_channel *chan, u16 cfgCtl,
u8 twiceAntennaReduction,
u8 twiceMaxRegulatoryPower,
u8 powerLimit)
{
- ah->txpower_limit = powerLimit;
- ar9003_hw_set_target_power_eeprom(ah, chan->channel);
+ struct ath_common *common = ath9k_hw_common(ah);
+ u8 targetPowerValT2[ar9300RateSize];
+ unsigned int i = 0;
+
+ ar9003_hw_set_target_power_eeprom(ah, chan->channel, targetPowerValT2);
+ ar9003_hw_set_power_per_rate_table(ah, chan,
+ targetPowerValT2, cfgCtl,
+ twiceAntennaReduction,
+ twiceMaxRegulatoryPower,
+ powerLimit);
+
+ while (i < ar9300RateSize) {
+ ath_print(common, ATH_DBG_EEPROM,
+ "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
+ i++;
+ ath_print(common, ATH_DBG_EEPROM,
+ "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
+ i++;
+ ath_print(common, ATH_DBG_EEPROM,
+ "TPC[%02d] 0x%08x ", i, targetPowerValT2[i]);
+ i++;
+ ath_print(common, ATH_DBG_EEPROM,
+ "TPC[%02d] 0x%08x\n\n", i, targetPowerValT2[i]);
+ i++;
+ }
+
+ /* Write target power array to registers */
+ ar9003_hw_tx_power_regwrite(ah, targetPowerValT2);
+
+ /*
+ * This is the TX power we send back to driver core,
+ * and it can use to pass to userspace to display our
+ * currently configured TX power setting.
+ *
+ * Since power is rate dependent, use one of the indices
+ * from the AR9300_Rates enum to select an entry from
+ * targetPowerValT2[] to report. Currently returns the
+ * power for HT40 MCS 0, HT20 MCS 0, or OFDM 6 Mbps
+ * as CCK power is less interesting (?).
+ */
+ i = ALL_TARGET_LEGACY_6_24; /* legacy */
+ if (IS_CHAN_HT40(chan))
+ i = ALL_TARGET_HT40_0_8_16; /* ht40 */
+ else if (IS_CHAN_HT20(chan))
+ i = ALL_TARGET_HT20_0_8_16; /* ht20 */
+
+ ah->txpower_limit = targetPowerValT2[i];
+
ar9003_hw_calibration_apply(ah, chan->channel);
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
index 49e0c865ce5..7c38229ba67 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
@@ -577,10 +577,11 @@ static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain)
}
void ar9003_paprd_populate_single_table(struct ath_hw *ah,
- struct ath9k_channel *chan, int chain)
+ struct ath9k_hw_cal_data *caldata,
+ int chain)
{
- u32 *paprd_table_val = chan->pa_table[chain];
- u32 small_signal_gain = chan->small_signal_gain[chain];
+ u32 *paprd_table_val = caldata->pa_table[chain];
+ u32 small_signal_gain = caldata->small_signal_gain[chain];
u32 training_power;
u32 reg = 0;
int i;
@@ -654,17 +655,17 @@ int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
}
EXPORT_SYMBOL(ar9003_paprd_setup_gain_table);
-int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan,
- int chain)
+int ar9003_paprd_create_curve(struct ath_hw *ah,
+ struct ath9k_hw_cal_data *caldata, int chain)
{
- u16 *small_signal_gain = &chan->small_signal_gain[chain];
- u32 *pa_table = chan->pa_table[chain];
+ u16 *small_signal_gain = &caldata->small_signal_gain[chain];
+ u32 *pa_table = caldata->pa_table[chain];
u32 *data_L, *data_U;
int i, status = 0;
u32 *buf;
u32 reg;
- memset(chan->pa_table[chain], 0, sizeof(chan->pa_table[chain]));
+ memset(caldata->pa_table[chain], 0, sizeof(caldata->pa_table[chain]));
buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC);
if (!buf)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index a753a431bb1..a491854fa38 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -542,7 +542,11 @@ static void ar9003_hw_prog_ini(struct ath_hw *ah,
u32 reg = INI_RA(iniArr, i, 0);
u32 val = INI_RA(iniArr, i, column);
- REG_WRITE(ah, reg, val);
+ if (reg >= 0x16000 && reg < 0x17000)
+ ath9k_hw_analog_shift_regwrite(ah, reg, val);
+ else
+ REG_WRITE(ah, reg, val);
+
DO_DELAY(regWrites);
}
}
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 998ae2c49ed..07f26ee7a72 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -510,7 +510,7 @@ void ath_deinit_leds(struct ath_softc *sc);
#define SC_OP_BEACONS BIT(1)
#define SC_OP_RXAGGR BIT(2)
#define SC_OP_TXAGGR BIT(3)
-#define SC_OP_FULL_RESET BIT(4)
+#define SC_OP_OFFCHANNEL BIT(4)
#define SC_OP_PREAMBLE_SHORT BIT(5)
#define SC_OP_PROTECT_ENABLE BIT(6)
#define SC_OP_RXFLUSH BIT(7)
@@ -609,6 +609,7 @@ struct ath_softc {
struct ath_wiphy {
struct ath_softc *sc; /* shared for all virtual wiphys */
struct ieee80211_hw *hw;
+ struct ath9k_hw_cal_data caldata;
enum ath_wiphy_state {
ATH_WIPHY_INACTIVE,
ATH_WIPHY_ACTIVE,
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index 139289e4e93..45208690c0e 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -22,23 +22,6 @@
/* We can tune this as we go by monitoring really low values */
#define ATH9K_NF_TOO_LOW -60
-/* AR5416 may return very high value (like -31 dBm), in those cases the nf
- * is incorrect and we should use the static NF value. Later we can try to
- * find out why they are reporting these values */
-
-static bool ath9k_hw_nf_in_range(struct ath_hw *ah, s16 nf)
-{
- if (nf > ATH9K_NF_TOO_LOW) {
- ath_print(ath9k_hw_common(ah), ATH_DBG_CALIBRATE,
- "noise floor value detected (%d) is "
- "lower than what we think is a "
- "reasonable value (%d)\n",
- nf, ATH9K_NF_TOO_LOW);
- return false;
- }
- return true;
-}
-
static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
{
int16_t nfval;
@@ -121,6 +104,19 @@ void ath9k_hw_reset_calibration(struct ath_hw *ah,
ah->cal_samples = 0;
}
+static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
+ struct ath9k_channel *chan)
+{
+ struct ath_nf_limits *limit;
+
+ if (!chan || IS_CHAN_2GHZ(chan))
+ limit = &ah->nf_2g;
+ else
+ limit = &ah->nf_5g;
+
+ return limit->nominal;
+}
+
/* This is done for the currently configured channel */
bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
{
@@ -128,7 +124,7 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
struct ieee80211_conf *conf = &common->hw->conf;
struct ath9k_cal_list *currCal = ah->cal_list_curr;
- if (!ah->curchan)
+ if (!ah->caldata)
return true;
if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
@@ -151,37 +147,55 @@ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
"Resetting Cal %d state for channel %u\n",
currCal->calData->calType, conf->channel->center_freq);
- ah->curchan->CalValid &= ~currCal->calData->calType;
+ ah->caldata->CalValid &= ~currCal->calData->calType;
currCal->calState = CAL_WAITING;
return false;
}
EXPORT_SYMBOL(ath9k_hw_reset_calvalid);
-void ath9k_hw_start_nfcal(struct ath_hw *ah)
+void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update)
{
+ if (ah->caldata)
+ ah->caldata->nfcal_pending = true;
+
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_ENABLE_NF);
- REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
+
+ if (update)
+ REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
+ AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+ else
+ REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
+
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
}
void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
{
- struct ath9k_nfcal_hist *h;
+ struct ath9k_nfcal_hist *h = NULL;
unsigned i, j;
int32_t val;
u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
struct ath_common *common = ath9k_hw_common(ah);
+ s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
- h = ah->nfCalHist;
+ if (ah->caldata)
+ h = ah->caldata->nfCalHist;
for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) {
+ s16 nfval;
+
+ if (h)
+ nfval = h[i].privNF;
+ else
+ nfval = default_nf;
+
val = REG_READ(ah, ah->nf_regs[i]);
val &= 0xFFFFFE00;
- val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
+ val |= (((u32) nfval << 1) & 0x1ff);
REG_WRITE(ah, ah->nf_regs[i], val);
}
}
@@ -277,22 +291,25 @@ static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
}
}
-int16_t ath9k_hw_getnf(struct ath_hw *ah,
- struct ath9k_channel *chan)
+bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
{
struct ath_common *common = ath9k_hw_common(ah);
int16_t nf, nfThresh;
int16_t nfarray[NUM_NF_READINGS] = { 0 };
struct ath9k_nfcal_hist *h;
struct ieee80211_channel *c = chan->chan;
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
+
+ if (!caldata)
+ return false;
chan->channelFlags &= (~CHANNEL_CW_INT);
if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
ath_print(common, ATH_DBG_CALIBRATE,
"NF did not complete in calibration window\n");
nf = 0;
- chan->rawNoiseFloor = nf;
- return chan->rawNoiseFloor;
+ caldata->rawNoiseFloor = nf;
+ return false;
} else {
ath9k_hw_do_getnf(ah, nfarray);
ath9k_hw_nf_sanitize(ah, nfarray);
@@ -307,47 +324,40 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
}
}
- h = ah->nfCalHist;
-
+ h = caldata->nfCalHist;
+ caldata->nfcal_pending = false;
ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
- chan->rawNoiseFloor = h[0].privNF;
-
- return chan->rawNoiseFloor;
+ caldata->rawNoiseFloor = h[0].privNF;
+ return true;
}
-void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
+ struct ath9k_channel *chan)
{
- struct ath_nf_limits *limit;
+ struct ath9k_nfcal_hist *h;
+ s16 default_nf;
int i, j;
- if (!ah->curchan || IS_CHAN_2GHZ(ah->curchan))
- limit = &ah->nf_2g;
- else
- limit = &ah->nf_5g;
+ if (!ah->caldata)
+ return;
+ h = ah->caldata->nfCalHist;
+ default_nf = ath9k_hw_get_default_nf(ah, chan);
for (i = 0; i < NUM_NF_READINGS; i++) {
- ah->nfCalHist[i].currIndex = 0;
- ah->nfCalHist[i].privNF = limit->nominal;
- ah->nfCalHist[i].invalidNFcount =
- AR_PHY_CCA_FILTERWINDOW_LENGTH;
+ h[i].currIndex = 0;
+ h[i].privNF = default_nf;
+ h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH;
for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
- ah->nfCalHist[i].nfCalBuffer[j] = limit->nominal;
+ h[i].nfCalBuffer[j] = default_nf;
}
}
}
s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan)
{
- s16 nf;
-
- if (chan->rawNoiseFloor == 0)
- nf = -96;
- else
- nf = chan->rawNoiseFloor;
-
- if (!ath9k_hw_nf_in_range(ah, nf))
- nf = ATH_DEFAULT_NOISE_FLOOR;
+ if (!ah->caldata || !ah->caldata->rawNoiseFloor)
+ return ath9k_hw_get_default_nf(ah, chan);
- return nf;
+ return ah->caldata->rawNoiseFloor;
}
EXPORT_SYMBOL(ath9k_hw_getchan_noise);
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index cd60d09cdda..0a304b3eeeb 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -108,11 +108,11 @@ struct ath9k_pacal_info{
};
bool ath9k_hw_reset_calvalid(struct ath_hw *ah);
-void ath9k_hw_start_nfcal(struct ath_hw *ah);
+void ath9k_hw_start_nfcal(struct ath_hw *ah, bool update);
void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
-int16_t ath9k_hw_getnf(struct ath_hw *ah,
- struct ath9k_channel *chan);
-void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah);
+bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
+ struct ath9k_channel *chan);
s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan);
void ath9k_hw_reset_calibration(struct ath_hw *ah,
struct ath9k_cal_list *currCal);
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 3756400e6bf..43b9e21bc56 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -353,6 +353,8 @@ struct ath9k_htc_priv {
u16 seq_no;
u32 bmiss_cnt;
+ struct ath9k_hw_cal_data caldata[38];
+
spinlock_t beacon_lock;
bool tx_queues_stop;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index cf9bcc67ade..ebed9d1691a 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -125,6 +125,7 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
struct ieee80211_conf *conf = &common->hw->conf;
bool fastcc = true;
struct ieee80211_channel *channel = hw->conf.channel;
+ struct ath9k_hw_cal_data *caldata;
enum htc_phymode mode;
__be16 htc_mode;
u8 cmd_rsp;
@@ -149,7 +150,8 @@ static int ath9k_htc_set_channel(struct ath9k_htc_priv *priv,
priv->ah->curchan->channel,
channel->center_freq, conf_is_ht(conf), conf_is_ht40(conf));
- ret = ath9k_hw_reset(ah, hchan, fastcc);
+ caldata = &priv->caldata[channel->hw_value];
+ ret = ath9k_hw_reset(ah, hchan, caldata, fastcc);
if (ret) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset channel (%u Mhz) "
@@ -1028,7 +1030,7 @@ static void ath9k_htc_radio_enable(struct ieee80211_hw *hw)
ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
/* Reset the HW */
- ret = ath9k_hw_reset(ah, ah->curchan, false);
+ ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (ret) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d "
@@ -1091,7 +1093,7 @@ static void ath9k_htc_radio_disable(struct ieee80211_hw *hw)
ah->curchan = ath9k_cmn_get_curchannel(hw, ah);
/* Reset the HW */
- ret = ath9k_hw_reset(ah, ah->curchan, false);
+ ret = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (ret) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d "
@@ -1179,7 +1181,7 @@ static int ath9k_htc_start(struct ieee80211_hw *hw)
ath9k_hw_configpcipowersave(ah, 0, 0);
ath9k_hw_htc_resetinit(ah);
- ret = ath9k_hw_reset(ah, init_channel, false);
+ ret = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (ret) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d "
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 8d291ccf5c8..3384ca16456 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -610,7 +610,6 @@ static int __ath9k_hw_init(struct ath_hw *ah)
else
ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
- ath9k_init_nfcal_hist_buffer(ah);
ah->bb_watchdog_timeout_ms = 25;
common->state = ATH_HW_INITIALIZED;
@@ -1183,9 +1182,6 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
ath9k_hw_spur_mitigate_freq(ah, chan);
- if (!chan->oneTimeCalsDone)
- chan->oneTimeCalsDone = true;
-
return true;
}
@@ -1218,7 +1214,7 @@ bool ath9k_hw_check_alive(struct ath_hw *ah)
EXPORT_SYMBOL(ath9k_hw_check_alive);
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
- bool bChannelChange)
+ struct ath9k_hw_cal_data *caldata, bool bChannelChange)
{
struct ath_common *common = ath9k_hw_common(ah);
u32 saveLedState;
@@ -1243,9 +1239,19 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return -EIO;
- if (curchan && !ah->chip_fullsleep)
+ if (curchan && !ah->chip_fullsleep && ah->caldata)
ath9k_hw_getnf(ah, curchan);
+ ah->caldata = caldata;
+ if (caldata &&
+ (chan->channel != caldata->channel ||
+ (chan->channelFlags & ~CHANNEL_CW_INT) !=
+ (caldata->channelFlags & ~CHANNEL_CW_INT))) {
+ /* Operating channel changed, reset channel calibration data */
+ memset(caldata, 0, sizeof(*caldata));
+ ath9k_init_nfcal_hist_buffer(ah, chan);
+ }
+
if (bChannelChange &&
(ah->chip_fullsleep != true) &&
(ah->curchan != NULL) &&
@@ -1256,7 +1262,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (ath9k_hw_channel_change(ah, chan)) {
ath9k_hw_loadnf(ah, ah->curchan);
- ath9k_hw_start_nfcal(ah);
+ ath9k_hw_start_nfcal(ah, true);
return 0;
}
}
@@ -1461,11 +1467,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (ah->btcoex_hw.enabled)
ath9k_hw_btcoex_enable(ah);
- if (AR_SREV_9300_20_OR_LATER(ah)) {
- ath9k_hw_loadnf(ah, curchan);
- ath9k_hw_start_nfcal(ah);
+ if (AR_SREV_9300_20_OR_LATER(ah))
ar9003_hw_bb_watchdog_config(ah);
- }
return 0;
}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 2d30efc0b94..399f7c1283c 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -346,19 +346,25 @@ enum ath9k_int {
CHANNEL_HT40PLUS | \
CHANNEL_HT40MINUS)
-struct ath9k_channel {
- struct ieee80211_channel *chan;
+struct ath9k_hw_cal_data {
u16 channel;
u32 channelFlags;
- u32 chanmode;
int32_t CalValid;
- bool oneTimeCalsDone;
int8_t iCoff;
int8_t qCoff;
int16_t rawNoiseFloor;
bool paprd_done;
+ bool nfcal_pending;
u16 small_signal_gain[AR9300_MAX_CHAINS];
u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
+ struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+};
+
+struct ath9k_channel {
+ struct ieee80211_channel *chan;
+ u16 channel;
+ u32 channelFlags;
+ u32 chanmode;
};
#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
@@ -669,7 +675,7 @@ struct ath_hw {
enum nl80211_iftype opmode;
enum ath9k_power_mode power_mode;
- struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
+ struct ath9k_hw_cal_data *caldata;
struct ath9k_pacal_info pacal_info;
struct ar5416Stats stats;
struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
@@ -863,7 +869,7 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid);
void ath9k_hw_deinit(struct ath_hw *ah);
int ath9k_hw_init(struct ath_hw *ah);
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
- bool bChannelChange);
+ struct ath9k_hw_cal_data *caldata, bool bChannelChange);
int ath9k_hw_fill_cap_info(struct ath_hw *ah);
u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
@@ -958,9 +964,10 @@ void ar9003_hw_bb_watchdog_read(struct ath_hw *ah);
void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);
void ar9003_paprd_enable(struct ath_hw *ah, bool val);
void ar9003_paprd_populate_single_table(struct ath_hw *ah,
- struct ath9k_channel *chan, int chain);
-int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan,
- int chain);
+ struct ath9k_hw_cal_data *caldata,
+ int chain);
+int ar9003_paprd_create_curve(struct ath_hw *ah,
+ struct ath9k_hw_cal_data *caldata, int chain);
int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
int ar9003_paprd_init_table(struct ath_hw *ah);
bool ar9003_paprd_is_done(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 0429dda0961..3caa32316e7 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -154,6 +154,27 @@ void ath9k_ps_restore(struct ath_softc *sc)
spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
}
+static void ath_start_ani(struct ath_common *common)
+{
+ struct ath_hw *ah = common->ah;
+ unsigned long timestamp = jiffies_to_msecs(jiffies);
+ struct ath_softc *sc = (struct ath_softc *) common->priv;
+
+ if (!(sc->sc_flags & SC_OP_ANI_RUN))
+ return;
+
+ if (sc->sc_flags & SC_OP_OFFCHANNEL)
+ return;
+
+ common->ani.longcal_timer = timestamp;
+ common->ani.shortcal_timer = timestamp;
+ common->ani.checkani_timer = timestamp;
+
+ mod_timer(&common->ani.timer,
+ jiffies +
+ msecs_to_jiffies((u32)ah->config.ani_poll_interval));
+}
+
/*
* Set/change channels. If the channel is really being changed, it's done
* by reseting the chip. To accomplish this we must first cleanup any pending
@@ -162,16 +183,23 @@ void ath9k_ps_restore(struct ath_softc *sc)
int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
struct ath9k_channel *hchan)
{
+ struct ath_wiphy *aphy = hw->priv;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_conf *conf = &common->hw->conf;
bool fastcc = true, stopped;
struct ieee80211_channel *channel = hw->conf.channel;
+ struct ath9k_hw_cal_data *caldata = NULL;
int r;
if (sc->sc_flags & SC_OP_INVALID)
return -EIO;
+ del_timer_sync(&common->ani.timer);
+ cancel_work_sync(&sc->paprd_work);
+ cancel_work_sync(&sc->hw_check_work);
+ cancel_delayed_work_sync(&sc->tx_complete_work);
+
ath9k_ps_wakeup(sc);
/*
@@ -191,9 +219,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
* to flush data frames already in queue because of
* changing channel. */
- if (!stopped || (sc->sc_flags & SC_OP_FULL_RESET))
+ if (!stopped || !(sc->sc_flags & SC_OP_OFFCHANNEL))
fastcc = false;
+ if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
+ caldata = &aphy->caldata;
+
ath_print(common, ATH_DBG_CONFIG,
"(%u MHz) -> (%u MHz), conf_is_ht40: %d\n",
sc->sc_ah->curchan->channel,
@@ -201,7 +232,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, hchan, fastcc);
+ r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
if (r) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset channel (%u MHz), "
@@ -212,8 +243,6 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
}
spin_unlock_bh(&sc->sc_resetlock);
- sc->sc_flags &= ~SC_OP_FULL_RESET;
-
if (ath_startrecv(sc) != 0) {
ath_print(common, ATH_DBG_FATAL,
"Unable to restart recv logic\n");
@@ -225,6 +254,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
ath_update_txpow(sc);
ath9k_hw_set_interrupts(ah, ah->imask);
+ if (!(sc->sc_flags & (SC_OP_OFFCHANNEL | SC_OP_SCANNING))) {
+ ath_start_ani(common);
+ ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
+ ath_beacon_config(sc, NULL);
+ }
+
ps_restore:
ath9k_ps_restore(sc);
return r;
@@ -233,17 +268,19 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
static void ath_paprd_activate(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
int chain;
- if (!ah->curchan->paprd_done)
+ if (!caldata || !caldata->paprd_done)
return;
ath9k_ps_wakeup(sc);
+ ar9003_paprd_enable(ah, false);
for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
if (!(ah->caps.tx_chainmask & BIT(chain)))
continue;
- ar9003_paprd_populate_single_table(ah, ah->curchan, chain);
+ ar9003_paprd_populate_single_table(ah, caldata, chain);
}
ar9003_paprd_enable(ah, true);
@@ -261,6 +298,7 @@ void ath_paprd_calibrate(struct work_struct *work)
int band = hw->conf.channel->band;
struct ieee80211_supported_band *sband = &sc->sbands[band];
struct ath_tx_control txctl;
+ struct ath9k_hw_cal_data *caldata = ah->caldata;
int qnum, ftype;
int chain_ok = 0;
int chain;
@@ -268,6 +306,9 @@ void ath_paprd_calibrate(struct work_struct *work)
int time_left;
int i;
+ if (!caldata)
+ return;
+
skb = alloc_skb(len, GFP_KERNEL);
if (!skb)
return;
@@ -322,7 +363,7 @@ void ath_paprd_calibrate(struct work_struct *work)
if (!ar9003_paprd_is_done(ah))
break;
- if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0)
+ if (ar9003_paprd_create_curve(ah, caldata, chain) != 0)
break;
chain_ok = 1;
@@ -330,7 +371,7 @@ void ath_paprd_calibrate(struct work_struct *work)
kfree_skb(skb);
if (chain_ok) {
- ah->curchan->paprd_done = true;
+ caldata->paprd_done = true;
ath_paprd_activate(sc);
}
@@ -439,33 +480,14 @@ set_timer:
cal_interval = min(cal_interval, (u32)short_cal_interval);
mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
- if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) &&
- !(sc->sc_flags & SC_OP_SCANNING)) {
- if (!sc->sc_ah->curchan->paprd_done)
+ if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) && ah->caldata) {
+ if (!ah->caldata->paprd_done)
ieee80211_queue_work(sc->hw, &sc->paprd_work);
else
ath_paprd_activate(sc);
}
}
-static void ath_start_ani(struct ath_common *common)
-{
- struct ath_hw *ah = common->ah;
- unsigned long timestamp = jiffies_to_msecs(jiffies);
- struct ath_softc *sc = (struct ath_softc *) common->priv;
-
- if (!(sc->sc_flags & SC_OP_ANI_RUN))
- return;
-
- common->ani.longcal_timer = timestamp;
- common->ani.shortcal_timer = timestamp;
- common->ani.checkani_timer = timestamp;
-
- mod_timer(&common->ani.timer,
- jiffies +
- msecs_to_jiffies((u32)ah->config.ani_poll_interval));
-}
-
/*
* Update tx/rx chainmask. For legacy association,
* hard code chainmask to 1x1, for 11n association, use
@@ -477,7 +499,7 @@ void ath_update_chainmask(struct ath_softc *sc, int is_ht)
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
- if ((sc->sc_flags & SC_OP_SCANNING) || is_ht ||
+ if ((sc->sc_flags & SC_OP_OFFCHANNEL) || is_ht ||
(ah->btcoex_hw.scheme != ATH_BTCOEX_CFG_NONE)) {
common->tx_chainmask = ah->caps.tx_chainmask;
common->rx_chainmask = ah->caps.rx_chainmask;
@@ -817,7 +839,7 @@ void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
ah->curchan = ath_get_curchannel(sc, sc->hw);
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, ah->curchan, false);
+ r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (r) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset channel (%u MHz), "
@@ -877,7 +899,7 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
ah->curchan = ath_get_curchannel(sc, hw);
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, ah->curchan, false);
+ r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
if (r) {
ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
"Unable to reset channel (%u MHz), "
@@ -910,7 +932,7 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
ath_flushrecv(sc);
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
+ r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
if (r)
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d\n", r);
@@ -1085,7 +1107,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
* and then setup of the interrupt mask.
*/
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, init_channel, false);
+ r = ath9k_hw_reset(ah, init_channel, ah->caldata, false);
if (r) {
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d "
@@ -1579,6 +1601,10 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
aphy->chan_idx = pos;
aphy->chan_is_ht = conf_is_ht(conf);
+ if (hw->conf.flags & IEEE80211_CONF_OFFCHANNEL)
+ sc->sc_flags |= SC_OP_OFFCHANNEL;
+ else
+ sc->sc_flags &= ~SC_OP_OFFCHANNEL;
if (aphy->state == ATH_WIPHY_SCAN ||
aphy->state == ATH_WIPHY_ACTIVE)
@@ -1990,7 +2016,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
mutex_lock(&sc->mutex);
if (ath9k_wiphy_scanning(sc)) {
@@ -2008,10 +2033,6 @@ static void ath9k_sw_scan_start(struct ieee80211_hw *hw)
aphy->state = ATH_WIPHY_SCAN;
ath9k_wiphy_pause_all_forced(sc, aphy);
sc->sc_flags |= SC_OP_SCANNING;
- del_timer_sync(&common->ani.timer);
- cancel_work_sync(&sc->paprd_work);
- cancel_work_sync(&sc->hw_check_work);
- cancel_delayed_work_sync(&sc->tx_complete_work);
mutex_unlock(&sc->mutex);
}
@@ -2023,15 +2044,10 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
{
struct ath_wiphy *aphy = hw->priv;
struct ath_softc *sc = aphy->sc;
- struct ath_common *common = ath9k_hw_common(sc->sc_ah);
mutex_lock(&sc->mutex);
aphy->state = ATH_WIPHY_ACTIVE;
sc->sc_flags &= ~SC_OP_SCANNING;
- sc->sc_flags |= SC_OP_FULL_RESET;
- ath_start_ani(common);
- ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
- ath_beacon_config(sc, NULL);
mutex_unlock(&sc->mutex);
}
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index da0cfe90c38..a3fc987ebab 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1140,6 +1140,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
if (flush)
goto requeue;
+ retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
+ rxs, &decrypt_error);
+ if (retval)
+ goto requeue;
+
rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
if (rs.rs_tstamp > tsf_lower &&
unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
@@ -1149,11 +1154,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
rxs->mactime += 0x100000000ULL;
- retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
- rxs, &decrypt_error);
- if (retval)
- goto requeue;
-
/* Ensure we always have an skb to requeue once we are done
* processing the current buffer's skb */
requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC);
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 501b72821b4..4dda14e3622 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -120,26 +120,14 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
list_add_tail(&ac->list, &txq->axq_acq);
}
-static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
-{
- struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
-
- spin_lock_bh(&txq->axq_lock);
- tid->paused++;
- spin_unlock_bh(&txq->axq_lock);
-}
-
static void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
struct ath_txq *txq = &sc->tx.txq[tid->ac->qnum];
- BUG_ON(tid->paused <= 0);
- spin_lock_bh(&txq->axq_lock);
-
- tid->paused--;
+ WARN_ON(!tid->paused);
- if (tid->paused > 0)
- goto unlock;
+ spin_lock_bh(&txq->axq_lock);
+ tid->paused = false;
if (list_empty(&tid->buf_q))
goto unlock;
@@ -157,15 +145,10 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
struct list_head bf_head;
INIT_LIST_HEAD(&bf_head);
- BUG_ON(tid->paused <= 0);
- spin_lock_bh(&txq->axq_lock);
+ WARN_ON(!tid->paused);
- tid->paused--;
-
- if (tid->paused > 0) {
- spin_unlock_bh(&txq->axq_lock);
- return;
- }
+ spin_lock_bh(&txq->axq_lock);
+ tid->paused = false;
while (!list_empty(&tid->buf_q)) {
bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
@@ -811,7 +794,7 @@ void ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
an = (struct ath_node *)sta->drv_priv;
txtid = ATH_AN_2_TID(an, tid);
txtid->state |= AGGR_ADDBA_PROGRESS;
- ath_tx_pause_tid(sc, txtid);
+ txtid->paused = true;
*ssn = txtid->seq_start;
}
@@ -835,10 +818,9 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
return;
}
- ath_tx_pause_tid(sc, txtid);
-
/* drop all software retried frames and mark this TID */
spin_lock_bh(&txq->axq_lock);
+ txtid->paused = true;
while (!list_empty(&txtid->buf_q)) {
bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
if (!bf_isretried(bf)) {
@@ -1181,7 +1163,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx)
"Failed to stop TX DMA. Resetting hardware!\n");
spin_lock_bh(&sc->sc_resetlock);
- r = ath9k_hw_reset(ah, sc->sc_ah->curchan, false);
+ r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false);
if (r)
ath_print(common, ATH_DBG_FATAL,
"Unable to reset hardware; reset status %d\n",
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index c2746fc7f2b..3b632161c10 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -42,7 +42,6 @@
#include <linux/moduleparam.h>
#include <linux/device.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -191,25 +190,23 @@ static int atmel_config_check(struct pcmcia_device *p_dev,
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
- p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.BasePort1 = io->win[0].base;
- p_dev->io.NumPorts1 = io->win[0].len;
+ p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ p_dev->resource[0]->flags |=
+ pcmcia_io_cfg_data_width(io->flags);
+ p_dev->resource[0]->start = io->win[0].base;
+ p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
- p_dev->io.Attributes2 = p_dev->io.Attributes1;
- p_dev->io.BasePort2 = io->win[1].base;
- p_dev->io.NumPorts2 = io->win[1].len;
+ p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+ p_dev->resource[1]->start = io->win[1].base;
+ p_dev->resource[1]->end = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
- return pcmcia_request_io(p_dev, &p_dev->io);
+ return pcmcia_request_io(p_dev);
}
static int atmel_config(struct pcmcia_device *link)
@@ -254,7 +251,7 @@ static int atmel_config(struct pcmcia_device *link)
((local_info_t*)link->priv)->eth_dev =
init_atmel_card(link->irq,
- link->io.BasePort1,
+ link->resource[0]->start,
did ? did->driver_info : ATMEL_FW_TYPE_NONE,
&link->dev,
card_present,
diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c
index 0e99b634267..dfbc41d431f 100644
--- a/drivers/net/wireless/b43/pcmcia.c
+++ b/drivers/net/wireless/b43/pcmcia.c
@@ -26,7 +26,6 @@
#include <linux/ssb/ssb.h>
#include <linux/slab.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ciscode.h>
@@ -65,7 +64,6 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
{
struct ssb_bus *ssb;
win_req_t win;
- memreq_t mem;
int err = -ENOMEM;
int res = 0;
@@ -78,12 +76,7 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
dev->conf.Attributes = CONF_ENABLE_IRQ;
dev->conf.IntType = INT_MEMORY_AND_IO;
- dev->io.BasePort2 = 0;
- dev->io.NumPorts2 = 0;
- dev->io.Attributes2 = 0;
-
- win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM |
- WIN_ENABLE | WIN_DATA_WIDTH_16 |
+ win.Attributes = WIN_ENABLE | WIN_DATA_WIDTH_16 |
WIN_USE_WAIT;
win.Base = 0;
win.Size = SSB_CORE_SIZE;
@@ -92,9 +85,7 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
if (res != 0)
goto err_kfree_ssb;
- mem.CardOffset = 0;
- mem.Page = 0;
- res = pcmcia_map_mem_page(dev, dev->win, &mem);
+ res = pcmcia_map_mem_page(dev, dev->win, 0);
if (res != 0)
goto err_disable;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 29b31a694b5..ba54d1b04d2 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -12,7 +12,6 @@
#include <linux/wireless.h>
#include <net/iw_handler.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -23,7 +22,7 @@
#include "hostap_wlan.h"
-static dev_info_t dev_info = "hostap_cs";
+static char *dev_info = "hostap_cs";
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN "
@@ -225,27 +224,18 @@ static int prism2_pccard_card_present(local_info_t *local)
static void sandisk_set_iobase(local_info_t *local)
{
int res;
- conf_reg_t reg;
struct hostap_cs_priv *hw_priv = local->hw_priv;
- reg.Function = 0;
- reg.Action = CS_WRITE;
- reg.Offset = 0x10; /* 0x3f0 IO base 1 */
- reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ res = pcmcia_write_config_byte(hw_priv->link, 0x10,
+ hw_priv->link->resource[0]->start & 0x00ff);
if (res != 0) {
printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
" res=%d\n", res);
}
udelay(10);
- reg.Function = 0;
- reg.Action = CS_WRITE;
- reg.Offset = 0x12; /* 0x3f2 IO base 2 */
- reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ res = pcmcia_write_config_byte(hw_priv->link, 0x12,
+ (hw_priv->link->resource[0]->start >> 8) & 0x00ff);
if (res != 0) {
printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
" res=%d\n", res);
@@ -271,12 +261,11 @@ static void sandisk_write_hcr(local_info_t *local, int hcr)
static int sandisk_enable_wireless(struct net_device *dev)
{
int res, ret = 0;
- conf_reg_t reg;
struct hostap_interface *iface = netdev_priv(dev);
local_info_t *local = iface->local;
struct hostap_cs_priv *hw_priv = local->hw_priv;
- if (hw_priv->link->io.NumPorts1 < 0x42) {
+ if (resource_size(hw_priv->link->resource[0]) < 0x42) {
/* Not enough ports to be SanDisk multi-function card */
ret = -ENODEV;
goto done;
@@ -298,12 +287,8 @@ static int sandisk_enable_wireless(struct net_device *dev)
" - using vendor-specific initialization\n", dev->name);
hw_priv->sandisk_connectplus = 1;
- reg.Function = 0;
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_COR;
- reg.Value = COR_SOFT_RESET;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR,
+ COR_SOFT_RESET);
if (res != 0) {
printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
dev->name, res);
@@ -311,16 +296,13 @@ static int sandisk_enable_wireless(struct net_device *dev)
}
mdelay(5);
- reg.Function = 0;
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_COR;
/*
* Do not enable interrupts here to avoid some bogus events. Interrupts
* will be enabled during the first cor_sreset call.
*/
- reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR,
+ (COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE |
+ COR_FUNC_ENA));
if (res != 0) {
printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
dev->name, res);
@@ -343,30 +325,23 @@ done:
static void prism2_pccard_cor_sreset(local_info_t *local)
{
int res;
- conf_reg_t reg;
+ u8 val;
struct hostap_cs_priv *hw_priv = local->hw_priv;
if (!prism2_pccard_card_present(local))
return;
- reg.Function = 0;
- reg.Action = CS_READ;
- reg.Offset = CISREG_COR;
- reg.Value = 0;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ res = pcmcia_read_config_byte(hw_priv->link, CISREG_COR, &val);
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
res);
return;
}
printk(KERN_DEBUG "prism2_pccard_cor_sreset: original COR %02x\n",
- reg.Value);
+ val);
- reg.Action = CS_WRITE;
- reg.Value |= COR_SOFT_RESET;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ val |= COR_SOFT_RESET;
+ res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR, val);
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
res);
@@ -375,11 +350,10 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
mdelay(hw_priv->sandisk_connectplus ? 5 : 2);
- reg.Value &= ~COR_SOFT_RESET;
+ val &= ~COR_SOFT_RESET;
if (hw_priv->sandisk_connectplus)
- reg.Value |= COR_IREQ_ENA;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ val |= COR_IREQ_ENA;
+ res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR, val);
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
res);
@@ -396,8 +370,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
{
int res;
- conf_reg_t reg;
- int old_cor;
+ u8 old_cor;
struct hostap_cs_priv *hw_priv = local->hw_priv;
if (!prism2_pccard_card_present(local))
@@ -408,25 +381,17 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
return;
}
- reg.Function = 0;
- reg.Action = CS_READ;
- reg.Offset = CISREG_COR;
- reg.Value = 0;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ res = pcmcia_read_config_byte(hw_priv->link, CISREG_COR, &old_cor);
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
"(%d)\n", res);
return;
}
printk(KERN_DEBUG "prism2_pccard_genesis_sreset: original COR %02x\n",
- reg.Value);
- old_cor = reg.Value;
+ old_cor);
- reg.Action = CS_WRITE;
- reg.Value |= COR_SOFT_RESET;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR,
+ old_cor | COR_SOFT_RESET);
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
"(%d)\n", res);
@@ -436,11 +401,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
mdelay(10);
/* Setup Genesis mode */
- reg.Action = CS_WRITE;
- reg.Value = hcr;
- reg.Offset = CISREG_CCSR;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ res = pcmcia_write_config_byte(hw_priv->link, CISREG_CCSR, hcr);
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
"(%d)\n", res);
@@ -448,11 +409,8 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
}
mdelay(10);
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_COR;
- reg.Value = old_cor & ~COR_SOFT_RESET;
- res = pcmcia_access_configuration_register(hw_priv->link,
- &reg);
+ res = pcmcia_write_config_byte(hw_priv->link, CISREG_COR,
+ old_cor & ~COR_SOFT_RESET);
if (res != 0) {
printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
"(%d)\n", res);
@@ -561,30 +519,24 @@ static int prism2_config_check(struct pcmcia_device *p_dev,
PDEBUG(DEBUG_EXTRA, "IO window settings: cfg->io.nwin=%d "
"dflt->io.nwin=%d\n",
cfg->io.nwin, dflt->io.nwin);
- p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- PDEBUG(DEBUG_EXTRA, "io->flags = 0x%04X, "
- "io.base=0x%04x, len=%d\n", io->flags,
- io->win[0].base, io->win[0].len);
- if (!(io->flags & CISTPL_IO_8BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.IOAddrLines = io->flags &
- CISTPL_IO_LINES_MASK;
- p_dev->io.BasePort1 = io->win[0].base;
- p_dev->io.NumPorts1 = io->win[0].len;
+ p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ p_dev->resource[0]->flags |=
+ pcmcia_io_cfg_data_width(io->flags);
+ p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->resource[0]->start = io->win[0].base;
+ p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
- p_dev->io.Attributes2 = p_dev->io.Attributes1;
- p_dev->io.BasePort2 = io->win[1].base;
- p_dev->io.NumPorts2 = io->win[1].len;
+ p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+ p_dev->resource[1]->start = io->win[1].base;
+ p_dev->resource[1]->end = io->win[1].len;
}
}
/* This reserves IO space but doesn't actually enable it */
- return pcmcia_request_io(p_dev, &p_dev->io);
+ return pcmcia_request_io(p_dev);
}
static int prism2_config(struct pcmcia_device *link)
@@ -646,7 +598,7 @@ static int prism2_config(struct pcmcia_device *link)
goto failed_unlock;
dev->irq = link->irq;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
spin_unlock_irqrestore(&local->irq_init_lock, flags);
@@ -658,12 +610,10 @@ static int prism2_config(struct pcmcia_device *link)
link->conf.Vpp % 10);
if (link->conf.Attributes & CONF_ENABLE_IRQ)
printk(", irq %d", link->irq);
- if (link->io.NumPorts1)
- printk(", io 0x%04x-0x%04x", link->io.BasePort1,
- link->io.BasePort1+link->io.NumPorts1-1);
- if (link->io.NumPorts2)
- printk(" & 0x%04x-0x%04x", link->io.BasePort2,
- link->io.BasePort2+link->io.NumPorts2-1);
+ if (link->resource[0])
+ printk(" & %pR", link->resource[0]);
+ if (link->resource[1])
+ printk(" & %pR", link->resource[1]);
printk("\n");
local->shutdown = 0;
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index c24c5efeae1..16bbfa3189a 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1924,6 +1924,10 @@ static int ipw2100_net_init(struct net_device *dev)
bg_band->channels =
kzalloc(geo->bg_channels *
sizeof(struct ieee80211_channel), GFP_KERNEL);
+ if (!bg_band->channels) {
+ ipw2100_down(priv);
+ return -ENOMEM;
+ }
/* translate geo->bg to bg_band.channels */
for (i = 0; i < geo->bg_channels; i++) {
bg_band->channels[i].band = IEEE80211_BAND_2GHZ;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
index f052c6d09b3..d706b8afbe5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-debugfs.c
@@ -980,7 +980,7 @@ ssize_t iwl_ucode_bt_stats_read(struct file *file,
le32_to_cpu(bt->lo_priority_tx_req_cnt),
accum_bt->lo_priority_tx_req_cnt);
pos += scnprintf(buf + pos, bufsz - pos,
- "lo_priority_rx_denied_cnt:\t%u\t\t\t%u\n",
+ "lo_priority_tx_denied_cnt:\t%u\t\t\t%u\n",
le32_to_cpu(bt->lo_priority_tx_denied_cnt),
accum_bt->lo_priority_tx_denied_cnt);
pos += scnprintf(buf + pos, bufsz - pos,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index a1b6d202d57..9dd9e64c2b0 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1429,7 +1429,7 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
void iwl_free_tfds_in_queue(struct iwl_priv *priv,
int sta_id, int tid, int freed)
{
- WARN_ON(!spin_is_locked(&priv->sta_lock));
+ lockdep_assert_held(&priv->sta_lock);
if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 35c86d22b14..23e5c42e7d7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -300,8 +300,9 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
struct ieee80211_sta *sta)
{
int ret = -EAGAIN;
+ u32 load = rs_tl_get_load(lq_data, tid);
- if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {
+ if (load > IWL_AGG_LOAD_THRESHOLD) {
IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
sta->addr, tid);
ret = ieee80211_start_tx_ba_session(sta, tid);
@@ -311,12 +312,14 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
* this might be cause by reloading firmware
* stop the tx ba session here
*/
- IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n",
+ IWL_ERR(priv, "Fail start Tx agg on tid: %d\n",
tid);
ieee80211_stop_tx_ba_session(sta, tid);
}
- } else
- IWL_ERR(priv, "Fail finding valid aggregation tid: %d\n", tid);
+ } else {
+ IWL_ERR(priv, "Aggregation not enabled for tid %d "
+ "because load = %u\n", tid, load);
+ }
return ret;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 55a1b31fd09..d04502d54df 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -1117,7 +1117,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
u8 *addr = priv->stations[sta_id].sta.sta.addr;
struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
- WARN_ON(!spin_is_locked(&priv->sta_lock));
+ lockdep_assert_held(&priv->sta_lock);
switch (priv->stations[sta_id].tid[tid].agg.state) {
case IWL_EMPTYING_HW_QUEUE_DELBA:
@@ -1331,7 +1331,14 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
tid = ba_resp->tid;
agg = &priv->stations[sta_id].tid[tid].agg;
if (unlikely(agg->txq_id != scd_flow)) {
- IWL_ERR(priv, "BA scd_flow %d does not match txq_id %d\n",
+ /*
+ * FIXME: this is a uCode bug which need to be addressed,
+ * log the information and return for now!
+ * since it is possible happen very often and in order
+ * not to fill the syslog, don't enable the logging by default
+ */
+ IWL_DEBUG_TX_REPLY(priv,
+ "BA scd_flow %d does not match txq_id %d\n",
scd_flow, agg->txq_id);
return;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 8024d44ce4b..8ccb6d205b6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2000,6 +2000,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
struct ieee80211_vif *vif)
{
struct iwl_priv *priv = hw->priv;
+ bool scan_completed = false;
IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -2013,7 +2014,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
if (priv->vif == vif) {
priv->vif = NULL;
if (priv->scan_vif == vif) {
- ieee80211_scan_completed(priv->hw, true);
+ scan_completed = true;
priv->scan_vif = NULL;
priv->scan_request = NULL;
}
@@ -2021,6 +2022,9 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
}
mutex_unlock(&priv->mutex);
+ if (scan_completed)
+ ieee80211_scan_completed(priv->hw, true);
+
IWL_DEBUG_MAC80211(priv, "leave\n");
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 5c2bcef5df0..0b961a353ff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -71,7 +71,7 @@ do { \
#define IWL_DEBUG(__priv, level, fmt, args...)
#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level,
- void *p, u32 len)
+ const void *p, u32 len)
{}
#endif /* CONFIG_IWLWIFI_DEBUG */
diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
index ae7319bb3a9..4cf864c664e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h
+++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h
@@ -193,7 +193,7 @@ TRACE_EVENT(iwlwifi_dev_tx,
__entry->framelen = buf0_len + buf1_len;
memcpy(__get_dynamic_array(tfd), tfd, tfdlen);
memcpy(__get_dynamic_array(buf0), buf0, buf0_len);
- memcpy(__get_dynamic_array(buf1), buf1, buf0_len);
+ memcpy(__get_dynamic_array(buf1), buf1, buf1_len);
),
TP_printk("[%p] TX %.2x (%zu bytes)",
__entry->priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index b0c6b047390..a4b3663a262 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -298,7 +298,7 @@ EXPORT_SYMBOL(iwl_init_scan_params);
static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif)
{
- WARN_ON(!mutex_is_locked(&priv->mutex));
+ lockdep_assert_held(&priv->mutex);
IWL_DEBUG_INFO(priv, "Starting scan...\n");
set_bit(STATUS_SCANNING, &priv->status);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 9511f03f07e..7e0829be5e7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -773,7 +773,7 @@ static int iwl_send_static_wepkey_cmd(struct iwl_priv *priv, u8 send_if_empty)
int iwl_restore_default_wep_keys(struct iwl_priv *priv)
{
- WARN_ON(!mutex_is_locked(&priv->mutex));
+ lockdep_assert_held(&priv->mutex);
return iwl_send_static_wepkey_cmd(priv, 0);
}
@@ -784,7 +784,7 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
{
int ret;
- WARN_ON(!mutex_is_locked(&priv->mutex));
+ lockdep_assert_held(&priv->mutex);
IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
keyconf->keyidx);
@@ -808,7 +808,7 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
{
int ret;
- WARN_ON(!mutex_is_locked(&priv->mutex));
+ lockdep_assert_held(&priv->mutex);
if (keyconf->keylen != WEP_KEY_LEN_128 &&
keyconf->keylen != WEP_KEY_LEN_64) {
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index 25f90276098..8e9fbfd804b 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -257,6 +257,29 @@ static int lbs_add_supported_rates_tlv(u8 *tlv)
return sizeof(rate_tlv->header) + i;
}
+/* Add common rates from a TLV and return the new end of the TLV */
+static u8 *
+add_ie_rates(u8 *tlv, const u8 *ie, int *nrates)
+{
+ int hw, ap, ap_max = ie[1];
+ u8 hw_rate;
+
+ /* Advance past IE header */
+ ie += 2;
+
+ lbs_deb_hex(LBS_DEB_ASSOC, "AP IE Rates", (u8 *) ie, ap_max);
+
+ for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
+ hw_rate = lbs_rates[hw].bitrate / 5;
+ for (ap = 0; ap < ap_max; ap++) {
+ if (hw_rate == (ie[ap] & 0x7f)) {
+ *tlv++ = ie[ap];
+ *nrates = *nrates + 1;
+ }
+ }
+ }
+ return tlv;
+}
/*
* Adds a TLV with all rates the hardware *and* BSS supports.
@@ -264,8 +287,11 @@ static int lbs_add_supported_rates_tlv(u8 *tlv)
static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
{
struct mrvl_ie_rates_param_set *rate_tlv = (void *)tlv;
- const u8 *rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
- int n;
+ const u8 *rates_eid, *ext_rates_eid;
+ int n = 0;
+
+ rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_SUPP_RATES);
+ ext_rates_eid = ieee80211_bss_get_ie(bss, WLAN_EID_EXT_SUPP_RATES);
/*
* 01 00 TLV_TYPE_RATES
@@ -275,26 +301,21 @@ static int lbs_add_common_rates_tlv(u8 *tlv, struct cfg80211_bss *bss)
rate_tlv->header.type = cpu_to_le16(TLV_TYPE_RATES);
tlv += sizeof(rate_tlv->header);
- if (!rates_eid) {
+ /* Add basic rates */
+ if (rates_eid) {
+ tlv = add_ie_rates(tlv, rates_eid, &n);
+
+ /* Add extended rates, if any */
+ if (ext_rates_eid)
+ tlv = add_ie_rates(tlv, ext_rates_eid, &n);
+ } else {
+ lbs_deb_assoc("assoc: bss had no basic rate IE\n");
/* Fallback: add basic 802.11b rates */
*tlv++ = 0x82;
*tlv++ = 0x84;
*tlv++ = 0x8b;
*tlv++ = 0x96;
n = 4;
- } else {
- int hw, ap;
- u8 ap_max = rates_eid[1];
- n = 0;
- for (hw = 0; hw < ARRAY_SIZE(lbs_rates); hw++) {
- u8 hw_rate = lbs_rates[hw].bitrate / 5;
- for (ap = 0; ap < ap_max; ap++) {
- if (hw_rate == (rates_eid[ap+2] & 0x7f)) {
- *tlv++ = rates_eid[ap+2];
- n++;
- }
- }
- }
}
rate_tlv->header.len = cpu_to_le16(n);
@@ -465,7 +486,15 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy,
lbs_deb_enter(LBS_DEB_CFG80211);
bsssize = get_unaligned_le16(&scanresp->bssdescriptsize);
- nr_sets = le16_to_cpu(resp->size);
+ nr_sets = le16_to_cpu(scanresp->nr_sets);
+
+ lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n",
+ nr_sets, bsssize, le16_to_cpu(resp->size));
+
+ if (nr_sets == 0) {
+ ret = 0;
+ goto done;
+ }
/*
* The general layout of the scan response is described in chapter
@@ -670,8 +699,13 @@ static void lbs_scan_worker(struct work_struct *work)
if (priv->scan_channel >= priv->scan_req->n_channels) {
/* Mark scan done */
- cfg80211_scan_done(priv->scan_req, false);
+ if (priv->internal_scan)
+ kfree(priv->scan_req);
+ else
+ cfg80211_scan_done(priv->scan_req, false);
+
priv->scan_req = NULL;
+ priv->last_scan = jiffies;
}
/* Restart network */
@@ -682,10 +716,33 @@ static void lbs_scan_worker(struct work_struct *work)
kfree(scan_cmd);
+ /* Wake up anything waiting on scan completion */
+ if (priv->scan_req == NULL) {
+ lbs_deb_scan("scan: waking up waiters\n");
+ wake_up_all(&priv->scan_q);
+ }
+
out_no_scan_cmd:
lbs_deb_leave(LBS_DEB_SCAN);
}
+static void _internal_start_scan(struct lbs_private *priv, bool internal,
+ struct cfg80211_scan_request *request)
+{
+ lbs_deb_enter(LBS_DEB_CFG80211);
+
+ lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
+ request->n_ssids, request->n_channels, request->ie_len);
+
+ priv->scan_channel = 0;
+ queue_delayed_work(priv->work_thread, &priv->scan_work,
+ msecs_to_jiffies(50));
+
+ priv->scan_req = request;
+ priv->internal_scan = internal;
+
+ lbs_deb_leave(LBS_DEB_CFG80211);
+}
static int lbs_cfg_scan(struct wiphy *wiphy,
struct net_device *dev,
@@ -702,18 +759,11 @@ static int lbs_cfg_scan(struct wiphy *wiphy,
goto out;
}
- lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
- request->n_ssids, request->n_channels, request->ie_len);
-
- priv->scan_channel = 0;
- queue_delayed_work(priv->work_thread, &priv->scan_work,
- msecs_to_jiffies(50));
+ _internal_start_scan(priv, false, request);
if (priv->surpriseremoved)
ret = -EIO;
- priv->scan_req = request;
-
out:
lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
return ret;
@@ -1000,6 +1050,7 @@ static int lbs_associate(struct lbs_private *priv,
int status;
int ret;
u8 *pos = &(cmd->iebuf[0]);
+ u8 *tmp;
lbs_deb_enter(LBS_DEB_CFG80211);
@@ -1044,7 +1095,9 @@ static int lbs_associate(struct lbs_private *priv,
pos += lbs_add_cf_param_tlv(pos);
/* add rates TLV */
+ tmp = pos + 4; /* skip Marvell IE header */
pos += lbs_add_common_rates_tlv(pos, bss);
+ lbs_deb_hex(LBS_DEB_ASSOC, "Common Rates", tmp, pos - tmp);
/* add auth type TLV */
if (priv->fwrelease >= 0x09000000)
@@ -1124,7 +1177,62 @@ done:
return ret;
}
+static struct cfg80211_scan_request *
+_new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme)
+{
+ struct cfg80211_scan_request *creq = NULL;
+ int i, n_channels = 0;
+ enum ieee80211_band band;
+
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ if (wiphy->bands[band])
+ n_channels += wiphy->bands[band]->n_channels;
+ }
+
+ creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +
+ n_channels * sizeof(void *),
+ GFP_ATOMIC);
+ if (!creq)
+ return NULL;
+
+ /* SSIDs come after channels */
+ creq->ssids = (void *)&creq->channels[n_channels];
+ creq->n_channels = n_channels;
+ creq->n_ssids = 1;
+
+ /* Scan all available channels */
+ i = 0;
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ int j;
+
+ if (!wiphy->bands[band])
+ continue;
+
+ for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+ /* ignore disabled channels */
+ if (wiphy->bands[band]->channels[j].flags &
+ IEEE80211_CHAN_DISABLED)
+ continue;
+
+ creq->channels[i] = &wiphy->bands[band]->channels[j];
+ i++;
+ }
+ }
+ if (i) {
+ /* Set real number of channels specified in creq->channels[] */
+ creq->n_channels = i;
+
+ /* Scan for the SSID we're going to connect to */
+ memcpy(creq->ssids[0].ssid, sme->ssid, sme->ssid_len);
+ creq->ssids[0].ssid_len = sme->ssid_len;
+ } else {
+ /* No channels found... */
+ kfree(creq);
+ creq = NULL;
+ }
+ return creq;
+}
static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_connect_params *sme)
@@ -1136,37 +1244,43 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
lbs_deb_enter(LBS_DEB_CFG80211);
- if (sme->bssid) {
- bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
- sme->ssid, sme->ssid_len,
- WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
- } else {
- /*
- * Here we have an impedance mismatch. The firmware command
- * CMD_802_11_ASSOCIATE always needs a BSSID, it cannot
- * connect otherwise. However, for the connect-API of
- * cfg80211 the bssid is purely optional. We don't get one,
- * except the user specifies one on the "iw" command line.
- *
- * If we don't got one, we could initiate a scan and look
- * for the best matching cfg80211_bss entry.
- *
- * Or, better yet, net/wireless/sme.c get's rewritten into
- * something more generally useful.
+ if (!sme->bssid) {
+ /* Run a scan if one isn't in-progress already and if the last
+ * scan was done more than 2 seconds ago.
*/
- lbs_pr_err("TODO: no BSS specified\n");
- ret = -ENOTSUPP;
- goto done;
- }
+ if (priv->scan_req == NULL &&
+ time_after(jiffies, priv->last_scan + (2 * HZ))) {
+ struct cfg80211_scan_request *creq;
+ creq = _new_connect_scan_req(wiphy, sme);
+ if (!creq) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ lbs_deb_assoc("assoc: scanning for compatible AP\n");
+ _internal_start_scan(priv, true, creq);
+ }
+
+ /* Wait for any in-progress scan to complete */
+ lbs_deb_assoc("assoc: waiting for scan to complete\n");
+ wait_event_interruptible_timeout(priv->scan_q,
+ (priv->scan_req == NULL),
+ (15 * HZ));
+ lbs_deb_assoc("assoc: scanning competed\n");
+ }
+ /* Find the BSS we want using available scan results */
+ bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
+ sme->ssid, sme->ssid_len,
+ WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
if (!bss) {
- lbs_pr_err("assicate: bss %pM not in scan results\n",
+ lbs_pr_err("assoc: bss %pM not in scan results\n",
sme->bssid);
ret = -ENOENT;
goto done;
}
- lbs_deb_assoc("trying %pM", sme->bssid);
+ lbs_deb_assoc("trying %pM\n", bss->bssid);
lbs_deb_assoc("cipher 0x%x, key index %d, key len %d\n",
sme->crypto.cipher_group,
sme->key_idx, sme->key_len);
@@ -1229,7 +1343,7 @@ static int lbs_cfg_connect(struct wiphy *wiphy, struct net_device *dev,
lbs_set_radio(priv, preamble, 1);
/* Do the actual association */
- lbs_associate(priv, bss, sme);
+ ret = lbs_associate(priv, bss, sme);
done:
if (bss)
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index 3c7e255e18c..f062ed58390 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -161,6 +161,11 @@ struct lbs_private {
/** Scanning */
struct delayed_work scan_work;
int scan_channel;
+ /* Queue of things waiting for scan completion */
+ wait_queue_head_t scan_q;
+ /* Whether the scan was initiated internally and not by cfg80211 */
+ bool internal_scan;
+ unsigned long last_scan;
};
extern struct cmd_confirm_sleep confirm_sleep;
diff --git a/drivers/net/wireless/libertas/if_cs.c b/drivers/net/wireless/libertas/if_cs.c
index 08e4e390800..9c298396be5 100644
--- a/drivers/net/wireless/libertas/if_cs.c
+++ b/drivers/net/wireless/libertas/if_cs.c
@@ -28,7 +28,6 @@
#include <linux/firmware.h>
#include <linux/netdevice.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/ds.h>
@@ -802,9 +801,9 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev,
unsigned int vcc,
void *priv_data)
{
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- p_dev->io.BasePort1 = cfg->io.win[0].base;
- p_dev->io.NumPorts1 = cfg->io.win[0].len;
+ p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_AUTO;
+ p_dev->resource[0]->start = cfg->io.win[0].base;
+ p_dev->resource[0]->end = cfg->io.win[0].len;
/* Do we need to allocate an interrupt? */
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
@@ -816,7 +815,7 @@ static int if_cs_ioprobe(struct pcmcia_device *p_dev,
}
/* This reserves IO space but doesn't actually enable it */
- return pcmcia_request_io(p_dev, &p_dev->io);
+ return pcmcia_request_io(p_dev);
}
static int if_cs_probe(struct pcmcia_device *p_dev)
@@ -854,7 +853,8 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
goto out1;
/* Initialize io access */
- card->iobase = ioport_map(p_dev->io.BasePort1, p_dev->io.NumPorts1);
+ card->iobase = ioport_map(p_dev->resource[0]->start,
+ resource_size(p_dev->resource[0]));
if (!card->iobase) {
lbs_pr_err("error in ioport_map\n");
ret = -EIO;
@@ -873,9 +873,7 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
}
/* Finally, report what we've done */
- lbs_deb_cs("irq %d, io 0x%04x-0x%04x\n",
- p_dev->irq, p_dev->io.BasePort1,
- p_dev->io.BasePort1 + p_dev->io.NumPorts1 - 1);
+ lbs_deb_cs("irq %d, io %pR", p_dev->irq, p_dev->resource[0]);
/*
* Most of the libertas cards can do unaligned register access, but some
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 258967144b9..24958a86747 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -719,6 +719,7 @@ static int lbs_init_adapter(struct lbs_private *priv)
priv->deep_sleep_required = 0;
priv->wakeup_dev_required = 0;
init_waitqueue_head(&priv->ds_awake_q);
+ init_waitqueue_head(&priv->scan_q);
priv->authtype_auto = 1;
priv->is_host_sleep_configured = 0;
priv->is_host_sleep_activated = 0;
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index b16d5db52a4..ef46a2d8853 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -17,7 +17,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -192,25 +191,23 @@ static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
- p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- p_dev->io.BasePort1 = io->win[0].base;
- p_dev->io.NumPorts1 = io->win[0].len;
+ p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ p_dev->resource[0]->flags |=
+ pcmcia_io_cfg_data_width(io->flags);
+ p_dev->resource[0]->start = io->win[0].base;
+ p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
- p_dev->io.Attributes2 = p_dev->io.Attributes1;
- p_dev->io.BasePort2 = io->win[1].base;
- p_dev->io.NumPorts2 = io->win[1].len;
+ p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+ p_dev->resource[1]->start = io->win[1].base;
+ p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+ if (pcmcia_request_io(p_dev) != 0)
goto next_entry;
}
return 0;
@@ -258,7 +255,8 @@ orinoco_cs_config(struct pcmcia_device *link)
/* We initialize the hermes structure before completing PCMCIA
* configuration just in case the interrupt handler gets
* called. */
- mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
+ mem = ioport_map(link->resource[0]->start,
+ resource_size(link->resource[0]));
if (!mem)
goto failed;
@@ -280,7 +278,7 @@ orinoco_cs_config(struct pcmcia_device *link)
}
/* Register an interface with the stack */
- if (orinoco_if_add(priv, link->io.BasePort1,
+ if (orinoco_if_add(priv, link->resource[0]->start,
link->irq, NULL) != 0) {
printk(KERN_ERR PFX "orinoco_if_add() failed\n");
goto failed;
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index b51a9adc80f..873877e17e1 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -25,7 +25,6 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -80,35 +79,27 @@ static int
spectrum_reset(struct pcmcia_device *link, int idle)
{
int ret;
- conf_reg_t reg;
- u_int save_cor;
+ u8 save_cor;
+ u8 ccsr;
/* Doing it if hardware is gone is guaranteed crash */
if (!pcmcia_dev_present(link))
return -ENODEV;
/* Save original COR value */
- reg.Function = 0;
- reg.Action = CS_READ;
- reg.Offset = CISREG_COR;
- ret = pcmcia_access_configuration_register(link, &reg);
+ ret = pcmcia_read_config_byte(link, CISREG_COR, &save_cor);
if (ret)
goto failed;
- save_cor = reg.Value;
/* Soft-Reset card */
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_COR;
- reg.Value = (save_cor | COR_SOFT_RESET);
- ret = pcmcia_access_configuration_register(link, &reg);
+ ret = pcmcia_write_config_byte(link, CISREG_COR,
+ (save_cor | COR_SOFT_RESET));
if (ret)
goto failed;
udelay(1000);
/* Read CCSR */
- reg.Action = CS_READ;
- reg.Offset = CISREG_CCSR;
- ret = pcmcia_access_configuration_register(link, &reg);
+ ret = pcmcia_read_config_byte(link, CISREG_CCSR, &ccsr);
if (ret)
goto failed;
@@ -116,19 +107,15 @@ spectrum_reset(struct pcmcia_device *link, int idle)
* Start or stop the firmware. Memory width bit should be
* preserved from the value we've just read.
*/
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_CCSR;
- reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
- ret = pcmcia_access_configuration_register(link, &reg);
+ ccsr = (idle ? HCR_IDLE : HCR_RUN) | (ccsr & HCR_MEM16);
+ ret = pcmcia_write_config_byte(link, CISREG_CCSR, ccsr);
if (ret)
goto failed;
udelay(1000);
/* Restore original COR configuration index */
- reg.Action = CS_WRITE;
- reg.Offset = CISREG_COR;
- reg.Value = (save_cor & ~COR_SOFT_RESET);
- ret = pcmcia_access_configuration_register(link, &reg);
+ ret = pcmcia_write_config_byte(link, CISREG_COR,
+ (save_cor & ~COR_SOFT_RESET));
if (ret)
goto failed;
udelay(1000);
@@ -266,25 +253,23 @@ static int spectrum_cs_config_check(struct pcmcia_device *p_dev,
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
- p_dev->io.NumPorts1 = p_dev->io.NumPorts2 = 0;
+ p_dev->resource[0]->end = p_dev->resource[1]->end = 0;
if ((cfg->io.nwin > 0) || (dflt->io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt->io;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
- if (!(io->flags & CISTPL_IO_8BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
- if (!(io->flags & CISTPL_IO_16BIT))
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
- p_dev->io.BasePort1 = io->win[0].base;
- p_dev->io.NumPorts1 = io->win[0].len;
+ p_dev->io_lines = io->flags & CISTPL_IO_LINES_MASK;
+ p_dev->resource[0]->flags &= ~IO_DATA_PATH_WIDTH;
+ p_dev->resource[0]->flags |=
+ pcmcia_io_cfg_data_width(io->flags);
+ p_dev->resource[0]->start = io->win[0].base;
+ p_dev->resource[0]->end = io->win[0].len;
if (io->nwin > 1) {
- p_dev->io.Attributes2 = p_dev->io.Attributes1;
- p_dev->io.BasePort2 = io->win[1].base;
- p_dev->io.NumPorts2 = io->win[1].len;
+ p_dev->resource[1]->flags = p_dev->resource[0]->flags;
+ p_dev->resource[1]->start = io->win[1].base;
+ p_dev->resource[1]->end = io->win[1].len;
}
/* This reserves IO space but doesn't actually enable it */
- if (pcmcia_request_io(p_dev, &p_dev->io) != 0)
+ if (pcmcia_request_io(p_dev) != 0)
goto next_entry;
}
return 0;
@@ -332,7 +317,8 @@ spectrum_cs_config(struct pcmcia_device *link)
/* We initialize the hermes structure before completing PCMCIA
* configuration just in case the interrupt handler gets
* called. */
- mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
+ mem = ioport_map(link->resource[0]->start,
+ resource_size(link->resource[0]));
if (!mem)
goto failed;
@@ -359,7 +345,7 @@ spectrum_cs_config(struct pcmcia_device *link)
}
/* Register an interface with the stack */
- if (orinoco_if_add(priv, link->io.BasePort1,
+ if (orinoco_if_add(priv, link->resource[0]->start,
link->irq, NULL) != 0) {
printk(KERN_ERR PFX "orinoco_if_add() failed\n");
goto failed;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 822f8dc26e9..71a101fb2e4 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -43,6 +43,8 @@ static DEFINE_PCI_DEVICE_TABLE(p54p_table) = {
{ PCI_DEVICE(0x1260, 0x3886) },
/* Intersil PRISM Xbow Wireless LAN adapter (Symbol AP-300) */
{ PCI_DEVICE(0x1260, 0xffff) },
+ /* Standard Microsystems Corp SMC2802W Wireless PCI */
+ { PCI_DEVICE(0x10b8, 0x2802) },
{ },
};
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 9c38fc331dc..88560d0ae50 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -46,7 +46,6 @@
#include <linux/ethtool.h>
#include <linux/ieee80211.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -315,9 +314,8 @@ static int ray_probe(struct pcmcia_device *p_dev)
local->finder = p_dev;
/* The io structure describes IO port mapping. None used here */
- p_dev->io.NumPorts1 = 0;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.IOAddrLines = 5;
+ p_dev->resource[0]->end = 0;
+ p_dev->resource[0]->flags |= IO_DATA_PATH_WIDTH_8;
/* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
@@ -394,7 +392,6 @@ static int ray_config(struct pcmcia_device *link)
int ret = 0;
int i;
win_req_t req;
- memreq_t mem;
struct net_device *dev = (struct net_device *)link->priv;
ray_dev_t *local = netdev_priv(dev);
@@ -431,9 +428,7 @@ static int ray_config(struct pcmcia_device *link)
ret = pcmcia_request_window(link, &req, &link->win);
if (ret)
goto failed;
- mem.CardOffset = 0x0000;
- mem.Page = 0;
- ret = pcmcia_map_mem_page(link, link->win, &mem);
+ ret = pcmcia_map_mem_page(link, link->win, 0);
if (ret)
goto failed;
local->sram = ioremap(req.Base, req.Size);
@@ -447,9 +442,7 @@ static int ray_config(struct pcmcia_device *link)
ret = pcmcia_request_window(link, &req, &local->rmem_handle);
if (ret)
goto failed;
- mem.CardOffset = 0x8000;
- mem.Page = 0;
- ret = pcmcia_map_mem_page(link, local->rmem_handle, &mem);
+ ret = pcmcia_map_mem_page(link, local->rmem_handle, 0x8000);
if (ret)
goto failed;
local->rmem = ioremap(req.Base, req.Size);
@@ -463,9 +456,7 @@ static int ray_config(struct pcmcia_device *link)
ret = pcmcia_request_window(link, &req, &local->amem_handle);
if (ret)
goto failed;
- mem.CardOffset = 0x0000;
- mem.Page = 0;
- ret = pcmcia_map_mem_page(link, local->amem_handle, &mem);
+ ret = pcmcia_map_mem_page(link, local->amem_handle, 0);
if (ret)
goto failed;
local->amem = ioremap(req.Base, req.Size);
@@ -793,7 +784,6 @@ static void ray_release(struct pcmcia_device *link)
{
struct net_device *dev = link->priv;
ray_dev_t *local = netdev_priv(dev);
- int i;
dev_dbg(&link->dev, "ray_release\n");
@@ -802,13 +792,6 @@ static void ray_release(struct pcmcia_device *link)
iounmap(local->sram);
iounmap(local->rmem);
iounmap(local->amem);
- /* Do bother checking to see if these succeed or not */
- i = pcmcia_release_window(link, local->amem_handle);
- if (i != 0)
- dev_dbg(&link->dev, "ReleaseWindow(local->amem) ret = %x\n", i);
- i = pcmcia_release_window(link, local->rmem_handle);
- if (i != 0)
- dev_dbg(&link->dev, "ReleaseWindow(local->rmem) ret = %x\n", i);
pcmcia_disable_device(link);
dev_dbg(&link->dev, "ray_release ending\n");
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index 19b262e1ddb..63c2cc408e1 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -240,16 +240,16 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
struct rt2x00_dev *rt2x00dev;
int retval;
- retval = pci_request_regions(pci_dev, pci_name(pci_dev));
+ retval = pci_enable_device(pci_dev);
if (retval) {
- ERROR_PROBE("PCI request regions failed.\n");
+ ERROR_PROBE("Enable device failed.\n");
return retval;
}
- retval = pci_enable_device(pci_dev);
+ retval = pci_request_regions(pci_dev, pci_name(pci_dev));
if (retval) {
- ERROR_PROBE("Enable device failed.\n");
- goto exit_release_regions;
+ ERROR_PROBE("PCI request regions failed.\n");
+ goto exit_disable_device;
}
pci_set_master(pci_dev);
@@ -260,14 +260,14 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
if (dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(32))) {
ERROR_PROBE("PCI DMA not supported.\n");
retval = -EIO;
- goto exit_disable_device;
+ goto exit_release_regions;
}
hw = ieee80211_alloc_hw(sizeof(struct rt2x00_dev), ops->hw);
if (!hw) {
ERROR_PROBE("Failed to allocate hardware.\n");
retval = -ENOMEM;
- goto exit_disable_device;
+ goto exit_release_regions;
}
pci_set_drvdata(pci_dev, hw);
@@ -300,13 +300,12 @@ exit_free_reg:
exit_free_device:
ieee80211_free_hw(hw);
-exit_disable_device:
- if (retval != -EBUSY)
- pci_disable_device(pci_dev);
-
exit_release_regions:
pci_release_regions(pci_dev);
+exit_disable_device:
+ pci_disable_device(pci_dev);
+
pci_set_drvdata(pci_dev, NULL);
return retval;
diff --git a/drivers/net/wireless/rtl818x/rtl8180_dev.c b/drivers/net/wireless/rtl818x/rtl8180_dev.c
index 1d8178563d7..b50c39aaec0 100644
--- a/drivers/net/wireless/rtl818x/rtl8180_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180_dev.c
@@ -695,6 +695,8 @@ static void rtl8180_beacon_work(struct work_struct *work)
/* grab a fresh beacon */
skb = ieee80211_beacon_get(dev, vif);
+ if (!skb)
+ goto resched;
/*
* update beacon timestamp w/ TSF value
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 96d25fb5049..4cb99c541e2 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -160,9 +160,8 @@ static void wl1271_spi_init(struct wl1271 *wl)
spi_message_add_tail(&t, &m);
spi_sync(wl_to_spi(wl), &m);
- kfree(cmd);
-
wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);
+ kfree(cmd);
}
#define WL1271_BUSY_WORD_TIMEOUT 1000
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 376c6b964a9..a1cc2d498a1 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -48,7 +48,6 @@
#include <net/iw_handler.h>
-#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
@@ -89,13 +88,6 @@
static int wl3501_config(struct pcmcia_device *link);
static void wl3501_release(struct pcmcia_device *link);
-/*
- * The dev_info variable is the "key" that is used to match up this
- * device driver with appropriate cards, through the card configuration
- * database.
- */
-static dev_info_t wl3501_dev_info = "wl3501_cs";
-
static const struct {
int reg_domain;
int min, max, deflt;
@@ -1421,7 +1413,7 @@ static struct iw_statistics *wl3501_get_wireless_stats(struct net_device *dev)
static void wl3501_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- strlcpy(info->driver, wl3501_dev_info, sizeof(info->driver));
+ strlcpy(info->driver, "wl3501_cs", sizeof(info->driver));
}
static const struct ethtool_ops ops = {
@@ -1892,9 +1884,8 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
struct wl3501_card *this;
/* The io structure describes IO port mapping */
- p_dev->io.NumPorts1 = 16;
- p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
- p_dev->io.IOAddrLines = 5;
+ p_dev->resource[0]->end = 16;
+ p_dev->resource[0]->flags = IO_DATA_PATH_WIDTH_8;
/* General socket configuration */
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
@@ -1940,13 +1931,14 @@ static int wl3501_config(struct pcmcia_device *link)
/* Try allocating IO ports. This tries a few fixed addresses. If you
* want, you can also read the card's config table to pick addresses --
* see the serial driver for an example. */
+ link->io_lines = 5;
for (j = 0x280; j < 0x400; j += 0x20) {
/* The '^0x300' is so that we probe 0x300-0x3ff first, then
* 0x200-0x2ff, and so on, because this seems safer */
- link->io.BasePort1 = j;
- link->io.BasePort2 = link->io.BasePort1 + 0x10;
- i = pcmcia_request_io(link, &link->io);
+ link->resource[0]->start = j;
+ link->resource[1]->start = link->resource[0]->start + 0x10;
+ i = pcmcia_request_io(link);
if (i == 0)
break;
}
@@ -1968,7 +1960,7 @@ static int wl3501_config(struct pcmcia_device *link)
goto failed;
dev->irq = link->irq;
- dev->base_addr = link->io.BasePort1;
+ dev->base_addr = link->resource[0]->start;
SET_NETDEV_DEV(dev, &link->dev);
if (register_netdev(dev)) {
printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index d04c5b26205..b2c2f391b29 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -20,7 +20,7 @@
#include <linux/skbuff.h>
#include <linux/io.h>
#include <linux/slab.h>
-
+#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/of_mdio.h>