aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/benet
diff options
context:
space:
mode:
authorAjit Khaparde <ajitk@serverengines.com>2009-09-03 23:12:16 -0400
committerDavid S. Miller <davem@davemloft.net>2009-09-07 04:56:38 -0400
commit84517482e19bc775de7b3b4e998dee2f506bc34e (patch)
treeae3491a5cf8891feef8c2896ef50758d763646f2 /drivers/net/benet
parent384824281caa9ac4b76664033416f1eac4a652fe (diff)
be2net: Changes to support flashing of the be2 network adapter
Changes to support flashing of the be2 network adapter using the request_firmware() & ethtool infrastructure. The trigger to flash the device will come from ethtool utility. The driver will invoke request_firmware() to start the flash process. The file containing the flash image is expected to be available in /lib/firmware/ Signed-off-by: Ajit Khaparde <ajitk@serverengines.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet')
-rw-r--r--drivers/net/benet/be.h4
-rw-r--r--drivers/net/benet/be_cmds.c30
-rw-r--r--drivers/net/benet/be_cmds.h20
-rw-r--r--drivers/net/benet/be_ethtool.c15
-rw-r--r--drivers/net/benet/be_hw.h85
-rw-r--r--drivers/net/benet/be_main.c167
6 files changed, 317 insertions, 4 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 6c45a2233d0d..13b72ce870de 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -28,10 +28,11 @@
28#include <linux/if_vlan.h> 28#include <linux/if_vlan.h>
29#include <linux/workqueue.h> 29#include <linux/workqueue.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/firmware.h>
31 32
32#include "be_hw.h" 33#include "be_hw.h"
33 34
34#define DRV_VER "2.0.400" 35#define DRV_VER "2.101.205"
35#define DRV_NAME "be2net" 36#define DRV_NAME "be2net"
36#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC" 37#define BE_NAME "ServerEngines BladeEngine2 10Gbps NIC"
37#define OC_NAME "Emulex OneConnect 10Gbps NIC" 38#define OC_NAME "Emulex OneConnect 10Gbps NIC"
@@ -361,4 +362,5 @@ static inline u8 is_udp_pkt(struct sk_buff *skb)
361extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm, 362extern void be_cq_notify(struct be_adapter *adapter, u16 qid, bool arm,
362 u16 num_popped); 363 u16 num_popped);
363extern void be_link_status_update(struct be_adapter *adapter, bool link_up); 364extern void be_link_status_update(struct be_adapter *adapter, bool link_up);
365extern int be_load_fw(struct be_adapter *adapter, u8 *func);
364#endif /* BE_H */ 366#endif /* BE_H */
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 2547ee296a7d..1db092498309 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -155,7 +155,7 @@ static int be_mbox_db_ready_wait(struct be_adapter *adapter, void __iomem *db)
155 if (ready) 155 if (ready)
156 break; 156 break;
157 157
158 if (cnt > 200000) { 158 if (cnt > 4000000) {
159 dev_err(&adapter->pdev->dev, "mbox poll timed out\n"); 159 dev_err(&adapter->pdev->dev, "mbox poll timed out\n");
160 return -1; 160 return -1;
161 } 161 }
@@ -1040,3 +1040,31 @@ int be_cmd_reset_function(struct be_adapter *adapter)
1040 spin_unlock(&adapter->mbox_lock); 1040 spin_unlock(&adapter->mbox_lock);
1041 return status; 1041 return status;
1042} 1042}
1043
1044int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
1045 u32 flash_type, u32 flash_opcode, u32 buf_size)
1046{
1047 struct be_mcc_wrb *wrb = wrb_from_mbox(&adapter->mbox_mem);
1048 struct be_cmd_write_flashrom *req = cmd->va;
1049 struct be_sge *sge = nonembedded_sgl(wrb);
1050 int status;
1051
1052 spin_lock(&adapter->mbox_lock);
1053 memset(wrb, 0, sizeof(*wrb));
1054 be_wrb_hdr_prepare(wrb, cmd->size, false, 1);
1055
1056 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1057 OPCODE_COMMON_WRITE_FLASHROM, cmd->size);
1058 sge->pa_hi = cpu_to_le32(upper_32_bits(cmd->dma));
1059 sge->pa_lo = cpu_to_le32(cmd->dma & 0xFFFFFFFF);
1060 sge->len = cpu_to_le32(cmd->size);
1061
1062 req->params.op_type = cpu_to_le32(flash_type);
1063 req->params.op_code = cpu_to_le32(flash_opcode);
1064 req->params.data_buf_size = cpu_to_le32(buf_size);
1065
1066 status = be_mbox_notify(adapter);
1067
1068 spin_unlock(&adapter->mbox_lock);
1069 return status;
1070}
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 70618064ae15..fd7028e5b78e 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -117,6 +117,7 @@ struct be_mcc_mailbox {
117#define OPCODE_COMMON_NTWK_MULTICAST_SET 3 117#define OPCODE_COMMON_NTWK_MULTICAST_SET 3
118#define OPCODE_COMMON_NTWK_VLAN_CONFIG 4 118#define OPCODE_COMMON_NTWK_VLAN_CONFIG 4
119#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY 5 119#define OPCODE_COMMON_NTWK_LINK_STATUS_QUERY 5
120#define OPCODE_COMMON_WRITE_FLASHROM 7
120#define OPCODE_COMMON_CQ_CREATE 12 121#define OPCODE_COMMON_CQ_CREATE 12
121#define OPCODE_COMMON_EQ_CREATE 13 122#define OPCODE_COMMON_EQ_CREATE 13
122#define OPCODE_COMMON_MCC_CREATE 21 123#define OPCODE_COMMON_MCC_CREATE 21
@@ -693,10 +694,24 @@ struct be_cmd_resp_query_fw_cfg {
693 u32 be_config_number; 694 u32 be_config_number;
694 u32 asic_revision; 695 u32 asic_revision;
695 u32 phys_port; 696 u32 phys_port;
696 u32 function_mode; 697 u32 function_cap;
697 u32 rsvd[26]; 698 u32 rsvd[26];
698}; 699};
699 700
701/****************** Firmware Flash ******************/
702struct flashrom_params {
703 u32 op_code;
704 u32 op_type;
705 u32 data_buf_size;
706 u32 offset;
707 u8 data_buf[4];
708};
709
710struct be_cmd_write_flashrom {
711 struct be_cmd_req_hdr hdr;
712 struct flashrom_params params;
713};
714
700extern int be_pci_fnum_get(struct be_adapter *adapter); 715extern int be_pci_fnum_get(struct be_adapter *adapter);
701extern int be_cmd_POST(struct be_adapter *adapter); 716extern int be_cmd_POST(struct be_adapter *adapter);
702extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, 717extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr,
@@ -747,3 +762,6 @@ extern int be_cmd_get_flow_control(struct be_adapter *adapter,
747extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num); 762extern int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num);
748extern int be_cmd_reset_function(struct be_adapter *adapter); 763extern int be_cmd_reset_function(struct be_adapter *adapter);
749extern void be_process_mcc(struct be_adapter *adapter); 764extern void be_process_mcc(struct be_adapter *adapter);
765extern int be_cmd_write_flashrom(struct be_adapter *adapter,
766 struct be_dma_mem *cmd, u32 flash_oper,
767 u32 flash_opcode, u32 buf_size);
diff --git a/drivers/net/benet/be_ethtool.c b/drivers/net/benet/be_ethtool.c
index 4ff3cc465406..11445df3dbc0 100644
--- a/drivers/net/benet/be_ethtool.c
+++ b/drivers/net/benet/be_ethtool.c
@@ -332,6 +332,20 @@ be_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *ecmd)
332 return status; 332 return status;
333} 333}
334 334
335static int
336be_do_flash(struct net_device *netdev, struct ethtool_flash *efl)
337{
338 struct be_adapter *adapter = netdev_priv(netdev);
339 char file_name[ETHTOOL_FLASH_MAX_FILENAME];
340 u32 region;
341
342 file_name[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0;
343 strcpy(file_name, efl->data);
344 region = efl->region;
345
346 return be_load_fw(adapter, file_name);
347}
348
335const struct ethtool_ops be_ethtool_ops = { 349const struct ethtool_ops be_ethtool_ops = {
336 .get_settings = be_get_settings, 350 .get_settings = be_get_settings,
337 .get_drvinfo = be_get_drvinfo, 351 .get_drvinfo = be_get_drvinfo,
@@ -352,4 +366,5 @@ const struct ethtool_ops be_ethtool_ops = {
352 .get_strings = be_get_stat_strings, 366 .get_strings = be_get_stat_strings,
353 .get_stats_count = be_get_stats_count, 367 .get_stats_count = be_get_stats_count,
354 .get_ethtool_stats = be_get_ethtool_stats, 368 .get_ethtool_stats = be_get_ethtool_stats,
369 .flash_device = be_do_flash,
355}; 370};
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h
index d28f0c679bc8..a3394b4aa14a 100644
--- a/drivers/net/benet/be_hw.h
+++ b/drivers/net/benet/be_hw.h
@@ -204,7 +204,7 @@ struct amap_eth_rx_compl {
204 u8 numfrags[3]; /* dword 1 */ 204 u8 numfrags[3]; /* dword 1 */
205 u8 rss_flush; /* dword 2 */ 205 u8 rss_flush; /* dword 2 */
206 u8 cast_enc[2]; /* dword 2 */ 206 u8 cast_enc[2]; /* dword 2 */
207 u8 qnq; /* dword 2 */ 207 u8 vtm; /* dword 2 */
208 u8 rss_bank; /* dword 2 */ 208 u8 rss_bank; /* dword 2 */
209 u8 rsvd1[23]; /* dword 2 */ 209 u8 rsvd1[23]; /* dword 2 */
210 u8 lro_pkt; /* dword 2 */ 210 u8 lro_pkt; /* dword 2 */
@@ -216,3 +216,86 @@ struct amap_eth_rx_compl {
216struct be_eth_rx_compl { 216struct be_eth_rx_compl {
217 u32 dw[4]; 217 u32 dw[4];
218}; 218};
219
220/* Flashrom related descriptors */
221#define IMAGE_TYPE_FIRMWARE 160
222#define IMAGE_TYPE_BOOTCODE 224
223#define IMAGE_TYPE_OPTIONROM 32
224
225#define NUM_FLASHDIR_ENTRIES 32
226
227#define FLASHROM_TYPE_ISCSI_ACTIVE 0
228#define FLASHROM_TYPE_BIOS 2
229#define FLASHROM_TYPE_PXE_BIOS 3
230#define FLASHROM_TYPE_FCOE_BIOS 8
231#define FLASHROM_TYPE_ISCSI_BACKUP 9
232#define FLASHROM_TYPE_FCOE_FW_ACTIVE 10
233#define FLASHROM_TYPE_FCOE_FW_BACKUP 11
234
235#define FLASHROM_OPER_FLASH 1
236#define FLASHROM_OPER_SAVE 2
237
238#define FLASH_IMAGE_MAX_SIZE (1310720) /* Max firmware image size */
239#define FLASH_BIOS_IMAGE_MAX_SIZE (262144) /* Max OPTION ROM image sz */
240
241/* Offsets for components on Flash. */
242#define FLASH_iSCSI_PRIMARY_IMAGE_START (1048576)
243#define FLASH_iSCSI_BACKUP_IMAGE_START (2359296)
244#define FLASH_FCoE_PRIMARY_IMAGE_START (3670016)
245#define FLASH_FCoE_BACKUP_IMAGE_START (4980736)
246#define FLASH_iSCSI_BIOS_START (7340032)
247#define FLASH_PXE_BIOS_START (7864320)
248#define FLASH_FCoE_BIOS_START (524288)
249
250struct controller_id {
251 u32 vendor;
252 u32 device;
253 u32 subvendor;
254 u32 subdevice;
255};
256
257struct flash_file_hdr {
258 u8 sign[32];
259 u32 cksum;
260 u32 antidote;
261 struct controller_id cont_id;
262 u32 file_len;
263 u32 chunk_num;
264 u32 total_chunks;
265 u32 num_imgs;
266 u8 build[24];
267};
268
269struct flash_section_hdr {
270 u32 format_rev;
271 u32 cksum;
272 u32 antidote;
273 u32 build_no;
274 u8 id_string[64];
275 u32 active_entry_mask;
276 u32 valid_entry_mask;
277 u32 org_content_mask;
278 u32 rsvd0;
279 u32 rsvd1;
280 u32 rsvd2;
281 u32 rsvd3;
282 u32 rsvd4;
283};
284
285struct flash_section_entry {
286 u32 type;
287 u32 offset;
288 u32 pad_size;
289 u32 image_size;
290 u32 cksum;
291 u32 entry_point;
292 u32 rsvd0;
293 u32 rsvd1;
294 u8 ver_data[32];
295};
296
297struct flash_section_info {
298 u8 cookie[32];
299 struct flash_section_hdr fsec_hdr;
300 struct flash_section_entry fsec_entry[32];
301};
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index bac85f950394..d09106f2e084 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -1699,6 +1699,173 @@ static int be_close(struct net_device *netdev)
1699 return 0; 1699 return 0;
1700} 1700}
1701 1701
1702#define FW_FILE_HDR_SIGN "ServerEngines Corp. "
1703char flash_cookie[2][16] = {"*** SE FLAS",
1704 "H DIRECTORY *** "};
1705static int be_flash_image(struct be_adapter *adapter,
1706 const struct firmware *fw,
1707 struct be_dma_mem *flash_cmd, u32 flash_type)
1708{
1709 int status;
1710 u32 flash_op, image_offset = 0, total_bytes, image_size = 0;
1711 int num_bytes;
1712 const u8 *p = fw->data;
1713 struct be_cmd_write_flashrom *req = flash_cmd->va;
1714
1715 switch (flash_type) {
1716 case FLASHROM_TYPE_ISCSI_ACTIVE:
1717 image_offset = FLASH_iSCSI_PRIMARY_IMAGE_START;
1718 image_size = FLASH_IMAGE_MAX_SIZE;
1719 break;
1720 case FLASHROM_TYPE_ISCSI_BACKUP:
1721 image_offset = FLASH_iSCSI_BACKUP_IMAGE_START;
1722 image_size = FLASH_IMAGE_MAX_SIZE;
1723 break;
1724 case FLASHROM_TYPE_FCOE_FW_ACTIVE:
1725 image_offset = FLASH_FCoE_PRIMARY_IMAGE_START;
1726 image_size = FLASH_IMAGE_MAX_SIZE;
1727 break;
1728 case FLASHROM_TYPE_FCOE_FW_BACKUP:
1729 image_offset = FLASH_FCoE_BACKUP_IMAGE_START;
1730 image_size = FLASH_IMAGE_MAX_SIZE;
1731 break;
1732 case FLASHROM_TYPE_BIOS:
1733 image_offset = FLASH_iSCSI_BIOS_START;
1734 image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
1735 break;
1736 case FLASHROM_TYPE_FCOE_BIOS:
1737 image_offset = FLASH_FCoE_BIOS_START;
1738 image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
1739 break;
1740 case FLASHROM_TYPE_PXE_BIOS:
1741 image_offset = FLASH_PXE_BIOS_START;
1742 image_size = FLASH_BIOS_IMAGE_MAX_SIZE;
1743 break;
1744 default:
1745 return 0;
1746 }
1747
1748 p += sizeof(struct flash_file_hdr) + image_offset;
1749 if (p + image_size > fw->data + fw->size)
1750 return -1;
1751
1752 total_bytes = image_size;
1753
1754 while (total_bytes) {
1755 if (total_bytes > 32*1024)
1756 num_bytes = 32*1024;
1757 else
1758 num_bytes = total_bytes;
1759 total_bytes -= num_bytes;
1760
1761 if (!total_bytes)
1762 flash_op = FLASHROM_OPER_FLASH;
1763 else
1764 flash_op = FLASHROM_OPER_SAVE;
1765 memcpy(req->params.data_buf, p, num_bytes);
1766 p += num_bytes;
1767 status = be_cmd_write_flashrom(adapter, flash_cmd,
1768 flash_type, flash_op, num_bytes);
1769 if (status) {
1770 dev_err(&adapter->pdev->dev,
1771 "cmd to write to flash rom failed. type/op %d/%d\n",
1772 flash_type, flash_op);
1773 return -1;
1774 }
1775 yield();
1776 }
1777
1778 return 0;
1779}
1780
1781int be_load_fw(struct be_adapter *adapter, u8 *func)
1782{
1783 char fw_file[ETHTOOL_FLASH_MAX_FILENAME];
1784 const struct firmware *fw;
1785 struct flash_file_hdr *fhdr;
1786 struct flash_section_info *fsec = NULL;
1787 struct be_dma_mem flash_cmd;
1788 int status;
1789 const u8 *p;
1790 bool entry_found = false;
1791 int flash_type;
1792 char fw_ver[FW_VER_LEN];
1793 char fw_cfg;
1794
1795 status = be_cmd_get_fw_ver(adapter, fw_ver);
1796 if (status)
1797 return status;
1798
1799 fw_cfg = *(fw_ver + 2);
1800 if (fw_cfg == '0')
1801 fw_cfg = '1';
1802 strcpy(fw_file, func);
1803
1804 status = request_firmware(&fw, fw_file, &adapter->pdev->dev);
1805 if (status)
1806 goto fw_exit;
1807
1808 p = fw->data;
1809 fhdr = (struct flash_file_hdr *) p;
1810 if (memcmp(fhdr->sign, FW_FILE_HDR_SIGN, strlen(FW_FILE_HDR_SIGN))) {
1811 dev_err(&adapter->pdev->dev,
1812 "Firmware(%s) load error (signature did not match)\n",
1813 fw_file);
1814 status = -1;
1815 goto fw_exit;
1816 }
1817
1818 dev_info(&adapter->pdev->dev, "Flashing firmware file %s\n", fw_file);
1819
1820 p += sizeof(struct flash_file_hdr);
1821 while (p < (fw->data + fw->size)) {
1822 fsec = (struct flash_section_info *)p;
1823 if (!memcmp(flash_cookie, fsec->cookie, sizeof(flash_cookie))) {
1824 entry_found = true;
1825 break;
1826 }
1827 p += 32;
1828 }
1829
1830 if (!entry_found) {
1831 status = -1;
1832 dev_err(&adapter->pdev->dev,
1833 "Flash cookie not found in firmware image\n");
1834 goto fw_exit;
1835 }
1836
1837 flash_cmd.size = sizeof(struct be_cmd_write_flashrom) + 32*1024;
1838 flash_cmd.va = pci_alloc_consistent(adapter->pdev, flash_cmd.size,
1839 &flash_cmd.dma);
1840 if (!flash_cmd.va) {
1841 status = -ENOMEM;
1842 dev_err(&adapter->pdev->dev,
1843 "Memory allocation failure while flashing\n");
1844 goto fw_exit;
1845 }
1846
1847 for (flash_type = FLASHROM_TYPE_ISCSI_ACTIVE;
1848 flash_type <= FLASHROM_TYPE_FCOE_FW_BACKUP; flash_type++) {
1849 status = be_flash_image(adapter, fw, &flash_cmd,
1850 flash_type);
1851 if (status)
1852 break;
1853 }
1854
1855 pci_free_consistent(adapter->pdev, flash_cmd.size, flash_cmd.va,
1856 flash_cmd.dma);
1857 if (status) {
1858 dev_err(&adapter->pdev->dev, "Firmware load error\n");
1859 goto fw_exit;
1860 }
1861
1862 dev_info(&adapter->pdev->dev, "Firmware flashed succesfully\n");
1863
1864fw_exit:
1865 release_firmware(fw);
1866 return status;
1867}
1868
1702static struct net_device_ops be_netdev_ops = { 1869static struct net_device_ops be_netdev_ops = {
1703 .ndo_open = be_open, 1870 .ndo_open = be_open,
1704 .ndo_stop = be_close, 1871 .ndo_stop = be_close,