code: func (e *endpoint) dispatchLoop(d stack.NetworkDispatcher) {
  	// Post initial set of buffers.
  	limit := e.rx.q.PostedBuffersLimit()
  	if l := uint64(len(e.rx.data)) / uint64(e.bufferSize); limit > l {
  		limit = l
  	}
  	for i := uint64(0); i < limit; i++ {
  		b := queue.RxBuffer{
  			Offset: i * uint64(e.bufferSize),
  			Size:   e.bufferSize,
  			ID:     i,
  		}
  		if !e.rx.q.PostBuffers([]queue.RxBuffer{b}) {
  			log.Printf("Unable to post %v-th buffer", i)
  		}
  	}
  
  	// Read in a loop until a stop is requested.
  	var rxb []queue.RxBuffer
  	for atomic.LoadUint32(&e.stopRequested) == 0 {
  		var n uint32
  		rxb, n = e.rx.postAndReceive(rxb, &e.stopRequested)
  
  		// Copy data from the shared area to its own buffer, then
  		// prepare to repost the buffer.
  		b := make([]byte, n)
  		offset := uint32(0)
  		for i := range rxb {
  			copy(b[offset:], e.rx.data[rxb[i].Offset:][:rxb[i].Size])
  			offset += rxb[i].Size
  
  			rxb[i].Size = e.bufferSize
  		}
  
  		if n < header.EthernetMinimumSize {
  			continue
  		}
  
  		// Send packet up the stack.
  		eth := header.Ethernet(b)
  		d.DeliverNetworkPacket(e, eth.SourceAddress(), eth.DestinationAddress(), eth.Type(), buffer.View(b[header.EthernetMinimumSize:]).ToVectorisedView())
  	}
  
  	// Clean state.
  	e.tx.cleanup()
  	e.rx.cleanup()
  
  	e.completed.Done()
  }
docs: // dispatchLoop reads packets from the rx queue in a loop and dispatches them
  // to the network stack.