19952f691SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 2f64f8808SVince Bridgers /* Altera TSE SGDMA and MSGDMA Linux driver 3f64f8808SVince Bridgers * Copyright (C) 2014 Altera Corporation. All rights reserved 4f64f8808SVince Bridgers */ 5f64f8808SVince Bridgers 6f64f8808SVince Bridgers #include <linux/list.h> 7f64f8808SVince Bridgers #include "altera_utils.h" 8f64f8808SVince Bridgers #include "altera_tse.h" 9f64f8808SVince Bridgers #include "altera_sgdmahw.h" 10f64f8808SVince Bridgers #include "altera_sgdma.h" 11f64f8808SVince Bridgers 1289830580SVince Bridgers static void sgdma_setup_descrip(struct sgdma_descrip __iomem *desc, 1389830580SVince Bridgers struct sgdma_descrip __iomem *ndesc, 14f64f8808SVince Bridgers dma_addr_t ndesc_phys, 15f64f8808SVince Bridgers dma_addr_t raddr, 16f64f8808SVince Bridgers dma_addr_t waddr, 17f64f8808SVince Bridgers u16 length, 18f64f8808SVince Bridgers int generate_eop, 19f64f8808SVince Bridgers int rfixed, 20f64f8808SVince Bridgers int wfixed); 21f64f8808SVince Bridgers 22f64f8808SVince Bridgers static int sgdma_async_write(struct altera_tse_private *priv, 2389830580SVince Bridgers struct sgdma_descrip __iomem *desc); 24f64f8808SVince Bridgers 25f64f8808SVince Bridgers static int sgdma_async_read(struct altera_tse_private *priv); 26f64f8808SVince Bridgers 27f64f8808SVince Bridgers static dma_addr_t 28f64f8808SVince Bridgers sgdma_txphysaddr(struct altera_tse_private *priv, 2989830580SVince Bridgers struct sgdma_descrip __iomem *desc); 30f64f8808SVince Bridgers 31f64f8808SVince Bridgers static dma_addr_t 32f64f8808SVince Bridgers sgdma_rxphysaddr(struct altera_tse_private *priv, 3389830580SVince Bridgers struct sgdma_descrip __iomem *desc); 34f64f8808SVince Bridgers 35f64f8808SVince Bridgers static int sgdma_txbusy(struct altera_tse_private *priv); 36f64f8808SVince Bridgers 37f64f8808SVince Bridgers static int sgdma_rxbusy(struct altera_tse_private *priv); 38f64f8808SVince Bridgers 39f64f8808SVince Bridgers static void 40f64f8808SVince Bridgers queue_tx(struct altera_tse_private *priv, struct tse_buffer *buffer); 41f64f8808SVince Bridgers 42f64f8808SVince Bridgers static void 43f64f8808SVince Bridgers queue_rx(struct altera_tse_private *priv, struct tse_buffer *buffer); 44f64f8808SVince Bridgers 45f64f8808SVince Bridgers static struct tse_buffer * 46f64f8808SVince Bridgers dequeue_tx(struct altera_tse_private *priv); 47f64f8808SVince Bridgers 48f64f8808SVince Bridgers static struct tse_buffer * 49f64f8808SVince Bridgers dequeue_rx(struct altera_tse_private *priv); 50f64f8808SVince Bridgers 51f64f8808SVince Bridgers static struct tse_buffer * 52f64f8808SVince Bridgers queue_rx_peekhead(struct altera_tse_private *priv); 53f64f8808SVince Bridgers 54f64f8808SVince Bridgers int sgdma_initialize(struct altera_tse_private *priv) 55f64f8808SVince Bridgers { 5637c0ffaaSVince Bridgers priv->txctrlreg = SGDMA_CTRLREG_ILASTD | 5737c0ffaaSVince Bridgers SGDMA_CTRLREG_INTEN; 58f64f8808SVince Bridgers 59f64f8808SVince Bridgers priv->rxctrlreg = SGDMA_CTRLREG_IDESCRIP | 6037c0ffaaSVince Bridgers SGDMA_CTRLREG_INTEN | 61f64f8808SVince Bridgers SGDMA_CTRLREG_ILASTD; 62f64f8808SVince Bridgers 63f64f8808SVince Bridgers INIT_LIST_HEAD(&priv->txlisthd); 64f64f8808SVince Bridgers INIT_LIST_HEAD(&priv->rxlisthd); 65f64f8808SVince Bridgers 66f64f8808SVince Bridgers priv->rxdescphys = (dma_addr_t) 0; 67f64f8808SVince Bridgers priv->txdescphys = (dma_addr_t) 0; 68f64f8808SVince Bridgers 6989830580SVince Bridgers priv->rxdescphys = dma_map_single(priv->device, 7089830580SVince Bridgers (void __force *)priv->rx_dma_desc, 71f64f8808SVince Bridgers priv->rxdescmem, DMA_BIDIRECTIONAL); 72f64f8808SVince Bridgers 73f64f8808SVince Bridgers if (dma_mapping_error(priv->device, priv->rxdescphys)) { 74f64f8808SVince Bridgers sgdma_uninitialize(priv); 75f64f8808SVince Bridgers netdev_err(priv->dev, "error mapping rx descriptor memory\n"); 76f64f8808SVince Bridgers return -EINVAL; 77f64f8808SVince Bridgers } 78f64f8808SVince Bridgers 7989830580SVince Bridgers priv->txdescphys = dma_map_single(priv->device, 8089830580SVince Bridgers (void __force *)priv->tx_dma_desc, 8180175f93SVince Bridgers priv->txdescmem, DMA_TO_DEVICE); 82f64f8808SVince Bridgers 83f64f8808SVince Bridgers if (dma_mapping_error(priv->device, priv->txdescphys)) { 84f64f8808SVince Bridgers sgdma_uninitialize(priv); 85f64f8808SVince Bridgers netdev_err(priv->dev, "error mapping tx descriptor memory\n"); 86f64f8808SVince Bridgers return -EINVAL; 87f64f8808SVince Bridgers } 88f64f8808SVince Bridgers 8937c0ffaaSVince Bridgers /* Initialize descriptor memory to all 0's, sync memory to cache */ 9089830580SVince Bridgers memset_io(priv->tx_dma_desc, 0, priv->txdescmem); 9189830580SVince Bridgers memset_io(priv->rx_dma_desc, 0, priv->rxdescmem); 9237c0ffaaSVince Bridgers 9337c0ffaaSVince Bridgers dma_sync_single_for_device(priv->device, priv->txdescphys, 9437c0ffaaSVince Bridgers priv->txdescmem, DMA_TO_DEVICE); 9537c0ffaaSVince Bridgers 9637c0ffaaSVince Bridgers dma_sync_single_for_device(priv->device, priv->rxdescphys, 9737c0ffaaSVince Bridgers priv->rxdescmem, DMA_TO_DEVICE); 9837c0ffaaSVince Bridgers 99f64f8808SVince Bridgers return 0; 100f64f8808SVince Bridgers } 101f64f8808SVince Bridgers 102f64f8808SVince Bridgers void sgdma_uninitialize(struct altera_tse_private *priv) 103f64f8808SVince Bridgers { 104f64f8808SVince Bridgers if (priv->rxdescphys) 105f64f8808SVince Bridgers dma_unmap_single(priv->device, priv->rxdescphys, 106f64f8808SVince Bridgers priv->rxdescmem, DMA_BIDIRECTIONAL); 107f64f8808SVince Bridgers 108f64f8808SVince Bridgers if (priv->txdescphys) 109f64f8808SVince Bridgers dma_unmap_single(priv->device, priv->txdescphys, 110f64f8808SVince Bridgers priv->txdescmem, DMA_TO_DEVICE); 111f64f8808SVince Bridgers } 112f64f8808SVince Bridgers 113f64f8808SVince Bridgers /* This function resets the SGDMA controller and clears the 114f64f8808SVince Bridgers * descriptor memory used for transmits and receives. 115f64f8808SVince Bridgers */ 116f64f8808SVince Bridgers void sgdma_reset(struct altera_tse_private *priv) 117f64f8808SVince Bridgers { 118f64f8808SVince Bridgers /* Initialize descriptor memory to 0 */ 11989830580SVince Bridgers memset_io(priv->tx_dma_desc, 0, priv->txdescmem); 12089830580SVince Bridgers memset_io(priv->rx_dma_desc, 0, priv->rxdescmem); 121f64f8808SVince Bridgers 12289830580SVince Bridgers csrwr32(SGDMA_CTRLREG_RESET, priv->tx_dma_csr, sgdma_csroffs(control)); 12389830580SVince Bridgers csrwr32(0, priv->tx_dma_csr, sgdma_csroffs(control)); 124f64f8808SVince Bridgers 12589830580SVince Bridgers csrwr32(SGDMA_CTRLREG_RESET, priv->rx_dma_csr, sgdma_csroffs(control)); 12689830580SVince Bridgers csrwr32(0, priv->rx_dma_csr, sgdma_csroffs(control)); 127f64f8808SVince Bridgers } 128f64f8808SVince Bridgers 12937c0ffaaSVince Bridgers /* For SGDMA, interrupts remain enabled after initially enabling, 13037c0ffaaSVince Bridgers * so no need to provide implementations for abstract enable 13137c0ffaaSVince Bridgers * and disable 13237c0ffaaSVince Bridgers */ 13337c0ffaaSVince Bridgers 134f64f8808SVince Bridgers void sgdma_enable_rxirq(struct altera_tse_private *priv) 135f64f8808SVince Bridgers { 136f64f8808SVince Bridgers } 137f64f8808SVince Bridgers 138f64f8808SVince Bridgers void sgdma_enable_txirq(struct altera_tse_private *priv) 139f64f8808SVince Bridgers { 140f64f8808SVince Bridgers } 141f64f8808SVince Bridgers 142f64f8808SVince Bridgers void sgdma_disable_rxirq(struct altera_tse_private *priv) 143f64f8808SVince Bridgers { 144f64f8808SVince Bridgers } 145f64f8808SVince Bridgers 146f64f8808SVince Bridgers void sgdma_disable_txirq(struct altera_tse_private *priv) 147f64f8808SVince Bridgers { 148f64f8808SVince Bridgers } 149f64f8808SVince Bridgers 150f64f8808SVince Bridgers void sgdma_clear_rxirq(struct altera_tse_private *priv) 151f64f8808SVince Bridgers { 15289830580SVince Bridgers tse_set_bit(priv->rx_dma_csr, sgdma_csroffs(control), 15389830580SVince Bridgers SGDMA_CTRLREG_CLRINT); 154f64f8808SVince Bridgers } 155f64f8808SVince Bridgers 156f64f8808SVince Bridgers void sgdma_clear_txirq(struct altera_tse_private *priv) 157f64f8808SVince Bridgers { 15889830580SVince Bridgers tse_set_bit(priv->tx_dma_csr, sgdma_csroffs(control), 15989830580SVince Bridgers SGDMA_CTRLREG_CLRINT); 160f64f8808SVince Bridgers } 161f64f8808SVince Bridgers 162f64f8808SVince Bridgers /* transmits buffer through SGDMA. Returns number of buffers 163f64f8808SVince Bridgers * transmitted, 0 if not possible. 164f64f8808SVince Bridgers * 165f64f8808SVince Bridgers * tx_lock is held by the caller 166f64f8808SVince Bridgers */ 167f64f8808SVince Bridgers int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer) 168f64f8808SVince Bridgers { 16989830580SVince Bridgers struct sgdma_descrip __iomem *descbase = 17089830580SVince Bridgers (struct sgdma_descrip __iomem *)priv->tx_dma_desc; 171f64f8808SVince Bridgers 17289830580SVince Bridgers struct sgdma_descrip __iomem *cdesc = &descbase[0]; 17389830580SVince Bridgers struct sgdma_descrip __iomem *ndesc = &descbase[1]; 174f64f8808SVince Bridgers 175f64f8808SVince Bridgers /* wait 'til the tx sgdma is ready for the next transmit request */ 176f64f8808SVince Bridgers if (sgdma_txbusy(priv)) 177f64f8808SVince Bridgers return 0; 178f64f8808SVince Bridgers 1791b444881STobias Klauser sgdma_setup_descrip(cdesc, /* current descriptor */ 180f64f8808SVince Bridgers ndesc, /* next descriptor */ 181f64f8808SVince Bridgers sgdma_txphysaddr(priv, ndesc), 182f64f8808SVince Bridgers buffer->dma_addr, /* address of packet to xmit */ 183f64f8808SVince Bridgers 0, /* write addr 0 for tx dma */ 184f64f8808SVince Bridgers buffer->len, /* length of packet */ 185f64f8808SVince Bridgers SGDMA_CONTROL_EOP, /* Generate EOP */ 186f64f8808SVince Bridgers 0, /* read fixed */ 187f64f8808SVince Bridgers SGDMA_CONTROL_WR_FIXED); /* Generate SOP */ 188f64f8808SVince Bridgers 18989830580SVince Bridgers sgdma_async_write(priv, cdesc); 190f64f8808SVince Bridgers 191f64f8808SVince Bridgers /* enqueue the request to the pending transmit queue */ 192f64f8808SVince Bridgers queue_tx(priv, buffer); 193f64f8808SVince Bridgers 194f64f8808SVince Bridgers return 1; 195f64f8808SVince Bridgers } 196f64f8808SVince Bridgers 197f64f8808SVince Bridgers 198f64f8808SVince Bridgers /* tx_lock held to protect access to queued tx list 199f64f8808SVince Bridgers */ 200f64f8808SVince Bridgers u32 sgdma_tx_completions(struct altera_tse_private *priv) 201f64f8808SVince Bridgers { 202f64f8808SVince Bridgers u32 ready = 0; 203f64f8808SVince Bridgers 204f64f8808SVince Bridgers if (!sgdma_txbusy(priv) && 20589830580SVince Bridgers ((csrrd8(priv->tx_dma_desc, sgdma_descroffs(control)) 20689830580SVince Bridgers & SGDMA_CONTROL_HW_OWNED) == 0) && 207f64f8808SVince Bridgers (dequeue_tx(priv))) { 208f64f8808SVince Bridgers ready = 1; 209f64f8808SVince Bridgers } 210f64f8808SVince Bridgers 211f64f8808SVince Bridgers return ready; 212f64f8808SVince Bridgers } 213f64f8808SVince Bridgers 21437c0ffaaSVince Bridgers void sgdma_start_rxdma(struct altera_tse_private *priv) 21537c0ffaaSVince Bridgers { 21637c0ffaaSVince Bridgers sgdma_async_read(priv); 21737c0ffaaSVince Bridgers } 21837c0ffaaSVince Bridgers 21937c0ffaaSVince Bridgers void sgdma_add_rx_desc(struct altera_tse_private *priv, 220f64f8808SVince Bridgers struct tse_buffer *rxbuffer) 221f64f8808SVince Bridgers { 222f64f8808SVince Bridgers queue_rx(priv, rxbuffer); 223f64f8808SVince Bridgers } 224f64f8808SVince Bridgers 225f64f8808SVince Bridgers /* status is returned on upper 16 bits, 226f64f8808SVince Bridgers * length is returned in lower 16 bits 227f64f8808SVince Bridgers */ 228f64f8808SVince Bridgers u32 sgdma_rx_status(struct altera_tse_private *priv) 229f64f8808SVince Bridgers { 23089830580SVince Bridgers struct sgdma_descrip __iomem *base = 23189830580SVince Bridgers (struct sgdma_descrip __iomem *)priv->rx_dma_desc; 23289830580SVince Bridgers struct sgdma_descrip __iomem *desc = NULL; 233f64f8808SVince Bridgers struct tse_buffer *rxbuffer = NULL; 23489830580SVince Bridgers unsigned int rxstatus = 0; 235f64f8808SVince Bridgers 23689830580SVince Bridgers u32 sts = csrrd32(priv->rx_dma_csr, sgdma_csroffs(status)); 237f64f8808SVince Bridgers 238f64f8808SVince Bridgers desc = &base[0]; 23937c0ffaaSVince Bridgers if (sts & SGDMA_STSREG_EOP) { 24089830580SVince Bridgers unsigned int pktlength = 0; 24189830580SVince Bridgers unsigned int pktstatus = 0; 24237c0ffaaSVince Bridgers dma_sync_single_for_cpu(priv->device, 24337c0ffaaSVince Bridgers priv->rxdescphys, 244c3ffe0caSTobias Klauser SGDMA_DESC_LEN, 24537c0ffaaSVince Bridgers DMA_FROM_DEVICE); 24637c0ffaaSVince Bridgers 24789830580SVince Bridgers pktlength = csrrd16(desc, sgdma_descroffs(bytes_xferred)); 24889830580SVince Bridgers pktstatus = csrrd8(desc, sgdma_descroffs(status)); 24989830580SVince Bridgers rxstatus = pktstatus & ~SGDMA_STATUS_EOP; 250f64f8808SVince Bridgers rxstatus = rxstatus << 16; 251f64f8808SVince Bridgers rxstatus |= (pktlength & 0xffff); 252f64f8808SVince Bridgers 25337c0ffaaSVince Bridgers if (rxstatus) { 25489830580SVince Bridgers csrwr8(0, desc, sgdma_descroffs(status)); 255f64f8808SVince Bridgers 256f64f8808SVince Bridgers rxbuffer = dequeue_rx(priv); 257f64f8808SVince Bridgers if (rxbuffer == NULL) 25837c0ffaaSVince Bridgers netdev_info(priv->dev, 259f64f8808SVince Bridgers "sgdma rx and rx queue empty!\n"); 260f64f8808SVince Bridgers 26137c0ffaaSVince Bridgers /* Clear control */ 26289830580SVince Bridgers csrwr32(0, priv->rx_dma_csr, sgdma_csroffs(control)); 26337c0ffaaSVince Bridgers /* clear status */ 26489830580SVince Bridgers csrwr32(0xf, priv->rx_dma_csr, sgdma_csroffs(status)); 26537c0ffaaSVince Bridgers 266f64f8808SVince Bridgers /* kick the rx sgdma after reaping this descriptor */ 26789830580SVince Bridgers sgdma_async_read(priv); 26837c0ffaaSVince Bridgers 26937c0ffaaSVince Bridgers } else { 27037c0ffaaSVince Bridgers /* If the SGDMA indicated an end of packet on recv, 27137c0ffaaSVince Bridgers * then it's expected that the rxstatus from the 27237c0ffaaSVince Bridgers * descriptor is non-zero - meaning a valid packet 27337c0ffaaSVince Bridgers * with a nonzero length, or an error has been 27437c0ffaaSVince Bridgers * indicated. if not, then all we can do is signal 27537c0ffaaSVince Bridgers * an error and return no packet received. Most likely 27637c0ffaaSVince Bridgers * there is a system design error, or an error in the 27737c0ffaaSVince Bridgers * underlying kernel (cache or cache management problem) 27837c0ffaaSVince Bridgers */ 27937c0ffaaSVince Bridgers netdev_err(priv->dev, 28037c0ffaaSVince Bridgers "SGDMA RX Error Info: %x, %x, %x\n", 28189830580SVince Bridgers sts, csrrd8(desc, sgdma_descroffs(status)), 28289830580SVince Bridgers rxstatus); 28337c0ffaaSVince Bridgers } 28437c0ffaaSVince Bridgers } else if (sts == 0) { 28589830580SVince Bridgers sgdma_async_read(priv); 286f64f8808SVince Bridgers } 287f64f8808SVince Bridgers 288f64f8808SVince Bridgers return rxstatus; 289f64f8808SVince Bridgers } 290f64f8808SVince Bridgers 291f64f8808SVince Bridgers 292f64f8808SVince Bridgers /* Private functions */ 29389830580SVince Bridgers static void sgdma_setup_descrip(struct sgdma_descrip __iomem *desc, 29489830580SVince Bridgers struct sgdma_descrip __iomem *ndesc, 295f64f8808SVince Bridgers dma_addr_t ndesc_phys, 296f64f8808SVince Bridgers dma_addr_t raddr, 297f64f8808SVince Bridgers dma_addr_t waddr, 298f64f8808SVince Bridgers u16 length, 299f64f8808SVince Bridgers int generate_eop, 300f64f8808SVince Bridgers int rfixed, 301f64f8808SVince Bridgers int wfixed) 302f64f8808SVince Bridgers { 303f64f8808SVince Bridgers /* Clear the next descriptor as not owned by hardware */ 304f64f8808SVince Bridgers 30589830580SVince Bridgers u32 ctrl = csrrd8(ndesc, sgdma_descroffs(control)); 30689830580SVince Bridgers ctrl &= ~SGDMA_CONTROL_HW_OWNED; 30789830580SVince Bridgers csrwr8(ctrl, ndesc, sgdma_descroffs(control)); 30889830580SVince Bridgers 309f64f8808SVince Bridgers ctrl = SGDMA_CONTROL_HW_OWNED; 310f64f8808SVince Bridgers ctrl |= generate_eop; 311f64f8808SVince Bridgers ctrl |= rfixed; 312f64f8808SVince Bridgers ctrl |= wfixed; 313f64f8808SVince Bridgers 314f64f8808SVince Bridgers /* Channel is implicitly zero, initialized to 0 by default */ 31589830580SVince Bridgers csrwr32(lower_32_bits(raddr), desc, sgdma_descroffs(raddr)); 31689830580SVince Bridgers csrwr32(lower_32_bits(waddr), desc, sgdma_descroffs(waddr)); 317f64f8808SVince Bridgers 31889830580SVince Bridgers csrwr32(0, desc, sgdma_descroffs(pad1)); 31989830580SVince Bridgers csrwr32(0, desc, sgdma_descroffs(pad2)); 32089830580SVince Bridgers csrwr32(lower_32_bits(ndesc_phys), desc, sgdma_descroffs(next)); 32189830580SVince Bridgers 32289830580SVince Bridgers csrwr8(ctrl, desc, sgdma_descroffs(control)); 32389830580SVince Bridgers csrwr8(0, desc, sgdma_descroffs(status)); 32489830580SVince Bridgers csrwr8(0, desc, sgdma_descroffs(wburst)); 32589830580SVince Bridgers csrwr8(0, desc, sgdma_descroffs(rburst)); 32689830580SVince Bridgers csrwr16(length, desc, sgdma_descroffs(bytes)); 32789830580SVince Bridgers csrwr16(0, desc, sgdma_descroffs(bytes_xferred)); 328f64f8808SVince Bridgers } 329f64f8808SVince Bridgers 330f64f8808SVince Bridgers /* If hardware is busy, don't restart async read. 331f64f8808SVince Bridgers * if status register is 0 - meaning initial state, restart async read, 332f64f8808SVince Bridgers * probably for the first time when populating a receive buffer. 333f64f8808SVince Bridgers * If read status indicate not busy and a status, restart the async 334f64f8808SVince Bridgers * DMA read. 335f64f8808SVince Bridgers */ 336f64f8808SVince Bridgers static int sgdma_async_read(struct altera_tse_private *priv) 337f64f8808SVince Bridgers { 33889830580SVince Bridgers struct sgdma_descrip __iomem *descbase = 33989830580SVince Bridgers (struct sgdma_descrip __iomem *)priv->rx_dma_desc; 340f64f8808SVince Bridgers 34189830580SVince Bridgers struct sgdma_descrip __iomem *cdesc = &descbase[0]; 34289830580SVince Bridgers struct sgdma_descrip __iomem *ndesc = &descbase[1]; 343f64f8808SVince Bridgers struct tse_buffer *rxbuffer = NULL; 344f64f8808SVince Bridgers 345f64f8808SVince Bridgers if (!sgdma_rxbusy(priv)) { 346f64f8808SVince Bridgers rxbuffer = queue_rx_peekhead(priv); 34737c0ffaaSVince Bridgers if (rxbuffer == NULL) { 34837c0ffaaSVince Bridgers netdev_err(priv->dev, "no rx buffers available\n"); 349f64f8808SVince Bridgers return 0; 35037c0ffaaSVince Bridgers } 351f64f8808SVince Bridgers 3521b444881STobias Klauser sgdma_setup_descrip(cdesc, /* current descriptor */ 353f64f8808SVince Bridgers ndesc, /* next descriptor */ 354f64f8808SVince Bridgers sgdma_rxphysaddr(priv, ndesc), 355f64f8808SVince Bridgers 0, /* read addr 0 for rx dma */ 356f64f8808SVince Bridgers rxbuffer->dma_addr, /* write addr for rx dma */ 357f64f8808SVince Bridgers 0, /* read 'til EOP */ 358f64f8808SVince Bridgers 0, /* EOP: NA for rx dma */ 359f64f8808SVince Bridgers 0, /* read fixed: NA for rx dma */ 360f64f8808SVince Bridgers 0); /* SOP: NA for rx DMA */ 361f64f8808SVince Bridgers 362f64f8808SVince Bridgers dma_sync_single_for_device(priv->device, 363f64f8808SVince Bridgers priv->rxdescphys, 364c3ffe0caSTobias Klauser SGDMA_DESC_LEN, 36537c0ffaaSVince Bridgers DMA_TO_DEVICE); 366f64f8808SVince Bridgers 36789830580SVince Bridgers csrwr32(lower_32_bits(sgdma_rxphysaddr(priv, cdesc)), 36889830580SVince Bridgers priv->rx_dma_csr, 36989830580SVince Bridgers sgdma_csroffs(next_descrip)); 370f64f8808SVince Bridgers 37189830580SVince Bridgers csrwr32((priv->rxctrlreg | SGDMA_CTRLREG_START), 37289830580SVince Bridgers priv->rx_dma_csr, 37389830580SVince Bridgers sgdma_csroffs(control)); 374f64f8808SVince Bridgers 375f64f8808SVince Bridgers return 1; 376f64f8808SVince Bridgers } 377f64f8808SVince Bridgers 378f64f8808SVince Bridgers return 0; 379f64f8808SVince Bridgers } 380f64f8808SVince Bridgers 381f64f8808SVince Bridgers static int sgdma_async_write(struct altera_tse_private *priv, 38289830580SVince Bridgers struct sgdma_descrip __iomem *desc) 383f64f8808SVince Bridgers { 384f64f8808SVince Bridgers if (sgdma_txbusy(priv)) 385f64f8808SVince Bridgers return 0; 386f64f8808SVince Bridgers 387f64f8808SVince Bridgers /* clear control and status */ 38889830580SVince Bridgers csrwr32(0, priv->tx_dma_csr, sgdma_csroffs(control)); 38989830580SVince Bridgers csrwr32(0x1f, priv->tx_dma_csr, sgdma_csroffs(status)); 390f64f8808SVince Bridgers 391f64f8808SVince Bridgers dma_sync_single_for_device(priv->device, priv->txdescphys, 392c3ffe0caSTobias Klauser SGDMA_DESC_LEN, DMA_TO_DEVICE); 393f64f8808SVince Bridgers 39489830580SVince Bridgers csrwr32(lower_32_bits(sgdma_txphysaddr(priv, desc)), 39589830580SVince Bridgers priv->tx_dma_csr, 39689830580SVince Bridgers sgdma_csroffs(next_descrip)); 397f64f8808SVince Bridgers 39889830580SVince Bridgers csrwr32((priv->txctrlreg | SGDMA_CTRLREG_START), 39989830580SVince Bridgers priv->tx_dma_csr, 40089830580SVince Bridgers sgdma_csroffs(control)); 401f64f8808SVince Bridgers 402f64f8808SVince Bridgers return 1; 403f64f8808SVince Bridgers } 404f64f8808SVince Bridgers 405f64f8808SVince Bridgers static dma_addr_t 406f64f8808SVince Bridgers sgdma_txphysaddr(struct altera_tse_private *priv, 40789830580SVince Bridgers struct sgdma_descrip __iomem *desc) 408f64f8808SVince Bridgers { 409f64f8808SVince Bridgers dma_addr_t paddr = priv->txdescmem_busaddr; 410a804ad0eSVince Bridgers uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->tx_dma_desc; 411a804ad0eSVince Bridgers return (dma_addr_t)((uintptr_t)paddr + offs); 412f64f8808SVince Bridgers } 413f64f8808SVince Bridgers 414f64f8808SVince Bridgers static dma_addr_t 415f64f8808SVince Bridgers sgdma_rxphysaddr(struct altera_tse_private *priv, 41689830580SVince Bridgers struct sgdma_descrip __iomem *desc) 417f64f8808SVince Bridgers { 418f64f8808SVince Bridgers dma_addr_t paddr = priv->rxdescmem_busaddr; 419a804ad0eSVince Bridgers uintptr_t offs = (uintptr_t)desc - (uintptr_t)priv->rx_dma_desc; 420a804ad0eSVince Bridgers return (dma_addr_t)((uintptr_t)paddr + offs); 421f64f8808SVince Bridgers } 422f64f8808SVince Bridgers 423f64f8808SVince Bridgers #define list_remove_head(list, entry, type, member) \ 424f64f8808SVince Bridgers do { \ 425f64f8808SVince Bridgers entry = NULL; \ 426f64f8808SVince Bridgers if (!list_empty(list)) { \ 427f64f8808SVince Bridgers entry = list_entry((list)->next, type, member); \ 428f64f8808SVince Bridgers list_del_init(&entry->member); \ 429f64f8808SVince Bridgers } \ 430f64f8808SVince Bridgers } while (0) 431f64f8808SVince Bridgers 432f64f8808SVince Bridgers #define list_peek_head(list, entry, type, member) \ 433f64f8808SVince Bridgers do { \ 434f64f8808SVince Bridgers entry = NULL; \ 435f64f8808SVince Bridgers if (!list_empty(list)) { \ 436f64f8808SVince Bridgers entry = list_entry((list)->next, type, member); \ 437f64f8808SVince Bridgers } \ 438f64f8808SVince Bridgers } while (0) 439f64f8808SVince Bridgers 440f64f8808SVince Bridgers /* adds a tse_buffer to the tail of a tx buffer list. 441f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 442f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list. 443f64f8808SVince Bridgers */ 444f64f8808SVince Bridgers static void 445f64f8808SVince Bridgers queue_tx(struct altera_tse_private *priv, struct tse_buffer *buffer) 446f64f8808SVince Bridgers { 447f64f8808SVince Bridgers list_add_tail(&buffer->lh, &priv->txlisthd); 448f64f8808SVince Bridgers } 449f64f8808SVince Bridgers 450f64f8808SVince Bridgers 451f64f8808SVince Bridgers /* adds a tse_buffer to the tail of a rx buffer list 452f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 453f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list. 454f64f8808SVince Bridgers */ 455f64f8808SVince Bridgers static void 456f64f8808SVince Bridgers queue_rx(struct altera_tse_private *priv, struct tse_buffer *buffer) 457f64f8808SVince Bridgers { 458f64f8808SVince Bridgers list_add_tail(&buffer->lh, &priv->rxlisthd); 459f64f8808SVince Bridgers } 460f64f8808SVince Bridgers 461f64f8808SVince Bridgers /* dequeues a tse_buffer from the transmit buffer list, otherwise 462f64f8808SVince Bridgers * returns NULL if empty. 463f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 464f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list. 465f64f8808SVince Bridgers */ 466f64f8808SVince Bridgers static struct tse_buffer * 467f64f8808SVince Bridgers dequeue_tx(struct altera_tse_private *priv) 468f64f8808SVince Bridgers { 469f64f8808SVince Bridgers struct tse_buffer *buffer = NULL; 470f64f8808SVince Bridgers list_remove_head(&priv->txlisthd, buffer, struct tse_buffer, lh); 471f64f8808SVince Bridgers return buffer; 472f64f8808SVince Bridgers } 473f64f8808SVince Bridgers 474f64f8808SVince Bridgers /* dequeues a tse_buffer from the receive buffer list, otherwise 475f64f8808SVince Bridgers * returns NULL if empty 476f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 477f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list. 478f64f8808SVince Bridgers */ 479f64f8808SVince Bridgers static struct tse_buffer * 480f64f8808SVince Bridgers dequeue_rx(struct altera_tse_private *priv) 481f64f8808SVince Bridgers { 482f64f8808SVince Bridgers struct tse_buffer *buffer = NULL; 483f64f8808SVince Bridgers list_remove_head(&priv->rxlisthd, buffer, struct tse_buffer, lh); 484f64f8808SVince Bridgers return buffer; 485f64f8808SVince Bridgers } 486f64f8808SVince Bridgers 487f64f8808SVince Bridgers /* dequeues a tse_buffer from the receive buffer list, otherwise 488f64f8808SVince Bridgers * returns NULL if empty 489f64f8808SVince Bridgers * assumes the caller is managing and holding a mutual exclusion 490f64f8808SVince Bridgers * primitive to avoid simultaneous pushes/pops to the list while the 491f64f8808SVince Bridgers * head is being examined. 492f64f8808SVince Bridgers */ 493f64f8808SVince Bridgers static struct tse_buffer * 494f64f8808SVince Bridgers queue_rx_peekhead(struct altera_tse_private *priv) 495f64f8808SVince Bridgers { 496f64f8808SVince Bridgers struct tse_buffer *buffer = NULL; 497f64f8808SVince Bridgers list_peek_head(&priv->rxlisthd, buffer, struct tse_buffer, lh); 498f64f8808SVince Bridgers return buffer; 499f64f8808SVince Bridgers } 500f64f8808SVince Bridgers 501f64f8808SVince Bridgers /* check and return rx sgdma status without polling 502f64f8808SVince Bridgers */ 503f64f8808SVince Bridgers static int sgdma_rxbusy(struct altera_tse_private *priv) 504f64f8808SVince Bridgers { 50589830580SVince Bridgers return csrrd32(priv->rx_dma_csr, sgdma_csroffs(status)) 50689830580SVince Bridgers & SGDMA_STSREG_BUSY; 507f64f8808SVince Bridgers } 508f64f8808SVince Bridgers 509f64f8808SVince Bridgers /* waits for the tx sgdma to finish it's current operation, returns 0 510f64f8808SVince Bridgers * when it transitions to nonbusy, returns 1 if the operation times out 511f64f8808SVince Bridgers */ 512f64f8808SVince Bridgers static int sgdma_txbusy(struct altera_tse_private *priv) 513f64f8808SVince Bridgers { 514f64f8808SVince Bridgers int delay = 0; 515f64f8808SVince Bridgers 516*a5e516d0STom Rix /* if DMA is busy, wait for current transaction to finish */ 51789830580SVince Bridgers while ((csrrd32(priv->tx_dma_csr, sgdma_csroffs(status)) 51889830580SVince Bridgers & SGDMA_STSREG_BUSY) && (delay++ < 100)) 519f64f8808SVince Bridgers udelay(1); 520f64f8808SVince Bridgers 52189830580SVince Bridgers if (csrrd32(priv->tx_dma_csr, sgdma_csroffs(status)) 52289830580SVince Bridgers & SGDMA_STSREG_BUSY) { 523f64f8808SVince Bridgers netdev_err(priv->dev, "timeout waiting for tx dma\n"); 524f64f8808SVince Bridgers return 1; 525f64f8808SVince Bridgers } 526f64f8808SVince Bridgers return 0; 527f64f8808SVince Bridgers } 528