| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- /*
- * Copyright (c) 2018 Microsemi Corporation
- */
- #include <linux/bitops.h>
- #include <linux/io.h>
- #include "mscc_mac_table.h"
- #define ANA_TABLES_MACACCESS_VALID BIT(11)
- #define ANA_TABLES_MACACCESS_ENTRYTYPE(x) ((x) << 9)
- #define ANA_TABLES_MACACCESS_DEST_IDX(x) ((x) << 3)
- #define ANA_TABLES_MACACCESS_MAC_TABLE_CMD(x) (x)
- #define ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M GENMASK(2, 0)
- #define MACACCESS_CMD_IDLE 0
- #define MACACCESS_CMD_LEARN 1
- /* MAC table entry types.
- * ENTRYTYPE_NORMAL is subject to aging.
- * ENTRYTYPE_LOCKED is not subject to aging.
- */
- enum macaccess_entry_type {
- ENTRYTYPE_NORMAL = 0,
- ENTRYTYPE_LOCKED,
- };
- static int vlan_wait_for_completion(void __iomem *regs,
- const unsigned long *mscc_mac_table_offset)
- {
- unsigned int val, timeout = 10;
- /* Wait for the issued mac table command to be completed, or timeout.
- * When the command read from ANA_TABLES_MACACCESS is
- * MACACCESS_CMD_IDLE, the issued command completed successfully.
- */
- do {
- val = readl(regs +
- mscc_mac_table_offset[MSCC_ANA_TABLES_MACACCESS]);
- val &= ANA_TABLES_MACACCESS_MAC_TABLE_CMD_M;
- } while (val != MACACCESS_CMD_IDLE && timeout--);
- if (!timeout)
- return -ETIMEDOUT;
- return 0;
- }
- int mscc_mac_table_add(void __iomem *regs,
- const unsigned long *mscc_mac_table_offset,
- const unsigned char mac[ETH_LEN], int pgid)
- {
- u32 macl = 0, mach = 0;
- /* Set the MAC address to handle and the vlan associated in a format
- * understood by the hardware.
- */
- mach |= MAC_VID << 16;
- mach |= ((u32)mac[0]) << 8;
- mach |= ((u32)mac[1]) << 0;
- macl |= ((u32)mac[2]) << 24;
- macl |= ((u32)mac[3]) << 16;
- macl |= ((u32)mac[4]) << 8;
- macl |= ((u32)mac[5]) << 0;
- writel(macl, regs + mscc_mac_table_offset[MSCC_ANA_TABLES_MACLDATA]);
- writel(mach, regs + mscc_mac_table_offset[MSCC_ANA_TABLES_MACHDATA]);
- writel(ANA_TABLES_MACACCESS_VALID |
- ANA_TABLES_MACACCESS_DEST_IDX(pgid) |
- ANA_TABLES_MACACCESS_ENTRYTYPE(ENTRYTYPE_LOCKED) |
- ANA_TABLES_MACACCESS_MAC_TABLE_CMD(MACACCESS_CMD_LEARN),
- regs + mscc_mac_table_offset[MSCC_ANA_TABLES_MACACCESS]);
- return vlan_wait_for_completion(regs, mscc_mac_table_offset);
- }
|