12. 네트워크 디바이스 드라이버
DESCRIPTION
12. 네트워크 디바이스 드라이버. data. TFTP header. data. Application Layer. TFTP message. FTP, Telnet, HTTP. Transport Layer. UDP header. TFTP header. data. UDP message. TCP, UDP. IP header. UDP header. TFTP header. data. Network Layer. IP packet. IP, ICMP, IGMP. Data link layer. - PowerPoint PPT PresentationTRANSCRIPT
www.huins.com 2
TCP/IP Protocol STACK
12.1 Network Divice Driver 12.1 Network Divice Driver 원리 및 구동원리 및 구동
FTP, Telnet, HTTP
TCP, UDP
IP, ICMP, IGMP
PPP, SLIP, Ethernet
Application LayerApplication Layer
Transport LayerTransport Layer
Network LayerNetwork Layer
Data link layerData link layer
TFTP headerTFTP header datadata
datadata
TFTP message
UDP message
UDP headerUDP
header
IP header
IP header
Ethernet header
Ethernet header
TFTP headerTFTP header datadata
IP packet
UDP headerUDP
headerTFTP headerTFTP header datadata
IP header
IP header
Ethernet frame
UDP headerUDP
headerTFTP headerTFTP header datadata
Ethernet trailer
Ethernet trailer
Device Driver
NIC
www.huins.com 3
System Call InterfaceSystem Call Interface
Virtual File System(VFS)Virtual File System(VFS)
Buffer CacheBuffer Cache
ApplicationApplication
CharacterDevice DriverCharacter
Device Driver
HardwareHardware
Network SubsystemNetwork
Subsystem
Device InterfaceDevice Interface
Kernel Area
ApplicationArea
Hardware
BlockDevice Driver
BlockDevice Driver
Network Device Driver
Network Device Driver
BSD socketBSD socket
Inet(AF_INET)Inet(AF_INET)Transport(TCP,
UDP)Transport(TCP,
UDP)Network(IP)Network(IP)
TCP/IP on Linux
12.1 Network Divice Driver 12.1 Network Divice Driver 원리 및 구동원리 및 구동
www.huins.com 4
Interface with kernel core struct net_devide
Kernel 에서 network device 를 활성화 시키거나 비활성화 시킬때 그리고 data 를 network device 를 통해 전송하고자 할 때 등 kernel 이 device 를 control 하기 휘해 호출할 함수의 포인터를 가지고 있다 .
hard_start_xmit() 그외 network device 의 설정이나 상태에 대한 정보를 갖는 변수들을
가지고 있다 . Name base_address
Interrupt data 의 수신은 비동기적으로 발생하는 사건이므로 interrupt 를 통해
처리한다 . Data 수신 외에도 chip 이 data 를 전송할 준비가 된 경우 , data 에
오류가 발생경우 등을 interrupt 를 통해 처리한다 .
12.1 Network Divice Driver 12.1 Network Divice Driver 원리 및 구동원리 및 구동
www.huins.com 5
Network device driver Kernel core
net_device 구조체 생성
Static struct net_device dev
초기화 함수 등록
dev.init = cirrus_probe()
kernel 에 등록
register_netdev(&dev)
net_deivce 구조체 리스트에 dev 삽입
dev.init() 호출net_device 구조체 초기화•name, base_addr, irq 등의 설정
•hard_start_xmit, open, close 등의 함수 포인터에 실제 함수 연결 dev.open() 호출
interrupt 등록
request_irq()
device 초기화
장치 활성화
Network Device Driver 초기화 과정
12.1 Network Divice Driver 12.1 Network Divice Driver 원리 및 구동원리 및 구동
www.huins.com 6
Send Data
sock_write()sock_write() /* net/socket.c */
/* fs/read_write.c */
inet_sendmsg()inet_sendmsg() /* net/ipv4/af_inet.c */
tcp_send_skb()tcp_send_skb() /* net/ipv4/tcp_output.c */
ip_queue_xmit()ip_queue_xmit() /* net/ipv4/ip_output.c */
hard_start_xmit()hard_start_xmit() /* driver/net/cirrus.c */
Linux kernelVFS
BSD socket
inet socket
TCP
IP
Device driver
Application
System call
CS8900A MACCS8900A MACMAC
Device interface
Application
H/W
CS8900A PHYCS8900A PHYPHY
sys_write()sys_write()
write()write()
f->f_op->write()f->f_op->write()
12.1 Network Divice Driver 12.1 Network Divice Driver 원리 및 구동원리 및 구동
www.huins.com 7
Send Data
Kernel protocol stackKernel protocol stack
ApplicationApplication
Network device driverNetwork device driver
net_device 구조체net_device 구조체
. . . . . .
net_device 구조체net_device 구조체
net_device 구조체net_device 구조체
net_device 구조체net_device 구조체
Data 전송 요청
net_device 구조체 리스트에서 application
이 사용하는 장치에서 등록한 구조체의 함수 (*hard_start
_xmit()) 호출
struct net_device{ name; …. open; hard_start_xmit; stop; hard_header; set_config; chagne_mtu; get_stats; ….}
struct net_device{ name; …. open; hard_start_xmit; stop; hard_header; set_config; chagne_mtu; get_stats; ….}
Network device 의 internal register 를 setting 하여 data 를
전송하도록 한다 .
HardwareHardware
net_device 구조체 의 hard_start_xmit 가 가리키고 있는
실제 device driver module 의 함수
실행
12.1 Network Divice Driver 12.1 Network Divice Driver 원리 및 구동원리 및 구동
www.huins.com 8
Receive Data
ip_rev()ip_rev()
sock_read()sock_read()
f->f_op->read()f->f_op->read()
inet_recvmsg()inet_recvmsg()
VFS
BSD socket
inet socket
TCP
IP
Device driver
CS9800 MACCS9800 MACMAC
Device interfaceH/W
CS9800 PHYCS9800 PHYPHY
netif_rx()netif_rx()
tcp_rev_state_process()tcp_rev_state_process()
sleep
wake up
interrupt handler 수행interrupt handler 수행
tcp_recvmsg()tcp_recvmsg()
Linux kernel
Application
System call
Application
sys_read()sys_read()
read()read()
12.1 Network Divice Driver 12.1 Network Divice Driver 원리 및 구동원리 및 구동
www.huins.com 9
Receive Data
Kernel protocol stackKernel protocol stack
ApplicationApplication
Network device driverNetwork device driver
Data Read 요청
HardwareHardware
data 가 들어올 때까지 process 를 sleep 상태로
Kernel interrupt handlerKernel interrupt handler
data
Kernel 에 data 를 전달한다 . kernel은 해당 process 를 wake up 한다 .
Data 를 수신하면 net device 는 interrupt
를 발생시킨다 .
driver 에서 등록한
handler 함수를 호출
12.1 Network Divice Driver 12.1 Network Divice Driver 원리 및 구동원리 및 구동
www.huins.com 10
Differ fro character and block driver Interface with protocol stack (not file system) struct net_device is similar to struct file_operations
12.2 net_device structure12.2 net_device structure
struct net_device { name mem_end, mem_start rmem_end, rmem_start base addr irq start, interrupt tbusy … Qdisc /* sk_buff */ …. interface information method status ….}
struct net_device { name mem_end, mem_start rmem_end, rmem_start base addr irq start, interrupt tbusy … Qdisc /* sk_buff */ …. interface information method status ….}
hard_header_lenmtutx_queue_lenFamily, addressbroadcast….
hard_header_lenmtutx_queue_lenFamily, addressbroadcast….
openhard_start_xmitstophard_headerset_configchagne_mtuget_statsioctl….
openhard_start_xmitstophard_headerset_configchagne_mtuget_statsioctl….
www.huins.com 11
12.2 net_device structure12.2 net_device structurestruct net_device
char name[IFNAMSIZ]; 디바이스의 이름
unsigned long rmem_end; 수신 공유 메모리 끝
unsigned long rmem_start; 수신 공유 메모리 시작
unsigned long mem_end; 송신 공유 메모리 끝
unsigned long mem_start; 수신 공유 메모리 시작
unsigned long base_addr; I/O 기본 주소
unsigned int irq; 지정된 인터럽트 번호
unsigned char if_port; 인터 페이스가 사용하는 하드웨어 포트
unsigned char dma; DMA 채널
unsigned long state; Device 의 state,
struct net_device *next; 다음 디바이스 포인터
int (*init)(struct net_device *dev); 초기화 함수
struct net_device_stats* (*get_stats)(struct net_device *dev); 디바이스의 통계정보에 대한 포인터 반환
www.huins.com 12
12.2 net_device structure12.2 net_device structureunsigned long trans_start; 마지막 송신 시각 (jiffies 값 )
unsigned long last_rx; 마시막 수신 시각 (jiffies 값 )
unsigned short flags; 인터페이스 플래그
unsigned mtu; /* interface MTU value */
unsigned short type; /* interface hardware type */
unsigned short hard_header_len; /* hardware hdr length */
void *priv; /* pointer to private data */
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
unsigned char addr_len; /* hardware address length */
struct dev_mc_list *mc_list; /* Multicast mac addresses */
int mc_count; /* Number of installed mcasts */
int watchdog_timeo; /* watchdog timer 의 count 값 */
unsigned long tx_queue_len; /* Max frames per queue allowed */
spinlock_t xmit_lock;
int xmit_lock_owner;
www.huins.com 13
12.2 net_device structure12.2 net_device structureint (*open)(struct net_device *dev); device 가 활성화될 때 수행될 함수 포인터
int (*stop)(struct net_device *dev); device 가 비활성화될 때 수행될 함수 포인터
int (*hard_start_xmit) (struct sk_buff *skb,struct net_device *dev);
kernel 이 transit 을 요청할때 호출하는 함수 포인터
int (*hard_header) (struct sk_buff *skb);
int (*rebuild_header)(struct sk_buff *skb);
void (*set_multicast_list)(struct net_device *dev); HAVE_MULTICAST
int (*set_mac_address)(struct net_device *dev, void *addr);
HAVE_SET_MAC_ADDR
int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);
HAVE_PRIVATE_IOCTL
int (*set_config)(struct net_device *dev, struct ifmap *map);
HAVE_SET_CONFIG
int (*hard_header_cache)(struct neighbour *neigh,struct hh_cache *hh);
HAVE_HEADER_CACHE
void (*header_cache_update) (struct hh_cache *hh, struct net_device *dev,unsigned char * haddr);
int (*change_mtu)(struct net_device *dev, int new_mtu); HAVE_CHANGE_MTU
www.huins.com 14
12.2 net_device structure12.2 net_device structurevoid (*tx_timeout) (struct net_device *dev); HAVE_TX_TIMEOUT
int (*hard_header_parse)(struct sk_buff *skb, unsigned char *haddr);
struct module *owner;
www.huins.com 15
cirrus.c 의 주요 함수
cirrus_init() module 이 커널에 적재될 때에 수행되는 함수 net_device 구조체를 만들고 register_netdev() 함수를 호출한다 .
cirrus_cleanup() module 이 커널에서 제거될 때에 수행되는 함수 release_region(), unregister_netdev() 호출
cirrus_probe() cirrus_init() 에서 register_netdev() 를 호출할때 parameter 로 전달하는
dev 구조체의 init 함수 포인터에 이 함수의 주소를 담아 전달한다 . register_netdev() 함수 호출시 커널에서 이함수를 호출 net_device 의 나머지 부분들을 device 에 맞게 초기화 한다 .
12.3 Device Driver source code – [kernel]/driver12.3 Device Driver source code – [kernel]/drivers/net/cirrus.cs/net/cirrus.c
www.huins.com 16
cirrus_start() device 가 활성화 될 때에 수행되는 함수로 인터럽트를 등록하고 칩의
설정에 관련된 레지스터를 setting 한다 .
cirrus_stop() device 가 비활성화 될 때에 수행되는 함수로 인터럽트를 해제하고 칩을
초기화한다 .
cirrus_send_start() Application 에서 data 의 전송을 요구할때 kernel 의 tcp/ip protocol stack
의 ip layer 에서 호출하는 함수로 device 의 레지스터를 설정하여 data를 전송하도록 한다 .
cirrus_receive() 외부에서 data 를 수신했을때에 cirrus_interrupt() 에서 호출하는 함수로
data 를 device 로 부터 받아와서 kernel 에 전달 해 준다 .
12.3 Device Driver source code – [kernel]/driver12.3 Device Driver source code – [kernel]/drivers/net/cirrus.cs/net/cirrus.c
www.huins.com 17
cirrus_interrupt() 인터럽트를 관리하는 5 개의 레지스터중 어느 레지스터에서 인터럽트가
발생하였는지를 관찰하고 어떤 인터럽트가 발생했는지를 확인하여 적절한 처리를 해주는 함수
cirrus_start() 함수에서 kernel 에 request_irq() 함수를 호출하여 이함수를 device 의 interrupt handler 함수로 등록한다 .
12.3 Device Driver source code – [kernel]/driver12.3 Device Driver source code – [kernel]/drivers/net/cirrus.cs/net/cirrus.c
www.huins.com 18
cirrus_start()cirrus_start()
Network Device Driver
cirrus_send_start() cirrus_send_start()
cirrus_probe()cirrus_probe()
cirrus_receive()cirrus_receive()
cirrus_stop()cirrus_stop()
cirrus_interrupt()cirrus_interrupt()
Kernel Area
ip_output() ip_output()
ip_rcv() ip_rcv()
protocol stackprotocol stack
register_netdev 함수를 호출 할때
수행됨
Kernel 이 ethernet 을 통해 메시지를 전송할 때
호출
device 가 data frame 을 수신하는 등의 interrupt
가 발생했을 때 수행됨
device 가 활성화 될 때 수행됨
device 가 비활성화 될 때 수행됨
12.3 Device Driver source code – [kernel]/driver12.3 Device Driver source code – [kernel]/drivers/net/cirrus.cs/net/cirrus.c
www.huins.com 19
12.3 Device Driver source code - MACRO12.3 Device Driver source code - MACRO
MODULE_AUTHOR ("Abraham van der Merwe <[email protected]>");
MODULE_DESCRIPTION ("Cirrus Logic CS8900A driver for Linux (V0.02)");
MODULE_LICENSE ("GPL");
MODULE_PARM_DESC (io,"I/O Base Address");
MODULE_PARM (io,"i");
MODULE_PARM_DESC (irq,"IRQ Number");
MODULE_PARM (irq,"i");
module_init (cirrus_init);
module_exit (cirrus_cleanup);
www.huins.com 20
static struct net_device dev;
…
static int __init cirrus_init (void)
{
memset (&dev,0,sizeof (struct net_device));
dev.init = cirrus_probe;
return (register_netdev (&dev));
}Dev 를 list 에 추가한 후 cirrus_probe() 호출
dev 를 0 으로 초기화
12.3 Device Driver source code - MACRO12.3 Device Driver source code - MACRO
www.huins.com 21
static void __exit cirrus_cleanup (void)
{
release_region (dev.base_addr,16);
unregister_netdev (&dev);
}
12.3 Device Driver source code - MACRO12.3 Device Driver source code - MACRO
www.huins.com 22
12.3 Device Driver source code – cirrus_probe( )12.3 Device Driver source code – cirrus_probe( )
int __init cirrus_probe (struct net_device *dev)
{
memset (&priv,0,sizeof (cirrus_t));
ether_setup (dev);
dev->open = cirrus_start;
dev->stop = cirrus_stop;
dev->hard_start_xmit = cirrus_send_start;
dev->get_stats = cirrus_get_stats;
dev->set_multicast_list = cirrus_set_receive_mode;
dev->set_mac_address = cirrus_set_mac_address;
dev->tx_timeout = cirrus_transmit_timeout;
dev->watchdog_timeo = HZ;
www.huins.com 23
dev->dev_addr[0] = 0x00;
dev->dev_addr[1] = 0x00;
dev->dev_addr[2] = 0x00;
dev->dev_addr[3] = 0x00;
dev->dev_addr[4] = 0x00;
dev->dev_addr[5] = 0x00;
dev->if_port = IF_PORT_10BASET;
dev->priv = (void *) &priv;
SET_MODULE_OWNER (dev);
dev->base_addr = CIRRUS_DEFAULT_IO;
dev->irq = CIRRUS_DEFAULT_IRQ;
12.3 Device Driver source code – cirrus_probe( )12.3 Device Driver source code – cirrus_probe( )
www.huins.com 24
/* module parameters override everything */
if (io > 0) dev->base_addr = io;
if (irq > 0) dev->irq = irq;
... ...
if ((result = check_region (dev->base_addr,16))) {
printk (KERN_ERR "%s: can't get I/O port address\ 0x%lx\n",dev->name,dev->base_addr);
return (result);
}
if(!request_region(dev->base_addr,16,dev->name) )
return –EBUSY;
... ...
12.3 Device Driver source code – cirrus_probe( )12.3 Device Driver source code – cirrus_probe( )
www.huins.com 25
#if 1
cirrus_write (dev,PP_SelfCTL,RESET);
while((( reset_status = cirrus_read(dev,PP_SelfST)) &INITD ) == 0 );
chip_status = cirrus_read(dev, PP_SelfST );
#endif
/* if an EEPROM is present, use it's MAC address */... ...
/* verify EISA registration number for Cirrus Logic */... ...
/* verify chip version */... ...
/* setup interrupt number */... ...
/* configure MAC address */... ...
return (0);
}
12.3 Device Driver source code – cirrus_probe( )12.3 Device Driver source code – cirrus_probe( )
www.huins.com 26
12.3 Device Driver source code – cirrus_start( )12.3 Device Driver source code – cirrus_start( )
static int cirrus_start (struct net_device *dev)
{
int result;
/* valid ethernet address? */
if (!is_valid_ether_addr(dev->dev_addr)) {
printk(KERN_ERR "%s: invalid ethernet MAC address\n",dev->name);
return (-EINVAL);
}
www.huins.com 27
/* install interrupt handler */
if ((result = request_irq (dev->irq,&cirrus_interrupt,0,dev->name,dev)) < 0)
{
printk (KERN_ERR "%s: could not register interrupt %d\n",dev->name,dev->irq);
return (result);
}
/* enable the ethernet controller */
cirrus_set (dev,PP_RxCFG,RxOKiE | BufferCRC | CRCerroriE | RuntiE | ExtradataiE);
cirrus_set (dev,PP_RxCTL,RxOKA | IndividualA | BroadcastA);
cirrus_set (dev,PP_TxCFG,TxOKiE | Out_of_windowiE | JabberiE);
cirrus_set (dev,PP_BufCFG,Rdy4TxiE | RxMissiE | TxUnderruniE | TxColOvfiE | MissOvfloiE);
cirrus_set (dev,PP_LineCTL,SerRxON | SerTxON);
cirrus_set (dev,PP_BusCTL,EnableRQ);
12.3 Device Driver source code – cirrus_start( )12.3 Device Driver source code – cirrus_start( )
www.huins.com 28
#ifdef FULL_DUPLEX
cirrus_set (dev,PP_TestCTL,FDX);
#endif /* #ifdef FULL_DUPLEX */
/* start the queue */
netif_start_queue (dev);
MOD_INC_USE_COUNT;
return (0);
}
12.3 Device Driver source code – cirrus_start( )12.3 Device Driver source code – cirrus_start( )
www.huins.com 29
12.3 Device Driver source code – cirrus_stop( )12.3 Device Driver source code – cirrus_stop( )
static int cirrus_stop (struct net_device *dev)
{
/* disable ethernet controller */
cirrus_write (dev,PP_BusCTL,0);
cirrus_write (dev,PP_TestCTL,0);
cirrus_write (dev,PP_SelfCTL,0);
cirrus_write (dev,PP_LineCTL,0);
cirrus_write (dev,PP_BufCFG,0);
cirrus_write (dev,PP_TxCFG,0);
cirrus_write (dev,PP_RxCTL,0);
cirrus_write (dev,PP_RxCFG,0);
www.huins.com 30
/* uninstall interrupt handler */
free_irq (dev->irq,dev);
/* stop the queue */
netif_stop_queue (dev);
MOD_DEC_USE_COUNT;
return (0);
}
12.3 Device Driver source code – cirrus_stop( )12.3 Device Driver source code – cirrus_stop( )
www.huins.com 31
12.3 Device Driver source code – cirrus_send_st12.3 Device Driver source code – cirrus_send_start( )art( )
static int cirrus_send_start (struct sk_buff *skb,struct net_device *dev)
{
cirrus_t *priv = (cirrus_t *) dev->priv;
u16 status;
netif_stop_queue (dev);
cirrus_write (dev,PP_TxCMD,TxStart (After5));
cirrus_write (dev,PP_TxLength,skb->len);
www.huins.com 32
status = cirrus_read (dev,PP_BusST);
if ((status & TxBidErr)) {
printk (KERN_WARNING "%s: Invalid frame size %d!\n",dev->name,skb->len);
priv->stats.tx_errors++;
priv->stats.tx_aborted_errors++;
priv->txlen = 0;
return (1);
}
if (!(status & Rdy4TxNOW)) {
printk (KERN_WARNING "%s: Transmit buffer not free!\n",dev->name);
priv->stats.tx_errors++;
priv->txlen = 0;
/* FIXME: store skb and send it in interrupt handler*/
return (1);
}
12.3 Device Driver source code – cirrus_send_st12.3 Device Driver source code – cirrus_send_start( )art( )
www.huins.com 33
cirrus_frame_write (dev,skb);
dev->trans_start = jiffies;
dev_kfree_skb (skb);
priv->txlen = skb->len;
return (0);
}
12.3 Device Driver source code – cirrus_send_st12.3 Device Driver source code – cirrus_send_start( )art( )
www.huins.com 34
12.3 Device Driver source code – cirrus_receive( 12.3 Device Driver source code – cirrus_receive( ))
static void cirrus_receive (struct net_device *dev)
{
cirrus_t *priv = (cirrus_t *) dev->priv;
struct sk_buff *skb;
u16 status,length;
status = cirrus_read (dev,PP_RxStatus);
length = cirrus_read (dev,PP_RxLength);
if (!(status & RxOK)) {
priv->stats.rx_errors++;
if ((status & (Runt | Extradata)))
priv->stats.rx_length_errors++;
if ((status & CRCerror))
priv->stats.rx_crc_errors++;
return;
}
www.huins.com 35
if ((skb = dev_alloc_skb (length + 4)) == NULL) {
priv->stats.rx_dropped++;
return;
}
skb->dev = dev;
skb_reserve (skb,2);
cirrus_frame_read (dev,skb,length);
12.3 Device Driver source code – cirrus_receive( 12.3 Device Driver source code – cirrus_receive( ))
www.huins.com 36
skb->protocol = eth_type_trans (skb,dev);
netif_rx (skb);
dev->last_rx = jiffies;
priv->stats.rx_packets++;
priv->stats.rx_bytes += length;
}
12.3 Device Driver source code – cirrus_receive( 12.3 Device Driver source code – cirrus_receive( ))
www.huins.com 37
12.3 Device Driver source code – cirrus_interrup12.3 Device Driver source code – cirrus_interrupt( )t( )
static void cirrus_interrupt (int irq,void *id,struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) id;
cirrus_t *priv;
u16 status;
if (dev->priv == NULL) {
printk (KERN_WARNING "%s: irq %d for unknown device.\n",dev->name,irq);
return;
}
priv = (cirrus_t *) dev->priv;
www.huins.com 38
while ((status = cirrus_read (dev,PP_ISQ))) {
switch (RegNum (status)) {
case RxEvent:
cirrus_receive (dev);
break;
12.3 Device Driver source code – cirrus_interrup12.3 Device Driver source code – cirrus_interrupt( )t( )
www.huins.com 39
case TxEvent:
priv->stats.collisions += ColCount (cirrus_read(dev,PP_TxCOL));
if (!(RegContent (status) & TxOK)) {
priv->stats.tx_errors++;
if ((RegContent (status) & Out_of_window))
priv->stats.tx_window_errors++;
if ((RegContent (status) & Jabber))
priv->stats.tx_aborted_errors++;
break;
} else if (priv->txlen) {
priv->stats.tx_packets++;
priv->stats.tx_bytes += priv->txlen;
}
priv->txlen = 0;
netif_wake_queue (dev);
break;
12.3 Device Driver source code – cirrus_interrup12.3 Device Driver source code – cirrus_interrupt( )t( )
www.huins.com 40
case BufEvent:
if ((RegContent (status) & RxMiss)) {
u16 missed = MissCount (cirrus_read (dev,PP_RxMISS));
priv->stats.rx_errors += missed;
priv->stats.rx_missed_errors += missed;
}
if ((RegContent (status) & TxUnderrun)) {
priv->stats.tx_errors++;
priv->stats.tx_fifo_errors++;
}
/* FIXME: if Rdy4Tx, transmit last sent packet (if any) */
priv->txlen = 0;
netif_wake_queue (dev);
break;
12.3 Device Driver source code – cirrus_interrup12.3 Device Driver source code – cirrus_interrupt( )t( )
www.huins.com 41
case TxCOL:
priv->stats.collisions += ColCount (cirrus_read (dev,PP_TxCOL));
break;
case RxMISS:
status = MissCount (cirrus_read (dev,PP_RxMISS));
priv->stats.rx_errors += status;
priv->stats.rx_missed_errors += status;
break;
}
}
}
12.3 Device Driver source code – cirrus_interrup12.3 Device Driver source code – cirrus_interrupt( )t( )
www.huins.com 42
Network device driver 동작 확인 ifconfig 를 명령 수행 eth0 가 보이지 않으면 % /etc/rc.d/init.d/network start 실행
12.4 Network device driver 12.4 Network device driver 구동구동
www.huins.com 43
Network Device Driver 동작 test Host 에 ping 을 보내어 제대로 동작하는지 확인한다 .
12.4 Network device driver 12.4 Network device driver 구동구동
www.huins.com 45
TCP/IP 계층 구조
현재 전 세계적으로 사용하고 있는 인터넷은 TCP/IP 라는 프로토콜을 기반으로 동작한다 .
네트워크 계층구조의 기준이라고 할 수 있는 OSI7 계층과 달리 TCP/IP 는 4 개의 계층으로 이루어져 있다 .
12.4 Socket()12.4 Socket()
www.huins.com 46
TCP/IP 계층 구조 중 ‘ Transport 계층’에서는 TCP 와 UDP 프로토콜을 제공한다 . 이 두 프로토콜의 차이점은 아래와 같다 .
12.4 Socket()12.4 Socket()
www.huins.com 47
IP 주소와 PORT 번호 IP
TCP/IP protocol 을 사용하여 데이터를 주고 받기 위해서는 주소가 필요 TCP/IP 에서 주소와 관련된 protocol 을 IP(Internel Protocol) 이라고 함 ‘.’ 으로 구분된 4byte 정수로 표시
Port 번호 Host 에는 여러 프로세스가 동작하고 있는데 어느 데이터가 전송되어
왔을 때 어느 프로세스가 수신할 것이지를 결정하는 것이 port 번호 2byte 정수로 표시하며 0~66535 까지 사용이 가능 telnet(23), ftp(21), httpd(80)
12.4 Socket()12.4 Socket()
www.huins.com 48
Socket 이란 TCP 계층에서 제공하는 인터페이스를 직접 사용하여 프로그래밍하는 것은 매우
복잡하고 관련 프로토콜의 내부 구조를 잘 알고 있어야 한다 . 이런 복잡한 작업을 간편하게 해주는 것이 socket 이다 . Socket 은 응용계층에서 TCP 계층의 기능을 사용할 수 있도록 제공하는 API 이다 .
12.4 Socket()12.4 Socket()
www.huins.com 49
Socket 은 같은 호스트에서 내부 프로세스들끼리 통신할 때 사용하는 유닉스도메인 Socket 과 다른 호스트와의 통신을 위한 인터넷 Socket 으로 구분된다 . AF_UNIX : 유닉스 도메인 Socket AF_INET : 인터넷 Socket
Socket 이 TCP 를 사용하느냐 , UDP 를 사용하느냐에 따라 두 가지로 구분된다 . SOCK_STREAM : TCP 를 사용 SOCK_DGRAM : UDP 를 사용
12.4 Socket()12.4 Socket()
www.huins.com 50
Socket 의 종류와 TCP/UDP 를 결합하면 4 가지 통신 유형이 나타난다 AF_UNIX, SOCK_STREAM AF_UNIX, SOCK_DGRAM AF_INET, SOCK_STREAM AF_INET, SOCK_DGRAM
12.4 Socket()12.4 Socket()
www.huins.com 51
Socket 주소 구조체 (1) socket 을 이용한 프로그래밍에서는 socket 의 종류와 IP 주소 ,
포트번호 등을 지정하기 위한 구조체를 사용한다 . 인터넷 소켓
sin_len: 구조체의 크기 , 보통 설정하지 않는다 . sin_family: AF_INET sin_port: 포트번호 sin_addr: IP 주소 ( 구조체 )
sin_zero: 패딩처리 (memset/bzero 로 0 으로 채워야함 )
12.4 Socket()12.4 Socket()
www.huins.com 53
Byte Ordering 함수 (1) 네트웍 통신에서 바이트를 저장하는 2 가지 방법이 있다 .(NBO) Big Endian
0x1234 를 저장할 경우 0x12, 0x34 의 순서대로 저장된다 . Little Endian
0x1234 를 저장할 경우 0x34, 0x12 의 순서처럼 거꾸로 저장이 된다 . TCP/IP 에서는 Big Endian 방식을 사용한다 . 이를 network byte or
der(NBO) 라고 한다 . Host 에서 사용하는 byte 순서는 Host Byte Order(HBO) 라고 한다 . NBO 와 HBO 간에 byte 순서를 변환하여 주는 함수들이 제공된다 .
12.4 Socket()12.4 Socket()
www.huins.com 54
Byte Ordering 함수 (2) sockaddr_in 구조체를 사용할 때 sin_addr 과 sin_port 는 NBO 로
저장한다 . 이것은 외부 네트워크를 통해 상대편으로 전달될 것이기 때문이다 . 반면 sin_family 는 HBO 로 저장한다 . 이는 시스템 내부에서만 사용될 것이기 때문이다 . short 는 16 비트용으로 포트번호를 변환할 때 사용하고 , long 은 32 비트용으로 IP 주소를 변환할 때 사용한다 .
12.4 Socket()12.4 Socket()
www.huins.com 55
IP 주소 변환 함수 (1) in_addr 구조체에서 IP 주소를 저장하는 변수의 자료형은 long
형이다 . 따라서 '.' 으로 구분되는 IP 주소를 long 형으로 변환시키고 , 이를 다시 문자형으로 변환하여 주는 함수들이 필요하다 .
12.4 Socket()12.4 Socket()
www.huins.com 56
IP 주소 변환 함수 (2) inet_addr() 함수는 IP 주소를 문자열로 받아 이를 long 형으로
바꿔준다 . inet_ntoa() 함수의 경우 인자로 in_addr 구조체를 받고 있음을 기억해야 한다 .
12.4 Socket()12.4 Socket()
www.huins.com 57
Socket Interface 함수 socket 을 이용하여 네트워크 프로그래밍을 할 때 사용되는
인터페이스 함수들은 다음과 같다 . socket() : 소켓 파일기술자 생성 bind() : 소켓 파일기술자를 지정된 IP 주소 / 포트번호와 결합 (bin
d) listen() : 클라이언트의 접속 요청 대기 connect() : 클라이언트가 서버에 접속 요청 accept() : 클라이언트의 접속 허용 recv() : 데이터 수신 send() : 데이터 송신 recvfrom() : 데이터 수신 ( 데이터그램 소켓 ) sendto() : 데이터 송신 ( 데이터그램 소켓 ) close() : 소켓 파일기술자 종료
12.4 Socket()12.4 Socket()
www.huins.com 58
socket() socket() 함수는 소켓 파일기술자를 생성하는 함수이다 .
family : AF_UNIX, AF_INET type : SOCK_STREAM, SOCK_DGRAM
protocol : 0 socket() 함수는 생성된 소켓파일기술자를 돌려준다 . 이
소켓파일기술자가 다른 함수들에 사용된다 .
12.4 Socket()12.4 Socket()
www.huins.com 59
bind()(1) bind() 함수는 socket() 함수로 생성된 소켓파일기술자를 지정된 IP
주소 / 포트번호와 결합시킨다 .
s : 소켓파일기술자 name : 소켓 주소 구조체 namelen : 소켓 주소 구조체 크기
12.4 Socket()12.4 Socket()
www.huins.com 61
listen()(1) 서버 프로세스가 클라이언트로부터의 요청을 기다리도록 하는
함수이다
s : 소켓파일기술자 backlog : 최대 허용 클라이언트수 ( 보통 20 이하 )
12.4 Socket()12.4 Socket()
www.huins.com 62
listen()(2) listen() 함수는 첫 번째 인자로 소켓파일기술자를 지정한다 . 특별히
접속을 기다리고 있는 소켓을 리스닝소켓 (listening socket) 이라고 한다 . listen() 함수는 반드시 bind() 함수를 실해한 뒤에 사용한다 .
12.4 Socket()12.4 Socket()
www.huins.com 63
connect()(1) 클라이언트가 서버로 접속을 요청하는 함수이다 .
s : 소켓파일기술자 addr : 소켓 주소 구조체 (IP 주소 , 포트번호 ) addrlen : 구조체의 크기
12.4 Socket()12.4 Socket()
www.huins.com 64
connect()(2) connect() 함수는 연결이 성공하면 0 을 돌려주고 , 실패하면 -1 을
돌려준다 . 이는 다른 함수들도 마찬가지이다 . 연결이 성공된 소켓을 연결된 소켓 (connected socket) 이라고 한다 . 연결된 소켓은 데이터를 주고 받기 위해 사용된다 .
12.4 Socket()12.4 Socket()
www.huins.com 65
accept()(1) 서버가 클라이언트의 접속을 허용하는 함수이다 .
s : 소켓파일기술자 addr : 접속을 요청한 클라이언트의 주소 구조체 addrlen : 구조체 크기
accept() 함수가 접속을 허용하면 연결된 소켓파일기술자를 돌려준다 . 실패할 경우 -1 을 돌려준다 .
12.4 Socket()12.4 Socket()
www.huins.com 66
accept()(2)
sockfd 는 리스닝소켓이고 , new_fd 는 연결된 소켓이다 . 이후로는 new_fd 를 통하여 데이터를 주고 받는다
12.4 Socket()12.4 Socket()
www.huins.com 67
send()(1) 연결된 소켓파일기술자를 통하여 데이터를 전송한다 .
s : 소켓파일기술자 msg : 전송할 데이터의 주소 len : 전송할 데이터의 크기 flags : 0
send() 함수는 실제로 전송한 바이트의 수를 돌려준다 . 지정한 크기보다 작으면 데이터를 다 보내지 못했음을 의미한다 . 나머지 데이터는 다시 보내도록 프로그래밍해야 한다 . -1 을 돌려주면 전송 자체를 실패했음을 의미한다 .
12.4 Socket()12.4 Socket()
www.huins.com 69
recv()(1) 연결된 소켓파일기술자를 통하여 전송된 데이터를 수신한다 .
s : 소켓파일기술자 buf : 수신할 버퍼의 주소 len : 버퍼의 크기 flags : 0
recv() 함수는 실제로 수신한 바이트의 수를 돌려준다 .
12.4 Socket()12.4 Socket()
www.huins.com 71
sendto()(1) 데이터그램을 이용한 소켓으로 데이터를 전송한다 .
s : 소켓파일기술자 msg : 전송할 데이터의 주소 len : 전송할 데이터의 크기 flags : 0 to : 목적지 주소 구조체 tolen : 주소 구조체 크기
데이터그램을 이용하여 데이터를 전송할 때 sendto() 함수를 사용한다 . 데이터그램 소켓을 보통 connect() 함수를 사용하지 않아 목적지가 설정되어 있지 않으므로 sendto() 함수 호출시 목적지 주소를 인자로 지정한다 .
12.4 Socket()12.4 Socket()
www.huins.com 73
recvfrom()(1) 데이터그램을 이용한 소켓파일기술자를 통하여 전송된 데이터를
수신한다 .
s : 소켓파일기술자 buf : 수신할 버퍼의 주소 len : 버퍼의 크기 flags : 0 to : 발신지 주소 구조체 tolen : 주소 구조체 크기
12.4 Socket()12.4 Socket()
www.huins.com 75
socket programming 예제 소켓 프로그래밍에 사용되는 함수들을 서버와 클라이언트로 구분하여
살펴보면 아래와 같다 . 인터넷소켓 (AF_INET) 과 TCP(SOCK_STREAM) 을 사용하여
통신하는 프로그램을 구현한다 . 예제에서는 서버와 클라이언트가 같은 호스트에 있지만 다른 호스트에서 서버를 실행할 경우 클라이언트에서 서버의 주소만 다르게 지정하면 된다 .
12.4 Socket()12.4 Socket()
www.huins.com 76
server program(1)#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <errno.h> #define PORTNUM 5001 main() {
char buf[256]; struct sockaddr_in sin, cli;
int sd, ns, clientlen = sizeof(cli); memset((char *)&sin, '\0', sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(PORTNUM); sin.sin_addr.s_addr = inet_addr("203.230.223.235");
12.4 Socket()12.4 Socket()
www.huins.com 77
server program(2) if((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if(bind(sd, (struct sockaddr *)&sin, sizeof(sin))) { perror("bind"); exit(1); } if(listen(sd, 5)) { perror("listen"); exit(1); }
12.4 Socket()12.4 Socket()
www.huins.com 78
server program(3) while(1) { if((ns = accept(sd, (struct sockaddr *)&cli, &clientlen)) == -1) { perror("accept"); exit(1);
} strcpy(buf, "Server Message"); if(send(ns, buf, strlen(buf) + 1, 0) == -1) { perror("send"); exit(1); } close(ns);
}
12.4 Socket()12.4 Socket()
www.huins.com 79
client program(1)#include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <errno.h> #define PORTNUM 5001 main() { int sd; char buf[256]; struct sockaddr_in sin; memset((char *)&sin, '\0', sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(PORTNUM); sin.sin_addr.s_addr = inet_addr("203.230.223.235");
12.4 Socket()12.4 Socket()
www.huins.com 80
client program(2) if((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } if(connect(sd, (struct sockaddr *)&sin, sizeof(sin))) { perror("bind"); exit(1); } if(recv(sd, buf, sizeof(buf), 0) == -1) { perror("recv"); exit(1); } close(sd); printf("From Server : %s\n", buf); }
12.4 Socket()12.4 Socket()
www.huins.com 81
컴파일과 실행% gcc -o ser 12-12s.c -lsocket –ln 니% gcc -o cli 12-12c.c -lsocket -lnsl
% ser&
% cli
12.4 Socket()12.4 Socket()
www.huins.com 83
Features Single-Chip IEEE 802.3 Ethernet Controller with Direct ISA-Bus Interface Maximum Current Consumption = 55mA(5V supply) 3V Operation Industrial Temperature Range Comprehensive Suite of Software Drivers Available Efficient PacketPage Architecture Operation in I/O and Memory Space, and DMA Full D
uplex Operation On-Chip RAM Buffers Transmit and Receive Frames 10BASE-T Port with Analog Filters AUI Port for 10BASE2, 10BASE5 and 10BASE-F Programmable Transmit Programmable Receive EEPROM Support for Jumperless Configuration Boot PROM Support Diskless Systems Boundary Scan and Loopback Test LED Drivers for Link Status and LAN Activity Standby and Suspend Sleep Modes
12.5 General Description12.5 General Description
www.huins.com 84
Block Diagram
12.5 General Description12.5 General Description
버퍼역할 (PacketPage)
I/O map
Memory map
DMANRZ/Manchester Signal
변환
20MHz 발진
Configuration
Transformer 임피던스 매칭
CSMA/CD
RJ45 Interfac
eISA Bus
Interface
www.huins.com 85
MAC Interface
12.5 General Description12.5 General Description1. 완전한 IEEE 802.3 Ethernet
standard 적용
2. Ethernet Frame 송수신의 모든 측면을 핸들링
3. Including : collision detection, preamble generation and detection
www.huins.com 87
Data path with pxa255
12.5 General Description12.5 General Description
A[1:19]
D[0:15]
pxa255 CS8900A
*dev
portnovalue
nCS[2]
I S A
I N T
E R
F A
C
E
TxLength
ISQ
PP Pointer
PP Data(1)
PP Data(2)
Off
set
Mem
ory
C
on
trolle
r
base addr0x300
Packet page
0x0000h Rx/Tx Data(1)
0x0002h
0x0004h
0x0006h
0x0008h
0x000ah
0x000bh
0x000ch
TxCMD
Rx/Tx Data(2)
nCS[2] 는 physical address 0x 0800 0000 에 mapping 됨A[0:15] 는 0x300h 를 base address 로 그러므로 CS8900A 의 pxa255 에서의 address 는 0x0800 0300 이다 .이것은 BUS 로 나가는 물리적인 주소이고 , MMU 를 사용할 경우는 0xf800 0300 에 mapping 된다 .리눅스에서는 이러한 정보를 dev 구조체 포인터의 base_addr 에서 포인팅하도록 되어있다 .
www.huins.com 88
12.5 General Description12.5 General Description
예 )static inline u16 cirrus_read(struct net_device *dev, u16 reg){ outw(reg, dev->base_addr + PP_Address); return inw(dev->base_addr + PP_Data);}Static inline void cirrus_write(struct net_device *dev, u16 reg, u16 value)
{ outw(reg, dev->base_addr + PP_Address); outw(value, dev->base_addr + PP_Data);}
RX/TX Data(port 1)R/W0002h
TxCMDW0004h
TxLengthW0006h
Interrupt Status QueueR0008h
Packet Page PointerR/W000Ah
Descriptiontypeoffset
RX/TX Data(port 0)R/W0000h
Packet Page Data(port0)R/W000Ch
Packet Page Data(port1)R/W000Eh
dev->base_addr : device I/O addressPP_Address : 0x000APP_Data : 0x000C
CS8900 I/O Mode Mapping 16bit I/O ports
www.huins.com 89
12.6 PacketPage(internal registers) Overview12.6 PacketPage(internal registers) Overview
Internal Memory (Registers ) Bus Interface Registers Status and Control Registers Initiate Transmit Registers Address Filter Registers Receive $ Transmit Frame Location
www.huins.com 90
12.6 PacketPage(internal registers) Overview12.6 PacketPage(internal registers) Overview
Bus Interface Registers CS8900A ISA bus 설정 Map the CS8900A into the host system’s I/O and Memory space 주로 초기화 단계에 값이 기록되어 변하지 않는다 . DMA 관련 레지스터의 경우는 DMA 를 사용할 때마다 값이 변경됨 CS8900A data sheet 의 section 4.3 on page 42 참고
www.huins.com 91
12.6 PacketPage(internal registers) Overview12.6 PacketPage(internal registers) Overview
Status and Control Registers CS8900A 의 동작 방식 설정
How frames will be transmitted and received. Which frames will be transmitted and received. Which event will cause interrupts to the host processor. How the Ethernet physical interface will be configured.
CS8900A 의 현재 상태 저장 Status of transmitted and received frames. Information about the configuration of the CS8900A.
CS8900A data sheet 의 section 4.4 on page 47 참고
www.huins.com 92
12.6 PacketPage(internal registers) Overview12.6 PacketPage(internal registers) Overview
Initiate Transmit Registers TxCmd, TxLength registers: 전송을 시작할 때 사용 CS8900A data sheet Section 4.5 on page 71 참고
Address Filter Registers Individual Address 저장 Logical Address filter 저장 CS8900A data sheet Section 4.6 on page 72 참고
www.huins.com 93
12.6 PacketPage(internal registers) Overview12.6 PacketPage(internal registers) Overview
Receive & Transmit Frame Location Ethernet frame 을 송신하거나 수신할 때 사용 송신 : Transmit Frame Location 에 송신할 data 를 기록 수신 : Receive Frame Location 에서 수신한 data 를 읽는다 . CA8900A data sheet Section 4.7 on page 73 참고
www.huins.com 94
12.6 PacketPage(internal registers) Overview12.6 PacketPage(internal registers) Overview
PacketPage memory map
www.huins.com 95
12.6 PacketPage(internal registers) Overview12.6 PacketPage(internal registers) Overview
PacketPage memory map
www.huins.com 96
Bus Interface
12.7 Registers Description12.7 Registers Description
Address Name Description
0x0000Product Identification Code
Chip 의 id 를 저장하고 있다 . Device Driver 에서 올바른 chip 인지를 검사하거나 chip의 종류를 구별하여 어느 기능을 구현할 수 있는지 알아보는 데 사용할 수 있다 .
0x0020 I/O Base AddressI/O Base Address Register 로 chip 이 연결되어 있는 host 의 16 bytes 의 연속된 I/O space 에 대한 base address 를 저장한다 . 기본적으로 0x300 으로 지정되어 있다 .
0x0022 Interrupt NumberInterrupt Number Register 로 interrupt pin 을 선택하기 위한 register 이다 . 4 개의 pin 이 있고 선택 되지 않은 pin 은 high impedence 를 갖는다 .
0x0024DMA
Channel NumberDMA Channel Number 를 선택하기 위한 register 이다 . 3 개의 pin 중 하나를 선택할 수 있으며 DMA 를 사용하지 않기 위해 3 개의 pin 모두 사용하지 않을 수 도 있다 .
0x0027DMA
Start of FrameDMA start of frame register 로 dma 로 전송할 시작 주소를 가지고 있다 .
0x0028DMA
Frame Count마지막으로 이 레지스터를 읽은 이후로 DMA 를 통해 전달된 유효한 (valid) frame 의 개수를 저장하고 있다 .
0x002ARxDMA
Byte Counter마지막으로 이 레지스터를 읽은 이후로 DMA 를 통해 전달된 유효한 (valid) byte 의 수를 저장하고 있다 .
0x002CMemory
Base AddressHost 의 Memory space 에 mapping 된 경우의 base address
0x0030Boot PROM
Base AddressBoot PROM 의 base address 를 가지고 있다 .
* Address 는 packet page pointe 에 들어갈 값이다 .
www.huins.com 97
Bus Interface
12.7 Registers Description12.7 Registers Description
Address Name Description
0x0034Boot PROM
Address MaskBoot PROM 의 size 를 가지고 있다 .
0x0040EEPROM
CommandEEPROM 에 read/write 명령을 줄때 사용한다 .
0x0042 EEPROM Data EEPROM 에 기록하거나 읽을 data 를 갖는다 .
0x0050Receive Frame
Byte Counter현재 받은 frame 의 총 byte 수를 갖는다 . 현재 frame 이 한 byte 를 받을 때마다 지속적으로 증가한다 .
* Address 는 packet page pointer 에 들어갈 값이다 .
www.huins.com 98
Status and Control Registers
12.6 Registers Description12.6 Registers Description
Address Name Description
0x0120Interrupt Status
QueueHost 에 interrupt 에 관한 정보를 제공하기 위한 레지스터로 어느 event 로 인해 interrupt 가 발생하였는 가를 알 수 있다 .
0x0102 Receiver ConfigurationFrmae 을 어떻게 전송할 것인지 , 어떤 frame type 을 수신했을 때 interrupt 를 발생 시킬 것인지등을 설정한다 .
0x0124 Receiver Event현재 받은 frame 의 상태에 대한 정보를 담고 있다 . crc 가 유효한가 ? Broadcast 로 전송된 frame인가 등
0x0104 Receiver Control어떤 type 의 frame 을 받아 들일 것인가 ? 어느 주소 (broadcast, multicast, individual 등 ) 로 전송된 data 를 받아들일 것인가 ? 등을 설정한다 .
0x0106 Transmit Configuration Frame 을 전송할 때 발생할 수 있는 event 에 대하여 interrupt 를 발생시킬 것인지의 여부를 결정한다 .
0x0218 Transmit Event마지막으로 전송한 패킷의 event status 를 가지고 있다 . 완전히 전송되었는가 ? 에러가 발생했는가 ? 어떤 에러가 발생했는가 ? 등의 정보 .
0x0108Transmit Command Status
마지막 Transmit Command 를 갖고 있다 .
0x010A Buffer ConfigurationBuffer 에서 발생할 수 있는 event 들에 대해 interrupt 를 발생시킬 것인지의 여부를 결정한다 . Received frame 을 잃은 경우 , frame 을 전송할 준비가 된 경우 등
0x012C Buffer Event Transmit and receive buffers 의 상태에 대한 정보를 가지고 있다 .
www.huins.com 99
Status and Control Registers
12.6 Registers Description12.6 Registers Description
Address Name Description
0x0130 Receiver Miss Counter Buffer space 의 부족으로 인해 손실된 frame 들의 수를 기록하고 있다 .
0x0132Transmit Collision Counter
Frame 전송시 collision 이 발생할 때마다 1 씩 증가한다 .
0x0112 Line ControlMAC engine 과 physical interface 을 설정한다 . Receiver or Transmitter 를 enable 하여 송수신을 가능하는 등
0x0134 Line StatusEthernet physical interface 의 상태를 report. AUI 나 10BT 중 어느것을 사용하는지 현재 frame 을 수신하는 중인지 등
0x0114 Self ControlLED 의 출력과 , lower-power modes 를 control. Data 의 전송이 없는 경우 sleep, 사용할때 awake 등의 control
0x0136 Self StatusEEPROM interface 와 initialization process 의 상태를 report. EEPROM 이 존재하는지 , 현재 사용중인지 등
0x0116 Bus Control ISA-bus interface 의 operation 을 control. DMA 초기화 , Memory Mode 사용 여부등의 설정
0x0138 Bus StatusBus 가 frame 을 전송할 준비가 되었는지 여부와 , host 에서 CS8900A 에서 전송을 하면 안될 frame(1518 bytes 보다 큰 frame) 을 전송했는지 여부를 나타냄
0x0118 Test Control CS8900A 의 진단
www.huins.com 100
Status and Control Registers
12.6 Registers Description12.6 Registers Description
Address Name Description
0x013CAUI Time Domain Reflectometer
Cable fault 를 찾아낼때 유용한 것으로 frame 을 전송한 후 collision 이나 loss of carrier error 가 발생할 때까지의 10 MHz clock periods 를 가지고 있다 .
www.huins.com 101
Initiate Transmit Registers
12.6 Registers Description12.6 Registers Description
Address Name Description
0x0144Transmit Command Request
CS8900A 에 다음 packet 이 어떻게 전송되어야 하는가를 알려준다 . MAC 에서 packet 전송 프로세스를 시작하기 전에 몇 바이트를 CS8900A 로 가져올 것인지 등
0x0146 Transmit Length 전송할 FRAME 의 길이를 알려준다 .
www.huins.com 102
Address Filter Registers
12.6 Registers Description12.6 Registers Description
Address Name Description
0x0150Logical Address Filter (hash table)
목적지 주소에 따라 frame 을 받아 들일것인지 버릴것인지를 결정할 수 있도록하는 filter 기능을 한다 .
0x0020Individual Address (IEEE address)
Chip 의 물리 주소를 가지고 있다 .
www.huins.com 103
Receive and Transmit Frame Locations
12.6 Registers Description12.6 Registers Description
Address Name Description
0x0400 Receive Status수신한 frame 의 상태에 대한 정보를 가지고 있다 . Receive Event register 와 동일한 값을 가지고 있지만 , 레지스터가 읽힌 후에 register 의 값이 clear 되지 않는다 .
0x0402 Receive Length 수신한 frame 의 길이를 가지고 있다 . (byte 단위 )
0x0404Receive Frame Location
수신한 frame 이 저장되는 위치이다 .
0x0A00Transmit Frame Location
송신할 frame 이 저장되는 위치이다 .