cregit-Linux how code gets into the kernel

Release 4.15 net/dsa/master.c

Directory: net/dsa
/*
 * Handling of a master device, switching frames via its switch fabric CPU port
 *
 * Copyright (c) 2017 Savoir-faire Linux Inc.
 *      Vivien Didelot <vivien.didelot@savoirfairelinux.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 */

#include "dsa_priv.h"


static void dsa_master_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, uint64_t *data) { struct dsa_port *cpu_dp = dev->dsa_ptr; const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops; struct dsa_switch *ds = cpu_dp->ds; int port = cpu_dp->index; int count = 0; if (ops && ops->get_sset_count && ops->get_ethtool_stats) { count = ops->get_sset_count(dev, ETH_SS_STATS); ops->get_ethtool_stats(dev, stats, data); } if (ds->ops->get_ethtool_stats) ds->ops->get_ethtool_stats(ds, port, data + count); }

Contributors

PersonTokensPropCommitsCommitProp
Vivien Didelot119100.00%3100.00%
Total119100.00%3100.00%


static int dsa_master_get_sset_count(struct net_device *dev, int sset) { struct dsa_port *cpu_dp = dev->dsa_ptr; const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops; struct dsa_switch *ds = cpu_dp->ds; int count = 0; if (ops && ops->get_sset_count) count += ops->get_sset_count(dev, sset); if (sset == ETH_SS_STATS && ds->ops->get_sset_count) count += ds->ops->get_sset_count(ds); return count; }

Contributors

PersonTokensPropCommitsCommitProp
Vivien Didelot92100.00%3100.00%
Total92100.00%3100.00%


static void dsa_master_get_strings(struct net_device *dev, uint32_t stringset, uint8_t *data) { struct dsa_port *cpu_dp = dev->dsa_ptr; const struct ethtool_ops *ops = cpu_dp->orig_ethtool_ops; struct dsa_switch *ds = cpu_dp->ds; int port = cpu_dp->index; int len = ETH_GSTRING_LEN; int mcount = 0, count; unsigned int i; uint8_t pfx[4]; uint8_t *ndata; snprintf(pfx, sizeof(pfx), "p%.2d", port); /* We do not want to be NULL-terminated, since this is a prefix */ pfx[sizeof(pfx) - 1] = '_'; if (ops && ops->get_sset_count && ops->get_strings) { mcount = ops->get_sset_count(dev, ETH_SS_STATS); ops->get_strings(dev, stringset, data); } if (stringset == ETH_SS_STATS && ds->ops->get_strings) { ndata = data + mcount * len; /* This function copies ETH_GSTRINGS_LEN bytes, we will mangle * the output after to prepend our CPU port prefix we * constructed earlier */ ds->ops->get_strings(ds, port, ndata); count = ds->ops->get_sset_count(ds); for (i = 0; i < count; i++) { memmove(ndata + (i * len + sizeof(pfx)), ndata + i * len, len - sizeof(pfx)); memcpy(ndata + i * len, pfx, sizeof(pfx)); } } }

Contributors

PersonTokensPropCommitsCommitProp
Vivien Didelot249100.00%3100.00%
Total249100.00%3100.00%


static int dsa_master_ethtool_setup(struct net_device *dev) { struct dsa_port *cpu_dp = dev->dsa_ptr; struct dsa_switch *ds = cpu_dp->ds; struct ethtool_ops *ops; ops = devm_kzalloc(ds->dev, sizeof(*ops), GFP_KERNEL); if (!ops) return -ENOMEM; cpu_dp->orig_ethtool_ops = dev->ethtool_ops; if (cpu_dp->orig_ethtool_ops) memcpy(ops, cpu_dp->orig_ethtool_ops, sizeof(*ops)); ops->get_sset_count = dsa_master_get_sset_count; ops->get_ethtool_stats = dsa_master_get_ethtool_stats; ops->get_strings = dsa_master_get_strings; dev->ethtool_ops = ops; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
Vivien Didelot116100.00%4100.00%
Total116100.00%4100.00%


static void dsa_master_ethtool_teardown(struct net_device *dev) { struct dsa_port *cpu_dp = dev->dsa_ptr; dev->ethtool_ops = cpu_dp->orig_ethtool_ops; cpu_dp->orig_ethtool_ops = NULL; }

Contributors

PersonTokensPropCommitsCommitProp
Vivien Didelot34100.00%4100.00%
Total34100.00%4100.00%


int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp) { /* If we use a tagging format that doesn't have an ethertype * field, make sure that all packets from this point on get * sent to the tag format's receive function. */ wmb(); dev->dsa_ptr = cpu_dp; return dsa_master_ethtool_setup(dev); }

Contributors

PersonTokensPropCommitsCommitProp
Vivien Didelot31100.00%1100.00%
Total31100.00%1100.00%


void dsa_master_teardown(struct net_device *dev) { dsa_master_ethtool_teardown(dev); dev->dsa_ptr = NULL; /* If we used a tagging format that doesn't have an ethertype * field, make sure that all packets from this point get sent * without the tag and go through the regular receive path. */ wmb(); }

Contributors

PersonTokensPropCommitsCommitProp
Vivien Didelot25100.00%1100.00%
Total25100.00%1100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
Vivien Didelot670100.00%4100.00%
Total670100.00%4100.00%
Directory: net/dsa
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.