source: azure_iot_hub_f767zi/trunk/asp_baseplatform/pdic/stm32f7xx/emac.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 43.4 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 * Copyright (C) 2015-2019 by TOPPERS PROJECT Educational Working Group.
9 *
10 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
11 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
12 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
13 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
14 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
15 * スコード中に含まれていること.
16 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
17 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
18 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
19 * の無保証規定を掲載すること.
20 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
21 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
22 * と.
23 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
24 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
25 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
26 * 報告すること.
27 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
28 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
29 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
30 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
31 * 免責すること.
32 *
33 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
34 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
35 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
36 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
37 * の責任を負わない.
38 *
39 * @(#) $Id$
40 */
41/*
42 *
43 * STM32F7XX:EMAC(LWIP用)ドライバ関数群
44 *
45 */
46#include "kernel_impl.h"
47#include <t_syslog.h>
48#include <t_stdlib.h>
49#include <stdio.h>
50#include <string.h>
51#include <sil.h>
52#include <target_syssvc.h>
53#include <string.h>
54#include "device.h"
55#include "phyreg.h"
56#include "emac.h"
57
58/*
59 * SIL関数のマクロ定義
60 */
61#define sil_orw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) | (b))
62#define sil_andw_mem(a, b) sil_wrw_mem((a), sil_rew_mem(a) & ~(b))
63#define sil_modw_mem(a, b, c) sil_wrw_mem((a), (sil_rew_mem(a) & (~b)) | (c))
64
65#define MIN(a, b) ((a) > (b) ? (b) : (a))
66
67/*
68 * EMACポートIDから管理ブロックを取り出すためのマクロ
69 */
70#define INDEX_EMAC(emacid) ((uint_t)((emacid) - 1))
71
72/*
73 * AUTO NEGOTIATION判定
74 */
75#define is_autonego(h) (((h)->linkvalue & EMAC_LINK_AUTONEGO) != 0)
76
77/* MDIO の Ready 待ち時間(msec) */
78#define EMAC_MDIO_READY_WAIT_MSEC 50
79
80#define MII_CLKRANGE_150_250M (0x10)
81
82
83/*
84 * MIIモード定義
85 */
86#define EMAC_CTRL_PHYSEL_GMII_MII 0x0
87#define EMAC_CTRL_PHYSEL_RGMII 0x1
88
89/*
90 * DESCRIPTOR定義
91 */
92/* TX DESCRIPTERステータスビット定義 */
93#define DESC_TXSTS_OWNBYDMA (1 << 31) /* OWN bit: descriptor is owned by DMA engine */
94#define DESC_TXSTS_TXINT (1 << 30) /* Interrupt on Completion */
95#define DESC_TXSTS_TXLAST (1 << 29) /* Last Segment */
96#define DESC_TXSTS_TXFIRST (1 << 28) /* First Segment */
97#define DESC_TXSTS_TXCRCDIS (1 << 27) /* Disable CRC */
98
99#define DESC_TXSTS_TXPADDIS (1 << 26) /* Disable Padding */
100#define DESC_TXSTS_DMATTSE (1 << 25) /* Transmit Time Stamp Enable */
101#define DESC_TXSTS_TXCHECKINSCTRL (3 << 22)
102#define DESC_TXSTS_TXRINGEND (1 << 21) /* Transmit End of Ring */
103#define DESC_TXSTS_TXCHAIN (1 << 20) /* Second Address Chained */
104#define DESC_TXSTS_MSK (0x1FFFF << 0)
105#define DESC_TXSTS_IHE (1 << 16) /* IP Header Error */
106#define DESC_TXSTS_ES (1 << 15) /* Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT */
107#define DESC_TXSTS_JT (1 << 14) /* Jabber Timeout */
108#define DESC_TXSTS_FF (1 << 13) /* Frame Flushed: DMA/MTL flushed the frame due to SW flush */
109#define DESC_TXSTS_PCE (1 << 12) /* Payload Checksum Error */
110#define DESC_TXSTS_LCA (1 << 11) /* Loss of Carrier: carrier lost during transmission */
111#define DESC_TXSTS_NC (1 << 10) /* No Carrier: no carrier signal from the transceiver */
112#define DESC_TXSTS_LCO (1 << 9) /* Late Collision: transmission aborted due to collision */
113#define DESC_TXSTS_EC (1 << 8) /* Excessive Collision: transmission aborted after 16 collisions */
114#define DESC_TXSTS_VF (1 << 7) /* VLAN Frame */
115#define DESC_TXSTS_CC (15 << 3) /* Collision Count */
116#define DESC_TXSTS_ED (1 << 2) /* Excessive Deferral */
117#define DESC_TXSTS_UF (1 << 1) /* Underflow Error: late data arrival from the memory */
118#define DESC_TXSTS_DB (1 << 0) /* Deferred Bit */
119
120/* RX DESCRIPTERステータスビット定義 */
121#define DESC_RXSTS_OWNBYDMA (1 << 31) /* OWN bit: descriptor is owned by DMA engine */
122#define DESC_RXSTS_DAFILTERFAIL (1 << 30) /* DA Filter Fail for the rx frame */
123#define DESC_RXSTS_FRMLENMSK (0x3FFF << 16)
124#define DESC_RXSTS_FRMLENSHFT (16)
125
126#define DESC_RXSTS_ERROR (1 << 15) /* Error summary: OR of the following bits */
127#define DESC_RXSTS_DESCERROR (1 << 14) /* Descriptor error: no more descriptors for receive frame */
128#define DESC_RXSTS_SAFILTERFAIL (1 << 13) /* SA Filter Fail for the received frame */
129#define DESC_RXSTS_FRAMELE (1 << 12) /* Frame size not matching with length field */
130#define DESC_RXSTS_OFERROR (1 << 11) /* Overflow Error: Frame was damaged due to buffer overflow */
131#define DESC_RXSTS_RXVLANTAG (1 << 10) /* VLAN Tag: received frame is a VLAN frame */
132#define DESC_RXSTS_RXFIRST (1 << 9) /* First descriptor of the frame */
133#define DESC_RXSTS_RXLAST (1 << 8) /* Last descriptor of the frame */
134#define DESC_RXSTS_IPV4HCE (1 << 7) /* IPC Checksum Error: Rx Ipv4 header checksum error */
135#define DESC_RXSTS_RXCOLLISION (1 << 6) /* Late collision occurred during reception */
136#define DESC_RXSTS_RXFRAMEETHER (1 << 5) /* Frame type - Ethernet, otherwise 802.3 */
137#define DESC_RXSTS_RXWATCHDOG (1 << 4) /* Receive Watchdog Timeout: watchdog timer expired during reception */
138#define DESC_RXSTS_RXMIIERROR (1 << 3) /* Receive error: error reported by MII interface */
139#define DESC_RXSTS_RXDRIBBLING (1 << 2) /* Dribble bit error: frame contains non int multiple of 8 bits */
140#define DESC_RXSTS_RXCRC (1 << 1) /* CRC error */
141#define DESC_RXSTS_MAMPCE (1 << 0)) /* Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */
142
143/* TX DESCRIPTOR 制御ビット定義 */
144#define DESC_TXCTRL_SIZE1SHFT (0)
145#define DESC_TXCTRL_SIZE1MASK (0x1FFF << DESC_TXCTRL_SIZE1SHFT)
146#define DESC_TXCTRL_SIZE2SHFT (16)
147#define DESC_TXCTRL_SIZE2MASK (0x1FFF << DESC_TXCTRL_SIZE2SHFT)
148
149/* RX DESCRIPTOR 制御ビット定義 */
150#define DESC_RXCTRL_RXINTDIS (1 << 31)
151#define DESC_RXCTRL_RXRINGEND (1 << 15)
152#define DESC_RXCTRL_RXCHAIN (1 << 14)
153
154#define DESC_RXCTRL_SIZE1SHFT (0)
155#define DESC_RXCTRL_SIZE1MASK (0x1FFF << DESC_RXCTRL_SIZE1SHFT)
156#define DESC_RXCTRL_SIZE2SHFT (16)
157#define DESC_RXCTRL_SIZE2MASK (0x1FFF << DESC_RXCTRL_SIZE2SHFT)
158
159
160/*
161 * EMAC制御設定
162 */
163#define ETH_MACCR_MASK (ETH_MACCR_WD | ETH_MACCR_JD | ETH_MACCR_IFG | ETH_MACCR_CSD | \
164 ETH_MACCR_FES | ETH_MACCR_ROD | ETH_MACCR_LM | ETH_MACCR_DM | \
165 ETH_MACCR_IPCO | ETH_MACCR_RD | ETH_MACCR_APCS | ETH_MACCR_DC | \
166 ETH_MACCR_BL)
167#define ETH_MACCR_INIT (ETH_MACCR_IFG_96Bit | ETH_MACCR_FES | ETH_MACCR_DM | \
168 ETH_MACCR_IPCO | ETH_MACCR_RD | ETH_MACCR_BL_10)
169#define ETH_MACFFR_INIT (ETH_MACFFR_PCF_BlockAll)
170#define ETH_MACFCR_MASK (ETH_MACFCR_PT | ETH_MACFCR_ZQPD | ETH_MACFCR_PLT | ETH_MACFCR_UPFD | \
171 ETH_MACFCR_RFCE | ETH_MACFCR_TFCE)
172#define ETH_MACFCR_INIT ((0<<16) | ETH_MACFCR_ZQPD | ETH_MACFCR_PLT_Minus4)
173#define ETH_MACVLANTR_INIT ((0<<16) | 0x0000)
174
175#define ETH_DMAOMR_MASK (ETH_DMAOMR_DTCEFD | ETH_DMAOMR_RSF | ETH_DMAOMR_TSF | ETH_DMAOMR_DFRF | \
176 ETH_DMAOMR_ST | ETH_DMAOMR_TTC | ETH_DMAOMR_FEF | ETH_DMAOMR_FUGF | \
177 ETH_DMAOMR_RTC | ETH_DMAOMR_OSF)
178#define ETH_DMAOMR_INIT (ETH_DMAOMR_RSF | /* ETH_DMAOMR_TSF | */ ETH_DMAOMR_TTC_64Bytes | \
179 ETH_DMAOMR_RTC_64Bytes | ETH_DMAOMR_OSF)
180#define ETH_DMABMR_INIT (ETH_DMABMR_AAB | ETH_DMABMR_FB | ETH_DMABMR_RDP_32Beat | ETH_DMABMR_PBL_32Beat | \
181 ETH_DMABMR_EDE | (0<<2) | ETH_DMABMR_RTPR_1_1)
182
183/*
184 * EMAC-DMA割り込み設定
185 */
186#define DMA_INTER_RXSTAT_ERROR (ETH_DMAIER_ROIE | ETH_DMAIER_RBUIE | ETH_DMAIER_RPSIE | ETH_DMAIER_RWTIE)
187#define DMA_INTR_NORMAL (ETH_DMAIER_NISE | ETH_DMAIER_RIE | ETH_DMAIER_TIE)
188#define DMA_INTR_ABNORMAL (ETH_DMAIER_AISE | ETH_DMAIER_TUIE | ETH_DMAIER_ETIE | \
189 ETH_DMAIER_FBEIE | ETH_DMAIER_TPSIE | ETH_DMAIER_TJTIE | \
190 DMA_INTER_RXSTAT_ERROR)
191#define DMA_INTR_DEFAULT_MASK (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL | ETH_DMAIER_ERIE)
192
193/*
194 * PHY FEATURES 定義
195 */
196#define ADVERTISE_MASK1 (ADVERTISE_10HALF | ADVERTISE_10FULL | \
197 ADVERTISE_100HALF | ADVERTISE_100FULL | \
198 ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM)
199
200
201/*
202 * PHY-GPIO定義
203 */
204#define GPIO_ETH_AF 0x0B
205#define RMII_REF_CLK_PORT TADR_GPIOA_BASE
206#define RMII_REF_CLK_BIN 1
207#define RMII_MDIO_PORT TADR_GPIOA_BASE
208#define RMII_MDIO_PIN 2
209#define RMII_MDC_PORT TADR_GPIOC_BASE
210#define RMII_MDC_PIN 1
211#define RMII_MII_CRS_DV_PORT TADR_GPIOA_BASE
212#define RMII_MII_CRS_DV_PIN 7
213#define RMII_MII_RXD0_PORT TADR_GPIOC_BASE
214#define RMII_MII_RXD0_PIN 4
215#define RMII_MII_RXD1_PORT TADR_GPIOC_BASE
216#define RMII_MII_RXD1_PIN 5
217#define RMII_MII_RXER_PORT TADR_GPIOG_BASE
218#define RMII_MII_RXER_PIN 2
219#define RMII_MII_TX_EN_PORT TADR_GPIOG_BASE
220#define RMII_MII_TX_EN_PIN 11
221#define RMII_MII_TXD0_PORT TADR_GPIOG_BASE
222#define RMII_MII_TXD0_PIN 13
223#ifndef RMII_MII_TXD1_PORT
224#define RMII_MII_TXD1_PORT TADR_GPIOB_BASE
225#define RMII_MII_TXD1_PIN 13
226#endif
227
228/*
229 * EMACハードウェア設定構造体
230 */
231typedef struct _I2C_PortControlBlock{
232 uint32_t base;
233 uint8_t intno;
234 uint8_t physel_shift;
235 uint8_t phy_sel;
236 uint8_t phy_addr;
237} EMAC_PortControlBlock;
238
239/*
240 * EMACポート設定テーブル
241 */
242static const EMAC_PortControlBlock emac_pcb[NUM_MACPORT] = {
243 { TADR_ETH_BASE, IRQ_VECTOR_ETH, 23, EMAC_CTRL_PHYSEL_RGMII, 0}
244};
245
246/*
247 * EMAC ハンドラ
248 */
249static EMAC_Handle_t EMacHandle[NUM_MACPORT];
250
251static uint32_t
252emac_ether_clockdiv(void)
253{
254#if SysFreHCLK >= 20000000 && SysFreHCLK < 35000000
255 /* CSR Clock Range between 20-35 MHz */
256 retrun (uint32_t)ETH_MACMIIAR_CR_Div16;
257#elif SysFreHCLK >= 35000000 && SysFreHCLK < 60000000
258 /* CSR Clock Range between 35-60 MHz */
259 return (uint32_t)ETH_MACMIIAR_CR_Div26;
260#elif SysFreHCLK >= 60000000 && SysFreHCLK < 100000000
261 /* CSR Clock Range between 60-100 MHz */
262 return (uint32_t)ETH_MACMIIAR_CR_Div42;
263#elif SysFreHCLK >= 100000000 && SysFreHCLK < 150000000
264 /* CSR Clock Range between 100-150 MHz */
265 return (uint32_t)ETH_MACMIIAR_CR_Div62;
266#else
267 /* CSR Clock Range between 150-216 MHz */
268 return (uint32_t)ETH_MACMIIAR_CR_Div102;
269#endif
270}
271
272/*
273 * MDIOのREADY待ち
274 * parameter1 base EMACレジスタのベースアドレス
275 * return E_OKで正常終了
276 */
277static ER
278emac_mdio_wait_ready(uint32_t base)
279{
280 int i;
281
282 for (i = 0; i < (EMAC_MDIO_READY_WAIT_MSEC*10); i++) {
283 if((sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR)) & ETH_MACMIIAR_MB) == 0)
284 return E_OK;
285 sil_dly_nse(100*1000);
286 }
287 syslog_0(LOG_ERROR, "EMAC:Error mdio timeout!");
288 return E_TMOUT;
289}
290
291/*
292 * PHYレジスタへのデータ書き込み
293 * parameter1 hmac EMACハンドラへのポインタ
294 * parameter2 reg レジスタ番号
295 * parameter3 val 書き込み値
296 * return E_OKで正常終了
297 */
298static ER
299emac_mdio_write(EMAC_Handle_t *hmac, int reg, int val)
300{
301 uint32_t miiaddr;
302 ER ercd = E_TMOUT;
303
304 if(hmac->Init.semid != 0)
305 wai_sem(hmac->Init.semid);
306
307 miiaddr = sil_rew_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIAR)) & ETH_MACMIIAR_CR;
308 miiaddr |= ((hmac->phy_addr << 11) & ETH_MACMIIAR_PA) | \
309 ((reg << 6) & ETH_MACMIIAR_MR) | ETH_MACMIIAR_MW;
310
311 /*
312 * READY待ち
313 */
314 if(emac_mdio_wait_ready(hmac->base) == E_OK){
315 /*
316 * データ設定後、PHYアドレスセット
317 */
318 sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIDR), val);
319 sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIAR), (miiaddr | ETH_MACMIIAR_MB));
320
321 /*
322 * READY待ち
323 */
324 if (emac_mdio_wait_ready(hmac->base) == E_OK)
325 ercd = E_OK;
326 }
327
328 if(hmac->Init.semid != 0)
329 sig_sem(hmac->Init.semid);
330 return ercd;
331}
332
333/*
334 * PHYレジスタからのデータ読み込み
335 * parameter1 hmac EMACハンドラへのポインタ
336 * parameter2 reg レジスタ番号
337 * return 0以上でレジスタ値
338 */
339static int
340emac_mdio_read(EMAC_Handle_t *hmac, int reg)
341{
342 uint32_t miiaddr;
343 int val = -1;
344
345 if(hmac->Init.semid != 0)
346 wai_sem(hmac->Init.semid);
347
348 miiaddr = sil_rew_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIAR)) & ETH_MACMIIAR_CR;
349 miiaddr |= ((hmac->phy_addr << 11) & ETH_MACMIIAR_PA) | ((reg << 6) & ETH_MACMIIAR_MR);
350
351 /*
352 * READY待ち
353 */
354 if(emac_mdio_wait_ready(hmac->base) == E_OK){
355 /*
356 * PHYアドレスセット
357 */
358 sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIAR), (miiaddr | ETH_MACMIIAR_MB));
359
360 /*
361 * READY待ちの後、データ取得
362 */
363 if(emac_mdio_wait_ready(hmac->base) == E_OK)
364 val = sil_rew_mem((uint32_t *)(hmac->base+TOFF_ETH_MACMIIDR)) & 0x0000ffffUL;
365 }
366
367 if(hmac->Init.semid != 0)
368 sig_sem(hmac->Init.semid);
369 return val;
370}
371
372/*
373 * PHYの初期設定
374 * parameter1 hmac EMACハンドラへのポインタ
375 * parameter2 phyadr PHYアドレス(32以上ならば自動センス)
376 * return E_OKで正常終了
377 */
378static ER
379emac_phy_init(EMAC_Handle_t *hmac, uint8_t phy_addr)
380{
381 int val;
382
383 if(phy_addr < 0x20){
384 hmac->phy_addr = phy_addr;
385 val = emac_mdio_read(hmac, MII_PHYSID1);
386 if((val > 0) && (val != 0xffff))
387 return E_OK;
388 else{
389 syslog_1(LOG_ERROR, "EMAC:emac_phy_init Error unkown phy address(%d)", phy_addr);
390 return E_ID;
391 }
392 }
393
394 /*
395 * 自動センスモード
396 */
397 for(phy_addr = 0; phy_addr < 0x20; phy_addr++){
398 hmac->phy_addr = phy_addr;
399 val = emac_mdio_read(hmac, MII_PHYSID1);
400 if((val > 0) && (val != 0xffff))
401 return E_OK;
402 }
403 syslog_0(LOG_ERROR, "EMAC:emac_phy_init Error unkown phy address");
404 return E_ID;
405}
406
407/*
408 * PHYをリセットする
409 * parameter1 hmac EMACハンドラへのポインタ
410 * return E_OKで正常終了
411 */
412static ER
413emac_phy_reset(EMAC_Handle_t *hmac)
414{
415 int i, val;
416
417 val = emac_mdio_read(hmac, MII_BMCR);
418 val &= ~(BMCR_ISOLATE | BMCR_ANENABLE);
419 val |= BMCR_RESET;
420 emac_mdio_write(hmac, MII_BMCR, val);
421
422 for(i = 0 ; i < 1000; i++){
423 val = emac_mdio_read(hmac, MII_BMCR);
424 if (val < 0)
425 break;
426 if ((val & BMCR_RESET) == 0) {
427 if (val & BMCR_ISOLATE) {
428 val &= (~BMCR_ISOLATE);
429 emac_mdio_write(hmac, MII_BMCR, val);
430 }
431 return E_OK;
432 }
433 dly_tsk(1);
434 }
435 syslog_0(LOG_ERROR, "EMAC:emac_phy_reset Error spin reset timeout");
436 return E_TMOUT;
437}
438
439/*
440 * PHYの状態を取り出す
441 * parameter1 hmac EMACハンドラへのポインタ
442 * return PHYの状態値
443 */
444static uint32_t
445emac_phy_features(EMAC_Handle_t *hmac)
446{
447 uint32_t bmsr;
448 uint32_t mode = ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
449
450 bmsr = emac_mdio_read(hmac, MII_BMSR);
451 if((bmsr & BMSR_10HALF) != 0)
452 mode |= ADVERTISE_10HALF;
453 if((bmsr & BMSR_10FULL) != 0)
454 mode |= ADVERTISE_10FULL;
455 if((bmsr & BMSR_100HALF) != 0)
456 mode |= ADVERTISE_100HALF;
457 if((bmsr & BMSR_100FULL) != 0)
458 mode |= ADVERTISE_100FULL;
459 return mode;
460}
461
462/*
463 * PHY処理開始要求
464 * parameter1 hmac EMACハンドラへのポインタ
465 * parameter2 link PHY設定値
466 * return E_OKで正常終了
467 */
468static ER
469emac_phy_start(EMAC_Handle_t *hmac, uint32_t link)
470{
471 ER ercd;
472 uint32_t id;
473 uint32_t mode, val;
474 int speed = 0, duplex = 0;
475
476 /*
477 * PHYをリセットする
478 */
479 if((ercd = emac_phy_reset(hmac)) != E_OK)
480 return ercd;
481
482 /*
483 * PHY情報を取得する
484 */
485 hmac->phy_features = emac_phy_features(hmac);
486 syslog_1(LOG_INFO, "EMAC:emac_phy_start phy featurs[%08x]", hmac->phy_features);
487
488 /*
489 * PHYのチップIDの確認
490 */
491 id = (emac_mdio_read(hmac, MII_PHYSID1) << 16);
492 id |= (emac_mdio_read(hmac, MII_PHYSID2) & 0xffff);
493
494 syslog_2(LOG_INFO, "EMAC:emac_phy_start PHY-ID[OUI&Model:0x%x, Rev:0x%x]", id & ~0xf, id & 0xf);
495
496 /*
497 * オプション設定があれば、実行
498 */
499 if(hmac->phy_opt_init)
500 hmac->phy_opt_init(hmac);
501
502 /*
503 * LINKパラメータを設定
504 */
505 link &= ~EMAC_LINK_CONNECT;
506 hmac->linkvalue = link;
507
508 switch(link){
509 case EMAC_LINK_10BASE_FULL:
510 duplex = BMCR_FULLDPLX;
511 case EMAC_LINK_10BASE_HALF:
512 speed = BMCR_SPEED10;
513 break;
514 case EMAC_LINK_100BASE_FULL:
515 duplex = BMCR_FULLDPLX;
516 case EMAC_LINK_100BASE_HALF:
517 speed = BMCR_SPEED100;
518 break;
519 case EMAC_LINK_AUTONEGO:
520 default:
521 /* Setup Auto-negotiation */
522 hmac->linkvalue |= EMAC_LINK_AUTONEGO;
523 mode = hmac->phy_features;
524 val = emac_mdio_read(hmac, MII_ADVERTISE);
525 val &= ~ADVERTISE_MASK1;
526 val |= mode & ADVERTISE_MASK1;
527 emac_mdio_write(hmac, MII_ADVERTISE, val);
528 break;
529 }
530
531 val = emac_mdio_read(hmac, MII_BMCR);
532 val &= ~(BMCR_FULLDPLX | BMCR_SPEED100 | BMCR_ANENABLE);
533 val |= is_autonego(hmac) ? (BMCR_ANENABLE | BMCR_ANRESTART) : (speed | duplex);
534 emac_mdio_write(hmac, MII_BMCR, val);
535 return E_OK;
536}
537
538/*
539 * AUTO-NEGOTIATION設定時のLINK状態の取得
540 * parameter1 hmac EMACハンドラへのポインタ
541 * return LINK状態
542 */
543static uint32_t
544emac_phy_link_autonego(EMAC_Handle_t *hmac)
545{
546 uint32_t link_detect;
547 uint32_t lpa;
548
549 lpa = emac_mdio_read(hmac, MII_LPA) & emac_mdio_read(hmac, MII_ADVERTISE);
550 if(lpa & LPA_100FULL)
551 link_detect = EMAC_LINK_100BASE_FULL;
552 else if(lpa & LPA_100HALF)
553 link_detect = EMAC_LINK_100BASE_HALF;
554 else if(lpa & LPA_10FULL)
555 link_detect = EMAC_LINK_10BASE_FULL;
556 else
557 link_detect = EMAC_LINK_10BASE_HALF;
558 return link_detect;
559}
560
561/*
562 * マニュアル設定時のLINK状態の取得
563 * parameter1 hmac EMACハンドラへのポインタ
564 * return LINK状態
565 */
566static uint32_t
567emac_phy_link_manual(EMAC_Handle_t *hmac)
568{
569 uint32_t link_detect;
570 int bmcr;
571
572 bmcr = emac_mdio_read(hmac, MII_BMCR);
573
574 if(bmcr & BMCR_SPEED100)
575 link_detect = EMAC_SPEED_100BASE;
576 else
577 link_detect = EMAC_SPEED_10BASE;
578 link_detect |= (bmcr & BMCR_FULLDPLX) ? EMAC_DUPLEX_FULL : EMAC_DUPLEX_HALF;
579 return link_detect;
580}
581
582/*
583 * DESCRIPTER領域の初期化
584 * parameter1 hmac EMACハンドラへのポインタ
585 */
586static void
587emac_bd_set(EMAC_Handle_t *hmac)
588{
589 uint32_t *desc, *next;
590 uint8_t *pdata = hmac->Init.databuffer;
591 int i;
592
593 /*
594 * DESCRIPTOR/BUFFER領域ののキャッシュをクリア
595 */
596 desc = (uint32_t *)hmac->Init.quebuffer;
597 next = (uint32_t *)(desc + DESC_TXRX_SIZE);
598
599 hmac->rx_top_desc = desc;
600 for(i = 0 ; i < hmac->Init.rxquecount ; i++) {
601 desc[DESC_TXRX_BUFFER] = (uint32_t)pdata;
602 desc[DESC_TXRX_NEXT] = (uint32_t)next;
603 desc[DESC_TXRX_CONTROL] =
604 (hmac->Init.paketbufsize & DESC_RXCTRL_SIZE1MASK) | \
605 DESC_RXCTRL_RXCHAIN;
606 desc[DESC_TXRX_STATUS] = DESC_RXSTS_OWNBYDMA;
607
608 pdata += hmac->Init.paketbufsize;
609 desc += DESC_TXRX_SIZE;
610 next += DESC_TXRX_SIZE;
611 }
612 *(desc - DESC_TXRX_SIZE + DESC_TXRX_NEXT)
613 = (uint32_t)(hmac->rx_top_desc);
614
615 hmac->tx_top_desc = desc;
616 for(i = 0 ; i < hmac->Init.txquecount ; i++){
617 desc[DESC_TXRX_BUFFER] = (uint32_t)pdata;
618 desc[DESC_TXRX_NEXT] = (uint32_t)next;
619 desc[DESC_TXRX_STATUS] &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
620 DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
621 DESC_TXSTS_TXCHECKINSCTRL | \
622 DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
623 desc[DESC_TXRX_STATUS] |= DESC_TXSTS_TXCHAIN | DESC_TXSTS_TXCHECKINSCTRL;
624 desc[DESC_TXRX_CONTROL] = 0;
625 desc[DESC_TXRX_STATUS] &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
626
627 pdata += hmac->Init.paketbufsize;
628 desc += DESC_TXRX_SIZE;
629 next += DESC_TXRX_SIZE;
630 }
631 *(desc - DESC_TXRX_SIZE + DESC_TXRX_NEXT)
632 = (uint32_t)(hmac->tx_top_desc);
633}
634
635
636/*
637 * EMACデバイスの初期化
638 * parameter1 portid EMACのポートID
639 * parameter2 ini 初期化構造体へのポインタ
640 * return ハンドラへのポインタ
641 */
642EMAC_Handle_t *
643emac_init(ID portid, EMAC_Init_t *ini)
644{
645 GPIO_Init_t GPIO_Init_Data;
646 const EMAC_PortControlBlock *pcb;
647 EMAC_Handle_t *hmac;
648 uint32_t base, no, tmp;
649 uint32_t timeout = 3000;
650
651 if(portid == 0 || portid > NUM_MACPORT)
652 return NULL;
653
654 no = INDEX_EMAC(portid);
655 pcb = &emac_pcb[no];
656 hmac = &EMacHandle[no];
657
658 hmac->base = base = pcb->base;
659 hmac->intno = pcb->intno;
660 memcpy(&hmac->Init, ini, sizeof(EMAC_Init_t));
661
662 /*
663 * PHY GPIO クロック設定
664 */
665 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOAEN);
666 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
667 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOCEN);
668 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
669 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_GPIOGEN);
670 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
671#ifdef RMII_MII_TXD1_CLOCK
672 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RMII_MII_TXD1_CLOCK);
673 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
674#endif
675
676 /*
677 * PHY GPIOピン設定
678 */
679 GPIO_Init_Data.mode = GPIO_MODE_AF;
680 GPIO_Init_Data.pull = GPIO_OTYPE_PP;
681 GPIO_Init_Data.otype = GPIO_NOPULL;
682 GPIO_Init_Data.speed = GPIO_SPEED_HIGH;
683 GPIO_Init_Data.alternate = GPIO_ETH_AF;
684 gpio_setup(RMII_REF_CLK_PORT, &GPIO_Init_Data, RMII_REF_CLK_BIN);
685 gpio_setup(RMII_MDIO_PORT, &GPIO_Init_Data, RMII_MDIO_PIN);
686 gpio_setup(RMII_MDC_PORT, &GPIO_Init_Data, RMII_MDC_PIN);
687 gpio_setup(RMII_MII_CRS_DV_PORT, &GPIO_Init_Data, RMII_MII_CRS_DV_PIN);
688 gpio_setup(RMII_MII_RXD0_PORT, &GPIO_Init_Data, RMII_MII_RXD0_PIN);
689 gpio_setup(RMII_MII_RXD1_PORT, &GPIO_Init_Data, RMII_MII_RXD1_PIN);
690 gpio_setup(RMII_MII_RXER_PORT, &GPIO_Init_Data, RMII_MII_RXER_PIN);
691 gpio_setup(RMII_MII_TX_EN_PORT, &GPIO_Init_Data, RMII_MII_TX_EN_PIN);
692 gpio_setup(RMII_MII_TXD0_PORT, &GPIO_Init_Data, RMII_MII_TXD0_PIN);
693 gpio_setup(RMII_MII_TXD1_PORT, &GPIO_Init_Data, RMII_MII_TXD1_PIN);
694
695 /*
696 * EMACクロック設定
697 */
698 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACEN);
699 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
700 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACTXEN);
701 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
702 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACRXEN);
703 tmp = sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR));
704
705 dis_int(hmac->intno);
706 sil_orw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_APB2ENR), RCC_APB2ENR_SYSCFGEN);
707 sil_andw_mem((uint32_t *)(TADR_SYSCFG_BASE+TOFF_SYSCFG_PMC), 1<<(pcb->physel_shift));
708 sil_orw_mem((uint32_t *)(TADR_SYSCFG_BASE+TOFF_SYSCFG_PMC), (pcb->phy_sel)<<(pcb->physel_shift));
709
710 /*
711 * MACをリセット
712 */
713 sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMABMR), ETH_DMABMR_SR);
714 while(timeout > 0){
715 if((sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMABMR)) & ETH_DMABMR_SR) == 0)
716 break;
717 dly_tsk(1);
718 timeout--;
719 }
720
721 /* Get the ETHERNET MACMIIAR value */
722 tmp= sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR));
723 /* Clear CSR Clock Range CR[2:0] bits */
724 tmp &= ~ETH_MACMIIAR_CR;
725 tmp |= emac_ether_clockdiv();
726 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR), tmp);
727
728 /*
729 * DESCRIPTORの初期化
730 */
731 emac_bd_set(hmac);
732
733 if(emac_phy_init(hmac, pcb->phy_addr) != E_OK)
734 return NULL;
735 hmac->macid = portid;
736 return hmac;
737}
738
739/*
740 * EMAC終了処理
741 * parameter1 hmac EMACハンドラへのポインタ
742 * return E_OKで正常終了
743 */
744ER
745emac_deinit(EMAC_Handle_t *hmac)
746{
747 if(hmac == NULL || hmac->macid == 0 || hmac->macid > NUM_MACPORT)
748 return E_OBJ;
749 dis_int(hmac->intno);
750
751 /*
752 * EMACクロック停止
753 */
754 sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACEN);
755 sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACTXEN);
756 sil_andw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), RCC_AHB1ENR_ETHMACRXEN);
757
758 hmac->macid = 0;
759 return E_OK;
760}
761
762/*
763 * EMAC送信要求
764 * parameter1 hmac EMACハンドラへのポインタ
765 * parameter2 num 送信パケット数
766 */
767static void
768emac_send_req(EMAC_Handle_t *hmac, int num)
769{
770 volatile uint32_t *desc, *top;
771 uint32_t base = hmac->base;
772
773 if(num > 0){
774 top = desc = hmac->tx_cur_desc;
775 desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
776 dis_int(hmac->intno);
777 if(hmac->tx_wait == 0)
778 sil_andw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMAOMR), ETH_DMAOMR_ST);
779 while (--num) {
780 /*
781 * 連続DESCRIPTORの送信DMA KICK
782 */
783 desc[DESC_TXRX_STATUS] |= DESC_TXSTS_OWNBYDMA;
784 hmac->tx_wait++;
785 desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
786 }
787 /*
788 * 先頭のDESCRIPTORの送信DMA KICK
789 */
790 top[DESC_TXRX_STATUS] |= DESC_TXSTS_OWNBYDMA;
791 hmac->tx_wait++;
792 hmac->tx_cur_desc = desc;
793 ena_int(hmac->intno);
794 }
795 else
796 sil_andw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMAOMR), ETH_DMAOMR_ST);
797 if((sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMASR)) & ETH_DMASR_TBUS) != 0){
798 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMASR), ETH_DMASR_TBUS);
799 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMATPDR), 0);
800 }
801 sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_ST);
802}
803
804/*
805 * EMAC送信処理
806 * parameter1 hmac EMACハンドラへのポインタ
807 * parameter2 pktp 送信パケット構造体(LWIP型)
808 * return E_OKで正常終了
809 */
810ER
811emac_send(EMAC_Handle_t *hmac, struct emac_pkt *pktp)
812{
813 int num, len, tlen, retry, i;
814 int start = 1;
815 int actlen = 0;
816 ER ercd = E_OK;
817 volatile uint32_t *desc;
818 uint32_t info_word = 0;
819 volatile uint8_t *pdata;
820 volatile uint8_t *s, *d;
821
822 if(hmac == NULL || pktp == NULL)
823 return E_PAR;
824
825 desc = hmac->tx_cur_desc;
826 s = pktp->payload;
827 len = pktp->len;
828
829 for(num = 0 ; num < hmac->Init.txquecount && pktp != NULL ; num++){
830 if(pktp->len == 0)
831 break;
832
833 /*
834 * 送信DESCRIPTORの開放待ち
835 */
836 if((desc[DESC_TXRX_STATUS] & DESC_TXSTS_OWNBYDMA) != 0){
837 for (retry = 0; retry < 3; retry++) {
838 /* 送信ディスクリプタがフルのとき、開放されるのを待つ */
839 dly_tsk(10);
840 /* 再度チェックを行う */
841 if((desc[DESC_TXRX_STATUS] & DESC_TXSTS_OWNBYDMA) == 0)
842 break;
843 /* 念のため、送信の開始を再要求する */
844 emac_send_req(hmac, 0);
845 }
846 if((desc[DESC_TXRX_STATUS] & DESC_TXSTS_OWNBYDMA) != 0){
847 syslog_1(LOG_ERROR, "EMAC:emac_send retry(%d) no descriptor", retry+1);
848 ercd = E_TMOUT;
849 break;
850 }
851 }
852
853 /*
854 * 送信データをバッファに書き込む
855 */
856 pdata = d = (volatile uint8_t *)(desc[DESC_TXRX_BUFFER]);
857 while(actlen < hmac->Init.paketbufsize){
858 tlen = MIN(len, (hmac->Init.paketbufsize - actlen));
859 for(i = 0 ; i < tlen ; i++)
860 *d++ = *s++;
861 actlen += tlen;
862 len -= tlen;
863 if(len == 0){
864 if((pktp = pktp->next) == NULL)
865 break;
866 if(pktp->len == 0)
867 break;
868 s = pktp->payload;
869 len = pktp->len;
870 }
871 }
872 syslog_4(LOG_DEBUG, "EMAC:emac_send(%d) desc[%08x] buf[%08x] actlen[%04x]", num, desc, pdata, actlen);
873
874 /*
875 * 送信サイズと送信モードをセット
876 */
877 desc[DESC_TXRX_CONTROL] = (actlen << DESC_TXCTRL_SIZE1SHFT) & DESC_TXCTRL_SIZE1MASK;
878
879 info_word = desc[DESC_TXRX_STATUS];
880 info_word &= ~(DESC_TXSTS_MSK | DESC_TXSTS_TXFIRST | DESC_TXSTS_TXLAST);
881 info_word |= DESC_TXSTS_TXINT;
882
883 if (start) {
884 start = 0;
885 info_word |= DESC_TXSTS_TXFIRST;
886 }
887 /*
888 * 次のデータ確認と終了マーク設定
889 */
890 if(pktp == NULL || pktp->len == 0)
891 info_word |= DESC_TXSTS_TXLAST;
892 desc[DESC_TXRX_STATUS] = info_word;
893
894 /*
895 * 次のDESCRIPTORへ更新する
896 */
897 desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
898 }
899
900 /* パケットの終端までセットしていないときはエラー応答 */
901 if((info_word & DESC_TXSTS_TXLAST) == 0){
902 syslog_0(LOG_ERROR, "EMAC:emac_send last error !");
903 return -1;
904 }
905
906 /* 送信を要求する */
907 if(num > 0)
908 emac_send_req(hmac, num);
909 return ercd;
910}
911
912/*
913 * 次の受信DESCRIPTORを取得する
914 * parameter1 hmac EMACハンドラへのポインタ
915 * return 次のDESCRIPTORへのポインタ
916 */
917volatile static uint32_t *
918emac_recv_desc_next(EMAC_Handle_t *hmac)
919{
920 volatile uint32_t *desc;
921
922 desc = hmac->rx_cur_desc;
923 desc[DESC_TXRX_CONTROL] =
924 (hmac->Init.paketbufsize & DESC_RXCTRL_SIZE1MASK) | \
925 DESC_RXCTRL_RXCHAIN;
926 desc[DESC_TXRX_STATUS] = DESC_RXSTS_OWNBYDMA;
927 desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
928 hmac->rx_cur_desc = desc;
929 return desc;
930}
931
932/*
933 * 受信の先頭パケットのDESCRIPTORを探す
934 * parameter1 hmac EMACハンドラへのポインタ
935 * return NULLでなければ、受信の先頭DESCRIPTORへのポインタ
936 */
937volatile static uint32_t *
938emac_recv_sop_find(EMAC_Handle_t *hmac)
939{
940 int num;
941 volatile uint32_t *desc = hmac->rx_cur_desc;
942 uint32_t info_word, length;
943
944 for(num = 0 ; num < hmac->Init.rxquecount ; num++) {
945 info_word = desc[DESC_TXRX_STATUS];
946
947 /*
948 * 受信データなしのときは、終了する
949 */
950 if ((info_word & DESC_RXSTS_OWNBYDMA) != 0)
951 break;
952
953 /*
954 * 受信データあり場合、Start of Packet のチェックを行う
955 */
956 length = (info_word & DESC_RXSTS_FRMLENMSK) >> DESC_RXSTS_FRMLENSHFT;
957 if (info_word & DESC_RXSTS_RXFIRST) {
958 if(length >= ETHER_HDR_SIZE)
959 return desc;
960 }
961 else
962 hmac->ifShortPkts++;
963
964 /*
965 * 次のDESCRIPTORを取得する
966 */
967 desc = emac_recv_desc_next(hmac);
968 }
969 return NULL;
970}
971
972/*
973 * 受信データ長の取り出し
974 * parameter1 hmac EMACハンドラへのポインタ
975 * return 0でなければ、受信パケット長
976 */
977int
978emac_recv_length(EMAC_Handle_t *hmac)
979{
980 int num, length = 0;
981 volatile uint32_t *desc;
982 uint32_t info_word;
983
984 /*
985 * 受信パケットの確認し、ない場合は終了
986 */
987 if((desc = emac_recv_sop_find(hmac)) == NULL)
988 return 0;
989
990 for(num = 0 ; num < hmac->Init.rxquecount ; num++){
991 info_word = desc[DESC_TXRX_STATUS];
992
993 /* 何も受信していないときは、終了する */
994 if ((info_word & DESC_RXSTS_OWNBYDMA) != 0)
995 break;
996
997 /* 受信データ長を取得する */
998 length += (desc[DESC_TXRX_STATUS] & DESC_RXSTS_FRMLENMSK) >> DESC_RXSTS_FRMLENSHFT;
999
1000 /*
1001 * End of Packetならば、終了
1002 */
1003 if(info_word & DESC_RXSTS_RXLAST)
1004 break;
1005
1006 /*
1007 * 次のDESCRIPTORを取得する
1008 */
1009 desc = (uint32_t *)(desc[DESC_TXRX_NEXT]);
1010 }
1011 return length;
1012}
1013
1014/*
1015 * 受信パケットの取得
1016 * parameter1 hmac EMACハンドラへのポインタ
1017 * parameter2 pktp 受信データ格納パケット構造体(LWIP型)
1018 * return E_OKならば、受信パケット長
1019 */
1020ER
1021emac_recv(EMAC_Handle_t *hmac, struct emac_pkt *pktp)
1022{
1023 int num, actlen, i;
1024 volatile uint32_t *desc;
1025 volatile uint8_t *b, *pdata;
1026 uint32_t info_word, len, tlen;
1027
1028 if(pktp != NULL){
1029 b = pktp->payload;
1030 len = pktp->len;
1031 }
1032 else{
1033 b = NULL;
1034 len = 0;
1035 }
1036
1037 sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMASR), ETH_DMASR_RS | DMA_INTER_RXSTAT_ERROR);
1038
1039 /*
1040 * 受信パケットの確認し、ない場合はエラー終了
1041 */
1042 if((desc = emac_recv_sop_find(hmac)) == NULL)
1043 return E_NOMEM;
1044
1045 for(num = 0 ; num < hmac->Init.rxquecount ; num++){
1046 info_word = desc[DESC_TXRX_STATUS];
1047
1048 /*
1049 * 受信データがない場合、終了する
1050 */
1051 if((info_word & DESC_RXSTS_OWNBYDMA) != 0)
1052 break;
1053
1054 /*
1055 * パケット格納領域がある場合は受信パケットを取得する
1056 */
1057 if(b != NULL){
1058 /* 受信データを取得する */
1059 pdata = (uint8_t *)(desc[DESC_TXRX_BUFFER]);
1060 actlen = (desc[DESC_TXRX_STATUS] & DESC_RXSTS_FRMLENMSK) >> DESC_RXSTS_FRMLENSHFT;
1061 syslog_5(LOG_DEBUG, "EMAC:emac_recv num(%d) desc[%08x] b[%08x] pdata[%08x] actlen[%08x] !", num, desc, b, pdata, actlen);
1062 syslog_4(LOG_DEBUG, " 12[%02x] 13[%02x] 14[%02x] 15[%02x]", pdata[12], pdata[13], pdata[14], pdata[15]);
1063 while(actlen > 0){
1064 tlen = MIN(len, actlen);
1065 for(i = 0 ; i < tlen ; i++)
1066 *b++ = *pdata++;
1067 actlen -= tlen;
1068 len -= tlen;
1069 if(len == 0 /*&& actlen > 0*/){
1070 if((pktp = pktp->next) == NULL){
1071 b = NULL;
1072 break;
1073 }
1074 b = pktp->payload;
1075 if((len = pktp->len) == 0){
1076 b = NULL;
1077 break;
1078 }
1079 }
1080 }
1081 }
1082 /*
1083 * 次のDESCRIPTORの取得と更新
1084 */
1085 desc = emac_recv_desc_next(hmac);
1086
1087 /*
1088 * End of Packetの場合、正常終了
1089 */
1090 if((info_word & DESC_RXSTS_RXLAST) != 0)
1091 return E_OK;
1092 }
1093 return E_NOMEM;
1094}
1095
1096/*
1097 * DESCRIPTORのリセット
1098 * parameter1 hmac EMACハンドラへのポインタ
1099 */
1100static void
1101emac_desc_reset(EMAC_Handle_t *hmac)
1102{
1103 volatile uint32_t *desc;
1104 int i;
1105
1106 /*
1107 * 送信ディスクリプタの初期化
1108 */
1109 desc = hmac->tx_top_desc;
1110 hmac->tx_cur_desc = desc;
1111 for(i = 0 ; i < hmac->Init.txquecount ; i++) {
1112 desc[DESC_TXRX_STATUS] &= ~(DESC_TXSTS_TXINT | DESC_TXSTS_TXLAST |
1113 DESC_TXSTS_TXFIRST | DESC_TXSTS_TXCRCDIS | \
1114 DESC_TXSTS_TXCHECKINSCTRL | \
1115 DESC_TXSTS_TXRINGEND | DESC_TXSTS_TXPADDIS);
1116 desc[DESC_TXRX_STATUS] |= DESC_TXSTS_TXCHAIN | DESC_TXSTS_TXCHECKINSCTRL;
1117 desc[DESC_TXRX_CONTROL] = 0;
1118 desc[DESC_TXRX_STATUS] &= ~(DESC_TXSTS_MSK | DESC_TXSTS_OWNBYDMA);
1119 desc += DESC_TXRX_SIZE;
1120 }
1121
1122 /*
1123 * 受信ディスクリプタの初期化
1124 */
1125 desc = hmac->rx_top_desc;
1126 hmac->rx_cur_desc = desc;
1127 for (i = 0 ; i < hmac->Init.rxquecount ; i++) {
1128 desc[DESC_TXRX_CONTROL] =
1129 (hmac->Init.paketbufsize & DESC_RXCTRL_SIZE1MASK) | DESC_RXCTRL_RXCHAIN;
1130 desc[DESC_TXRX_STATUS] = DESC_RXSTS_OWNBYDMA;
1131 desc += DESC_TXRX_SIZE;
1132 }
1133
1134 sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMATDLAR), (uint32_t)(hmac->tx_top_desc));
1135 sil_wrw_mem((uint32_t *)(hmac->base+TOFF_ETH_DMARDLAR), (uint32_t)(hmac->rx_top_desc));
1136}
1137
1138/*
1139 * ETHERNET通信を開始する
1140 * parameter1 hmac EMACハンドラへのポインタ
1141 * parameter2 link 通信モード
1142 * return E_OKで正常終了
1143 */
1144ER
1145emac_start(EMAC_Handle_t *hmac, uint32_t link)
1146{
1147 uint32_t base, tmp;
1148
1149 if(hmac == NULL)
1150 return E_PAR;
1151 base = hmac->base;
1152
1153 /*
1154 * PHYスタート
1155 */
1156 emac_phy_start(hmac, link);
1157
1158 /*
1159 * 送受信を有効設定
1160 */
1161 sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_SR);
1162
1163 /*
1164 * 割り込みマスク設定
1165 */
1166 sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAIER), DMA_INTR_DEFAULT_MASK);
1167
1168 /*
1169 * 割り込み許可
1170 */
1171 ena_int(hmac->intno);
1172
1173 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMASR), 0x0001FFFF);
1174 sil_orw_mem((uint32_t *)(base+TOFF_ETH_MACCR), (ETH_MACCR_TE | ETH_MACCR_RE));
1175 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
1176 dly_tsk(1);
1177 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
1178 return E_OK;
1179}
1180
1181/*
1182 * ETHERNET通信を停止する
1183 * parameter1 hmac EMACハンドラへのポインタ
1184 * parameter2 disable 送受信の無効化設定(1で無効化)
1185 * return E_OKで正常終了
1186 */
1187ER
1188emac_stop(EMAC_Handle_t *hmac, int disable)
1189{
1190 uint32_t base, tmp;
1191 ER ercd = E_OK;
1192
1193 if(hmac == NULL)
1194 return E_PAR;
1195 base = hmac->base;
1196
1197 /*
1198 * 割り込み停止
1199 */
1200 dis_int(hmac->intno);
1201 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMAIER), 0);
1202
1203 if(disable == 1) {
1204 /*
1205 * 送受信を無効に設定
1206 */
1207 sil_andw_mem((uint32_t *)(base+TOFF_ETH_MACCR), ETH_MACCR_RE);
1208 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
1209 dly_tsk(1);
1210 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
1211
1212 dly_tsk(200);
1213
1214 /*
1215 * 受信済みパケットを破棄
1216 */
1217 while(ercd == E_OK){
1218 ercd = emac_recv(hmac, NULL);
1219 dly_tsk(1);
1220 syslog_1(LOG_NOTICE, "EMAC:emac_stop flush result(%d) !", ercd);
1221 }
1222 sil_andw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_SR);
1223 sil_andw_mem((uint32_t *)(base+TOFF_ETH_MACCR), ETH_MACCR_TE);
1224 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
1225 dly_tsk(1);
1226 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
1227 sil_andw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_ST);
1228 }
1229 return E_OK;
1230}
1231
1232/*
1233 * LINK状態を取得する
1234 * parameter1 hmac EMACハンドラへのポインタ
1235 * return LINK状態(0で未接続)
1236 */
1237uint32_t
1238emac_link_detect(EMAC_Handle_t *hmac)
1239{
1240 uint32_t link_detect = 0;
1241 int bmsr;
1242
1243 /* 最初は空読み */
1244 emac_mdio_read(hmac, MII_BMSR);
1245 bmsr = emac_mdio_read(hmac, MII_BMSR);
1246 //syslog_2(LOG_INFO, "EMAC:phy_link_detect[%08x] phydev->auto_nego(%d)", bmsr, is_autonego(hmac));
1247
1248 if((bmsr >= 0) && (bmsr & BMSR_LSTATUS)){
1249 link_detect = is_autonego(hmac)
1250 ? emac_phy_link_autonego(hmac)
1251 : emac_phy_link_manual(hmac);
1252 }
1253 return link_detect;
1254}
1255
1256/*
1257 * EMACの制御設定を行う
1258 * parameter1 hmac EMACハンドラへのポインタ
1259 * parameter2 link EMAC設定モード
1260 * return E_OKで正常終了
1261 */
1262ER
1263emac_link_mode_set(EMAC_Handle_t *hmac, uint32_t link)
1264{
1265 uint32_t base, conf;
1266
1267 if(hmac == NULL || link == 0)
1268 return E_PAR;
1269 base = hmac->base;
1270 conf = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
1271
1272 if((link & EMAC_SPEED_MASK) != EMAC_SPEED_10BASE)
1273 conf |= ETH_MACCR_FES;
1274 else
1275 conf &= ~ETH_MACCR_FES;
1276
1277 if((link & EMAC_DUPLEX_MASK) == EMAC_DUPLEX_FULL)
1278 conf |= ETH_MACCR_DM;
1279 else
1280 conf &= ~ETH_MACCR_DM;
1281 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), conf);
1282 return E_OK;
1283}
1284
1285/*
1286 * EMACをリセットする
1287 * parameter1 hmac EMACハンドラへのポインタ
1288 * parameter2 macadr MACアドレスデータへのポインタ
1289 * return E_OKで正常終了
1290 */
1291ER
1292emac_reset(EMAC_Handle_t *hmac, uint8_t *mac_addr)
1293{
1294 uint32_t timeout = 3000;
1295 uint32_t base, tmp;
1296 uint32_t macid_hi, macid_lo;
1297 uint8_t *b = (uint8_t *)&mac_addr[0];
1298
1299 if(hmac == NULL || mac_addr == NULL)
1300 return E_PAR;
1301 base = hmac->base;
1302
1303 /*
1304 * MACをリセット
1305 */
1306 sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMABMR), ETH_DMABMR_SR);
1307 while(timeout > 0){
1308 if((sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMABMR)) & ETH_DMABMR_SR) == 0)
1309 break;
1310 dly_tsk(1);
1311 timeout--;
1312 }
1313
1314 /* Get the ETHERNET MACMIIAR value */
1315 tmp= sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR));
1316 /* Clear CSR Clock Range CR[2:0] bits */
1317 tmp &= ~ETH_MACMIIAR_CR;
1318 tmp |= emac_ether_clockdiv();
1319 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACMIIAR), tmp);
1320
1321 /*
1322 * 送受信の停止
1323 */
1324 emac_stop(hmac, 0);
1325
1326 /*
1327 * MACアドレスの登録
1328 */
1329 macid_lo = b[0] + (b[1] << 8) + (b[2] << 16) + (b[3] << 24);
1330 macid_hi = b[4] + (b[5] << 8);
1331 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACA0HR), macid_hi);
1332 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACA0LR), macid_lo);
1333
1334 /*
1335 * MACの設定
1336 */
1337 sil_modw_mem((uint32_t *)(base+TOFF_ETH_MACCR), ETH_MACCR_MASK, ETH_MACCR_INIT);
1338 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
1339 dly_tsk(1);
1340 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
1341
1342 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACFFR), ETH_MACFFR_INIT);
1343 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACFFR));
1344 dly_tsk(1);
1345 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACFFR), tmp);
1346
1347 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACHTHR), 0x00000000);
1348 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACHTLR), 0x00000000);
1349
1350 sil_modw_mem((uint32_t *)(base+TOFF_ETH_MACFCR), ETH_MACFCR_MASK, ETH_MACFCR_INIT);
1351 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACFCR));
1352 dly_tsk(1);
1353 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACFCR), tmp);
1354
1355 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACVLANTR), ETH_MACVLANTR_INIT);
1356
1357 sil_modw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_MASK, ETH_DMAOMR_INIT);
1358 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMAOMR));
1359 dly_tsk(1);
1360 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), tmp);
1361
1362 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMABMR), ETH_DMABMR_INIT);
1363 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMABMR));
1364 dly_tsk(1);
1365 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMABMR), tmp);
1366
1367 /*
1368 * 送受信DESCRIPTERリセット
1369 */
1370 emac_desc_reset(hmac);
1371
1372 sil_orw_mem((uint32_t *)(base+TOFF_ETH_MACCR), (ETH_MACCR_TE | ETH_MACCR_RE));
1373 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_MACCR));
1374 dly_tsk(1);
1375 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_MACCR), tmp);
1376
1377 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMASR), 0x0001FFFF);
1378 sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_FTF);
1379 tmp = sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMAOMR));
1380 dly_tsk(1);
1381 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), tmp);
1382 sil_orw_mem((uint32_t *)(base+TOFF_ETH_DMAOMR), ETH_DMAOMR_SR);
1383 return E_OK;
1384}
1385
1386
1387/*
1388 * EMAC DMA用割り込み処理
1389 */
1390static int
1391emac_dma_interrupt(EMAC_Handle_t *hmac, uint32_t status)
1392{
1393 int event = 0;
1394
1395 if((status & 0x1FFFF) == 0)
1396 return 0;
1397 event = 0;
1398
1399 /*
1400 * ABNORMAL割り込み
1401 */
1402 if((status & ETH_DMASR_AIS) != 0) {
1403 if((status & ETH_DMASR_TUS) != 0)
1404 hmac->tx_undeflow_irq++;
1405 if((status & ETH_DMASR_TJTS) != 0)
1406 hmac->tx_jabber_irq++;
1407 if((status & ETH_DMASR_ROS) != 0)
1408 hmac->rx_overflow_irq++;
1409 if((status & ETH_DMASR_RBUS) != 0)
1410 hmac->rx_buf_unav_irq++;
1411 if((status & ETH_DMASR_RPSS) != 0)
1412 hmac->rx_process_stopped_irq++;
1413 if((status & ETH_DMASR_RWTS) != 0)
1414 hmac->rx_watchdog_irq++;
1415 if((status & ETH_DMASR_ETS) != 0)
1416 hmac->tx_early_irq++;
1417 if((status & ETH_DMASR_TPSS) != 0)
1418 hmac->tx_process_stopped_irq++;
1419 if((status & ETH_DMASR_FBES) != 0){
1420 hmac->fatal_bus_error_irq++;
1421 event |= 0x0004;
1422 }
1423 }
1424
1425 /*
1426 * TX/RX NORMAL割り込み
1427 */
1428 if((status & ETH_DMASR_NIS) != 0)
1429 hmac->normal_irq_n++;
1430 if((status & ETH_DMASR_RS) != 0) {
1431 uint32_t value = sil_rew_mem((uint32_t *)(hmac->base+TOFF_ETH_DMAIER));
1432 /* to schedule NAPI on real RIE event. */
1433 if((value & ETH_DMAIER_RIE) != 0){
1434 hmac->rx_normal_irq_n++;
1435 if(hmac->emacevent != NULL)
1436 hmac->emacevent(hmac, 0, RECV_EVENT_DETECT);
1437 }
1438 }
1439 if((status & ETH_DMASR_TS) != 0){
1440 /*
1441 * 送信割り込みを通知する
1442 */
1443 if(hmac->tx_wait != 0){
1444 if(hmac->emacevent != NULL)
1445 hmac->emacevent(hmac, 0, SEND_EVENT_DETECT);
1446 if(hmac->tx_wait > 0)
1447 hmac->tx_wait--;
1448 }
1449 }
1450 if((status & ETH_DMASR_ERS) != 0)
1451 hmac->rx_early_irq++;
1452 return event;
1453}
1454
1455/*
1456 * EMAC割り込みサービスルーチン
1457 */
1458void
1459emac_hps_isr(intptr_t exinf)
1460{
1461 EMAC_Handle_t *hmac = &EMacHandle[INDEX_EMAC((uint32_t)exinf)];
1462 uint32_t base, dstatus;
1463 uint32_t event;
1464
1465 base = hmac->base;
1466 dstatus = sil_rew_mem((uint32_t *)(base+TOFF_ETH_DMASR));
1467 syslog_1(LOG_DEBUG, "emac_hps_isr SR[%08x]", dstatus);
1468 if(dstatus != 0){
1469 event = emac_dma_interrupt(hmac, dstatus);
1470 sil_wrw_mem((uint32_t *)(base+TOFF_ETH_DMASR), (dstatus & 0x0001FFFB));
1471 /*
1472 * DMAエラーがあった場合、通知
1473 */
1474 if(event != 0){
1475 syslog_2(LOG_ERROR, "EMAC:emac_isr id(%d) DMA error[%08x] !", (int)exinf, event);
1476 if(hmac->emacevent != NULL)
1477 hmac->emacevent(hmac, 0, RESET_EVNT_DETECT);
1478 }
1479 }
1480}
1481
Note: See TracBrowser for help on using the repository browser.