]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/net/ethernet/stmicro/stmmac/chain_mode.c
UBUNTU: Ubuntu-4.15.0-96.97
[mirror_ubuntu-bionic-kernel.git] / drivers / net / ethernet / stmicro / stmmac / chain_mode.c
CommitLineData
286a8372
GC
1/*******************************************************************************
2 Specialised functions for managing Chained mode
3
4 Copyright(C) 2011 STMicroelectronics Ltd
5
6 It defines all the functions used to handle the normal/enhanced
7 descriptors in case of the DMA is configured to work in chained or
8 in ring mode.
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms and conditions of the GNU General Public License,
12 version 2, as published by the Free Software Foundation.
13
14 This program is distributed in the hope it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
286a8372
GC
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
23*******************************************************************************/
24
25#include "stmmac.h"
26
362b37be 27static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
286a8372 28{
ce736788 29 struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)p;
286a8372 30 unsigned int nopaged_len = skb_headlen(skb);
ce736788
JP
31 struct stmmac_priv *priv = tx_q->priv_data;
32 unsigned int entry = tx_q->cur_tx;
f8be0d78 33 unsigned int bmax, des2;
286a8372 34 unsigned int i = 1, len;
ce736788
JP
35 struct dma_desc *desc;
36
37 desc = tx_q->dma_tx + entry;
286a8372
GC
38
39 if (priv->plat->enh_desc)
40 bmax = BUF_SIZE_8KiB;
41 else
42 bmax = BUF_SIZE_2KiB;
43
44 len = nopaged_len - bmax;
45
f8be0d78
MW
46 des2 = dma_map_single(priv->device, skb->data,
47 bmax, DMA_TO_DEVICE);
48 desc->des2 = cpu_to_le32(des2);
49 if (dma_mapping_error(priv->device, des2))
362b37be 50 return -1;
ce736788
JP
51 tx_q->tx_skbuff_dma[entry].buf = des2;
52 tx_q->tx_skbuff_dma[entry].len = bmax;
be434d50
GC
53 /* do not close the descriptor and do not set own bit */
54 priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE,
fe6af0e1 55 0, false, skb->len);
286a8372
GC
56
57 while (len != 0) {
ce736788 58 tx_q->tx_skbuff[entry] = NULL;
e3ad57c9 59 entry = STMMAC_GET_ENTRY(entry, DMA_TX_SIZE);
ce736788 60 desc = tx_q->dma_tx + entry;
286a8372
GC
61
62 if (len > bmax) {
f8be0d78
MW
63 des2 = dma_map_single(priv->device,
64 (skb->data + bmax * i),
65 bmax, DMA_TO_DEVICE);
66 desc->des2 = cpu_to_le32(des2);
67 if (dma_mapping_error(priv->device, des2))
362b37be 68 return -1;
ce736788
JP
69 tx_q->tx_skbuff_dma[entry].buf = des2;
70 tx_q->tx_skbuff_dma[entry].len = bmax;
4a7d666a 71 priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
be434d50 72 STMMAC_CHAIN_MODE, 1,
fe6af0e1 73 false, skb->len);
286a8372
GC
74 len -= bmax;
75 i++;
76 } else {
f8be0d78
MW
77 des2 = dma_map_single(priv->device,
78 (skb->data + bmax * i), len,
79 DMA_TO_DEVICE);
80 desc->des2 = cpu_to_le32(des2);
81 if (dma_mapping_error(priv->device, des2))
362b37be 82 return -1;
ce736788
JP
83 tx_q->tx_skbuff_dma[entry].buf = des2;
84 tx_q->tx_skbuff_dma[entry].len = len;
be434d50 85 /* last descriptor can be set now */
4a7d666a 86 priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
be434d50 87 STMMAC_CHAIN_MODE, 1,
fe6af0e1 88 true, skb->len);
286a8372
GC
89 len = 0;
90 }
91 }
e3ad57c9 92
ce736788 93 tx_q->cur_tx = entry;
e3ad57c9 94
286a8372
GC
95 return entry;
96}
97
98static unsigned int stmmac_is_jumbo_frm(int len, int enh_desc)
99{
100 unsigned int ret = 0;
101
102 if ((enh_desc && (len > BUF_SIZE_8KiB)) ||
103 (!enh_desc && (len > BUF_SIZE_2KiB))) {
104 ret = 1;
105 }
106
107 return ret;
108}
109
c24602ef
GC
110static void stmmac_init_dma_chain(void *des, dma_addr_t phy_addr,
111 unsigned int size, unsigned int extend_desc)
286a8372
GC
112{
113 /*
114 * In chained mode the des3 points to the next element in the ring.
115 * The latest element has to point to the head.
116 */
117 int i;
286a8372
GC
118 dma_addr_t dma_phy = phy_addr;
119
c24602ef 120 if (extend_desc) {
ceb69499 121 struct dma_extended_desc *p = (struct dma_extended_desc *)des;
c24602ef
GC
122 for (i = 0; i < (size - 1); i++) {
123 dma_phy += sizeof(struct dma_extended_desc);
f8be0d78 124 p->basic.des3 = cpu_to_le32((unsigned int)dma_phy);
c24602ef
GC
125 p++;
126 }
f8be0d78 127 p->basic.des3 = cpu_to_le32((unsigned int)phy_addr);
c24602ef
GC
128
129 } else {
ceb69499 130 struct dma_desc *p = (struct dma_desc *)des;
c24602ef
GC
131 for (i = 0; i < (size - 1); i++) {
132 dma_phy += sizeof(struct dma_desc);
f8be0d78 133 p->des3 = cpu_to_le32((unsigned int)dma_phy);
c24602ef
GC
134 p++;
135 }
f8be0d78 136 p->des3 = cpu_to_le32((unsigned int)phy_addr);
286a8372 137 }
286a8372
GC
138}
139
891434b1
RK
140static void stmmac_refill_desc3(void *priv_ptr, struct dma_desc *p)
141{
54139cf3
JP
142 struct stmmac_rx_queue *rx_q = (struct stmmac_rx_queue *)priv_ptr;
143 struct stmmac_priv *priv = rx_q->priv_data;
891434b1
RK
144
145 if (priv->hwts_rx_en && !priv->extend_desc)
146 /* NOTE: Device will overwrite des3 with timestamp value if
147 * 1588-2002 time stamping is enabled, hence reinitialize it
148 * to keep explicit chaining in the descriptor.
149 */
54139cf3
JP
150 p->des3 = cpu_to_le32((unsigned int)(rx_q->dma_rx_phy +
151 (((rx_q->dirty_rx) + 1) %
f8be0d78
MW
152 DMA_RX_SIZE) *
153 sizeof(struct dma_desc)));
891434b1
RK
154}
155
156static void stmmac_clean_desc3(void *priv_ptr, struct dma_desc *p)
157{
ce736788
JP
158 struct stmmac_tx_queue *tx_q = (struct stmmac_tx_queue *)priv_ptr;
159 struct stmmac_priv *priv = tx_q->priv_data;
160 unsigned int entry = tx_q->dirty_tx;
891434b1 161
ce736788 162 if (tx_q->tx_skbuff_dma[entry].last_segment && !priv->extend_desc &&
96951366 163 priv->hwts_tx_en)
891434b1
RK
164 /* NOTE: Device will overwrite des3 with timestamp value if
165 * 1588-2002 time stamping is enabled, hence reinitialize it
166 * to keep explicit chaining in the descriptor.
167 */
ce736788
JP
168 p->des3 = cpu_to_le32((unsigned int)((tx_q->dma_tx_phy +
169 ((tx_q->dirty_tx + 1) % DMA_TX_SIZE))
f8be0d78 170 * sizeof(struct dma_desc)));
891434b1
RK
171}
172
29896a67 173const struct stmmac_mode_ops chain_mode_ops = {
c24602ef 174 .init = stmmac_init_dma_chain,
286a8372
GC
175 .is_jumbo_frm = stmmac_is_jumbo_frm,
176 .jumbo_frm = stmmac_jumbo_frm,
891434b1
RK
177 .refill_desc3 = stmmac_refill_desc3,
178 .clean_desc3 = stmmac_clean_desc3,
286a8372 179};