2 * This file is part of stlc45xx
4 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
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.
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.
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
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>
37 #include "stlc45xx_lmac.h"
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
44 static int stlc45xx_gpio_power
= 97;
45 module_param(stlc45xx_gpio_power
, int, 0444);
46 MODULE_PARM_DESC(stlc45xx_gpio_power
, "stlc45xx gpio number for power line");
48 static int stlc45xx_gpio_irq
= 87;
49 module_param(stlc45xx_gpio_irq
, int, 0444);
50 MODULE_PARM_DESC(stlc45xx_gpio_irq
, "stlc45xx gpio number for irq line");
52 static 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,
400 static 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 };
412 static void stlc45xx_tx_edcf(struct stlc45xx
*stlc
);
413 static void stlc45xx_tx_setup(struct stlc45xx
*stlc
);
414 static void stlc45xx_tx_scan(struct stlc45xx
*stlc
);
415 static void stlc45xx_tx_psm(struct stlc45xx
*stlc
, bool enable
);
416 static int stlc45xx_tx_nullfunc(struct stlc45xx
*stlc
, bool powersave
);
417 static int stlc45xx_tx_pspoll(struct stlc45xx
*stlc
, bool powersave
);
419 static ssize_t
stlc45xx_sysfs_show_cal_rssi(struct device
*dev
,
420 struct device_attribute
*attr
,
423 struct stlc45xx
*stlc
= dev_get_drvdata(dev
);
426 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
430 mutex_lock(&stlc
->mutex
);
433 hex_dump_to_buffer(stlc
->cal_rssi
, RSSI_CAL_ARRAY_LEN
, 16,
435 mutex_unlock(&stlc
->mutex
);
442 static ssize_t
stlc45xx_sysfs_store_cal_rssi(struct device
*dev
,
443 struct device_attribute
*attr
,
444 const char *buf
, size_t count
)
446 struct stlc45xx
*stlc
= dev_get_drvdata(dev
);
448 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
450 mutex_lock(&stlc
->mutex
);
452 if (count
!= RSSI_CAL_ARRAY_LEN
) {
453 stlc45xx_error("invalid cal_rssi length: %zu", count
);
458 kfree(stlc
->cal_rssi
);
460 stlc
->cal_rssi
= kmemdup(buf
, RSSI_CAL_ARRAY_LEN
, GFP_KERNEL
);
462 if (!stlc
->cal_rssi
) {
463 stlc45xx_error("failed to allocate memory for cal_rssi");
469 mutex_unlock(&stlc
->mutex
);
474 static ssize_t
stlc45xx_sysfs_show_cal_channels(struct device
*dev
,
475 struct device_attribute
*attr
,
478 struct stlc45xx
*stlc
= dev_get_drvdata(dev
);
481 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
485 mutex_lock(&stlc
->mutex
);
487 if (stlc
->cal_channels
)
488 hex_dump_to_buffer(stlc
->cal_channels
, CHANNEL_CAL_ARRAY_LEN
,
491 mutex_unlock(&stlc
->mutex
);
498 static ssize_t
stlc45xx_sysfs_store_cal_channels(struct device
*dev
,
499 struct device_attribute
*attr
,
500 const char *buf
, size_t count
)
502 struct stlc45xx
*stlc
= dev_get_drvdata(dev
);
504 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
506 mutex_lock(&stlc
->mutex
);
508 if (count
!= CHANNEL_CAL_ARRAY_LEN
) {
509 stlc45xx_error("invalid cal_channels size: %zu ", count
);
514 kfree(stlc
->cal_channels
);
516 stlc
->cal_channels
= kmemdup(buf
, count
, GFP_KERNEL
);
518 if (!stlc
->cal_channels
) {
519 stlc45xx_error("failed to allocate memory for cal_channels");
525 mutex_unlock(&stlc
->mutex
);
530 static ssize_t
stlc45xx_sysfs_show_tx_buf(struct device
*dev
,
531 struct device_attribute
*attr
,
534 struct stlc45xx
*stlc
= dev_get_drvdata(dev
);
535 struct txbuffer
*entry
;
538 stlc45xx_debug(DEBUG_FUNC
, "%s()", __func__
);
540 mutex_lock(&stlc
->mutex
);
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
,
548 mutex_unlock(&stlc
->mutex
);
553 static DEVICE_ATTR(cal_rssi
, S_IRUGO
| S_IWUSR
,
554 stlc45xx_sysfs_show_cal_rssi
,
555 stlc45xx_sysfs_store_cal_rssi
);
556 static DEVICE_ATTR(cal_channels
, S_IRUGO
| S_IWUSR
,
557 stlc45xx_sysfs_show_cal_channels
,
558 stlc45xx_sysfs_store_cal_channels
);
559 static DEVICE_ATTR(tx_buf
, S_IRUGO
, stlc45xx_sysfs_show_tx_buf
, NULL
);
561 static void stlc45xx_spi_read(struct stlc45xx
*stlc
, unsigned long addr
,
562 void *buf
, size_t len
)
564 struct spi_transfer t
[2];
565 struct spi_message m
;
567 /* We first push the address */
568 addr
= (addr
<< 8) | ADDR_READ_BIT_15
;
570 spi_message_init(&m
);
571 memset(t
, 0, sizeof(t
));
575 spi_message_add_tail(&t
[0], &m
);
579 spi_message_add_tail(&t
[1], &m
);
581 spi_sync(stlc
->spi
, &m
);
585 static void stlc45xx_spi_write(struct stlc45xx
*stlc
, unsigned long addr
,
586 void *buf
, size_t len
)
588 struct spi_transfer t
[3];
589 struct spi_message m
;
592 /* We first push the address */
595 spi_message_init(&m
);
596 memset(t
, 0, sizeof(t
));
600 spi_message_add_tail(&t
[0], &m
);
604 spi_message_add_tail(&t
[1], &m
);
607 last_word
= ((u8
*)buf
)[len
- 1];
609 t
[2].tx_buf
= &last_word
;
611 spi_message_add_tail(&t
[2], &m
);
614 spi_sync(stlc
->spi
, &m
);
617 static u16
stlc45xx_read16(struct stlc45xx
*stlc
, unsigned long addr
)
621 stlc45xx_spi_read(stlc
, addr
, &val
, sizeof(val
));
626 static u32
stlc45xx_read32(struct stlc45xx
*stlc
, unsigned long addr
)
630 stlc45xx_spi_read(stlc
, addr
, &val
, sizeof(val
));
635 static void stlc45xx_write16(struct stlc45xx
*stlc
, unsigned long addr
, u16 val
)
637 stlc45xx_spi_write(stlc
, addr
, &val
, sizeof(val
));
640 static void stlc45xx_write32(struct stlc45xx
*stlc
, unsigned long addr
, u32 val
)
642 stlc45xx_spi_write(stlc
, addr
, &val
, sizeof(val
));
645 struct stlc45xx_spi_reg
{
651 /* caller must hold tx_lock */
652 static void stlc45xx_txbuffer_dump(struct stlc45xx
*stlc
)
654 struct txbuffer
*txbuffer
;
656 int buf_len
, l
, count
;
658 if (!(DEBUG_LEVEL
& DEBUG_TXBUFFER
))
661 stlc45xx_debug(DEBUG_FUNC
, "%s()", __func__
);
664 buf
= kmalloc(buf_len
, GFP_ATOMIC
);
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 */
685 stlc45xx_debug(DEBUG_TXBUFFER
, "txbuffer: in buffer %d regions: %s",
691 /* caller must hold tx_lock */
692 static int stlc45xx_txbuffer_find(struct stlc45xx
*stlc
, size_t len
)
694 struct txbuffer
*txbuffer
;
697 stlc45xx_debug(DEBUG_FUNC
, "%s()", __func__
);
699 pos
= FIRMWARE_TXBUFFER_START
;
701 if (list_empty(&stlc
->txbuffer
))
705 * the entries in txbuffer must be in the same order as they are in
708 list_for_each_entry(txbuffer
, &stlc
->txbuffer
, buffer_list
) {
709 if (pos
+ len
< txbuffer
->start
)
711 pos
= ALIGN(txbuffer
->end
+ 1, 4);
714 if (pos
+ len
> FIRMWARE_TXBUFFER_END
)
715 /* not enough room */
718 stlc45xx_debug(DEBUG_TXBUFFER
, "txbuffer: find %zu B: 0x%x", len
, pos
);
724 static int stlc45xx_txbuffer_add(struct stlc45xx
*stlc
,
725 struct txbuffer
*txbuffer
)
727 struct txbuffer
*r
, *prev
= NULL
;
729 if (list_empty(&stlc
->txbuffer
)) {
730 list_add(&txbuffer
->buffer_list
, &stlc
->txbuffer
);
734 r
= list_first_entry(&stlc
->txbuffer
, struct txbuffer
, buffer_list
);
736 if (txbuffer
->start
< r
->start
) {
737 /* add to the beginning of the list */
738 list_add(&txbuffer
->buffer_list
, &stlc
->txbuffer
);
743 list_for_each_entry(r
, &stlc
->txbuffer
, buffer_list
) {
744 /* skip first entry, we checked for that above */
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
);
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
);
767 list_add_tail(&txbuffer
->buffer_list
, &stlc
->txbuffer
);
773 /* caller must hold tx_lock */
774 static struct txbuffer
*stlc45xx_txbuffer_alloc(struct stlc45xx
*stlc
,
777 struct txbuffer
*entry
= NULL
;
781 stlc45xx_debug(DEBUG_FUNC
, "%s()", __func__
);
783 len
= FIRMWARE_TXBUFFER_HEADER
+ frame_len
+ FIRMWARE_TXBUFFER_TRAILER
;
784 pos
= stlc45xx_txbuffer_find(stlc
, len
);
789 WARN_ON_ONCE(pos
+ len
> FIRMWARE_TXBUFFER_END
);
790 WARN_ON_ONCE(pos
< FIRMWARE_TXBUFFER_START
);
792 entry
= kmalloc(sizeof(*entry
), GFP_ATOMIC
);
794 entry
->frame_start
= pos
+ FIRMWARE_TXBUFFER_HEADER
;
795 entry
->end
= entry
->start
+ len
- 1;
797 stlc45xx_debug(DEBUG_TXBUFFER
, "txbuffer: allocated 0x%x-0x%x",
798 entry
->start
, entry
->end
);
800 stlc45xx_txbuffer_add(stlc
, entry
);
802 stlc45xx_txbuffer_dump(stlc
);
807 /* caller must hold tx_lock */
808 static void stlc45xx_txbuffer_free(struct stlc45xx
*stlc
,
809 struct txbuffer
*txbuffer
)
811 stlc45xx_debug(DEBUG_FUNC
, "%s()", __func__
);
813 stlc45xx_debug(DEBUG_TXBUFFER
, "txbuffer: freed 0x%x-0x%x",
814 txbuffer
->start
, txbuffer
->end
);
816 list_del(&txbuffer
->buffer_list
);
821 static int stlc45xx_wait_bit(struct stlc45xx
*stlc
, u16 reg
, u32 mask
,
827 for (i
= 0; i
< 2000; i
++) {
828 stlc45xx_spi_read(stlc
, reg
, buffer
, sizeof(buffer
));
829 if (((*(u32
*)buffer
) & mask
) == expected
)
837 static int stlc45xx_request_firmware(struct stlc45xx
*stlc
)
839 const struct firmware
*fw
;
842 /* FIXME: should driver use it's own struct device? */
843 ret
= request_firmware(&fw
, "3826.arm", &stlc
->spi
->dev
);
846 stlc45xx_error("request_firmware() failed: %d", ret
);
851 stlc45xx_error("firmware size is not multiple of 32bit: %zu",
853 return -EILSEQ
; /* Illegal byte sequence */;
856 if (fw
->size
< 1000) {
857 stlc45xx_error("firmware is too small: %zu", fw
->size
);
861 stlc
->fw
= kmemdup(fw
->data
, fw
->size
, GFP_KERNEL
);
863 stlc45xx_error("could not allocate memory for firmware");
867 stlc
->fw_len
= fw
->size
;
869 release_firmware(fw
);
874 static int stlc45xx_upload_firmware(struct stlc45xx
*stlc
)
876 struct s_dma_regs dma_regs
;
877 unsigned long fw_len
, fw_addr
;
881 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
884 ret
= stlc45xx_request_firmware(stlc
);
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
);
894 msleep(TARGET_BOOT_SLEEP
);
896 stlc45xx_write16(stlc
, SPI_ADRS_DEV_CTRL_STAT
,
897 SPI_CTRL_STAT_HOST_OVERRIDE
898 | SPI_CTRL_STAT_START_HALTED
);
900 msleep(TARGET_BOOT_SLEEP
);
902 fw_addr
= FIRMWARE_ADDRESS
;
903 fw_len
= stlc
->fw_len
;
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
);
915 stlc45xx_write16(stlc
, SPI_ADRS_DMA_WRITE_CTRL
, dma_regs
.cmd
);
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");
923 stlc45xx_write16(stlc
, SPI_ADRS_DMA_WRITE_LEN
, dma_regs
.len
);
924 stlc45xx_write32(stlc
, SPI_ADRS_DMA_WRITE_BASE
, dma_regs
.addr
);
926 stlc45xx_spi_write(stlc
, SPI_ADRS_DMA_DATA
, stlc
->fw
, _fw_len
);
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! */
935 /* enable host interrupts */
936 stlc45xx_write32(stlc
, SPI_ADRS_HOST_INT_EN
, SPI_HOST_INTS_DEFAULT
);
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
);
943 msleep(TARGET_BOOT_SLEEP
);
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
);
952 /* caller must hold tx_lock */
953 static void stlc45xx_check_txsent(struct stlc45xx
*stlc
)
955 struct txbuffer
*entry
, *n
;
957 list_for_each_entry_safe(entry
, n
, &stlc
->tx_sent
, tx_list
) {
958 if (time_after(jiffies
, entry
->lifetime
)) {
960 stlc45xx_warning("frame 0x%x lifetime exceeded",
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
);
970 static void stlc45xx_power_off(struct stlc45xx
*stlc
)
972 disable_irq(gpio_to_irq(stlc45xx_gpio_irq
));
973 gpio_set_value(stlc45xx_gpio_power
, 0);
976 static void stlc45xx_power_on(struct stlc45xx
*stlc
)
978 gpio_set_value(stlc45xx_gpio_power
, 1);
979 enable_irq(gpio_to_irq(stlc45xx_gpio_irq
));
982 * need to wait a while before device can be accessed, the length
988 /* caller must hold tx_lock */
989 static void stlc45xx_flush_queues(struct stlc45xx
*stlc
)
991 struct txbuffer
*entry
;
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
);
1001 WARN_ON(!list_empty(&stlc
->tx_sent
));
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
);
1011 WARN_ON(!list_empty(&stlc
->tx_pending
));
1012 WARN_ON(!list_empty(&stlc
->txbuffer
));
1015 static void stlc45xx_work_reset(struct work_struct
*work
)
1017 struct stlc45xx
*stlc
= container_of(work
, struct stlc45xx
,
1020 mutex_lock(&stlc
->mutex
);
1022 if (stlc
->fw_state
!= FW_STATE_RESET
)
1025 stlc45xx_power_off(stlc
);
1027 mutex_unlock(&stlc
->mutex
);
1029 /* wait that all work_structs have finished, we can't hold
1030 * stlc->mutex to avoid deadlock */
1031 cancel_work_sync(&stlc
->work
);
1033 /* FIXME: find out good value to wait for chip power down */
1036 mutex_lock(&stlc
->mutex
);
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
);
1042 spin_lock_bh(&stlc
->tx_lock
);
1043 stlc45xx_flush_queues(stlc
);
1044 spin_unlock_bh(&stlc
->tx_lock
);
1046 stlc
->fw_state
= FW_STATE_RESETTING
;
1048 stlc45xx_power_on(stlc
);
1049 stlc45xx_upload_firmware(stlc
);
1052 mutex_unlock(&stlc
->mutex
);
1055 /* caller must hold mutex */
1056 static void stlc45xx_reset(struct stlc45xx
*stlc
)
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
);
1064 static void stlc45xx_work_tx_timeout(struct work_struct
*work
)
1066 struct stlc45xx
*stlc
= container_of(work
, struct stlc45xx
,
1067 work_tx_timeout
.work
);
1069 stlc45xx_warning("tx timeout");
1071 mutex_lock(&stlc
->mutex
);
1073 if (stlc
->fw_state
!= FW_STATE_READY
)
1076 stlc45xx_reset(stlc
);
1079 mutex_unlock(&stlc
->mutex
);
1082 static void stlc45xx_int_ack(struct stlc45xx
*stlc
, u32 val
)
1084 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
1086 stlc45xx_write32(stlc
, SPI_ADRS_HOST_INT_ACK
, val
);
1089 static void stlc45xx_wakeup(struct stlc45xx
*stlc
)
1091 unsigned long timeout
;
1094 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
1097 stlc45xx_write32(stlc
, SPI_ADRS_ARM_INTERRUPTS
, SPI_TARGET_INT_WAKEUP
);
1099 /* And wait for the READY interrupt */
1100 timeout
= jiffies
+ HZ
;
1102 ints
= stlc45xx_read32(stlc
, SPI_ADRS_HOST_INTERRUPTS
);
1103 while (!(ints
& SPI_HOST_INT_READY
)) {
1104 if (time_after(jiffies
, timeout
))
1106 ints
= stlc45xx_read32(stlc
, SPI_ADRS_HOST_INTERRUPTS
);
1109 stlc45xx_int_ack(stlc
, SPI_HOST_INT_READY
);
1115 static void stlc45xx_sleep(struct stlc45xx
*stlc
)
1117 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
1119 stlc45xx_write32(stlc
, SPI_ADRS_ARM_INTERRUPTS
, SPI_TARGET_INT_SLEEP
);
1122 static void stlc45xx_int_ready(struct stlc45xx
*stlc
)
1124 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
1126 stlc45xx_write32(stlc
, SPI_ADRS_HOST_INT_EN
,
1127 SPI_HOST_INT_UPDATE
| SPI_HOST_INT_SW_UPDATE
);
1129 switch (stlc
->fw_state
) {
1130 case FW_STATE_BOOTING
:
1131 stlc
->fw_state
= FW_STATE_READY
;
1132 complete(&stlc
->fw_comp
);
1134 case FW_STATE_RESETTING
:
1135 stlc
->fw_state
= FW_STATE_READY
;
1137 stlc45xx_tx_scan(stlc
);
1138 stlc45xx_tx_setup(stlc
);
1139 stlc45xx_tx_edcf(stlc
);
1141 ieee80211_wake_queues(stlc
->hw
);
1148 static int stlc45xx_rx_txack(struct stlc45xx
*stlc
, struct sk_buff
*skb
)
1150 struct ieee80211_tx_info
*info
;
1151 struct s_lm_control
*control
;
1152 struct s_lmo_tx
*tx
;
1153 struct txbuffer
*entry
;
1156 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
1158 control
= (struct s_lm_control
*) skb
->data
;
1159 tx
= (struct s_lmo_tx
*) (control
+ 1);
1161 if (list_empty(&stlc
->tx_sent
)) {
1162 if (net_ratelimit())
1163 stlc45xx_warning("no frames waiting for "
1168 list_for_each_entry(entry
, &stlc
->tx_sent
, tx_list
) {
1169 if (control
->handle
== entry
->handle
) {
1176 if (net_ratelimit())
1177 stlc45xx_warning("couldn't find frame for tx ack 0x%x",
1182 stlc45xx_debug(DEBUG_TX
, "TX ACK 0x%x", entry
->handle
);
1184 if (entry
->status_needed
) {
1185 info
= IEEE80211_SKB_CB(entry
->skb
);
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;
1193 skb_pull(entry
->skb
, entry
->header_len
);
1195 ieee80211_tx_status(stlc
->hw
, entry
->skb
);
1198 list_del(&entry
->tx_list
);
1200 stlc45xx_check_txsent(stlc
);
1201 if (list_empty(&stlc
->tx_sent
))
1202 /* there are no pending frames, we can stop the tx timeout
1204 cancel_delayed_work(&stlc
->work_tx_timeout
);
1206 spin_lock_bh(&stlc
->tx_lock
);
1208 stlc45xx_txbuffer_free(stlc
, entry
);
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;
1217 spin_unlock_bh(&stlc
->tx_lock
);
1222 static int stlc45xx_rx_control(struct stlc45xx
*stlc
, struct sk_buff
*skb
)
1224 struct s_lm_control
*control
;
1227 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
1229 control
= (struct s_lm_control
*) skb
->data
;
1231 switch (control
->oid
) {
1233 ret
= stlc45xx_rx_txack(stlc
, skb
);
1239 case LM_OID_KEYCACHE
:
1244 stlc45xx_warning("unhandled rx control oid %d\n",
1254 /* copied from mac80211 */
1255 static void stlc45xx_parse_elems(u8
*start
, size_t len
,
1256 struct stlc45xx_ie_tim
**tim
,
1274 *tim
= (struct stlc45xx_ie_tim
*) pos
;
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
1291 static int stlc45xx_check_more_data(struct stlc45xx
*stlc
, struct sk_buff
*skb
)
1293 struct s_lm_data_in
*data
= (struct s_lm_data_in
*) skb
->data
;
1294 struct ieee80211_hdr
*hdr
;
1298 hdr
= (void *) skb
->data
+ sizeof(*data
);
1299 len
= skb
->len
- sizeof(*data
);
1301 /* minimum frame length is the null frame length 24 bytes */
1303 stlc45xx_warning("invalid frame length when checking for "
1308 fc
= le16_to_cpu(hdr
->frame_control
);
1309 if (!(fc
& IEEE80211_FCTL_FROMDS
))
1310 /* this is not from DS */
1313 if (compare_ether_addr(hdr
->addr1
, stlc
->mac_addr
) != 0)
1314 /* the frame was not for us */
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;
1324 /* MOREDATA bit is set, let's ask for a new frame from the AP */
1325 stlc45xx_tx_pspoll(stlc
, stlc
->psm
);
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.
1334 static int stlc45xx_rx_data_beacon(struct stlc45xx
*stlc
, struct sk_buff
*skb
)
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
;
1342 mgmt
= (void *) skb
->data
+ sizeof(*data
);
1344 baselen
= (u8
*) mgmt
->u
.beacon
.variable
- (u8
*) mgmt
;
1345 if (baselen
> len
) {
1346 stlc45xx_warning("invalid baselen in beacon");
1350 stlc45xx_parse_elems(mgmt
->u
.beacon
.variable
, len
- baselen
, &tim
,
1354 stlc45xx_warning("didn't find tim from a beacon");
1358 bmap_offset
= tim
->bmap_control
& 0xfe;
1359 index
= stlc
->aid
/ 8 - bmap_offset
;
1361 pvbmap_len
= tim_len
- 3;
1362 if (index
> pvbmap_len
)
1365 aid_bit
= !!(tim
->pvbmap
[index
] & (1 << stlc
->aid
% 8));
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
);
1375 stlc
->pspolling
= true;
1376 stlc45xx_tx_pspoll(stlc
, stlc
->psm
);
1381 static int stlc45xx_rx_data(struct stlc45xx
*stlc
, struct sk_buff
*skb
)
1383 struct ieee80211_rx_status status
;
1384 struct s_lm_data_in
*data
= (struct s_lm_data_in
*) skb
->data
;
1389 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
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
);
1398 memset(&status
, 0, sizeof(status
));
1400 status
.freq
= data
->frequency
;
1401 status
.signal
= data
->rcpi
/ 2 - 110;
1403 /* let's assume that maximum rcpi value is 140 (= 35 dBm) */
1404 status
.qual
= data
->rcpi
* 100 / 140;
1406 status
.band
= IEEE80211_BAND_2GHZ
;
1409 * FIXME: this gives warning from __ieee80211_rx()
1411 * status.rate_idx = data->rate;
1416 if (data
->flags
& LM_FLAG_ALIGN
)
1419 skb_pull(skb
, sizeof(*data
));
1424 skb_pull(skb
, align_len
);
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
);
1432 ieee80211_rx(stlc
->hw
, skb
, &status
);
1439 static int stlc45xx_rx(struct stlc45xx
*stlc
)
1441 struct s_lm_control
*control
;
1442 struct sk_buff
*skb
;
1446 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
1448 stlc45xx_wakeup(stlc
);
1450 /* dummy read to flush SPI DMA controller bug */
1451 stlc45xx_read16(stlc
, SPI_ADRS_GEN_PURP_1
);
1453 len
= stlc45xx_read16(stlc
, SPI_ADRS_DMA_DATA
);
1456 stlc45xx_warning("rx request of zero bytes");
1460 skb
= dev_alloc_skb(len
);
1462 stlc45xx_warning("could not alloc skb");
1466 stlc45xx_spi_read(stlc
, SPI_ADRS_DMA_DATA
, skb_put(skb
, len
), len
);
1468 stlc45xx_sleep(stlc
);
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
);
1473 control
= (struct s_lm_control
*) skb
->data
;
1475 if (control
->flags
& LM_FLAG_CONTROL
)
1476 ret
= stlc45xx_rx_control(stlc
, skb
);
1478 ret
= stlc45xx_rx_data(stlc
, skb
);
1484 static irqreturn_t
stlc45xx_interrupt(int irq
, void *config
)
1486 struct spi_device
*spi
= config
;
1487 struct stlc45xx
*stlc
= dev_get_drvdata(&spi
->dev
);
1489 stlc45xx_debug(DEBUG_IRQ
, "IRQ");
1491 queue_work(stlc
->hw
->workqueue
, &stlc
->work
);
1496 static int stlc45xx_tx_frame(struct stlc45xx
*stlc
, u32 address
,
1497 void *buf
, size_t len
)
1499 struct s_dma_regs dma_regs
;
1500 unsigned long timeout
;
1506 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
1508 stlc45xx_debug(DEBUG_TX
, "tx frame 0x%p %zu B", buf
, len
);
1509 stlc45xx_dump(DEBUG_TX_CONTENT
, buf
, len
);
1511 stlc45xx_wakeup(stlc
);
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
);
1517 stlc45xx_spi_write(stlc
, SPI_ADRS_DMA_WRITE_CTRL
, &dma_regs
,
1520 stlc45xx_spi_write(stlc
, SPI_ADRS_DMA_DATA
, buf
, len
);
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");
1530 ints
= stlc45xx_read32(stlc
, SPI_ADRS_HOST_INTERRUPTS
);
1533 stlc45xx_int_ack(stlc
, SPI_HOST_INT_WR_READY
);
1535 stlc45xx_sleep(stlc
);
1541 static int stlc45xx_wq_tx(struct stlc45xx
*stlc
)
1543 struct txbuffer
*entry
;
1546 spin_lock_bh(&stlc
->tx_lock
);
1548 while (!list_empty(&stlc
->tx_pending
)) {
1549 entry
= list_entry(stlc
->tx_pending
.next
,
1550 struct txbuffer
, tx_list
);
1552 list_del_init(&entry
->tx_list
);
1554 spin_unlock_bh(&stlc
->tx_lock
);
1556 ret
= stlc45xx_tx_frame(stlc
, entry
->frame_start
,
1557 entry
->skb
->data
, entry
->skb
->len
);
1559 spin_lock_bh(&stlc
->tx_lock
);
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
);
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
));
1576 spin_unlock_bh(&stlc
->tx_lock
);
1580 static void stlc45xx_work(struct work_struct
*work
)
1582 struct stlc45xx
*stlc
= container_of(work
, struct stlc45xx
, work
);
1586 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
1588 mutex_lock(&stlc
->mutex
);
1590 if (stlc
->fw_state
== FW_STATE_OFF
&&
1591 stlc
->fw_state
== FW_STATE_RESET
)
1594 ints
= stlc45xx_read32(stlc
, SPI_ADRS_HOST_INTERRUPTS
);
1595 stlc45xx_debug(DEBUG_BH
, "begin host_ints 0x%08x", ints
);
1597 if (ints
& SPI_HOST_INT_READY
) {
1598 stlc45xx_int_ready(stlc
);
1599 stlc45xx_int_ack(stlc
, SPI_HOST_INT_READY
);
1602 if (stlc
->fw_state
!= FW_STATE_READY
)
1605 if (ints
& SPI_HOST_INT_UPDATE
) {
1606 stlc45xx_int_ack(stlc
, SPI_HOST_INT_UPDATE
);
1607 ret
= stlc45xx_rx(stlc
);
1609 stlc45xx_reset(stlc
);
1613 if (ints
& SPI_HOST_INT_SW_UPDATE
) {
1614 stlc45xx_int_ack(stlc
, SPI_HOST_INT_SW_UPDATE
);
1615 ret
= stlc45xx_rx(stlc
);
1617 stlc45xx_reset(stlc
);
1622 ret
= stlc45xx_wq_tx(stlc
);
1624 stlc45xx_reset(stlc
);
1628 ints
= stlc45xx_read32(stlc
, SPI_ADRS_HOST_INTERRUPTS
);
1629 stlc45xx_debug(DEBUG_BH
, "end host_ints 0x%08x", ints
);
1632 mutex_unlock(&stlc
->mutex
);
1635 static void stlc45xx_tx_edcf(struct stlc45xx
*stlc
)
1637 struct s_lm_control
*control
;
1638 struct s_lmo_edcf
*edcf
;
1639 size_t len
, edcf_len
;
1641 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
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);
1648 control
->flags
= LM_FLAG_CONTROL
| LM_CTRL_OPSET
;
1649 control
->length
= edcf_len
;
1650 control
->oid
= LM_OID_EDCF
;
1652 edcf
->slottime
= 0x14;
1655 edcf
->maxburst
= 1500;
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;
1698 stlc45xx_tx_frame(stlc
, FIRMWARE_CONFIG_START
, control
, len
);
1703 static void stlc45xx_tx_setup(struct stlc45xx
*stlc
)
1705 struct s_lm_control
*control
;
1706 struct s_lmo_setup
*setup
;
1707 size_t len
, setup_len
;
1709 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
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);
1716 control
->flags
= LM_FLAG_CONTROL
| LM_CTRL_OPSET
;
1717 control
->length
= setup_len
;
1718 control
->oid
= LM_OID_SETUP
;
1720 setup
->flags
= LM_SETUP_INFRA
;
1722 setup
->rx_align
= 0;
1723 setup
->rx_buffer
= FIRMWARE_RXBUFFER_START
;
1724 setup
->rx_mtu
= FIRMWARE_MTU
;
1725 setup
->frontend
= 5;
1727 setup
->truncate
= 48896;
1728 setup
->bratemask
= 0xffffffff;
1729 setup
->ref_clock
= 644245094;
1730 setup
->lpf_bandwidth
= 65535;
1731 setup
->osc_start_delay
= 65535;
1733 memcpy(setup
->macaddr
, stlc
->mac_addr
, ETH_ALEN
);
1734 memcpy(setup
->bssid
, stlc
->bssid
, ETH_ALEN
);
1736 stlc45xx_tx_frame(stlc
, FIRMWARE_CONFIG_START
, control
, len
);
1741 static void stlc45xx_tx_scan(struct stlc45xx
*stlc
)
1743 struct s_lm_control
*control
;
1744 struct s_lmo_scan
*scan
;
1745 size_t len
, scan_len
;
1747 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
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);
1754 control
->flags
= LM_FLAG_CONTROL
| LM_CTRL_OPSET
;
1755 control
->length
= scan_len
;
1756 control
->oid
= LM_OID_SCAN
;
1758 scan
->flags
= LM_SCAN_EXIT
;
1759 scan
->bratemask
= 0x15f;
1769 memcpy(&scan
->rssical
, &stlc
->cal_rssi
[(stlc
->channel
- 1) *
1772 memcpy(&scan
->channel
, &stlc
->cal_channels
[(stlc
->channel
- 1) *
1776 stlc45xx_tx_frame(stlc
, FIRMWARE_CONFIG_START
, control
, len
);
1782 * caller must hold mutex
1784 static int stlc45xx_tx_pspoll(struct stlc45xx
*stlc
, bool powersave
)
1786 struct ieee80211_hdr
*pspoll
;
1787 int payload_len
, padding
, i
;
1788 struct s_lm_data_out
*data
;
1789 struct txbuffer
*entry
;
1790 struct sk_buff
*skb
;
1794 skb
= dev_alloc_skb(stlc
->hw
->extra_tx_headroom
+ 16);
1796 stlc45xx_warning("failed to allocate pspoll frame");
1799 skb_reserve(skb
, stlc
->hw
->extra_tx_headroom
);
1801 pspoll
= (struct ieee80211_hdr
*) skb_put(skb
, 16);
1802 memset(pspoll
, 0, 16);
1803 fc
= IEEE80211_FTYPE_CTL
| IEEE80211_STYPE_PSPOLL
;
1805 fc
|= IEEE80211_FCTL_PM
;
1806 pspoll
->frame_control
= cpu_to_le16(fc
);
1807 pspoll
->duration_id
= cpu_to_le16(stlc
->aid
);
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);
1812 memcpy(pspoll
->addr1
, stlc
->bssid
, ETH_ALEN
);
1813 memcpy(pspoll
->addr2
, stlc
->mac_addr
, ETH_ALEN
);
1815 stlc45xx_debug(DEBUG_PSM
, "sending PS-Poll frame to %pM (powersave %d, "
1816 "fc 0x%x, aid %d)", pspoll
->addr1
,
1817 powersave
, fc
, stlc
->aid
);
1819 spin_lock_bh(&stlc
->tx_lock
);
1821 entry
= stlc45xx_txbuffer_alloc(stlc
, skb
->len
);
1823 spin_unlock_bh(&stlc
->tx_lock
);
1827 * The queue should be stopped before the firmware buffer
1828 * is full, so firmware buffer should always have enough
1831 * But I'm too lazy and omit it for now.
1833 if (net_ratelimit())
1834 stlc45xx_warning("firmware tx buffer full is full "
1839 payload
= skb
->data
;
1840 payload_len
= skb
->len
;
1841 padding
= (int) (skb
->data
- sizeof(*data
)) & 3;
1842 entry
->header_len
= sizeof(*data
) + padding
;
1845 entry
->status_needed
= false;
1846 entry
->handle
= (u32
) skb
;
1847 entry
->lifetime
= jiffies
+ msecs_to_jiffies(TX_FRAME_LIFETIME
);
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
,
1853 stlc45xx_dump(DEBUG_TX_CONTENT
, payload
, payload_len
);
1855 data
= (struct s_lm_data_out
*) skb_push(skb
, entry
->header_len
);
1857 memset(data
, 0, entry
->header_len
);
1860 data
->flags
= LM_FLAG_ALIGN
;
1862 data
->flags
= LM_OUT_BURST
;
1863 data
->length
= payload_len
;
1864 data
->handle
= entry
->handle
;
1866 data
->rts_retries
= 7;
1868 data
->aloft_ctrl
= 0;
1869 data
->crypt_offset
= 58;
1872 data
->queue
= LM_QUEUE_DATA3
;
1878 for (i
= 0; i
< 8; i
++)
1882 * check if there's enough space in tx buffer
1884 * FIXME: ignored for now
1887 stlc45xx_tx_frame(stlc
, entry
->start
, skb
->data
, skb
->len
);
1889 list_add(&entry
->tx_list
, &stlc
->tx_sent
);
1895 * caller must hold mutex
1897 * shamelessly stolen from mac80211/ieee80211_send_nullfunc
1899 static int stlc45xx_tx_nullfunc(struct stlc45xx
*stlc
, bool powersave
)
1901 struct ieee80211_hdr
*nullfunc
;
1902 int payload_len
, padding
, i
;
1903 struct s_lm_data_out
*data
;
1904 struct txbuffer
*entry
;
1905 struct sk_buff
*skb
;
1909 skb
= dev_alloc_skb(stlc
->hw
->extra_tx_headroom
+ 24);
1911 stlc45xx_warning("failed to allocate buffer for null frame\n");
1914 skb_reserve(skb
, stlc
->hw
->extra_tx_headroom
);
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
;
1922 fc
|= IEEE80211_FCTL_PM
;
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
);
1929 stlc45xx_debug(DEBUG_PSM
, "sending Null frame to %pM (powersave %d, "
1930 "fc 0x%x)", nullfunc
->addr1
, powersave
, fc
);
1932 spin_lock_bh(&stlc
->tx_lock
);
1934 entry
= stlc45xx_txbuffer_alloc(stlc
, skb
->len
);
1936 spin_unlock_bh(&stlc
->tx_lock
);
1940 * The queue should be stopped before the firmware buffer
1941 * is full, so firmware buffer should always have enough
1944 * But I'm too lazy and omit it for now.
1946 if (net_ratelimit())
1947 stlc45xx_warning("firmware tx buffer full is full "
1952 payload
= skb
->data
;
1953 payload_len
= skb
->len
;
1954 padding
= (int) (skb
->data
- sizeof(*data
)) & 3;
1955 entry
->header_len
= sizeof(*data
) + padding
;
1958 entry
->status_needed
= false;
1959 entry
->handle
= (u32
) skb
;
1960 entry
->lifetime
= jiffies
+ msecs_to_jiffies(TX_FRAME_LIFETIME
);
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
,
1966 stlc45xx_dump(DEBUG_TX_CONTENT
, payload
, payload_len
);
1968 data
= (struct s_lm_data_out
*) skb_push(skb
, entry
->header_len
);
1970 memset(data
, 0, entry
->header_len
);
1973 data
->flags
= LM_FLAG_ALIGN
;
1975 data
->flags
= LM_OUT_BURST
;
1976 data
->length
= payload_len
;
1977 data
->handle
= entry
->handle
;
1979 data
->rts_retries
= 7;
1981 data
->aloft_ctrl
= 0;
1982 data
->crypt_offset
= 58;
1985 data
->queue
= LM_QUEUE_DATA3
;
1991 for (i
= 0; i
< 8; i
++)
1995 * check if there's enough space in tx buffer
1997 * FIXME: ignored for now
2000 stlc45xx_tx_frame(stlc
, entry
->start
, skb
->data
, skb
->len
);
2002 list_add(&entry
->tx_list
, &stlc
->tx_sent
);
2007 /* caller must hold mutex */
2008 static void stlc45xx_tx_psm(struct stlc45xx
*stlc
, bool enable
)
2010 struct s_lm_control
*control
;
2011 struct s_lmo_psm
*psm
;
2012 size_t len
, psm_len
;
2014 WARN_ON(!stlc
->associated
);
2015 WARN_ON(stlc
->aid
< 1);
2016 WARN_ON(stlc
->aid
> 2007);
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);
2023 control
->flags
= LM_FLAG_CONTROL
| LM_CTRL_OPSET
;
2024 control
->length
= psm_len
;
2025 control
->oid
= LM_OID_PSM
;
2028 psm
->flags
|= LM_PSM
;
2030 psm
->aid
= stlc
->aid
;
2032 psm
->beacon_rcpi_skip_max
= 60;
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;
2044 psm
->exclude
[0] = 0;
2046 stlc45xx_debug(DEBUG_PSM
, "sending LM_OID_PSM (aid %d, interval %d)",
2047 psm
->aid
, psm
->intervals
[0].interval
);
2049 stlc45xx_tx_frame(stlc
, FIRMWARE_CONFIG_START
, control
, len
);
2054 static int stlc45xx_op_tx(struct ieee80211_hw
*hw
, struct sk_buff
*skb
)
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
;
2064 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2066 spin_lock_bh(&stlc
->tx_lock
);
2068 entry
= stlc45xx_txbuffer_alloc(stlc
, skb
->len
);
2070 /* the queue should be stopped before the firmware buffer
2071 * is full, so firmware buffer should always have enough
2073 if (net_ratelimit())
2074 stlc45xx_warning("firmware buffer full");
2075 spin_unlock_bh(&stlc
->tx_lock
);
2076 return NETDEV_TX_BUSY
;
2079 info
= IEEE80211_SKB_CB(skb
);
2081 payload
= skb
->data
;
2082 payload_len
= skb
->len
;
2083 padding
= (int) (skb
->data
- sizeof(*data
)) & 3;
2084 entry
->header_len
= sizeof(*data
) + padding
;
2087 entry
->status_needed
= true;
2088 entry
->handle
= (u32
) skb
;
2089 entry
->lifetime
= jiffies
+ msecs_to_jiffies(TX_FRAME_LIFETIME
);
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
,
2095 stlc45xx_dump(DEBUG_TX_CONTENT
, payload
, payload_len
);
2097 data
= (struct s_lm_data_out
*) skb_push(skb
, entry
->header_len
);
2099 memset(data
, 0, entry
->header_len
);
2102 data
->flags
= LM_FLAG_ALIGN
;
2104 data
->flags
= LM_OUT_BURST
;
2105 data
->length
= payload_len
;
2106 data
->handle
= entry
->handle
;
2108 data
->rts_retries
= 7;
2110 data
->aloft_ctrl
= 0;
2111 data
->crypt_offset
= 58;
2120 for (i
= 0; i
< 8; i
++) {
2121 rate
= ieee80211_get_tx_rate(stlc
->hw
, info
);
2122 data
->aloft
[i
] = rate
->hw_value
;
2125 list_add_tail(&entry
->tx_list
, &stlc
->tx_pending
);
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
);
2134 queue_work(stlc
->hw
->workqueue
, &stlc
->work
);
2136 spin_unlock_bh(&stlc
->tx_lock
);
2138 return NETDEV_TX_OK
;
2141 static int stlc45xx_op_start(struct ieee80211_hw
*hw
)
2143 struct stlc45xx
*stlc
= hw
->priv
;
2144 unsigned long timeout
;
2147 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2149 mutex_lock(&stlc
->mutex
);
2151 stlc
->fw_state
= FW_STATE_BOOTING
;
2154 stlc45xx_power_on(stlc
);
2156 ret
= stlc45xx_upload_firmware(stlc
);
2158 stlc45xx_power_off(stlc
);
2162 stlc
->tx_queue_stopped
= 0;
2164 mutex_unlock(&stlc
->mutex
);
2166 timeout
= msecs_to_jiffies(2000);
2167 timeout
= wait_for_completion_interruptible_timeout(&stlc
->fw_comp
,
2170 stlc45xx_error("firmware boot failed");
2171 stlc45xx_power_off(stlc
);
2176 stlc45xx_debug(DEBUG_BOOT
, "firmware booted");
2178 /* FIXME: should we take mutex just after wait_for_completion()? */
2179 mutex_lock(&stlc
->mutex
);
2181 WARN_ON(stlc
->fw_state
!= FW_STATE_READY
);
2184 mutex_unlock(&stlc
->mutex
);
2190 static void stlc45xx_op_stop(struct ieee80211_hw
*hw
)
2192 struct stlc45xx
*stlc
= hw
->priv
;
2194 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2196 mutex_lock(&stlc
->mutex
);
2198 WARN_ON(stlc
->fw_state
!= FW_STATE_READY
);
2200 stlc45xx_power_off(stlc
);
2202 /* FIXME: make sure that all work_structs have completed */
2204 spin_lock_bh(&stlc
->tx_lock
);
2205 stlc45xx_flush_queues(stlc
);
2206 spin_unlock_bh(&stlc
->tx_lock
);
2208 stlc
->fw_state
= FW_STATE_OFF
;
2210 mutex_unlock(&stlc
->mutex
);
2213 static int stlc45xx_op_add_interface(struct ieee80211_hw
*hw
,
2214 struct ieee80211_if_init_conf
*conf
)
2216 struct stlc45xx
*stlc
= hw
->priv
;
2218 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2220 switch (conf
->type
) {
2221 case NL80211_IFTYPE_STATION
:
2227 memcpy(stlc
->mac_addr
, conf
->mac_addr
, ETH_ALEN
);
2232 static void stlc45xx_op_remove_interface(struct ieee80211_hw
*hw
,
2233 struct ieee80211_if_init_conf
*conf
)
2235 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2238 static int stlc45xx_op_config_interface(struct ieee80211_hw
*hw
,
2239 struct ieee80211_vif
*vif
,
2240 struct ieee80211_if_conf
*conf
)
2242 struct stlc45xx
*stlc
= hw
->priv
;
2244 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2246 mutex_lock(&stlc
->mutex
);
2248 memcpy(stlc
->bssid
, conf
->bssid
, ETH_ALEN
);
2249 stlc45xx_tx_setup(stlc
);
2251 mutex_unlock(&stlc
->mutex
);
2256 static int stlc45xx_op_config(struct ieee80211_hw
*hw
, u32 changed
)
2258 struct stlc45xx
*stlc
= hw
->priv
;
2260 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2262 mutex_lock(&stlc
->mutex
);
2264 stlc
->channel
= hw
->conf
.channel
->hw_value
;
2265 stlc45xx_tx_scan(stlc
);
2266 stlc45xx_tx_setup(stlc
);
2267 stlc45xx_tx_edcf(stlc
);
2269 if ((hw
->conf
.flags
& IEEE80211_CONF_PS
) != stlc
->psm
) {
2270 stlc
->psm
= hw
->conf
.flags
& IEEE80211_CONF_PS
;
2271 if (stlc
->associated
) {
2272 stlc45xx_tx_psm(stlc
, stlc
->psm
);
2273 stlc45xx_tx_nullfunc(stlc
, stlc
->psm
);
2277 mutex_unlock(&stlc
->mutex
);
2282 static void stlc45xx_op_configure_filter(struct ieee80211_hw
*hw
,
2283 unsigned int changed_flags
,
2284 unsigned int *total_flags
,
2286 struct dev_addr_list
*mc_list
)
2291 static void stlc45xx_op_bss_info_changed(struct ieee80211_hw
*hw
,
2292 struct ieee80211_vif
*vif
,
2293 struct ieee80211_bss_conf
*info
,
2296 struct stlc45xx
*stlc
= hw
->priv
;
2298 if (changed
& BSS_CHANGED_ASSOC
) {
2299 stlc
->associated
= info
->assoc
;
2301 stlc
->aid
= info
->aid
;
2306 stlc45xx_tx_psm(stlc
, stlc
->psm
);
2307 stlc45xx_tx_nullfunc(stlc
, stlc
->psm
);
2313 /* can't be const, mac80211 writes to this */
2314 static struct ieee80211_rate stlc45xx_rates
[] = {
2315 { .bitrate
= 10, .hw_value
= 0, .hw_value_short
= 0, },
2316 { .bitrate
= 20, .hw_value
= 1, .hw_value_short
= 1, },
2317 { .bitrate
= 55, .hw_value
= 2, .hw_value_short
= 2, },
2318 { .bitrate
= 110, .hw_value
= 3, .hw_value_short
= 3, },
2319 { .bitrate
= 60, .hw_value
= 4, .hw_value_short
= 4, },
2320 { .bitrate
= 90, .hw_value
= 5, .hw_value_short
= 5, },
2321 { .bitrate
= 120, .hw_value
= 6, .hw_value_short
= 6, },
2322 { .bitrate
= 180, .hw_value
= 7, .hw_value_short
= 7, },
2323 { .bitrate
= 240, .hw_value
= 8, .hw_value_short
= 8, },
2324 { .bitrate
= 360, .hw_value
= 9, .hw_value_short
= 9, },
2325 { .bitrate
= 480, .hw_value
= 10, .hw_value_short
= 10, },
2326 { .bitrate
= 540, .hw_value
= 11, .hw_value_short
= 11, },
2329 /* can't be const, mac80211 writes to this */
2330 static struct ieee80211_channel stlc45xx_channels
[] = {
2331 { .hw_value
= 1, .center_freq
= 2412},
2332 { .hw_value
= 2, .center_freq
= 2417},
2333 { .hw_value
= 3, .center_freq
= 2422},
2334 { .hw_value
= 4, .center_freq
= 2427},
2335 { .hw_value
= 5, .center_freq
= 2432},
2336 { .hw_value
= 6, .center_freq
= 2437},
2337 { .hw_value
= 7, .center_freq
= 2442},
2338 { .hw_value
= 8, .center_freq
= 2447},
2339 { .hw_value
= 9, .center_freq
= 2452},
2340 { .hw_value
= 10, .center_freq
= 2457},
2341 { .hw_value
= 11, .center_freq
= 2462},
2342 { .hw_value
= 12, .center_freq
= 2467},
2343 { .hw_value
= 13, .center_freq
= 2472},
2346 /* can't be const, mac80211 writes to this */
2347 static struct ieee80211_supported_band stlc45xx_band_2ghz
= {
2348 .channels
= stlc45xx_channels
,
2349 .n_channels
= ARRAY_SIZE(stlc45xx_channels
),
2350 .bitrates
= stlc45xx_rates
,
2351 .n_bitrates
= ARRAY_SIZE(stlc45xx_rates
),
2354 static const struct ieee80211_ops stlc45xx_ops
= {
2355 .start
= stlc45xx_op_start
,
2356 .stop
= stlc45xx_op_stop
,
2357 .add_interface
= stlc45xx_op_add_interface
,
2358 .remove_interface
= stlc45xx_op_remove_interface
,
2359 .config
= stlc45xx_op_config
,
2360 .config_interface
= stlc45xx_op_config_interface
,
2361 .configure_filter
= stlc45xx_op_configure_filter
,
2362 .tx
= stlc45xx_op_tx
,
2363 .bss_info_changed
= stlc45xx_op_bss_info_changed
,
2366 static int stlc45xx_register_mac80211(struct stlc45xx
*stlc
)
2368 /* FIXME: SET_IEEE80211_PERM_ADDR() requires default_mac_addr
2369 to be non-const for some strange reason */
2370 static u8 default_mac_addr
[ETH_ALEN
] = {
2371 0x00, 0x02, 0xee, 0xc0, 0xff, 0xee
2375 SET_IEEE80211_PERM_ADDR(stlc
->hw
, default_mac_addr
);
2377 ret
= ieee80211_register_hw(stlc
->hw
);
2379 stlc45xx_error("unable to register mac80211 hw: %d", ret
);
2386 static void stlc45xx_device_release(struct device
*dev
)
2391 static struct platform_device stlc45xx_device
= {
2395 /* device model insists to have a release function */
2397 .release
= stlc45xx_device_release
,
2401 static int __devinit
stlc45xx_probe(struct spi_device
*spi
)
2403 struct stlc45xx
*stlc
;
2404 struct ieee80211_hw
*hw
;
2407 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2409 /* mac80211 alloc */
2410 hw
= ieee80211_alloc_hw(sizeof(*stlc
), &stlc45xx_ops
);
2412 stlc45xx_error("could not alloc ieee80211_hw");
2417 /* mac80211 clears hw->priv */
2421 dev_set_drvdata(&spi
->dev
, stlc
);
2424 spi
->bits_per_word
= 16;
2425 spi
->max_speed_hz
= 24000000;
2427 ret
= spi_setup(spi
);
2429 stlc45xx_error("spi_setup failed");
2431 ret
= gpio_request(stlc45xx_gpio_power
, "stlc45xx power");
2433 stlc45xx_error("power GPIO request failed: %d", ret
);
2437 ret
= gpio_request(stlc45xx_gpio_irq
, "stlc45xx irq");
2439 stlc45xx_error("irq GPIO request failed: %d", ret
);
2443 gpio_direction_output(stlc45xx_gpio_power
, 0);
2444 gpio_direction_input(stlc45xx_gpio_irq
);
2446 ret
= request_irq(gpio_to_irq(stlc45xx_gpio_irq
),
2447 stlc45xx_interrupt
, IRQF_DISABLED
, "stlc45xx",
2450 /* FIXME: handle the error */
2451 stlc45xx_error("request_irq() failed");
2453 set_irq_type(gpio_to_irq(stlc45xx_gpio_irq
),
2454 IRQ_TYPE_EDGE_RISING
);
2456 disable_irq(gpio_to_irq(stlc45xx_gpio_irq
));
2458 ret
= platform_device_register(&stlc45xx_device
);
2460 stlc45xx_error("Couldn't register wlan_omap device.");
2463 dev_set_drvdata(&stlc45xx_device
.dev
, stlc
);
2465 INIT_WORK(&stlc
->work
, stlc45xx_work
);
2466 INIT_WORK(&stlc
->work_reset
, stlc45xx_work_reset
);
2467 INIT_DELAYED_WORK(&stlc
->work_tx_timeout
, stlc45xx_work_tx_timeout
);
2468 mutex_init(&stlc
->mutex
);
2469 init_completion(&stlc
->fw_comp
);
2470 spin_lock_init(&stlc
->tx_lock
);
2471 INIT_LIST_HEAD(&stlc
->txbuffer
);
2472 INIT_LIST_HEAD(&stlc
->tx_pending
);
2473 INIT_LIST_HEAD(&stlc
->tx_sent
);
2475 hw
->flags
= IEEE80211_HW_RX_INCLUDES_FCS
|
2476 IEEE80211_HW_SIGNAL_DBM
|
2477 IEEE80211_HW_NOISE_DBM
;
2478 /* four bytes for padding */
2479 hw
->extra_tx_headroom
= sizeof(struct s_lm_data_out
) + 4;
2482 hw
->channel_change_time
= 1000;
2484 hw
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
);
2485 hw
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &stlc45xx_band_2ghz
;
2487 SET_IEEE80211_DEV(hw
, &spi
->dev
);
2489 BUILD_BUG_ON(sizeof(default_cal_rssi
) != RSSI_CAL_ARRAY_LEN
);
2490 BUILD_BUG_ON(sizeof(default_cal_channels
) != CHANNEL_CAL_ARRAY_LEN
);
2492 stlc
->cal_rssi
= kmemdup(default_cal_rssi
, RSSI_CAL_ARRAY_LEN
,
2494 stlc
->cal_channels
= kmemdup(default_cal_channels
,
2495 CHANNEL_CAL_ARRAY_LEN
,
2498 ret
= device_create_file(&stlc45xx_device
.dev
, &dev_attr_cal_rssi
);
2500 stlc45xx_error("failed to create sysfs file cal_rssi");
2504 ret
= device_create_file(&stlc45xx_device
.dev
, &dev_attr_cal_channels
);
2506 stlc45xx_error("failed to create sysfs file cal_channels");
2510 ret
= device_create_file(&stlc45xx_device
.dev
, &dev_attr_tx_buf
);
2512 stlc45xx_error("failed to create sysfs file tx_buf");
2516 ret
= stlc45xx_register_mac80211(stlc
);
2520 stlc45xx_info("v" DRIVER_VERSION
" loaded");
2522 stlc45xx_info("config buffer 0x%x-0x%x",
2523 FIRMWARE_CONFIG_START
, FIRMWARE_CONFIG_END
);
2524 stlc45xx_info("tx 0x%x-0x%x, rx 0x%x-0x%x",
2525 FIRMWARE_TXBUFFER_START
, FIRMWARE_TXBUFFER_END
,
2526 FIRMWARE_RXBUFFER_START
, FIRMWARE_RXBUFFER_END
);
2532 static int __devexit
stlc45xx_remove(struct spi_device
*spi
)
2534 struct stlc45xx
*stlc
= dev_get_drvdata(&spi
->dev
);
2536 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2538 platform_device_unregister(&stlc45xx_device
);
2540 ieee80211_unregister_hw(stlc
->hw
);
2542 free_irq(gpio_to_irq(stlc45xx_gpio_irq
), spi
);
2544 gpio_free(stlc45xx_gpio_power
);
2545 gpio_free(stlc45xx_gpio_irq
);
2547 /* FIXME: free cal_channels and cal_rssi? */
2551 mutex_destroy(&stlc
->mutex
);
2553 /* frees also stlc */
2554 ieee80211_free_hw(stlc
->hw
);
2561 static struct spi_driver stlc45xx_spi_driver
= {
2563 /* use cx3110x name because board-n800.c uses that for the
2566 .bus
= &spi_bus_type
,
2567 .owner
= THIS_MODULE
,
2570 .probe
= stlc45xx_probe
,
2571 .remove
= __devexit_p(stlc45xx_remove
),
2574 static int __init
stlc45xx_init(void)
2578 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2580 ret
= spi_register_driver(&stlc45xx_spi_driver
);
2582 stlc45xx_error("failed to register SPI driver: %d", ret
);
2590 static void __exit
stlc45xx_exit(void)
2592 stlc45xx_debug(DEBUG_FUNC
, "%s", __func__
);
2594 spi_unregister_driver(&stlc45xx_spi_driver
);
2596 stlc45xx_info("unloaded");
2599 module_init(stlc45xx_init
);
2600 module_exit(stlc45xx_exit
);
2602 MODULE_LICENSE("GPL");
2603 MODULE_AUTHOR("Kalle Valo <kalle.valo@nokia.com>");