aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 00:04:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 00:04:44 -0400
commitf8965467f366fd18f01feafb5db10512d7b4422c (patch)
tree3706a9cd779859271ca61b85c63a1bc3f82d626e /drivers/net/wireless/orinoco
parenta26272e5200765691e67d6780e52b32498fdb659 (diff)
parent2ec8c6bb5d8f3a62a79f463525054bae1e3d4487 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1674 commits) qlcnic: adding co maintainer ixgbe: add support for active DA cables ixgbe: dcb, do not tag tc_prio_control frames ixgbe: fix ixgbe_tx_is_paused logic ixgbe: always enable vlan strip/insert when DCB is enabled ixgbe: remove some redundant code in setting FCoE FIP filter ixgbe: fix wrong offset to fc_frame_header in ixgbe_fcoe_ddp ixgbe: fix header len when unsplit packet overflows to data buffer ipv6: Never schedule DAD timer on dead address ipv6: Use POSTDAD state ipv6: Use state_lock to protect ifa state ipv6: Replace inet6_ifaddr->dead with state cxgb4: notify upper drivers if the device is already up when they load cxgb4: keep interrupts available when the ports are brought down cxgb4: fix initial addition of MAC address cnic: Return SPQ credit to bnx2x after ring setup and shutdown. cnic: Convert cnic_local_flags to atomic ops. can: Fix SJA1000 command register writes on SMP systems bridge: fix build for CONFIG_SYSFS disabled ARCNET: Limit com20020 PCI ID matches for SOHARD cards ... Fix up various conflicts with pcmcia tree drivers/net/ {pcmcia/3c589_cs.c, wireless/orinoco/orinoco_cs.c and wireless/orinoco/spectrum_cs.c} and feature removal (Documentation/feature-removal-schedule.txt). Also fix a non-content conflict due to pm_qos_requirement getting renamed in the PM tree (now pm_qos_request) in net/mac80211/scan.c
Diffstat (limited to 'drivers/net/wireless/orinoco')
-rw-r--r--drivers/net/wireless/orinoco/Kconfig20
-rw-r--r--drivers/net/wireless/orinoco/Makefile4
-rw-r--r--drivers/net/wireless/orinoco/airport.c8
-rw-r--r--drivers/net/wireless/orinoco/cfg.c91
-rw-r--r--drivers/net/wireless/orinoco/fw.c10
-rw-r--r--drivers/net/wireless/orinoco/hermes.c286
-rw-r--r--drivers/net/wireless/orinoco/hermes.h62
-rw-r--r--drivers/net/wireless/orinoco/hermes_dld.c243
-rw-r--r--drivers/net/wireless/orinoco/hw.c102
-rw-r--r--drivers/net/wireless/orinoco/hw.h1
-rw-r--r--drivers/net/wireless/orinoco/main.c307
-rw-r--r--drivers/net/wireless/orinoco/main.h12
-rw-r--r--drivers/net/wireless/orinoco/orinoco.h38
-rw-r--r--drivers/net/wireless/orinoco/orinoco_cs.c85
-rw-r--r--drivers/net/wireless/orinoco/orinoco_nortel.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_pci.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_plx.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_tmd.c2
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c1795
-rw-r--r--drivers/net/wireless/orinoco/scan.c4
-rw-r--r--drivers/net/wireless/orinoco/spectrum_cs.c7
-rw-r--r--drivers/net/wireless/orinoco/wext.c273
22 files changed, 2614 insertions, 742 deletions
diff --git a/drivers/net/wireless/orinoco/Kconfig b/drivers/net/wireless/orinoco/Kconfig
index e2a2c18920aa..60819bcf4377 100644
--- a/drivers/net/wireless/orinoco/Kconfig
+++ b/drivers/net/wireless/orinoco/Kconfig
@@ -27,6 +27,17 @@ config HERMES
27 configure your card and that /etc/pcmcia/wireless.opts works : 27 configure your card and that /etc/pcmcia/wireless.opts works :
28 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html> 28 <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>
29 29
30config HERMES_PRISM
31 bool "Support Prism 2/2.5 chipset"
32 depends on HERMES
33 ---help---
34
35 Say Y to enable support for Prism 2 and 2.5 chipsets. These
36 chipsets are better handled by the hostap driver. This driver
37 would not support WPA or firmware download for Prism chipset.
38
39 If you are not sure, say N.
40
30config HERMES_CACHE_FW_ON_INIT 41config HERMES_CACHE_FW_ON_INIT
31 bool "Cache Hermes firmware on driver initialisation" 42 bool "Cache Hermes firmware on driver initialisation"
32 depends on HERMES 43 depends on HERMES
@@ -86,7 +97,7 @@ config NORTEL_HERMES
86 97
87config PCI_HERMES 98config PCI_HERMES
88 tristate "Prism 2.5 PCI 802.11b adaptor support" 99 tristate "Prism 2.5 PCI 802.11b adaptor support"
89 depends on PCI && HERMES 100 depends on PCI && HERMES && HERMES_PRISM
90 help 101 help
91 Enable support for PCI and mini-PCI 802.11b wireless NICs based on 102 Enable support for PCI and mini-PCI 802.11b wireless NICs based on
92 the Prism 2.5 chipset. These are true PCI cards, not the 802.11b 103 the Prism 2.5 chipset. These are true PCI cards, not the 802.11b
@@ -121,3 +132,10 @@ config PCMCIA_SPECTRUM
121 This driver requires firmware download on startup. Utilities 132 This driver requires firmware download on startup. Utilities
122 for downloading Symbol firmware are available at 133 for downloading Symbol firmware are available at
123 <http://sourceforge.net/projects/orinoco/> 134 <http://sourceforge.net/projects/orinoco/>
135
136config ORINOCO_USB
137 tristate "Agere Orinoco USB support"
138 depends on USB && HERMES
139 select FW_LOADER
140 ---help---
141 This driver is for USB versions of the Agere Orinoco card.
diff --git a/drivers/net/wireless/orinoco/Makefile b/drivers/net/wireless/orinoco/Makefile
index 9abd6329bcbd..bfdefb85abcd 100644
--- a/drivers/net/wireless/orinoco/Makefile
+++ b/drivers/net/wireless/orinoco/Makefile
@@ -11,3 +11,7 @@ obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o
11obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o 11obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o
12obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o 12obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o
13obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o 13obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o
14obj-$(CONFIG_ORINOCO_USB) += orinoco_usb.o
15
16# Orinoco should be endian clean.
17ccflags-y += -D__CHECK_ENDIAN__
diff --git a/drivers/net/wireless/orinoco/airport.c b/drivers/net/wireless/orinoco/airport.c
index c60df2c1aca3..9bcee10c9308 100644
--- a/drivers/net/wireless/orinoco/airport.c
+++ b/drivers/net/wireless/orinoco/airport.c
@@ -77,9 +77,9 @@ airport_resume(struct macio_dev *mdev)
77 77
78 enable_irq(card->irq); 78 enable_irq(card->irq);
79 79
80 spin_lock_irqsave(&priv->lock, flags); 80 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
81 err = orinoco_up(priv); 81 err = orinoco_up(priv);
82 spin_unlock_irqrestore(&priv->lock, flags); 82 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
83 83
84 return err; 84 return err;
85} 85}
@@ -195,7 +195,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
195 ssleep(1); 195 ssleep(1);
196 196
197 /* Reset it before we get the interrupt */ 197 /* Reset it before we get the interrupt */
198 hermes_init(hw); 198 hw->ops->init(hw);
199 199
200 if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) { 200 if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) {
201 printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq); 201 printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq);
@@ -210,7 +210,7 @@ airport_attach(struct macio_dev *mdev, const struct of_device_id *match)
210 } 210 }
211 211
212 /* Register an interface with the stack */ 212 /* Register an interface with the stack */
213 if (orinoco_if_add(priv, phys_addr, card->irq) != 0) { 213 if (orinoco_if_add(priv, phys_addr, card->irq, NULL) != 0) {
214 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 214 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
215 goto failed; 215 goto failed;
216 } 216 }
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 27f2d3342645..8c4169c227ae 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -88,7 +88,9 @@ int orinoco_wiphy_register(struct wiphy *wiphy)
88 88
89 wiphy->rts_threshold = priv->rts_thresh; 89 wiphy->rts_threshold = priv->rts_thresh;
90 if (!priv->has_mwo) 90 if (!priv->has_mwo)
91 wiphy->frag_threshold = priv->frag_thresh; 91 wiphy->frag_threshold = priv->frag_thresh + 1;
92 wiphy->retry_short = priv->short_retry_limit;
93 wiphy->retry_long = priv->long_retry_limit;
92 94
93 return wiphy_register(wiphy); 95 return wiphy_register(wiphy);
94} 96}
@@ -157,6 +159,7 @@ static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev,
157} 159}
158 160
159static int orinoco_set_channel(struct wiphy *wiphy, 161static int orinoco_set_channel(struct wiphy *wiphy,
162 struct net_device *netdev,
160 struct ieee80211_channel *chan, 163 struct ieee80211_channel *chan,
161 enum nl80211_channel_type channel_type) 164 enum nl80211_channel_type channel_type)
162{ 165{
@@ -187,7 +190,7 @@ static int orinoco_set_channel(struct wiphy *wiphy,
187 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { 190 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
188 /* Fast channel change - no commit if successful */ 191 /* Fast channel change - no commit if successful */
189 hermes_t *hw = &priv->hw; 192 hermes_t *hw = &priv->hw;
190 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 193 err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
191 HERMES_TEST_SET_CHANNEL, 194 HERMES_TEST_SET_CHANNEL,
192 channel, NULL); 195 channel, NULL);
193 } 196 }
@@ -196,8 +199,92 @@ static int orinoco_set_channel(struct wiphy *wiphy,
196 return err; 199 return err;
197} 200}
198 201
202static int orinoco_set_wiphy_params(struct wiphy *wiphy, u32 changed)
203{
204 struct orinoco_private *priv = wiphy_priv(wiphy);
205 int frag_value = -1;
206 int rts_value = -1;
207 int err = 0;
208
209 if (changed & WIPHY_PARAM_RETRY_SHORT) {
210 /* Setting short retry not supported */
211 err = -EINVAL;
212 }
213
214 if (changed & WIPHY_PARAM_RETRY_LONG) {
215 /* Setting long retry not supported */
216 err = -EINVAL;
217 }
218
219 if (changed & WIPHY_PARAM_FRAG_THRESHOLD) {
220 /* Set fragmentation */
221 if (priv->has_mwo) {
222 if (wiphy->frag_threshold < 0)
223 frag_value = 0;
224 else {
225 printk(KERN_WARNING "%s: Fixed fragmentation "
226 "is not supported on this firmware. "
227 "Using MWO robust instead.\n",
228 priv->ndev->name);
229 frag_value = 1;
230 }
231 } else {
232 if (wiphy->frag_threshold < 0)
233 frag_value = 2346;
234 else if ((wiphy->frag_threshold < 257) ||
235 (wiphy->frag_threshold > 2347))
236 err = -EINVAL;
237 else
238 /* cfg80211 value is 257-2347 (odd only)
239 * orinoco rid has range 256-2346 (even only) */
240 frag_value = wiphy->frag_threshold & ~0x1;
241 }
242 }
243
244 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
245 /* Set RTS.
246 *
247 * Prism documentation suggests default of 2432,
248 * and a range of 0-3000.
249 *
250 * Current implementation uses 2347 as the default and
251 * the upper limit.
252 */
253
254 if (wiphy->rts_threshold < 0)
255 rts_value = 2347;
256 else if (wiphy->rts_threshold > 2347)
257 err = -EINVAL;
258 else
259 rts_value = wiphy->rts_threshold;
260 }
261
262 if (!err) {
263 unsigned long flags;
264
265 if (orinoco_lock(priv, &flags) != 0)
266 return -EBUSY;
267
268 if (frag_value >= 0) {
269 if (priv->has_mwo)
270 priv->mwo_robust = frag_value;
271 else
272 priv->frag_thresh = frag_value;
273 }
274 if (rts_value >= 0)
275 priv->rts_thresh = rts_value;
276
277 err = orinoco_commit(priv);
278
279 orinoco_unlock(priv, &flags);
280 }
281
282 return err;
283}
284
199const struct cfg80211_ops orinoco_cfg_ops = { 285const struct cfg80211_ops orinoco_cfg_ops = {
200 .change_virtual_intf = orinoco_change_vif, 286 .change_virtual_intf = orinoco_change_vif,
201 .set_channel = orinoco_set_channel, 287 .set_channel = orinoco_set_channel,
202 .scan = orinoco_scan, 288 .scan = orinoco_scan,
289 .set_wiphy_params = orinoco_set_wiphy_params,
203}; 290};
diff --git a/drivers/net/wireless/orinoco/fw.c b/drivers/net/wireless/orinoco/fw.c
index 5ea0f7cf85b1..3e1947d097ca 100644
--- a/drivers/net/wireless/orinoco/fw.c
+++ b/drivers/net/wireless/orinoco/fw.c
@@ -122,7 +122,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
122 dev_dbg(dev, "Attempting to download firmware %s\n", firmware); 122 dev_dbg(dev, "Attempting to download firmware %s\n", firmware);
123 123
124 /* Read current plug data */ 124 /* Read current plug data */
125 err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0); 125 err = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size);
126 dev_dbg(dev, "Read PDA returned %d\n", err); 126 dev_dbg(dev, "Read PDA returned %d\n", err);
127 if (err) 127 if (err)
128 goto free; 128 goto free;
@@ -149,7 +149,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
149 } 149 }
150 150
151 /* Enable aux port to allow programming */ 151 /* Enable aux port to allow programming */
152 err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point)); 152 err = hw->ops->program_init(hw, le32_to_cpu(hdr->entry_point));
153 dev_dbg(dev, "Program init returned %d\n", err); 153 dev_dbg(dev, "Program init returned %d\n", err);
154 if (err != 0) 154 if (err != 0)
155 goto abort; 155 goto abort;
@@ -177,7 +177,7 @@ orinoco_dl_firmware(struct orinoco_private *priv,
177 goto abort; 177 goto abort;
178 178
179 /* Tell card we've finished */ 179 /* Tell card we've finished */
180 err = hermesi_program_end(hw); 180 err = hw->ops->program_end(hw);
181 dev_dbg(dev, "Program end returned %d\n", err); 181 dev_dbg(dev, "Program end returned %d\n", err);
182 if (err != 0) 182 if (err != 0)
183 goto abort; 183 goto abort;
@@ -224,7 +224,7 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
224 if (!pda) 224 if (!pda)
225 return -ENOMEM; 225 return -ENOMEM;
226 226
227 ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1); 227 ret = hw->ops->read_pda(hw, pda, fw->pda_addr, fw->pda_size);
228 if (ret) 228 if (ret)
229 goto free; 229 goto free;
230 } 230 }
@@ -260,7 +260,7 @@ symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
260 } 260 }
261 261
262 /* Reset hermes chip and make sure it responds */ 262 /* Reset hermes chip and make sure it responds */
263 ret = hermes_init(hw); 263 ret = hw->ops->init(hw);
264 264
265 /* hermes_reset() should return 0 with the secondary firmware */ 265 /* hermes_reset() should return 0 with the secondary firmware */
266 if (secondary && ret != 0) 266 if (secondary && ret != 0)
diff --git a/drivers/net/wireless/orinoco/hermes.c b/drivers/net/wireless/orinoco/hermes.c
index 1a2fca76fd3c..6c6a23e08df6 100644
--- a/drivers/net/wireless/orinoco/hermes.c
+++ b/drivers/net/wireless/orinoco/hermes.c
@@ -52,6 +52,26 @@
52#define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */ 52#define ALLOC_COMPL_TIMEOUT (1000) /* in iterations of ~10us */
53 53
54/* 54/*
55 * AUX port access. To unlock the AUX port write the access keys to the
56 * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
57 * register. Then read it and make sure it's HERMES_AUX_ENABLED.
58 */
59#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */
60#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */
61#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */
62#define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */
63
64#define HERMES_AUX_PW0 0xFE01
65#define HERMES_AUX_PW1 0xDC23
66#define HERMES_AUX_PW2 0xBA45
67
68/* HERMES_CMD_DOWNLD */
69#define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD)
70#define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD)
71#define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD)
72#define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD)
73
74/*
55 * Debugging helpers 75 * Debugging helpers
56 */ 76 */
57 77
@@ -70,6 +90,7 @@
70 90
71#endif /* ! HERMES_DEBUG */ 91#endif /* ! HERMES_DEBUG */
72 92
93static const struct hermes_ops hermes_ops_local;
73 94
74/* 95/*
75 * Internal functions 96 * Internal functions
@@ -111,9 +132,9 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0,
111 */ 132 */
112 133
113/* For doing cmds that wipe the magic constant in SWSUPPORT0 */ 134/* For doing cmds that wipe the magic constant in SWSUPPORT0 */
114int hermes_doicmd_wait(hermes_t *hw, u16 cmd, 135static int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
115 u16 parm0, u16 parm1, u16 parm2, 136 u16 parm0, u16 parm1, u16 parm2,
116 struct hermes_response *resp) 137 struct hermes_response *resp)
117{ 138{
118 int err = 0; 139 int err = 0;
119 int k; 140 int k;
@@ -163,17 +184,18 @@ int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
163out: 184out:
164 return err; 185 return err;
165} 186}
166EXPORT_SYMBOL(hermes_doicmd_wait);
167 187
168void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing) 188void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing)
169{ 189{
170 hw->iobase = address; 190 hw->iobase = address;
171 hw->reg_spacing = reg_spacing; 191 hw->reg_spacing = reg_spacing;
172 hw->inten = 0x0; 192 hw->inten = 0x0;
193 hw->eeprom_pda = false;
194 hw->ops = &hermes_ops_local;
173} 195}
174EXPORT_SYMBOL(hermes_struct_init); 196EXPORT_SYMBOL(hermes_struct_init);
175 197
176int hermes_init(hermes_t *hw) 198static int hermes_init(hermes_t *hw)
177{ 199{
178 u16 reg; 200 u16 reg;
179 int err = 0; 201 int err = 0;
@@ -217,7 +239,6 @@ int hermes_init(hermes_t *hw)
217 239
218 return err; 240 return err;
219} 241}
220EXPORT_SYMBOL(hermes_init);
221 242
222/* Issue a command to the chip, and (busy!) wait for it to 243/* Issue a command to the chip, and (busy!) wait for it to
223 * complete. 244 * complete.
@@ -228,8 +249,8 @@ EXPORT_SYMBOL(hermes_init);
228 * > 0 on error returned by the firmware 249 * > 0 on error returned by the firmware
229 * 250 *
230 * Callable from any context, but locking is your problem. */ 251 * Callable from any context, but locking is your problem. */
231int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0, 252static int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
232 struct hermes_response *resp) 253 struct hermes_response *resp)
233{ 254{
234 int err; 255 int err;
235 int k; 256 int k;
@@ -291,9 +312,8 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
291 out: 312 out:
292 return err; 313 return err;
293} 314}
294EXPORT_SYMBOL(hermes_docmd_wait);
295 315
296int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) 316static int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
297{ 317{
298 int err = 0; 318 int err = 0;
299 int k; 319 int k;
@@ -333,7 +353,6 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
333 353
334 return 0; 354 return 0;
335} 355}
336EXPORT_SYMBOL(hermes_allocate);
337 356
338/* Set up a BAP to read a particular chunk of data from card's internal buffer. 357/* Set up a BAP to read a particular chunk of data from card's internal buffer.
339 * 358 *
@@ -403,8 +422,8 @@ static int hermes_bap_seek(hermes_t *hw, int bap, u16 id, u16 offset)
403 * 0 on success 422 * 0 on success
404 * > 0 on error from firmware 423 * > 0 on error from firmware
405 */ 424 */
406int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len, 425static int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
407 u16 id, u16 offset) 426 u16 id, u16 offset)
408{ 427{
409 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 428 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
410 int err = 0; 429 int err = 0;
@@ -422,7 +441,6 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
422 out: 441 out:
423 return err; 442 return err;
424} 443}
425EXPORT_SYMBOL(hermes_bap_pread);
426 444
427/* Write a block of data to the chip's buffer, via the 445/* Write a block of data to the chip's buffer, via the
428 * BAP. Synchronization/serialization is the caller's problem. 446 * BAP. Synchronization/serialization is the caller's problem.
@@ -432,8 +450,8 @@ EXPORT_SYMBOL(hermes_bap_pread);
432 * 0 on success 450 * 0 on success
433 * > 0 on error from firmware 451 * > 0 on error from firmware
434 */ 452 */
435int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len, 453static int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
436 u16 id, u16 offset) 454 u16 id, u16 offset)
437{ 455{
438 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 456 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
439 int err = 0; 457 int err = 0;
@@ -451,7 +469,6 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
451 out: 469 out:
452 return err; 470 return err;
453} 471}
454EXPORT_SYMBOL(hermes_bap_pwrite);
455 472
456/* Read a Length-Type-Value record from the card. 473/* Read a Length-Type-Value record from the card.
457 * 474 *
@@ -461,8 +478,8 @@ EXPORT_SYMBOL(hermes_bap_pwrite);
461 * practice. 478 * practice.
462 * 479 *
463 * Callable from user or bh context. */ 480 * Callable from user or bh context. */
464int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize, 481static int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
465 u16 *length, void *buf) 482 u16 *length, void *buf)
466{ 483{
467 int err = 0; 484 int err = 0;
468 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 485 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
@@ -505,10 +522,9 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
505 522
506 return 0; 523 return 0;
507} 524}
508EXPORT_SYMBOL(hermes_read_ltv);
509 525
510int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, 526static int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
511 u16 length, const void *value) 527 u16 length, const void *value)
512{ 528{
513 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0; 529 int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
514 int err = 0; 530 int err = 0;
@@ -533,4 +549,228 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
533 549
534 return err; 550 return err;
535} 551}
536EXPORT_SYMBOL(hermes_write_ltv); 552
553/*** Hermes AUX control ***/
554
555static inline void
556hermes_aux_setaddr(hermes_t *hw, u32 addr)
557{
558 hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
559 hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
560}
561
562static inline int
563hermes_aux_control(hermes_t *hw, int enabled)
564{
565 int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED;
566 int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE;
567 int i;
568
569 /* Already open? */
570 if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state)
571 return 0;
572
573 hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
574 hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
575 hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
576 hermes_write_reg(hw, HERMES_CONTROL, action);
577
578 for (i = 0; i < 20; i++) {
579 udelay(10);
580 if (hermes_read_reg(hw, HERMES_CONTROL) ==
581 desired_state)
582 return 0;
583 }
584
585 return -EBUSY;
586}
587
588/*** Hermes programming ***/
589
590/* About to start programming data (Hermes I)
591 * offset is the entry point
592 *
593 * Spectrum_cs' Symbol fw does not require this
594 * wl_lkm Agere fw does
595 * Don't know about intersil
596 */
597static int hermesi_program_init(hermes_t *hw, u32 offset)
598{
599 int err;
600
601 /* Disable interrupts?*/
602 /*hw->inten = 0x0;*/
603 /*hermes_write_regn(hw, INTEN, 0);*/
604 /*hermes_set_irqmask(hw, 0);*/
605
606 /* Acknowledge any outstanding command */
607 hermes_write_regn(hw, EVACK, 0xFFFF);
608
609 /* Using init_cmd_wait rather than cmd_wait */
610 err = hw->ops->init_cmd_wait(hw,
611 0x0100 | HERMES_CMD_INIT,
612 0, 0, 0, NULL);
613 if (err)
614 return err;
615
616 err = hw->ops->init_cmd_wait(hw,
617 0x0000 | HERMES_CMD_INIT,
618 0, 0, 0, NULL);
619 if (err)
620 return err;
621
622 err = hermes_aux_control(hw, 1);
623 pr_debug("AUX enable returned %d\n", err);
624
625 if (err)
626 return err;
627
628 pr_debug("Enabling volatile, EP 0x%08x\n", offset);
629 err = hw->ops->init_cmd_wait(hw,
630 HERMES_PROGRAM_ENABLE_VOLATILE,
631 offset & 0xFFFFu,
632 offset >> 16,
633 0,
634 NULL);
635 pr_debug("PROGRAM_ENABLE returned %d\n", err);
636
637 return err;
638}
639
640/* Done programming data (Hermes I)
641 *
642 * Spectrum_cs' Symbol fw does not require this
643 * wl_lkm Agere fw does
644 * Don't know about intersil
645 */
646static int hermesi_program_end(hermes_t *hw)
647{
648 struct hermes_response resp;
649 int rc = 0;
650 int err;
651
652 rc = hw->ops->cmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
653
654 pr_debug("PROGRAM_DISABLE returned %d, "
655 "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
656 rc, resp.resp0, resp.resp1, resp.resp2);
657
658 if ((rc == 0) &&
659 ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
660 rc = -EIO;
661
662 err = hermes_aux_control(hw, 0);
663 pr_debug("AUX disable returned %d\n", err);
664
665 /* Acknowledge any outstanding command */
666 hermes_write_regn(hw, EVACK, 0xFFFF);
667
668 /* Reinitialise, ignoring return */
669 (void) hw->ops->init_cmd_wait(hw, 0x0000 | HERMES_CMD_INIT,
670 0, 0, 0, NULL);
671
672 return rc ? rc : err;
673}
674
675static int hermes_program_bytes(struct hermes *hw, const char *data,
676 u32 addr, u32 len)
677{
678 /* wl lkm splits the programming into chunks of 2000 bytes.
679 * This restriction appears to come from USB. The PCMCIA
680 * adapters can program the whole lot in one go */
681 hermes_aux_setaddr(hw, addr);
682 hermes_write_bytes(hw, HERMES_AUXDATA, data, len);
683 return 0;
684}
685
686/* Read PDA from the adapter */
687static int hermes_read_pda(hermes_t *hw, __le16 *pda, u32 pda_addr, u16 pda_len)
688{
689 int ret;
690 u16 pda_size;
691 u16 data_len = pda_len;
692 __le16 *data = pda;
693
694 if (hw->eeprom_pda) {
695 /* PDA of spectrum symbol is in eeprom */
696
697 /* Issue command to read EEPROM */
698 ret = hw->ops->cmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
699 if (ret)
700 return ret;
701 } else {
702 /* wl_lkm does not include PDA size in the PDA area.
703 * We will pad the information into pda, so other routines
704 * don't have to be modified */
705 pda[0] = cpu_to_le16(pda_len - 2);
706 /* Includes CFG_PROD_DATA but not itself */
707 pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
708 data_len = pda_len - 4;
709 data = pda + 2;
710 }
711
712 /* Open auxiliary port */
713 ret = hermes_aux_control(hw, 1);
714 pr_debug("AUX enable returned %d\n", ret);
715 if (ret)
716 return ret;
717
718 /* Read PDA */
719 hermes_aux_setaddr(hw, pda_addr);
720 hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2);
721
722 /* Close aux port */
723 ret = hermes_aux_control(hw, 0);
724 pr_debug("AUX disable returned %d\n", ret);
725
726 /* Check PDA length */
727 pda_size = le16_to_cpu(pda[0]);
728 pr_debug("Actual PDA length %d, Max allowed %d\n",
729 pda_size, pda_len);
730 if (pda_size > pda_len)
731 return -EINVAL;
732
733 return 0;
734}
735
736static void hermes_lock_irqsave(spinlock_t *lock,
737 unsigned long *flags) __acquires(lock)
738{
739 spin_lock_irqsave(lock, *flags);
740}
741
742static void hermes_unlock_irqrestore(spinlock_t *lock,
743 unsigned long *flags) __releases(lock)
744{
745 spin_unlock_irqrestore(lock, *flags);
746}
747
748static void hermes_lock_irq(spinlock_t *lock) __acquires(lock)
749{
750 spin_lock_irq(lock);
751}
752
753static void hermes_unlock_irq(spinlock_t *lock) __releases(lock)
754{
755 spin_unlock_irq(lock);
756}
757
758/* Hermes operations for local buses */
759static const struct hermes_ops hermes_ops_local = {
760 .init = hermes_init,
761 .cmd_wait = hermes_docmd_wait,
762 .init_cmd_wait = hermes_doicmd_wait,
763 .allocate = hermes_allocate,
764 .read_ltv = hermes_read_ltv,
765 .write_ltv = hermes_write_ltv,
766 .bap_pread = hermes_bap_pread,
767 .bap_pwrite = hermes_bap_pwrite,
768 .read_pda = hermes_read_pda,
769 .program_init = hermesi_program_init,
770 .program_end = hermesi_program_end,
771 .program = hermes_program_bytes,
772 .lock_irqsave = hermes_lock_irqsave,
773 .unlock_irqrestore = hermes_unlock_irqrestore,
774 .lock_irq = hermes_lock_irq,
775 .unlock_irq = hermes_unlock_irq,
776};
diff --git a/drivers/net/wireless/orinoco/hermes.h b/drivers/net/wireless/orinoco/hermes.h
index 2dddbb597c4d..9ca34e722b45 100644
--- a/drivers/net/wireless/orinoco/hermes.h
+++ b/drivers/net/wireless/orinoco/hermes.h
@@ -374,6 +374,37 @@ struct hermes_multicast {
374/* Timeouts */ 374/* Timeouts */
375#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */ 375#define HERMES_BAP_BUSY_TIMEOUT (10000) /* In iterations of ~1us */
376 376
377struct hermes;
378
379/* Functions to access hardware */
380struct hermes_ops {
381 int (*init)(struct hermes *hw);
382 int (*cmd_wait)(struct hermes *hw, u16 cmd, u16 parm0,
383 struct hermes_response *resp);
384 int (*init_cmd_wait)(struct hermes *hw, u16 cmd,
385 u16 parm0, u16 parm1, u16 parm2,
386 struct hermes_response *resp);
387 int (*allocate)(struct hermes *hw, u16 size, u16 *fid);
388 int (*read_ltv)(struct hermes *hw, int bap, u16 rid, unsigned buflen,
389 u16 *length, void *buf);
390 int (*write_ltv)(struct hermes *hw, int bap, u16 rid,
391 u16 length, const void *value);
392 int (*bap_pread)(struct hermes *hw, int bap, void *buf, int len,
393 u16 id, u16 offset);
394 int (*bap_pwrite)(struct hermes *hw, int bap, const void *buf,
395 int len, u16 id, u16 offset);
396 int (*read_pda)(struct hermes *hw, __le16 *pda,
397 u32 pda_addr, u16 pda_len);
398 int (*program_init)(struct hermes *hw, u32 entry_point);
399 int (*program_end)(struct hermes *hw);
400 int (*program)(struct hermes *hw, const char *buf,
401 u32 addr, u32 len);
402 void (*lock_irqsave)(spinlock_t *lock, unsigned long *flags);
403 void (*unlock_irqrestore)(spinlock_t *lock, unsigned long *flags);
404 void (*lock_irq)(spinlock_t *lock);
405 void (*unlock_irq)(spinlock_t *lock);
406};
407
377/* Basic control structure */ 408/* Basic control structure */
378typedef struct hermes { 409typedef struct hermes {
379 void __iomem *iobase; 410 void __iomem *iobase;
@@ -381,6 +412,9 @@ typedef struct hermes {
381#define HERMES_16BIT_REGSPACING 0 412#define HERMES_16BIT_REGSPACING 0
382#define HERMES_32BIT_REGSPACING 1 413#define HERMES_32BIT_REGSPACING 1
383 u16 inten; /* Which interrupts should be enabled? */ 414 u16 inten; /* Which interrupts should be enabled? */
415 bool eeprom_pda;
416 const struct hermes_ops *ops;
417 void *priv;
384} hermes_t; 418} hermes_t;
385 419
386/* Register access convenience macros */ 420/* Register access convenience macros */
@@ -394,22 +428,6 @@ typedef struct hermes {
394 428
395/* Function prototypes */ 429/* Function prototypes */
396void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing); 430void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing);
397int hermes_init(hermes_t *hw);
398int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
399 struct hermes_response *resp);
400int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
401 u16 parm0, u16 parm1, u16 parm2,
402 struct hermes_response *resp);
403int hermes_allocate(hermes_t *hw, u16 size, u16 *fid);
404
405int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
406 u16 id, u16 offset);
407int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
408 u16 id, u16 offset);
409int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
410 u16 *length, void *buf);
411int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
412 u16 length, const void *value);
413 431
414/* Inline functions */ 432/* Inline functions */
415 433
@@ -426,13 +444,13 @@ static inline void hermes_set_irqmask(hermes_t *hw, u16 events)
426 444
427static inline int hermes_enable_port(hermes_t *hw, int port) 445static inline int hermes_enable_port(hermes_t *hw, int port)
428{ 446{
429 return hermes_docmd_wait(hw, HERMES_CMD_ENABLE | (port << 8), 447 return hw->ops->cmd_wait(hw, HERMES_CMD_ENABLE | (port << 8),
430 0, NULL); 448 0, NULL);
431} 449}
432 450
433static inline int hermes_disable_port(hermes_t *hw, int port) 451static inline int hermes_disable_port(hermes_t *hw, int port)
434{ 452{
435 return hermes_docmd_wait(hw, HERMES_CMD_DISABLE | (port << 8), 453 return hw->ops->cmd_wait(hw, HERMES_CMD_DISABLE | (port << 8),
436 0, NULL); 454 0, NULL);
437} 455}
438 456
@@ -440,7 +458,7 @@ static inline int hermes_disable_port(hermes_t *hw, int port)
440 * information frame in __orinoco_ev_info() */ 458 * information frame in __orinoco_ev_info() */
441static inline int hermes_inquire(hermes_t *hw, u16 rid) 459static inline int hermes_inquire(hermes_t *hw, u16 rid)
442{ 460{
443 return hermes_docmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL); 461 return hw->ops->cmd_wait(hw, HERMES_CMD_INQUIRE, rid, NULL);
444} 462}
445 463
446#define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1) 464#define HERMES_BYTES_TO_RECLEN(n) ((((n)+1)/2) + 1)
@@ -475,10 +493,10 @@ static inline void hermes_clear_words(struct hermes *hw, int off,
475} 493}
476 494
477#define HERMES_READ_RECORD(hw, bap, rid, buf) \ 495#define HERMES_READ_RECORD(hw, bap, rid, buf) \
478 (hermes_read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf))) 496 (hw->ops->read_ltv((hw), (bap), (rid), sizeof(*buf), NULL, (buf)))
479#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \ 497#define HERMES_WRITE_RECORD(hw, bap, rid, buf) \
480 (hermes_write_ltv((hw), (bap), (rid), \ 498 (hw->ops->write_ltv((hw), (bap), (rid), \
481 HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf))) 499 HERMES_BYTES_TO_RECLEN(sizeof(*buf)), (buf)))
482 500
483static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word) 501static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
484{ 502{
diff --git a/drivers/net/wireless/orinoco/hermes_dld.c b/drivers/net/wireless/orinoco/hermes_dld.c
index fb157eb889ca..6da85e75fce0 100644
--- a/drivers/net/wireless/orinoco/hermes_dld.c
+++ b/drivers/net/wireless/orinoco/hermes_dld.c
@@ -46,37 +46,11 @@
46 46
47#define PFX "hermes_dld: " 47#define PFX "hermes_dld: "
48 48
49/*
50 * AUX port access. To unlock the AUX port write the access keys to the
51 * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
52 * register. Then read it and make sure it's HERMES_AUX_ENABLED.
53 */
54#define HERMES_AUX_ENABLE 0x8000 /* Enable auxiliary port access */
55#define HERMES_AUX_DISABLE 0x4000 /* Disable to auxiliary port access */
56#define HERMES_AUX_ENABLED 0xC000 /* Auxiliary port is open */
57#define HERMES_AUX_DISABLED 0x0000 /* Auxiliary port is closed */
58
59#define HERMES_AUX_PW0 0xFE01
60#define HERMES_AUX_PW1 0xDC23
61#define HERMES_AUX_PW2 0xBA45
62
63/* HERMES_CMD_DOWNLD */
64#define HERMES_PROGRAM_DISABLE (0x0000 | HERMES_CMD_DOWNLD)
65#define HERMES_PROGRAM_ENABLE_VOLATILE (0x0100 | HERMES_CMD_DOWNLD)
66#define HERMES_PROGRAM_ENABLE_NON_VOLATILE (0x0200 | HERMES_CMD_DOWNLD)
67#define HERMES_PROGRAM_NON_VOLATILE (0x0300 | HERMES_CMD_DOWNLD)
68
69/* End markers used in dblocks */ 49/* End markers used in dblocks */
70#define PDI_END 0x00000000 /* End of PDA */ 50#define PDI_END 0x00000000 /* End of PDA */
71#define BLOCK_END 0xFFFFFFFF /* Last image block */ 51#define BLOCK_END 0xFFFFFFFF /* Last image block */
72#define TEXT_END 0x1A /* End of text header */ 52#define TEXT_END 0x1A /* End of text header */
73 53
74/* Limit the amout we try to download in a single shot.
75 * Size is in bytes.
76 */
77#define MAX_DL_SIZE 1024
78#define LIMIT_PROGRAM_SIZE 0
79
80/* 54/*
81 * The following structures have little-endian fields denoted by 55 * The following structures have little-endian fields denoted by
82 * the leading underscore. Don't access them directly - use inline 56 * the leading underscore. Don't access them directly - use inline
@@ -165,41 +139,6 @@ pdi_len(const struct pdi *pdi)
165 return 2 * (le16_to_cpu(pdi->len) - 1); 139 return 2 * (le16_to_cpu(pdi->len) - 1);
166} 140}
167 141
168/*** Hermes AUX control ***/
169
170static inline void
171hermes_aux_setaddr(hermes_t *hw, u32 addr)
172{
173 hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
174 hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
175}
176
177static inline int
178hermes_aux_control(hermes_t *hw, int enabled)
179{
180 int desired_state = enabled ? HERMES_AUX_ENABLED : HERMES_AUX_DISABLED;
181 int action = enabled ? HERMES_AUX_ENABLE : HERMES_AUX_DISABLE;
182 int i;
183
184 /* Already open? */
185 if (hermes_read_reg(hw, HERMES_CONTROL) == desired_state)
186 return 0;
187
188 hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
189 hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
190 hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
191 hermes_write_reg(hw, HERMES_CONTROL, action);
192
193 for (i = 0; i < 20; i++) {
194 udelay(10);
195 if (hermes_read_reg(hw, HERMES_CONTROL) ==
196 desired_state)
197 return 0;
198 }
199
200 return -EBUSY;
201}
202
203/*** Plug Data Functions ***/ 142/*** Plug Data Functions ***/
204 143
205/* 144/*
@@ -271,62 +210,7 @@ hermes_plug_pdi(hermes_t *hw, const struct pdr *first_pdr,
271 return -EINVAL; 210 return -EINVAL;
272 211
273 /* do the actual plugging */ 212 /* do the actual plugging */
274 hermes_aux_setaddr(hw, pdr_addr(pdr)); 213 hw->ops->program(hw, pdi->data, pdr_addr(pdr), pdi_len(pdi));
275 hermes_write_bytes(hw, HERMES_AUXDATA, pdi->data, pdi_len(pdi));
276
277 return 0;
278}
279
280/* Read PDA from the adapter */
281int hermes_read_pda(hermes_t *hw,
282 __le16 *pda,
283 u32 pda_addr,
284 u16 pda_len,
285 int use_eeprom) /* can we get this into hw? */
286{
287 int ret;
288 u16 pda_size;
289 u16 data_len = pda_len;
290 __le16 *data = pda;
291
292 if (use_eeprom) {
293 /* PDA of spectrum symbol is in eeprom */
294
295 /* Issue command to read EEPROM */
296 ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
297 if (ret)
298 return ret;
299 } else {
300 /* wl_lkm does not include PDA size in the PDA area.
301 * We will pad the information into pda, so other routines
302 * don't have to be modified */
303 pda[0] = cpu_to_le16(pda_len - 2);
304 /* Includes CFG_PROD_DATA but not itself */
305 pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
306 data_len = pda_len - 4;
307 data = pda + 2;
308 }
309
310 /* Open auxiliary port */
311 ret = hermes_aux_control(hw, 1);
312 pr_debug(PFX "AUX enable returned %d\n", ret);
313 if (ret)
314 return ret;
315
316 /* read PDA from EEPROM */
317 hermes_aux_setaddr(hw, pda_addr);
318 hermes_read_words(hw, HERMES_AUXDATA, data, data_len / 2);
319
320 /* Close aux port */
321 ret = hermes_aux_control(hw, 0);
322 pr_debug(PFX "AUX disable returned %d\n", ret);
323
324 /* Check PDA length */
325 pda_size = le16_to_cpu(pda[0]);
326 pr_debug(PFX "Actual PDA length %d, Max allowed %d\n",
327 pda_size, pda_len);
328 if (pda_size > pda_len)
329 return -EINVAL;
330 214
331 return 0; 215 return 0;
332} 216}
@@ -389,101 +273,13 @@ hermes_blocks_length(const char *first_block, const void *end)
389 273
390/*** Hermes programming ***/ 274/*** Hermes programming ***/
391 275
392/* About to start programming data (Hermes I)
393 * offset is the entry point
394 *
395 * Spectrum_cs' Symbol fw does not require this
396 * wl_lkm Agere fw does
397 * Don't know about intersil
398 */
399int hermesi_program_init(hermes_t *hw, u32 offset)
400{
401 int err;
402
403 /* Disable interrupts?*/
404 /*hw->inten = 0x0;*/
405 /*hermes_write_regn(hw, INTEN, 0);*/
406 /*hermes_set_irqmask(hw, 0);*/
407
408 /* Acknowledge any outstanding command */
409 hermes_write_regn(hw, EVACK, 0xFFFF);
410
411 /* Using doicmd_wait rather than docmd_wait */
412 err = hermes_doicmd_wait(hw,
413 0x0100 | HERMES_CMD_INIT,
414 0, 0, 0, NULL);
415 if (err)
416 return err;
417
418 err = hermes_doicmd_wait(hw,
419 0x0000 | HERMES_CMD_INIT,
420 0, 0, 0, NULL);
421 if (err)
422 return err;
423
424 err = hermes_aux_control(hw, 1);
425 pr_debug(PFX "AUX enable returned %d\n", err);
426
427 if (err)
428 return err;
429
430 pr_debug(PFX "Enabling volatile, EP 0x%08x\n", offset);
431 err = hermes_doicmd_wait(hw,
432 HERMES_PROGRAM_ENABLE_VOLATILE,
433 offset & 0xFFFFu,
434 offset >> 16,
435 0,
436 NULL);
437 pr_debug(PFX "PROGRAM_ENABLE returned %d\n", err);
438
439 return err;
440}
441
442/* Done programming data (Hermes I)
443 *
444 * Spectrum_cs' Symbol fw does not require this
445 * wl_lkm Agere fw does
446 * Don't know about intersil
447 */
448int hermesi_program_end(hermes_t *hw)
449{
450 struct hermes_response resp;
451 int rc = 0;
452 int err;
453
454 rc = hermes_docmd_wait(hw, HERMES_PROGRAM_DISABLE, 0, &resp);
455
456 pr_debug(PFX "PROGRAM_DISABLE returned %d, "
457 "r0 0x%04x, r1 0x%04x, r2 0x%04x\n",
458 rc, resp.resp0, resp.resp1, resp.resp2);
459
460 if ((rc == 0) &&
461 ((resp.status & HERMES_STATUS_CMDCODE) != HERMES_CMD_DOWNLD))
462 rc = -EIO;
463
464 err = hermes_aux_control(hw, 0);
465 pr_debug(PFX "AUX disable returned %d\n", err);
466
467 /* Acknowledge any outstanding command */
468 hermes_write_regn(hw, EVACK, 0xFFFF);
469
470 /* Reinitialise, ignoring return */
471 (void) hermes_doicmd_wait(hw, 0x0000 | HERMES_CMD_INIT,
472 0, 0, 0, NULL);
473
474 return rc ? rc : err;
475}
476
477/* Program the data blocks */ 276/* Program the data blocks */
478int hermes_program(hermes_t *hw, const char *first_block, const void *end) 277int hermes_program(hermes_t *hw, const char *first_block, const void *end)
479{ 278{
480 const struct dblock *blk; 279 const struct dblock *blk;
481 u32 blkaddr; 280 u32 blkaddr;
482 u32 blklen; 281 u32 blklen;
483#if LIMIT_PROGRAM_SIZE 282 int err = 0;
484 u32 addr;
485 u32 len;
486#endif
487 283
488 blk = (const struct dblock *) first_block; 284 blk = (const struct dblock *) first_block;
489 285
@@ -498,30 +294,10 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end)
498 pr_debug(PFX "Programming block of length %d " 294 pr_debug(PFX "Programming block of length %d "
499 "to address 0x%08x\n", blklen, blkaddr); 295 "to address 0x%08x\n", blklen, blkaddr);
500 296
501#if !LIMIT_PROGRAM_SIZE 297 err = hw->ops->program(hw, blk->data, blkaddr, blklen);
502 /* wl_lkm driver splits this into writes of 2000 bytes */ 298 if (err)
503 hermes_aux_setaddr(hw, blkaddr); 299 break;
504 hermes_write_bytes(hw, HERMES_AUXDATA, blk->data, 300
505 blklen);
506#else
507 len = (blklen < MAX_DL_SIZE) ? blklen : MAX_DL_SIZE;
508 addr = blkaddr;
509
510 while (addr < (blkaddr + blklen)) {
511 pr_debug(PFX "Programming subblock of length %d "
512 "to address 0x%08x. Data @ %p\n",
513 len, addr, &blk->data[addr - blkaddr]);
514
515 hermes_aux_setaddr(hw, addr);
516 hermes_write_bytes(hw, HERMES_AUXDATA,
517 &blk->data[addr - blkaddr],
518 len);
519
520 addr += len;
521 len = ((blkaddr + blklen - addr) < MAX_DL_SIZE) ?
522 (blkaddr + blklen - addr) : MAX_DL_SIZE;
523 }
524#endif
525 blk = (const struct dblock *) &blk->data[blklen]; 301 blk = (const struct dblock *) &blk->data[blklen];
526 302
527 if ((void *) blk > (end - sizeof(*blk))) 303 if ((void *) blk > (end - sizeof(*blk)))
@@ -530,7 +306,7 @@ int hermes_program(hermes_t *hw, const char *first_block, const void *end)
530 blkaddr = dblock_addr(blk); 306 blkaddr = dblock_addr(blk);
531 blklen = dblock_len(blk); 307 blklen = dblock_len(blk);
532 } 308 }
533 return 0; 309 return err;
534} 310}
535 311
536/*** Default plugging data for Hermes I ***/ 312/*** Default plugging data for Hermes I ***/
@@ -690,9 +466,8 @@ int hermes_apply_pda_with_defaults(hermes_t *hw,
690 if ((pdi_len(pdi) == pdr_len(pdr)) && 466 if ((pdi_len(pdi) == pdr_len(pdr)) &&
691 ((void *) pdi->data + pdi_len(pdi) < pda_end)) { 467 ((void *) pdi->data + pdi_len(pdi) < pda_end)) {
692 /* do the actual plugging */ 468 /* do the actual plugging */
693 hermes_aux_setaddr(hw, pdr_addr(pdr)); 469 hw->ops->program(hw, pdi->data, pdr_addr(pdr),
694 hermes_write_bytes(hw, HERMES_AUXDATA, 470 pdi_len(pdi));
695 pdi->data, pdi_len(pdi));
696 } 471 }
697 } 472 }
698 473
diff --git a/drivers/net/wireless/orinoco/hw.c b/drivers/net/wireless/orinoco/hw.c
index e6369242e49c..6fbd78850123 100644
--- a/drivers/net/wireless/orinoco/hw.c
+++ b/drivers/net/wireless/orinoco/hw.c
@@ -177,9 +177,9 @@ int determine_fw_capabilities(struct orinoco_private *priv,
177 /* 3Com MAC : 00:50:DA:* */ 177 /* 3Com MAC : 00:50:DA:* */
178 memset(tmp, 0, sizeof(tmp)); 178 memset(tmp, 0, sizeof(tmp));
179 /* Get the Symbol firmware version */ 179 /* Get the Symbol firmware version */
180 err = hermes_read_ltv(hw, USER_BAP, 180 err = hw->ops->read_ltv(hw, USER_BAP,
181 HERMES_RID_SECONDARYVERSION_SYMBOL, 181 HERMES_RID_SECONDARYVERSION_SYMBOL,
182 SYMBOL_MAX_VER_LEN, NULL, &tmp); 182 SYMBOL_MAX_VER_LEN, NULL, &tmp);
183 if (err) { 183 if (err) {
184 dev_warn(dev, "Error %d reading Symbol firmware info. " 184 dev_warn(dev, "Error %d reading Symbol firmware info. "
185 "Wildly guessing capabilities...\n", err); 185 "Wildly guessing capabilities...\n", err);
@@ -262,6 +262,13 @@ int determine_fw_capabilities(struct orinoco_private *priv,
262 if (fw_name) 262 if (fw_name)
263 dev_info(dev, "Firmware determined as %s\n", fw_name); 263 dev_info(dev, "Firmware determined as %s\n", fw_name);
264 264
265#ifndef CONFIG_HERMES_PRISM
266 if (priv->firmware_type == FIRMWARE_TYPE_INTERSIL) {
267 dev_err(dev, "Support for Prism chipset is not enabled\n");
268 return -ENODEV;
269 }
270#endif
271
265 return 0; 272 return 0;
266} 273}
267 274
@@ -279,8 +286,8 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
279 u16 reclen; 286 u16 reclen;
280 287
281 /* Get the MAC address */ 288 /* Get the MAC address */
282 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, 289 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
283 ETH_ALEN, NULL, dev_addr); 290 ETH_ALEN, NULL, dev_addr);
284 if (err) { 291 if (err) {
285 dev_warn(dev, "Failed to read MAC address!\n"); 292 dev_warn(dev, "Failed to read MAC address!\n");
286 goto out; 293 goto out;
@@ -289,8 +296,8 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
289 dev_dbg(dev, "MAC address %pM\n", dev_addr); 296 dev_dbg(dev, "MAC address %pM\n", dev_addr);
290 297
291 /* Get the station name */ 298 /* Get the station name */
292 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, 299 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
293 sizeof(nickbuf), &reclen, &nickbuf); 300 sizeof(nickbuf), &reclen, &nickbuf);
294 if (err) { 301 if (err) {
295 dev_err(dev, "failed to read station name\n"); 302 dev_err(dev, "failed to read station name\n");
296 goto out; 303 goto out;
@@ -367,6 +374,32 @@ int orinoco_hw_read_card_settings(struct orinoco_private *priv, u8 *dev_addr)
367 err = hermes_read_wordrec(hw, USER_BAP, 374 err = hermes_read_wordrec(hw, USER_BAP,
368 HERMES_RID_CNFPREAMBLE_SYMBOL, 375 HERMES_RID_CNFPREAMBLE_SYMBOL,
369 &priv->preamble); 376 &priv->preamble);
377 if (err) {
378 dev_err(dev, "Failed to read preamble setup\n");
379 goto out;
380 }
381 }
382
383 /* Retry settings */
384 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
385 &priv->short_retry_limit);
386 if (err) {
387 dev_err(dev, "Failed to read short retry limit\n");
388 goto out;
389 }
390
391 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
392 &priv->long_retry_limit);
393 if (err) {
394 dev_err(dev, "Failed to read long retry limit\n");
395 goto out;
396 }
397
398 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
399 &priv->retry_lifetime);
400 if (err) {
401 dev_err(dev, "Failed to read max retry lifetime\n");
402 goto out;
370 } 403 }
371 404
372out: 405out:
@@ -380,11 +413,11 @@ int orinoco_hw_allocate_fid(struct orinoco_private *priv)
380 struct hermes *hw = &priv->hw; 413 struct hermes *hw = &priv->hw;
381 int err; 414 int err;
382 415
383 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); 416 err = hw->ops->allocate(hw, priv->nicbuf_size, &priv->txfid);
384 if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) { 417 if (err == -EIO && priv->nicbuf_size > TX_NICBUF_SIZE_BUG) {
385 /* Try workaround for old Symbol firmware bug */ 418 /* Try workaround for old Symbol firmware bug */
386 priv->nicbuf_size = TX_NICBUF_SIZE_BUG; 419 priv->nicbuf_size = TX_NICBUF_SIZE_BUG;
387 err = hermes_allocate(hw, priv->nicbuf_size, &priv->txfid); 420 err = hw->ops->allocate(hw, priv->nicbuf_size, &priv->txfid);
388 421
389 dev_warn(dev, "Firmware ALLOC bug detected " 422 dev_warn(dev, "Firmware ALLOC bug detected "
390 "(old Symbol firmware?). Work around %s\n", 423 "(old Symbol firmware?). Work around %s\n",
@@ -430,8 +463,9 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
430 struct hermes_idstring idbuf; 463 struct hermes_idstring idbuf;
431 464
432 /* Set the MAC address */ 465 /* Set the MAC address */
433 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR, 466 err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNMACADDR,
434 HERMES_BYTES_TO_RECLEN(ETH_ALEN), dev->dev_addr); 467 HERMES_BYTES_TO_RECLEN(ETH_ALEN),
468 dev->dev_addr);
435 if (err) { 469 if (err) {
436 printk(KERN_ERR "%s: Error %d setting MAC address\n", 470 printk(KERN_ERR "%s: Error %d setting MAC address\n",
437 dev->name, err); 471 dev->name, err);
@@ -494,7 +528,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
494 idbuf.len = cpu_to_le16(strlen(priv->desired_essid)); 528 idbuf.len = cpu_to_le16(strlen(priv->desired_essid));
495 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val)); 529 memcpy(&idbuf.val, priv->desired_essid, sizeof(idbuf.val));
496 /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */ 530 /* WinXP wants partner to configure OWNSSID even in IBSS mode. (jimc) */
497 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID, 531 err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNSSID,
498 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), 532 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
499 &idbuf); 533 &idbuf);
500 if (err) { 534 if (err) {
@@ -502,7 +536,7 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
502 dev->name, err); 536 dev->name, err);
503 return err; 537 return err;
504 } 538 }
505 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID, 539 err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFDESIREDSSID,
506 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2), 540 HERMES_BYTES_TO_RECLEN(strlen(priv->desired_essid)+2),
507 &idbuf); 541 &idbuf);
508 if (err) { 542 if (err) {
@@ -514,9 +548,9 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
514 /* Set the station name */ 548 /* Set the station name */
515 idbuf.len = cpu_to_le16(strlen(priv->nick)); 549 idbuf.len = cpu_to_le16(strlen(priv->nick));
516 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val)); 550 memcpy(&idbuf.val, priv->nick, sizeof(idbuf.val));
517 err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME, 551 err = hw->ops->write_ltv(hw, USER_BAP, HERMES_RID_CNFOWNNAME,
518 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2), 552 HERMES_BYTES_TO_RECLEN(strlen(priv->nick)+2),
519 &idbuf); 553 &idbuf);
520 if (err) { 554 if (err) {
521 printk(KERN_ERR "%s: Error %d setting nickname\n", 555 printk(KERN_ERR "%s: Error %d setting nickname\n",
522 dev->name, err); 556 dev->name, err);
@@ -631,12 +665,12 @@ int orinoco_hw_program_rids(struct orinoco_private *priv)
631 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { 665 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
632 /* Enable monitor mode */ 666 /* Enable monitor mode */
633 dev->type = ARPHRD_IEEE80211; 667 dev->type = ARPHRD_IEEE80211;
634 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 668 err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
635 HERMES_TEST_MONITOR, 0, NULL); 669 HERMES_TEST_MONITOR, 0, NULL);
636 } else { 670 } else {
637 /* Disable monitor mode */ 671 /* Disable monitor mode */
638 dev->type = ARPHRD_ETHER; 672 dev->type = ARPHRD_ETHER;
639 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 673 err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
640 HERMES_TEST_STOP, 0, NULL); 674 HERMES_TEST_STOP, 0, NULL);
641 } 675 }
642 if (err) 676 if (err)
@@ -662,8 +696,8 @@ int orinoco_hw_get_tkip_iv(struct orinoco_private *priv, int key, u8 *tsc)
662 if ((key < 0) || (key >= 4)) 696 if ((key < 0) || (key >= 4))
663 return -EINVAL; 697 return -EINVAL;
664 698
665 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV, 699 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_TKIP_IV,
666 sizeof(tsc_arr), NULL, &tsc_arr); 700 sizeof(tsc_arr), NULL, &tsc_arr);
667 if (!err) 701 if (!err)
668 memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0])); 702 memcpy(tsc, &tsc_arr[key][0], sizeof(tsc_arr[0]));
669 703
@@ -842,7 +876,7 @@ int __orinoco_hw_setup_wepkeys(struct orinoco_private *priv)
842 memcpy(key, priv->keys[i].key, 876 memcpy(key, priv->keys[i].key,
843 priv->keys[i].key_len); 877 priv->keys[i].key_len);
844 878
845 err = hermes_write_ltv(hw, USER_BAP, 879 err = hw->ops->write_ltv(hw, USER_BAP,
846 HERMES_RID_CNFDEFAULTKEY0 + i, 880 HERMES_RID_CNFDEFAULTKEY0 + i,
847 HERMES_BYTES_TO_RECLEN(keylen), 881 HERMES_BYTES_TO_RECLEN(keylen),
848 key); 882 key);
@@ -1049,17 +1083,17 @@ int __orinoco_hw_set_multicast_list(struct orinoco_private *priv,
1049 * group address if either we want to multicast, or if we were 1083 * group address if either we want to multicast, or if we were
1050 * multicasting and want to stop */ 1084 * multicasting and want to stop */
1051 if (!promisc && (mc_count || priv->mc_count)) { 1085 if (!promisc && (mc_count || priv->mc_count)) {
1052 struct dev_mc_list *p; 1086 struct netdev_hw_addr *ha;
1053 struct hermes_multicast mclist; 1087 struct hermes_multicast mclist;
1054 int i = 0; 1088 int i = 0;
1055 1089
1056 netdev_for_each_mc_addr(p, dev) { 1090 netdev_for_each_mc_addr(ha, dev) {
1057 if (i == mc_count) 1091 if (i == mc_count)
1058 break; 1092 break;
1059 memcpy(mclist.addr[i++], p->dmi_addr, ETH_ALEN); 1093 memcpy(mclist.addr[i++], ha->addr, ETH_ALEN);
1060 } 1094 }
1061 1095
1062 err = hermes_write_ltv(hw, USER_BAP, 1096 err = hw->ops->write_ltv(hw, USER_BAP,
1063 HERMES_RID_CNFGROUPADDRESSES, 1097 HERMES_RID_CNFGROUPADDRESSES,
1064 HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN), 1098 HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
1065 &mclist); 1099 &mclist);
@@ -1101,15 +1135,15 @@ int orinoco_hw_get_essid(struct orinoco_private *priv, int *active,
1101 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID : 1135 rid = (priv->port_type == 3) ? HERMES_RID_CNFOWNSSID :
1102 HERMES_RID_CNFDESIREDSSID; 1136 HERMES_RID_CNFDESIREDSSID;
1103 1137
1104 err = hermes_read_ltv(hw, USER_BAP, rid, sizeof(essidbuf), 1138 err = hw->ops->read_ltv(hw, USER_BAP, rid, sizeof(essidbuf),
1105 NULL, &essidbuf); 1139 NULL, &essidbuf);
1106 if (err) 1140 if (err)
1107 goto fail_unlock; 1141 goto fail_unlock;
1108 } else { 1142 } else {
1109 *active = 0; 1143 *active = 0;
1110 1144
1111 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID, 1145 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTSSID,
1112 sizeof(essidbuf), NULL, &essidbuf); 1146 sizeof(essidbuf), NULL, &essidbuf);
1113 if (err) 1147 if (err)
1114 goto fail_unlock; 1148 goto fail_unlock;
1115 } 1149 }
@@ -1180,8 +1214,8 @@ int orinoco_hw_get_bitratelist(struct orinoco_private *priv,
1180 if (orinoco_lock(priv, &flags) != 0) 1214 if (orinoco_lock(priv, &flags) != 0)
1181 return -EBUSY; 1215 return -EBUSY;
1182 1216
1183 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES, 1217 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_SUPPORTEDDATARATES,
1184 sizeof(list), NULL, &list); 1218 sizeof(list), NULL, &list);
1185 orinoco_unlock(priv, &flags); 1219 orinoco_unlock(priv, &flags);
1186 1220
1187 if (err) 1221 if (err)
@@ -1248,7 +1282,7 @@ int orinoco_hw_trigger_scan(struct orinoco_private *priv,
1248 idbuf.len = cpu_to_le16(len); 1282 idbuf.len = cpu_to_le16(len);
1249 memcpy(idbuf.val, ssid->ssid, len); 1283 memcpy(idbuf.val, ssid->ssid, len);
1250 1284
1251 err = hermes_write_ltv(hw, USER_BAP, 1285 err = hw->ops->write_ltv(hw, USER_BAP,
1252 HERMES_RID_CNFSCANSSID_AGERE, 1286 HERMES_RID_CNFSCANSSID_AGERE,
1253 HERMES_BYTES_TO_RECLEN(len + 2), 1287 HERMES_BYTES_TO_RECLEN(len + 2),
1254 &idbuf); 1288 &idbuf);
@@ -1312,8 +1346,8 @@ int orinoco_hw_get_current_bssid(struct orinoco_private *priv,
1312 hermes_t *hw = &priv->hw; 1346 hermes_t *hw = &priv->hw;
1313 int err; 1347 int err;
1314 1348
1315 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, 1349 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
1316 ETH_ALEN, NULL, addr); 1350 ETH_ALEN, NULL, addr);
1317 1351
1318 return err; 1352 return err;
1319} 1353}
diff --git a/drivers/net/wireless/orinoco/hw.h b/drivers/net/wireless/orinoco/hw.h
index 9799a1d14a63..97af71e79950 100644
--- a/drivers/net/wireless/orinoco/hw.h
+++ b/drivers/net/wireless/orinoco/hw.h
@@ -22,7 +22,6 @@
22 22
23/* Forward declarations */ 23/* Forward declarations */
24struct orinoco_private; 24struct orinoco_private;
25struct dev_addr_list;
26 25
27int determine_fw_capabilities(struct orinoco_private *priv, char *fw_name, 26int determine_fw_capabilities(struct orinoco_private *priv, char *fw_name,
28 size_t fw_name_len, u32 *hw_ver); 27 size_t fw_name_len, u32 *hw_ver);
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c
index 413e9ab6cab3..ca71f08709bc 100644
--- a/drivers/net/wireless/orinoco/main.c
+++ b/drivers/net/wireless/orinoco/main.c
@@ -254,7 +254,7 @@ void set_port_type(struct orinoco_private *priv)
254/* Device methods */ 254/* Device methods */
255/********************************************************************/ 255/********************************************************************/
256 256
257static int orinoco_open(struct net_device *dev) 257int orinoco_open(struct net_device *dev)
258{ 258{
259 struct orinoco_private *priv = ndev_priv(dev); 259 struct orinoco_private *priv = ndev_priv(dev);
260 unsigned long flags; 260 unsigned long flags;
@@ -272,8 +272,9 @@ static int orinoco_open(struct net_device *dev)
272 272
273 return err; 273 return err;
274} 274}
275EXPORT_SYMBOL(orinoco_open);
275 276
276static int orinoco_stop(struct net_device *dev) 277int orinoco_stop(struct net_device *dev)
277{ 278{
278 struct orinoco_private *priv = ndev_priv(dev); 279 struct orinoco_private *priv = ndev_priv(dev);
279 int err = 0; 280 int err = 0;
@@ -281,25 +282,27 @@ static int orinoco_stop(struct net_device *dev)
281 /* We mustn't use orinoco_lock() here, because we need to be 282 /* We mustn't use orinoco_lock() here, because we need to be
282 able to close the interface even if hw_unavailable is set 283 able to close the interface even if hw_unavailable is set
283 (e.g. as we're released after a PC Card removal) */ 284 (e.g. as we're released after a PC Card removal) */
284 spin_lock_irq(&priv->lock); 285 orinoco_lock_irq(priv);
285 286
286 priv->open = 0; 287 priv->open = 0;
287 288
288 err = __orinoco_down(priv); 289 err = __orinoco_down(priv);
289 290
290 spin_unlock_irq(&priv->lock); 291 orinoco_unlock_irq(priv);
291 292
292 return err; 293 return err;
293} 294}
295EXPORT_SYMBOL(orinoco_stop);
294 296
295static struct net_device_stats *orinoco_get_stats(struct net_device *dev) 297struct net_device_stats *orinoco_get_stats(struct net_device *dev)
296{ 298{
297 struct orinoco_private *priv = ndev_priv(dev); 299 struct orinoco_private *priv = ndev_priv(dev);
298 300
299 return &priv->stats; 301 return &priv->stats;
300} 302}
303EXPORT_SYMBOL(orinoco_get_stats);
301 304
302static void orinoco_set_multicast_list(struct net_device *dev) 305void orinoco_set_multicast_list(struct net_device *dev)
303{ 306{
304 struct orinoco_private *priv = ndev_priv(dev); 307 struct orinoco_private *priv = ndev_priv(dev);
305 unsigned long flags; 308 unsigned long flags;
@@ -313,8 +316,9 @@ static void orinoco_set_multicast_list(struct net_device *dev)
313 __orinoco_set_multicast_list(dev); 316 __orinoco_set_multicast_list(dev);
314 orinoco_unlock(priv, &flags); 317 orinoco_unlock(priv, &flags);
315} 318}
319EXPORT_SYMBOL(orinoco_set_multicast_list);
316 320
317static int orinoco_change_mtu(struct net_device *dev, int new_mtu) 321int orinoco_change_mtu(struct net_device *dev, int new_mtu)
318{ 322{
319 struct orinoco_private *priv = ndev_priv(dev); 323 struct orinoco_private *priv = ndev_priv(dev);
320 324
@@ -330,23 +334,115 @@ static int orinoco_change_mtu(struct net_device *dev, int new_mtu)
330 334
331 return 0; 335 return 0;
332} 336}
337EXPORT_SYMBOL(orinoco_change_mtu);
333 338
334/********************************************************************/ 339/********************************************************************/
335/* Tx path */ 340/* Tx path */
336/********************************************************************/ 341/********************************************************************/
337 342
343/* Add encapsulation and MIC to the existing SKB.
344 * The main xmit routine will then send the whole lot to the card.
345 * Need 8 bytes headroom
346 * Need 8 bytes tailroom
347 *
348 * With encapsulated ethernet II frame
349 * --------
350 * 803.3 header (14 bytes)
351 * dst[6]
352 * -------- src[6]
353 * 803.3 header (14 bytes) len[2]
354 * dst[6] 803.2 header (8 bytes)
355 * src[6] encaps[6]
356 * len[2] <- leave alone -> len[2]
357 * -------- -------- <-- 0
358 * Payload Payload
359 * ... ...
360 *
361 * -------- --------
362 * MIC (8 bytes)
363 * --------
364 *
365 * returns 0 on success, -ENOMEM on error.
366 */
367int orinoco_process_xmit_skb(struct sk_buff *skb,
368 struct net_device *dev,
369 struct orinoco_private *priv,
370 int *tx_control,
371 u8 *mic_buf)
372{
373 struct orinoco_tkip_key *key;
374 struct ethhdr *eh;
375 int do_mic;
376
377 key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key;
378
379 do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) &&
380 (key != NULL));
381
382 if (do_mic)
383 *tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) |
384 HERMES_TXCTRL_MIC;
385
386 eh = (struct ethhdr *)skb->data;
387
388 /* Encapsulate Ethernet-II frames */
389 if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
390 struct header_struct {
391 struct ethhdr eth; /* 802.3 header */
392 u8 encap[6]; /* 802.2 header */
393 } __attribute__ ((packed)) hdr;
394 int len = skb->len + sizeof(encaps_hdr) - (2 * ETH_ALEN);
395
396 if (skb_headroom(skb) < ENCAPS_OVERHEAD) {
397 if (net_ratelimit())
398 printk(KERN_ERR
399 "%s: Not enough headroom for 802.2 headers %d\n",
400 dev->name, skb_headroom(skb));
401 return -ENOMEM;
402 }
403
404 /* Fill in new header */
405 memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
406 hdr.eth.h_proto = htons(len);
407 memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
408
409 /* Make room for the new header, and copy it in */
410 eh = (struct ethhdr *) skb_push(skb, ENCAPS_OVERHEAD);
411 memcpy(eh, &hdr, sizeof(hdr));
412 }
413
414 /* Calculate Michael MIC */
415 if (do_mic) {
416 size_t len = skb->len - ETH_HLEN;
417 u8 *mic = &mic_buf[0];
418
419 /* Have to write to an even address, so copy the spare
420 * byte across */
421 if (skb->len % 2) {
422 *mic = skb->data[skb->len - 1];
423 mic++;
424 }
425
426 orinoco_mic(priv->tx_tfm_mic, key->tx_mic,
427 eh->h_dest, eh->h_source, 0 /* priority */,
428 skb->data + ETH_HLEN,
429 len, mic);
430 }
431
432 return 0;
433}
434EXPORT_SYMBOL(orinoco_process_xmit_skb);
435
338static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev) 436static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
339{ 437{
340 struct orinoco_private *priv = ndev_priv(dev); 438 struct orinoco_private *priv = ndev_priv(dev);
341 struct net_device_stats *stats = &priv->stats; 439 struct net_device_stats *stats = &priv->stats;
342 struct orinoco_tkip_key *key;
343 hermes_t *hw = &priv->hw; 440 hermes_t *hw = &priv->hw;
344 int err = 0; 441 int err = 0;
345 u16 txfid = priv->txfid; 442 u16 txfid = priv->txfid;
346 struct ethhdr *eh;
347 int tx_control; 443 int tx_control;
348 unsigned long flags; 444 unsigned long flags;
349 int do_mic; 445 u8 mic_buf[MICHAEL_MIC_LEN+1];
350 446
351 if (!netif_running(dev)) { 447 if (!netif_running(dev)) {
352 printk(KERN_ERR "%s: Tx on stopped device!\n", 448 printk(KERN_ERR "%s: Tx on stopped device!\n",
@@ -378,16 +474,12 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
378 if (skb->len < ETH_HLEN) 474 if (skb->len < ETH_HLEN)
379 goto drop; 475 goto drop;
380 476
381 key = (struct orinoco_tkip_key *) priv->keys[priv->tx_key].key;
382
383 do_mic = ((priv->encode_alg == ORINOCO_ALG_TKIP) &&
384 (key != NULL));
385
386 tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX; 477 tx_control = HERMES_TXCTRL_TX_OK | HERMES_TXCTRL_TX_EX;
387 478
388 if (do_mic) 479 err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control,
389 tx_control |= (priv->tx_key << HERMES_MIC_KEY_ID_SHIFT) | 480 &mic_buf[0]);
390 HERMES_TXCTRL_MIC; 481 if (err)
482 goto drop;
391 483
392 if (priv->has_alt_txcntl) { 484 if (priv->has_alt_txcntl) {
393 /* WPA enabled firmwares have tx_cntl at the end of 485 /* WPA enabled firmwares have tx_cntl at the end of
@@ -400,8 +492,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
400 memset(&desc, 0, sizeof(desc)); 492 memset(&desc, 0, sizeof(desc));
401 493
402 *txcntl = cpu_to_le16(tx_control); 494 *txcntl = cpu_to_le16(tx_control);
403 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), 495 err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
404 txfid, 0); 496 txfid, 0);
405 if (err) { 497 if (err) {
406 if (net_ratelimit()) 498 if (net_ratelimit())
407 printk(KERN_ERR "%s: Error %d writing Tx " 499 printk(KERN_ERR "%s: Error %d writing Tx "
@@ -414,8 +506,8 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
414 memset(&desc, 0, sizeof(desc)); 506 memset(&desc, 0, sizeof(desc));
415 507
416 desc.tx_control = cpu_to_le16(tx_control); 508 desc.tx_control = cpu_to_le16(tx_control);
417 err = hermes_bap_pwrite(hw, USER_BAP, &desc, sizeof(desc), 509 err = hw->ops->bap_pwrite(hw, USER_BAP, &desc, sizeof(desc),
418 txfid, 0); 510 txfid, 0);
419 if (err) { 511 if (err) {
420 if (net_ratelimit()) 512 if (net_ratelimit())
421 printk(KERN_ERR "%s: Error %d writing Tx " 513 printk(KERN_ERR "%s: Error %d writing Tx "
@@ -430,68 +522,24 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
430 HERMES_802_3_OFFSET - HERMES_802_11_OFFSET); 522 HERMES_802_3_OFFSET - HERMES_802_11_OFFSET);
431 } 523 }
432 524
433 eh = (struct ethhdr *)skb->data; 525 err = hw->ops->bap_pwrite(hw, USER_BAP, skb->data, skb->len,
434 526 txfid, HERMES_802_3_OFFSET);
435 /* Encapsulate Ethernet-II frames */
436 if (ntohs(eh->h_proto) > ETH_DATA_LEN) { /* Ethernet-II frame */
437 struct header_struct {
438 struct ethhdr eth; /* 802.3 header */
439 u8 encap[6]; /* 802.2 header */
440 } __attribute__ ((packed)) hdr;
441
442 /* Strip destination and source from the data */
443 skb_pull(skb, 2 * ETH_ALEN);
444
445 /* And move them to a separate header */
446 memcpy(&hdr.eth, eh, 2 * ETH_ALEN);
447 hdr.eth.h_proto = htons(sizeof(encaps_hdr) + skb->len);
448 memcpy(hdr.encap, encaps_hdr, sizeof(encaps_hdr));
449
450 /* Insert the SNAP header */
451 if (skb_headroom(skb) < sizeof(hdr)) {
452 printk(KERN_ERR
453 "%s: Not enough headroom for 802.2 headers %d\n",
454 dev->name, skb_headroom(skb));
455 goto drop;
456 }
457 eh = (struct ethhdr *) skb_push(skb, sizeof(hdr));
458 memcpy(eh, &hdr, sizeof(hdr));
459 }
460
461 err = hermes_bap_pwrite(hw, USER_BAP, skb->data, skb->len,
462 txfid, HERMES_802_3_OFFSET);
463 if (err) { 527 if (err) {
464 printk(KERN_ERR "%s: Error %d writing packet to BAP\n", 528 printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
465 dev->name, err); 529 dev->name, err);
466 goto busy; 530 goto busy;
467 } 531 }
468 532
469 /* Calculate Michael MIC */ 533 if (tx_control & HERMES_TXCTRL_MIC) {
470 if (do_mic) { 534 size_t offset = HERMES_802_3_OFFSET + skb->len;
471 u8 mic_buf[MICHAEL_MIC_LEN + 1]; 535 size_t len = MICHAEL_MIC_LEN;
472 u8 *mic;
473 size_t offset;
474 size_t len;
475 536
476 if (skb->len % 2) { 537 if (offset % 2) {
477 /* MIC start is on an odd boundary */ 538 offset--;
478 mic_buf[0] = skb->data[skb->len - 1]; 539 len++;
479 mic = &mic_buf[1];
480 offset = skb->len - 1;
481 len = MICHAEL_MIC_LEN + 1;
482 } else {
483 mic = &mic_buf[0];
484 offset = skb->len;
485 len = MICHAEL_MIC_LEN;
486 } 540 }
487 541 err = hw->ops->bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
488 orinoco_mic(priv->tx_tfm_mic, key->tx_mic, 542 txfid, offset);
489 eh->h_dest, eh->h_source, 0 /* priority */,
490 skb->data + ETH_HLEN, skb->len - ETH_HLEN, mic);
491
492 /* Write the MIC */
493 err = hermes_bap_pwrite(hw, USER_BAP, &mic_buf[0], len,
494 txfid, HERMES_802_3_OFFSET + offset);
495 if (err) { 543 if (err) {
496 printk(KERN_ERR "%s: Error %d writing MIC to BAP\n", 544 printk(KERN_ERR "%s: Error %d writing MIC to BAP\n",
497 dev->name, err); 545 dev->name, err);
@@ -502,7 +550,7 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
502 /* Finally, we actually initiate the send */ 550 /* Finally, we actually initiate the send */
503 netif_stop_queue(dev); 551 netif_stop_queue(dev);
504 552
505 err = hermes_docmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL, 553 err = hw->ops->cmd_wait(hw, HERMES_CMD_TX | HERMES_CMD_RECL,
506 txfid, NULL); 554 txfid, NULL);
507 if (err) { 555 if (err) {
508 netif_start_queue(dev); 556 netif_start_queue(dev);
@@ -512,7 +560,6 @@ static netdev_tx_t orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
512 goto busy; 560 goto busy;
513 } 561 }
514 562
515 dev->trans_start = jiffies;
516 stats->tx_bytes += HERMES_802_3_OFFSET + skb->len; 563 stats->tx_bytes += HERMES_802_3_OFFSET + skb->len;
517 goto ok; 564 goto ok;
518 565
@@ -572,9 +619,9 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
572 return; /* Nothing's really happened */ 619 return; /* Nothing's really happened */
573 620
574 /* Read part of the frame header - we need status and addr1 */ 621 /* Read part of the frame header - we need status and addr1 */
575 err = hermes_bap_pread(hw, IRQ_BAP, &hdr, 622 err = hw->ops->bap_pread(hw, IRQ_BAP, &hdr,
576 sizeof(struct hermes_txexc_data), 623 sizeof(struct hermes_txexc_data),
577 fid, 0); 624 fid, 0);
578 625
579 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); 626 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
580 stats->tx_errors++; 627 stats->tx_errors++;
@@ -615,7 +662,7 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
615 netif_wake_queue(dev); 662 netif_wake_queue(dev);
616} 663}
617 664
618static void orinoco_tx_timeout(struct net_device *dev) 665void orinoco_tx_timeout(struct net_device *dev)
619{ 666{
620 struct orinoco_private *priv = ndev_priv(dev); 667 struct orinoco_private *priv = ndev_priv(dev);
621 struct net_device_stats *stats = &priv->stats; 668 struct net_device_stats *stats = &priv->stats;
@@ -630,6 +677,7 @@ static void orinoco_tx_timeout(struct net_device *dev)
630 677
631 schedule_work(&priv->reset_work); 678 schedule_work(&priv->reset_work);
632} 679}
680EXPORT_SYMBOL(orinoco_tx_timeout);
633 681
634/********************************************************************/ 682/********************************************************************/
635/* Rx path (data frames) */ 683/* Rx path (data frames) */
@@ -764,9 +812,9 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
764 812
765 /* If any, copy the data from the card to the skb */ 813 /* If any, copy the data from the card to the skb */
766 if (datalen > 0) { 814 if (datalen > 0) {
767 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, datalen), 815 err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, datalen),
768 ALIGN(datalen, 2), rxfid, 816 ALIGN(datalen, 2), rxfid,
769 HERMES_802_2_OFFSET); 817 HERMES_802_2_OFFSET);
770 if (err) { 818 if (err) {
771 printk(KERN_ERR "%s: error %d reading monitor frame\n", 819 printk(KERN_ERR "%s: error %d reading monitor frame\n",
772 dev->name, err); 820 dev->name, err);
@@ -792,7 +840,7 @@ static void orinoco_rx_monitor(struct net_device *dev, u16 rxfid,
792 stats->rx_dropped++; 840 stats->rx_dropped++;
793} 841}
794 842
795static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw) 843void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
796{ 844{
797 struct orinoco_private *priv = ndev_priv(dev); 845 struct orinoco_private *priv = ndev_priv(dev);
798 struct net_device_stats *stats = &priv->stats; 846 struct net_device_stats *stats = &priv->stats;
@@ -814,8 +862,8 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
814 862
815 rxfid = hermes_read_regn(hw, RXFID); 863 rxfid = hermes_read_regn(hw, RXFID);
816 864
817 err = hermes_bap_pread(hw, IRQ_BAP, desc, sizeof(*desc), 865 err = hw->ops->bap_pread(hw, IRQ_BAP, desc, sizeof(*desc),
818 rxfid, 0); 866 rxfid, 0);
819 if (err) { 867 if (err) {
820 printk(KERN_ERR "%s: error %d reading Rx descriptor. " 868 printk(KERN_ERR "%s: error %d reading Rx descriptor. "
821 "Frame dropped.\n", dev->name, err); 869 "Frame dropped.\n", dev->name, err);
@@ -882,9 +930,9 @@ static void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw)
882 nothing is removed. 2 is for aligning the IP header. */ 930 nothing is removed. 2 is for aligning the IP header. */
883 skb_reserve(skb, ETH_HLEN + 2); 931 skb_reserve(skb, ETH_HLEN + 2);
884 932
885 err = hermes_bap_pread(hw, IRQ_BAP, skb_put(skb, length), 933 err = hw->ops->bap_pread(hw, IRQ_BAP, skb_put(skb, length),
886 ALIGN(length, 2), rxfid, 934 ALIGN(length, 2), rxfid,
887 HERMES_802_2_OFFSET); 935 HERMES_802_2_OFFSET);
888 if (err) { 936 if (err) {
889 printk(KERN_ERR "%s: error %d reading frame. " 937 printk(KERN_ERR "%s: error %d reading frame. "
890 "Frame dropped.\n", dev->name, err); 938 "Frame dropped.\n", dev->name, err);
@@ -913,6 +961,7 @@ update_stats:
913out: 961out:
914 kfree(desc); 962 kfree(desc);
915} 963}
964EXPORT_SYMBOL(__orinoco_ev_rx);
916 965
917static void orinoco_rx(struct net_device *dev, 966static void orinoco_rx(struct net_device *dev,
918 struct hermes_rx_descriptor *desc, 967 struct hermes_rx_descriptor *desc,
@@ -1145,9 +1194,9 @@ static void orinoco_join_ap(struct work_struct *work)
1145 goto out; 1194 goto out;
1146 1195
1147 /* Read scan results from the firmware */ 1196 /* Read scan results from the firmware */
1148 err = hermes_read_ltv(hw, USER_BAP, 1197 err = hw->ops->read_ltv(hw, USER_BAP,
1149 HERMES_RID_SCANRESULTSTABLE, 1198 HERMES_RID_SCANRESULTSTABLE,
1150 MAX_SCAN_LEN, &len, buf); 1199 MAX_SCAN_LEN, &len, buf);
1151 if (err) { 1200 if (err) {
1152 printk(KERN_ERR "%s: Cannot read scan results\n", 1201 printk(KERN_ERR "%s: Cannot read scan results\n",
1153 dev->name); 1202 dev->name);
@@ -1194,8 +1243,8 @@ static void orinoco_send_bssid_wevent(struct orinoco_private *priv)
1194 union iwreq_data wrqu; 1243 union iwreq_data wrqu;
1195 int err; 1244 int err;
1196 1245
1197 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID, 1246 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENTBSSID,
1198 ETH_ALEN, NULL, wrqu.ap_addr.sa_data); 1247 ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1199 if (err != 0) 1248 if (err != 0)
1200 return; 1249 return;
1201 1250
@@ -1217,8 +1266,8 @@ static void orinoco_send_assocreqie_wevent(struct orinoco_private *priv)
1217 if (!priv->has_wpa) 1266 if (!priv->has_wpa)
1218 return; 1267 return;
1219 1268
1220 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO, 1269 err = hw->ops->read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_REQ_INFO,
1221 sizeof(buf), NULL, &buf); 1270 sizeof(buf), NULL, &buf);
1222 if (err != 0) 1271 if (err != 0)
1223 return; 1272 return;
1224 1273
@@ -1247,8 +1296,9 @@ static void orinoco_send_assocrespie_wevent(struct orinoco_private *priv)
1247 if (!priv->has_wpa) 1296 if (!priv->has_wpa)
1248 return; 1297 return;
1249 1298
1250 err = hermes_read_ltv(hw, USER_BAP, HERMES_RID_CURRENT_ASSOC_RESP_INFO, 1299 err = hw->ops->read_ltv(hw, USER_BAP,
1251 sizeof(buf), NULL, &buf); 1300 HERMES_RID_CURRENT_ASSOC_RESP_INFO,
1301 sizeof(buf), NULL, &buf);
1252 if (err != 0) 1302 if (err != 0)
1253 return; 1303 return;
1254 1304
@@ -1353,7 +1403,7 @@ static void orinoco_process_scan_results(struct work_struct *work)
1353 spin_unlock_irqrestore(&priv->scan_lock, flags); 1403 spin_unlock_irqrestore(&priv->scan_lock, flags);
1354} 1404}
1355 1405
1356static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) 1406void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1357{ 1407{
1358 struct orinoco_private *priv = ndev_priv(dev); 1408 struct orinoco_private *priv = ndev_priv(dev);
1359 u16 infofid; 1409 u16 infofid;
@@ -1371,8 +1421,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1371 infofid = hermes_read_regn(hw, INFOFID); 1421 infofid = hermes_read_regn(hw, INFOFID);
1372 1422
1373 /* Read the info frame header - don't try too hard */ 1423 /* Read the info frame header - don't try too hard */
1374 err = hermes_bap_pread(hw, IRQ_BAP, &info, sizeof(info), 1424 err = hw->ops->bap_pread(hw, IRQ_BAP, &info, sizeof(info),
1375 infofid, 0); 1425 infofid, 0);
1376 if (err) { 1426 if (err) {
1377 printk(KERN_ERR "%s: error %d reading info frame. " 1427 printk(KERN_ERR "%s: error %d reading info frame. "
1378 "Frame dropped.\n", dev->name, err); 1428 "Frame dropped.\n", dev->name, err);
@@ -1393,8 +1443,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1393 len = sizeof(tallies); 1443 len = sizeof(tallies);
1394 } 1444 }
1395 1445
1396 err = hermes_bap_pread(hw, IRQ_BAP, &tallies, len, 1446 err = hw->ops->bap_pread(hw, IRQ_BAP, &tallies, len,
1397 infofid, sizeof(info)); 1447 infofid, sizeof(info));
1398 if (err) 1448 if (err)
1399 break; 1449 break;
1400 1450
@@ -1429,8 +1479,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1429 break; 1479 break;
1430 } 1480 }
1431 1481
1432 err = hermes_bap_pread(hw, IRQ_BAP, &linkstatus, len, 1482 err = hw->ops->bap_pread(hw, IRQ_BAP, &linkstatus, len,
1433 infofid, sizeof(info)); 1483 infofid, sizeof(info));
1434 if (err) 1484 if (err)
1435 break; 1485 break;
1436 newstatus = le16_to_cpu(linkstatus.linkstatus); 1486 newstatus = le16_to_cpu(linkstatus.linkstatus);
@@ -1494,8 +1544,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1494 } 1544 }
1495 1545
1496 /* Read scan data */ 1546 /* Read scan data */
1497 err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len, 1547 err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) buf, len,
1498 infofid, sizeof(info)); 1548 infofid, sizeof(info));
1499 if (err) { 1549 if (err) {
1500 kfree(buf); 1550 kfree(buf);
1501 qabort_scan(priv); 1551 qabort_scan(priv);
@@ -1547,8 +1597,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1547 break; 1597 break;
1548 1598
1549 /* Read scan data */ 1599 /* Read scan data */
1550 err = hermes_bap_pread(hw, IRQ_BAP, (void *) bss, len, 1600 err = hw->ops->bap_pread(hw, IRQ_BAP, (void *) bss, len,
1551 infofid, sizeof(info)); 1601 infofid, sizeof(info));
1552 if (err) 1602 if (err)
1553 kfree(bss); 1603 kfree(bss);
1554 else 1604 else
@@ -1568,9 +1618,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1568 /* We don't actually do anything about it */ 1618 /* We don't actually do anything about it */
1569 break; 1619 break;
1570 } 1620 }
1571
1572 return;
1573} 1621}
1622EXPORT_SYMBOL(__orinoco_ev_info);
1574 1623
1575static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw) 1624static void __orinoco_ev_infdrop(struct net_device *dev, hermes_t *hw)
1576{ 1625{
@@ -1647,7 +1696,7 @@ static int orinoco_reinit_firmware(struct orinoco_private *priv)
1647 struct hermes *hw = &priv->hw; 1696 struct hermes *hw = &priv->hw;
1648 int err; 1697 int err;
1649 1698
1650 err = hermes_init(hw); 1699 err = hw->ops->init(hw);
1651 if (priv->do_fw_download && !err) { 1700 if (priv->do_fw_download && !err) {
1652 err = orinoco_download(priv); 1701 err = orinoco_download(priv);
1653 if (err) 1702 if (err)
@@ -1735,7 +1784,7 @@ void orinoco_reset(struct work_struct *work)
1735 } 1784 }
1736 1785
1737 /* This has to be called from user context */ 1786 /* This has to be called from user context */
1738 spin_lock_irq(&priv->lock); 1787 orinoco_lock_irq(priv);
1739 1788
1740 priv->hw_unavailable--; 1789 priv->hw_unavailable--;
1741 1790
@@ -1750,7 +1799,7 @@ void orinoco_reset(struct work_struct *work)
1750 dev->trans_start = jiffies; 1799 dev->trans_start = jiffies;
1751 } 1800 }
1752 1801
1753 spin_unlock_irq(&priv->lock); 1802 orinoco_unlock_irq(priv);
1754 1803
1755 return; 1804 return;
1756 disable: 1805 disable:
@@ -1984,7 +2033,7 @@ int orinoco_init(struct orinoco_private *priv)
1984 priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN; 2033 priv->nicbuf_size = IEEE80211_MAX_FRAME_LEN + ETH_HLEN;
1985 2034
1986 /* Initialize the firmware */ 2035 /* Initialize the firmware */
1987 err = hermes_init(hw); 2036 err = hw->ops->init(hw);
1988 if (err != 0) { 2037 if (err != 0) {
1989 dev_err(dev, "Failed to initialize firmware (err = %d)\n", 2038 dev_err(dev, "Failed to initialize firmware (err = %d)\n",
1990 err); 2039 err);
@@ -2067,9 +2116,9 @@ int orinoco_init(struct orinoco_private *priv)
2067 2116
2068 /* Make the hardware available, as long as it hasn't been 2117 /* Make the hardware available, as long as it hasn't been
2069 * removed elsewhere (e.g. by PCMCIA hot unplug) */ 2118 * removed elsewhere (e.g. by PCMCIA hot unplug) */
2070 spin_lock_irq(&priv->lock); 2119 orinoco_lock_irq(priv);
2071 priv->hw_unavailable--; 2120 priv->hw_unavailable--;
2072 spin_unlock_irq(&priv->lock); 2121 orinoco_unlock_irq(priv);
2073 2122
2074 dev_dbg(dev, "Ready\n"); 2123 dev_dbg(dev, "Ready\n");
2075 2124
@@ -2192,7 +2241,8 @@ EXPORT_SYMBOL(alloc_orinocodev);
2192 */ 2241 */
2193int orinoco_if_add(struct orinoco_private *priv, 2242int orinoco_if_add(struct orinoco_private *priv,
2194 unsigned long base_addr, 2243 unsigned long base_addr,
2195 unsigned int irq) 2244 unsigned int irq,
2245 const struct net_device_ops *ops)
2196{ 2246{
2197 struct wiphy *wiphy = priv_to_wiphy(priv); 2247 struct wiphy *wiphy = priv_to_wiphy(priv);
2198 struct wireless_dev *wdev; 2248 struct wireless_dev *wdev;
@@ -2211,16 +2261,21 @@ int orinoco_if_add(struct orinoco_private *priv,
2211 2261
2212 /* Setup / override net_device fields */ 2262 /* Setup / override net_device fields */
2213 dev->ieee80211_ptr = wdev; 2263 dev->ieee80211_ptr = wdev;
2214 dev->netdev_ops = &orinoco_netdev_ops;
2215 dev->watchdog_timeo = HZ; /* 1 second timeout */ 2264 dev->watchdog_timeo = HZ; /* 1 second timeout */
2216 dev->wireless_handlers = &orinoco_handler_def; 2265 dev->wireless_handlers = &orinoco_handler_def;
2217#ifdef WIRELESS_SPY 2266#ifdef WIRELESS_SPY
2218 dev->wireless_data = &priv->wireless_data; 2267 dev->wireless_data = &priv->wireless_data;
2219#endif 2268#endif
2269 /* Default to standard ops if not set */
2270 if (ops)
2271 dev->netdev_ops = ops;
2272 else
2273 dev->netdev_ops = &orinoco_netdev_ops;
2274
2220 /* we use the default eth_mac_addr for setting the MAC addr */ 2275 /* we use the default eth_mac_addr for setting the MAC addr */
2221 2276
2222 /* Reserve space in skb for the SNAP header */ 2277 /* Reserve space in skb for the SNAP header */
2223 dev->hard_header_len += ENCAPS_OVERHEAD; 2278 dev->needed_headroom = ENCAPS_OVERHEAD;
2224 2279
2225 netif_carrier_off(dev); 2280 netif_carrier_off(dev);
2226 2281
@@ -2305,7 +2360,7 @@ int orinoco_up(struct orinoco_private *priv)
2305 unsigned long flags; 2360 unsigned long flags;
2306 int err; 2361 int err;
2307 2362
2308 spin_lock_irqsave(&priv->lock, flags); 2363 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
2309 2364
2310 err = orinoco_reinit_firmware(priv); 2365 err = orinoco_reinit_firmware(priv);
2311 if (err) { 2366 if (err) {
@@ -2325,7 +2380,7 @@ int orinoco_up(struct orinoco_private *priv)
2325 } 2380 }
2326 2381
2327exit: 2382exit:
2328 spin_unlock_irqrestore(&priv->lock, flags); 2383 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
2329 2384
2330 return 0; 2385 return 0;
2331} 2386}
@@ -2337,7 +2392,7 @@ void orinoco_down(struct orinoco_private *priv)
2337 unsigned long flags; 2392 unsigned long flags;
2338 int err; 2393 int err;
2339 2394
2340 spin_lock_irqsave(&priv->lock, flags); 2395 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
2341 err = __orinoco_down(priv); 2396 err = __orinoco_down(priv);
2342 if (err) 2397 if (err)
2343 printk(KERN_WARNING "%s: Error %d downing interface\n", 2398 printk(KERN_WARNING "%s: Error %d downing interface\n",
@@ -2345,7 +2400,7 @@ void orinoco_down(struct orinoco_private *priv)
2345 2400
2346 netif_device_detach(dev); 2401 netif_device_detach(dev);
2347 priv->hw_unavailable++; 2402 priv->hw_unavailable++;
2348 spin_unlock_irqrestore(&priv->lock, flags); 2403 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
2349} 2404}
2350EXPORT_SYMBOL(orinoco_down); 2405EXPORT_SYMBOL(orinoco_down);
2351 2406
diff --git a/drivers/net/wireless/orinoco/main.h b/drivers/net/wireless/orinoco/main.h
index 21ab36cd76c7..4dadf9880a97 100644
--- a/drivers/net/wireless/orinoco/main.h
+++ b/drivers/net/wireless/orinoco/main.h
@@ -33,18 +33,6 @@ int orinoco_commit(struct orinoco_private *priv);
33void orinoco_reset(struct work_struct *work); 33void orinoco_reset(struct work_struct *work);
34 34
35/* Information element helpers - find a home for these... */ 35/* Information element helpers - find a home for these... */
36static inline u8 *orinoco_get_ie(u8 *data, size_t len,
37 enum ieee80211_eid eid)
38{
39 u8 *p = data;
40 while ((p + 2) < (data + len)) {
41 if (p[0] == eid)
42 return p;
43 p += p[1] + 2;
44 }
45 return NULL;
46}
47
48#define WPA_OUI_TYPE "\x00\x50\xF2\x01" 36#define WPA_OUI_TYPE "\x00\x50\xF2\x01"
49#define WPA_SELECTOR_LEN 4 37#define WPA_SELECTOR_LEN 4
50static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len) 38static inline u8 *orinoco_get_wpa_ie(u8 *data, size_t len)
diff --git a/drivers/net/wireless/orinoco/orinoco.h b/drivers/net/wireless/orinoco/orinoco.h
index 665ef56f8382..a6da86e0a70f 100644
--- a/drivers/net/wireless/orinoco/orinoco.h
+++ b/drivers/net/wireless/orinoco/orinoco.h
@@ -131,6 +131,8 @@ struct orinoco_private {
131 u16 ap_density, rts_thresh; 131 u16 ap_density, rts_thresh;
132 u16 pm_on, pm_mcast, pm_period, pm_timeout; 132 u16 pm_on, pm_mcast, pm_period, pm_timeout;
133 u16 preamble; 133 u16 preamble;
134 u16 short_retry_limit, long_retry_limit;
135 u16 retry_lifetime;
134#ifdef WIRELESS_SPY 136#ifdef WIRELESS_SPY
135 struct iw_spy_data spy_data; /* iwspy support */ 137 struct iw_spy_data spy_data; /* iwspy support */
136 struct iw_public_data wireless_data; 138 struct iw_public_data wireless_data;
@@ -188,12 +190,30 @@ extern void free_orinocodev(struct orinoco_private *priv);
188extern int orinoco_init(struct orinoco_private *priv); 190extern int orinoco_init(struct orinoco_private *priv);
189extern int orinoco_if_add(struct orinoco_private *priv, 191extern int orinoco_if_add(struct orinoco_private *priv,
190 unsigned long base_addr, 192 unsigned long base_addr,
191 unsigned int irq); 193 unsigned int irq,
194 const struct net_device_ops *ops);
192extern void orinoco_if_del(struct orinoco_private *priv); 195extern void orinoco_if_del(struct orinoco_private *priv);
193extern int orinoco_up(struct orinoco_private *priv); 196extern int orinoco_up(struct orinoco_private *priv);
194extern void orinoco_down(struct orinoco_private *priv); 197extern void orinoco_down(struct orinoco_private *priv);
195extern irqreturn_t orinoco_interrupt(int irq, void *dev_id); 198extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
196 199
200extern void __orinoco_ev_info(struct net_device *dev, hermes_t *hw);
201extern void __orinoco_ev_rx(struct net_device *dev, hermes_t *hw);
202
203int orinoco_process_xmit_skb(struct sk_buff *skb,
204 struct net_device *dev,
205 struct orinoco_private *priv,
206 int *tx_control,
207 u8 *mic);
208
209/* Common ndo functions exported for reuse by orinoco_usb */
210int orinoco_open(struct net_device *dev);
211int orinoco_stop(struct net_device *dev);
212struct net_device_stats *orinoco_get_stats(struct net_device *dev);
213void orinoco_set_multicast_list(struct net_device *dev);
214int orinoco_change_mtu(struct net_device *dev, int new_mtu);
215void orinoco_tx_timeout(struct net_device *dev);
216
197/********************************************************************/ 217/********************************************************************/
198/* Locking and synchronization functions */ 218/* Locking and synchronization functions */
199/********************************************************************/ 219/********************************************************************/
@@ -201,11 +221,11 @@ extern irqreturn_t orinoco_interrupt(int irq, void *dev_id);
201static inline int orinoco_lock(struct orinoco_private *priv, 221static inline int orinoco_lock(struct orinoco_private *priv,
202 unsigned long *flags) 222 unsigned long *flags)
203{ 223{
204 spin_lock_irqsave(&priv->lock, *flags); 224 priv->hw.ops->lock_irqsave(&priv->lock, flags);
205 if (priv->hw_unavailable) { 225 if (priv->hw_unavailable) {
206 DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n", 226 DEBUG(1, "orinoco_lock() called with hw_unavailable (dev=%p)\n",
207 priv->ndev); 227 priv->ndev);
208 spin_unlock_irqrestore(&priv->lock, *flags); 228 priv->hw.ops->unlock_irqrestore(&priv->lock, flags);
209 return -EBUSY; 229 return -EBUSY;
210 } 230 }
211 return 0; 231 return 0;
@@ -214,7 +234,17 @@ static inline int orinoco_lock(struct orinoco_private *priv,
214static inline void orinoco_unlock(struct orinoco_private *priv, 234static inline void orinoco_unlock(struct orinoco_private *priv,
215 unsigned long *flags) 235 unsigned long *flags)
216{ 236{
217 spin_unlock_irqrestore(&priv->lock, *flags); 237 priv->hw.ops->unlock_irqrestore(&priv->lock, flags);
238}
239
240static inline void orinoco_lock_irq(struct orinoco_private *priv)
241{
242 priv->hw.ops->lock_irq(&priv->lock);
243}
244
245static inline void orinoco_unlock_irq(struct orinoco_private *priv)
246{
247 priv->hw.ops->unlock_irq(&priv->lock);
218} 248}
219 249
220/*** Navigate from net_device to orinoco_private ***/ 250/*** Navigate from net_device to orinoco_private ***/
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c
index 03056ab73032..b16d5db52a4d 100644
--- a/drivers/net/wireless/orinoco/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco/orinoco_cs.c
@@ -281,7 +281,7 @@ orinoco_cs_config(struct pcmcia_device *link)
281 281
282 /* Register an interface with the stack */ 282 /* Register an interface with the stack */
283 if (orinoco_if_add(priv, link->io.BasePort1, 283 if (orinoco_if_add(priv, link->io.BasePort1,
284 link->irq) != 0) { 284 link->irq, NULL) != 0) {
285 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 285 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
286 goto failed; 286 goto failed;
287 } 287 }
@@ -306,9 +306,9 @@ orinoco_cs_release(struct pcmcia_device *link)
306 306
307 /* We're committed to taking the device away now, so mark the 307 /* We're committed to taking the device away now, so mark the
308 * hardware as unavailable */ 308 * hardware as unavailable */
309 spin_lock_irqsave(&priv->lock, flags); 309 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
310 priv->hw_unavailable++; 310 priv->hw_unavailable++;
311 spin_unlock_irqrestore(&priv->lock, flags); 311 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
312 312
313 pcmcia_disable_device(link); 313 pcmcia_disable_device(link);
314 if (priv->hw.iobase) 314 if (priv->hw.iobase)
@@ -353,87 +353,90 @@ static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
353 "Pavel Roskin <proski@gnu.org>, et al)"; 353 "Pavel Roskin <proski@gnu.org>, et al)";
354 354
355static struct pcmcia_device_id orinoco_cs_ids[] = { 355static struct pcmcia_device_id orinoco_cs_ids[] = {
356 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
357 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
358 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
359 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */ 356 PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
360 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
361 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
362 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */ 357 PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
363 PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */ 358 PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
364 PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */ 359 PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
365 PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
366 PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
367 PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */ 360 PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
368 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */ 361 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
369 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */ 362 PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0003), /* ARtem Onair Comcard 11 */
370 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */ 363 PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
371 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
372 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
373 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
374 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
375 PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */ 364 PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
376 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */ 365 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
377 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */ 366 PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x3021), /* SpeedStream Wireless Adapter */
378 PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */ 367 PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
368 PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
369 PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
370 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
371 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
372 PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
373 PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
374 PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
375 PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
376 PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
377 PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
378 PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
379 PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
380 PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
381 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
382 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
383 PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
384 PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
385 PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
386 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
387 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
388 PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
389 PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
390#ifdef CONFIG_HERMES_PRISM
391 /* Only entries that certainly identify Prism chipset */
392 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
393 PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
394 PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
395 PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
396 PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
397 PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
398 PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
399 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
400 PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
401 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
402 PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
379 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */ 403 PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
380 PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */ 404 PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
381 PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */ 405 PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
382 PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */ 406 PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
383 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */ 407 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
384 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */ 408 PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
385 PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9), 409 PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
386 PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
387 PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5), 410 PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
388 PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2), 411 PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
389 PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
390 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
391 PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
392 PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
393 PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
394 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
395 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18), 412 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
396 PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90), 413 PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
397 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b), 414 PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
398 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584), 415 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
399 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9), 416 PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
400 PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae), 417 PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
418 PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
401 PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac), 419 PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
402 PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab), 420 PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
403 PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916), 421 PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
404 PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
405 PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
406 PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
407 PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
408 PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
409 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18), 422 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
410 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77), 423 PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
411 PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf), 424 PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
412 PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
413 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395), 425 PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
414 PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
415 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
416 PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
417 PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01), 426 PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
418 PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
419 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
420 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1), 427 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
421 PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767), 428 PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
422 PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6), 429 PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
423 PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
424 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264), 430 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
425 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178), 431 PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
426 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
427 PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
428 PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
429 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757), 432 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2532W-B EliteConnect Wireless Adapter", 0xc4f8b18b, 0x196bd757),
430 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a), 433 PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
431 PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
432 PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee), 434 PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
433 PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092), 435 PCMCIA_DEVICE_PROD_ID3("HFA3863", 0x355cb092),
434 PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2), 436 PCMCIA_DEVICE_PROD_ID3("ISL37100P", 0x630d52b2),
435 PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b), 437 PCMCIA_DEVICE_PROD_ID3("ISL37101P-10", 0xdd97a26b),
436 PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39), 438 PCMCIA_DEVICE_PROD_ID3("ISL37300P", 0xc9049a39),
439#endif
437 PCMCIA_DEVICE_NULL, 440 PCMCIA_DEVICE_NULL,
438}; 441};
439MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids); 442MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
diff --git a/drivers/net/wireless/orinoco/orinoco_nortel.c b/drivers/net/wireless/orinoco/orinoco_nortel.c
index 075f446b3139..bc3ea0b67a4f 100644
--- a/drivers/net/wireless/orinoco/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco/orinoco_nortel.c
@@ -220,7 +220,7 @@ static int orinoco_nortel_init_one(struct pci_dev *pdev,
220 goto fail; 220 goto fail;
221 } 221 }
222 222
223 err = orinoco_if_add(priv, 0, 0); 223 err = orinoco_if_add(priv, 0, 0, NULL);
224 if (err) { 224 if (err) {
225 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 225 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
226 goto fail; 226 goto fail;
diff --git a/drivers/net/wireless/orinoco/orinoco_pci.c b/drivers/net/wireless/orinoco/orinoco_pci.c
index bda5317cc596..468197f86673 100644
--- a/drivers/net/wireless/orinoco/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco/orinoco_pci.c
@@ -170,7 +170,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev,
170 goto fail; 170 goto fail;
171 } 171 }
172 172
173 err = orinoco_if_add(priv, 0, 0); 173 err = orinoco_if_add(priv, 0, 0, NULL);
174 if (err) { 174 if (err) {
175 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 175 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
176 goto fail; 176 goto fail;
diff --git a/drivers/net/wireless/orinoco/orinoco_plx.c b/drivers/net/wireless/orinoco/orinoco_plx.c
index e0d5874ab42f..9358f4d2307b 100644
--- a/drivers/net/wireless/orinoco/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco/orinoco_plx.c
@@ -259,7 +259,7 @@ static int orinoco_plx_init_one(struct pci_dev *pdev,
259 goto fail; 259 goto fail;
260 } 260 }
261 261
262 err = orinoco_if_add(priv, 0, 0); 262 err = orinoco_if_add(priv, 0, 0, NULL);
263 if (err) { 263 if (err) {
264 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 264 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
265 goto fail; 265 goto fail;
diff --git a/drivers/net/wireless/orinoco/orinoco_tmd.c b/drivers/net/wireless/orinoco/orinoco_tmd.c
index 88cbc7902aa0..784605f0af15 100644
--- a/drivers/net/wireless/orinoco/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco/orinoco_tmd.c
@@ -156,7 +156,7 @@ static int orinoco_tmd_init_one(struct pci_dev *pdev,
156 goto fail; 156 goto fail;
157 } 157 }
158 158
159 err = orinoco_if_add(priv, 0, 0); 159 err = orinoco_if_add(priv, 0, 0, NULL);
160 if (err) { 160 if (err) {
161 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 161 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
162 goto fail; 162 goto fail;
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
new file mode 100644
index 000000000000..78f089baa8c9
--- /dev/null
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -0,0 +1,1795 @@
1/*
2 * USB Orinoco driver
3 *
4 * Copyright (c) 2003 Manuel Estrada Sainz
5 *
6 * The contents of this file are subject to the Mozilla Public License
7 * Version 1.1 (the "License"); you may not use this file except in
8 * compliance with the License. You may obtain a copy of the License
9 * at http://www.mozilla.org/MPL/
10 *
11 * Software distributed under the License is distributed on an "AS IS"
12 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
13 * the License for the specific language governing rights and
14 * limitations under the License.
15 *
16 * Alternatively, the contents of this file may be used under the
17 * terms of the GNU General Public License version 2 (the "GPL"), in
18 * which case the provisions of the GPL are applicable instead of the
19 * above. If you wish to allow the use of your version of this file
20 * only under the terms of the GPL and not to allow others to use your
21 * version of this file under the MPL, indicate your decision by
22 * deleting the provisions above and replace them with the notice and
23 * other provisions required by the GPL. If you do not delete the
24 * provisions above, a recipient may use your version of this file
25 * under either the MPL or the GPL.
26 *
27 * Queueing code based on linux-wlan-ng 0.2.1-pre5
28 *
29 * Copyright (C) 1999 AbsoluteValue Systems, Inc. All Rights Reserved.
30 *
31 * The license is the same as above.
32 *
33 * Initialy based on USB Skeleton driver - 0.7
34 *
35 * Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
36 *
37 * This program is free software; you can redistribute it and/or
38 * modify it under the terms of the GNU General Public License as
39 * published by the Free Software Foundation; either version 2 of
40 * the License, or (at your option) any later version.
41 *
42 * NOTE: The original USB Skeleton driver is GPL, but all that code is
43 * gone so MPL/GPL applies.
44 */
45
46#define DRIVER_NAME "orinoco_usb"
47#define PFX DRIVER_NAME ": "
48
49#include <linux/module.h>
50#include <linux/kernel.h>
51#include <linux/sched.h>
52#include <linux/signal.h>
53#include <linux/errno.h>
54#include <linux/poll.h>
55#include <linux/init.h>
56#include <linux/slab.h>
57#include <linux/fcntl.h>
58#include <linux/spinlock.h>
59#include <linux/list.h>
60#include <linux/smp_lock.h>
61#include <linux/usb.h>
62#include <linux/timer.h>
63
64#include <linux/netdevice.h>
65#include <linux/if_arp.h>
66#include <linux/etherdevice.h>
67#include <linux/wireless.h>
68#include <linux/firmware.h>
69
70#include "mic.h"
71#include "orinoco.h"
72
73#ifndef URB_ASYNC_UNLINK
74#define URB_ASYNC_UNLINK 0
75#endif
76
77/* 802.2 LLC/SNAP header used for Ethernet encapsulation over 802.11 */
78static const u8 encaps_hdr[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
79#define ENCAPS_OVERHEAD (sizeof(encaps_hdr) + 2)
80
81struct header_struct {
82 /* 802.3 */
83 u8 dest[ETH_ALEN];
84 u8 src[ETH_ALEN];
85 __be16 len;
86 /* 802.2 */
87 u8 dsap;
88 u8 ssap;
89 u8 ctrl;
90 /* SNAP */
91 u8 oui[3];
92 __be16 ethertype;
93} __attribute__ ((packed));
94
95struct ez_usb_fw {
96 u16 size;
97 const u8 *code;
98};
99
100static struct ez_usb_fw firmware = {
101 .size = 0,
102 .code = NULL,
103};
104
105#ifdef CONFIG_USB_DEBUG
106static int debug = 1;
107#else
108static int debug;
109#endif
110
111/* Debugging macros */
112#undef dbg
113#define dbg(format, arg...) \
114 do { if (debug) printk(KERN_DEBUG PFX "%s: " format "\n", \
115 __func__ , ## arg); } while (0)
116#undef err
117#define err(format, arg...) \
118 do { printk(KERN_ERR PFX format "\n", ## arg); } while (0)
119
120/* Module paramaters */
121module_param(debug, int, 0644);
122MODULE_PARM_DESC(debug, "Debug enabled or not");
123
124MODULE_FIRMWARE("orinoco_ezusb_fw");
125
126/*
127 * Under some conditions, the card gets stuck and stops paying attention
128 * to the world (i.e. data communication stalls) until we do something to
129 * it. Sending an INQ_TALLIES command seems to be enough and should be
130 * harmless otherwise. This behaviour has been observed when using the
131 * driver on a systemimager client during installation. In the past a
132 * timer was used to send INQ_TALLIES commands when there was no other
133 * activity, but it was troublesome and was removed.
134 */
135
136#define USB_COMPAQ_VENDOR_ID 0x049f /* Compaq Computer Corp. */
137#define USB_COMPAQ_WL215_ID 0x001f /* Compaq WL215 USB Adapter */
138#define USB_COMPAQ_W200_ID 0x0076 /* Compaq W200 USB Adapter */
139#define USB_HP_WL215_ID 0x0082 /* Compaq WL215 USB Adapter */
140
141#define USB_MELCO_VENDOR_ID 0x0411
142#define USB_BUFFALO_L11_ID 0x0006 /* BUFFALO WLI-USB-L11 */
143#define USB_BUFFALO_L11G_WR_ID 0x000B /* BUFFALO WLI-USB-L11G-WR */
144#define USB_BUFFALO_L11G_ID 0x000D /* BUFFALO WLI-USB-L11G */
145
146#define USB_LUCENT_VENDOR_ID 0x047E /* Lucent Technologies */
147#define USB_LUCENT_ORINOCO_ID 0x0300 /* Lucent/Agere Orinoco USB Client */
148
149#define USB_AVAYA8_VENDOR_ID 0x0D98
150#define USB_AVAYAE_VENDOR_ID 0x0D9E
151#define USB_AVAYA_WIRELESS_ID 0x0300 /* Avaya Wireless USB Card */
152
153#define USB_AGERE_VENDOR_ID 0x0D4E /* Agere Systems */
154#define USB_AGERE_MODEL0801_ID 0x1000 /* Wireless USB Card Model 0801 */
155#define USB_AGERE_MODEL0802_ID 0x1001 /* Wireless USB Card Model 0802 */
156#define USB_AGERE_REBRANDED_ID 0x047A /* WLAN USB Card */
157
158#define USB_ELSA_VENDOR_ID 0x05CC
159#define USB_ELSA_AIRLANCER_ID 0x3100 /* ELSA AirLancer USB-11 */
160
161#define USB_LEGEND_VENDOR_ID 0x0E7C
162#define USB_LEGEND_JOYNET_ID 0x0300 /* Joynet WLAN USB Card */
163
164#define USB_SAMSUNG_VENDOR_ID 0x04E8
165#define USB_SAMSUNG_SEW2001U1_ID 0x5002 /* Samsung SEW-2001u Card */
166#define USB_SAMSUNG_SEW2001U2_ID 0x5B11 /* Samsung SEW-2001u Card */
167#define USB_SAMSUNG_SEW2003U_ID 0x7011 /* Samsung SEW-2003U Card */
168
169#define USB_IGATE_VENDOR_ID 0x0681
170#define USB_IGATE_IGATE_11M_ID 0x0012 /* I-GATE 11M USB Card */
171
172#define USB_FUJITSU_VENDOR_ID 0x0BF8
173#define USB_FUJITSU_E1100_ID 0x1002 /* connect2AIR WLAN E-1100 USB */
174
175#define USB_2WIRE_VENDOR_ID 0x1630
176#define USB_2WIRE_WIRELESS_ID 0xff81 /* 2Wire Wireless USB adapter */
177
178
179#define EZUSB_REQUEST_FW_TRANS 0xA0
180#define EZUSB_REQUEST_TRIGER 0xAA
181#define EZUSB_REQUEST_TRIG_AC 0xAC
182#define EZUSB_CPUCS_REG 0x7F92
183
184#define EZUSB_RID_TX 0x0700
185#define EZUSB_RID_RX 0x0701
186#define EZUSB_RID_INIT1 0x0702
187#define EZUSB_RID_ACK 0x0710
188#define EZUSB_RID_READ_PDA 0x0800
189#define EZUSB_RID_PROG_INIT 0x0852
190#define EZUSB_RID_PROG_SET_ADDR 0x0853
191#define EZUSB_RID_PROG_BYTES 0x0854
192#define EZUSB_RID_PROG_END 0x0855
193#define EZUSB_RID_DOCMD 0x0860
194
195/* Recognize info frames */
196#define EZUSB_IS_INFO(id) ((id >= 0xF000) && (id <= 0xF2FF))
197
198#define EZUSB_MAGIC 0x0210
199
200#define EZUSB_FRAME_DATA 1
201#define EZUSB_FRAME_CONTROL 2
202
203#define DEF_TIMEOUT (3*HZ)
204
205#define BULK_BUF_SIZE 2048
206
207#define MAX_DL_SIZE (BULK_BUF_SIZE - sizeof(struct ezusb_packet))
208
209#define FW_BUF_SIZE 64
210#define FW_VAR_OFFSET_PTR 0x359
211#define FW_VAR_VALUE 0
212#define FW_HOLE_START 0x100
213#define FW_HOLE_END 0x300
214
215struct ezusb_packet {
216 __le16 magic; /* 0x0210 */
217 u8 req_reply_count;
218 u8 ans_reply_count;
219 __le16 frame_type; /* 0x01 for data frames, 0x02 otherwise */
220 __le16 size; /* transport size */
221 __le16 crc; /* CRC up to here */
222 __le16 hermes_len;
223 __le16 hermes_rid;
224 u8 data[0];
225} __attribute__ ((packed));
226
227/* Table of devices that work or may work with this driver */
228static struct usb_device_id ezusb_table[] = {
229 {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_WL215_ID)},
230 {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_HP_WL215_ID)},
231 {USB_DEVICE(USB_COMPAQ_VENDOR_ID, USB_COMPAQ_W200_ID)},
232 {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11_ID)},
233 {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11G_WR_ID)},
234 {USB_DEVICE(USB_MELCO_VENDOR_ID, USB_BUFFALO_L11G_ID)},
235 {USB_DEVICE(USB_LUCENT_VENDOR_ID, USB_LUCENT_ORINOCO_ID)},
236 {USB_DEVICE(USB_AVAYA8_VENDOR_ID, USB_AVAYA_WIRELESS_ID)},
237 {USB_DEVICE(USB_AVAYAE_VENDOR_ID, USB_AVAYA_WIRELESS_ID)},
238 {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_MODEL0801_ID)},
239 {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_MODEL0802_ID)},
240 {USB_DEVICE(USB_ELSA_VENDOR_ID, USB_ELSA_AIRLANCER_ID)},
241 {USB_DEVICE(USB_LEGEND_VENDOR_ID, USB_LEGEND_JOYNET_ID)},
242 {USB_DEVICE_VER(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2001U1_ID,
243 0, 0)},
244 {USB_DEVICE(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2001U2_ID)},
245 {USB_DEVICE(USB_SAMSUNG_VENDOR_ID, USB_SAMSUNG_SEW2003U_ID)},
246 {USB_DEVICE(USB_IGATE_VENDOR_ID, USB_IGATE_IGATE_11M_ID)},
247 {USB_DEVICE(USB_FUJITSU_VENDOR_ID, USB_FUJITSU_E1100_ID)},
248 {USB_DEVICE(USB_2WIRE_VENDOR_ID, USB_2WIRE_WIRELESS_ID)},
249 {USB_DEVICE(USB_AGERE_VENDOR_ID, USB_AGERE_REBRANDED_ID)},
250 {} /* Terminating entry */
251};
252
253MODULE_DEVICE_TABLE(usb, ezusb_table);
254
255/* Structure to hold all of our device specific stuff */
256struct ezusb_priv {
257 struct usb_device *udev;
258 struct net_device *dev;
259 struct mutex mtx;
260 spinlock_t req_lock;
261 struct list_head req_pending;
262 struct list_head req_active;
263 spinlock_t reply_count_lock;
264 u16 hermes_reg_fake[0x40];
265 u8 *bap_buf;
266 struct urb *read_urb;
267 int read_pipe;
268 int write_pipe;
269 u8 reply_count;
270};
271
272enum ezusb_state {
273 EZUSB_CTX_START,
274 EZUSB_CTX_QUEUED,
275 EZUSB_CTX_REQ_SUBMITTED,
276 EZUSB_CTX_REQ_COMPLETE,
277 EZUSB_CTX_RESP_RECEIVED,
278 EZUSB_CTX_REQ_TIMEOUT,
279 EZUSB_CTX_REQ_FAILED,
280 EZUSB_CTX_RESP_TIMEOUT,
281 EZUSB_CTX_REQSUBMIT_FAIL,
282 EZUSB_CTX_COMPLETE,
283};
284
285struct request_context {
286 struct list_head list;
287 atomic_t refcount;
288 struct completion done; /* Signals that CTX is dead */
289 int killed;
290 struct urb *outurb; /* OUT for req pkt */
291 struct ezusb_priv *upriv;
292 struct ezusb_packet *buf;
293 int buf_length;
294 struct timer_list timer; /* Timeout handling */
295 enum ezusb_state state; /* Current state */
296 /* the RID that we will wait for */
297 u16 out_rid;
298 u16 in_rid;
299};
300
301
302/* Forward declarations */
303static void ezusb_ctx_complete(struct request_context *ctx);
304static void ezusb_req_queue_run(struct ezusb_priv *upriv);
305static void ezusb_bulk_in_callback(struct urb *urb);
306
307static inline u8 ezusb_reply_inc(u8 count)
308{
309 if (count < 0x7F)
310 return count + 1;
311 else
312 return 1;
313}
314
315static void ezusb_request_context_put(struct request_context *ctx)
316{
317 if (!atomic_dec_and_test(&ctx->refcount))
318 return;
319
320 WARN_ON(!ctx->done.done);
321 BUG_ON(ctx->outurb->status == -EINPROGRESS);
322 BUG_ON(timer_pending(&ctx->timer));
323 usb_free_urb(ctx->outurb);
324 kfree(ctx->buf);
325 kfree(ctx);
326}
327
328static inline void ezusb_mod_timer(struct ezusb_priv *upriv,
329 struct timer_list *timer,
330 unsigned long expire)
331{
332 if (!upriv->udev)
333 return;
334 mod_timer(timer, expire);
335}
336
337static void ezusb_request_timerfn(u_long _ctx)
338{
339 struct request_context *ctx = (void *) _ctx;
340
341 ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK;
342 if (usb_unlink_urb(ctx->outurb) == -EINPROGRESS) {
343 ctx->state = EZUSB_CTX_REQ_TIMEOUT;
344 } else {
345 ctx->state = EZUSB_CTX_RESP_TIMEOUT;
346 dbg("couldn't unlink");
347 atomic_inc(&ctx->refcount);
348 ctx->killed = 1;
349 ezusb_ctx_complete(ctx);
350 ezusb_request_context_put(ctx);
351 }
352};
353
354static struct request_context *ezusb_alloc_ctx(struct ezusb_priv *upriv,
355 u16 out_rid, u16 in_rid)
356{
357 struct request_context *ctx;
358
359 ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
360 if (!ctx)
361 return NULL;
362
363 memset(ctx, 0, sizeof(*ctx));
364
365 ctx->buf = kmalloc(BULK_BUF_SIZE, GFP_ATOMIC);
366 if (!ctx->buf) {
367 kfree(ctx);
368 return NULL;
369 }
370 ctx->outurb = usb_alloc_urb(0, GFP_ATOMIC);
371 if (!ctx->outurb) {
372 kfree(ctx->buf);
373 kfree(ctx);
374 return NULL;
375 }
376
377 ctx->upriv = upriv;
378 ctx->state = EZUSB_CTX_START;
379 ctx->out_rid = out_rid;
380 ctx->in_rid = in_rid;
381
382 atomic_set(&ctx->refcount, 1);
383 init_completion(&ctx->done);
384
385 init_timer(&ctx->timer);
386 ctx->timer.function = ezusb_request_timerfn;
387 ctx->timer.data = (u_long) ctx;
388 return ctx;
389}
390
391
392/* Hopefully the real complete_all will soon be exported, in the mean
393 * while this should work. */
394static inline void ezusb_complete_all(struct completion *comp)
395{
396 complete(comp);
397 complete(comp);
398 complete(comp);
399 complete(comp);
400}
401
402static void ezusb_ctx_complete(struct request_context *ctx)
403{
404 struct ezusb_priv *upriv = ctx->upriv;
405 unsigned long flags;
406
407 spin_lock_irqsave(&upriv->req_lock, flags);
408
409 list_del_init(&ctx->list);
410 if (upriv->udev) {
411 spin_unlock_irqrestore(&upriv->req_lock, flags);
412 ezusb_req_queue_run(upriv);
413 spin_lock_irqsave(&upriv->req_lock, flags);
414 }
415
416 switch (ctx->state) {
417 case EZUSB_CTX_COMPLETE:
418 case EZUSB_CTX_REQSUBMIT_FAIL:
419 case EZUSB_CTX_REQ_FAILED:
420 case EZUSB_CTX_REQ_TIMEOUT:
421 case EZUSB_CTX_RESP_TIMEOUT:
422 spin_unlock_irqrestore(&upriv->req_lock, flags);
423
424 if ((ctx->out_rid == EZUSB_RID_TX) && upriv->dev) {
425 struct net_device *dev = upriv->dev;
426 struct orinoco_private *priv = ndev_priv(dev);
427 struct net_device_stats *stats = &priv->stats;
428
429 if (ctx->state != EZUSB_CTX_COMPLETE)
430 stats->tx_errors++;
431 else
432 stats->tx_packets++;
433
434 netif_wake_queue(dev);
435 }
436 ezusb_complete_all(&ctx->done);
437 ezusb_request_context_put(ctx);
438 break;
439
440 default:
441 spin_unlock_irqrestore(&upriv->req_lock, flags);
442 if (!upriv->udev) {
443 /* This is normal, as all request contexts get flushed
444 * when the device is disconnected */
445 err("Called, CTX not terminating, but device gone");
446 ezusb_complete_all(&ctx->done);
447 ezusb_request_context_put(ctx);
448 break;
449 }
450
451 err("Called, CTX not in terminating state.");
452 /* Things are really bad if this happens. Just leak
453 * the CTX because it may still be linked to the
454 * queue or the OUT urb may still be active.
455 * Just leaking at least prevents an Oops or Panic.
456 */
457 break;
458 }
459}
460
461/**
462 * ezusb_req_queue_run:
463 * Description:
464 * Note: Only one active CTX at any one time, because there's no
465 * other (reliable) way to match the response URB to the correct
466 * CTX.
467 **/
468static void ezusb_req_queue_run(struct ezusb_priv *upriv)
469{
470 unsigned long flags;
471 struct request_context *ctx;
472 int result;
473
474 spin_lock_irqsave(&upriv->req_lock, flags);
475
476 if (!list_empty(&upriv->req_active))
477 goto unlock;
478
479 if (list_empty(&upriv->req_pending))
480 goto unlock;
481
482 ctx =
483 list_entry(upriv->req_pending.next, struct request_context,
484 list);
485
486 if (!ctx->upriv->udev)
487 goto unlock;
488
489 /* We need to split this off to avoid a race condition */
490 list_move_tail(&ctx->list, &upriv->req_active);
491
492 if (ctx->state == EZUSB_CTX_QUEUED) {
493 atomic_inc(&ctx->refcount);
494 result = usb_submit_urb(ctx->outurb, GFP_ATOMIC);
495 if (result) {
496 ctx->state = EZUSB_CTX_REQSUBMIT_FAIL;
497
498 spin_unlock_irqrestore(&upriv->req_lock, flags);
499
500 err("Fatal, failed to submit command urb."
501 " error=%d\n", result);
502
503 ezusb_ctx_complete(ctx);
504 ezusb_request_context_put(ctx);
505 goto done;
506 }
507
508 ctx->state = EZUSB_CTX_REQ_SUBMITTED;
509 ezusb_mod_timer(ctx->upriv, &ctx->timer,
510 jiffies + DEF_TIMEOUT);
511 }
512
513 unlock:
514 spin_unlock_irqrestore(&upriv->req_lock, flags);
515
516 done:
517 return;
518}
519
520static void ezusb_req_enqueue_run(struct ezusb_priv *upriv,
521 struct request_context *ctx)
522{
523 unsigned long flags;
524
525 spin_lock_irqsave(&upriv->req_lock, flags);
526
527 if (!ctx->upriv->udev) {
528 spin_unlock_irqrestore(&upriv->req_lock, flags);
529 goto done;
530 }
531 atomic_inc(&ctx->refcount);
532 list_add_tail(&ctx->list, &upriv->req_pending);
533 spin_unlock_irqrestore(&upriv->req_lock, flags);
534
535 ctx->state = EZUSB_CTX_QUEUED;
536 ezusb_req_queue_run(upriv);
537
538 done:
539 return;
540}
541
542static void ezusb_request_out_callback(struct urb *urb)
543{
544 unsigned long flags;
545 enum ezusb_state state;
546 struct request_context *ctx = urb->context;
547 struct ezusb_priv *upriv = ctx->upriv;
548
549 spin_lock_irqsave(&upriv->req_lock, flags);
550
551 del_timer(&ctx->timer);
552
553 if (ctx->killed) {
554 spin_unlock_irqrestore(&upriv->req_lock, flags);
555 pr_warning("interrupt called with dead ctx");
556 goto out;
557 }
558
559 state = ctx->state;
560
561 if (urb->status == 0) {
562 switch (state) {
563 case EZUSB_CTX_REQ_SUBMITTED:
564 if (ctx->in_rid) {
565 ctx->state = EZUSB_CTX_REQ_COMPLETE;
566 /* reply URB still pending */
567 ezusb_mod_timer(upriv, &ctx->timer,
568 jiffies + DEF_TIMEOUT);
569 spin_unlock_irqrestore(&upriv->req_lock,
570 flags);
571 break;
572 }
573 /* fall through */
574 case EZUSB_CTX_RESP_RECEIVED:
575 /* IN already received before this OUT-ACK */
576 ctx->state = EZUSB_CTX_COMPLETE;
577 spin_unlock_irqrestore(&upriv->req_lock, flags);
578 ezusb_ctx_complete(ctx);
579 break;
580
581 default:
582 spin_unlock_irqrestore(&upriv->req_lock, flags);
583 err("Unexpected state(0x%x, %d) in OUT URB",
584 state, urb->status);
585 break;
586 }
587 } else {
588 /* If someone cancels the OUT URB then its status
589 * should be either -ECONNRESET or -ENOENT.
590 */
591 switch (state) {
592 case EZUSB_CTX_REQ_SUBMITTED:
593 case EZUSB_CTX_RESP_RECEIVED:
594 ctx->state = EZUSB_CTX_REQ_FAILED;
595 /* fall through */
596
597 case EZUSB_CTX_REQ_FAILED:
598 case EZUSB_CTX_REQ_TIMEOUT:
599 spin_unlock_irqrestore(&upriv->req_lock, flags);
600
601 ezusb_ctx_complete(ctx);
602 break;
603
604 default:
605 spin_unlock_irqrestore(&upriv->req_lock, flags);
606
607 err("Unexpected state(0x%x, %d) in OUT URB",
608 state, urb->status);
609 break;
610 }
611 }
612 out:
613 ezusb_request_context_put(ctx);
614}
615
616static void ezusb_request_in_callback(struct ezusb_priv *upriv,
617 struct urb *urb)
618{
619 struct ezusb_packet *ans = urb->transfer_buffer;
620 struct request_context *ctx = NULL;
621 enum ezusb_state state;
622 unsigned long flags;
623
624 /* Find the CTX on the active queue that requested this URB */
625 spin_lock_irqsave(&upriv->req_lock, flags);
626 if (upriv->udev) {
627 struct list_head *item;
628
629 list_for_each(item, &upriv->req_active) {
630 struct request_context *c;
631 int reply_count;
632
633 c = list_entry(item, struct request_context, list);
634 reply_count =
635 ezusb_reply_inc(c->buf->req_reply_count);
636 if ((ans->ans_reply_count == reply_count)
637 && (le16_to_cpu(ans->hermes_rid) == c->in_rid)) {
638 ctx = c;
639 break;
640 }
641 dbg("Skipped (0x%x/0x%x) (%d/%d)",
642 le16_to_cpu(ans->hermes_rid),
643 c->in_rid, ans->ans_reply_count, reply_count);
644 }
645 }
646
647 if (ctx == NULL) {
648 spin_unlock_irqrestore(&upriv->req_lock, flags);
649 err("%s: got unexpected RID: 0x%04X", __func__,
650 le16_to_cpu(ans->hermes_rid));
651 ezusb_req_queue_run(upriv);
652 return;
653 }
654
655 /* The data we want is in the in buffer, exchange */
656 urb->transfer_buffer = ctx->buf;
657 ctx->buf = (void *) ans;
658 ctx->buf_length = urb->actual_length;
659
660 state = ctx->state;
661 switch (state) {
662 case EZUSB_CTX_REQ_SUBMITTED:
663 /* We have received our response URB before
664 * our request has been acknowledged. Do NOT
665 * destroy our CTX yet, because our OUT URB
666 * is still alive ...
667 */
668 ctx->state = EZUSB_CTX_RESP_RECEIVED;
669 spin_unlock_irqrestore(&upriv->req_lock, flags);
670
671 /* Let the machine continue running. */
672 break;
673
674 case EZUSB_CTX_REQ_COMPLETE:
675 /* This is the usual path: our request
676 * has already been acknowledged, and
677 * we have now received the reply.
678 */
679 ctx->state = EZUSB_CTX_COMPLETE;
680
681 /* Stop the intimer */
682 del_timer(&ctx->timer);
683 spin_unlock_irqrestore(&upriv->req_lock, flags);
684
685 /* Call the completion handler */
686 ezusb_ctx_complete(ctx);
687 break;
688
689 default:
690 spin_unlock_irqrestore(&upriv->req_lock, flags);
691
692 pr_warning("Matched IN URB, unexpected context state(0x%x)",
693 state);
694 /* Throw this CTX away and try submitting another */
695 del_timer(&ctx->timer);
696 ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK;
697 usb_unlink_urb(ctx->outurb);
698 ezusb_req_queue_run(upriv);
699 break;
700 } /* switch */
701}
702
703
704static void ezusb_req_ctx_wait(struct ezusb_priv *upriv,
705 struct request_context *ctx)
706{
707 switch (ctx->state) {
708 case EZUSB_CTX_QUEUED:
709 case EZUSB_CTX_REQ_SUBMITTED:
710 case EZUSB_CTX_REQ_COMPLETE:
711 case EZUSB_CTX_RESP_RECEIVED:
712 if (in_softirq()) {
713 /* If we get called from a timer, timeout timers don't
714 * get the chance to run themselves. So we make sure
715 * that we don't sleep for ever */
716 int msecs = DEF_TIMEOUT * (1000 / HZ);
717 while (!ctx->done.done && msecs--)
718 udelay(1000);
719 } else {
720 wait_event_interruptible(ctx->done.wait,
721 ctx->done.done);
722 }
723 break;
724 default:
725 /* Done or failed - nothing to wait for */
726 break;
727 }
728}
729
730static inline u16 build_crc(struct ezusb_packet *data)
731{
732 u16 crc = 0;
733 u8 *bytes = (u8 *)data;
734 int i;
735
736 for (i = 0; i < 8; i++)
737 crc = (crc << 1) + bytes[i];
738
739 return crc;
740}
741
742/**
743 * ezusb_fill_req:
744 *
745 * if data == NULL and length > 0 the data is assumed to be already in
746 * the target buffer and only the header is filled.
747 *
748 */
749static int ezusb_fill_req(struct ezusb_packet *req, u16 length, u16 rid,
750 const void *data, u16 frame_type, u8 reply_count)
751{
752 int total_size = sizeof(*req) + length;
753
754 BUG_ON(total_size > BULK_BUF_SIZE);
755
756 req->magic = cpu_to_le16(EZUSB_MAGIC);
757 req->req_reply_count = reply_count;
758 req->ans_reply_count = 0;
759 req->frame_type = cpu_to_le16(frame_type);
760 req->size = cpu_to_le16(length + 4);
761 req->crc = cpu_to_le16(build_crc(req));
762 req->hermes_len = cpu_to_le16(HERMES_BYTES_TO_RECLEN(length));
763 req->hermes_rid = cpu_to_le16(rid);
764 if (data)
765 memcpy(req->data, data, length);
766 return total_size;
767}
768
769static int ezusb_submit_in_urb(struct ezusb_priv *upriv)
770{
771 int retval = 0;
772 void *cur_buf = upriv->read_urb->transfer_buffer;
773
774 if (upriv->read_urb->status == -EINPROGRESS) {
775 dbg("urb busy, not resubmiting");
776 retval = -EBUSY;
777 goto exit;
778 }
779 usb_fill_bulk_urb(upriv->read_urb, upriv->udev, upriv->read_pipe,
780 cur_buf, BULK_BUF_SIZE,
781 ezusb_bulk_in_callback, upriv);
782 upriv->read_urb->transfer_flags = 0;
783 retval = usb_submit_urb(upriv->read_urb, GFP_ATOMIC);
784 if (retval)
785 err("%s submit failed %d", __func__, retval);
786
787 exit:
788 return retval;
789}
790
791static inline int ezusb_8051_cpucs(struct ezusb_priv *upriv, int reset)
792{
793 u8 res_val = reset; /* avoid argument promotion */
794
795 if (!upriv->udev) {
796 err("%s: !upriv->udev", __func__);
797 return -EFAULT;
798 }
799 return usb_control_msg(upriv->udev,
800 usb_sndctrlpipe(upriv->udev, 0),
801 EZUSB_REQUEST_FW_TRANS,
802 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
803 USB_DIR_OUT, EZUSB_CPUCS_REG, 0, &res_val,
804 sizeof(res_val), DEF_TIMEOUT);
805}
806
807static int ezusb_firmware_download(struct ezusb_priv *upriv,
808 struct ez_usb_fw *fw)
809{
810 u8 fw_buffer[FW_BUF_SIZE];
811 int retval, addr;
812 int variant_offset;
813
814 /*
815 * This byte is 1 and should be replaced with 0. The offset is
816 * 0x10AD in version 0.0.6. The byte in question should follow
817 * the end of the code pointed to by the jump in the beginning
818 * of the firmware. Also, it is read by code located at 0x358.
819 */
820 variant_offset = be16_to_cpup((__be16 *) &fw->code[FW_VAR_OFFSET_PTR]);
821 if (variant_offset >= fw->size) {
822 printk(KERN_ERR PFX "Invalid firmware variant offset: "
823 "0x%04x\n", variant_offset);
824 retval = -EINVAL;
825 goto fail;
826 }
827
828 retval = ezusb_8051_cpucs(upriv, 1);
829 if (retval < 0)
830 goto fail;
831 for (addr = 0; addr < fw->size; addr += FW_BUF_SIZE) {
832 /* 0x100-0x300 should be left alone, it contains card
833 * specific data, like USB enumeration information */
834 if ((addr >= FW_HOLE_START) && (addr < FW_HOLE_END))
835 continue;
836
837 memcpy(fw_buffer, &fw->code[addr], FW_BUF_SIZE);
838 if (variant_offset >= addr &&
839 variant_offset < addr + FW_BUF_SIZE) {
840 dbg("Patching card_variant byte at 0x%04X",
841 variant_offset);
842 fw_buffer[variant_offset - addr] = FW_VAR_VALUE;
843 }
844 retval = usb_control_msg(upriv->udev,
845 usb_sndctrlpipe(upriv->udev, 0),
846 EZUSB_REQUEST_FW_TRANS,
847 USB_TYPE_VENDOR | USB_RECIP_DEVICE
848 | USB_DIR_OUT,
849 addr, 0x0,
850 fw_buffer, FW_BUF_SIZE,
851 DEF_TIMEOUT);
852
853 if (retval < 0)
854 goto fail;
855 }
856 retval = ezusb_8051_cpucs(upriv, 0);
857 if (retval < 0)
858 goto fail;
859
860 goto exit;
861 fail:
862 printk(KERN_ERR PFX "Firmware download failed, error %d\n",
863 retval);
864 exit:
865 return retval;
866}
867
868static int ezusb_access_ltv(struct ezusb_priv *upriv,
869 struct request_context *ctx,
870 u16 length, const void *data, u16 frame_type,
871 void *ans_buff, int ans_size, u16 *ans_length)
872{
873 int req_size;
874 int retval = 0;
875 enum ezusb_state state;
876
877 BUG_ON(in_irq());
878
879 if (!upriv->udev) {
880 dbg("Device disconnected");
881 return -ENODEV;
882 }
883
884 if (upriv->read_urb->status != -EINPROGRESS)
885 err("%s: in urb not pending", __func__);
886
887 /* protect upriv->reply_count, guarantee sequential numbers */
888 spin_lock_bh(&upriv->reply_count_lock);
889 req_size = ezusb_fill_req(ctx->buf, length, ctx->out_rid, data,
890 frame_type, upriv->reply_count);
891 usb_fill_bulk_urb(ctx->outurb, upriv->udev, upriv->write_pipe,
892 ctx->buf, req_size,
893 ezusb_request_out_callback, ctx);
894
895 if (ctx->in_rid)
896 upriv->reply_count = ezusb_reply_inc(upriv->reply_count);
897
898 ezusb_req_enqueue_run(upriv, ctx);
899
900 spin_unlock_bh(&upriv->reply_count_lock);
901
902 if (ctx->in_rid)
903 ezusb_req_ctx_wait(upriv, ctx);
904
905 state = ctx->state;
906 switch (state) {
907 case EZUSB_CTX_COMPLETE:
908 retval = ctx->outurb->status;
909 break;
910
911 case EZUSB_CTX_QUEUED:
912 case EZUSB_CTX_REQ_SUBMITTED:
913 if (!ctx->in_rid)
914 break;
915 default:
916 err("%s: Unexpected context state %d", __func__,
917 state);
918 /* fall though */
919 case EZUSB_CTX_REQ_TIMEOUT:
920 case EZUSB_CTX_REQ_FAILED:
921 case EZUSB_CTX_RESP_TIMEOUT:
922 case EZUSB_CTX_REQSUBMIT_FAIL:
923 printk(KERN_ERR PFX "Access failed, resetting (state %d,"
924 " reply_count %d)\n", state, upriv->reply_count);
925 upriv->reply_count = 0;
926 if (state == EZUSB_CTX_REQ_TIMEOUT
927 || state == EZUSB_CTX_RESP_TIMEOUT) {
928 printk(KERN_ERR PFX "ctx timed out\n");
929 retval = -ETIMEDOUT;
930 } else {
931 printk(KERN_ERR PFX "ctx failed\n");
932 retval = -EFAULT;
933 }
934 goto exit;
935 break;
936 }
937 if (ctx->in_rid) {
938 struct ezusb_packet *ans = ctx->buf;
939 int exp_len;
940
941 if (ans->hermes_len != 0)
942 exp_len = le16_to_cpu(ans->hermes_len) * 2 + 12;
943 else
944 exp_len = 14;
945
946 if (exp_len != ctx->buf_length) {
947 err("%s: length mismatch for RID 0x%04x: "
948 "expected %d, got %d", __func__,
949 ctx->in_rid, exp_len, ctx->buf_length);
950 retval = -EIO;
951 goto exit;
952 }
953
954 if (ans_buff)
955 memcpy(ans_buff, ans->data,
956 min_t(int, exp_len, ans_size));
957 if (ans_length)
958 *ans_length = le16_to_cpu(ans->hermes_len);
959 }
960 exit:
961 ezusb_request_context_put(ctx);
962 return retval;
963}
964
965static int ezusb_write_ltv(hermes_t *hw, int bap, u16 rid,
966 u16 length, const void *data)
967{
968 struct ezusb_priv *upriv = hw->priv;
969 u16 frame_type;
970 struct request_context *ctx;
971
972 if (length == 0)
973 return -EINVAL;
974
975 length = HERMES_RECLEN_TO_BYTES(length);
976
977 /* On memory mapped devices HERMES_RID_CNFGROUPADDRESSES can be
978 * set to be empty, but the USB bridge doesn't like it */
979 if (length == 0)
980 return 0;
981
982 ctx = ezusb_alloc_ctx(upriv, rid, EZUSB_RID_ACK);
983 if (!ctx)
984 return -ENOMEM;
985
986 if (rid == EZUSB_RID_TX)
987 frame_type = EZUSB_FRAME_DATA;
988 else
989 frame_type = EZUSB_FRAME_CONTROL;
990
991 return ezusb_access_ltv(upriv, ctx, length, data, frame_type,
992 NULL, 0, NULL);
993}
994
995static int ezusb_read_ltv(hermes_t *hw, int bap, u16 rid,
996 unsigned bufsize, u16 *length, void *buf)
997{
998 struct ezusb_priv *upriv = hw->priv;
999 struct request_context *ctx;
1000
1001 if ((bufsize < 0) || (bufsize % 2))
1002 return -EINVAL;
1003
1004 ctx = ezusb_alloc_ctx(upriv, rid, rid);
1005 if (!ctx)
1006 return -ENOMEM;
1007
1008 return ezusb_access_ltv(upriv, ctx, 0, NULL, EZUSB_FRAME_CONTROL,
1009 buf, bufsize, length);
1010}
1011
1012static int ezusb_doicmd_wait(hermes_t *hw, u16 cmd, u16 parm0, u16 parm1,
1013 u16 parm2, struct hermes_response *resp)
1014{
1015 struct ezusb_priv *upriv = hw->priv;
1016 struct request_context *ctx;
1017
1018 __le16 data[4] = {
1019 cpu_to_le16(cmd),
1020 cpu_to_le16(parm0),
1021 cpu_to_le16(parm1),
1022 cpu_to_le16(parm2),
1023 };
1024 dbg("0x%04X, parm0 0x%04X, parm1 0x%04X, parm2 0x%04X",
1025 cmd, parm0, parm1, parm2);
1026 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_DOCMD, EZUSB_RID_ACK);
1027 if (!ctx)
1028 return -ENOMEM;
1029
1030 return ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1031 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1032}
1033
1034static int ezusb_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
1035 struct hermes_response *resp)
1036{
1037 struct ezusb_priv *upriv = hw->priv;
1038 struct request_context *ctx;
1039
1040 __le16 data[4] = {
1041 cpu_to_le16(cmd),
1042 cpu_to_le16(parm0),
1043 0,
1044 0,
1045 };
1046 dbg("0x%04X, parm0 0x%04X", cmd, parm0);
1047 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_DOCMD, EZUSB_RID_ACK);
1048 if (!ctx)
1049 return -ENOMEM;
1050
1051 return ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1052 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1053}
1054
1055static int ezusb_bap_pread(struct hermes *hw, int bap,
1056 void *buf, int len, u16 id, u16 offset)
1057{
1058 struct ezusb_priv *upriv = hw->priv;
1059 struct ezusb_packet *ans = (void *) upriv->read_urb->transfer_buffer;
1060 int actual_length = upriv->read_urb->actual_length;
1061
1062 if (id == EZUSB_RID_RX) {
1063 if ((sizeof(*ans) + offset + len) > actual_length) {
1064 printk(KERN_ERR PFX "BAP read beyond buffer end "
1065 "in rx frame\n");
1066 return -EINVAL;
1067 }
1068 memcpy(buf, ans->data + offset, len);
1069 return 0;
1070 }
1071
1072 if (EZUSB_IS_INFO(id)) {
1073 /* Include 4 bytes for length/type */
1074 if ((sizeof(*ans) + offset + len - 4) > actual_length) {
1075 printk(KERN_ERR PFX "BAP read beyond buffer end "
1076 "in info frame\n");
1077 return -EFAULT;
1078 }
1079 memcpy(buf, ans->data + offset - 4, len);
1080 } else {
1081 printk(KERN_ERR PFX "Unexpected fid 0x%04x\n", id);
1082 return -EINVAL;
1083 }
1084
1085 return 0;
1086}
1087
1088static int ezusb_read_pda(struct hermes *hw, __le16 *pda,
1089 u32 pda_addr, u16 pda_len)
1090{
1091 struct ezusb_priv *upriv = hw->priv;
1092 struct request_context *ctx;
1093 __le16 data[] = {
1094 cpu_to_le16(pda_addr & 0xffff),
1095 cpu_to_le16(pda_len - 4)
1096 };
1097 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_READ_PDA, EZUSB_RID_READ_PDA);
1098 if (!ctx)
1099 return -ENOMEM;
1100
1101 /* wl_lkm does not include PDA size in the PDA area.
1102 * We will pad the information into pda, so other routines
1103 * don't have to be modified */
1104 pda[0] = cpu_to_le16(pda_len - 2);
1105 /* Includes CFG_PROD_DATA but not itself */
1106 pda[1] = cpu_to_le16(0x0800); /* CFG_PROD_DATA */
1107
1108 return ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1109 EZUSB_FRAME_CONTROL, &pda[2], pda_len - 4,
1110 NULL);
1111}
1112
1113static int ezusb_program_init(struct hermes *hw, u32 entry_point)
1114{
1115 struct ezusb_priv *upriv = hw->priv;
1116 struct request_context *ctx;
1117 __le32 data = cpu_to_le32(entry_point);
1118
1119 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_INIT, EZUSB_RID_ACK);
1120 if (!ctx)
1121 return -ENOMEM;
1122
1123 return ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1124 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1125}
1126
1127static int ezusb_program_end(struct hermes *hw)
1128{
1129 struct ezusb_priv *upriv = hw->priv;
1130 struct request_context *ctx;
1131
1132 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_END, EZUSB_RID_ACK);
1133 if (!ctx)
1134 return -ENOMEM;
1135
1136 return ezusb_access_ltv(upriv, ctx, 0, NULL,
1137 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1138}
1139
1140static int ezusb_program_bytes(struct hermes *hw, const char *buf,
1141 u32 addr, u32 len)
1142{
1143 struct ezusb_priv *upriv = hw->priv;
1144 struct request_context *ctx;
1145 __le32 data = cpu_to_le32(addr);
1146 int err;
1147
1148 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_SET_ADDR, EZUSB_RID_ACK);
1149 if (!ctx)
1150 return -ENOMEM;
1151
1152 err = ezusb_access_ltv(upriv, ctx, sizeof(data), &data,
1153 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1154 if (err)
1155 return err;
1156
1157 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_PROG_BYTES, EZUSB_RID_ACK);
1158 if (!ctx)
1159 return -ENOMEM;
1160
1161 return ezusb_access_ltv(upriv, ctx, len, buf,
1162 EZUSB_FRAME_CONTROL, NULL, 0, NULL);
1163}
1164
1165static int ezusb_program(struct hermes *hw, const char *buf,
1166 u32 addr, u32 len)
1167{
1168 u32 ch_addr;
1169 u32 ch_len;
1170 int err = 0;
1171
1172 /* We can only send 2048 bytes out of the bulk xmit at a time,
1173 * so we have to split any programming into chunks of <2048
1174 * bytes. */
1175
1176 ch_len = (len < MAX_DL_SIZE) ? len : MAX_DL_SIZE;
1177 ch_addr = addr;
1178
1179 while (ch_addr < (addr + len)) {
1180 pr_debug("Programming subblock of length %d "
1181 "to address 0x%08x. Data @ %p\n",
1182 ch_len, ch_addr, &buf[ch_addr - addr]);
1183
1184 err = ezusb_program_bytes(hw, &buf[ch_addr - addr],
1185 ch_addr, ch_len);
1186 if (err)
1187 break;
1188
1189 ch_addr += ch_len;
1190 ch_len = ((addr + len - ch_addr) < MAX_DL_SIZE) ?
1191 (addr + len - ch_addr) : MAX_DL_SIZE;
1192 }
1193
1194 return err;
1195}
1196
1197static netdev_tx_t ezusb_xmit(struct sk_buff *skb, struct net_device *dev)
1198{
1199 struct orinoco_private *priv = ndev_priv(dev);
1200 struct net_device_stats *stats = &priv->stats;
1201 struct ezusb_priv *upriv = priv->card;
1202 u8 mic[MICHAEL_MIC_LEN+1];
1203 int err = 0;
1204 int tx_control;
1205 unsigned long flags;
1206 struct request_context *ctx;
1207 u8 *buf;
1208 int tx_size;
1209
1210 if (!netif_running(dev)) {
1211 printk(KERN_ERR "%s: Tx on stopped device!\n",
1212 dev->name);
1213 return NETDEV_TX_BUSY;
1214 }
1215
1216 if (netif_queue_stopped(dev)) {
1217 printk(KERN_DEBUG "%s: Tx while transmitter busy!\n",
1218 dev->name);
1219 return NETDEV_TX_BUSY;
1220 }
1221
1222 if (orinoco_lock(priv, &flags) != 0) {
1223 printk(KERN_ERR
1224 "%s: ezusb_xmit() called while hw_unavailable\n",
1225 dev->name);
1226 return NETDEV_TX_BUSY;
1227 }
1228
1229 if (!netif_carrier_ok(dev) ||
1230 (priv->iw_mode == NL80211_IFTYPE_MONITOR)) {
1231 /* Oops, the firmware hasn't established a connection,
1232 silently drop the packet (this seems to be the
1233 safest approach). */
1234 goto drop;
1235 }
1236
1237 /* Check packet length */
1238 if (skb->len < ETH_HLEN)
1239 goto drop;
1240
1241 ctx = ezusb_alloc_ctx(upriv, EZUSB_RID_TX, 0);
1242 if (!ctx)
1243 goto busy;
1244
1245 memset(ctx->buf, 0, BULK_BUF_SIZE);
1246 buf = ctx->buf->data;
1247
1248 tx_control = 0;
1249
1250 err = orinoco_process_xmit_skb(skb, dev, priv, &tx_control,
1251 &mic[0]);
1252 if (err)
1253 goto drop;
1254
1255 {
1256 __le16 *tx_cntl = (__le16 *)buf;
1257 *tx_cntl = cpu_to_le16(tx_control);
1258 buf += sizeof(*tx_cntl);
1259 }
1260
1261 memcpy(buf, skb->data, skb->len);
1262 buf += skb->len;
1263
1264 if (tx_control & HERMES_TXCTRL_MIC) {
1265 u8 *m = mic;
1266 /* Mic has been offset so it can be copied to an even
1267 * address. We're copying eveything anyway, so we
1268 * don't need to copy that first byte. */
1269 if (skb->len % 2)
1270 m++;
1271 memcpy(buf, m, MICHAEL_MIC_LEN);
1272 buf += MICHAEL_MIC_LEN;
1273 }
1274
1275 /* Finally, we actually initiate the send */
1276 netif_stop_queue(dev);
1277
1278 /* The card may behave better if we send evenly sized usb transfers */
1279 tx_size = ALIGN(buf - ctx->buf->data, 2);
1280
1281 err = ezusb_access_ltv(upriv, ctx, tx_size, NULL,
1282 EZUSB_FRAME_DATA, NULL, 0, NULL);
1283
1284 if (err) {
1285 netif_start_queue(dev);
1286 if (net_ratelimit())
1287 printk(KERN_ERR "%s: Error %d transmitting packet\n",
1288 dev->name, err);
1289 goto busy;
1290 }
1291
1292 dev->trans_start = jiffies;
1293 stats->tx_bytes += skb->len;
1294 goto ok;
1295
1296 drop:
1297 stats->tx_errors++;
1298 stats->tx_dropped++;
1299
1300 ok:
1301 orinoco_unlock(priv, &flags);
1302 dev_kfree_skb(skb);
1303 return NETDEV_TX_OK;
1304
1305 busy:
1306 orinoco_unlock(priv, &flags);
1307 return NETDEV_TX_BUSY;
1308}
1309
1310static int ezusb_allocate(struct hermes *hw, u16 size, u16 *fid)
1311{
1312 *fid = EZUSB_RID_TX;
1313 return 0;
1314}
1315
1316
1317static int ezusb_hard_reset(struct orinoco_private *priv)
1318{
1319 struct ezusb_priv *upriv = priv->card;
1320 int retval = ezusb_8051_cpucs(upriv, 1);
1321
1322 if (retval < 0) {
1323 err("Failed to reset");
1324 return retval;
1325 }
1326
1327 retval = ezusb_8051_cpucs(upriv, 0);
1328 if (retval < 0) {
1329 err("Failed to unreset");
1330 return retval;
1331 }
1332
1333 dbg("sending control message");
1334 retval = usb_control_msg(upriv->udev,
1335 usb_sndctrlpipe(upriv->udev, 0),
1336 EZUSB_REQUEST_TRIGER,
1337 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
1338 USB_DIR_OUT, 0x0, 0x0, NULL, 0,
1339 DEF_TIMEOUT);
1340 if (retval < 0) {
1341 err("EZUSB_REQUEST_TRIGER failed retval %d", retval);
1342 return retval;
1343 }
1344#if 0
1345 dbg("Sending EZUSB_REQUEST_TRIG_AC");
1346 retval = usb_control_msg(upriv->udev,
1347 usb_sndctrlpipe(upriv->udev, 0),
1348 EZUSB_REQUEST_TRIG_AC,
1349 USB_TYPE_VENDOR | USB_RECIP_DEVICE |
1350 USB_DIR_OUT, 0x00FA, 0x0, NULL, 0,
1351 DEF_TIMEOUT);
1352 if (retval < 0) {
1353 err("EZUSB_REQUEST_TRIG_AC failed retval %d", retval);
1354 return retval;
1355 }
1356#endif
1357
1358 return 0;
1359}
1360
1361
1362static int ezusb_init(hermes_t *hw)
1363{
1364 struct ezusb_priv *upriv = hw->priv;
1365 int retval;
1366
1367 BUG_ON(in_interrupt());
1368 BUG_ON(!upriv);
1369
1370 upriv->reply_count = 0;
1371 /* Write the MAGIC number on the simulated registers to keep
1372 * orinoco.c happy */
1373 hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
1374 hermes_write_regn(hw, RXFID, EZUSB_RID_RX);
1375
1376 usb_kill_urb(upriv->read_urb);
1377 ezusb_submit_in_urb(upriv);
1378
1379 retval = ezusb_write_ltv(hw, 0, EZUSB_RID_INIT1,
1380 HERMES_BYTES_TO_RECLEN(2), "\x10\x00");
1381 if (retval < 0) {
1382 printk(KERN_ERR PFX "EZUSB_RID_INIT1 error %d\n", retval);
1383 return retval;
1384 }
1385
1386 retval = ezusb_docmd_wait(hw, HERMES_CMD_INIT, 0, NULL);
1387 if (retval < 0) {
1388 printk(KERN_ERR PFX "HERMES_CMD_INIT error %d\n", retval);
1389 return retval;
1390 }
1391
1392 return 0;
1393}
1394
1395static void ezusb_bulk_in_callback(struct urb *urb)
1396{
1397 struct ezusb_priv *upriv = (struct ezusb_priv *) urb->context;
1398 struct ezusb_packet *ans = urb->transfer_buffer;
1399 u16 crc;
1400 u16 hermes_rid;
1401
1402 if (upriv->udev == NULL) {
1403 dbg("disconnected");
1404 return;
1405 }
1406
1407 if (urb->status == -ETIMEDOUT) {
1408 /* When a device gets unplugged we get this every time
1409 * we resubmit, flooding the logs. Since we don't use
1410 * USB timeouts, it shouldn't happen any other time*/
1411 pr_warning("%s: urb timed out, not resubmiting", __func__);
1412 return;
1413 }
1414 if (urb->status == -ECONNABORTED) {
1415 pr_warning("%s: connection abort, resubmiting urb",
1416 __func__);
1417 goto resubmit;
1418 }
1419 if ((urb->status == -EILSEQ)
1420 || (urb->status == -ENOENT)
1421 || (urb->status == -ECONNRESET)) {
1422 dbg("status %d, not resubmiting", urb->status);
1423 return;
1424 }
1425 if (urb->status)
1426 dbg("status: %d length: %d",
1427 urb->status, urb->actual_length);
1428 if (urb->actual_length < sizeof(*ans)) {
1429 err("%s: short read, ignoring", __func__);
1430 goto resubmit;
1431 }
1432 crc = build_crc(ans);
1433 if (le16_to_cpu(ans->crc) != crc) {
1434 err("CRC error, ignoring packet");
1435 goto resubmit;
1436 }
1437
1438 hermes_rid = le16_to_cpu(ans->hermes_rid);
1439 if ((hermes_rid != EZUSB_RID_RX) && !EZUSB_IS_INFO(hermes_rid)) {
1440 ezusb_request_in_callback(upriv, urb);
1441 } else if (upriv->dev) {
1442 struct net_device *dev = upriv->dev;
1443 struct orinoco_private *priv = ndev_priv(dev);
1444 hermes_t *hw = &priv->hw;
1445
1446 if (hermes_rid == EZUSB_RID_RX) {
1447 __orinoco_ev_rx(dev, hw);
1448 } else {
1449 hermes_write_regn(hw, INFOFID,
1450 le16_to_cpu(ans->hermes_rid));
1451 __orinoco_ev_info(dev, hw);
1452 }
1453 }
1454
1455 resubmit:
1456 if (upriv->udev)
1457 ezusb_submit_in_urb(upriv);
1458}
1459
1460static inline void ezusb_delete(struct ezusb_priv *upriv)
1461{
1462 struct net_device *dev;
1463 struct list_head *item;
1464 struct list_head *tmp_item;
1465 unsigned long flags;
1466
1467 BUG_ON(in_interrupt());
1468 BUG_ON(!upriv);
1469
1470 dev = upriv->dev;
1471 mutex_lock(&upriv->mtx);
1472
1473 upriv->udev = NULL; /* No timer will be rearmed from here */
1474
1475 usb_kill_urb(upriv->read_urb);
1476
1477 spin_lock_irqsave(&upriv->req_lock, flags);
1478 list_for_each_safe(item, tmp_item, &upriv->req_active) {
1479 struct request_context *ctx;
1480 int err;
1481
1482 ctx = list_entry(item, struct request_context, list);
1483 atomic_inc(&ctx->refcount);
1484
1485 ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK;
1486 err = usb_unlink_urb(ctx->outurb);
1487
1488 spin_unlock_irqrestore(&upriv->req_lock, flags);
1489 if (err == -EINPROGRESS)
1490 wait_for_completion(&ctx->done);
1491
1492 del_timer_sync(&ctx->timer);
1493 /* FIXME: there is an slight chance for the irq handler to
1494 * be running */
1495 if (!list_empty(&ctx->list))
1496 ezusb_ctx_complete(ctx);
1497
1498 ezusb_request_context_put(ctx);
1499 spin_lock_irqsave(&upriv->req_lock, flags);
1500 }
1501 spin_unlock_irqrestore(&upriv->req_lock, flags);
1502
1503 list_for_each_safe(item, tmp_item, &upriv->req_pending)
1504 ezusb_ctx_complete(list_entry(item,
1505 struct request_context, list));
1506
1507 if (upriv->read_urb->status == -EINPROGRESS)
1508 printk(KERN_ERR PFX "Some URB in progress\n");
1509
1510 mutex_unlock(&upriv->mtx);
1511
1512 kfree(upriv->read_urb->transfer_buffer);
1513 if (upriv->bap_buf != NULL)
1514 kfree(upriv->bap_buf);
1515 if (upriv->read_urb != NULL)
1516 usb_free_urb(upriv->read_urb);
1517 if (upriv->dev) {
1518 struct orinoco_private *priv = ndev_priv(upriv->dev);
1519 orinoco_if_del(priv);
1520 free_orinocodev(priv);
1521 }
1522}
1523
1524static void ezusb_lock_irqsave(spinlock_t *lock,
1525 unsigned long *flags) __acquires(lock)
1526{
1527 spin_lock_bh(lock);
1528}
1529
1530static void ezusb_unlock_irqrestore(spinlock_t *lock,
1531 unsigned long *flags) __releases(lock)
1532{
1533 spin_unlock_bh(lock);
1534}
1535
1536static void ezusb_lock_irq(spinlock_t *lock) __acquires(lock)
1537{
1538 spin_lock_bh(lock);
1539}
1540
1541static void ezusb_unlock_irq(spinlock_t *lock) __releases(lock)
1542{
1543 spin_unlock_bh(lock);
1544}
1545
1546static const struct hermes_ops ezusb_ops = {
1547 .init = ezusb_init,
1548 .cmd_wait = ezusb_docmd_wait,
1549 .init_cmd_wait = ezusb_doicmd_wait,
1550 .allocate = ezusb_allocate,
1551 .read_ltv = ezusb_read_ltv,
1552 .write_ltv = ezusb_write_ltv,
1553 .bap_pread = ezusb_bap_pread,
1554 .read_pda = ezusb_read_pda,
1555 .program_init = ezusb_program_init,
1556 .program_end = ezusb_program_end,
1557 .program = ezusb_program,
1558 .lock_irqsave = ezusb_lock_irqsave,
1559 .unlock_irqrestore = ezusb_unlock_irqrestore,
1560 .lock_irq = ezusb_lock_irq,
1561 .unlock_irq = ezusb_unlock_irq,
1562};
1563
1564static const struct net_device_ops ezusb_netdev_ops = {
1565 .ndo_open = orinoco_open,
1566 .ndo_stop = orinoco_stop,
1567 .ndo_start_xmit = ezusb_xmit,
1568 .ndo_set_multicast_list = orinoco_set_multicast_list,
1569 .ndo_change_mtu = orinoco_change_mtu,
1570 .ndo_set_mac_address = eth_mac_addr,
1571 .ndo_validate_addr = eth_validate_addr,
1572 .ndo_tx_timeout = orinoco_tx_timeout,
1573 .ndo_get_stats = orinoco_get_stats,
1574};
1575
1576static int ezusb_probe(struct usb_interface *interface,
1577 const struct usb_device_id *id)
1578{
1579 struct usb_device *udev = interface_to_usbdev(interface);
1580 struct orinoco_private *priv;
1581 hermes_t *hw;
1582 struct ezusb_priv *upriv = NULL;
1583 struct usb_interface_descriptor *iface_desc;
1584 struct usb_endpoint_descriptor *ep;
1585 const struct firmware *fw_entry;
1586 int retval = 0;
1587 int i;
1588
1589 priv = alloc_orinocodev(sizeof(*upriv), &udev->dev,
1590 ezusb_hard_reset, NULL);
1591 if (!priv) {
1592 err("Couldn't allocate orinocodev");
1593 goto exit;
1594 }
1595
1596 hw = &priv->hw;
1597
1598 upriv = priv->card;
1599
1600 mutex_init(&upriv->mtx);
1601 spin_lock_init(&upriv->reply_count_lock);
1602
1603 spin_lock_init(&upriv->req_lock);
1604 INIT_LIST_HEAD(&upriv->req_pending);
1605 INIT_LIST_HEAD(&upriv->req_active);
1606
1607 upriv->udev = udev;
1608
1609 hw->iobase = (void __force __iomem *) &upriv->hermes_reg_fake;
1610 hw->reg_spacing = HERMES_16BIT_REGSPACING;
1611 hw->priv = upriv;
1612 hw->ops = &ezusb_ops;
1613
1614 /* set up the endpoint information */
1615 /* check out the endpoints */
1616
1617 iface_desc = &interface->altsetting[0].desc;
1618 for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
1619 ep = &interface->altsetting[0].endpoint[i].desc;
1620
1621 if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
1622 == USB_DIR_IN) &&
1623 ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
1624 == USB_ENDPOINT_XFER_BULK)) {
1625 /* we found a bulk in endpoint */
1626 if (upriv->read_urb != NULL) {
1627 pr_warning("Found a second bulk in ep, ignored");
1628 continue;
1629 }
1630
1631 upriv->read_urb = usb_alloc_urb(0, GFP_KERNEL);
1632 if (!upriv->read_urb) {
1633 err("No free urbs available");
1634 goto error;
1635 }
1636 if (le16_to_cpu(ep->wMaxPacketSize) != 64)
1637 pr_warning("bulk in: wMaxPacketSize!= 64");
1638 if (ep->bEndpointAddress != (2 | USB_DIR_IN))
1639 pr_warning("bulk in: bEndpointAddress: %d",
1640 ep->bEndpointAddress);
1641 upriv->read_pipe = usb_rcvbulkpipe(udev,
1642 ep->
1643 bEndpointAddress);
1644 upriv->read_urb->transfer_buffer =
1645 kmalloc(BULK_BUF_SIZE, GFP_KERNEL);
1646 if (!upriv->read_urb->transfer_buffer) {
1647 err("Couldn't allocate IN buffer");
1648 goto error;
1649 }
1650 }
1651
1652 if (((ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
1653 == USB_DIR_OUT) &&
1654 ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
1655 == USB_ENDPOINT_XFER_BULK)) {
1656 /* we found a bulk out endpoint */
1657 if (upriv->bap_buf != NULL) {
1658 pr_warning("Found a second bulk out ep, ignored");
1659 continue;
1660 }
1661
1662 if (le16_to_cpu(ep->wMaxPacketSize) != 64)
1663 pr_warning("bulk out: wMaxPacketSize != 64");
1664 if (ep->bEndpointAddress != 2)
1665 pr_warning("bulk out: bEndpointAddress: %d",
1666 ep->bEndpointAddress);
1667 upriv->write_pipe = usb_sndbulkpipe(udev,
1668 ep->
1669 bEndpointAddress);
1670 upriv->bap_buf = kmalloc(BULK_BUF_SIZE, GFP_KERNEL);
1671 if (!upriv->bap_buf) {
1672 err("Couldn't allocate bulk_out_buffer");
1673 goto error;
1674 }
1675 }
1676 }
1677 if (!upriv->bap_buf || !upriv->read_urb) {
1678 err("Didn't find the required bulk endpoints");
1679 goto error;
1680 }
1681
1682 if (request_firmware(&fw_entry, "orinoco_ezusb_fw",
1683 &interface->dev) == 0) {
1684 firmware.size = fw_entry->size;
1685 firmware.code = fw_entry->data;
1686 }
1687 if (firmware.size && firmware.code) {
1688 ezusb_firmware_download(upriv, &firmware);
1689 } else {
1690 err("No firmware to download");
1691 goto error;
1692 }
1693
1694 if (ezusb_hard_reset(priv) < 0) {
1695 err("Cannot reset the device");
1696 goto error;
1697 }
1698
1699 /* If the firmware is already downloaded orinoco.c will call
1700 * ezusb_init but if the firmware is not already there, that will make
1701 * the kernel very unstable, so we try initializing here and quit in
1702 * case of error */
1703 if (ezusb_init(hw) < 0) {
1704 err("Couldn't initialize the device");
1705 err("Firmware may not be downloaded or may be wrong.");
1706 goto error;
1707 }
1708
1709 /* Initialise the main driver */
1710 if (orinoco_init(priv) != 0) {
1711 err("orinoco_init() failed\n");
1712 goto error;
1713 }
1714
1715 if (orinoco_if_add(priv, 0, 0, &ezusb_netdev_ops) != 0) {
1716 upriv->dev = NULL;
1717 err("%s: orinoco_if_add() failed", __func__);
1718 goto error;
1719 }
1720 upriv->dev = priv->ndev;
1721
1722 goto exit;
1723
1724 error:
1725 ezusb_delete(upriv);
1726 if (upriv->dev) {
1727 /* upriv->dev was 0, so ezusb_delete() didn't free it */
1728 free_orinocodev(priv);
1729 }
1730 upriv = NULL;
1731 retval = -EFAULT;
1732 exit:
1733 if (fw_entry) {
1734 firmware.code = NULL;
1735 firmware.size = 0;
1736 release_firmware(fw_entry);
1737 }
1738 usb_set_intfdata(interface, upriv);
1739 return retval;
1740}
1741
1742
1743static void ezusb_disconnect(struct usb_interface *intf)
1744{
1745 struct ezusb_priv *upriv = usb_get_intfdata(intf);
1746 usb_set_intfdata(intf, NULL);
1747 ezusb_delete(upriv);
1748 printk(KERN_INFO PFX "Disconnected\n");
1749}
1750
1751
1752/* usb specific object needed to register this driver with the usb subsystem */
1753static struct usb_driver orinoco_driver = {
1754 .name = DRIVER_NAME,
1755 .probe = ezusb_probe,
1756 .disconnect = ezusb_disconnect,
1757 .id_table = ezusb_table,
1758};
1759
1760/* Can't be declared "const" or the whole __initdata section will
1761 * become const */
1762static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
1763 " (Manuel Estrada Sainz)";
1764
1765static int __init ezusb_module_init(void)
1766{
1767 int err;
1768
1769 printk(KERN_DEBUG "%s\n", version);
1770
1771 /* register this driver with the USB subsystem */
1772 err = usb_register(&orinoco_driver);
1773 if (err < 0) {
1774 printk(KERN_ERR PFX "usb_register failed, error %d\n",
1775 err);
1776 return err;
1777 }
1778
1779 return 0;
1780}
1781
1782static void __exit ezusb_module_exit(void)
1783{
1784 /* deregister this driver with the USB subsystem */
1785 usb_deregister(&orinoco_driver);
1786}
1787
1788
1789module_init(ezusb_module_init);
1790module_exit(ezusb_module_exit);
1791
1792MODULE_AUTHOR("Manuel Estrada Sainz");
1793MODULE_DESCRIPTION
1794 ("Driver for Orinoco wireless LAN cards using EZUSB bridge");
1795MODULE_LICENSE("Dual MPL/GPL");
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c
index 330d42d45333..4300d9db7d8c 100644
--- a/drivers/net/wireless/orinoco/scan.c
+++ b/drivers/net/wireless/orinoco/scan.c
@@ -127,7 +127,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
127{ 127{
128 struct wiphy *wiphy = priv_to_wiphy(priv); 128 struct wiphy *wiphy = priv_to_wiphy(priv);
129 struct ieee80211_channel *channel; 129 struct ieee80211_channel *channel;
130 u8 *ie; 130 const u8 *ie;
131 u64 timestamp; 131 u64 timestamp;
132 s32 signal; 132 s32 signal;
133 u16 capability; 133 u16 capability;
@@ -136,7 +136,7 @@ void orinoco_add_extscan_result(struct orinoco_private *priv,
136 int chan, freq; 136 int chan, freq;
137 137
138 ie_len = len - sizeof(*bss); 138 ie_len = len - sizeof(*bss);
139 ie = orinoco_get_ie(bss->data, ie_len, WLAN_EID_DS_PARAMS); 139 ie = cfg80211_find_ie(WLAN_EID_DS_PARAMS, bss->data, ie_len);
140 chan = ie ? ie[2] : 0; 140 chan = ie ? ie[2] : 0;
141 freq = ieee80211_dsss_chan_to_freq(chan); 141 freq = ieee80211_dsss_chan_to_freq(chan);
142 channel = ieee80211_get_channel(wiphy, freq); 142 channel = ieee80211_get_channel(wiphy, freq);
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c
index 41b9ce425855..b51a9adc80f6 100644
--- a/drivers/net/wireless/orinoco/spectrum_cs.c
+++ b/drivers/net/wireless/orinoco/spectrum_cs.c
@@ -337,6 +337,7 @@ spectrum_cs_config(struct pcmcia_device *link)
337 goto failed; 337 goto failed;
338 338
339 hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); 339 hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
340 hw->eeprom_pda = true;
340 341
341 /* 342 /*
342 * This actually configures the PCMCIA socket -- setting up 343 * This actually configures the PCMCIA socket -- setting up
@@ -359,7 +360,7 @@ spectrum_cs_config(struct pcmcia_device *link)
359 360
360 /* Register an interface with the stack */ 361 /* Register an interface with the stack */
361 if (orinoco_if_add(priv, link->io.BasePort1, 362 if (orinoco_if_add(priv, link->io.BasePort1,
362 link->irq) != 0) { 363 link->irq, NULL) != 0) {
363 printk(KERN_ERR PFX "orinoco_if_add() failed\n"); 364 printk(KERN_ERR PFX "orinoco_if_add() failed\n");
364 goto failed; 365 goto failed;
365 } 366 }
@@ -384,9 +385,9 @@ spectrum_cs_release(struct pcmcia_device *link)
384 385
385 /* We're committed to taking the device away now, so mark the 386 /* We're committed to taking the device away now, so mark the
386 * hardware as unavailable */ 387 * hardware as unavailable */
387 spin_lock_irqsave(&priv->lock, flags); 388 priv->hw.ops->lock_irqsave(&priv->lock, &flags);
388 priv->hw_unavailable++; 389 priv->hw_unavailable++;
389 spin_unlock_irqrestore(&priv->lock, flags); 390 priv->hw.ops->unlock_irqrestore(&priv->lock, &flags);
390 391
391 pcmcia_disable_device(link); 392 pcmcia_disable_device(link);
392 if (priv->hw.iobase) 393 if (priv->hw.iobase)
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c
index fbcc6e1a2e1d..5775124e2aee 100644
--- a/drivers/net/wireless/orinoco/wext.c
+++ b/drivers/net/wireless/orinoco/wext.c
@@ -458,7 +458,7 @@ static int orinoco_ioctl_setfreq(struct net_device *dev,
458 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { 458 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
459 /* Fast channel change - no commit if successful */ 459 /* Fast channel change - no commit if successful */
460 hermes_t *hw = &priv->hw; 460 hermes_t *hw = &priv->hw;
461 err = hermes_docmd_wait(hw, HERMES_CMD_TEST | 461 err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST |
462 HERMES_TEST_SET_CHANNEL, 462 HERMES_TEST_SET_CHANNEL,
463 chan, NULL); 463 chan, NULL);
464 } 464 }
@@ -538,125 +538,6 @@ static int orinoco_ioctl_setsens(struct net_device *dev,
538 return -EINPROGRESS; /* Call commit handler */ 538 return -EINPROGRESS; /* Call commit handler */
539} 539}
540 540
541static int orinoco_ioctl_setrts(struct net_device *dev,
542 struct iw_request_info *info,
543 struct iw_param *rrq,
544 char *extra)
545{
546 struct orinoco_private *priv = ndev_priv(dev);
547 int val = rrq->value;
548 unsigned long flags;
549
550 if (rrq->disabled)
551 val = 2347;
552
553 if ((val < 0) || (val > 2347))
554 return -EINVAL;
555
556 if (orinoco_lock(priv, &flags) != 0)
557 return -EBUSY;
558
559 priv->rts_thresh = val;
560 orinoco_unlock(priv, &flags);
561
562 return -EINPROGRESS; /* Call commit handler */
563}
564
565static int orinoco_ioctl_getrts(struct net_device *dev,
566 struct iw_request_info *info,
567 struct iw_param *rrq,
568 char *extra)
569{
570 struct orinoco_private *priv = ndev_priv(dev);
571
572 rrq->value = priv->rts_thresh;
573 rrq->disabled = (rrq->value == 2347);
574 rrq->fixed = 1;
575
576 return 0;
577}
578
579static int orinoco_ioctl_setfrag(struct net_device *dev,
580 struct iw_request_info *info,
581 struct iw_param *frq,
582 char *extra)
583{
584 struct orinoco_private *priv = ndev_priv(dev);
585 int err = -EINPROGRESS; /* Call commit handler */
586 unsigned long flags;
587
588 if (orinoco_lock(priv, &flags) != 0)
589 return -EBUSY;
590
591 if (priv->has_mwo) {
592 if (frq->disabled)
593 priv->mwo_robust = 0;
594 else {
595 if (frq->fixed)
596 printk(KERN_WARNING "%s: Fixed fragmentation "
597 "is not supported on this firmware. "
598 "Using MWO robust instead.\n",
599 dev->name);
600 priv->mwo_robust = 1;
601 }
602 } else {
603 if (frq->disabled)
604 priv->frag_thresh = 2346;
605 else {
606 if ((frq->value < 256) || (frq->value > 2346))
607 err = -EINVAL;
608 else
609 /* must be even */
610 priv->frag_thresh = frq->value & ~0x1;
611 }
612 }
613
614 orinoco_unlock(priv, &flags);
615
616 return err;
617}
618
619static int orinoco_ioctl_getfrag(struct net_device *dev,
620 struct iw_request_info *info,
621 struct iw_param *frq,
622 char *extra)
623{
624 struct orinoco_private *priv = ndev_priv(dev);
625 hermes_t *hw = &priv->hw;
626 int err;
627 u16 val;
628 unsigned long flags;
629
630 if (orinoco_lock(priv, &flags) != 0)
631 return -EBUSY;
632
633 if (priv->has_mwo) {
634 err = hermes_read_wordrec(hw, USER_BAP,
635 HERMES_RID_CNFMWOROBUST_AGERE,
636 &val);
637 if (err)
638 val = 0;
639
640 frq->value = val ? 2347 : 0;
641 frq->disabled = !val;
642 frq->fixed = 0;
643 } else {
644 err = hermes_read_wordrec(hw, USER_BAP,
645 HERMES_RID_CNFFRAGMENTATIONTHRESHOLD,
646 &val);
647 if (err)
648 val = 0;
649
650 frq->value = val;
651 frq->disabled = (val >= 2346);
652 frq->fixed = 1;
653 }
654
655 orinoco_unlock(priv, &flags);
656
657 return err;
658}
659
660static int orinoco_ioctl_setrate(struct net_device *dev, 541static int orinoco_ioctl_setrate(struct net_device *dev,
661 struct iw_request_info *info, 542 struct iw_request_info *info,
662 struct iw_param *rrq, 543 struct iw_param *rrq,
@@ -1201,60 +1082,6 @@ static int orinoco_ioctl_set_mlme(struct net_device *dev,
1201 return ret; 1082 return ret;
1202} 1083}
1203 1084
1204static int orinoco_ioctl_getretry(struct net_device *dev,
1205 struct iw_request_info *info,
1206 struct iw_param *rrq,
1207 char *extra)
1208{
1209 struct orinoco_private *priv = ndev_priv(dev);
1210 hermes_t *hw = &priv->hw;
1211 int err = 0;
1212 u16 short_limit, long_limit, lifetime;
1213 unsigned long flags;
1214
1215 if (orinoco_lock(priv, &flags) != 0)
1216 return -EBUSY;
1217
1218 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_SHORTRETRYLIMIT,
1219 &short_limit);
1220 if (err)
1221 goto out;
1222
1223 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_LONGRETRYLIMIT,
1224 &long_limit);
1225 if (err)
1226 goto out;
1227
1228 err = hermes_read_wordrec(hw, USER_BAP, HERMES_RID_MAXTRANSMITLIFETIME,
1229 &lifetime);
1230 if (err)
1231 goto out;
1232
1233 rrq->disabled = 0; /* Can't be disabled */
1234
1235 /* Note : by default, display the retry number */
1236 if ((rrq->flags & IW_RETRY_TYPE) == IW_RETRY_LIFETIME) {
1237 rrq->flags = IW_RETRY_LIFETIME;
1238 rrq->value = lifetime * 1000; /* ??? */
1239 } else {
1240 /* By default, display the min number */
1241 if ((rrq->flags & IW_RETRY_LONG)) {
1242 rrq->flags = IW_RETRY_LIMIT | IW_RETRY_LONG;
1243 rrq->value = long_limit;
1244 } else {
1245 rrq->flags = IW_RETRY_LIMIT;
1246 rrq->value = short_limit;
1247 if (short_limit != long_limit)
1248 rrq->flags |= IW_RETRY_SHORT;
1249 }
1250 }
1251
1252 out:
1253 orinoco_unlock(priv, &flags);
1254
1255 return err;
1256}
1257
1258static int orinoco_ioctl_reset(struct net_device *dev, 1085static int orinoco_ioctl_reset(struct net_device *dev,
1259 struct iw_request_info *info, 1086 struct iw_request_info *info,
1260 void *wrqu, 1087 void *wrqu,
@@ -1446,8 +1273,8 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
1446 if (orinoco_lock(priv, &flags) != 0) 1273 if (orinoco_lock(priv, &flags) != 0)
1447 return -EBUSY; 1274 return -EBUSY;
1448 1275
1449 err = hermes_read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length, 1276 err = hw->ops->read_ltv(hw, USER_BAP, rid, MAX_RID_LEN, &length,
1450 extra); 1277 extra);
1451 if (err) 1278 if (err)
1452 goto out; 1279 goto out;
1453 1280
@@ -1506,46 +1333,44 @@ static const struct iw_priv_args orinoco_privtab[] = {
1506 * Structures to export the Wireless Handlers 1333 * Structures to export the Wireless Handlers
1507 */ 1334 */
1508 1335
1509#define STD_IW_HANDLER(id, func) \
1510 [IW_IOCTL_IDX(id)] = (iw_handler) func
1511static const iw_handler orinoco_handler[] = { 1336static const iw_handler orinoco_handler[] = {
1512 STD_IW_HANDLER(SIOCSIWCOMMIT, orinoco_ioctl_commit), 1337 IW_HANDLER(SIOCSIWCOMMIT, (iw_handler)orinoco_ioctl_commit),
1513 STD_IW_HANDLER(SIOCGIWNAME, cfg80211_wext_giwname), 1338 IW_HANDLER(SIOCGIWNAME, (iw_handler)cfg80211_wext_giwname),
1514 STD_IW_HANDLER(SIOCSIWFREQ, orinoco_ioctl_setfreq), 1339 IW_HANDLER(SIOCSIWFREQ, (iw_handler)orinoco_ioctl_setfreq),
1515 STD_IW_HANDLER(SIOCGIWFREQ, orinoco_ioctl_getfreq), 1340 IW_HANDLER(SIOCGIWFREQ, (iw_handler)orinoco_ioctl_getfreq),
1516 STD_IW_HANDLER(SIOCSIWMODE, cfg80211_wext_siwmode), 1341 IW_HANDLER(SIOCSIWMODE, (iw_handler)cfg80211_wext_siwmode),
1517 STD_IW_HANDLER(SIOCGIWMODE, cfg80211_wext_giwmode), 1342 IW_HANDLER(SIOCGIWMODE, (iw_handler)cfg80211_wext_giwmode),
1518 STD_IW_HANDLER(SIOCSIWSENS, orinoco_ioctl_setsens), 1343 IW_HANDLER(SIOCSIWSENS, (iw_handler)orinoco_ioctl_setsens),
1519 STD_IW_HANDLER(SIOCGIWSENS, orinoco_ioctl_getsens), 1344 IW_HANDLER(SIOCGIWSENS, (iw_handler)orinoco_ioctl_getsens),
1520 STD_IW_HANDLER(SIOCGIWRANGE, cfg80211_wext_giwrange), 1345 IW_HANDLER(SIOCGIWRANGE, (iw_handler)cfg80211_wext_giwrange),
1521 STD_IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy), 1346 IW_HANDLER(SIOCSIWSPY, iw_handler_set_spy),
1522 STD_IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy), 1347 IW_HANDLER(SIOCGIWSPY, iw_handler_get_spy),
1523 STD_IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy), 1348 IW_HANDLER(SIOCSIWTHRSPY, iw_handler_set_thrspy),
1524 STD_IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy), 1349 IW_HANDLER(SIOCGIWTHRSPY, iw_handler_get_thrspy),
1525 STD_IW_HANDLER(SIOCSIWAP, orinoco_ioctl_setwap), 1350 IW_HANDLER(SIOCSIWAP, (iw_handler)orinoco_ioctl_setwap),
1526 STD_IW_HANDLER(SIOCGIWAP, orinoco_ioctl_getwap), 1351 IW_HANDLER(SIOCGIWAP, (iw_handler)orinoco_ioctl_getwap),
1527 STD_IW_HANDLER(SIOCSIWSCAN, cfg80211_wext_siwscan), 1352 IW_HANDLER(SIOCSIWSCAN, (iw_handler)cfg80211_wext_siwscan),
1528 STD_IW_HANDLER(SIOCGIWSCAN, cfg80211_wext_giwscan), 1353 IW_HANDLER(SIOCGIWSCAN, (iw_handler)cfg80211_wext_giwscan),
1529 STD_IW_HANDLER(SIOCSIWESSID, orinoco_ioctl_setessid), 1354 IW_HANDLER(SIOCSIWESSID, (iw_handler)orinoco_ioctl_setessid),
1530 STD_IW_HANDLER(SIOCGIWESSID, orinoco_ioctl_getessid), 1355 IW_HANDLER(SIOCGIWESSID, (iw_handler)orinoco_ioctl_getessid),
1531 STD_IW_HANDLER(SIOCSIWRATE, orinoco_ioctl_setrate), 1356 IW_HANDLER(SIOCSIWRATE, (iw_handler)orinoco_ioctl_setrate),
1532 STD_IW_HANDLER(SIOCGIWRATE, orinoco_ioctl_getrate), 1357 IW_HANDLER(SIOCGIWRATE, (iw_handler)orinoco_ioctl_getrate),
1533 STD_IW_HANDLER(SIOCSIWRTS, orinoco_ioctl_setrts), 1358 IW_HANDLER(SIOCSIWRTS, (iw_handler)cfg80211_wext_siwrts),
1534 STD_IW_HANDLER(SIOCGIWRTS, orinoco_ioctl_getrts), 1359 IW_HANDLER(SIOCGIWRTS, (iw_handler)cfg80211_wext_giwrts),
1535 STD_IW_HANDLER(SIOCSIWFRAG, orinoco_ioctl_setfrag), 1360 IW_HANDLER(SIOCSIWFRAG, (iw_handler)cfg80211_wext_siwfrag),
1536 STD_IW_HANDLER(SIOCGIWFRAG, orinoco_ioctl_getfrag), 1361 IW_HANDLER(SIOCGIWFRAG, (iw_handler)cfg80211_wext_giwfrag),
1537 STD_IW_HANDLER(SIOCGIWRETRY, orinoco_ioctl_getretry), 1362 IW_HANDLER(SIOCGIWRETRY, (iw_handler)cfg80211_wext_giwretry),
1538 STD_IW_HANDLER(SIOCSIWENCODE, orinoco_ioctl_setiwencode), 1363 IW_HANDLER(SIOCSIWENCODE, (iw_handler)orinoco_ioctl_setiwencode),
1539 STD_IW_HANDLER(SIOCGIWENCODE, orinoco_ioctl_getiwencode), 1364 IW_HANDLER(SIOCGIWENCODE, (iw_handler)orinoco_ioctl_getiwencode),
1540 STD_IW_HANDLER(SIOCSIWPOWER, orinoco_ioctl_setpower), 1365 IW_HANDLER(SIOCSIWPOWER, (iw_handler)orinoco_ioctl_setpower),
1541 STD_IW_HANDLER(SIOCGIWPOWER, orinoco_ioctl_getpower), 1366 IW_HANDLER(SIOCGIWPOWER, (iw_handler)orinoco_ioctl_getpower),
1542 STD_IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie), 1367 IW_HANDLER(SIOCSIWGENIE, orinoco_ioctl_set_genie),
1543 STD_IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie), 1368 IW_HANDLER(SIOCGIWGENIE, orinoco_ioctl_get_genie),
1544 STD_IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme), 1369 IW_HANDLER(SIOCSIWMLME, orinoco_ioctl_set_mlme),
1545 STD_IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth), 1370 IW_HANDLER(SIOCSIWAUTH, orinoco_ioctl_set_auth),
1546 STD_IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth), 1371 IW_HANDLER(SIOCGIWAUTH, orinoco_ioctl_get_auth),
1547 STD_IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext), 1372 IW_HANDLER(SIOCSIWENCODEEXT, orinoco_ioctl_set_encodeext),
1548 STD_IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext), 1373 IW_HANDLER(SIOCGIWENCODEEXT, orinoco_ioctl_get_encodeext),
1549}; 1374};
1550 1375
1551 1376
@@ -1553,15 +1378,15 @@ static const iw_handler orinoco_handler[] = {
1553 Added typecasting since we no longer use iwreq_data -- Moustafa 1378 Added typecasting since we no longer use iwreq_data -- Moustafa
1554 */ 1379 */
1555static const iw_handler orinoco_private_handler[] = { 1380static const iw_handler orinoco_private_handler[] = {
1556 [0] = (iw_handler) orinoco_ioctl_reset, 1381 [0] = (iw_handler)orinoco_ioctl_reset,
1557 [1] = (iw_handler) orinoco_ioctl_reset, 1382 [1] = (iw_handler)orinoco_ioctl_reset,
1558 [2] = (iw_handler) orinoco_ioctl_setport3, 1383 [2] = (iw_handler)orinoco_ioctl_setport3,
1559 [3] = (iw_handler) orinoco_ioctl_getport3, 1384 [3] = (iw_handler)orinoco_ioctl_getport3,
1560 [4] = (iw_handler) orinoco_ioctl_setpreamble, 1385 [4] = (iw_handler)orinoco_ioctl_setpreamble,
1561 [5] = (iw_handler) orinoco_ioctl_getpreamble, 1386 [5] = (iw_handler)orinoco_ioctl_getpreamble,
1562 [6] = (iw_handler) orinoco_ioctl_setibssport, 1387 [6] = (iw_handler)orinoco_ioctl_setibssport,
1563 [7] = (iw_handler) orinoco_ioctl_getibssport, 1388 [7] = (iw_handler)orinoco_ioctl_getibssport,
1564 [9] = (iw_handler) orinoco_ioctl_getrid, 1389 [9] = (iw_handler)orinoco_ioctl_getrid,
1565}; 1390};
1566 1391
1567const struct iw_handler_def orinoco_handler_def = { 1392const struct iw_handler_def orinoco_handler_def = {