error_t ksz8851SendPacket(NetInterface *interface,
   const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
{
   size_t n;
   size_t length;
   Ksz8851TxHeader header;
   Ksz8851Context *context;

   //Point to the driver context
   context = (Ksz8851Context *) interface->nicContext;

   //Retrieve the length of the packet
   length = netBufferGetLength(buffer) - offset;

   //Check the frame length
   if(length > ETH_MAX_FRAME_SIZE)
   {
      //The transmitter can accept another packet
      osSetEvent(&interface->nicTxEvent);
      //Report an error
      return ERROR_INVALID_LENGTH;
   }

   //Get the amount of free memory available in the TX FIFO
   n = ksz8851ReadReg(interface, KSZ8851_TXMIR) & KSZ8851_TXMIR_TXMA;

   //Make sure the TX FIFO is available for writing
   if(n < (length + 8))
   {
      return ERROR_FAILURE;
   }

   //Copy user data
   netBufferRead(context->txBuffer, buffer, offset, length);

   //Format control word
   header.controlWord = htole16(KSZ8851_TX_CTRL_TXIC |
      (context->frameId++ & KSZ8851_TX_CTRL_TXFID));

   //Total number of bytes to be transmitted
   header.byteCount = htole16(length);

   //Enable TXQ write access
   ksz8851SetBit(interface, KSZ8851_RXQCR, KSZ8851_RXQCR_SDA);
   //Write TX packet header
   ksz8851WriteFifo(interface, (uint8_t *) &header, sizeof(Ksz8851TxHeader));
   //Write data
   ksz8851WriteFifo(interface, context->txBuffer, length);
   //End TXQ write access
   ksz8851ClearBit(interface, KSZ8851_RXQCR, KSZ8851_RXQCR_SDA);

   //Start transmission
   ksz8851SetBit(interface, KSZ8851_TXQCR, KSZ8851_TXQCR_METFE);

   //Get the amount of free memory available in the TX FIFO
   n = ksz8851ReadReg(interface, KSZ8851_TXMIR) & KSZ8851_TXMIR_TXMA;

   //Check whether the TX FIFO is available for writing
   if(n >= (ETH_MAX_FRAME_SIZE + 8))
   {
      //The transmitter can accept another packet
      osSetEvent(&interface->nicTxEvent);
   }

   //Successful processing
   return NO_ERROR;
}
error_t ksz8851SendPacket(NetInterface *interface,
   const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
{
   size_t n;
   size_t length;
   Ksz8851TxHeader header;
   Ksz8851Context *context;

    
   context = (Ksz8851Context *) interface->nicContext;

    
   length = netBufferGetLength(buffer) - offset;

    
   if(length > ETH_MAX_FRAME_SIZE)
   {
       
      osSetEvent(&interface->nicTxEvent);
       
      return ERROR_INVALID_LENGTH;
   }

    
   n = ksz8851ReadReg(interface, KSZ8851_TXMIR) & KSZ8851_TXMIR_TXMA;

    
   if(n < (length + 8))
   {
      return ERROR_FAILURE;
   }

    
   netBufferRead(context->txBuffer, buffer, offset, length);

    
   header.controlWord = htole16(KSZ8851_TX_CTRL_TXIC |
      (context->frameId++ & KSZ8851_TX_CTRL_TXFID));

    
   header.byteCount = htole16(length);

    
   ksz8851SetBit(interface, KSZ8851_RXQCR, KSZ8851_RXQCR_SDA);
    
   ksz8851WriteFifo(interface, (uint8_t *) &header, sizeof(Ksz8851TxHeader));
    
   ksz8851WriteFifo(interface, context->txBuffer, length);
    
   ksz8851ClearBit(interface, KSZ8851_RXQCR, KSZ8851_RXQCR_SDA);

    
   ksz8851SetBit(interface, KSZ8851_TXQCR, KSZ8851_TXQCR_METFE);

    
   n = ksz8851ReadReg(interface, KSZ8851_TXMIR) & KSZ8851_TXMIR_TXMA;

    
   if(n >= (ETH_MAX_FRAME_SIZE + 8))
   {
       
      osSetEvent(&interface->nicTxEvent);
   }

    
   return NO_ERROR;
}