ia64/linux-2.6.18-xen.hg

view drivers/net/sfc/mtd.c @ 847:ad4d307bf9ce

net sfc: Update sfc and sfc_resource driver to latest release

...and update sfc_netfront, sfc_netback, sfc_netutil for any API changes

sfc_netback: Fix asymmetric use of SFC buffer table alloc and free
sfc_netback: Clean up if no SFC accel device found
sfc_netback: Gracefully handle case where page grant fails
sfc_netback: Disable net acceleration if the physical link goes down
sfc_netfront: Less verbose error messages, more verbose counters for
rx discard errors
sfc_netfront: Gracefully handle case where SFC netfront fails during
initialisation

Signed-off-by: Kieran Mansley <kmansley@solarflare.com>
author Keir Fraser <keir.fraser@citrix.com>
date Tue Mar 31 11:59:10 2009 +0100 (2009-03-31)
parents fc90e9b2c12b
children
line source
1 /****************************************************************************
2 * Driver for Solarflare network controllers
3 * (including support for SFE4001 10GBT NIC)
4 *
5 * Copyright 2005-2006: Fen Systems Ltd.
6 * Copyright 2006-2008: Solarflare Communications Inc,
7 * 9501 Jeronimo Road, Suite 250,
8 * Irvine, CA 92618, USA
9 *
10 * Initially developed by Michael Brown <mbrown@fensystems.co.uk>
11 * Maintained by Solarflare Communications <linux-net-drivers@solarflare.com>
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License version 2 as published
15 * by the Free Software Foundation, incorporated herein by reference.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 ****************************************************************************
26 */
28 #include <linux/module.h>
29 #include <linux/mtd/mtd.h>
30 #include <linux/mtd/partitions.h>
31 #include <linux/delay.h>
33 #define EFX_DRIVER_NAME "sfc_mtd"
34 #include "driverlink_api.h"
35 #include "net_driver.h"
36 #include "spi.h"
38 /*
39 * Flash and EEPROM (MTD) device driver
40 *
41 * This file provides a separate kernel module (sfc_mtd) which
42 * exposes the flash and EEPROM devices present on Solarflare NICs as
43 * MTD devices, enabling you to reflash the boot ROM code (or use the
44 * remaining space on the flash as a jffs2 filesystem, should you want
45 * to do so).
46 */
48 #define EFX_MTD_VERIFY_BUF_LEN 16
49 #define EFX_MAX_PARTITIONS 2
50 #define EFX_FLASH_BOOTROM_OFFSET 0x8000U
52 /* Write enable for EEPROM/flash configuration area
53 *
54 * Normally, writes to parts of non-volatile storage which contain
55 * critical configuration are disabled to prevent accidents. This
56 * parameter allows enabling of such writes.
57 */
58 static unsigned int efx_allow_nvconfig_writes;
60 struct efx_mtd {
61 struct mtd_info mtd;
62 struct mtd_partition part[EFX_MAX_PARTITIONS];
63 char part_name[EFX_MAX_PARTITIONS][32];
64 char name[32];
65 struct efx_dl_device *efx_dev;
66 struct efx_nic *efx;
67 /* This must be held when using *spi; it guards against races
68 * with device reset and between sequences of dependent
69 * commands. */
70 struct semaphore access_lock;
71 struct efx_spi_device *spi;
72 };
74 /* SPI utilities */
76 static int efx_spi_fast_wait(struct efx_mtd *efx_mtd)
77 {
78 struct efx_spi_device *spi = efx_mtd->spi;
79 u8 status;
80 int i, rc;
82 /* Wait up to 1000us for flash/EEPROM to finish a fast operation. */
83 for (i = 0; i < 50; i++) {
84 udelay(20);
86 rc = spi->read(spi, efx_mtd->efx, SPI_RDSR, -1,
87 &status, sizeof(status));
88 if (rc)
89 return rc;
90 if (!(status & SPI_STATUS_NRDY))
91 return 0;
92 }
93 EFX_ERR(efx_mtd->efx, "timed out waiting for %s last status=0x%02x\n",
94 efx_mtd->name, status);
95 return -ETIMEDOUT;
96 }
98 static int efx_spi_slow_wait(struct efx_mtd *efx_mtd, int uninterruptible)
99 {
100 struct efx_spi_device *spi = efx_mtd->spi;
101 u8 status;
102 int rc, i;
104 /* Wait up to 4s for flash/EEPROM to finish a slow operation. */
105 for (i = 0; i < 40; i++) {
106 __set_current_state(uninterruptible ?
107 TASK_UNINTERRUPTIBLE : TASK_INTERRUPTIBLE);
108 schedule_timeout(HZ / 10);
109 rc = spi->read(spi, efx_mtd->efx, SPI_RDSR, -1,
110 &status, sizeof(status));
111 if (rc)
112 return rc;
113 if (!(status & SPI_STATUS_NRDY))
114 return 0;
115 if (signal_pending(current))
116 return -EINTR;
117 }
118 EFX_ERR(efx_mtd->efx, "timed out waiting for %s\n", efx_mtd->name);
119 return -ETIMEDOUT;
120 }
122 static int
123 efx_spi_write_enable(struct efx_mtd *efx_mtd)
124 {
125 struct efx_spi_device *spi = efx_mtd->spi;
127 return spi->write(spi, efx_mtd->efx, SPI_WREN, -1, NULL, 0);
128 }
130 static int efx_spi_unlock(struct efx_mtd *efx_mtd)
131 {
132 struct efx_spi_device *spi = efx_mtd->spi;
133 const u8 unlock_mask = (SPI_STATUS_BP2 | SPI_STATUS_BP1 |
134 SPI_STATUS_BP0);
135 u8 status;
136 int rc;
138 rc = spi->read(spi, efx_mtd->efx, SPI_RDSR, -1, &status,
139 sizeof(status));
140 if (rc)
141 return rc;
143 if (!(status & unlock_mask))
144 return 0; /* already unlocked */
146 rc = efx_spi_write_enable(efx_mtd);
147 if (rc)
148 return rc;
149 rc = spi->write(spi, efx_mtd->efx, SPI_SST_EWSR, -1, NULL, 0);
150 if (rc)
151 return rc;
153 status &= ~unlock_mask;
154 rc = spi->write(spi, efx_mtd->efx, SPI_WRSR, -1, &status,
155 sizeof(status));
156 if (rc)
157 return rc;
158 rc = efx_spi_fast_wait(efx_mtd);
159 if (rc)
160 return rc;
162 return 0;
163 }
165 /* Dummy device used in case of a failed reset */
167 static int efx_spi_dummy_read(const struct efx_spi_device *spi,
168 struct efx_nic *efx, unsigned int command,
169 int address, void *data, unsigned int len)
170 {
171 return -EIO;
172 }
174 static int efx_spi_dummy_write(const struct efx_spi_device *spi,
175 struct efx_nic *efx, unsigned int command,
176 int address, const void *data, unsigned int len)
177 {
178 return -EIO;
179 }
181 static struct efx_spi_device efx_spi_dummy_device = {
182 .block_size = 1,
183 .erase_command = 0xff,
184 .read = efx_spi_dummy_read,
185 .write = efx_spi_dummy_write,
186 };
188 /* MTD interface */
190 static int efx_mtd_read(struct mtd_info *mtd, loff_t start, size_t len,
191 size_t *retlen, u8 *buffer)
192 {
193 struct efx_mtd *efx_mtd = mtd->priv;
194 struct efx_spi_device *spi;
195 unsigned int command;
196 unsigned int block_len;
197 unsigned int pos = 0;
198 int rc;
200 rc = down_interruptible(&efx_mtd->access_lock);
201 if (rc)
202 goto out;
203 spi = efx_mtd->spi;
205 while (pos < len) {
206 block_len = min((unsigned int)len - pos,
207 efx_spi_read_limit(spi, start + pos));
208 command = efx_spi_munge_command(spi, SPI_READ, start + pos);
209 rc = spi->read(spi, efx_mtd->efx, command, start + pos,
210 buffer + pos, block_len);
211 if (rc)
212 break;
213 pos += block_len;
215 /* Avoid locking up the system */
216 cond_resched();
217 if (signal_pending(current)) {
218 rc = -EINTR;
219 break;
220 }
221 }
223 up(&efx_mtd->access_lock);
224 out:
225 *retlen = pos;
226 return rc;
227 }
229 /* Check that device contents match buffer. If repeat is true, buffer
230 * contains a pattern of length EFX_MTD_VERIFY_BUF_LEN which the
231 * device contents should match repeatedly.
232 */
233 static int efx_mtd_verify(struct mtd_info *mtd, loff_t start,
234 size_t len, const u8 *buffer, int repeat)
235 {
236 u8 verify_buffer[EFX_MTD_VERIFY_BUF_LEN];
237 unsigned int block_len;
238 size_t read_len;
239 unsigned int pos = 0;
240 int rc = 0;
242 while (pos < len) {
243 block_len = min(len - pos, sizeof(verify_buffer));
244 rc = efx_mtd_read(mtd, start + pos, block_len, &read_len,
245 verify_buffer);
246 if (rc)
247 return rc;
248 if (memcmp(repeat ? buffer : buffer + pos, verify_buffer,
249 block_len))
250 return -EIO;
251 pos += block_len;
252 }
254 return 0;
255 }
257 static int efx_mtd_erase(struct mtd_info *mtd, struct erase_info *erase)
258 {
259 struct efx_mtd *efx_mtd = mtd->priv;
260 struct efx_spi_device *spi;
261 u8 empty[EFX_MTD_VERIFY_BUF_LEN];
262 int rc;
264 if (erase->len != mtd->erasesize) {
265 rc = -EINVAL;
266 goto out;
267 }
269 rc = down_interruptible(&efx_mtd->access_lock);
270 if (rc)
271 goto out;
272 spi = efx_mtd->spi;
273 if (spi->erase_command == 0) {
274 rc = -EOPNOTSUPP;
275 goto out_up;
276 }
278 rc = efx_spi_unlock(efx_mtd);
279 if (rc)
280 goto out_up;
281 rc = efx_spi_write_enable(efx_mtd);
282 if (rc)
283 goto out_up;
284 rc = spi->write(spi, efx_mtd->efx, spi->erase_command, erase->addr,
285 NULL, 0);
286 if (rc)
287 goto out_up;
288 rc = efx_spi_slow_wait(efx_mtd, 0);
290 out_up:
291 up(&efx_mtd->access_lock);
292 if (rc)
293 goto out;
295 memset(empty, 0xff, sizeof(empty));
296 rc = efx_mtd_verify(mtd, erase->addr, erase->len, empty, 1);
298 out:
299 if (rc == 0) {
300 erase->state = MTD_ERASE_DONE;
301 } else {
302 erase->state = MTD_ERASE_FAILED;
303 erase->fail_addr = 0xffffffff;
304 }
305 mtd_erase_callback(erase);
306 return rc;
307 }
309 static int efx_mtd_write(struct mtd_info *mtd, loff_t start,
310 size_t len, size_t *retlen, const u8 *buffer)
311 {
312 struct efx_mtd *efx_mtd = mtd->priv;
313 struct efx_spi_device *spi;
314 unsigned int command;
315 unsigned int block_len;
316 unsigned int pos = 0;
317 int rc;
319 rc = down_interruptible(&efx_mtd->access_lock);
320 if (rc)
321 goto out;
322 spi = efx_mtd->spi;
324 rc = efx_spi_unlock(efx_mtd);
325 if (rc)
326 goto out_up;
328 while (pos < len) {
329 rc = efx_spi_write_enable(efx_mtd);
330 if (rc)
331 break;
333 block_len = min((unsigned int)len - pos,
334 efx_spi_write_limit(spi, start + pos));
335 command = efx_spi_munge_command(spi, SPI_WRITE, start + pos);
336 rc = spi->write(spi, efx_mtd->efx, command, start + pos,
337 buffer + pos, block_len);
338 if (rc)
339 break;
340 pos += block_len;
342 rc = efx_spi_fast_wait(efx_mtd);
343 if (rc)
344 break;
346 /* Avoid locking up the system */
347 cond_resched();
348 if (signal_pending(current)) {
349 rc = -EINTR;
350 break;
351 }
352 }
354 out_up:
355 up(&efx_mtd->access_lock);
356 if (rc == 0)
357 rc = efx_mtd_verify(mtd, start, len, buffer, 0);
358 out:
359 *retlen = pos;
360 return rc;
361 }
363 static void efx_mtd_sync(struct mtd_info *mtd)
364 {
365 struct efx_mtd *efx_mtd = mtd->priv;
366 int rc;
368 down(&efx_mtd->access_lock);
369 rc = efx_spi_slow_wait(efx_mtd, 1);
370 if (rc)
371 EFX_ERR(efx_mtd->efx, "%s sync failed (%d)\n",
372 efx_mtd->name, rc);
373 up(&efx_mtd->access_lock);
374 }
376 /* Driverlink interface */
378 static void efx_mtd_reset_suspend(struct efx_dl_device *efx_dev)
379 {
380 struct efx_mtd *efx_mtd = efx_dev->priv;
382 if (!efx_mtd)
383 return;
385 /* Acquire lock to ensure that any in-progress operations have
386 * completed, and no new ones can start.
387 */
388 down(&efx_mtd->access_lock);
389 }
391 static void efx_mtd_reset_resume(struct efx_dl_device *efx_dev, int ok)
392 {
393 struct efx_mtd *efx_mtd = efx_dev->priv;
395 if (!efx_mtd)
396 return;
398 /* If device reset failed already, or SPI device doesn't
399 * become ready, disable device.
400 */
401 if (!ok || efx_spi_slow_wait(efx_mtd, 1) != 0) {
402 efx_mtd->spi = &efx_spi_dummy_device;
403 EFX_ERR(efx_mtd->efx, "%s disabled after failed reset\n",
404 efx_mtd->name);
405 }
407 up(&efx_mtd->access_lock);
408 }
410 static void efx_mtd_remove(struct efx_dl_device *efx_dev)
411 {
412 struct efx_mtd *efx_mtd = efx_dev->priv;
414 del_mtd_partitions(&efx_mtd->mtd);
415 kfree(efx_mtd);
416 efx_dev->priv = NULL;
417 }
419 static __devinit int efx_mtd_register(struct efx_mtd *efx_mtd,
420 struct efx_dl_device *efx_dev,
421 struct efx_nic *efx,
422 struct efx_spi_device *spi,
423 const char *type_name,
424 const char **part_type_name,
425 unsigned int num_parts)
426 {
427 int i;
429 efx_dev->priv = efx_mtd;
431 efx_mtd->efx_dev = efx_dev;
432 efx_mtd->efx = efx;
433 efx_mtd->spi = spi;
434 sema_init(&efx_mtd->access_lock, 1);
436 efx_mtd->mtd.size = spi->size;
437 efx_mtd->mtd.erasesize = spi->erase_size;
438 efx_mtd->mtd.writesize = 1;
439 if (snprintf(efx_mtd->name, sizeof(efx_mtd->name),
440 "%s %s", efx->name, type_name) >=
441 sizeof(efx_mtd->name))
442 return -ENAMETOOLONG;
444 efx_mtd->mtd.priv = efx_mtd;
445 efx_mtd->mtd.name = efx_mtd->name;
446 efx_mtd->mtd.erase = efx_mtd_erase;
447 efx_mtd->mtd.read = efx_mtd_read;
448 efx_mtd->mtd.write = efx_mtd_write;
449 efx_mtd->mtd.sync = efx_mtd_sync;
451 for (i = 0; i < num_parts; i++) {
452 efx_mtd->part[i].name = efx_mtd->part_name[i];
453 if (snprintf(efx_mtd->part_name[i],
454 sizeof(efx_mtd->part_name[i]),
455 "%s %s", efx->name, part_type_name[i]) >=
456 sizeof(efx_mtd->part_name[i]))
457 return -ENAMETOOLONG;
459 if (efx_allow_nvconfig_writes)
460 efx_mtd->part[i].mask_flags &= ~MTD_WRITEABLE;
461 }
463 return add_mtd_partitions(&efx_mtd->mtd, efx_mtd->part, num_parts);
464 }
466 static int __devinit
467 efx_flash_probe(struct efx_dl_device *efx_dev,
468 const struct net_device *net_dev,
469 const struct efx_dl_device_info *dev_info,
470 const char *silicon_rev)
471 {
472 struct efx_nic *efx = efx_dl_get_nic(efx_dev);
473 struct efx_mtd *efx_mtd;
474 const char *part_type_name[2];
475 unsigned int num_parts;
476 int rc;
478 if (!efx->spi_flash)
479 return -ENODEV;
481 efx_mtd = kzalloc(sizeof(*efx_mtd), GFP_KERNEL);
482 if (!efx_mtd)
483 return -ENOMEM;
485 efx_mtd->mtd.type = MTD_NORFLASH;
486 efx_mtd->mtd.flags = MTD_CAP_NORFLASH;
488 part_type_name[0] = "sfc_flash_config";
489 efx_mtd->part[0].offset = 0;
490 efx_mtd->part[0].size = min(efx->spi_flash->size,
491 EFX_FLASH_BOOTROM_OFFSET);
492 efx_mtd->part[0].mask_flags = MTD_WRITEABLE;
494 if (efx->spi_flash->size <= EFX_FLASH_BOOTROM_OFFSET) {
495 num_parts = 1;
496 } else {
497 part_type_name[1] = "sfc_flash_bootrom";
498 efx_mtd->part[1].offset = EFX_FLASH_BOOTROM_OFFSET;
499 efx_mtd->part[1].size = (efx->spi_flash->size
500 - EFX_FLASH_BOOTROM_OFFSET);
501 num_parts = 2;
502 }
504 rc = efx_mtd_register(efx_mtd, efx_dev, efx, efx->spi_flash,
505 "sfc_flash", part_type_name, num_parts);
506 if (rc)
507 kfree(efx_mtd);
508 return rc;
509 }
511 static struct efx_dl_driver efx_flash_driver = {
512 .name = "sfc_flash",
513 .probe = efx_flash_probe,
514 .remove = efx_mtd_remove,
515 .reset_suspend = efx_mtd_reset_suspend,
516 .reset_resume = efx_mtd_reset_resume,
517 };
519 static int __devinit
520 efx_eeprom_probe(struct efx_dl_device *efx_dev,
521 const struct net_device *net_dev,
522 const struct efx_dl_device_info *dev_info,
523 const char *silicon_rev)
524 {
525 struct efx_nic *efx = efx_dl_get_nic(efx_dev);
526 struct efx_mtd *efx_mtd;
527 const char *type_name;
528 const char *part_type_name[1];
529 int rc;
531 if (!efx->spi_eeprom)
532 return -ENODEV;
534 efx_mtd = kzalloc(sizeof(*efx_mtd), GFP_KERNEL);
535 if (!efx_mtd)
536 return -ENOMEM;
538 efx_mtd->mtd.type = MTD_RAM;
539 efx_mtd->mtd.flags = MTD_CAP_RAM;
541 efx_mtd->part[0].offset = 0;
542 efx_mtd->part[0].size = efx->spi_eeprom->size;
543 efx_mtd->part[0].mask_flags = MTD_WRITEABLE;
545 if (efx->spi_eeprom->size <= 0x200) {
546 type_name = "sfc_small_eeprom";
547 part_type_name[0] = "sfc_small_config";
548 } else {
549 type_name = "sfc_large_eeprom";
550 part_type_name[0] = "sfc_large_config";
551 }
553 rc = efx_mtd_register(efx_mtd, efx_dev, efx, efx->spi_eeprom,
554 type_name, part_type_name, 1);
555 if (rc)
556 kfree(efx_mtd);
557 return rc;
558 }
560 static struct efx_dl_driver efx_eeprom_driver = {
561 .name = "sfc_eeprom",
562 .probe = efx_eeprom_probe,
563 .remove = efx_mtd_remove,
564 .reset_suspend = efx_mtd_reset_suspend,
565 .reset_resume = efx_mtd_reset_resume,
566 };
568 /* Kernel module interface */
570 static int __init efx_mtd_init_module(void)
571 {
572 int rc;
574 rc = efx_dl_register_driver(&efx_flash_driver);
575 if (rc)
576 return rc;
577 rc = efx_dl_register_driver(&efx_eeprom_driver);
578 if (rc) {
579 efx_dl_unregister_driver(&efx_flash_driver);
580 return rc;
581 }
583 return 0;
584 }
586 static void __exit efx_mtd_exit_module(void)
587 {
588 efx_dl_unregister_driver(&efx_eeprom_driver);
589 efx_dl_unregister_driver(&efx_flash_driver);
590 }
592 module_init(efx_mtd_init_module);
593 module_exit(efx_mtd_exit_module);
595 MODULE_AUTHOR("Michael Brown <mbrown@fensystems.co.uk> and "
596 "Solarflare Communications");
597 MODULE_DESCRIPTION("SFC MTD driver");
598 MODULE_LICENSE("GPL");