1f64f8808SVince Bridgers /* Altera TSE SGDMA and MSGDMA Linux driver 2f64f8808SVince Bridgers * Copyright (C) 2014 Altera Corporation. All rights reserved 3f64f8808SVince Bridgers * 4f64f8808SVince Bridgers * This program is free software; you can redistribute it and/or modify it 5f64f8808SVince Bridgers * under the terms and conditions of the GNU General Public License, 6f64f8808SVince Bridgers * version 2, as published by the Free Software Foundation. 7f64f8808SVince Bridgers * 8f64f8808SVince Bridgers * This program is distributed in the hope it will be useful, but WITHOUT 9f64f8808SVince Bridgers * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10f64f8808SVince Bridgers * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11f64f8808SVince Bridgers * more details. 12f64f8808SVince Bridgers * 13f64f8808SVince Bridgers * You should have received a copy of the GNU General Public License along with 14f64f8808SVince Bridgers * this program. If not, see <http://www.gnu.org/licenses/>. 15f64f8808SVince Bridgers */ 16f64f8808SVince Bridgers 17f64f8808SVince Bridgers #include <linux/list.h> 18f64f8808SVince Bridgers #include "altera_utils.h" 19f64f8808SVince Bridgers #include "altera_tse.h" 20f64f8808SVince Bridgers #include "altera_sgdmahw.h" 21f64f8808SVince Bridgers #include "altera_sgdma.h" 22f64f8808SVince Bridgers 23f64f8808SVince Bridgers static void sgdma_descrip(struct sgdma_descrip *desc, 24f64f8808SVince Bridgers struct sgdma_descrip *ndesc, 25f64f8808SVince Bridgers dma_addr_t ndesc_phys, 26f64f8808SVince Bridgers dma_addr_t raddr, 27f64f8808SVince Bridgers dma_addr_t waddr, 28f64f8808SVince Bridgers u16 length, 29f64f8808SVince Bridgers int generate_eop, 30f64f8808SVince Bridgers int rfixed, 31f64f8808SVince Bridgers int wfixed); 32f64f8808SVince Bridgers 33f64f8808SVince Bridgers static int sgdma_async_write(struct altera_tse_private *priv, 34f64f8808SVince Bridgers struct sgdma_descrip *desc); 35f64f8808SVince Bridgers 36f64f8808SVince Bridgers static int sgdma_async_read(struct altera_tse_private *priv); 37f64f8808SVince Bridgers 38f64f8808SVince Bridgers static dma_addr_t 39f64f8808SVince Bridgers sgdma_txphysaddr(struct altera_tse_private *priv, 40f64f8808SVince Bridgers struct sgdma_descrip *desc); 41f64f8808SVince Bridgers 42f64f8808SVince Bridgers static dma_addr_t 43f64f8808SVince Bridgers sgdma_rxphysaddr(struct altera_tse_private *priv, 44f64f8808SVince Bridgers struct sgdma_descrip *desc); 45f64f8808SVince Bridgers 46f64f8808SVince Bridgers static int sgdma_txbusy(struct altera_tse_private *priv); 47f64f8808SVince Bridgers 48f64f8808SVince Bridgers static int sgdma_rxbusy(struct altera_tse_private *priv); 49f64f8808SVince Bridgers 50f64f8808SVince Bridgers static void 51f64f8808SVince Bridgers queue_tx(struct altera_tse_private *priv, struct tse_buffer *buffer); 52f64f8808SVince Bridgers 53f64f8808SVince Bridgers static void 54f64f8808SVince Bridgers queue_rx(struct altera_tse_private *priv, struct tse_buffer *buffer); 55f64f8808SVince Bridgers 56f64f8808SVince Bridgers static struct tse_buffer * 57f64f8808SVince Bridgers dequeue_tx(struct altera_tse_private *priv); 58f64f8808SVince Bridgers 59f64f8808SVince Bridgers static struct tse_buffer * 60f64f8808SVince Bridgers dequeue_rx(struct altera_tse_private *priv); 61f64f8808SVince Bridgers 62f64f8808SVince Bridgers static struct tse_buffer * 63f64f8808SVince Bridgers queue_rx_peekhead(struct altera_tse_private *priv); 64f64f8808SVince Bridgers 65f64f8808SVince Bridgers int sgdma_initialize(struct altera_tse_private *priv) 66f64f8808SVince Bridgers { 67f64f8808SVince Bridgers priv->txctrlreg = SGDMA_CTRLREG_ILASTD; 68f64f8808SVince Bridgers 69f64f8808SVince Bridgers priv->rxctrlreg = SGDMA_CTRLREG_IDESCRIP | 70f64f8808SVince Bridgers SGDMA_CTRLREG_ILASTD; 71f64f8808SVince Bridgers 72f64f8808SVince Bridgers INIT_LIST_HEAD(&priv->txlisthd); 73f64f8808SVince Bridgers INIT_LIST_HEAD(&priv->rxlisthd); 74f64f8808SVince Bridgers 75f64f8808SVince Bridgers priv->rxdescphys = (dma_addr_t) 0; 76f64f8808SVince Bridgers priv->txdescphys = (dma_addr_t) 0; 77f64f8808SVince Bridgers 78f64f8808SVince Bridgers priv->rxdescphys = dma_map_single(priv->device, priv->rx_dma_desc, 79f64f8808SVince Bridgers priv->rxdescmem, DMA_BIDIRECTIONAL); 80f64f8808SVince Bridgers 81f64f8808SVince Bridgers if (dma_mapping_error(priv->device, priv->rxdescphys)) { 82f64f8808SVince Bridgers sgdma_uninitialize(priv); 83f64f8808SVince Bridgers netdev_err(priv->dev, "error mapping rx descriptor memory\n"); 84f64f8808SVince Bridgers return -EINVAL; 85f64f8808SVince Bridgers } 86f64f8808SVince Bridgers 87*80175f93SVince Bridgers priv->txdescphys = dma_map_single(priv->device, priv->tx_dma_desc, 88*80175f93SVince Bridgers priv->txdescmem, DMA_TO_DEVICE); 89f64f8808SVince Bridgers 90f64f8808SVince Bridgers if (dma_mapping_error(priv->device, priv->txdescphys)) { 91f64f8808SVince Bridgers sgdma_uninitialize(priv); 92f64f8808SVince Bridgers netdev_err(priv->dev, "error mapping tx descriptor memory\n"); 93f64f8808SVince Bridgers return -EINVAL; 94f64f8808SVince Bridgers } 95f64f8808SVince Bridgers 96f64f8808SVince Bridgers return 0; 97f64f8808SVince Bridgers } 98f64f8808SVince Bridgers 99f64f8808SVince Bridgers void sgdma_uninitialize(struct altera_tse_private *priv) 100f64f8808SVince Bridgers { 101f64f8808SVince Bridgers if (priv->rxdescphys) 102f64f8808SVince Bridgers dma_unmap_single(priv->device, priv->rxdescphys, 103f64f8808SVince Bridgers priv->rxdescmem, DMA_BIDIRECTIONAL); 104f64f8808SVince Bridgers 105f64f8808SVince Bridgers if (priv->txdescphys) 106f64f8808SVince Bridgers dma_unmap_single(priv->device, priv->txdescphys, 107f64f8808SVince Bridgers priv->txdescmem, DMA_TO_DEVICE); 108f64f8808SVince Bridgers } 109f64f8808SVince Bridgers 110f64f8808SVince Bridgers /* This function resets the SGDMA controller and clears the 111f64f8808SVince Bridgers * descriptor memory used for transmits and receives. 112f64f8808SVince Bridgers */ 113f64f8808SVince Bridgers void sgdma_reset(struct altera_tse_private *priv) 114f64f8808SVince Bridgers { 115f64f8808SVince Bridgers u32 *ptxdescripmem = (u32 *)priv->tx_dma_desc; 116f64f8808SVince Bridgers u32 txdescriplen = priv->txdescmem; 117f64f8808SVince Bridgers u32 *prxdescripmem = (u32 *)priv->rx_dma_desc; 118f64f8808SVince Bridgers u32 rxdescriplen = priv->rxdescmem; 119f64f8808SVince Bridgers struct sgdma_csr *ptxsgdma = (struct sgdma_csr *)priv->tx_dma_csr; 120f64f8808SVince Bridgers struct sgdma_csr *prxsgdma = (struct sgdma_csr *)priv->rx_dma_csr; 121f64f8808SVince Bridgers 122f64f8808SVince Bridgers /* Initialize descriptor memory to 0 */ 123f64f8808SVince Bridgers memset(ptxdescripmem, 0, txdescriplen); 124f64f8808SVince Bridgers memset(prxdescripmem, 0, rxdescriplen); 125f64f8808SVince Bridgers 126f64f8808SVince Bridgers iowrite32(SGDMA_CTRLREG_RESET, &ptxsgdma->control); 127f64f8808SVince Bridgers iowrite32(0, &ptxsgdma->control); 128f64f8808SVince Bridgers 129f64f8808SVince Bridgers iowrite32(SGDMA_CTRLREG_RESET, &prxsgdma->control); 130f64f8808SVince Bridgers iowrite32(0, &prxsgdma->control); 131f64f8808SVince Bridgers } 132f64f8808SVince Bridgers 133f64f8808SVince Bridgers void sgdma_enable_rxirq(struct altera_tse_private *priv) 134f64f8808SVince Bridgers { 135f64f8808SVince Bridgers struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; 136f64f8808SVince Bridgers priv->rxctrlreg |= SGDMA_CTRLREG_INTEN; 137f64f8808SVince Bridgers tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN); 138f64f8808SVince Bridgers } 139f64f8808SVince Bridgers 140f64f8808SVince Bridgers void sgdma_enable_txirq(struct altera_tse_private *priv) 141f64f8808SVince Bridgers { 142f64f8808SVince Bridgers struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr; 143f64f8808SVince Bridgers priv->txctrlreg |= SGDMA_CTRLREG_INTEN; 144f64f8808SVince Bridgers tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN); 145f64f8808SVince Bridgers } 146f64f8808SVince Bridgers 147f64f8808SVince Bridgers /* for SGDMA, RX interrupts remain enabled after enabling */ 148f64f8808SVince Bridgers void sgdma_disable_rxirq(struct altera_tse_private *priv) 149f64f8808SVince Bridgers { 150f64f8808SVince Bridgers } 151f64f8808SVince Bridgers 152f64f8808SVince Bridgers /* for SGDMA, TX interrupts remain enabled after enabling */ 153f64f8808SVince Bridgers void sgdma_disable_txirq(struct altera_tse_private *priv) 154f64f8808SVince Bridgers { 155f64f8808SVince Bridgers } 156f64f8808SVince Bridgers 157f64f8808SVince Bridgers void sgdma_clear_rxirq(struct altera_tse_private *priv) 158f64f8808SVince Bridgers { 159f64f8808SVince Bridgers struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; 160f64f8808SVince Bridgers tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT); 161f64f8808SVince Bridgers } 162f64f8808SVince Bridgers 163f64f8808SVince Bridgers void sgdma_clear_txirq(struct altera_tse_private *priv) 164f64f8808SVince Bridgers { 165f64f8808SVince Bridgers struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr; 166f64f8808SVince Bridgers tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT); 167f64f8808SVince Bridgers } 168f64f8808SVince Bridgers 169f64f8808SVince Bridgers /* transmits buffer through SGDMA. Returns number of buffers 170f64f8808SVince Bridgers * transmitted, 0 if not possible. 171f64f8808SVince Bridgers * 172f64f8808SVince Bridgers * tx_lock is held by the caller 173f64f8808SVince Bridgers */ 174f64f8808SVince Bridgers int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer) 175f64f8808SVince Bridgers { 176f64f8808SVince Bridgers int pktstx = 0; 177f64f8808SVince Bridgers struct sgdma_descrip *descbase = 178f64f8808SVince Bridgers (struct sgdma_descrip *)priv->tx_dma_desc; 179f64f8808SVince Bridgers 180f64f8808SVince Bridgers struct sgdma_descrip *cdesc = &descbase[0]; 181f64f8808SVince Bridgers struct sgdma_descrip *ndesc = &descbase[1]; 182f64f8808SVince Bridgers 183f64f8808SVince Bridgers /* wait 'til the tx sgdma is ready for the next transmit request */ 184f64f8808SVince Bridgers if (sgdma_txbusy(priv)) 185f64f8808SVince Bridgers return 0; 186f64f8808SVince Bridgers 187f64f8808SVince Bridgers sgdma_descrip(cdesc, /* current descriptor */ 188f64f8808SVince Bridgers ndesc, /* next descriptor */ 189f64f8808SVince Bridgers sgdma_txphysaddr(priv, ndesc), 190f64f8808SVince Bridgers buffer->dma_addr, /* address of packet to xmit */ 191f64f8808SVince Bridgers 0, /* write addr 0 for tx dma */ 192f64f8808SVince Bridgers buffer->len, /* length of packet */ 193f64f8808SVince Bridgers SGDMA_CONTROL_EOP, /* Generate EOP */ 194f64f8808SVince Bridgers 0, /* read fixed */ 195f64f8808SVince Bridgers SGDMA_CONTROL_WR_FIXED); /* Generate SOP */ 196f64f8808SVince Bridgers 197f64f8808SVince Bridgers pktstx = sgdma_async_write(priv, cdesc); 198f64f8808SVince Bridgers 199f64f8808SVince Bridgers /* enqueue the request to the pending transmit queue */ 200f64f8808SVince Bridgers queue_tx(priv, buffer); 201f64f8808SVince Bridgers 202f64f8808SVince Bridgers return 1; 203f64f8808SVince Bridgers } 204f64f8808SVince Bridgers 205f64f8808SVince Bridgers 206f64f8808SVince Bridgers /* tx_lock held to protect access to queued tx list 207f64f8808SVince Bridgers */ 208f64f8808SVince Bridgers u32 sgdma_tx_completions(struct altera_tse_private *priv) 209f64f8808SVince Bridgers { 210f64f8808SVince Bridgers u32 ready = 0; 211f64f8808SVince Bridgers struct sgdma_descrip *desc = (struct sgdma_descrip *)priv->tx_dma_desc; 212f64f8808SVince Bridgers 213f64f8808SVince Bridgers if (!sgdma_txbusy(priv) && 214f64f8808SVince Bridgers ((desc->control & SGDMA_CONTROL_HW_OWNED) == 0) && 215f64f8808SVince Bridgers (dequeue_tx(priv))) { 216f64f8808SVince Bridgers ready = 1; 217f64f8808SVince Bridgers } 218f64f8808SVince Bridgers 219f64f8808SVince Bridgers return ready; 220f64f8808SVince Bridgers } 221f64f8808SVince Bridgers 222f64f8808SVince Bridgers int sgdma_add_rx_desc(struct altera_tse_private *priv, 223f64f8808SVince Bridgers struct tse_buffer *rxbuffer) 224f64f8808SVince Bridgers { 225f64f8808SVince Bridgers queue_rx(priv, rxbuffer); 226f64f8808SVince Bridgers return sgdma_async_read(priv); 227f64f8808SVince Bridgers } 228f64f8808SVince Bridgers 229f64f8808SVince Bridgers /* status is returned on upper 16 bits, 230f64f8808SVince Bridgers * length is returned in lower 16 bits 231f64f8808SVince Bridgers */ 232f64f8808SVince Bridgers u32 sgdma_rx_status(struct altera_tse_private *priv) 233f64f8808SVince Bridgers { 234f64f8808SVince Bridgers struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; 235f64f8808SVince Bridgers struct sgdma_descrip *base = (struct sgdma_descrip *)priv->rx_dma_desc; 236f64f8808SVince Bridgers struct sgdma_descrip *desc = NULL; 237f64f8808SVince Bridgers int pktsrx; 238f64f8808SVince Bridgers unsigned int rxstatus = 0; 239f64f8808SVince Bridgers unsigned int pktlength = 0; 240f64f8808SVince Bridgers unsigned int pktstatus = 0; 241f64f8808SVince Bridgers struct tse_buffer *rxbuffer = NULL; 242f64f8808SVince Bridgers 243f64f8808SVince Bridgers dma_sync_single_for_cpu(priv->device, 244f64f8808SVince Bridgers priv->rxdescphys, 245f64f8808SVince Bridgers priv->rxdescmem, 246f64f8808SVince Bridgers DMA_BIDIRECTIONAL); 247f64f8808SVince Bridgers 248f64f8808SVince Bridgers desc = &base[0]; 249f64f8808SVince Bridgers if ((ioread32(&csr->status) & SGDMA_STSREG_EOP) || 250f64f8808SVince Bridgers (desc->status & SGDMA_STATUS_EOP)) { 251f64f8808SVince Bridgers pktlength = desc->bytes_xferred; 252f64f8808SVince Bridgers pktstatus = desc->status & 0x3f; 253f64f8808SVince Bridgers rxstatus = pktstatus; 254f64f8808SVince Bridgers rxstatus = rxstatus << 16; 255f64f8808SVince Bridgers rxstatus |= (pktlength & 0xffff); 256f64f8808SVince Bridgers 257f64f8808SVince Bridgers desc->status = 0; 258f64f8808SVince Bridgers 259f64f8808SVince Bridgers rxbuffer = dequeue_rx(priv); 260f64f8808SVince Bridgers if (rxbuffer == NULL) 261f64f8808SVince Bridgers netdev_err(priv->dev, 262f64f8808SVince Bridgers "sgdma rx and rx queue empty!\n"); 263f64f8808SVince Bridgers 264f64f8808SVince Bridgers /* kick the rx sgdma after reaping this descriptor */ 265f64f8808SVince Bridgers pktsrx = sgdma_async_read(priv); 266f64f8808SVince Bridgers } 267f64f8808SVince Bridgers 268f64f8808SVince Bridgers return rxstatus; 269f64f8808SVince Bridgers } 270f64f8808SVince Bridgers 271f64f8808SVince Bridgers 272f64f8808SVince Bridgers /* Private functions */ 273f64f8808SVince Bridgers static void sgdma_descrip(struct sgdma_descrip *desc, 274f64f8808SVince Bridgers struct sgdma_descrip *ndesc, 275f64f8808SVince Bridgers dma_addr_t ndesc_phys, 276f64f8808SVince Bridgers dma_addr_t raddr, 277f64f8808SVince Bridgers dma_addr_t waddr, 278f64f8808SVince Bridgers u16 length, 279f64f8808SVince Bridgers int generate_eop, 280f64f8808SVince Bridgers int rfixed, 281f64f8808SVince Bridgers int wfixed) 282f64f8808SVince Bridgers { 283f64f8808SVince Bridgers /* Clear the next descriptor as not owned by hardware */ 284f64f8808SVince Bridgers u32 ctrl = ndesc->control; 285f64f8808SVince Bridgers ctrl &= ~SGDMA_CONTROL_HW_OWNED; 286f64f8808SVince Bridgers ndesc->control = ctrl; 287f64f8808SVince Bridgers 288f64f8808SVince Bridgers ctrl = 0; 289f64f8808SVince Bridgers ctrl = SGDMA_CONTROL_HW_OWNED; 290f64f8808SVince Bridgers ctrl |= generate_eop; 291f64f8808SVince Bridgers ctrl |= rfixed; 292f64f8808SVince Bridgers ctrl |= wfixed; 293f64f8808SVince Bridgers 294f64f8808SVince Bridgers /* Channel is implicitly zero, initialized to 0 by default */ 295f64f8808SVince Bridgers 296f64f8808SVince Bridgers desc->raddr = raddr; 297f64f8808SVince Bridgers desc->waddr = waddr; 298f64f8808SVince Bridgers desc->next = lower_32_bits(ndesc_phys); 299f64f8808SVince Bridgers desc->control = ctrl; 300f64f8808SVince Bridgers desc->status = 0; 301f64f8808SVince Bridgers desc->rburst = 0; 302f64f8808SVince Bridgers desc->wburst = 0; 303f64f8808SVince Bridgers desc->bytes = length; 304f64f8808SVince Bridgers desc->bytes_xferred = 0; 305f64f8808SVince Bridgers } 306f64f8808SVince Bridgers 307f64f8808SVince Bridgers /* If hardware is busy, don't restart async read. 308f64f8808SVince Bridgers * if status register is 0 - meaning initial state, restart async read, 309f64f8808SVince Bridgers * probably for the first time when populating a receive buffer. 310f64f8808SVince Bridgers * If read status indicate not busy and a status, restart the async 311f64f8808SVince Bridgers * DMA read. 312f64f8808SVince Bridgers */ 313f64f8808SVince Bridgers static int sgdma_async_read(struct altera_tse_private *priv) 314f64f8808SVince Bridgers { 315f64f8808SVince Bridgers struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; 316f64f8808SVince Bridgers struct sgdma_descrip *descbase = 317f64f8808SVince Bridgers (struct sgdma_descrip *)priv->rx_dma_desc; 318f64f8808SVince Bridgers 319f64f8808SVince Bridgers struct sgdma_descrip *cdesc = &descbase[0]; 320f64f8808SVince Bridgers struct sgdma_descrip *ndesc = &descbase[1]; 321f64f8808SVince Bridgers 322f64f8808SVince Bridgers unsigned int sts = ioread32(&csr->status); 323f64f8808SVince Bridgers struct tse_buffer *rxbuffer = NULL; 324f64f8808SVince Bridgers 325f64f8808SVince Bridgers if (!sgdma_rxbusy(priv)) { 326f64f8808SVince Bridgers rxbuffer = queue_rx_peekhead(priv); 327f64f8808SVince Bridgers if (rxbuffer == NULL) 328f64f8808SVince Bridgers return 0; 329f64f8808SVince Bridgers 330f64f8808SVince Bridgers sgdma_descrip(cdesc, /* current descriptor */ 331f64f8808SVince Bridgers ndesc, /* next descriptor */ 332f64f8808SVince Bridgers sgdma_rxphysaddr(priv, ndesc), 333f64f8808SVince Bridgers 0, /* read addr 0 for rx dma */ 334f64f8808SVince Bridgers rxbuffer->dma_addr, /* write addr for rx dma */ 335f64f8808SVince Bridgers 0, /* read 'til EOP */ 336f64f8808SVince Bridgers 0, /* EOP: NA for rx dma */ 337f64f8808SVince Bridgers 0, /* read fixed: NA for rx dma */ 338f64f8808SVince Bridgers 0); /* SOP: NA for rx DMA */ 339f64f8808SVince Bridgers 340f64f8808SVince Bridgers /* clear control and status */ 341f64f8808SVince Bridgers iowrite32(0, &csr->control); 342f64f8808SVince Bridgers 343*80175f93SVince Bridgers /* If status available, clear those bits */ 344f64f8808SVince Bridgers if (sts & 0xf) 345f64f8808SVince Bridgers iowrite32(0xf, &csr->status); 346f64f8808SVince Bridgers 347f64f8808SVince Bridgers dma_sync_single_for_device(priv->device, 348f64f8808SVince Bridgers priv->rxdescphys, 349f64f8808SVince Bridgers priv->rxdescmem, 350f64f8808SVince Bridgers DMA_BIDIRECTIONAL); 351f64f8808SVince Bridgers 352f64f8808SVince Bridgers iowrite32(lower_32_bits(sgdma_rxphysaddr(priv, cdesc)), 353f64f8808SVince Bridgers &csr->next_descrip); 354f64f8808SVince Bridgers 355f64f8808SVince Bridgers iowrite32((priv->rxctrlreg | SGDMA_CTRLREG_START), 356f64f8808SVince Bridgers &csr->control); 357f64f8808SVince Bridgers 358f64f8808SVince Bridgers return 1; 359f64f8808SVince Bridgers } 360f64f8808SVince Bridgers 361f64f8808SVince Bridgers return 0; 362f64f8808SVince Bridgers } 363f64f8808SVince Bridgers 364f64f8808SVince Bridgers static int sgdma_async_write(struct altera_tse_private *priv, 365f64f8808SVince Bridgers struct sgdma_descrip *desc) 366f64f8808SVince Bridgers { 367f64f8808SVince Bridgers struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr; 368f64f8808SVince Bridgers 369f64f8808SVince Bridgers if (sgdma_txbusy(priv)) 370f64f8808SVince Bridgers return 0; 371f64f8808SVince Bridgers 372f64f8808SVince Bridgers /* clear control and status */ 373f64f8808SVince Bridgers iowrite32(0, &csr->control); 374f64f8808SVince Bridgers iowrite32(0x1f, &csr->status); 375f64f8808SVince Bridgers 376f64f8808SVince Bridgers dma_sync_single_for_device(priv->device, priv->txdescphys, 377f64f8808SVince Bridgers priv->txdescmem, DMA_TO_DEVICE); 378f64f8808SVince Bridgers 379f64f8808SVince Bridgers iowrite32(lower_32_bits(sgdma_txphysaddr(priv, desc)), 380f64f8808SVince Bridgers &csr->next_descrip); 381f64f8808SVince Bridgers 382f64f8808SVince Bridgers iowrite32((priv->txctrlreg | SGDMA_CTRLREG_START), 383f64f8808SVince Bridgers &csr->control); 384f64f8808SVince Bridgers 385f64f8808SVince Bridgers return 1; 386f64f8808SVince Bridgers } 387f64f8808SVince Bridgers 388f64f8808SVince Bridgers static dma_addr_t 389f64f8808SVince Bridgers sgdma_txphysaddr(struct altera_tse_private *priv, 390f64f8808SVince Bridgers struct sgdma_descrip *desc) 391f64f8808SVince Bridgers { 392f64f8808SVince Bridgers dma_addr_t paddr = priv->txdescmem_busaddr; 393a804ad0eSVince Bridgers uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->tx_dma_desc; 394a804ad0eSVince Bridgers return (dma_addr_t)((uintptr_t)paddr + offs); 395f64f8808SVince Bridgers } 396f64f8808SVince Bridgers 397f64f8808SVince Bridgers static dma_addr_t 398f64f8808SVince Bridgers sgdma_rxphysaddr(struct altera_tse_private *priv, 399f64f8808SVince Bridgers struct sgdma_descrip *desc) 400f64f8808SVince Bridgers { 401f64f8808SVince Bridgers dma_addr_t paddr = priv->rxdescmem_busaddr; 402a804ad0eSVince Bridgers uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->rx_dma_desc; 403a804ad0eSVince Bridgers return (dma_addr_t)((uintptr_t)paddr + offs); 404f64f8808SVince Bridgers } 405f64f8808SVince Bridgers 406f64f8808SVince Bridgers #define list_remove_head(list, entry, type, member) \ 407f64f8808SVince Bridgers do { \ 408f64f8808SVince Bridgers entry = NULL; \ 409f64f8808SVince Bridgers if (!list_empty(list)) { \ 410f64f8808SVince Bridgers entry = list_entry((list)->next, type, member); \ 411f64f8808SVince Bridgers list_del_init(&entry->member); \ 412f64f8808SVince Bridgers } \ 413f64f8808SVince Bridgers } while (0) 414f64f8808SVince Bridgers 415f64f8808SVince Bridgers #define list_peek_head(list, entry, type, member) \ 416f64f8808SVince Bridgers do { \ 417f64f8808SVince Bridgers entry = NULL; \ 418f64f8808SVince Bridgers if (!list_empty(list)) { \ 419f64f8808SVince Bridgers entry = list_entry((list)->next, type, member); \ 420f64f8808SVince Bridgers } \ 421f64f8808SVince Bridgers } while (0) 422f64f8808SVince Bridgers 423f64f8808SVince Bridgers /* adds a tse_buffer to the tail of a tx buffer list. 424f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 425f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list. 426f64f8808SVince Bridgers */ 427f64f8808SVince Bridgers static void 428f64f8808SVince Bridgers queue_tx(struct altera_tse_private *priv, struct tse_buffer *buffer) 429f64f8808SVince Bridgers { 430f64f8808SVince Bridgers list_add_tail(&buffer->lh, &priv->txlisthd); 431f64f8808SVince Bridgers } 432f64f8808SVince Bridgers 433f64f8808SVince Bridgers 434f64f8808SVince Bridgers /* adds a tse_buffer to the tail of a rx buffer list 435f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 436f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list. 437f64f8808SVince Bridgers */ 438f64f8808SVince Bridgers static void 439f64f8808SVince Bridgers queue_rx(struct altera_tse_private *priv, struct tse_buffer *buffer) 440f64f8808SVince Bridgers { 441f64f8808SVince Bridgers list_add_tail(&buffer->lh, &priv->rxlisthd); 442f64f8808SVince Bridgers } 443f64f8808SVince Bridgers 444f64f8808SVince Bridgers /* dequeues a tse_buffer from the transmit buffer list, otherwise 445f64f8808SVince Bridgers * returns NULL if empty. 446f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 447f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list. 448f64f8808SVince Bridgers */ 449f64f8808SVince Bridgers static struct tse_buffer * 450f64f8808SVince Bridgers dequeue_tx(struct altera_tse_private *priv) 451f64f8808SVince Bridgers { 452f64f8808SVince Bridgers struct tse_buffer *buffer = NULL; 453f64f8808SVince Bridgers list_remove_head(&priv->txlisthd, buffer, struct tse_buffer, lh); 454f64f8808SVince Bridgers return buffer; 455f64f8808SVince Bridgers } 456f64f8808SVince Bridgers 457f64f8808SVince Bridgers /* dequeues a tse_buffer from the receive buffer list, otherwise 458f64f8808SVince Bridgers * returns NULL if empty 459f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 460f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list. 461f64f8808SVince Bridgers */ 462f64f8808SVince Bridgers static struct tse_buffer * 463f64f8808SVince Bridgers dequeue_rx(struct altera_tse_private *priv) 464f64f8808SVince Bridgers { 465f64f8808SVince Bridgers struct tse_buffer *buffer = NULL; 466f64f8808SVince Bridgers list_remove_head(&priv->rxlisthd, buffer, struct tse_buffer, lh); 467f64f8808SVince Bridgers return buffer; 468f64f8808SVince Bridgers } 469f64f8808SVince Bridgers 470f64f8808SVince Bridgers /* dequeues a tse_buffer from the receive buffer list, otherwise 471f64f8808SVince Bridgers * returns NULL if empty 472f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 473f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list while the 474f64f8808SVince Bridgers * head is being examined. 475f64f8808SVince Bridgers */ 476f64f8808SVince Bridgers static struct tse_buffer * 477f64f8808SVince Bridgers queue_rx_peekhead(struct altera_tse_private *priv) 478f64f8808SVince Bridgers { 479f64f8808SVince Bridgers struct tse_buffer *buffer = NULL; 480f64f8808SVince Bridgers list_peek_head(&priv->rxlisthd, buffer, struct tse_buffer, lh); 481f64f8808SVince Bridgers return buffer; 482f64f8808SVince Bridgers } 483f64f8808SVince Bridgers 484f64f8808SVince Bridgers /* check and return rx sgdma status without polling 485f64f8808SVince Bridgers */ 486f64f8808SVince Bridgers static int sgdma_rxbusy(struct altera_tse_private *priv) 487f64f8808SVince Bridgers { 488f64f8808SVince Bridgers struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; 489f64f8808SVince Bridgers return ioread32(&csr->status) & SGDMA_STSREG_BUSY; 490f64f8808SVince Bridgers } 491f64f8808SVince Bridgers 492f64f8808SVince Bridgers /* waits for the tx sgdma to finish it's current operation, returns 0 493f64f8808SVince Bridgers * when it transitions to nonbusy, returns 1 if the operation times out 494f64f8808SVince Bridgers */ 495f64f8808SVince Bridgers static int sgdma_txbusy(struct altera_tse_private *priv) 496f64f8808SVince Bridgers { 497f64f8808SVince Bridgers int delay = 0; 498f64f8808SVince Bridgers struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr; 499f64f8808SVince Bridgers 500f64f8808SVince Bridgers /* if DMA is busy, wait for current transactino to finish */ 501f64f8808SVince Bridgers while ((ioread32(&csr->status) & SGDMA_STSREG_BUSY) && (delay++ < 100)) 502f64f8808SVince Bridgers udelay(1); 503f64f8808SVince Bridgers 504f64f8808SVince Bridgers if (ioread32(&csr->status) & SGDMA_STSREG_BUSY) { 505f64f8808SVince Bridgers netdev_err(priv->dev, "timeout waiting for tx dma\n"); 506f64f8808SVince Bridgers return 1; 507f64f8808SVince Bridgers } 508f64f8808SVince Bridgers return 0; 509f64f8808SVince Bridgers } 510