MarvellのORIONのネットワークドライバは以下にあります。
sys/dev/marvell/if_mvgbe.c
sys/dev/marvell/の下にはごちゃまぜでmarvellのいろいろな機能のチップのコードが入っていて、こういうdevの下のディレクトリはFreeBSDでは見た事なくて斬新です。^ ^;
ターゲットのモジュールはmiiでスイッチの88E6131に接続されているようです。もちろんサポートが無いのでukphyとして認識されます。
88E6131は8ポートのようで、内蔵PHYが3で後はMACだけなのかもしれません
。ターゲットは外付けPHYを2個つけて、あと一つのMACをSOCに接続しているものと思われます。初期のgigaのスイッチなので構成が変則的です。
phy関係は
sys/dev/mii/
にあります。
調べてみると、ここにあるmvphy.cがMarvellのスイッチの88E6060のコードのようです。
一般的なスイッチはPHYと同じインターフェースで、OS側の新しい作り込みが必要ないようになっています。
mdioで32のアドレスについて32のアドレスが読めます。アドレスを0からスキャンしてPHYのIDを確認して対応するPHYのコードをattachします。
88E6060は100の初期のスイッチでFON2201などで使われています。6060は.1qではなくて原始的なスイッチでこの後の6065が.1qになっています。
6060はいろいろなモジュールで使われていましたが、6065はそれほど多く見かけません。これは6065が出来た頃にはすでにgigaのスイッチが出てきていてMarvellが主力をgigaの方にシフトしていたのからかもしれません。
6060と6065はマイナーチェンジのように見えますが、大きく違っていて6065はこれ以降(gigaも含めて)のアーキテクチャの基本となります。
とりあえずこのコードをベースにいじるのが良さそうです。
まずはほんとに88E6131がいるか調べてみます。
diff --git a/sys/dev/marvell/if_mvgbe.c b/sys/dev/marvell/if_mvgbe.c
index c54c7c446b7..934ee8c1b3f 100644
--- a/sys/dev/marvell/if_mvgbe.c
+++ b/sys/dev/marvell/if_mvgbe.c
@@ -896,6 +896,9 @@ mvgbe_attach(device_t parent, device_t self, void *aux)
mii->mii_readreg = mvgbec_miibus_readreg;
mii->mii_writereg = mvgbec_miibus_writereg;
mii->mii_statchg = mvgbec_miibus_statchg;
+uint16_t pid;
+mvgbec_miibus_readreg(self, 0x10, 3, &pid);
+printf("MORIMORI PID %x\n", pid);
sc->sc_ethercom.ec_mii = mii;
ifmedia_init(&mii->mii_media, 0, mvgbe_mediachange, mvgbe_mediastatus);
実行してみると
[ 1.0000000] MORIMORI PID 1066
Switch Identifier Register
Offset: 0x03 or Decimal 3
Bits | Field | Type | Description |
---|---|---|---|
15:4 | ProductNum | RO | Product Number or identifier. |
3:0 | Rev | RO | Revision Identifier. |
Marvellのオープンソース(dsa)で定義されているPORT_SWITCH_ID_6131_B2のID(0x1066)が返ってくるのでちゃんと接続されてます。
実はこのスイッチFreeBSDではうまく動かすことが出来なかったんで、再度トライしてみたいと思います。
FreeBSDではそもそも古いarmのサポートが壊れていて、現実的に使えなかったし、clangでくそ時間がかかるのであきらめたような記憶があります。
u-bootでネットワークが使えているので、使えるようにできないわけがありません。
6131のmiiのレジスタは以下のようになっています。
Addr | Type |
---|---|
0x0c-0x0f | PHY Registor |
0x10-0x17 | Switch Registor |
0x1b | Grobal Registor |
0x1c | Grobal Registor 2 |
6131にはPHY Polling Unit (PPU)というのが入っていて、PHYの状態を見てるみたいだけど、よく分からないのが上のPHY Registorに出てこない。そもそも内蔵PHYは3つしかないのに4つレジスタがあるのも意味不明。
Marvellのいけてないところは、ちょこちょこ仕様を変えるところ。6131は初期のgigaのスイッチなので、どうもこれ以降の製品と微妙に仕様が違うっぽい。
たとえば6065のPHY Registorは0始まりなのに、6131ではc始まりなってお終わりをfにしたよう。また6065のGrobal RegistorとGrobal Registor2の順番が6131とは逆です。またこれらの後のチップでGrobal Registor1を追加してます。
Switch Registorのダンプ
[ 1.0000000] MORI SW Reg 0 fd80 7080 7080 6e88 6086 7086 6086 7086
[ 1.0000000] MORI SW Reg 1 3 3 3 33 403 403 403 403
[ 1.0000000] MORI SW Reg 2 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 3 1066 1066 1066 1066 1066 1066 1066 1066
[ 1.0000000] MORI SW Reg 4 77 77 77 77 74 74 74 77
[ 1.0000000] MORI SW Reg 5 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 6 708 708 708 787 7ef 7df 7bf 708
[ 1.0000000] MORI SW Reg 7 1 2 3 1 1 1 1 8
[ 1.0000000] MORI SW Reg 8 cf cf cf cf cf cf cf cf
[ 1.0000000] MORI SW Reg 9 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg a 3000 3000 3000 3000 3000 3000 3000 3000
[ 1.0000000] MORI SW Reg b 1 2 4 8 10 20 40 80
[ 1.0000000] MORI SW Reg c 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg d 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg e 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg f 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 10 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 11 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 12 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 13 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 14 403 403 403 8403 403 403 403 403
[ 1.0000000] MORI SW Reg 15 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 16 73d 702 702 700 f41 f02 f41 f02
[ 1.0000000] MORI SW Reg 17 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 18 3210 3210 3210 3210 3210 3210 3210 3210
[ 1.0000000] MORI SW Reg 19 7654 7654 7654 7654 7654 7654 7654 7654
[ 1.0000000] MORI SW Reg 1a 8280 0 250 f00 0 6db1 2863 10c
[ 1.0000000] MORI SW Reg 1b 24 0 0 4 0 0 0 0
[ 1.0000000] MORI SW Reg 1c 0 0 0 0 0 0 0 0
[ 1.0000000] MORI SW Reg 1d c84 c84 c84 c84 c84 c84 c84 c84
[ 1.0000000] MORI SW Reg 1e 22 22 22 22 22 22 22 22
[ 1.0000000] MORI SW Reg 1f 4444 4444 4444 4444 4444 4444 4444 4444
PORTは左から2,1,0,7,5でCPUポートが3のようです。
最初.1qで設定しているのかと思ったのですが、そんな面倒な事しないですよね。普通にPORT BASEでした。
ダンプを見るとPORT BASE VLAN(6)で各ポートがCPUポートへの接続になっているようなので、全ポートにしたところポート間の疎通がとれました。
から
にしました。
あとはCPUポートとの通信ですが、ポート間の疎通が取れているのでスイッチとしてはCPUポートにもパケットを投げていて、スイッチとSOCの接続設定に問題があると思われます。
この場合いスイッチかSOCかどちらかになりますが、スイッチ側は明らかに初期化されているので、おそらくSOC側の問題の可能性が濃厚です。
このSOCのEthernetはMII,GMII,RGMIIで外部と接続することができます。この接続設定が上手くて規定ないと想像できます。
今はu-bootでネットワークブートしているので、スイッチやインターフェースが初期化されてその副作用で上手くいくことがあります。ローカルのflashから起動された場合は初期化されない可能性もあり、その時はスイッチやインターフェースのレジスタをすべて同じ設定にしたら良いです。
sys/dev/marvell/if_mvgbe.cのmbgbe_init()のMVGBE_PSCの設定を外したとところpingが通りました。めでたしめでたし。
FreeBSDにはetherswitchフレームワークという強力な仕組みがあります。かなり複雑な仕組みなのでNetBSDポートするのは難しいと思われますが、なにか簡単にスイッチを扱える仕組みがあるといいのですが。
STR9102にVitesseのスイッチのVSC7385が付いたモジュールがあります。VSC7385はパラレルかSPIでの制御が可能なようですが、STR9102にはSPIが無いので、I2CなEPROMに固定で設定を入れているようです。