blob: a137c78fac0982ee293860344bc172b757fb7ead [file] [log] [blame]
Kalle Valo14c0b3e2009-01-07 22:01:20 +02001/*
2 * This file is part of stlc45xx
3 *
4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23
24#include "stlc45xx.h"
25
26#include <linux/module.h>
27#include <linux/platform_device.h>
28#include <linux/interrupt.h>
29#include <linux/firmware.h>
30#include <linux/delay.h>
31#include <linux/irq.h>
32#include <linux/spi/spi.h>
33#include <linux/etherdevice.h>
34#include <linux/gpio.h>
35#include <linux/moduleparam.h>
36
37#include "stlc45xx_lmac.h"
38
39/*
40 * gpios should be handled in board files and provided via platform data,
41 * but because it's currently impossible for stlc45xx to have a header file
42 * in include/linux, let's use module paramaters for now
43 */
44static int stlc45xx_gpio_power = 97;
45module_param(stlc45xx_gpio_power, int, 0444);
46MODULE_PARM_DESC(stlc45xx_gpio_power, "stlc45xx gpio number for power line");
47
48static int stlc45xx_gpio_irq = 87;
49module_param(stlc45xx_gpio_irq, int, 0444);
50MODULE_PARM_DESC(stlc45xx_gpio_irq, "stlc45xx gpio number for irq line");
51
52static const u8 default_cal_channels[] = {
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x09,
55 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10,
56 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xe0, 0x00, 0xe0, 0x00,
57 0xe0, 0x00, 0xe0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
58 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
59 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
60 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9,
61 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00,
62 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
63 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
64 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
65 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d,
66 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa,
67 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
68 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17,
69 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
70 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00,
71 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00,
72 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
73 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
75 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x71, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8,
82 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
83 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0,
84 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6,
85 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00,
86 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
87 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
88 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
89 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca,
90 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4,
91 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
92 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21,
93 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
94 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00,
95 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00,
96 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
97 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0,
98 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
99 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76,
108 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01,
109 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0,
110 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
111 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
112 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
113 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37,
114 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc,
115 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
116 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b,
117 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
118 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00,
119 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00,
120 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
121 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0,
122 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
123 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a,
124 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
125 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
126 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, 0x09, 0x00, 0x00, 0xc9, 0xff,
135 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
136 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
137 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab,
138 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb,
139 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
140 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33,
141 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
142 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00,
143 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00,
144 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
145 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0,
146 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
147 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7,
148 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
149 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
150 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d,
151 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00,
152 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80,
159 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x80, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00,
162 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00,
163 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0,
164 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42,
165 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
166 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01,
167 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00,
168 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
169 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0,
170 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
171 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0,
172 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
173 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
174 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17,
175 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00,
176 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
177 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
178 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
179 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
185 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00,
186 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x09, 0x00, 0x00, 0xc9,
188 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01,
189 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
190 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01,
191 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00,
192 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
193 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0,
194 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
195 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb,
196 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
197 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
198 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21,
199 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00,
200 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
201 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
202 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
203 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0,
204 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96,
205 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
206 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06,
212 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
214 0x00, 0x8a, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00,
215 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0,
216 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
217 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0,
218 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
219 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22,
220 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
221 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
222 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b,
223 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00,
224 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
225 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
226 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
227 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0,
228 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0,
229 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
230 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d,
231 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
232 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
235 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00,
239 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x09, 0x00, 0x00,
241 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10,
242 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00,
243 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54,
244 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42,
245 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
246 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33,
247 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00,
248 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
249 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0,
250 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
251 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0,
252 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa,
253 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
254 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17,
255 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
256 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c,
257 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00,
258 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
259 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
261 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
262 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
263 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
264 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
265 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 0x00, 0x00, 0x94, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00,
268 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01,
269 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0,
270 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42,
271 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00,
272 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
273 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0,
274 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc,
275 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0,
276 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4,
277 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
278 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21,
279 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00,
280 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d,
281 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00,
282 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
283 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0,
284 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96,
285 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
293 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x09, 0x00,
294 0x00, 0xc9, 0xff, 0xd8, 0xff, 0x00, 0x00, 0x00, 0x01, 0x10, 0x01,
295 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0,
296 0x00, 0xf0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00,
297 0x54, 0x01, 0xab, 0xf6, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0,
298 0x42, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb,
299 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0,
300 0x33, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc,
301 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
302 0xbc, 0xfb, 0x00, 0xca, 0x79, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b,
303 0xc0, 0x2b, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00,
304 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54,
305 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00,
306 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
307 0x00, 0xaa, 0xa7, 0x00, 0xa9, 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0,
308 0x17, 0xc0, 0x17, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
309 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06,
310 0x2c, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96,
311 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
312 0x96, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
313 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
314 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
315 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
317 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
318 0x00, 0x06, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320 0x00, 0x00, 0x00, 0x9e, 0x09, 0x00, 0x00, 0xc9, 0xff, 0xd8, 0xff,
321 0x00, 0x00, 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10,
322 0x01, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xf0, 0x00, 0xd0, 0x00,
323 0xd0, 0x00, 0xd0, 0x00, 0xd0, 0x00, 0x54, 0x01, 0xab, 0xf6, 0xc0,
324 0x42, 0xc0, 0x42, 0xc0, 0x42, 0xc0, 0x42, 0x00, 0xcb, 0x00, 0xcb,
325 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00, 0xcb, 0x00,
326 0xcb, 0x22, 0x01, 0x37, 0xa9, 0xc0, 0x33, 0xc0, 0x33, 0xc0, 0x33,
327 0xc0, 0x33, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00,
328 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0x00, 0xbc, 0xfb, 0x00, 0xca, 0x79,
329 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0xc0, 0x2b, 0x00, 0xb4, 0x00,
330 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4, 0x00, 0xb4,
331 0x00, 0xb4, 0xd0, 0x00, 0x5d, 0x54, 0xc0, 0x21, 0xc0, 0x21, 0xc0,
332 0x21, 0xc0, 0x21, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa,
333 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0x00, 0xaa, 0xa7, 0x00, 0xa9,
334 0x3d, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0xc0, 0x17, 0x00, 0xa0,
335 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00,
336 0xa0, 0x00, 0xa0, 0x7a, 0x00, 0x06, 0x2c, 0xc0, 0x0d, 0xc0, 0x0d,
337 0xc0, 0x0d, 0xc0, 0x0d, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00,
338 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x96, 0x00, 0x00,
339 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x80, 0x80, 0x00,
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
361 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
363 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
366 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
389 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
392 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
393 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
395 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
397 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398 0x00 };
399
400static const u8 default_cal_rssi[] = {
401 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72,
402 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00,
403 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a,
404 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe,
405 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00,
406 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01,
407 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a,
408 0x00, 0x00, 0x00, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
409 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410 0x00, 0x00, 0x00, 0x00, 0x00 };
411
412static void stlc45xx_tx_edcf(struct stlc45xx *stlc);
413static void stlc45xx_tx_setup(struct stlc45xx *stlc);
414static void stlc45xx_tx_scan(struct stlc45xx *stlc);
415static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable);
416static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave);
417static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave);
418
419static ssize_t stlc45xx_sysfs_show_cal_rssi(struct device *dev,
420 struct device_attribute *attr,
421 char *buf)
422{
423 struct stlc45xx *stlc = dev_get_drvdata(dev);
424 ssize_t len;
425
426 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
427
428 len = PAGE_SIZE;
429
430 mutex_lock(&stlc->mutex);
431
432 if (stlc->cal_rssi)
433 hex_dump_to_buffer(stlc->cal_rssi, RSSI_CAL_ARRAY_LEN, 16,
434 2, buf, len, 0);
435 mutex_unlock(&stlc->mutex);
436
437 len = strlen(buf);
438
439 return len;
440}
441
442static ssize_t stlc45xx_sysfs_store_cal_rssi(struct device *dev,
443 struct device_attribute *attr,
444 const char *buf, size_t count)
445{
446 struct stlc45xx *stlc = dev_get_drvdata(dev);
447
448 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
449
450 mutex_lock(&stlc->mutex);
451
452 if (count != RSSI_CAL_ARRAY_LEN) {
Randy Dunlap793bccb2009-02-11 13:21:46 -0800453 stlc45xx_error("invalid cal_rssi length: %zu", count);
Kalle Valo14c0b3e2009-01-07 22:01:20 +0200454 count = 0;
455 goto out_unlock;
456 }
457
458 kfree(stlc->cal_rssi);
459
460 stlc->cal_rssi = kmemdup(buf, RSSI_CAL_ARRAY_LEN, GFP_KERNEL);
461
462 if (!stlc->cal_rssi) {
463 stlc45xx_error("failed to allocate memory for cal_rssi");
464 count = 0;
465 goto out_unlock;
466 }
467
468 out_unlock:
469 mutex_unlock(&stlc->mutex);
470
471 return count;
472}
473
474static ssize_t stlc45xx_sysfs_show_cal_channels(struct device *dev,
475 struct device_attribute *attr,
476 char *buf)
477{
478 struct stlc45xx *stlc = dev_get_drvdata(dev);
479 ssize_t len;
480
481 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
482
483 len = PAGE_SIZE;
484
485 mutex_lock(&stlc->mutex);
486
487 if (stlc->cal_channels)
488 hex_dump_to_buffer(stlc->cal_channels, CHANNEL_CAL_ARRAY_LEN,
489 16, 2, buf, len, 0);
490
491 mutex_unlock(&stlc->mutex);
492
493 len = strlen(buf);
494
495 return len;
496}
497
498static ssize_t stlc45xx_sysfs_store_cal_channels(struct device *dev,
499 struct device_attribute *attr,
500 const char *buf, size_t count)
501{
502 struct stlc45xx *stlc = dev_get_drvdata(dev);
503
504 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
505
506 mutex_lock(&stlc->mutex);
507
508 if (count != CHANNEL_CAL_ARRAY_LEN) {
Randy Dunlap793bccb2009-02-11 13:21:46 -0800509 stlc45xx_error("invalid cal_channels size: %zu ", count);
Kalle Valo14c0b3e2009-01-07 22:01:20 +0200510 count = 0;
511 goto out_unlock;
512 }
513
514 kfree(stlc->cal_channels);
515
516 stlc->cal_channels = kmemdup(buf, count, GFP_KERNEL);
517
518 if (!stlc->cal_channels) {
519 stlc45xx_error("failed to allocate memory for cal_channels");
520 count = 0;
521 goto out_unlock;
522 }
523
524out_unlock:
525 mutex_unlock(&stlc->mutex);
526
527 return count;
528}
529
530static ssize_t stlc45xx_sysfs_show_tx_buf(struct device *dev,
531 struct device_attribute *attr,
532 char *buf)
533{
534 struct stlc45xx *stlc = dev_get_drvdata(dev);
535 struct txbuffer *entry;
536 ssize_t len = 0;
537
538 stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
539
540 mutex_lock(&stlc->mutex);
541
542 list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
543 len += sprintf(buf + len, "0x%x: 0x%x-0x%x\n",
544 entry->handle, entry->start,
545 entry->end);
546 }
547
548 mutex_unlock(&stlc->mutex);
549
550 return len;
551}
552
553static DEVICE_ATTR(cal_rssi, S_IRUGO | S_IWUSR,
554 stlc45xx_sysfs_show_cal_rssi,
555 stlc45xx_sysfs_store_cal_rssi);
556static DEVICE_ATTR(cal_channels, S_IRUGO | S_IWUSR,
557 stlc45xx_sysfs_show_cal_channels,
558 stlc45xx_sysfs_store_cal_channels);
559static DEVICE_ATTR(tx_buf, S_IRUGO, stlc45xx_sysfs_show_tx_buf, NULL);
560
561static void stlc45xx_spi_read(struct stlc45xx *stlc, unsigned long addr,
562 void *buf, size_t len)
563{
564 struct spi_transfer t[2];
565 struct spi_message m;
566
567 /* We first push the address */
568 addr = (addr << 8) | ADDR_READ_BIT_15;
569
570 spi_message_init(&m);
571 memset(t, 0, sizeof(t));
572
573 t[0].tx_buf = &addr;
574 t[0].len = 2;
575 spi_message_add_tail(&t[0], &m);
576
577 t[1].rx_buf = buf;
578 t[1].len = len;
579 spi_message_add_tail(&t[1], &m);
580
581 spi_sync(stlc->spi, &m);
582}
583
584
585static void stlc45xx_spi_write(struct stlc45xx *stlc, unsigned long addr,
586 void *buf, size_t len)
587{
588 struct spi_transfer t[3];
589 struct spi_message m;
590 u16 last_word;
591
592 /* We first push the address */
593 addr = addr << 8;
594
595 spi_message_init(&m);
596 memset(t, 0, sizeof(t));
597
598 t[0].tx_buf = &addr;
599 t[0].len = 2;
600 spi_message_add_tail(&t[0], &m);
601
602 t[1].tx_buf = buf;
603 t[1].len = len;
604 spi_message_add_tail(&t[1], &m);
605
606 if (len % 2) {
607 last_word = ((u8 *)buf)[len - 1];
608
609 t[2].tx_buf = &last_word;
610 t[2].len = 2;
611 spi_message_add_tail(&t[2], &m);
612 }
613
614 spi_sync(stlc->spi, &m);
615}
616
617static u16 stlc45xx_read16(struct stlc45xx *stlc, unsigned long addr)
618{
619 u16 val;
620
621 stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
622
623 return val;
624}
625
626static u32 stlc45xx_read32(struct stlc45xx *stlc, unsigned long addr)
627{
628 u32 val;
629
630 stlc45xx_spi_read(stlc, addr, &val, sizeof(val));
631
632 return val;
633}
634
635static void stlc45xx_write16(struct stlc45xx *stlc, unsigned long addr, u16 val)
636{
637 stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
638}
639
640static void stlc45xx_write32(struct stlc45xx *stlc, unsigned long addr, u32 val)
641{
642 stlc45xx_spi_write(stlc, addr, &val, sizeof(val));
643}
644
645struct stlc45xx_spi_reg {
646 u16 address;
647 u16 length;
648 char *name;
649};
650
651/* caller must hold tx_lock */
652static void stlc45xx_txbuffer_dump(struct stlc45xx *stlc)
653{
654 struct txbuffer *txbuffer;
655 char *buf, *pos;
656 int buf_len, l, count;
657
658 if (!(DEBUG_LEVEL & DEBUG_TXBUFFER))
659 return;
660
661 stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
662
663 buf_len = 500;
664 buf = kmalloc(buf_len, GFP_ATOMIC);
665 if (!buf)
666 return;
667
668 pos = buf;
669 count = 0;
670
671 list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
672 l = snprintf(pos, buf_len, "0x%x-0x%x,",
673 txbuffer->start, txbuffer->end);
674 /* drop the null byte */
675 pos += l;
676 buf_len -= l;
677 count++;
678 }
679
680 if (count == 0)
681 *pos = '\0';
682 else
683 *--pos = '\0';
684
685 stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: in buffer %d regions: %s",
686 count, buf);
687
688 kfree(buf);
689}
690
691/* caller must hold tx_lock */
692static int stlc45xx_txbuffer_find(struct stlc45xx *stlc, size_t len)
693{
694 struct txbuffer *txbuffer;
695 int pos;
696
697 stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
698
699 pos = FIRMWARE_TXBUFFER_START;
700
701 if (list_empty(&stlc->txbuffer))
702 goto out;
703
704 /*
705 * the entries in txbuffer must be in the same order as they are in
706 * the real buffer
707 */
708 list_for_each_entry(txbuffer, &stlc->txbuffer, buffer_list) {
709 if (pos + len < txbuffer->start)
710 break;
711 pos = ALIGN(txbuffer->end + 1, 4);
712 }
713
714 if (pos + len > FIRMWARE_TXBUFFER_END)
715 /* not enough room */
716 pos = -1;
717
Randy Dunlap793bccb2009-02-11 13:21:46 -0800718 stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: find %zu B: 0x%x", len, pos);
Kalle Valo14c0b3e2009-01-07 22:01:20 +0200719
720out:
721 return pos;
722}
723
724static int stlc45xx_txbuffer_add(struct stlc45xx *stlc,
725 struct txbuffer *txbuffer)
726{
727 struct txbuffer *r, *prev = NULL;
728
729 if (list_empty(&stlc->txbuffer)) {
730 list_add(&txbuffer->buffer_list, &stlc->txbuffer);
731 return 0;
732 }
733
734 r = list_first_entry(&stlc->txbuffer, struct txbuffer, buffer_list);
735
736 if (txbuffer->start < r->start) {
737 /* add to the beginning of the list */
738 list_add(&txbuffer->buffer_list, &stlc->txbuffer);
739 return 0;
740 }
741
742 prev = NULL;
743 list_for_each_entry(r, &stlc->txbuffer, buffer_list) {
744 /* skip first entry, we checked for that above */
745 if (!prev) {
746 prev = r;
747 continue;
748 }
749
750 /* double-check overlaps */
751 WARN_ON_ONCE(txbuffer->start >= r->start &&
752 txbuffer->start <= r->end);
753 WARN_ON_ONCE(txbuffer->end >= r->start &&
754 txbuffer->end <= r->end);
755
756 if (prev->end < txbuffer->start &&
757 txbuffer->end < r->start) {
758 /* insert at this spot */
759 list_add_tail(&txbuffer->buffer_list, &r->buffer_list);
760 return 0;
761 }
762
763 prev = r;
764 }
765
766 /* not found */
767 list_add_tail(&txbuffer->buffer_list, &stlc->txbuffer);
768
769 return 0;
770
771}
772
773/* caller must hold tx_lock */
774static struct txbuffer *stlc45xx_txbuffer_alloc(struct stlc45xx *stlc,
775 size_t frame_len)
776{
777 struct txbuffer *entry = NULL;
778 size_t len;
779 int pos;
780
781 stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
782
783 len = FIRMWARE_TXBUFFER_HEADER + frame_len + FIRMWARE_TXBUFFER_TRAILER;
784 pos = stlc45xx_txbuffer_find(stlc, len);
785
786 if (pos < 0)
787 return NULL;
788
789 WARN_ON_ONCE(pos + len > FIRMWARE_TXBUFFER_END);
790 WARN_ON_ONCE(pos < FIRMWARE_TXBUFFER_START);
791
792 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
793 entry->start = pos;
794 entry->frame_start = pos + FIRMWARE_TXBUFFER_HEADER;
795 entry->end = entry->start + len - 1;
796
797 stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: allocated 0x%x-0x%x",
798 entry->start, entry->end);
799
800 stlc45xx_txbuffer_add(stlc, entry);
801
802 stlc45xx_txbuffer_dump(stlc);
803
804 return entry;
805}
806
807/* caller must hold tx_lock */
808static void stlc45xx_txbuffer_free(struct stlc45xx *stlc,
809 struct txbuffer *txbuffer)
810{
811 stlc45xx_debug(DEBUG_FUNC, "%s()", __func__);
812
813 stlc45xx_debug(DEBUG_TXBUFFER, "txbuffer: freed 0x%x-0x%x",
814 txbuffer->start, txbuffer->end);
815
816 list_del(&txbuffer->buffer_list);
817 kfree(txbuffer);
818}
819
820
821static int stlc45xx_wait_bit(struct stlc45xx *stlc, u16 reg, u32 mask,
822 u32 expected)
823{
824 int i;
825 char buffer[4];
826
827 for (i = 0; i < 2000; i++) {
828 stlc45xx_spi_read(stlc, reg, buffer, sizeof(buffer));
829 if (((*(u32 *)buffer) & mask) == expected)
830 return 1;
831 msleep(1);
832 }
833
834 return 0;
835}
836
837static int stlc45xx_request_firmware(struct stlc45xx *stlc)
838{
839 const struct firmware *fw;
840 int ret;
841
842 /* FIXME: should driver use it's own struct device? */
843 ret = request_firmware(&fw, "3826.arm", &stlc->spi->dev);
844
845 if (ret < 0) {
846 stlc45xx_error("request_firmware() failed: %d", ret);
847 return ret;
848 }
849
850 if (fw->size % 4) {
Randy Dunlap793bccb2009-02-11 13:21:46 -0800851 stlc45xx_error("firmware size is not multiple of 32bit: %zu",
Kalle Valo14c0b3e2009-01-07 22:01:20 +0200852 fw->size);
853 return -EILSEQ; /* Illegal byte sequence */;
854 }
855
856 if (fw->size < 1000) {
Randy Dunlap793bccb2009-02-11 13:21:46 -0800857 stlc45xx_error("firmware is too small: %zu", fw->size);
Kalle Valo14c0b3e2009-01-07 22:01:20 +0200858 return -EILSEQ;
859 }
860
861 stlc->fw = kmemdup(fw->data, fw->size, GFP_KERNEL);
862 if (!stlc->fw) {
863 stlc45xx_error("could not allocate memory for firmware");
864 return -ENOMEM;
865 }
866
867 stlc->fw_len = fw->size;
868
869 release_firmware(fw);
870
871 return 0;
872}
873
874static int stlc45xx_upload_firmware(struct stlc45xx *stlc)
875{
876 struct s_dma_regs dma_regs;
877 unsigned long fw_len, fw_addr;
878 long _fw_len;
879 int ret;
880
881 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
882
883 if (!stlc->fw) {
884 ret = stlc45xx_request_firmware(stlc);
885 if (ret < 0)
886 return ret;
887 }
888
889 /* stop the device */
890 stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
891 SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
892 | SPI_CTRL_STAT_START_HALTED);
893
894 msleep(TARGET_BOOT_SLEEP);
895
896 stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
897 SPI_CTRL_STAT_HOST_OVERRIDE
898 | SPI_CTRL_STAT_START_HALTED);
899
900 msleep(TARGET_BOOT_SLEEP);
901
902 fw_addr = FIRMWARE_ADDRESS;
903 fw_len = stlc->fw_len;
904
905 while (fw_len > 0) {
906 _fw_len = (fw_len > SPI_MAX_PACKET_SIZE)
907 ? SPI_MAX_PACKET_SIZE : fw_len;
908 dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
909 dma_regs.len = cpu_to_le16(_fw_len);
910 dma_regs.addr = cpu_to_le32(fw_addr);
911
912 fw_len -= _fw_len;
913 fw_addr += _fw_len;
914
915 stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_CTRL, dma_regs.cmd);
916
917 if (stlc45xx_wait_bit(stlc, SPI_ADRS_DMA_WRITE_CTRL,
918 HOST_ALLOWED, HOST_ALLOWED) == 0) {
919 stlc45xx_error("fw_upload not allowed to DMA write");
920 return -EAGAIN;
921 }
922
923 stlc45xx_write16(stlc, SPI_ADRS_DMA_WRITE_LEN, dma_regs.len);
924 stlc45xx_write32(stlc, SPI_ADRS_DMA_WRITE_BASE, dma_regs.addr);
925
926 stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, stlc->fw, _fw_len);
927
928 /* FIXME: I think this doesn't work if firmware is large,
929 * this loop goes to second round. fw->data is not
930 * increased at all! */
931 }
932
933 BUG_ON(fw_len != 0);
934
935 /* enable host interrupts */
936 stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN, SPI_HOST_INTS_DEFAULT);
937
938 /* boot the device */
939 stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
940 SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_HOST_RESET
941 | SPI_CTRL_STAT_RAM_BOOT);
942
943 msleep(TARGET_BOOT_SLEEP);
944
945 stlc45xx_write16(stlc, SPI_ADRS_DEV_CTRL_STAT,
946 SPI_CTRL_STAT_HOST_OVERRIDE | SPI_CTRL_STAT_RAM_BOOT);
947 msleep(TARGET_BOOT_SLEEP);
948
949 return 0;
950}
951
952/* caller must hold tx_lock */
953static void stlc45xx_check_txsent(struct stlc45xx *stlc)
954{
955 struct txbuffer *entry, *n;
956
957 list_for_each_entry_safe(entry, n, &stlc->tx_sent, tx_list) {
958 if (time_after(jiffies, entry->lifetime)) {
959 if (net_ratelimit())
960 stlc45xx_warning("frame 0x%x lifetime exceeded",
961 entry->start);
962 list_del(&entry->tx_list);
963 skb_pull(entry->skb, entry->header_len);
964 ieee80211_tx_status(stlc->hw, entry->skb);
965 stlc45xx_txbuffer_free(stlc, entry);
966 }
967 }
968}
969
970static void stlc45xx_power_off(struct stlc45xx *stlc)
971{
972 disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
973 gpio_set_value(stlc45xx_gpio_power, 0);
974}
975
976static void stlc45xx_power_on(struct stlc45xx *stlc)
977{
978 gpio_set_value(stlc45xx_gpio_power, 1);
979 enable_irq(gpio_to_irq(stlc45xx_gpio_irq));
980
981 /*
982 * need to wait a while before device can be accessed, the length
983 * is just a guess
984 */
985 msleep(10);
986}
987
988/* caller must hold tx_lock */
989static void stlc45xx_flush_queues(struct stlc45xx *stlc)
990{
991 struct txbuffer *entry;
992
993 while (!list_empty(&stlc->tx_sent)) {
994 entry = list_first_entry(&stlc->tx_sent,
995 struct txbuffer, tx_list);
996 list_del(&entry->tx_list);
997 dev_kfree_skb(entry->skb);
998 stlc45xx_txbuffer_free(stlc, entry);
999 }
1000
1001 WARN_ON(!list_empty(&stlc->tx_sent));
1002
1003 while (!list_empty(&stlc->tx_pending)) {
1004 entry = list_first_entry(&stlc->tx_pending,
1005 struct txbuffer, tx_list);
1006 list_del(&entry->tx_list);
1007 dev_kfree_skb(entry->skb);
1008 stlc45xx_txbuffer_free(stlc, entry);
1009 }
1010
1011 WARN_ON(!list_empty(&stlc->tx_pending));
1012 WARN_ON(!list_empty(&stlc->txbuffer));
1013}
1014
1015static void stlc45xx_work_reset(struct work_struct *work)
1016{
1017 struct stlc45xx *stlc = container_of(work, struct stlc45xx,
1018 work_reset);
1019
1020 mutex_lock(&stlc->mutex);
1021
1022 if (stlc->fw_state != FW_STATE_RESET)
1023 goto out;
1024
1025 stlc45xx_power_off(stlc);
1026
1027 mutex_unlock(&stlc->mutex);
1028
1029 /* wait that all work_structs have finished, we can't hold
1030 * stlc->mutex to avoid deadlock */
1031 cancel_work_sync(&stlc->work);
1032
1033 /* FIXME: find out good value to wait for chip power down */
1034 msleep(100);
1035
1036 mutex_lock(&stlc->mutex);
1037
1038 /* FIXME: we should gracefully handle if the state has changed
1039 * after re-acquiring mutex */
1040 WARN_ON(stlc->fw_state != FW_STATE_RESET);
1041
1042 spin_lock_bh(&stlc->tx_lock);
1043 stlc45xx_flush_queues(stlc);
1044 spin_unlock_bh(&stlc->tx_lock);
1045
1046 stlc->fw_state = FW_STATE_RESETTING;
1047
1048 stlc45xx_power_on(stlc);
1049 stlc45xx_upload_firmware(stlc);
1050
1051out:
1052 mutex_unlock(&stlc->mutex);
1053}
1054
1055/* caller must hold mutex */
1056static void stlc45xx_reset(struct stlc45xx *stlc)
1057{
1058 stlc45xx_warning("resetting firmware");
1059 stlc->fw_state = FW_STATE_RESET;
1060 ieee80211_stop_queues(stlc->hw);
1061 queue_work(stlc->hw->workqueue, &stlc->work_reset);
1062}
1063
1064static void stlc45xx_work_tx_timeout(struct work_struct *work)
1065{
1066 struct stlc45xx *stlc = container_of(work, struct stlc45xx,
1067 work_tx_timeout.work);
1068
1069 stlc45xx_warning("tx timeout");
1070
1071 mutex_lock(&stlc->mutex);
1072
1073 if (stlc->fw_state != FW_STATE_READY)
1074 goto out;
1075
1076 stlc45xx_reset(stlc);
1077
1078out:
1079 mutex_unlock(&stlc->mutex);
1080}
1081
1082static void stlc45xx_int_ack(struct stlc45xx *stlc, u32 val)
1083{
1084 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1085
1086 stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_ACK, val);
1087}
1088
1089static void stlc45xx_wakeup(struct stlc45xx *stlc)
1090{
1091 unsigned long timeout;
1092 u32 ints;
1093
1094 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1095
1096 /* wake the chip */
1097 stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_WAKEUP);
1098
1099 /* And wait for the READY interrupt */
1100 timeout = jiffies + HZ;
1101
1102 ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
1103 while (!(ints & SPI_HOST_INT_READY)) {
1104 if (time_after(jiffies, timeout))
1105 goto out;
1106 ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
1107 }
1108
1109 stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
1110
1111out:
1112 return;
1113}
1114
1115static void stlc45xx_sleep(struct stlc45xx *stlc)
1116{
1117 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1118
1119 stlc45xx_write32(stlc, SPI_ADRS_ARM_INTERRUPTS, SPI_TARGET_INT_SLEEP);
1120}
1121
1122static void stlc45xx_int_ready(struct stlc45xx *stlc)
1123{
1124 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1125
1126 stlc45xx_write32(stlc, SPI_ADRS_HOST_INT_EN,
1127 SPI_HOST_INT_UPDATE | SPI_HOST_INT_SW_UPDATE);
1128
1129 switch (stlc->fw_state) {
1130 case FW_STATE_BOOTING:
1131 stlc->fw_state = FW_STATE_READY;
1132 complete(&stlc->fw_comp);
1133 break;
1134 case FW_STATE_RESETTING:
1135 stlc->fw_state = FW_STATE_READY;
1136
1137 stlc45xx_tx_scan(stlc);
1138 stlc45xx_tx_setup(stlc);
1139 stlc45xx_tx_edcf(stlc);
1140
1141 ieee80211_wake_queues(stlc->hw);
1142 break;
1143 default:
1144 break;
1145 }
1146}
1147
1148static int stlc45xx_rx_txack(struct stlc45xx *stlc, struct sk_buff *skb)
1149{
1150 struct ieee80211_tx_info *info;
1151 struct s_lm_control *control;
1152 struct s_lmo_tx *tx;
1153 struct txbuffer *entry;
1154 int found = 0;
1155
1156 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1157
1158 control = (struct s_lm_control *) skb->data;
1159 tx = (struct s_lmo_tx *) (control + 1);
1160
1161 if (list_empty(&stlc->tx_sent)) {
1162 if (net_ratelimit())
1163 stlc45xx_warning("no frames waiting for "
1164 "acknowledgement");
1165 return -1;
1166 }
1167
1168 list_for_each_entry(entry, &stlc->tx_sent, tx_list) {
1169 if (control->handle == entry->handle) {
1170 found = 1;
1171 break;
1172 }
1173 }
1174
1175 if (!found) {
1176 if (net_ratelimit())
1177 stlc45xx_warning("couldn't find frame for tx ack 0x%x",
1178 control->handle);
1179 return -1;
1180 }
1181
1182 stlc45xx_debug(DEBUG_TX, "TX ACK 0x%x", entry->handle);
1183
1184 if (entry->status_needed) {
1185 info = IEEE80211_SKB_CB(entry->skb);
1186
1187 if (!(tx->flags & LM_TX_FAILED)) {
1188 /* frame was acked */
1189 info->flags |= IEEE80211_TX_STAT_ACK;
1190 info->status.ack_signal = tx->rcpi / 2 - 110;
1191 }
1192
1193 skb_pull(entry->skb, entry->header_len);
1194
1195 ieee80211_tx_status(stlc->hw, entry->skb);
1196 }
1197
1198 list_del(&entry->tx_list);
1199
1200 stlc45xx_check_txsent(stlc);
1201 if (list_empty(&stlc->tx_sent))
1202 /* there are no pending frames, we can stop the tx timeout
1203 * timer */
1204 cancel_delayed_work(&stlc->work_tx_timeout);
1205
1206 spin_lock_bh(&stlc->tx_lock);
1207
1208 stlc45xx_txbuffer_free(stlc, entry);
1209
1210 if (stlc->tx_queue_stopped &&
1211 stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) != -1) {
1212 stlc45xx_debug(DEBUG_QUEUE, "room in tx buffer, waking queues");
1213 ieee80211_wake_queues(stlc->hw);
1214 stlc->tx_queue_stopped = 0;
1215 }
1216
1217 spin_unlock_bh(&stlc->tx_lock);
1218
1219 return 0;
1220}
1221
1222static int stlc45xx_rx_control(struct stlc45xx *stlc, struct sk_buff *skb)
1223{
1224 struct s_lm_control *control;
1225 int ret = 0;
1226
1227 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1228
1229 control = (struct s_lm_control *) skb->data;
1230
1231 switch (control->oid) {
1232 case LM_OID_TX:
1233 ret = stlc45xx_rx_txack(stlc, skb);
1234 break;
1235 case LM_OID_SETUP:
1236 case LM_OID_SCAN:
1237 case LM_OID_TRAP:
1238 case LM_OID_EDCF:
1239 case LM_OID_KEYCACHE:
1240 case LM_OID_PSM:
1241 case LM_OID_STATS:
1242 case LM_OID_LED:
1243 default:
1244 stlc45xx_warning("unhandled rx control oid %d\n",
1245 control->oid);
1246 break;
1247 }
1248
1249 dev_kfree_skb(skb);
1250
1251 return ret;
1252}
1253
1254/* copied from mac80211 */
1255static void stlc45xx_parse_elems(u8 *start, size_t len,
1256 struct stlc45xx_ie_tim **tim,
1257 size_t *tim_len)
1258{
1259 size_t left = len;
1260 u8 *pos = start;
1261
1262 while (left >= 2) {
1263 u8 id, elen;
1264
1265 id = *pos++;
1266 elen = *pos++;
1267 left -= 2;
1268
1269 if (elen > left)
1270 return;
1271
1272 switch (id) {
1273 case WLAN_EID_TIM:
1274 *tim = (struct stlc45xx_ie_tim *) pos;
1275 *tim_len = elen;
1276 break;
1277 default:
1278 break;
1279 }
1280
1281 left -= elen;
1282 pos += elen;
1283 }
1284}
1285
1286/*
1287 * mac80211 doesn't have support for asking frames with PS-Poll, so let's
1288 * implement in the driver for now. We have to add support to mac80211
1289 * later.
1290 */
1291static int stlc45xx_check_more_data(struct stlc45xx *stlc, struct sk_buff *skb)
1292{
1293 struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
1294 struct ieee80211_hdr *hdr;
1295 size_t len;
1296 u16 fc;
1297
1298 hdr = (void *) skb->data + sizeof(*data);
1299 len = skb->len - sizeof(*data);
1300
1301 /* minimum frame length is the null frame length 24 bytes */
1302 if (len < 24) {
1303 stlc45xx_warning("invalid frame length when checking for "
1304 "more data");
1305 return -EINVAL;
1306 }
1307
1308 fc = le16_to_cpu(hdr->frame_control);
1309 if (!(fc & IEEE80211_FCTL_FROMDS))
1310 /* this is not from DS */
1311 return 0;
1312
1313 if (compare_ether_addr(hdr->addr1, stlc->mac_addr) != 0)
1314 /* the frame was not for us */
1315 return 0;
1316
1317 if (!(fc & IEEE80211_FCTL_MOREDATA)) {
1318 /* AP has no more frames buffered for us */
1319 stlc45xx_debug(DEBUG_PSM, "all buffered frames retrieved");
1320 stlc->pspolling = false;
1321 return 0;
1322 }
1323
1324 /* MOREDATA bit is set, let's ask for a new frame from the AP */
1325 stlc45xx_tx_pspoll(stlc, stlc->psm);
1326
1327 return 0;
1328}
1329
1330/*
1331 * mac80211 cannot read TIM from beacons, so let's add a hack to the
1332 * driver. We have to add support to mac80211 later.
1333 */
1334static int stlc45xx_rx_data_beacon(struct stlc45xx *stlc, struct sk_buff *skb)
1335{
1336 struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
1337 size_t len = skb->len, tim_len = 0, baselen, pvbmap_len;
1338 struct ieee80211_mgmt *mgmt;
1339 struct stlc45xx_ie_tim *tim = NULL;
1340 int bmap_offset, index, aid_bit;
1341
1342 mgmt = (void *) skb->data + sizeof(*data);
1343
1344 baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
1345 if (baselen > len) {
1346 stlc45xx_warning("invalid baselen in beacon");
1347 return -EINVAL;
1348 }
1349
1350 stlc45xx_parse_elems(mgmt->u.beacon.variable, len - baselen, &tim,
1351 &tim_len);
1352
1353 if (!tim) {
1354 stlc45xx_warning("didn't find tim from a beacon");
1355 return -EINVAL;
1356 }
1357
1358 bmap_offset = tim->bmap_control & 0xfe;
1359 index = stlc->aid / 8 - bmap_offset;
1360
1361 pvbmap_len = tim_len - 3;
1362 if (index > pvbmap_len)
1363 return -EINVAL;
1364
1365 aid_bit = !!(tim->pvbmap[index] & (1 << stlc->aid % 8));
1366
1367 stlc45xx_debug(DEBUG_PSM, "fc 0x%x duration %d seq %d dtim %u "
1368 "bmap_control 0x%x aid_bit %d",
1369 mgmt->frame_control, mgmt->duration, mgmt->seq_ctrl >> 4,
1370 tim->dtim_count, tim->bmap_control, aid_bit);
1371
1372 if (!aid_bit)
1373 return 0;
1374
1375 stlc->pspolling = true;
1376 stlc45xx_tx_pspoll(stlc, stlc->psm);
1377
1378 return 0;
1379}
1380
1381static int stlc45xx_rx_data(struct stlc45xx *stlc, struct sk_buff *skb)
1382{
1383 struct ieee80211_rx_status status;
1384 struct s_lm_data_in *data = (struct s_lm_data_in *) skb->data;
1385 int align = 0;
1386 u8 *p, align_len;
1387 u16 len;
1388
1389 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1390
1391 if (stlc->psm) {
1392 if (data->flags & LM_IN_BEACON)
1393 stlc45xx_rx_data_beacon(stlc, skb);
1394 else if (stlc->pspolling && (data->flags & LM_IN_DATA))
1395 stlc45xx_check_more_data(stlc, skb);
1396 }
1397
1398 memset(&status, 0, sizeof(status));
1399
1400 status.freq = data->frequency;
1401 status.signal = data->rcpi / 2 - 110;
1402
1403 /* let's assume that maximum rcpi value is 140 (= 35 dBm) */
1404 status.qual = data->rcpi * 100 / 140;
1405
1406 status.band = IEEE80211_BAND_2GHZ;
1407
1408 /*
1409 * FIXME: this gives warning from __ieee80211_rx()
1410 *
1411 * status.rate_idx = data->rate;
1412 */
1413
1414 len = data->length;
1415
1416 if (data->flags & LM_FLAG_ALIGN)
1417 align = 1;
1418
1419 skb_pull(skb, sizeof(*data));
1420
1421 if (align) {
1422 p = skb->data;
1423 align_len = *p;
1424 skb_pull(skb, align_len);
1425 }
1426
1427 skb_trim(skb, len);
1428
1429 stlc45xx_debug(DEBUG_RX, "rx data 0x%p %d B", skb->data, skb->len);
1430 stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
1431
1432 ieee80211_rx(stlc->hw, skb, &status);
1433
1434 return 0;
1435}
1436
1437
1438
1439static int stlc45xx_rx(struct stlc45xx *stlc)
1440{
1441 struct s_lm_control *control;
1442 struct sk_buff *skb;
1443 int ret;
1444 u16 len;
1445
1446 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1447
1448 stlc45xx_wakeup(stlc);
1449
1450 /* dummy read to flush SPI DMA controller bug */
1451 stlc45xx_read16(stlc, SPI_ADRS_GEN_PURP_1);
1452
1453 len = stlc45xx_read16(stlc, SPI_ADRS_DMA_DATA);
1454
1455 if (len == 0) {
1456 stlc45xx_warning("rx request of zero bytes");
1457 return 0;
1458 }
1459
1460 skb = dev_alloc_skb(len);
1461 if (!skb) {
1462 stlc45xx_warning("could not alloc skb");
1463 return 0;
1464 }
1465
1466 stlc45xx_spi_read(stlc, SPI_ADRS_DMA_DATA, skb_put(skb, len), len);
1467
1468 stlc45xx_sleep(stlc);
1469
1470 stlc45xx_debug(DEBUG_RX, "rx frame 0x%p %d B", skb->data, skb->len);
1471 stlc45xx_dump(DEBUG_RX_CONTENT, skb->data, skb->len);
1472
1473 control = (struct s_lm_control *) skb->data;
1474
1475 if (control->flags & LM_FLAG_CONTROL)
1476 ret = stlc45xx_rx_control(stlc, skb);
1477 else
1478 ret = stlc45xx_rx_data(stlc, skb);
1479
1480 return ret;
1481}
1482
1483
1484static irqreturn_t stlc45xx_interrupt(int irq, void *config)
1485{
1486 struct spi_device *spi = config;
1487 struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
1488
1489 stlc45xx_debug(DEBUG_IRQ, "IRQ");
1490
1491 queue_work(stlc->hw->workqueue, &stlc->work);
1492
1493 return IRQ_HANDLED;
1494}
1495
1496static int stlc45xx_tx_frame(struct stlc45xx *stlc, u32 address,
1497 void *buf, size_t len)
1498{
1499 struct s_dma_regs dma_regs;
1500 unsigned long timeout;
1501 int ret = 0;
1502 u32 ints;
1503
1504 stlc->tx_frames++;
1505
1506 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1507
Randy Dunlap793bccb2009-02-11 13:21:46 -08001508 stlc45xx_debug(DEBUG_TX, "tx frame 0x%p %zu B", buf, len);
Kalle Valo14c0b3e2009-01-07 22:01:20 +02001509 stlc45xx_dump(DEBUG_TX_CONTENT, buf, len);
1510
1511 stlc45xx_wakeup(stlc);
1512
1513 dma_regs.cmd = SPI_DMA_WRITE_CTRL_ENABLE;
1514 dma_regs.len = cpu_to_le16(len);
1515 dma_regs.addr = cpu_to_le32(address);
1516
1517 stlc45xx_spi_write(stlc, SPI_ADRS_DMA_WRITE_CTRL, &dma_regs,
1518 sizeof(dma_regs));
1519
1520 stlc45xx_spi_write(stlc, SPI_ADRS_DMA_DATA, buf, len);
1521
1522 timeout = jiffies + 2 * HZ;
1523 ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
1524 while (!(ints & SPI_HOST_INT_WR_READY)) {
1525 if (time_after(jiffies, timeout)) {
1526 stlc45xx_warning("WR_READY timeout");
1527 ret = -1;
1528 goto out;
1529 }
1530 ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
1531 }
1532
1533 stlc45xx_int_ack(stlc, SPI_HOST_INT_WR_READY);
1534
1535 stlc45xx_sleep(stlc);
1536
1537out:
1538 return ret;
1539}
1540
1541static int stlc45xx_wq_tx(struct stlc45xx *stlc)
1542{
1543 struct txbuffer *entry;
1544 int ret = 0;
1545
1546 spin_lock_bh(&stlc->tx_lock);
1547
1548 while (!list_empty(&stlc->tx_pending)) {
1549 entry = list_entry(stlc->tx_pending.next,
1550 struct txbuffer, tx_list);
1551
1552 list_del_init(&entry->tx_list);
1553
1554 spin_unlock_bh(&stlc->tx_lock);
1555
1556 ret = stlc45xx_tx_frame(stlc, entry->frame_start,
1557 entry->skb->data, entry->skb->len);
1558
1559 spin_lock_bh(&stlc->tx_lock);
1560
1561 if (ret < 0) {
1562 /* frame transfer to firmware buffer failed */
1563 /* FIXME: report this to mac80211 */
1564 dev_kfree_skb(entry->skb);
1565 stlc45xx_txbuffer_free(stlc, entry);
1566 goto out;
1567 }
1568
1569 list_add(&entry->tx_list, &stlc->tx_sent);
1570 queue_delayed_work(stlc->hw->workqueue,
1571 &stlc->work_tx_timeout,
1572 msecs_to_jiffies(TX_TIMEOUT));
1573 }
1574
1575out:
1576 spin_unlock_bh(&stlc->tx_lock);
1577 return ret;
1578}
1579
1580static void stlc45xx_work(struct work_struct *work)
1581{
1582 struct stlc45xx *stlc = container_of(work, struct stlc45xx, work);
1583 u32 ints;
1584 int ret;
1585
1586 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1587
1588 mutex_lock(&stlc->mutex);
1589
1590 if (stlc->fw_state == FW_STATE_OFF &&
1591 stlc->fw_state == FW_STATE_RESET)
1592 goto out;
1593
1594 ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
1595 stlc45xx_debug(DEBUG_BH, "begin host_ints 0x%08x", ints);
1596
1597 if (ints & SPI_HOST_INT_READY) {
1598 stlc45xx_int_ready(stlc);
1599 stlc45xx_int_ack(stlc, SPI_HOST_INT_READY);
1600 }
1601
1602 if (stlc->fw_state != FW_STATE_READY)
1603 goto out;
1604
1605 if (ints & SPI_HOST_INT_UPDATE) {
1606 stlc45xx_int_ack(stlc, SPI_HOST_INT_UPDATE);
1607 ret = stlc45xx_rx(stlc);
1608 if (ret < 0) {
1609 stlc45xx_reset(stlc);
1610 goto out;
1611 }
1612 }
1613 if (ints & SPI_HOST_INT_SW_UPDATE) {
1614 stlc45xx_int_ack(stlc, SPI_HOST_INT_SW_UPDATE);
1615 ret = stlc45xx_rx(stlc);
1616 if (ret < 0) {
1617 stlc45xx_reset(stlc);
1618 goto out;
1619 }
1620 }
1621
1622 ret = stlc45xx_wq_tx(stlc);
1623 if (ret < 0) {
1624 stlc45xx_reset(stlc);
1625 goto out;
1626 }
1627
1628 ints = stlc45xx_read32(stlc, SPI_ADRS_HOST_INTERRUPTS);
1629 stlc45xx_debug(DEBUG_BH, "end host_ints 0x%08x", ints);
1630
1631out:
1632 mutex_unlock(&stlc->mutex);
1633}
1634
1635static void stlc45xx_tx_edcf(struct stlc45xx *stlc)
1636{
1637 struct s_lm_control *control;
1638 struct s_lmo_edcf *edcf;
1639 size_t len, edcf_len;
1640
1641 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1642
1643 edcf_len = sizeof(*edcf);
1644 len = sizeof(*control) + edcf_len;
1645 control = kzalloc(len, GFP_KERNEL);
1646 edcf = (struct s_lmo_edcf *) (control + 1);
1647
1648 control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
1649 control->length = edcf_len;
1650 control->oid = LM_OID_EDCF;
1651
1652 edcf->slottime = 0x14;
1653 edcf->sifs = 10;
1654 edcf->eofpad = 6;
1655 edcf->maxburst = 1500;
1656
1657 edcf->queues[0].aifs = 2;
1658 edcf->queues[0].pad0 = 1;
1659 edcf->queues[0].cwmin = 3;
1660 edcf->queues[0].cwmax = 7;
1661 edcf->queues[0].txop = 47;
1662 edcf->queues[1].aifs = 2;
1663 edcf->queues[1].pad0 = 0;
1664 edcf->queues[1].cwmin = 7;
1665 edcf->queues[1].cwmax = 15;
1666 edcf->queues[1].txop = 94;
1667 edcf->queues[2].aifs = 3;
1668 edcf->queues[2].pad0 = 0;
1669 edcf->queues[2].cwmin = 15;
1670 edcf->queues[2].cwmax = 1023;
1671 edcf->queues[2].txop = 0;
1672 edcf->queues[3].aifs = 7;
1673 edcf->queues[3].pad0 = 0;
1674 edcf->queues[3].cwmin = 15;
1675 edcf->queues[3].cwmax = 1023;
1676 edcf->queues[3].txop = 0;
1677 edcf->queues[4].aifs = 13;
1678 edcf->queues[4].pad0 = 99;
1679 edcf->queues[4].cwmin = 3437;
1680 edcf->queues[4].cwmax = 512;
1681 edcf->queues[4].txop = 12;
1682 edcf->queues[5].aifs = 142;
1683 edcf->queues[5].pad0 = 109;
1684 edcf->queues[5].cwmin = 8756;
1685 edcf->queues[5].cwmax = 6;
1686 edcf->queues[5].txop = 0;
1687 edcf->queues[6].aifs = 4;
1688 edcf->queues[6].pad0 = 0;
1689 edcf->queues[6].cwmin = 0;
1690 edcf->queues[6].cwmax = 58705;
1691 edcf->queues[6].txop = 25716;
1692 edcf->queues[7].aifs = 0;
1693 edcf->queues[7].pad0 = 0;
1694 edcf->queues[7].cwmin = 0;
1695 edcf->queues[7].cwmax = 0;
1696 edcf->queues[7].txop = 0;
1697
1698 stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
1699
1700 kfree(control);
1701}
1702
1703static void stlc45xx_tx_setup(struct stlc45xx *stlc)
1704{
1705 struct s_lm_control *control;
1706 struct s_lmo_setup *setup;
1707 size_t len, setup_len;
1708
1709 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1710
1711 setup_len = sizeof(*setup);
1712 len = sizeof(*control) + setup_len;
1713 control = kzalloc(len, GFP_KERNEL);
1714 setup = (struct s_lmo_setup *) (control + 1);
1715
1716 control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
1717 control->length = setup_len;
1718 control->oid = LM_OID_SETUP;
1719
1720 setup->flags = LM_SETUP_INFRA;
1721 setup->antenna = 2;
1722 setup->rx_align = 0;
1723 setup->rx_buffer = FIRMWARE_RXBUFFER_START;
1724 setup->rx_mtu = FIRMWARE_MTU;
1725 setup->frontend = 5;
1726 setup->timeout = 0;
1727 setup->truncate = 48896;
1728 setup->bratemask = 0xffffffff;
1729 setup->ref_clock = 644245094;
1730 setup->lpf_bandwidth = 65535;
1731 setup->osc_start_delay = 65535;
1732
1733 memcpy(setup->macaddr, stlc->mac_addr, ETH_ALEN);
1734 memcpy(setup->bssid, stlc->bssid, ETH_ALEN);
1735
1736 stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
1737
1738 kfree(control);
1739}
1740
1741static void stlc45xx_tx_scan(struct stlc45xx *stlc)
1742{
1743 struct s_lm_control *control;
1744 struct s_lmo_scan *scan;
1745 size_t len, scan_len;
1746
1747 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
1748
1749 scan_len = sizeof(*scan);
1750 len = sizeof(*control) + scan_len;
1751 control = kzalloc(len, GFP_KERNEL);
1752 scan = (struct s_lmo_scan *) (control + 1);
1753
1754 control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
1755 control->length = scan_len;
1756 control->oid = LM_OID_SCAN;
1757
1758 scan->flags = LM_SCAN_EXIT;
1759 scan->bratemask = 0x15f;
1760 scan->aloft[0] = 3;
1761 scan->aloft[1] = 3;
1762 scan->aloft[2] = 1;
1763 scan->aloft[3] = 0;
1764 scan->aloft[4] = 0;
1765 scan->aloft[5] = 0;
1766 scan->aloft[6] = 0;
1767 scan->aloft[7] = 0;
1768
1769 memcpy(&scan->rssical, &stlc->cal_rssi[(stlc->channel - 1) *
1770 RSSI_CAL_LEN],
1771 RSSI_CAL_LEN);
1772 memcpy(&scan->channel, &stlc->cal_channels[(stlc->channel - 1) *
1773 CHANNEL_CAL_LEN],
1774 CHANNEL_CAL_LEN);
1775
1776 stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
1777
1778 kfree(control);
1779}
1780
1781/*
1782 * caller must hold mutex
1783 */
1784static int stlc45xx_tx_pspoll(struct stlc45xx *stlc, bool powersave)
1785{
1786 struct ieee80211_hdr *pspoll;
1787 int payload_len, padding, i;
1788 struct s_lm_data_out *data;
1789 struct txbuffer *entry;
Kalle Valo14c0b3e2009-01-07 22:01:20 +02001790 struct sk_buff *skb;
1791 char *payload;
1792 u16 fc;
1793
1794 skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 16);
1795 if (!skb) {
1796 stlc45xx_warning("failed to allocate pspoll frame");
1797 return -ENOMEM;
1798 }
1799 skb_reserve(skb, stlc->hw->extra_tx_headroom);
1800
1801 pspoll = (struct ieee80211_hdr *) skb_put(skb, 16);
1802 memset(pspoll, 0, 16);
1803 fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL;
1804 if (powersave)
1805 fc |= IEEE80211_FCTL_PM;
1806 pspoll->frame_control = cpu_to_le16(fc);
1807 pspoll->duration_id = cpu_to_le16(stlc->aid);
1808
1809 /* aid in PS-Poll has its two MSBs each set to 1 */
1810 pspoll->duration_id |= cpu_to_le16(1 << 15) | cpu_to_le16(1 << 14);
1811
1812 memcpy(pspoll->addr1, stlc->bssid, ETH_ALEN);
1813 memcpy(pspoll->addr2, stlc->mac_addr, ETH_ALEN);
1814
Alexander Beregalovf71fb772009-04-11 23:03:04 +04001815 stlc45xx_debug(DEBUG_PSM, "sending PS-Poll frame to %pM (powersave %d, "
1816 "fc 0x%x, aid %d)", pspoll->addr1,
Kalle Valo14c0b3e2009-01-07 22:01:20 +02001817 powersave, fc, stlc->aid);
1818
1819 spin_lock_bh(&stlc->tx_lock);
1820
1821 entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
1822
1823 spin_unlock_bh(&stlc->tx_lock);
1824
1825 if (!entry) {
1826 /*
1827 * The queue should be stopped before the firmware buffer
1828 * is full, so firmware buffer should always have enough
1829 * space.
1830 *
1831 * But I'm too lazy and omit it for now.
1832 */
1833 if (net_ratelimit())
1834 stlc45xx_warning("firmware tx buffer full is full "
1835 "for null frame");
1836 return -ENOSPC;
1837 }
1838
1839 payload = skb->data;
1840 payload_len = skb->len;
1841 padding = (int) (skb->data - sizeof(*data)) & 3;
1842 entry->header_len = sizeof(*data) + padding;
1843
1844 entry->skb = skb;
1845 entry->status_needed = false;
1846 entry->handle = (u32) skb;
1847 entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
1848
1849 stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
1850 "padding %d header_len %d)",
1851 entry->handle, payload, payload_len, padding,
1852 entry->header_len);
1853 stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
1854
1855 data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
1856
1857 memset(data, 0, entry->header_len);
1858
1859 if (padding)
1860 data->flags = LM_FLAG_ALIGN;
1861
1862 data->flags = LM_OUT_BURST;
1863 data->length = payload_len;
1864 data->handle = entry->handle;
1865 data->aid = 1;
1866 data->rts_retries = 7;
1867 data->retries = 7;
1868 data->aloft_ctrl = 0;
1869 data->crypt_offset = 58;
1870 data->keytype = 0;
1871 data->keylen = 0;
1872 data->queue = LM_QUEUE_DATA3;
1873 data->backlog = 32;
1874 data->antenna = 2;
1875 data->cts = 3;
1876 data->power = 127;
1877
1878 for (i = 0; i < 8; i++)
1879 data->aloft[i] = 0;
1880
1881 /*
1882 * check if there's enough space in tx buffer
1883 *
1884 * FIXME: ignored for now
1885 */
1886
1887 stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
1888
1889 list_add(&entry->tx_list, &stlc->tx_sent);
1890
1891 return 0;
1892}
1893
1894/*
1895 * caller must hold mutex
1896 *
1897 * shamelessly stolen from mac80211/ieee80211_send_nullfunc
1898 */
1899static int stlc45xx_tx_nullfunc(struct stlc45xx *stlc, bool powersave)
1900{
1901 struct ieee80211_hdr *nullfunc;
1902 int payload_len, padding, i;
1903 struct s_lm_data_out *data;
1904 struct txbuffer *entry;
Kalle Valo14c0b3e2009-01-07 22:01:20 +02001905 struct sk_buff *skb;
1906 char *payload;
1907 u16 fc;
1908
1909 skb = dev_alloc_skb(stlc->hw->extra_tx_headroom + 24);
1910 if (!skb) {
1911 stlc45xx_warning("failed to allocate buffer for null frame\n");
1912 return -ENOMEM;
1913 }
1914 skb_reserve(skb, stlc->hw->extra_tx_headroom);
1915
1916 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
1917 memset(nullfunc, 0, 24);
1918 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
1919 IEEE80211_FCTL_TODS;
1920
1921 if (powersave)
1922 fc |= IEEE80211_FCTL_PM;
1923
1924 nullfunc->frame_control = cpu_to_le16(fc);
1925 memcpy(nullfunc->addr1, stlc->bssid, ETH_ALEN);
1926 memcpy(nullfunc->addr2, stlc->mac_addr, ETH_ALEN);
1927 memcpy(nullfunc->addr3, stlc->bssid, ETH_ALEN);
1928
Alexander Beregalovf71fb772009-04-11 23:03:04 +04001929 stlc45xx_debug(DEBUG_PSM, "sending Null frame to %pM (powersave %d, "
1930 "fc 0x%x)", nullfunc->addr1, powersave, fc);
Kalle Valo14c0b3e2009-01-07 22:01:20 +02001931
1932 spin_lock_bh(&stlc->tx_lock);
1933
1934 entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
1935
1936 spin_unlock_bh(&stlc->tx_lock);
1937
1938 if (!entry) {
1939 /*
1940 * The queue should be stopped before the firmware buffer
1941 * is full, so firmware buffer should always have enough
1942 * space.
1943 *
1944 * But I'm too lazy and omit it for now.
1945 */
1946 if (net_ratelimit())
1947 stlc45xx_warning("firmware tx buffer full is full "
1948 "for null frame");
1949 return -ENOSPC;
1950 }
1951
1952 payload = skb->data;
1953 payload_len = skb->len;
1954 padding = (int) (skb->data - sizeof(*data)) & 3;
1955 entry->header_len = sizeof(*data) + padding;
1956
1957 entry->skb = skb;
1958 entry->status_needed = false;
1959 entry->handle = (u32) skb;
1960 entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
1961
1962 stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
1963 "padding %d header_len %d)",
1964 entry->handle, payload, payload_len, padding,
1965 entry->header_len);
1966 stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
1967
1968 data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
1969
1970 memset(data, 0, entry->header_len);
1971
1972 if (padding)
1973 data->flags = LM_FLAG_ALIGN;
1974
1975 data->flags = LM_OUT_BURST;
1976 data->length = payload_len;
1977 data->handle = entry->handle;
1978 data->aid = 1;
1979 data->rts_retries = 7;
1980 data->retries = 7;
1981 data->aloft_ctrl = 0;
1982 data->crypt_offset = 58;
1983 data->keytype = 0;
1984 data->keylen = 0;
1985 data->queue = LM_QUEUE_DATA3;
1986 data->backlog = 32;
1987 data->antenna = 2;
1988 data->cts = 3;
1989 data->power = 127;
1990
1991 for (i = 0; i < 8; i++)
1992 data->aloft[i] = 0;
1993
1994 /*
1995 * check if there's enough space in tx buffer
1996 *
1997 * FIXME: ignored for now
1998 */
1999
2000 stlc45xx_tx_frame(stlc, entry->start, skb->data, skb->len);
2001
2002 list_add(&entry->tx_list, &stlc->tx_sent);
2003
2004 return 0;
2005}
2006
2007/* caller must hold mutex */
2008static void stlc45xx_tx_psm(struct stlc45xx *stlc, bool enable)
2009{
2010 struct s_lm_control *control;
2011 struct s_lmo_psm *psm;
2012 size_t len, psm_len;
2013
2014 WARN_ON(!stlc->associated);
2015 WARN_ON(stlc->aid < 1);
2016 WARN_ON(stlc->aid > 2007);
2017
2018 psm_len = sizeof(*psm);
2019 len = sizeof(*control) + psm_len;
2020 control = kzalloc(len, GFP_KERNEL);
2021 psm = (struct s_lmo_psm *) (control + 1);
2022
2023 control->flags = LM_FLAG_CONTROL | LM_CTRL_OPSET;
2024 control->length = psm_len;
2025 control->oid = LM_OID_PSM;
2026
2027 if (enable)
2028 psm->flags |= LM_PSM;
2029
2030 psm->aid = stlc->aid;
2031
2032 psm->beacon_rcpi_skip_max = 60;
2033
2034 psm->intervals[0].interval = 1;
2035 psm->intervals[0].periods = 1;
2036 psm->intervals[1].interval = 1;
2037 psm->intervals[1].periods = 1;
2038 psm->intervals[2].interval = 1;
2039 psm->intervals[2].periods = 1;
2040 psm->intervals[3].interval = 1;
2041 psm->intervals[3].periods = 1;
2042
2043 psm->nr = 0;
2044 psm->exclude[0] = 0;
2045
2046 stlc45xx_debug(DEBUG_PSM, "sending LM_OID_PSM (aid %d, interval %d)",
2047 psm->aid, psm->intervals[0].interval);
2048
2049 stlc45xx_tx_frame(stlc, FIRMWARE_CONFIG_START, control, len);
2050
2051 kfree(control);
2052}
2053
2054static int stlc45xx_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2055{
2056 struct stlc45xx *stlc = hw->priv;
2057 struct ieee80211_tx_info *info;
2058 struct ieee80211_rate *rate;
2059 int payload_len, padding, i;
2060 struct s_lm_data_out *data;
2061 struct txbuffer *entry;
2062 char *payload;
2063
2064 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2065
2066 spin_lock_bh(&stlc->tx_lock);
2067
2068 entry = stlc45xx_txbuffer_alloc(stlc, skb->len);
2069 if (!entry) {
2070 /* the queue should be stopped before the firmware buffer
2071 * is full, so firmware buffer should always have enough
2072 * space */
2073 if (net_ratelimit())
2074 stlc45xx_warning("firmware buffer full");
2075 spin_unlock_bh(&stlc->tx_lock);
2076 return NETDEV_TX_BUSY;
2077 }
2078
2079 info = IEEE80211_SKB_CB(skb);
2080
2081 payload = skb->data;
2082 payload_len = skb->len;
2083 padding = (int) (skb->data - sizeof(*data)) & 3;
2084 entry->header_len = sizeof(*data) + padding;
2085
2086 entry->skb = skb;
2087 entry->status_needed = true;
2088 entry->handle = (u32) skb;
2089 entry->lifetime = jiffies + msecs_to_jiffies(TX_FRAME_LIFETIME);
2090
2091 stlc45xx_debug(DEBUG_TX, "tx data 0x%x (0x%p payload %d B "
2092 "padding %d header_len %d)",
2093 entry->handle, payload, payload_len, padding,
2094 entry->header_len);
2095 stlc45xx_dump(DEBUG_TX_CONTENT, payload, payload_len);
2096
2097 data = (struct s_lm_data_out *) skb_push(skb, entry->header_len);
2098
2099 memset(data, 0, entry->header_len);
2100
2101 if (padding)
2102 data->flags = LM_FLAG_ALIGN;
2103
2104 data->flags = LM_OUT_BURST;
2105 data->length = payload_len;
2106 data->handle = entry->handle;
2107 data->aid = 1;
2108 data->rts_retries = 7;
2109 data->retries = 7;
2110 data->aloft_ctrl = 0;
2111 data->crypt_offset = 58;
2112 data->keytype = 0;
2113 data->keylen = 0;
2114 data->queue = 2;
2115 data->backlog = 32;
2116 data->antenna = 2;
2117 data->cts = 3;
2118 data->power = 127;
2119
2120 for (i = 0; i < 8; i++) {
2121 rate = ieee80211_get_tx_rate(stlc->hw, info);
2122 data->aloft[i] = rate->hw_value;
2123 }
2124
2125 list_add_tail(&entry->tx_list, &stlc->tx_pending);
2126
2127 /* check if there's enough space in tx buffer */
2128 if (stlc45xx_txbuffer_find(stlc, MAX_FRAME_LEN) == -1) {
2129 stlc45xx_debug(DEBUG_QUEUE, "tx buffer full, stopping queues");
2130 stlc->tx_queue_stopped = 1;
2131 ieee80211_stop_queues(stlc->hw);
2132 }
2133
2134 queue_work(stlc->hw->workqueue, &stlc->work);
2135
2136 spin_unlock_bh(&stlc->tx_lock);
2137
2138 return NETDEV_TX_OK;
2139}
2140
2141static int stlc45xx_op_start(struct ieee80211_hw *hw)
2142{
2143 struct stlc45xx *stlc = hw->priv;
2144 unsigned long timeout;
2145 int ret = 0;
2146
2147 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2148
2149 mutex_lock(&stlc->mutex);
2150
2151 stlc->fw_state = FW_STATE_BOOTING;
2152 stlc->channel = 1;
2153
2154 stlc45xx_power_on(stlc);
2155
2156 ret = stlc45xx_upload_firmware(stlc);
2157 if (ret < 0) {
2158 stlc45xx_power_off(stlc);
2159 goto out_unlock;
2160 }
2161
2162 stlc->tx_queue_stopped = 0;
2163
2164 mutex_unlock(&stlc->mutex);
2165
2166 timeout = msecs_to_jiffies(2000);
2167 timeout = wait_for_completion_interruptible_timeout(&stlc->fw_comp,
2168 timeout);
2169 if (!timeout) {
2170 stlc45xx_error("firmware boot failed");
2171 stlc45xx_power_off(stlc);
2172 ret = -1;
2173 goto out;
2174 }
2175
2176 stlc45xx_debug(DEBUG_BOOT, "firmware booted");
2177
2178 /* FIXME: should we take mutex just after wait_for_completion()? */
2179 mutex_lock(&stlc->mutex);
2180
2181 WARN_ON(stlc->fw_state != FW_STATE_READY);
2182
2183out_unlock:
2184 mutex_unlock(&stlc->mutex);
2185
2186out:
2187 return ret;
2188}
2189
2190static void stlc45xx_op_stop(struct ieee80211_hw *hw)
2191{
2192 struct stlc45xx *stlc = hw->priv;
2193
2194 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2195
2196 mutex_lock(&stlc->mutex);
2197
2198 WARN_ON(stlc->fw_state != FW_STATE_READY);
2199
2200 stlc45xx_power_off(stlc);
2201
2202 /* FIXME: make sure that all work_structs have completed */
2203
2204 spin_lock_bh(&stlc->tx_lock);
2205 stlc45xx_flush_queues(stlc);
2206 spin_unlock_bh(&stlc->tx_lock);
2207
2208 stlc->fw_state = FW_STATE_OFF;
2209
2210 mutex_unlock(&stlc->mutex);
2211}
2212
2213static int stlc45xx_op_add_interface(struct ieee80211_hw *hw,
2214 struct ieee80211_if_init_conf *conf)
2215{
2216 struct stlc45xx *stlc = hw->priv;
2217
2218 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2219
2220 switch (conf->type) {
2221 case NL80211_IFTYPE_STATION:
2222 break;
2223 default:
2224 return -EOPNOTSUPP;
2225 }
2226
2227 memcpy(stlc->mac_addr, conf->mac_addr, ETH_ALEN);
2228
2229 return 0;
2230}
2231
2232static void stlc45xx_op_remove_interface(struct ieee80211_hw *hw,
2233 struct ieee80211_if_init_conf *conf)
2234{
2235 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2236}
2237
Kalle Valo14c0b3e2009-01-07 22:01:20 +02002238static int stlc45xx_op_config(struct ieee80211_hw *hw, u32 changed)
2239{
2240 struct stlc45xx *stlc = hw->priv;
2241
2242 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2243
2244 mutex_lock(&stlc->mutex);
2245
2246 stlc->channel = hw->conf.channel->hw_value;
2247 stlc45xx_tx_scan(stlc);
2248 stlc45xx_tx_setup(stlc);
2249 stlc45xx_tx_edcf(stlc);
2250
2251 if ((hw->conf.flags & IEEE80211_CONF_PS) != stlc->psm) {
2252 stlc->psm = hw->conf.flags & IEEE80211_CONF_PS;
2253 if (stlc->associated) {
2254 stlc45xx_tx_psm(stlc, stlc->psm);
2255 stlc45xx_tx_nullfunc(stlc, stlc->psm);
2256 }
2257 }
2258
2259 mutex_unlock(&stlc->mutex);
2260
2261 return 0;
2262}
2263
2264static void stlc45xx_op_configure_filter(struct ieee80211_hw *hw,
2265 unsigned int changed_flags,
2266 unsigned int *total_flags,
2267 int mc_count,
2268 struct dev_addr_list *mc_list)
2269{
2270 *total_flags = 0;
2271}
2272
2273static void stlc45xx_op_bss_info_changed(struct ieee80211_hw *hw,
2274 struct ieee80211_vif *vif,
2275 struct ieee80211_bss_conf *info,
2276 u32 changed)
2277{
2278 struct stlc45xx *stlc = hw->priv;
2279
Alexander Beregalovf6387182009-06-20 20:58:33 +04002280 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2281 mutex_lock(&stlc->mutex);
2282
2283 memcpy(stlc->bssid, info->bssid, ETH_ALEN);
2284 stlc45xx_tx_setup(stlc);
2285
2286 mutex_unlock(&stlc->mutex);
2287
Kalle Valo14c0b3e2009-01-07 22:01:20 +02002288 if (changed & BSS_CHANGED_ASSOC) {
2289 stlc->associated = info->assoc;
2290 if (info->assoc)
2291 stlc->aid = info->aid;
2292 else
2293 stlc->aid = -1;
2294
2295 if (stlc->psm) {
2296 stlc45xx_tx_psm(stlc, stlc->psm);
2297 stlc45xx_tx_nullfunc(stlc, stlc->psm);
2298 }
2299 }
2300}
2301
2302
2303/* can't be const, mac80211 writes to this */
2304static struct ieee80211_rate stlc45xx_rates[] = {
2305 { .bitrate = 10, .hw_value = 0, .hw_value_short = 0, },
2306 { .bitrate = 20, .hw_value = 1, .hw_value_short = 1, },
2307 { .bitrate = 55, .hw_value = 2, .hw_value_short = 2, },
2308 { .bitrate = 110, .hw_value = 3, .hw_value_short = 3, },
2309 { .bitrate = 60, .hw_value = 4, .hw_value_short = 4, },
2310 { .bitrate = 90, .hw_value = 5, .hw_value_short = 5, },
2311 { .bitrate = 120, .hw_value = 6, .hw_value_short = 6, },
2312 { .bitrate = 180, .hw_value = 7, .hw_value_short = 7, },
2313 { .bitrate = 240, .hw_value = 8, .hw_value_short = 8, },
2314 { .bitrate = 360, .hw_value = 9, .hw_value_short = 9, },
2315 { .bitrate = 480, .hw_value = 10, .hw_value_short = 10, },
2316 { .bitrate = 540, .hw_value = 11, .hw_value_short = 11, },
2317};
2318
2319/* can't be const, mac80211 writes to this */
2320static struct ieee80211_channel stlc45xx_channels[] = {
2321 { .hw_value = 1, .center_freq = 2412},
2322 { .hw_value = 2, .center_freq = 2417},
2323 { .hw_value = 3, .center_freq = 2422},
2324 { .hw_value = 4, .center_freq = 2427},
2325 { .hw_value = 5, .center_freq = 2432},
2326 { .hw_value = 6, .center_freq = 2437},
2327 { .hw_value = 7, .center_freq = 2442},
2328 { .hw_value = 8, .center_freq = 2447},
2329 { .hw_value = 9, .center_freq = 2452},
2330 { .hw_value = 10, .center_freq = 2457},
2331 { .hw_value = 11, .center_freq = 2462},
2332 { .hw_value = 12, .center_freq = 2467},
2333 { .hw_value = 13, .center_freq = 2472},
2334};
2335
2336/* can't be const, mac80211 writes to this */
2337static struct ieee80211_supported_band stlc45xx_band_2ghz = {
2338 .channels = stlc45xx_channels,
2339 .n_channels = ARRAY_SIZE(stlc45xx_channels),
2340 .bitrates = stlc45xx_rates,
2341 .n_bitrates = ARRAY_SIZE(stlc45xx_rates),
2342};
2343
2344static const struct ieee80211_ops stlc45xx_ops = {
2345 .start = stlc45xx_op_start,
2346 .stop = stlc45xx_op_stop,
2347 .add_interface = stlc45xx_op_add_interface,
2348 .remove_interface = stlc45xx_op_remove_interface,
2349 .config = stlc45xx_op_config,
Kalle Valo14c0b3e2009-01-07 22:01:20 +02002350 .configure_filter = stlc45xx_op_configure_filter,
2351 .tx = stlc45xx_op_tx,
2352 .bss_info_changed = stlc45xx_op_bss_info_changed,
2353};
2354
2355static int stlc45xx_register_mac80211(struct stlc45xx *stlc)
2356{
2357 /* FIXME: SET_IEEE80211_PERM_ADDR() requires default_mac_addr
2358 to be non-const for some strange reason */
2359 static u8 default_mac_addr[ETH_ALEN] = {
2360 0x00, 0x02, 0xee, 0xc0, 0xff, 0xee
2361 };
2362 int ret;
2363
2364 SET_IEEE80211_PERM_ADDR(stlc->hw, default_mac_addr);
2365
2366 ret = ieee80211_register_hw(stlc->hw);
2367 if (ret) {
2368 stlc45xx_error("unable to register mac80211 hw: %d", ret);
2369 return ret;
2370 }
2371
2372 return 0;
2373}
2374
2375static void stlc45xx_device_release(struct device *dev)
2376{
2377
2378}
2379
2380static struct platform_device stlc45xx_device = {
2381 .name = "stlc45xx",
2382 .id = -1,
2383
2384 /* device model insists to have a release function */
2385 .dev = {
2386 .release = stlc45xx_device_release,
2387 },
2388};
2389
2390static int __devinit stlc45xx_probe(struct spi_device *spi)
2391{
2392 struct stlc45xx *stlc;
2393 struct ieee80211_hw *hw;
2394 int ret;
2395
2396 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2397
2398 /* mac80211 alloc */
2399 hw = ieee80211_alloc_hw(sizeof(*stlc), &stlc45xx_ops);
2400 if (!hw) {
2401 stlc45xx_error("could not alloc ieee80211_hw");
2402 ret = -ENOMEM;
2403 goto out;
2404 }
2405
2406 /* mac80211 clears hw->priv */
2407 stlc = hw->priv;
2408
2409 stlc->hw = hw;
2410 dev_set_drvdata(&spi->dev, stlc);
2411 stlc->spi = spi;
2412
2413 spi->bits_per_word = 16;
2414 spi->max_speed_hz = 24000000;
2415
2416 ret = spi_setup(spi);
2417 if (ret < 0)
2418 stlc45xx_error("spi_setup failed");
2419
2420 ret = gpio_request(stlc45xx_gpio_power, "stlc45xx power");
2421 if (ret < 0) {
2422 stlc45xx_error("power GPIO request failed: %d", ret);
2423 return ret;
2424 }
2425
2426 ret = gpio_request(stlc45xx_gpio_irq, "stlc45xx irq");
2427 if (ret < 0) {
2428 stlc45xx_error("irq GPIO request failed: %d", ret);
2429 goto out;
2430 }
2431
2432 gpio_direction_output(stlc45xx_gpio_power, 0);
2433 gpio_direction_input(stlc45xx_gpio_irq);
2434
2435 ret = request_irq(gpio_to_irq(stlc45xx_gpio_irq),
2436 stlc45xx_interrupt, IRQF_DISABLED, "stlc45xx",
2437 stlc->spi);
2438 if (ret < 0)
2439 /* FIXME: handle the error */
2440 stlc45xx_error("request_irq() failed");
2441
2442 set_irq_type(gpio_to_irq(stlc45xx_gpio_irq),
2443 IRQ_TYPE_EDGE_RISING);
2444
2445 disable_irq(gpio_to_irq(stlc45xx_gpio_irq));
2446
2447 ret = platform_device_register(&stlc45xx_device);
2448 if (ret) {
2449 stlc45xx_error("Couldn't register wlan_omap device.");
2450 return ret;
2451 }
2452 dev_set_drvdata(&stlc45xx_device.dev, stlc);
2453
2454 INIT_WORK(&stlc->work, stlc45xx_work);
2455 INIT_WORK(&stlc->work_reset, stlc45xx_work_reset);
2456 INIT_DELAYED_WORK(&stlc->work_tx_timeout, stlc45xx_work_tx_timeout);
2457 mutex_init(&stlc->mutex);
2458 init_completion(&stlc->fw_comp);
2459 spin_lock_init(&stlc->tx_lock);
2460 INIT_LIST_HEAD(&stlc->txbuffer);
2461 INIT_LIST_HEAD(&stlc->tx_pending);
2462 INIT_LIST_HEAD(&stlc->tx_sent);
2463
2464 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
2465 IEEE80211_HW_SIGNAL_DBM |
2466 IEEE80211_HW_NOISE_DBM;
2467 /* four bytes for padding */
2468 hw->extra_tx_headroom = sizeof(struct s_lm_data_out) + 4;
2469
2470 /* unit us */
2471 hw->channel_change_time = 1000;
2472
2473 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
2474 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &stlc45xx_band_2ghz;
2475
2476 SET_IEEE80211_DEV(hw, &spi->dev);
2477
2478 BUILD_BUG_ON(sizeof(default_cal_rssi) != RSSI_CAL_ARRAY_LEN);
2479 BUILD_BUG_ON(sizeof(default_cal_channels) != CHANNEL_CAL_ARRAY_LEN);
2480
2481 stlc->cal_rssi = kmemdup(default_cal_rssi, RSSI_CAL_ARRAY_LEN,
2482 GFP_KERNEL);
2483 stlc->cal_channels = kmemdup(default_cal_channels,
2484 CHANNEL_CAL_ARRAY_LEN,
2485 GFP_KERNEL);
2486
2487 ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_rssi);
2488 if (ret < 0) {
2489 stlc45xx_error("failed to create sysfs file cal_rssi");
2490 goto out;
2491 }
2492
2493 ret = device_create_file(&stlc45xx_device.dev, &dev_attr_cal_channels);
2494 if (ret < 0) {
2495 stlc45xx_error("failed to create sysfs file cal_channels");
2496 goto out;
2497 }
2498
2499 ret = device_create_file(&stlc45xx_device.dev, &dev_attr_tx_buf);
2500 if (ret < 0) {
2501 stlc45xx_error("failed to create sysfs file tx_buf");
2502 goto out;
2503 }
2504
2505 ret = stlc45xx_register_mac80211(stlc);
2506 if (ret < 0)
2507 goto out;
2508
2509 stlc45xx_info("v" DRIVER_VERSION " loaded");
2510
2511 stlc45xx_info("config buffer 0x%x-0x%x",
2512 FIRMWARE_CONFIG_START, FIRMWARE_CONFIG_END);
2513 stlc45xx_info("tx 0x%x-0x%x, rx 0x%x-0x%x",
2514 FIRMWARE_TXBUFFER_START, FIRMWARE_TXBUFFER_END,
2515 FIRMWARE_RXBUFFER_START, FIRMWARE_RXBUFFER_END);
2516
2517out:
2518 return ret;
2519}
2520
2521static int __devexit stlc45xx_remove(struct spi_device *spi)
2522{
2523 struct stlc45xx *stlc = dev_get_drvdata(&spi->dev);
2524
2525 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2526
2527 platform_device_unregister(&stlc45xx_device);
2528
2529 ieee80211_unregister_hw(stlc->hw);
2530
2531 free_irq(gpio_to_irq(stlc45xx_gpio_irq), spi);
2532
2533 gpio_free(stlc45xx_gpio_power);
2534 gpio_free(stlc45xx_gpio_irq);
2535
2536 /* FIXME: free cal_channels and cal_rssi? */
2537
2538 kfree(stlc->fw);
2539
2540 mutex_destroy(&stlc->mutex);
2541
2542 /* frees also stlc */
2543 ieee80211_free_hw(stlc->hw);
2544 stlc = NULL;
2545
2546 return 0;
2547}
2548
2549
2550static struct spi_driver stlc45xx_spi_driver = {
2551 .driver = {
2552 /* use cx3110x name because board-n800.c uses that for the
2553 * SPI port */
2554 .name = "cx3110x",
2555 .bus = &spi_bus_type,
2556 .owner = THIS_MODULE,
2557 },
2558
2559 .probe = stlc45xx_probe,
2560 .remove = __devexit_p(stlc45xx_remove),
2561};
2562
2563static int __init stlc45xx_init(void)
2564{
2565 int ret;
2566
2567 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2568
2569 ret = spi_register_driver(&stlc45xx_spi_driver);
2570 if (ret < 0) {
2571 stlc45xx_error("failed to register SPI driver: %d", ret);
2572 goto out;
2573 }
2574
2575out:
2576 return ret;
2577}
2578
2579static void __exit stlc45xx_exit(void)
2580{
2581 stlc45xx_debug(DEBUG_FUNC, "%s", __func__);
2582
2583 spi_unregister_driver(&stlc45xx_spi_driver);
2584
2585 stlc45xx_info("unloaded");
2586}
2587
2588module_init(stlc45xx_init);
2589module_exit(stlc45xx_exit);
2590
2591MODULE_LICENSE("GPL");
2592MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");