一、 MTK7621 网络通讯原理简述

本篇博文分析的是mtk7621的芯片所内嵌的交换芯片mt7530的驱动程序,MTK7621采用内部的 MDIO 接口管理MT7530 的 switch 芯片;MT7530包含多个7个 PHY 接口,其中第7个口连接到MTK7621芯片的eth0网口。MTK7621通过MDIO 进行寄存器读写配置使用,逻辑框图如下。

                                            ------------------|  CPU /mtk7621  ||   -----------  ||   | MAC/ephy   |  |___|__||_____|__|||                           RGMII/ ||  RXP/TXPMII    ||||------------------------------------------------||--------- |   Switch  MT7530                              ||        ||                                               ||        ||                                               ||        ||   |-----|   |-----|   |-----|   |-----|    |-----|      |____|_____|___|_____|___|_____|___|_____|____|_____|______|PHY1      PHY2      PHY3      PHY4      PHY/MAC

二、通过设备树看 MT7530 交换芯片

  • 1.linux 内核源码相对路径:
OpenWrt/mtk7621-19.07/build_dir/target-mipsel_24kc_musl/linux-ramips_mt7621/linux-4.14.200
  • 2.设备树文件相对路径:
/OpenWrt/mtk7621-19.07$ ls target/linux/ramips/dts/ |grep 7621
AP-MT7621A-V60.dts
MT7621.dts
mt7621.dtsi
U7621-06-256M-16M.dts
U7621-06-256M-64M.dts
U7621-06-512M-64M.dts
U7621-06.dtsi
  • 3.mt7621.dtsi 文件内容
    文件名称: target/linux/ramips/dts/mt7621.dtsi
 ethernet: ethernet@1e100000 {compatible = "mediatek,mt7621-eth";   # 对应的驱动程序 soc_mt7621.c 文件中reg = <0x1e100000 0x10000>;#address-cells = <1>;#size-cells = <1>;resets = <&rstctrl 6 &rstctrl 23>;reset-names = "fe", "eth";interrupt-parent = <&gic>;interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>;mediatek,switch = <&gsw>;  #交换芯片 mt7530mdio-bus {#address-cells = <1>;#size-cells = <0>;phy1f: ethernet-phy@1f {  # 内部 MDIO 总线描述reg = <0x1f>;phy-mode = "rgmii";};};hnat: hnat@0 {compatible = "mediatek,mt7623-hnat";reg = <0 0x10000>;mtketh-ppd = "eth0";mtketh-lan = "eth0";mtketh-wan = "eth0";resets = <&rstctrl 0>;reset-names = "mtketh";};};gsw: gsw@1e110000 {compatible = "mediatek,mt7621-gsw";   # 对应驱动程序 gsw_mt7621.c 文件中。reg = <0x1e110000 0x8000>;interrupt-parent = <&gic>;interrupts = <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>;};
  • 4.驱动文件位置
    检索驱动文件: $ ls drivers/net/ethernet/mediatek/
built-in.o    gsw_mt7620.c  mdio.c         mdio_rt2880.h    mtk_debugfs.o  mtk_offload.h  soc_rt3050.c
esw_rt3050.c  gsw_mt7620.h  mdio.h         modules.builtin  mtk_eth_soc.c  mtk_offload.o  soc_rt3883.c
esw_rt3050.h  gsw_mt7621.c  mdio_mt7620.c  mt7530.c         mtk_eth_soc.h  soc_mt7620.c
ethtool.c     gsw_mt7621.o  mdio_mt7620.o  mt7530.h         mtk_eth_soc.o  soc_mt7621.c
ethtool.h     Kconfig       mdio.o         mt7530.o         mtk-eth-soc.o  soc_mt7621.o
ethtool.o     Makefile      mdio_rt2880.c  mtk_debugfs.c    mtk_offload.c  soc_rt2880.c

三、网口与交换芯片如何关联起来? 网口驱动加载。

MT7621 的片上网口驱动 soc_mt7621.c 文件中,eth 驱动方法结构体定义如下:

static struct fe_soc_data mt7621_data = {.init_data = mt7621_init_data,           /*  芯片初始化  */.reset_fe = mt7621_fe_reset,.set_mac = mt7621_set_mac,.fwd_config = mt7621_fwd_config,         /* Vlan 转发配置    */.tx_dma = mt7621_tx_dma,.switch_init = mtk_gsw_init,            /*  关联 MT7530 交换芯片,初始化配置         */.switch_config = mt7621_gsw_config,     /*  配置 MT7530 芯片、并 probe MT7530 驱动 */.reg_table = mt7621_reg_table,.pdma_glo_cfg = FE_PDMA_SIZE_16DWORDS,.rx_int = RT5350_RX_DONE_INT,.tx_int = RT5350_TX_DONE_INT,.status_int = (MT7621_FE_GDM1_AF | MT7621_FE_GDM2_AF),.checksum_bit = MT7621_L4_VALID,.has_carrier = mt7620_has_carrier,      /* mdio_mt7621.c 状态检测 */.mdio_read = mt7620_mdio_read,          /* mdio 总线读取操作   */.mdio_write = mt7620_mdio_write,        /* mdio 总线写操作     */.mdio_adjust_link = mt7620_mdio_link_adjust, /* mdio_mt7621.c 连接检测 */
};
/* mtk7621-eth 驱动程序入口处 */
const struct of_device_id of_fe_match[] = {{ .compatible = "mediatek,mt7621-eth", .data = &mt7621_data },{},
};
MODULE_DEVICE_TABLE(of, of_fe_match);

mtk7621 片上的eth驱动就包含这 switch 芯片的驱动内容, mt7530 的驱动挂载是由 mt7621_gsw_config 函数触发。

由源码调用关系,mt7530操作函数主要是 vlan 和 port 的操作,如:mt7530_get_vlan_ports 函数,最终调用 mdiobus_read/mdio_write 函数实现操作内部芯片mt7530 的目的。

switch 交换芯片驱动加载

mtk7621 片上交换芯片设备名称mt7621-gsw ,驱动程序 gsw_mt7621.c 文件中。

   gsw: gsw@1e110000 {compatible = "mediatek,mt7621-gsw";   # 对应驱动程序 gsw_mt7621.c 文件中。reg = <0x1e110000 0x8000>;interrupt-parent = <&gic>;interrupts = <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>;};


mtk7621_gsw 驱动实现的是 gsw 设备实例 与 网口设备的绑定,卸载 mt7621-gsw 驱动,实际上是移除 gsw 与 网口间关系。

mt7621-eth 初始化分析

  • mt7621 驱动支持的芯片操作函数集合
static struct fe_soc_data mt7621_data = {.init_data = mt7621_init_data,.reset_fe = mt7621_fe_reset,.set_mac = mt7621_set_mac,.fwd_config = mt7621_fwd_config,.tx_dma = mt7621_tx_dma,.switch_init = mtk_gsw_init,                /* switch 芯片初始化 */.switch_config = mt7621_gsw_config,.reg_table = mt7621_reg_table,.pdma_glo_cfg = FE_PDMA_SIZE_16DWORDS,.rx_int = RT5350_RX_DONE_INT,.tx_int = RT5350_TX_DONE_INT,.status_int = (MT7621_FE_GDM1_AF | MT7621_FE_GDM2_AF),.checksum_bit = MT7621_L4_VALID,.has_carrier = mt7620_has_carrier,.mdio_read = mt7620_mdio_read,.mdio_write = mt7620_mdio_write,.mdio_adjust_link = mt7620_mdio_link_adjust,
};
  • mtk_gsw_init 初始化
int mtk_gsw_init(struct fe_priv *priv)
{struct device_node *np = priv->switch_np;struct platform_device *pdev = of_find_device_by_node(np);struct mt7620_gsw *gsw;if (!pdev)return -ENODEV;if (!of_device_is_compatible(np, mediatek_gsw_match->compatible))return -EINVAL;gsw = platform_get_drvdata(pdev);/* 申请中断 */priv->soc->swpriv = gsw;if (gsw->irq) {request_irq(gsw->irq, gsw_interrupt_mt7621, 0,"gsw", priv);disable_irq(gsw->irq);}
/* mt7621-hw 硬件初始化 */mt7621_hw_init(gsw, np);if (gsw->irq)enable_irq(gsw->irq);return 0;
}
  • 初始内容如下
static void mt7621_hw_init(struct mt7620_gsw *gsw, struct device_node *np)
{u32 i;u32 val;/* wardware reset the switch */fe_reset(RST_CTRL_MCM);mdelay(10);/* reduce RGMII2 PAD driving strength */rt_sysc_m32(3 << 4, 0, SYSC_PAD_RGMII2_MDIO);/* gpio mux - RGMII1=Normal mode */rt_sysc_m32(BIT(14), 0, SYSC_GPIO_MODE);/* set GMAC1 RGMII mode */rt_sysc_m32(3 << 12, 0, SYSC_REG_CFG1);/* enable MDIO to control MT7530 ,设置 MDIO 控制 MT7530 */rt_sysc_m32(3 << 12, 0, SYSC_GPIO_MODE);/* turn off all PHYs */for (i = 0; i <= 4; i++) {val = _mt7620_mii_read(gsw, i, 0x0);val |= BIT(11);_mt7620_mii_write(gsw, i, 0x0, val);}/* reset the switch */mt7530_mdio_w32(gsw, 0x7000, 0x3);usleep_range(10, 20);/* (GE1, Force 1000M/FD, FC OFF, MAX_RX_LENGTH 1536) */mtk_switch_w32(gsw, 0x2305e30b, GSW_REG_MAC_P0_MCR);mt7530_mdio_w32(gsw, 0x3600, 0x5e30b);/* (GE2, Link down) , 关闭 GE2 口,此接口暂时未使用 */mtk_switch_w32(gsw, 0x8000, GSW_REG_MAC_P1_MCR);/* Set switch max RX frame length to 2k */mt7530_mdio_w32(gsw, GSW_REG_GMACCR, 0x3F0B);/* Enable Port 6, P5 as GMAC5, P5 disable */val = mt7530_mdio_r32(gsw, 0x7804);val &= ~BIT(8);val |= BIT(6) | BIT(13) | BIT(16);mt7530_mdio_w32(gsw, 0x7804, val);val = rt_sysc_r32(0x10);val = (val >> 6) & 0x7;if (val >= 6) {/* 25Mhz Xtal - do nothing */} else if (val >= 3) {/* 40Mhz *//* disable MT7530 core clock */_mt7620_mii_write(gsw, 0, 13, 0x1f);_mt7620_mii_write(gsw, 0, 14, 0x410);_mt7620_mii_write(gsw, 0, 13, 0x401f);_mt7620_mii_write(gsw, 0, 14, 0x0);/* 省略部分代码 */ } else {/* 20Mhz Xtal - TODO */}/* RGMII */_mt7620_mii_write(gsw, 0, 14, 0x1);/* set MT7530 central align */
/* 省略部分代码 */ /* delay setting for 10/1000M */
/* 省略部分代码 */ /* lower Tx Driving*/
/* 省略部分代码 */ /* turn on all PHYs */for (i = 0; i <= 4; i++) {val = _mt7620_mii_read(gsw, i, 0);val &= ~BIT(11);_mt7620_mii_write(gsw, i, 0, val);}/* enable irq ,打开中断接收允许  */mt7530_mdio_w32(gsw, 0x7008, 0x1f);val = mt7530_mdio_r32(gsw, 0x7808);val |= 3 << 16;mt7530_mdio_w32(gsw, 0x7808, val);
}

本篇描述 mtk7621 芯片 eth 网口、switch交换芯片之间关系,驱动加载关系;在此 mtk7621 具备数据接收与发送功能,下一篇分享网络协议栈数据接收过程。

当开启 switch 交换口时(例如,通过 ifconfig eth0.2 up),mtk7621_ops 中的 mt7530_set_port 方法会被调用;设置端口、配置vlan 的 vid 号等操作,与mtk7621_ops各方法对应。

5-->详解《switch 数据接收驱动框架、mtk7621集成交换芯片mt7530》之一相关推荐

  1. 6 -->详解《switch 数据接收驱动框架、mtk7621集成交换芯片mt7530》之二

    一. MTK7621 网络通讯原理简述 本篇博文分析的是mtk7621的芯片所内嵌的交换芯片mt7530的驱动程序,MTK7621采用内部的 MDIO 接口管理MT7530 的 switch 芯片:M ...

  2. R语言tidyr包gather()函数实战详解:数据收缩、从宽表到窄表

    R语言tidyr包gather()函数实战详解:数据收缩.从宽表到窄表 目录 R语言tidyr包gather()函数实战详解:数据收缩.从宽表到窄表 收缩两列数据

  3. R语言tidyr包spread()函数实战详解:数据裂变、从窄表到宽表

    R语言tidyr包spread()函数实战详解:数据裂变.从窄表到宽表 目录 R语言tidyr包spread()函数实战详解:数据裂变.从窄表到宽表

  4. linux 进程间通信 dbus-glib【实例】详解三 数据类型和dteeth(类型签名type域)(层级结构:服务Service --> Node(对象、object) 等 )(附代码)

    linux 进程间通信 dbus-glib[实例]详解一(附代码)(d-feet工具使用) linux 进程间通信 dbus-glib[实例]详解二(上) 消息和消息总线(附代码) linux 进程间 ...

  5. mysql 数据分组_详解MySQL 数据分组

    创建分组 分组是在select语句中的group by 子句中建立的. 例: select vend_id, count(*) as num_prods from products group by ...

  6. 读书笔记:详解FPGA人工智能的驱动引擎(石侃)

    最近读了一本关于我偶像的一本书,知名up主老石的一本书<详解FPGA人工智能的驱动引擎>,这本书写了老石对FPGA的一些心得和行业总结,个人觉得写的非常不错,第一次看还是有点难以深刻理解, ...

  7. 【React】 详解下一代开源混合应用框架Reapp

    详解下一代开源混合应用框架Reapp reapp官网 转载于:https://www.cnblogs.com/dongdong230/p/4314978.html

  8. 学习笔记之-Kubernetes(K8S)介绍,集群环境搭建,Pod详解,Pod控制器详解,Service详解,数据存储,安全认证,DashBoard

    笔记来源于观看黑马程序员Kubernetes(K8S)教程 第一章 kubernetes介绍 应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代: 传统部署:互联网早期,会直接将应用程序部署 ...

  9. ue4移动到一定距离_UE4移动组件详解(一)——移动框架与实现原理

    原文链接(转载请标明):UE4移动组件详解(一)--移动框架与实现原理_Jerish的博客-CSDN博客​blog.csdn.net 前言 关于UE4的移动组件,我写了一篇非常详细的分析文档.由于篇幅 ...

最新文章

  1. QIIME 2教程. 20实用程序Utilities(2020.11)
  2. 德赛西威与智驾科技MAXIEYE发布“九逵计划”,部署商用车自动驾驶技术及服务...
  3. WinCE/Mobile上下滑动浏览DataGrid数据 【转】
  4. Redis分布式锁的正确实现方式(Java版)
  5. 友盟 点完登陆后无反应_高考缴费艺术生到底该交多少钱?密码找不到了怎么办?等级考缴费吗?点进来查看!...
  6. mysql数据库套件_MySQL数据库管理开发套件(EMS SQL Management Studio For MySQL)下载 v1.3.0.46170 官方版 - 比克尔下载...
  7. 微软允许员工永久在家办公,远程办公时代真的要来临了吗?
  8. 窃取任意GitHub Actions敏感信息如此简单,只需要分支改个名?
  9. 测控技术与仪器是计算机相关的,测控技术与仪器专业
  10. hive中的集合操作函数
  11. SIMULATE 受力分析简单教程
  12. 【Kilav】数据库知识点速通 其二
  13. 电脑开机计算机配置,电脑开机显示配置更新怎么办
  14. 网络操作系统VyOS之NAT实践
  15. 统计学三大相关系数之斯皮尔曼(spearman)相关系数
  16. poi解析excel(处理单元格公式)
  17. 计算机网络线接法,电脑网线插座接法图文详解
  18. 蓝桥杯 算法训练 跳马
  19. 这12张数据治理内涵图,你看懂了吗
  20. 【ERP知识】一个VMI(供应商管理库存)实现方案

热门文章

  1. 从0到1学SpringCloud——08 通过fegin实现微服务之间请求调用
  2. C++ ARX二次开发-创建三维实体
  3. 实现图片在线预览,可切换可放大缩小
  4. 计算机辅助教育的阶段,第一章计算机辅助教育概述.ppt
  5. java label自动换行_Java label自动换行
  6. 一篇干货告诉你!新手小白如何做自媒体、短视频赚钱!
  7. 求职者说:成功应聘华为后的总结
  8. 哪些软件可以拍照翻译成中文?这些办法值得一试
  9. 游戏蓝牙耳机哪个品牌好?吃鸡蓝牙耳机无延迟排行榜
  10. Mapinfo 2 googleearth插件原创