1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 2 /* Copyright 2013-2016 Freescale Semiconductor Inc. 3 * Copyright 2019 NXP 4 */ 5 #include <linux/fsl/mc.h> 6 #include "dpmac.h" 7 #include "dpmac-cmd.h" 8 9 /** 10 * dpmac_open() - Open a control session for the specified object. 11 * @mc_io: Pointer to MC portal's I/O object 12 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 13 * @dpmac_id: DPMAC unique ID 14 * @token: Returned token; use in subsequent API calls 15 * 16 * This function can be used to open a control session for an 17 * already created object; an object may have been declared in 18 * the DPL or by calling the dpmac_create function. 19 * This function returns a unique authentication token, 20 * associated with the specific object ID and the specific MC 21 * portal; this token must be used in all subsequent commands for 22 * this specific object 23 * 24 * Return: '0' on Success; Error code otherwise. 25 */ 26 int dpmac_open(struct fsl_mc_io *mc_io, 27 u32 cmd_flags, 28 int dpmac_id, 29 u16 *token) 30 { 31 struct dpmac_cmd_open *cmd_params; 32 struct fsl_mc_command cmd = { 0 }; 33 int err; 34 35 /* prepare command */ 36 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_OPEN, 37 cmd_flags, 38 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 */ 64 int dpmac_close(struct fsl_mc_io *mc_io, 65 u32 cmd_flags, 66 u16 token) 67 { 68 struct fsl_mc_command cmd = { 0 }; 69 70 /* prepare command */ 71 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLOSE, cmd_flags, 72 token); 73 74 /* send command to mc*/ 75 return mc_send_command(mc_io, &cmd); 76 } 77 78 /** 79 * dpmac_get_attributes - Retrieve DPMAC attributes. 80 * 81 * @mc_io: Pointer to MC portal's I/O object 82 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 83 * @token: Token of DPMAC object 84 * @attr: Returned object's attributes 85 * 86 * Return: '0' on Success; Error code otherwise. 87 */ 88 int dpmac_get_attributes(struct fsl_mc_io *mc_io, 89 u32 cmd_flags, 90 u16 token, 91 struct dpmac_attr *attr) 92 { 93 struct dpmac_rsp_get_attributes *rsp_params; 94 struct fsl_mc_command cmd = { 0 }; 95 int err; 96 97 /* prepare command */ 98 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_ATTR, 99 cmd_flags, 100 token); 101 102 /* send command to mc*/ 103 err = mc_send_command(mc_io, &cmd); 104 if (err) 105 return err; 106 107 /* retrieve response parameters */ 108 rsp_params = (struct dpmac_rsp_get_attributes *)cmd.params; 109 attr->eth_if = rsp_params->eth_if; 110 attr->link_type = rsp_params->link_type; 111 attr->id = le16_to_cpu(rsp_params->id); 112 attr->max_rate = le32_to_cpu(rsp_params->max_rate); 113 114 return 0; 115 } 116 117 /** 118 * dpmac_set_link_state() - Set the Ethernet link status 119 * @mc_io: Pointer to opaque I/O object 120 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 121 * @token: Token of DPMAC object 122 * @link_state: Link state configuration 123 * 124 * Return: '0' on Success; Error code otherwise. 125 */ 126 int dpmac_set_link_state(struct fsl_mc_io *mc_io, 127 u32 cmd_flags, 128 u16 token, 129 struct dpmac_link_state *link_state) 130 { 131 struct dpmac_cmd_set_link_state *cmd_params; 132 struct fsl_mc_command cmd = { 0 }; 133 134 /* prepare command */ 135 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_LINK_STATE, 136 cmd_flags, 137 token); 138 cmd_params = (struct dpmac_cmd_set_link_state *)cmd.params; 139 cmd_params->options = cpu_to_le64(link_state->options); 140 cmd_params->rate = cpu_to_le32(link_state->rate); 141 dpmac_set_field(cmd_params->state, STATE, link_state->up); 142 dpmac_set_field(cmd_params->state, STATE_VALID, 143 link_state->state_valid); 144 cmd_params->supported = cpu_to_le64(link_state->supported); 145 cmd_params->advertising = cpu_to_le64(link_state->advertising); 146 147 /* send command to mc*/ 148 return mc_send_command(mc_io, &cmd); 149 } 150 151 /** 152 * dpmac_get_counter() - Read a specific DPMAC counter 153 * @mc_io: Pointer to opaque I/O object 154 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 155 * @token: Token of DPMAC object 156 * @id: The requested counter ID 157 * @value: Returned counter value 158 * 159 * Return: The requested counter; '0' otherwise. 160 */ 161 int dpmac_get_counter(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, 162 enum dpmac_counter_id id, u64 *value) 163 { 164 struct dpmac_cmd_get_counter *dpmac_cmd; 165 struct dpmac_rsp_get_counter *dpmac_rsp; 166 struct fsl_mc_command cmd = { 0 }; 167 int err = 0; 168 169 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_COUNTER, 170 cmd_flags, 171 token); 172 dpmac_cmd = (struct dpmac_cmd_get_counter *)cmd.params; 173 dpmac_cmd->id = id; 174 175 err = mc_send_command(mc_io, &cmd); 176 if (err) 177 return err; 178 179 dpmac_rsp = (struct dpmac_rsp_get_counter *)cmd.params; 180 *value = le64_to_cpu(dpmac_rsp->counter); 181 182 return 0; 183 } 184 185 /** 186 * dpmac_get_api_version() - Get Data Path MAC version 187 * @mc_io: Pointer to MC portal's I/O object 188 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 189 * @major_ver: Major version of data path mac API 190 * @minor_ver: Minor version of data path mac API 191 * 192 * Return: '0' on Success; Error code otherwise. 193 */ 194 int dpmac_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags, 195 u16 *major_ver, u16 *minor_ver) 196 { 197 struct dpmac_rsp_get_api_version *rsp_params; 198 struct fsl_mc_command cmd = { 0 }; 199 int err; 200 201 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_API_VERSION, 202 cmd_flags, 203 0); 204 205 err = mc_send_command(mc_io, &cmd); 206 if (err) 207 return err; 208 209 rsp_params = (struct dpmac_rsp_get_api_version *)cmd.params; 210 *major_ver = le16_to_cpu(rsp_params->major); 211 *minor_ver = le16_to_cpu(rsp_params->minor); 212 213 return 0; 214 } 215 216 /** 217 * dpmac_set_protocol() - Reconfigure the DPMAC protocol 218 * @mc_io: Pointer to opaque I/O object 219 * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 220 * @token: Token of DPMAC object 221 * @protocol: New protocol for the DPMAC to be reconfigured in. 222 * 223 * Return: '0' on Success; Error code otherwise. 224 */ 225 int dpmac_set_protocol(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, 226 enum dpmac_eth_if protocol) 227 { 228 struct dpmac_cmd_set_protocol *cmd_params; 229 struct fsl_mc_command cmd = { 0 }; 230 231 cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_PROTOCOL, 232 cmd_flags, token); 233 cmd_params = (struct dpmac_cmd_set_protocol *)cmd.params; 234 cmd_params->eth_if = protocol; 235 236 return mc_send_command(mc_io, &cmd); 237 } 238