diff options
-rw-r--r-- | drivers/net/wireless/orinoco/hw.c | 216 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/hw.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco/main.c | 218 |
3 files changed, 219 insertions, 216 deletions
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c index 632fac86a308..209c6bef0cd9 100644 --- a/drivers/net/wireless/orinoco/hw.c +++ b/drivers/net/wireless/orinoco/hw.c | |||
@@ -13,6 +13,8 @@ | |||
13 | 13 | ||
14 | #include "hw.h" | 14 | #include "hw.h" |
15 | 15 | ||
16 | #define SYMBOL_MAX_VER_LEN (14) | ||
17 | |||
16 | /********************************************************************/ | 18 | /********************************************************************/ |
17 | /* Data tables */ | 19 | /* Data tables */ |
18 | /********************************************************************/ | 20 | /********************************************************************/ |
@@ -36,6 +38,220 @@ static const struct { | |||
36 | }; | 38 | }; |
37 | #define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table) | 39 | #define BITRATE_TABLE_SIZE ARRAY_SIZE(bitrate_table) |
38 | 40 | ||
41 | /* Firmware version encoding */ | ||
42 | struct comp_id { | ||
43 | u16 id, variant, major, minor; | ||
44 | } __attribute__ ((packed)); | ||
45 | |||
46 | static inline fwtype_t determine_firmware_type(struct comp_id *nic_id) | ||
47 | { | ||
48 | if (nic_id->id < 0x8000) | ||
49 | return FIRMWARE_TYPE_AGERE; | ||
50 | else if (nic_id->id == 0x8000 && nic_id->major == 0) | ||
51 | return FIRMWARE_TYPE_SYMBOL; | ||
52 | else | ||
53 | return FIRMWARE_TYPE_INTERSIL; | ||
54 | } | ||
55 | |||
56 | /* Set priv->firmware type, determine firmware properties */ | ||
57 | int determine_fw_capabilities(struct orinoco_private *priv) | ||
58 | { | ||
59 | struct net_device *dev = priv->ndev; | ||
60 | hermes_t *hw = &priv->hw; | ||
61 | int err; | ||
62 | struct comp_id nic_id, sta_id; | ||
63 | unsigned int firmver; | ||
64 | char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2))); | ||
65 | |||
66 | /* Get the hardware version */ | ||
67 | err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id); | ||
68 | if (err) { | ||
69 | printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n", | ||
70 | dev->name, err); | ||
71 | return err; | ||
72 | } | ||
73 | |||
74 | le16_to_cpus(&nic_id.id); | ||
75 | le16_to_cpus(&nic_id.variant); | ||
76 | le16_to_cpus(&nic_id.major); | ||
77 | le16_to_cpus(&nic_id.minor); | ||
78 | printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n", | ||
79 | dev->name, nic_id.id, nic_id.variant, | ||
80 | nic_id.major, nic_id.minor); | ||
81 | |||
82 | priv->firmware_type = determine_firmware_type(&nic_id); | ||
83 | |||
84 | /* Get the firmware version */ | ||
85 | err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id); | ||
86 | if (err) { | ||
87 | printk(KERN_ERR "%s: Cannot read station identity: error %d\n", | ||
88 | dev->name, err); | ||
89 | return err; | ||
90 | } | ||
91 | |||
92 | le16_to_cpus(&sta_id.id); | ||
93 | le16_to_cpus(&sta_id.variant); | ||
94 | le16_to_cpus(&sta_id.major); | ||
95 | le16_to_cpus(&sta_id.minor); | ||
96 | printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n", | ||
97 | dev->name, sta_id.id, sta_id.variant, | ||
98 | sta_id.major, sta_id.minor); | ||
99 | |||
100 | switch (sta_id.id) { | ||
101 | case 0x15: | ||
102 | printk(KERN_ERR "%s: Primary firmware is active\n", | ||
103 | dev->name); | ||
104 | return -ENODEV; | ||
105 | case 0x14b: | ||
106 | printk(KERN_ERR "%s: Tertiary firmware is active\n", | ||
107 | dev->name); | ||
108 | return -ENODEV; | ||
109 | case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */ | ||
110 | case 0x21: /* Symbol Spectrum24 Trilogy */ | ||
111 | break; | ||
112 | default: | ||
113 | printk(KERN_NOTICE "%s: Unknown station ID, please report\n", | ||
114 | dev->name); | ||
115 | break; | ||
116 | } | ||
117 | |||
118 | /* Default capabilities */ | ||
119 | priv->has_sensitivity = 1; | ||
120 | priv->has_mwo = 0; | ||
121 | priv->has_preamble = 0; | ||
122 | priv->has_port3 = 1; | ||
123 | priv->has_ibss = 1; | ||
124 | priv->has_wep = 0; | ||
125 | priv->has_big_wep = 0; | ||
126 | priv->has_alt_txcntl = 0; | ||
127 | priv->has_ext_scan = 0; | ||
128 | priv->has_wpa = 0; | ||
129 | priv->do_fw_download = 0; | ||
130 | |||
131 | /* Determine capabilities from the firmware version */ | ||
132 | switch (priv->firmware_type) { | ||
133 | case FIRMWARE_TYPE_AGERE: | ||
134 | /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout, | ||
135 | ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */ | ||
136 | snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, | ||
137 | "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor); | ||
138 | |||
139 | firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor; | ||
140 | |||
141 | priv->has_ibss = (firmver >= 0x60006); | ||
142 | priv->has_wep = (firmver >= 0x40020); | ||
143 | priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell | ||
144 | Gold cards from the others? */ | ||
145 | priv->has_mwo = (firmver >= 0x60000); | ||
146 | priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */ | ||
147 | priv->ibss_port = 1; | ||
148 | priv->has_hostscan = (firmver >= 0x8000a); | ||
149 | priv->do_fw_download = 1; | ||
150 | priv->broken_monitor = (firmver >= 0x80000); | ||
151 | priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */ | ||
152 | priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */ | ||
153 | priv->has_wpa = (firmver >= 0x9002a); | ||
154 | /* Tested with Agere firmware : | ||
155 | * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II | ||
156 | * Tested CableTron firmware : 4.32 => Anton */ | ||
157 | break; | ||
158 | case FIRMWARE_TYPE_SYMBOL: | ||
159 | /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */ | ||
160 | /* Intel MAC : 00:02:B3:* */ | ||
161 | /* 3Com MAC : 00:50:DA:* */ | ||
162 | memset(tmp, 0, sizeof(tmp)); | ||
163 | /* Get the Symbol firmware version */ | ||
164 | err = hermes_read_ltv(hw, USER_BAP, | ||
165 | HERMES_RID_SECONDARYVERSION_SYMBOL, | ||
166 | SYMBOL_MAX_VER_LEN, NULL, &tmp); | ||
167 | if (err) { | ||
168 | printk(KERN_WARNING | ||
169 | "%s: Error %d reading Symbol firmware info. " | ||
170 | "Wildly guessing capabilities...\n", | ||
171 | dev->name, err); | ||
172 | firmver = 0; | ||
173 | tmp[0] = '\0'; | ||
174 | } else { | ||
175 | /* The firmware revision is a string, the format is | ||
176 | * something like : "V2.20-01". | ||
177 | * Quick and dirty parsing... - Jean II | ||
178 | */ | ||
179 | firmver = ((tmp[1] - '0') << 16) | ||
180 | | ((tmp[3] - '0') << 12) | ||
181 | | ((tmp[4] - '0') << 8) | ||
182 | | ((tmp[6] - '0') << 4) | ||
183 | | (tmp[7] - '0'); | ||
184 | |||
185 | tmp[SYMBOL_MAX_VER_LEN] = '\0'; | ||
186 | } | ||
187 | |||
188 | snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, | ||
189 | "Symbol %s", tmp); | ||
190 | |||
191 | priv->has_ibss = (firmver >= 0x20000); | ||
192 | priv->has_wep = (firmver >= 0x15012); | ||
193 | priv->has_big_wep = (firmver >= 0x20000); | ||
194 | priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || | ||
195 | (firmver >= 0x29000 && firmver < 0x30000) || | ||
196 | firmver >= 0x31000; | ||
197 | priv->has_preamble = (firmver >= 0x20000); | ||
198 | priv->ibss_port = 4; | ||
199 | |||
200 | /* Symbol firmware is found on various cards, but | ||
201 | * there has been no attempt to check firmware | ||
202 | * download on non-spectrum_cs based cards. | ||
203 | * | ||
204 | * Given that the Agere firmware download works | ||
205 | * differently, we should avoid doing a firmware | ||
206 | * download with the Symbol algorithm on non-spectrum | ||
207 | * cards. | ||
208 | * | ||
209 | * For now we can identify a spectrum_cs based card | ||
210 | * because it has a firmware reset function. | ||
211 | */ | ||
212 | priv->do_fw_download = (priv->stop_fw != NULL); | ||
213 | |||
214 | priv->broken_disableport = (firmver == 0x25013) || | ||
215 | (firmver >= 0x30000 && firmver <= 0x31000); | ||
216 | priv->has_hostscan = (firmver >= 0x31001) || | ||
217 | (firmver >= 0x29057 && firmver < 0x30000); | ||
218 | /* Tested with Intel firmware : 0x20015 => Jean II */ | ||
219 | /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ | ||
220 | break; | ||
221 | case FIRMWARE_TYPE_INTERSIL: | ||
222 | /* D-Link, Linksys, Adtron, ZoomAir, and many others... | ||
223 | * Samsung, Compaq 100/200 and Proxim are slightly | ||
224 | * different and less well tested */ | ||
225 | /* D-Link MAC : 00:40:05:* */ | ||
226 | /* Addtron MAC : 00:90:D1:* */ | ||
227 | snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, | ||
228 | "Intersil %d.%d.%d", sta_id.major, sta_id.minor, | ||
229 | sta_id.variant); | ||
230 | |||
231 | firmver = ((unsigned long)sta_id.major << 16) | | ||
232 | ((unsigned long)sta_id.minor << 8) | sta_id.variant; | ||
233 | |||
234 | priv->has_ibss = (firmver >= 0x000700); /* FIXME */ | ||
235 | priv->has_big_wep = priv->has_wep = (firmver >= 0x000800); | ||
236 | priv->has_pm = (firmver >= 0x000700); | ||
237 | priv->has_hostscan = (firmver >= 0x010301); | ||
238 | |||
239 | if (firmver >= 0x000800) | ||
240 | priv->ibss_port = 0; | ||
241 | else { | ||
242 | printk(KERN_NOTICE "%s: Intersil firmware earlier " | ||
243 | "than v0.8.x - several features not supported\n", | ||
244 | dev->name); | ||
245 | priv->ibss_port = 1; | ||
246 | } | ||
247 | break; | ||
248 | } | ||
249 | printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name, | ||
250 | priv->fw_name); | ||
251 | |||
252 | return 0; | ||
253 | } | ||
254 | |||
39 | int orinoco_get_bitratemode(int bitrate, int automatic) | 255 | int orinoco_get_bitratemode(int bitrate, int automatic) |
40 | { | 256 | { |
41 | int ratemode = -1; | 257 | int ratemode = -1; |
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h index dc3f23a9c1c7..f7845b855f76 100644 --- a/drivers/net/wireless/orinoco/hw.h +++ b/drivers/net/wireless/orinoco/hw.h | |||
@@ -23,6 +23,7 @@ | |||
23 | struct orinoco_private; | 23 | struct orinoco_private; |
24 | struct dev_addr_list; | 24 | struct dev_addr_list; |
25 | 25 | ||
26 | int determine_fw_capabilities(struct orinoco_private *priv); | ||
26 | int orinoco_get_bitratemode(int bitrate, int automatic); | 27 | int orinoco_get_bitratemode(int bitrate, int automatic); |
27 | void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic); | 28 | void orinoco_get_ratemode_cfg(int ratemode, int *bitrate, int *automatic); |
28 | 29 | ||
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index 345593c4accb..33326d6ef815 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -142,7 +142,6 @@ static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; | |||
142 | #define ORINOCO_MIN_MTU 256 | 142 | #define ORINOCO_MIN_MTU 256 |
143 | #define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD) | 143 | #define ORINOCO_MAX_MTU (IEEE80211_MAX_DATA_LEN - ENCAPS_OVERHEAD) |
144 | 144 | ||
145 | #define SYMBOL_MAX_VER_LEN (14) | ||
146 | #define MAX_IRQLOOPS_PER_IRQ 10 | 145 | #define MAX_IRQLOOPS_PER_IRQ 10 |
147 | #define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of | 146 | #define MAX_IRQLOOPS_PER_JIFFY (20000/HZ) /* Based on a guestimate of |
148 | * how many events the | 147 | * how many events the |
@@ -2096,219 +2095,6 @@ static void orinoco_unregister_pm_notifier(struct orinoco_private *priv) | |||
2096 | /* Initialization */ | 2095 | /* Initialization */ |
2097 | /********************************************************************/ | 2096 | /********************************************************************/ |
2098 | 2097 | ||
2099 | struct comp_id { | ||
2100 | u16 id, variant, major, minor; | ||
2101 | } __attribute__ ((packed)); | ||
2102 | |||
2103 | static inline fwtype_t determine_firmware_type(struct comp_id *nic_id) | ||
2104 | { | ||
2105 | if (nic_id->id < 0x8000) | ||
2106 | return FIRMWARE_TYPE_AGERE; | ||
2107 | else if (nic_id->id == 0x8000 && nic_id->major == 0) | ||
2108 | return FIRMWARE_TYPE_SYMBOL; | ||
2109 | else | ||
2110 | return FIRMWARE_TYPE_INTERSIL; | ||
2111 | } | ||
2112 | |||
2113 | /* Set priv->firmware type, determine firmware properties */ | ||
2114 | static int determine_firmware(struct net_device *dev) | ||
2115 | { | ||
2116 | struct orinoco_private *priv = netdev_priv(dev); | ||
2117 | hermes_t *hw = &priv->hw; | ||
2118 | int err; | ||
2119 | struct comp_id nic_id, sta_id; | ||
2120 | unsigned int firmver; | ||
2121 | char tmp[SYMBOL_MAX_VER_LEN+1] __attribute__((aligned(2))); | ||
2122 | |||
2123 | /* Get the hardware version */ | ||
2124 | err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_NICID, &nic_id); | ||
2125 | if (err) { | ||
2126 | printk(KERN_ERR "%s: Cannot read hardware identity: error %d\n", | ||
2127 | dev->name, err); | ||
2128 | return err; | ||
2129 | } | ||
2130 | |||
2131 | le16_to_cpus(&nic_id.id); | ||
2132 | le16_to_cpus(&nic_id.variant); | ||
2133 | le16_to_cpus(&nic_id.major); | ||
2134 | le16_to_cpus(&nic_id.minor); | ||
2135 | printk(KERN_DEBUG "%s: Hardware identity %04x:%04x:%04x:%04x\n", | ||
2136 | dev->name, nic_id.id, nic_id.variant, | ||
2137 | nic_id.major, nic_id.minor); | ||
2138 | |||
2139 | priv->firmware_type = determine_firmware_type(&nic_id); | ||
2140 | |||
2141 | /* Get the firmware version */ | ||
2142 | err = HERMES_READ_RECORD(hw, USER_BAP, HERMES_RID_STAID, &sta_id); | ||
2143 | if (err) { | ||
2144 | printk(KERN_ERR "%s: Cannot read station identity: error %d\n", | ||
2145 | dev->name, err); | ||
2146 | return err; | ||
2147 | } | ||
2148 | |||
2149 | le16_to_cpus(&sta_id.id); | ||
2150 | le16_to_cpus(&sta_id.variant); | ||
2151 | le16_to_cpus(&sta_id.major); | ||
2152 | le16_to_cpus(&sta_id.minor); | ||
2153 | printk(KERN_DEBUG "%s: Station identity %04x:%04x:%04x:%04x\n", | ||
2154 | dev->name, sta_id.id, sta_id.variant, | ||
2155 | sta_id.major, sta_id.minor); | ||
2156 | |||
2157 | switch (sta_id.id) { | ||
2158 | case 0x15: | ||
2159 | printk(KERN_ERR "%s: Primary firmware is active\n", | ||
2160 | dev->name); | ||
2161 | return -ENODEV; | ||
2162 | case 0x14b: | ||
2163 | printk(KERN_ERR "%s: Tertiary firmware is active\n", | ||
2164 | dev->name); | ||
2165 | return -ENODEV; | ||
2166 | case 0x1f: /* Intersil, Agere, Symbol Spectrum24 */ | ||
2167 | case 0x21: /* Symbol Spectrum24 Trilogy */ | ||
2168 | break; | ||
2169 | default: | ||
2170 | printk(KERN_NOTICE "%s: Unknown station ID, please report\n", | ||
2171 | dev->name); | ||
2172 | break; | ||
2173 | } | ||
2174 | |||
2175 | /* Default capabilities */ | ||
2176 | priv->has_sensitivity = 1; | ||
2177 | priv->has_mwo = 0; | ||
2178 | priv->has_preamble = 0; | ||
2179 | priv->has_port3 = 1; | ||
2180 | priv->has_ibss = 1; | ||
2181 | priv->has_wep = 0; | ||
2182 | priv->has_big_wep = 0; | ||
2183 | priv->has_alt_txcntl = 0; | ||
2184 | priv->has_ext_scan = 0; | ||
2185 | priv->has_wpa = 0; | ||
2186 | priv->do_fw_download = 0; | ||
2187 | |||
2188 | /* Determine capabilities from the firmware version */ | ||
2189 | switch (priv->firmware_type) { | ||
2190 | case FIRMWARE_TYPE_AGERE: | ||
2191 | /* Lucent Wavelan IEEE, Lucent Orinoco, Cabletron RoamAbout, | ||
2192 | ELSA, Melco, HP, IBM, Dell 1150, Compaq 110/210 */ | ||
2193 | snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, | ||
2194 | "Lucent/Agere %d.%02d", sta_id.major, sta_id.minor); | ||
2195 | |||
2196 | firmver = ((unsigned long)sta_id.major << 16) | sta_id.minor; | ||
2197 | |||
2198 | priv->has_ibss = (firmver >= 0x60006); | ||
2199 | priv->has_wep = (firmver >= 0x40020); | ||
2200 | priv->has_big_wep = 1; /* FIXME: this is wrong - how do we tell | ||
2201 | Gold cards from the others? */ | ||
2202 | priv->has_mwo = (firmver >= 0x60000); | ||
2203 | priv->has_pm = (firmver >= 0x40020); /* Don't work in 7.52 ? */ | ||
2204 | priv->ibss_port = 1; | ||
2205 | priv->has_hostscan = (firmver >= 0x8000a); | ||
2206 | priv->do_fw_download = 1; | ||
2207 | priv->broken_monitor = (firmver >= 0x80000); | ||
2208 | priv->has_alt_txcntl = (firmver >= 0x90000); /* All 9.x ? */ | ||
2209 | priv->has_ext_scan = (firmver >= 0x90000); /* All 9.x ? */ | ||
2210 | priv->has_wpa = (firmver >= 0x9002a); | ||
2211 | /* Tested with Agere firmware : | ||
2212 | * 1.16 ; 4.08 ; 4.52 ; 6.04 ; 6.16 ; 7.28 => Jean II | ||
2213 | * Tested CableTron firmware : 4.32 => Anton */ | ||
2214 | break; | ||
2215 | case FIRMWARE_TYPE_SYMBOL: | ||
2216 | /* Symbol , 3Com AirConnect, Intel, Ericsson WLAN */ | ||
2217 | /* Intel MAC : 00:02:B3:* */ | ||
2218 | /* 3Com MAC : 00:50:DA:* */ | ||
2219 | memset(tmp, 0, sizeof(tmp)); | ||
2220 | /* Get the Symbol firmware version */ | ||
2221 | err = hermes_read_ltv(hw, USER_BAP, | ||
2222 | HERMES_RID_SECONDARYVERSION_SYMBOL, | ||
2223 | SYMBOL_MAX_VER_LEN, NULL, &tmp); | ||
2224 | if (err) { | ||
2225 | printk(KERN_WARNING | ||
2226 | "%s: Error %d reading Symbol firmware info. " | ||
2227 | "Wildly guessing capabilities...\n", | ||
2228 | dev->name, err); | ||
2229 | firmver = 0; | ||
2230 | tmp[0] = '\0'; | ||
2231 | } else { | ||
2232 | /* The firmware revision is a string, the format is | ||
2233 | * something like : "V2.20-01". | ||
2234 | * Quick and dirty parsing... - Jean II | ||
2235 | */ | ||
2236 | firmver = ((tmp[1] - '0') << 16) | ||
2237 | | ((tmp[3] - '0') << 12) | ||
2238 | | ((tmp[4] - '0') << 8) | ||
2239 | | ((tmp[6] - '0') << 4) | ||
2240 | | (tmp[7] - '0'); | ||
2241 | |||
2242 | tmp[SYMBOL_MAX_VER_LEN] = '\0'; | ||
2243 | } | ||
2244 | |||
2245 | snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, | ||
2246 | "Symbol %s", tmp); | ||
2247 | |||
2248 | priv->has_ibss = (firmver >= 0x20000); | ||
2249 | priv->has_wep = (firmver >= 0x15012); | ||
2250 | priv->has_big_wep = (firmver >= 0x20000); | ||
2251 | priv->has_pm = (firmver >= 0x20000 && firmver < 0x22000) || | ||
2252 | (firmver >= 0x29000 && firmver < 0x30000) || | ||
2253 | firmver >= 0x31000; | ||
2254 | priv->has_preamble = (firmver >= 0x20000); | ||
2255 | priv->ibss_port = 4; | ||
2256 | |||
2257 | /* Symbol firmware is found on various cards, but | ||
2258 | * there has been no attempt to check firmware | ||
2259 | * download on non-spectrum_cs based cards. | ||
2260 | * | ||
2261 | * Given that the Agere firmware download works | ||
2262 | * differently, we should avoid doing a firmware | ||
2263 | * download with the Symbol algorithm on non-spectrum | ||
2264 | * cards. | ||
2265 | * | ||
2266 | * For now we can identify a spectrum_cs based card | ||
2267 | * because it has a firmware reset function. | ||
2268 | */ | ||
2269 | priv->do_fw_download = (priv->stop_fw != NULL); | ||
2270 | |||
2271 | priv->broken_disableport = (firmver == 0x25013) || | ||
2272 | (firmver >= 0x30000 && firmver <= 0x31000); | ||
2273 | priv->has_hostscan = (firmver >= 0x31001) || | ||
2274 | (firmver >= 0x29057 && firmver < 0x30000); | ||
2275 | /* Tested with Intel firmware : 0x20015 => Jean II */ | ||
2276 | /* Tested with 3Com firmware : 0x15012 & 0x22001 => Jean II */ | ||
2277 | break; | ||
2278 | case FIRMWARE_TYPE_INTERSIL: | ||
2279 | /* D-Link, Linksys, Adtron, ZoomAir, and many others... | ||
2280 | * Samsung, Compaq 100/200 and Proxim are slightly | ||
2281 | * different and less well tested */ | ||
2282 | /* D-Link MAC : 00:40:05:* */ | ||
2283 | /* Addtron MAC : 00:90:D1:* */ | ||
2284 | snprintf(priv->fw_name, sizeof(priv->fw_name) - 1, | ||
2285 | "Intersil %d.%d.%d", sta_id.major, sta_id.minor, | ||
2286 | sta_id.variant); | ||
2287 | |||
2288 | firmver = ((unsigned long)sta_id.major << 16) | | ||
2289 | ((unsigned long)sta_id.minor << 8) | sta_id.variant; | ||
2290 | |||
2291 | priv->has_ibss = (firmver >= 0x000700); /* FIXME */ | ||
2292 | priv->has_big_wep = priv->has_wep = (firmver >= 0x000800); | ||
2293 | priv->has_pm = (firmver >= 0x000700); | ||
2294 | priv->has_hostscan = (firmver >= 0x010301); | ||
2295 | |||
2296 | if (firmver >= 0x000800) | ||
2297 | priv->ibss_port = 0; | ||
2298 | else { | ||
2299 | printk(KERN_NOTICE "%s: Intersil firmware earlier " | ||
2300 | "than v0.8.x - several features not supported\n", | ||
2301 | dev->name); | ||
2302 | priv->ibss_port = 1; | ||
2303 | } | ||
2304 | break; | ||
2305 | } | ||
2306 | printk(KERN_DEBUG "%s: Firmware determined as %s\n", dev->name, | ||
2307 | priv->fw_name); | ||
2308 | |||
2309 | return 0; | ||
2310 | } | ||
2311 | |||
2312 | static int orinoco_init(struct net_device *dev) | 2098 | static int orinoco_init(struct net_device *dev) |
2313 | { | 2099 | { |
2314 | struct orinoco_private *priv = netdev_priv(dev); | 2100 | struct orinoco_private *priv = netdev_priv(dev); |
@@ -2330,7 +2116,7 @@ static int orinoco_init(struct net_device *dev) | |||
2330 | goto out; | 2116 | goto out; |
2331 | } | 2117 | } |
2332 | 2118 | ||
2333 | err = determine_firmware(dev); | 2119 | err = determine_fw_capabilities(priv); |
2334 | if (err != 0) { | 2120 | if (err != 0) { |
2335 | printk(KERN_ERR "%s: Incompatible firmware, aborting\n", | 2121 | printk(KERN_ERR "%s: Incompatible firmware, aborting\n", |
2336 | dev->name); | 2122 | dev->name); |
@@ -2347,7 +2133,7 @@ static int orinoco_init(struct net_device *dev) | |||
2347 | priv->do_fw_download = 0; | 2133 | priv->do_fw_download = 0; |
2348 | 2134 | ||
2349 | /* Check firmware version again */ | 2135 | /* Check firmware version again */ |
2350 | err = determine_firmware(dev); | 2136 | err = determine_fw_capabilities(priv); |
2351 | if (err != 0) { | 2137 | if (err != 0) { |
2352 | printk(KERN_ERR "%s: Incompatible firmware, aborting\n", | 2138 | printk(KERN_ERR "%s: Incompatible firmware, aborting\n", |
2353 | dev->name); | 2139 | dev->name); |