Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright (c) 2018-2019, Vladimir Oltean <olteanv@gmail.com>
0003  */
0004 #include "sja1105.h"
0005 
0006 enum sja1105_counter_index {
0007     __SJA1105_COUNTER_UNUSED,
0008     /* MAC */
0009     N_RUNT,
0010     N_SOFERR,
0011     N_ALIGNERR,
0012     N_MIIERR,
0013     TYPEERR,
0014     SIZEERR,
0015     TCTIMEOUT,
0016     PRIORERR,
0017     NOMASTER,
0018     MEMOV,
0019     MEMERR,
0020     INVTYP,
0021     INTCYOV,
0022     DOMERR,
0023     PCFBAGDROP,
0024     SPCPRIOR,
0025     AGEPRIOR,
0026     PORTDROP,
0027     LENDROP,
0028     BAGDROP,
0029     POLICEERR,
0030     DRPNONA664ERR,
0031     SPCERR,
0032     AGEDRP,
0033     /* HL1 */
0034     N_N664ERR,
0035     N_VLANERR,
0036     N_UNRELEASED,
0037     N_SIZEERR,
0038     N_CRCERR,
0039     N_VLNOTFOUND,
0040     N_CTPOLERR,
0041     N_POLERR,
0042     N_RXFRM,
0043     N_RXBYTE,
0044     N_TXFRM,
0045     N_TXBYTE,
0046     /* HL2 */
0047     N_QFULL,
0048     N_PART_DROP,
0049     N_EGR_DISABLED,
0050     N_NOT_REACH,
0051     __MAX_SJA1105ET_PORT_COUNTER,
0052     /* P/Q/R/S only */
0053     /* ETHER */
0054     N_DROPS_NOLEARN = __MAX_SJA1105ET_PORT_COUNTER,
0055     N_DROPS_NOROUTE,
0056     N_DROPS_ILL_DTAG,
0057     N_DROPS_DTAG,
0058     N_DROPS_SOTAG,
0059     N_DROPS_SITAG,
0060     N_DROPS_UTAG,
0061     N_TX_BYTES_1024_2047,
0062     N_TX_BYTES_512_1023,
0063     N_TX_BYTES_256_511,
0064     N_TX_BYTES_128_255,
0065     N_TX_BYTES_65_127,
0066     N_TX_BYTES_64,
0067     N_TX_MCAST,
0068     N_TX_BCAST,
0069     N_RX_BYTES_1024_2047,
0070     N_RX_BYTES_512_1023,
0071     N_RX_BYTES_256_511,
0072     N_RX_BYTES_128_255,
0073     N_RX_BYTES_65_127,
0074     N_RX_BYTES_64,
0075     N_RX_MCAST,
0076     N_RX_BCAST,
0077     __MAX_SJA1105PQRS_PORT_COUNTER,
0078 };
0079 
0080 struct sja1105_port_counter {
0081     enum sja1105_stats_area area;
0082     const char name[ETH_GSTRING_LEN];
0083     int offset;
0084     int start;
0085     int end;
0086     bool is_64bit;
0087 };
0088 
0089 static const struct sja1105_port_counter sja1105_port_counters[] = {
0090     /* MAC-Level Diagnostic Counters */
0091     [N_RUNT] = {
0092         .area = MAC,
0093         .name = "n_runt",
0094         .offset = 0,
0095         .start = 31,
0096         .end = 24,
0097     },
0098     [N_SOFERR] = {
0099         .area = MAC,
0100         .name = "n_soferr",
0101         .offset = 0x0,
0102         .start = 23,
0103         .end = 16,
0104     },
0105     [N_ALIGNERR] = {
0106         .area = MAC,
0107         .name = "n_alignerr",
0108         .offset = 0x0,
0109         .start = 15,
0110         .end = 8,
0111     },
0112     [N_MIIERR] = {
0113         .area = MAC,
0114         .name = "n_miierr",
0115         .offset = 0x0,
0116         .start = 7,
0117         .end = 0,
0118     },
0119     /* MAC-Level Diagnostic Flags */
0120     [TYPEERR] = {
0121         .area = MAC,
0122         .name = "typeerr",
0123         .offset = 0x1,
0124         .start = 27,
0125         .end = 27,
0126     },
0127     [SIZEERR] = {
0128         .area = MAC,
0129         .name = "sizeerr",
0130         .offset = 0x1,
0131         .start = 26,
0132         .end = 26,
0133     },
0134     [TCTIMEOUT] = {
0135         .area = MAC,
0136         .name = "tctimeout",
0137         .offset = 0x1,
0138         .start = 25,
0139         .end = 25,
0140     },
0141     [PRIORERR] = {
0142         .area = MAC,
0143         .name = "priorerr",
0144         .offset = 0x1,
0145         .start = 24,
0146         .end = 24,
0147     },
0148     [NOMASTER] = {
0149         .area = MAC,
0150         .name = "nomaster",
0151         .offset = 0x1,
0152         .start = 23,
0153         .end = 23,
0154     },
0155     [MEMOV] = {
0156         .area = MAC,
0157         .name = "memov",
0158         .offset = 0x1,
0159         .start = 22,
0160         .end = 22,
0161     },
0162     [MEMERR] = {
0163         .area = MAC,
0164         .name = "memerr",
0165         .offset = 0x1,
0166         .start = 21,
0167         .end = 21,
0168     },
0169     [INVTYP] = {
0170         .area = MAC,
0171         .name = "invtyp",
0172         .offset = 0x1,
0173         .start = 19,
0174         .end = 19,
0175     },
0176     [INTCYOV] = {
0177         .area = MAC,
0178         .name = "intcyov",
0179         .offset = 0x1,
0180         .start = 18,
0181         .end = 18,
0182     },
0183     [DOMERR] = {
0184         .area = MAC,
0185         .name = "domerr",
0186         .offset = 0x1,
0187         .start = 17,
0188         .end = 17,
0189     },
0190     [PCFBAGDROP] = {
0191         .area = MAC,
0192         .name = "pcfbagdrop",
0193         .offset = 0x1,
0194         .start = 16,
0195         .end = 16,
0196     },
0197     [SPCPRIOR] = {
0198         .area = MAC,
0199         .name = "spcprior",
0200         .offset = 0x1,
0201         .start = 15,
0202         .end = 12,
0203     },
0204     [AGEPRIOR] = {
0205         .area = MAC,
0206         .name = "ageprior",
0207         .offset = 0x1,
0208         .start = 11,
0209         .end = 8,
0210     },
0211     [PORTDROP] = {
0212         .area = MAC,
0213         .name = "portdrop",
0214         .offset = 0x1,
0215         .start = 6,
0216         .end = 6,
0217     },
0218     [LENDROP] = {
0219         .area = MAC,
0220         .name = "lendrop",
0221         .offset = 0x1,
0222         .start = 5,
0223         .end = 5,
0224     },
0225     [BAGDROP] = {
0226         .area = MAC,
0227         .name = "bagdrop",
0228         .offset = 0x1,
0229         .start = 4,
0230         .end = 4,
0231     },
0232     [POLICEERR] = {
0233         .area = MAC,
0234         .name = "policeerr",
0235         .offset = 0x1,
0236         .start = 3,
0237         .end = 3,
0238     },
0239     [DRPNONA664ERR] = {
0240         .area = MAC,
0241         .name = "drpnona664err",
0242         .offset = 0x1,
0243         .start = 2,
0244         .end = 2,
0245     },
0246     [SPCERR] = {
0247         .area = MAC,
0248         .name = "spcerr",
0249         .offset = 0x1,
0250         .start = 1,
0251         .end = 1,
0252     },
0253     [AGEDRP] = {
0254         .area = MAC,
0255         .name = "agedrp",
0256         .offset = 0x1,
0257         .start = 0,
0258         .end = 0,
0259     },
0260     /* High-Level Diagnostic Counters */
0261     [N_N664ERR] = {
0262         .area = HL1,
0263         .name = "n_n664err",
0264         .offset = 0xF,
0265         .start = 31,
0266         .end = 0,
0267     },
0268     [N_VLANERR] = {
0269         .area = HL1,
0270         .name = "n_vlanerr",
0271         .offset = 0xE,
0272         .start = 31,
0273         .end = 0,
0274     },
0275     [N_UNRELEASED] = {
0276         .area = HL1,
0277         .name = "n_unreleased",
0278         .offset = 0xD,
0279         .start = 31,
0280         .end = 0,
0281     },
0282     [N_SIZEERR] = {
0283         .area = HL1,
0284         .name = "n_sizeerr",
0285         .offset = 0xC,
0286         .start = 31,
0287         .end = 0,
0288     },
0289     [N_CRCERR] = {
0290         .area = HL1,
0291         .name = "n_crcerr",
0292         .offset = 0xB,
0293         .start = 31,
0294         .end = 0,
0295     },
0296     [N_VLNOTFOUND] = {
0297         .area = HL1,
0298         .name = "n_vlnotfound",
0299         .offset = 0xA,
0300         .start = 31,
0301         .end = 0,
0302     },
0303     [N_CTPOLERR] = {
0304         .area = HL1,
0305         .name = "n_ctpolerr",
0306         .offset = 0x9,
0307         .start = 31,
0308         .end = 0,
0309     },
0310     [N_POLERR] = {
0311         .area = HL1,
0312         .name = "n_polerr",
0313         .offset = 0x8,
0314         .start = 31,
0315         .end = 0,
0316     },
0317     [N_RXFRM] = {
0318         .area = HL1,
0319         .name = "n_rxfrm",
0320         .offset = 0x6,
0321         .start = 31,
0322         .end = 0,
0323         .is_64bit = true,
0324     },
0325     [N_RXBYTE] = {
0326         .area = HL1,
0327         .name = "n_rxbyte",
0328         .offset = 0x4,
0329         .start = 31,
0330         .end = 0,
0331         .is_64bit = true,
0332     },
0333     [N_TXFRM] = {
0334         .area = HL1,
0335         .name = "n_txfrm",
0336         .offset = 0x2,
0337         .start = 31,
0338         .end = 0,
0339         .is_64bit = true,
0340     },
0341     [N_TXBYTE] = {
0342         .area = HL1,
0343         .name = "n_txbyte",
0344         .offset = 0x0,
0345         .start = 31,
0346         .end = 0,
0347         .is_64bit = true,
0348     },
0349     [N_QFULL] = {
0350         .area = HL2,
0351         .name = "n_qfull",
0352         .offset = 0x3,
0353         .start = 31,
0354         .end = 0,
0355     },
0356     [N_PART_DROP] = {
0357         .area = HL2,
0358         .name = "n_part_drop",
0359         .offset = 0x2,
0360         .start = 31,
0361         .end = 0,
0362     },
0363     [N_EGR_DISABLED] = {
0364         .area = HL2,
0365         .name = "n_egr_disabled",
0366         .offset = 0x1,
0367         .start = 31,
0368         .end = 0,
0369     },
0370     [N_NOT_REACH] = {
0371         .area = HL2,
0372         .name = "n_not_reach",
0373         .offset = 0x0,
0374         .start = 31,
0375         .end = 0,
0376     },
0377     /* Ether Stats */
0378     [N_DROPS_NOLEARN] = {
0379         .area = ETHER,
0380         .name = "n_drops_nolearn",
0381         .offset = 0x16,
0382         .start = 31,
0383         .end = 0,
0384     },
0385     [N_DROPS_NOROUTE] = {
0386         .area = ETHER,
0387         .name = "n_drops_noroute",
0388         .offset = 0x15,
0389         .start = 31,
0390         .end = 0,
0391     },
0392     [N_DROPS_ILL_DTAG] = {
0393         .area = ETHER,
0394         .name = "n_drops_ill_dtag",
0395         .offset = 0x14,
0396         .start = 31,
0397         .end = 0,
0398     },
0399     [N_DROPS_DTAG] = {
0400         .area = ETHER,
0401         .name = "n_drops_dtag",
0402         .offset = 0x13,
0403         .start = 31,
0404         .end = 0,
0405     },
0406     [N_DROPS_SOTAG] = {
0407         .area = ETHER,
0408         .name = "n_drops_sotag",
0409         .offset = 0x12,
0410         .start = 31,
0411         .end = 0,
0412     },
0413     [N_DROPS_SITAG] = {
0414         .area = ETHER,
0415         .name = "n_drops_sitag",
0416         .offset = 0x11,
0417         .start = 31,
0418         .end = 0,
0419     },
0420     [N_DROPS_UTAG] = {
0421         .area = ETHER,
0422         .name = "n_drops_utag",
0423         .offset = 0x10,
0424         .start = 31,
0425         .end = 0,
0426     },
0427     [N_TX_BYTES_1024_2047] = {
0428         .area = ETHER,
0429         .name = "n_tx_bytes_1024_2047",
0430         .offset = 0x0F,
0431         .start = 31,
0432         .end = 0,
0433     },
0434     [N_TX_BYTES_512_1023] = {
0435         .area = ETHER,
0436         .name = "n_tx_bytes_512_1023",
0437         .offset = 0x0E,
0438         .start = 31,
0439         .end = 0,
0440     },
0441     [N_TX_BYTES_256_511] = {
0442         .area = ETHER,
0443         .name = "n_tx_bytes_256_511",
0444         .offset = 0x0D,
0445         .start = 31,
0446         .end = 0,
0447     },
0448     [N_TX_BYTES_128_255] = {
0449         .area = ETHER,
0450         .name = "n_tx_bytes_128_255",
0451         .offset = 0x0C,
0452         .start = 31,
0453         .end = 0,
0454     },
0455     [N_TX_BYTES_65_127] = {
0456         .area = ETHER,
0457         .name = "n_tx_bytes_65_127",
0458         .offset = 0x0B,
0459         .start = 31,
0460         .end = 0,
0461     },
0462     [N_TX_BYTES_64] = {
0463         .area = ETHER,
0464         .name = "n_tx_bytes_64",
0465         .offset = 0x0A,
0466         .start = 31,
0467         .end = 0,
0468     },
0469     [N_TX_MCAST] = {
0470         .area = ETHER,
0471         .name = "n_tx_mcast",
0472         .offset = 0x09,
0473         .start = 31,
0474         .end = 0,
0475     },
0476     [N_TX_BCAST] = {
0477         .area = ETHER,
0478         .name = "n_tx_bcast",
0479         .offset = 0x08,
0480         .start = 31,
0481         .end = 0,
0482     },
0483     [N_RX_BYTES_1024_2047] = {
0484         .area = ETHER,
0485         .name = "n_rx_bytes_1024_2047",
0486         .offset = 0x07,
0487         .start = 31,
0488         .end = 0,
0489     },
0490     [N_RX_BYTES_512_1023] = {
0491         .area = ETHER,
0492         .name = "n_rx_bytes_512_1023",
0493         .offset = 0x06,
0494         .start = 31,
0495         .end = 0,
0496     },
0497     [N_RX_BYTES_256_511] = {
0498         .area = ETHER,
0499         .name = "n_rx_bytes_256_511",
0500         .offset = 0x05,
0501         .start = 31,
0502         .end = 0,
0503     },
0504     [N_RX_BYTES_128_255] = {
0505         .area = ETHER,
0506         .name = "n_rx_bytes_128_255",
0507         .offset = 0x04,
0508         .start = 31,
0509         .end = 0,
0510     },
0511     [N_RX_BYTES_65_127] = {
0512         .area = ETHER,
0513         .name = "n_rx_bytes_65_127",
0514         .offset = 0x03,
0515         .start = 31,
0516         .end = 0,
0517     },
0518     [N_RX_BYTES_64] = {
0519         .area = ETHER,
0520         .name = "n_rx_bytes_64",
0521         .offset = 0x02,
0522         .start = 31,
0523         .end = 0,
0524     },
0525     [N_RX_MCAST] = {
0526         .area = ETHER,
0527         .name = "n_rx_mcast",
0528         .offset = 0x01,
0529         .start = 31,
0530         .end = 0,
0531     },
0532     [N_RX_BCAST] = {
0533         .area = ETHER,
0534         .name = "n_rx_bcast",
0535         .offset = 0x00,
0536         .start = 31,
0537         .end = 0,
0538     },
0539 };
0540 
0541 static int sja1105_port_counter_read(struct sja1105_private *priv, int port,
0542                      enum sja1105_counter_index idx, u64 *ctr)
0543 {
0544     const struct sja1105_port_counter *c = &sja1105_port_counters[idx];
0545     size_t size = c->is_64bit ? 8 : 4;
0546     u8 buf[8] = {0};
0547     u64 regs;
0548     int rc;
0549 
0550     regs = priv->info->regs->stats[c->area][port];
0551 
0552     rc = sja1105_xfer_buf(priv, SPI_READ, regs + c->offset, buf, size);
0553     if (rc)
0554         return rc;
0555 
0556     sja1105_unpack(buf, ctr, c->start, c->end, size);
0557 
0558     return 0;
0559 }
0560 
0561 void sja1105_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data)
0562 {
0563     struct sja1105_private *priv = ds->priv;
0564     enum sja1105_counter_index max_ctr, i;
0565     int rc, k = 0;
0566 
0567     if (priv->info->device_id == SJA1105E_DEVICE_ID ||
0568         priv->info->device_id == SJA1105T_DEVICE_ID)
0569         max_ctr = __MAX_SJA1105ET_PORT_COUNTER;
0570     else
0571         max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
0572 
0573     for (i = 0; i < max_ctr; i++) {
0574         rc = sja1105_port_counter_read(priv, port, i, &data[k++]);
0575         if (rc) {
0576             dev_err(ds->dev,
0577                 "Failed to read port %d counters: %d\n",
0578                 port, rc);
0579             break;
0580         }
0581     }
0582 }
0583 
0584 void sja1105_get_strings(struct dsa_switch *ds, int port,
0585              u32 stringset, u8 *data)
0586 {
0587     struct sja1105_private *priv = ds->priv;
0588     enum sja1105_counter_index max_ctr, i;
0589     char *p = data;
0590 
0591     if (stringset != ETH_SS_STATS)
0592         return;
0593 
0594     if (priv->info->device_id == SJA1105E_DEVICE_ID ||
0595         priv->info->device_id == SJA1105T_DEVICE_ID)
0596         max_ctr = __MAX_SJA1105ET_PORT_COUNTER;
0597     else
0598         max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
0599 
0600     for (i = 0; i < max_ctr; i++) {
0601         strscpy(p, sja1105_port_counters[i].name, ETH_GSTRING_LEN);
0602         p += ETH_GSTRING_LEN;
0603     }
0604 }
0605 
0606 int sja1105_get_sset_count(struct dsa_switch *ds, int port, int sset)
0607 {
0608     struct sja1105_private *priv = ds->priv;
0609     enum sja1105_counter_index max_ctr, i;
0610     int sset_count = 0;
0611 
0612     if (sset != ETH_SS_STATS)
0613         return -EOPNOTSUPP;
0614 
0615     if (priv->info->device_id == SJA1105E_DEVICE_ID ||
0616         priv->info->device_id == SJA1105T_DEVICE_ID)
0617         max_ctr = __MAX_SJA1105ET_PORT_COUNTER;
0618     else
0619         max_ctr = __MAX_SJA1105PQRS_PORT_COUNTER;
0620 
0621     for (i = 0; i < max_ctr; i++) {
0622         if (!strlen(sja1105_port_counters[i].name))
0623             continue;
0624 
0625         sset_count++;
0626     }
0627 
0628     return sset_count;
0629 }