Commit f03c8a1e authored by Dimitris Michailidis's avatar Dimitris Michailidis Committed by Jakub Kicinski

net/funeth: Support for ethtool -m

Add the FW command for reading port module memory pages and implement
ethtool's get_module_eeprom_by_page operation.
Signed-off-by: default avatarDimitris Michailidis <dmichail@fungible.com>
Link: https://lore.kernel.org/r/20220627182000.8198-1-dmichail@fungible.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 849d5aa3
...@@ -442,6 +442,7 @@ enum fun_port_lane_attr { ...@@ -442,6 +442,7 @@ enum fun_port_lane_attr {
}; };
enum fun_admin_port_subop { enum fun_admin_port_subop {
FUN_ADMIN_PORT_SUBOP_XCVR_READ = 0x23,
FUN_ADMIN_PORT_SUBOP_INETADDR_EVENT = 0x24, FUN_ADMIN_PORT_SUBOP_INETADDR_EVENT = 0x24,
}; };
...@@ -595,6 +596,19 @@ struct fun_admin_port_req { ...@@ -595,6 +596,19 @@ struct fun_admin_port_req {
struct fun_admin_read48_req read48[]; struct fun_admin_read48_req read48[];
} read; } read;
struct fun_admin_port_xcvr_read_req {
u8 subop;
u8 rsvd0;
__be16 flags;
__be32 id;
u8 bank;
u8 page;
u8 offset;
u8 length;
u8 dev_addr;
u8 rsvd1[3];
} xcvr_read;
struct fun_admin_port_inetaddr_event_req { struct fun_admin_port_inetaddr_event_req {
__u8 subop; __u8 subop;
__u8 rsvd0; __u8 rsvd0;
...@@ -625,6 +639,15 @@ struct fun_admin_port_req { ...@@ -625,6 +639,15 @@ struct fun_admin_port_req {
.id = cpu_to_be32(_id), \ .id = cpu_to_be32(_id), \
} }
#define FUN_ADMIN_PORT_XCVR_READ_REQ_INIT(_flags, _id, _bank, _page, \
_offset, _length, _dev_addr) \
((struct fun_admin_port_xcvr_read_req) { \
.subop = FUN_ADMIN_PORT_SUBOP_XCVR_READ, \
.flags = cpu_to_be16(_flags), .id = cpu_to_be32(_id), \
.bank = (_bank), .page = (_page), .offset = (_offset), \
.length = (_length), .dev_addr = (_dev_addr), \
})
struct fun_admin_port_rsp { struct fun_admin_port_rsp {
struct fun_admin_rsp_common common; struct fun_admin_rsp_common common;
...@@ -659,6 +682,23 @@ struct fun_admin_port_rsp { ...@@ -659,6 +682,23 @@ struct fun_admin_port_rsp {
} u; } u;
}; };
struct fun_admin_port_xcvr_read_rsp {
struct fun_admin_rsp_common common;
u8 subop;
u8 rsvd0[3];
__be32 id;
u8 bank;
u8 page;
u8 offset;
u8 length;
u8 dev_addr;
u8 rsvd1[3];
u8 data[128];
};
enum fun_xcvr_type { enum fun_xcvr_type {
FUN_XCVR_BASET = 0x0, FUN_XCVR_BASET = 0x0,
FUN_XCVR_CU = 0x1, FUN_XCVR_CU = 0x1,
......
...@@ -1118,6 +1118,39 @@ static int fun_set_fecparam(struct net_device *netdev, ...@@ -1118,6 +1118,39 @@ static int fun_set_fecparam(struct net_device *netdev,
return fun_port_write_cmd(fp, FUN_ADMIN_PORT_KEY_FEC, fec_mode); return fun_port_write_cmd(fp, FUN_ADMIN_PORT_KEY_FEC, fec_mode);
} }
static int fun_get_port_module_page(struct net_device *netdev,
const struct ethtool_module_eeprom *req,
struct netlink_ext_ack *extack)
{
union {
struct fun_admin_port_req req;
struct fun_admin_port_xcvr_read_rsp rsp;
} cmd;
struct funeth_priv *fp = netdev_priv(netdev);
int rc;
if (fp->port_caps & FUN_PORT_CAP_VPORT) {
NL_SET_ERR_MSG_MOD(extack,
"Specified port is virtual, only physical ports have modules");
return -EOPNOTSUPP;
}
cmd.req.common = FUN_ADMIN_REQ_COMMON_INIT2(FUN_ADMIN_OP_PORT,
sizeof(cmd.req));
cmd.req.u.xcvr_read =
FUN_ADMIN_PORT_XCVR_READ_REQ_INIT(0, netdev->dev_port,
req->bank, req->page,
req->offset, req->length,
req->i2c_address);
rc = fun_submit_admin_sync_cmd(fp->fdev, &cmd.req.common, &cmd.rsp,
sizeof(cmd.rsp), 0);
if (rc)
return rc;
memcpy(req->data, cmd.rsp.data, req->length);
return req->length;
}
static const struct ethtool_ops fun_ethtool_ops = { static const struct ethtool_ops fun_ethtool_ops = {
.supported_coalesce_params = ETHTOOL_COALESCE_USECS | .supported_coalesce_params = ETHTOOL_COALESCE_USECS |
ETHTOOL_COALESCE_MAX_FRAMES, ETHTOOL_COALESCE_MAX_FRAMES,
...@@ -1156,6 +1189,7 @@ static const struct ethtool_ops fun_ethtool_ops = { ...@@ -1156,6 +1189,7 @@ static const struct ethtool_ops fun_ethtool_ops = {
.get_eth_mac_stats = fun_get_802_3_stats, .get_eth_mac_stats = fun_get_802_3_stats,
.get_eth_ctrl_stats = fun_get_802_3_ctrl_stats, .get_eth_ctrl_stats = fun_get_802_3_ctrl_stats,
.get_rmon_stats = fun_get_rmon_stats, .get_rmon_stats = fun_get_rmon_stats,
.get_module_eeprom_by_page = fun_get_port_module_page,
}; };
void fun_set_ethtool_ops(struct net_device *netdev) void fun_set_ethtool_ops(struct net_device *netdev)
......
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