65a22f193f92c9301f237c536f19c401ca10ee3f
[safe/jmp/linux-2.6] / drivers / net / sfc / mtd.c
1 /****************************************************************************
2  * Driver for Solarflare Solarstorm network controllers and boards
3  * Copyright 2005-2006 Fen Systems Ltd.
4  * Copyright 2006-2008 Solarflare Communications Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published
8  * by the Free Software Foundation, incorporated herein by reference.
9  */
10
11 #include <linux/module.h>
12 #include <linux/mtd/mtd.h>
13 #include <linux/delay.h>
14 #include <linux/rtnetlink.h>
15
16 #define EFX_DRIVER_NAME "sfc_mtd"
17 #include "net_driver.h"
18 #include "spi.h"
19 #include "efx.h"
20 #include "nic.h"
21
22 #define EFX_SPI_VERIFY_BUF_LEN 16
23
24 struct efx_mtd_partition {
25         struct mtd_info mtd;
26         size_t offset;
27         const char *type_name;
28         char name[IFNAMSIZ + 20];
29 };
30
31 struct efx_mtd_ops {
32         int (*read)(struct mtd_info *mtd, loff_t start, size_t len,
33                     size_t *retlen, u8 *buffer);
34         int (*erase)(struct mtd_info *mtd, loff_t start, size_t len);
35         int (*write)(struct mtd_info *mtd, loff_t start, size_t len,
36                      size_t *retlen, const u8 *buffer);
37         int (*sync)(struct mtd_info *mtd);
38 };
39
40 struct efx_mtd {
41         struct list_head node;
42         struct efx_nic *efx;
43         const struct efx_spi_device *spi;
44         const char *name;
45         const struct efx_mtd_ops *ops;
46         size_t n_parts;
47         struct efx_mtd_partition part[0];
48 };
49
50 #define efx_for_each_partition(part, efx_mtd)                   \
51         for ((part) = &(efx_mtd)->part[0];                      \
52              (part) != &(efx_mtd)->part[(efx_mtd)->n_parts];    \
53              (part)++)
54
55 #define to_efx_mtd_partition(mtd)                               \
56         container_of(mtd, struct efx_mtd_partition, mtd)
57
58 static int falcon_mtd_probe(struct efx_nic *efx);
59
60 /* SPI utilities */
61
62 static int efx_spi_slow_wait(struct efx_mtd *efx_mtd, bool uninterruptible)
63 {
64         const struct efx_spi_device *spi = efx_mtd->spi;
65         struct efx_nic *efx = efx_mtd->efx;
66         u8 status;
67         int rc, i;
68
69         /* Wait up to 4s for flash/EEPROM to finish a slow operation. */
70         for (i = 0; i < 40; i++) {
71                 __set_current_state(uninterruptible ?
72                                     TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
73                 schedule_timeout(HZ / 10);
74                 rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
75                                     &status, sizeof(status));
76                 if (rc)
77                         return rc;
78                 if (!(status & SPI_STATUS_NRDY))
79                         return 0;
80                 if (signal_pending(current))
81                         return -EINTR;
82         }
83         EFX_ERR(efx, "timed out waiting for %s\n", efx_mtd->name);
84         return -ETIMEDOUT;
85 }
86
87 static int
88 efx_spi_unlock(struct efx_nic *efx, const struct efx_spi_device *spi)
89 {
90         const u8 unlock_mask = (SPI_STATUS_BP2 | SPI_STATUS_BP1 |
91                                 SPI_STATUS_BP0);
92         u8 status;
93         int rc;
94
95         rc = falcon_spi_cmd(efx, spi, SPI_RDSR, -1, NULL,
96                             &status, sizeof(status));
97         if (rc)
98                 return rc;
99
100         if (!(status & unlock_mask))
101                 return 0; /* already unlocked */
102
103         rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
104         if (rc)
105                 return rc;
106         rc = falcon_spi_cmd(efx, spi, SPI_SST_EWSR, -1, NULL, NULL, 0);
107         if (rc)
108                 return rc;
109
110         status &= ~unlock_mask;
111         rc = falcon_spi_cmd(efx, spi, SPI_WRSR, -1, &status,
112                             NULL, sizeof(status));
113         if (rc)
114                 return rc;
115         rc = falcon_spi_wait_write(efx, spi);
116         if (rc)
117                 return rc;
118
119         return 0;
120 }
121
122 static int efx_spi_erase(struct efx_mtd *efx_mtd, loff_t start, size_t len)
123 {
124         const struct efx_spi_device *spi = efx_mtd->spi;
125         struct efx_nic *efx = efx_mtd->efx;
126         unsigned pos, block_len;
127         u8 empty[EFX_SPI_VERIFY_BUF_LEN];
128         u8 buffer[EFX_SPI_VERIFY_BUF_LEN];
129         int rc;
130
131         if (len != spi->erase_size)
132                 return -EINVAL;
133
134         if (spi->erase_command == 0)
135                 return -EOPNOTSUPP;
136
137         rc = efx_spi_unlock(efx, spi);
138         if (rc)
139                 return rc;
140         rc = falcon_spi_cmd(efx, spi, SPI_WREN, -1, NULL, NULL, 0);
141         if (rc)
142                 return rc;
143         rc = falcon_spi_cmd(efx, spi, spi->erase_command, start, NULL,
144                             NULL, 0);
145         if (rc)
146                 return rc;
147         rc = efx_spi_slow_wait(efx_mtd, false);
148
149         /* Verify the entire region has been wiped */
150         memset(empty, 0xff, sizeof(empty));
151         for (pos = 0; pos < len; pos += block_len) {
152                 block_len = min(len - pos, sizeof(buffer));
153                 rc = falcon_spi_read(efx, spi, start + pos, block_len,
154                                      NULL, buffer);
155                 if (rc)
156                         return rc;
157                 if (memcmp(empty, buffer, block_len))
158                         return -EIO;
159
160                 /* Avoid locking up the system */
161                 cond_resched();
162                 if (signal_pending(current))
163                         return -EINTR;
164         }
165
166         return rc;
167 }
168
169 /* MTD interface */
170
171 static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
172 {
173         struct efx_mtd *efx_mtd = mtd->priv;
174         int rc;
175
176         rc = efx_mtd->ops->erase(mtd, erase->addr, erase->len);
177         if (rc == 0) {
178                 erase->state = MTD_ERASE_DONE;
179         } else {
180                 erase->state = MTD_ERASE_FAILED;
181                 erase->fail_addr = 0xffffffff;
182         }
183         mtd_erase_callback(erase);
184         return rc;
185 }
186
187 static void efx_mtd_sync(struct mtd_info *mtd)
188 {
189         struct efx_mtd *efx_mtd = mtd->priv;
190         struct efx_nic *efx = efx_mtd->efx;
191         int rc;
192
193         rc = efx_mtd->ops->sync(mtd);
194         if (rc)
195                 EFX_ERR(efx, "%s sync failed (%d)\n", efx_mtd->name, rc);
196 }
197
198 static void efx_mtd_remove_partition(struct efx_mtd_partition *part)
199 {
200         int rc;
201
202         for (;;) {
203                 rc = del_mtd_device(&part->mtd);
204                 if (rc != -EBUSY)
205                         break;
206                 ssleep(1);
207         }
208         WARN_ON(rc);
209 }
210
211 static void efx_mtd_remove_device(struct efx_mtd *efx_mtd)
212 {
213         struct efx_mtd_partition *part;
214
215         efx_for_each_partition(part, efx_mtd)
216                 efx_mtd_remove_partition(part);
217         list_del(&efx_mtd->node);
218         kfree(efx_mtd);
219 }
220
221 static void efx_mtd_rename_device(struct efx_mtd *efx_mtd)
222 {
223         struct efx_mtd_partition *part;
224
225         efx_for_each_partition(part, efx_mtd)
226                 snprintf(part->name, sizeof(part->name),
227                          "%s %s", efx_mtd->efx->name,
228                          part->type_name);
229 }
230
231 static int efx_mtd_probe_device(struct efx_nic *efx, struct efx_mtd *efx_mtd)
232 {
233         struct efx_mtd_partition *part;
234
235         efx_mtd->efx = efx;
236
237         efx_mtd_rename_device(efx_mtd);
238
239         efx_for_each_partition(part, efx_mtd) {
240                 part->mtd.writesize = 1;
241
242                 part->mtd.owner = THIS_MODULE;
243                 part->mtd.priv = efx_mtd;
244                 part->mtd.name = part->name;
245                 part->mtd.erase = efx_mtd_erase;
246                 part->mtd.read = efx_mtd->ops->read;
247                 part->mtd.write = efx_mtd->ops->write;
248                 part->mtd.sync = efx_mtd_sync;
249
250                 if (add_mtd_device(&part->mtd))
251                         goto fail;
252         }
253
254         list_add(&efx_mtd->node, &efx->mtd_list);
255         return 0;
256
257 fail:
258         while (part != &efx_mtd->part[0]) {
259                 --part;
260                 efx_mtd_remove_partition(part);
261         }
262         /* add_mtd_device() returns 1 if the MTD table is full */
263         return -ENOMEM;
264 }
265
266 void efx_mtd_remove(struct efx_nic *efx)
267 {
268         struct efx_mtd *efx_mtd, *next;
269
270         WARN_ON(efx_dev_registered(efx));
271
272         list_for_each_entry_safe(efx_mtd, next, &efx->mtd_list, node)
273                 efx_mtd_remove_device(efx_mtd);
274 }
275
276 void efx_mtd_rename(struct efx_nic *efx)
277 {
278         struct efx_mtd *efx_mtd;
279
280         ASSERT_RTNL();
281
282         list_for_each_entry(efx_mtd, &efx->mtd_list, node)
283                 efx_mtd_rename_device(efx_mtd);
284 }
285
286 int efx_mtd_probe(struct efx_nic *efx)
287 {
288         return falcon_mtd_probe(efx);
289 }
290
291 /* Implementation of MTD operations for Falcon */
292
293 static int falcon_mtd_read(struct mtd_info *mtd, loff_t start,
294                            size_t len, size_t *retlen, u8 *buffer)
295 {
296         struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
297         struct efx_mtd *efx_mtd = mtd->priv;
298         const struct efx_spi_device *spi = efx_mtd->spi;
299         struct efx_nic *efx = efx_mtd->efx;
300         int rc;
301
302         rc = mutex_lock_interruptible(&efx->spi_lock);
303         if (rc)
304                 return rc;
305         rc = falcon_spi_read(efx, spi, part->offset + start, len,
306                              retlen, buffer);
307         mutex_unlock(&efx->spi_lock);
308         return rc;
309 }
310
311 static int falcon_mtd_erase(struct mtd_info *mtd, loff_t start, size_t len)
312 {
313         struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
314         struct efx_mtd *efx_mtd = mtd->priv;
315         struct efx_nic *efx = efx_mtd->efx;
316         int rc;
317
318         rc = mutex_lock_interruptible(&efx->spi_lock);
319         if (rc)
320                 return rc;
321         rc = efx_spi_erase(efx_mtd, part->offset + start, len);
322         mutex_unlock(&efx->spi_lock);
323         return rc;
324 }
325
326 static int falcon_mtd_write(struct mtd_info *mtd, loff_t start,
327                             size_t len, size_t *retlen, const u8 *buffer)
328 {
329         struct efx_mtd_partition *part = to_efx_mtd_partition(mtd);
330         struct efx_mtd *efx_mtd = mtd->priv;
331         const struct efx_spi_device *spi = efx_mtd->spi;
332         struct efx_nic *efx = efx_mtd->efx;
333         int rc;
334
335         rc = mutex_lock_interruptible(&efx->spi_lock);
336         if (rc)
337                 return rc;
338         rc = falcon_spi_write(efx, spi, part->offset + start, len,
339                               retlen, buffer);
340         mutex_unlock(&efx->spi_lock);
341         return rc;
342 }
343
344 static int falcon_mtd_sync(struct mtd_info *mtd)
345 {
346         struct efx_mtd *efx_mtd = mtd->priv;
347         struct efx_nic *efx = efx_mtd->efx;
348         int rc;
349
350         mutex_lock(&efx->spi_lock);
351         rc = efx_spi_slow_wait(efx_mtd, true);
352         mutex_unlock(&efx->spi_lock);
353         return rc;
354 }
355
356 static struct efx_mtd_ops falcon_mtd_ops = {
357         .read   = falcon_mtd_read,
358         .erase  = falcon_mtd_erase,
359         .write  = falcon_mtd_write,
360         .sync   = falcon_mtd_sync,
361 };
362
363 static int falcon_mtd_probe(struct efx_nic *efx)
364 {
365         struct efx_spi_device *spi = efx->spi_flash;
366         struct efx_mtd *efx_mtd;
367         int rc;
368
369         ASSERT_RTNL();
370
371         if (!spi || spi->size <= FALCON_FLASH_BOOTCODE_START)
372                 return -ENODEV;
373
374         efx_mtd = kzalloc(sizeof(*efx_mtd) + sizeof(efx_mtd->part[0]),
375                           GFP_KERNEL);
376         if (!efx_mtd)
377                 return -ENOMEM;
378
379         efx_mtd->spi = spi;
380         efx_mtd->name = "flash";
381         efx_mtd->ops = &falcon_mtd_ops;
382
383         efx_mtd->n_parts = 1;
384         efx_mtd->part[0].mtd.type = MTD_NORFLASH;
385         efx_mtd->part[0].mtd.flags = MTD_CAP_NORFLASH;
386         efx_mtd->part[0].mtd.size = spi->size - FALCON_FLASH_BOOTCODE_START;
387         efx_mtd->part[0].mtd.erasesize = spi->erase_size;
388         efx_mtd->part[0].offset = FALCON_FLASH_BOOTCODE_START;
389         efx_mtd->part[0].type_name = "sfc_flash_bootrom";
390
391         rc = efx_mtd_probe_device(efx, efx_mtd);
392         if (rc)
393                 kfree(efx_mtd);
394         return rc;
395 }