aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@evo.osdl.org>2005-09-06 03:47:18 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-06 03:47:18 -0400
commit5bcaa155797ab62ed363932ec0f02fbcb5db1ef1 (patch)
tree1db633712bd47ce72ac5a1aed62b3417733ac63a /drivers/net
parent1e231efe50ffe4d291be24d2fe393188de9c4b08 (diff)
parent3a48c4c2d52a08e12319ab7caacad0a9b88e6cb4 (diff)
Merge branch 'upstream' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig9
-rw-r--r--drivers/net/chelsio/common.h4
-rw-r--r--drivers/net/chelsio/cxgb2.c2
-rw-r--r--drivers/net/e1000/e1000_hw.h2
-rw-r--r--drivers/net/mv643xx_eth.c139
-rw-r--r--drivers/net/mv643xx_eth.h4
-rw-r--r--drivers/net/ne3210.c9
-rw-r--r--drivers/net/phy/Kconfig2
-rw-r--r--drivers/net/phy/mdio_bus.c2
-rw-r--r--drivers/net/s2io.c14
-rw-r--r--drivers/net/sis190.c131
-rw-r--r--drivers/net/tulip/uli526x.c2
-rw-r--r--drivers/net/wireless/Kconfig38
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ipw2100.c69
-rw-r--r--drivers/net/wireless/ipw2200.h1
-rw-r--r--drivers/net/wireless/orinoco.c93
-rw-r--r--drivers/net/wireless/orinoco_cs.c1
-rw-r--r--drivers/net/wireless/orinoco_nortel.c324
-rw-r--r--drivers/net/wireless/spectrum_cs.c1120
20 files changed, 1735 insertions, 233 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 7d8bcb38797a..ae9e7a579b94 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -397,7 +397,7 @@ config SUN3LANCE
397 If you're not building a kernel for a Sun 3, say N. 397 If you're not building a kernel for a Sun 3, say N.
398 398
399config SUN3_82586 399config SUN3_82586
400 tristate "Sun3 on-board Intel 82586 support" 400 bool "Sun3 on-board Intel 82586 support"
401 depends on NET_ETHERNET && SUN3 401 depends on NET_ETHERNET && SUN3
402 help 402 help
403 This driver enables support for the on-board Intel 82586 based 403 This driver enables support for the on-board Intel 82586 based
@@ -1924,12 +1924,15 @@ config R8169_VLAN
1924 If in doubt, say Y. 1924 If in doubt, say Y.
1925 1925
1926config SIS190 1926config SIS190
1927 tristate "SiS190 gigabit ethernet support" 1927 tristate "SiS190/SiS191 gigabit ethernet support"
1928 depends on PCI 1928 depends on PCI
1929 select CRC32 1929 select CRC32
1930 select MII 1930 select MII
1931 ---help--- 1931 ---help---
1932 Say Y here if you have a SiS 190 PCI Gigabit Ethernet adapter. 1932 Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or
1933 a SiS 191 PCI Gigabit Ethernet adapter. Both are expected to
1934 appear in lan on motherboard designs which are based on SiS 965
1935 and SiS 966 south bridge.
1933 1936
1934 To compile this driver as a module, choose M here: the module 1937 To compile this driver as a module, choose M here: the module
1935 will be called sis190. This is recommended. 1938 will be called sis190. This is recommended.
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index f09348802b46..bf3e7b6a7a18 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -88,7 +88,7 @@ struct t1_rx_mode {
88 88
89static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm) 89static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm)
90{ 90{
91 u8 *addr = 0; 91 u8 *addr = NULL;
92 92
93 if (rm->idx++ < rm->dev->mc_count) { 93 if (rm->idx++ < rm->dev->mc_count) {
94 addr = rm->list->dmi_addr; 94 addr = rm->list->dmi_addr;
@@ -190,7 +190,7 @@ struct sge;
190struct peespi; 190struct peespi;
191 191
192struct adapter { 192struct adapter {
193 u8 *regs; 193 u8 __iomem *regs;
194 struct pci_dev *pdev; 194 struct pci_dev *pdev;
195 unsigned long registered_device_map; 195 unsigned long registered_device_map;
196 unsigned long open_device_map; 196 unsigned long open_device_map;
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index 28ae478b386d..349ebe783ed6 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -824,7 +824,7 @@ static void cxgb_proc_cleanup(struct adapter *adapter,
824static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd) 824static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
825{ 825{
826 struct adapter *adapter = dev->priv; 826 struct adapter *adapter = dev->priv;
827 struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data; 827 struct mii_ioctl_data *data = if_mii(req);
828 828
829 switch (cmd) { 829 switch (cmd) {
830 case SIOCGMIIPHY: 830 case SIOCGMIIPHY:
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 93e9f8788751..51c2b3a18b6f 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1270,7 +1270,7 @@ struct e1000_hw_stats {
1270 1270
1271/* Structure containing variables used by the shared code (e1000_hw.c) */ 1271/* Structure containing variables used by the shared code (e1000_hw.c) */
1272struct e1000_hw { 1272struct e1000_hw {
1273 uint8_t *hw_addr; 1273 uint8_t __iomem *hw_addr;
1274 uint8_t *flash_address; 1274 uint8_t *flash_address;
1275 e1000_mac_type mac_type; 1275 e1000_mac_type mac_type;
1276 e1000_phy_type phy_type; 1276 e1000_phy_type phy_type;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index fb6b232069d6..7c9dbc8c9423 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -58,11 +58,10 @@
58 58
59#define INT_CAUSE_UNMASK_ALL 0x0007ffff 59#define INT_CAUSE_UNMASK_ALL 0x0007ffff
60#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff 60#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff
61#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
62#define INT_CAUSE_MASK_ALL 0x00000000 61#define INT_CAUSE_MASK_ALL 0x00000000
62#define INT_CAUSE_MASK_ALL_EXT 0x00000000
63#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL 63#define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL
64#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT 64#define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT
65#endif
66 65
67#ifdef MV643XX_CHECKSUM_OFFLOAD_TX 66#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
68#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1) 67#define MAX_DESCS_PER_SKB (MAX_SKB_FRAGS + 1)
@@ -259,14 +258,13 @@ static void mv643xx_eth_update_mac_address(struct net_device *dev)
259static void mv643xx_eth_set_rx_mode(struct net_device *dev) 258static void mv643xx_eth_set_rx_mode(struct net_device *dev)
260{ 259{
261 struct mv643xx_private *mp = netdev_priv(dev); 260 struct mv643xx_private *mp = netdev_priv(dev);
262 u32 config_reg;
263 261
264 config_reg = ethernet_get_config_reg(mp->port_num);
265 if (dev->flags & IFF_PROMISC) 262 if (dev->flags & IFF_PROMISC)
266 config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; 263 mp->port_config |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
267 else 264 else
268 config_reg &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; 265 mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
269 ethernet_set_config_reg(mp->port_num, config_reg); 266
267 mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config);
270} 268}
271 269
272/* 270/*
@@ -369,15 +367,6 @@ static int mv643xx_eth_free_tx_queue(struct net_device *dev,
369 367
370 dev_kfree_skb_irq(pkt_info.return_info); 368 dev_kfree_skb_irq(pkt_info.return_info);
371 released = 0; 369 released = 0;
372
373 /*
374 * Decrement the number of outstanding skbs counter on
375 * the TX queue.
376 */
377 if (mp->tx_ring_skbs == 0)
378 panic("ERROR - TX outstanding SKBs"
379 " counter is corrupted");
380 mp->tx_ring_skbs--;
381 } else 370 } else
382 dma_unmap_page(NULL, pkt_info.buf_ptr, 371 dma_unmap_page(NULL, pkt_info.buf_ptr,
383 pkt_info.byte_cnt, DMA_TO_DEVICE); 372 pkt_info.byte_cnt, DMA_TO_DEVICE);
@@ -412,15 +401,13 @@ static int mv643xx_eth_receive_queue(struct net_device *dev)
412 struct pkt_info pkt_info; 401 struct pkt_info pkt_info;
413 402
414#ifdef MV643XX_NAPI 403#ifdef MV643XX_NAPI
415 while (eth_port_receive(mp, &pkt_info) == ETH_OK && budget > 0) { 404 while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
416#else 405#else
417 while (eth_port_receive(mp, &pkt_info) == ETH_OK) { 406 while (eth_port_receive(mp, &pkt_info) == ETH_OK) {
418#endif 407#endif
419 mp->rx_ring_skbs--; 408 mp->rx_ring_skbs--;
420 received_packets++; 409 received_packets++;
421#ifdef MV643XX_NAPI 410
422 budget--;
423#endif
424 /* Update statistics. Note byte count includes 4 byte CRC count */ 411 /* Update statistics. Note byte count includes 4 byte CRC count */
425 stats->rx_packets++; 412 stats->rx_packets++;
426 stats->rx_bytes += pkt_info.byte_cnt; 413 stats->rx_bytes += pkt_info.byte_cnt;
@@ -1044,9 +1031,6 @@ static void mv643xx_tx(struct net_device *dev)
1044 DMA_TO_DEVICE); 1031 DMA_TO_DEVICE);
1045 1032
1046 dev_kfree_skb_irq(pkt_info.return_info); 1033 dev_kfree_skb_irq(pkt_info.return_info);
1047
1048 if (mp->tx_ring_skbs)
1049 mp->tx_ring_skbs--;
1050 } else 1034 } else
1051 dma_unmap_page(NULL, pkt_info.buf_ptr, 1035 dma_unmap_page(NULL, pkt_info.buf_ptr,
1052 pkt_info.byte_cnt, DMA_TO_DEVICE); 1036 pkt_info.byte_cnt, DMA_TO_DEVICE);
@@ -1189,7 +1173,6 @@ linear:
1189 pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len, 1173 pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
1190 DMA_TO_DEVICE); 1174 DMA_TO_DEVICE);
1191 pkt_info.return_info = skb; 1175 pkt_info.return_info = skb;
1192 mp->tx_ring_skbs++;
1193 status = eth_port_send(mp, &pkt_info); 1176 status = eth_port_send(mp, &pkt_info);
1194 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) 1177 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
1195 printk(KERN_ERR "%s: Error on transmitting packet\n", 1178 printk(KERN_ERR "%s: Error on transmitting packet\n",
@@ -1274,7 +1257,6 @@ linear:
1274 pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT | 1257 pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT |
1275 ETH_TX_LAST_DESC; 1258 ETH_TX_LAST_DESC;
1276 pkt_info.return_info = skb; 1259 pkt_info.return_info = skb;
1277 mp->tx_ring_skbs++;
1278 } else { 1260 } else {
1279 pkt_info.return_info = 0; 1261 pkt_info.return_info = 0;
1280 } 1262 }
@@ -1311,7 +1293,6 @@ linear:
1311 pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len, 1293 pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
1312 DMA_TO_DEVICE); 1294 DMA_TO_DEVICE);
1313 pkt_info.return_info = skb; 1295 pkt_info.return_info = skb;
1314 mp->tx_ring_skbs++;
1315 status = eth_port_send(mp, &pkt_info); 1296 status = eth_port_send(mp, &pkt_info);
1316 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL)) 1297 if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
1317 printk(KERN_ERR "%s: Error on transmitting packet\n", 1298 printk(KERN_ERR "%s: Error on transmitting packet\n",
@@ -1356,6 +1337,43 @@ static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev)
1356 return &mp->stats; 1337 return &mp->stats;
1357} 1338}
1358 1339
1340#ifdef CONFIG_NET_POLL_CONTROLLER
1341static inline void mv643xx_enable_irq(struct mv643xx_private *mp)
1342{
1343 int port_num = mp->port_num;
1344 unsigned long flags;
1345
1346 spin_lock_irqsave(&mp->lock, flags);
1347 mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
1348 INT_CAUSE_UNMASK_ALL);
1349 mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
1350 INT_CAUSE_UNMASK_ALL_EXT);
1351 spin_unlock_irqrestore(&mp->lock, flags);
1352}
1353
1354static inline void mv643xx_disable_irq(struct mv643xx_private *mp)
1355{
1356 int port_num = mp->port_num;
1357 unsigned long flags;
1358
1359 spin_lock_irqsave(&mp->lock, flags);
1360 mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
1361 INT_CAUSE_MASK_ALL);
1362 mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
1363 INT_CAUSE_MASK_ALL_EXT);
1364 spin_unlock_irqrestore(&mp->lock, flags);
1365}
1366
1367static void mv643xx_netpoll(struct net_device *netdev)
1368{
1369 struct mv643xx_private *mp = netdev_priv(netdev);
1370
1371 mv643xx_disable_irq(mp);
1372 mv643xx_eth_int_handler(netdev->irq, netdev, NULL);
1373 mv643xx_enable_irq(mp);
1374}
1375#endif
1376
1359/*/ 1377/*/
1360 * mv643xx_eth_probe 1378 * mv643xx_eth_probe
1361 * 1379 *
@@ -1406,6 +1424,10 @@ static int mv643xx_eth_probe(struct device *ddev)
1406 dev->weight = 64; 1424 dev->weight = 64;
1407#endif 1425#endif
1408 1426
1427#ifdef CONFIG_NET_POLL_CONTROLLER
1428 dev->poll_controller = mv643xx_netpoll;
1429#endif
1430
1409 dev->watchdog_timeo = 2 * HZ; 1431 dev->watchdog_timeo = 2 * HZ;
1410 dev->tx_queue_len = mp->tx_ring_size; 1432 dev->tx_queue_len = mp->tx_ring_size;
1411 dev->base_addr = 0; 1433 dev->base_addr = 0;
@@ -1883,6 +1905,9 @@ static void eth_port_start(struct mv643xx_private *mp)
1883 /* Enable port Rx. */ 1905 /* Enable port Rx. */
1884 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 1906 mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
1885 mp->port_rx_queue_command); 1907 mp->port_rx_queue_command);
1908
1909 /* Disable port bandwidth limits by clearing MTU register */
1910 mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0);
1886} 1911}
1887 1912
1888/* 1913/*
@@ -2292,34 +2317,6 @@ static void eth_port_reset(unsigned int port_num)
2292 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data); 2317 mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data);
2293} 2318}
2294 2319
2295/*
2296 * ethernet_set_config_reg - Set specified bits in configuration register.
2297 *
2298 * DESCRIPTION:
2299 * This function sets specified bits in the given ethernet
2300 * configuration register.
2301 *
2302 * INPUT:
2303 * unsigned int eth_port_num Ethernet Port number.
2304 * unsigned int value 32 bit value.
2305 *
2306 * OUTPUT:
2307 * The set bits in the value parameter are set in the configuration
2308 * register.
2309 *
2310 * RETURN:
2311 * None.
2312 *
2313 */
2314static void ethernet_set_config_reg(unsigned int eth_port_num,
2315 unsigned int value)
2316{
2317 unsigned int eth_config_reg;
2318
2319 eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num));
2320 eth_config_reg |= value;
2321 mv_write(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num), eth_config_reg);
2322}
2323 2320
2324static int eth_port_autoneg_supported(unsigned int eth_port_num) 2321static int eth_port_autoneg_supported(unsigned int eth_port_num)
2325{ 2322{
@@ -2346,31 +2343,6 @@ static int eth_port_link_is_up(unsigned int eth_port_num)
2346} 2343}
2347 2344
2348/* 2345/*
2349 * ethernet_get_config_reg - Get the port configuration register
2350 *
2351 * DESCRIPTION:
2352 * This function returns the configuration register value of the given
2353 * ethernet port.
2354 *
2355 * INPUT:
2356 * unsigned int eth_port_num Ethernet Port number.
2357 *
2358 * OUTPUT:
2359 * None.
2360 *
2361 * RETURN:
2362 * Port configuration register value.
2363 */
2364static unsigned int ethernet_get_config_reg(unsigned int eth_port_num)
2365{
2366 unsigned int eth_config_reg;
2367
2368 eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_EXTEND_REG
2369 (eth_port_num));
2370 return eth_config_reg;
2371}
2372
2373/*
2374 * eth_port_read_smi_reg - Read PHY registers 2346 * eth_port_read_smi_reg - Read PHY registers
2375 * 2347 *
2376 * DESCRIPTION: 2348 * DESCRIPTION:
@@ -2528,6 +2500,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2528 return ETH_ERROR; 2500 return ETH_ERROR;
2529 } 2501 }
2530 2502
2503 mp->tx_ring_skbs++;
2504 BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
2505
2531 /* Get the Tx Desc ring indexes */ 2506 /* Get the Tx Desc ring indexes */
2532 tx_desc_curr = mp->tx_curr_desc_q; 2507 tx_desc_curr = mp->tx_curr_desc_q;
2533 tx_desc_used = mp->tx_used_desc_q; 2508 tx_desc_used = mp->tx_used_desc_q;
@@ -2594,6 +2569,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp,
2594 if (mp->tx_resource_err) 2569 if (mp->tx_resource_err)
2595 return ETH_QUEUE_FULL; 2570 return ETH_QUEUE_FULL;
2596 2571
2572 mp->tx_ring_skbs++;
2573 BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
2574
2597 /* Get the Tx Desc ring indexes */ 2575 /* Get the Tx Desc ring indexes */
2598 tx_desc_curr = mp->tx_curr_desc_q; 2576 tx_desc_curr = mp->tx_curr_desc_q;
2599 tx_desc_used = mp->tx_used_desc_q; 2577 tx_desc_used = mp->tx_used_desc_q;
@@ -2694,6 +2672,9 @@ static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp,
2694 /* Any Tx return cancels the Tx resource error status */ 2672 /* Any Tx return cancels the Tx resource error status */
2695 mp->tx_resource_err = 0; 2673 mp->tx_resource_err = 0;
2696 2674
2675 BUG_ON(mp->tx_ring_skbs == 0);
2676 mp->tx_ring_skbs--;
2677
2697 return ETH_OK; 2678 return ETH_OK;
2698} 2679}
2699 2680
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
index 7678b59c2952..bcfda5192da0 100644
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -408,10 +408,6 @@ static void eth_port_init(struct mv643xx_private *mp);
408static void eth_port_reset(unsigned int eth_port_num); 408static void eth_port_reset(unsigned int eth_port_num);
409static void eth_port_start(struct mv643xx_private *mp); 409static void eth_port_start(struct mv643xx_private *mp);
410 410
411static void ethernet_set_config_reg(unsigned int eth_port_num,
412 unsigned int value);
413static unsigned int ethernet_get_config_reg(unsigned int eth_port_num);
414
415/* Port MAC address routines */ 411/* Port MAC address routines */
416static void eth_port_uc_addr_set(unsigned int eth_port_num, 412static void eth_port_uc_addr_set(unsigned int eth_port_num,
417 unsigned char *p_addr); 413 unsigned char *p_addr);
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
index 6c92f0969015..73501d846588 100644
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -26,9 +26,6 @@
26 Updated to EISA probing API 5/2003 by Marc Zyngier. 26 Updated to EISA probing API 5/2003 by Marc Zyngier.
27*/ 27*/
28 28
29static const char *version =
30 "ne3210.c: Driver revision v0.03, 30/09/98\n";
31
32#include <linux/module.h> 29#include <linux/module.h>
33#include <linux/eisa.h> 30#include <linux/eisa.h>
34#include <linux/kernel.h> 31#include <linux/kernel.h>
@@ -197,7 +194,7 @@ static int __init ne3210_eisa_probe (struct device *device)
197 ei_status.priv = phys_mem; 194 ei_status.priv = phys_mem;
198 195
199 if (ei_debug > 0) 196 if (ei_debug > 0)
200 printk(version); 197 printk("ne3210 loaded.\n");
201 198
202 ei_status.reset_8390 = &ne3210_reset_8390; 199 ei_status.reset_8390 = &ne3210_reset_8390;
203 ei_status.block_input = &ne3210_block_input; 200 ei_status.block_input = &ne3210_block_input;
@@ -360,12 +357,12 @@ MODULE_DESCRIPTION("NE3210 EISA Ethernet driver");
360MODULE_LICENSE("GPL"); 357MODULE_LICENSE("GPL");
361MODULE_DEVICE_TABLE(eisa, ne3210_ids); 358MODULE_DEVICE_TABLE(eisa, ne3210_ids);
362 359
363int ne3210_init(void) 360static int ne3210_init(void)
364{ 361{
365 return eisa_driver_register (&ne3210_eisa_driver); 362 return eisa_driver_register (&ne3210_eisa_driver);
366} 363}
367 364
368void ne3210_cleanup(void) 365static void ne3210_cleanup(void)
369{ 366{
370 eisa_driver_unregister (&ne3210_eisa_driver); 367 eisa_driver_unregister (&ne3210_eisa_driver);
371} 368}
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 6a2fe3583478..14f4de1a8180 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -6,7 +6,7 @@ menu "PHY device support"
6 6
7config PHYLIB 7config PHYLIB
8 tristate "PHY Device support and infrastructure" 8 tristate "PHY Device support and infrastructure"
9 depends on NET_ETHERNET 9 depends on NET_ETHERNET && (BROKEN || !ARCH_S390)
10 help 10 help
11 Ethernet controllers are usually attached to PHY 11 Ethernet controllers are usually attached to PHY
12 devices. This option provides infrastructure for 12 devices. This option provides infrastructure for
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 5e81494e9a9a..90630672703d 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -170,7 +170,7 @@ int __init mdio_bus_init(void)
170 return bus_register(&mdio_bus_type); 170 return bus_register(&mdio_bus_type);
171} 171}
172 172
173void __exit mdio_bus_exit(void) 173void mdio_bus_exit(void)
174{ 174{
175 bus_unregister(&mdio_bus_type); 175 bus_unregister(&mdio_bus_type);
176} 176}
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 7ca78228b104..5dda043bd9d7 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -686,7 +686,7 @@ static void free_shared_mem(struct s2io_nic *nic)
686 686
687static int s2io_verify_pci_mode(nic_t *nic) 687static int s2io_verify_pci_mode(nic_t *nic)
688{ 688{
689 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 689 XENA_dev_config_t __iomem *bar0 = nic->bar0;
690 register u64 val64 = 0; 690 register u64 val64 = 0;
691 int mode; 691 int mode;
692 692
@@ -704,7 +704,7 @@ static int s2io_verify_pci_mode(nic_t *nic)
704 */ 704 */
705static int s2io_print_pci_mode(nic_t *nic) 705static int s2io_print_pci_mode(nic_t *nic)
706{ 706{
707 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 707 XENA_dev_config_t __iomem *bar0 = nic->bar0;
708 register u64 val64 = 0; 708 register u64 val64 = 0;
709 int mode; 709 int mode;
710 struct config_param *config = &nic->config; 710 struct config_param *config = &nic->config;
@@ -1403,7 +1403,7 @@ static int init_nic(struct s2io_nic *nic)
1403 writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7); 1403 writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7);
1404 1404
1405 /* Disable RMAC PAD STRIPPING */ 1405 /* Disable RMAC PAD STRIPPING */
1406 add = (void *) &bar0->mac_cfg; 1406 add = &bar0->mac_cfg;
1407 val64 = readq(&bar0->mac_cfg); 1407 val64 = readq(&bar0->mac_cfg);
1408 val64 &= ~(MAC_CFG_RMAC_STRIP_PAD); 1408 val64 &= ~(MAC_CFG_RMAC_STRIP_PAD);
1409 writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); 1409 writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
@@ -1934,7 +1934,7 @@ static int start_nic(struct s2io_nic *nic)
1934 val64 |= 0x0000800000000000ULL; 1934 val64 |= 0x0000800000000000ULL;
1935 writeq(val64, &bar0->gpio_control); 1935 writeq(val64, &bar0->gpio_control);
1936 val64 = 0x0411040400000000ULL; 1936 val64 = 0x0411040400000000ULL;
1937 writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700)); 1937 writeq(val64, (void __iomem *)bar0 + 0x2700);
1938 } 1938 }
1939 1939
1940 /* 1940 /*
@@ -2395,7 +2395,7 @@ static int s2io_poll(struct net_device *dev, int *budget)
2395 int pkt_cnt = 0, org_pkts_to_process; 2395 int pkt_cnt = 0, org_pkts_to_process;
2396 mac_info_t *mac_control; 2396 mac_info_t *mac_control;
2397 struct config_param *config; 2397 struct config_param *config;
2398 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; 2398 XENA_dev_config_t __iomem *bar0 = nic->bar0;
2399 u64 val64; 2399 u64 val64;
2400 int i; 2400 int i;
2401 2401
@@ -2831,7 +2831,7 @@ void s2io_reset(nic_t * sp)
2831 val64 |= 0x0000800000000000ULL; 2831 val64 |= 0x0000800000000000ULL;
2832 writeq(val64, &bar0->gpio_control); 2832 writeq(val64, &bar0->gpio_control);
2833 val64 = 0x0411040400000000ULL; 2833 val64 = 0x0411040400000000ULL;
2834 writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700)); 2834 writeq(val64, (void __iomem *)bar0 + 0x2700);
2835 } 2835 }
2836 2836
2837 /* 2837 /*
@@ -3234,7 +3234,7 @@ s2io_alarm_handle(unsigned long data)
3234 3234
3235static void s2io_txpic_intr_handle(nic_t *sp) 3235static void s2io_txpic_intr_handle(nic_t *sp)
3236{ 3236{
3237 XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; 3237 XENA_dev_config_t __iomem *bar0 = sp->bar0;
3238 u64 val64; 3238 u64 val64;
3239 3239
3240 val64 = readq(&bar0->pic_int_status); 3240 val64 = readq(&bar0->pic_int_status);
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index bf3440aa6c24..92f75529eff8 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -179,14 +179,6 @@ enum sis190_register_content {
179 TxInterFrameGapShift = 24, 179 TxInterFrameGapShift = 24,
180 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ 180 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
181 181
182 /* StationControl */
183 _1000bpsF = 0x1c00,
184 _1000bpsH = 0x0c00,
185 _100bpsF = 0x1800,
186 _100bpsH = 0x0800,
187 _10bpsF = 0x1400,
188 _10bpsH = 0x0400,
189
190 LinkStatus = 0x02, // unused 182 LinkStatus = 0x02, // unused
191 FullDup = 0x01, // unused 183 FullDup = 0x01, // unused
192 184
@@ -279,6 +271,12 @@ enum sis190_eeprom_address {
279 EEPROMMACAddr = 0x03 271 EEPROMMACAddr = 0x03
280}; 272};
281 273
274enum sis190_feature {
275 F_HAS_RGMII = 1,
276 F_PHY_88E1111 = 2,
277 F_PHY_BCM5461 = 4
278};
279
282struct sis190_private { 280struct sis190_private {
283 void __iomem *mmio_addr; 281 void __iomem *mmio_addr;
284 struct pci_dev *pci_dev; 282 struct pci_dev *pci_dev;
@@ -300,6 +298,7 @@ struct sis190_private {
300 u32 msg_enable; 298 u32 msg_enable;
301 struct mii_if_info mii_if; 299 struct mii_if_info mii_if;
302 struct list_head first_phy; 300 struct list_head first_phy;
301 u32 features;
303}; 302};
304 303
305struct sis190_phy { 304struct sis190_phy {
@@ -321,24 +320,25 @@ static struct mii_chip_info {
321 const char *name; 320 const char *name;
322 u16 id[2]; 321 u16 id[2];
323 unsigned int type; 322 unsigned int type;
323 u32 feature;
324} mii_chip_table[] = { 324} mii_chip_table[] = {
325 { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN }, 325 { "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
326 { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN }, 326 { "Agere PHY ET1101B", { 0x0282, 0xf010 }, LAN, 0 },
327 { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN }, 327 { "Marvell PHY 88E1111", { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 },
328 { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN }, 328 { "Realtek PHY RTL8201", { 0x0000, 0x8200 }, LAN, 0 },
329 { NULL, } 329 { NULL, }
330}; 330};
331 331
332const static struct { 332const static struct {
333 const char *name; 333 const char *name;
334 u8 version; /* depend on docs */
335 u32 RxConfigMask; /* clear the bits supported by this chip */
336} sis_chip_info[] = { 334} sis_chip_info[] = {
337 { DRV_NAME, 0x00, 0xff7e1880, }, 335 { "SiS 190 PCI Fast Ethernet adapter" },
336 { "SiS 191 PCI Gigabit Ethernet adapter" },
338}; 337};
339 338
340static struct pci_device_id sis190_pci_tbl[] __devinitdata = { 339static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
341 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 }, 340 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
341 { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
342 { 0, }, 342 { 0, },
343}; 343};
344 344
@@ -360,7 +360,7 @@ MODULE_VERSION(DRV_VERSION);
360MODULE_LICENSE("GPL"); 360MODULE_LICENSE("GPL");
361 361
362static const u32 sis190_intr_mask = 362static const u32 sis190_intr_mask =
363 RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt; 363 RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt | LinkChange;
364 364
365/* 365/*
366 * Maximum number of multicast addresses to filter (vs. Rx-all-multicast). 366 * Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
@@ -879,11 +879,6 @@ static void sis190_hw_start(struct net_device *dev)
879 879
880 SIS_W32(IntrStatus, 0xffffffff); 880 SIS_W32(IntrStatus, 0xffffffff);
881 SIS_W32(IntrMask, 0x0); 881 SIS_W32(IntrMask, 0x0);
882 /*
883 * Default is 100Mbps.
884 * A bit strange: 100Mbps is 0x1801 elsewhere -- FR 2005/06/09
885 */
886 SIS_W16(StationControl, 0x1901);
887 SIS_W32(GMIIControl, 0x0); 882 SIS_W32(GMIIControl, 0x0);
888 SIS_W32(TxMacControl, 0x60); 883 SIS_W32(TxMacControl, 0x60);
889 SIS_W16(RxMacControl, 0x02); 884 SIS_W16(RxMacControl, 0x02);
@@ -923,35 +918,30 @@ static void sis190_phy_task(void * data)
923 BMSR_ANEGCOMPLETE)) { 918 BMSR_ANEGCOMPLETE)) {
924 net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n", 919 net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n",
925 dev->name); 920 dev->name);
921 netif_carrier_off(dev);
926 mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET); 922 mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET);
927 mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT); 923 mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
928 } else { 924 } else {
929 /* Rejoice ! */ 925 /* Rejoice ! */
930 struct { 926 struct {
931 int val; 927 int val;
928 u32 ctl;
932 const char *msg; 929 const char *msg;
933 u16 ctl;
934 } reg31[] = { 930 } reg31[] = {
935 { LPA_1000XFULL | LPA_SLCT, 931 { LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000,
936 "1000 Mbps Full Duplex", 932 "1000 Mbps Full Duplex" },
937 0x01 | _1000bpsF }, 933 { LPA_1000XHALF | LPA_SLCT, 0x07000c00,
938 { LPA_1000XHALF | LPA_SLCT, 934 "1000 Mbps Half Duplex" },
939 "1000 Mbps Half Duplex", 935 { LPA_100FULL, 0x04000800 | 0x00001000,
940 0x01 | _1000bpsH }, 936 "100 Mbps Full Duplex" },
941 { LPA_100FULL, 937 { LPA_100HALF, 0x04000800,
942 "100 Mbps Full Duplex", 938 "100 Mbps Half Duplex" },
943 0x01 | _100bpsF }, 939 { LPA_10FULL, 0x04000400 | 0x00001000,
944 { LPA_100HALF, 940 "10 Mbps Full Duplex" },
945 "100 Mbps Half Duplex", 941 { LPA_10HALF, 0x04000400,
946 0x01 | _100bpsH }, 942 "10 Mbps Half Duplex" },
947 { LPA_10FULL, 943 { 0, 0x04000400, "unknown" }
948 "10 Mbps Full Duplex", 944 }, *p;
949 0x01 | _10bpsF },
950 { LPA_10HALF,
951 "10 Mbps Half Duplex",
952 0x01 | _10bpsH },
953 { 0, "unknown", 0x0000 }
954 }, *p;
955 u16 adv; 945 u16 adv;
956 946
957 val = mdio_read(ioaddr, phy_id, 0x1f); 947 val = mdio_read(ioaddr, phy_id, 0x1f);
@@ -964,12 +954,29 @@ static void sis190_phy_task(void * data)
964 954
965 val &= adv; 955 val &= adv;
966 956
967 for (p = reg31; p->ctl; p++) { 957 for (p = reg31; p->val; p++) {
968 if ((val & p->val) == p->val) 958 if ((val & p->val) == p->val)
969 break; 959 break;
970 } 960 }
971 if (p->ctl) 961
972 SIS_W16(StationControl, p->ctl); 962 p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;
963
964 if ((tp->features & F_HAS_RGMII) &&
965 (tp->features & F_PHY_BCM5461)) {
966 // Set Tx Delay in RGMII mode.
967 mdio_write(ioaddr, phy_id, 0x18, 0xf1c7);
968 udelay(200);
969 mdio_write(ioaddr, phy_id, 0x1c, 0x8c00);
970 p->ctl |= 0x03000000;
971 }
972
973 SIS_W32(StationControl, p->ctl);
974
975 if (tp->features & F_HAS_RGMII) {
976 SIS_W32(RGDelay, 0x0441);
977 SIS_W32(RGDelay, 0x0440);
978 }
979
973 net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name, 980 net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name,
974 p->msg); 981 p->msg);
975 netif_carrier_on(dev); 982 netif_carrier_on(dev);
@@ -1308,6 +1315,7 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
1308 phy->type = (p->type == MIX) ? 1315 phy->type = (p->type == MIX) ?
1309 ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ? 1316 ((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
1310 LAN : HOME) : p->type; 1317 LAN : HOME) : p->type;
1318 tp->features |= p->feature;
1311 } else 1319 } else
1312 phy->type = UNKNOWN; 1320 phy->type = UNKNOWN;
1313 1321
@@ -1316,6 +1324,25 @@ static void sis190_init_phy(struct net_device *dev, struct sis190_private *tp,
1316 (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id); 1324 (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id);
1317} 1325}
1318 1326
1327static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp)
1328{
1329 if (tp->features & F_PHY_88E1111) {
1330 void __iomem *ioaddr = tp->mmio_addr;
1331 int phy_id = tp->mii_if.phy_id;
1332 u16 reg[2][2] = {
1333 { 0x808b, 0x0ce1 },
1334 { 0x808f, 0x0c60 }
1335 }, *p;
1336
1337 p = (tp->features & F_HAS_RGMII) ? reg[0] : reg[1];
1338
1339 mdio_write(ioaddr, phy_id, 0x1b, p[0]);
1340 udelay(200);
1341 mdio_write(ioaddr, phy_id, 0x14, p[1]);
1342 udelay(200);
1343 }
1344}
1345
1319/** 1346/**
1320 * sis190_mii_probe - Probe MII PHY for sis190 1347 * sis190_mii_probe - Probe MII PHY for sis190
1321 * @dev: the net device to probe for 1348 * @dev: the net device to probe for
@@ -1366,6 +1393,8 @@ static int __devinit sis190_mii_probe(struct net_device *dev)
1366 /* Select default PHY for mac */ 1393 /* Select default PHY for mac */
1367 sis190_default_phy(dev); 1394 sis190_default_phy(dev);
1368 1395
1396 sis190_mii_probe_88e1111_fixup(tp);
1397
1369 mii_if->dev = dev; 1398 mii_if->dev = dev;
1370 mii_if->mdio_read = __mdio_read; 1399 mii_if->mdio_read = __mdio_read;
1371 mii_if->mdio_write = __mdio_write; 1400 mii_if->mdio_write = __mdio_write;
@@ -1505,6 +1534,11 @@ static void sis190_tx_timeout(struct net_device *dev)
1505 netif_wake_queue(dev); 1534 netif_wake_queue(dev);
1506} 1535}
1507 1536
1537static void sis190_set_rgmii(struct sis190_private *tp, u8 reg)
1538{
1539 tp->features |= (reg & 0x80) ? F_HAS_RGMII : 0;
1540}
1541
1508static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev, 1542static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
1509 struct net_device *dev) 1543 struct net_device *dev)
1510{ 1544{
@@ -1532,6 +1566,8 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
1532 ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w); 1566 ((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
1533 } 1567 }
1534 1568
1569 sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
1570
1535 return 0; 1571 return 0;
1536} 1572}
1537 1573
@@ -1577,6 +1613,8 @@ static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
1577 outb(0x12, 0x78); 1613 outb(0x12, 0x78);
1578 reg = inb(0x79); 1614 reg = inb(0x79);
1579 1615
1616 sis190_set_rgmii(tp, reg);
1617
1580 /* Restore the value to ISA Bridge */ 1618 /* Restore the value to ISA Bridge */
1581 pci_write_config_byte(isa_bridge, 0x48, tmp8); 1619 pci_write_config_byte(isa_bridge, 0x48, tmp8);
1582 pci_dev_put(isa_bridge); 1620 pci_dev_put(isa_bridge);
@@ -1799,6 +1837,9 @@ static int __devinit sis190_init_one(struct pci_dev *pdev,
1799 dev->dev_addr[2], dev->dev_addr[3], 1837 dev->dev_addr[2], dev->dev_addr[3],
1800 dev->dev_addr[4], dev->dev_addr[5]); 1838 dev->dev_addr[4], dev->dev_addr[5]);
1801 1839
1840 net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name,
1841 (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
1842
1802 netif_carrier_off(dev); 1843 netif_carrier_off(dev);
1803 1844
1804 sis190_set_speed_auto(dev); 1845 sis190_set_speed_auto(dev);
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 5ae22b7bc5ca..1a4316336256 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -21,7 +21,6 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/string.h> 22#include <linux/string.h>
23#include <linux/timer.h> 23#include <linux/timer.h>
24#include <linux/ptrace.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/ioport.h> 25#include <linux/ioport.h>
27#include <linux/slab.h> 26#include <linux/slab.h>
@@ -34,6 +33,7 @@
34#include <linux/skbuff.h> 33#include <linux/skbuff.h>
35#include <linux/delay.h> 34#include <linux/delay.h>
36#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <linux/dma-mapping.h>
37 37
38#include <asm/processor.h> 38#include <asm/processor.h>
39#include <asm/bitops.h> 39#include <asm/bitops.h>
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index dd7dbf7b14d4..00a07f32a81e 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -289,8 +289,8 @@ config APPLE_AIRPORT
289 a non-standard interface 289 a non-standard interface
290 290
291config PLX_HERMES 291config PLX_HERMES
292 tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)" 292 tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
293 depends on PCI && HERMES && EXPERIMENTAL 293 depends on PCI && HERMES
294 help 294 help
295 Enable support for PCMCIA cards supported by the "Hermes" (aka 295 Enable support for PCMCIA cards supported by the "Hermes" (aka
296 orinoco) driver when used in PLX9052 based PCI adaptors. These 296 orinoco) driver when used in PLX9052 based PCI adaptors. These
@@ -299,12 +299,9 @@ config PLX_HERMES
299 802.11b PCMCIA cards can be used in desktop machines. The Netgear 299 802.11b PCMCIA cards can be used in desktop machines. The Netgear
300 MA301 is such an adaptor. 300 MA301 is such an adaptor.
301 301
302 Support for these adaptors is so far still incomplete and buggy.
303 You have been warned.
304
305config TMD_HERMES 302config TMD_HERMES
306 tristate "Hermes in TMD7160 based PCI adaptor support (EXPERIMENTAL)" 303 tristate "Hermes in TMD7160 based PCI adaptor support"
307 depends on PCI && HERMES && EXPERIMENTAL 304 depends on PCI && HERMES
308 help 305 help
309 Enable support for PCMCIA cards supported by the "Hermes" (aka 306 Enable support for PCMCIA cards supported by the "Hermes" (aka
310 orinoco) driver when used in TMD7160 based PCI adaptors. These 307 orinoco) driver when used in TMD7160 based PCI adaptors. These
@@ -312,12 +309,18 @@ config TMD_HERMES
312 PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that 309 PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that
313 802.11b PCMCIA cards can be used in desktop machines. 310 802.11b PCMCIA cards can be used in desktop machines.
314 311
315 Support for these adaptors is so far still incomplete and buggy. 312config NORTEL_HERMES
316 You have been warned. 313 tristate "Nortel emobility PCI adaptor support"
314 depends on PCI && HERMES
315 help
316 Enable support for PCMCIA cards supported by the "Hermes" (aka
317 orinoco) driver when used in Nortel emobility PCI adaptors. These
318 adaptors are not full PCMCIA controllers, but act as a more limited
319 PCI <-> PCMCIA bridge.
317 320
318config PCI_HERMES 321config PCI_HERMES
319 tristate "Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)" 322 tristate "Prism 2.5 PCI 802.11b adaptor support"
320 depends on PCI && HERMES && EXPERIMENTAL 323 depends on PCI && HERMES
321 help 324 help
322 Enable support for PCI and mini-PCI 802.11b wireless NICs based on 325 Enable support for PCI and mini-PCI 802.11b wireless NICs based on
323 the Prism 2.5 chipset. These are true PCI cards, not the 802.11b 326 the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
@@ -372,6 +375,19 @@ config PCMCIA_HERMES
372 configure your card and that /etc/pcmcia/wireless.opts works: 375 configure your card and that /etc/pcmcia/wireless.opts works:
373 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. 376 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
374 377
378config PCMCIA_SPECTRUM
379 tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
380 depends on NET_RADIO && PCMCIA && HERMES
381 ---help---
382
383 This is a driver for 802.11b cards using RAM-loadable Symbol
384 firmware, such as Symbol Wireless Networker LA4100, CompactFlash
385 cards by Socket Communications and Intel PRO/Wireless 2011B.
386
387 This driver requires firmware download on startup. Utilities
388 for downloading Symbol firmware are available at
389 <http://sourceforge.net/projects/orinoco/>
390
375config AIRO_CS 391config AIRO_CS
376 tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" 392 tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
377 depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) 393 depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 0953cc0cdee6..3a6f7ba326ca 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -22,6 +22,8 @@ obj-$(CONFIG_APPLE_AIRPORT) += airport.o
22obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o 22obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o
23obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o 23obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o
24obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o 24obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o
25obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o
26obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o
25 27
26obj-$(CONFIG_AIRO) += airo.o 28obj-$(CONFIG_AIRO) += airo.o
27obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o 29obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index a47fce4beadf..2414e6493aa5 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -327,38 +327,38 @@ static struct iw_handler_def ipw2100_wx_handler_def;
327 327
328static inline void read_register(struct net_device *dev, u32 reg, u32 *val) 328static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
329{ 329{
330 *val = readl((void *)(dev->base_addr + reg)); 330 *val = readl((void __iomem *)(dev->base_addr + reg));
331 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val); 331 IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
332} 332}
333 333
334static inline void write_register(struct net_device *dev, u32 reg, u32 val) 334static inline void write_register(struct net_device *dev, u32 reg, u32 val)
335{ 335{
336 writel(val, (void *)(dev->base_addr + reg)); 336 writel(val, (void __iomem *)(dev->base_addr + reg));
337 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val); 337 IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
338} 338}
339 339
340static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val) 340static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val)
341{ 341{
342 *val = readw((void *)(dev->base_addr + reg)); 342 *val = readw((void __iomem *)(dev->base_addr + reg));
343 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val); 343 IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
344} 344}
345 345
346static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val) 346static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val)
347{ 347{
348 *val = readb((void *)(dev->base_addr + reg)); 348 *val = readb((void __iomem *)(dev->base_addr + reg));
349 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val); 349 IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
350} 350}
351 351
352static inline void write_register_word(struct net_device *dev, u32 reg, u16 val) 352static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
353{ 353{
354 writew(val, (void *)(dev->base_addr + reg)); 354 writew(val, (void __iomem *)(dev->base_addr + reg));
355 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val); 355 IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
356} 356}
357 357
358 358
359static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val) 359static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
360{ 360{
361 writeb(val, (void *)(dev->base_addr + reg)); 361 writeb(val, (void __iomem *)(dev->base_addr + reg));
362 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val); 362 IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
363} 363}
364 364
@@ -498,7 +498,7 @@ static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
498static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev) 498static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
499{ 499{
500 return (dev->base_addr && 500 return (dev->base_addr &&
501 (readl((void *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START)) 501 (readl((void __iomem *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START))
502 == IPW_DATA_DOA_DEBUG_VALUE)); 502 == IPW_DATA_DOA_DEBUG_VALUE));
503} 503}
504 504
@@ -2125,19 +2125,19 @@ static void isr_indicate_scanning(struct ipw2100_priv *priv, u32 status)
2125} 2125}
2126 2126
2127static const struct ipw2100_status_indicator status_handlers[] = { 2127static const struct ipw2100_status_indicator status_handlers[] = {
2128 IPW2100_HANDLER(IPW_STATE_INITIALIZED, 0), 2128 IPW2100_HANDLER(IPW_STATE_INITIALIZED, NULL),
2129 IPW2100_HANDLER(IPW_STATE_COUNTRY_FOUND, 0), 2129 IPW2100_HANDLER(IPW_STATE_COUNTRY_FOUND, NULL),
2130 IPW2100_HANDLER(IPW_STATE_ASSOCIATED, isr_indicate_associated), 2130 IPW2100_HANDLER(IPW_STATE_ASSOCIATED, isr_indicate_associated),
2131 IPW2100_HANDLER(IPW_STATE_ASSN_LOST, isr_indicate_association_lost), 2131 IPW2100_HANDLER(IPW_STATE_ASSN_LOST, isr_indicate_association_lost),
2132 IPW2100_HANDLER(IPW_STATE_ASSN_CHANGED, 0), 2132 IPW2100_HANDLER(IPW_STATE_ASSN_CHANGED, NULL),
2133 IPW2100_HANDLER(IPW_STATE_SCAN_COMPLETE, isr_scan_complete), 2133 IPW2100_HANDLER(IPW_STATE_SCAN_COMPLETE, isr_scan_complete),
2134 IPW2100_HANDLER(IPW_STATE_ENTERED_PSP, 0), 2134 IPW2100_HANDLER(IPW_STATE_ENTERED_PSP, NULL),
2135 IPW2100_HANDLER(IPW_STATE_LEFT_PSP, 0), 2135 IPW2100_HANDLER(IPW_STATE_LEFT_PSP, NULL),
2136 IPW2100_HANDLER(IPW_STATE_RF_KILL, isr_indicate_rf_kill), 2136 IPW2100_HANDLER(IPW_STATE_RF_KILL, isr_indicate_rf_kill),
2137 IPW2100_HANDLER(IPW_STATE_DISABLED, 0), 2137 IPW2100_HANDLER(IPW_STATE_DISABLED, NULL),
2138 IPW2100_HANDLER(IPW_STATE_POWER_DOWN, 0), 2138 IPW2100_HANDLER(IPW_STATE_POWER_DOWN, NULL),
2139 IPW2100_HANDLER(IPW_STATE_SCANNING, isr_indicate_scanning), 2139 IPW2100_HANDLER(IPW_STATE_SCANNING, isr_indicate_scanning),
2140 IPW2100_HANDLER(-1, 0) 2140 IPW2100_HANDLER(-1, NULL)
2141}; 2141};
2142 2142
2143 2143
@@ -6327,7 +6327,7 @@ static void ipw2100_irq_tasklet(struct ipw2100_priv *priv);
6327 6327
6328static struct net_device *ipw2100_alloc_device( 6328static struct net_device *ipw2100_alloc_device(
6329 struct pci_dev *pci_dev, 6329 struct pci_dev *pci_dev,
6330 char *base_addr, 6330 void __iomem *base_addr,
6331 unsigned long mem_start, 6331 unsigned long mem_start,
6332 unsigned long mem_len) 6332 unsigned long mem_len)
6333{ 6333{
@@ -6474,7 +6474,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6474 const struct pci_device_id *ent) 6474 const struct pci_device_id *ent)
6475{ 6475{
6476 unsigned long mem_start, mem_len, mem_flags; 6476 unsigned long mem_start, mem_len, mem_flags;
6477 char *base_addr = NULL; 6477 void __iomem *base_addr = NULL;
6478 struct net_device *dev = NULL; 6478 struct net_device *dev = NULL;
6479 struct ipw2100_priv *priv = NULL; 6479 struct ipw2100_priv *priv = NULL;
6480 int err = 0; 6480 int err = 0;
@@ -6664,7 +6664,7 @@ static int ipw2100_pci_init_one(struct pci_dev *pci_dev,
6664 } 6664 }
6665 6665
6666 if (base_addr) 6666 if (base_addr)
6667 iounmap((char*)base_addr); 6667 iounmap(base_addr);
6668 6668
6669 pci_release_regions(pci_dev); 6669 pci_release_regions(pci_dev);
6670 pci_disable_device(pci_dev); 6670 pci_disable_device(pci_dev);
@@ -6714,7 +6714,7 @@ static void __devexit ipw2100_pci_remove_one(struct pci_dev *pci_dev)
6714 free_irq(dev->irq, priv); 6714 free_irq(dev->irq, priv);
6715 6715
6716 if (dev->base_addr) 6716 if (dev->base_addr)
6717 iounmap((unsigned char *)dev->base_addr); 6717 iounmap((void __iomem *)dev->base_addr);
6718 6718
6719 free_ieee80211(dev); 6719 free_ieee80211(dev);
6720 } 6720 }
@@ -8574,6 +8574,7 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
8574 struct net_device *dev = priv->net_dev; 8574 struct net_device *dev = priv->net_dev;
8575 const unsigned char *microcode_data = fw->uc.data; 8575 const unsigned char *microcode_data = fw->uc.data;
8576 unsigned int microcode_data_left = fw->uc.size; 8576 unsigned int microcode_data_left = fw->uc.size;
8577 void __iomem *reg = (void __iomem *)dev->base_addr;
8577 8578
8578 struct symbol_alive_response response; 8579 struct symbol_alive_response response;
8579 int i, j; 8580 int i, j;
@@ -8581,23 +8582,23 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
8581 8582
8582 /* Symbol control */ 8583 /* Symbol control */
8583 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703); 8584 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
8584 readl((void *)(dev->base_addr)); 8585 readl(reg);
8585 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707); 8586 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
8586 readl((void *)(dev->base_addr)); 8587 readl(reg);
8587 8588
8588 /* HW config */ 8589 /* HW config */
8589 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */ 8590 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
8590 readl((void *)(dev->base_addr)); 8591 readl(reg);
8591 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */ 8592 write_nic_byte(dev, 0x210014, 0x72); /* fifo width =16 */
8592 readl((void *)(dev->base_addr)); 8593 readl(reg);
8593 8594
8594 /* EN_CS_ACCESS bit to reset control store pointer */ 8595 /* EN_CS_ACCESS bit to reset control store pointer */
8595 write_nic_byte(dev, 0x210000, 0x40); 8596 write_nic_byte(dev, 0x210000, 0x40);
8596 readl((void *)(dev->base_addr)); 8597 readl(reg);
8597 write_nic_byte(dev, 0x210000, 0x0); 8598 write_nic_byte(dev, 0x210000, 0x0);
8598 readl((void *)(dev->base_addr)); 8599 readl(reg);
8599 write_nic_byte(dev, 0x210000, 0x40); 8600 write_nic_byte(dev, 0x210000, 0x40);
8600 readl((void *)(dev->base_addr)); 8601 readl(reg);
8601 8602
8602 /* copy microcode from buffer into Symbol */ 8603 /* copy microcode from buffer into Symbol */
8603 8604
@@ -8609,31 +8610,31 @@ static int ipw2100_ucode_download(struct ipw2100_priv *priv,
8609 8610
8610 /* EN_CS_ACCESS bit to reset the control store pointer */ 8611 /* EN_CS_ACCESS bit to reset the control store pointer */
8611 write_nic_byte(dev, 0x210000, 0x0); 8612 write_nic_byte(dev, 0x210000, 0x0);
8612 readl((void *)(dev->base_addr)); 8613 readl(reg);
8613 8614
8614 /* Enable System (Reg 0) 8615 /* Enable System (Reg 0)
8615 * first enable causes garbage in RX FIFO */ 8616 * first enable causes garbage in RX FIFO */
8616 write_nic_byte(dev, 0x210000, 0x0); 8617 write_nic_byte(dev, 0x210000, 0x0);
8617 readl((void *)(dev->base_addr)); 8618 readl(reg);
8618 write_nic_byte(dev, 0x210000, 0x80); 8619 write_nic_byte(dev, 0x210000, 0x80);
8619 readl((void *)(dev->base_addr)); 8620 readl(reg);
8620 8621
8621 /* Reset External Baseband Reg */ 8622 /* Reset External Baseband Reg */
8622 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703); 8623 write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
8623 readl((void *)(dev->base_addr)); 8624 readl(reg);
8624 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707); 8625 write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
8625 readl((void *)(dev->base_addr)); 8626 readl(reg);
8626 8627
8627 /* HW Config (Reg 5) */ 8628 /* HW Config (Reg 5) */
8628 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16 8629 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
8629 readl((void *)(dev->base_addr)); 8630 readl(reg);
8630 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16 8631 write_nic_byte(dev, 0x210014, 0x72); // fifo width =16
8631 readl((void *)(dev->base_addr)); 8632 readl(reg);
8632 8633
8633 /* Enable System (Reg 0) 8634 /* Enable System (Reg 0)
8634 * second enable should be OK */ 8635 * second enable should be OK */
8635 write_nic_byte(dev, 0x210000, 0x00); // clear enable system 8636 write_nic_byte(dev, 0x210000, 0x00); // clear enable system
8636 readl((void *)(dev->base_addr)); 8637 readl(reg);
8637 write_nic_byte(dev, 0x210000, 0x80); // set enable system 8638 write_nic_byte(dev, 0x210000, 0x80); // set enable system
8638 8639
8639 /* check Symbol is enabled - upped this from 5 as it wasn't always 8640 /* check Symbol is enabled - upped this from 5 as it wasn't always
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index dc3e7bc805fc..66bb5903537f 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -42,6 +42,7 @@
42#include <linux/etherdevice.h> 42#include <linux/etherdevice.h>
43#include <linux/delay.h> 43#include <linux/delay.h>
44#include <linux/random.h> 44#include <linux/random.h>
45#include <linux/dma-mapping.h>
45 46
46#include <linux/firmware.h> 47#include <linux/firmware.h>
47#include <linux/wireless.h> 48#include <linux/wireless.h>
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index d7947358e49d..8de49fe57233 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -1053,8 +1053,9 @@ static void orinoco_join_ap(struct net_device *dev)
1053 u16 channel; 1053 u16 channel;
1054 } __attribute__ ((packed)) req; 1054 } __attribute__ ((packed)) req;
1055 const int atom_len = offsetof(struct prism2_scan_apinfo, atim); 1055 const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
1056 struct prism2_scan_apinfo *atom; 1056 struct prism2_scan_apinfo *atom = NULL;
1057 int offset = 4; 1057 int offset = 4;
1058 int found = 0;
1058 u8 *buf; 1059 u8 *buf;
1059 u16 len; 1060 u16 len;
1060 1061
@@ -1089,15 +1090,18 @@ static void orinoco_join_ap(struct net_device *dev)
1089 * we were requested to join */ 1090 * we were requested to join */
1090 for (; offset + atom_len <= len; offset += atom_len) { 1091 for (; offset + atom_len <= len; offset += atom_len) {
1091 atom = (struct prism2_scan_apinfo *) (buf + offset); 1092 atom = (struct prism2_scan_apinfo *) (buf + offset);
1092 if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) 1093 if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
1093 goto found; 1094 found = 1;
1095 break;
1096 }
1094 } 1097 }
1095 1098
1096 DEBUG(1, "%s: Requested AP not found in scan results\n", 1099 if (! found) {
1097 dev->name); 1100 DEBUG(1, "%s: Requested AP not found in scan results\n",
1098 goto out; 1101 dev->name);
1102 goto out;
1103 }
1099 1104
1100 found:
1101 memcpy(req.bssid, priv->desired_bssid, ETH_ALEN); 1105 memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
1102 req.channel = atom->channel; /* both are little-endian */ 1106 req.channel = atom->channel; /* both are little-endian */
1103 err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST, 1107 err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
@@ -1284,8 +1288,10 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1284 /* Read scan data */ 1288 /* Read scan data */
1285 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len, 1289 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
1286 infofid, sizeof(info)); 1290 infofid, sizeof(info));
1287 if (err) 1291 if (err) {
1292 kfree(buf);
1288 break; 1293 break;
1294 }
1289 1295
1290#ifdef ORINOCO_DEBUG 1296#ifdef ORINOCO_DEBUG
1291 { 1297 {
@@ -4021,7 +4027,8 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
4021} 4027}
4022 4028
4023/* Translate scan data returned from the card to a card independant 4029/* Translate scan data returned from the card to a card independant
4024 * format that the Wireless Tools will understand - Jean II */ 4030 * format that the Wireless Tools will understand - Jean II
4031 * Return message length or -errno for fatal errors */
4025static inline int orinoco_translate_scan(struct net_device *dev, 4032static inline int orinoco_translate_scan(struct net_device *dev,
4026 char *buffer, 4033 char *buffer,
4027 char *scan, 4034 char *scan,
@@ -4061,13 +4068,19 @@ static inline int orinoco_translate_scan(struct net_device *dev,
4061 break; 4068 break;
4062 case FIRMWARE_TYPE_INTERSIL: 4069 case FIRMWARE_TYPE_INTERSIL:
4063 offset = 4; 4070 offset = 4;
4064 if (priv->has_hostscan) 4071 if (priv->has_hostscan) {
4065 atom_len = scan[0] + (scan[1] << 8); 4072 atom_len = le16_to_cpup((u16 *)scan);
4066 else 4073 /* Sanity check for atom_len */
4074 if (atom_len < sizeof(struct prism2_scan_apinfo)) {
4075 printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
4076 dev->name, atom_len);
4077 return -EIO;
4078 }
4079 } else
4067 atom_len = offsetof(struct prism2_scan_apinfo, atim); 4080 atom_len = offsetof(struct prism2_scan_apinfo, atim);
4068 break; 4081 break;
4069 default: 4082 default:
4070 return 0; 4083 return -EOPNOTSUPP;
4071 } 4084 }
4072 4085
4073 /* Check that we got an whole number of atoms */ 4086 /* Check that we got an whole number of atoms */
@@ -4075,7 +4088,7 @@ static inline int orinoco_translate_scan(struct net_device *dev,
4075 printk(KERN_ERR "%s: Unexpected scan data length %d, " 4088 printk(KERN_ERR "%s: Unexpected scan data length %d, "
4076 "atom_len %d, offset %d\n", dev->name, scan_len, 4089 "atom_len %d, offset %d\n", dev->name, scan_len,
4077 atom_len, offset); 4090 atom_len, offset);
4078 return 0; 4091 return -EIO;
4079 } 4092 }
4080 4093
4081 /* Read the entries one by one */ 4094 /* Read the entries one by one */
@@ -4210,33 +4223,41 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
4210 /* We have some results to push back to user space */ 4223 /* We have some results to push back to user space */
4211 4224
4212 /* Translate to WE format */ 4225 /* Translate to WE format */
4213 srq->length = orinoco_translate_scan(dev, extra, 4226 int ret = orinoco_translate_scan(dev, extra,
4214 priv->scan_result, 4227 priv->scan_result,
4215 priv->scan_len); 4228 priv->scan_len);
4216 4229
4217 /* Return flags */ 4230 if (ret < 0) {
4218 srq->flags = (__u16) priv->scan_mode; 4231 err = ret;
4232 kfree(priv->scan_result);
4233 priv->scan_result = NULL;
4234 } else {
4235 srq->length = ret;
4219 4236
4220 /* Results are here, so scan no longer in progress */ 4237 /* Return flags */
4221 priv->scan_inprogress = 0; 4238 srq->flags = (__u16) priv->scan_mode;
4222 4239
4223 /* In any case, Scan results will be cleaned up in the 4240 /* In any case, Scan results will be cleaned up in the
4224 * reset function and when exiting the driver. 4241 * reset function and when exiting the driver.
4225 * The person triggering the scanning may never come to 4242 * The person triggering the scanning may never come to
4226 * pick the results, so we need to do it in those places. 4243 * pick the results, so we need to do it in those places.
4227 * Jean II */ 4244 * Jean II */
4228 4245
4229#ifdef SCAN_SINGLE_READ 4246#ifdef SCAN_SINGLE_READ
4230 /* If you enable this option, only one client (the first 4247 /* If you enable this option, only one client (the first
4231 * one) will be able to read the result (and only one 4248 * one) will be able to read the result (and only one
4232 * time). If there is multiple concurent clients that 4249 * time). If there is multiple concurent clients that
4233 * want to read scan results, this behavior is not 4250 * want to read scan results, this behavior is not
4234 * advisable - Jean II */ 4251 * advisable - Jean II */
4235 kfree(priv->scan_result); 4252 kfree(priv->scan_result);
4236 priv->scan_result = NULL; 4253 priv->scan_result = NULL;
4237#endif /* SCAN_SINGLE_READ */ 4254#endif /* SCAN_SINGLE_READ */
4238 /* Here, if too much time has elapsed since last scan, 4255 /* Here, if too much time has elapsed since last scan,
4239 * we may want to clean up scan results... - Jean II */ 4256 * we may want to clean up scan results... - Jean II */
4257 }
4258
4259 /* Scan is no longer in progress */
4260 priv->scan_inprogress = 0;
4240 } 4261 }
4241 4262
4242 orinoco_unlock(priv, &flags); 4263 orinoco_unlock(priv, &flags);
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 1cc1492083c9..d1fb1bab8aa8 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -604,7 +604,6 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
604 604
605static struct pcmcia_device_id orinoco_cs_ids[] = { 605static struct pcmcia_device_id orinoco_cs_ids[] = {
606 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), 606 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
607 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001),
608 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), 607 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
609 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), 608 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
610 PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), 609 PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
new file mode 100644
index 000000000000..86fa58e5cfac
--- /dev/null
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -0,0 +1,324 @@
1/* orinoco_nortel.c
2 *
3 * Driver for Prism II devices which would usually be driven by orinoco_cs,
4 * but are connected to the PCI bus by a Nortel PCI-PCMCIA-Adapter.
5 *
6 * Copyright (C) 2002 Tobias Hoffmann
7 * (C) 2003 Christoph Jungegger <disdos@traum404.de>
8 *
9 * Some of this code is borrowed from orinoco_plx.c
10 * Copyright (C) 2001 Daniel Barlow
11 * Some of this code is borrowed from orinoco_pci.c
12 * Copyright (C) 2001 Jean Tourrilhes
13 * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
14 * has been copied from it. linux-wlan-ng-0.1.10 is originally :
15 * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
16 *
17 * The contents of this file are subject to the Mozilla Public License
18 * Version 1.1 (the "License"); you may not use this file except in
19 * compliance with the License. You may obtain a copy of the License
20 * at http://www.mozilla.org/MPL/
21 *
22 * Software distributed under the License is distributed on an "AS IS"
23 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
24 * the License for the specific language governing rights and
25 * limitations under the License.
26 *
27 * Alternatively, the contents of this file may be used under the
28 * terms of the GNU General Public License version 2 (the "GPL"), in
29 * which case the provisions of the GPL are applicable instead of the
30 * above. If you wish to allow the use of your version of this file
31 * only under the terms of the GPL and not to allow others to use your
32 * version of this file under the MPL, indicate your decision by
33 * deleting the provisions above and replace them with the notice and
34 * other provisions required by the GPL. If you do not delete the
35 * provisions above, a recipient may use your version of this file
36 * under either the MPL or the GPL.
37 */
38
39#define DRIVER_NAME "orinoco_nortel"
40#define PFX DRIVER_NAME ": "
41
42#include <linux/config.h>
43
44#include <linux/module.h>
45#include <linux/kernel.h>
46#include <linux/init.h>
47#include <linux/sched.h>
48#include <linux/ptrace.h>
49#include <linux/slab.h>
50#include <linux/string.h>
51#include <linux/timer.h>
52#include <linux/ioport.h>
53#include <asm/uaccess.h>
54#include <asm/io.h>
55#include <asm/system.h>
56#include <linux/netdevice.h>
57#include <linux/if_arp.h>
58#include <linux/etherdevice.h>
59#include <linux/list.h>
60#include <linux/pci.h>
61#include <linux/fcntl.h>
62
63#include <pcmcia/cisreg.h>
64
65#include "hermes.h"
66#include "orinoco.h"
67
68#define COR_OFFSET (0xe0) /* COR attribute offset of Prism2 PC card */
69#define COR_VALUE (COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
70
71
72/* Nortel specific data */
73struct nortel_pci_card {
74 unsigned long iobase1;
75 unsigned long iobase2;
76};
77
78/*
79 * Do a soft reset of the PCI card using the Configuration Option Register
80 * We need this to get going...
81 * This is the part of the code that is strongly inspired from wlan-ng
82 *
83 * Note bis : Don't try to access HERMES_CMD during the reset phase.
84 * It just won't work !
85 */
86static int nortel_pci_cor_reset(struct orinoco_private *priv)
87{
88 struct nortel_pci_card *card = priv->card;
89
90 /* Assert the reset until the card notice */
91 outw_p(8, card->iobase1 + 2);
92 inw(card->iobase2 + COR_OFFSET);
93 outw_p(0x80, card->iobase2 + COR_OFFSET);
94 mdelay(1);
95
96 /* Give time for the card to recover from this hard effort */
97 outw_p(0, card->iobase2 + COR_OFFSET);
98 outw_p(0, card->iobase2 + COR_OFFSET);
99 mdelay(1);
100
101 /* set COR as usual */
102 outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
103 outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
104 mdelay(1);
105
106 outw_p(0x228, card->iobase1 + 2);
107
108 return 0;
109}
110
111int nortel_pci_hw_init(struct nortel_pci_card *card)
112{
113 int i;
114 u32 reg;
115
116 /* setup bridge */
117 if (inw(card->iobase1) & 1) {
118 printk(KERN_ERR PFX "brg1 answer1 wrong\n");
119 return -EBUSY;
120 }
121 outw_p(0x118, card->iobase1 + 2);
122 outw_p(0x108, card->iobase1 + 2);
123 mdelay(30);
124 outw_p(0x8, card->iobase1 + 2);
125 for (i = 0; i < 30; i++) {
126 mdelay(30);
127 if (inw(card->iobase1) & 0x10) {
128 break;
129 }
130 }
131 if (i == 30) {
132 printk(KERN_ERR PFX "brg1 timed out\n");
133 return -EBUSY;
134 }
135 if (inw(card->iobase2 + 0xe0) & 1) {
136 printk(KERN_ERR PFX "brg2 answer1 wrong\n");
137 return -EBUSY;
138 }
139 if (inw(card->iobase2 + 0xe2) & 1) {
140 printk(KERN_ERR PFX "brg2 answer2 wrong\n");
141 return -EBUSY;
142 }
143 if (inw(card->iobase2 + 0xe4) & 1) {
144 printk(KERN_ERR PFX "brg2 answer3 wrong\n");
145 return -EBUSY;
146 }
147
148 /* set the PCMCIA COR-Register */
149 outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
150 mdelay(1);
151 reg = inw(card->iobase2 + COR_OFFSET);
152 if (reg != COR_VALUE) {
153 printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n",
154 reg);
155 return -EBUSY;
156 }
157
158 /* set leds */
159 outw_p(1, card->iobase1 + 10);
160 return 0;
161}
162
163static int nortel_pci_init_one(struct pci_dev *pdev,
164 const struct pci_device_id *ent)
165{
166 int err;
167 struct orinoco_private *priv;
168 struct nortel_pci_card *card;
169 struct net_device *dev;
170 void __iomem *iomem;
171
172 err = pci_enable_device(pdev);
173 if (err) {
174 printk(KERN_ERR PFX "Cannot enable PCI device\n");
175 return err;
176 }
177
178 err = pci_request_regions(pdev, DRIVER_NAME);
179 if (err != 0) {
180 printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
181 goto fail_resources;
182 }
183
184 iomem = pci_iomap(pdev, 3, 0);
185 if (!iomem) {
186 err = -ENOMEM;
187 goto fail_map_io;
188 }
189
190 /* Allocate network device */
191 dev = alloc_orinocodev(sizeof(*card), nortel_pci_cor_reset);
192 if (!dev) {
193 printk(KERN_ERR PFX "Cannot allocate network device\n");
194 err = -ENOMEM;
195 goto fail_alloc;
196 }
197
198 priv = netdev_priv(dev);
199 card = priv->card;
200 card->iobase1 = pci_resource_start(pdev, 0);
201 card->iobase2 = pci_resource_start(pdev, 1);
202 dev->base_addr = pci_resource_start(pdev, 2);
203 SET_MODULE_OWNER(dev);
204 SET_NETDEV_DEV(dev, &pdev->dev);
205
206 hermes_struct_init(&priv->hw, iomem, HERMES_16BIT_REGSPACING);
207
208 printk(KERN_DEBUG PFX "Detected Nortel PCI device at %s irq:%d, "
209 "io addr:0x%lx\n", pci_name(pdev), pdev->irq, dev->base_addr);
210
211 err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
212 dev->name, dev);
213 if (err) {
214 printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
215 err = -EBUSY;
216 goto fail_irq;
217 }
218 dev->irq = pdev->irq;
219
220 err = nortel_pci_hw_init(card);
221 if (err) {
222 printk(KERN_ERR PFX "Hardware initialization failed\n");
223 goto fail;
224 }
225
226 err = nortel_pci_cor_reset(priv);
227 if (err) {
228 printk(KERN_ERR PFX "Initial reset failed\n");
229 goto fail;
230 }
231
232
233 err = register_netdev(dev);
234 if (err) {
235 printk(KERN_ERR PFX "Cannot register network device\n");
236 goto fail;
237 }
238
239 pci_set_drvdata(pdev, dev);
240
241 return 0;
242
243 fail:
244 free_irq(pdev->irq, dev);
245
246 fail_irq:
247 pci_set_drvdata(pdev, NULL);
248 free_orinocodev(dev);
249
250 fail_alloc:
251 pci_iounmap(pdev, iomem);
252
253 fail_map_io:
254 pci_release_regions(pdev);
255
256 fail_resources:
257 pci_disable_device(pdev);
258
259 return err;
260}
261
262static void __devexit nortel_pci_remove_one(struct pci_dev *pdev)
263{
264 struct net_device *dev = pci_get_drvdata(pdev);
265 struct orinoco_private *priv = netdev_priv(dev);
266 struct nortel_pci_card *card = priv->card;
267
268 /* clear leds */
269 outw_p(0, card->iobase1 + 10);
270
271 unregister_netdev(dev);
272 free_irq(dev->irq, dev);
273 pci_set_drvdata(pdev, NULL);
274 free_orinocodev(dev);
275 pci_iounmap(pdev, priv->hw.iobase);
276 pci_release_regions(pdev);
277 pci_disable_device(pdev);
278}
279
280
281static struct pci_device_id nortel_pci_id_table[] = {
282 /* Nortel emobility PCI */
283 {0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
284 {0,},
285};
286
287MODULE_DEVICE_TABLE(pci, nortel_pci_id_table);
288
289static struct pci_driver nortel_pci_driver = {
290 .name = DRIVER_NAME,
291 .id_table = nortel_pci_id_table,
292 .probe = nortel_pci_init_one,
293 .remove = __devexit_p(nortel_pci_remove_one),
294};
295
296static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
297 " (Tobias Hoffmann & Christoph Jungegger <disdos@traum404.de>)";
298MODULE_AUTHOR("Christoph Jungegger <disdos@traum404.de>");
299MODULE_DESCRIPTION
300 ("Driver for wireless LAN cards using the Nortel PCI bridge");
301MODULE_LICENSE("Dual MPL/GPL");
302
303static int __init nortel_pci_init(void)
304{
305 printk(KERN_DEBUG "%s\n", version);
306 return pci_module_init(&nortel_pci_driver);
307}
308
309static void __exit nortel_pci_exit(void)
310{
311 pci_unregister_driver(&nortel_pci_driver);
312 ssleep(1);
313}
314
315module_init(nortel_pci_init);
316module_exit(nortel_pci_exit);
317
318/*
319 * Local variables:
320 * c-indent-level: 8
321 * c-basic-offset: 8
322 * tab-width: 8
323 * End:
324 */
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
new file mode 100644
index 000000000000..39c6cdf7f3f7
--- /dev/null
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -0,0 +1,1120 @@
1/*
2 * Driver for 802.11b cards using RAM-loadable Symbol firmware, such as
3 * Symbol Wireless Networker LA4100, CompactFlash cards by Socket
4 * Communications and Intel PRO/Wireless 2011B.
5 *
6 * The driver implements Symbol firmware download. The rest is handled
7 * in hermes.c and orinoco.c.
8 *
9 * Utilities for downloading the Symbol firmware are available at
10 * http://sourceforge.net/projects/orinoco/
11 *
12 * Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org>
13 * Portions based on orinoco_cs.c:
14 * Copyright (C) David Gibson, Linuxcare Australia
15 * Portions based on Spectrum24tDnld.c from original spectrum24 driver:
16 * Copyright (C) Symbol Technologies.
17 *
18 * See copyright notice in file orinoco.c.
19 */
20
21#define DRIVER_NAME "spectrum_cs"
22#define PFX DRIVER_NAME ": "
23
24#include <linux/config.h>
25#ifdef __IN_PCMCIA_PACKAGE__
26#include <pcmcia/k_compat.h>
27#endif /* __IN_PCMCIA_PACKAGE__ */
28
29#include <linux/module.h>
30#include <linux/kernel.h>
31#include <linux/init.h>
32#include <linux/sched.h>
33#include <linux/ptrace.h>
34#include <linux/slab.h>
35#include <linux/string.h>
36#include <linux/ioport.h>
37#include <linux/netdevice.h>
38#include <linux/if_arp.h>
39#include <linux/etherdevice.h>
40#include <linux/wireless.h>
41
42#include <pcmcia/cs_types.h>
43#include <pcmcia/cs.h>
44#include <pcmcia/cistpl.h>
45#include <pcmcia/cisreg.h>
46#include <pcmcia/ds.h>
47
48#include <asm/uaccess.h>
49#include <asm/io.h>
50#include <asm/system.h>
51
52#include "orinoco.h"
53
54/*
55 * If SPECTRUM_FW_INCLUDED is defined, the firmware is hardcoded into
56 * the driver. Use get_symbol_fw script to generate spectrum_fw.h and
57 * copy it to the same directory as spectrum_cs.c.
58 *
59 * If SPECTRUM_FW_INCLUDED is not defined, the firmware is loaded at the
60 * runtime using hotplug. Use the same get_symbol_fw script to generate
61 * files symbol_sp24t_prim_fw symbol_sp24t_sec_fw, copy them to the
62 * hotplug firmware directory (typically /usr/lib/hotplug/firmware) and
63 * make sure that you have hotplug installed and enabled in the kernel.
64 */
65/* #define SPECTRUM_FW_INCLUDED 1 */
66
67#ifdef SPECTRUM_FW_INCLUDED
68/* Header with the firmware */
69#include "spectrum_fw.h"
70#else /* !SPECTRUM_FW_INCLUDED */
71#include <linux/firmware.h>
72static unsigned char *primsym;
73static unsigned char *secsym;
74static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
75static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
76#endif /* !SPECTRUM_FW_INCLUDED */
77
78/********************************************************************/
79/* Module stuff */
80/********************************************************************/
81
82MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
83MODULE_DESCRIPTION("Driver for Symbol Spectrum24 Trilogy cards with firmware downloader");
84MODULE_LICENSE("Dual MPL/GPL");
85
86/* Module parameters */
87
88/* Some D-Link cards have buggy CIS. They do work at 5v properly, but
89 * don't have any CIS entry for it. This workaround it... */
90static int ignore_cis_vcc; /* = 0 */
91module_param(ignore_cis_vcc, int, 0);
92MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
93
94/********************************************************************/
95/* Magic constants */
96/********************************************************************/
97
98/*
99 * The dev_info variable is the "key" that is used to match up this
100 * device driver with appropriate cards, through the card
101 * configuration database.
102 */
103static dev_info_t dev_info = DRIVER_NAME;
104
105/********************************************************************/
106/* Data structures */
107/********************************************************************/
108
109/* PCMCIA specific device information (goes in the card field of
110 * struct orinoco_private */
111struct orinoco_pccard {
112 dev_link_t link;
113 dev_node_t node;
114};
115
116/*
117 * A linked list of "instances" of the device. Each actual PCMCIA
118 * card corresponds to one device instance, and is described by one
119 * dev_link_t structure (defined in ds.h).
120 */
121static dev_link_t *dev_list; /* = NULL */
122
123/********************************************************************/
124/* Function prototypes */
125/********************************************************************/
126
127/* device methods */
128static int spectrum_cs_hard_reset(struct orinoco_private *priv);
129
130/* PCMCIA gumpf */
131static void spectrum_cs_config(dev_link_t * link);
132static void spectrum_cs_release(dev_link_t * link);
133static int spectrum_cs_event(event_t event, int priority,
134 event_callback_args_t * args);
135
136static dev_link_t *spectrum_cs_attach(void);
137static void spectrum_cs_detach(dev_link_t *);
138
139/********************************************************************/
140/* Firmware downloader */
141/********************************************************************/
142
143/* Position of PDA in the adapter memory */
144#define EEPROM_ADDR 0x3000
145#define EEPROM_LEN 0x200
146#define PDA_OFFSET 0x100
147
148#define PDA_ADDR (EEPROM_ADDR + PDA_OFFSET)
149#define PDA_WORDS ((EEPROM_LEN - PDA_OFFSET) / 2)
150
151/* Constants for the CISREG_CCSR register */
152#define HCR_RUN 0x07 /* run firmware after reset */
153#define HCR_IDLE 0x0E /* don't run firmware after reset */
154#define HCR_MEM16 0x10 /* memory width bit, should be preserved */
155
156/*
157 * AUX port access. To unlock the AUX port write the access keys to the
158 * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
159 * register. Then read it and make sure it's HERMES_AUX_ENABLED.
160 */
161#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */
162#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */
163#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */
164
165#define HERMES_AUX_PW0 0xFE01
166#define HERMES_AUX_PW1 0xDC23
167#define HERMES_AUX_PW2 0xBA45
168
169/* End markers */
170#define PDI_END 0x00000000 /* End of PDA */
171#define BLOCK_END 0xFFFFFFFF /* Last image block */
172#define TEXT_END 0x1A /* End of text header */
173
174/*
175 * The following structures have little-endian fields denoted by
176 * the leading underscore. Don't access them directly - use inline
177 * functions defined below.
178 */
179
180/*
181 * The binary image to be downloaded consists of series of data blocks.
182 * Each block has the following structure.
183 */
184struct dblock {
185 u32 _addr; /* adapter address where to write the block */
186 u16 _len; /* length of the data only, in bytes */
187 char data[0]; /* data to be written */
188} __attribute__ ((packed));
189
190/*
191 * Plug Data References are located in in the image after the last data
192 * block. They refer to areas in the adapter memory where the plug data
193 * items with matching ID should be written.
194 */
195struct pdr {
196 u32 _id; /* record ID */
197 u32 _addr; /* adapter address where to write the data */
198 u32 _len; /* expected length of the data, in bytes */
199 char next[0]; /* next PDR starts here */
200} __attribute__ ((packed));
201
202
203/*
204 * Plug Data Items are located in the EEPROM read from the adapter by
205 * primary firmware. They refer to the device-specific data that should
206 * be plugged into the secondary firmware.
207 */
208struct pdi {
209 u16 _len; /* length of ID and data, in words */
210 u16 _id; /* record ID */
211 char data[0]; /* plug data */
212} __attribute__ ((packed));;
213
214
215/* Functions for access to little-endian data */
216static inline u32
217dblock_addr(const struct dblock *blk)
218{
219 return le32_to_cpu(blk->_addr);
220}
221
222static inline u32
223dblock_len(const struct dblock *blk)
224{
225 return le16_to_cpu(blk->_len);
226}
227
228static inline u32
229pdr_id(const struct pdr *pdr)
230{
231 return le32_to_cpu(pdr->_id);
232}
233
234static inline u32
235pdr_addr(const struct pdr *pdr)
236{
237 return le32_to_cpu(pdr->_addr);
238}
239
240static inline u32
241pdr_len(const struct pdr *pdr)
242{
243 return le32_to_cpu(pdr->_len);
244}
245
246static inline u32
247pdi_id(const struct pdi *pdi)
248{
249 return le16_to_cpu(pdi->_id);
250}
251
252/* Return length of the data only, in bytes */
253static inline u32
254pdi_len(const struct pdi *pdi)
255{
256 return 2 * (le16_to_cpu(pdi->_len) - 1);
257}
258
259
260/* Set address of the auxiliary port */
261static inline void
262spectrum_aux_setaddr(hermes_t *hw, u32 addr)
263{
264 hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
265 hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
266}
267
268
269/* Open access to the auxiliary port */
270static int
271spectrum_aux_open(hermes_t *hw)
272{
273 int i;
274
275 /* Already open? */
276 if (hermes_read_reg(hw, HERMES_CONTROL) == HERMES_AUX_ENABLED)
277 return 0;
278
279 hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
280 hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
281 hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
282 hermes_write_reg(hw, HERMES_CONTROL, HERMES_AUX_ENABLE);
283
284 for (i = 0; i < 20; i++) {
285 udelay(10);
286 if (hermes_read_reg(hw, HERMES_CONTROL) ==
287 HERMES_AUX_ENABLED)
288 return 0;
289 }
290
291 return -EBUSY;
292}
293
294
295#define CS_CHECK(fn, ret) \
296 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
297
298/*
299 * Reset the card using configuration registers COR and CCSR.
300 * If IDLE is 1, stop the firmware, so that it can be safely rewritten.
301 */
302static int
303spectrum_reset(dev_link_t *link, int idle)
304{
305 int last_ret, last_fn;
306 conf_reg_t reg;
307 u_int save_cor;
308
309 /* Doing it if hardware is gone is guaranteed crash */
310 if (!(link->state & DEV_CONFIG))
311 return -ENODEV;
312
313 /* Save original COR value */
314 reg.Function = 0;
315 reg.Action = CS_READ;
316 reg.Offset = CISREG_COR;
317 CS_CHECK(AccessConfigurationRegister,
318 pcmcia_access_configuration_register(link->handle, &reg));
319 save_cor = reg.Value;
320
321 /* Soft-Reset card */
322 reg.Action = CS_WRITE;
323 reg.Offset = CISREG_COR;
324 reg.Value = (save_cor | COR_SOFT_RESET);
325 CS_CHECK(AccessConfigurationRegister,
326 pcmcia_access_configuration_register(link->handle, &reg));
327 udelay(1000);
328
329 /* Read CCSR */
330 reg.Action = CS_READ;
331 reg.Offset = CISREG_CCSR;
332 CS_CHECK(AccessConfigurationRegister,
333 pcmcia_access_configuration_register(link->handle, &reg));
334
335 /*
336 * Start or stop the firmware. Memory width bit should be
337 * preserved from the value we've just read.
338 */
339 reg.Action = CS_WRITE;
340 reg.Offset = CISREG_CCSR;
341 reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
342 CS_CHECK(AccessConfigurationRegister,
343 pcmcia_access_configuration_register(link->handle, &reg));
344 udelay(1000);
345
346 /* Restore original COR configuration index */
347 reg.Action = CS_WRITE;
348 reg.Offset = CISREG_COR;
349 reg.Value = (save_cor & ~COR_SOFT_RESET);
350 CS_CHECK(AccessConfigurationRegister,
351 pcmcia_access_configuration_register(link->handle, &reg));
352 udelay(1000);
353 return 0;
354
355 cs_failed:
356 cs_error(link->handle, last_fn, last_ret);
357 return -ENODEV;
358}
359
360
361/*
362 * Scan PDR for the record with the specified RECORD_ID.
363 * If it's not found, return NULL.
364 */
365static struct pdr *
366spectrum_find_pdr(struct pdr *first_pdr, u32 record_id)
367{
368 struct pdr *pdr = first_pdr;
369
370 while (pdr_id(pdr) != PDI_END) {
371 /*
372 * PDR area is currently not terminated by PDI_END.
373 * It's followed by CRC records, which have the type
374 * field where PDR has length. The type can be 0 or 1.
375 */
376 if (pdr_len(pdr) < 2)
377 return NULL;
378
379 /* If the record ID matches, we are done */
380 if (pdr_id(pdr) == record_id)
381 return pdr;
382
383 pdr = (struct pdr *) pdr->next;
384 }
385 return NULL;
386}
387
388
389/* Process one Plug Data Item - find corresponding PDR and plug it */
390static int
391spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi)
392{
393 struct pdr *pdr;
394
395 /* Find the PDI corresponding to this PDR */
396 pdr = spectrum_find_pdr(first_pdr, pdi_id(pdi));
397
398 /* No match is found, safe to ignore */
399 if (!pdr)
400 return 0;
401
402 /* Lengths of the data in PDI and PDR must match */
403 if (pdi_len(pdi) != pdr_len(pdr))
404 return -EINVAL;
405
406 /* do the actual plugging */
407 spectrum_aux_setaddr(hw, pdr_addr(pdr));
408 hermes_write_words(hw, HERMES_AUXDATA, pdi->data,
409 pdi_len(pdi) / 2);
410
411 return 0;
412}
413
414
415/* Read PDA from the adapter */
416static int
417spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
418{
419 int ret;
420 int pda_size;
421
422 /* Issue command to read EEPROM */
423 ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
424 if (ret)
425 return ret;
426
427 /* Open auxiliary port */
428 ret = spectrum_aux_open(hw);
429 if (ret)
430 return ret;
431
432 /* read PDA from EEPROM */
433 spectrum_aux_setaddr(hw, PDA_ADDR);
434 hermes_read_words(hw, HERMES_AUXDATA, pda, pda_len / 2);
435
436 /* Check PDA length */
437 pda_size = le16_to_cpu(pda[0]);
438 if (pda_size > pda_len)
439 return -EINVAL;
440
441 return 0;
442}
443
444
445/* Parse PDA and write the records into the adapter */
446static int
447spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block,
448 u16 *pda)
449{
450 int ret;
451 struct pdi *pdi;
452 struct pdr *first_pdr;
453 const struct dblock *blk = first_block;
454
455 /* Skip all blocks to locate Plug Data References */
456 while (dblock_addr(blk) != BLOCK_END)
457 blk = (struct dblock *) &blk->data[dblock_len(blk)];
458
459 first_pdr = (struct pdr *) blk;
460
461 /* Go through every PDI and plug them into the adapter */
462 pdi = (struct pdi *) (pda + 2);
463 while (pdi_id(pdi) != PDI_END) {
464 ret = spectrum_plug_pdi(hw, first_pdr, pdi);
465 if (ret)
466 return ret;
467
468 /* Increment to the next PDI */
469 pdi = (struct pdi *) &pdi->data[pdi_len(pdi)];
470 }
471 return 0;
472}
473
474
475/* Load firmware blocks into the adapter */
476static int
477spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block)
478{
479 const struct dblock *blk;
480 u32 blkaddr;
481 u32 blklen;
482
483 blk = first_block;
484 blkaddr = dblock_addr(blk);
485 blklen = dblock_len(blk);
486
487 while (dblock_addr(blk) != BLOCK_END) {
488 spectrum_aux_setaddr(hw, blkaddr);
489 hermes_write_words(hw, HERMES_AUXDATA, blk->data,
490 blklen / 2);
491
492 blk = (struct dblock *) &blk->data[blklen];
493 blkaddr = dblock_addr(blk);
494 blklen = dblock_len(blk);
495 }
496 return 0;
497}
498
499
500/*
501 * Process a firmware image - stop the card, load the firmware, reset
502 * the card and make sure it responds. For the secondary firmware take
503 * care of the PDA - read it and then write it on top of the firmware.
504 */
505static int
506spectrum_dl_image(hermes_t *hw, dev_link_t *link,
507 const unsigned char *image)
508{
509 int ret;
510 const unsigned char *ptr;
511 const struct dblock *first_block;
512
513 /* Plug Data Area (PDA) */
514 u16 pda[PDA_WORDS];
515
516 /* Binary block begins after the 0x1A marker */
517 ptr = image;
518 while (*ptr++ != TEXT_END);
519 first_block = (const struct dblock *) ptr;
520
521 /* Read the PDA */
522 if (image != primsym) {
523 ret = spectrum_read_pda(hw, pda, sizeof(pda));
524 if (ret)
525 return ret;
526 }
527
528 /* Stop the firmware, so that it can be safely rewritten */
529 ret = spectrum_reset(link, 1);
530 if (ret)
531 return ret;
532
533 /* Program the adapter with new firmware */
534 ret = spectrum_load_blocks(hw, first_block);
535 if (ret)
536 return ret;
537
538 /* Write the PDA to the adapter */
539 if (image != primsym) {
540 ret = spectrum_apply_pda(hw, first_block, pda);
541 if (ret)
542 return ret;
543 }
544
545 /* Run the firmware */
546 ret = spectrum_reset(link, 0);
547 if (ret)
548 return ret;
549
550 /* Reset hermes chip and make sure it responds */
551 ret = hermes_init(hw);
552
553 /* hermes_reset() should return 0 with the secondary firmware */
554 if (image != primsym && ret != 0)
555 return -ENODEV;
556
557 /* And this should work with any firmware */
558 if (!hermes_present(hw))
559 return -ENODEV;
560
561 return 0;
562}
563
564
565/*
566 * Download the firmware into the card, this also does a PCMCIA soft
567 * reset on the card, to make sure it's in a sane state.
568 */
569static int
570spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
571{
572 int ret;
573 client_handle_t handle = link->handle;
574
575#ifndef SPECTRUM_FW_INCLUDED
576 const struct firmware *fw_entry;
577
578 if (request_firmware(&fw_entry, primary_fw_name,
579 &handle_to_dev(handle)) == 0) {
580 primsym = fw_entry->data;
581 } else {
582 printk(KERN_ERR PFX "Cannot find firmware: %s\n",
583 primary_fw_name);
584 return -ENOENT;
585 }
586
587 if (request_firmware(&fw_entry, secondary_fw_name,
588 &handle_to_dev(handle)) == 0) {
589 secsym = fw_entry->data;
590 } else {
591 printk(KERN_ERR PFX "Cannot find firmware: %s\n",
592 secondary_fw_name);
593 return -ENOENT;
594 }
595#endif
596
597 /* Load primary firmware */
598 ret = spectrum_dl_image(hw, link, primsym);
599 if (ret) {
600 printk(KERN_ERR PFX "Primary firmware download failed\n");
601 return ret;
602 }
603
604 /* Load secondary firmware */
605 ret = spectrum_dl_image(hw, link, secsym);
606
607 if (ret) {
608 printk(KERN_ERR PFX "Secondary firmware download failed\n");
609 }
610
611 return ret;
612}
613
614/********************************************************************/
615/* Device methods */
616/********************************************************************/
617
618static int
619spectrum_cs_hard_reset(struct orinoco_private *priv)
620{
621 struct orinoco_pccard *card = priv->card;
622 dev_link_t *link = &card->link;
623 int err;
624
625 if (!hermes_present(&priv->hw)) {
626 /* The firmware needs to be reloaded */
627 if (spectrum_dl_firmware(&priv->hw, &card->link) != 0) {
628 printk(KERN_ERR PFX "Firmware download failed\n");
629 err = -ENODEV;
630 }
631 } else {
632 /* Soft reset using COR and HCR */
633 spectrum_reset(link, 0);
634 }
635
636 return 0;
637}
638
639/********************************************************************/
640/* PCMCIA stuff */
641/********************************************************************/
642
643/*
644 * This creates an "instance" of the driver, allocating local data
645 * structures for one device. The device is registered with Card
646 * Services.
647 *
648 * The dev_link structure is initialized, but we don't actually
649 * configure the card at this point -- we wait until we receive a card
650 * insertion event. */
651static dev_link_t *
652spectrum_cs_attach(void)
653{
654 struct net_device *dev;
655 struct orinoco_private *priv;
656 struct orinoco_pccard *card;
657 dev_link_t *link;
658 client_reg_t client_reg;
659 int ret;
660
661 dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
662 if (! dev)
663 return NULL;
664 priv = netdev_priv(dev);
665 card = priv->card;
666
667 /* Link both structures together */
668 link = &card->link;
669 link->priv = dev;
670
671 /* Interrupt setup */
672 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
673 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
674 link->irq.Handler = orinoco_interrupt;
675 link->irq.Instance = dev;
676
677 /* General socket configuration defaults can go here. In this
678 * client, we assume very little, and rely on the CIS for
679 * almost everything. In most clients, many details (i.e.,
680 * number, sizes, and attributes of IO windows) are fixed by
681 * the nature of the device, and can be hard-wired here. */
682 link->conf.Attributes = 0;
683 link->conf.IntType = INT_MEMORY_AND_IO;
684
685 /* Register with Card Services */
686 /* FIXME: need a lock? */
687 link->next = dev_list;
688 dev_list = link;
689
690 client_reg.dev_info = &dev_info;
691 client_reg.Version = 0x0210; /* FIXME: what does this mean? */
692 client_reg.event_callback_args.client_data = link;
693
694 ret = pcmcia_register_client(&link->handle, &client_reg);
695 if (ret != CS_SUCCESS) {
696 cs_error(link->handle, RegisterClient, ret);
697 spectrum_cs_detach(link);
698 return NULL;
699 }
700
701 return link;
702} /* spectrum_cs_attach */
703
704/*
705 * This deletes a driver "instance". The device is de-registered with
706 * Card Services. If it has been released, all local data structures
707 * are freed. Otherwise, the structures will be freed when the device
708 * is released.
709 */
710static void spectrum_cs_detach(dev_link_t *link)
711{
712 dev_link_t **linkp;
713 struct net_device *dev = link->priv;
714
715 /* Locate device structure */
716 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
717 if (*linkp == link)
718 break;
719
720 BUG_ON(*linkp == NULL);
721
722 if (link->state & DEV_CONFIG)
723 spectrum_cs_release(link);
724
725 /* Break the link with Card Services */
726 if (link->handle)
727 pcmcia_deregister_client(link->handle);
728
729 /* Unlink device structure, and free it */
730 *linkp = link->next;
731 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
732 if (link->dev) {
733 DEBUG(0, PFX "About to unregister net device %p\n",
734 dev);
735 unregister_netdev(dev);
736 }
737 free_orinocodev(dev);
738} /* spectrum_cs_detach */
739
740/*
741 * spectrum_cs_config() is scheduled to run after a CARD_INSERTION
742 * event is received, to configure the PCMCIA socket, and to make the
743 * device available to the system.
744 */
745
746static void
747spectrum_cs_config(dev_link_t *link)
748{
749 struct net_device *dev = link->priv;
750 client_handle_t handle = link->handle;
751 struct orinoco_private *priv = netdev_priv(dev);
752 struct orinoco_pccard *card = priv->card;
753 hermes_t *hw = &priv->hw;
754 int last_fn, last_ret;
755 u_char buf[64];
756 config_info_t conf;
757 cisinfo_t info;
758 tuple_t tuple;
759 cisparse_t parse;
760 void __iomem *mem;
761
762 CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info));
763
764 /*
765 * This reads the card's CONFIG tuple to find its
766 * configuration registers.
767 */
768 tuple.DesiredTuple = CISTPL_CONFIG;
769 tuple.Attributes = 0;
770 tuple.TupleData = buf;
771 tuple.TupleDataMax = sizeof(buf);
772 tuple.TupleOffset = 0;
773 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
774 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
775 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
776 link->conf.ConfigBase = parse.config.base;
777 link->conf.Present = parse.config.rmask[0];
778
779 /* Configure card */
780 link->state |= DEV_CONFIG;
781
782 /* Look up the current Vcc */
783 CS_CHECK(GetConfigurationInfo,
784 pcmcia_get_configuration_info(handle, &conf));
785 link->conf.Vcc = conf.Vcc;
786
787 /*
788 * In this loop, we scan the CIS for configuration table
789 * entries, each of which describes a valid card
790 * configuration, including voltage, IO window, memory window,
791 * and interrupt settings.
792 *
793 * We make no assumptions about the card to be configured: we
794 * use just the information available in the CIS. In an ideal
795 * world, this would work for any PCMCIA card, but it requires
796 * a complete and accurate CIS. In practice, a driver usually
797 * "knows" most of these things without consulting the CIS,
798 * and most client drivers will only use the CIS to fill in
799 * implementation-defined details.
800 */
801 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
802 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
803 while (1) {
804 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
805 cistpl_cftable_entry_t dflt = { .index = 0 };
806
807 if ( (pcmcia_get_tuple_data(handle, &tuple) != 0)
808 || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0))
809 goto next_entry;
810
811 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
812 dflt = *cfg;
813 if (cfg->index == 0)
814 goto next_entry;
815 link->conf.ConfigIndex = cfg->index;
816
817 /* Does this card need audio output? */
818 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
819 link->conf.Attributes |= CONF_ENABLE_SPKR;
820 link->conf.Status = CCSR_AUDIO_ENA;
821 }
822
823 /* Use power settings for Vcc and Vpp if present */
824 /* Note that the CIS values need to be rescaled */
825 if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
826 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
827 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
828 if (!ignore_cis_vcc)
829 goto next_entry;
830 }
831 } else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
832 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
833 DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n", conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
834 if(!ignore_cis_vcc)
835 goto next_entry;
836 }
837 }
838
839 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
840 link->conf.Vpp1 = link->conf.Vpp2 =
841 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
842 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
843 link->conf.Vpp1 = link->conf.Vpp2 =
844 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
845
846 /* Do we need to allocate an interrupt? */
847 link->conf.Attributes |= CONF_ENABLE_IRQ;
848
849 /* IO window settings */
850 link->io.NumPorts1 = link->io.NumPorts2 = 0;
851 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
852 cistpl_io_t *io =
853 (cfg->io.nwin) ? &cfg->io : &dflt.io;
854 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
855 if (!(io->flags & CISTPL_IO_8BIT))
856 link->io.Attributes1 =
857 IO_DATA_PATH_WIDTH_16;
858 if (!(io->flags & CISTPL_IO_16BIT))
859 link->io.Attributes1 =
860 IO_DATA_PATH_WIDTH_8;
861 link->io.IOAddrLines =
862 io->flags & CISTPL_IO_LINES_MASK;
863 link->io.BasePort1 = io->win[0].base;
864 link->io.NumPorts1 = io->win[0].len;
865 if (io->nwin > 1) {
866 link->io.Attributes2 =
867 link->io.Attributes1;
868 link->io.BasePort2 = io->win[1].base;
869 link->io.NumPorts2 = io->win[1].len;
870 }
871
872 /* This reserves IO space but doesn't actually enable it */
873 if (pcmcia_request_io(link->handle, &link->io) != 0)
874 goto next_entry;
875 }
876
877
878 /* If we got this far, we're cool! */
879
880 break;
881
882 next_entry:
883 if (link->io.NumPorts1)
884 pcmcia_release_io(link->handle, &link->io);
885 last_ret = pcmcia_get_next_tuple(handle, &tuple);
886 if (last_ret == CS_NO_MORE_ITEMS) {
887 printk(KERN_ERR PFX "GetNextTuple(): No matching "
888 "CIS configuration. Maybe you need the "
889 "ignore_cis_vcc=1 parameter.\n");
890 goto cs_failed;
891 }
892 }
893
894 /*
895 * Allocate an interrupt line. Note that this does not assign
896 * a handler to the interrupt, unless the 'Handler' member of
897 * the irq structure is initialized.
898 */
899 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
900
901 /* We initialize the hermes structure before completing PCMCIA
902 * configuration just in case the interrupt handler gets
903 * called. */
904 mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
905 if (!mem)
906 goto cs_failed;
907
908 hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
909
910 /*
911 * This actually configures the PCMCIA socket -- setting up
912 * the I/O windows and the interrupt mapping, and putting the
913 * card and host interface into "Memory and IO" mode.
914 */
915 CS_CHECK(RequestConfiguration,
916 pcmcia_request_configuration(link->handle, &link->conf));
917
918 /* Ok, we have the configuration, prepare to register the netdev */
919 dev->base_addr = link->io.BasePort1;
920 dev->irq = link->irq.AssignedIRQ;
921 SET_MODULE_OWNER(dev);
922 card->node.major = card->node.minor = 0;
923
924 /* Reset card and download firmware */
925 if (spectrum_cs_hard_reset(priv) != 0) {
926 goto failed;
927 }
928
929 SET_NETDEV_DEV(dev, &handle_to_dev(handle));
930 /* Tell the stack we exist */
931 if (register_netdev(dev) != 0) {
932 printk(KERN_ERR PFX "register_netdev() failed\n");
933 goto failed;
934 }
935
936 /* At this point, the dev_node_t structure(s) needs to be
937 * initialized and arranged in a linked list at link->dev. */
938 strcpy(card->node.dev_name, dev->name);
939 link->dev = &card->node; /* link->dev being non-NULL is also
940 used to indicate that the
941 net_device has been registered */
942 link->state &= ~DEV_CONFIG_PENDING;
943
944 /* Finally, report what we've done */
945 printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d",
946 dev->name, link->conf.ConfigIndex,
947 link->conf.Vcc / 10, link->conf.Vcc % 10);
948 if (link->conf.Vpp1)
949 printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
950 link->conf.Vpp1 % 10);
951 printk(", irq %d", link->irq.AssignedIRQ);
952 if (link->io.NumPorts1)
953 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
954 link->io.BasePort1 + link->io.NumPorts1 - 1);
955 if (link->io.NumPorts2)
956 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
957 link->io.BasePort2 + link->io.NumPorts2 - 1);
958 printk("\n");
959
960 return;
961
962 cs_failed:
963 cs_error(link->handle, last_fn, last_ret);
964
965 failed:
966 spectrum_cs_release(link);
967} /* spectrum_cs_config */
968
969/*
970 * After a card is removed, spectrum_cs_release() will unregister the
971 * device, and release the PCMCIA configuration. If the device is
972 * still open, this will be postponed until it is closed.
973 */
974static void
975spectrum_cs_release(dev_link_t *link)
976{
977 struct net_device *dev = link->priv;
978 struct orinoco_private *priv = netdev_priv(dev);
979 unsigned long flags;
980
981 /* We're committed to taking the device away now, so mark the
982 * hardware as unavailable */
983 spin_lock_irqsave(&priv->lock, flags);
984 priv->hw_unavailable++;
985 spin_unlock_irqrestore(&priv->lock, flags);
986
987 /* Don't bother checking to see if these succeed or not */
988 pcmcia_release_configuration(link->handle);
989 if (link->io.NumPorts1)
990 pcmcia_release_io(link->handle, &link->io);
991 if (link->irq.AssignedIRQ)
992 pcmcia_release_irq(link->handle, &link->irq);
993 link->state &= ~DEV_CONFIG;
994 if (priv->hw.iobase)
995 ioport_unmap(priv->hw.iobase);
996} /* spectrum_cs_release */
997
998/*
999 * The card status event handler. Mostly, this schedules other stuff
1000 * to run after an event is received.
1001 */
1002static int
1003spectrum_cs_event(event_t event, int priority,
1004 event_callback_args_t * args)
1005{
1006 dev_link_t *link = args->client_data;
1007 struct net_device *dev = link->priv;
1008 struct orinoco_private *priv = netdev_priv(dev);
1009 int err = 0;
1010 unsigned long flags;
1011
1012 switch (event) {
1013 case CS_EVENT_CARD_REMOVAL:
1014 link->state &= ~DEV_PRESENT;
1015 if (link->state & DEV_CONFIG) {
1016 unsigned long flags;
1017
1018 spin_lock_irqsave(&priv->lock, flags);
1019 netif_device_detach(dev);
1020 priv->hw_unavailable++;
1021 spin_unlock_irqrestore(&priv->lock, flags);
1022 }
1023 break;
1024
1025 case CS_EVENT_CARD_INSERTION:
1026 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1027 spectrum_cs_config(link);
1028 break;
1029
1030 case CS_EVENT_PM_SUSPEND:
1031 link->state |= DEV_SUSPEND;
1032 /* Fall through... */
1033 case CS_EVENT_RESET_PHYSICAL:
1034 /* Mark the device as stopped, to block IO until later */
1035 if (link->state & DEV_CONFIG) {
1036 /* This is probably racy, but I can't think of
1037 a better way, short of rewriting the PCMCIA
1038 layer to not suck :-( */
1039 spin_lock_irqsave(&priv->lock, flags);
1040
1041 err = __orinoco_down(dev);
1042 if (err)
1043 printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
1044 dev->name,
1045 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
1046 err);
1047
1048 netif_device_detach(dev);
1049 priv->hw_unavailable++;
1050
1051 spin_unlock_irqrestore(&priv->lock, flags);
1052
1053 pcmcia_release_configuration(link->handle);
1054 }
1055 break;
1056
1057 case CS_EVENT_PM_RESUME:
1058 link->state &= ~DEV_SUSPEND;
1059 /* Fall through... */
1060 case CS_EVENT_CARD_RESET:
1061 if (link->state & DEV_CONFIG) {
1062 /* FIXME: should we double check that this is
1063 * the same card as we had before */
1064 pcmcia_request_configuration(link->handle, &link->conf);
1065 netif_device_attach(dev);
1066 priv->hw_unavailable--;
1067 schedule_work(&priv->reset_work);
1068 }
1069 break;
1070 }
1071
1072 return err;
1073} /* spectrum_cs_event */
1074
1075/********************************************************************/
1076/* Module initialization */
1077/********************************************************************/
1078
1079/* Can't be declared "const" or the whole __initdata section will
1080 * become const */
1081static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
1082 " (Pavel Roskin <proski@gnu.org>,"
1083 " David Gibson <hermes@gibson.dropbear.id.au>, et al)";
1084
1085static struct pcmcia_device_id spectrum_cs_ids[] = {
1086 PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
1087 PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
1088 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001), /* Intel PRO/Wireless 2011B */
1089 PCMCIA_DEVICE_NULL,
1090};
1091MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
1092
1093static struct pcmcia_driver orinoco_driver = {
1094 .owner = THIS_MODULE,
1095 .drv = {
1096 .name = DRIVER_NAME,
1097 },
1098 .attach = spectrum_cs_attach,
1099 .event = spectrum_cs_event,
1100 .detach = spectrum_cs_detach,
1101 .id_table = spectrum_cs_ids,
1102};
1103
1104static int __init
1105init_spectrum_cs(void)
1106{
1107 printk(KERN_DEBUG "%s\n", version);
1108
1109 return pcmcia_register_driver(&orinoco_driver);
1110}
1111
1112static void __exit
1113exit_spectrum_cs(void)
1114{
1115 pcmcia_unregister_driver(&orinoco_driver);
1116 BUG_ON(dev_list != NULL);
1117}
1118
1119module_init(init_spectrum_cs);
1120module_exit(exit_spectrum_cs);