Linux Network Driver
I would like to use this article to commemorate the past years
I. Preface
In Linux, the network driver is also a big head, how to understand the network drive is as a Linux driver engineers must have the skills. But the same equipment, in different people's hands will have different effects, the reason is that the driver is good or not.
Two. Device Registration
The driving of learning Network is the same as learning common Cdev drive, it is learning its template and then creating learning. In the Learning network drive process, we ignore its hardware specific operation, this will be more universal. Take dm9000a as an example. The network driver, like the USB drive, has a lot of work done by its kernel. DM9000A used the platform bus approach to match the device to the driver. In the previous article also said that its device belongs to the type of device and the type of device does not have a relationship, such as a USB bus, its USB keyboard belongs to Cdev, and the USB storage is a block device, but they are USB bus devices. Network equipment is the same. Therefore, the equipment used in the platform bus instead more intuitive. Registration and driver registration for platform devices we won't talk about it. But before you do that, you need to explain something about memory mapping, which is not a mapping. Take s3c6410 and dm9000a as an example, dm9000a's data and address lines are connected to the Srom1 interface of the CPU. In the inside you need to understand a macro definition
#define S3C64XX_PA_DM9000 (0x18000000) and # define Dm9000_cmd 0x04
The first is why the physical address of DM9000 is 0x18000000, because dm9000 's data and addr are connected to the Srom1 interface, and Srom1 's starting address is 0x18000000, here is the address for the peripheral.
The second is the CMD address why is 0x04, because the dm9000 cmd and the data to differentiate the pin connected in the srom1 addr[2], so the address of the CMD is 0x04, if you learn a few electricity this is very understood.
We begin our network-driven journey starting with the detection of the device.
2.1 Device Detection
In Network device detection, the hardware initialization of its various devices is different, but its nature is the same.
void Dm9000_probe (struct platform_device *pdev)
{
struct Net_device *ndev; It's the core.
Ndev = Alloc_etherdev (sizeof (struct private_data)); --The following parameters are actually Ndev's private data
Set_netdev_dev (Ndev, &pdev->dev); --#define SET_NETDEV_DEV (NET, Pdev) ((net)->dev.parent = (Pdev)) Set Ndev parent device to Pdev
Ether_setup (Ndev); --the core of the function is to initialize the members of the Ndev.
--The following is a set Ndev function member.
Ndev->open = &dm9000_open; --Device Open
Ndev->hard_start_xmit = &dm9000_start_xmit; --Start transfer
Ndev->tx_timeout = &dm9000_timeout; --timed overflow processing function
Ndev->watchdog_timeo = Msecs_to_jiffies (watchdog);
Ndev->stop = &dm9000_stop; --Close.
Ndev->set_multicast_list = &dm9000_hash_table; --Set the multicast address.
db->msg_enable = Netif_msg_link;
Db->mii.phy_id_mask = 0x1f; -This is the Mii interface
Db->mii.reg_num_mask = 0x1f;
Db->mii.force_media = 0;
Db->mii.full_duplex = 0;
Db->mii.dev = Ndev;
Db->mii.mdio_read = Dm9000_phy_read;
Db->mii.mdio_write = Dm9000_phy_write;
Platform_set_drvdata (Pdev, Ndev); --Set Ndev as the private function of Pdev and save it for later uninstallation
Register_netdev (Ndev); --Register Ndev
}
Probe in the operation of the Ndev is divided into three parts to open Ndev-and initialization Ndev-registration Ndev, there is no way to find out how this process is similar to other driving model. The core of this is Ndev.
2.2 Opening and releasing of network devices
In open, it is often to apply for interrupts, reset the hardware, and activate the device send queue, taking Dm9000_open as an example
static int Dm9000_open (struct net_device *dev)
{
if (Request_irq (DEV->IRQ, &dm9000_interrupt, Dm9000_irq_flags, Dev->name, Dev))--Request an interruption of resources
Return-eagain;
Mii_check_media (&db->mii, Netif_msg_link (db), 1); -The core of this is to detect the interface state of Mii
Netif_start_queue (Dev); --Activating the device send queue
return 0;
}
In close, the opposite is primarily the release of resources and the stop device send queue.
static int dm9000_stop (struct net_device *ndev)
{
board_info_t *db = (board_info_t *) ndev->priv;
Netif_stop_queue (Ndev);
Netif_carrier_off (Ndev);
FREE_IRQ (NDEV->IRQ, Ndev);
return 0;
}
2.3 Data transmission
The media that will be sent from the upper layer of incoming data.
static int dm9000_start_xmit (struct sk_buff *skb, struct net_device *dev)
{
unsigned long flags;
board_info_t *db = (board_info_t *) dev->priv;
if (db->tx_pkt_cnt > 1)-No more than 2 packages
return 1;
Spin_lock_irqsave (&db->lock, flags);
Writeb (Dm9000_mwcmd, db->io_addr);
(DB->OUTBLK) (Db->io_data, Skb->data, Skb->len);
Dev->stats.tx_bytes + = skb->len;
db->tx_pkt_cnt++;
if (db->tx_pkt_cnt = = 1) {
IOW (db, DM9000_TXPLL, Skb->len & 0xff);
IOW (DB, Dm9000_txplh, (Skb->len >> 8) & 0xff);
IOW (db, DM9000_TCR, tcr_txreq);
Dev->trans_start = jiffies; --Save time stamp
} else {
Db->queue_pkt_len = skb->len;
Netif_stop_queue (Dev);
}
Spin_unlock_irqrestore (&db->lock, flags);
DEV_KFREE_SKB (SKB);
return 0;
}
2.4 Interrupt Handling
An interrupt is generated for media each time a transfer or send completes a frame of data, depending on the break flags to determine whether the send is completed or accepted.
static irqreturn_t dm9000_interrupt (int irq, void *dev_id)
{
if (Int_status & ISR_PRS)-accepts data interrupts.
Dm9000_rx (Dev);
if (Int_status & isr_pts)
Dm9000_tx_done (dev, db);
}
static void Dm9000_tx_done (struct net_device *dev, board_info_t * db)
{
Netif_wake_queue (Dev); --wake-up waiting queue
}
2.5 Data Acceptance
For data acceptance, the data is actually read from the media buffer and then submitted to the upper layer. The real core of reading data is the following code
static void Dm9000_rx (struct net_device *dev)
{
SKB = DEV_ALLOC_SKB (Rxlen + 4)); --Assigning a SKB
Skb_reserve (SKB, 2); --keep 22 bytes
Rdptr = (U8 *) skb_put (SKB, RxLen-4); --Hardware Read data
(DB->INBLK) (Db->io_data, Rdptr, Rxlen);
Dev->stats.rx_bytes + = Rxlen;
Skb->protocol = Eth_type_trans (SKB, Dev); --Get the type of the book agreement
Netif_rx (SKB); --Submit a packet to the upper layer
dev->stats.rx_packets++;
}
2.6 A timer is set in the drive
The function of this timer is to check the status of Mii regularly.
Three. Summary
The core of network drive is Ndev and SKB, need to understand well.
This time the network-driven learning is very rough, because the network drive is a big part of the need to slowly chew each one of the points. The future is bright, but the road is tortuous.
Linux Network device drivers