4.4 Fast Ethernet Controller (FEC)
4.4.1 Introduction
FEC(Fast Ethernet Controller) 드라이버는 IEEE 802.3/Ethernet CSMA/CD 미디어 액세스 컨트롤과 채널 인터페이스 기능의 전체 세트를 수행한다.
FEC는 Ethernet 미디어 인터페이스를 완성하기 위해 외부 인터페이스 어댑터와 트랜시버 기능을 필요로 한다. 10 Mbps, 100 Mbps, 1000 Mbps 관련 Ethernet 네트워크에서는 반이중이나 전이중 작동을 지원한다.
FEC 드라이버는 다음 기능을 지원한다 :
- Full/Half duplex operation (전이중/반이중 작동)
- Link 상태 변화 감지
- Auto-negotiation (네트워크 속도와 전이중/반이중 작동을 결정함)
- 출동(collision) 시 자동 재전송과 CRC 생성 등의 전송 기능
- 전송 충돌과 같은 정보를 디바이스로 부터 통계 정보 얻기
네트워크 어댑터는 인터페이스 이름인 ethx와 함께 ifconfig 명령으로 액세스할 수 있다. 드리이버는 외부 어댑터(PHY 디바이스)를 자동으로 검색(auto-probe)한다.
4.4.2 Hardware Operation
FEC는 LAN 네트워크로 시스템을 인터페이스하는 Ethernet 컨트롤러이다.
FEC는 외부 Ethernet 트랜시버에 연결하기 위해 다양한 표준 MAC-PHY(물리적) 인터페이스를 지원한다. FEC는 10/100 Mbps MII, 10/100 Mbps RMII, 10/100/1000 Mbps RGMII를 지원한다. 또한 FEC는 125MHz에서 작동하는 4비트 reduced GMII를 사용하는 1000 Mbps RGMII를 지원한다.
디바이스 기능에 대한 간략한 개요가 여기서 제공된다. 자세한 내용은 Applications Processor Reference Manual의 FEC 장을 참조한다.
MII 모드에는 IEEE 802.3 표준에서 정의되고 EMAC에서 지원하는 18개의 신호가 있다. MII, RMII, RGMII 모드는 18개의 신호의 서브셋를 사용한다. 이러한 신호는 아래 테이블에 나열되어 있다.
Table 40. Pin Usage in MII, RMII and RGMII Modes
Direction | EMAC Pin Name | RMII Usage | RGMII Usage(not supported by i.MX 6UltraLite) |
In/Out | FEC_MDIO | 데이터 입/출력 관리 | 데이터 입/출력 관리 |
Out | FEC_MDC | 범용 출력 | 데이터 clock 관리 |
Out | FEC_TXD[0] | 비트 0 출력 데이터 | 비트 0 출력 데이터 |
Out | FEC_TXD[1] | 비트 1 출력 데이터 | 비트 1 출력 데이터 |
Out | FEC_TXD[2] | 사용 안함 | 비트 2 출력 데이터 |
Out | FEC_TXD[3] | 사용 안함 | 비트 3 출력 데이터 |
Out | FEC_TX_EN | 전송 활성화 | 전송 활성화 |
Out | FEC_TX_ER | 사용 안함 | 사용 안함 |
In | FEC_CRS | 사용 안함 | 사용 안함 |
In | FEC_COL | 사용 안함 | 사용 안함 |
In | FEC_TX_CLK | 사용 안함 | 레퍼런스 동기 clock (REF_CLK, PHY에서 연결할 수 있음) |
In | FEC_RX_ER | 수신 에러 | 사용 안함 |
In | FEC_RX_CLK | 사용 안함 | 레퍼런스 동기 clock (REF_CLK, PHY에서 연결할 수 있음) |
In | FEC_RX_DV | 유효한 데이터 수신과 CRS 생성 | FEC_RX_CLK 하강 에지에서 RXDV XOR RXERR |
In | FEC_RXD[0] | 비트 0 데이터 입력 | 비트 0 데이터 입력 |
In | FEC_RXD[1] | 비트 1 데이터 입력 | 비트 1 데이터 입력 |
In | FEC_RXD[2] | 사용 안함 | 비트 2 데이터 입력 |
In | FEC_RXD[3] | 사용 안함 | 비트 3 데이터 입력 |
MII 관리 인터페이스는 FEC_MDIO와 FEC_MDC 두 핀으로 구성된다. FEC 하드웨어 작동은 아래 나열된 부분으로 나눌 수 있다. 자세한 내용은 Applications Processor Reference Manuals를 참조한다.
- Transmission(전송) - Ethernet 전송기는 소프트웨어 개입이 거의 없이 작동하도록 설계되어 있다. ECR[ETHER_EN]이 지정되고 데이터가 전송 FIFO에 나타나면, Ethernet MAC는 네트워크로 전송할 수 있다. 전송 FIFO가 워터마크(TFWR에서 정의된)를 채우면, MAC 전송 로직은 FEC_TX_EN을 지정하고, 프리앰블(PA: preamble) 시퀀스, 시작 프레임 구분 기호(SFD: start frame delimiter)와 FIFO의 프레임 정보 전송을 시작한다. 그러나 네트워크가 사용 중(busy: FEC_CRS 지정)이면 컨트롤러는 전송을 연기한다.
- 전송하기 전, 컨트롤러는 carrier sense가 비활성화될 때까지 기다린 다음에 carrier sense가 60 비트회 동안 비활성화 상태를 유지하는지 확인한다. 추가로 36 비트회(carrier sense가 원래 비활성화된 후 96 비트회)를 대기한 후 전송이 시작되면, 버퍼(TXB)와 프레임(TXF) 인터럽트가 EIMR의 설정에 따라 모두 생성될 수 있다.
- Reception(수신) - FEC 수신기는 호스트의 개입이 거의 없이 작동하도록 설계되었으며, 주소 인식, CRC 검사, 짧은 프레임 검사, 최대 프레임 길이 검사를 수행할 수 있다. 드라이버가 ECR[ETHER_EN]을 지정하여 FEC를 활성화하면, 즉시 수신 프레임 처리를 시작한다. FEC_RX_DV가 지정될 때, 수신기는 PA/SFD 헤더가 유효한지 확인한다. PA/SFD가 유효하면 제거되고, 수신기에서는 프레임 처리를 시작한다. 유효한 PA/SFD를 찾지 못하면, 프레임은 무시된다. MII 모드에서 수신기는 SFD와 일치하는 적어도 하나의 바이트를 확인한다. 0 이상의 PA 바이트가 발생할 수 있지만, SFD 바이트 이전에 00 비트 시퀀스가 감지되면 프레임은 무시된다.
- 프레임의 처음 6 바이트가 수신된 후, FEC는 프레임에서 주소 인식을 수행한다. 수신하는 동안, Ethernet 컨트롤러는 다양한 오류 조건을 검사하고, 전체 프레임이 FIFO에 저장되면 32 비트 프레임 상태 워드를 FIFO에 기록된다. 이 상태 워드에는 M, BC, MC, LG, NO, CR, OV, TR 상태 비트와 프레임 길이가 포함된다. EMIR 레지스터에 의해 활성화된 경우, Receive Buffer(RXB)와 Frame Interrupts(RXF)가 생성될 수 있다. 수신 프레임이 완료되면, FEC는 RxBD에 L 비트를 설정하고, RxBD에 다른 프레임 상태 비트를 저장하고 E 비트를 지운다. 다음으로 Ethernet 컨트롤러는 프레임이 수신되었고 메모리에 있다는 것을 나타내는 마스크 가능한 인터럽트(EIR의 RXF 비트, EIMR의 RXF 비트로 마스크 가능)를 생성한다. 그런 다음 Ethernet 컨트롤러는 새로운 프레임을 기다린다.
- Interrupt management(인터럽트 관리) - EIR 비트를 설정하는 이벤트가 발생하면, 인터럽트 마스크 레지스터(EIMR)에서 해당하는 비트도 설정되면 인터럽트가 생성된다. EIR에서 비트는 해당하는 비트 위치에 1이 기록되면 지워진다. 0을 기록하면 효과가 없다. 이 레지스터는 하드웨어 리셋 시 지워진다. 이러한 인터럽트는 작동 인터럽트, 전송기/네트워크 오류 인터럽트, 내부 오류 인터럽트로 나눌 수 있다. 일반적인 동작에서 발생할 수 있는 인터럽트는 GRA, TXF, TXB, RXF, RXB이다. 네트워크나 전송기에서 감지된 오류/문제로 인한 인터럽트는 HBERR, BABR, BABT, LC, RL이다. 내부 오류로 인한 인터럽트는 HBERR, UN이다. 일부 오류 인터럽트는 MIB 블록 카운터에서 독립적으로 계산된다. 소프트웨어는 이러한 오류가 MIB 카운터로 네트워크 관리에 표시되기 때문에 이러한 인터럽트를 mask off(제외)하도록 선택할 수 있다.
- PHY management(PHY 관리) - phylib는 PHY 검색, 링크 상태, 상태 머신과 같은 모든 FEC PHY 관련 작업을 관리하는 데 사용된다. MDIO 버스는 FEC 드라이버에서 생성되고 시스템에 등록된다. 자세한 내용은 Linux OS 소스 디렉토리 아래 Documentation/networking/phy.txt를 참조한다.
4.4.3 Software Operation
FEC 드라이버는 아래 기능을 제공한다 :
- Module initialization(모듈 초기화) - 디바이스별 구조체로 모듈을 초기화한다.
- Rx/Tx 전송
- 인터럽트 서비스 루틴
- PHY 관리
- init/start/stop과 같은 FEC 관리
- i.MX 6 FEC 모듈은 리틀 엔디안 형식을 사용
4.4.4 Source Code Structure
아래 테이블은 소스파일을 보여준다.
drivers/net/ethernet/freescale 디렉토리에서 사용할 수 있다.
Table 41. FEC Driver Files
File | Description |
drivers/net/ethernet/freescale/fec.h | 레지스터를 정의한 헤더 파일 |
drivers/net/ethernet/freescale/fec_main.c | Ethernet LAN 컨트롤러용 Linux 드라이버 |
drivers/net/ethernet/freescale/fec_fixup.c | SoC와 PHY 특수 구현용 Linux 드라이버 |
4.4.5 Menu Configuration Options
이 모듈을 제공하도록 커널을 구성한다 :
- CONFIG_FEC는 이 모듈을 위해서 제공된다. 이 옵션은 아래에서 사용할 수 있다 :
- Device Drivers > Network device support > Ethernet (10, 100 or 1000 Mbit) > FEC Ethernet controller
- FEC로 NFS-rootfs를 마운트하려면, 필요한 경우 menuconfig에서 다른 네트워크 구성을 비활성화한다.
4.4.6 Programming Interface
디바이스별 정의가 헤더 파일(fec.h)에 추가되고 공통된 보드 구성 옵션을 제공한다.
fec.h는 레지스터 액세스를 위한 구조체와 버퍼 디스크립터를 위한 구조체를 정의한다. 예들 들어,
/*
* Define the buffer descriptor structure.
*/
struct bufdesc {
unsigned short cbd_datlen; /* Data length */
unsigned short cbd_sc; /* Control and status info */
unsigned long cbd_bufaddr; /* Buffer address */
};
struct bufdesc_ex {
struct bufdesc desc;
unsigned long cbd_esc;
unsigned long cbd_prot;
unsigned long cbd_bdu;
unsigned long ts;
unsigned short res0[4];
};
/*
* Define the register access structure.
*/
#define FEC_IEVENT 0x004 /* Interrupt event reg */
#define FEC_IMASK 0x008 /* Interrupt mask reg */
#define FEC_R_DES_ACTIVE 0x010 /* Receive descriptor reg */
#define FEC_X_DES_ACTIVE 0x014 /* Transmit descriptor reg */
#define FEC_ECNTRL 0x024 /* Ethernet control reg */
#define FEC_MII_DATA 0x040 /* MII manage frame reg */
#define FEC_MII_SPEED 0x044 /* MII speed control reg */
#define FEC_MIB_CTRLSTAT 0x064 /* MIB control/status reg */
#define FEC_R_CNTRL 0x084 /* Receive control reg */
#define FEC_X_CNTRL 0x0c4 /* Transmit Control reg */
#define FEC_ADDR_LOW 0x0e4 /* Low 32bits MAC address */
#define FEC_ADDR_HIGH 0x0e8 /* High 16bits MAC address */
#define FEC_OPD 0x0ec /* Opcode + Pause duration */
#define FEC_HASH_TABLE_HIGH 0x118 /* High 32bits hash table */
#define FEC_HASH_TABLE_LOW 0x11c /* Low 32bits hash table */
#define FEC_GRP_HASH_TABLE_HIGH 0x120 /* High 32bits hash table */
#define FEC_GRP_HASH_TABLE_LOW 0x124 /* Low 32bits hash table */
#define FEC_X_WMRK 0x144 /* FIFO transmit water mark */
#define FEC_R_BOUND 0x14c /* FIFO receive bound reg */
#define FEC_R_FSTART 0x150 /* FIFO receive start reg */
#define FEC_R_DES_START 0x180 /* Receive descriptor ring */
#define FEC_X_DES_START 0x184 /* Transmit descriptor ring */
#define FEC_R_BUFF_SIZE 0x188 /* Maximum receive buff size */
#define FEC_MIIGSK_CFGR 0x300 /* MIIGSK config register */
#define FEC_MIIGSK_ENR 0x308 /* MIIGSK enable register */
4.4.6.1 Getting a MAC Address
MAC 주소는 커널 커맨드 라인, 커널 디바이스 트리 DTS 파일, OCOTP나 U-Boot와 같은 부트로더에서 설정한 MAC 레지스터로 설정할 수 있다. FEC 드라이버는 이를 사용하여 네트워크 디바이스의 MAC 주소를 구성한다. 일반적으로 MAC 주소를 설정하려고 fec.macaddr=0x00,0x04,0x9f,0x01,0x30,0xe0 형식의 커널 커맨드 라인을 사용한다. 특정 핀의 충돌(FEC_RMII 모드는 레퍼런스 clock 입/출력 채널로 GPIO_16이나 RGMII_TX_CTL 핀을 사용해야 함)로 인해, 분기 라인이 clock에 심각한 영향을 미치기 때문에 두 핀 중 하나를 다른 모듈에서 사용할 분기 라인에 연결할 수 없다.