1 /* Altera TSE SGDMA and MSGDMA Linux driver 2 * Copyright (C) 2014 Altera Corporation. All rights reserved 3 * 4 * This program is free software; you can redistribute it and/or modify it 5 * under the terms and conditions of the GNU General Public License, 6 * version 2, as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 * more details. 12 * 13 * You should have received a copy of the GNU General Public License along with 14 * this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include <linux/netdevice.h> 18 #include "altera_utils.h" 19 #include "altera_tse.h" 20 #include "altera_msgdmahw.h" 21 22 /* No initialization work to do for MSGDMA */ 23 int msgdma_initialize(struct altera_tse_private *priv) 24 { 25 return 0; 26 } 27 28 void msgdma_uninitialize(struct altera_tse_private *priv) 29 { 30 } 31 32 void msgdma_reset(struct altera_tse_private *priv) 33 { 34 int counter; 35 struct msgdma_csr *txcsr = 36 (struct msgdma_csr *)priv->tx_dma_csr; 37 struct msgdma_csr *rxcsr = 38 (struct msgdma_csr *)priv->rx_dma_csr; 39 40 /* Reset Rx mSGDMA */ 41 iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status); 42 iowrite32(MSGDMA_CSR_CTL_RESET, &rxcsr->control); 43 44 counter = 0; 45 while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { 46 if (tse_bit_is_clear(&rxcsr->status, 47 MSGDMA_CSR_STAT_RESETTING)) 48 break; 49 udelay(1); 50 } 51 52 if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) 53 netif_warn(priv, drv, priv->dev, 54 "TSE Rx mSGDMA resetting bit never cleared!\n"); 55 56 /* clear all status bits */ 57 iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status); 58 59 /* Reset Tx mSGDMA */ 60 iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status); 61 iowrite32(MSGDMA_CSR_CTL_RESET, &txcsr->control); 62 63 counter = 0; 64 while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { 65 if (tse_bit_is_clear(&txcsr->status, 66 MSGDMA_CSR_STAT_RESETTING)) 67 break; 68 udelay(1); 69 } 70 71 if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) 72 netif_warn(priv, drv, priv->dev, 73 "TSE Tx mSGDMA resetting bit never cleared!\n"); 74 75 /* clear all status bits */ 76 iowrite32(MSGDMA_CSR_STAT_MASK, &txcsr->status); 77 } 78 79 void msgdma_disable_rxirq(struct altera_tse_private *priv) 80 { 81 struct msgdma_csr *csr = priv->rx_dma_csr; 82 tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR); 83 } 84 85 void msgdma_enable_rxirq(struct altera_tse_private *priv) 86 { 87 struct msgdma_csr *csr = priv->rx_dma_csr; 88 tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR); 89 } 90 91 void msgdma_disable_txirq(struct altera_tse_private *priv) 92 { 93 struct msgdma_csr *csr = priv->tx_dma_csr; 94 tse_clear_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR); 95 } 96 97 void msgdma_enable_txirq(struct altera_tse_private *priv) 98 { 99 struct msgdma_csr *csr = priv->tx_dma_csr; 100 tse_set_bit(&csr->control, MSGDMA_CSR_CTL_GLOBAL_INTR); 101 } 102 103 void msgdma_clear_rxirq(struct altera_tse_private *priv) 104 { 105 struct msgdma_csr *csr = priv->rx_dma_csr; 106 iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status); 107 } 108 109 void msgdma_clear_txirq(struct altera_tse_private *priv) 110 { 111 struct msgdma_csr *csr = priv->tx_dma_csr; 112 iowrite32(MSGDMA_CSR_STAT_IRQ, &csr->status); 113 } 114 115 /* return 0 to indicate transmit is pending */ 116 int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer) 117 { 118 struct msgdma_extended_desc *desc = priv->tx_dma_desc; 119 120 iowrite32(lower_32_bits(buffer->dma_addr), &desc->read_addr_lo); 121 iowrite32(upper_32_bits(buffer->dma_addr), &desc->read_addr_hi); 122 iowrite32(0, &desc->write_addr_lo); 123 iowrite32(0, &desc->write_addr_hi); 124 iowrite32(buffer->len, &desc->len); 125 iowrite32(0, &desc->burst_seq_num); 126 iowrite32(MSGDMA_DESC_TX_STRIDE, &desc->stride); 127 iowrite32(MSGDMA_DESC_CTL_TX_SINGLE, &desc->control); 128 return 0; 129 } 130 131 u32 msgdma_tx_completions(struct altera_tse_private *priv) 132 { 133 u32 ready = 0; 134 u32 inuse; 135 u32 status; 136 struct msgdma_csr *txcsr = 137 (struct msgdma_csr *)priv->tx_dma_csr; 138 139 /* Get number of sent descriptors */ 140 inuse = ioread32(&txcsr->rw_fill_level) & 0xffff; 141 142 if (inuse) { /* Tx FIFO is not empty */ 143 ready = priv->tx_prod - priv->tx_cons - inuse - 1; 144 } else { 145 /* Check for buffered last packet */ 146 status = ioread32(&txcsr->status); 147 if (status & MSGDMA_CSR_STAT_BUSY) 148 ready = priv->tx_prod - priv->tx_cons - 1; 149 else 150 ready = priv->tx_prod - priv->tx_cons; 151 } 152 return ready; 153 } 154 155 /* Put buffer to the mSGDMA RX FIFO 156 */ 157 int msgdma_add_rx_desc(struct altera_tse_private *priv, 158 struct tse_buffer *rxbuffer) 159 { 160 struct msgdma_extended_desc *desc = priv->rx_dma_desc; 161 u32 len = priv->rx_dma_buf_sz; 162 dma_addr_t dma_addr = rxbuffer->dma_addr; 163 u32 control = (MSGDMA_DESC_CTL_END_ON_EOP 164 | MSGDMA_DESC_CTL_END_ON_LEN 165 | MSGDMA_DESC_CTL_TR_COMP_IRQ 166 | MSGDMA_DESC_CTL_EARLY_IRQ 167 | MSGDMA_DESC_CTL_TR_ERR_IRQ 168 | MSGDMA_DESC_CTL_GO); 169 170 iowrite32(0, &desc->read_addr_lo); 171 iowrite32(0, &desc->read_addr_hi); 172 iowrite32(lower_32_bits(dma_addr), &desc->write_addr_lo); 173 iowrite32(upper_32_bits(dma_addr), &desc->write_addr_hi); 174 iowrite32(len, &desc->len); 175 iowrite32(0, &desc->burst_seq_num); 176 iowrite32(0x00010001, &desc->stride); 177 iowrite32(control, &desc->control); 178 return 1; 179 } 180 181 /* status is returned on upper 16 bits, 182 * length is returned in lower 16 bits 183 */ 184 u32 msgdma_rx_status(struct altera_tse_private *priv) 185 { 186 u32 rxstatus = 0; 187 u32 pktlength; 188 u32 pktstatus; 189 struct msgdma_csr *rxcsr = 190 (struct msgdma_csr *)priv->rx_dma_csr; 191 struct msgdma_response *rxresp = 192 (struct msgdma_response *)priv->rx_dma_resp; 193 194 if (ioread32(&rxcsr->resp_fill_level) & 0xffff) { 195 pktlength = ioread32(&rxresp->bytes_transferred); 196 pktstatus = ioread32(&rxresp->status); 197 rxstatus = pktstatus; 198 rxstatus = rxstatus << 16; 199 rxstatus |= (pktlength & 0xffff); 200 } 201 return rxstatus; 202 } 203