netdev
[Top] [All Lists]

[PATCH 2.6.11-rc2] wireless: Atmel clearer firmware selection and 502e m

To: netdev@xxxxxxxxxxx
Subject: [PATCH 2.6.11-rc2] wireless: Atmel clearer firmware selection and 502e max rssi fix
From: Dan Williams <dcbw@xxxxxxxxxx>
Date: Sun, 30 Jan 2005 19:05:20 -0500 (EST)
Cc: jgarzik@xxxxxxxxxx, jt@xxxxxxxxxx, simon@xxxxxxxxxxxxxxxxx
Sender: netdev-bounce@xxxxxxxxxxx
Clear up firmware selection by passing an enum into init_atmel_card() 
rather than the firmware string.  Necessary to differentiate between 
firmware versions due to different max rssi for each firmware.  Move 
common prototypes into new atmel.h file which also contains firmware enum.

Signed-off-by: Dan Williams <dcbw@xxxxxxxxxx>


--- /dev/null   1969-12-31 19:00:00.000000000 -0500
+++ b/drivers/net/wireless/atmel.h      2005-01-30 18:33:31.000000000 -0500
@@ -0,0 +1,43 @@
+/*** -*- 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
--- a/drivers/net/wireless/atmel.c      2005-01-27 20:26:46.000000000 -0500
+++ b/drivers/net/wireless/atmel.c      2005-01-30 18:37:27.000000000 -0500
@@ -69,6 +69,7 @@
 #include <linux/moduleparam.h>
 #include <linux/firmware.h>
 #include "ieee802_11.h"
+#include "atmel.h"
 
 #define DRIVER_MAJOR 0
 #define DRIVER_MINOR 96
@@ -83,6 +84,22 @@
 static char *firmware = NULL;
 module_param(firmware, charp, 0);
 
+/* table of firmware file names */
+static struct { 
+       AtmelFWType fw_type;
+       const char *filename;
+} firmware_table[] = {
+       { ATMEL_FW_TYPE_502,      "atmel_at76c502%s.bin" },
+       { ATMEL_FW_TYPE_502D,     "atmel_at76c502d%s.bin" },
+       { ATMEL_FW_TYPE_502E,     "atmel_at76c502e%s.bin" },
+       { ATMEL_FW_TYPE_502_3COM, "atmel_at76c502_3com%s.bin" },
+       { ATMEL_FW_TYPE_504,      "atmel_at76c504%s.bin" },
+       { ATMEL_FW_TYPE_504_2958, "atmel_at76c504_2958%s.bin" },
+       { ATMEL_FW_TYPE_504A_2958,"atmel_at76c504a_2958%s.bin" },
+       { ATMEL_FW_TYPE_506,      "atmel_at76c506%s.bin" },
+       { ATMEL_FW_TYPE_NONE,      NULL }
+};
+
 #define MAX_SSID_LENGTH 32
 #define MGMT_JIFFIES (256 * HZ / 100)
 
@@ -458,8 +475,8 @@
        void *card; /* Bus dependent stucture varies for PCcard */
        int (*present_callback)(void *); /* And callback which uses it */
        char firmware_id[32];
-       char firmware_template[32];
-       unsigned char *firmware;
+       AtmelFWType firmware_type;
+       u8 *firmware;
        int firmware_length;
        struct timer_list management_timer;
        struct net_device *dev;
@@ -1293,17 +1310,21 @@
        if (priv->operating_mode == IW_MODE_INFRA) {
                if (priv->station_state != STATION_STATE_READY) {
                        priv->wstats.qual.qual = 0;
-                       priv->wstats.qual.level = 0;
+                       priv->wstats.qual.level = 0;
+                       priv->wstats.qual.updated |= (IW_QUAL_QUAL_INVALID
+                                               | IW_QUAL_LEVEL_INVALID);
                }
                priv->wstats.qual.noise = 0;
-               priv->wstats.qual.updated = 7;
+               priv->wstats.qual.updated |= IW_QUAL_NOISE_INVALID;
        } else {
                /* Quality levels cannot be determined in ad-hoc mode,
                   because we can 'hear' more that one remote station. */
                priv->wstats.qual.qual = 0;
                priv->wstats.qual.level = 0;
                priv->wstats.qual.noise = 0;
-               priv->wstats.qual.updated = 0;
+               priv->wstats.qual.updated = IW_QUAL_QUAL_INVALID
+                                       | IW_QUAL_LEVEL_INVALID
+                                       | IW_QUAL_NOISE_INVALID;
                priv->wstats.miss.beacon = 0;
        }
        
@@ -1482,7 +1503,7 @@
         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 net_device *dev;
@@ -1507,11 +1528,9 @@
        priv->card = card;
        priv->firmware = NULL;
        priv->firmware_id[0] = '\0';
-       priv->firmware_template[0] = '\0';
+       priv->firmware_type = fw_type;
        if (firmware) /* module parameter */
                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->station_state = STATION_STATE_DOWN;
        priv->do_rx_crc = 0;
@@ -2218,6 +2237,9 @@
        range->max_qual.qual = 100;
        range->max_qual.level = 100;
        range->max_qual.noise = 0;
+       range->max_qual.updated = IW_QUAL_QUAL_UPDATED
+                               | IW_QUAL_LEVEL_UPDATED
+                               | IW_QUAL_NOISE_INVALID;
        range->sensitivity = 0;
 
        range->bitrate[0] =  1000000;
@@ -2247,9 +2269,13 @@
        range->r_time_flags = 0;
        range->min_retry = 1;
        range->max_retry = 65535;
+
        range->avg_qual.qual = 50;
        range->avg_qual.level = 50;
        range->avg_qual.noise = 0;
+       range->avg_qual.updated = IW_QUAL_QUAL_UPDATED
+                               | IW_QUAL_LEVEL_UPDATED
+                               | IW_QUAL_NOISE_INVALID;
 
        return 0;
 }
@@ -3025,16 +3051,23 @@
 static void smooth_rssi(struct atmel_private *priv, u8 rssi)
 {
        u8 old = priv->wstats.qual.level;
+       u8 max_rssi = 42; /* 502-rmfd-revd max by experiment */
 
-       /* 502-rmfd-revd gives max signal level as 42, by experiment.
-          This is going to break for other hardware variants. */
+       switch (priv->firmware_type) {
+               case ATMEL_FW_TYPE_502E:
+                       max_rssi = 63; /* 502-rmfd-reve max by experiment */
+                       break;
+               default:
+                       break;
+       }
 
-       rssi = rssi * 100 / 42;
+       rssi = rssi * 100 / max_rssi;
        if((rssi + old) % 2)
                priv->wstats.qual.level =  ((rssi + old)/2) + 1;
        else
                priv->wstats.qual.level =  ((rssi + old)/2);            
-       
+       priv->wstats.qual.updated |= IW_QUAL_LEVEL_UPDATED;
+       priv->wstats.qual.updated &= ~IW_QUAL_LEVEL_INVALID;
 }
 
 static void atmel_smooth_qual(struct atmel_private *priv)
@@ -3047,8 +3080,10 @@
                        priv->beacons_this_sec * priv->beacon_period * 
(priv->wstats.qual.level + 100) / 4000;
                priv->beacons_this_sec = 0;
        }
+       priv->wstats.qual.updated |= IW_QUAL_QUAL_UPDATED;
+       priv->wstats.qual.updated &= ~IW_QUAL_QUAL_INVALID;
 }
-       
+
 /* deals with incoming managment frames. */
 static void atmel_management_frame(struct atmel_private *priv, struct 
ieee802_11_hdr *header, 
                      u16 frame_len, u8 rssi)
@@ -3571,6 +3606,17 @@
        atmel_set_mib(priv, Mac_Wep_Mib_Type, 0, (u8 *)&mib, sizeof(mib));
 }
                                        
+static const char *atmel_get_firmware_template (const AtmelFWType fw_type)
+{
+       int i;
+       for(i = 0; i < sizeof(firmware_table)/sizeof(firmware_table[0]); i++)
+       {
+               if (firmware_table[i].fw_type == fw_type)
+                       return firmware_table[i].filename;
+       }
+       return NULL;
+}
+
 static int reset_atmel_card(struct net_device *dev) 
 {
        /* do everything necessary to wake up the hardware, including
@@ -3611,8 +3657,8 @@
                const struct firmware *fw_entry = NULL;
                unsigned char *fw;
                int len = priv->firmware_length;
-               if (!(fw = priv->firmware)) { 
-                       if (strlen(priv->firmware_template) == 0) {     
+               if (!(fw = priv->firmware)) {
+                       if (priv->firmware_type == ATMEL_FW_TYPE_NONE) {
                                if (strlen(priv->firmware_id) == 0) {
                                        printk(KERN_INFO
                                               "%s: card type is unknown: 
assuming at76c502 firmware is OK.\n",
@@ -3627,24 +3673,24 @@
                                               "%s: firmware %s is missing, 
cannot continue.\n", 
                                               dev->name, priv->firmware_id);
                                        return 0;
-                                       
-                               } 
+                               }
                        } else {
                                int i;
+                               const char *s = 
atmel_get_firmware_template(priv->firmware_type);
                                
-                               for (i = 0; firmware_modifier[i]; i++) {
-                                       sprintf(priv->firmware_id, 
priv->firmware_template, firmware_modifier[i]);
+                               for (i = 0; s && firmware_modifier[i]; i++) {
+                                       snprintf(priv->firmware_id, 32, s, 
firmware_modifier[i]);
+                                       priv->firmware_id[31] = '\0';
                                        if (request_firmware(&fw_entry, 
priv->firmware_id, priv->sys_dev) == 0) 
                                                break;
                                }
-                               if (!firmware_modifier[i]) {
+                               if (!s || !firmware_modifier[i]) {
                                        printk(KERN_ALERT 
                                               "%s: firmware %s is missing, 
cannot start.\n", 
                                               dev->name, priv->firmware_id);
                                        priv->firmware_id[0] = '\0';
                                        return 0;       
                                }
-                               priv->firmware_template[0] = '\0';      
                        }
                        
                        fw = fw_entry->data;
--- a/drivers/net/wireless/atmel_cs.c   2005-01-27 20:26:46.000000000 -0500
+++ b/drivers/net/wireless/atmel_cs.c   2005-01-30 14:05:08.000000000 -0500
@@ -55,6 +55,7 @@
 #include <asm/system.h>
 #include <linux/wireless.h>
 
+#include "atmel.h"
 
 /*
    All the PCMCIA modules use PCMCIA_DEBUG to control debugging.  If
@@ -90,11 +91,6 @@
    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_release(dev_link_t *link);
 static int atmel_event(event_t event, int priority,
@@ -307,28 +303,28 @@
 static struct { 
        int manf, card;
        char *ver1;
-       char *firmware;
+       AtmelFWType firmware;
        char *name;
 } card_table[] = {
-       { 0, 0, "WLAN/802.11b PC CARD", "atmel_at76c502d%s.bin", "Actiontec 
802CAT1" },  
-       { 0, 0, "ATMEL/AT76C502AR", "atmel_at76c502%s.bin", "NoName-RFMD" }, 
-       { 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 
3CRSHPW196" }, 
-       { 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" }, 
-       { 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, "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" } 
+       { 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, "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" } 
 };
 
 static void atmel_config(dev_link_t *link)
@@ -520,7 +516,7 @@
        ((local_info_t*)link->priv)->eth_dev = 
                init_atmel_card(link->irq.AssignedIRQ,
                                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),
                                card_present, 
                                link);
--- a/drivers/net/wireless/atmel_pci.c  2005-01-27 20:26:46.000000000 -0500
+++ b/drivers/net/wireless/atmel_pci.c  2005-01-30 14:05:30.000000000 -0500
@@ -25,6 +25,7 @@
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/netdevice.h>
+#include "atmel.h"
 
 MODULE_AUTHOR("Simon Kelley");
 MODULE_DESCRIPTION("Support for Atmel at76c50x 802.11 wireless ethernet 
cards.");
@@ -40,9 +41,6 @@
 
 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",
@@ -63,7 +61,7 @@
        pci_set_master(pdev);
        
        dev = init_atmel_card(pdev->irq, pdev->resource[1].start, 
-                             "atmel_at76c506%s.bin",
+                             ATMEL_FW_TYPE_506,
                              &pdev->dev, NULL, NULL);
        if (!dev)
                return -ENODEV;

Attachment: atmel-502e-quality-fix.patch
Description: Text document

<Prev in Thread] Current Thread [Next in Thread>
  • [PATCH 2.6.11-rc2] wireless: Atmel clearer firmware selection and 502e max rssi fix, Dan Williams <=