aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJon Mason <jon.mason@exar.com>2010-11-10 23:25:57 -0500
committerDavid S. Miller <davem@davemloft.net>2010-11-11 12:30:21 -0500
commite8ac175615b9458a00193c55617b5b8865e67817 (patch)
tree31c688b4b9d2a3578ef712d05534bca4395e6281 /drivers/net
parent8424e00dfd5282026a93996a165fc4079d382169 (diff)
vxge: add support for ethtool firmware flashing
Add the ability in the vxge driver to flash firmware via ethtool. Updated to include comments from Ben Hutchings. Signed-off-by: Jon Mason <jon.mason@exar.com> Signed-off-by: Ram Vepa <ram.vepa@exar.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/vxge/vxge-config.c183
-rw-r--r--drivers/net/vxge/vxge-config.h71
-rw-r--r--drivers/net/vxge/vxge-ethtool.c20
-rw-r--r--drivers/net/vxge/vxge-main.c190
-rw-r--r--drivers/net/vxge/vxge-main.h2
-rw-r--r--drivers/net/vxge/vxge-reg.h29
-rw-r--r--drivers/net/vxge/vxge-version.h27
7 files changed, 500 insertions, 22 deletions
diff --git a/drivers/net/vxge/vxge-config.c b/drivers/net/vxge/vxge-config.c
index c822463faf0..7761b9e0ad8 100644
--- a/drivers/net/vxge/vxge-config.c
+++ b/drivers/net/vxge/vxge-config.c
@@ -155,7 +155,6 @@ __vxge_hw_vpath_reset_check(struct __vxge_hw_virtualpath *vpath);
155static enum vxge_hw_status 155static enum vxge_hw_status
156__vxge_hw_vpath_sw_reset(struct __vxge_hw_device *devh, u32 vp_id); 156__vxge_hw_vpath_sw_reset(struct __vxge_hw_device *devh, u32 vp_id);
157 157
158
159static enum vxge_hw_status 158static enum vxge_hw_status
160__vxge_hw_vpath_mac_configure(struct __vxge_hw_device *devh, u32 vp_id); 159__vxge_hw_vpath_mac_configure(struct __vxge_hw_device *devh, u32 vp_id);
161 160
@@ -322,6 +321,188 @@ out:
322 return status; 321 return status;
323} 322}
324 323
324enum vxge_hw_status
325vxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major,
326 u32 *minor, u32 *build)
327{
328 u64 data0 = 0, data1 = 0, steer_ctrl = 0;
329 struct __vxge_hw_virtualpath *vpath;
330 enum vxge_hw_status status;
331
332 vpath = &hldev->virtual_paths[hldev->first_vp_id];
333
334 status = vxge_hw_vpath_fw_api(vpath,
335 VXGE_HW_FW_UPGRADE_ACTION,
336 VXGE_HW_FW_UPGRADE_MEMO,
337 VXGE_HW_FW_UPGRADE_OFFSET_READ,
338 &data0, &data1, &steer_ctrl);
339 if (status != VXGE_HW_OK)
340 return status;
341
342 *major = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MAJOR(data0);
343 *minor = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_MINOR(data0);
344 *build = VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_FW_VER_BUILD(data0);
345
346 return status;
347}
348
349enum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev)
350{
351 u64 data0 = 0, data1 = 0, steer_ctrl = 0;
352 struct __vxge_hw_virtualpath *vpath;
353 enum vxge_hw_status status;
354 u32 ret;
355
356 vpath = &hldev->virtual_paths[hldev->first_vp_id];
357
358 status = vxge_hw_vpath_fw_api(vpath,
359 VXGE_HW_FW_UPGRADE_ACTION,
360 VXGE_HW_FW_UPGRADE_MEMO,
361 VXGE_HW_FW_UPGRADE_OFFSET_COMMIT,
362 &data0, &data1, &steer_ctrl);
363 if (status != VXGE_HW_OK) {
364 vxge_debug_init(VXGE_ERR, "%s: FW upgrade failed", __func__);
365 goto exit;
366 }
367
368 ret = VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(steer_ctrl) & 0x7F;
369 if (ret != 1) {
370 vxge_debug_init(VXGE_ERR, "%s: FW commit failed with error %d",
371 __func__, ret);
372 status = VXGE_HW_FAIL;
373 }
374
375exit:
376 return status;
377}
378
379enum vxge_hw_status
380vxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *fwdata, int size)
381{
382 u64 data0 = 0, data1 = 0, steer_ctrl = 0;
383 struct __vxge_hw_virtualpath *vpath;
384 enum vxge_hw_status status;
385 int ret_code, sec_code;
386
387 vpath = &hldev->virtual_paths[hldev->first_vp_id];
388
389 /* send upgrade start command */
390 status = vxge_hw_vpath_fw_api(vpath,
391 VXGE_HW_FW_UPGRADE_ACTION,
392 VXGE_HW_FW_UPGRADE_MEMO,
393 VXGE_HW_FW_UPGRADE_OFFSET_START,
394 &data0, &data1, &steer_ctrl);
395 if (status != VXGE_HW_OK) {
396 vxge_debug_init(VXGE_ERR, " %s: Upgrade start cmd failed",
397 __func__);
398 return status;
399 }
400
401 /* Transfer fw image to adapter 16 bytes at a time */
402 for (; size > 0; size -= VXGE_HW_FW_UPGRADE_BLK_SIZE) {
403 steer_ctrl = 0;
404
405 /* The next 128bits of fwdata to be loaded onto the adapter */
406 data0 = *((u64 *)fwdata);
407 data1 = *((u64 *)fwdata + 1);
408
409 status = vxge_hw_vpath_fw_api(vpath,
410 VXGE_HW_FW_UPGRADE_ACTION,
411 VXGE_HW_FW_UPGRADE_MEMO,
412 VXGE_HW_FW_UPGRADE_OFFSET_SEND,
413 &data0, &data1, &steer_ctrl);
414 if (status != VXGE_HW_OK) {
415 vxge_debug_init(VXGE_ERR, "%s: Upgrade send failed",
416 __func__);
417 goto out;
418 }
419
420 ret_code = VXGE_HW_UPGRADE_GET_RET_ERR_CODE(data0);
421 switch (ret_code) {
422 case VXGE_HW_FW_UPGRADE_OK:
423 /* All OK, send next 16 bytes. */
424 break;
425 case VXGE_FW_UPGRADE_BYTES2SKIP:
426 /* skip bytes in the stream */
427 fwdata += (data0 >> 8) & 0xFFFFFFFF;
428 break;
429 case VXGE_HW_FW_UPGRADE_DONE:
430 goto out;
431 case VXGE_HW_FW_UPGRADE_ERR:
432 sec_code = VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(data0);
433 switch (sec_code) {
434 case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1:
435 case VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7:
436 printk(KERN_ERR
437 "corrupted data from .ncf file\n");
438 break;
439 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3:
440 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4:
441 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5:
442 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6:
443 case VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8:
444 printk(KERN_ERR "invalid .ncf file\n");
445 break;
446 case VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW:
447 printk(KERN_ERR "buffer overflow\n");
448 break;
449 case VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH:
450 printk(KERN_ERR "failed to flash the image\n");
451 break;
452 case VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN:
453 printk(KERN_ERR
454 "generic error. Unknown error type\n");
455 break;
456 default:
457 printk(KERN_ERR "Unknown error of type %d\n",
458 sec_code);
459 break;
460 }
461 status = VXGE_HW_FAIL;
462 goto out;
463 default:
464 printk(KERN_ERR "Unknown FW error: %d\n", ret_code);
465 status = VXGE_HW_FAIL;
466 goto out;
467 }
468 /* point to next 16 bytes */
469 fwdata += VXGE_HW_FW_UPGRADE_BLK_SIZE;
470 }
471out:
472 return status;
473}
474
475enum vxge_hw_status
476vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev,
477 struct eprom_image *img)
478{
479 u64 data0 = 0, data1 = 0, steer_ctrl = 0;
480 struct __vxge_hw_virtualpath *vpath;
481 enum vxge_hw_status status;
482 int i;
483
484 vpath = &hldev->virtual_paths[hldev->first_vp_id];
485
486 for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) {
487 data0 = VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(i);
488 data1 = steer_ctrl = 0;
489
490 status = vxge_hw_vpath_fw_api(vpath,
491 VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO,
492 VXGE_HW_FW_API_GET_EPROM_REV,
493 0, &data0, &data1, &steer_ctrl);
494 if (status != VXGE_HW_OK)
495 break;
496
497 img[i].is_valid = VXGE_HW_GET_EPROM_IMAGE_VALID(data0);
498 img[i].index = VXGE_HW_GET_EPROM_IMAGE_INDEX(data0);
499 img[i].type = VXGE_HW_GET_EPROM_IMAGE_TYPE(data0);
500 img[i].version = VXGE_HW_GET_EPROM_IMAGE_REV(data0);
501 }
502
503 return status;
504}
505
325/* 506/*
326 * __vxge_hw_channel_allocate - Allocate memory for channel 507 * __vxge_hw_channel_allocate - Allocate memory for channel
327 * This function allocates required memory for the channel and various arrays 508 * This function allocates required memory for the channel and various arrays
diff --git a/drivers/net/vxge/vxge-config.h b/drivers/net/vxge/vxge-config.h
index 6a81014df59..95230bda065 100644
--- a/drivers/net/vxge/vxge-config.h
+++ b/drivers/net/vxge/vxge-config.h
@@ -29,6 +29,15 @@
29#define VXGE_HW_MAX_MTU 9600 29#define VXGE_HW_MAX_MTU 9600
30#define VXGE_HW_DEFAULT_MTU 1500 30#define VXGE_HW_DEFAULT_MTU 1500
31 31
32#define VXGE_HW_MAX_ROM_IMAGES 8
33
34struct eprom_image {
35 u8 is_valid:1;
36 u8 index;
37 u8 type;
38 u16 version;
39};
40
32#ifdef VXGE_DEBUG_ASSERT 41#ifdef VXGE_DEBUG_ASSERT
33/** 42/**
34 * vxge_assert 43 * vxge_assert
@@ -148,6 +157,47 @@ enum vxge_hw_device_link_state {
148}; 157};
149 158
150/** 159/**
160 * enum enum vxge_hw_fw_upgrade_code - FW upgrade return codes.
161 * @VXGE_HW_FW_UPGRADE_OK: All OK send next 16 bytes
162 * @VXGE_HW_FW_UPGRADE_DONE: upload completed
163 * @VXGE_HW_FW_UPGRADE_ERR: upload error
164 * @VXGE_FW_UPGRADE_BYTES2SKIP: skip bytes in the stream
165 *
166 */
167enum vxge_hw_fw_upgrade_code {
168 VXGE_HW_FW_UPGRADE_OK = 0,
169 VXGE_HW_FW_UPGRADE_DONE = 1,
170 VXGE_HW_FW_UPGRADE_ERR = 2,
171 VXGE_FW_UPGRADE_BYTES2SKIP = 3
172};
173
174/**
175 * enum enum vxge_hw_fw_upgrade_err_code - FW upgrade error codes.
176 * @VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1: corrupt data
177 * @VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW: buffer overflow
178 * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3: invalid .ncf file
179 * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4: invalid .ncf file
180 * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5: invalid .ncf file
181 * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6: invalid .ncf file
182 * @VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7: corrupt data
183 * @VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8: invalid .ncf file
184 * @VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN: generic error unknown type
185 * @VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH: failed to flash image check failed
186 */
187enum vxge_hw_fw_upgrade_err_code {
188 VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_1 = 1,
189 VXGE_HW_FW_UPGRADE_ERR_BUFFER_OVERFLOW = 2,
190 VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_3 = 3,
191 VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_4 = 4,
192 VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_5 = 5,
193 VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_6 = 6,
194 VXGE_HW_FW_UPGRADE_ERR_CORRUPT_DATA_7 = 7,
195 VXGE_HW_FW_UPGRADE_ERR_INV_NCF_FILE_8 = 8,
196 VXGE_HW_FW_UPGRADE_ERR_GENERIC_ERROR_UNKNOWN = 9,
197 VXGE_HW_FW_UPGRADE_ERR_FAILED_TO_FLASH = 10
198};
199
200/**
151 * struct vxge_hw_device_date - Date Format 201 * struct vxge_hw_device_date - Date Format
152 * @day: Day 202 * @day: Day
153 * @month: Month 203 * @month: Month
@@ -454,7 +504,6 @@ struct vxge_hw_device_config {
454 * See also: vxge_hw_driver_initialize(). 504 * See also: vxge_hw_driver_initialize().
455 */ 505 */
456struct vxge_hw_uld_cbs { 506struct vxge_hw_uld_cbs {
457
458 void (*link_up)(struct __vxge_hw_device *devh); 507 void (*link_up)(struct __vxge_hw_device *devh);
459 void (*link_down)(struct __vxge_hw_device *devh); 508 void (*link_down)(struct __vxge_hw_device *devh);
460 void (*crit_err)(struct __vxge_hw_device *devh, 509 void (*crit_err)(struct __vxge_hw_device *devh,
@@ -721,6 +770,7 @@ struct __vxge_hw_device {
721 u32 debug_level; 770 u32 debug_level;
722 u32 level_err; 771 u32 level_err;
723 u32 level_trace; 772 u32 level_trace;
773 u16 eprom_versions[VXGE_HW_MAX_ROM_IMAGES];
724}; 774};
725 775
726#define VXGE_HW_INFO_LEN 64 776#define VXGE_HW_INFO_LEN 64
@@ -2032,7 +2082,22 @@ __vxge_hw_device_is_privilaged(u32 host_type, u32 func_id);
2032#define VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT 5 2082#define VXGE_HW_MIN_SUCCESSIVE_IDLE_COUNT 5
2033#define VXGE_HW_MAX_POLLING_COUNT 100 2083#define VXGE_HW_MAX_POLLING_COUNT 100
2034 2084
2035int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id); 2085void
2086vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev);
2087
2088enum vxge_hw_status
2089vxge_hw_upgrade_read_version(struct __vxge_hw_device *hldev, u32 *major,
2090 u32 *minor, u32 *build);
2091
2092enum vxge_hw_status vxge_hw_flash_fw(struct __vxge_hw_device *hldev);
2036 2093
2037void vxge_hw_device_wait_receive_idle(struct __vxge_hw_device *hldev); 2094enum vxge_hw_status
2095vxge_update_fw_image(struct __vxge_hw_device *hldev, const u8 *filebuf,
2096 int size);
2097
2098enum vxge_hw_status
2099vxge_hw_vpath_eprom_img_ver_get(struct __vxge_hw_device *hldev,
2100 struct eprom_image *eprom_image_data);
2101
2102int vxge_hw_vpath_wait_receive_idle(struct __vxge_hw_device *hldev, u32 vp_id);
2038#endif 2103#endif
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index f8fd8da4f17..3d2cd6acf30 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -1153,6 +1153,25 @@ static int vxge_set_flags(struct net_device *dev, u32 data)
1153 return 0; 1153 return 0;
1154} 1154}
1155 1155
1156static int vxge_fw_flash(struct net_device *dev, struct ethtool_flash *parms)
1157{
1158 struct vxgedev *vdev = (struct vxgedev *)netdev_priv(dev);
1159
1160 if (vdev->max_vpath_supported != VXGE_HW_MAX_VIRTUAL_PATHS) {
1161 printk(KERN_INFO "Single Function Mode is required to flash the"
1162 " firmware\n");
1163 return -EINVAL;
1164 }
1165
1166 if (netif_running(dev)) {
1167 printk(KERN_INFO "Interface %s must be down to flash the "
1168 "firmware\n", dev->name);
1169 return -EBUSY;
1170 }
1171
1172 return vxge_fw_upgrade(vdev, parms->data, 1);
1173}
1174
1156static const struct ethtool_ops vxge_ethtool_ops = { 1175static const struct ethtool_ops vxge_ethtool_ops = {
1157 .get_settings = vxge_ethtool_gset, 1176 .get_settings = vxge_ethtool_gset,
1158 .set_settings = vxge_ethtool_sset, 1177 .set_settings = vxge_ethtool_sset,
@@ -1175,6 +1194,7 @@ static const struct ethtool_ops vxge_ethtool_ops = {
1175 .get_sset_count = vxge_ethtool_get_sset_count, 1194 .get_sset_count = vxge_ethtool_get_sset_count,
1176 .get_ethtool_stats = vxge_get_ethtool_stats, 1195 .get_ethtool_stats = vxge_get_ethtool_stats,
1177 .set_flags = vxge_set_flags, 1196 .set_flags = vxge_set_flags,
1197 .flash_device = vxge_fw_flash,
1178}; 1198};
1179 1199
1180void vxge_initialize_ethtool_ops(struct net_device *ndev) 1200void vxge_initialize_ethtool_ops(struct net_device *ndev)
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 53db6a4b960..10549bd3922 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -50,6 +50,7 @@
50#include <net/ip.h> 50#include <net/ip.h>
51#include <linux/netdevice.h> 51#include <linux/netdevice.h>
52#include <linux/etherdevice.h> 52#include <linux/etherdevice.h>
53#include <linux/firmware.h>
53#include "vxge-main.h" 54#include "vxge-main.h"
54#include "vxge-reg.h" 55#include "vxge-reg.h"
55 56
@@ -3248,6 +3249,7 @@ static int __devinit vxge_device_register(struct __vxge_hw_device *hldev,
3248 "%s: Ethernet device registered", 3249 "%s: Ethernet device registered",
3249 ndev->name); 3250 ndev->name);
3250 3251
3252 hldev->ndev = ndev;
3251 *vdev_out = vdev; 3253 *vdev_out = vdev;
3252 3254
3253 /* Resetting the Device stats */ 3255 /* Resetting the Device stats */
@@ -3935,6 +3937,142 @@ static inline u32 vxge_get_num_vfs(u64 function_mode)
3935 return num_functions; 3937 return num_functions;
3936} 3938}
3937 3939
3940int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override)
3941{
3942 struct __vxge_hw_device *hldev = vdev->devh;
3943 u32 maj, min, bld, cmaj, cmin, cbld;
3944 enum vxge_hw_status status;
3945 const struct firmware *fw;
3946 int ret;
3947
3948 ret = request_firmware(&fw, fw_name, &vdev->pdev->dev);
3949 if (ret) {
3950 vxge_debug_init(VXGE_ERR, "%s: Firmware file '%s' not found",
3951 VXGE_DRIVER_NAME, fw_name);
3952 goto out;
3953 }
3954
3955 /* Load the new firmware onto the adapter */
3956 status = vxge_update_fw_image(hldev, fw->data, fw->size);
3957 if (status != VXGE_HW_OK) {
3958 vxge_debug_init(VXGE_ERR,
3959 "%s: FW image download to adapter failed '%s'.",
3960 VXGE_DRIVER_NAME, fw_name);
3961 ret = -EIO;
3962 goto out;
3963 }
3964
3965 /* Read the version of the new firmware */
3966 status = vxge_hw_upgrade_read_version(hldev, &maj, &min, &bld);
3967 if (status != VXGE_HW_OK) {
3968 vxge_debug_init(VXGE_ERR,
3969 "%s: Upgrade read version failed '%s'.",
3970 VXGE_DRIVER_NAME, fw_name);
3971 ret = -EIO;
3972 goto out;
3973 }
3974
3975 cmaj = vdev->config.device_hw_info.fw_version.major;
3976 cmin = vdev->config.device_hw_info.fw_version.minor;
3977 cbld = vdev->config.device_hw_info.fw_version.build;
3978 /* It's possible the version in /lib/firmware is not the latest version.
3979 * If so, we could get into a loop of trying to upgrade to the latest
3980 * and flashing the older version.
3981 */
3982 if (VXGE_FW_VER(maj, min, bld) == VXGE_FW_VER(cmaj, cmin, cbld) &&
3983 !override) {
3984 ret = -EINVAL;
3985 goto out;
3986 }
3987
3988 printk(KERN_NOTICE "Upgrade to firmware version %d.%d.%d commencing\n",
3989 maj, min, bld);
3990
3991 /* Flash the adapter with the new firmware */
3992 status = vxge_hw_flash_fw(hldev);
3993 if (status != VXGE_HW_OK) {
3994 vxge_debug_init(VXGE_ERR, "%s: Upgrade commit failed '%s'.",
3995 VXGE_DRIVER_NAME, fw_name);
3996 ret = -EIO;
3997 goto out;
3998 }
3999
4000 printk(KERN_NOTICE "Upgrade of firmware successful! Adapter must be "
4001 "hard reset before using, thus requiring a system reboot or a "
4002 "hotplug event.\n");
4003
4004out:
4005 return ret;
4006}
4007
4008static int vxge_probe_fw_update(struct vxgedev *vdev)
4009{
4010 u32 maj, min, bld;
4011 int ret, gpxe = 0;
4012 char *fw_name;
4013
4014 maj = vdev->config.device_hw_info.fw_version.major;
4015 min = vdev->config.device_hw_info.fw_version.minor;
4016 bld = vdev->config.device_hw_info.fw_version.build;
4017
4018 if (VXGE_FW_VER(maj, min, bld) == VXGE_CERT_FW_VER)
4019 return 0;
4020
4021 /* Ignore the build number when determining if the current firmware is
4022 * "too new" to load the driver
4023 */
4024 if (VXGE_FW_VER(maj, min, 0) > VXGE_CERT_FW_VER) {
4025 vxge_debug_init(VXGE_ERR, "%s: Firmware newer than last known "
4026 "version, unable to load driver\n",
4027 VXGE_DRIVER_NAME);
4028 return -EINVAL;
4029 }
4030
4031 /* Firmware 1.4.4 and older cannot be upgraded, and is too ancient to
4032 * work with this driver.
4033 */
4034 if (VXGE_FW_VER(maj, min, bld) <= VXGE_FW_DEAD_VER) {
4035 vxge_debug_init(VXGE_ERR, "%s: Firmware %d.%d.%d cannot be "
4036 "upgraded\n", VXGE_DRIVER_NAME, maj, min, bld);
4037 return -EINVAL;
4038 }
4039
4040 /* If file not specified, determine gPXE or not */
4041 if (VXGE_FW_VER(maj, min, bld) >= VXGE_EPROM_FW_VER) {
4042 int i;
4043 for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++)
4044 if (vdev->devh->eprom_versions[i]) {
4045 gpxe = 1;
4046 break;
4047 }
4048 }
4049 if (gpxe)
4050 fw_name = "vxge/X3fw-pxe.ncf";
4051 else
4052 fw_name = "vxge/X3fw.ncf";
4053
4054 ret = vxge_fw_upgrade(vdev, fw_name, 0);
4055 /* -EINVAL and -ENOENT are not fatal errors for flashing firmware on
4056 * probe, so ignore them
4057 */
4058 if (ret != -EINVAL && ret != -ENOENT)
4059 return -EIO;
4060 else
4061 ret = 0;
4062
4063 if (VXGE_FW_VER(VXGE_CERT_FW_VER_MAJOR, VXGE_CERT_FW_VER_MINOR, 0) >
4064 VXGE_FW_VER(maj, min, 0)) {
4065 vxge_debug_init(VXGE_ERR, "%s: Firmware %d.%d.%d is too old to"
4066 " be used with this driver.\n"
4067 "Please get the latest version from "
4068 "ftp://ftp.s2io.com/pub/X3100-Drivers/FIRMWARE",
4069 VXGE_DRIVER_NAME, maj, min, bld);
4070 return -EINVAL;
4071 }
4072
4073 return ret;
4074}
4075
3938/** 4076/**
3939 * vxge_probe 4077 * vxge_probe
3940 * @pdev : structure containing the PCI related information of the device. 4078 * @pdev : structure containing the PCI related information of the device.
@@ -4093,16 +4231,6 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
4093 goto _exit3; 4231 goto _exit3;
4094 } 4232 }
4095 4233
4096 if (ll_config->device_hw_info.fw_version.major !=
4097 VXGE_DRIVER_FW_VERSION_MAJOR) {
4098 vxge_debug_init(VXGE_ERR,
4099 "%s: Incorrect firmware version."
4100 "Please upgrade the firmware to version 1.x.x",
4101 VXGE_DRIVER_NAME);
4102 ret = -EINVAL;
4103 goto _exit3;
4104 }
4105
4106 vpath_mask = ll_config->device_hw_info.vpath_mask; 4234 vpath_mask = ll_config->device_hw_info.vpath_mask;
4107 if (vpath_mask == 0) { 4235 if (vpath_mask == 0) {
4108 vxge_debug_ll_config(VXGE_TRACE, 4236 vxge_debug_ll_config(VXGE_TRACE,
@@ -4166,6 +4294,32 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
4166 goto _exit3; 4294 goto _exit3;
4167 } 4295 }
4168 4296
4297 if (VXGE_FW_VER(ll_config->device_hw_info.fw_version.major,
4298 ll_config->device_hw_info.fw_version.minor,
4299 ll_config->device_hw_info.fw_version.build) >=
4300 VXGE_EPROM_FW_VER) {
4301 struct eprom_image img[VXGE_HW_MAX_ROM_IMAGES];
4302
4303 status = vxge_hw_vpath_eprom_img_ver_get(hldev, img);
4304 if (status != VXGE_HW_OK) {
4305 vxge_debug_init(VXGE_ERR, "%s: Reading of EPROM failed",
4306 VXGE_DRIVER_NAME);
4307 /* This is a non-fatal error, continue */
4308 }
4309
4310 for (i = 0; i < VXGE_HW_MAX_ROM_IMAGES; i++) {
4311 hldev->eprom_versions[i] = img[i].version;
4312 if (!img[i].is_valid)
4313 break;
4314 vxge_debug_init(VXGE_TRACE, "%s: EPROM %d, version "
4315 "%d.%d.%d.%d\n", VXGE_DRIVER_NAME, i,
4316 VXGE_EPROM_IMG_MAJOR(img[i].version),
4317 VXGE_EPROM_IMG_MINOR(img[i].version),
4318 VXGE_EPROM_IMG_FIX(img[i].version),
4319 VXGE_EPROM_IMG_BUILD(img[i].version));
4320 }
4321 }
4322
4169 /* if FCS stripping is not disabled in MAC fail driver load */ 4323 /* if FCS stripping is not disabled in MAC fail driver load */
4170 if (vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask) != VXGE_HW_OK) { 4324 if (vxge_hw_vpath_strip_fcs_check(hldev, vpath_mask) != VXGE_HW_OK) {
4171 vxge_debug_init(VXGE_ERR, 4325 vxge_debug_init(VXGE_ERR,
@@ -4194,18 +4348,22 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
4194 ll_config->tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE; 4348 ll_config->tx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
4195 ll_config->rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE; 4349 ll_config->rx_pause_enable = VXGE_PAUSE_CTRL_ENABLE;
4196 4350
4197 if (vxge_device_register(hldev, ll_config, high_dma, no_of_vpath, 4351 ret = vxge_device_register(hldev, ll_config, high_dma, no_of_vpath,
4198 &vdev)) { 4352 &vdev);
4353 if (ret) {
4199 ret = -EINVAL; 4354 ret = -EINVAL;
4200 goto _exit4; 4355 goto _exit4;
4201 } 4356 }
4202 4357
4358 ret = vxge_probe_fw_update(vdev);
4359 if (ret)
4360 goto _exit5;
4361
4203 vxge_hw_device_debug_set(hldev, VXGE_TRACE, VXGE_COMPONENT_LL); 4362 vxge_hw_device_debug_set(hldev, VXGE_TRACE, VXGE_COMPONENT_LL);
4204 VXGE_COPY_DEBUG_INFO_TO_LL(vdev, vxge_hw_device_error_level_get(hldev), 4363 VXGE_COPY_DEBUG_INFO_TO_LL(vdev, vxge_hw_device_error_level_get(hldev),
4205 vxge_hw_device_trace_level_get(hldev)); 4364 vxge_hw_device_trace_level_get(hldev));
4206 4365
4207 /* set private HW device info */ 4366 /* set private HW device info */
4208 hldev->ndev = vdev->ndev;
4209 vdev->mtu = VXGE_HW_DEFAULT_MTU; 4367 vdev->mtu = VXGE_HW_DEFAULT_MTU;
4210 vdev->bar0 = attr.bar0; 4368 vdev->bar0 = attr.bar0;
4211 vdev->max_vpath_supported = max_vpath_supported; 4369 vdev->max_vpath_supported = max_vpath_supported;
@@ -4307,7 +4465,7 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
4307 "%s: mac_addr_list : memory allocation failed", 4465 "%s: mac_addr_list : memory allocation failed",
4308 vdev->ndev->name); 4466 vdev->ndev->name);
4309 ret = -EPERM; 4467 ret = -EPERM;
4310 goto _exit5; 4468 goto _exit6;
4311 } 4469 }
4312 macaddr = (u8 *)&entry->macaddr; 4470 macaddr = (u8 *)&entry->macaddr;
4313 memcpy(macaddr, vdev->ndev->dev_addr, ETH_ALEN); 4471 memcpy(macaddr, vdev->ndev->dev_addr, ETH_ALEN);
@@ -4347,10 +4505,10 @@ vxge_probe(struct pci_dev *pdev, const struct pci_device_id *pre)
4347 kfree(ll_config); 4505 kfree(ll_config);
4348 return 0; 4506 return 0;
4349 4507
4350_exit5: 4508_exit6:
4351 for (i = 0; i < vdev->no_of_vpath; i++) 4509 for (i = 0; i < vdev->no_of_vpath; i++)
4352 vxge_free_mac_add_list(&vdev->vpaths[i]); 4510 vxge_free_mac_add_list(&vdev->vpaths[i]);
4353 4511_exit5:
4354 vxge_device_unregister(hldev); 4512 vxge_device_unregister(hldev);
4355_exit4: 4513_exit4:
4356 pci_disable_sriov(pdev); 4514 pci_disable_sriov(pdev);
diff --git a/drivers/net/vxge/vxge-main.h b/drivers/net/vxge/vxge-main.h
index 3845e628a59..1699d7590b3 100644
--- a/drivers/net/vxge/vxge-main.h
+++ b/drivers/net/vxge/vxge-main.h
@@ -397,6 +397,8 @@ struct vxge_tx_priv {
397extern void vxge_initialize_ethtool_ops(struct net_device *ndev); 397extern void vxge_initialize_ethtool_ops(struct net_device *ndev);
398enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev); 398enum vxge_hw_status vxge_reset_all_vpaths(struct vxgedev *vdev);
399 399
400int vxge_fw_upgrade(struct vxgedev *vdev, char *fw_name, int override);
401
400/** 402/**
401 * #define VXGE_DEBUG_INIT: debug for initialization functions 403 * #define VXGE_DEBUG_INIT: debug for initialization functions
402 * #define VXGE_DEBUG_TX : debug transmit related functions 404 * #define VXGE_DEBUG_TX : debug transmit related functions
diff --git a/drivers/net/vxge/vxge-reg.h b/drivers/net/vxge/vxge-reg.h
index 93fd752187b..0df52dbd42a 100644
--- a/drivers/net/vxge/vxge-reg.h
+++ b/drivers/net/vxge/vxge-reg.h
@@ -49,6 +49,30 @@
49#define VXGE_HW_TITAN_VPMGMT_REG_SPACES 17 49#define VXGE_HW_TITAN_VPMGMT_REG_SPACES 17
50#define VXGE_HW_TITAN_VPATH_REG_SPACES 17 50#define VXGE_HW_TITAN_VPATH_REG_SPACES 17
51 51
52#define VXGE_HW_FW_API_GET_EPROM_REV 31
53
54#define VXGE_EPROM_IMG_MAJOR(val) (u32) vxge_bVALn(val, 48, 4)
55#define VXGE_EPROM_IMG_MINOR(val) (u32) vxge_bVALn(val, 52, 4)
56#define VXGE_EPROM_IMG_FIX(val) (u32) vxge_bVALn(val, 56, 4)
57#define VXGE_EPROM_IMG_BUILD(val) (u32) vxge_bVALn(val, 60, 4)
58
59#define VXGE_HW_GET_EPROM_IMAGE_INDEX(val) vxge_bVALn(val, 16, 8)
60#define VXGE_HW_GET_EPROM_IMAGE_VALID(val) vxge_bVALn(val, 31, 1)
61#define VXGE_HW_GET_EPROM_IMAGE_TYPE(val) vxge_bVALn(val, 40, 8)
62#define VXGE_HW_GET_EPROM_IMAGE_REV(val) vxge_bVALn(val, 48, 16)
63#define VXGE_HW_RTS_ACCESS_STEER_ROM_IMAGE_INDEX(val) vxge_vBIT(val, 16, 8)
64
65#define VXGE_HW_FW_UPGRADE_MEMO 13
66#define VXGE_HW_FW_UPGRADE_ACTION 16
67#define VXGE_HW_FW_UPGRADE_OFFSET_START 2
68#define VXGE_HW_FW_UPGRADE_OFFSET_SEND 3
69#define VXGE_HW_FW_UPGRADE_OFFSET_COMMIT 4
70#define VXGE_HW_FW_UPGRADE_OFFSET_READ 5
71
72#define VXGE_HW_FW_UPGRADE_BLK_SIZE 16
73#define VXGE_HW_UPGRADE_GET_RET_ERR_CODE(val) (val & 0xff)
74#define VXGE_HW_UPGRADE_GET_SEC_ERR_CODE(val) ((val >> 8) & 0xff)
75
52#define VXGE_HW_ASIC_MODE_RESERVED 0 76#define VXGE_HW_ASIC_MODE_RESERVED 0
53#define VXGE_HW_ASIC_MODE_NO_IOV 1 77#define VXGE_HW_ASIC_MODE_NO_IOV 1
54#define VXGE_HW_ASIC_MODE_SR_IOV 2 78#define VXGE_HW_ASIC_MODE_SR_IOV 2
@@ -165,13 +189,13 @@
165#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_ETYPE 2 189#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_ETYPE 2
166#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_PN 3 190#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_PN 3
167#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG 5 191#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_GEN_CFG 5
168#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6 192#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_SOLO_IT 6
169#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_JHASH_CFG 7 193#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_JHASH_CFG 7
170#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK 8 194#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MASK 8
171#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY 9 195#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_RTH_KEY 9
172#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_QOS 10 196#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_QOS 10
173#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DS 11 197#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_DS 11
174#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12 198#define VXGE_HW_RTS_ACS_STEER_CTRL_DATA_STRUCT_SEL_RTH_MULTI_IT 12
175#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO 13 199#define VXGE_HW_RTS_ACCESS_STEER_CTRL_DATA_STRUCT_SEL_FW_MEMO 13
176 200
177#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(bits) \ 201#define VXGE_HW_RTS_ACCESS_STEER_DATA0_GET_DA_MAC_ADDR(bits) \
@@ -437,6 +461,7 @@
437#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(bits) \ 461#define VXGE_HW_RTS_ACCESS_STEER_DATA1_GET_FLASH_VER_BUILD(bits) \
438 vxge_bVALn(bits, 48, 16) 462 vxge_bVALn(bits, 48, 16)
439#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_BUILD vxge_vBIT(val, 48, 16) 463#define VXGE_HW_RTS_ACCESS_STEER_DATA1_FLASH_VER_BUILD vxge_vBIT(val, 48, 16)
464#define VXGE_HW_RTS_ACCESS_STEER_CTRL_GET_ACTION(bits) vxge_bVALn(bits, 0, 8)
440 465
441#define VXGE_HW_SRPCIM_TO_VPATH_ALARM_REG_GET_PPIF_SRPCIM_TO_VPATH_ALARM(bits)\ 466#define VXGE_HW_SRPCIM_TO_VPATH_ALARM_REG_GET_PPIF_SRPCIM_TO_VPATH_ALARM(bits)\
442 vxge_bVALn(bits, 0, 18) 467 vxge_bVALn(bits, 0, 18)
diff --git a/drivers/net/vxge/vxge-version.h b/drivers/net/vxge/vxge-version.h
index 53fefe13736..b4eced19e45 100644
--- a/drivers/net/vxge/vxge-version.h
+++ b/drivers/net/vxge/vxge-version.h
@@ -19,4 +19,31 @@
19#define VXGE_VERSION_FIX "9" 19#define VXGE_VERSION_FIX "9"
20#define VXGE_VERSION_BUILD "20840" 20#define VXGE_VERSION_BUILD "20840"
21#define VXGE_VERSION_FOR "k" 21#define VXGE_VERSION_FOR "k"
22
23#define VXGE_FW_VER(maj, min, bld) (((maj) << 16) + ((min) << 8) + (bld))
24
25#define VXGE_DEAD_FW_VER_MAJOR 1
26#define VXGE_DEAD_FW_VER_MINOR 4
27#define VXGE_DEAD_FW_VER_BUILD 4
28
29#define VXGE_FW_DEAD_VER VXGE_FW_VER(VXGE_DEAD_FW_VER_MAJOR, \
30 VXGE_DEAD_FW_VER_MINOR, \
31 VXGE_DEAD_FW_VER_BUILD)
32
33#define VXGE_EPROM_FW_VER_MAJOR 1
34#define VXGE_EPROM_FW_VER_MINOR 6
35#define VXGE_EPROM_FW_VER_BUILD 1
36
37#define VXGE_EPROM_FW_VER VXGE_FW_VER(VXGE_EPROM_FW_VER_MAJOR, \
38 VXGE_EPROM_FW_VER_MINOR, \
39 VXGE_EPROM_FW_VER_BUILD)
40
41#define VXGE_CERT_FW_VER_MAJOR 1
42#define VXGE_CERT_FW_VER_MINOR 8
43#define VXGE_CERT_FW_VER_BUILD 1
44
45#define VXGE_CERT_FW_VER VXGE_FW_VER(VXGE_CERT_FW_VER_MAJOR, \
46 VXGE_CERT_FW_VER_MINOR, \
47 VXGE_CERT_FW_VER_BUILD)
48
22#endif 49#endif