Skip to content

Commit

Permalink
be2net: add register dump feature for Lancer
Browse files Browse the repository at this point in the history
Implement register dump using ethtool for Lancer.

Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Padmanabh Ratnakar authored and David S. Miller committed Nov 16, 2011
1 parent 293c4a7 commit de49bd5
Show file tree
Hide file tree
Showing 3 changed files with 151 additions and 4 deletions.
47 changes: 47 additions & 0 deletions drivers/net/ethernet/emulex/benet/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -1828,6 +1828,53 @@ int lancer_cmd_write_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
return status;
}

int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 data_size, u32 data_offset, const char *obj_name,
u32 *data_read, u32 *eof, u8 *addn_status)
{
struct be_mcc_wrb *wrb;
struct lancer_cmd_req_read_object *req;
struct lancer_cmd_resp_read_object *resp;
int status;

spin_lock_bh(&adapter->mcc_lock);

wrb = wrb_from_mccq(adapter);
if (!wrb) {
status = -EBUSY;
goto err_unlock;
}

req = embedded_payload(wrb);

be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
OPCODE_COMMON_READ_OBJECT,
sizeof(struct lancer_cmd_req_read_object), wrb,
NULL);

req->desired_read_len = cpu_to_le32(data_size);
req->read_offset = cpu_to_le32(data_offset);
strcpy(req->object_name, obj_name);
req->descriptor_count = cpu_to_le32(1);
req->buf_len = cpu_to_le32(data_size);
req->addr_low = cpu_to_le32((cmd->dma & 0xFFFFFFFF));
req->addr_high = cpu_to_le32(upper_32_bits(cmd->dma));

status = be_mcc_notify_wait(adapter);

resp = embedded_payload(wrb);
if (!status) {
*data_read = le32_to_cpu(resp->actual_read_len);
*eof = le32_to_cpu(resp->eof);
} else {
*addn_status = resp->additional_status;
}

err_unlock:
spin_unlock_bh(&adapter->mcc_lock);
return status;
}

int be_cmd_write_flashrom(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 flash_type, u32 flash_opcode, u32 buf_size)
{
Expand Down
34 changes: 34 additions & 0 deletions drivers/net/ethernet/emulex/benet/be_cmds.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ struct be_mcc_mailbox {
#define OPCODE_COMMON_GET_PHY_DETAILS 102
#define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103
#define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121
#define OPCODE_COMMON_READ_OBJECT 171
#define OPCODE_COMMON_WRITE_OBJECT 172

#define OPCODE_ETH_RSS_CONFIG 1
Expand Down Expand Up @@ -1161,6 +1162,36 @@ struct lancer_cmd_resp_write_object {
u32 actual_write_len;
};

/************************ Lancer Read FW info **************/
#define LANCER_READ_FILE_CHUNK (32*1024)
#define LANCER_READ_FILE_EOF_MASK 0x80000000

#define LANCER_FW_DUMP_FILE "/dbg/dump.bin"

struct lancer_cmd_req_read_object {
struct be_cmd_req_hdr hdr;
u32 desired_read_len;
u32 read_offset;
u8 object_name[104];
u32 descriptor_count;
u32 buf_len;
u32 addr_low;
u32 addr_high;
};

struct lancer_cmd_resp_read_object {
u8 opcode;
u8 subsystem;
u8 rsvd1[2];
u8 status;
u8 additional_status;
u8 rsvd2[2];
u32 resp_len;
u32 actual_resp_len;
u32 actual_read_len;
u32 eof;
};

/************************ WOL *******************************/
struct be_cmd_req_acpi_wol_magic_config{
struct be_cmd_req_hdr hdr;
Expand Down Expand Up @@ -1480,6 +1511,9 @@ extern int lancer_cmd_write_object(struct be_adapter *adapter,
u32 data_size, u32 data_offset,
const char *obj_name,
u32 *data_written, u8 *addn_status);
int lancer_cmd_read_object(struct be_adapter *adapter, struct be_dma_mem *cmd,
u32 data_size, u32 data_offset, const char *obj_name,
u32 *data_read, u32 *eof, u8 *addn_status);
int be_cmd_get_flash_crc(struct be_adapter *adapter, u8 *flashed_crc,
int offset);
extern int be_cmd_enable_magic_wol(struct be_adapter *adapter, u8 *mac,
Expand Down
74 changes: 70 additions & 4 deletions drivers/net/ethernet/emulex/benet/be_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,15 +143,77 @@ static void be_get_drvinfo(struct net_device *netdev,
drvinfo->eedump_len = 0;
}

static u32
lancer_cmd_get_file_len(struct be_adapter *adapter, u8 *file_name)
{
u32 data_read = 0, eof;
u8 addn_status;
struct be_dma_mem data_len_cmd;
int status;

memset(&data_len_cmd, 0, sizeof(data_len_cmd));
/* data_offset and data_size should be 0 to get reg len */
status = lancer_cmd_read_object(adapter, &data_len_cmd, 0, 0,
file_name, &data_read, &eof, &addn_status);

return data_read;
}

static int
lancer_cmd_read_file(struct be_adapter *adapter, u8 *file_name,
u32 buf_len, void *buf)
{
struct be_dma_mem read_cmd;
u32 read_len = 0, total_read_len = 0, chunk_size;
u32 eof = 0;
u8 addn_status;
int status = 0;

read_cmd.size = LANCER_READ_FILE_CHUNK;
read_cmd.va = pci_alloc_consistent(adapter->pdev, read_cmd.size,
&read_cmd.dma);

if (!read_cmd.va) {
dev_err(&adapter->pdev->dev,
"Memory allocation failure while reading dump\n");
return -ENOMEM;
}

while ((total_read_len < buf_len) && !eof) {
chunk_size = min_t(u32, (buf_len - total_read_len),
LANCER_READ_FILE_CHUNK);
chunk_size = ALIGN(chunk_size, 4);
status = lancer_cmd_read_object(adapter, &read_cmd, chunk_size,
total_read_len, file_name, &read_len,
&eof, &addn_status);
if (!status) {
memcpy(buf + total_read_len, read_cmd.va, read_len);
total_read_len += read_len;
eof &= LANCER_READ_FILE_EOF_MASK;
} else {
status = -EIO;
break;
}
}
pci_free_consistent(adapter->pdev, read_cmd.size, read_cmd.va,
read_cmd.dma);

return status;
}

static int
be_get_reg_len(struct net_device *netdev)
{
struct be_adapter *adapter = netdev_priv(netdev);
u32 log_size = 0;

if (be_physfn(adapter))
be_cmd_get_reg_len(adapter, &log_size);

if (be_physfn(adapter)) {
if (lancer_chip(adapter))
log_size = lancer_cmd_get_file_len(adapter,
LANCER_FW_DUMP_FILE);
else
be_cmd_get_reg_len(adapter, &log_size);
}
return log_size;
}

Expand All @@ -162,7 +224,11 @@ be_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *buf)

if (be_physfn(adapter)) {
memset(buf, 0, regs->len);
be_cmd_get_regs(adapter, regs->len, buf);
if (lancer_chip(adapter))
lancer_cmd_read_file(adapter, LANCER_FW_DUMP_FILE,
regs->len, buf);
else
be_cmd_get_regs(adapter, regs->len, buf);
}
}

Expand Down

0 comments on commit de49bd5

Please sign in to comment.