Skip to content

Commit

Permalink
be2net: Implement initiate FW dump feature for Lancer
Browse files Browse the repository at this point in the history
Added code to initiate FW dump via ethtool. Driver checks if the previous dump
has been cleared before initiating the dump. It doesn't initiate the dump
if it is not cleared.

Signed-off-by: Kalesh AP <kalesh.purayil@emulex.com>
Signed-off-by: Somnath Kotur <somnath.kotur@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Somnath Kotur authored and David S. Miller committed Jun 1, 2013
1 parent 28a19fe commit 5c51081
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 35 deletions.
3 changes: 3 additions & 0 deletions drivers/net/ethernet/emulex/benet/be.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ enum vf_state {
#define BE_VF_UC_PMAC_COUNT 2
#define BE_FLAGS_QNQ_ASYNC_EVT_RCVD (1 << 11)

/* Ethtool set_dump flags */
#define LANCER_INITIATE_FW_DUMP 0x1

struct phy_info {
u8 transceiver;
u8 autoneg;
Expand Down
66 changes: 66 additions & 0 deletions drivers/net/ethernet/emulex/benet/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -3255,6 +3255,72 @@ int be_cmd_get_if_id(struct be_adapter *adapter, struct be_vf_cfg *vf_cfg,
return status;
}

static int lancer_wait_idle(struct be_adapter *adapter)
{
#define SLIPORT_IDLE_TIMEOUT 30
u32 reg_val;
int status = 0, i;

for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
break;

ssleep(1);
}

if (i == SLIPORT_IDLE_TIMEOUT)
status = -1;

return status;
}

int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask)
{
int status = 0;

status = lancer_wait_idle(adapter);
if (status)
return status;

iowrite32(mask, adapter->db + PHYSDEV_CONTROL_OFFSET);

return status;
}

/* Routine to check whether dump image is present or not */
bool dump_present(struct be_adapter *adapter)
{
u32 sliport_status = 0;

sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
return !!(sliport_status & SLIPORT_STATUS_DIP_MASK);
}

int lancer_initiate_dump(struct be_adapter *adapter)
{
int status;

/* give firmware reset and diagnostic dump */
status = lancer_physdev_ctrl(adapter, PHYSDEV_CONTROL_FW_RESET_MASK |
PHYSDEV_CONTROL_DD_MASK);
if (status < 0) {
dev_err(&adapter->pdev->dev, "Firmware reset failed\n");
return status;
}

status = lancer_wait_idle(adapter);
if (status)
return status;

if (!dump_present(adapter)) {
dev_err(&adapter->pdev->dev, "Dump image not present\n");
return -1;
}

return 0;
}

/* Uses sync mcc */
int be_cmd_enable_vf(struct be_adapter *adapter, u8 domain)
{
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/emulex/benet/be_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -1937,6 +1937,9 @@ extern int be_cmd_set_ext_fat_capabilites(struct be_adapter *adapter,
struct be_dma_mem *cmd,
struct be_fat_conf_params *cfgs);
extern int lancer_wait_ready(struct be_adapter *adapter);
extern int lancer_physdev_ctrl(struct be_adapter *adapter, u32 mask);
extern int lancer_initiate_dump(struct be_adapter *adapter);
extern bool dump_present(struct be_adapter *adapter);
extern int lancer_test_and_set_rdy_state(struct be_adapter *adapter);
extern int be_cmd_query_port_name(struct be_adapter *adapter, u8 *port_name);
extern int be_cmd_get_func_config(struct be_adapter *adapter);
Expand Down
29 changes: 29 additions & 0 deletions drivers/net/ethernet/emulex/benet/be_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -669,6 +669,34 @@ be_set_phys_id(struct net_device *netdev,
return 0;
}

static int be_set_dump(struct net_device *netdev, struct ethtool_dump *dump)
{
struct be_adapter *adapter = netdev_priv(netdev);
struct device *dev = &adapter->pdev->dev;
int status;

if (!lancer_chip(adapter)) {
dev_err(dev, "FW dump not supported\n");
return -EOPNOTSUPP;
}

if (dump_present(adapter)) {
dev_err(dev, "Previous dump not cleared, not forcing dump\n");
return 0;
}

switch (dump->flag) {
case LANCER_INITIATE_FW_DUMP:
status = lancer_initiate_dump(adapter);
if (!status)
dev_info(dev, "F/w dump initiated successfully\n");
break;
default:
dev_err(dev, "Invalid dump level: 0x%x\n", dump->flag);
return -EINVAL;
}
return status;
}

static void
be_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
Expand Down Expand Up @@ -1106,6 +1134,7 @@ const struct ethtool_ops be_ethtool_ops = {
.set_pauseparam = be_set_pauseparam,
.get_strings = be_get_stat_strings,
.set_phys_id = be_set_phys_id,
.set_dump = be_set_dump,
.get_msglevel = be_get_msg_level,
.set_msglevel = be_set_msg_level,
.get_sset_count = be_get_sset_count,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/emulex/benet/be_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,12 @@
#define PHYSDEV_CONTROL_OFFSET 0x414

#define SLIPORT_STATUS_ERR_MASK 0x80000000
#define SLIPORT_STATUS_DIP_MASK 0x02000000
#define SLIPORT_STATUS_RN_MASK 0x01000000
#define SLIPORT_STATUS_RDY_MASK 0x00800000
#define SLI_PORT_CONTROL_IP_MASK 0x08000000
#define PHYSDEV_CONTROL_FW_RESET_MASK 0x00000002
#define PHYSDEV_CONTROL_DD_MASK 0x00000004
#define PHYSDEV_CONTROL_INP_MASK 0x40000000

#define SLIPORT_ERROR_NO_RESOURCE1 0x2
Expand Down
37 changes: 2 additions & 35 deletions drivers/net/ethernet/emulex/benet/be_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3551,40 +3551,6 @@ static int be_flash_skyhawk(struct be_adapter *adapter,
return 0;
}

static int lancer_wait_idle(struct be_adapter *adapter)
{
#define SLIPORT_IDLE_TIMEOUT 30
u32 reg_val;
int status = 0, i;

for (i = 0; i < SLIPORT_IDLE_TIMEOUT; i++) {
reg_val = ioread32(adapter->db + PHYSDEV_CONTROL_OFFSET);
if ((reg_val & PHYSDEV_CONTROL_INP_MASK) == 0)
break;

ssleep(1);
}

if (i == SLIPORT_IDLE_TIMEOUT)
status = -1;

return status;
}

static int lancer_fw_reset(struct be_adapter *adapter)
{
int status = 0;

status = lancer_wait_idle(adapter);
if (status)
return status;

iowrite32(PHYSDEV_CONTROL_FW_RESET_MASK, adapter->db +
PHYSDEV_CONTROL_OFFSET);

return status;
}

static int lancer_fw_download(struct be_adapter *adapter,
const struct firmware *fw)
{
Expand Down Expand Up @@ -3662,7 +3628,8 @@ static int lancer_fw_download(struct be_adapter *adapter,
}

if (change_status == LANCER_FW_RESET_NEEDED) {
status = lancer_fw_reset(adapter);
status = lancer_physdev_ctrl(adapter,
PHYSDEV_CONTROL_FW_RESET_MASK);
if (status) {
dev_err(&adapter->pdev->dev,
"Adapter busy for FW reset.\n"
Expand Down

0 comments on commit 5c51081

Please sign in to comment.