WIFI|軟體 茶凳淺談 高通WIN QSDK - IPQ6000 與 88Q2112 的相遇

Qualcomm IPQ 系列的Ethernet IC 搭配的有 QCA8075, QCA8081 … 等等Qualcomm自家出產的芯片。QSDK中內建可以支持的3rd party芯片,卻寥寥可數。日前,客戶使用车载以太网 - 88Q2112 - Marvell與IPQ6000做搭配。將之記錄下來,以供參考。

方塊圖:

block

把原本reference board上的QCA8075、QCA8081都換成Marvell的88Q2112。傳輸介面走的protocol也由SGMII+ 、 PSGMII換成SGMII。

IPQ60x8與88Q2112之間有兩個介面,一個是MDC/MDIO的控制介面,一個是GMII的資料傳輸介面。

使用user guide提到的方式,修改DTS

MII node :

qca8081

所以在本質上應該使用cp02的DTS來做修改。

MDIO node:

改用gpio16來做reset phy的腳位。tlmm的gpio改為gpio16

mdio_pins: mdio_pinmux {

                                      ……

                mux_2 {

                        pins = "gpio16";

                        function = "gpio";

                        bias-pull-up;

                };

        };


mdio中使用&tlmm 再次指定phy-reset-gpio

       mdio: mdio@90000 {

                pinctrl-0 = <&mdio_pins>;

                pinctrl-names = "default";

                phy-reset-gpio = <&tlmm 16 0>;

                   ……


後面應該照著原來的設定。因為88Q2112要用Clause 45,所以每個port都要加上compatible="ethernet-phy-ieee802.3-c45"

而那個reg參數 分別對應到 QCA8081的PHYAD[4..2]。

PhyAddr1
PhyAddr2

 mdio: mdio@90000 {

                pinctrl-0 = <&mdio_pins>;

                pinctrl-names = "default";

                phy-reset-gpio = <&tlmm 16 0>;

                status = "ok";

                phy0: ethernet-phy@0 {

                        reg = <0x10>;

                        compatible=”ethernet-phy-ieee802.3-c45”

                };

                phy1: ethernet-phy@1 {

                        reg = <0x14>;

                        compatible=”ethernet-phy-ieee802.3-c45”

                };

        };


這裡要注意的是 88Q2112 只有定義 PHYAD[2..0],PHYAD[4..3]要填甚麼值需要確認下。當然這個值還是要參考88Q2112的電路bootconf的設定。

ess-switch 應該跟cp02一樣。注意一下phyaddress的設定,以及加上ethernet-phy-ieee802.3-c45;

ess-switch@3a000000 {

                switch_cpu_bmp = <0x1>;  /* cpu port bitmap */

                switch_lan_bmp = <0x10>; /* lan port bitmap */

                switch_wan_bmp = <0x20>; /* wan port bitmap */

                switch_inner_bmp = <0xc0>; /*inner port bitmap*/

                switch_mac_mode = <0xf>; /* mac mode for uniphy instance0*/

switch_mac_mode1 = <0xf>; /* mac mode for uniphy instance1*/

                switch_mac_mode2 = <0xff>; /* mac mode for uniphy instance2*/

                qcom,port_phyinfo {

                        port@4 {

                                port_id = <4>;

                                phy_address = <0x10>;

                                port_mac_sel = "QGMAC_PORT";

                                ethernet-phy-ieee802.3-c45;

                        };

                        port@5 {

                                port_id = <5>;

                                phy_address = <0x14>;

                                port_mac_sel = "QGMAC_PORT";

                                ethernet-phy-ieee802.3-c45;

                        };

                };

        };


照理說現在應該可以利用MDIO讀取88Q2112的PHYID。 然後就要看看ssdk中是否有support這個PHY。讓Ethernet Driver可以正常的啟動。

在qsdk/qca/src/qca-ssdk/include/hsl/phy/hsl_phy.h 加個phy id define



/*qca808x_start*/

#define QCA8081_PHY_V1_1        0x004DD101

+#define 88Q2112_PHY                   0x002b0983

#define INVALID_PHY_ID          0xFFFFFFFF


在qsdk/qca/src/qca-ssdk/src/hsl/phy/hsl_phy.c 裡面 借用QCA8081的driver來用。這樣就不用全部重寫。

/*qca808x_start*/

                   case QCA8081_PHY_V1_1:

+                 case 88Q2112_PHY:

                             phytype = QCA808X_PHY_CHIP;

                             break;


之後循著 qca-ssdk/src/hsl/phy/qca808x.c, qca808x_phy.c 去debug。

 

mdio 覺得都無法正常的使用;

ssdk一開始會使用mvl88q_phy_reg_read 這個function。可是marvell的phy不支持Clause22的格式,這個呼叫就會失敗。進而導致異常。所以這裡要直接回應return PHY_INVALID_DATA;給ssdk,讓他不要再使用這個command。

在qca808x_phy.c中有qca808x_phy_reg_read/write, 以及qca808x_phy_mmd_read/write之分,xxx_phy_mmd_read/write 走的就是Clause45的方式來存取phy上的register。

我們在使用mvl88q的時候,就都要改成使用xxx_phy_mmd_read/write的方式。在DTS中加ethernet-phy-ieee802.3-c45;這個參數,無法全面地改用Clause45的方式來存取phy。只會影響部分的api。

尤其是註冊給kernel的ops function。其他模組在調用api的時候,傳進來的參數並沒有附帶c45的flag。 現在明確的分開成兩個api。可以確認,在DUT上可以透過mdio正確的access marvell 88q2112的register了。

因為無法全面使用CAUSE45的方式來存取phy,重新參考aquantia_phy.c 來實作marvell 88Q2112的driver,把最底層讀寫phy reg的函式,套用成 Clause45的格式。

static sw_error_t

marvell_phy_reg_read(a_uint32_t dev_id, a_uint32_t phy_id, a_uint32_t reg_mmd,

          a_uint32_t reg_id, a_uint16_t *phy_data)

{

          sw_error_t rv;

 

          SSDK_INFO("+++++++++++++++++++++++++++++++++++\n");

          reg_id = MARVELL_REG_ADDRESS(reg_mmd, reg_id);

          HSL_PHY_GET(rv, dev_id, phy_id, reg_id, phy_data);

          SSDK_INFO("+---------------------------------+\n");

 

          return rv;

}


這樣就可以正常的存取Phy了。可見88Q2112 對PHYAD[4..3]是一種Don’t care的狀態。

實際碰到的問題:

在T1 上量測到的波型,像是digital 的訊號。很奇怪。

wave


客人的線路圖中,C110,C113 與C157,C154 使用的數值應該是4700pF。用470pF反而把訊號給濾掉了。把電容換掉,波型就正常,auto nego就正常了。

schema

接著,就一個蘿蔔一個坑的把marvell_phy_api_ops_init 中所指定的call back function 給填寫好就行了。

static int marvell_phy_api_ops_init(void)

{

          int ret;

          hsl_phy_ops_t *marvell_phy_api_ops = NULL;

          SSDK_INFO("\n");

          SSDK_INFO("+++++++++++++++++++++++++++++++++++\n");

 

          marvell_phy_api_ops = kzalloc(sizeof(hsl_phy_ops_t), GFP_KERNEL);

          if (marvell_phy_api_ops == NULL) {

                   SSDK_ERROR("marvell phy ops kzalloc failed!\n");

                   return -ENOMEM;

          }

 

          phy_api_ops_init(MARVELL_PHY_CHIP);

 

          marvell_phy_api_ops->phy_speed_get = marvell_phy_get_speed;

          marvell_phy_api_ops->phy_speed_set = marvell_phy_set_speed;

          marvell_phy_api_ops->phy_duplex_get = marvell_phy_get_duplex;

          marvell_phy_api_ops->phy_duplex_set = marvell_phy_set_duplex;

          marvell_phy_api_ops->phy_autoneg_enable_set = marvell_phy_enable_autoneg;

          marvell_phy_api_ops->phy_restart_autoneg = marvell_phy_restart_autoneg;

          marvell_phy_api_ops->phy_autoneg_status_get = marvell_phy_autoneg_status;

          marvell_phy_api_ops->phy_autoneg_adv_set = marvell_phy_set_autoneg_adv;

          marvell_phy_api_ops->phy_autoneg_adv_get = marvell_phy_get_autoneg_adv;


透過QSDK中的ssdk framework,只要follow phy driver的模板把 marvel phy 的api都實作起來。就可以輕鬆地將3’rd party 芯片給porting上了。


參考:

aquantia_phy.c

qca808x_phy.c

linux-4.4\Documentation\devicetree

88Q2110_88Q2112 Datasheet

Marvell New SMI Register Access GUI User Guide

IPQ401x/IPQ806x/IPQ807x NSS Networking Debug User Guide

SOHO Switch Software Development Kit Reference Manual

 

Q&A:

  1. 我想換用其他廠牌的Switch IC,高通會幫忙porting嗎?

Ans: 不會,請參考SOHO Switch Software Development Kit Reference Manual自行porting。

 

  1. Porting 3’rd party 的Switch/Phy IC 碰到問題,該如何獲得協助?

Ans: 高通本身有完整的產品Switch/Phy IC,基本上不支持porting第三方的IC。Porting 3rd party的switch/phy IC 要靠自己,建議使用高通產品。詮鼎的優質客戶可直接聯繫我們PM。

 

  1. 甚麼是Clause45?

 clause45-1
clause45-2
clause45-3

  1. 甚麼是Clause 22?
clause22

      5. 掛載多的Switch, MDIO介面不夠用怎麼辦?

Ans: MDIO介面可以支持並聯多個Switch的。只要區分好Phy Address就可以。如果真沒辦法,可以使用I2C去模擬送出Clause22以及Clause45的指令,讀寫Switch內的設定。

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

參考來源

評論