aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/emulex
diff options
context:
space:
mode:
authorVasundhara Volam <vasundhara.volam@emulex.com>2015-02-06 08:18:39 -0500
committerDavid S. Miller <davem@davemloft.net>2015-02-08 01:50:58 -0500
commit70a7b5257018c518007c7212977bab6ccacd9468 (patch)
treedd2d2df029bbba6d5bfe7abb533cca3f2be074aa /drivers/net/ethernet/emulex
parent81a9e226ff2c5cf963a79c1cbecd6e68c0e35a21 (diff)
be2net: use offset based FW flashing for Skyhawk chip
While sending FW update cmds to the FW, the driver specifies the "type" of each component that needs to be flashed. The FW then picks the offset in the flash area at which the componnet is to be flashed. This doesn't work when new components that the current FW doesn't recognize, need to be flashed. Recent FWs (10.2 and above) support a scheme of FW-update wherein the "offset" of the component in the flash area can be specified instead of the "type". This patch uses the "offset" based FW-update mechanism and only when it fails, it fallsback to the old "type" based update. Signed-off-by: Vasundhara Volam <vasundhara.volam@emulex.com> Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/emulex')
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c18
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h6
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c65
3 files changed, 66 insertions, 23 deletions
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index 6830bffa4eee..03119ac548f6 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2436,7 +2436,8 @@ err_unlock:
2436} 2436}
2437 2437
2438int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, 2438int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
2439 u32 flash_type, u32 flash_opcode, u32 buf_size) 2439 u32 flash_type, u32 flash_opcode, u32 img_offset,
2440 u32 buf_size)
2440{ 2441{
2441 struct be_mcc_wrb *wrb; 2442 struct be_mcc_wrb *wrb;
2442 struct be_cmd_write_flashrom *req; 2443 struct be_cmd_write_flashrom *req;
@@ -2457,6 +2458,9 @@ int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
2457 cmd); 2458 cmd);
2458 2459
2459 req->params.op_type = cpu_to_le32(flash_type); 2460 req->params.op_type = cpu_to_le32(flash_type);
2461 if (flash_type == OPTYPE_OFFSET_SPECIFIED)
2462 req->params.offset = cpu_to_le32(img_offset);
2463
2460 req->params.op_code = cpu_to_le32(flash_opcode); 2464 req->params.op_code = cpu_to_le32(flash_opcode);
2461 req->params.data_buf_size = cpu_to_le32(buf_size); 2465 req->params.data_buf_size = cpu_to_le32(buf_size);
2462 2466
@@ -2477,10 +2481,10 @@ err_unlock:
2477} 2481}
2478 2482
2479int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, 2483int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
2480 u16 optype, int offset) 2484 u16 img_optype, u32 img_offset, u32 crc_offset)
2481{ 2485{
2482 struct be_mcc_wrb *wrb;
2483 struct be_cmd_read_flash_crc *req; 2486 struct be_cmd_read_flash_crc *req;
2487 struct be_mcc_wrb *wrb;
2484 int status; 2488 int status;
2485 2489
2486 spin_lock_bh(&adapter->mcc_lock); 2490 spin_lock_bh(&adapter->mcc_lock);
@@ -2496,9 +2500,13 @@ int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
2496 OPCODE_COMMON_READ_FLASHROM, sizeof(*req), 2500 OPCODE_COMMON_READ_FLASHROM, sizeof(*req),
2497 wrb, NULL); 2501 wrb, NULL);
2498 2502
2499 req->params.op_type = cpu_to_le32(optype); 2503 req->params.op_type = cpu_to_le32(img_optype);
2504 if (img_optype == OPTYPE_OFFSET_SPECIFIED)
2505 req->params.offset = cpu_to_le32(img_offset + crc_offset);
2506 else
2507 req->params.offset = cpu_to_le32(crc_offset);
2508
2500 req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT); 2509 req->params.op_code = cpu_to_le32(FLASHROM_OPER_REPORT);
2501 req->params.offset = cpu_to_le32(offset);
2502 req->params.data_buf_size = cpu_to_le32(0x4); 2510 req->params.data_buf_size = cpu_to_le32(0x4);
2503 2511
2504 status = be_mcc_notify_wait(adapter); 2512 status = be_mcc_notify_wait(adapter);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index 774c5d1719e1..402d64f5bb7c 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -1172,6 +1172,7 @@ struct be_cmd_resp_get_beacon_state {
1172#define OPTYPE_REDBOOT 1 1172#define OPTYPE_REDBOOT 1
1173#define OPTYPE_BIOS 2 1173#define OPTYPE_BIOS 2
1174#define OPTYPE_PXE_BIOS 3 1174#define OPTYPE_PXE_BIOS 3
1175#define OPTYPE_OFFSET_SPECIFIED 7
1175#define OPTYPE_FCOE_BIOS 8 1176#define OPTYPE_FCOE_BIOS 8
1176#define OPTYPE_ISCSI_BACKUP 9 1177#define OPTYPE_ISCSI_BACKUP 9
1177#define OPTYPE_FCOE_FW_ACTIVE 10 1178#define OPTYPE_FCOE_FW_ACTIVE 10
@@ -2255,7 +2256,8 @@ int be_cmd_read_port_transceiver_data(struct be_adapter *adapter,
2255 u8 page_num, u8 *data); 2256 u8 page_num, u8 *data);
2256int be_cmd_query_cable_type(struct be_adapter *adapter); 2257int be_cmd_query_cable_type(struct be_adapter *adapter);
2257int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, 2258int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
2258 u32 flash_oper, u32 flash_opcode, u32 buf_size); 2259 u32 flash_oper, u32 flash_opcode, u32 img_offset,
2260 u32 buf_size);
2259int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd, 2261int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
2260 u32 data_size, u32 data_offset, 2262 u32 data_size, u32 data_offset,
2261 const char *obj_name, u32 *data_written, 2263 const char *obj_name, u32 *data_written,
@@ -2265,7 +2267,7 @@ int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
2265 u32 *data_read, u32 *eof, u8 *addn_status); 2267 u32 *data_read, u32 *eof, u8 *addn_status);
2266int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name); 2268int lancer_cmd_delete_object(struct be_adapter *adapter, const char *obj_name);
2267int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, 2269int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
2268 u16 optype, int offset); 2270 u16 img_optype, u32 img_offset, u32 crc_offset);
2269int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, 2271int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
2270 struct be_dma_mem *nonemb_cmd); 2272 struct be_dma_mem *nonemb_cmd);
2271int be_cmd_fw_init(struct be_adapter *adapter); 2273int be_cmd_fw_init(struct be_adapter *adapter);
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index 36f140a9c31e..01571da9cd12 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -3942,7 +3942,8 @@ static int be_check_flash_crc(struct be_adapter *adapter, const u8 *p,
3942 int status; 3942 int status;
3943 u8 crc[4]; 3943 u8 crc[4];
3944 3944
3945 status = be_cmd_get_flash_crc(adapter, crc, img_optype, img_size - 4); 3945 status = be_cmd_get_flash_crc(adapter, crc, img_optype, img_offset,
3946 img_size - 4);
3946 if (status) 3947 if (status)
3947 return status; 3948 return status;
3948 3949
@@ -3958,13 +3959,13 @@ static int be_check_flash_crc(struct be_adapter *adapter, const u8 *p,
3958} 3959}
3959 3960
3960static int be_flash(struct be_adapter *adapter, const u8 *img, 3961static int be_flash(struct be_adapter *adapter, const u8 *img,
3961 struct be_dma_mem *flash_cmd, int optype, int img_size) 3962 struct be_dma_mem *flash_cmd, int optype, int img_size,
3963 u32 img_offset)
3962{ 3964{
3965 u32 flash_op, num_bytes, total_bytes = img_size, bytes_sent = 0;
3963 struct be_cmd_write_flashrom *req = flash_cmd->va; 3966 struct be_cmd_write_flashrom *req = flash_cmd->va;
3964 u32 total_bytes, flash_op, num_bytes;
3965 int status; 3967 int status;
3966 3968
3967 total_bytes = img_size;
3968 while (total_bytes) { 3969 while (total_bytes) {
3969 num_bytes = min_t(u32, 32*1024, total_bytes); 3970 num_bytes = min_t(u32, 32*1024, total_bytes);
3970 3971
@@ -3985,12 +3986,15 @@ static int be_flash(struct be_adapter *adapter, const u8 *img,
3985 memcpy(req->data_buf, img, num_bytes); 3986 memcpy(req->data_buf, img, num_bytes);
3986 img += num_bytes; 3987 img += num_bytes;
3987 status = be_cmd_write_flashrom(adapter, flash_cmd, optype, 3988 status = be_cmd_write_flashrom(adapter, flash_cmd, optype,
3988 flash_op, num_bytes); 3989 flash_op, img_offset +
3990 bytes_sent, num_bytes);
3989 if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST && 3991 if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST &&
3990 optype == OPTYPE_PHY_FW) 3992 optype == OPTYPE_PHY_FW)
3991 break; 3993 break;
3992 else if (status) 3994 else if (status)
3993 return status; 3995 return status;
3996
3997 bytes_sent += num_bytes;
3994 } 3998 }
3995 return 0; 3999 return 0;
3996} 4000}
@@ -4103,7 +4107,7 @@ static int be_flash_BEx(struct be_adapter *adapter,
4103 return -1; 4107 return -1;
4104 4108
4105 status = be_flash(adapter, p, flash_cmd, pflashcomp[i].optype, 4109 status = be_flash(adapter, p, flash_cmd, pflashcomp[i].optype,
4106 pflashcomp[i].size); 4110 pflashcomp[i].size, 0);
4107 if (status) { 4111 if (status) {
4108 dev_err(dev, "Flashing section type 0x%x failed\n", 4112 dev_err(dev, "Flashing section type 0x%x failed\n",
4109 pflashcomp[i].img_type); 4113 pflashcomp[i].img_type);
@@ -4170,12 +4174,12 @@ static int be_flash_skyhawk(struct be_adapter *adapter,
4170 struct be_dma_mem *flash_cmd, int num_of_images) 4174 struct be_dma_mem *flash_cmd, int num_of_images)
4171{ 4175{
4172 int img_hdrs_size = num_of_images * sizeof(struct image_hdr); 4176 int img_hdrs_size = num_of_images * sizeof(struct image_hdr);
4177 bool crc_match, old_fw_img, flash_offset_support = true;
4173 struct device *dev = &adapter->pdev->dev; 4178 struct device *dev = &adapter->pdev->dev;
4174 struct flash_section_info *fsec = NULL; 4179 struct flash_section_info *fsec = NULL;
4175 u32 img_offset, img_size, img_type; 4180 u32 img_offset, img_size, img_type;
4181 u16 img_optype, flash_optype;
4176 int status, i, filehdr_size; 4182 int status, i, filehdr_size;
4177 bool crc_match, old_fw_img;
4178 u16 img_optype;
4179 const u8 *p; 4183 const u8 *p;
4180 4184
4181 filehdr_size = sizeof(struct flash_file_hdr_g3); 4185 filehdr_size = sizeof(struct flash_file_hdr_g3);
@@ -4185,6 +4189,7 @@ static int be_flash_skyhawk(struct be_adapter *adapter,
4185 return -EINVAL; 4189 return -EINVAL;
4186 } 4190 }
4187 4191
4192retry_flash:
4188 for (i = 0; i < le32_to_cpu(fsec->fsec_hdr.num_images); i++) { 4193 for (i = 0; i < le32_to_cpu(fsec->fsec_hdr.num_images); i++) {
4189 img_offset = le32_to_cpu(fsec->fsec_entry[i].offset); 4194 img_offset = le32_to_cpu(fsec->fsec_entry[i].offset);
4190 img_size = le32_to_cpu(fsec->fsec_entry[i].pad_size); 4195 img_size = le32_to_cpu(fsec->fsec_entry[i].pad_size);
@@ -4194,6 +4199,12 @@ static int be_flash_skyhawk(struct be_adapter *adapter,
4194 4199
4195 if (img_optype == 0xFFFF) 4200 if (img_optype == 0xFFFF)
4196 continue; 4201 continue;
4202
4203 if (flash_offset_support)
4204 flash_optype = OPTYPE_OFFSET_SPECIFIED;
4205 else
4206 flash_optype = img_optype;
4207
4197 /* Don't bother verifying CRC if an old FW image is being 4208 /* Don't bother verifying CRC if an old FW image is being
4198 * flashed 4209 * flashed
4199 */ 4210 */
@@ -4202,16 +4213,26 @@ static int be_flash_skyhawk(struct be_adapter *adapter,
4202 4213
4203 status = be_check_flash_crc(adapter, fw->data, img_offset, 4214 status = be_check_flash_crc(adapter, fw->data, img_offset,
4204 img_size, filehdr_size + 4215 img_size, filehdr_size +
4205 img_hdrs_size, img_optype, 4216 img_hdrs_size, flash_optype,
4206 &crc_match); 4217 &crc_match);
4207 /* The current FW image on the card does not recognize the new
4208 * FLASH op_type. The FW download is partially complete.
4209 * Reboot the server now to enable FW image to recognize the
4210 * new FLASH op_type. To complete the remaining process,
4211 * download the same FW again after the reboot.
4212 */
4213 if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST || 4218 if (base_status(status) == MCC_STATUS_ILLEGAL_REQUEST ||
4214 base_status(status) == MCC_STATUS_ILLEGAL_FIELD) { 4219 base_status(status) == MCC_STATUS_ILLEGAL_FIELD) {
4220 /* The current FW image on the card does not support
4221 * OFFSET based flashing. Retry using older mechanism
4222 * of OPTYPE based flashing
4223 */
4224 if (flash_optype == OPTYPE_OFFSET_SPECIFIED) {
4225 flash_offset_support = false;
4226 goto retry_flash;
4227 }
4228
4229 /* The current FW image on the card does not recognize
4230 * the new FLASH op_type. The FW download is partially
4231 * complete. Reboot the server now to enable FW image
4232 * to recognize the new FLASH op_type. To complete the
4233 * remaining process, download the same FW again after
4234 * the reboot.
4235 */
4215 dev_err(dev, "Flash incomplete. Reset the server\n"); 4236 dev_err(dev, "Flash incomplete. Reset the server\n");
4216 dev_err(dev, "Download FW image again after reset\n"); 4237 dev_err(dev, "Download FW image again after reset\n");
4217 return -EAGAIN; 4238 return -EAGAIN;
@@ -4229,7 +4250,19 @@ flash:
4229 if (p + img_size > fw->data + fw->size) 4250 if (p + img_size > fw->data + fw->size)
4230 return -1; 4251 return -1;
4231 4252
4232 status = be_flash(adapter, p, flash_cmd, img_optype, img_size); 4253 status = be_flash(adapter, p, flash_cmd, flash_optype, img_size,
4254 img_offset);
4255
4256 /* The current FW image on the card does not support OFFSET
4257 * based flashing. Retry using older mechanism of OPTYPE based
4258 * flashing
4259 */
4260 if (base_status(status) == MCC_STATUS_ILLEGAL_FIELD &&
4261 flash_optype == OPTYPE_OFFSET_SPECIFIED) {
4262 flash_offset_support = false;
4263 goto retry_flash;
4264 }
4265
4233 /* For old FW images ignore ILLEGAL_FIELD error or errors on 4266 /* For old FW images ignore ILLEGAL_FIELD error or errors on
4234 * UFI_DIR region 4267 * UFI_DIR region
4235 */ 4268 */