blob: add4e2e2836af2ebeb1e5082c1ba52966498d371 [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"
#if defined(IN_SWCONFIG)
int
_qca_ar8327_sw_capture_port_counter(struct switch_dev *dev, int port)
{
fal_mib_info_t mib_Info;
struct qca_phy_priv *priv = qca_phy_priv_get(dev);
memset(&mib_Info, 0, sizeof(mib_Info));
fal_get_mib_info(priv->device_id, port, &mib_Info);
return 0;
}
int
qca_ar8327_sw_set_reset_mibs(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
int i = 0;
int len = 0;
struct qca_phy_priv *priv = qca_phy_priv_get(dev);
fal_mib_info_t mib_Info;
len = dev->ports * QCA_MIB_ITEM_NUMBER *
sizeof(*priv->mib_counters);
mutex_lock(&priv->mib_lock);
memset(priv->mib_counters, '\0', len);
for (i = 0; i < dev->ports; i++)
{
fal_get_mib_info(priv->device_id, i, &mib_Info);
fal_mib_port_flush_counters(priv->device_id, i);
}
mutex_unlock(&priv->mib_lock);
return 0;
}
int
qca_ar8327_sw_set_port_reset_mib(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
int len = 0;
struct qca_phy_priv *priv = qca_phy_priv_get(dev);
fal_mib_info_t mib_Info;
len = QCA_MIB_ITEM_NUMBER * sizeof(*priv->mib_counters);
mutex_lock(&priv->mib_lock);
memset(priv->mib_counters + (val->port_vlan * QCA_MIB_ITEM_NUMBER), '\0', len);
fal_get_mib_info(priv->device_id, val->port_vlan, &mib_Info);
fal_mib_port_flush_counters(priv->device_id, val->port_vlan);
mutex_unlock(&priv->mib_lock);
return 0;
}
#ifdef HPPE
static int qca_ar8327_sw_print_xgport_mib(struct switch_dev *dev,
const struct switch_attr *attr, struct switch_val *val)
{
int port = 0;
int len = 0;
fal_xgmib_info_t xgmib_info;
struct qca_phy_priv *priv = qca_phy_priv_get(dev);
char *buf = (char *)(priv->buf);
port = val->port_vlan;
if (port >= dev->ports)
return -EINVAL;
fal_get_xgmib_info(priv->device_id, port, &xgmib_info);
mutex_lock(&priv->mib_lock);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"XG Port %d MIB counters\n",
port);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxFrame", xgmib_info.RxFrame);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxByte", xgmib_info.RxByte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxByteGood", xgmib_info.RxByteGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxBroadGood", xgmib_info.RxBroadGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxMultiGood", xgmib_info.RxMultiGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxFcsErr", xgmib_info.RxFcsErr);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxRuntErr", xgmib_info.RxRuntErr );
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxJabberError", xgmib_info.RxJabberError);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxUndersizeGood", xgmib_info.RxUndersizeGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxOversizeGood", xgmib_info.RxOversizeGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Rx64Byte", xgmib_info.Rx64Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Rx128Byte", xgmib_info.Rx128Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Rx256Byte", xgmib_info.Rx256Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Rx512Byte", xgmib_info.Rx512Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Rx1024Byte", xgmib_info.Rx1024Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxMaxByte", xgmib_info.RxMaxByte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxUnicastGood", xgmib_info.RxUnicastGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxLengthError", xgmib_info.RxLengthError);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxOutOfRangeError", xgmib_info.RxOutOfRangeError);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxPause", xgmib_info.RxPause);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxOverFlow", xgmib_info.RxOverFlow);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxVLANFrameGoodBad", xgmib_info.RxVLANFrameGoodBad);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxWatchDogError", xgmib_info.RxWatchDogError);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxLPIUsec", xgmib_info.RxLPIUsec);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxLPITran", xgmib_info.RxLPITran);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxDropFrameGoodBad", xgmib_info.RxDropFrameGoodBad);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "RxDropByteGoodBad", xgmib_info.RxDropByteGoodBad);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxByte", xgmib_info.TxByte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxFrame", xgmib_info.TxFrame);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxBroadGood", xgmib_info.TxBroadGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxMultiGood", xgmib_info.TxMultiGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Tx64Byte", xgmib_info.Tx64Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Tx128Byte", xgmib_info.Tx128Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Tx256Byte", xgmib_info.Tx256Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Tx512Byte", xgmib_info.Tx512Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "Tx1024Byte", xgmib_info.Tx1024Byte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxMaxByte", xgmib_info.TxMaxByte);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxUnicast", xgmib_info.TxUnicast);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxMulti", xgmib_info.TxMulti);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxBroad", xgmib_info.TxBroad);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxUnderFlowError", xgmib_info.TxUnderFlowError);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxByteGood", xgmib_info.TxByteGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxByteGood", xgmib_info.TxByteGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxPause", xgmib_info.TxPause);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxVLANFrameGood", xgmib_info.TxVLANFrameGood);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxLPIUsec", xgmib_info.TxLPIUsec);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-18s: %llu\n", "TxLPITran", xgmib_info.TxLPITran);
mutex_unlock(&priv->mib_lock);
val->value.s = buf;
val->len = len;
return 0;
}
#endif
int
qca_ar8327_sw_get_port_mib(struct switch_dev *dev,
const struct switch_attr *attr,
struct switch_val *val)
{
int port = 0;
int len = 0;
int pos = 0;
struct qca_phy_priv *priv = qca_phy_priv_get(dev);
char *buf = (char *)(priv->buf);
port = val->port_vlan;
if (port >= dev->ports)
return -EINVAL;
#ifdef HPPE
if (priv->version == QCA_VER_HPPE &&
qca_hppe_port_mac_type_get(priv->device_id, port) == PORT_XGMAC_TYPE)
{
qca_ar8327_sw_print_xgport_mib(dev, attr, val);
return 0;
}
#endif
mutex_lock(&priv->mib_lock);
_qca_ar8327_sw_capture_port_counter(dev, port);
pos = port * (sizeof(fal_mib_counter_t)/sizeof(a_uint64_t));
len += snprintf(buf + len, sizeof(priv->buf) - len,
"Port %d MIB counters\n",
port);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxBroad",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxPause",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxMulti",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxFcsErr",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxAlignErr",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxRunt",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxFragment",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Rx64Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Rx128Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Rx256Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Rx512Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Rx1024Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Rx1518Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxMaxByte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxTooLong",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxGoodByte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxBadByte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxOverFlow",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Filtered",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxBroad",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxPause",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxMulti",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxUnderRun",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Tx64Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Tx128Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Tx256Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Tx512Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Tx1024Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"Tx1518Byte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxMaxByte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxOverSize",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxByte",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxCollision",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxAbortCol",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxMultiCol",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxSingleCol",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxExcDefer",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxDefer",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxLateCol",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"RxUniCast",
priv->mib_counters[pos++]);
len += snprintf(buf + len, sizeof(priv->buf) - len,
"%-12s: %llu\n",
"TxUniCast",
priv->mib_counters[pos++]);
mutex_unlock(&priv->mib_lock);
val->value.s = buf;
val->len = len;
return 0;
}
#endif
int
_qca_ar8327_sw_capture_port_tx_counter(struct qca_phy_priv *priv, int port)
{
fal_mib_info_t mib_Info;
memset(&mib_Info, 0, sizeof(fal_mib_info_t));
fal_get_tx_mib_info(priv->device_id, port, &mib_Info);
return 0;
}
int
_qca_ar8327_sw_capture_port_rx_counter(struct qca_phy_priv *priv, int port)
{
fal_mib_info_t mib_Info;
memset(&mib_Info, 0, sizeof(fal_mib_info_t));
fal_get_rx_mib_info(priv->device_id, port, &mib_Info);
return 0;
}
void
qca_ar8327_sw_mib_task(struct qca_phy_priv *priv)
{
static int loop = 0;
mutex_lock(&priv->reg_mutex);
if ((loop % 2) == 0)
_qca_ar8327_sw_capture_port_rx_counter(priv, loop/2);
else
_qca_ar8327_sw_capture_port_tx_counter(priv, loop/2);
if(++loop == (2 * (priv->ports))) {
loop = 0;
}
mutex_unlock(&priv->reg_mutex);
return;
}