// SPDX-License-Identifier: GPL-2.0-only
#include <asm/mach-rtl838x/mach-rtl83xx.h>
+#include <linux/etherdevice.h>
#include <linux/iopoll.h>
#include <net/nexthop.h>
void rtl838x_print_matrix(void)
{
unsigned volatile int *ptr8;
- int i;
ptr8 = RTL838X_SW_BASE + RTL838X_PORT_ISO_CTRL(0);
- for (i = 0; i < 28; i += 8)
+ for (int i = 0; i < 28; i += 8)
pr_debug("> %8x %8x %8x %8x %8x %8x %8x %8x\n",
ptr8[i + 0], ptr8[i + 1], ptr8[i + 2], ptr8[i + 3],
ptr8[i + 4], ptr8[i + 5], ptr8[i + 6], ptr8[i + 7]);
u32 r[3];
struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 0); /* Access L2 Table 0 */
u32 idx = (0 << 14) | (hash << 2) | pos; /* Search SRAM, with hash and at pos in bucket */
- int i;
rtl_table_read(q, idx);
- for (i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++)
r[i] = sw_r32(rtl_table_data(q, i));
rtl_table_release(q);
{
u32 r[3];
struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 0);
- int i;
u32 idx = (0 << 14) | (hash << 2) | pos; /* Access SRAM, with hash and at pos in bucket */
rtl838x_fill_l2_row(r, e);
- for (i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++)
sw_w32(r[i], rtl_table_data(q, i));
rtl_table_write(q, idx);
{
u32 r[3];
struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 1); /* Access L2 Table 1 */
- int i;
rtl_table_read(q, idx);
- for (i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++)
r[i] = sw_r32(rtl_table_data(q, i));
rtl_table_release(q);
{
u32 r[3];
struct table_reg *q = rtl_table_get(RTL8380_TBL_L2, 1); /* Access L2 Table 1 */
- int i;
rtl838x_fill_l2_row(r, e);
- for (i = 0; i < 3; i++)
+ for (int i = 0; i < 3; i++)
sw_w32(r[i], rtl_table_data(q, i));
rtl_table_write(q, idx);
}
+static void rtl838x_set_static_move_action(int port, bool forward)
+{
+ int shift = MV_ACT_PORT_SHIFT(port);
+ u32 val = forward ? MV_ACT_FORWARD : MV_ACT_DROP;
+
+ sw_w32_mask(MV_ACT_MASK << shift, val << shift,
+ RTL838X_L2_PORT_STATIC_MV_ACT(port));
+}
+
static void rtl838x_stp_get(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
{
- int i;
u32 cmd = 1 << 15 | /* Execute cmd */
1 << 14 | /* Read */
2 << 12 | /* Table type 0b10 */
(msti & 0xfff);
priv->r->exec_tbl0_cmd(cmd);
- for (i = 0; i < 2; i++)
+ for (int i = 0; i < 2; i++)
port_state[i] = sw_r32(priv->r->tbl_access_data_0(i));
}
static void rtl838x_stp_set(struct rtl838x_switch_priv *priv, u16 msti, u32 port_state[])
{
- int i;
u32 cmd = 1 << 15 | /* Execute cmd */
0 << 14 | /* Write */
2 << 12 | /* Table type 0b10 */
(msti & 0xfff);
- for (i = 0; i < 2; i++)
+ for (int i = 0; i < 2; i++)
sw_w32(port_state[i], priv->r->tbl_access_data_0(i));
priv->r->exec_tbl0_cmd(cmd);
}
static void rtl838x_init_eee(struct rtl838x_switch_priv *priv, bool enable)
{
- int i;
-
pr_info("Setting up EEE, state: %d\n", enable);
sw_w32_mask(0x4, 0, RTL838X_SMI_GLB_CTRL);
sw_w32(0x5001417, RTL838X_EEE_TX_TIMER_GELITE_CTRL);
/* Enable EEE MAC support on ports */
- for (i = 0; i < priv->cpu_port; i++) {
+ for (int i = 0; i < priv->cpu_port; i++) {
if (priv->ports[i].phy)
rtl838x_port_eee_set(priv, i, enable);
}
int block_from = index_from / PIE_BLOCK_SIZE;
int block_to = index_to / PIE_BLOCK_SIZE;
u32 v = (index_from << 1)| (index_to << 12 ) | BIT(0);
- int block;
u32 block_state;
pr_debug("%s: from %d to %d\n", __func__, index_from, index_to);
block_state = sw_r32(RTL838X_ACL_BLK_LOOKUP_CTRL);
/* Make sure rule-lookup is disabled in the relevant blocks */
- for (block = block_from; block <= block_to; block++) {
+ for (int block = block_from; block <= block_to; block++) {
if (block_state & BIT(block))
sw_w32(block_state & (~BIT(block)), RTL838X_ACL_BLK_LOOKUP_CTRL);
}
} while (sw_r32(RTL838X_ACL_CLR_CTRL) & BIT(0));
/* Re-enable rule lookup */
- for (block = block_from; block <= block_to; block++) {
+ for (int block = block_from; block <= block_to; block++) {
if (!(block_state & BIT(block)))
sw_w32(block_state | BIT(block), RTL838X_ACL_BLK_LOOKUP_CTRL);
}
*/
static void rtl838x_write_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[])
{
- int i;
- enum template_field_id field_type;
- u16 data, data_m;
-
- for (i = 0; i < N_FIXED_FIELDS; i++) {
- field_type = t[i];
- data = data_m = 0;
+ for (int i = 0; i < N_FIXED_FIELDS; i++) {
+ enum template_field_id field_type = t[i];
+ u16 data = 0, data_m = 0;
switch (field_type) {
case TEMPLATE_FIELD_SPM0:
*/
static void rtl838x_read_pie_templated(u32 r[], struct pie_rule *pr, enum template_field_id t[])
{
- int i;
- enum template_field_id field_type;
- u16 data, data_m;
+ for (int i = 0; i < N_FIXED_FIELDS; i++) {
+ enum template_field_id field_type = t[i];
+ u16 data, data_m;
- for (i = 0; i < N_FIXED_FIELDS; i++) {
field_type = t[i];
if (!(i % 2)) {
data = r[5 - i / 2];
pr_info("Sel : %08x\n", r[17]);
}
-static void rtl838x_pie_rule_dump(struct pie_rule *pr)
-{
- pr_info("Drop: %d, fwd: %d, ovid: %d, ivid: %d, flt: %d, log: %d, rmk: %d, meter: %d tagst: %d, mir: %d, nopri: %d, cpupri: %d, otpid: %d, itpid: %d, shape: %d\n",
- pr->drop, pr->fwd_sel, pr->ovid_sel, pr->ivid_sel, pr->flt_sel, pr->log_sel, pr->rmk_sel, pr->log_sel, pr->tagst_sel, pr->mir_sel, pr->nopri_sel,
- pr->cpupri_sel, pr->otpid_sel, pr->itpid_sel, pr->shaper_sel);
- if (pr->fwd_sel)
- pr_info("FWD: %08x\n", pr->fwd_data);
- pr_info("TID: %x, %x\n", pr->tid, pr->tid_m);
-}
+// Currently not used
+// static void rtl838x_pie_rule_dump(struct pie_rule *pr)
+// {
+// pr_info("Drop: %d, fwd: %d, ovid: %d, ivid: %d, flt: %d, log: %d, rmk: %d, meter: %d tagst: %d, mir: %d, nopri: %d, cpupri: %d, otpid: %d, itpid: %d, shape: %d\n",
+// pr->drop, pr->fwd_sel, pr->ovid_sel, pr->ivid_sel, pr->flt_sel, pr->log_sel, pr->rmk_sel, pr->log_sel, pr->tagst_sel, pr->mir_sel, pr->nopri_sel,
+// pr->cpupri_sel, pr->otpid_sel, pr->itpid_sel, pr->shaper_sel);
+// if (pr->fwd_sel)
+// pr_info("FWD: %08x\n", pr->fwd_data);
+// pr_info("TID: %x, %x\n", pr->tid, pr->tid_m);
+// }
static int rtl838x_pie_rule_read(struct rtl838x_switch_priv *priv, int idx, struct pie_rule *pr)
{
/* Read IACL table (1) via register 0 */
struct table_reg *q = rtl_table_get(RTL8380_TBL_0, 1);
u32 r[18];
- int i;
int block = idx / PIE_BLOCK_SIZE;
u32 t_select = sw_r32(RTL838X_ACL_BLK_TMPLTE_CTRL(block));
memset(pr, 0, sizeof(*pr));
rtl_table_read(q, idx);
- for (i = 0; i < 18; i++)
+ for (int i = 0; i < 18; i++)
r[i] = sw_r32(rtl_table_data(q, i));
rtl_table_release(q);
/* Access IACL table (1) via register 0 */
struct table_reg *q = rtl_table_get(RTL8380_TBL_0, 1);
u32 r[18];
- int i, err = 0;
+ int err;
int block = idx / PIE_BLOCK_SIZE;
u32 t_select = sw_r32(RTL838X_ACL_BLK_TMPLTE_CTRL(block));
pr_debug("%s: %d, t_select: %08x\n", __func__, idx, t_select);
- for (i = 0; i < 18; i++)
+ for (int i = 0; i < 18; i++)
r[i] = 0;
- if (!pr->valid)
- goto err_out;
+ if (!pr->valid) {
+ err = -EINVAL;
+ pr_err("Rule invalid\n");
+ goto errout;
+ }
rtl838x_write_pie_fixed_fields(r, pr);
pr_debug("%s: template %d\n", __func__, (t_select >> (pr->tid * 3)) & 0x7);
rtl838x_write_pie_templated(r, pr, fixed_templates[(t_select >> (pr->tid * 3)) & 0x7]);
- if (rtl838x_write_pie_action(r, pr)) {
+ err = rtl838x_write_pie_action(r, pr);
+ if (err) {
pr_err("Rule actions too complex\n");
- goto err_out;
+ goto errout;
}
/* rtl838x_pie_rule_dump_raw(r); */
- for (i = 0; i < 18; i++)
+ for (int i = 0; i < 18; i++)
sw_w32(r[i], rtl_table_data(q, i));
-err_out:
+errout:
rtl_table_write(q, idx);
rtl_table_release(q);
static bool rtl838x_pie_templ_has(int t, enum template_field_id field_type)
{
- int i;
enum template_field_id ft;
- for (i = 0; i < N_FIXED_FIELDS; i++) {
+ for (int i = 0; i < N_FIXED_FIELDS; i++) {
ft = fixed_templates[t][i];
if (field_type == ft)
return true;
static int rtl838x_pie_rule_add(struct rtl838x_switch_priv *priv, struct pie_rule *pr)
{
- int idx, block, j, t;
+ int idx, block, j;
pr_debug("In %s\n", __func__);
for (block = 0; block < priv->n_pie_blocks; block++) {
for (j = 0; j < 3; j++) {
- t = (sw_r32(RTL838X_ACL_BLK_TMPLTE_CTRL(block)) >> (j * 3)) & 0x7;
+ int t = (sw_r32(RTL838X_ACL_BLK_TMPLTE_CTRL(block)) >> (j * 3)) & 0x7;
pr_debug("Testing block %d, template %d, template id %d\n", block, j, t);
idx = rtl838x_pie_verify_template(priv, pr, t, block);
if (idx >= 0)
*/
static void rtl838x_pie_init(struct rtl838x_switch_priv *priv)
{
- int i;
u32 template_selectors;
mutex_init(&priv->pie_mutex);
/* Enable ACL lookup on all ports, including CPU_PORT */
- for (i = 0; i <= priv->cpu_port; i++)
+ for (int i = 0; i <= priv->cpu_port; i++)
sw_w32(1, RTL838X_ACL_PORT_LOOKUP_CTRL(i));
/* Power on all PIE blocks */
- for (i = 0; i < priv->n_pie_blocks; i++)
+ for (int i = 0; i < priv->n_pie_blocks; i++)
sw_w32_mask(0, BIT(i), RTL838X_ACL_BLK_PWR_CTRL);
/* Include IPG in metering */
/* Enable predefined templates 0, 1 and 2 for even blocks */
template_selectors = 0 | (1 << 3) | (2 << 6);
- for (i = 0; i < 6; i += 2)
+ for (int i = 0; i < 6; i += 2)
sw_w32(template_selectors, RTL838X_ACL_BLK_TMPLTE_CTRL(i));
/* Enable predefined templates 0, 3 and 4 (IPv6 support) for odd blocks */
template_selectors = 0 | (3 << 3) | (4 << 6);
- for (i = 1; i < priv->n_pie_blocks; i += 2)
+ for (int i = 1; i < priv->n_pie_blocks; i += 2)
sw_w32(template_selectors, RTL838X_ACL_BLK_TMPLTE_CTRL(i));
/* Group each pair of physical blocks together to a logical block */
.enable_flood = rtl838x_enable_flood,
.enable_mcast_flood = rtl838x_enable_mcast_flood,
.enable_bcast_flood = rtl838x_enable_bcast_flood,
+ .set_static_move_action = rtl838x_set_static_move_action,
.stp_get = rtl838x_stp_get,
.stp_set = rtl838x_stp_set,
.mac_port_ctrl = rtl838x_mac_port_ctrl,
u32 status = sw_r32(RTL838X_ISR_GLB_SRC);
u32 ports = sw_r32(RTL838X_ISR_PORT_LINK_STS_CHG);
u32 link;
- int i;
/* Clear status */
sw_w32(ports, RTL838X_ISR_PORT_LINK_STS_CHG);
pr_info("RTL8380 Link change: status: %x, ports %x\n", status, ports);
- for (i = 0; i < 28; i++) {
+ for (int i = 0; i < 28; i++) {
if (ports & BIT(i)) {
link = sw_r32(RTL838X_MAC_LINK_STS);
if (link & BIT(i))
/* Reads a register in a page from the PHY */
int rtl838x_read_phy(u32 port, u32 page, u32 reg, u32 *val)
{
- int err = -ETIMEDOUT;
+ int err;
u32 v;
u32 park_page;
mutex_lock(&smi_lock);
- if (rtl838x_smi_wait_op(100000))
- goto timeout;
+ err = rtl838x_smi_wait_op(100000);
+ if (err)
+ goto errout;
sw_w32_mask(0xffff0000, port << 16, RTL838X_SMI_ACCESS_PHY_CTRL_2);
sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
- if (rtl838x_smi_wait_op(100000))
- goto timeout;
+ err = rtl838x_smi_wait_op(100000);
+ if (err)
+ goto errout;
*val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
err = 0;
-timeout:
+errout:
mutex_unlock(&smi_lock);
- return -ETIMEDOUT;
+ return err;
}
/* Write to a register in a page of the PHY */
int rtl838x_write_phy(u32 port, u32 page, u32 reg, u32 val)
{
- int err = -ETIMEDOUT;
+ int err;
u32 v;
u32 park_page;
return -ENOTSUPP;
mutex_lock(&smi_lock);
- if (rtl838x_smi_wait_op(100000))
- goto timeout;
+ err = rtl838x_smi_wait_op(100000);
+ if (err)
+ goto errout;
sw_w32(BIT(port), RTL838X_SMI_ACCESS_PHY_CTRL_0);
mdelay(10);
sw_w32(v | park_page, RTL838X_SMI_ACCESS_PHY_CTRL_1);
sw_w32_mask(0, 1, RTL838X_SMI_ACCESS_PHY_CTRL_1);
- if (rtl838x_smi_wait_op(100000))
- goto timeout;
+ err = rtl838x_smi_wait_op(100000);
+ if (err)
+ goto errout;
err = 0;
-timeout:
+errout:
mutex_unlock(&smi_lock);
- return -ETIMEDOUT;
+ return err;
}
/* Read an mmd register of a PHY */
int rtl838x_read_mmd_phy(u32 port, u32 addr, u32 reg, u32 *val)
{
- int err = -ETIMEDOUT;
+ int err;
u32 v;
mutex_lock(&smi_lock);
- if (rtl838x_smi_wait_op(100000))
- goto timeout;
+ err = rtl838x_smi_wait_op(100000);
+ if (err)
+ goto errout;
sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
mdelay(10);
v = 1 << 1 | 0 << 2 | 1;
sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
- if (rtl838x_smi_wait_op(100000))
- goto timeout;
+ err = rtl838x_smi_wait_op(100000);
+ if (err)
+ goto errout;
*val = sw_r32(RTL838X_SMI_ACCESS_PHY_CTRL_2) & 0xffff;
err = 0;
-timeout:
+errout:
mutex_unlock(&smi_lock);
return err;
/* Write to an mmd register of a PHY */
int rtl838x_write_mmd_phy(u32 port, u32 addr, u32 reg, u32 val)
{
- int err = -ETIMEDOUT;
+ int err;
u32 v;
pr_debug("MMD write: port %d, dev %d, reg %d, val %x\n", port, addr, reg, val);
val &= 0xffff;
mutex_lock(&smi_lock);
- if (rtl838x_smi_wait_op(100000))
- goto timeout;
+ err = rtl838x_smi_wait_op(100000);
+ if (err)
+ goto errout;
sw_w32(1 << port, RTL838X_SMI_ACCESS_PHY_CTRL_0);
mdelay(10);
v = 1 << 1 | 1 << 2 | 1;
sw_w32(v, RTL838X_SMI_ACCESS_PHY_CTRL_1);
- if (rtl838x_smi_wait_op(100000))
- goto timeout;
+ err = rtl838x_smi_wait_op(100000);
+ if (err)
+ goto errout;
err = 0;
-timeout:
+errout:
mutex_unlock(&smi_lock);
return err;
}