blob: 7c1a5fcc91871db434fe733b420bd8d522cdd9c8 [file] [log] [blame]
/*
* Copyright (c) 2012, 2017, The Linux Foundation. All rights reserved.
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
* OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "sw.h"
#include "ssdk_init.h"
#include "fal_init.h"
#include "fal_misc.h"
#include "fal_mib.h"
#include "fal_port_ctrl.h"
#include "fal_portvlan.h"
#include "fal_fdb.h"
#include "fal_stp.h"
#include "fal_igmp.h"
#include "fal_qos.h"
#include "hsl.h"
#include "hsl_dev.h"
#include "ssdk_init.h"
#include <linux/kconfig.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/phy.h>
#include <linux/platform_device.h>
#include <linux/types.h>
//#include <asm/mach-types.h>
#include <generated/autoconf.h>
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,14,0))
#include <linux/ar8216_platform.h>
#endif
#include <linux/delay.h>
#include <linux/phy.h>
#include <linux/netdevice.h>
#include "ssdk_plat.h"
#include "ref_vlan.h"
#include "ref_fdb.h"
#if defined(IN_SWCONFIG)
int
qca_ar8327_sw_atu_flush(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
struct qca_phy_priv *priv = qca_phy_priv_get(dev);
/* 0: dynamic 1:dynamic, static */
fal_fdb_entry_flush(priv->device_id, 1);
return 0;
}
int
qca_ar8327_sw_atu_dump(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
struct qca_phy_priv *priv = qca_phy_priv_get(dev);
a_uint32_t rv;
char *buf;
a_uint32_t len = 0;
a_uint32_t i = 0;
fal_fdb_op_t option;
fal_fdb_entry_t entry;
fal_pbmp_t port_bmp = 0;
a_uint32_t port_type = 0;
buf = (char*) priv->buf;
memset(buf, 0, 2048);
memset(&option, 0, sizeof(fal_fdb_op_t));
memset(&entry, 0, sizeof(fal_fdb_entry_t));
if (priv->version == QCA_VER_AR8227)
rv = fal_fdb_entry_getfirst(priv->device_id, &entry);
else
rv = fal_fdb_entry_extend_getfirst(priv->device_id, &option, &entry);
while (!rv)
{
len += snprintf(buf+len, 2048-len, "MAC: %02x:%02x:%02x:%02x:%02x:%02x ",
entry.addr.uc[0],entry.addr.uc[1],entry.addr.uc[2],entry.addr.uc[3],
entry.addr.uc[4],entry.addr.uc[5]);
if(entry.portmap_en == A_TRUE) {
port_bmp = entry.port.map;
len += snprintf(buf+len, 2048-len,
"PORTMAP: 0x%02x VID: 0x%x STATUS: 0x%x\n",
port_bmp, entry.fid, entry.static_en);
} else {
port_type = FAL_PORT_ID_TYPE(entry.port.id);
if(port_type == FAL_PORT_TYPE_PPORT) {
port_bmp = 1 << entry.port.id;
len += snprintf(buf+len, 2048-len,
"PORTMAP: 0x%02x VID: 0x%x STATUS: 0x%x\n",
port_bmp, entry.fid, entry.static_en);
} else {
len += snprintf(buf+len, 2048-len,
"DEST_INFO: 0x%02x VID: 0x%x STATUS: 0x%x\n",
entry.port.id, entry.fid, entry.static_en);
}
}
if (2048-len < 74){
// snprintf(buf+len, 2048-len, "Buffer not enough!\n");
break;
}
if (priv->version == QCA_VER_AR8227)
rv = fal_fdb_entry_getnext_byindex(priv->device_id, &i, &entry);
else
rv = fal_fdb_entry_extend_getnext(priv->device_id, &option, &entry);
}
val->value.s = (char*)(priv->buf);
val->len = len;
return 0;
}
#endif
#define MAX_PORT 6
/*
* example:
* vid=4;
* char addr[6] = {0x00, 0x01, 0x02, 0x88, 0x00, 0xaa}
*
* return value:
* success: 0 - 5
* fail: 0xffffffff
*/
fal_port_t
ref_fdb_get_port_by_mac(unsigned int vid, const char * addr)
{
fal_fdb_entry_t entry;
unsigned char i;
sw_error_t rv;
a_uint32_t dev_id = 0;
memset(&entry, 0, sizeof(entry));
SSDK_DEBUG("the fdb entry with MAC:%x-%x-%x-%x-%x-%x, fid:%d will be searched\n",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5], vid);
entry.fid = vid;
for (i = 0; i < 6; i++)
entry.addr.uc[i] = addr[i];
for(dev_id = 0; dev_id < SW_MAX_NR_DEV; dev_id++)
{
rv = fal_fdb_find(dev_id, &entry);
if (rv == SW_OK)
{
SSDK_DEBUG("device %d have the entry\n", dev_id);
break;
}
}
if(rv != SW_OK)
{
SSDK_DEBUG("the entry cannot be found\n");
return 0xffffffff;
}
for (i = 0; i < MAX_PORT; i++)
{
if (entry.port.id & (0x1 << i))
{
return i;
}
}
return 0xffffffff;
}
EXPORT_SYMBOL(ref_fdb_get_port_by_mac);