root/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_descs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. dwxgmac2_get_tx_status
  2. dwxgmac2_get_rx_status
  3. dwxgmac2_get_tx_len
  4. dwxgmac2_get_tx_owner
  5. dwxgmac2_set_tx_owner
  6. dwxgmac2_set_rx_owner
  7. dwxgmac2_get_tx_ls
  8. dwxgmac2_get_rx_frame_len
  9. dwxgmac2_enable_tx_timestamp
  10. dwxgmac2_get_tx_timestamp_status
  11. dwxgmac2_get_timestamp
  12. dwxgmac2_rx_check_timestamp
  13. dwxgmac2_get_rx_timestamp_status
  14. dwxgmac2_init_rx_desc
  15. dwxgmac2_init_tx_desc
  16. dwxgmac2_prepare_tx_desc
  17. dwxgmac2_prepare_tso_tx_desc
  18. dwxgmac2_release_tx_desc
  19. dwxgmac2_set_tx_ic
  20. dwxgmac2_set_mss
  21. dwxgmac2_get_addr
  22. dwxgmac2_set_addr
  23. dwxgmac2_clear
  24. dwxgmac2_get_rx_hash
  25. dwxgmac2_get_rx_header_len
  26. dwxgmac2_set_sec_addr
  27. dwxgmac2_set_sarc
  28. dwxgmac2_set_vlan_tag
  29. dwxgmac2_set_vlan

   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 
  30         if (unlikely(rdes3 & XGMAC_RDES3_OWN))
  31                 return dma_own;
  32         if (unlikely(rdes3 & XGMAC_RDES3_CTXT))
  33                 return discard_frame;
  34         if (likely(!(rdes3 & XGMAC_RDES3_LD)))
  35                 return rx_not_ls;
  36         if (unlikely((rdes3 & XGMAC_RDES3_ES) && (rdes3 & XGMAC_RDES3_LD)))
  37                 return discard_frame;
  38 
  39         return good_frame;
  40 }
  41 
  42 static int dwxgmac2_get_tx_len(struct dma_desc *p)
  43 {
  44         return (le32_to_cpu(p->des2) & XGMAC_TDES2_B1L);
  45 }
  46 
  47 static int dwxgmac2_get_tx_owner(struct dma_desc *p)
  48 {
  49         return (le32_to_cpu(p->des3) & XGMAC_TDES3_OWN) > 0;
  50 }
  51 
  52 static void dwxgmac2_set_tx_owner(struct dma_desc *p)
  53 {
  54         p->des3 |= cpu_to_le32(XGMAC_TDES3_OWN);
  55 }
  56 
  57 static void dwxgmac2_set_rx_owner(struct dma_desc *p, int disable_rx_ic)
  58 {
  59         p->des3 |= cpu_to_le32(XGMAC_RDES3_OWN);
  60 
  61         if (!disable_rx_ic)
  62                 p->des3 |= cpu_to_le32(XGMAC_RDES3_IOC);
  63 }
  64 
  65 static int dwxgmac2_get_tx_ls(struct dma_desc *p)
  66 {
  67         return (le32_to_cpu(p->des3) & XGMAC_RDES3_LD) > 0;
  68 }
  69 
  70 static int dwxgmac2_get_rx_frame_len(struct dma_desc *p, int rx_coe)
  71 {
  72         return (le32_to_cpu(p->des3) & XGMAC_RDES3_PL);
  73 }
  74 
  75 static void dwxgmac2_enable_tx_timestamp(struct dma_desc *p)
  76 {
  77         p->des2 |= cpu_to_le32(XGMAC_TDES2_TTSE);
  78 }
  79 
  80 static int dwxgmac2_get_tx_timestamp_status(struct dma_desc *p)
  81 {
  82         return 0; /* Not supported */
  83 }
  84 
  85 static inline void dwxgmac2_get_timestamp(void *desc, u32 ats, u64 *ts)
  86 {
  87         struct dma_desc *p = (struct dma_desc *)desc;
  88         u64 ns = 0;
  89 
  90         ns += le32_to_cpu(p->des1) * 1000000000ULL;
  91         ns += le32_to_cpu(p->des0);
  92 
  93         *ts = ns;
  94 }
  95 
  96 static int dwxgmac2_rx_check_timestamp(void *desc)
  97 {
  98         struct dma_desc *p = (struct dma_desc *)desc;
  99         unsigned int rdes3 = le32_to_cpu(p->des3);
 100         bool desc_valid, ts_valid;
 101 
 102         dma_rmb();
 103 
 104         desc_valid = !(rdes3 & XGMAC_RDES3_OWN) && (rdes3 & XGMAC_RDES3_CTXT);
 105         ts_valid = !(rdes3 & XGMAC_RDES3_TSD) && (rdes3 & XGMAC_RDES3_TSA);
 106 
 107         if (likely(desc_valid && ts_valid)) {
 108                 if ((p->des0 == 0xffffffff) && (p->des1 == 0xffffffff))
 109                         return -EINVAL;
 110                 return 0;
 111         }
 112 
 113         return -EINVAL;
 114 }
 115 
 116 static int dwxgmac2_get_rx_timestamp_status(void *desc, void *next_desc,
 117                                             u32 ats)
 118 {
 119         struct dma_desc *p = (struct dma_desc *)desc;
 120         unsigned int rdes3 = le32_to_cpu(p->des3);
 121         int ret = -EBUSY;
 122 
 123         if (likely(rdes3 & XGMAC_RDES3_CDA))
 124                 ret = dwxgmac2_rx_check_timestamp(next_desc);
 125 
 126         return !ret;
 127 }
 128 
 129 static void dwxgmac2_init_rx_desc(struct dma_desc *p, int disable_rx_ic,
 130                                   int mode, int end, int bfsize)
 131 {
 132         dwxgmac2_set_rx_owner(p, disable_rx_ic);
 133 }
 134 
 135 static void dwxgmac2_init_tx_desc(struct dma_desc *p, int mode, int end)
 136 {
 137         p->des0 = 0;
 138         p->des1 = 0;
 139         p->des2 = 0;
 140         p->des3 = 0;
 141 }
 142 
 143 static void dwxgmac2_prepare_tx_desc(struct dma_desc *p, int is_fs, int len,
 144                                      bool csum_flag, int mode, bool tx_own,
 145                                      bool ls, unsigned int tot_pkt_len)
 146 {
 147         unsigned int tdes3 = le32_to_cpu(p->des3);
 148 
 149         p->des2 |= cpu_to_le32(len & XGMAC_TDES2_B1L);
 150 
 151         tdes3 |= tot_pkt_len & XGMAC_TDES3_FL;
 152         if (is_fs)
 153                 tdes3 |= XGMAC_TDES3_FD;
 154         else
 155                 tdes3 &= ~XGMAC_TDES3_FD;
 156 
 157         if (csum_flag)
 158                 tdes3 |= 0x3 << XGMAC_TDES3_CIC_SHIFT;
 159         else
 160                 tdes3 &= ~XGMAC_TDES3_CIC;
 161 
 162         if (ls)
 163                 tdes3 |= XGMAC_TDES3_LD;
 164         else
 165                 tdes3 &= ~XGMAC_TDES3_LD;
 166 
 167         /* Finally set the OWN bit. Later the DMA will start! */
 168         if (tx_own)
 169                 tdes3 |= XGMAC_TDES3_OWN;
 170 
 171         if (is_fs && tx_own)
 172                 /* When the own bit, for the first frame, has to be set, all
 173                  * descriptors for the same frame has to be set before, to
 174                  * avoid race condition.
 175                  */
 176                 dma_wmb();
 177 
 178         p->des3 = cpu_to_le32(tdes3);
 179 }
 180 
 181 static void dwxgmac2_prepare_tso_tx_desc(struct dma_desc *p, int is_fs,
 182                                          int len1, int len2, bool tx_own,
 183                                          bool ls, unsigned int tcphdrlen,
 184                                          unsigned int tcppayloadlen)
 185 {
 186         unsigned int tdes3 = le32_to_cpu(p->des3);
 187 
 188         if (len1)
 189                 p->des2 |= cpu_to_le32(len1 & XGMAC_TDES2_B1L);
 190         if (len2)
 191                 p->des2 |= cpu_to_le32((len2 << XGMAC_TDES2_B2L_SHIFT) &
 192                                 XGMAC_TDES2_B2L);
 193         if (is_fs) {
 194                 tdes3 |= XGMAC_TDES3_FD | XGMAC_TDES3_TSE;
 195                 tdes3 |= (tcphdrlen << XGMAC_TDES3_THL_SHIFT) &
 196                         XGMAC_TDES3_THL;
 197                 tdes3 |= tcppayloadlen & XGMAC_TDES3_TPL;
 198         } else {
 199                 tdes3 &= ~XGMAC_TDES3_FD;
 200         }
 201 
 202         if (ls)
 203                 tdes3 |= XGMAC_TDES3_LD;
 204         else
 205                 tdes3 &= ~XGMAC_TDES3_LD;
 206 
 207         /* Finally set the OWN bit. Later the DMA will start! */
 208         if (tx_own)
 209                 tdes3 |= XGMAC_TDES3_OWN;
 210 
 211         if (is_fs && tx_own)
 212                 /* When the own bit, for the first frame, has to be set, all
 213                  * descriptors for the same frame has to be set before, to
 214                  * avoid race condition.
 215                  */
 216                 dma_wmb();
 217 
 218         p->des3 = cpu_to_le32(tdes3);
 219 }
 220 
 221 static void dwxgmac2_release_tx_desc(struct dma_desc *p, int mode)
 222 {
 223         p->des0 = 0;
 224         p->des1 = 0;
 225         p->des2 = 0;
 226         p->des3 = 0;
 227 }
 228 
 229 static void dwxgmac2_set_tx_ic(struct dma_desc *p)
 230 {
 231         p->des2 |= cpu_to_le32(XGMAC_TDES2_IOC);
 232 }
 233 
 234 static void dwxgmac2_set_mss(struct dma_desc *p, unsigned int mss)
 235 {
 236         p->des0 = 0;
 237         p->des1 = 0;
 238         p->des2 = cpu_to_le32(mss);
 239         p->des3 = cpu_to_le32(XGMAC_TDES3_CTXT | XGMAC_TDES3_TCMSSV);
 240 }
 241 
 242 static void dwxgmac2_get_addr(struct dma_desc *p, unsigned int *addr)
 243 {
 244         *addr = le32_to_cpu(p->des0);
 245 }
 246 
 247 static void dwxgmac2_set_addr(struct dma_desc *p, dma_addr_t addr)
 248 {
 249         p->des0 = cpu_to_le32(lower_32_bits(addr));
 250         p->des1 = cpu_to_le32(upper_32_bits(addr));
 251 }
 252 
 253 static void dwxgmac2_clear(struct dma_desc *p)
 254 {
 255         p->des0 = 0;
 256         p->des1 = 0;
 257         p->des2 = 0;
 258         p->des3 = 0;
 259 }
 260 
 261 static int dwxgmac2_get_rx_hash(struct dma_desc *p, u32 *hash,
 262                                 enum pkt_hash_types *type)
 263 {
 264         unsigned int rdes3 = le32_to_cpu(p->des3);
 265         u32 ptype;
 266 
 267         if (rdes3 & XGMAC_RDES3_RSV) {
 268                 ptype = (rdes3 & XGMAC_RDES3_L34T) >> XGMAC_RDES3_L34T_SHIFT;
 269 
 270                 switch (ptype) {
 271                 case XGMAC_L34T_IP4TCP:
 272                 case XGMAC_L34T_IP4UDP:
 273                 case XGMAC_L34T_IP6TCP:
 274                 case XGMAC_L34T_IP6UDP:
 275                         *type = PKT_HASH_TYPE_L4;
 276                         break;
 277                 default:
 278                         *type = PKT_HASH_TYPE_L3;
 279                         break;
 280                 }
 281 
 282                 *hash = le32_to_cpu(p->des1);
 283                 return 0;
 284         }
 285 
 286         return -EINVAL;
 287 }
 288 
 289 static int dwxgmac2_get_rx_header_len(struct dma_desc *p, unsigned int *len)
 290 {
 291         if (le32_to_cpu(p->des3) & XGMAC_RDES3_L34T)
 292                 *len = le32_to_cpu(p->des2) & XGMAC_RDES2_HL;
 293         return 0;
 294 }
 295 
 296 static void dwxgmac2_set_sec_addr(struct dma_desc *p, dma_addr_t addr)
 297 {
 298         p->des2 = cpu_to_le32(lower_32_bits(addr));
 299         p->des3 = cpu_to_le32(upper_32_bits(addr));
 300 }
 301 
 302 static void dwxgmac2_set_sarc(struct dma_desc *p, u32 sarc_type)
 303 {
 304         sarc_type <<= XGMAC_TDES3_SAIC_SHIFT;
 305 
 306         p->des3 |= cpu_to_le32(sarc_type & XGMAC_TDES3_SAIC);
 307 }
 308 
 309 static void dwxgmac2_set_vlan_tag(struct dma_desc *p, u16 tag, u16 inner_tag,
 310                                   u32 inner_type)
 311 {
 312         p->des0 = 0;
 313         p->des1 = 0;
 314         p->des2 = 0;
 315         p->des3 = 0;
 316 
 317         /* Inner VLAN */
 318         if (inner_type) {
 319                 u32 des = inner_tag << XGMAC_TDES2_IVT_SHIFT;
 320 
 321                 des &= XGMAC_TDES2_IVT;
 322                 p->des2 = cpu_to_le32(des);
 323 
 324                 des = inner_type << XGMAC_TDES3_IVTIR_SHIFT;
 325                 des &= XGMAC_TDES3_IVTIR;
 326                 p->des3 = cpu_to_le32(des | XGMAC_TDES3_IVLTV);
 327         }
 328 
 329         /* Outer VLAN */
 330         p->des3 |= cpu_to_le32(tag & XGMAC_TDES3_VT);
 331         p->des3 |= cpu_to_le32(XGMAC_TDES3_VLTV);
 332 
 333         p->des3 |= cpu_to_le32(XGMAC_TDES3_CTXT);
 334 }
 335 
 336 static void dwxgmac2_set_vlan(struct dma_desc *p, u32 type)
 337 {
 338         type <<= XGMAC_TDES2_VTIR_SHIFT;
 339         p->des2 |= cpu_to_le32(type & XGMAC_TDES2_VTIR);
 340 }
 341 
 342 const struct stmmac_desc_ops dwxgmac210_desc_ops = {
 343         .tx_status = dwxgmac2_get_tx_status,
 344         .rx_status = dwxgmac2_get_rx_status,
 345         .get_tx_len = dwxgmac2_get_tx_len,
 346         .get_tx_owner = dwxgmac2_get_tx_owner,
 347         .set_tx_owner = dwxgmac2_set_tx_owner,
 348         .set_rx_owner = dwxgmac2_set_rx_owner,
 349         .get_tx_ls = dwxgmac2_get_tx_ls,
 350         .get_rx_frame_len = dwxgmac2_get_rx_frame_len,
 351         .enable_tx_timestamp = dwxgmac2_enable_tx_timestamp,
 352         .get_tx_timestamp_status = dwxgmac2_get_tx_timestamp_status,
 353         .get_rx_timestamp_status = dwxgmac2_get_rx_timestamp_status,
 354         .get_timestamp = dwxgmac2_get_timestamp,
 355         .set_tx_ic = dwxgmac2_set_tx_ic,
 356         .prepare_tx_desc = dwxgmac2_prepare_tx_desc,
 357         .prepare_tso_tx_desc = dwxgmac2_prepare_tso_tx_desc,
 358         .release_tx_desc = dwxgmac2_release_tx_desc,
 359         .init_rx_desc = dwxgmac2_init_rx_desc,
 360         .init_tx_desc = dwxgmac2_init_tx_desc,
 361         .set_mss = dwxgmac2_set_mss,
 362         .get_addr = dwxgmac2_get_addr,
 363         .set_addr = dwxgmac2_set_addr,
 364         .clear = dwxgmac2_clear,
 365         .get_rx_hash = dwxgmac2_get_rx_hash,
 366         .get_rx_header_len = dwxgmac2_get_rx_header_len,
 367         .set_sec_addr = dwxgmac2_set_sec_addr,
 368         .set_sarc = dwxgmac2_set_sarc,
 369         .set_vlan_tag = dwxgmac2_set_vlan_tag,
 370         .set_vlan = dwxgmac2_set_vlan,
 371 };

/* [<][>][^][v][top][bottom][index][help] */