1 // SPDX-License-Identifier: (GPL-2.0 OR MIT) 2 /* 3 * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates. 4 * stmmac XGMAC support. 5 */ 6 7 #include <linux/stmmac.h> 8 #include "common.h" 9 #include "dwxgmac2.h" 10 11 static int dwxgmac2_get_tx_status(void *data, struct stmmac_extra_stats *x, 12 struct dma_desc *p, void __iomem *ioaddr) 13 { 14 unsigned int tdes3 = le32_to_cpu(p->des3); 15 int ret = tx_done; 16 17 if (unlikely(tdes3 & XGMAC_TDES3_OWN)) 18 return tx_dma_own; 19 if (likely(!(tdes3 & XGMAC_TDES3_LD))) 20 return tx_not_ls; 21 22 return ret; 23 } 24 25 static int dwxgmac2_get_rx_status(void *data, struct stmmac_extra_stats *x, 26 struct dma_desc *p) 27 { 28 unsigned int rdes3 = le32_to_cpu(p->des3); 29 int ret = good_frame; 30 31 if (unlikely(rdes3 & XGMAC_RDES3_OWN)) 32 return dma_own; 33 if (likely(!(rdes3 & XGMAC_RDES3_LD))) 34 return discard_frame; 35 if (unlikely(rdes3 & XGMAC_RDES3_ES)) 36 ret = discard_frame; 37 38 return ret; 39 } 40 41 static int dwxgmac2_get_tx_len(struct dma_desc *p) 42 { 43 return (le32_to_cpu(p->des2) & XGMAC_TDES2_B1L); 44 } 45 46 static int dwxgmac2_get_tx_owner(struct dma_desc *p) 47 { 48 return (le32_to_cpu(p->des3) & XGMAC_TDES3_OWN) > 0; 49 } 50 51 static void dwxgmac2_set_tx_owner(struct dma_desc *p) 52 { 53 p->des3 |= cpu_to_le32(XGMAC_TDES3_OWN); 54 } 55 56 static void dwxgmac2_set_rx_owner(struct dma_desc *p, int disable_rx_ic) 57 { 58 p->des3 = cpu_to_le32(XGMAC_RDES3_OWN); 59 60 if (!disable_rx_ic) 61 p->des3 |= cpu_to_le32(XGMAC_RDES3_IOC); 62 } 63 64 static int dwxgmac2_get_tx_ls(struct dma_desc *p) 65 { 66 return (le32_to_cpu(p->des3) & XGMAC_RDES3_LD) > 0; 67 } 68 69 static int dwxgmac2_get_rx_frame_len(struct dma_desc *p, int rx_coe) 70 { 71 return (le32_to_cpu(p->des3) & XGMAC_RDES3_PL); 72 } 73 74 static void dwxgmac2_enable_tx_timestamp(struct dma_desc *p) 75 { 76 p->des2 |= cpu_to_le32(XGMAC_TDES2_TTSE); 77 } 78 79 static int dwxgmac2_get_tx_timestamp_status(struct dma_desc *p) 80 { 81 return 0; /* Not supported */ 82 } 83 84 static inline void dwxgmac2_get_timestamp(void *desc, u32 ats, u64 *ts) 85 { 86 struct dma_desc *p = (struct dma_desc *)desc; 87 u64 ns = 0; 88 89 ns += le32_to_cpu(p->des1) * 1000000000ULL; 90 ns += le32_to_cpu(p->des0); 91 92 *ts = ns; 93 } 94 95 static int dwxgmac2_rx_check_timestamp(void *desc) 96 { 97 struct dma_desc *p = (struct dma_desc *)desc; 98 unsigned int rdes3 = le32_to_cpu(p->des3); 99 bool desc_valid, ts_valid; 100 101 desc_valid = !(rdes3 & XGMAC_RDES3_OWN) && (rdes3 & XGMAC_RDES3_CTXT); 102 ts_valid = !(rdes3 & XGMAC_RDES3_TSD) && (rdes3 & XGMAC_RDES3_TSA); 103 104 if (likely(desc_valid && ts_valid)) 105 return 0; 106 return -EINVAL; 107 } 108 109 static int dwxgmac2_get_rx_timestamp_status(void *desc, void *next_desc, 110 u32 ats) 111 { 112 struct dma_desc *p = (struct dma_desc *)desc; 113 unsigned int rdes3 = le32_to_cpu(p->des3); 114 int ret = -EBUSY; 115 116 if (likely(rdes3 & XGMAC_RDES3_CDA)) { 117 ret = dwxgmac2_rx_check_timestamp(next_desc); 118 if (ret) 119 return ret; 120 } 121 122 return ret; 123 } 124 125 static void dwxgmac2_init_rx_desc(struct dma_desc *p, int disable_rx_ic, 126 int mode, int end) 127 { 128 dwxgmac2_set_rx_owner(p, disable_rx_ic); 129 } 130 131 static void dwxgmac2_init_tx_desc(struct dma_desc *p, int mode, int end) 132 { 133 p->des0 = 0; 134 p->des1 = 0; 135 p->des2 = 0; 136 p->des3 = 0; 137 } 138 139 static void dwxgmac2_prepare_tx_desc(struct dma_desc *p, int is_fs, int len, 140 bool csum_flag, int mode, bool tx_own, 141 bool ls, unsigned int tot_pkt_len) 142 { 143 unsigned int tdes3 = le32_to_cpu(p->des3); 144 145 p->des2 |= cpu_to_le32(len & XGMAC_TDES2_B1L); 146 147 tdes3 = tot_pkt_len & XGMAC_TDES3_FL; 148 if (is_fs) 149 tdes3 |= XGMAC_TDES3_FD; 150 else 151 tdes3 &= ~XGMAC_TDES3_FD; 152 153 if (csum_flag) 154 tdes3 |= 0x3 << XGMAC_TDES3_CIC_SHIFT; 155 else 156 tdes3 &= ~XGMAC_TDES3_CIC; 157 158 if (ls) 159 tdes3 |= XGMAC_TDES3_LD; 160 else 161 tdes3 &= ~XGMAC_TDES3_LD; 162 163 /* Finally set the OWN bit. Later the DMA will start! */ 164 if (tx_own) 165 tdes3 |= XGMAC_TDES3_OWN; 166 167 if (is_fs && tx_own) 168 /* When the own bit, for the first frame, has to be set, all 169 * descriptors for the same frame has to be set before, to 170 * avoid race condition. 171 */ 172 dma_wmb(); 173 174 p->des3 = cpu_to_le32(tdes3); 175 } 176 177 static void dwxgmac2_prepare_tso_tx_desc(struct dma_desc *p, int is_fs, 178 int len1, int len2, bool tx_own, 179 bool ls, unsigned int tcphdrlen, 180 unsigned int tcppayloadlen) 181 { 182 unsigned int tdes3 = le32_to_cpu(p->des3); 183 184 if (len1) 185 p->des2 |= cpu_to_le32(len1 & XGMAC_TDES2_B1L); 186 if (len2) 187 p->des2 |= cpu_to_le32((len2 << XGMAC_TDES2_B2L_SHIFT) & 188 XGMAC_TDES2_B2L); 189 if (is_fs) { 190 tdes3 |= XGMAC_TDES3_FD | XGMAC_TDES3_TSE; 191 tdes3 |= (tcphdrlen << XGMAC_TDES3_THL_SHIFT) & 192 XGMAC_TDES3_THL; 193 tdes3 |= tcppayloadlen & XGMAC_TDES3_TPL; 194 } else { 195 tdes3 &= ~XGMAC_TDES3_FD; 196 } 197 198 if (ls) 199 tdes3 |= XGMAC_TDES3_LD; 200 else 201 tdes3 &= ~XGMAC_TDES3_LD; 202 203 /* Finally set the OWN bit. Later the DMA will start! */ 204 if (tx_own) 205 tdes3 |= XGMAC_TDES3_OWN; 206 207 if (is_fs && tx_own) 208 /* When the own bit, for the first frame, has to be set, all 209 * descriptors for the same frame has to be set before, to 210 * avoid race condition. 211 */ 212 dma_wmb(); 213 214 p->des3 = cpu_to_le32(tdes3); 215 } 216 217 static void dwxgmac2_release_tx_desc(struct dma_desc *p, int mode) 218 { 219 p->des0 = 0; 220 p->des1 = 0; 221 p->des2 = 0; 222 p->des3 = 0; 223 } 224 225 static void dwxgmac2_set_tx_ic(struct dma_desc *p) 226 { 227 p->des2 |= cpu_to_le32(XGMAC_TDES2_IOC); 228 } 229 230 static void dwxgmac2_set_mss(struct dma_desc *p, unsigned int mss) 231 { 232 p->des0 = 0; 233 p->des1 = 0; 234 p->des2 = cpu_to_le32(mss); 235 p->des3 = cpu_to_le32(XGMAC_TDES3_CTXT | XGMAC_TDES3_TCMSSV); 236 } 237 238 static void dwxgmac2_get_addr(struct dma_desc *p, unsigned int *addr) 239 { 240 *addr = le32_to_cpu(p->des0); 241 } 242 243 static void dwxgmac2_set_addr(struct dma_desc *p, dma_addr_t addr) 244 { 245 p->des0 = cpu_to_le32(addr); 246 p->des1 = 0; 247 } 248 249 static void dwxgmac2_clear(struct dma_desc *p) 250 { 251 p->des0 = 0; 252 p->des1 = 0; 253 p->des2 = 0; 254 p->des3 = 0; 255 } 256 257 const struct stmmac_desc_ops dwxgmac210_desc_ops = { 258 .tx_status = dwxgmac2_get_tx_status, 259 .rx_status = dwxgmac2_get_rx_status, 260 .get_tx_len = dwxgmac2_get_tx_len, 261 .get_tx_owner = dwxgmac2_get_tx_owner, 262 .set_tx_owner = dwxgmac2_set_tx_owner, 263 .set_rx_owner = dwxgmac2_set_rx_owner, 264 .get_tx_ls = dwxgmac2_get_tx_ls, 265 .get_rx_frame_len = dwxgmac2_get_rx_frame_len, 266 .enable_tx_timestamp = dwxgmac2_enable_tx_timestamp, 267 .get_tx_timestamp_status = dwxgmac2_get_tx_timestamp_status, 268 .get_rx_timestamp_status = dwxgmac2_get_rx_timestamp_status, 269 .get_timestamp = dwxgmac2_get_timestamp, 270 .set_tx_ic = dwxgmac2_set_tx_ic, 271 .prepare_tx_desc = dwxgmac2_prepare_tx_desc, 272 .prepare_tso_tx_desc = dwxgmac2_prepare_tso_tx_desc, 273 .release_tx_desc = dwxgmac2_release_tx_desc, 274 .init_rx_desc = dwxgmac2_init_rx_desc, 275 .init_tx_desc = dwxgmac2_init_tx_desc, 276 .set_mss = dwxgmac2_set_mss, 277 .get_addr = dwxgmac2_get_addr, 278 .set_addr = dwxgmac2_set_addr, 279 .clear = dwxgmac2_clear, 280 }; 281