OSDN Git Service

orinoco: Storage class should be before const qualifier
[uclinux-h8/linux.git] / drivers / net / wireless / orinoco / fw.c
1 /* Firmware file reading and download helpers
2  *
3  * See copyright notice in main.c
4  */
5 #include <linux/kernel.h>
6 #include <linux/firmware.h>
7
8 #include "hermes.h"
9 #include "hermes_dld.h"
10 #include "orinoco.h"
11
12 #include "fw.h"
13
14 /* End markers (for Symbol firmware only) */
15 #define TEXT_END        0x1A            /* End of text header */
16
17 struct fw_info {
18         char *pri_fw;
19         char *sta_fw;
20         char *ap_fw;
21         u32 pda_addr;
22         u16 pda_size;
23 };
24
25 static const struct fw_info orinoco_fw[] = {
26         { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 },
27         { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 },
28         { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 }
29 };
30
31 /* Structure used to access fields in FW
32  * Make sure LE decoding macros are used
33  */
34 struct orinoco_fw_header {
35         char hdr_vers[6];       /* ASCII string for header version */
36         __le16 headersize;      /* Total length of header */
37         __le32 entry_point;     /* NIC entry point */
38         __le32 blocks;          /* Number of blocks to program */
39         __le32 block_offset;    /* Offset of block data from eof header */
40         __le32 pdr_offset;      /* Offset to PDR data from eof header */
41         __le32 pri_offset;      /* Offset to primary plug data */
42         __le32 compat_offset;   /* Offset to compatibility data*/
43         char signature[0];      /* FW signature length headersize-20 */
44 } __attribute__ ((packed));
45
46 /* Download either STA or AP firmware into the card. */
47 static int
48 orinoco_dl_firmware(struct orinoco_private *priv,
49                     const struct fw_info *fw,
50                     int ap)
51 {
52         /* Plug Data Area (PDA) */
53         __le16 *pda;
54
55         hermes_t *hw = &priv->hw;
56         const struct firmware *fw_entry;
57         const struct orinoco_fw_header *hdr;
58         const unsigned char *first_block;
59         const unsigned char *end;
60         const char *firmware;
61         struct net_device *dev = priv->ndev;
62         int err = 0;
63
64         pda = kzalloc(fw->pda_size, GFP_KERNEL);
65         if (!pda)
66                 return -ENOMEM;
67
68         if (ap)
69                 firmware = fw->ap_fw;
70         else
71                 firmware = fw->sta_fw;
72
73         printk(KERN_DEBUG "%s: Attempting to download firmware %s\n",
74                dev->name, firmware);
75
76         /* Read current plug data */
77         err = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 0);
78         printk(KERN_DEBUG "%s: Read PDA returned %d\n", dev->name, err);
79         if (err)
80                 goto free;
81
82         if (!priv->cached_fw) {
83                 err = request_firmware(&fw_entry, firmware, priv->dev);
84
85                 if (err) {
86                         printk(KERN_ERR "%s: Cannot find firmware %s\n",
87                                dev->name, firmware);
88                         err = -ENOENT;
89                         goto free;
90                 }
91         } else
92                 fw_entry = priv->cached_fw;
93
94         hdr = (const struct orinoco_fw_header *) fw_entry->data;
95
96         /* Enable aux port to allow programming */
97         err = hermesi_program_init(hw, le32_to_cpu(hdr->entry_point));
98         printk(KERN_DEBUG "%s: Program init returned %d\n", dev->name, err);
99         if (err != 0)
100                 goto abort;
101
102         /* Program data */
103         first_block = (fw_entry->data +
104                        le16_to_cpu(hdr->headersize) +
105                        le32_to_cpu(hdr->block_offset));
106         end = fw_entry->data + fw_entry->size;
107
108         err = hermes_program(hw, first_block, end);
109         printk(KERN_DEBUG "%s: Program returned %d\n", dev->name, err);
110         if (err != 0)
111                 goto abort;
112
113         /* Update production data */
114         first_block = (fw_entry->data +
115                        le16_to_cpu(hdr->headersize) +
116                        le32_to_cpu(hdr->pdr_offset));
117
118         err = hermes_apply_pda_with_defaults(hw, first_block, pda);
119         printk(KERN_DEBUG "%s: Apply PDA returned %d\n", dev->name, err);
120         if (err)
121                 goto abort;
122
123         /* Tell card we've finished */
124         err = hermesi_program_end(hw);
125         printk(KERN_DEBUG "%s: Program end returned %d\n", dev->name, err);
126         if (err != 0)
127                 goto abort;
128
129         /* Check if we're running */
130         printk(KERN_DEBUG "%s: hermes_present returned %d\n",
131                dev->name, hermes_present(hw));
132
133 abort:
134         /* If we requested the firmware, release it. */
135         if (!priv->cached_fw)
136                 release_firmware(fw_entry);
137
138 free:
139         kfree(pda);
140         return err;
141 }
142
143 /*
144  * Process a firmware image - stop the card, load the firmware, reset
145  * the card and make sure it responds.  For the secondary firmware take
146  * care of the PDA - read it and then write it on top of the firmware.
147  */
148 static int
149 symbol_dl_image(struct orinoco_private *priv, const struct fw_info *fw,
150                 const unsigned char *image, const unsigned char *end,
151                 int secondary)
152 {
153         hermes_t *hw = &priv->hw;
154         int ret = 0;
155         const unsigned char *ptr;
156         const unsigned char *first_block;
157
158         /* Plug Data Area (PDA) */
159         __le16 *pda = NULL;
160
161         /* Binary block begins after the 0x1A marker */
162         ptr = image;
163         while (*ptr++ != TEXT_END);
164         first_block = ptr;
165
166         /* Read the PDA from EEPROM */
167         if (secondary) {
168                 pda = kzalloc(fw->pda_size, GFP_KERNEL);
169                 if (!pda)
170                         return -ENOMEM;
171
172                 ret = hermes_read_pda(hw, pda, fw->pda_addr, fw->pda_size, 1);
173                 if (ret)
174                         goto free;
175         }
176
177         /* Stop the firmware, so that it can be safely rewritten */
178         if (priv->stop_fw) {
179                 ret = priv->stop_fw(priv, 1);
180                 if (ret)
181                         goto free;
182         }
183
184         /* Program the adapter with new firmware */
185         ret = hermes_program(hw, first_block, end);
186         if (ret)
187                 goto free;
188
189         /* Write the PDA to the adapter */
190         if (secondary) {
191                 size_t len = hermes_blocks_length(first_block);
192                 ptr = first_block + len;
193                 ret = hermes_apply_pda(hw, ptr, pda);
194                 kfree(pda);
195                 if (ret)
196                         return ret;
197         }
198
199         /* Run the firmware */
200         if (priv->stop_fw) {
201                 ret = priv->stop_fw(priv, 0);
202                 if (ret)
203                         return ret;
204         }
205
206         /* Reset hermes chip and make sure it responds */
207         ret = hermes_init(hw);
208
209         /* hermes_reset() should return 0 with the secondary firmware */
210         if (secondary && ret != 0)
211                 return -ENODEV;
212
213         /* And this should work with any firmware */
214         if (!hermes_present(hw))
215                 return -ENODEV;
216
217         return 0;
218
219 free:
220         kfree(pda);
221         return ret;
222 }
223
224
225 /*
226  * Download the firmware into the card, this also does a PCMCIA soft
227  * reset on the card, to make sure it's in a sane state.
228  */
229 static int
230 symbol_dl_firmware(struct orinoco_private *priv,
231                    const struct fw_info *fw)
232 {
233         struct net_device *dev = priv->ndev;
234         int ret;
235         const struct firmware *fw_entry;
236
237         if (!priv->cached_pri_fw) {
238                 if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) {
239                         printk(KERN_ERR "%s: Cannot find firmware: %s\n",
240                                dev->name, fw->pri_fw);
241                         return -ENOENT;
242                 }
243         } else
244                 fw_entry = priv->cached_pri_fw;
245
246         /* Load primary firmware */
247         ret = symbol_dl_image(priv, fw, fw_entry->data,
248                               fw_entry->data + fw_entry->size, 0);
249
250         if (!priv->cached_pri_fw)
251                 release_firmware(fw_entry);
252         if (ret) {
253                 printk(KERN_ERR "%s: Primary firmware download failed\n",
254                        dev->name);
255                 return ret;
256         }
257
258         if (!priv->cached_fw) {
259                 if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) {
260                         printk(KERN_ERR "%s: Cannot find firmware: %s\n",
261                                dev->name, fw->sta_fw);
262                         return -ENOENT;
263                 }
264         } else
265                 fw_entry = priv->cached_fw;
266
267         /* Load secondary firmware */
268         ret = symbol_dl_image(priv, fw, fw_entry->data,
269                               fw_entry->data + fw_entry->size, 1);
270         if (!priv->cached_fw)
271                 release_firmware(fw_entry);
272         if (ret) {
273                 printk(KERN_ERR "%s: Secondary firmware download failed\n",
274                        dev->name);
275         }
276
277         return ret;
278 }
279
280 int orinoco_download(struct orinoco_private *priv)
281 {
282         int err = 0;
283         /* Reload firmware */
284         switch (priv->firmware_type) {
285         case FIRMWARE_TYPE_AGERE:
286                 /* case FIRMWARE_TYPE_INTERSIL: */
287                 err = orinoco_dl_firmware(priv,
288                                           &orinoco_fw[priv->firmware_type], 0);
289                 break;
290
291         case FIRMWARE_TYPE_SYMBOL:
292                 err = symbol_dl_firmware(priv,
293                                          &orinoco_fw[priv->firmware_type]);
294                 break;
295         case FIRMWARE_TYPE_INTERSIL:
296                 break;
297         }
298         /* TODO: if we fail we probably need to reinitialise
299          * the driver */
300
301         return err;
302 }
303
304 void orinoco_cache_fw(struct orinoco_private *priv, int ap)
305 {
306 #if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
307         const struct firmware *fw_entry = NULL;
308         const char *pri_fw;
309         const char *fw;
310
311         pri_fw = orinoco_fw[priv->firmware_type].pri_fw;
312         if (ap)
313                 fw = orinoco_fw[priv->firmware_type].ap_fw;
314         else
315                 fw = orinoco_fw[priv->firmware_type].sta_fw;
316
317         if (pri_fw) {
318                 if (request_firmware(&fw_entry, pri_fw, priv->dev) == 0)
319                         priv->cached_pri_fw = fw_entry;
320         }
321
322         if (fw) {
323                 if (request_firmware(&fw_entry, fw, priv->dev) == 0)
324                         priv->cached_fw = fw_entry;
325         }
326 #endif
327 }
328
329 void orinoco_uncache_fw(struct orinoco_private *priv)
330 {
331 #if defined(CONFIG_HERMES_CACHE_FW_ON_INIT) || defined(CONFIG_PM_SLEEP)
332         if (priv->cached_pri_fw)
333                 release_firmware(priv->cached_pri_fw);
334         if (priv->cached_fw)
335                 release_firmware(priv->cached_fw);
336
337         priv->cached_pri_fw = NULL;
338         priv->cached_fw = NULL;
339 #endif
340 }