Commit e5a2baf7 authored by Simon Kelley's avatar Simon Kelley Committed by Jeff Garzik

[wireless atmel] update

	Add PCI device support - there are atmel_pci.ko and atmel_cs.ko
	modules and a library module called atmel.ko

	Tweak the PCMCIA card -> firmware table for new cards.

	Fix workarounds for uniquely broken 3com cards, which were
	rendered unuable by the 0.9 changes.

	Bump version to 0.91
parent e9967b6c
......@@ -221,6 +221,29 @@ config PCI_HERMES
common. Some of the built-in wireless adaptors in laptops are of
this variety.
config ATMEL
tristate "Atmel at76c50x chipset 802.11b support"
depends on NET_RADIO && EXPERIMENTAL
enable FW_LOADER
enable CRC32
---help---
A driver 802.11b wireless cards based on the Atmel fast-vnet
chips. This driver supports standard Linux wireless extensions.
Many cards based on this chipset do not have flash memory
and need their firmware loaded at start-up. If yours is
one of these, you will need to provide a firmware image
to be loaded into the card by the driver. The Atmel
firmware package can be downloaded from
http://www.thekelleys.org.uk/atmel
config PCI_ATMEL
tristate "Atmel at76c506 PCI cards"
depends on ATMEL && PCI
---help---
Enable support for PCI and mini-PCI cards containing the
Atmel at76c506 chip.
# If Pcmcia is compiled in, offer Pcmcia cards...
comment "Wireless 802.11b Pcmcia/Cardbus cards support"
depends on NET_RADIO && PCMCIA
......@@ -268,21 +291,13 @@ config AIRO_CS
available from <http://www.tldp.org/docs.html#howto>.
config PCMCIA_ATMEL
tristate "Atmel at76c502/at76c504 PCMCIA cards"
depends on NET_RADIO && EXPERIMENTAL && PCMCIA
select FW_LOADER
select CRC32
---help---
A driver for PCMCIA 802.11 wireless cards based on the
Atmel fast-vnet chips. This driver supports standard
Linux wireless extensions.
Many cards based on this chipset do not have flash memory
and need their firmware loaded at start-up. If yours is
one of these, you will need to provide a firmware image
to be loaded into the card by the driver. The Atmel
firmware package can be downloaded from
http://www.thekelleys.org.uk/atmel
tristate "Atmel at76c502/at76c504 PCMCIA cards"
depends on NET_RADIO && ATMEL && PCMCIA
select FW_LOADER
select CRC32
---help---
Enable support for PCMCIA cards containing the
Atmel at76c502 and at76c504 chips.
config PCMCIA_WL3501
tristate "Planet WL3501 PCMCIA cards"
......
......@@ -22,7 +22,10 @@ obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o
obj-$(CONFIG_AIRO) += airo.o
obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o
obj-$(CONFIG_ATMEL) += atmel.o
obj-$(CONFIG_PCI_ATMEL) += atmel_pci.o
obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
# 16-bit wireless PCMCIA client drivers
obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o atmel.o
obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
......@@ -17,9 +17,6 @@
This file contains the module in binary form and, under the terms
of the GPL, in source form. The source is located at the end of the file.
For all queries about this code, please contact the current author,
Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
......@@ -34,6 +31,12 @@
along with Atmel wireless lan drivers; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
For all queries about this code, please contact the current author,
Simon Kelley <simon@thekelleys.org.uk> and not Atmel Corporation.
Credit is due to HP UK and Cambridge Online Systems Ltd for supplying
hardware used during development of this driver.
******************************************************************************/
#include <linux/config.h>
......@@ -67,7 +70,7 @@
#include "ieee802_11.h"
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 9
#define DRIVER_MINOR 91
MODULE_AUTHOR("Simon Kelley");
MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
......@@ -469,7 +472,6 @@ struct atmel_private {
CARD_TYPE_SPI_FLASH,
CARD_TYPE_EEPROM
} card_type;
int is3com; /* is this a 3com card? they are uniquely borken */
int do_rx_crc; /* If we need to CRC incoming packets */
int probe_crc; /* set if we don't yet know */
int crc_ok_cnt, crc_ko_cnt; /* counters for probing */
......@@ -484,7 +486,7 @@ struct atmel_private {
u8 group_cipher_suite, pairwise_cipher_suite;
u8 wep_keys[MAX_ENCRYPTION_KEYS][MAX_ENCRYPTION_KEY_SIZE];
int wep_key_len[MAX_ENCRYPTION_KEYS];
int use_wpa;
int use_wpa, radio_on_broken; /* firmware dependent stuff. */
u16 host_info_base;
struct host_info_struct {
......@@ -1386,7 +1388,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, char *firmware_id, int is3com,
struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware_id,
struct device *sys_dev, int (*card_present)(void *), void *card)
{
struct net_device *dev;
......@@ -1418,7 +1420,6 @@ struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware
strcpy(priv->firmware_template, firmware_id);
priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
priv->station_state = STATION_STATE_DOWN;
priv->is3com = is3com;
priv->do_rx_crc = 0;
/* For PCMCIA cards, some chips need CRC, some don't
so we have to probe. */
......@@ -1525,16 +1526,15 @@ EXPORT_SYMBOL(init_atmel_card);
void stop_atmel_card(struct net_device *dev, int freeres)
{
struct atmel_private *priv = dev->priv;
unregister_netdev(dev);
/* put a brick on it... */
if (priv->bus_type == BUS_TYPE_PCCARD)
atmel_write16(dev, GCR, 0x0060);
atmel_write16(dev, GCR, 0x0040);
remove_proc_entry("driver/atmel", NULL);
del_timer_sync(&priv->management_timer);
unregister_netdev(dev);
remove_proc_entry("driver/atmel", NULL);
free_irq(dev->irq, dev);
if (priv->firmware)
kfree(priv->firmware);
......@@ -1995,8 +1995,8 @@ static int atmel_set_freq(struct net_device *dev,
/* If setting by frequency, convert to a channel */
if((fwrq->e == 1) &&
(fwrq->m >= (int) 2.412e8) &&
(fwrq->m <= (int) 2.487e8)) {
(fwrq->m >= (int) 241200000) &&
(fwrq->m <= (int) 248700000)) {
int f = fwrq->m / 100000;
int c = 0;
while((c < 14) && (f != frequency_list[c]))
......@@ -3594,8 +3594,12 @@ int reset_atmel_card(struct net_device *dev)
return 0;
/* Check the version and set the correct flag for wpa stuff,
old and new firmware is incompatible. */
priv->use_wpa = (priv->host_info.major_version >= 4);
old and new firmware is incompatible.
The pre-wpa 3com firmware reports major version 5,
the wpa 3com firmware is major version 4 and doesn't need
the 3com broken-ness filter. */
priv->use_wpa = (priv->host_info.major_version == 4);
priv->radio_on_broken = (priv->host_info.major_version == 5);
/* unmask all irq sources */
atmel_wmem8(priv, atmel_hi(priv, IFACE_INT_MASK_OFFSET), 0xff);
......@@ -3640,7 +3644,7 @@ int reset_atmel_card(struct net_device *dev)
if ((channel = atmel_validate_channel(priv, priv->channel)))
priv->channel = channel;
if (!priv->is3com) {
if (!priv->radio_on_broken) {
if (atmel_send_command_wait(priv, CMD_EnableRadio, NULL, 0) ==
CMD_STATUS_REJECTED_RADIO_OFF) {
printk(KERN_INFO
......@@ -3854,7 +3858,6 @@ static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data)
atmel_write16(priv->dev, DR, data >> 16);
}
/***************************************************************************/
/* There follows the source form of the MAC address reading firmware */
/***************************************************************************/
......
......@@ -101,7 +101,7 @@ MODULE_PARM(irq_list, "1-4i");
event handler.
*/
struct net_device *init_atmel_card(int, int, char *, int, struct device *,
struct net_device *init_atmel_card(int, int, char *, struct device *,
int (*present_func)(void *), void * );
void stop_atmel_card( struct net_device *, int );
int reset_atmel_card( struct net_device * );
......@@ -332,15 +332,20 @@ static struct {
{ 0, 0, "ATMEL/AT76C502AR_D", "atmel_at76c502d%s.bin", "NoName-revD" },
{ 0, 0, "ATMEL/AT76C502AR_E", "atmel_at76c502e%s.bin", "NoName-revE" },
{ 0, 0, "ATMEL/AT76C504", "atmel_at76c504%s.bin", "NoName-504" },
{ 0, 0, "ATMEL/AT76C504A", "atmel_at76c504a_2958%s.bin", "NoName-504a-2958" },
{ 0, 0, "ATMEL/AT76C504_R", "atmel_at76c504_2958%s.bin", "NoName-504-2958" },
{ MANFID_3COM, 0x0620, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRWE62092B" },
{ MANFID_3COM, 0x0696, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRSHPW_96" },
{ 0, 0, "SMC/2632W-V2", "atmel_at76c502%s.bin", "SMC 2632W-V2" },
{ 0, 0, "SMC/2632W", "atmel_at76c502d%s.bin", "SMC 2632W-V3" },
{ 0xd601, 0x0007, NULL, "atmel_at76c502%s.bin", "Sitecom WLAN-011"}, /* suspect - from a usenet posting. */
{ 0x01bf, 0x3302, NULL, "atmel_at76c502d%s.bin", "Belkin F5D6060u"}, /* " " " " " */
{ 0, 0, "BT/Voyager 1020 Laptop Adapter", "atmel_at76c502%s.bin", "BT Voyager 1020"},
{ 0xd601, 0x0007, NULL, "atmel_at76c502%s.bin", "Sitecom WLAN-011" },
{ 0x01bf, 0x3302, NULL, "atmel_at76c502e%s.bin", "Belkin F5D6020-V2" },
{ 0, 0, "BT/Voyager 1020 Laptop Adapter", "atmel_at76c502%s.bin", "BT Voyager 1020" },
{ 0, 0, "IEEE 802.11b/Wireless LAN PC Card", "atmel_at76c502%s.bin", "Siemens Gigaset PC Card II" },
{ 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", "atmel_at76c502e%s.bin", "CNet CNWLC-811ARL" }
{ 0, 0, "CNet/CNWLC 11Mbps Wireless PC Card V-5", "atmel_at76c502e%s.bin", "CNet CNWLC-811ARL" },
{ 0, 0, "Wireless/PC_CARD", "atmel_at76c502d%s.bin", "Planet WL-3552" },
{ 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", "atmel_at76c502%s.bin", "OEM 11Mbps WLAN PCMCIA Card" },
{ 0, 0, "11WAVE/11WP611AL-E", "atmel_at76c502e%s.bin", "11WAVE WaveBuddy" }
};
/* This is strictly temporary, until PCMCIA devices get integrated into the device model. */
......@@ -538,7 +543,6 @@ static void atmel_config(dev_link_t *link)
init_atmel_card(link->irq.AssignedIRQ,
link->io.BasePort1,
card_index == -1 ? NULL : card_table[card_index].firmware,
card_index == -1 ? 0 : (card_table[card_index].manf == MANFID_3COM),
&atmel_device,
card_present,
link);
......
/*** -*- linux-c -*- **********************************************************
Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
Copyright 2004 Simon Kelley.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This software is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Atmel wireless lan drivers; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
******************************************************************************/
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
MODULE_AUTHOR("Simon Kelley");
MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("Atmel at76c506 PCI wireless cards");
static struct pci_device_id card_ids[] = {
{ 0x1114, 0x0506, PCI_ANY_ID, PCI_ANY_ID },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, card_ids);
static int atmel_pci_probe(struct pci_dev *, const struct pci_device_id *);
static void atmel_pci_remove(struct pci_dev *);
struct net_device *init_atmel_card(int, int, char *, struct device *,
int (*present_func)(void *), void * );
void stop_atmel_card( struct net_device *, int );
static struct pci_driver atmel_driver = {
.name = "atmel",
.id_table = card_ids,
.probe = atmel_pci_probe,
.remove = __devexit_p(atmel_pci_remove),
};
static int __devinit atmel_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *pent)
{
struct net_device *dev;
if (pci_enable_device(pdev))
return -ENODEV;
pci_set_master(pdev);
dev = init_atmel_card(pdev->irq, pdev->resource[1].start,
"atmel_at76c506%s.bin",
&pdev->dev, NULL, NULL);
if (!dev)
return -ENODEV;
pci_set_drvdata(pdev, dev);
return 0;
}
static void __devexit atmel_pci_remove(struct pci_dev *pdev)
{
stop_atmel_card(pci_get_drvdata(pdev), 1);
}
static int __init atmel_init_module(void)
{
return pci_module_init(&atmel_driver);
}
static void __exit atmel_cleanup_module(void)
{
pci_unregister_driver(&atmel_driver);
}
module_init(atmel_init_module);
module_exit(atmel_cleanup_module);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment