~ubuntu-branches/ubuntu/precise/linux-backports-modules-3.2.0/precise

« back to all changes in this revision

Viewing changes to updates/cw-3.3/drivers/net/wireless/wl1251/boot.c

  • Committer: Package Import Robot
  • Author(s): Leann Ogasawara
  • Date: 2012-02-15 08:42:08 UTC
  • Revision ID: package-import@ubuntu.com-20120215084208-2gcs2zosufz014pi
Tags: 3.2.0-18.1
* Open Precise LBM
* Add compat-wireless v3.3
* Consolidated amd64 server flavour into generic
* Remove lpia control file
* Update Vcs-Git to ubuntu-preicse-lbm

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * This file is part of wl1251
 
3
 *
 
4
 * Copyright (C) 2008 Nokia Corporation
 
5
 *
 
6
 * This program is free software; you can redistribute it and/or
 
7
 * modify it under the terms of the GNU General Public License
 
8
 * version 2 as published by the Free Software Foundation.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful, but
 
11
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 
18
 * 02110-1301 USA
 
19
 *
 
20
 */
 
21
 
 
22
#include <linux/slab.h>
 
23
 
 
24
#include "reg.h"
 
25
#include "boot.h"
 
26
#include "io.h"
 
27
#include "spi.h"
 
28
#include "event.h"
 
29
#include "acx.h"
 
30
 
 
31
void wl1251_boot_target_enable_interrupts(struct wl1251 *wl)
 
32
{
 
33
        wl1251_reg_write32(wl, ACX_REG_INTERRUPT_MASK, ~(wl->intr_mask));
 
34
        wl1251_reg_write32(wl, HI_CFG, HI_CFG_DEF_VAL);
 
35
}
 
36
 
 
37
int wl1251_boot_soft_reset(struct wl1251 *wl)
 
38
{
 
39
        unsigned long timeout;
 
40
        u32 boot_data;
 
41
 
 
42
        /* perform soft reset */
 
43
        wl1251_reg_write32(wl, ACX_REG_SLV_SOFT_RESET, ACX_SLV_SOFT_RESET_BIT);
 
44
 
 
45
        /* SOFT_RESET is self clearing */
 
46
        timeout = jiffies + usecs_to_jiffies(SOFT_RESET_MAX_TIME);
 
47
        while (1) {
 
48
                boot_data = wl1251_reg_read32(wl, ACX_REG_SLV_SOFT_RESET);
 
49
                wl1251_debug(DEBUG_BOOT, "soft reset bootdata 0x%x", boot_data);
 
50
                if ((boot_data & ACX_SLV_SOFT_RESET_BIT) == 0)
 
51
                        break;
 
52
 
 
53
                if (time_after(jiffies, timeout)) {
 
54
                        /* 1.2 check pWhalBus->uSelfClearTime if the
 
55
                         * timeout was reached */
 
56
                        wl1251_error("soft reset timeout");
 
57
                        return -1;
 
58
                }
 
59
 
 
60
                udelay(SOFT_RESET_STALL_TIME);
 
61
        }
 
62
 
 
63
        /* disable Rx/Tx */
 
64
        wl1251_reg_write32(wl, ENABLE, 0x0);
 
65
 
 
66
        /* disable auto calibration on start*/
 
67
        wl1251_reg_write32(wl, SPARE_A2, 0xffff);
 
68
 
 
69
        return 0;
 
70
}
 
71
 
 
72
int wl1251_boot_init_seq(struct wl1251 *wl)
 
73
{
 
74
        u32 scr_pad6, init_data, tmp, elp_cmd, ref_freq;
 
75
 
 
76
        /*
 
77
         * col #1: INTEGER_DIVIDER
 
78
         * col #2: FRACTIONAL_DIVIDER
 
79
         * col #3: ATTN_BB
 
80
         * col #4: ALPHA_BB
 
81
         * col #5: STOP_TIME_BB
 
82
         * col #6: BB_PLL_LOOP_FILTER
 
83
         */
 
84
        static const u32 LUT[REF_FREQ_NUM][LUT_PARAM_NUM] = {
 
85
 
 
86
                {   83, 87381,  0xB, 5, 0xF00,  3}, /* REF_FREQ_19_2*/
 
87
                {   61, 141154, 0xB, 5, 0x1450, 2}, /* REF_FREQ_26_0*/
 
88
                {   41, 174763, 0xC, 6, 0x2D00, 1}, /* REF_FREQ_38_4*/
 
89
                {   40, 0,      0xC, 6, 0x2EE0, 1}, /* REF_FREQ_40_0*/
 
90
                {   47, 162280, 0xC, 6, 0x2760, 1}  /* REF_FREQ_33_6        */
 
91
        };
 
92
 
 
93
        /* read NVS params */
 
94
        scr_pad6 = wl1251_reg_read32(wl, SCR_PAD6);
 
95
        wl1251_debug(DEBUG_BOOT, "scr_pad6 0x%x", scr_pad6);
 
96
 
 
97
        /* read ELP_CMD */
 
98
        elp_cmd = wl1251_reg_read32(wl, ELP_CMD);
 
99
        wl1251_debug(DEBUG_BOOT, "elp_cmd 0x%x", elp_cmd);
 
100
 
 
101
        /* set the BB calibration time to be 300 usec (PLL_CAL_TIME) */
 
102
        ref_freq = scr_pad6 & 0x000000FF;
 
103
        wl1251_debug(DEBUG_BOOT, "ref_freq 0x%x", ref_freq);
 
104
 
 
105
        wl1251_reg_write32(wl, PLL_CAL_TIME, 0x9);
 
106
 
 
107
        /*
 
108
         * PG 1.2: set the clock buffer time to be 210 usec (CLK_BUF_TIME)
 
109
         */
 
110
        wl1251_reg_write32(wl, CLK_BUF_TIME, 0x6);
 
111
 
 
112
        /*
 
113
         * set the clock detect feature to work in the restart wu procedure
 
114
         * (ELP_CFG_MODE[14]) and Select the clock source type
 
115
         * (ELP_CFG_MODE[13:12])
 
116
         */
 
117
        tmp = ((scr_pad6 & 0x0000FF00) << 4) | 0x00004000;
 
118
        wl1251_reg_write32(wl, ELP_CFG_MODE, tmp);
 
119
 
 
120
        /* PG 1.2: enable the BB PLL fix. Enable the PLL_LIMP_CLK_EN_CMD */
 
121
        elp_cmd |= 0x00000040;
 
122
        wl1251_reg_write32(wl, ELP_CMD, elp_cmd);
 
123
 
 
124
        /* PG 1.2: Set the BB PLL stable time to be 1000usec
 
125
         * (PLL_STABLE_TIME) */
 
126
        wl1251_reg_write32(wl, CFG_PLL_SYNC_CNT, 0x20);
 
127
 
 
128
        /* PG 1.2: read clock request time */
 
129
        init_data = wl1251_reg_read32(wl, CLK_REQ_TIME);
 
130
 
 
131
        /*
 
132
         * PG 1.2: set the clock request time to be ref_clk_settling_time -
 
133
         * 1ms = 4ms
 
134
         */
 
135
        if (init_data > 0x21)
 
136
                tmp = init_data - 0x21;
 
137
        else
 
138
                tmp = 0;
 
139
        wl1251_reg_write32(wl, CLK_REQ_TIME, tmp);
 
140
 
 
141
        /* set BB PLL configurations in RF AFE */
 
142
        wl1251_reg_write32(wl, 0x003058cc, 0x4B5);
 
143
 
 
144
        /* set RF_AFE_REG_5 */
 
145
        wl1251_reg_write32(wl, 0x003058d4, 0x50);
 
146
 
 
147
        /* set RF_AFE_CTRL_REG_2 */
 
148
        wl1251_reg_write32(wl, 0x00305948, 0x11c001);
 
149
 
 
150
        /*
 
151
         * change RF PLL and BB PLL divider for VCO clock and adjust VCO
 
152
         * bais current(RF_AFE_REG_13)
 
153
         */
 
154
        wl1251_reg_write32(wl, 0x003058f4, 0x1e);
 
155
 
 
156
        /* set BB PLL configurations */
 
157
        tmp = LUT[ref_freq][LUT_PARAM_INTEGER_DIVIDER] | 0x00017000;
 
158
        wl1251_reg_write32(wl, 0x00305840, tmp);
 
159
 
 
160
        /* set fractional divider according to Appendix C-BB PLL
 
161
         * Calculations
 
162
         */
 
163
        tmp = LUT[ref_freq][LUT_PARAM_FRACTIONAL_DIVIDER];
 
164
        wl1251_reg_write32(wl, 0x00305844, tmp);
 
165
 
 
166
        /* set the initial data for the sigma delta */
 
167
        wl1251_reg_write32(wl, 0x00305848, 0x3039);
 
168
 
 
169
        /*
 
170
         * set the accumulator attenuation value, calibration loop1
 
171
         * (alpha), calibration loop2 (beta), calibration loop3 (gamma) and
 
172
         * the VCO gain
 
173
         */
 
174
        tmp = (LUT[ref_freq][LUT_PARAM_ATTN_BB] << 16) |
 
175
                (LUT[ref_freq][LUT_PARAM_ALPHA_BB] << 12) | 0x1;
 
176
        wl1251_reg_write32(wl, 0x00305854, tmp);
 
177
 
 
178
        /*
 
179
         * set the calibration stop time after holdoff time expires and set
 
180
         * settling time HOLD_OFF_TIME_BB
 
181
         */
 
182
        tmp = LUT[ref_freq][LUT_PARAM_STOP_TIME_BB] | 0x000A0000;
 
183
        wl1251_reg_write32(wl, 0x00305858, tmp);
 
184
 
 
185
        /*
 
186
         * set BB PLL Loop filter capacitor3- BB_C3[2:0] and set BB PLL
 
187
         * constant leakage current to linearize PFD to 0uA -
 
188
         * BB_ILOOPF[7:3]
 
189
         */
 
190
        tmp = LUT[ref_freq][LUT_PARAM_BB_PLL_LOOP_FILTER] | 0x00000030;
 
191
        wl1251_reg_write32(wl, 0x003058f8, tmp);
 
192
 
 
193
        /*
 
194
         * set regulator output voltage for n divider to
 
195
         * 1.35-BB_REFDIV[1:0], set charge pump current- BB_CPGAIN[4:2],
 
196
         * set BB PLL Loop filter capacitor2- BB_C2[7:5], set gain of BB
 
197
         * PLL auto-call to normal mode- BB_CALGAIN_3DB[8]
 
198
         */
 
199
        wl1251_reg_write32(wl, 0x003058f0, 0x29);
 
200
 
 
201
        /* enable restart wakeup sequence (ELP_CMD[0]) */
 
202
        wl1251_reg_write32(wl, ELP_CMD, elp_cmd | 0x1);
 
203
 
 
204
        /* restart sequence completed */
 
205
        udelay(2000);
 
206
 
 
207
        return 0;
 
208
}
 
209
 
 
210
static void wl1251_boot_set_ecpu_ctrl(struct wl1251 *wl, u32 flag)
 
211
{
 
212
        u32 cpu_ctrl;
 
213
 
 
214
        /* 10.5.0 run the firmware (I) */
 
215
        cpu_ctrl = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
 
216
 
 
217
        /* 10.5.1 run the firmware (II) */
 
218
        cpu_ctrl &= ~flag;
 
219
        wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, cpu_ctrl);
 
220
}
 
221
 
 
222
int wl1251_boot_run_firmware(struct wl1251 *wl)
 
223
{
 
224
        int loop, ret;
 
225
        u32 chip_id, acx_intr;
 
226
 
 
227
        wl1251_boot_set_ecpu_ctrl(wl, ECPU_CONTROL_HALT);
 
228
 
 
229
        chip_id = wl1251_reg_read32(wl, CHIP_ID_B);
 
230
 
 
231
        wl1251_debug(DEBUG_BOOT, "chip id after firmware boot: 0x%x", chip_id);
 
232
 
 
233
        if (chip_id != wl->chip_id) {
 
234
                wl1251_error("chip id doesn't match after firmware boot");
 
235
                return -EIO;
 
236
        }
 
237
 
 
238
        /* wait for init to complete */
 
239
        loop = 0;
 
240
        while (loop++ < INIT_LOOP) {
 
241
                udelay(INIT_LOOP_DELAY);
 
242
                acx_intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR);
 
243
 
 
244
                if (acx_intr == 0xffffffff) {
 
245
                        wl1251_error("error reading hardware complete "
 
246
                                     "init indication");
 
247
                        return -EIO;
 
248
                }
 
249
                /* check that ACX_INTR_INIT_COMPLETE is enabled */
 
250
                else if (acx_intr & WL1251_ACX_INTR_INIT_COMPLETE) {
 
251
                        wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK,
 
252
                                           WL1251_ACX_INTR_INIT_COMPLETE);
 
253
                        break;
 
254
                }
 
255
        }
 
256
 
 
257
        if (loop > INIT_LOOP) {
 
258
                wl1251_error("timeout waiting for the hardware to "
 
259
                             "complete initialization");
 
260
                return -EIO;
 
261
        }
 
262
 
 
263
        /* get hardware config command mail box */
 
264
        wl->cmd_box_addr = wl1251_reg_read32(wl, REG_COMMAND_MAILBOX_PTR);
 
265
 
 
266
        /* get hardware config event mail box */
 
267
        wl->event_box_addr = wl1251_reg_read32(wl, REG_EVENT_MAILBOX_PTR);
 
268
 
 
269
        /* set the working partition to its "running" mode offset */
 
270
        wl1251_set_partition(wl, WL1251_PART_WORK_MEM_START,
 
271
                             WL1251_PART_WORK_MEM_SIZE,
 
272
                             WL1251_PART_WORK_REG_START,
 
273
                             WL1251_PART_WORK_REG_SIZE);
 
274
 
 
275
        wl1251_debug(DEBUG_MAILBOX, "cmd_box_addr 0x%x event_box_addr 0x%x",
 
276
                     wl->cmd_box_addr, wl->event_box_addr);
 
277
 
 
278
        wl1251_acx_fw_version(wl, wl->fw_ver, sizeof(wl->fw_ver));
 
279
 
 
280
        /*
 
281
         * in case of full asynchronous mode the firmware event must be
 
282
         * ready to receive event from the command mailbox
 
283
         */
 
284
 
 
285
        /* enable gpio interrupts */
 
286
        wl1251_enable_interrupts(wl);
 
287
 
 
288
        /* Enable target's interrupts */
 
289
        wl->intr_mask = WL1251_ACX_INTR_RX0_DATA |
 
290
                WL1251_ACX_INTR_RX1_DATA |
 
291
                WL1251_ACX_INTR_TX_RESULT |
 
292
                WL1251_ACX_INTR_EVENT_A |
 
293
                WL1251_ACX_INTR_EVENT_B |
 
294
                WL1251_ACX_INTR_INIT_COMPLETE;
 
295
        wl1251_boot_target_enable_interrupts(wl);
 
296
 
 
297
        wl->event_mask = SCAN_COMPLETE_EVENT_ID | BSS_LOSE_EVENT_ID |
 
298
                SYNCHRONIZATION_TIMEOUT_EVENT_ID |
 
299
                ROAMING_TRIGGER_LOW_RSSI_EVENT_ID |
 
300
                ROAMING_TRIGGER_REGAINED_RSSI_EVENT_ID |
 
301
                REGAINED_BSS_EVENT_ID | BT_PTA_SENSE_EVENT_ID |
 
302
                BT_PTA_PREDICTION_EVENT_ID | JOIN_EVENT_COMPLETE_ID;
 
303
 
 
304
        ret = wl1251_event_unmask(wl);
 
305
        if (ret < 0) {
 
306
                wl1251_error("EVENT mask setting failed");
 
307
                return ret;
 
308
        }
 
309
 
 
310
        wl1251_event_mbox_config(wl);
 
311
 
 
312
        /* firmware startup completed */
 
313
        return 0;
 
314
}
 
315
 
 
316
static int wl1251_boot_upload_firmware(struct wl1251 *wl)
 
317
{
 
318
        int addr, chunk_num, partition_limit;
 
319
        size_t fw_data_len, len;
 
320
        u8 *p, *buf;
 
321
 
 
322
        /* whal_FwCtrl_LoadFwImageSm() */
 
323
 
 
324
        wl1251_debug(DEBUG_BOOT, "chip id before fw upload: 0x%x",
 
325
                     wl1251_reg_read32(wl, CHIP_ID_B));
 
326
 
 
327
        /* 10.0 check firmware length and set partition */
 
328
        fw_data_len =  (wl->fw[4] << 24) | (wl->fw[5] << 16) |
 
329
                (wl->fw[6] << 8) | (wl->fw[7]);
 
330
 
 
331
        wl1251_debug(DEBUG_BOOT, "fw_data_len %zu chunk_size %d", fw_data_len,
 
332
                CHUNK_SIZE);
 
333
 
 
334
        if ((fw_data_len % 4) != 0) {
 
335
                wl1251_error("firmware length not multiple of four");
 
336
                return -EIO;
 
337
        }
 
338
 
 
339
        buf = kmalloc(CHUNK_SIZE, GFP_KERNEL);
 
340
        if (!buf) {
 
341
                wl1251_error("allocation for firmware upload chunk failed");
 
342
                return -ENOMEM;
 
343
        }
 
344
 
 
345
        wl1251_set_partition(wl, WL1251_PART_DOWN_MEM_START,
 
346
                             WL1251_PART_DOWN_MEM_SIZE,
 
347
                             WL1251_PART_DOWN_REG_START,
 
348
                             WL1251_PART_DOWN_REG_SIZE);
 
349
 
 
350
        /* 10.1 set partition limit and chunk num */
 
351
        chunk_num = 0;
 
352
        partition_limit = WL1251_PART_DOWN_MEM_SIZE;
 
353
 
 
354
        while (chunk_num < fw_data_len / CHUNK_SIZE) {
 
355
                /* 10.2 update partition, if needed */
 
356
                addr = WL1251_PART_DOWN_MEM_START +
 
357
                        (chunk_num + 2) * CHUNK_SIZE;
 
358
                if (addr > partition_limit) {
 
359
                        addr = WL1251_PART_DOWN_MEM_START +
 
360
                                chunk_num * CHUNK_SIZE;
 
361
                        partition_limit = chunk_num * CHUNK_SIZE +
 
362
                                WL1251_PART_DOWN_MEM_SIZE;
 
363
                        wl1251_set_partition(wl,
 
364
                                             addr,
 
365
                                             WL1251_PART_DOWN_MEM_SIZE,
 
366
                                             WL1251_PART_DOWN_REG_START,
 
367
                                             WL1251_PART_DOWN_REG_SIZE);
 
368
                }
 
369
 
 
370
                /* 10.3 upload the chunk */
 
371
                addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
 
372
                p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
 
373
                wl1251_debug(DEBUG_BOOT, "uploading fw chunk 0x%p to 0x%x",
 
374
                             p, addr);
 
375
 
 
376
                /* need to copy the chunk for dma */
 
377
                len = CHUNK_SIZE;
 
378
                memcpy(buf, p, len);
 
379
                wl1251_mem_write(wl, addr, buf, len);
 
380
 
 
381
                chunk_num++;
 
382
        }
 
383
 
 
384
        /* 10.4 upload the last chunk */
 
385
        addr = WL1251_PART_DOWN_MEM_START + chunk_num * CHUNK_SIZE;
 
386
        p = wl->fw + FW_HDR_SIZE + chunk_num * CHUNK_SIZE;
 
387
 
 
388
        /* need to copy the chunk for dma */
 
389
        len = fw_data_len % CHUNK_SIZE;
 
390
        memcpy(buf, p, len);
 
391
 
 
392
        wl1251_debug(DEBUG_BOOT, "uploading fw last chunk (%zu B) 0x%p to 0x%x",
 
393
                     len, p, addr);
 
394
        wl1251_mem_write(wl, addr, buf, len);
 
395
 
 
396
        kfree(buf);
 
397
 
 
398
        return 0;
 
399
}
 
400
 
 
401
static int wl1251_boot_upload_nvs(struct wl1251 *wl)
 
402
{
 
403
        size_t nvs_len, nvs_bytes_written, burst_len;
 
404
        int nvs_start, i;
 
405
        u32 dest_addr, val;
 
406
        u8 *nvs_ptr, *nvs;
 
407
 
 
408
        nvs = wl->nvs;
 
409
        if (nvs == NULL)
 
410
                return -ENODEV;
 
411
 
 
412
        nvs_ptr = nvs;
 
413
 
 
414
        nvs_len = wl->nvs_len;
 
415
        nvs_start = wl->fw_len;
 
416
 
 
417
        /*
 
418
         * Layout before the actual NVS tables:
 
419
         * 1 byte : burst length.
 
420
         * 2 bytes: destination address.
 
421
         * n bytes: data to burst copy.
 
422
         *
 
423
         * This is ended by a 0 length, then the NVS tables.
 
424
         */
 
425
 
 
426
        while (nvs_ptr[0]) {
 
427
                burst_len = nvs_ptr[0];
 
428
                dest_addr = (nvs_ptr[1] & 0xfe) | ((u32)(nvs_ptr[2] << 8));
 
429
 
 
430
                /* We move our pointer to the data */
 
431
                nvs_ptr += 3;
 
432
 
 
433
                for (i = 0; i < burst_len; i++) {
 
434
                        val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
 
435
                               | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
 
436
 
 
437
                        wl1251_debug(DEBUG_BOOT,
 
438
                                     "nvs burst write 0x%x: 0x%x",
 
439
                                     dest_addr, val);
 
440
                        wl1251_mem_write32(wl, dest_addr, val);
 
441
 
 
442
                        nvs_ptr += 4;
 
443
                        dest_addr += 4;
 
444
                }
 
445
        }
 
446
 
 
447
        /*
 
448
         * We've reached the first zero length, the first NVS table
 
449
         * is 7 bytes further.
 
450
         */
 
451
        nvs_ptr += 7;
 
452
        nvs_len -= nvs_ptr - nvs;
 
453
        nvs_len = ALIGN(nvs_len, 4);
 
454
 
 
455
        /* Now we must set the partition correctly */
 
456
        wl1251_set_partition(wl, nvs_start,
 
457
                             WL1251_PART_DOWN_MEM_SIZE,
 
458
                             WL1251_PART_DOWN_REG_START,
 
459
                             WL1251_PART_DOWN_REG_SIZE);
 
460
 
 
461
        /* And finally we upload the NVS tables */
 
462
        nvs_bytes_written = 0;
 
463
        while (nvs_bytes_written < nvs_len) {
 
464
                val = (nvs_ptr[0] | (nvs_ptr[1] << 8)
 
465
                       | (nvs_ptr[2] << 16) | (nvs_ptr[3] << 24));
 
466
 
 
467
                val = cpu_to_le32(val);
 
468
 
 
469
                wl1251_debug(DEBUG_BOOT,
 
470
                             "nvs write table 0x%x: 0x%x",
 
471
                             nvs_start, val);
 
472
                wl1251_mem_write32(wl, nvs_start, val);
 
473
 
 
474
                nvs_ptr += 4;
 
475
                nvs_bytes_written += 4;
 
476
                nvs_start += 4;
 
477
        }
 
478
 
 
479
        return 0;
 
480
}
 
481
 
 
482
int wl1251_boot(struct wl1251 *wl)
 
483
{
 
484
        int ret = 0, minor_minor_e2_ver;
 
485
        u32 tmp, boot_data;
 
486
 
 
487
        /* halt embedded ARM CPU while loading firmware */
 
488
        wl1251_reg_write32(wl, ACX_REG_ECPU_CONTROL, ECPU_CONTROL_HALT);
 
489
 
 
490
        ret = wl1251_boot_soft_reset(wl);
 
491
        if (ret < 0)
 
492
                goto out;
 
493
 
 
494
        /* 2. start processing NVS file */
 
495
        if (wl->use_eeprom) {
 
496
                wl1251_reg_write32(wl, ACX_REG_EE_START, START_EEPROM_MGR);
 
497
                /* Wait for EEPROM NVS burst read to complete */
 
498
                msleep(40);
 
499
                wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, USE_EEPROM);
 
500
        } else {
 
501
                ret = wl1251_boot_upload_nvs(wl);
 
502
                if (ret < 0)
 
503
                        goto out;
 
504
 
 
505
                /* write firmware's last address (ie. it's length) to
 
506
                 * ACX_EEPROMLESS_IND_REG */
 
507
                wl1251_reg_write32(wl, ACX_EEPROMLESS_IND_REG, wl->fw_len);
 
508
        }
 
509
 
 
510
        /* 6. read the EEPROM parameters */
 
511
        tmp = wl1251_reg_read32(wl, SCR_PAD2);
 
512
 
 
513
        /* 7. read bootdata */
 
514
        wl->boot_attr.radio_type = (tmp & 0x0000FF00) >> 8;
 
515
        wl->boot_attr.major = (tmp & 0x00FF0000) >> 16;
 
516
        tmp = wl1251_reg_read32(wl, SCR_PAD3);
 
517
 
 
518
        /* 8. check bootdata and call restart sequence */
 
519
        wl->boot_attr.minor = (tmp & 0x00FF0000) >> 16;
 
520
        minor_minor_e2_ver = (tmp & 0xFF000000) >> 24;
 
521
 
 
522
        wl1251_debug(DEBUG_BOOT, "radioType 0x%x majorE2Ver 0x%x "
 
523
                     "minorE2Ver 0x%x minor_minor_e2_ver 0x%x",
 
524
                     wl->boot_attr.radio_type, wl->boot_attr.major,
 
525
                     wl->boot_attr.minor, minor_minor_e2_ver);
 
526
 
 
527
        ret = wl1251_boot_init_seq(wl);
 
528
        if (ret < 0)
 
529
                goto out;
 
530
 
 
531
        /* 9. NVS processing done */
 
532
        boot_data = wl1251_reg_read32(wl, ACX_REG_ECPU_CONTROL);
 
533
 
 
534
        wl1251_debug(DEBUG_BOOT, "halt boot_data 0x%x", boot_data);
 
535
 
 
536
        /* 10. check that ECPU_CONTROL_HALT bits are set in
 
537
         * pWhalBus->uBootData and start uploading firmware
 
538
         */
 
539
        if ((boot_data & ECPU_CONTROL_HALT) == 0) {
 
540
                wl1251_error("boot failed, ECPU_CONTROL_HALT not set");
 
541
                ret = -EIO;
 
542
                goto out;
 
543
        }
 
544
 
 
545
        ret = wl1251_boot_upload_firmware(wl);
 
546
        if (ret < 0)
 
547
                goto out;
 
548
 
 
549
        /* 10.5 start firmware */
 
550
        ret = wl1251_boot_run_firmware(wl);
 
551
        if (ret < 0)
 
552
                goto out;
 
553
 
 
554
out:
 
555
        return ret;
 
556
}