Merge pull request #360 from BU-Automation/topic/js/ksz9477-broadcast-rate-limit
Topic/js/ksz9477 broadcast rate limit
This commit is contained in:
@@ -10,6 +10,7 @@ ksz_switch-objs += ksz_ptp.o
|
||||
endif
|
||||
|
||||
ksz_switch-objs += ksz8_ethtool.o
|
||||
ksz_switch-objs += ksz9477_ethtool.o
|
||||
ksz_switch-objs += ksz_devlink.o
|
||||
obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C) += ksz9477_i2c.o
|
||||
obj-$(CONFIG_NET_DSA_MICROCHIP_KSZ_SPI) += ksz_spi.o
|
||||
|
||||
@@ -2,64 +2,17 @@
|
||||
|
||||
#include "ksz8_ethtool.h"
|
||||
#include "ksz8.h"
|
||||
|
||||
enum {
|
||||
KSZ8_REGDUMP_ID_GLOBAL = 0x1100,
|
||||
KSZ8_REGDUMP_ID_PORT = 0x1200,
|
||||
KSZ8_REGDUMP_ID_STAT_MAC_TBL = 0x2000,
|
||||
KSZ8_REGDUMP_ID_FDB = 0x2100,
|
||||
};
|
||||
|
||||
struct ksz_regdump_hdr {
|
||||
u32 module_id;
|
||||
u32 len;
|
||||
};
|
||||
|
||||
struct ksz_regdump_record {
|
||||
struct ksz_regdump_hdr hdr;
|
||||
u32 start_off;
|
||||
u32 end_off;
|
||||
};
|
||||
|
||||
// creates a regdump record entry
|
||||
// note we use u32 to transport register values, despite their size in
|
||||
// the device
|
||||
#define KSZ_REGDUMP_ENTRY(id, start, end) { \
|
||||
.hdr.module_id = (id), \
|
||||
.hdr.len = (((end) - (start)) * sizeof(u32)) * 2 \
|
||||
+ sizeof(struct ksz_regdump_hdr), \
|
||||
.start_off = (start), \
|
||||
.end_off = (end), \
|
||||
}
|
||||
|
||||
#define SIZE_IS_MULTIPLE_OF(T, T2) (sizeof(T) == (DIV_ROUND_UP(sizeof(T), sizeof(T2))* sizeof(T2)))
|
||||
|
||||
// sizeof(ksz8_dyn_mac_entry) == 12
|
||||
struct ksz8_dyn_mac_entry {
|
||||
/*entry 1*/
|
||||
u32 : 24;
|
||||
u8 timestamp;
|
||||
/* entry 2 & 3 */
|
||||
u8 fid;
|
||||
u8 src_port;
|
||||
u8 mac[ETH_ALEN];
|
||||
};
|
||||
|
||||
#define KSZ8_REGDUMP_MAC_ENTRY(id, entry_size, max_entries) { \
|
||||
.hdr.module_id = (id), \
|
||||
.hdr.len = 2 * sizeof(u32) + (entry_size) * (max_entries) \
|
||||
+ sizeof(struct ksz_regdump_hdr), \
|
||||
.start_off = 0, \
|
||||
.end_off = 0, \
|
||||
}
|
||||
#include "ksz_ethtool.h"
|
||||
|
||||
static const struct ksz_regdump_record ksz8_regdump_records[] = {
|
||||
KSZ_REGDUMP_ENTRY(KSZ8_REGDUMP_ID_GLOBAL, 0x00, 0x10),
|
||||
KSZ_REGDUMP_ENTRY(KSZ8_REGDUMP_ID_PORT, 0x10, 0x20),
|
||||
KSZ_REGDUMP_ENTRY(KSZ8_REGDUMP_ID_PORT + 1, 0x20, 0x30),
|
||||
KSZ_REGDUMP_ENTRY(KSZ8_REGDUMP_ID_PORT + 2, 0x30, 0x40),
|
||||
KSZ8_REGDUMP_MAC_ENTRY(KSZ8_REGDUMP_ID_STAT_MAC_TBL, sizeof(struct alu_struct), 8),
|
||||
KSZ8_REGDUMP_MAC_ENTRY(KSZ8_REGDUMP_ID_FDB, sizeof(struct ksz8_dyn_mac_entry), 1024),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_GLOBAL, 0x00, 0x10),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT, 0x10, 0x20),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT + 1, 0x20, 0x30),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT + 2, 0x30, 0x40),
|
||||
KSZ8_REGDUMP_MAC_ENTRY(KSZ_REGDUMP_ID_STAT_MAC_TBL,
|
||||
sizeof(struct alu_struct), 8),
|
||||
KSZ8_REGDUMP_MAC_ENTRY(KSZ_REGDUMP_ID_FDB,
|
||||
sizeof(struct ksz8_dyn_mac_entry), 1024),
|
||||
};
|
||||
|
||||
int ksz8_get_regs_len(struct ksz_device *dev, int port)
|
||||
@@ -72,20 +25,22 @@ int ksz8_get_regs_len(struct ksz_device *dev, int port)
|
||||
return length;
|
||||
}
|
||||
|
||||
static void ksz8_get_regs_dump_static_mac_table(struct ksz_device *dev, u32 *reg, u32 *pos)
|
||||
static void ksz8_get_regs_dump_static_mac_table(struct ksz_device *dev,
|
||||
u32 *reg, u32 *pos)
|
||||
{
|
||||
BUILD_BUG_ON(!SIZE_IS_MULTIPLE_OF(struct alu_struct, u32));
|
||||
int index, ret;
|
||||
u32 cnt = *pos;
|
||||
|
||||
reg[cnt++] = KSZ8_REGDUMP_ID_STAT_MAC_TBL;
|
||||
struct ksz_regdump_hdr *hdr = (struct ksz_regdump_hdr *)®[cnt];
|
||||
|
||||
const u32 pos_length = cnt++;
|
||||
reg[pos_length] = sizeof(struct ksz_regdump_hdr);
|
||||
hdr->module_id = KSZ_REGDUMP_ID_STAT_MAC_TBL;
|
||||
hdr->len = sizeof(struct ksz_regdump_hdr);
|
||||
cnt += 2;
|
||||
|
||||
for (index = 0; index < dev->info->num_statics; index++) {
|
||||
bool valid;
|
||||
struct alu_struct* alu = (struct alu_struct*)®[cnt];
|
||||
struct alu_struct *alu = (struct alu_struct *)®[cnt];
|
||||
|
||||
ret = ksz8_r_sta_mac_table(dev, index, alu, &valid);
|
||||
if (ret)
|
||||
@@ -94,7 +49,7 @@ static void ksz8_get_regs_dump_static_mac_table(struct ksz_device *dev, u32 *reg
|
||||
if (!valid)
|
||||
continue;
|
||||
|
||||
reg[pos_length] += sizeof(struct alu_struct);
|
||||
hdr->len += sizeof(struct alu_struct);
|
||||
cnt += sizeof(struct alu_struct) / sizeof(u32);
|
||||
}
|
||||
*pos = cnt;
|
||||
@@ -107,55 +62,80 @@ static void ksz8_get_regs_dump_fdb(struct ksz_device *dev, u32 *reg, u32 *pos)
|
||||
u16 entries = 0;
|
||||
u32 cnt = *pos;
|
||||
|
||||
reg[cnt++] = KSZ8_REGDUMP_ID_FDB;
|
||||
struct ksz_regdump_hdr *hdr = (struct ksz_regdump_hdr *)®[cnt];
|
||||
|
||||
const u32 pos_length = cnt++;
|
||||
reg[pos_length] = sizeof(struct ksz_regdump_hdr);
|
||||
hdr->module_id = KSZ_REGDUMP_ID_FDB;
|
||||
hdr->len = sizeof(struct ksz_regdump_hdr);
|
||||
cnt += 2;
|
||||
|
||||
do {
|
||||
struct ksz8_dyn_mac_entry *entry = (struct ksz8_dyn_mac_entry*) ®[cnt];
|
||||
int ret = ksz8_r_dyn_mac_table(dev, i, entry->mac, &entry->fid, &entry->src_port,
|
||||
&entry->timestamp, &entries);
|
||||
struct ksz8_dyn_mac_entry *entry =
|
||||
(struct ksz8_dyn_mac_entry *)®[cnt];
|
||||
int ret = ksz8_r_dyn_mac_table(dev, i, entry->mac, &entry->fid,
|
||||
&entry->src_port,
|
||||
&entry->timestamp, &entries);
|
||||
|
||||
if (!ret) {
|
||||
reg[pos_length] += sizeof(struct ksz8_dyn_mac_entry);
|
||||
cnt += DIV_ROUND_UP(sizeof(struct ksz8_dyn_mac_entry), sizeof(u32));
|
||||
hdr->len += sizeof(struct ksz8_dyn_mac_entry);
|
||||
cnt += DIV_ROUND_UP(sizeof(struct ksz8_dyn_mac_entry),
|
||||
sizeof(u32));
|
||||
}
|
||||
i++;
|
||||
} while (i < entries);
|
||||
*pos = cnt;
|
||||
}
|
||||
|
||||
void ksz8_get_regs(struct ksz_device *dev, int port,
|
||||
struct ethtool_regs *regs, void *p)
|
||||
static void ksz_dump_regmap_range(struct ksz_device *dev, u32 *regs, u32 *pos,
|
||||
u32 start, u32 end)
|
||||
{
|
||||
int i, j;
|
||||
int i, length = *pos;
|
||||
|
||||
const struct regmap_range *yes_ranges = dev->info->rd_table->yes_ranges;
|
||||
for (i = 0; i < dev->info->rd_table->n_yes_ranges; i++) {
|
||||
const struct regmap_range range = yes_ranges[i];
|
||||
u32 reg;
|
||||
if (range.range_max < start || range.range_min >= end)
|
||||
continue;
|
||||
|
||||
for (reg = range.range_min; reg <= range.range_max; reg++) {
|
||||
u8 val;
|
||||
ksz_read8(dev, reg, &val);
|
||||
|
||||
regs[length++] = reg;
|
||||
regs[length++] = val;
|
||||
}
|
||||
}
|
||||
|
||||
*pos = length;
|
||||
}
|
||||
|
||||
void ksz8_get_regs(struct ksz_device *dev, int port, struct ethtool_regs *regs,
|
||||
void *p)
|
||||
{
|
||||
int i;
|
||||
u32 pos = 0;
|
||||
u32 *reg = p;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ksz8_regdump_records); i++) {
|
||||
struct ksz_regdump_record rec = ksz8_regdump_records[i];
|
||||
struct ksz_regdump_hdr *hdr =
|
||||
(struct ksz_regdump_hdr *)®[pos];
|
||||
|
||||
if (rec.hdr.module_id == KSZ8_REGDUMP_ID_STAT_MAC_TBL) {
|
||||
if (rec.hdr.module_id == KSZ_REGDUMP_ID_STAT_MAC_TBL) {
|
||||
ksz8_get_regs_dump_static_mac_table(dev, reg, &pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rec.hdr.module_id == KSZ8_REGDUMP_ID_FDB) {
|
||||
if (rec.hdr.module_id == KSZ_REGDUMP_ID_FDB) {
|
||||
ksz8_get_regs_dump_fdb(dev, reg, &pos);
|
||||
continue;
|
||||
}
|
||||
|
||||
reg[pos++] = rec.hdr.module_id;
|
||||
reg[pos++] = rec.hdr.len;
|
||||
|
||||
for (j = rec.start_off;
|
||||
j < rec.end_off; j++) {
|
||||
u8 val;
|
||||
|
||||
reg[pos++] = j;
|
||||
ksz_read8(dev, j, &val);
|
||||
reg[pos++] = val;
|
||||
}
|
||||
pos += 2;
|
||||
hdr->module_id = rec.hdr.module_id;
|
||||
hdr->len = pos;
|
||||
ksz_dump_regmap_range(dev, reg, &pos, rec.start_off,
|
||||
rec.end_off);
|
||||
hdr->len = (pos - hdr->len + 2) * sizeof(u32);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
#define __KSZ8XXX_ETHTOOL_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "ksz_ethtool.h"
|
||||
#include "ksz_common.h"
|
||||
|
||||
|
||||
int ksz8_get_regs_len(struct ksz_device *dev, int port);
|
||||
void ksz8_get_regs(struct ksz_device *dev, int port,
|
||||
struct ethtool_regs *regs, void *p);
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "ksz9477_ethtool.h"
|
||||
#include "ksz_ethtool.h"
|
||||
|
||||
static const struct ksz_regdump_record ksz8_regdump_records[] = {
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_GLOBAL, 0x00, 0x700),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT + 0, 0x1000, 0x1fff),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT + 1, 0x2000, 0x2fff),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT + 2, 0x3000, 0x3fff),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT + 3, 0x4000, 0x4fff),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT + 4, 0x5000, 0x5fff),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT + 5, 0x6000, 0x6fff),
|
||||
KSZ_REGDUMP_ENTRY(KSZ_REGDUMP_ID_PORT + 6, 0x7000, 0x7fff),
|
||||
};
|
||||
|
||||
int ksz9477_get_regs_len(struct ksz_device *dev, int port)
|
||||
{
|
||||
int i, length = 0;
|
||||
|
||||
const struct regmap_range *yes_ranges = dev->info->rd_table->yes_ranges;
|
||||
|
||||
for (i = 0; i < dev->info->rd_table->n_yes_ranges; i++) {
|
||||
const struct regmap_range range = yes_ranges[i];
|
||||
length += (range.range_max - range.range_min + 1) *
|
||||
sizeof(u32) * 2;
|
||||
}
|
||||
// ports + global + stat + fdb
|
||||
length += (7 + 1 + 1 + 1) * sizeof(struct ksz_regdump_hdr);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
static void ksz_dump_regmap_range(struct ksz_device *dev, u32 *regs, u32 *pos,
|
||||
u32 start, u32 end)
|
||||
{
|
||||
int i, length = *pos;
|
||||
|
||||
const struct regmap_range *yes_ranges = dev->info->rd_table->yes_ranges;
|
||||
|
||||
for (i = 0; i < dev->info->rd_table->n_yes_ranges; i++) {
|
||||
const struct regmap_range range = yes_ranges[i];
|
||||
u32 reg;
|
||||
if (range.range_max < start || range.range_min >= end)
|
||||
continue;
|
||||
|
||||
for (reg = range.range_min; reg <= range.range_max; reg++) {
|
||||
u8 val;
|
||||
ksz_read8(dev, reg, &val);
|
||||
|
||||
regs[length++] = reg;
|
||||
regs[length++] = val;
|
||||
}
|
||||
}
|
||||
|
||||
*pos = length;
|
||||
}
|
||||
|
||||
void ksz9477_get_regs(struct ksz_device *dev, int port,
|
||||
struct ethtool_regs *regs, void *p)
|
||||
{
|
||||
int i;
|
||||
u32 pos = 0;
|
||||
u32 *reg = p;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(ksz8_regdump_records); i++) {
|
||||
struct ksz_regdump_record rec = ksz8_regdump_records[i];
|
||||
struct ksz_regdump_hdr *hdr =
|
||||
(struct ksz_regdump_hdr *)®[pos];
|
||||
hdr->module_id = rec.hdr.module_id;
|
||||
pos += 2;
|
||||
|
||||
if (rec.hdr.module_id == KSZ_REGDUMP_ID_STAT_MAC_TBL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rec.hdr.module_id == KSZ_REGDUMP_ID_FDB) {
|
||||
continue;
|
||||
}
|
||||
|
||||
hdr->len = pos;
|
||||
ksz_dump_regmap_range(dev, reg, &pos, rec.start_off,
|
||||
rec.end_off);
|
||||
hdr->len = (pos - hdr->len + 2) * sizeof(u32);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef __KSZ9477_ETHTOOL_H
|
||||
#define __KSZ9477_ETHTOOL_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include "ksz_ethtool.h"
|
||||
#include "ksz_common.h"
|
||||
|
||||
int ksz9477_get_regs_len(struct ksz_device *dev, int port);
|
||||
void ksz9477_get_regs(struct ksz_device *dev, int port,
|
||||
struct ethtool_regs *regs, void *p);
|
||||
|
||||
#endif
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "lan937x.h"
|
||||
#include "ksz_devlink.h"
|
||||
#include "ksz8_ethtool.h"
|
||||
#include "ksz9477_ethtool.h"
|
||||
|
||||
#define MIB_COUNTER_NUM 0x20
|
||||
|
||||
@@ -218,9 +219,9 @@ static const struct ksz_dev_ops ksz8_dev_ops = {
|
||||
.change_mtu = ksz8_change_mtu,
|
||||
.devlink_param_setup = ksz8_setup_devlink_params,
|
||||
.devlink_param_teardown = ksz8_teardown_devlink_params,
|
||||
.devlink_param_get = ksz8_devlink_param_get,
|
||||
.devlink_param_set = ksz8_devlink_param_set,
|
||||
.devlink_info_get= ksz8_devlink_info_get,
|
||||
.devlink_param_get = ksz_devlink_param_get,
|
||||
.devlink_param_set = ksz_devlink_param_set,
|
||||
.devlink_info_get= ksz_devlink_info_get,
|
||||
.get_regs = ksz8_get_regs,
|
||||
.get_regs_len = ksz8_get_regs_len,
|
||||
};
|
||||
@@ -262,9 +263,16 @@ static const struct ksz_dev_ops ksz9477_dev_ops = {
|
||||
.config_cpu_port = ksz9477_config_cpu_port,
|
||||
.tc_cbs_set_cinc = ksz9477_tc_cbs_set_cinc,
|
||||
.enable_stp_addr = ksz9477_enable_stp_addr,
|
||||
.devlink_info_get = ksz_devlink_info_get,
|
||||
.devlink_param_get = ksz_devlink_param_get,
|
||||
.devlink_param_set = ksz_devlink_param_set,
|
||||
.devlink_param_setup = ksz9477_setup_devlink_params,
|
||||
.devlink_param_teardown = ksz9477_teardown_devlink_params,
|
||||
.reset = ksz9477_reset_switch,
|
||||
.init = ksz9477_switch_init,
|
||||
.exit = ksz9477_switch_exit,
|
||||
.get_regs = ksz9477_get_regs,
|
||||
.get_regs_len = ksz9477_get_regs_len,
|
||||
};
|
||||
|
||||
static const struct ksz_dev_ops lan937x_dev_ops = {
|
||||
@@ -3442,7 +3450,7 @@ static int ksz_devlink_param_setup(struct dsa_switch *ds)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ksz_devlink_info_get(struct dsa_switch *ds, struct devlink_info_req *req, struct netlink_ext_ack *extack) {
|
||||
static int ksz_get_devlink_info(struct dsa_switch *ds, struct devlink_info_req *req, struct netlink_ext_ack *extack) {
|
||||
|
||||
struct ksz_device* dev = ds->priv;
|
||||
|
||||
@@ -3452,7 +3460,7 @@ static int ksz_devlink_info_get(struct dsa_switch *ds, struct devlink_info_req *
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int ksz_devlink_param_get(struct dsa_switch *ds, u32 id,
|
||||
static int ksz_get_devlink_param(struct dsa_switch *ds, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
@@ -3463,7 +3471,7 @@ static int ksz_devlink_param_get(struct dsa_switch *ds, u32 id,
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static int ksz_devlink_param_set(struct dsa_switch *ds, u32 id,
|
||||
static int ksz_set_devlink_param(struct dsa_switch *ds, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
struct ksz_device *dev = ds->priv;
|
||||
@@ -3538,9 +3546,9 @@ static const struct dsa_switch_ops ksz_switch_ops = {
|
||||
.port_setup_tc = ksz_setup_tc,
|
||||
.get_mac_eee = ksz_get_mac_eee,
|
||||
.set_mac_eee = ksz_set_mac_eee,
|
||||
.devlink_param_get = ksz_devlink_param_get,
|
||||
.devlink_param_set = ksz_devlink_param_set,
|
||||
.devlink_info_get = ksz_devlink_info_get,
|
||||
.devlink_param_get = ksz_get_devlink_param,
|
||||
.devlink_param_set = ksz_set_devlink_param,
|
||||
.devlink_info_get = ksz_get_devlink_info,
|
||||
.get_regs = ksz_get_regs,
|
||||
.get_regs_len = ksz_get_regs_len,
|
||||
};
|
||||
|
||||
@@ -7,13 +7,20 @@
|
||||
#include <net/devlink.h>
|
||||
#include <net/dsa.h>
|
||||
|
||||
#include "ksz8795_reg.h"
|
||||
#include "ksz_common.h"
|
||||
|
||||
|
||||
#define KSZ8_P_BCAST_STORM_CTRL 0
|
||||
#define KSZ8_PORT_BROADCAST_STORM BIT(7)
|
||||
|
||||
#define KSZ9_P_BCAST_STORM_CTRL 0x400
|
||||
#define KSZ9_PORT_BROADCAST_STORM BIT(1)
|
||||
|
||||
|
||||
static void ksz_port_cfg(struct ksz_device *dev, int port, int offset, u8 bits,
|
||||
bool set)
|
||||
{
|
||||
regmap_update_bits(ksz_regmap_8(dev), PORT_CTRL_ADDR(port, offset),
|
||||
regmap_update_bits(ksz_regmap_8(dev), dev->dev_ops->get_port_addr(port, offset),
|
||||
bits, set ? bits : 0);
|
||||
}
|
||||
|
||||
@@ -23,9 +30,11 @@ enum ksz_devlink_param_id {
|
||||
KSZ_DEVLINK_PARAM_ID_MCAST_STORM_RATE_DISABLE,
|
||||
KSZ_DEVLINK_PARAM_ID_PORT_BASE,
|
||||
KSZ_DEVLINK_PARAM_ID_PORT_MAX = KSZ_DEVLINK_PARAM_ID_PORT_BASE + 3,
|
||||
KSZ9_DEVLINK_PARAM_ID_PORT_BASE,
|
||||
KSZ9_DEVLINK_PARAM_ID_PORT_MAX = KSZ9_DEVLINK_PARAM_ID_PORT_BASE + 8,
|
||||
};
|
||||
|
||||
static const struct devlink_param ksz_devlink_params[] = {
|
||||
static const struct devlink_param ksz8_devlink_params[] = {
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ_DEVLINK_PARAM_ID_BROADCAST_STORM_RATE,
|
||||
"bcast storm rate", DEVLINK_PARAM_TYPE_U16,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
@@ -48,19 +57,73 @@ static const struct devlink_param ksz_devlink_params[] = {
|
||||
|
||||
};
|
||||
|
||||
static const struct devlink_param ksz9_devlink_params[] = {
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ_DEVLINK_PARAM_ID_BROADCAST_STORM_RATE,
|
||||
"bcast storm rate", DEVLINK_PARAM_TYPE_U16,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ_DEVLINK_PARAM_ID_MCAST_STORM_RATE_DISABLE,
|
||||
"mcast storm rate disable",
|
||||
DEVLINK_PARAM_TYPE_BOOL,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ9_DEVLINK_PARAM_ID_PORT_BASE,
|
||||
"bcast storm protection enable port 0",
|
||||
DEVLINK_PARAM_TYPE_BOOL,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ9_DEVLINK_PARAM_ID_PORT_BASE + 1,
|
||||
"bcast storm protection enable port 1",
|
||||
DEVLINK_PARAM_TYPE_BOOL,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ9_DEVLINK_PARAM_ID_PORT_BASE + 2,
|
||||
"bcast storm protection enable port 2",
|
||||
DEVLINK_PARAM_TYPE_BOOL,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ9_DEVLINK_PARAM_ID_PORT_BASE + 3,
|
||||
"bcast storm protection enable port 3",
|
||||
DEVLINK_PARAM_TYPE_BOOL,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ9_DEVLINK_PARAM_ID_PORT_BASE + 4,
|
||||
"bcast storm protection enable port 4",
|
||||
DEVLINK_PARAM_TYPE_BOOL,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ9_DEVLINK_PARAM_ID_PORT_BASE + 5,
|
||||
"bcast storm protection enable port 5",
|
||||
DEVLINK_PARAM_TYPE_BOOL,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ9_DEVLINK_PARAM_ID_PORT_BASE + 6,
|
||||
"bcast storm protection enable port 6",
|
||||
DEVLINK_PARAM_TYPE_BOOL,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
DSA_DEVLINK_PARAM_DRIVER(KSZ9_DEVLINK_PARAM_ID_PORT_BASE + 7,
|
||||
"bcast storm protection enable port 7",
|
||||
DEVLINK_PARAM_TYPE_BOOL,
|
||||
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
||||
};
|
||||
|
||||
int ksz8_setup_devlink_params(struct dsa_switch *ds)
|
||||
{
|
||||
return dsa_devlink_params_register(ds, ksz_devlink_params,
|
||||
ARRAY_SIZE(ksz_devlink_params));
|
||||
return dsa_devlink_params_register(ds, ksz8_devlink_params,
|
||||
ARRAY_SIZE(ksz8_devlink_params));
|
||||
}
|
||||
|
||||
void ksz8_teardown_devlink_params(struct dsa_switch *ds)
|
||||
{
|
||||
dsa_devlink_params_unregister(ds, ksz_devlink_params,
|
||||
ARRAY_SIZE(ksz_devlink_params));
|
||||
dsa_devlink_params_unregister(ds, ksz8_devlink_params,
|
||||
ARRAY_SIZE(ksz8_devlink_params));
|
||||
}
|
||||
|
||||
int ksz8_devlink_param_get(struct ksz_device *dev, u32 id,
|
||||
int ksz9477_setup_devlink_params(struct dsa_switch *ds)
|
||||
{
|
||||
return dsa_devlink_params_register(ds, ksz9_devlink_params,
|
||||
ARRAY_SIZE(ksz9_devlink_params));
|
||||
}
|
||||
|
||||
void ksz9477_teardown_devlink_params(struct dsa_switch *ds)
|
||||
{
|
||||
dsa_devlink_params_unregister(ds, ksz9_devlink_params,
|
||||
ARRAY_SIZE(ksz9_devlink_params));
|
||||
}
|
||||
|
||||
int ksz_devlink_param_get(struct ksz_device *dev, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
const u16 *regs = dev->info->regs;
|
||||
@@ -84,9 +147,19 @@ int ksz8_devlink_param_get(struct ksz_device *dev, u32 id,
|
||||
int port = id - KSZ_DEVLINK_PARAM_ID_PORT_BASE;
|
||||
u8 val;
|
||||
|
||||
ksz_pread8(dev, port, P_BCAST_STORM_CTRL, &val);
|
||||
ctx->val.vbool = (val & PORT_BROADCAST_STORM) ==
|
||||
PORT_BROADCAST_STORM;
|
||||
ksz_pread8(dev, port, KSZ8_P_BCAST_STORM_CTRL, &val);
|
||||
ctx->val.vbool = (val & KSZ8_PORT_BROADCAST_STORM) ==
|
||||
KSZ8_PORT_BROADCAST_STORM;
|
||||
} break;
|
||||
|
||||
case KSZ9_DEVLINK_PARAM_ID_PORT_BASE ... KSZ9_DEVLINK_PARAM_ID_PORT_MAX: {
|
||||
int port = id - KSZ9_DEVLINK_PARAM_ID_PORT_BASE;
|
||||
u8 val;
|
||||
|
||||
ksz_pread8(dev, port, 0x400, &val);
|
||||
|
||||
ctx->val.vbool = (val & KSZ9_PORT_BROADCAST_STORM) ==
|
||||
KSZ9_PORT_BROADCAST_STORM;
|
||||
} break;
|
||||
|
||||
default:
|
||||
@@ -96,7 +169,7 @@ int ksz8_devlink_param_get(struct ksz_device *dev, u32 id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ksz8_devlink_param_set(struct ksz_device *dev, u32 id,
|
||||
int ksz_devlink_param_set(struct ksz_device *dev, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx)
|
||||
{
|
||||
const u16 *regs;
|
||||
@@ -128,8 +201,15 @@ int ksz8_devlink_param_set(struct ksz_device *dev, u32 id,
|
||||
case KSZ_DEVLINK_PARAM_ID_PORT_BASE ... KSZ_DEVLINK_PARAM_ID_PORT_MAX: {
|
||||
int port = id - KSZ_DEVLINK_PARAM_ID_PORT_BASE;
|
||||
|
||||
ksz_port_cfg(dev, port, P_BCAST_STORM_CTRL,
|
||||
PORT_BROADCAST_STORM, ctx->val.vbool);
|
||||
ksz_port_cfg(dev, port, KSZ8_P_BCAST_STORM_CTRL,
|
||||
KSZ8_PORT_BROADCAST_STORM, ctx->val.vbool);
|
||||
} break;
|
||||
|
||||
case KSZ9_DEVLINK_PARAM_ID_PORT_BASE ... KSZ9_DEVLINK_PARAM_ID_PORT_MAX: {
|
||||
int port = id - KSZ9_DEVLINK_PARAM_ID_PORT_BASE;
|
||||
|
||||
ksz_port_cfg(dev, port, KSZ9_P_BCAST_STORM_CTRL,
|
||||
KSZ9_PORT_BROADCAST_STORM, ctx->val.vbool);
|
||||
} break;
|
||||
|
||||
default:
|
||||
@@ -139,12 +219,9 @@ int ksz8_devlink_param_set(struct ksz_device *dev, u32 id,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ksz8_devlink_info_get(struct ksz_device *dev, struct devlink_info_req *req,
|
||||
int ksz_devlink_info_get(struct ksz_device *dev, struct devlink_info_req *req,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
|
||||
return devlink_info_version_fixed_put(
|
||||
req, DEVLINK_INFO_VERSION_GENERIC_ASIC_ID,
|
||||
dev->info->dev_name);
|
||||
req, DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, dev->info->dev_name);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,15 @@
|
||||
int ksz8_setup_devlink_params(struct dsa_switch *ds);
|
||||
void ksz8_teardown_devlink_params(struct dsa_switch *ds);
|
||||
|
||||
int ksz8_devlink_param_get(struct ksz_device *dev, u32 id,
|
||||
int ksz9477_setup_devlink_params(struct dsa_switch *ds);
|
||||
void ksz9477_teardown_devlink_params(struct dsa_switch *ds);
|
||||
|
||||
int ksz_devlink_param_get(struct ksz_device *dev, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx);
|
||||
int ksz8_devlink_param_set(struct ksz_device *dev, u32 id,
|
||||
int ksz_devlink_param_set(struct ksz_device *dev, u32 id,
|
||||
struct devlink_param_gset_ctx *ctx);
|
||||
|
||||
int ksz8_devlink_info_get(struct ksz_device *dev, struct devlink_info_req *req,
|
||||
int ksz_devlink_info_get(struct ksz_device *dev, struct devlink_info_req *req,
|
||||
struct netlink_ext_ack *extack);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef __KSZ_ETHTOOL_H
|
||||
#define __KSZ_ETHTOOL_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
// sizeof(ksz8_dyn_mac_entry) == 12
|
||||
struct ksz8_dyn_mac_entry {
|
||||
/*entry 1*/
|
||||
u32 : 24;
|
||||
u8 timestamp;
|
||||
/* entry 2 & 3 */
|
||||
u8 fid;
|
||||
u8 src_port;
|
||||
u8 mac[ETH_ALEN];
|
||||
};
|
||||
|
||||
struct ksz_regdump_hdr {
|
||||
u32 module_id;
|
||||
u32 len;
|
||||
};
|
||||
|
||||
struct ksz_regdump_record {
|
||||
struct ksz_regdump_hdr hdr;
|
||||
u32 start_off;
|
||||
u32 end_off;
|
||||
};
|
||||
|
||||
enum {
|
||||
KSZ_REGDUMP_ID_GLOBAL = 0x1100,
|
||||
KSZ_REGDUMP_ID_PORT = 0x1200,
|
||||
KSZ_REGDUMP_ID_STAT_MAC_TBL = 0x2000,
|
||||
KSZ_REGDUMP_ID_FDB = 0x2100,
|
||||
};
|
||||
|
||||
// creates a regdump record entry
|
||||
// note we use u32 to transport register values, despite their size in
|
||||
// the device
|
||||
#define KSZ_REGDUMP_ENTRY(id, start, end) { \
|
||||
.hdr.module_id = (id), \
|
||||
.hdr.len = (((end) - (start)) * sizeof(u32)) * 2 \
|
||||
+ sizeof(struct ksz_regdump_hdr), \
|
||||
.start_off = (start), \
|
||||
.end_off = (end), \
|
||||
}
|
||||
|
||||
#define SIZE_IS_MULTIPLE_OF(T, T2) (sizeof(T) == (DIV_ROUND_UP(sizeof(T), sizeof(T2))* sizeof(T2)))
|
||||
|
||||
#define KSZ8_REGDUMP_MAC_ENTRY(id, entry_size, max_entries) { \
|
||||
.hdr.module_id = (id), \
|
||||
.hdr.len = 2 * sizeof(u32) + (entry_size) * (max_entries) \
|
||||
+ sizeof(struct ksz_regdump_hdr), \
|
||||
.start_off = 0, \
|
||||
.end_off = 0, \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user