1f2835adfSPeng Ma // SPDX-License-Identifier: GPL-2.0 2f2835adfSPeng Ma // Copyright 2019 NXP 3f2835adfSPeng Ma 4*53596dfaSPeng Ma #include <linux/module.h> 5f2835adfSPeng Ma #include <linux/types.h> 6f2835adfSPeng Ma #include <linux/io.h> 7f2835adfSPeng Ma #include <linux/fsl/mc.h> 8f2835adfSPeng Ma #include "dpdmai.h" 9f2835adfSPeng Ma 10f2835adfSPeng Ma struct dpdmai_rsp_get_attributes { 11f2835adfSPeng Ma __le32 id; 12f2835adfSPeng Ma u8 num_of_priorities; 13f2835adfSPeng Ma u8 pad0[3]; 14f2835adfSPeng Ma __le16 major; 15f2835adfSPeng Ma __le16 minor; 16f2835adfSPeng Ma }; 17f2835adfSPeng Ma 18f2835adfSPeng Ma struct dpdmai_cmd_queue { 19f2835adfSPeng Ma __le32 dest_id; 20f2835adfSPeng Ma u8 priority; 21f2835adfSPeng Ma u8 queue; 22f2835adfSPeng Ma u8 dest_type; 23f2835adfSPeng Ma u8 pad; 24f2835adfSPeng Ma __le64 user_ctx; 25f2835adfSPeng Ma union { 26f2835adfSPeng Ma __le32 options; 27f2835adfSPeng Ma __le32 fqid; 28f2835adfSPeng Ma }; 29f2835adfSPeng Ma }; 30f2835adfSPeng Ma 31f2835adfSPeng Ma struct dpdmai_rsp_get_tx_queue { 32f2835adfSPeng Ma __le64 pad; 33f2835adfSPeng Ma __le32 fqid; 34f2835adfSPeng Ma }; 35f2835adfSPeng Ma 36f2835adfSPeng Ma #define MC_CMD_OP(_cmd, _param, _offset, _width, _type, _arg) \ 37f2835adfSPeng Ma ((_cmd).params[_param] |= mc_enc((_offset), (_width), _arg)) 38f2835adfSPeng Ma 39f2835adfSPeng Ma /* cmd, param, offset, width, type, arg_name */ 40f2835adfSPeng Ma #define DPDMAI_CMD_CREATE(_cmd, _cfg) \ 41f2835adfSPeng Ma do { \ 42f2835adfSPeng Ma typeof(_cmd) (cmd) = (_cmd); \ 43f2835adfSPeng Ma typeof(_cfg) (cfg) = (_cfg); \ 44f2835adfSPeng Ma MC_CMD_OP(cmd, 0, 8, 8, u8, (cfg)->priorities[0]);\ 45f2835adfSPeng Ma MC_CMD_OP(cmd, 0, 16, 8, u8, (cfg)->priorities[1]);\ 46f2835adfSPeng Ma } while (0) 47f2835adfSPeng Ma 48f2835adfSPeng Ma static inline u64 mc_enc(int lsoffset, int width, u64 val) 49f2835adfSPeng Ma { 50f2835adfSPeng Ma return (val & MAKE_UMASK64(width)) << lsoffset; 51f2835adfSPeng Ma } 52f2835adfSPeng Ma 53f2835adfSPeng Ma /** 54f2835adfSPeng Ma * dpdmai_open() - Open a control session for the specified object 55f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 56f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 57f2835adfSPeng Ma * @dpdmai_id: DPDMAI unique ID 58f2835adfSPeng Ma * @token: Returned token; use in subsequent API calls 59f2835adfSPeng Ma * 60f2835adfSPeng Ma * This function can be used to open a control session for an 61f2835adfSPeng Ma * already created object; an object may have been declared in 62f2835adfSPeng Ma * the DPL or by calling the dpdmai_create() function. 63f2835adfSPeng Ma * This function returns a unique authentication token, 64f2835adfSPeng Ma * associated with the specific object ID and the specific MC 65f2835adfSPeng Ma * portal; this token must be used in all subsequent commands for 66f2835adfSPeng Ma * this specific object. 67f2835adfSPeng Ma * 68f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 69f2835adfSPeng Ma */ 70f2835adfSPeng Ma int dpdmai_open(struct fsl_mc_io *mc_io, u32 cmd_flags, 71f2835adfSPeng Ma int dpdmai_id, u16 *token) 72f2835adfSPeng Ma { 73f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 74f2835adfSPeng Ma __le64 *cmd_dpdmai_id; 75f2835adfSPeng Ma int err; 76f2835adfSPeng Ma 77f2835adfSPeng Ma /* prepare command */ 78f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_OPEN, 79f2835adfSPeng Ma cmd_flags, 0); 80f2835adfSPeng Ma 81f2835adfSPeng Ma cmd_dpdmai_id = cmd.params; 82f2835adfSPeng Ma *cmd_dpdmai_id = cpu_to_le32(dpdmai_id); 83f2835adfSPeng Ma 84f2835adfSPeng Ma /* send command to mc*/ 85f2835adfSPeng Ma err = mc_send_command(mc_io, &cmd); 86f2835adfSPeng Ma if (err) 87f2835adfSPeng Ma return err; 88f2835adfSPeng Ma 89f2835adfSPeng Ma /* retrieve response parameters */ 90f2835adfSPeng Ma *token = mc_cmd_hdr_read_token(&cmd); 91f2835adfSPeng Ma 92f2835adfSPeng Ma return 0; 93f2835adfSPeng Ma } 94*53596dfaSPeng Ma EXPORT_SYMBOL_GPL(dpdmai_open); 95f2835adfSPeng Ma 96f2835adfSPeng Ma /** 97f2835adfSPeng Ma * dpdmai_close() - Close the control session of the object 98f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 99f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 100f2835adfSPeng Ma * @token: Token of DPDMAI object 101f2835adfSPeng Ma * 102f2835adfSPeng Ma * After this function is called, no further operations are 103f2835adfSPeng Ma * allowed on the object without opening a new control session. 104f2835adfSPeng Ma * 105f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 106f2835adfSPeng Ma */ 107f2835adfSPeng Ma int dpdmai_close(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) 108f2835adfSPeng Ma { 109f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 110f2835adfSPeng Ma 111f2835adfSPeng Ma /* prepare command */ 112f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CLOSE, 113f2835adfSPeng Ma cmd_flags, token); 114f2835adfSPeng Ma 115f2835adfSPeng Ma /* send command to mc*/ 116f2835adfSPeng Ma return mc_send_command(mc_io, &cmd); 117f2835adfSPeng Ma } 118*53596dfaSPeng Ma EXPORT_SYMBOL_GPL(dpdmai_close); 119f2835adfSPeng Ma 120f2835adfSPeng Ma /** 121f2835adfSPeng Ma * dpdmai_create() - Create the DPDMAI object 122f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 123f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 124f2835adfSPeng Ma * @cfg: Configuration structure 125f2835adfSPeng Ma * @token: Returned token; use in subsequent API calls 126f2835adfSPeng Ma * 127f2835adfSPeng Ma * Create the DPDMAI object, allocate required resources and 128f2835adfSPeng Ma * perform required initialization. 129f2835adfSPeng Ma * 130f2835adfSPeng Ma * The object can be created either by declaring it in the 131f2835adfSPeng Ma * DPL file, or by calling this function. 132f2835adfSPeng Ma * 133f2835adfSPeng Ma * This function returns a unique authentication token, 134f2835adfSPeng Ma * associated with the specific object ID and the specific MC 135f2835adfSPeng Ma * portal; this token must be used in all subsequent calls to 136f2835adfSPeng Ma * this specific object. For objects that are created using the 137f2835adfSPeng Ma * DPL file, call dpdmai_open() function to get an authentication 138f2835adfSPeng Ma * token first. 139f2835adfSPeng Ma * 140f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 141f2835adfSPeng Ma */ 142f2835adfSPeng Ma int dpdmai_create(struct fsl_mc_io *mc_io, u32 cmd_flags, 143f2835adfSPeng Ma const struct dpdmai_cfg *cfg, u16 *token) 144f2835adfSPeng Ma { 145f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 146f2835adfSPeng Ma int err; 147f2835adfSPeng Ma 148f2835adfSPeng Ma /* prepare command */ 149f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_CREATE, 150f2835adfSPeng Ma cmd_flags, 0); 151f2835adfSPeng Ma DPDMAI_CMD_CREATE(cmd, cfg); 152f2835adfSPeng Ma 153f2835adfSPeng Ma /* send command to mc*/ 154f2835adfSPeng Ma err = mc_send_command(mc_io, &cmd); 155f2835adfSPeng Ma if (err) 156f2835adfSPeng Ma return err; 157f2835adfSPeng Ma 158f2835adfSPeng Ma /* retrieve response parameters */ 159f2835adfSPeng Ma *token = mc_cmd_hdr_read_token(&cmd); 160f2835adfSPeng Ma 161f2835adfSPeng Ma return 0; 162f2835adfSPeng Ma } 163f2835adfSPeng Ma 164f2835adfSPeng Ma /** 165f2835adfSPeng Ma * dpdmai_enable() - Enable the DPDMAI, allow sending and receiving frames. 166f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 167f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 168f2835adfSPeng Ma * @token: Token of DPDMAI object 169f2835adfSPeng Ma * 170f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 171f2835adfSPeng Ma */ 172f2835adfSPeng Ma int dpdmai_enable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) 173f2835adfSPeng Ma { 174f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 175f2835adfSPeng Ma 176f2835adfSPeng Ma /* prepare command */ 177f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_ENABLE, 178f2835adfSPeng Ma cmd_flags, token); 179f2835adfSPeng Ma 180f2835adfSPeng Ma /* send command to mc*/ 181f2835adfSPeng Ma return mc_send_command(mc_io, &cmd); 182f2835adfSPeng Ma } 183*53596dfaSPeng Ma EXPORT_SYMBOL_GPL(dpdmai_enable); 184f2835adfSPeng Ma 185f2835adfSPeng Ma /** 186f2835adfSPeng Ma * dpdmai_disable() - Disable the DPDMAI, stop sending and receiving frames. 187f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 188f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 189f2835adfSPeng Ma * @token: Token of DPDMAI object 190f2835adfSPeng Ma * 191f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 192f2835adfSPeng Ma */ 193f2835adfSPeng Ma int dpdmai_disable(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) 194f2835adfSPeng Ma { 195f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 196f2835adfSPeng Ma 197f2835adfSPeng Ma /* prepare command */ 198f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_DISABLE, 199f2835adfSPeng Ma cmd_flags, token); 200f2835adfSPeng Ma 201f2835adfSPeng Ma /* send command to mc*/ 202f2835adfSPeng Ma return mc_send_command(mc_io, &cmd); 203f2835adfSPeng Ma } 204*53596dfaSPeng Ma EXPORT_SYMBOL_GPL(dpdmai_disable); 205f2835adfSPeng Ma 206f2835adfSPeng Ma /** 207f2835adfSPeng Ma * dpdmai_reset() - Reset the DPDMAI, returns the object to initial state. 208f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 209f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 210f2835adfSPeng Ma * @token: Token of DPDMAI object 211f2835adfSPeng Ma * 212f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 213f2835adfSPeng Ma */ 214f2835adfSPeng Ma int dpdmai_reset(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token) 215f2835adfSPeng Ma { 216f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 217f2835adfSPeng Ma 218f2835adfSPeng Ma /* prepare command */ 219f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_RESET, 220f2835adfSPeng Ma cmd_flags, token); 221f2835adfSPeng Ma 222f2835adfSPeng Ma /* send command to mc*/ 223f2835adfSPeng Ma return mc_send_command(mc_io, &cmd); 224f2835adfSPeng Ma } 225*53596dfaSPeng Ma EXPORT_SYMBOL_GPL(dpdmai_reset); 226f2835adfSPeng Ma 227f2835adfSPeng Ma /** 228f2835adfSPeng Ma * dpdmai_get_attributes() - Retrieve DPDMAI attributes. 229f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 230f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 231f2835adfSPeng Ma * @token: Token of DPDMAI object 232f2835adfSPeng Ma * @attr: Returned object's attributes 233f2835adfSPeng Ma * 234f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 235f2835adfSPeng Ma */ 236f2835adfSPeng Ma int dpdmai_get_attributes(struct fsl_mc_io *mc_io, u32 cmd_flags, 237f2835adfSPeng Ma u16 token, struct dpdmai_attr *attr) 238f2835adfSPeng Ma { 239f2835adfSPeng Ma struct dpdmai_rsp_get_attributes *rsp_params; 240f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 241f2835adfSPeng Ma int err; 242f2835adfSPeng Ma 243f2835adfSPeng Ma /* prepare command */ 244f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_ATTR, 245f2835adfSPeng Ma cmd_flags, token); 246f2835adfSPeng Ma 247f2835adfSPeng Ma /* send command to mc*/ 248f2835adfSPeng Ma err = mc_send_command(mc_io, &cmd); 249f2835adfSPeng Ma if (err) 250f2835adfSPeng Ma return err; 251f2835adfSPeng Ma 252f2835adfSPeng Ma /* retrieve response parameters */ 253f2835adfSPeng Ma rsp_params = (struct dpdmai_rsp_get_attributes *)cmd.params; 254f2835adfSPeng Ma attr->id = le32_to_cpu(rsp_params->id); 255f2835adfSPeng Ma attr->version.major = le16_to_cpu(rsp_params->major); 256f2835adfSPeng Ma attr->version.minor = le16_to_cpu(rsp_params->minor); 257f2835adfSPeng Ma attr->num_of_priorities = rsp_params->num_of_priorities; 258f2835adfSPeng Ma 259f2835adfSPeng Ma return 0; 260f2835adfSPeng Ma } 261*53596dfaSPeng Ma EXPORT_SYMBOL_GPL(dpdmai_get_attributes); 262f2835adfSPeng Ma 263f2835adfSPeng Ma /** 264f2835adfSPeng Ma * dpdmai_set_rx_queue() - Set Rx queue configuration 265f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 266f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 267f2835adfSPeng Ma * @token: Token of DPDMAI object 268f2835adfSPeng Ma * @priority: Select the queue relative to number of 269f2835adfSPeng Ma * priorities configured at DPDMAI creation 270f2835adfSPeng Ma * @cfg: Rx queue configuration 271f2835adfSPeng Ma * 272f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 273f2835adfSPeng Ma */ 274f2835adfSPeng Ma int dpdmai_set_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, 275f2835adfSPeng Ma u8 priority, const struct dpdmai_rx_queue_cfg *cfg) 276f2835adfSPeng Ma { 277f2835adfSPeng Ma struct dpdmai_cmd_queue *cmd_params; 278f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 279f2835adfSPeng Ma 280f2835adfSPeng Ma /* prepare command */ 281f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_SET_RX_QUEUE, 282f2835adfSPeng Ma cmd_flags, token); 283f2835adfSPeng Ma 284f2835adfSPeng Ma cmd_params = (struct dpdmai_cmd_queue *)cmd.params; 285f2835adfSPeng Ma cmd_params->dest_id = cpu_to_le32(cfg->dest_cfg.dest_id); 286f2835adfSPeng Ma cmd_params->priority = cfg->dest_cfg.priority; 287f2835adfSPeng Ma cmd_params->queue = priority; 288f2835adfSPeng Ma cmd_params->dest_type = cfg->dest_cfg.dest_type; 289f2835adfSPeng Ma cmd_params->user_ctx = cpu_to_le64(cfg->user_ctx); 290f2835adfSPeng Ma cmd_params->options = cpu_to_le32(cfg->options); 291f2835adfSPeng Ma 292f2835adfSPeng Ma /* send command to mc*/ 293f2835adfSPeng Ma return mc_send_command(mc_io, &cmd); 294f2835adfSPeng Ma } 295*53596dfaSPeng Ma EXPORT_SYMBOL_GPL(dpdmai_set_rx_queue); 296f2835adfSPeng Ma 297f2835adfSPeng Ma /** 298f2835adfSPeng Ma * dpdmai_get_rx_queue() - Retrieve Rx queue attributes. 299f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 300f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 301f2835adfSPeng Ma * @token: Token of DPDMAI object 302f2835adfSPeng Ma * @priority: Select the queue relative to number of 303f2835adfSPeng Ma * priorities configured at DPDMAI creation 304f2835adfSPeng Ma * @attr: Returned Rx queue attributes 305f2835adfSPeng Ma * 306f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 307f2835adfSPeng Ma */ 308f2835adfSPeng Ma int dpdmai_get_rx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, 309f2835adfSPeng Ma u8 priority, struct dpdmai_rx_queue_attr *attr) 310f2835adfSPeng Ma { 311f2835adfSPeng Ma struct dpdmai_cmd_queue *cmd_params; 312f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 313f2835adfSPeng Ma int err; 314f2835adfSPeng Ma 315f2835adfSPeng Ma /* prepare command */ 316f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_RX_QUEUE, 317f2835adfSPeng Ma cmd_flags, token); 318f2835adfSPeng Ma 319f2835adfSPeng Ma cmd_params = (struct dpdmai_cmd_queue *)cmd.params; 320f2835adfSPeng Ma cmd_params->queue = priority; 321f2835adfSPeng Ma 322f2835adfSPeng Ma /* send command to mc*/ 323f2835adfSPeng Ma err = mc_send_command(mc_io, &cmd); 324f2835adfSPeng Ma if (err) 325f2835adfSPeng Ma return err; 326f2835adfSPeng Ma 327f2835adfSPeng Ma /* retrieve response parameters */ 328f2835adfSPeng Ma attr->dest_cfg.dest_id = le32_to_cpu(cmd_params->dest_id); 329f2835adfSPeng Ma attr->dest_cfg.priority = cmd_params->priority; 330f2835adfSPeng Ma attr->dest_cfg.dest_type = cmd_params->dest_type; 331f2835adfSPeng Ma attr->user_ctx = le64_to_cpu(cmd_params->user_ctx); 332f2835adfSPeng Ma attr->fqid = le32_to_cpu(cmd_params->fqid); 333f2835adfSPeng Ma 334f2835adfSPeng Ma return 0; 335f2835adfSPeng Ma } 336*53596dfaSPeng Ma EXPORT_SYMBOL_GPL(dpdmai_get_rx_queue); 337f2835adfSPeng Ma 338f2835adfSPeng Ma /** 339f2835adfSPeng Ma * dpdmai_get_tx_queue() - Retrieve Tx queue attributes. 340f2835adfSPeng Ma * @mc_io: Pointer to MC portal's I/O object 341f2835adfSPeng Ma * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' 342f2835adfSPeng Ma * @token: Token of DPDMAI object 343f2835adfSPeng Ma * @priority: Select the queue relative to number of 344f2835adfSPeng Ma * priorities configured at DPDMAI creation 345f2835adfSPeng Ma * @fqid: Returned Tx queue 346f2835adfSPeng Ma * 347f2835adfSPeng Ma * Return: '0' on Success; Error code otherwise. 348f2835adfSPeng Ma */ 349f2835adfSPeng Ma int dpdmai_get_tx_queue(struct fsl_mc_io *mc_io, u32 cmd_flags, 350f2835adfSPeng Ma u16 token, u8 priority, u32 *fqid) 351f2835adfSPeng Ma { 352f2835adfSPeng Ma struct dpdmai_rsp_get_tx_queue *rsp_params; 353f2835adfSPeng Ma struct dpdmai_cmd_queue *cmd_params; 354f2835adfSPeng Ma struct fsl_mc_command cmd = { 0 }; 355f2835adfSPeng Ma int err; 356f2835adfSPeng Ma 357f2835adfSPeng Ma /* prepare command */ 358f2835adfSPeng Ma cmd.header = mc_encode_cmd_header(DPDMAI_CMDID_GET_TX_QUEUE, 359f2835adfSPeng Ma cmd_flags, token); 360f2835adfSPeng Ma 361f2835adfSPeng Ma cmd_params = (struct dpdmai_cmd_queue *)cmd.params; 362f2835adfSPeng Ma cmd_params->queue = priority; 363f2835adfSPeng Ma 364f2835adfSPeng Ma /* send command to mc*/ 365f2835adfSPeng Ma err = mc_send_command(mc_io, &cmd); 366f2835adfSPeng Ma if (err) 367f2835adfSPeng Ma return err; 368f2835adfSPeng Ma 369f2835adfSPeng Ma /* retrieve response parameters */ 370f2835adfSPeng Ma 371f2835adfSPeng Ma rsp_params = (struct dpdmai_rsp_get_tx_queue *)cmd.params; 372f2835adfSPeng Ma *fqid = le32_to_cpu(rsp_params->fqid); 373f2835adfSPeng Ma 374f2835adfSPeng Ma return 0; 375f2835adfSPeng Ma } 376*53596dfaSPeng Ma EXPORT_SYMBOL_GPL(dpdmai_get_tx_queue); 377*53596dfaSPeng Ma 378*53596dfaSPeng Ma MODULE_LICENSE("GPL v2"); 379