13dec9fcdSqs148142 /* 23dec9fcdSqs148142 * CDDL HEADER START 33dec9fcdSqs148142 * 43dec9fcdSqs148142 * The contents of this file are subject to the terms of the 53dec9fcdSqs148142 * Common Development and Distribution License (the "License"). 63dec9fcdSqs148142 * You may not use this file except in compliance with the License. 73dec9fcdSqs148142 * 83dec9fcdSqs148142 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93dec9fcdSqs148142 * or http://www.opensolaris.org/os/licensing. 103dec9fcdSqs148142 * See the License for the specific language governing permissions 113dec9fcdSqs148142 * and limitations under the License. 123dec9fcdSqs148142 * 133dec9fcdSqs148142 * When distributing Covered Code, include this CDDL HEADER in each 143dec9fcdSqs148142 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153dec9fcdSqs148142 * If applicable, add the following below this CDDL HEADER, with the 163dec9fcdSqs148142 * fields enclosed by brackets "[]" replaced with your own identifying 173dec9fcdSqs148142 * information: Portions Copyright [yyyy] [name of copyright owner] 183dec9fcdSqs148142 * 193dec9fcdSqs148142 * CDDL HEADER END 203dec9fcdSqs148142 */ 213dec9fcdSqs148142 /* 223dec9fcdSqs148142 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 233dec9fcdSqs148142 * Use is subject to license terms. 243dec9fcdSqs148142 */ 253dec9fcdSqs148142 263dec9fcdSqs148142 #pragma ident "%Z%%M% %I% %E% SMI" 273dec9fcdSqs148142 283dec9fcdSqs148142 #include <hpi_txdma.h> 29*fe930412Sqs148142 #include <hxge_impl.h> 303dec9fcdSqs148142 313dec9fcdSqs148142 #define TXDMA_WAIT_LOOP 10000 323dec9fcdSqs148142 #define TXDMA_WAIT_MSEC 5 333dec9fcdSqs148142 343dec9fcdSqs148142 static hpi_status_t hpi_txdma_control_reset_wait(hpi_handle_t handle, 353dec9fcdSqs148142 uint8_t channel); 363dec9fcdSqs148142 373dec9fcdSqs148142 hpi_status_t 383dec9fcdSqs148142 hpi_txdma_log_page_handle_set(hpi_handle_t handle, uint8_t channel, 393dec9fcdSqs148142 tdc_page_handle_t *hdl_p) 403dec9fcdSqs148142 { 413dec9fcdSqs148142 int status = HPI_SUCCESS; 423dec9fcdSqs148142 433dec9fcdSqs148142 if (!TXDMA_CHANNEL_VALID(channel)) { 443dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 453dec9fcdSqs148142 " hpi_txdma_log_page_handle_set" 463dec9fcdSqs148142 " Invalid Input: channel <0x%x>", channel)); 473dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel)); 483dec9fcdSqs148142 } 493dec9fcdSqs148142 503dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_PAGE_HANDLE, channel, hdl_p->value); 513dec9fcdSqs148142 523dec9fcdSqs148142 return (status); 533dec9fcdSqs148142 } 543dec9fcdSqs148142 553dec9fcdSqs148142 hpi_status_t 563dec9fcdSqs148142 hpi_txdma_channel_reset(hpi_handle_t handle, uint8_t channel) 573dec9fcdSqs148142 { 583dec9fcdSqs148142 HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL, 593dec9fcdSqs148142 " hpi_txdma_channel_reset" " RESETTING", channel)); 603dec9fcdSqs148142 return (hpi_txdma_channel_control(handle, TXDMA_RESET, channel)); 613dec9fcdSqs148142 } 623dec9fcdSqs148142 633dec9fcdSqs148142 hpi_status_t 643dec9fcdSqs148142 hpi_txdma_channel_init_enable(hpi_handle_t handle, uint8_t channel) 653dec9fcdSqs148142 { 663dec9fcdSqs148142 return (hpi_txdma_channel_control(handle, TXDMA_INIT_START, channel)); 673dec9fcdSqs148142 } 683dec9fcdSqs148142 693dec9fcdSqs148142 hpi_status_t 703dec9fcdSqs148142 hpi_txdma_channel_enable(hpi_handle_t handle, uint8_t channel) 713dec9fcdSqs148142 { 723dec9fcdSqs148142 return (hpi_txdma_channel_control(handle, TXDMA_START, channel)); 733dec9fcdSqs148142 } 743dec9fcdSqs148142 753dec9fcdSqs148142 hpi_status_t 763dec9fcdSqs148142 hpi_txdma_channel_disable(hpi_handle_t handle, uint8_t channel) 773dec9fcdSqs148142 { 783dec9fcdSqs148142 return (hpi_txdma_channel_control(handle, TXDMA_STOP, channel)); 793dec9fcdSqs148142 } 803dec9fcdSqs148142 813dec9fcdSqs148142 hpi_status_t 823dec9fcdSqs148142 hpi_txdma_channel_mbox_enable(hpi_handle_t handle, uint8_t channel) 833dec9fcdSqs148142 { 843dec9fcdSqs148142 return (hpi_txdma_channel_control(handle, TXDMA_MBOX_ENABLE, channel)); 853dec9fcdSqs148142 } 863dec9fcdSqs148142 873dec9fcdSqs148142 hpi_status_t 883dec9fcdSqs148142 hpi_txdma_channel_control(hpi_handle_t handle, txdma_cs_cntl_t control, 893dec9fcdSqs148142 uint8_t channel) 903dec9fcdSqs148142 { 913dec9fcdSqs148142 int status = HPI_SUCCESS; 923dec9fcdSqs148142 tdc_stat_t cs; 933dec9fcdSqs148142 tdc_tdr_cfg_t cfg; 943dec9fcdSqs148142 953dec9fcdSqs148142 if (!TXDMA_CHANNEL_VALID(channel)) { 963dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 973dec9fcdSqs148142 " hpi_txdma_channel_control" 983dec9fcdSqs148142 " Invalid Input: channel <0x%x>", channel)); 993dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel)); 1003dec9fcdSqs148142 } 1013dec9fcdSqs148142 1023dec9fcdSqs148142 switch (control) { 1033dec9fcdSqs148142 case TXDMA_INIT_RESET: 1043dec9fcdSqs148142 cfg.value = 0; 1053dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &cfg.value); 1063dec9fcdSqs148142 cfg.bits.reset = 1; 1073dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value); 1083dec9fcdSqs148142 return (hpi_txdma_control_reset_wait(handle, channel)); 1093dec9fcdSqs148142 1103dec9fcdSqs148142 case TXDMA_INIT_START: 1113dec9fcdSqs148142 cfg.value = 0; 1123dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &cfg.value); 1133dec9fcdSqs148142 cfg.bits.enable = 1; 1143dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value); 1153dec9fcdSqs148142 break; 1163dec9fcdSqs148142 1173dec9fcdSqs148142 case TXDMA_RESET: 1183dec9fcdSqs148142 /* 1193dec9fcdSqs148142 * Sets reset bit only (Hardware will reset all the RW bits but 1203dec9fcdSqs148142 * leave the RO bits alone. 1213dec9fcdSqs148142 */ 1223dec9fcdSqs148142 cfg.value = 0; 1233dec9fcdSqs148142 cfg.bits.reset = 1; 1243dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value); 1253dec9fcdSqs148142 return (hpi_txdma_control_reset_wait(handle, channel)); 1263dec9fcdSqs148142 1273dec9fcdSqs148142 case TXDMA_START: 1283dec9fcdSqs148142 /* Enable the DMA channel */ 1293dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &cfg.value); 1303dec9fcdSqs148142 cfg.bits.enable = 1; 1313dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value); 1323dec9fcdSqs148142 break; 1333dec9fcdSqs148142 1343dec9fcdSqs148142 case TXDMA_STOP: 1353dec9fcdSqs148142 /* Disable the DMA channel */ 1363dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &cfg.value); 1373dec9fcdSqs148142 cfg.bits.enable = 0; 1383dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, cfg.value); 1393dec9fcdSqs148142 status = hpi_txdma_control_stop_wait(handle, channel); 1403dec9fcdSqs148142 if (status) { 1413dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1423dec9fcdSqs148142 "Cannot stop channel %d (TXC hung!)", channel)); 1433dec9fcdSqs148142 } 1443dec9fcdSqs148142 break; 1453dec9fcdSqs148142 1463dec9fcdSqs148142 case TXDMA_MBOX_ENABLE: 1473dec9fcdSqs148142 /* 1483dec9fcdSqs148142 * Write 1 to MB bit to enable mailbox update (cleared to 0 by 1493dec9fcdSqs148142 * hardware after update). 1503dec9fcdSqs148142 */ 1513dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_STAT, channel, &cs.value); 1523dec9fcdSqs148142 cs.bits.mb = 1; 1533dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_STAT, channel, cs.value); 1543dec9fcdSqs148142 break; 1553dec9fcdSqs148142 1563dec9fcdSqs148142 default: 1573dec9fcdSqs148142 status = (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel)); 1583dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1593dec9fcdSqs148142 " hpi_txdma_channel_control" 1603dec9fcdSqs148142 " Invalid Input: control <0x%x>", control)); 1613dec9fcdSqs148142 } 1623dec9fcdSqs148142 1633dec9fcdSqs148142 return (status); 1643dec9fcdSqs148142 } 1653dec9fcdSqs148142 1663dec9fcdSqs148142 hpi_status_t 1673dec9fcdSqs148142 hpi_txdma_control_status(hpi_handle_t handle, io_op_t op_mode, uint8_t channel, 1683dec9fcdSqs148142 tdc_stat_t *cs_p) 1693dec9fcdSqs148142 { 1703dec9fcdSqs148142 int status = HPI_SUCCESS; 1713dec9fcdSqs148142 tdc_stat_t txcs; 1723dec9fcdSqs148142 1733dec9fcdSqs148142 if (!TXDMA_CHANNEL_VALID(channel)) { 1743dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1753dec9fcdSqs148142 " hpi_txdma_control_status" 1763dec9fcdSqs148142 " Invalid Input: channel <0x%x>", channel)); 1773dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel)); 1783dec9fcdSqs148142 } 1793dec9fcdSqs148142 switch (op_mode) { 1803dec9fcdSqs148142 case OP_GET: 1813dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_STAT, channel, &cs_p->value); 1823dec9fcdSqs148142 break; 1833dec9fcdSqs148142 1843dec9fcdSqs148142 case OP_SET: 1853dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_STAT, channel, cs_p->value); 1863dec9fcdSqs148142 break; 1873dec9fcdSqs148142 1883dec9fcdSqs148142 case OP_UPDATE: 1893dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_STAT, channel, &txcs.value); 1903dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_STAT, channel, 1913dec9fcdSqs148142 cs_p->value | txcs.value); 1923dec9fcdSqs148142 break; 1933dec9fcdSqs148142 1943dec9fcdSqs148142 default: 1953dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 1963dec9fcdSqs148142 " hpi_txdma_control_status" 1973dec9fcdSqs148142 " Invalid Input: control <0x%x>", op_mode)); 1983dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel)); 1993dec9fcdSqs148142 } 2003dec9fcdSqs148142 2013dec9fcdSqs148142 return (status); 2023dec9fcdSqs148142 } 2033dec9fcdSqs148142 2043dec9fcdSqs148142 hpi_status_t 2053dec9fcdSqs148142 hpi_txdma_event_mask(hpi_handle_t handle, io_op_t op_mode, uint8_t channel, 2063dec9fcdSqs148142 tdc_int_mask_t *mask_p) 2073dec9fcdSqs148142 { 2083dec9fcdSqs148142 int status = HPI_SUCCESS; 2093dec9fcdSqs148142 tdc_int_mask_t mask; 2103dec9fcdSqs148142 2113dec9fcdSqs148142 if (!TXDMA_CHANNEL_VALID(channel)) { 2123dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2133dec9fcdSqs148142 " hpi_txdma_event_mask Invalid Input: channel <0x%x>", 2143dec9fcdSqs148142 channel)); 2153dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel)); 2163dec9fcdSqs148142 } 2173dec9fcdSqs148142 switch (op_mode) { 2183dec9fcdSqs148142 case OP_GET: 2193dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_INT_MASK, channel, &mask_p->value); 2203dec9fcdSqs148142 break; 2213dec9fcdSqs148142 2223dec9fcdSqs148142 case OP_SET: 2233dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_INT_MASK, channel, mask_p->value); 2243dec9fcdSqs148142 break; 2253dec9fcdSqs148142 2263dec9fcdSqs148142 case OP_UPDATE: 2273dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_INT_MASK, channel, &mask.value); 2283dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_INT_MASK, channel, 2293dec9fcdSqs148142 mask_p->value | mask.value); 2303dec9fcdSqs148142 break; 2313dec9fcdSqs148142 2323dec9fcdSqs148142 default: 2333dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2343dec9fcdSqs148142 " hpi_txdma_event_mask Invalid Input: eventmask <0x%x>", 2353dec9fcdSqs148142 op_mode)); 2363dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel)); 2373dec9fcdSqs148142 } 2383dec9fcdSqs148142 2393dec9fcdSqs148142 return (status); 2403dec9fcdSqs148142 } 2413dec9fcdSqs148142 2423dec9fcdSqs148142 hpi_status_t 2433dec9fcdSqs148142 hpi_txdma_ring_config(hpi_handle_t handle, io_op_t op_mode, 2443dec9fcdSqs148142 uint8_t channel, uint64_t *reg_data) 2453dec9fcdSqs148142 { 2463dec9fcdSqs148142 int status = HPI_SUCCESS; 2473dec9fcdSqs148142 2483dec9fcdSqs148142 if (!TXDMA_CHANNEL_VALID(channel)) { 2493dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2503dec9fcdSqs148142 " hpi_txdma_ring_config" 2513dec9fcdSqs148142 " Invalid Input: channel <0x%x>", channel)); 2523dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel)); 2533dec9fcdSqs148142 } 2543dec9fcdSqs148142 switch (op_mode) { 2553dec9fcdSqs148142 case OP_GET: 2563dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, reg_data); 2573dec9fcdSqs148142 break; 2583dec9fcdSqs148142 2593dec9fcdSqs148142 case OP_SET: 2603dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_TDR_CFG, channel, *reg_data); 2613dec9fcdSqs148142 break; 2623dec9fcdSqs148142 2633dec9fcdSqs148142 default: 2643dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2653dec9fcdSqs148142 " hpi_txdma_ring_config" 2663dec9fcdSqs148142 " Invalid Input: ring_config <0x%x>", op_mode)); 2673dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel)); 2683dec9fcdSqs148142 } 2693dec9fcdSqs148142 2703dec9fcdSqs148142 return (status); 2713dec9fcdSqs148142 } 2723dec9fcdSqs148142 2733dec9fcdSqs148142 hpi_status_t 2743dec9fcdSqs148142 hpi_txdma_mbox_config(hpi_handle_t handle, io_op_t op_mode, 2753dec9fcdSqs148142 uint8_t channel, uint64_t *mbox_addr) 2763dec9fcdSqs148142 { 2773dec9fcdSqs148142 int status = HPI_SUCCESS; 2783dec9fcdSqs148142 tdc_mbh_t mh; 2793dec9fcdSqs148142 tdc_mbl_t ml; 2803dec9fcdSqs148142 2813dec9fcdSqs148142 if (!TXDMA_CHANNEL_VALID(channel)) { 2823dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 2833dec9fcdSqs148142 " hpi_txdma_mbox_config Invalid Input: channel <0x%x>", 2843dec9fcdSqs148142 channel)); 2853dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel)); 2863dec9fcdSqs148142 } 2873dec9fcdSqs148142 2883dec9fcdSqs148142 mh.value = ml.value = 0; 2893dec9fcdSqs148142 2903dec9fcdSqs148142 switch (op_mode) { 2913dec9fcdSqs148142 case OP_GET: 2923dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_MBH, channel, &mh.value); 2933dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_MBL, channel, &ml.value); 2943dec9fcdSqs148142 *mbox_addr = ml.value; 2953dec9fcdSqs148142 *mbox_addr |= (mh.value << TDC_MBH_ADDR_SHIFT); 2963dec9fcdSqs148142 2973dec9fcdSqs148142 break; 2983dec9fcdSqs148142 2993dec9fcdSqs148142 case OP_SET: 3003dec9fcdSqs148142 ml.bits.mbaddr = ((*mbox_addr & TDC_MBL_MASK) >> TDC_MBL_SHIFT); 3013dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_MBL, channel, ml.value); 3023dec9fcdSqs148142 mh.bits.mbaddr = ((*mbox_addr >> TDC_MBH_ADDR_SHIFT) & 3033dec9fcdSqs148142 TDC_MBH_MASK); 3043dec9fcdSqs148142 TXDMA_REG_WRITE64(handle, TDC_MBH, channel, mh.value); 3053dec9fcdSqs148142 break; 3063dec9fcdSqs148142 3073dec9fcdSqs148142 default: 3083dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3093dec9fcdSqs148142 " hpi_txdma_mbox_config Invalid Input: mbox <0x%x>", 3103dec9fcdSqs148142 op_mode)); 3113dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_OPCODE_INVALID(channel)); 3123dec9fcdSqs148142 } 3133dec9fcdSqs148142 3143dec9fcdSqs148142 return (status); 3153dec9fcdSqs148142 } 3163dec9fcdSqs148142 3173dec9fcdSqs148142 /* 3183dec9fcdSqs148142 * This function is called to set up a transmit descriptor entry. 3193dec9fcdSqs148142 */ 3203dec9fcdSqs148142 hpi_status_t 3213dec9fcdSqs148142 hpi_txdma_desc_gather_set(hpi_handle_t handle, p_tx_desc_t desc_p, 3223dec9fcdSqs148142 uint8_t gather_index, boolean_t mark, uint8_t ngathers, 3233dec9fcdSqs148142 uint64_t dma_ioaddr, uint32_t transfer_len) 3243dec9fcdSqs148142 { 3253dec9fcdSqs148142 int status; 3263dec9fcdSqs148142 3273dec9fcdSqs148142 status = HPI_TXDMA_GATHER_INDEX(gather_index); 3283dec9fcdSqs148142 if (status) { 3293dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3303dec9fcdSqs148142 " hpi_txdma_desc_gather_set" 3313dec9fcdSqs148142 " Invalid Input: gather_index <0x%x>", gather_index)); 3323dec9fcdSqs148142 return (status); 3333dec9fcdSqs148142 } 3343dec9fcdSqs148142 if (transfer_len > TX_MAX_TRANSFER_LENGTH) { 3353dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3363dec9fcdSqs148142 " hpi_txdma_desc_gather_set" 3373dec9fcdSqs148142 " Invalid Input: tr_len <0x%x>", transfer_len)); 3383dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_XFER_LEN_INVALID); 3393dec9fcdSqs148142 } 3403dec9fcdSqs148142 if (gather_index == 0) { 3413dec9fcdSqs148142 desc_p->bits.sop = 1; 3423dec9fcdSqs148142 desc_p->bits.mark = mark; 3433dec9fcdSqs148142 desc_p->bits.num_ptr = ngathers; 3443dec9fcdSqs148142 HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL, 3453dec9fcdSqs148142 "hpi_txdma_gather_set: SOP len %d (%d)", 3463dec9fcdSqs148142 desc_p->bits.tr_len, transfer_len)); 3473dec9fcdSqs148142 } 3483dec9fcdSqs148142 desc_p->bits.tr_len = transfer_len; 349*fe930412Sqs148142 desc_p->bits.sad = dma_ioaddr >> 32; 350*fe930412Sqs148142 desc_p->bits.sad_l = dma_ioaddr & 0xffffffff; 3513dec9fcdSqs148142 3523dec9fcdSqs148142 HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL, 3533dec9fcdSqs148142 "hpi_txdma_gather_set: xfer len %d to set (%d)", 3543dec9fcdSqs148142 desc_p->bits.tr_len, transfer_len)); 3553dec9fcdSqs148142 3563dec9fcdSqs148142 HXGE_MEM_PIO_WRITE64(handle, desc_p->value); 3573dec9fcdSqs148142 3583dec9fcdSqs148142 return (status); 3593dec9fcdSqs148142 } 3603dec9fcdSqs148142 3613dec9fcdSqs148142 hpi_status_t 3623dec9fcdSqs148142 hpi_txdma_desc_set_zero(hpi_handle_t handle, uint16_t entries) 3633dec9fcdSqs148142 { 3643dec9fcdSqs148142 uint32_t offset; 3653dec9fcdSqs148142 int i; 3663dec9fcdSqs148142 3673dec9fcdSqs148142 /* 3683dec9fcdSqs148142 * Assume no wrapped around. 3693dec9fcdSqs148142 */ 3703dec9fcdSqs148142 offset = 0; 3713dec9fcdSqs148142 for (i = 0; i < entries; i++) { 3723dec9fcdSqs148142 HXGE_REG_WR64(handle, offset, 0); 3733dec9fcdSqs148142 offset += (i * (sizeof (tx_desc_t))); 3743dec9fcdSqs148142 } 3753dec9fcdSqs148142 3763dec9fcdSqs148142 return (HPI_SUCCESS); 3773dec9fcdSqs148142 } 3783dec9fcdSqs148142 3793dec9fcdSqs148142 /* 3803dec9fcdSqs148142 * This function is called to get the transmit ring head index. 3813dec9fcdSqs148142 */ 3823dec9fcdSqs148142 hpi_status_t 3833dec9fcdSqs148142 hpi_txdma_ring_head_get(hpi_handle_t handle, uint8_t channel, 3843dec9fcdSqs148142 tdc_tdr_head_t *hdl_p) 3853dec9fcdSqs148142 { 3863dec9fcdSqs148142 int status = HPI_SUCCESS; 3873dec9fcdSqs148142 3883dec9fcdSqs148142 if (!TXDMA_CHANNEL_VALID(channel)) { 3893dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 3903dec9fcdSqs148142 " hpi_txdma_ring_head_get" 3913dec9fcdSqs148142 " Invalid Input: channel <0x%x>", channel)); 3923dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_CHANNEL_INVALID(channel)); 3933dec9fcdSqs148142 } 3943dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_TDR_HEAD, channel, &hdl_p->value); 3953dec9fcdSqs148142 3963dec9fcdSqs148142 return (status); 3973dec9fcdSqs148142 } 3983dec9fcdSqs148142 3993dec9fcdSqs148142 /* 4003dec9fcdSqs148142 * Dumps the contents of transmit descriptors. 4013dec9fcdSqs148142 */ 4023dec9fcdSqs148142 /*ARGSUSED*/ 4033dec9fcdSqs148142 void 4043dec9fcdSqs148142 hpi_txdma_dump_desc_one(hpi_handle_t handle, p_tx_desc_t desc_p, int desc_index) 4053dec9fcdSqs148142 { 4063dec9fcdSqs148142 tx_desc_t desc, *desp; 4073dec9fcdSqs148142 4083dec9fcdSqs148142 #ifdef HXGE_DEBUG 4093dec9fcdSqs148142 uint64_t sad; 4103dec9fcdSqs148142 int xfer_len; 4113dec9fcdSqs148142 #endif 4123dec9fcdSqs148142 4133dec9fcdSqs148142 HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL, 4143dec9fcdSqs148142 "\n==> hpi_txdma_dump_desc_one: dump " 4153dec9fcdSqs148142 " desc_p $%p descriptor entry %d\n", desc_p, desc_index)); 4163dec9fcdSqs148142 desc.value = 0; 4173dec9fcdSqs148142 desp = ((desc_p != NULL) ? desc_p : (p_tx_desc_t)&desc); 418*fe930412Sqs148142 HXGE_MEM_PIO_READ64(handle, &desp->value); 4193dec9fcdSqs148142 #ifdef HXGE_DEBUG 4203dec9fcdSqs148142 sad = desp->bits.sad; 421*fe930412Sqs148142 sad = (sad << 32) | desp->bits.sad_l; 4223dec9fcdSqs148142 xfer_len = desp->bits.tr_len; 4233dec9fcdSqs148142 #endif 4243dec9fcdSqs148142 HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL, "\n\t: value 0x%llx\n" 4253dec9fcdSqs148142 "\t\tsad $%p\ttr_len %d len %d\tnptrs %d\tmark %d sop %d\n", 4263dec9fcdSqs148142 desp->value, sad, desp->bits.tr_len, xfer_len, 4273dec9fcdSqs148142 desp->bits.num_ptr, desp->bits.mark, desp->bits.sop)); 4283dec9fcdSqs148142 4293dec9fcdSqs148142 HPI_DEBUG_MSG((handle.function, HPI_TDC_CTL, 4303dec9fcdSqs148142 "\n<== hpi_txdma_dump_desc_one: Done \n")); 4313dec9fcdSqs148142 } 4323dec9fcdSqs148142 4333dec9fcdSqs148142 /* 4343dec9fcdSqs148142 * Static functions start here. 4353dec9fcdSqs148142 */ 4363dec9fcdSqs148142 static hpi_status_t 4373dec9fcdSqs148142 hpi_txdma_control_reset_wait(hpi_handle_t handle, uint8_t channel) 4383dec9fcdSqs148142 { 4393dec9fcdSqs148142 tdc_tdr_cfg_t txcs; 4403dec9fcdSqs148142 int loop = 0; 4413dec9fcdSqs148142 4423dec9fcdSqs148142 txcs.value = 0; 4433dec9fcdSqs148142 do { 4443dec9fcdSqs148142 HXGE_DELAY(TXDMA_WAIT_MSEC); 4453dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &txcs.value); 4463dec9fcdSqs148142 4473dec9fcdSqs148142 /* 4483dec9fcdSqs148142 * Reset completes when this bit is set to 1 by hw 4493dec9fcdSqs148142 */ 4503dec9fcdSqs148142 if (txcs.bits.qst) { 4513dec9fcdSqs148142 return (HPI_SUCCESS); 4523dec9fcdSqs148142 } 4533dec9fcdSqs148142 loop++; 4543dec9fcdSqs148142 } while (loop < TXDMA_WAIT_LOOP); 4553dec9fcdSqs148142 4563dec9fcdSqs148142 if (loop == TXDMA_WAIT_LOOP) { 4573dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 4583dec9fcdSqs148142 "hpi_txdma_control_reset_wait: RST bit not " 4593dec9fcdSqs148142 "cleared to 0 txcs.bits 0x%llx", txcs.value)); 4603dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_RESET_FAILED); 4613dec9fcdSqs148142 } 4623dec9fcdSqs148142 return (HPI_SUCCESS); 4633dec9fcdSqs148142 } 4643dec9fcdSqs148142 465*fe930412Sqs148142 hpi_status_t 4663dec9fcdSqs148142 hpi_txdma_control_stop_wait(hpi_handle_t handle, uint8_t channel) 4673dec9fcdSqs148142 { 4683dec9fcdSqs148142 tdc_tdr_cfg_t txcs; 4693dec9fcdSqs148142 int loop = 0; 4703dec9fcdSqs148142 4713dec9fcdSqs148142 do { 4723dec9fcdSqs148142 txcs.value = 0; 4733dec9fcdSqs148142 HXGE_DELAY(TXDMA_WAIT_MSEC); 4743dec9fcdSqs148142 TXDMA_REG_READ64(handle, TDC_TDR_CFG, channel, &txcs.value); 4753dec9fcdSqs148142 if (txcs.bits.qst) { 4763dec9fcdSqs148142 return (HPI_SUCCESS); 4773dec9fcdSqs148142 } 4783dec9fcdSqs148142 loop++; 4793dec9fcdSqs148142 } while (loop < TXDMA_WAIT_LOOP); 4803dec9fcdSqs148142 4813dec9fcdSqs148142 if (loop == TXDMA_WAIT_LOOP) { 4823dec9fcdSqs148142 HPI_ERROR_MSG((handle.function, HPI_ERR_CTL, 4833dec9fcdSqs148142 "hpi_txdma_control_stop_wait: SNG_STATE not " 4843dec9fcdSqs148142 "set to 1 txcs.bits 0x%llx", txcs.value)); 4853dec9fcdSqs148142 return (HPI_FAILURE | HPI_TXDMA_STOP_FAILED); 4863dec9fcdSqs148142 } 4873dec9fcdSqs148142 return (HPI_SUCCESS); 4883dec9fcdSqs148142 } 489