mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-07 05:34:28 +00:00
75 lines
2.2 KiB
C
75 lines
2.2 KiB
C
|
// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
|
||
|
/*
|
||
|
* Copyright (c) 2018 Microsemi Corporation
|
||
|
*/
|
||
|
|
||
|
#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);
|
||
|
}
|