Initial commit
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled
Some checks failed
Build Kernel / Build all affected Kernels (push) Has been cancelled
Build all core packages / Build all core packages for selected target (push) Has been cancelled
Build and Push prebuilt tools container / Build and Push all prebuilt containers (push) Has been cancelled
Build Toolchains / Build Toolchains for each target (push) Has been cancelled
Build host tools / Build host tools for linux and macos based systems (push) Has been cancelled
Coverity scan build / Coverity x86/64 build (push) Has been cancelled
This commit is contained in:
580
target/linux/mediatek/files/drivers/net/phy/rtk/rtl8367s.c
Normal file
580
target/linux/mediatek/files/drivers/net/phy/rtk/rtl8367s.c
Normal file
@@ -0,0 +1,580 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/switch.h>
|
||||
|
||||
//include from rtl8367c dir
|
||||
#include "./rtl8367c/include/rtk_switch.h"
|
||||
#include "./rtl8367c/include/vlan.h"
|
||||
#include "./rtl8367c/include/stat.h"
|
||||
#include "./rtl8367c/include/port.h"
|
||||
|
||||
#define RTL8367C_SW_CPU_PORT 6
|
||||
|
||||
//RTL8367C_PHY_PORT_NUM + ext0 + ext1
|
||||
#define RTL8367C_NUM_PORTS 7
|
||||
#define RTL8367C_NUM_VIDS 4096
|
||||
|
||||
struct rtl8367_priv {
|
||||
struct switch_dev swdev;
|
||||
bool global_vlan_enable;
|
||||
};
|
||||
|
||||
struct rtl8367_mib_counter {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct rtl8367_vlan_info {
|
||||
unsigned short vid;
|
||||
unsigned int untag;
|
||||
unsigned int member;
|
||||
unsigned char fid;
|
||||
};
|
||||
|
||||
struct rtl8367_priv rtl8367_priv_data;
|
||||
|
||||
unsigned int rtl8367c_port_id[RTL8367C_NUM_PORTS]={0,1,2,3,4,EXT_PORT1,EXT_PORT0};
|
||||
|
||||
void (*rtl8367_switch_reset_func)(void)=NULL;
|
||||
|
||||
static struct rtl8367_mib_counter rtl8367c_mib_counters[] = {
|
||||
{"ifInOctets"},
|
||||
{"dot3StatsFCSErrors"},
|
||||
{"dot3StatsSymbolErrors"},
|
||||
{"dot3InPauseFrames"},
|
||||
{"dot3ControlInUnknownOpcodes"},
|
||||
{"etherStatsFragments"},
|
||||
{"etherStatsJabbers"},
|
||||
{"ifInUcastPkts"},
|
||||
{"etherStatsDropEvents"},
|
||||
{"etherStatsOctets"},
|
||||
{"etherStatsUndersizePkts"},
|
||||
{"etherStatsOversizePkts"},
|
||||
{"etherStatsPkts64Octets"},
|
||||
{"etherStatsPkts65to127Octets"},
|
||||
{"etherStatsPkts128to255Octets"},
|
||||
{"etherStatsPkts256to511Octets"},
|
||||
{"etherStatsPkts512to1023Octets"},
|
||||
{"etherStatsPkts1024toMaxOctets"},
|
||||
{"etherStatsMcastPkts"},
|
||||
{"etherStatsBcastPkts"},
|
||||
{"ifOutOctets"},
|
||||
{"dot3StatsSingleCollisionFrames"},
|
||||
{"dot3StatsMultipleCollisionFrames"},
|
||||
{"dot3StatsDeferredTransmissions"},
|
||||
{"dot3StatsLateCollisions"},
|
||||
{"etherStatsCollisions"},
|
||||
{"dot3StatsExcessiveCollisions"},
|
||||
{"dot3OutPauseFrames"},
|
||||
{"dot1dBasePortDelayExceededDiscards"},
|
||||
{"dot1dTpPortInDiscards"},
|
||||
{"ifOutUcastPkts"},
|
||||
{"ifOutMulticastPkts"},
|
||||
{"ifOutBrocastPkts"},
|
||||
{"outOampduPkts"},
|
||||
{"inOampduPkts"},
|
||||
{"pktgenPkts"},
|
||||
{"inMldChecksumError"},
|
||||
{"inIgmpChecksumError"},
|
||||
{"inMldSpecificQuery"},
|
||||
{"inMldGeneralQuery"},
|
||||
{"inIgmpSpecificQuery"},
|
||||
{"inIgmpGeneralQuery"},
|
||||
{"inMldLeaves"},
|
||||
{"inIgmpLeaves"},
|
||||
{"inIgmpJoinsSuccess"},
|
||||
{"inIgmpJoinsFail"},
|
||||
{"inMldJoinsSuccess"},
|
||||
{"inMldJoinsFail"},
|
||||
{"inReportSuppressionDrop"},
|
||||
{"inLeaveSuppressionDrop"},
|
||||
{"outIgmpReports"},
|
||||
{"outIgmpLeaves"},
|
||||
{"outIgmpGeneralQuery"},
|
||||
{"outIgmpSpecificQuery"},
|
||||
{"outMldReports"},
|
||||
{"outMldLeaves"},
|
||||
{"outMldGeneralQuery"},
|
||||
{"outMldSpecificQuery"},
|
||||
{"inKnownMulticastPkts"},
|
||||
{"ifInMulticastPkts"},
|
||||
{"ifInBroadcastPkts"},
|
||||
{"ifOutDiscards"}
|
||||
};
|
||||
|
||||
/*rtl8367c proprietary switch API wrapper */
|
||||
static inline unsigned int rtl8367c_sw_to_phy_port(int port)
|
||||
{
|
||||
return rtl8367c_port_id[port];
|
||||
}
|
||||
|
||||
static inline unsigned int rtl8367c_portmask_phy_to_sw(rtk_portmask_t phy_portmask)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < RTL8367C_NUM_PORTS; i++) {
|
||||
if(RTK_PORTMASK_IS_PORT_SET(phy_portmask,rtl8367c_sw_to_phy_port(i))) {
|
||||
RTK_PORTMASK_PORT_CLEAR(phy_portmask,rtl8367c_sw_to_phy_port(i));
|
||||
RTK_PORTMASK_PORT_SET(phy_portmask,i);
|
||||
}
|
||||
|
||||
}
|
||||
return (unsigned int)phy_portmask.bits[0];
|
||||
}
|
||||
|
||||
static int rtl8367c_reset_mibs(void)
|
||||
{
|
||||
return rtk_stat_global_reset();
|
||||
}
|
||||
|
||||
static int rtl8367c_reset_port_mibs(int port)
|
||||
{
|
||||
|
||||
return rtk_stat_port_reset(rtl8367c_sw_to_phy_port(port));
|
||||
}
|
||||
|
||||
static int rtl8367c_get_mibs_num(void)
|
||||
{
|
||||
return ARRAY_SIZE(rtl8367c_mib_counters);
|
||||
}
|
||||
|
||||
static const char *rtl8367c_get_mib_name(int idx)
|
||||
{
|
||||
|
||||
return rtl8367c_mib_counters[idx].name;
|
||||
}
|
||||
|
||||
static int rtl8367c_get_port_mib_counter(int idx, int port, unsigned long long *counter)
|
||||
{
|
||||
return rtk_stat_port_get(rtl8367c_sw_to_phy_port(port), idx, counter);
|
||||
}
|
||||
|
||||
static int rtl8367c_is_vlan_valid(unsigned int vlan)
|
||||
{
|
||||
unsigned max = RTL8367C_NUM_VIDS;
|
||||
|
||||
if (vlan == 0 || vlan >= max)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int rtl8367c_get_vlan( unsigned short vid, struct rtl8367_vlan_info *vlan)
|
||||
{
|
||||
rtk_vlan_cfg_t vlan_cfg;
|
||||
|
||||
memset(vlan, '\0', sizeof(struct rtl8367_vlan_info));
|
||||
|
||||
if (vid >= RTL8367C_NUM_VIDS)
|
||||
return -EINVAL;
|
||||
|
||||
if(rtk_vlan_get(vid,&vlan_cfg))
|
||||
return -EINVAL;
|
||||
|
||||
vlan->vid = vid;
|
||||
vlan->member = rtl8367c_portmask_phy_to_sw(vlan_cfg.mbr);
|
||||
vlan->untag = rtl8367c_portmask_phy_to_sw(vlan_cfg.untag);
|
||||
vlan->fid = vlan_cfg.fid_msti;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8367c_set_vlan( unsigned short vid, u32 mbr, u32 untag, u8 fid)
|
||||
{
|
||||
rtk_vlan_cfg_t vlan_cfg;
|
||||
int i;
|
||||
|
||||
memset(&vlan_cfg, 0x00, sizeof(rtk_vlan_cfg_t));
|
||||
|
||||
for (i = 0; i < RTL8367C_NUM_PORTS; i++) {
|
||||
if (mbr & (1 << i)) {
|
||||
RTK_PORTMASK_PORT_SET(vlan_cfg.mbr, rtl8367c_sw_to_phy_port(i));
|
||||
if(untag & (1 << i))
|
||||
RTK_PORTMASK_PORT_SET(vlan_cfg.untag, rtl8367c_sw_to_phy_port(i));
|
||||
}
|
||||
}
|
||||
vlan_cfg.fid_msti=fid;
|
||||
vlan_cfg.ivl_en = 1;
|
||||
return rtk_vlan_set(vid, &vlan_cfg);
|
||||
}
|
||||
|
||||
|
||||
static int rtl8367c_get_pvid( int port, int *pvid)
|
||||
{
|
||||
u32 prio=0;
|
||||
|
||||
if (port >= RTL8367C_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
return rtk_vlan_portPvid_get(rtl8367c_sw_to_phy_port(port),pvid,&prio);
|
||||
}
|
||||
|
||||
|
||||
static int rtl8367c_set_pvid( int port, int pvid)
|
||||
{
|
||||
u32 prio=0;
|
||||
|
||||
if (port >= RTL8367C_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
return rtk_vlan_portPvid_set(rtl8367c_sw_to_phy_port(port),pvid,prio);
|
||||
}
|
||||
|
||||
static int rtl8367c_get_port_link(int port, int *link, int *speed, int *duplex)
|
||||
{
|
||||
|
||||
if(rtk_port_phyStatus_get(rtl8367c_sw_to_phy_port(port),(rtk_port_linkStatus_t *)link,
|
||||
(rtk_port_speed_t *)speed,(rtk_port_duplex_t *)duplex))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*common rtl8367 swconfig entry API*/
|
||||
|
||||
static int
|
||||
rtl8367_sw_set_vlan_enable(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev);
|
||||
|
||||
priv->global_vlan_enable = val->value.i ;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
rtl8367_sw_get_vlan_enable(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
struct rtl8367_priv *priv = container_of(dev, struct rtl8367_priv, swdev);
|
||||
|
||||
val->value.i = priv->global_vlan_enable;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8367_sw_reset_mibs(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
return rtl8367c_reset_mibs();
|
||||
}
|
||||
|
||||
|
||||
static int rtl8367_sw_reset_port_mibs(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
int port;
|
||||
|
||||
port = val->port_vlan;
|
||||
if (port >= RTL8367C_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
return rtl8367c_reset_port_mibs(port);
|
||||
}
|
||||
|
||||
static int rtl8367_sw_get_port_mib(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
int i, len = 0;
|
||||
unsigned long long counter = 0;
|
||||
static char mib_buf[4096];
|
||||
|
||||
if (val->port_vlan >= RTL8367C_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
len += snprintf(mib_buf + len, sizeof(mib_buf) - len,
|
||||
"Port %d MIB counters\n",
|
||||
val->port_vlan);
|
||||
|
||||
for (i = 0; i <rtl8367c_get_mibs_num(); ++i) {
|
||||
len += snprintf(mib_buf + len, sizeof(mib_buf) - len,
|
||||
"%-36s: ",rtl8367c_get_mib_name(i));
|
||||
if (!rtl8367c_get_port_mib_counter(i, val->port_vlan,
|
||||
&counter))
|
||||
len += snprintf(mib_buf + len, sizeof(mib_buf) - len,
|
||||
"%llu\n", counter);
|
||||
else
|
||||
len += snprintf(mib_buf + len, sizeof(mib_buf) - len,
|
||||
"%s\n", "N/A");
|
||||
}
|
||||
|
||||
val->value.s = mib_buf;
|
||||
val->len = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int rtl8367_sw_get_vlan_info(struct switch_dev *dev,
|
||||
const struct switch_attr *attr,
|
||||
struct switch_val *val)
|
||||
{
|
||||
int i;
|
||||
u32 len = 0;
|
||||
struct rtl8367_vlan_info vlan;
|
||||
static char vlan_buf[256];
|
||||
int err;
|
||||
|
||||
if (!rtl8367c_is_vlan_valid(val->port_vlan))
|
||||
return -EINVAL;
|
||||
|
||||
memset(vlan_buf, '\0', sizeof(vlan_buf));
|
||||
|
||||
err = rtl8367c_get_vlan(val->port_vlan, &vlan);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
len += snprintf(vlan_buf + len, sizeof(vlan_buf) - len,
|
||||
"VLAN %d: Ports: '", vlan.vid);
|
||||
|
||||
for (i = 0; i <RTL8367C_NUM_PORTS; i++) {
|
||||
if (!(vlan.member & (1 << i)))
|
||||
continue;
|
||||
|
||||
len += snprintf(vlan_buf + len, sizeof(vlan_buf) - len, "%d%s", i,
|
||||
(vlan.untag & (1 << i)) ? "" : "t");
|
||||
}
|
||||
|
||||
len += snprintf(vlan_buf + len, sizeof(vlan_buf) - len,
|
||||
"', members=%04x, untag=%04x, fid=%u",
|
||||
vlan.member, vlan.untag, vlan.fid);
|
||||
|
||||
val->value.s = vlan_buf;
|
||||
val->len = len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int rtl8367_sw_get_vlan_ports(struct switch_dev *dev, struct switch_val *val)
|
||||
{
|
||||
struct switch_port *port;
|
||||
struct rtl8367_vlan_info vlan;
|
||||
int i;
|
||||
|
||||
if (!rtl8367c_is_vlan_valid(val->port_vlan))
|
||||
return -EINVAL;
|
||||
|
||||
if(rtl8367c_get_vlan(val->port_vlan, &vlan))
|
||||
return -EINVAL;
|
||||
|
||||
port = &val->value.ports[0];
|
||||
val->len = 0;
|
||||
for (i = 0; i <RTL8367C_NUM_PORTS ; i++) {
|
||||
if (!(vlan.member & BIT(i)))
|
||||
continue;
|
||||
|
||||
port->id = i;
|
||||
port->flags = (vlan.untag & BIT(i)) ?
|
||||
0 : BIT(SWITCH_PORT_FLAG_TAGGED);
|
||||
val->len++;
|
||||
port++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int rtl8367_sw_set_vlan_ports(struct switch_dev *dev, struct switch_val *val)
|
||||
{
|
||||
struct switch_port *port;
|
||||
u32 member = 0;
|
||||
u32 untag = 0;
|
||||
u8 fid=0;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
if (!rtl8367c_is_vlan_valid(val->port_vlan))
|
||||
return -EINVAL;
|
||||
|
||||
port = &val->value.ports[0];
|
||||
for (i = 0; i < val->len; i++, port++) {
|
||||
int pvid = 0;
|
||||
member |= BIT(port->id);
|
||||
|
||||
if (!(port->flags & BIT(SWITCH_PORT_FLAG_TAGGED)))
|
||||
untag |= BIT(port->id);
|
||||
|
||||
/*
|
||||
* To ensure that we have a valid MC entry for this VLAN,
|
||||
* initialize the port VLAN ID here.
|
||||
*/
|
||||
err = rtl8367c_get_pvid(port->id, &pvid);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (pvid == 0) {
|
||||
err = rtl8367c_set_pvid(port->id, val->port_vlan);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
//pr_info("[%s] vid=%d , mem=%x,untag=%x,fid=%d \n",__func__,val->port_vlan,member,untag,fid);
|
||||
|
||||
return rtl8367c_set_vlan(val->port_vlan, member, untag, fid);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static int rtl8367_sw_get_port_pvid(struct switch_dev *dev, int port, int *val)
|
||||
{
|
||||
return rtl8367c_get_pvid(port, val);
|
||||
}
|
||||
|
||||
|
||||
static int rtl8367_sw_set_port_pvid(struct switch_dev *dev, int port, int val)
|
||||
{
|
||||
return rtl8367c_set_pvid(port, val);
|
||||
}
|
||||
|
||||
|
||||
static int rtl8367_sw_reset_switch(struct switch_dev *dev)
|
||||
{
|
||||
if(rtl8367_switch_reset_func)
|
||||
(*rtl8367_switch_reset_func)();
|
||||
else
|
||||
printk("rest switch is not supported\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rtl8367_sw_get_port_link(struct switch_dev *dev, int port,
|
||||
struct switch_port_link *link)
|
||||
{
|
||||
int speed;
|
||||
|
||||
if (port >= RTL8367C_NUM_PORTS)
|
||||
return -EINVAL;
|
||||
|
||||
if(rtl8367c_get_port_link(port,(int *)&link->link,(int *)&speed,(int *)&link->duplex))
|
||||
return -EINVAL;
|
||||
|
||||
if (!link->link)
|
||||
return 0;
|
||||
|
||||
switch (speed) {
|
||||
case 0:
|
||||
link->speed = SWITCH_PORT_SPEED_10;
|
||||
break;
|
||||
case 1:
|
||||
link->speed = SWITCH_PORT_SPEED_100;
|
||||
break;
|
||||
case 2:
|
||||
link->speed = SWITCH_PORT_SPEED_1000;
|
||||
break;
|
||||
default:
|
||||
link->speed = SWITCH_PORT_SPEED_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static struct switch_attr rtl8367_globals[] = {
|
||||
{
|
||||
.type = SWITCH_TYPE_INT,
|
||||
.name = "enable_vlan",
|
||||
.description = "Enable VLAN mode",
|
||||
.set = rtl8367_sw_set_vlan_enable,
|
||||
.get = rtl8367_sw_get_vlan_enable,
|
||||
.max = 1,
|
||||
}, {
|
||||
.type = SWITCH_TYPE_NOVAL,
|
||||
.name = "reset_mibs",
|
||||
.description = "Reset all MIB counters",
|
||||
.set = rtl8367_sw_reset_mibs,
|
||||
}
|
||||
};
|
||||
|
||||
static struct switch_attr rtl8367_port[] = {
|
||||
{
|
||||
.type = SWITCH_TYPE_NOVAL,
|
||||
.name = "reset_mib",
|
||||
.description = "Reset single port MIB counters",
|
||||
.set = rtl8367_sw_reset_port_mibs,
|
||||
}, {
|
||||
.type = SWITCH_TYPE_STRING,
|
||||
.name = "mib",
|
||||
.description = "Get MIB counters for port",
|
||||
//.max = 33,
|
||||
.set = NULL,
|
||||
.get = rtl8367_sw_get_port_mib,
|
||||
},
|
||||
};
|
||||
|
||||
static struct switch_attr rtl8367_vlan[] = {
|
||||
{
|
||||
.type = SWITCH_TYPE_STRING,
|
||||
.name = "info",
|
||||
.description = "Get vlan information",
|
||||
.max = 1,
|
||||
.set = NULL,
|
||||
.get = rtl8367_sw_get_vlan_info,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct switch_dev_ops rtl8367_sw_ops = {
|
||||
.attr_global = {
|
||||
.attr = rtl8367_globals,
|
||||
.n_attr = ARRAY_SIZE(rtl8367_globals),
|
||||
},
|
||||
.attr_port = {
|
||||
.attr = rtl8367_port,
|
||||
.n_attr = ARRAY_SIZE(rtl8367_port),
|
||||
},
|
||||
.attr_vlan = {
|
||||
.attr = rtl8367_vlan,
|
||||
.n_attr = ARRAY_SIZE(rtl8367_vlan),
|
||||
},
|
||||
|
||||
.get_vlan_ports = rtl8367_sw_get_vlan_ports,
|
||||
.set_vlan_ports = rtl8367_sw_set_vlan_ports,
|
||||
.get_port_pvid = rtl8367_sw_get_port_pvid,
|
||||
.set_port_pvid = rtl8367_sw_set_port_pvid,
|
||||
.reset_switch = rtl8367_sw_reset_switch,
|
||||
.get_port_link = rtl8367_sw_get_port_link,
|
||||
};
|
||||
|
||||
int rtl8367s_swconfig_init(void (*reset_func)(void))
|
||||
{
|
||||
struct rtl8367_priv *priv = &rtl8367_priv_data;
|
||||
struct switch_dev *dev=&priv->swdev;
|
||||
int err=0;
|
||||
|
||||
rtl8367_switch_reset_func = reset_func ;
|
||||
|
||||
memset(priv, 0, sizeof(struct rtl8367_priv));
|
||||
priv->global_vlan_enable =0;
|
||||
|
||||
dev->name = "RTL8367C";
|
||||
dev->cpu_port = RTL8367C_SW_CPU_PORT;
|
||||
dev->ports = RTL8367C_NUM_PORTS;
|
||||
dev->vlans = RTL8367C_NUM_VIDS;
|
||||
dev->ops = &rtl8367_sw_ops;
|
||||
dev->alias = "RTL8367C";
|
||||
err = register_switch(dev, NULL);
|
||||
|
||||
pr_info("[%s]\n",__func__);
|
||||
|
||||
return err;
|
||||
}
|
||||
Reference in New Issue
Block a user