1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Freescale Layerscape MC I/O wrapper
4  *
5  * Copyright 2015-2016 Freescale Semiconductor, Inc.
6  * Copyright 2017 NXP
7  * Author: Prabhakar Kushwaha <prabhakar@freescale.com>
8  */
9 
10 #include <fsl-mc/fsl_mc_sys.h>
11 #include <fsl-mc/fsl_mc_cmd.h>
12 #include <fsl-mc/fsl_dpmac.h>
13 
14 /**
15  * dpmac_open() - Open a control session for the specified object.
16  * @mc_io:	Pointer to MC portal's I/O object
17  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
18  * @dpmac_id:	DPMAC unique ID
19  * @token:	Returned token; use in subsequent API calls
20  *
21  * This function can be used to open a control session for an
22  * already created object; an object may have been declared in
23  * the DPL or by calling the dpmac_create function.
24  * This function returns a unique authentication token,
25  * associated with the specific object ID and the specific MC
26  * portal; this token must be used in all subsequent commands for
27  * this specific object
28  *
29  * Return:	'0' on Success; Error code otherwise.
30  */
dpmac_open(struct fsl_mc_io * mc_io,u32 cmd_flags,int dpmac_id,u16 * token)31 int dpmac_open(struct fsl_mc_io *mc_io, u32 cmd_flags, int dpmac_id, u16 *token)
32 {
33 	struct dpmac_cmd_open *cmd_params;
34 	struct mc_command cmd = { 0 };
35 	int err;
36 
37 	/* prepare command */
38 	cmd.header = mc_encode_cmd_header(DPMAC_CMDID_OPEN, cmd_flags, 0);
39 	cmd_params = (struct dpmac_cmd_open *)cmd.params;
40 	cmd_params->dpmac_id = cpu_to_le32(dpmac_id);
41 
42 	/* send command to mc*/
43 	err = mc_send_command(mc_io, &cmd);
44 	if (err)
45 		return err;
46 
47 	/* retrieve response parameters */
48 	*token = mc_cmd_hdr_read_token(&cmd);
49 
50 	return err;
51 }
52 
53 /**
54  * dpmac_close() - Close the control session of the object
55  * @mc_io:	Pointer to MC portal's I/O object
56  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
57  * @token:	Token of DPMAC object
58  *
59  * After this function is called, no further operations are
60  * allowed on the object without opening a new control session.
61  *
62  * Return:	'0' on Success; Error code otherwise.
63  */
dpmac_close(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token)64 int dpmac_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token)
65 {
66 	struct mc_command cmd = { 0 };
67 
68 	/* prepare command */
69 	cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLOSE, cmd_flags, token);
70 
71 	/* send command to mc*/
72 	return mc_send_command(mc_io, &cmd);
73 }
74 
75 /**
76  * dpmac_create() - Create the DPMAC object.
77  * @mc_io:	Pointer to MC portal's I/O object
78  * @dprc_token: Parent container token; '0' for default container
79  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
80  * @cfg:	Configuration structure
81  * @obj_id:	Returned object id
82  *
83  * Create the DPMAC object, allocate required resources and
84  * perform required initialization.
85  *
86  * The function accepts an authentication token of a parent
87  * container that this object should be assigned to. The token
88  * can be '0' so the object will be assigned to the default container.
89  * The newly created object can be opened with the returned
90  * object id and using the container's associated tokens and MC portals.
91  *
92  * Return:	'0' on Success; Error code otherwise.
93  */
dpmac_create(struct fsl_mc_io * mc_io,u16 dprc_token,u32 cmd_flags,const struct dpmac_cfg * cfg,u32 * obj_id)94 int dpmac_create(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags,
95 		 const struct dpmac_cfg *cfg, u32 *obj_id)
96 {
97 	struct dpmac_cmd_create *cmd_params;
98 	struct mc_command cmd = { 0 };
99 	int err;
100 
101 	/* prepare command */
102 	cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CREATE, cmd_flags, dprc_token);
103 	cmd_params = (struct dpmac_cmd_create *)cmd.params;
104 	cmd_params->mac_id = cpu_to_le32(cfg->mac_id);
105 
106 	/* send command to mc*/
107 	err = mc_send_command(mc_io, &cmd);
108 	if (err)
109 		return err;
110 
111 	/* retrieve response parameters */
112 	*obj_id = mc_cmd_read_object_id(&cmd);
113 
114 	return 0;
115 }
116 
117 /**
118  * dpmac_destroy() - Destroy the DPMAC object and release all its resources.
119  * @mc_io:	Pointer to MC portal's I/O object
120  * @dprc_token: Parent container token; '0' for default container
121  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
122  * @object_id:	The object id; it must be a valid id within the container that
123  * created this object;
124  *
125  * The function accepts the authentication token of the parent container that
126  * created the object (not the one that currently owns the object). The object
127  * is searched within parent using the provided 'object_id'.
128  * All tokens to the object must be closed before calling destroy.
129  *
130  * Return:	'0' on Success; error code otherwise.
131  */
dpmac_destroy(struct fsl_mc_io * mc_io,u16 dprc_token,u32 cmd_flags,u32 object_id)132 int dpmac_destroy(struct fsl_mc_io *mc_io, u16 dprc_token, u32 cmd_flags,
133 		  u32 object_id)
134 {
135 	struct dpmac_cmd_destroy *cmd_params;
136 	struct mc_command cmd = { 0 };
137 
138 	/* prepare command */
139 	cmd.header = mc_encode_cmd_header(DPMAC_CMDID_DESTROY,
140 					  cmd_flags,
141 					  dprc_token);
142 	cmd_params = (struct dpmac_cmd_destroy *)cmd.params;
143 	cmd_params->dpmac_id = cpu_to_le32(object_id);
144 
145 	/* send command to mc*/
146 	return mc_send_command(mc_io, &cmd);
147 }
148 
149 /**
150  * dpmac_set_link_state() - Set the Ethernet link status
151  * @mc_io:	Pointer to opaque I/O object
152  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
153  * @token:	Token of DPMAC object
154  * @link_state:	Link state configuration
155  *
156  * Return:	'0' on Success; Error code otherwise.
157  */
dpmac_set_link_state(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,struct dpmac_link_state * link_state)158 int dpmac_set_link_state(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
159 			 struct dpmac_link_state *link_state)
160 {
161 	struct dpmac_cmd_set_link_state *cmd_params;
162 	struct mc_command cmd = { 0 };
163 
164 	/* prepare command */
165 	cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_LINK_STATE, cmd_flags, token);
166 	cmd_params = (struct dpmac_cmd_set_link_state *)cmd.params;
167 	cmd_params->options = cpu_to_le64(link_state->options);
168 	cmd_params->rate = cpu_to_le32(link_state->rate);
169 	cmd_params->up = dpmac_get_field(link_state->up, STATE);
170 	dpmac_set_field(cmd_params->up, STATE_VALID, link_state->state_valid);
171 	cmd_params->supported = cpu_to_le64(link_state->supported);
172 	cmd_params->advertising = cpu_to_le64(link_state->advertising);
173 
174 	/* send command to mc*/
175 	return mc_send_command(mc_io, &cmd);
176 }
177 
178 /**
179  * dpmac_get_counter() - Read a specific DPMAC counter
180  * @mc_io:	Pointer to opaque I/O object
181  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
182  * @token:	Token of DPMAC object
183  * @type:	The requested counter
184  * @counter:	Returned counter value
185  *
186  * Return:	The requested counter; '0' otherwise.
187  */
dpmac_get_counter(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 token,enum dpmac_counter type,uint64_t * counter)188 int dpmac_get_counter(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token,
189 		      enum dpmac_counter type, uint64_t *counter)
190 {
191 	struct dpmac_cmd_get_counter *dpmac_cmd;
192 	struct dpmac_rsp_get_counter *dpmac_rsp;
193 	struct mc_command cmd = { 0 };
194 	int err = 0;
195 
196 	/* prepare command */
197 	cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_COUNTER,
198 					  cmd_flags,
199 					  token);
200 	dpmac_cmd = (struct dpmac_cmd_get_counter *)cmd.params;
201 	dpmac_cmd->type = type;
202 
203 	/* send command to mc*/
204 	err = mc_send_command(mc_io, &cmd);
205 	if (err)
206 		return err;
207 
208 	dpmac_rsp = (struct dpmac_rsp_get_counter *)cmd.params;
209 	*counter = le64_to_cpu(dpmac_rsp->counter);
210 
211 	return 0;
212 }
213 
214 /**
215  * dpmac_get_api_version() - Get Data Path MAC version
216  * @mc_io:	Pointer to MC portal's I/O object
217  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
218  * @major_ver:	Major version of data path mac API
219  * @minor_ver:	Minor version of data path mac API
220  *
221  * Return:  '0' on Success; Error code otherwise.
222  */
dpmac_get_api_version(struct fsl_mc_io * mc_io,u32 cmd_flags,u16 * major_ver,u16 * minor_ver)223 int dpmac_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags,
224 			  u16 *major_ver, u16 *minor_ver)
225 {
226 	struct mc_command cmd = { 0 };
227 	int err;
228 
229 	cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_API_VERSION,
230 					cmd_flags,
231 					0);
232 
233 	err = mc_send_command(mc_io, &cmd);
234 	if (err)
235 		return err;
236 
237 	mc_cmd_read_api_version(&cmd, major_ver, minor_ver);
238 
239 	return 0;
240 }
241