12. 네트워크 디바이스 드라이버

103
12. 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 Presentation

Transcript of 12. 네트워크 디바이스 드라이버

12. 12. 네트워크 디바이스 드라이버네트워크 디바이스 드라이버

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 구동구동

Socket ProgramingSocket Programing

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 52

Socket 주소 구조체 (2) Unix Socket

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 60

bind(2)

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 68

send()(2)

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 70

recv()(2)

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 72

sendto()(2)

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 74

recvfrom()(2)

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()

PXA255-Pro CS8900PXA255-Pro CS8900

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 86

Ethernet Frame Format

12.5 General Description12.5 General Description

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 이 저장되는 위치이다 .