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 #include "altera_msgdma.h" 22 23 /* No initialization work to do for MSGDMA */ 24 int msgdma_initialize(struct altera_tse_private *priv) 25 { 26 return 0; 27 } 28 29 void msgdma_uninitialize(struct altera_tse_private *priv) 30 { 31 } 32 33 void msgdma_start_rxdma(struct altera_tse_private *priv) 34 { 35 } 36 37 void msgdma_reset(struct altera_tse_private *priv) 38 { 39 int counter; 40 41 /* Reset Rx mSGDMA */ 42 csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr, 43 msgdma_csroffs(status)); 44 csrwr32(MSGDMA_CSR_CTL_RESET, priv->rx_dma_csr, 45 msgdma_csroffs(control)); 46 47 counter = 0; 48 while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { 49 if (tse_bit_is_clear(priv->rx_dma_csr, msgdma_csroffs(status), 50 MSGDMA_CSR_STAT_RESETTING)) 51 break; 52 udelay(1); 53 } 54 55 if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) 56 netif_warn(priv, drv, priv->dev, 57 "TSE Rx mSGDMA resetting bit never cleared!\n"); 58 59 /* clear all status bits */ 60 csrwr32(MSGDMA_CSR_STAT_MASK, priv->rx_dma_csr, msgdma_csroffs(status)); 61 62 /* Reset Tx mSGDMA */ 63 csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr, 64 msgdma_csroffs(status)); 65 66 csrwr32(MSGDMA_CSR_CTL_RESET, priv->tx_dma_csr, 67 msgdma_csroffs(control)); 68 69 counter = 0; 70 while (counter++ < ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) { 71 if (tse_bit_is_clear(priv->tx_dma_csr, msgdma_csroffs(status), 72 MSGDMA_CSR_STAT_RESETTING)) 73 break; 74 udelay(1); 75 } 76 77 if (counter >= ALTERA_TSE_SW_RESET_WATCHDOG_CNTR) 78 netif_warn(priv, drv, priv->dev, 79 "TSE Tx mSGDMA resetting bit never cleared!\n"); 80 81 /* clear all status bits */ 82 csrwr32(MSGDMA_CSR_STAT_MASK, priv->tx_dma_csr, msgdma_csroffs(status)); 83 } 84 85 void msgdma_disable_rxirq(struct altera_tse_private *priv) 86 { 87 tse_clear_bit(priv->rx_dma_csr, msgdma_csroffs(control), 88 MSGDMA_CSR_CTL_GLOBAL_INTR); 89 } 90 91 void msgdma_enable_rxirq(struct altera_tse_private *priv) 92 { 93 tse_set_bit(priv->rx_dma_csr, msgdma_csroffs(control), 94 MSGDMA_CSR_CTL_GLOBAL_INTR); 95 } 96 97 void msgdma_disable_txirq(struct altera_tse_private *priv) 98 { 99 tse_clear_bit(priv->tx_dma_csr, msgdma_csroffs(control), 100 MSGDMA_CSR_CTL_GLOBAL_INTR); 101 } 102 103 void msgdma_enable_txirq(struct altera_tse_private *priv) 104 { 105 tse_set_bit(priv->tx_dma_csr, msgdma_csroffs(control), 106 MSGDMA_CSR_CTL_GLOBAL_INTR); 107 } 108 109 void msgdma_clear_rxirq(struct altera_tse_private *priv) 110 { 111 csrwr32(MSGDMA_CSR_STAT_IRQ, priv->rx_dma_csr, msgdma_csroffs(status)); 112 } 113 114 void msgdma_clear_txirq(struct altera_tse_private *priv) 115 { 116 csrwr32(MSGDMA_CSR_STAT_IRQ, priv->tx_dma_csr, msgdma_csroffs(status)); 117 } 118 119 /* return 0 to indicate transmit is pending */ 120 int msgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer) 121 { 122 csrwr32(lower_32_bits(buffer->dma_addr), priv->tx_dma_desc, 123 msgdma_descroffs(read_addr_lo)); 124 csrwr32(upper_32_bits(buffer->dma_addr), priv->tx_dma_desc, 125 msgdma_descroffs(read_addr_hi)); 126 csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_lo)); 127 csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(write_addr_hi)); 128 csrwr32(buffer->len, priv->tx_dma_desc, msgdma_descroffs(len)); 129 csrwr32(0, priv->tx_dma_desc, msgdma_descroffs(burst_seq_num)); 130 csrwr32(MSGDMA_DESC_TX_STRIDE, priv->tx_dma_desc, 131 msgdma_descroffs(stride)); 132 csrwr32(MSGDMA_DESC_CTL_TX_SINGLE, priv->tx_dma_desc, 133 msgdma_descroffs(control)); 134 return 0; 135 } 136 137 u32 msgdma_tx_completions(struct altera_tse_private *priv) 138 { 139 u32 ready = 0; 140 u32 inuse; 141 u32 status; 142 143 /* Get number of sent descriptors */ 144 inuse = csrrd32(priv->tx_dma_csr, msgdma_csroffs(rw_fill_level)) 145 & 0xffff; 146 147 if (inuse) { /* Tx FIFO is not empty */ 148 ready = max_t(int, 149 priv->tx_prod - priv->tx_cons - inuse - 1, 0); 150 } else { 151 /* Check for buffered last packet */ 152 status = csrrd32(priv->tx_dma_csr, msgdma_csroffs(status)); 153 if (status & MSGDMA_CSR_STAT_BUSY) 154 ready = priv->tx_prod - priv->tx_cons - 1; 155 else 156 ready = priv->tx_prod - priv->tx_cons; 157 } 158 return ready; 159 } 160 161 /* Put buffer to the mSGDMA RX FIFO 162 */ 163 void msgdma_add_rx_desc(struct altera_tse_private *priv, 164 struct tse_buffer *rxbuffer) 165 { 166 u32 len = priv->rx_dma_buf_sz; 167 dma_addr_t dma_addr = rxbuffer->dma_addr; 168 u32 control = (MSGDMA_DESC_CTL_END_ON_EOP 169 | MSGDMA_DESC_CTL_END_ON_LEN 170 | MSGDMA_DESC_CTL_TR_COMP_IRQ 171 | MSGDMA_DESC_CTL_EARLY_IRQ 172 | MSGDMA_DESC_CTL_TR_ERR_IRQ 173 | MSGDMA_DESC_CTL_GO); 174 175 csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_lo)); 176 csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(read_addr_hi)); 177 csrwr32(lower_32_bits(dma_addr), priv->rx_dma_desc, 178 msgdma_descroffs(write_addr_lo)); 179 csrwr32(upper_32_bits(dma_addr), priv->rx_dma_desc, 180 msgdma_descroffs(write_addr_hi)); 181 csrwr32(len, priv->rx_dma_desc, msgdma_descroffs(len)); 182 csrwr32(0, priv->rx_dma_desc, msgdma_descroffs(burst_seq_num)); 183 csrwr32(0x00010001, priv->rx_dma_desc, msgdma_descroffs(stride)); 184 csrwr32(control, priv->rx_dma_desc, msgdma_descroffs(control)); 185 } 186 187 /* status is returned on upper 16 bits, 188 * length is returned in lower 16 bits 189 */ 190 u32 msgdma_rx_status(struct altera_tse_private *priv) 191 { 192 u32 rxstatus = 0; 193 u32 pktlength; 194 u32 pktstatus; 195 196 if (csrrd32(priv->rx_dma_csr, msgdma_csroffs(resp_fill_level)) 197 & 0xffff) { 198 pktlength = csrrd32(priv->rx_dma_resp, 199 msgdma_respoffs(bytes_transferred)); 200 pktstatus = csrrd32(priv->rx_dma_resp, 201 msgdma_respoffs(status)); 202 rxstatus = pktstatus; 203 rxstatus = rxstatus << 16; 204 rxstatus |= (pktlength & 0xffff); 205 } 206 return rxstatus; 207 } 208