aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/hermes.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/hermes.c')
-rw-r--r--drivers/net/wireless/hermes.c124
1 files changed, 71 insertions, 53 deletions
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index 29d39105f5b8..bfa375369df3 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -87,7 +87,8 @@ MODULE_LICENSE("Dual MPL/GPL");
87 87
88 Callable from any context. 88 Callable from any context.
89*/ 89*/
90static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0) 90static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0,
91 u16 param1, u16 param2)
91{ 92{
92 int k = CMD_BUSY_TIMEOUT; 93 int k = CMD_BUSY_TIMEOUT;
93 u16 reg; 94 u16 reg;
@@ -103,8 +104,8 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0)
103 return -EBUSY; 104 return -EBUSY;
104 } 105 }
105 106
106 hermes_write_regn(hw, PARAM2, 0); 107 hermes_write_regn(hw, PARAM2, param2);
107 hermes_write_regn(hw, PARAM1, 0); 108 hermes_write_regn(hw, PARAM1, param1);
108 hermes_write_regn(hw, PARAM0, param0); 109 hermes_write_regn(hw, PARAM0, param0);
109 hermes_write_regn(hw, CMD, cmd); 110 hermes_write_regn(hw, CMD, cmd);
110 111
@@ -115,16 +116,72 @@ static int hermes_issue_cmd(hermes_t *hw, u16 cmd, u16 param0)
115 * Function definitions 116 * Function definitions
116 */ 117 */
117 118
119/* For doing cmds that wipe the magic constant in SWSUPPORT0 */
120int hermes_doicmd_wait(hermes_t *hw, u16 cmd,
121 u16 parm0, u16 parm1, u16 parm2,
122 struct hermes_response *resp)
123{
124 int err = 0;
125 int k;
126 u16 status, reg;
127
128 err = hermes_issue_cmd(hw, cmd, parm0, parm1, parm2);
129 if (err)
130 return err;
131
132 reg = hermes_read_regn(hw, EVSTAT);
133 k = CMD_INIT_TIMEOUT;
134 while ((!(reg & HERMES_EV_CMD)) && k) {
135 k--;
136 udelay(10);
137 reg = hermes_read_regn(hw, EVSTAT);
138 }
139
140 hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
141
142 if (!hermes_present(hw)) {
143 DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n",
144 hw->iobase);
145 err = -ENODEV;
146 goto out;
147 }
148
149 if (!(reg & HERMES_EV_CMD)) {
150 printk(KERN_ERR "hermes @ %p: "
151 "Timeout waiting for card to reset (reg=0x%04x)!\n",
152 hw->iobase, reg);
153 err = -ETIMEDOUT;
154 goto out;
155 }
156
157 status = hermes_read_regn(hw, STATUS);
158 if (resp) {
159 resp->status = status;
160 resp->resp0 = hermes_read_regn(hw, RESP0);
161 resp->resp1 = hermes_read_regn(hw, RESP1);
162 resp->resp2 = hermes_read_regn(hw, RESP2);
163 }
164
165 hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
166
167 if (status & HERMES_STATUS_RESULT)
168 err = -EIO;
169out:
170 return err;
171}
172EXPORT_SYMBOL(hermes_doicmd_wait);
173
118void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing) 174void hermes_struct_init(hermes_t *hw, void __iomem *address, int reg_spacing)
119{ 175{
120 hw->iobase = address; 176 hw->iobase = address;
121 hw->reg_spacing = reg_spacing; 177 hw->reg_spacing = reg_spacing;
122 hw->inten = 0x0; 178 hw->inten = 0x0;
123} 179}
180EXPORT_SYMBOL(hermes_struct_init);
124 181
125int hermes_init(hermes_t *hw) 182int hermes_init(hermes_t *hw)
126{ 183{
127 u16 status, reg; 184 u16 reg;
128 int err = 0; 185 int err = 0;
129 int k; 186 int k;
130 187
@@ -162,45 +219,11 @@ int hermes_init(hermes_t *hw)
162 219
163 /* We don't use hermes_docmd_wait here, because the reset wipes 220 /* We don't use hermes_docmd_wait here, because the reset wipes
164 the magic constant in SWSUPPORT0 away, and it gets confused */ 221 the magic constant in SWSUPPORT0 away, and it gets confused */
165 err = hermes_issue_cmd(hw, HERMES_CMD_INIT, 0); 222 err = hermes_doicmd_wait(hw, HERMES_CMD_INIT, 0, 0, 0, NULL);
166 if (err)
167 return err;
168
169 reg = hermes_read_regn(hw, EVSTAT);
170 k = CMD_INIT_TIMEOUT;
171 while ( (! (reg & HERMES_EV_CMD)) && k) {
172 k--;
173 udelay(10);
174 reg = hermes_read_regn(hw, EVSTAT);
175 }
176
177 hermes_write_regn(hw, SWSUPPORT0, HERMES_MAGIC);
178
179 if (! hermes_present(hw)) {
180 DEBUG(0, "hermes @ 0x%x: Card removed during reset.\n",
181 hw->iobase);
182 err = -ENODEV;
183 goto out;
184 }
185
186 if (! (reg & HERMES_EV_CMD)) {
187 printk(KERN_ERR "hermes @ %p: "
188 "Timeout waiting for card to reset (reg=0x%04x)!\n",
189 hw->iobase, reg);
190 err = -ETIMEDOUT;
191 goto out;
192 }
193 223
194 status = hermes_read_regn(hw, STATUS);
195
196 hermes_write_regn(hw, EVACK, HERMES_EV_CMD);
197
198 if (status & HERMES_STATUS_RESULT)
199 err = -EIO;
200
201 out:
202 return err; 224 return err;
203} 225}
226EXPORT_SYMBOL(hermes_init);
204 227
205/* Issue a command to the chip, and (busy!) wait for it to 228/* Issue a command to the chip, and (busy!) wait for it to
206 * complete. 229 * complete.
@@ -216,7 +239,7 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
216 u16 reg; 239 u16 reg;
217 u16 status; 240 u16 status;
218 241
219 err = hermes_issue_cmd(hw, cmd, parm0); 242 err = hermes_issue_cmd(hw, cmd, parm0, 0, 0);
220 if (err) { 243 if (err) {
221 if (! hermes_present(hw)) { 244 if (! hermes_present(hw)) {
222 if (net_ratelimit()) 245 if (net_ratelimit())
@@ -271,6 +294,7 @@ int hermes_docmd_wait(hermes_t *hw, u16 cmd, u16 parm0,
271 out: 294 out:
272 return err; 295 return err;
273} 296}
297EXPORT_SYMBOL(hermes_docmd_wait);
274 298
275int hermes_allocate(hermes_t *hw, u16 size, u16 *fid) 299int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
276{ 300{
@@ -313,7 +337,7 @@ int hermes_allocate(hermes_t *hw, u16 size, u16 *fid)
313 337
314 return 0; 338 return 0;
315} 339}
316 340EXPORT_SYMBOL(hermes_allocate);
317 341
318/* Set up a BAP to read a particular chunk of data from card's internal buffer. 342/* Set up a BAP to read a particular chunk of data from card's internal buffer.
319 * 343 *
@@ -397,6 +421,7 @@ int hermes_bap_pread(hermes_t *hw, int bap, void *buf, int len,
397 out: 421 out:
398 return err; 422 return err;
399} 423}
424EXPORT_SYMBOL(hermes_bap_pread);
400 425
401/* Write a block of data to the chip's buffer, via the 426/* Write a block of data to the chip's buffer, via the
402 * BAP. Synchronization/serialization is the caller's problem. 427 * BAP. Synchronization/serialization is the caller's problem.
@@ -422,6 +447,7 @@ int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, int len,
422 out: 447 out:
423 return err; 448 return err;
424} 449}
450EXPORT_SYMBOL(hermes_bap_pwrite);
425 451
426/* Read a Length-Type-Value record from the card. 452/* Read a Length-Type-Value record from the card.
427 * 453 *
@@ -463,7 +489,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
463 if (rtype != rid) 489 if (rtype != rid)
464 printk(KERN_WARNING "hermes @ %p: %s(): " 490 printk(KERN_WARNING "hermes @ %p: %s(): "
465 "rid (0x%04x) does not match type (0x%04x)\n", 491 "rid (0x%04x) does not match type (0x%04x)\n",
466 hw->iobase, __FUNCTION__, rid, rtype); 492 hw->iobase, __func__, rid, rtype);
467 if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize) 493 if (HERMES_RECLEN_TO_BYTES(rlength) > bufsize)
468 printk(KERN_WARNING "hermes @ %p: " 494 printk(KERN_WARNING "hermes @ %p: "
469 "Truncating LTV record from %d to %d bytes. " 495 "Truncating LTV record from %d to %d bytes. "
@@ -475,6 +501,7 @@ int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned bufsize,
475 501
476 return 0; 502 return 0;
477} 503}
504EXPORT_SYMBOL(hermes_read_ltv);
478 505
479int hermes_write_ltv(hermes_t *hw, int bap, u16 rid, 506int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
480 u16 length, const void *value) 507 u16 length, const void *value)
@@ -497,20 +524,11 @@ int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
497 524
498 hermes_write_bytes(hw, dreg, value, count << 1); 525 hermes_write_bytes(hw, dreg, value, count << 1);
499 526
500 err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE, 527 err = hermes_docmd_wait(hw, HERMES_CMD_ACCESS | HERMES_CMD_WRITE,
501 rid, NULL); 528 rid, NULL);
502 529
503 return err; 530 return err;
504} 531}
505
506EXPORT_SYMBOL(hermes_struct_init);
507EXPORT_SYMBOL(hermes_init);
508EXPORT_SYMBOL(hermes_docmd_wait);
509EXPORT_SYMBOL(hermes_allocate);
510
511EXPORT_SYMBOL(hermes_bap_pread);
512EXPORT_SYMBOL(hermes_bap_pwrite);
513EXPORT_SYMBOL(hermes_read_ltv);
514EXPORT_SYMBOL(hermes_write_ltv); 532EXPORT_SYMBOL(hermes_write_ltv);
515 533
516static int __init init_hermes(void) 534static int __init init_hermes(void)