{"id":639,"date":"2016-05-10T18:56:42","date_gmt":"2016-05-10T16:56:42","guid":{"rendered":"http:\/\/queen.run.montefiore.ulg.ac.be\/~barbette\/?p=639"},"modified":"2016-05-10T18:56:43","modified_gmt":"2016-05-10T16:56:43","slug":"a-word-about-mode-3","status":"publish","type":"post","link":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/","title":{"rendered":"A word about mode 3"},"content":{"rendered":"<p>First, you probably noted that it&#8217;s mostly a bonus, start the mode 3 code when everything else is finished.<\/p>\n<p>We already saw in the first slides how the rx_rings of the e1000 NIC work. Normally you also now the main receive function : e1000_clean_rx_irq.<\/p>\n<p>There is one struct\u00a0e1000_rx_ring per hardware RX ring. Normaly, there is only one ring (and you should only care about one for step 7).<\/p>\n<p>I think the fields are pretty well defined (for once&#8230;) :<\/p>\n<pre><a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L191\" name=\"L191\">191<\/a> struct <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=e1000_rx_ring\">e1000_rx_ring<\/a> {\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L192\" name=\"L192\">192<\/a>         <b><i>\/* pointer to the descriptor ring memory *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L193\" name=\"L193\">193<\/a>         void *<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=desc\">desc<\/a>;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L194\" name=\"L194\">194<\/a>         <b><i>\/* physical address of the descriptor ring *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L195\" name=\"L195\">195<\/a>         <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=dma_addr_t\">dma_addr_t<\/a> <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=dma\">dma<\/a>;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L196\" name=\"L196\">196<\/a>         <b><i>\/* length of descriptor ring in bytes *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L197\" name=\"L197\">197<\/a>         unsigned int <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=size\">size<\/a>;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L198\" name=\"L198\">198<\/a>         <b><i>\/* number of descriptors in the ring *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L199\" name=\"L199\">199<\/a>         unsigned int <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=count\">count<\/a>;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L200\" name=\"L200\">200<\/a>         <b><i>\/* next descriptor to associate a buffer with *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L201\" name=\"L201\">201<\/a>         unsigned int next_to_use;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L202\" name=\"L202\">202<\/a>         <b><i>\/* next descriptor to check for DD status bit *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L203\" name=\"L203\">203<\/a>         unsigned int next_to_clean;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L204\" name=\"L204\">204<\/a>         <b><i>\/* array of buffer information structs *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L205\" name=\"L205\">205<\/a>         struct <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=e1000_rx_buffer\">e1000_rx_buffer<\/a> *<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=buffer_info\">buffer_info<\/a>;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L206\" name=\"L206\">206<\/a>         struct <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=sk_buff\">sk_buff<\/a> *rx_skb_top;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L207\" name=\"L207\">207<\/a> \r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L208\" name=\"L208\">208<\/a>         <b><i>\/* cpu for rx queue *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L209\" name=\"L209\">209<\/a>         int <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=cpu\">cpu<\/a>;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L210\" name=\"L210\">210<\/a> \r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L211\" name=\"L211\">211<\/a>         <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=u16\">u16<\/a> rdh;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L212\" name=\"L212\">212<\/a>         <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=u16\">u16<\/a> rdt;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000.h?v=4.1#L213\" name=\"L213\">213<\/a> };<\/pre>\n<p>The desc is a pointer to the memory zone, containing the ring. This memory zone is accessible by the NIC itself through the dma address. The ring is a contiguous zone of e1000_rx_desc structures. Usually you access it with<\/p>\n<pre><a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=E1000_RX_DESC\">E1000_RX_DESC<\/a>(<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=R\">R<\/a>, <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=i\">i<\/a>)<\/pre>\n<p>where R is the ring pointer and i the index of the descriptor.<\/p>\n<p>One descriptor i composed of :<\/p>\n<pre><a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_hw.h?v=4.1#L522\" name=\"L522\">522<\/a> struct <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=e1000_rx_desc\">e1000_rx_desc<\/a> {\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_hw.h?v=4.1#L523\" name=\"L523\">523<\/a>         <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=__le64\">__le64<\/a> buffer_addr;     <b><i>\/* Address of the descriptor's data buffer *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_hw.h?v=4.1#L524\" name=\"L524\">524<\/a>         <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=__le16\">__le16<\/a> <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=length\">length<\/a>;          <b><i>\/* Length of data DMAed into data buffer *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_hw.h?v=4.1#L525\" name=\"L525\">525<\/a>         <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=__le16\">__le16<\/a> <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=csum\">csum<\/a>;            <b><i>\/* Packet checksum *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_hw.h?v=4.1#L526\" name=\"L526\">526<\/a>         <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=u8\">u8<\/a> <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=status\">status<\/a>;              <b><i>\/* Descriptor status *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_hw.h?v=4.1#L527\" name=\"L527\">527<\/a>         <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=u8\">u8<\/a> <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=errors\">errors<\/a>;              <b><i>\/* Descriptor Errors *\/<\/i><\/b>\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_hw.h?v=4.1#L528\" name=\"L528\">528<\/a>         <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=__le16\">__le16<\/a> <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=special\">special<\/a>;\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_hw.h?v=4.1#L529\" name=\"L529\">529<\/a> };<\/pre>\n<p>The buffer_addr variable is a pointer to the physical memory address where a packet can be received. The problem is that the Kernel normal put hte address of a skbuff-&gt;data there. But when a packet is received and its content is copied inside that buffer, how to get back the corresponding skbuff? This is why the e1000_rx_ring structure has also a buffer_info pointer. There is exactly as many buffer_info than e1000_rx_desc. \u00a0The buffer info contains all the software-only information that we need to keep about each descriptors, such as the skbuff which will receive the data pointed by buffer_addr.<\/p>\n<p>Before receiving any packets, all buffer_addr have to be setted ! Or the NIC wouldn&#8217;t know where to put the data. This is done in e1000_configure :<\/p>\n<pre><a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L407\" name=\"L407\">407<\/a>         for (<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=i\">i<\/a> = 0; <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=i\">i<\/a> &lt; <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=adapter\">adapter<\/a>-&gt;num_rx_queues; <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=i\">i<\/a>++) {\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L408\" name=\"L408\">408<\/a>                 struct <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=e1000_rx_ring\">e1000_rx_ring<\/a> *<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=ring\">ring<\/a> = &amp;<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=adapter\">adapter<\/a>-&gt;<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=rx_ring\">rx_ring<\/a>[<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=i\">i<\/a>];\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L409\" name=\"L409\">409<\/a>                 <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=adapter\">adapter<\/a>-&gt;alloc_rx_buf(<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=adapter\">adapter<\/a>, <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=ring\">ring<\/a>,\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L410\" name=\"L410\">410<\/a>                                       <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=E1000_DESC_UNUSED\">E1000_DESC_UNUSED<\/a>(<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=ring\">ring<\/a>));\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L411\" name=\"L411\">411<\/a>         }<\/pre>\n<p>alloc_rx_buf is a pointer to the function e1000_alloc_rx_buffers (if you don&#8217;t use jumbo frame, and you shouldn&#8217;t here). \u00a0We see that this functions is called for all rx rings.<\/p>\n<p>The function e1000_alloc_rx_buffers is defined at line 4561. \u00a0It calls &#8220;e1000_alloc_frag&#8221; for each buffers between rx_ring-&gt;next_to_use (initialized to 0) up to cleaned_count (in configure, the size of the ring is passed, so this is equivalent to a full reset).<\/p>\n<p>The memory obtained from e1000_alloc_frag is (probably) not accessible by hardware, so we have to map &#8220;DMA map&#8221; it :<\/p>\n<pre><a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L4613\" name=\"L4613\">4613<\/a>                 <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=buffer_info\">buffer_info<\/a>-&gt;<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=dma\">dma<\/a> = <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=dma_map_single\">dma_map_single<\/a>(&amp;<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=pdev\">pdev<\/a>-&gt;<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=dev\">dev<\/a>,\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L4614\" name=\"L4614\">4614<\/a>                                                   <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=data\">data<\/a>,\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L4615\" name=\"L4615\">4615<\/a>                                                   <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=adapter\">adapter<\/a>-&gt;rx_buffer_len,\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L4616\" name=\"L4616\">4616<\/a>                                                   DMA_FROM_DEVICE);<\/pre>\n<p><strong>You will have to do this with your fastnet buffers !<\/strong><\/p>\n<p>Then the result in dma is putted inside buffer_addr (line 4650).<\/p>\n<p>When some packet are received, e1000_clean_rx_irq will make skbuff out of them, and we&#8217;ll need to allocate new buffers and put pointers to them inside the ring so next packet can be received. This is done at the end of e1000_clean_rx_irq :<\/p>\n<pre><a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L4481\" name=\"L4481\">4481<\/a>         cleaned_count = <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=E1000_DESC_UNUSED\">E1000_DESC_UNUSED<\/a>(<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=rx_ring\">rx_ring<\/a>);\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L4482\" name=\"L4482\">4482<\/a>         if (cleaned_count)\r\n<a href=\"http:\/\/lxr.free-electrons.com\/source\/drivers\/net\/ethernet\/intel\/e1000\/e1000_main.c?v=4.1#L4483\" name=\"L4483\">4483<\/a>                 <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=adapter\">adapter<\/a>-&gt;alloc_rx_buf(<a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=adapter\">adapter<\/a>, <a href=\"http:\/\/lxr.free-electrons.com\/ident?v=4.1;i=rx_ring\">rx_ring<\/a>, cleaned_count);<\/pre>\n<p>So when the device goes in mode 3 you have to :<\/p>\n<ul>\n<li style=\"text-align: justify;\">Change the adapter-&gt;alloc_rx_buf function per your new one which will\u00a0set buffer_addr to dma mapped fastnet buffers.<\/li>\n<li>Do a full pass of a new alloc_rx_buf\u00a0to replace all current skb buffers by fastnet buffers\u00a0so all new packets will be received directly in the fastnet zone.<\/li>\n<\/ul>\n<p>When a packet is received :<\/p>\n<ul>\n<li>In fastnet mode 3, do not call any skb related function in clean_rx_irq : from line 4385 to 4401 which creates the skb, line 4424, line 4438, and 4453 to 4463.<\/li>\n<li>Instead of line 4464 calling the kernel receive path, do the copy of the packet length to the fastnet buffer descriptor. Note that as for skb in buffer_info, you will need to keep a pointer to the related fastnet descriptor. There is no need to call the kernel receive path anymore : the whole purpose of mode 3 is to directly receive the packet in userspace. Just set the length so the user knows there is a packet available inside the corresponding buffer !<\/li>\n<\/ul>\n<p>What I want with a &#8220;generic way&#8221; is that the least possible code has to be written inside e1000, so do not implement any fastnet descriptor related code in e1000 : create a function in fastnet.c to get the next fastnet buffer that you will map, and use net_dev_ops or adapter-&gt; functions so that fastnet ioctl can call a generic function like dev-&gt;ops-&gt;set_in_fastnet_zc_mode that any driver may or may not implement.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>First, you probably noted that it&#8217;s mostly a bonus, start the mode 3 code when everything else is finished. We already saw in the first slides how the rx_rings of the e1000 NIC work. Normally you also now the main receive function : e1000_clean_rx_irq. There is one struct\u00a0e1000_rx_ring per hardware RX ring. Normaly, there is &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;A word about mode 3&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[76],"tags":[],"class_list":["post-639","post","type-post","status-publish","format-standard","hentry","category-os2016"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>A word about mode 3 - Tom Barbette<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"A word about mode 3 - Tom Barbette\" \/>\n<meta property=\"og:description\" content=\"First, you probably noted that it&#8217;s mostly a bonus, start the mode 3 code when everything else is finished. We already saw in the first slides how the rx_rings of the e1000 NIC work. Normally you also now the main receive function : e1000_clean_rx_irq. There is one struct\u00a0e1000_rx_ring per hardware RX ring. Normaly, there is &hellip; Continue reading &quot;A word about mode 3&quot;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/\" \/>\n<meta property=\"og:site_name\" content=\"Tom Barbette\" \/>\n<meta property=\"article:published_time\" content=\"2016-05-10T16:56:42+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2016-05-10T16:56:43+00:00\" \/>\n<meta name=\"author\" content=\"Tom Barbette\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@TomBarbette\" \/>\n<meta name=\"twitter:site\" content=\"@TomBarbette\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Tom Barbette\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/a-word-about-mode-3\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/a-word-about-mode-3\\\/\"},\"author\":{\"name\":\"Tom Barbette\",\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/#\\\/schema\\\/person\\\/7f791766092e1207bc7a94a65e74f4fd\"},\"headline\":\"A word about mode 3\",\"datePublished\":\"2016-05-10T16:56:42+00:00\",\"dateModified\":\"2016-05-10T16:56:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/a-word-about-mode-3\\\/\"},\"wordCount\":714,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/#organization\"},\"articleSection\":[\"INFO-0940 Operating Systems \u2013 2015-2016 Specific posts\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/a-word-about-mode-3\\\/\",\"url\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/a-word-about-mode-3\\\/\",\"name\":\"A word about mode 3 - Tom Barbette\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/#website\"},\"datePublished\":\"2016-05-10T16:56:42+00:00\",\"dateModified\":\"2016-05-10T16:56:43+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/a-word-about-mode-3\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/a-word-about-mode-3\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/a-word-about-mode-3\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"A word about mode 3\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/#website\",\"url\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/\",\"name\":\"Tom Barbette\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/#organization\",\"name\":\"Efficiency of Networked Systems Group\",\"url\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/cropped-logo-uclouvain-2021-barbette.png\",\"contentUrl\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/wp-content\\\/uploads\\\/2022\\\/04\\\/cropped-logo-uclouvain-2021-barbette.png\",\"width\":512,\"height\":512,\"caption\":\"Efficiency of Networked Systems Group\"},\"image\":{\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/TomBarbette\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/tom-barbette\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/#\\\/schema\\\/person\\\/7f791766092e1207bc7a94a65e74f4fd\",\"name\":\"Tom Barbette\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/aecd99cba3b4d91d3775fde3219bfa362cd99acfbe95848ec303b9685f366fcd?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/aecd99cba3b4d91d3775fde3219bfa362cd99acfbe95848ec303b9685f366fcd?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/aecd99cba3b4d91d3775fde3219bfa362cd99acfbe95848ec303b9685f366fcd?s=96&r=g\",\"caption\":\"Tom Barbette\"},\"sameAs\":[\"https:\\\/\\\/www.tombarbette.be\"],\"url\":\"https:\\\/\\\/perso.uclouvain.be\\\/tom.barbette\\\/author\\\/tom\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"A word about mode 3 - Tom Barbette","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/","og_locale":"en_US","og_type":"article","og_title":"A word about mode 3 - Tom Barbette","og_description":"First, you probably noted that it&#8217;s mostly a bonus, start the mode 3 code when everything else is finished. We already saw in the first slides how the rx_rings of the e1000 NIC work. Normally you also now the main receive function : e1000_clean_rx_irq. There is one struct\u00a0e1000_rx_ring per hardware RX ring. Normaly, there is &hellip; Continue reading \"A word about mode 3\"","og_url":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/","og_site_name":"Tom Barbette","article_published_time":"2016-05-10T16:56:42+00:00","article_modified_time":"2016-05-10T16:56:43+00:00","author":"Tom Barbette","twitter_card":"summary_large_image","twitter_creator":"@TomBarbette","twitter_site":"@TomBarbette","twitter_misc":{"Written by":"Tom Barbette","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/#article","isPartOf":{"@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/"},"author":{"name":"Tom Barbette","@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/#\/schema\/person\/7f791766092e1207bc7a94a65e74f4fd"},"headline":"A word about mode 3","datePublished":"2016-05-10T16:56:42+00:00","dateModified":"2016-05-10T16:56:43+00:00","mainEntityOfPage":{"@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/"},"wordCount":714,"commentCount":0,"publisher":{"@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/#organization"},"articleSection":["INFO-0940 Operating Systems \u2013 2015-2016 Specific posts"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/","url":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/","name":"A word about mode 3 - Tom Barbette","isPartOf":{"@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/#website"},"datePublished":"2016-05-10T16:56:42+00:00","dateModified":"2016-05-10T16:56:43+00:00","breadcrumb":{"@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/a-word-about-mode-3\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/perso.uclouvain.be\/tom.barbette\/"},{"@type":"ListItem","position":2,"name":"A word about mode 3"}]},{"@type":"WebSite","@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/#website","url":"https:\/\/perso.uclouvain.be\/tom.barbette\/","name":"Tom Barbette","description":"","publisher":{"@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/perso.uclouvain.be\/tom.barbette\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/#organization","name":"Efficiency of Networked Systems Group","url":"https:\/\/perso.uclouvain.be\/tom.barbette\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/#\/schema\/logo\/image\/","url":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-content\/uploads\/2022\/04\/cropped-logo-uclouvain-2021-barbette.png","contentUrl":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-content\/uploads\/2022\/04\/cropped-logo-uclouvain-2021-barbette.png","width":512,"height":512,"caption":"Efficiency of Networked Systems Group"},"image":{"@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/TomBarbette","https:\/\/www.linkedin.com\/in\/tom-barbette"]},{"@type":"Person","@id":"https:\/\/perso.uclouvain.be\/tom.barbette\/#\/schema\/person\/7f791766092e1207bc7a94a65e74f4fd","name":"Tom Barbette","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/aecd99cba3b4d91d3775fde3219bfa362cd99acfbe95848ec303b9685f366fcd?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/aecd99cba3b4d91d3775fde3219bfa362cd99acfbe95848ec303b9685f366fcd?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/aecd99cba3b4d91d3775fde3219bfa362cd99acfbe95848ec303b9685f366fcd?s=96&r=g","caption":"Tom Barbette"},"sameAs":["https:\/\/www.tombarbette.be"],"url":"https:\/\/perso.uclouvain.be\/tom.barbette\/author\/tom\/"}]}},"_links":{"self":[{"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/posts\/639","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/comments?post=639"}],"version-history":[{"count":1,"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/posts\/639\/revisions"}],"predecessor-version":[{"id":640,"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/posts\/639\/revisions\/640"}],"wp:attachment":[{"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/media?parent=639"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/categories?post=639"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/perso.uclouvain.be\/tom.barbette\/wp-json\/wp\/v2\/tags?post=639"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}