Commit 8b87cfcc authored by Dan Williams's avatar Dan Williams Committed by Jeff Garzik

[PATCH] wireless: Clean up firmware loading in

(resend)

Identify different firmware by enums, not strings, as we need to have
some integral firmware identifier for choosing maximum rssi values for
each different firmware type.  Consolidate the information about
firmware filenames and capabilities in the atmel module, not in atmel_cs
or atmel_pci.  Move common prototypes and firmware enum into new atmel.h
file.  The atmel_cs driver also thought that init_atmel_card() took "int
irq" as the first parameter, this is now fixed to be "unsigned short
irq".
Signed-off-by: default avatarDan Williams <dcbw@redhat.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent d62edbe1
...@@ -69,6 +69,7 @@ ...@@ -69,6 +69,7 @@
#include <linux/moduleparam.h> #include <linux/moduleparam.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include "ieee802_11.h" #include "ieee802_11.h"
#include "atmel.h"
#define DRIVER_MAJOR 0 #define DRIVER_MAJOR 0
#define DRIVER_MINOR 96 #define DRIVER_MINOR 96
...@@ -83,6 +84,23 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards"); ...@@ -83,6 +84,23 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x wireless cards");
static char *firmware = NULL; static char *firmware = NULL;
module_param(firmware, charp, 0); module_param(firmware, charp, 0);
/* table of firmware file names */
static struct {
AtmelFWType fw_type;
const char *fw_file;
const char *fw_file_ext;
} fw_table[] = {
{ ATMEL_FW_TYPE_502, "atmel_at76c502", "bin" },
{ ATMEL_FW_TYPE_502D, "atmel_at76c502d", "bin" },
{ ATMEL_FW_TYPE_502E, "atmel_at76c502e", "bin" },
{ ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com", "bin" },
{ ATMEL_FW_TYPE_504, "atmel_at76c504", "bin" },
{ ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958", "bin" },
{ ATMEL_FW_TYPE_504A_2958,"atmel_at76c504a_2958","bin" },
{ ATMEL_FW_TYPE_506, "atmel_at76c506", "bin" },
{ ATMEL_FW_TYPE_NONE, NULL, NULL }
};
#define MAX_SSID_LENGTH 32 #define MAX_SSID_LENGTH 32
#define MGMT_JIFFIES (256 * HZ / 100) #define MGMT_JIFFIES (256 * HZ / 100)
...@@ -458,8 +476,8 @@ struct atmel_private { ...@@ -458,8 +476,8 @@ struct atmel_private {
void *card; /* Bus dependent stucture varies for PCcard */ void *card; /* Bus dependent stucture varies for PCcard */
int (*present_callback)(void *); /* And callback which uses it */ int (*present_callback)(void *); /* And callback which uses it */
char firmware_id[32]; char firmware_id[32];
char firmware_template[32]; AtmelFWType firmware_type;
unsigned char *firmware; u8 *firmware;
int firmware_length; int firmware_length;
struct timer_list management_timer; struct timer_list management_timer;
struct net_device *dev; struct net_device *dev;
...@@ -1482,7 +1500,7 @@ static int atmel_read_proc(char *page, char **start, off_t off, ...@@ -1482,7 +1500,7 @@ static int atmel_read_proc(char *page, char **start, off_t off,
return len; return len;
} }
struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware_id, struct net_device *init_atmel_card( unsigned short irq, int port, const AtmelFWType fw_type,
struct device *sys_dev, int (*card_present)(void *), void *card) struct device *sys_dev, int (*card_present)(void *), void *card)
{ {
struct net_device *dev; struct net_device *dev;
...@@ -1507,11 +1525,9 @@ struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware ...@@ -1507,11 +1525,9 @@ struct net_device *init_atmel_card( unsigned short irq, int port, char *firmware
priv->card = card; priv->card = card;
priv->firmware = NULL; priv->firmware = NULL;
priv->firmware_id[0] = '\0'; priv->firmware_id[0] = '\0';
priv->firmware_template[0] = '\0'; priv->firmware_type = fw_type;
if (firmware) /* module parameter */ if (firmware) /* module parameter */
strcpy(priv->firmware_id, firmware); strcpy(priv->firmware_id, firmware);
else if (firmware_id) /* from PCMCIA card-matching or PCI */
strcpy(priv->firmware_template, firmware_id);
priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI; priv->bus_type = card_present ? BUS_TYPE_PCCARD : BUS_TYPE_PCI;
priv->station_state = STATION_STATE_DOWN; priv->station_state = STATION_STATE_DOWN;
priv->do_rx_crc = 0; priv->do_rx_crc = 0;
...@@ -3612,7 +3628,7 @@ static int reset_atmel_card(struct net_device *dev) ...@@ -3612,7 +3628,7 @@ static int reset_atmel_card(struct net_device *dev)
unsigned char *fw; unsigned char *fw;
int len = priv->firmware_length; int len = priv->firmware_length;
if (!(fw = priv->firmware)) { if (!(fw = priv->firmware)) {
if (strlen(priv->firmware_template) == 0) { if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
if (strlen(priv->firmware_id) == 0) { if (strlen(priv->firmware_id) == 0) {
printk(KERN_INFO printk(KERN_INFO
"%s: card type is unknown: assuming at76c502 firmware is OK.\n", "%s: card type is unknown: assuming at76c502 firmware is OK.\n",
...@@ -3627,24 +3643,36 @@ static int reset_atmel_card(struct net_device *dev) ...@@ -3627,24 +3643,36 @@ static int reset_atmel_card(struct net_device *dev)
"%s: firmware %s is missing, cannot continue.\n", "%s: firmware %s is missing, cannot continue.\n",
dev->name, priv->firmware_id); dev->name, priv->firmware_id);
return 0; return 0;
} }
} else { } else {
int i; int fw_index = 0;
int success = 0;
/* get firmware filename entry based on firmware type ID */
while (fw_table[fw_index].fw_type != priv->firmware_type
&& fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE)
fw_index++;
/* construct the actual firmware file name */
if (fw_table[fw_index].fw_type != ATMEL_FW_TYPE_NONE) {
int i;
for (i = 0; firmware_modifier[i]; i++) { for (i = 0; firmware_modifier[i]; i++) {
sprintf(priv->firmware_id, priv->firmware_template, firmware_modifier[i]); snprintf(priv->firmware_id, 32, "%s%s.%s", fw_table[fw_index].fw_file,
if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) firmware_modifier[i], fw_table[fw_index].fw_file_ext);
priv->firmware_id[31] = '\0';
if (request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev) == 0) {
success = 1;
break; break;
} }
if (!firmware_modifier[i]) { }
}
if (!success) {
printk(KERN_ALERT printk(KERN_ALERT
"%s: firmware %s is missing, cannot start.\n", "%s: firmware %s is missing, cannot start.\n",
dev->name, priv->firmware_id); dev->name, priv->firmware_id);
priv->firmware_id[0] = '\0'; priv->firmware_id[0] = '\0';
return 0; return 0;
} }
priv->firmware_template[0] = '\0';
} }
fw = fw_entry->data; fw = fw_entry->data;
......
/*** -*- linux-c -*- **********************************************************
Driver for Atmel at76c502 at76c504 and at76c506 wireless cards.
Copyright 2005 Dan Williams and Red Hat, Inc.
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
******************************************************************************/
#ifndef _ATMEL_H
#define _ATMEL_H
typedef enum {
ATMEL_FW_TYPE_NONE = 0,
ATMEL_FW_TYPE_502,
ATMEL_FW_TYPE_502D,
ATMEL_FW_TYPE_502E,
ATMEL_FW_TYPE_502_3COM,
ATMEL_FW_TYPE_504,
ATMEL_FW_TYPE_504_2958,
ATMEL_FW_TYPE_504A_2958,
ATMEL_FW_TYPE_506
} AtmelFWType;
struct net_device *init_atmel_card(unsigned short, int, const AtmelFWType, struct device *,
int (*present_func)(void *), void * );
void stop_atmel_card( struct net_device *, int );
int atmel_open( struct net_device * );
#endif
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include <asm/system.h> #include <asm/system.h>
#include <linux/wireless.h> #include <linux/wireless.h>
#include "atmel.h"
/* /*
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
...@@ -90,11 +91,6 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards"); ...@@ -90,11 +91,6 @@ MODULE_SUPPORTED_DEVICE("Atmel at76c50x PCMCIA cards");
event handler. event handler.
*/ */
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 atmel_open( struct net_device * );
static void atmel_config(dev_link_t *link); static void atmel_config(dev_link_t *link);
static void atmel_release(dev_link_t *link); static void atmel_release(dev_link_t *link);
static int atmel_event(event_t event, int priority, static int atmel_event(event_t event, int priority,
...@@ -307,28 +303,28 @@ static int card_present(void *arg) ...@@ -307,28 +303,28 @@ static int card_present(void *arg)
static struct { static struct {
int manf, card; int manf, card;
char *ver1; char *ver1;
char *firmware; AtmelFWType firmware;
char *name; char *name;
} card_table[] = { } card_table[] = {
{ 0, 0, "WLAN/802.11b PC CARD", "atmel_at76c502d%s.bin", "Actiontec 802CAT1" }, { 0, 0, "WLAN/802.11b PC CARD", ATMEL_FW_TYPE_502D, "Actiontec 802CAT1" },
{ 0, 0, "ATMEL/AT76C502AR", "atmel_at76c502%s.bin", "NoName-RFMD" }, { 0, 0, "ATMEL/AT76C502AR", ATMEL_FW_TYPE_502, "NoName-RFMD" },
{ 0, 0, "ATMEL/AT76C502AR_D", "atmel_at76c502d%s.bin", "NoName-revD" }, { 0, 0, "ATMEL/AT76C502AR_D", ATMEL_FW_TYPE_502D, "NoName-revD" },
{ 0, 0, "ATMEL/AT76C502AR_E", "atmel_at76c502e%s.bin", "NoName-revE" }, { 0, 0, "ATMEL/AT76C502AR_E", ATMEL_FW_TYPE_502E, "NoName-revE" },
{ 0, 0, "ATMEL/AT76C504", "atmel_at76c504%s.bin", "NoName-504" }, { 0, 0, "ATMEL/AT76C504", ATMEL_FW_TYPE_504, "NoName-504" },
{ 0, 0, "ATMEL/AT76C504A", "atmel_at76c504a_2958%s.bin", "NoName-504a-2958" }, { 0, 0, "ATMEL/AT76C504A", ATMEL_FW_TYPE_504A_2958, "NoName-504a-2958" },
{ 0, 0, "ATMEL/AT76C504_R", "atmel_at76c504_2958%s.bin", "NoName-504-2958" }, { 0, 0, "ATMEL/AT76C504_R", ATMEL_FW_TYPE_504_2958, "NoName-504-2958" },
{ MANFID_3COM, 0x0620, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRWE62092B" }, { MANFID_3COM, 0x0620, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRWE62092B" },
{ MANFID_3COM, 0x0696, NULL, "atmel_at76c502_3com%s.bin", "3com 3CRSHPW196" }, { MANFID_3COM, 0x0696, NULL, ATMEL_FW_TYPE_502_3COM, "3com 3CRSHPW196" },
{ 0, 0, "SMC/2632W-V2", "atmel_at76c502%s.bin", "SMC 2632W-V2" }, { 0, 0, "SMC/2632W-V2", ATMEL_FW_TYPE_502, "SMC 2632W-V2" },
{ 0, 0, "SMC/2632W", "atmel_at76c502d%s.bin", "SMC 2632W-V3" }, { 0, 0, "SMC/2632W", ATMEL_FW_TYPE_502D, "SMC 2632W-V3" },
{ 0xd601, 0x0007, NULL, "atmel_at76c502%s.bin", "Sitecom WLAN-011" }, { 0xd601, 0x0007, NULL, ATMEL_FW_TYPE_502, "Sitecom WLAN-011" },
{ 0x01bf, 0x3302, NULL, "atmel_at76c502e%s.bin", "Belkin F5D6020-V2" }, { 0x01bf, 0x3302, NULL, ATMEL_FW_TYPE_502E, "Belkin F5D6020-V2" },
{ 0, 0, "BT/Voyager 1020 Laptop Adapter", "atmel_at76c502%s.bin", "BT Voyager 1020" }, { 0, 0, "BT/Voyager 1020 Laptop Adapter", ATMEL_FW_TYPE_502, "BT Voyager 1020" },
{ 0, 0, "IEEE 802.11b/Wireless LAN PC Card", "atmel_at76c502%s.bin", "Siemens Gigaset PC Card II" }, { 0, 0, "IEEE 802.11b/Wireless LAN PC Card", ATMEL_FW_TYPE_502, "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_FW_TYPE_502E, "CNet CNWLC-811ARL" },
{ 0, 0, "Wireless/PC_CARD", "atmel_at76c502d%s.bin", "Planet WL-3552" }, { 0, 0, "Wireless/PC_CARD", ATMEL_FW_TYPE_502D, "Planet WL-3552" },
{ 0, 0, "OEM/11Mbps Wireless LAN PC Card V-3", "atmel_at76c502%s.bin", "OEM 11Mbps WLAN PCMCIA Card" }, { 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_at76c502e%s.bin", "11WAVE WaveBuddy" } { 0, 0, "11WAVE/11WP611AL-E", ATMEL_FW_TYPE_502E, "11WAVE WaveBuddy" }
}; };
static void atmel_config(dev_link_t *link) static void atmel_config(dev_link_t *link)
...@@ -520,7 +516,7 @@ static void atmel_config(dev_link_t *link) ...@@ -520,7 +516,7 @@ static void atmel_config(dev_link_t *link)
((local_info_t*)link->priv)->eth_dev = ((local_info_t*)link->priv)->eth_dev =
init_atmel_card(link->irq.AssignedIRQ, init_atmel_card(link->irq.AssignedIRQ,
link->io.BasePort1, link->io.BasePort1,
card_index == -1 ? NULL : card_table[card_index].firmware, card_index == -1 ? ATMEL_FW_TYPE_NONE : card_table[card_index].firmware,
&handle_to_dev(handle), &handle_to_dev(handle),
card_present, card_present,
link); link);
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include "atmel.h"
MODULE_AUTHOR("Simon Kelley"); MODULE_AUTHOR("Simon Kelley");
MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards."); MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet cards.");
...@@ -40,9 +41,6 @@ MODULE_DEVICE_TABLE(pci, card_ids); ...@@ -40,9 +41,6 @@ MODULE_DEVICE_TABLE(pci, card_ids);
static int atmel_pci_probe(struct pci_dev *, const struct pci_device_id *); static int atmel_pci_probe(struct pci_dev *, const struct pci_device_id *);
static void atmel_pci_remove(struct pci_dev *); 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 = { static struct pci_driver atmel_driver = {
.name = "atmel", .name = "atmel",
...@@ -63,7 +61,7 @@ static int __devinit atmel_pci_probe(struct pci_dev *pdev, ...@@ -63,7 +61,7 @@ static int __devinit atmel_pci_probe(struct pci_dev *pdev,
pci_set_master(pdev); pci_set_master(pdev);
dev = init_atmel_card(pdev->irq, pdev->resource[1].start, dev = init_atmel_card(pdev->irq, pdev->resource[1].start,
"atmel_at76c506%s.bin", ATMEL_FW_TYPE_506,
&pdev->dev, NULL, NULL); &pdev->dev, NULL, NULL);
if (!dev) if (!dev)
return -ENODEV; return -ENODEV;
......
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