diff mbox series

[RFC,net-next,06/28] net: ethernet: ti: cpsw-proxy-client: add helper to get virtual port info

Message ID 20240518124234.2671651-7-s-vadapalli@ti.com (mailing list archive)
State New, archived
Headers show
Series Add CPSW Proxy Client driver | expand

Commit Message

Siddharth Vadapalli May 18, 2024, 12:42 p.m. UTC
Add the helper function "get_virtual_port_info()" to send the
ETHFW_VIRT_PORT_INFO request and store details of virtual port
allocation. The details include type of virtual port, the virtual
port ID and the token identifying the virtual port.

Signed-off-by: Siddharth Vadapalli <s-vadapalli@ti.com>
---
 drivers/net/ethernet/ti/cpsw-proxy-client.c | 75 +++++++++++++++++++++
 1 file changed, 75 insertions(+)
diff mbox series

Patch

diff --git a/drivers/net/ethernet/ti/cpsw-proxy-client.c b/drivers/net/ethernet/ti/cpsw-proxy-client.c
index 70b8cfe67921..262fbf59ac72 100644
--- a/drivers/net/ethernet/ti/cpsw-proxy-client.c
+++ b/drivers/net/ethernet/ti/cpsw-proxy-client.c
@@ -14,6 +14,11 @@ 
 
 #define ETHFW_RESPONSE_TIMEOUT_MS	500
 
+enum virtual_port_type {
+	VIRT_SWITCH_PORT,
+	VIRT_MAC_ONLY_PORT,
+};
+
 struct cpsw_proxy_req_params {
 	struct message	req_msg;	/* Request message to be filled */
 	u32		token;
@@ -30,13 +35,26 @@  struct cpsw_proxy_req_params {
 	u8		ipv4_addr[ETHFW_IPV4ADDRLEN];
 };
 
+struct virtual_port {
+	struct cpsw_proxy_priv		*proxy_priv;
+	enum virtual_port_type		port_type;
+	u32				port_id;
+};
+
 struct cpsw_proxy_priv {
 	struct rpmsg_device		*rpdev;
 	struct device			*dev;
+	struct virtual_port		*virt_ports;
 	struct cpsw_proxy_req_params	req_params;
+	struct mutex			req_params_mutex; /* Request params mutex */
 	struct message			resp_msg;
 	struct completion		wait_for_response;
 	int				resp_msg_len;
+	u32				vswitch_ports; /* Bitmask of Virtual Switch Port IDs */
+	u32				vmac_ports /* Bitmask of Virtual MAC Only Port IDs */;
+	u32				num_switch_ports;
+	u32				num_mac_ports;
+	u32				num_virt_ports;
 };
 
 static int cpsw_proxy_client_cb(struct rpmsg_device *rpdev, void *data,
@@ -275,6 +293,63 @@  static int send_request_get_response(struct cpsw_proxy_priv *proxy_priv,
 	return ret;
 }
 
+static int get_virtual_port_info(struct cpsw_proxy_priv *proxy_priv)
+{
+	struct virt_port_info_response *vpi_resp;
+	struct cpsw_proxy_req_params *req_p;
+	struct virtual_port *vport;
+	struct message resp_msg;
+	unsigned int vp_id, i;
+	int ret;
+
+	mutex_lock(&proxy_priv->req_params_mutex);
+	req_p = &proxy_priv->req_params;
+	req_p->request_type = ETHFW_VIRT_PORT_INFO;
+	ret = send_request_get_response(proxy_priv, &resp_msg);
+	mutex_unlock(&proxy_priv->req_params_mutex);
+
+	if (ret) {
+		dev_err(proxy_priv->dev, "failed to get virtual port info\n");
+		return ret;
+	}
+
+	vpi_resp = (struct virt_port_info_response *)&resp_msg;
+	proxy_priv->vswitch_ports = vpi_resp->switch_port_mask;
+	proxy_priv->vmac_ports = vpi_resp->mac_port_mask;
+	/* Number of 1s set in vswitch_ports is the count of switch ports */
+	proxy_priv->num_switch_ports = hweight32(proxy_priv->vswitch_ports);
+	proxy_priv->num_virt_ports = proxy_priv->num_switch_ports;
+	/* Number of 1s set in vmac_ports is the count of mac ports */
+	proxy_priv->num_mac_ports = hweight32(proxy_priv->vmac_ports);
+	proxy_priv->num_virt_ports += proxy_priv->num_mac_ports;
+
+	proxy_priv->virt_ports = devm_kcalloc(proxy_priv->dev,
+					      proxy_priv->num_virt_ports,
+					      sizeof(*proxy_priv->virt_ports),
+					      GFP_KERNEL);
+
+	vp_id = 0;
+	for (i = 0; i < proxy_priv->num_switch_ports; i++) {
+		vport = &proxy_priv->virt_ports[vp_id];
+		vport->proxy_priv = proxy_priv;
+		vport->port_type = VIRT_SWITCH_PORT;
+		/* Port ID is derived from the bit set in the bitmask */
+		vport->port_id = fns(proxy_priv->vswitch_ports, i);
+		vp_id++;
+	}
+
+	for (i = 0; i < proxy_priv->num_mac_ports; i++) {
+		vport = &proxy_priv->virt_ports[vp_id];
+		vport->proxy_priv = proxy_priv;
+		vport->port_type = VIRT_MAC_ONLY_PORT;
+		/* Port ID is derived from the bit set in the bitmask */
+		vport->port_id = fns(proxy_priv->vmac_ports, i);
+		vp_id++;
+	}
+
+	return 0;
+}
+
 static int cpsw_proxy_client_probe(struct rpmsg_device *rpdev)
 {
 	struct cpsw_proxy_priv *proxy_priv;