硬件工程师参考RTL8211FS-CG发布的设计图设计
以下为部分截图
在设计过程中参考realtek发过的参考设计,建议咨询一下phy厂家,看有哪些注意地方
注意: 8211FS使用外部3.3V,电平要与主控GMAC1相匹配;
使用UTP<->RGMII的接法,且CFG_MODE2:0=010兼容光口和电口;
建议先调电口RJ45,调通后再接光口,可能更容易;调电口时先插百兆网线调百兆,成功后再换千兆网线
在kernel下输入make menuconfig
Device Drivers --->
[*] Network device support --->
-*- PHY Device support and infrastructure --->
-*- Realtek PHYs
这样realtek.c就可以编译到kernel了
&gmac1 {
/* Use rgmii-rxid mode to disable rx delay inside Soc */
phy-mode = "rgmii-rxid";
clock_in_out = "output";
snps,reset-gpio = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>;
snps,reset-active-low;
/* Reset time is 20ms, 100ms for rtl8211f */
snps,reset-delays-us = <0 20000 100000>;
pinctrl-names = "default";
pinctrl-0 = <&gmac1_miim
&gmac1_tx_bus2
&gmac1_rx_bus2
&gmac1_rgmii_clk
&gmac1_rgmii_bus
&gmac1_clkinout>;
tx_delay = <0x43>;
/* rx_delay = <0x4f>; */
phy-handle = <&rgmii_phy1>;
status = "okay";
};
&mdio1 {
rgmii_phy1: phy@1 {
compatible = "ethernet-phy-ieee802.3-c22";
reg = <0x1>;
};
};
插千兆网线有相关打印且可以ping通百度
此时插光口没有分配IP地址
打开IO调试命令
CONFIG_DEVMEM=y
find /sys -name phy_registers //先找到以太网寄存器的配置节点并进入所在目录
echo 31 0xdc0 >phy_registers //切换到PHY的PAGE 0xdc0
cat phy_registers //读取当前PAGE寄存器的值,核对PHYID1,PHYID2是否正确来确认寄存器是否正确
echo 0 0x value >phy_registers //改写PAGE0第0个寄存器的值为需要的value
cat phy_registers //读取值检查是否修改成功
echo 31 0 > phy_registers //切回到PAGE0寄存器!!!!重要,一定写完要切回来才会生效
如果修改无效,参阅PHY规格书的8.5章节修改
setup_fiber_mode
#endif
+static int phy_8211fS_fiber_mode_fixup(struct phy_device *phydev)
+{ int i;
+ printk("%s in\n", __func__);
+ phy_write(phydev, 31, 0xdc0 );
+ phy_write(phydev, 16, 0x79ad );
+ //phy_write(phydev, 20, 0x79ad );
+ printk("page 0xdc0 register\n");
+ for(i =0; i<8,i++)
+ printk("%d: %x\n",i,phy_read(phydev,i));
+ phy_write(phydev, 31, 0xdc1 );
+ printk("23: %x\n", phy_read(phydev,23));
+ phy_write(phydev, 31, 0x0 );
+ printk("page 0 register\n");
+ for(i =0; i<32,i++)
+ printk("%d: %x\n",i,phy_read(phydev,i));
+
+ return 0;
+}
/**
* stmmac_dvr_probe
* @device: device pointer
#ifdef CONFIG_DWMAC_RK_AUTO_DELAYLINE
INIT_DELAYED_WORK(&priv->scan_dwork, stmmac_scan_delayline_dwork);
#endif
+ ret = phy_register_fixup_for_uid(RTL_8211FS_PHY_ID, 0xffffffff, +phy_8211fS_fiber_mode_fixup);
+ if (ret)
+ pr_warn("Cannot register PHY board fixup.\n");
return ret;
error_netdev_register:
编译烧写之后网口灯状态已经变为光口模式了,此时插入光口还是无法分配IP地址
--- a/kernel/drivers/net/phy/realtek.c
+++ b/kernel/drivers/net/phy/realtek.c
@@ -46,6 +46,11 @@
#define RTL8366RB_POWER_SAVE 0x15
#define RTL8366RB_POWER_SAVE_ON BIT(12)
+#define RTL8211FS_FIBER_ESR 0x0F
+#define RTL8211FS_MODE_MASK 0xC000
+#define RTL8211F_MODE_COPPER 0
+#define RTL8211FS_MODE_FIBER 1
+
#define RTL_SUPPORTS_5000FULL BIT(14)
#define RTL_SUPPORTS_2500FULL BIT(13)
#define RTL_SUPPORTS_10000FULL BIT(0)
@@ -58,6 +63,10 @@
#define RTL_GENERIC_PHYID 0x001cc800
+struct rtl8211f_priv {
+ int lastmode;
+};
+
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
MODULE_LICENSE("GPL");
@@ -93,7 +102,6 @@ static int rtl821x_ack_interrupt(struct phy_device *phydev)
static int rtl8211f_ack_interrupt(struct phy_device *phydev)
{
int err;
-
err = phy_read_paged(phydev, 0xa43, RTL8211F_INSR);
return (err < 0) ? err : 0;
@@ -140,7 +148,6 @@ static int rtl8211e_config_intr(struct phy_device *phydev)
static int rtl8211f_config_intr(struct phy_device *phydev)
{
u16 val;
-
if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
val = RTL8211F_INER_LINK_STATUS;
else
@@ -242,7 +249,7 @@ static int rtl8211f_config_init(struct phy_device *phydev)
"2ns RX delay was already %s (by pin-strapping RXD0 or bootloader configuration)\n",
val_rxdly ? "enabled" : "disabled");
}
-
+
return 0;
}
@@ -560,6 +567,89 @@ static int rtlgen_resume(struct phy_device *phydev)
return ret;
}
+static int rtl8211f_probe(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ struct rtl8211f_priv *priv;
+
+ priv = devm_kzalloc(dev, sizeof(struct rtl8211f_priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ phydev->priv = priv;
+
+ return 0;
+}
+
+static void rtl8211f_remove(struct phy_device *phydev)
+{
+ struct device *dev = &phydev->mdio.dev;
+ struct rtl8211f_priv *priv = phydev->priv;
+
+ if (priv)
+ devm_kfree(dev, priv);
+}
+
+static int rtl8211f_mode(struct phy_device *phydev)
+{
+ u16 val;
+
+ val = phy_read(phydev, RTL8211FS_FIBER_ESR);
+ val &= RTL8211FS_MODE_MASK;
+
+ if(val)
+ return RTL8211FS_MODE_FIBER;
+ else
+ return RTL8211F_MODE_COPPER;
+}
+
+static int rtl8211f_config_aneg(struct phy_device *phydev)
+{
+ int ret;
+
+ struct rtl8211f_priv *priv = phydev->priv;
+
+ ret = genphy_read_abilities(phydev);
+ if(ret < 0)
+ return ret;
+
+ linkmode_copy(phydev->advertising, phydev->supported);
+
+ if (rtl8211f_mode(phydev) == RTL8211FS_MODE_FIBER) {
+ dev_info(&phydev->mdio.dev, "Fiber Mode");
+ priv->lastmode = RTL8211FS_MODE_FIBER;
+ return genphy_c37_config_aneg(phydev);
+ }
+
+ dev_info(&phydev->mdio.dev, "Copper Mode");
+
+ priv->lastmode = RTL8211F_MODE_COPPER;
+
+ return genphy_config_aneg(phydev);
+}
+
+static int rtl8211f_read_status(struct phy_device *phydev)
+{
+ int ret;
+ struct rtl8211f_priv *priv = phydev->priv;
+
+ if(rtl8211f_mode(phydev) != priv->lastmode) {
+ ret = rtl8211f_config_aneg(phydev);
+ if(ret < 0)
+ return ret;
+
+ ret = genphy_restart_aneg(phydev);
+ if(ret < 0)
+ return ret;
+ }
+
+ if (rtl8211f_mode(phydev) == RTL8211FS_MODE_FIBER)
+ return genphy_c37_read_status(phydev);
+
+ return genphy_read_status(phydev);
+}
+
+
static struct phy_driver realtek_drvs[] = {
{
PHY_ID_MATCH_EXACT(0x00008201),
@@ -632,10 +722,15 @@ static struct phy_driver realtek_drvs[] = {
.write_page = rtl821x_write_page,
}, {
PHY_ID_MATCH_EXACT(0x001cc916),
- .name = "RTL8211F Gigabit Ethernet",
+ // .name = "RTL8211F Gigabit Ethernet",
+ .name = "RTL8211F(S) Gigabit Ethernet",
+ .probe = rtl8211f_probe,
+ .remove = rtl8211f_remove,
.config_init = &rtl8211f_config_init,
.ack_interrupt = &rtl8211f_ack_interrupt,
.config_intr = &rtl8211f_config_intr,
+ .config_aneg = rtl8211f_config_aneg,
+ .read_status = rtl8211f_read_status,
.suspend = genphy_suspend,
.resume = rtl821x_resume,
.read_page = rtl821x_read_page,
将补丁加进去
上电之后再复位reset脚一次可以识别到光口了
io -4 0xFEC40000 0x80000000 拉低
sleep 0.1
io -4 0xFEC40000 0x80008000 拉高
RTL8211F(S) Gigabit Ethernet stmmac-1:01: Copper Mode
总结
RTL8211FS,只要硬件线路配置为RGMII to Fiber 等涉及到Fiber的模式,即可工作。Fiber相关的模式设定可参考RTL8211FS数据手册中寄存器描述,公司推动 realtek 跟进解决。

我有一个使用postgresql的Rails4应用程序。我还有一个backbone.js应用程序,可将JSON推送到Rails4应用程序。这是我的Controller:defcreate@product=Product.new(ActiveSupport::JSON.decodeproduct_params)respond_todo|format|if@product.saveformat.json{renderaction:'show',status::created,location:@product}elseformat.json{renderjson:@product.erro
我正在尝试序列化和反序列化哈希。当散列被反序列化时,键被去符号化;例如不是更多:一个,而是“一个”。从Rails控制台:>>h={:one=>1,:two=>"two"}{:one=>1,:two=>"two"}>>j=ActiveSupport::JSON.encode(h)"{\"one\":1,\"two\":\"two\"}">>h2=ActiveSupport::JSON.decode(j){"one"=>1,"two"=>"two"}>>h2[:one]nil>>h[:one]1我现在已经切换到使用Marshal.dump/load。但是,我想把它扔出去看看是否有办法将它保
我正在尝试解码一些HTML实体,例如'<'成为'.我有一个旧gem(html_helpers),但它似乎已经被遗弃了两次。有什么建议吗?我需要在模型中使用它。 最佳答案 要对字符进行编码,可以使用CGI.escapeHTML:string=CGI.escapeHTML('test"escaping"')要解码它们,有CGI.unescapeHTML:CGI.unescapeHTML("test"unescaping"<characters>")当然,在此之前你需要包含CGI库:requi
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Hextobinaryinruby在Python中,我可以执行以下操作:>>>str='000E0000000000'>>>str.decode('hex')'\x00\x0e\x00\x00\x00\x00\x00'如果我必须在ruby中实现相同的输出,我可以调用哪个?to_s(16)试过了,好像不行。我需要采用该特定格式的输出,因此我希望得到以下内容:"\\x00\\x0e\\x00\\x00\\x00\\x00\\x00"
由于Facebook弃用新的FBML,我正在寻找一种创建“显示”选项卡(向粉丝显示一个版本而向非粉丝显示另一个版本的页面选项卡)的新方法。Facebook已将数据添加到signed_request:Whenauserselectsyourappintheleft-handmenu,theappwillreceivethesigned_requestparameterwithoneadditionalparameter,page,aJSONarraywhichcontainsthe‘id’oftheFacebookPageyourTabishostedwithin,aboolean(‘l
我正在使用FacebookAPI和RubyonRails,我正在尝试解析返回的JSON。我遇到的问题是Facebookbase64URL对其数据进行编码。Ruby没有内置的base64URL解码。关于base64编码和base64URL编码的区别,seewikipedia.我如何使用Ruby/Rails对此进行解码?编辑:因为有些人阅读有困难——base64URL与base64不同 最佳答案 Dmitry的回答是正确的。它说明了在字符串解码之前必须出现的“=”符号填充。我一直收到格式错误的JSON,最后发现这是由于填充造成的。Rea
如何在Ruby中将"1234567890"转换为"\x12\x34\x56\x78\x90"? 最佳答案 试试这个:["1234567890"].pack('H*') 关于ruby-将十六进制字符串转换(解码)为二进制字符串,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/862140/
我正在尝试读取包含编码的base64字符串的文件,并将解码后的输出写入另一个文件。我的Input.txt包含一个base64字符串,类似于:PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48cmV2aWV3LWNhc2UgY3JlYXRl\r\nZGF0ZT0iMTMvTWFyLzIwMTQgMDk6MDQ6NTEiIHN5c3RlbT0iVHJhZmlndXJhX1RlbXBsYXRlX01h\r\nbmFnZW1lbnRfdjUuMSIgYmF0Y2hpZD0iMCIgdHJhbnNhY3Rpb25ubz0iMSIgYmF0Y2
我是Node.js的新手,正在阅读FabianCook的Node.jsEssentials。当尝试使用JWT进行身份验证时,我从jwt.decode(token)得到了一个NULL,但该token可以由jwt.io上的调试器解析。代码有什么问题?varPassport=require('passport');varLocalStrategy=require('passport-local').Strategy;varExpress=require('express');varBodyParser=require('body-parser');varjwt=require('jsonwe
出于某些原因,我有一个网页可以解码wave文件。Chrome和Safari似乎工作正常。Firefox有时无法解码文件并给出错误:“传递给decodeAudioData的缓冲区包含无法成功解码的无效内容。”我创建了一个jsfiddle这说明了这个问题:varaudioCtx=new(window.AudioContext||window.webkitAudioContext)();varsource;functiongetData(){source=audioCtx.createBufferSource();request=newXMLHttpRequest();request.ope