162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) 262306a36Sopenharmony_ci/* Copyright 2013-2016 Freescale Semiconductor Inc. 362306a36Sopenharmony_ci * Copyright 2019 NXP 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci#include <linux/fsl/mc.h> 662306a36Sopenharmony_ci#include "dpmac.h" 762306a36Sopenharmony_ci#include "dpmac-cmd.h" 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci/** 1062306a36Sopenharmony_ci * dpmac_open() - Open a control session for the specified object. 1162306a36Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 1262306a36Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 1362306a36Sopenharmony_ci * @dpmac_id: DPMAC unique ID 1462306a36Sopenharmony_ci * @token: Returned token; use in subsequent API calls 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * This function can be used to open a control session for an 1762306a36Sopenharmony_ci * already created object; an object may have been declared in 1862306a36Sopenharmony_ci * the DPL or by calling the dpmac_create function. 1962306a36Sopenharmony_ci * This function returns a unique authentication token, 2062306a36Sopenharmony_ci * associated with the specific object ID and the specific MC 2162306a36Sopenharmony_ci * portal; this token must be used in all subsequent commands for 2262306a36Sopenharmony_ci * this specific object 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 2562306a36Sopenharmony_ci */ 2662306a36Sopenharmony_ciint dpmac_open(struct fsl_mc_io *mc_io, 2762306a36Sopenharmony_ci u32 cmd_flags, 2862306a36Sopenharmony_ci int dpmac_id, 2962306a36Sopenharmony_ci u16 *token) 3062306a36Sopenharmony_ci{ 3162306a36Sopenharmony_ci struct dpmac_cmd_open *cmd_params; 3262306a36Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 3362306a36Sopenharmony_ci int err; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci /* prepare command */ 3662306a36Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPMAC_CMDID_OPEN, 3762306a36Sopenharmony_ci cmd_flags, 3862306a36Sopenharmony_ci 0); 3962306a36Sopenharmony_ci cmd_params = (struct dpmac_cmd_open *)cmd.params; 4062306a36Sopenharmony_ci cmd_params->dpmac_id = cpu_to_le32(dpmac_id); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci /* send command to mc*/ 4362306a36Sopenharmony_ci err = mc_send_command(mc_io, &cmd); 4462306a36Sopenharmony_ci if (err) 4562306a36Sopenharmony_ci return err; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci /* retrieve response parameters */ 4862306a36Sopenharmony_ci *token = mc_cmd_hdr_read_token(&cmd); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci return err; 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/** 5462306a36Sopenharmony_ci * dpmac_close() - Close the control session of the object 5562306a36Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 5662306a36Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 5762306a36Sopenharmony_ci * @token: Token of DPMAC object 5862306a36Sopenharmony_ci * 5962306a36Sopenharmony_ci * After this function is called, no further operations are 6062306a36Sopenharmony_ci * allowed on the object without opening a new control session. 6162306a36Sopenharmony_ci * 6262306a36Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 6362306a36Sopenharmony_ci */ 6462306a36Sopenharmony_ciint dpmac_close(struct fsl_mc_io *mc_io, 6562306a36Sopenharmony_ci u32 cmd_flags, 6662306a36Sopenharmony_ci u16 token) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci /* prepare command */ 7162306a36Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPMAC_CMDID_CLOSE, cmd_flags, 7262306a36Sopenharmony_ci token); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci /* send command to mc*/ 7562306a36Sopenharmony_ci return mc_send_command(mc_io, &cmd); 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci/** 7962306a36Sopenharmony_ci * dpmac_get_attributes - Retrieve DPMAC attributes. 8062306a36Sopenharmony_ci * 8162306a36Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 8262306a36Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 8362306a36Sopenharmony_ci * @token: Token of DPMAC object 8462306a36Sopenharmony_ci * @attr: Returned object's attributes 8562306a36Sopenharmony_ci * 8662306a36Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 8762306a36Sopenharmony_ci */ 8862306a36Sopenharmony_ciint dpmac_get_attributes(struct fsl_mc_io *mc_io, 8962306a36Sopenharmony_ci u32 cmd_flags, 9062306a36Sopenharmony_ci u16 token, 9162306a36Sopenharmony_ci struct dpmac_attr *attr) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci struct dpmac_rsp_get_attributes *rsp_params; 9462306a36Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 9562306a36Sopenharmony_ci int err; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci /* prepare command */ 9862306a36Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_ATTR, 9962306a36Sopenharmony_ci cmd_flags, 10062306a36Sopenharmony_ci token); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci /* send command to mc*/ 10362306a36Sopenharmony_ci err = mc_send_command(mc_io, &cmd); 10462306a36Sopenharmony_ci if (err) 10562306a36Sopenharmony_ci return err; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci /* retrieve response parameters */ 10862306a36Sopenharmony_ci rsp_params = (struct dpmac_rsp_get_attributes *)cmd.params; 10962306a36Sopenharmony_ci attr->eth_if = rsp_params->eth_if; 11062306a36Sopenharmony_ci attr->link_type = rsp_params->link_type; 11162306a36Sopenharmony_ci attr->id = le16_to_cpu(rsp_params->id); 11262306a36Sopenharmony_ci attr->max_rate = le32_to_cpu(rsp_params->max_rate); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci return 0; 11562306a36Sopenharmony_ci} 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci/** 11862306a36Sopenharmony_ci * dpmac_set_link_state() - Set the Ethernet link status 11962306a36Sopenharmony_ci * @mc_io: Pointer to opaque I/O object 12062306a36Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 12162306a36Sopenharmony_ci * @token: Token of DPMAC object 12262306a36Sopenharmony_ci * @link_state: Link state configuration 12362306a36Sopenharmony_ci * 12462306a36Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 12562306a36Sopenharmony_ci */ 12662306a36Sopenharmony_ciint dpmac_set_link_state(struct fsl_mc_io *mc_io, 12762306a36Sopenharmony_ci u32 cmd_flags, 12862306a36Sopenharmony_ci u16 token, 12962306a36Sopenharmony_ci struct dpmac_link_state *link_state) 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci struct dpmac_cmd_set_link_state *cmd_params; 13262306a36Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci /* prepare command */ 13562306a36Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_LINK_STATE, 13662306a36Sopenharmony_ci cmd_flags, 13762306a36Sopenharmony_ci token); 13862306a36Sopenharmony_ci cmd_params = (struct dpmac_cmd_set_link_state *)cmd.params; 13962306a36Sopenharmony_ci cmd_params->options = cpu_to_le64(link_state->options); 14062306a36Sopenharmony_ci cmd_params->rate = cpu_to_le32(link_state->rate); 14162306a36Sopenharmony_ci dpmac_set_field(cmd_params->state, STATE, link_state->up); 14262306a36Sopenharmony_ci dpmac_set_field(cmd_params->state, STATE_VALID, 14362306a36Sopenharmony_ci link_state->state_valid); 14462306a36Sopenharmony_ci cmd_params->supported = cpu_to_le64(link_state->supported); 14562306a36Sopenharmony_ci cmd_params->advertising = cpu_to_le64(link_state->advertising); 14662306a36Sopenharmony_ci 14762306a36Sopenharmony_ci /* send command to mc*/ 14862306a36Sopenharmony_ci return mc_send_command(mc_io, &cmd); 14962306a36Sopenharmony_ci} 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci/** 15262306a36Sopenharmony_ci * dpmac_get_counter() - Read a specific DPMAC counter 15362306a36Sopenharmony_ci * @mc_io: Pointer to opaque I/O object 15462306a36Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 15562306a36Sopenharmony_ci * @token: Token of DPMAC object 15662306a36Sopenharmony_ci * @id: The requested counter ID 15762306a36Sopenharmony_ci * @value: Returned counter value 15862306a36Sopenharmony_ci * 15962306a36Sopenharmony_ci * Return: The requested counter; '0' otherwise. 16062306a36Sopenharmony_ci */ 16162306a36Sopenharmony_ciint dpmac_get_counter(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, 16262306a36Sopenharmony_ci enum dpmac_counter_id id, u64 *value) 16362306a36Sopenharmony_ci{ 16462306a36Sopenharmony_ci struct dpmac_cmd_get_counter *dpmac_cmd; 16562306a36Sopenharmony_ci struct dpmac_rsp_get_counter *dpmac_rsp; 16662306a36Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 16762306a36Sopenharmony_ci int err = 0; 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_COUNTER, 17062306a36Sopenharmony_ci cmd_flags, 17162306a36Sopenharmony_ci token); 17262306a36Sopenharmony_ci dpmac_cmd = (struct dpmac_cmd_get_counter *)cmd.params; 17362306a36Sopenharmony_ci dpmac_cmd->id = id; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci err = mc_send_command(mc_io, &cmd); 17662306a36Sopenharmony_ci if (err) 17762306a36Sopenharmony_ci return err; 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci dpmac_rsp = (struct dpmac_rsp_get_counter *)cmd.params; 18062306a36Sopenharmony_ci *value = le64_to_cpu(dpmac_rsp->counter); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci return 0; 18362306a36Sopenharmony_ci} 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci/** 18662306a36Sopenharmony_ci * dpmac_get_api_version() - Get Data Path MAC version 18762306a36Sopenharmony_ci * @mc_io: Pointer to MC portal's I/O object 18862306a36Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 18962306a36Sopenharmony_ci * @major_ver: Major version of data path mac API 19062306a36Sopenharmony_ci * @minor_ver: Minor version of data path mac API 19162306a36Sopenharmony_ci * 19262306a36Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 19362306a36Sopenharmony_ci */ 19462306a36Sopenharmony_ciint dpmac_get_api_version(struct fsl_mc_io *mc_io, u32 cmd_flags, 19562306a36Sopenharmony_ci u16 *major_ver, u16 *minor_ver) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci struct dpmac_rsp_get_api_version *rsp_params; 19862306a36Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 19962306a36Sopenharmony_ci int err; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPMAC_CMDID_GET_API_VERSION, 20262306a36Sopenharmony_ci cmd_flags, 20362306a36Sopenharmony_ci 0); 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci err = mc_send_command(mc_io, &cmd); 20662306a36Sopenharmony_ci if (err) 20762306a36Sopenharmony_ci return err; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci rsp_params = (struct dpmac_rsp_get_api_version *)cmd.params; 21062306a36Sopenharmony_ci *major_ver = le16_to_cpu(rsp_params->major); 21162306a36Sopenharmony_ci *minor_ver = le16_to_cpu(rsp_params->minor); 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_ci return 0; 21462306a36Sopenharmony_ci} 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci/** 21762306a36Sopenharmony_ci * dpmac_set_protocol() - Reconfigure the DPMAC protocol 21862306a36Sopenharmony_ci * @mc_io: Pointer to opaque I/O object 21962306a36Sopenharmony_ci * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 22062306a36Sopenharmony_ci * @token: Token of DPMAC object 22162306a36Sopenharmony_ci * @protocol: New protocol for the DPMAC to be reconfigured in. 22262306a36Sopenharmony_ci * 22362306a36Sopenharmony_ci * Return: '0' on Success; Error code otherwise. 22462306a36Sopenharmony_ci */ 22562306a36Sopenharmony_ciint dpmac_set_protocol(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, 22662306a36Sopenharmony_ci enum dpmac_eth_if protocol) 22762306a36Sopenharmony_ci{ 22862306a36Sopenharmony_ci struct dpmac_cmd_set_protocol *cmd_params; 22962306a36Sopenharmony_ci struct fsl_mc_command cmd = { 0 }; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci cmd.header = mc_encode_cmd_header(DPMAC_CMDID_SET_PROTOCOL, 23262306a36Sopenharmony_ci cmd_flags, token); 23362306a36Sopenharmony_ci cmd_params = (struct dpmac_cmd_set_protocol *)cmd.params; 23462306a36Sopenharmony_ci cmd_params->eth_if = protocol; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci return mc_send_command(mc_io, &cmd); 23762306a36Sopenharmony_ci} 238