net/ethtool/phy.c

Source file repositories/reference/linux-study-clean/net/ethtool/phy.c

File Facts

System
Linux kernel
Corpus path
net/ethtool/phy.c
Extension
.c
Size
5061 bytes
Lines
195
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct phy_req_info {
	struct ethnl_req_info base;
};

struct phy_reply_data {
	struct ethnl_reply_data	base;
	u32 phyindex;
	char *drvname;
	char *name;
	unsigned int upstream_type;
	char *upstream_sfp_name;
	unsigned int upstream_index;
	char *downstream_sfp_name;
};

#define PHY_REPDATA(__reply_base) \
	container_of(__reply_base, struct phy_reply_data, base)

const struct nla_policy ethnl_phy_get_policy[ETHTOOL_A_PHY_HEADER + 1] = {
	[ETHTOOL_A_PHY_HEADER] = NLA_POLICY_NESTED(ethnl_header_policy),
};

static int phy_reply_size(const struct ethnl_req_info *req_info,
			  const struct ethnl_reply_data *reply_data)
{
	struct phy_reply_data *rep_data = PHY_REPDATA(reply_data);
	size_t size = 0;

	/* ETHTOOL_A_PHY_INDEX */
	size += nla_total_size(sizeof(u32));

	/* ETHTOOL_A_DRVNAME */
	if (rep_data->drvname)
		size += nla_total_size(strlen(rep_data->drvname) + 1);

	/* ETHTOOL_A_NAME */
	size += nla_total_size(strlen(rep_data->name) + 1);

	/* ETHTOOL_A_PHY_UPSTREAM_TYPE */
	size += nla_total_size(sizeof(u32));

	/* ETHTOOL_A_PHY_UPSTREAM_SFP_NAME */
	if (rep_data->upstream_sfp_name)
		size += nla_total_size(strlen(rep_data->upstream_sfp_name) + 1);

	/* ETHTOOL_A_PHY_UPSTREAM_INDEX */
	if (rep_data->upstream_index)
		size += nla_total_size(sizeof(u32));

	/* ETHTOOL_A_PHY_DOWNSTREAM_SFP_NAME */
	if (rep_data->downstream_sfp_name)
		size += nla_total_size(strlen(rep_data->downstream_sfp_name) + 1);

	return size;
}

static int phy_prepare_data(const struct ethnl_req_info *req_info,
			    struct ethnl_reply_data *reply_data,
			    const struct genl_info *info)
{
	struct phy_link_topology *topo = reply_data->dev->link_topo;
	struct phy_reply_data *rep_data = PHY_REPDATA(reply_data);
	struct nlattr **tb = info->attrs;
	struct phy_device_node *pdn;
	struct phy_device *phydev;
	int ret;

	phydev = ethnl_req_get_phydev(req_info, tb, ETHTOOL_A_PHY_HEADER,
				      info->extack);
	if (IS_ERR_OR_NULL(phydev))
		return -EOPNOTSUPP;

	pdn = xa_load(&topo->phys, phydev->phyindex);
	if (!pdn)
		return -EOPNOTSUPP;

	rep_data->phyindex = phydev->phyindex;

	rep_data->name = kstrdup(dev_name(&phydev->mdio.dev), GFP_KERNEL);
	if (!rep_data->name)
		return -ENOMEM;

	if (phydev->drv) {
		rep_data->drvname = kstrdup(phydev->drv->name, GFP_KERNEL);
		if (!rep_data->drvname) {
			ret = -ENOMEM;
			goto err_free_name;
		}
	}

Annotation

Implementation Notes