Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b16a228d authored by Simon Kelley's avatar Simon Kelley Committed by Jeff Garzik
Browse files

[PATCH] Atmel wireless update



* Merge PCMCIA card table with new Brodowski PCMCIA id table.
* Add missing entries to PCMCIA id table.
* Other tweaks to conform with Documentation/driver-changes.txt
  (types, call request_region, etc)
* Fix size of requested IO region.
* Reduce printk verbosity.
* Remove EXPERIMENTAL
* tweak to association code - don't force shared key authentication
  when wep in use.

Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 741b2252
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -330,7 +330,7 @@ config PCI_HERMES

config ATMEL
      tristate "Atmel at76c50x chipset  802.11b support"
      depends on NET_RADIO && EXPERIMENTAL
      depends on NET_RADIO
      select FW_LOADER
      select CRC32
       ---help---
+43 −45
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@
#include "atmel.h"

#define DRIVER_MAJOR 0
#define DRIVER_MINOR 96
#define DRIVER_MINOR 98

MODULE_AUTHOR("Simon Kelley");
MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
@@ -1504,7 +1504,7 @@ static int atmel_read_proc(char *page, char **start, off_t off,
        return len;
}

struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWType fw_type,  
struct net_device *init_atmel_card( unsigned short irq, unsigned long port, const AtmelFWType fw_type,  
				    struct device *sys_dev, int (*card_present)(void *), void *card)
{
	struct net_device *dev;
@@ -1605,8 +1605,8 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT
		goto err_out_free;
	}

	if (priv->bus_type == BUS_TYPE_PCI &&
	    !request_region( dev->base_addr, 64, dev->name )) {
	if (!request_region(dev->base_addr, 32, 
			    priv->bus_type == BUS_TYPE_PCCARD ?  "atmel_cs" : "atmel_pci")) {
		goto err_out_irq;
	}
	
@@ -1622,15 +1622,16 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT
	
	create_proc_read_entry ("driver/atmel", 0, NULL, atmel_read_proc, priv);	
	
	printk(KERN_INFO "%s: Atmel at76c50x wireless. Version %d.%d simon@thekelleys.org.uk\n",
	       dev->name, DRIVER_MAJOR, DRIVER_MINOR);
	printk(KERN_INFO "%s: Atmel at76c50x. Version %d.%d. MAC %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
	       dev->name, DRIVER_MAJOR, DRIVER_MINOR,
	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
	
	SET_MODULE_OWNER(dev);
	return dev;
	
 err_out_res:
	if (priv->bus_type == BUS_TYPE_PCI)
	        release_region( dev->base_addr, 64 );
	release_region( dev->base_addr, 32);
 err_out_irq:
	free_irq(dev->irq, dev);
 err_out_free:
@@ -1640,7 +1641,7 @@ struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWT

EXPORT_SYMBOL(init_atmel_card);

void stop_atmel_card(struct net_device *dev, int freeres)
void stop_atmel_card(struct net_device *dev)
{
	struct atmel_private *priv = netdev_priv(dev);
		
@@ -1655,10 +1656,7 @@ void stop_atmel_card(struct net_device *dev, int freeres)
	free_irq(dev->irq, dev);
	if (priv->firmware)
		kfree(priv->firmware);
	if (freeres) {
		/* PCMCIA frees this stuff, so only for PCI */
	        release_region(dev->base_addr, 64);
        }
	release_region(dev->base_addr, 32);
	free_netdev(dev);
}

@@ -1828,11 +1826,12 @@ static int atmel_get_encode(struct net_device *dev,
	
	if (!priv->wep_is_on)
		dwrq->flags = IW_ENCODE_DISABLED;
	else if (priv->exclude_unencrypted)
	else {
		if (priv->exclude_unencrypted)
			dwrq->flags = IW_ENCODE_RESTRICTED;
		else
			dwrq->flags = IW_ENCODE_OPEN;
		
	}
		/* Which key do we want ? -1 -> tx index */
	if (index < 0 || index >= 4)
		index = priv->default_key;
@@ -2648,7 +2647,7 @@ static void handle_beacon_probe(struct atmel_private *priv, u16 capability, u8 c
}


static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
static void send_authentication_request(struct atmel_private *priv, u16 system, u8 *challenge, int challenge_len)
{
	struct ieee80211_hdr header;
	struct auth_body auth;
@@ -2660,14 +2659,11 @@ static void send_authentication_request(struct atmel_private *priv, u8 *challeng
	memcpy(header.addr2, priv->dev->dev_addr, 6);
	memcpy(header.addr3, priv->CurrentBSSID, 6);
	
	if (priv->wep_is_on) {
		auth.alg = cpu_to_le16(C80211_MGMT_AAN_SHAREDKEY); 
	if (priv->wep_is_on && priv->CurrentAuthentTransactionSeqNum != 1) 
		/* no WEP for authentication frames with TrSeqNo 1 */
		if (priv->CurrentAuthentTransactionSeqNum != 1)
                header.frame_ctl |=  cpu_to_le16(IEEE80211_FCTL_PROTECTED);
	} else {
		auth.alg = cpu_to_le16(C80211_MGMT_AAN_OPENSYSTEM);
	}
	
	auth.alg = cpu_to_le16(system); 

	auth.status = 0;
	auth.trans_seq = cpu_to_le16(priv->CurrentAuthentTransactionSeqNum);
@@ -2836,6 +2832,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
	struct auth_body *auth = (struct auth_body *)priv->rx_buf;
	u16 status = le16_to_cpu(auth->status);
	u16 trans_seq_no = le16_to_cpu(auth->trans_seq);
	u16 system = le16_to_cpu(auth->alg);
	
	if (status == C80211_MGMT_SC_Success && !priv->wep_is_on) { 
		/* no WEP */
@@ -2857,7 +2854,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
				
		if (trans_seq_no == 0x0002 &&
		    auth->el_id == C80211_MGMT_ElementID_ChallengeText) {
			send_authentication_request(priv, auth->chall_text, auth->chall_text_len);
			send_authentication_request(priv, system, auth->chall_text, auth->chall_text_len);
			return;
		}
		
@@ -2874,7 +2871,12 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
		}
	}			
	
	if (status == C80211_MGMT_SC_AuthAlgNotSupported && priv->connect_to_any_BSS) {
	if (status == C80211_MGMT_SC_AuthAlgNotSupported) {
		/* Do opensystem first, then try sharedkey */
		if (system ==  C80211_MGMT_AAN_OPENSYSTEM) {
			priv->CurrentAuthentTransactionSeqNum = 0x001;
			send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
		} else if (priv->connect_to_any_BSS) {
			int bss_index;
			
			priv->BSSinfo[(int)(priv->current_BSS)].channel |= 0x80;
@@ -2884,6 +2886,7 @@ static void authenticate(struct atmel_private *priv, u16 frame_len)
				return;
			}
		}
	}
	
	
	priv->AuthenticationRequestRetryCnt = 0;
@@ -3207,7 +3210,7 @@ static void atmel_management_timer(u_long a)
		  priv->AuthenticationRequestRetryCnt++;
		  priv->CurrentAuthentTransactionSeqNum = 0x0001;
		  mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
		  send_authentication_request(priv, NULL, 0);
		  send_authentication_request(priv, C80211_MGMT_AAN_OPENSYSTEM, NULL, 0);
	  }
	  
	  break;
@@ -3314,7 +3317,7 @@ static void atmel_command_irq(struct atmel_private *priv)
				
				mod_timer(&priv->management_timer, jiffies + MGMT_JIFFIES);
				priv->CurrentAuthentTransactionSeqNum = 0x0001;
				send_authentication_request(priv, NULL, 0);
				send_authentication_request(priv, C80211_MGMT_AAN_SHAREDKEY, NULL, 0);
			}
			return;
		}
@@ -3484,11 +3487,6 @@ static int probe_atmel_card(struct net_device *dev)
			printk(KERN_ALERT "%s: *** Invalid MAC address. UPGRADE Firmware ****\n", dev->name);
			memcpy(dev->dev_addr, default_mac, 6);
		}
		printk(KERN_INFO "%s: MAC address %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
		       dev->name,
		       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
		       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5] );
		
	}
	
	return rc;
+2 −2
Original line number Diff line number Diff line
@@ -35,9 +35,9 @@ typedef enum {
	ATMEL_FW_TYPE_506
} AtmelFWType;

struct net_device *init_atmel_card(unsigned short, int, const AtmelFWType, struct device *, 
struct net_device *init_atmel_card(unsigned short, unsigned long, const AtmelFWType, struct device *, 
				    int (*present_func)(void *), void * );
void stop_atmel_card( struct net_device *, int );
void stop_atmel_card( struct net_device *);
int atmel_open( struct net_device * );

#endif
+47 −129
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
   be present but disabled -- but it can then be enabled for specific
   modules at load time with a 'pc_debug=#' option to insmod.
*/

#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
module_param(pc_debug, int, 0);
@@ -288,41 +289,6 @@ static int card_present(void *arg)
	return 0;
}

/* list of cards we know about and their firmware requirements.
   Go either by Manfid or version strings.
   Cards not in this list will need a firmware parameter to the module
   in all probability. Note that the SMC 2632 V2 and V3 have the same
   manfids, so we ignore those and use the version1 strings. */

static struct { 
	int manf, card;
	char *ver1;
	AtmelFWType firmware;
	char *name;
} card_table[] = {
	{ 0, 0, "WLAN/802.11b PC CARD", ATMEL_FW_TYPE_502D, "Actiontec 802CAT1" },  
	{ 0, 0, "ATMEL/AT76C502AR", ATMEL_FW_TYPE_502, "NoName-RFMD" }, 
	{ 0, 0, "ATMEL/AT76C502AR_D", ATMEL_FW_TYPE_502D, "NoName-revD" }, 
	{ 0, 0, "ATMEL/AT76C502AR_E", ATMEL_FW_TYPE_502E, "NoName-revE" },
	{ 0, 0, "ATMEL/AT76C504", ATMEL_FW_TYPE_504, "NoName-504" },
	{ 0, 0, "ATMEL/AT76C504A", ATMEL_FW_TYPE_504A_2958, "NoName-504a-2958" },
	{ 0, 0, "ATMEL/AT76C504_R", ATMEL_FW_TYPE_504_2958, "NoName-504-2958" },
	{ MANFID_3COM, 0x0620, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRWE62092B" }, 
	{ MANFID_3COM, 0x0696, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRSHPW196" }, 
	{ 0, 0, "SMC/2632W-V2", ATMEL_FW_TYPE_502, "SMC 2632W-V2" },
	{ 0, 0, "SMC/2632W", ATMEL_FW_TYPE_502D, "SMC 2632W-V3" },
	{ 0xd601, 0x0007, NULL, ATMEL_FW_TYPE_502, "Sitecom WLAN-011" }, 
	{ 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" }, 
	{ 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" },
	{ 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "Siemens Gigaset PC Card II" },
	{ 0, 0, "IEEE 802.11b/Wireless LAN Card S", ATMEL_FW_TYPE_504_2958, "Siemens Gigaset PC Card II" },
	{ 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", ATMEL_FW_TYPE_502E, "CNet CNWLC-811ARL" },
	{ 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" },
	{ 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", ATMEL_FW_TYPE_502, "OEM 11Mbps WLAN PCMCIA Card" },
	{ 0, 0, "11WAVE/11WP611AL-E", ATMEL_FW_TYPE_502E, "11WAVE WaveBuddy" },
	{ 0, 0, "LG/LW2100N", ATMEL_FW_TYPE_502E, "LG LW2100N 11Mbps WLAN PCMCIA Card" },
};

static void atmel_config(dev_link_t *link)
{
	client_handle_t handle;
@@ -331,10 +297,11 @@ static void atmel_config(dev_link_t *link)
	local_info_t *dev;
	int last_fn, last_ret;
	u_char buf[64];
	int card_index = -1, done = 0;
	struct pcmcia_device_id *did;

	handle = link->handle;
	dev = link->priv;
	did = handle_to_dev(handle).driver_data;

	DEBUG(0, "atmel_config(0x%p)\n", link);
	
@@ -343,59 +310,6 @@ static void atmel_config(dev_link_t *link)
	tuple.TupleDataMax = sizeof(buf);
	tuple.TupleOffset = 0;
	
	tuple.DesiredTuple = CISTPL_MANFID;
	if (pcmcia_get_first_tuple(handle, &tuple) == 0) {
		int i;
		cistpl_manfid_t *manfid;
		CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
		CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
		manfid = &(parse.manfid);
		for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
			if (!card_table[i].ver1 &&
			    manfid->manf == card_table[i].manf &&
			    manfid->card == card_table[i].card) {
				card_index = i;
				done = 1;
			}
		}
	}

	tuple.DesiredTuple = CISTPL_VERS_1;
	if (!done && (pcmcia_get_first_tuple(handle, &tuple) == 0)) {
		int i, j, k;
		cistpl_vers_1_t *ver1;
		CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
		CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
		ver1 = &(parse.version_1);
		
		for (i = 0; i < sizeof(card_table)/sizeof(card_table[0]); i++) {
			for (j = 0; j < ver1->ns; j++) {
				char *p = card_table[i].ver1;
				char *q = &ver1->str[ver1->ofs[j]];
				if (!p)
					goto mismatch;
				for (k = 0; k < j; k++) {
					while ((*p != '\0') && (*p != '/')) p++;
					if (*p == '\0') {
						if (*q != '\0')
							goto mismatch;
					} else {
						p++;
					}
				}
				while((*q != '\0') && (*p != '\0') && 
				      (*p != '/') && (*p == *q)) p++, q++;
				if (((*p != '\0') && *p != '/') || *q != '\0')
					goto mismatch;
			}
			card_index = i;
			break;	/* done */
			
		mismatch:
			j = 0; /* dummy stmt to shut up compiler */
		}
	}		

	/*
	  This reads the card's CONFIG tuple to find its configuration
	  registers.
@@ -512,13 +426,14 @@ static void atmel_config(dev_link_t *link)
	((local_info_t*)link->priv)->eth_dev = 
		init_atmel_card(link->irq.AssignedIRQ,
				link->io.BasePort1,
				card_index == -1 ? ATMEL_FW_TYPE_NONE :  card_table[card_index].firmware,
				did ? did->driver_info : ATMEL_FW_TYPE_NONE,
				&handle_to_dev(handle),
				card_present, 
				link);
	if (!((local_info_t*)link->priv)->eth_dev) 
			goto cs_failed;
	
	
	/*
	  At this point, the dev_node_t structure(s) need to be
	  initialized and arranged in a linked list at link->dev.
@@ -527,25 +442,6 @@ static void atmel_config(dev_link_t *link)
	dev->node.major = dev->node.minor = 0;
	link->dev = &dev->node;
			
	/* Finally, report what we've done */
	printk(KERN_INFO "%s: %s%sindex 0x%02x: Vcc %d.%d",
	       dev->node.dev_name,
	       card_index == -1 ? "" :  card_table[card_index].name,
	       card_index == -1 ? "" : " ",
	       link->conf.ConfigIndex,
	       link->conf.Vcc/10, link->conf.Vcc%10);
	if (link->conf.Vpp1)
		printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
	if (link->conf.Attributes & CONF_ENABLE_IRQ)
		printk(", irq %d", link->irq.AssignedIRQ);
	if (link->io.NumPorts1)
		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
		       link->io.BasePort1+link->io.NumPorts1-1);
	if (link->io.NumPorts2)
		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
		       link->io.BasePort2+link->io.NumPorts2-1);
	printk("\n");
	
	link->state &= ~DEV_CONFIG_PENDING;
	return;
	
@@ -572,7 +468,7 @@ static void atmel_release(dev_link_t *link)
	link->dev = NULL;
	
	if (dev) 
		stop_atmel_card(dev, 0);
		stop_atmel_card(dev);
	((local_info_t*)link->priv)->eth_dev = NULL; 
	
	/* Don't bother checking to see if these succeed or not */
@@ -640,25 +536,47 @@ static int atmel_event(event_t event, int priority,
} /* atmel_event */

/*====================================================================*/
/* We use the driver_info field to store the correct firmware type for a card. */

#define PCMCIA_DEVICE_MANF_CARD_INFO(manf, card, info) { \
	.match_flags = PCMCIA_DEV_ID_MATCH_MANF_ID| \
			PCMCIA_DEV_ID_MATCH_CARD_ID, \
	.manf_id = (manf), \
	.card_id = (card), \
        .driver_info = (kernel_ulong_t)(info), }

#define PCMCIA_DEVICE_PROD_ID12_INFO(v1, v2, vh1, vh2, info) { \
	.match_flags = PCMCIA_DEV_ID_MATCH_PROD_ID1| \
			PCMCIA_DEV_ID_MATCH_PROD_ID2, \
	.prod_id = { (v1), (v2), NULL, NULL }, \
	.prod_id_hash = { (vh1), (vh2), 0, 0 }, \
        .driver_info = (kernel_ulong_t)(info), }

static struct pcmcia_device_id atmel_ids[] = {
	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0620),
	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0696),
	PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x3302),
	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0007),
	PCMCIA_DEVICE_PROD_ID12("11WAVE", "11WP611AL-E", 0x9eb2da1f, 0xc9a0d3f9),
	PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C502AR", 0xabda4164, 0x41b37e1f),
	PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C504", 0xabda4164, 0x5040670a),
	PCMCIA_DEVICE_PROD_ID12("ATMEL", "AT76C504A", 0xabda4164, 0xe15ed87f),
	PCMCIA_DEVICE_PROD_ID12("BT", "Voyager 1020 Laptop Adapter", 0xae49b86a, 0x1e957cd5),
	PCMCIA_DEVICE_PROD_ID12("CNet", "CNWLC 11Mbps Wireless PC Card V-5", 0xbc477dde, 0x502fae6b),
	PCMCIA_DEVICE_PROD_ID12("IEEE 802.11b", "Wireless LAN PC Card", 0x5b878724, 0x122f1df6),
	PCMCIA_DEVICE_PROD_ID12("OEM", "11Mbps Wireless LAN PC Card V-3", 0xfea54c90, 0x1c5b0f68),
	PCMCIA_DEVICE_PROD_ID12("SMC", "2632W", 0xc4f8b18b, 0x30f38774),
	PCMCIA_DEVICE_PROD_ID12("SMC", "2632W-V2", 0xc4f8b18b, 0x172d1377),
	PCMCIA_DEVICE_PROD_ID12("Wireless", "PC", 0xa407ecdd, 0x556e4d7e),
	PCMCIA_DEVICE_PROD_ID12("WLAN", "802.11b PC CARD", 0x575c516c, 0xb1f6dbc4),
	PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0620, ATMEL_FW_TYPE_502_3COM),
	PCMCIA_DEVICE_MANF_CARD_INFO(0x0101, 0x0696, ATMEL_FW_TYPE_502_3COM),
	PCMCIA_DEVICE_MANF_CARD_INFO(0x01bf, 0x3302, ATMEL_FW_TYPE_502E),
	PCMCIA_DEVICE_MANF_CARD_INFO(0xd601, 0x0007, ATMEL_FW_TYPE_502),
	PCMCIA_DEVICE_PROD_ID12_INFO("11WAVE", "11WP611AL-E", 0x9eb2da1f, 0xc9a0d3f9, ATMEL_FW_TYPE_502E),
	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR", 0xabda4164, 0x41b37e1f, ATMEL_FW_TYPE_502),
	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_D", 0xabda4164, 0x3675d704, ATMEL_FW_TYPE_502D),
	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C502AR_E", 0xabda4164, 0x4172e792, ATMEL_FW_TYPE_502E),
	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504_R", 0xabda4164, 0x917f3d72, ATMEL_FW_TYPE_504_2958),
	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504", 0xabda4164, 0x5040670a, ATMEL_FW_TYPE_504),
	PCMCIA_DEVICE_PROD_ID12_INFO("ATMEL", "AT76C504A", 0xabda4164, 0xe15ed87f, ATMEL_FW_TYPE_504A_2958),
	PCMCIA_DEVICE_PROD_ID12_INFO("BT", "Voyager 1020 Laptop Adapter", 0xae49b86a, 0x1e957cd5, ATMEL_FW_TYPE_502),
	PCMCIA_DEVICE_PROD_ID12_INFO("CNet", "CNWLC 11Mbps Wireless PC Card V-5", 0xbc477dde, 0x502fae6b, ATMEL_FW_TYPE_502E),
	PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN PC Card", 0x5b878724, 0x122f1df6, ATMEL_FW_TYPE_502),
	PCMCIA_DEVICE_PROD_ID12_INFO("IEEE 802.11b", "Wireless LAN Card S", 0x5b878724, 0x5fba533a, ATMEL_FW_TYPE_504_2958),
	PCMCIA_DEVICE_PROD_ID12_INFO("OEM", "11Mbps Wireless LAN PC Card V-3", 0xfea54c90, 0x1c5b0f68, ATMEL_FW_TYPE_502),
	PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W", 0xc4f8b18b, 0x30f38774, ATMEL_FW_TYPE_502D),
	PCMCIA_DEVICE_PROD_ID12_INFO("SMC", "2632W-V2", 0xc4f8b18b, 0x172d1377, ATMEL_FW_TYPE_502),
	PCMCIA_DEVICE_PROD_ID12_INFO("Wireless", "PC_CARD", 0xa407ecdd, 0x119f6314, ATMEL_FW_TYPE_502D),
	PCMCIA_DEVICE_PROD_ID12_INFO("WLAN", "802.11b PC CARD", 0x575c516c, 0xb1f6dbc4, ATMEL_FW_TYPE_502D),
	PCMCIA_DEVICE_PROD_ID12_INFO("LG", "LW2100N", 0xb474d43a, 0x6b1fec94, ATMEL_FW_TYPE_502E),
	PCMCIA_DEVICE_NULL
};

MODULE_DEVICE_TABLE(pcmcia, atmel_ids);

static struct pcmcia_driver atmel_driver = {
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ static int __devinit atmel_pci_probe(struct pci_dev *pdev,

static void __devexit atmel_pci_remove(struct pci_dev *pdev)
{
	stop_atmel_card(pci_get_drvdata(pdev), 1);
	stop_atmel_card(pci_get_drvdata(pdev));
}

static int __init atmel_init_module(void)