おせわになります。もう といいます。
今、当社設計RZカスタムボードにてLinuxを組み込もうとしています。
ポーティングマニュアルに従い、BSP1.3.0をポーティングし、Linuxはブートできているのですが、
pingコマンドにてWindowsPC-カスタムボード間LAN通信でパケットロスが10~20%ぐらい発生してしまいます。
RSKボードなど評価ボードと比較してLAN関連で異なる部品といえば、
・PHYがTI社のDP83848Kであること。
・PHYのアドレスが1番であること
ぐらいです。
パケットロスの原因を調査するため、Linuxイーサネットドライバのsh_eth.c(関数sh_eth_rx)を調べると
受信ディスクリプタRD0のRACT、RDLEが0のとき、
受信フレーム位置(RFP1、RFP2)が00となっており、
また、そのときRFEビットは0なのに、RFS9、RFS4のビットが1となっています。
(受信FIFOオーバフロー、端数ビットフレーム受信エラー)
RFS9、RFS4のビットが立っているため、フレーム異常として破棄されて
パケットロスとなっているみたいです。
ハード要因も疑いましたが、PHY-CPU間の通信波形には異常が見られずお手上げ状態です。
なにか調査すべき点、考えられる原因ありませんでしょうか?
もう さん
> pingコマンドにてWindowsPC-カスタムボード間LAN通信でパケットロスが10~20%ぐらい発生してしまいます。
もう少し詳しく、機器構成や実験方法を教えていただけますか?上の文を素直に読むと「Windows から Windows の ping コマンドでカスタムボードの RZ/A1 Linux にping すると...」となるのですが、1秒に1回程度の ping で 10~20%のパケットロス?ですか?また、Windows PC のイーサネットカード/コントローラ、ping コマンドに指定したオプション、等々もお願いします。
> パケットロスの原因を調査するため、Linuxイーサネットドライバのsh_eth.c(関数sh_eth_rx)を調べると ~中略~> パケットロスとなっているみたいです。
RZ/A1 と PHY 間は、RMII ではなく MII で接続されていますね?RZ/A1 Linux 上で ethtool や miitool を使って、オートネゴシエーションを再実行し、インタフェースの状態を表示してみてください。同じく ping の実験後、netstat や ifconfig で受信エラーが出ていることを確認してください。
御社と同様な printk を加えたドライバを使い、flood ping でネットワークに負荷をかけたり、意図的にCPUやバスに負荷をかけたり、ケーブルを抜き差ししたり、意図的に CRCエラーのパケットを送ってみたりと、色々と試してみて、(ifconfig で表示できる) 一通りの受信エラーを起こしてみましたが、
RX packets:55780 errors:408 dropped:32 overruns:408 frame:912
当方の環境では、ご提示のようなエラー
Read RD0:610 RD1(Flame):62 RD1(Buffer):610 entry:28
が出ることは、ありませんでした(当方では、RD0 は、3000 か 7000)。
また、御社と類似した事例があるか確認してみましたが、ありませんでした。
ですので、現時点では、御社のボード(ハードウェア要因)に問題があるのでは?と考えています。
念のため、上のエラー表示、特に RD0 の値が正しく表示出来ているか、今一度、ソースをご確認ください(RFE がセットされないのが不思議です)。
また、可能でしたら、接続機器を変える(ケーブル/ハブ/スイッチを交換してみる、ケーブルで直結する、ダムハブ/スイッチで中継する、など)、あるいは、ethtool などでリンク速度や全二重/半二重などを変えてみる、で状況が変わるか確認してみてください。
> printk("Read RD0:%X RD1(Flame):%X RD1(Buffer):%X entry:%d\n", desc_status,dec_flength, dec_blength, entry);> にて表示しています。そちらで表示された状況と同じでしょうか?
最初は、御社同様、if の then 節に置いたのですが、何も出ないので、最終的に if の前に置いた以外は、ほぼ同じです。
printk("Read RD0:%04x, RD1(Flame):%04x RD1(Buffer):%04x entry:%d\n", desc_status, rxdesc->frame_length, rxdesc->buffer_length, mdp->cur_rx);
> ご指摘のようにRFEはセットされていないので、実はエラーではなかったりすると> うれしいのですが、RD0のRACT、RDLE、RFP1、RFP0が全部0となることは> ありえないのかなと思います。(あってますか?)> 全部0となる状況ってどんな場合なのでしょうか?
このドライバ自体は、GbE のコントローラ"も"サポートしていますから、例えば、ジャンボフレームを受信した場合には、複数のバッファに分割して保存することになり、RFP が 00/01/10 の場合もあるのでしょう。
> GenericPHYを使用する場合、なにか気をつける点とかはないでしょうか?
基本、標準(共通)のレジスタ/ビットを操作するだけですから、PHY が特殊な機能をデフォルトにしていない限り、問題はないはずです。
もし、MAC-PHY 間は大丈夫そうとの感触をお持ちならば、RJ45-PHY 間を疑うのも1つかもしれません。その場合、PHY の拡張レジスタに役立つものがあるかもしれません。
> RD0、RD1などを受信ディスクリプタのコピーはDMAが行っていると思いますが> なにか設定間違いなどありえますか?(Linuxドライバそのまま使用していますが) (中略)> バスステートコントローラはSD-RAMを32ビットとして設定はしているつもりですが> 本件のような不具合発生が関連する可能性はないでしょうか?
RZ/A1 の内部バスの構成を考え合わせると、設定間違いや不具合があるとしたらイーサネットコントローラではなくバスステートコントローラの方でしょう。
タグに RZ/A1H とありますが、現状、内蔵 RAM に 1KB の空きがありますか?受信ディスクリプタを外部 SDRAM から内蔵 RAM に移動して、不具合が修正されるか試してみてください。
内蔵 RAM に確保した 1 KB の領域の先頭物理アドレスを 0x20XXXXXX とすると、Github の最新ソースの drivers/net/ethernet/renesas/sh_eth.c で
1190 static int sh_eth_ring_init(struct net_device *ndev) 1191 { 1192 struct sh_eth_private *mdp = netdev_priv(ndev); 1193 int rx_ringsize, tx_ringsize, ret = 0; (中略) 1220 /* Allocate all Rx descriptors. */ 1221 rx_ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; - 1222 mdp->rx_ring = dma_alloc_coherent(NULL, rx_ringsize, &mdp->rx_desc_dma, - 1223 GFP_KERNEL); + BUG_ON(rx_ringsize > (16 * 64)); + mdp->rx_ring = ioremap_uncache(0x20XXXXXX, rx_ringsize); 1224 if (!mdp->rx_ring) { 1225 ret = -ENOMEM; 1226 goto desc_ring_free; 1227 } (中略) 1241 desc_ring_free: 1242 /* free DMA buffer */ - 1243 dma_free_coherent(NULL, rx_ringsize, mdp->rx_ring, mdp->rx_desc_dma); + iounmap(mdp->rx_ring); 1244 (中略) 1254 static void sh_eth_free_dma_buffer(struct sh_eth_private *mdp) 1255 { 1256 int ringsize; 1257 1258 if (mdp->rx_ring) { 1259 ringsize = sizeof(struct sh_eth_rxdesc) * mdp->num_rx_ring; - 1260 dma_free_coherent(NULL, ringsize, mdp->rx_ring, - 1261 mdp->rx_desc_dma); + iounmap(mdp->rx_ring); 1262 mdp->rx_ring = NULL;
のように修正してください。# 試していませんが。
なお、確保する領域は、1 KB だったと思いますが、もし足りなければ、BUG_ON() が呼ばれますから、増やしてください。
> 修正して試してみました。(ioremap_uncacheだとエラーになるので、ioremap_nocacheにしてmakeしました。あってますか?)
私の勘違いです。ioremap_nocacheで正しいです。
前半は、確認してから回答するとして、とりあえず、後半だけ回答します。
> あと、別件ですが、前の返信を見ていただくとわかりますが、RD1の受信バッファサイズの値が> 0x610で表示されているのですが、RZ/A1Hのハードウェアマニュアルを見ると、> RBLの値は、32バイト境界で指定とあります。> 0x610だと32で割り切れません。
最初、受信バッファサイズに32バイト境界?と思ったのですが、確認してみると、確かにハードウェアマニュアルにそのように記載されていますね。推測ですが、E-DMACが受信フレームを32バイト単位で転送するため、最後にゴミが付く場合があり、それを心配して、こうした記述になったのでしょう。RBLは、0x610 で正しい(ドライバの記述通り)です。また、イーサネットの最大フレーム長は、1518バイトで、VLANタグを含めても、1522バイト(=0x5F2)ですから、転送サイズが 0x600を超えることは、通常、ありません。
これで回答になっていますか?