Commit 306f1348 authored by Sathya Perla's avatar Sathya Perla Committed by David S. Miller

be2net: add support for flashing Teranetics PHY firmware

Support for flashing RJ45 PHY (from Teranetics) on a 10GBaseT BE3 card.
Signed-off-by: default avatarNaresh G <bgottumukkala@emulex.com>
Signed-off-by: default avatarSathya Perla <sathya.perla@emulex.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5b8821b7
...@@ -2186,11 +2186,13 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter, ...@@ -2186,11 +2186,13 @@ int be_cmd_get_seeprom_data(struct be_adapter *adapter,
return status; return status;
} }
int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd) int be_cmd_get_phy_info(struct be_adapter *adapter,
struct be_phy_info *phy_info)
{ {
struct be_mcc_wrb *wrb; struct be_mcc_wrb *wrb;
struct be_cmd_req_get_phy_info *req; struct be_cmd_req_get_phy_info *req;
struct be_sge *sge; struct be_sge *sge;
struct be_dma_mem cmd;
int status; int status;
spin_lock_bh(&adapter->mcc_lock); spin_lock_bh(&adapter->mcc_lock);
...@@ -2200,8 +2202,16 @@ int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd) ...@@ -2200,8 +2202,16 @@ int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd)
status = -EBUSY; status = -EBUSY;
goto err; goto err;
} }
cmd.size = sizeof(struct be_cmd_req_get_phy_info);
cmd.va = pci_alloc_consistent(adapter->pdev, cmd.size,
&cmd.dma);
if (!cmd.va) {
dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
status = -ENOMEM;
goto err;
}
req = cmd->va; req = cmd.va;
sge = nonembedded_sgl(wrb); sge = nonembedded_sgl(wrb);
be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1, be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
...@@ -2211,11 +2221,20 @@ int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd) ...@@ -2211,11 +2221,20 @@ int be_cmd_get_phy_info(struct be_adapter *adapter, struct be_dma_mem *cmd)
OPCODE_COMMON_GET_PHY_DETAILS, OPCODE_COMMON_GET_PHY_DETAILS,
sizeof(*req)); sizeof(*req));
sge->pa_hi = cpu_to_le32(upper_32_bits(cmd->dma)); sge->pa_hi = cpu_to_le32(upper_32_bits(cmd.dma));
sge->pa_lo = cpu_to_le32(cmd->dma & 0xFFFFFFFF); sge->pa_lo = cpu_to_le32(cmd.dma & 0xFFFFFFFF);
sge->len = cpu_to_le32(cmd->size); sge->len = cpu_to_le32(cmd.size);
status = be_mcc_notify_wait(adapter); status = be_mcc_notify_wait(adapter);
if (!status) {
struct be_phy_info *resp_phy_info =
cmd.va + sizeof(struct be_cmd_req_hdr);
phy_info->phy_type = le16_to_cpu(resp_phy_info->phy_type);
phy_info->interface_type =
le16_to_cpu(resp_phy_info->interface_type);
}
pci_free_consistent(adapter->pdev, cmd.size,
cmd.va, cmd.dma);
err: err:
spin_unlock_bh(&adapter->mcc_lock); spin_unlock_bh(&adapter->mcc_lock);
return status; return status;
......
...@@ -1244,14 +1244,19 @@ struct be_cmd_req_get_phy_info { ...@@ -1244,14 +1244,19 @@ struct be_cmd_req_get_phy_info {
struct be_cmd_req_hdr hdr; struct be_cmd_req_hdr hdr;
u8 rsvd0[24]; u8 rsvd0[24];
}; };
struct be_cmd_resp_get_phy_info {
struct be_cmd_req_hdr hdr; struct be_phy_info {
u16 phy_type; u16 phy_type;
u16 interface_type; u16 interface_type;
u32 misc_params; u32 misc_params;
u32 future_use[4]; u32 future_use[4];
}; };
struct be_cmd_resp_get_phy_info {
struct be_cmd_req_hdr hdr;
struct be_phy_info phy_info;
};
/*********************** Set QOS ***********************/ /*********************** Set QOS ***********************/
#define BE_QOS_BITS_NIC 1 #define BE_QOS_BITS_NIC 1
...@@ -1486,7 +1491,7 @@ extern int be_cmd_get_seeprom_data(struct be_adapter *adapter, ...@@ -1486,7 +1491,7 @@ extern int be_cmd_get_seeprom_data(struct be_adapter *adapter,
extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num, extern int be_cmd_set_loopback(struct be_adapter *adapter, u8 port_num,
u8 loopback_type, u8 enable); u8 loopback_type, u8 enable);
extern int be_cmd_get_phy_info(struct be_adapter *adapter, extern int be_cmd_get_phy_info(struct be_adapter *adapter,
struct be_dma_mem *cmd); struct be_phy_info *phy_info);
extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain);
extern void be_detect_dump_ue(struct be_adapter *adapter); extern void be_detect_dump_ue(struct be_adapter *adapter);
extern int be_cmd_get_die_temperature(struct be_adapter *adapter); extern int be_cmd_get_die_temperature(struct be_adapter *adapter);
......
...@@ -349,12 +349,10 @@ static int be_get_sset_count(struct net_device *netdev, int stringset) ...@@ -349,12 +349,10 @@ static int be_get_sset_count(struct net_device *netdev, int stringset)
static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
{ {
struct be_adapter *adapter = netdev_priv(netdev); struct be_adapter *adapter = netdev_priv(netdev);
struct be_dma_mem phy_cmd; struct be_phy_info phy_info;
struct be_cmd_resp_get_phy_info *resp;
u8 mac_speed = 0; u8 mac_speed = 0;
u16 link_speed = 0; u16 link_speed = 0;
int status; int status;
u16 intf_type;
if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) { if ((adapter->link_speed < 0) || (!(netdev->flags & IFF_UP))) {
status = be_cmd_link_status_query(adapter, &mac_speed, status = be_cmd_link_status_query(adapter, &mac_speed,
...@@ -383,20 +381,9 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -383,20 +381,9 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
} }
} }
phy_cmd.size = sizeof(struct be_cmd_req_get_phy_info); status = be_cmd_get_phy_info(adapter, &phy_info);
phy_cmd.va = dma_alloc_coherent(&adapter->pdev->dev,
phy_cmd.size, &phy_cmd.dma,
GFP_KERNEL);
if (!phy_cmd.va) {
dev_err(&adapter->pdev->dev, "Memory alloc failure\n");
return -ENOMEM;
}
status = be_cmd_get_phy_info(adapter, &phy_cmd);
if (!status) { if (!status) {
resp = phy_cmd.va; switch (phy_info.interface_type) {
intf_type = le16_to_cpu(resp->interface_type);
switch (intf_type) {
case PHY_TYPE_XFP_10GB: case PHY_TYPE_XFP_10GB:
case PHY_TYPE_SFP_1GB: case PHY_TYPE_SFP_1GB:
case PHY_TYPE_SFP_PLUS_10GB: case PHY_TYPE_SFP_PLUS_10GB:
...@@ -407,7 +394,7 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -407,7 +394,7 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
break; break;
} }
switch (intf_type) { switch (phy_info.interface_type) {
case PHY_TYPE_KR_10GB: case PHY_TYPE_KR_10GB:
case PHY_TYPE_KX4_10GB: case PHY_TYPE_KX4_10GB:
ecmd->autoneg = AUTONEG_ENABLE; ecmd->autoneg = AUTONEG_ENABLE;
...@@ -425,8 +412,6 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) ...@@ -425,8 +412,6 @@ static int be_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
adapter->port_type = ecmd->port; adapter->port_type = ecmd->port;
adapter->transceiver = ecmd->transceiver; adapter->transceiver = ecmd->transceiver;
adapter->autoneg = ecmd->autoneg; adapter->autoneg = ecmd->autoneg;
dma_free_coherent(&adapter->pdev->dev, phy_cmd.size, phy_cmd.va,
phy_cmd.dma);
} else { } else {
ethtool_cmd_speed_set(ecmd, adapter->link_speed); ethtool_cmd_speed_set(ecmd, adapter->link_speed);
ecmd->port = adapter->port_type; ecmd->port = adapter->port_type;
......
...@@ -175,18 +175,24 @@ ...@@ -175,18 +175,24 @@
#define IMG_TYPE_FCOE_FW_ACTIVE 10 #define IMG_TYPE_FCOE_FW_ACTIVE 10
#define IMG_TYPE_FCOE_FW_BACKUP 11 #define IMG_TYPE_FCOE_FW_BACKUP 11
#define IMG_TYPE_NCSI_FW 13 #define IMG_TYPE_NCSI_FW 13
#define IMG_TYPE_PHY_FW 99
#define TN_8022 13
#define ILLEGAL_IOCTL_REQ 2
#define FLASHROM_OPER_PHY_FLASH 9
#define FLASHROM_OPER_PHY_SAVE 10
#define FLASHROM_OPER_FLASH 1 #define FLASHROM_OPER_FLASH 1
#define FLASHROM_OPER_SAVE 2 #define FLASHROM_OPER_SAVE 2
#define FLASHROM_OPER_REPORT 4 #define FLASHROM_OPER_REPORT 4
#define FLASH_IMAGE_MAX_SIZE_g2 (1310720) /* Max firmware image sz */ #define FLASH_IMAGE_MAX_SIZE_g2 (1310720) /* Max firmware image size */
#define FLASH_BIOS_IMAGE_MAX_SIZE_g2 (262144) /* Max OPTION ROM img sz */ #define FLASH_BIOS_IMAGE_MAX_SIZE_g2 (262144) /* Max OPTION ROM image sz */
#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g2 (262144) /* Max Redboot image sz */ #define FLASH_REDBOOT_IMAGE_MAX_SIZE_g2 (262144) /* Max Redboot image sz */
#define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max fw image size */ #define FLASH_IMAGE_MAX_SIZE_g3 (2097152) /* Max firmware image size */
#define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM img sz */ #define FLASH_BIOS_IMAGE_MAX_SIZE_g3 (524288) /* Max OPTION ROM image sz */
#define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */ #define FLASH_REDBOOT_IMAGE_MAX_SIZE_g3 (1048576) /* Max Redboot image sz */
#define FLASH_NCSI_IMAGE_MAX_SIZE_g3 (262144) /* Max NSCI image sz */ #define FLASH_NCSI_IMAGE_MAX_SIZE_g3 (262144)
#define FLASH_PHY_FW_IMAGE_MAX_SIZE_g3 262144
#define FLASH_NCSI_MAGIC (0x16032009) #define FLASH_NCSI_MAGIC (0x16032009)
#define FLASH_NCSI_DISABLED (0) #define FLASH_NCSI_DISABLED (0)
...@@ -213,6 +219,7 @@ ...@@ -213,6 +219,7 @@
#define FLASH_PXE_BIOS_START_g3 (13107200) #define FLASH_PXE_BIOS_START_g3 (13107200)
#define FLASH_FCoE_BIOS_START_g3 (13631488) #define FLASH_FCoE_BIOS_START_g3 (13631488)
#define FLASH_REDBOOT_START_g3 (262144) #define FLASH_REDBOOT_START_g3 (262144)
#define FLASH_PHY_FW_START_g3 1310720
/************* Rx Packet Type Encoding **************/ /************* Rx Packet Type Encoding **************/
#define BE_UNICAST_PACKET 0 #define BE_UNICAST_PACKET 0
......
...@@ -2569,6 +2569,21 @@ static bool be_flash_redboot(struct be_adapter *adapter, ...@@ -2569,6 +2569,21 @@ static bool be_flash_redboot(struct be_adapter *adapter,
return true; return true;
} }
static bool phy_flashing_required(struct be_adapter *adapter)
{
int status = 0;
struct be_phy_info phy_info;
status = be_cmd_get_phy_info(adapter, &phy_info);
if (status)
return false;
if ((phy_info.phy_type == TN_8022) &&
(phy_info.interface_type == PHY_TYPE_BASET_10GB)) {
return true;
}
return false;
}
static int be_flash_data(struct be_adapter *adapter, static int be_flash_data(struct be_adapter *adapter,
const struct firmware *fw, const struct firmware *fw,
struct be_dma_mem *flash_cmd, int num_of_images) struct be_dma_mem *flash_cmd, int num_of_images)
...@@ -2582,7 +2597,7 @@ static int be_flash_data(struct be_adapter *adapter, ...@@ -2582,7 +2597,7 @@ static int be_flash_data(struct be_adapter *adapter,
const struct flash_comp *pflashcomp; const struct flash_comp *pflashcomp;
int num_comp; int num_comp;
static const struct flash_comp gen3_flash_types[9] = { static const struct flash_comp gen3_flash_types[10] = {
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE, { FLASH_iSCSI_PRIMARY_IMAGE_START_g3, IMG_TYPE_ISCSI_ACTIVE,
FLASH_IMAGE_MAX_SIZE_g3}, FLASH_IMAGE_MAX_SIZE_g3},
{ FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT, { FLASH_REDBOOT_START_g3, IMG_TYPE_REDBOOT,
...@@ -2600,7 +2615,9 @@ static int be_flash_data(struct be_adapter *adapter, ...@@ -2600,7 +2615,9 @@ static int be_flash_data(struct be_adapter *adapter,
{ FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP, { FLASH_FCoE_BACKUP_IMAGE_START_g3, IMG_TYPE_FCOE_FW_BACKUP,
FLASH_IMAGE_MAX_SIZE_g3}, FLASH_IMAGE_MAX_SIZE_g3},
{ FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW, { FLASH_NCSI_START_g3, IMG_TYPE_NCSI_FW,
FLASH_NCSI_IMAGE_MAX_SIZE_g3} FLASH_NCSI_IMAGE_MAX_SIZE_g3},
{ FLASH_PHY_FW_START_g3, IMG_TYPE_PHY_FW,
FLASH_PHY_FW_IMAGE_MAX_SIZE_g3}
}; };
static const struct flash_comp gen2_flash_types[8] = { static const struct flash_comp gen2_flash_types[8] = {
{ FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE, { FLASH_iSCSI_PRIMARY_IMAGE_START_g2, IMG_TYPE_ISCSI_ACTIVE,
...@@ -2634,6 +2651,10 @@ static int be_flash_data(struct be_adapter *adapter, ...@@ -2634,6 +2651,10 @@ static int be_flash_data(struct be_adapter *adapter,
if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) && if ((pflashcomp[i].optype == IMG_TYPE_NCSI_FW) &&
memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0) memcmp(adapter->fw_ver, "3.102.148.0", 11) < 0)
continue; continue;
if (pflashcomp[i].optype == IMG_TYPE_PHY_FW) {
if (!phy_flashing_required(adapter))
continue;
}
if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) && if ((pflashcomp[i].optype == IMG_TYPE_REDBOOT) &&
(!be_flash_redboot(adapter, fw->data, (!be_flash_redboot(adapter, fw->data,
pflashcomp[i].offset, pflashcomp[i].size, filehdr_size + pflashcomp[i].offset, pflashcomp[i].size, filehdr_size +
...@@ -2651,16 +2672,26 @@ static int be_flash_data(struct be_adapter *adapter, ...@@ -2651,16 +2672,26 @@ static int be_flash_data(struct be_adapter *adapter,
else else
num_bytes = total_bytes; num_bytes = total_bytes;
total_bytes -= num_bytes; total_bytes -= num_bytes;
if (!total_bytes) {
if (!total_bytes) if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
flash_op = FLASHROM_OPER_PHY_FLASH;
else
flash_op = FLASHROM_OPER_FLASH; flash_op = FLASHROM_OPER_FLASH;
} else {
if (pflashcomp[i].optype == IMG_TYPE_PHY_FW)
flash_op = FLASHROM_OPER_PHY_SAVE;
else else
flash_op = FLASHROM_OPER_SAVE; flash_op = FLASHROM_OPER_SAVE;
}
memcpy(req->params.data_buf, p, num_bytes); memcpy(req->params.data_buf, p, num_bytes);
p += num_bytes; p += num_bytes;
status = be_cmd_write_flashrom(adapter, flash_cmd, status = be_cmd_write_flashrom(adapter, flash_cmd,
pflashcomp[i].optype, flash_op, num_bytes); pflashcomp[i].optype, flash_op, num_bytes);
if (status) { if (status) {
if ((status == ILLEGAL_IOCTL_REQ) &&
(pflashcomp[i].optype ==
IMG_TYPE_PHY_FW))
break;
dev_err(&adapter->pdev->dev, dev_err(&adapter->pdev->dev,
"cmd to write to flash rom failed.\n"); "cmd to write to flash rom failed.\n");
return -1; return -1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment