Chinaunix首页 | 论坛 | 博客
  • 博客访问: 75942
  • 博文数量: 35
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 140
  • 用 户 组: 普通用户
  • 注册时间: 2015-03-11 10:56
文章分类

全部博文(35)

文章存档

2016年(2)

2015年(33)

我的朋友

分类: LINUX

2015-03-18 16:11:52

Analy the skelet of netdriver (Isa-skeleton.c)

 

init

 

//private data

struct net_local {

         struct net_device_stats stats;

         long open_time;                         /* Useless example local info. */

         spinlock_t lock;

};

 

int init_module(void)

         //create function

->alloc_etherdev(sizeof(struct net_local));

                   ->alloc_netdev(sizeof_priv, "eth%d", ether_setup);

                            ->p = kzalloc(alloc_size, GFP_KERNEL);

                            ->setup(dev);

                            //void ether_setup(struct net_device *dev)

{

                             dev->change_mtu          = eth_change_mtu;

                  dev->hard_header          = eth_header;

                        dev->rebuild_header    = eth_rebuild_header;

                            dev->set_mac_address        = eth_mac_addr;

                            dev->hard_header_cache      = eth_header_cache;

                             dev->header_cache_update= eth_header_cache_update;

                             dev->hard_header_parse      = eth_header_parse;

                             dev->type                = ARPHRD_ETHER;

                             dev->hard_header_len          = ETH_HLEN;

                             dev->mtu                 = ETH_DATA_LEN;

                             dev->addr_len                 = ETH_ALEN;

                             dev->tx_queue_len        = 1000;     /* Ethernet wants good queues */

                             dev->flags               = IFF_BROADCAST|IFF_MULTICAST;

                             memset(dev->broadcast, 0xFF, ETH_ALEN);

}

         //get resource from platform_device

         ->dev->base_addr = io;

         ->dev->irq       = irq;

         ->dev->dma       = dma;

         ->dev->mem_start = mem;

         //real work

->do_netcard_probe(dev)

         ->netcard_probe1(dev, base_addr)

                   //fill the net_device object

                   ->request_region(ioaddr, NETCARD_IO_EXTENT, cardname)

                   ->request_irq(dev->irq, &net_interrupt, 0, cardname, dev);

                   ->request_dma(dev->dma, cardname)

                   ->dev->open              = net_open;

                  ->dev->stop               = net_close;

                  ->dev->hard_start_xmit  = net_send_packet;

                  ->dev->get_stats              = net_get_stats;

                  ->dev->set_multicast_list = &set_multicast_list;

        -> dev->tx_timeout           = &net_tx_timeout;

        ->dev->watchdog_timeo = MY_TX_TIMEOUT;

                   //Take a completed network device structure and add it to the kernel interfaces.

                   ->register_netdev(dev);

                            ->dev_alloc_name(dev, dev->name)

                            ->register_netdevice(dev);

                                    ->netdev_register_sysfs(dev);

                                     ->dev_init_scheduler(dev);

 

 

Net_open

 

net_open(struct net_device *dev)

->request_irq(dev->irq, &net_interrupt, 0, cardname, dev)

->request_dma(dev->dma, cardname)

->chipset_init(dev, 1);

-> np->open_time = jiffies;

->netif_start_queue(dev);

->clear_bit(__LINK_STATE_XOFF, &dev->state);

 

 

Send data

 

net_send_packet(struct sk_buff *skb, struct net_device *dev)(isa-skeleton.c)

         ->spin_lock_irq(&np->lock);

         //force the hard to send

//touch the interrupt?????

         ->add_to_tx_ring(np, skb, length);

         ->dev->trans_start = jiffies;

         ->if (tx_full(dev)) netif_stop_queue(dev);

 

 

interrupt

 

static irqreturn_t net_interrupt(int irq, void *dev_id)

         //receicve

->if (status & RX_INTR)

 /* Got a packet(s). */

net_rx(dev);

         ->struct sk_buff *skb;

         lp->stats.rx_bytes+=pkt_len;

         skb = dev_alloc_skb(pkt_len);

         skb->dev = dev;

                   insw(ioaddr, skb->data, (pkt_len + 1) >> 1);

         netif_rx(skb);

         dev->last_rx = jiffies;

         lp->stats.rx_packets++;

         lp->stats.rx_bytes += pkt_len;

         }

         //transmit

->if (status & TX_INTR) {

/* Transmit complete. */

net_tx(dev);

       //cpu put data to mac fifo

       ->while (tx_entry_is_sent(np, entry)) {

                struct sk_buff *skb = np->skbs[entry];

                np->stats.tx_bytes += skb->len;

                dev_kfree_skb_irq (skb);

                entry = next_tx_entry(np, entry);

                }

阅读(675) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~