aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/benet
diff options
context:
space:
mode:
authorShripad Nunjundarao <shripad.nunjundarao@emulex.com>2011-05-16 03:36:59 -0400
committerDavid S. Miller <davem@davemloft.net>2011-05-16 14:13:53 -0400
commit485bf569ba798b4702bc2efbfd3a355fe2c8db04 (patch)
treee0de5f64bfcf568d5a3a186df5106c2829415e3b /drivers/net/benet
parent005d569600b404cae0b356e3c4085290ecc17775 (diff)
be2net: FW download for Lancer
Added implementation of FW download feature for Lancer. Signed-off-by: Shripad Nunjundarao <shripad.nunjundarao@emulex.com> Signed-off-by: Sevin Xavier <selvin.xavier@emulex.com> Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet')
-rw-r--r--drivers/net/benet/be_cmds.c78
-rw-r--r--drivers/net/benet/be_cmds.h36
-rw-r--r--drivers/net/benet/be_main.c129
3 files changed, 223 insertions, 20 deletions
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index aaef0c731b9a..2463b1c97922 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -71,7 +71,8 @@ static int be_mcc_compl_process(struct be_adapter *adapter,
71 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) & 71 compl_status = (compl->status >> CQE_STATUS_COMPL_SHIFT) &
72 CQE_STATUS_COMPL_MASK; 72 CQE_STATUS_COMPL_MASK;
73 73
74 if ((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) && 74 if (((compl->tag0 == OPCODE_COMMON_WRITE_FLASHROM) ||
75 (compl->tag0 == OPCODE_COMMON_WRITE_OBJECT)) &&
75 (compl->tag1 == CMD_SUBSYSTEM_COMMON)) { 76 (compl->tag1 == CMD_SUBSYSTEM_COMMON)) {
76 adapter->flash_status = compl_status; 77 adapter->flash_status = compl_status;
77 complete(&adapter->flash_compl); 78 complete(&adapter->flash_compl);
@@ -1801,6 +1802,81 @@ err:
1801 return status; 1802 return status;
1802} 1803}
1803 1804
1805int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
1806 u32 data_size, u32 data_offset, const char *obj_name,
1807 u32 *data_written, u8 *addn_status)
1808{
1809 struct be_mcc_wrb *wrb;
1810 struct lancer_cmd_req_write_object *req;
1811 struct lancer_cmd_resp_write_object *resp;
1812 void *ctxt = NULL;
1813 int status;
1814
1815 spin_lock_bh(&adapter->mcc_lock);
1816 adapter->flash_status = 0;
1817
1818 wrb = wrb_from_mccq(adapter);
1819 if (!wrb) {
1820 status = -EBUSY;
1821 goto err_unlock;
1822 }
1823
1824 req = embedded_payload(wrb);
1825
1826 be_wrb_hdr_prepare(wrb, sizeof(struct lancer_cmd_req_write_object),
1827 true, 1, OPCODE_COMMON_WRITE_OBJECT);
1828 wrb->tag1 = CMD_SUBSYSTEM_COMMON;
1829
1830 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1831 OPCODE_COMMON_WRITE_OBJECT,
1832 sizeof(struct lancer_cmd_req_write_object));
1833
1834 ctxt = &req->context;
1835 AMAP_SET_BITS(struct amap_lancer_write_obj_context,
1836 write_length, ctxt, data_size);
1837
1838 if (data_size == 0)
1839 AMAP_SET_BITS(struct amap_lancer_write_obj_context,
1840 eof, ctxt, 1);
1841 else
1842 AMAP_SET_BITS(struct amap_lancer_write_obj_context,
1843 eof, ctxt, 0);
1844
1845 be_dws_cpu_to_le(ctxt, sizeof(req->context));
1846 req->write_offset = cpu_to_le32(data_offset);
1847 strcpy(req->object_name, obj_name);
1848 req->descriptor_count = cpu_to_le32(1);
1849 req->buf_len = cpu_to_le32(data_size);
1850 req->addr_low = cpu_to_le32((cmd->dma +
1851 sizeof(struct lancer_cmd_req_write_object))
1852 & 0xFFFFFFFF);
1853 req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma +
1854 sizeof(struct lancer_cmd_req_write_object)));
1855
1856 be_mcc_notify(adapter);
1857 spin_unlock_bh(&adapter->mcc_lock);
1858
1859 if (!wait_for_completion_timeout(&adapter->flash_compl,
1860 msecs_to_jiffies(12000)))
1861 status = -1;
1862 else
1863 status = adapter->flash_status;
1864
1865 resp = embedded_payload(wrb);
1866 if (!status) {
1867 *data_written = le32_to_cpu(resp->actual_write_len);
1868 } else {
1869 *addn_status = resp->additional_status;
1870 status = resp->status;
1871 }
1872
1873 return status;
1874
1875err_unlock:
1876 spin_unlock_bh(&adapter->mcc_lock);
1877 return status;
1878}
1879
1804int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd, 1880int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
1805 u32 flash_type, u32 flash_opcode, u32 buf_size) 1881 u32 flash_type, u32 flash_opcode, u32 buf_size)
1806{ 1882{
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 9cff226c94f1..8148cc66cbe9 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -193,6 +193,7 @@ struct be_mcc_mailbox {
193#define OPCODE_COMMON_GET_PHY_DETAILS 102 193#define OPCODE_COMMON_GET_PHY_DETAILS 102
194#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 194#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103
195#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 195#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
196#define OPCODE_COMMON_WRITE_OBJECT 172
196 197
197#define OPCODE_ETH_RSS_CONFIG 1 198#define OPCODE_ETH_RSS_CONFIG 1
198#define OPCODE_ETH_ACPI_CONFIG 2 199#define OPCODE_ETH_ACPI_CONFIG 2
@@ -1131,6 +1132,36 @@ struct be_cmd_write_flashrom {
1131 struct flashrom_params params; 1132 struct flashrom_params params;
1132}; 1133};
1133 1134
1135/**************** Lancer Firmware Flash ************/
1136struct amap_lancer_write_obj_context {
1137 u8 write_length[24];
1138 u8 reserved1[7];
1139 u8 eof;
1140} __packed;
1141
1142struct lancer_cmd_req_write_object {
1143 struct be_cmd_req_hdr hdr;
1144 u8 context[sizeof(struct amap_lancer_write_obj_context) / 8];
1145 u32 write_offset;
1146 u8 object_name[104];
1147 u32 descriptor_count;
1148 u32 buf_len;
1149 u32 addr_low;
1150 u32 addr_high;
1151};
1152
1153struct lancer_cmd_resp_write_object {
1154 u8 opcode;
1155 u8 subsystem;
1156 u8 rsvd1[2];
1157 u8 status;
1158 u8 additional_status;
1159 u8 rsvd2[2];
1160 u32 resp_len;
1161 u32 actual_resp_len;
1162 u32 actual_write_len;
1163};
1164
1134/************************ WOL *******************************/ 1165/************************ WOL *******************************/
1135struct be_cmd_req_acpi_wol_magic_config{ 1166struct be_cmd_req_acpi_wol_magic_config{
1136 struct be_cmd_req_hdr hdr; 1167 struct be_cmd_req_hdr hdr;
@@ -1481,6 +1512,11 @@ extern int be_cmd_get_beacon_state(struct be_adapter *adapter,
1481extern int be_cmd_write_flashrom(struct be_adapter *adapter, 1512extern int be_cmd_write_flashrom(struct be_adapter *adapter,
1482 struct be_dma_mem *cmd, u32 flash_oper, 1513 struct be_dma_mem *cmd, u32 flash_oper,
1483 u32 flash_opcode, u32 buf_size); 1514 u32 flash_opcode, u32 buf_size);
1515extern int lancer_cmd_write_object(struct be_adapter *adapter,
1516 struct be_dma_mem *cmd,
1517 u32 data_size, u32 data_offset,
1518 const char *obj_name,
1519 u32 *data_written, u8 *addn_status);
1484int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc, 1520int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
1485 int offset); 1521 int offset);
1486extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac, 1522extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 93be84ce9bad..7322a511e936 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -2712,7 +2712,6 @@ static int be_flash_data(struct be_adapter *adapter,
2712 "cmd to write to flash rom failed.\n"); 2712 "cmd to write to flash rom failed.\n");
2713 return -1; 2713 return -1;
2714 } 2714 }
2715 yield();
2716 } 2715 }
2717 } 2716 }
2718 return 0; 2717 return 0;
@@ -2730,32 +2729,98 @@ static int get_ufigen_type(struct flash_file_hdr_g2 *fhdr)
2730 return 0; 2729 return 0;
2731} 2730}
2732 2731
2733int be_load_fw(struct be_adapter *adapter, u8 *func) 2732static int lancer_fw_download(struct be_adapter *adapter,
2733 const struct firmware *fw)
2734{ 2734{
2735 char fw_file[ETHTOOL_FLASH_MAX_FILENAME]; 2735#define LANCER_FW_DOWNLOAD_CHUNK (32 * 1024)
2736 const struct firmware *fw; 2736#define LANCER_FW_DOWNLOAD_LOCATION "/prg"
2737 struct flash_file_hdr_g2 *fhdr;
2738 struct flash_file_hdr_g3 *fhdr3;
2739 struct image_hdr *img_hdr_ptr = NULL;
2740 struct be_dma_mem flash_cmd; 2737 struct be_dma_mem flash_cmd;
2741 int status, i = 0, num_imgs = 0; 2738 struct lancer_cmd_req_write_object *req;
2742 const u8 *p; 2739 const u8 *data_ptr = NULL;
2740 u8 *dest_image_ptr = NULL;
2741 size_t image_size = 0;
2742 u32 chunk_size = 0;
2743 u32 data_written = 0;
2744 u32 offset = 0;
2745 int status = 0;
2746 u8 add_status = 0;
2743 2747
2744 if (!netif_running(adapter->netdev)) { 2748 if (!IS_ALIGNED(fw->size, sizeof(u32))) {
2745 dev_err(&adapter->pdev->dev, 2749 dev_err(&adapter->pdev->dev,
2746 "Firmware load not allowed (interface is down)\n"); 2750 "FW Image not properly aligned. "
2747 return -EPERM; 2751 "Length must be 4 byte aligned.\n");
2752 status = -EINVAL;
2753 goto lancer_fw_exit;
2748 } 2754 }
2749 2755
2750 strcpy(fw_file, func); 2756 flash_cmd.size = sizeof(struct lancer_cmd_req_write_object)
2757 + LANCER_FW_DOWNLOAD_CHUNK;
2758 flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
2759 &flash_cmd.dma, GFP_KERNEL);
2760 if (!flash_cmd.va) {
2761 status = -ENOMEM;
2762 dev_err(&adapter->pdev->dev,
2763 "Memory allocation failure while flashing\n");
2764 goto lancer_fw_exit;
2765 }
2751 2766
2752 status = request_firmware(&fw, fw_file, &adapter->pdev->dev); 2767 req = flash_cmd.va;
2753 if (status) 2768 dest_image_ptr = flash_cmd.va +
2754 goto fw_exit; 2769 sizeof(struct lancer_cmd_req_write_object);
2770 image_size = fw->size;
2771 data_ptr = fw->data;
2772
2773 while (image_size) {
2774 chunk_size = min_t(u32, image_size, LANCER_FW_DOWNLOAD_CHUNK);
2775
2776 /* Copy the image chunk content. */
2777 memcpy(dest_image_ptr, data_ptr, chunk_size);
2778
2779 status = lancer_cmd_write_object(adapter, &flash_cmd,
2780 chunk_size, offset, LANCER_FW_DOWNLOAD_LOCATION,
2781 &data_written, &add_status);
2782
2783 if (status)
2784 break;
2785
2786 offset += data_written;
2787 data_ptr += data_written;
2788 image_size -= data_written;
2789 }
2790
2791 if (!status) {
2792 /* Commit the FW written */
2793 status = lancer_cmd_write_object(adapter, &flash_cmd,
2794 0, offset, LANCER_FW_DOWNLOAD_LOCATION,
2795 &data_written, &add_status);
2796 }
2797
2798 dma_free_coherent(&adapter->pdev->dev, flash_cmd.size, flash_cmd.va,
2799 flash_cmd.dma);
2800 if (status) {
2801 dev_err(&adapter->pdev->dev,
2802 "Firmware load error. "
2803 "Status code: 0x%x Additional Status: 0x%x\n",
2804 status, add_status);
2805 goto lancer_fw_exit;
2806 }
2807
2808 dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
2809lancer_fw_exit:
2810 return status;
2811}
2812
2813static int be_fw_download(struct be_adapter *adapter, const struct firmware* fw)
2814{
2815 struct flash_file_hdr_g2 *fhdr;
2816 struct flash_file_hdr_g3 *fhdr3;
2817 struct image_hdr *img_hdr_ptr = NULL;
2818 struct be_dma_mem flash_cmd;
2819 const u8 *p;
2820 int status = 0, i = 0, num_imgs = 0;
2755 2821
2756 p = fw->data; 2822 p = fw->data;
2757 fhdr = (struct flash_file_hdr_g2 *) p; 2823 fhdr = (struct flash_file_hdr_g2 *) p;
2758 dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
2759 2824
2760 flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024; 2825 flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
2761 flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size, 2826 flash_cmd.va = dma_alloc_coherent(&adapter->pdev->dev, flash_cmd.size,
@@ -2764,7 +2829,7 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
2764 status = -ENOMEM; 2829 status = -ENOMEM;
2765 dev_err(&adapter->pdev->dev, 2830 dev_err(&adapter->pdev->dev,
2766 "Memory allocation failure while flashing\n"); 2831 "Memory allocation failure while flashing\n");
2767 goto fw_exit; 2832 goto be_fw_exit;
2768 } 2833 }
2769 2834
2770 if ((adapter->generation == BE_GEN3) && 2835 if ((adapter->generation == BE_GEN3) &&
@@ -2792,11 +2857,37 @@ int be_load_fw(struct be_adapter *adapter, u8 *func)
2792 flash_cmd.dma); 2857 flash_cmd.dma);
2793 if (status) { 2858 if (status) {
2794 dev_err(&adapter->pdev->dev, "Firmware load error\n"); 2859 dev_err(&adapter->pdev->dev, "Firmware load error\n");
2795 goto fw_exit; 2860 goto be_fw_exit;
2796 } 2861 }
2797 2862
2798 dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n"); 2863 dev_info(&adapter->pdev->dev, "Firmware flashed successfully\n");
2799 2864
2865be_fw_exit:
2866 return status;
2867}
2868
2869int be_load_fw(struct be_adapter *adapter, u8 *fw_file)
2870{
2871 const struct firmware *fw;
2872 int status;
2873
2874 if (!netif_running(adapter->netdev)) {
2875 dev_err(&adapter->pdev->dev,
2876 "Firmware load not allowed (interface is down)\n");
2877 return -1;
2878 }
2879
2880 status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
2881 if (status)
2882 goto fw_exit;
2883
2884 dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
2885
2886 if (lancer_chip(adapter))
2887 status = lancer_fw_download(adapter, fw);
2888 else
2889 status = be_fw_download(adapter, fw);
2890
2800fw_exit: 2891fw_exit:
2801 release_firmware(fw); 2892 release_firmware(fw);
2802 return status; 2893 return status;