linux DSA 开发上手笔记(一)
linux DSA 开发上手笔记(一)
与 DSA 相关的代码
./net/dsa/*
./drivers/net/dsa/*
./net/dsa/Kconfig
# net/dsa/Kconfig 里面主要定义了以下CONFIG选项
NET_DSA
NET_DSA_TAG_8021Q
NET_DSA_TAG_xxx
./net/dsa/Makefile
# SPDX-License-Identifier: GPL-2.0
# the core
obj-$(CONFIG_NET_DSA) += dsa_core.o
dsa_core-y += dsa.o dsa2.o master.o port.o slave.o switch.o# tagging formats
obj-$(CONFIG_NET_DSA_TAG_8021Q) += tag_8021q.o
obj-$(CONFIG_NET_DSA_TAG_BRCM_COMMON) += tag_brcm.o
obj-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o
obj-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o
obj-$(CONFIG_NET_DSA_TAG_GSWIP) += tag_gswip.o
obj-$(CONFIG_NET_DSA_TAG_KSZ) += tag_ksz.o
obj-$(CONFIG_NET_DSA_TAG_LAN9303) += tag_lan9303.o
obj-$(CONFIG_NET_DSA_TAG_MTK) += tag_mtk.o
obj-$(CONFIG_NET_DSA_TAG_QCA) += tag_qca.o
obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o
obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
由此可见核心代码是:
obj-$(CONFIG_NET_DSA) += dsa_core.o
dsa_core-y += dsa.o dsa2.o master.o port.o slave.o switch.o
./drivers/net/dsa/Makefile
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_NET_DSA_BCM_SF2) += bcm-sf2.o
bcm-sf2-objs := bcm_sf2.o bcm_sf2_cfp.o
obj-$(CONFIG_NET_DSA_LOOP) += dsa_loop.o
ifdef CONFIG_NET_DSA_LOOP
obj-$(CONFIG_FIXED_PHY) += dsa_loop_bdinfo.o
endif
obj-$(CONFIG_NET_DSA_LANTIQ_GSWIP) += lantiq_gswip.o
obj-$(CONFIG_NET_DSA_MT7530) += mt7530.o
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
obj-$(CONFIG_NET_DSA_QCA8K) += qca8k.o
obj-$(CONFIG_NET_DSA_REALTEK_SMI) += realtek-smi.o
realtek-smi-objs := realtek-smi-core.o rtl8366.o rtl8366rb.o
obj-$(CONFIG_NET_DSA_SMSC_LAN9303) += lan9303-core.o
obj-$(CONFIG_NET_DSA_SMSC_LAN9303_I2C) += lan9303_i2c.o
obj-$(CONFIG_NET_DSA_SMSC_LAN9303_MDIO) += lan9303_mdio.o
obj-$(CONFIG_NET_DSA_VITESSE_VSC73XX) += vitesse-vsc73xx-core.o
obj-$(CONFIG_NET_DSA_VITESSE_VSC73XX_PLATFORM) += vitesse-vsc73xx-platform.o
obj-$(CONFIG_NET_DSA_VITESSE_VSC73XX_SPI) += vitesse-vsc73xx-spi.o
obj-y += b53/
obj-y += microchip/
obj-y += mv88e6xxx/
obj-y += sja1105/# 这里是不同厂家switch 驱动
以 mt7530.c 为例,学习 dsa switch 驱动的写法
static struct mdio_driver mt7530_mdio_driver = {.probe = mt7530_probe,.remove = mt7530_remove,.mdiodrv.driver = {.name = "mt7530",.of_match_table = mt7530_of_match,},
};mdio_module_driver(mt7530_mdio_driver);
要点:是用 mdio_module_driver
/*** mdio_module_driver() - Helper macro for registering mdio drivers** Helper macro for MDIO drivers which do not do anything special in module* init/exit. Each module may only use this macro once, and calling it* replaces module_init() and module_exit().*/
#define mdio_module_driver(_mdio_driver) \
static int __init mdio_module_init(void) \
{ \return mdio_driver_register(&_mdio_driver); \
} \
module_init(mdio_module_init); \
static void __exit mdio_module_exit(void) \
{ \mdio_driver_unregister(&_mdio_driver); \
} \
module_exit(mdio_module_exit)
mt7530_probe
static int
mt7530_probe(struct mdio_device *mdiodev)
{//...priv->bus = mdiodev->bus;priv->dev = &mdiodev->dev;priv->ds->priv = priv;priv->ds->ops = &mt7530_switch_ops; //关键代码mutex_init(&priv->reg_mutex);dev_set_drvdata(&mdiodev->dev, priv);return dsa_register_switch(priv->ds); //关键代码
}
关键在于 mt7530_switch_ops 和 dsa_register_switch
mt7530_switch_ops
static const struct dsa_switch_ops mt7530_switch_ops = {.get_tag_protocol = mtk_get_tag_protocol,.setup = mt7530_setup,.get_strings = mt7530_get_strings,.phy_read = mt7530_phy_read,.phy_write = mt7530_phy_write,.get_ethtool_stats = mt7530_get_ethtool_stats,.get_sset_count = mt7530_get_sset_count,.port_enable = mt7530_port_enable,.port_disable = mt7530_port_disable,.port_stp_state_set = mt7530_stp_state_set,.port_bridge_join = mt7530_port_bridge_join,.port_bridge_leave = mt7530_port_bridge_leave,.port_fdb_add = mt7530_port_fdb_add,.port_fdb_del = mt7530_port_fdb_del,.port_fdb_dump = mt7530_port_fdb_dump,.port_vlan_filtering = mt7530_port_vlan_filtering,.port_vlan_prepare = mt7530_port_vlan_prepare,.port_vlan_add = mt7530_port_vlan_add,.port_vlan_del = mt7530_port_vlan_del,.phylink_validate = mt7530_phylink_validate,.phylink_mac_link_state = mt7530_phylink_mac_link_state,.phylink_mac_config = mt7530_phylink_mac_config,.phylink_mac_link_down = mt7530_phylink_mac_link_down,.phylink_mac_link_up = mt7530_phylink_mac_link_up,
};
定义了一些关键函数。
小结 :
- dsa switch 驱动本身是 mdio 设备驱动
- dsa switch 驱动的核心是实现 struct dsa_switch_ops 结构体
dts 写法
ð {status = "okay";gmac0: mac@0 {compatible = "mediatek,eth-mac";reg = <0>;phy-mode = "trgmii";fixed-link {speed = <1000>;full-duplex;pause;};};mdio: mdio-bus {#address-cells = <1>;#size-cells = <0>;switch@0 {compatible = "mediatek,mt7530";reg = <0>;reset-gpios = <&pio 33 0>;core-supply = <&mt6323_vpa_reg>;io-supply = <&mt6323_vemc3v3_reg>;ports {#address-cells = <1>;#size-cells = <0>;port@0 {reg = <0>;label = "wan";};port@1 {reg = <1>;label = "lan0";};port@2 {reg = <2>;label = "lan1";};port@3 {reg = <3>;label = "lan2";};port@4 {reg = <4>;label = "lan3";};port@6 {reg = <6>;label = "cpu";ethernet = <&gmac0>;phy-mode = "trgmii";fixed-link {speed = <1000>;full-duplex;pause;};};};};};
};
详见:Documentation/devicetree/bindings/net/dsa/dsa.txt
dsa switch 驱动的骨架
static const struct dsa_switch_ops mt7530_switch_ops = {};static const struct of_device_id mt7530_of_match[] = {{ .compatible = "mediatek,mt7621", .data = (void *)ID_MT7621, },{ .compatible = "mediatek,mt7530", .data = (void *)ID_MT7530, },{ /* sentinel */ },
};MODULE_DEVICE_TABLE(of, mt7530_of_match);
static int
mt7530_probe(struct mdio_device *mdiodev)
{}static void
mt7530_remove(struct mdio_device *mdiodev)
{}static struct mdio_driver mt7530_mdio_driver = {.probe = mt7530_probe,.remove = mt7530_remove,.mdiodrv.driver = {.name = "mt7530",.of_match_table = mt7530_of_match,},
};mdio_module_driver(mt7530_mdio_driver);MODULE_LICENSE("GPL");
linux DSA 开发上手笔记(一)相关推荐
- linux DSA 开发(一)
linux DSA 开发(一) 本文主要是翻译,原文链接如下:https://www.kernel.org/doc/html/latest/networking/dsa/dsa.html 纲要 本文档 ...
- Linux驱动开发学习笔记【12】:Linux自带LED灯驱动
目录 一.内核自带LED驱动使能 二.内核自带LED驱动分析 三.内核自带LED驱动使用 一.内核自带LED驱动使能 在Linux内核中,已经自带了LED灯的驱动程序,使用的就是platform平台驱 ...
- linux平台开发自学笔记(三)-代码编译
linux和window编代码其实大致上是差不多的,不过在一些概念上还有差别,比如使用的库不一样,编译工具不一样,shell不一样,库的链接方式也不一样,这里做个简要的总结 1.库 window上有两 ...
- 正点原子 Linux驱动开发学习笔记-06 chrdevbase虚拟设备驱动的完善
要求:应用程序可以对驱动进行读写操作. 读:从驱动读一个字符串 写:应用程序向驱动写一个字符串 驱动的缓冲,与应用程序的读写buffer都是100. 1. read驱动函数编写,需要用到copy_to ...
- Linux驱动开发学习笔记【8】:Linux中断系统
目录 一.Linux内核中断处理过程 1.1.裸机中断 1.2.linux中断 二.linux中断的上半部和下半部 2.1 软中断 2.2 tasklet 2.3 工作队列 2.4 中断线程化 三.设 ...
- Linux驱动开发学习笔记-电容触摸屏驱动
<电容触摸屏驱动框架> 电容触摸屏驱动其实是以下几种 linux 驱动框架的组合: ① IIC 设备驱动,因为电容触摸 IC 基本都是 IIC 接口的,因此大框架就是 IIC 设备驱动. ...
- linux驱动开发学习笔记二十一:异步通知
一.异步通知简介 我们首先来回顾一下"中断",中断是处理器提供的一种异步机制,我们配置好中断以后就可以让处理器去处理其他的事情了,当中断发生以后会触发我们事先设置好的中断服务函数, ...
- LINUX驱动开发学习笔记--DDR3内存
在学习DDR之前,我们首先要知道什么是RAM和ROM RAM:随机存储器,可以随时进行读写操作,速度很快,掉电以后数据会丢失.比如内存条. SRAM. SDRAM. DDR等都是 RAM. RAM一般 ...
- Vue快速上手笔记2 - 开发环境的搭建
Vue快速上手笔记2 - 开发环境的搭建 CSDN:JcLee95 邮箱:291148484@163.com 专题目录:https://blog.csdn.net/qq_28550263/articl ...
- linux 内核模块开发,Linux内核模块开发(笔记)
Linux内核模块开发(笔记) 作者:扶凯 来源: 扶凯 时间:2011-11-21 00:21:11 人气:249 评论:0 标签: 内核 个人笔记..在不放过来都快找不到了.有空还得好好整理一下了 ...
最新文章
- mysql数据库移植到另一台电脑,将mysql数据库从一台计算机复制到另一台计算机...
- 这样调优:让你的 IDEA 快到飞起来,效率真高!
- PP面向订单生产模式探讨
- 64 大小_32位和64位Windows系统差别在哪里
- 求无序数组的第二小的元素
- 零基础 Amazon Web Services (AWS) 入门教程图文版(一)
- linux关机机器语言,Linux 核心源代码分析 - 第十章 开机 关机 [续二] [超星]...
- hdu2844 Coins -----多重背包+二进制优化
- 不同计算机用户的区别是什么意思,电脑的系统64位和32位是什么意思呢?
- 数据分析(Data Analysis)
- 2021年危险化学品生产单位安全生产管理人员找解析及危险化学品生产单位安全生产管理人员复审考试
- 【华为认证考试扫盲】超详细的华为认证入门基础知识,考证必看。
- 工行u盾显示316_工行U盾只显示金融@家怎么显密码
- STM32F103RC单片机ADC1使用TIM1自动触发注入通道组的AD转换
- 触发器详解——(三)T触发器
- walking与Matlab入门教程-介绍示例模型
- 拼音四线三格图片_一年级拼音总结,请查收
- Fluent的融化凝固模型介绍
- 如何系统地学习 C++ 语言?
- ip地址+斜杠数字含义
热门文章
- Excel控制AutoCad进行坐标标注
- Centos中重置MySQL密码
- SNMP:简单网络管理协议(一)
- 惠普局域网共享打印机设置_已解决: hp1106局域网共享打印机共享 - 惠普支持社区 - 817337...
- 模糊控制 之 模糊集,隶属函数,模糊关系
- alitum designer 的PCB生成gerber文件步骤
- Python常用模块库下载及安装
- 基于ADS仿真的465khz检波电路
- Fragstats官方入门教程1 配置软件
- 第26课:JSP Cookie 处理 读取和删除cookie(JSP教程 JSP入门实战教程 黄菊华Java网站开发系列教程)