ocelot.c (25027c8409b4541611d0060077607d8ca70740df) ocelot.c (fe90104cd6048364db821c06bcb2246074919c04)
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Microsemi Ocelot Switch driver
4 *
5 * Copyright (c) 2017 Microsemi Corporation
6 */
7#include <linux/dsa/ocelot.h>
8#include <linux/if_bridge.h>

--- 1839 unchanged lines hidden (view full) ---

1848 /* Commit back the result & save it */
1849 memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg));
1850 mutex_unlock(&ocelot->ptp_lock);
1851
1852 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
1853}
1854EXPORT_SYMBOL(ocelot_hwstamp_set);
1855
1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
2/*
3 * Microsemi Ocelot Switch driver
4 *
5 * Copyright (c) 2017 Microsemi Corporation
6 */
7#include <linux/dsa/ocelot.h>
8#include <linux/if_bridge.h>

--- 1839 unchanged lines hidden (view full) ---

1848 /* Commit back the result & save it */
1849 memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg));
1850 mutex_unlock(&ocelot->ptp_lock);
1851
1852 return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
1853}
1854EXPORT_SYMBOL(ocelot_hwstamp_set);
1855
1856void ocelot_get_strings(struct ocelot *ocelot, int port, u32 sset, u8 *data)
1857{
1858 int i;
1859
1860 if (sset != ETH_SS_STATS)
1861 return;
1862
1863 for (i = 0; i < OCELOT_NUM_STATS; i++) {
1864 if (ocelot->stats_layout[i].name[0] == '\0')
1865 continue;
1866
1867 memcpy(data + i * ETH_GSTRING_LEN, ocelot->stats_layout[i].name,
1868 ETH_GSTRING_LEN);
1869 }
1870}
1871EXPORT_SYMBOL(ocelot_get_strings);
1872
1873/* Read the counters from hardware and keep them in region->buf.
1874 * Caller must hold &ocelot->stat_view_lock.
1875 */
1876static int ocelot_port_update_stats(struct ocelot *ocelot, int port)
1877{
1878 struct ocelot_stats_region *region;
1879 int err;
1880
1881 /* Configure the port to read the stats from */
1882 ocelot_write(ocelot, SYS_STAT_CFG_STAT_VIEW(port), SYS_STAT_CFG);
1883
1884 list_for_each_entry(region, &ocelot->stats_regions, node) {
1885 err = ocelot_bulk_read(ocelot, region->base, region->buf,
1886 region->count);
1887 if (err)
1888 return err;
1889 }
1890
1891 return 0;
1892}
1893
1894/* Transfer the counters from region->buf to ocelot->stats.
1895 * Caller must hold &ocelot->stat_view_lock and &ocelot->stats_lock.
1896 */
1897static void ocelot_port_transfer_stats(struct ocelot *ocelot, int port)
1898{
1899 unsigned int idx = port * OCELOT_NUM_STATS;
1900 struct ocelot_stats_region *region;
1901 int j;
1902
1903 list_for_each_entry(region, &ocelot->stats_regions, node) {
1904 for (j = 0; j < region->count; j++) {
1905 u64 *stat = &ocelot->stats[idx + j];
1906 u64 val = region->buf[j];
1907
1908 if (val < (*stat & U32_MAX))
1909 *stat += (u64)1 << 32;
1910
1911 *stat = (*stat & ~(u64)U32_MAX) + val;
1912 }
1913
1914 idx += region->count;
1915 }
1916}
1917
1918static void ocelot_check_stats_work(struct work_struct *work)
1919{
1920 struct delayed_work *del_work = to_delayed_work(work);
1921 struct ocelot *ocelot = container_of(del_work, struct ocelot,
1922 stats_work);
1923 int port, err;
1924
1925 mutex_lock(&ocelot->stat_view_lock);
1926
1927 for (port = 0; port < ocelot->num_phys_ports; port++) {
1928 err = ocelot_port_update_stats(ocelot, port);
1929 if (err)
1930 break;
1931
1932 spin_lock(&ocelot->stats_lock);
1933 ocelot_port_transfer_stats(ocelot, port);
1934 spin_unlock(&ocelot->stats_lock);
1935 }
1936
1937 if (!err && ocelot->ops->update_stats)
1938 ocelot->ops->update_stats(ocelot);
1939
1940 mutex_unlock(&ocelot->stat_view_lock);
1941
1942 if (err)
1943 dev_err(ocelot->dev, "Error %d updating ethtool stats\n", err);
1944
1945 queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work,
1946 OCELOT_STATS_CHECK_DELAY);
1947}
1948
1949void ocelot_get_ethtool_stats(struct ocelot *ocelot, int port, u64 *data)
1950{
1951 int i, err;
1952
1953 mutex_lock(&ocelot->stat_view_lock);
1954
1955 /* check and update now */
1956 err = ocelot_port_update_stats(ocelot, port);
1957
1958 spin_lock(&ocelot->stats_lock);
1959
1960 ocelot_port_transfer_stats(ocelot, port);
1961
1962 /* Copy all supported counters */
1963 for (i = 0; i < OCELOT_NUM_STATS; i++) {
1964 int index = port * OCELOT_NUM_STATS + i;
1965
1966 if (ocelot->stats_layout[i].name[0] == '\0')
1967 continue;
1968
1969 *data++ = ocelot->stats[index];
1970 }
1971
1972 spin_unlock(&ocelot->stats_lock);
1973
1974 mutex_unlock(&ocelot->stat_view_lock);
1975
1976 if (err)
1977 dev_err(ocelot->dev, "Error %d updating ethtool stats\n", err);
1978}
1979EXPORT_SYMBOL(ocelot_get_ethtool_stats);
1980
1981int ocelot_get_sset_count(struct ocelot *ocelot, int port, int sset)
1982{
1983 int i, num_stats = 0;
1984
1985 if (sset != ETH_SS_STATS)
1986 return -EOPNOTSUPP;
1987
1988 for (i = 0; i < OCELOT_NUM_STATS; i++)
1989 if (ocelot->stats_layout[i].name[0] != '\0')
1990 num_stats++;
1991
1992 return num_stats;
1993}
1994EXPORT_SYMBOL(ocelot_get_sset_count);
1995
1996static int ocelot_prepare_stats_regions(struct ocelot *ocelot)
1997{
1998 struct ocelot_stats_region *region = NULL;
1999 unsigned int last;
2000 int i;
2001
2002 INIT_LIST_HEAD(&ocelot->stats_regions);
2003
2004 for (i = 0; i < OCELOT_NUM_STATS; i++) {
2005 if (ocelot->stats_layout[i].name[0] == '\0')
2006 continue;
2007
2008 if (region && ocelot->stats_layout[i].reg == last + 4) {
2009 region->count++;
2010 } else {
2011 region = devm_kzalloc(ocelot->dev, sizeof(*region),
2012 GFP_KERNEL);
2013 if (!region)
2014 return -ENOMEM;
2015
2016 region->base = ocelot->stats_layout[i].reg;
2017 region->count = 1;
2018 list_add_tail(&region->node, &ocelot->stats_regions);
2019 }
2020
2021 last = ocelot->stats_layout[i].reg;
2022 }
2023
2024 list_for_each_entry(region, &ocelot->stats_regions, node) {
2025 region->buf = devm_kcalloc(ocelot->dev, region->count,
2026 sizeof(*region->buf), GFP_KERNEL);
2027 if (!region->buf)
2028 return -ENOMEM;
2029 }
2030
2031 return 0;
2032}
2033
2034int ocelot_get_ts_info(struct ocelot *ocelot, int port,
2035 struct ethtool_ts_info *info)
2036{
2037 info->phc_index = ocelot->ptp_clock ?
2038 ptp_clock_index(ocelot->ptp_clock) : -1;
2039 if (info->phc_index == -1) {
2040 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
2041 SOF_TIMESTAMPING_RX_SOFTWARE |

--- 1358 unchanged lines hidden (view full) ---

3400 ocelot->packet_buffer_size = 240 * SYS_MMGT_FREECNT(mmgt);
3401
3402 eq_ctrl = ocelot_read(ocelot, QSYS_EQ_CTRL);
3403 ocelot->num_frame_refs = QSYS_MMGT_EQ_CTRL_FP_FREE_CNT(eq_ctrl);
3404}
3405
3406int ocelot_init(struct ocelot *ocelot)
3407{
1856int ocelot_get_ts_info(struct ocelot *ocelot, int port,
1857 struct ethtool_ts_info *info)
1858{
1859 info->phc_index = ocelot->ptp_clock ?
1860 ptp_clock_index(ocelot->ptp_clock) : -1;
1861 if (info->phc_index == -1) {
1862 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE |
1863 SOF_TIMESTAMPING_RX_SOFTWARE |

--- 1358 unchanged lines hidden (view full) ---

3222 ocelot->packet_buffer_size = 240 * SYS_MMGT_FREECNT(mmgt);
3223
3224 eq_ctrl = ocelot_read(ocelot, QSYS_EQ_CTRL);
3225 ocelot->num_frame_refs = QSYS_MMGT_EQ_CTRL_FP_FREE_CNT(eq_ctrl);
3226}
3227
3228int ocelot_init(struct ocelot *ocelot)
3229{
3408 char queue_name[32];
3409 int i, ret;
3410 u32 port;
3411
3412 if (ocelot->ops->reset) {
3413 ret = ocelot->ops->reset(ocelot);
3414 if (ret) {
3415 dev_err(ocelot->dev, "Switch reset failed\n");
3416 return ret;
3417 }
3418 }
3419
3230 int i, ret;
3231 u32 port;
3232
3233 if (ocelot->ops->reset) {
3234 ret = ocelot->ops->reset(ocelot);
3235 if (ret) {
3236 dev_err(ocelot->dev, "Switch reset failed\n");
3237 return ret;
3238 }
3239 }
3240
3420 ocelot->stats = devm_kcalloc(ocelot->dev,
3421 ocelot->num_phys_ports * OCELOT_NUM_STATS,
3422 sizeof(u64), GFP_KERNEL);
3423 if (!ocelot->stats)
3424 return -ENOMEM;
3425
3426 spin_lock_init(&ocelot->stats_lock);
3427 mutex_init(&ocelot->stat_view_lock);
3428 mutex_init(&ocelot->ptp_lock);
3429 mutex_init(&ocelot->mact_lock);
3430 mutex_init(&ocelot->fwd_domain_lock);
3431 mutex_init(&ocelot->tas_lock);
3432 spin_lock_init(&ocelot->ptp_clock_lock);
3433 spin_lock_init(&ocelot->ts_id_lock);
3241 mutex_init(&ocelot->ptp_lock);
3242 mutex_init(&ocelot->mact_lock);
3243 mutex_init(&ocelot->fwd_domain_lock);
3244 mutex_init(&ocelot->tas_lock);
3245 spin_lock_init(&ocelot->ptp_clock_lock);
3246 spin_lock_init(&ocelot->ts_id_lock);
3434 snprintf(queue_name, sizeof(queue_name), "%s-stats",
3435 dev_name(ocelot->dev));
3436 ocelot->stats_queue = create_singlethread_workqueue(queue_name);
3437 if (!ocelot->stats_queue)
3438 return -ENOMEM;
3439
3440 ocelot->owq = alloc_ordered_workqueue("ocelot-owq", 0);
3247
3248 ocelot->owq = alloc_ordered_workqueue("ocelot-owq", 0);
3441 if (!ocelot->owq) {
3442 destroy_workqueue(ocelot->stats_queue);
3249 if (!ocelot->owq)
3443 return -ENOMEM;
3250 return -ENOMEM;
3251
3252 ret = ocelot_stats_init(ocelot);
3253 if (ret) {
3254 destroy_workqueue(ocelot->owq);
3255 return ret;
3444 }
3445
3446 INIT_LIST_HEAD(&ocelot->multicast);
3447 INIT_LIST_HEAD(&ocelot->pgids);
3448 INIT_LIST_HEAD(&ocelot->vlans);
3449 INIT_LIST_HEAD(&ocelot->lag_fdbs);
3450 ocelot_detect_features(ocelot);
3451 ocelot_mact_init(ocelot);

--- 95 unchanged lines hidden (view full) ---

3547 ANA_CPUQ_CFG_CPUQ_IPMC_CTRL(6) |
3548 ANA_CPUQ_CFG_CPUQ_IGMP(6) |
3549 ANA_CPUQ_CFG_CPUQ_MLD(6), ANA_CPUQ_CFG);
3550 for (i = 0; i < 16; i++)
3551 ocelot_write_rix(ocelot, ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL(6) |
3552 ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL(6),
3553 ANA_CPUQ_8021_CFG, i);
3554
3256 }
3257
3258 INIT_LIST_HEAD(&ocelot->multicast);
3259 INIT_LIST_HEAD(&ocelot->pgids);
3260 INIT_LIST_HEAD(&ocelot->vlans);
3261 INIT_LIST_HEAD(&ocelot->lag_fdbs);
3262 ocelot_detect_features(ocelot);
3263 ocelot_mact_init(ocelot);

--- 95 unchanged lines hidden (view full) ---

3359 ANA_CPUQ_CFG_CPUQ_IPMC_CTRL(6) |
3360 ANA_CPUQ_CFG_CPUQ_IGMP(6) |
3361 ANA_CPUQ_CFG_CPUQ_MLD(6), ANA_CPUQ_CFG);
3362 for (i = 0; i < 16; i++)
3363 ocelot_write_rix(ocelot, ANA_CPUQ_8021_CFG_CPUQ_GARP_VAL(6) |
3364 ANA_CPUQ_8021_CFG_CPUQ_BPDU_VAL(6),
3365 ANA_CPUQ_8021_CFG, i);
3366
3555 ret = ocelot_prepare_stats_regions(ocelot);
3556 if (ret) {
3557 destroy_workqueue(ocelot->stats_queue);
3558 destroy_workqueue(ocelot->owq);
3559 return ret;
3560 }
3561
3562 INIT_DELAYED_WORK(&ocelot->stats_work, ocelot_check_stats_work);
3563 queue_delayed_work(ocelot->stats_queue, &ocelot->stats_work,
3564 OCELOT_STATS_CHECK_DELAY);
3565
3566 return 0;
3567}
3568EXPORT_SYMBOL(ocelot_init);
3569
3570void ocelot_deinit(struct ocelot *ocelot)
3571{
3367 return 0;
3368}
3369EXPORT_SYMBOL(ocelot_init);
3370
3371void ocelot_deinit(struct ocelot *ocelot)
3372{
3572 cancel_delayed_work(&ocelot->stats_work);
3573 destroy_workqueue(ocelot->stats_queue);
3373 ocelot_stats_deinit(ocelot);
3574 destroy_workqueue(ocelot->owq);
3575}
3576EXPORT_SYMBOL(ocelot_deinit);
3577
3578void ocelot_deinit_port(struct ocelot *ocelot, int port)
3579{
3580 struct ocelot_port *ocelot_port = ocelot->ports[port];
3581
3582 skb_queue_purge(&ocelot_port->tx_skbs);
3583}
3584EXPORT_SYMBOL(ocelot_deinit_port);
3585
3586MODULE_LICENSE("Dual MIT/GPL");
3374 destroy_workqueue(ocelot->owq);
3375}
3376EXPORT_SYMBOL(ocelot_deinit);
3377
3378void ocelot_deinit_port(struct ocelot *ocelot, int port)
3379{
3380 struct ocelot_port *ocelot_port = ocelot->ports[port];
3381
3382 skb_queue_purge(&ocelot_port->tx_skbs);
3383}
3384EXPORT_SYMBOL(ocelot_deinit_port);
3385
3386MODULE_LICENSE("Dual MIT/GPL");