Skip to content

Commit

Permalink
net: mscc: ocelot: auto-detect packet buffer size and number of frame…
Browse files Browse the repository at this point in the history
… references

Instead of reading these values from the reference manual and writing
them down into the driver, it appears that the hardware gives us the
option of detecting them dynamically.

The number of frame references corresponds to what the reference manual
notes, however it seems that the frame buffers are reported as slightly
less than the books would indicate. On VSC9959 (Felix), the books say it
should have 128KB of packet buffer, but the registers indicate only
129840 bytes (126.79 KB). Also, the unit of measurement for FREECNT from
the documentation of all these devices is incorrect (taken from an older
generation). This was confirmed by Younes Leroul from Microchip support.

Not having anything better to do with these values at the moment* (this
will change soon), let's just print them.

*The frame buffer size is, in fact, used to calculate the tail dropping
watermarks.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Vladimir Oltean authored and Jakub Kicinski committed Jan 16, 2021
1 parent 2d9116b commit f6fe01d
Show file tree
Hide file tree
Showing 8 changed files with 26 additions and 7 deletions.
1 change: 0 additions & 1 deletion drivers/net/dsa/ocelot/felix.c
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,6 @@ static int felix_init_structs(struct felix *felix, int num_phys_ports)
ocelot->map = felix->info->map;
ocelot->stats_layout = felix->info->stats_layout;
ocelot->num_stats = felix->info->num_stats;
ocelot->shared_queue_sz = felix->info->shared_queue_sz;
ocelot->num_mact_rows = felix->info->num_mact_rows;
ocelot->vcap = felix->info->vcap;
ocelot->ops = felix->info->ops;
Expand Down
1 change: 0 additions & 1 deletion drivers/net/dsa/ocelot/felix.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ struct felix_info {
const struct reg_field *regfields;
const u32 *const *map;
const struct ocelot_ops *ops;
int shared_queue_sz;
int num_mact_rows;
const struct ocelot_stat_layout *stats_layout;
unsigned int num_stats;
Expand Down
1 change: 0 additions & 1 deletion drivers/net/dsa/ocelot/felix_vsc9959.c
Original file line number Diff line number Diff line change
Expand Up @@ -1356,7 +1356,6 @@ static const struct felix_info felix_info_vsc9959 = {
.stats_layout = vsc9959_stats_layout,
.num_stats = ARRAY_SIZE(vsc9959_stats_layout),
.vcap = vsc9959_vcap_props,
.shared_queue_sz = 128 * 1024,
.num_mact_rows = 2048,
.num_ports = 6,
.num_tx_queues = FELIX_NUM_TC,
Expand Down
1 change: 0 additions & 1 deletion drivers/net/dsa/ocelot/seville_vsc9953.c
Original file line number Diff line number Diff line change
Expand Up @@ -1181,7 +1181,6 @@ static const struct felix_info seville_info_vsc9953 = {
.stats_layout = vsc9953_stats_layout,
.num_stats = ARRAY_SIZE(vsc9953_stats_layout),
.vcap = vsc9953_vcap_props,
.shared_queue_sz = 256 * 1024,
.num_mact_rows = 2048,
.num_ports = 10,
.mdio_bus_alloc = vsc9953_mdio_bus_alloc,
Expand Down
22 changes: 21 additions & 1 deletion drivers/net/ethernet/mscc/ocelot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1354,7 +1354,7 @@ void ocelot_port_set_maxlen(struct ocelot *ocelot, int port, size_t sdu)
pause_stop);

/* Tail dropping watermarks */
atop_tot = (ocelot->shared_queue_sz - 9 * maxlen) /
atop_tot = (ocelot->packet_buffer_size - 9 * maxlen) /
OCELOT_BUFFER_CELL_SZ;
atop = (9 * maxlen) / OCELOT_BUFFER_CELL_SZ;
ocelot_write_rix(ocelot, ocelot->ops->wm_enc(atop), SYS_ATOP, port);
Expand Down Expand Up @@ -1467,6 +1467,25 @@ static void ocelot_cpu_port_init(struct ocelot *ocelot)
ANA_PORT_VLAN_CFG, cpu);
}

static void ocelot_detect_features(struct ocelot *ocelot)
{
int mmgt, eq_ctrl;

/* For Ocelot, Felix, Seville, Serval etc, SYS:MMGT:MMGT:FREECNT holds
* the number of 240-byte free memory words (aka 4-cell chunks) and not
* 192 bytes as the documentation incorrectly says.
*/
mmgt = ocelot_read(ocelot, SYS_MMGT);
ocelot->packet_buffer_size = 240 * SYS_MMGT_FREECNT(mmgt);

eq_ctrl = ocelot_read(ocelot, QSYS_EQ_CTRL);
ocelot->num_frame_refs = QSYS_MMGT_EQ_CTRL_FP_FREE_CNT(eq_ctrl);

dev_info(ocelot->dev,
"Detected %d bytes of packet buffer and %d frame references\n",
ocelot->packet_buffer_size, ocelot->num_frame_refs);
}

int ocelot_init(struct ocelot *ocelot)
{
char queue_name[32];
Expand Down Expand Up @@ -1509,6 +1528,7 @@ int ocelot_init(struct ocelot *ocelot)

INIT_LIST_HEAD(&ocelot->multicast);
INIT_LIST_HEAD(&ocelot->pgids);
ocelot_detect_features(ocelot);
ocelot_mact_init(ocelot);
ocelot_vlan_init(ocelot);
ocelot_vcap_init(ocelot);
Expand Down
1 change: 0 additions & 1 deletion drivers/net/ethernet/mscc/ocelot_vsc7514.c
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,6 @@ static int ocelot_chip_init(struct ocelot *ocelot, const struct ocelot_ops *ops)
ocelot->map = ocelot_regmap;
ocelot->stats_layout = ocelot_stats_layout;
ocelot->num_stats = ARRAY_SIZE(ocelot_stats_layout);
ocelot->shared_queue_sz = 224 * 1024;
ocelot->num_mact_rows = 1024;
ocelot->ops = ops;

Expand Down
3 changes: 2 additions & 1 deletion include/soc/mscc/ocelot.h
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,8 @@ struct ocelot {
const struct ocelot_stat_layout *stats_layout;
unsigned int num_stats;

int shared_queue_sz;
int packet_buffer_size;
int num_frame_refs;
int num_mact_rows;

struct net_device *hw_bridge_dev;
Expand Down
3 changes: 3 additions & 0 deletions include/soc/mscc/ocelot_qsys.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@
#define QSYS_RES_STAT_MAXUSE(x) ((x) & GENMASK(11, 0))
#define QSYS_RES_STAT_MAXUSE_M GENMASK(11, 0)

#define QSYS_MMGT_EQ_CTRL_FP_FREE_CNT(x) ((x) & GENMASK(15, 0))
#define QSYS_MMGT_EQ_CTRL_FP_FREE_CNT_M GENMASK(15, 0)

#define QSYS_EVENTS_CORE_EV_FDC(x) (((x) << 2) & GENMASK(4, 2))
#define QSYS_EVENTS_CORE_EV_FDC_M GENMASK(4, 2)
#define QSYS_EVENTS_CORE_EV_FDC_X(x) (((x) & GENMASK(4, 2)) >> 2)
Expand Down

0 comments on commit f6fe01d

Please sign in to comment.