示例#1
0
文件: ibmlana.c 项目: xricson/knoppix
static void irqtxerr_handler(struct net_device *dev)
{
	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
	tda_t tda;

	/* fetch descriptor to check status */
	isa_memcpy_fromio(&tda, dev->mem_start + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));

	/* update statistics */
	priv->stat.tx_errors++;
	if (tda.status & (TCREG_NCRS | TCREG_CRSL))
		priv->stat.tx_carrier_errors++;
	if (tda.status & TCREG_EXC)
		priv->stat.tx_aborted_errors++;
	if (tda.status & TCREG_OWC)
		priv->stat.tx_window_errors++;
	if (tda.status & TCREG_FU)
		priv->stat.tx_fifo_errors++;

	/* update our pointers */
	priv->txused[priv->currtxdescr] = 0;
	priv->txusedcnt--;

	/* if there are more descriptors present in RAM, start them */
	if (priv->txusedcnt > 0)
		StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT);

	/* tell the upper layer we can go on transmitting */
	netif_wake_queue(dev);
}
// Transmit full frame
int SerialIntrf::Tx(int DevAddr, uint8_t *pData, int DataLen)
{
    int count = 0;

    if (pData && StartTx(DevAddr))
    {
        count = TxData(pData, DataLen);
        StopTx();
    }

    return count;
}
示例#3
0
static void irqtxerr_handler(struct IBMLANA_NETDEV *dev)
{
	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
	tda_t tda;

	/* fetch descriptor to check status */

	IBMLANA_FROMIO(&tda,
		       dev->mem_start + priv->tdastart +
		       (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));

	/* update statistics */

	priv->stat.tx_errors++;
	if (tda.status & (TCREG_NCRS | TCREG_CRSL))
		priv->stat.tx_carrier_errors++;
	if (tda.status & TCREG_EXC)
		priv->stat.tx_aborted_errors++;
	if (tda.status & TCREG_OWC)
		priv->stat.tx_window_errors++;
	if (tda.status & TCREG_FU)
		priv->stat.tx_fifo_errors++;

	/* update our pointers */

	priv->txused[priv->currtxdescr] = 0;
	priv->txusedcnt--;

	/* if there are more descriptors present in RAM, start them */

	if (priv->txusedcnt > 0)
		StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT);

	/* tell the upper layer we can go on transmitting */

#if LINUX_VERSION_CODE >= 0x02032a
	netif_wake_queue(dev);
#else
	dev->tbusy = 0;
	mark_bh(NET_BH);
#endif
}
示例#4
0
/* ------------------------------------------------------------------------- */
static int TxMessage(TServant *const servant, const ezxml_t message)
{
    char* str;
    size_t len;
    TTxControl *const ctrl = &servant->m_tx;

    str = ezxml_toxml(message, false);
    if (!str)
        return -EXIT_FAILURE;
    len = strlen(str);
#if 1 /* workaround - it inserts the header */
    {
        char* tmp;

        tmp = malloc(len + MESSAGE_HEADER_LEN);
        if (!tmp)
        {
            free(str);
            return -EXIT_FAILURE;
        }
        memcpy(&tmp[MESSAGE_HEADER_LEN], str, len);
        free(str);

        tmp[0] = (len & 0xFF00) >> 8;
        tmp[1] = len & 0x00FF;

        str = tmp;
        len += MESSAGE_HEADER_LEN;
    }
#endif

    IoBuffer_Free(&ctrl->m_buffer);
    IoBuffer_TakeOwnership(&ctrl->m_buffer, str, len);
    ctrl->m_n_to_send = len;
    if (StartTx(servant))
        return -EXIT_FAILURE;

    return -EXIT_SUCCESS;
}
示例#5
0
文件: ibmlana.c 项目: xricson/knoppix
static void irqtx_handler(struct net_device *dev)
{
	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
	tda_t tda;

	/* fetch descriptor (we forgot the size ;-) */
	isa_memcpy_fromio(&tda, dev->mem_start + priv->tdastart + (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));

	/* update statistics */
	priv->stat.tx_packets++;
	priv->stat.tx_bytes += tda.length;

	/* update our pointers */
	priv->txused[priv->currtxdescr] = 0;
	priv->txusedcnt--;

	/* if there are more descriptors present in RAM, start them */
	if (priv->txusedcnt > 0)
		StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT);

	/* tell the upper layer we can go on transmitting */
	netif_wake_queue(dev);
}
示例#6
0
static void irqtx_handler(struct IBMLANA_NETDEV *dev)
{
	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
	tda_t tda;

	/* fetch descriptor (we forgot the size ;-) */

	IBMLANA_FROMIO(&tda,
		       dev->mem_start + priv->tdastart +
		       (priv->currtxdescr * sizeof(tda_t)), sizeof(tda_t));

	/* update statistics */

	priv->stat.tx_packets++;
#if (LINUX_VERSION_CODE >= 0x020119)
	priv->stat.tx_bytes += tda.length;
#endif

	/* update our pointers */

	priv->txused[priv->currtxdescr] = 0;
	priv->txusedcnt--;

	/* if there are more descriptors present in RAM, start them */

	if (priv->txusedcnt > 0)
		StartTx(dev, (priv->currtxdescr + 1) % TXBUFCNT);

	/* tell the upper layer we can go on transmitting */

#if LINUX_VERSION_CODE >= 0x02032a
	netif_wake_queue(dev);
#else
	dev->tbusy = 0;
	mark_bh(NET_BH);
#endif
}
示例#7
0
/*
 *  UEFI Reset () function
 *
 */
EFI_STATUS
EFIAPI
SnpReset (
  IN        EFI_SIMPLE_NETWORK_PROTOCOL* Snp,
  IN        BOOLEAN Verification
  )
{
  UINT32     PmConf;
  UINT32     HwConf;
  UINT32     ResetFlags;
  EFI_STATUS Status;

  PmConf = 0;
  HwConf = 0;
  ResetFlags = 0;

  // Check Snp Instance
  if (Snp == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  // First check that driver has not already been initialized
  if (Snp->Mode->State == EfiSimpleNetworkStarted) {
    DEBUG ((EFI_D_WARN, "Warning: LAN9118 Driver not yet initialized\n"));
    return EFI_DEVICE_ERROR;
  } else if (Snp->Mode->State == EfiSimpleNetworkStopped) {
    DEBUG ((EFI_D_WARN, "Warning: LAN9118 Driver not started\n"));
    return EFI_NOT_STARTED;
  }

  // Initiate a PHY reset
  Status = PhySoftReset (PHY_RESET_PMT, Snp);
  if (EFI_ERROR (Status)) {
    Snp->Mode->State = EfiSimpleNetworkStopped;
    return EFI_NOT_STARTED;
  }

  // Initiate a software reset
  ResetFlags |= SOFT_RESET_CHECK_MAC_ADDR_LOAD | SOFT_RESET_CLEAR_INT;

  if (Verification) {
    ResetFlags |= SOFT_RESET_SELF_TEST;
  }

  Status = SoftReset (ResetFlags, Snp);
  if (EFI_ERROR (Status)) {
    DEBUG ((EFI_D_WARN, "Warning: Soft Reset Failed: Hardware Error\n"));
    return EFI_DEVICE_ERROR;
  }

  // Read the PM register
  PmConf = MmioRead32 (LAN9118_PMT_CTRL);

  // MPTCTRL_WOL_EN: Allow Wake-On-Lan to detect wake up frames or magic packets
  // MPTCTRL_ED_EN:  Allow energy detection to allow lowest power consumption mode
  // MPTCTRL_PME_EN: Allow Power Management Events
  PmConf |= (MPTCTRL_WOL_EN | MPTCTRL_ED_EN | MPTCTRL_PME_EN);

  // Write the current configuration to the register
  MmioWrite32 (LAN9118_PMT_CTRL, PmConf);
  gBS->Stall (LAN9118_STALL);

  // Check that a buffer size was specified in SnpInitialize
  if (gTxBuffer != 0) {
    HwConf = MmioRead32 (LAN9118_HW_CFG);        // Read the HW register
    HwConf &= ~HW_CFG_TX_FIFO_SIZE_MASK;         // Clear buffer bits first
    HwConf |= HW_CFG_TX_FIFO_SIZE(gTxBuffer);    // assign size chosen in SnpInitialize

    MmioWrite32 (LAN9118_HW_CFG, HwConf);        // Write the conf
    gBS->Stall (LAN9118_STALL);
  }

  // Enable the receiver and transmitter and clear their contents
  StartRx (START_RX_CLEAR, Snp);
  StartTx (START_TX_MAC | START_TX_CFG | START_TX_CLEAR, Snp);

  // Now acknowledge all interrupts
  MmioWrite32 (LAN9118_INT_STS, ~0);

  return EFI_SUCCESS;
}
示例#8
0
/*
 *  UEFI Initialize() function
 *
 */
EFI_STATUS
EFIAPI
SnpInitialize (
  IN        EFI_SIMPLE_NETWORK_PROTOCOL* Snp,
  IN        UINTN                        RxBufferSize    OPTIONAL,
  IN        UINTN                        TxBufferSize    OPTIONAL
  )
{
  EFI_STATUS Status;
  UINT32     PmConf;
  INT32      AllocResult;
  UINT32     RxStatusSize;
  UINT32     TxStatusSize;

  // Initialize variables
  // Global variables to hold tx and rx FIFO allocation
  gTxBuffer = 0;

  // Check Snp Instance
  if (Snp == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  // First check that driver has not already been initialized
  if (Snp->Mode->State == EfiSimpleNetworkInitialized) {
    DEBUG ((EFI_D_WARN, "LAN9118 Driver already initialized\n"));
    return EFI_SUCCESS;
  } else
  if (Snp->Mode->State == EfiSimpleNetworkStopped) {
    DEBUG ((EFI_D_WARN, "LAN9118 Driver not started\n"));
    return EFI_NOT_STARTED;
  }

  // Initiate a PHY reset
  Status = PhySoftReset (PHY_RESET_PMT, Snp);
  if (EFI_ERROR (Status)) {
    Snp->Mode->State = EfiSimpleNetworkStopped;
    DEBUG ((EFI_D_WARN, "Warning: Link not ready after TimeOut. Check ethernet cable\n"));
    return EFI_NOT_STARTED;
  }

  // Initiate a software reset
  Status = SoftReset (0, Snp);
  if (EFI_ERROR(Status)) {
    DEBUG ((EFI_D_WARN, "Soft Reset Failed: Hardware Error\n"));
    return EFI_DEVICE_ERROR;
  }

  // Read the PM register
  PmConf = MmioRead32 (LAN9118_PMT_CTRL);

  // MPTCTRL_WOL_EN: Allow Wake-On-Lan to detect wake up frames or magic packets
  // MPTCTRL_ED_EN:  Allow energy detection to allow lowest power consumption mode
  // MPTCTRL_PME_EN: Allow Power Management Events
  PmConf = 0;
  PmConf |= (MPTCTRL_WOL_EN | MPTCTRL_ED_EN | MPTCTRL_PME_EN);

  // Write the current configuration to the register
  MmioWrite32 (LAN9118_PMT_CTRL, PmConf);
  gBS->Stall (LAN9118_STALL);
  gBS->Stall (LAN9118_STALL);

  // Configure GPIO and HW
  Status = ConfigureHardware (HW_CONF_USE_LEDS, Snp);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  // Assign the transmitter buffer size (default values)
  TxStatusSize = LAN9118_TX_STATUS_SIZE;
  RxStatusSize = LAN9118_RX_STATUS_SIZE;

  // Check that a buff size was specified
  if (TxBufferSize > 0) {
    if (RxBufferSize == 0) {
      RxBufferSize = LAN9118_RX_DATA_SIZE;
    }

    AllocResult = ChangeFifoAllocation (
                          ALLOC_USE_FIFOS,
                          &TxBufferSize,
                          &RxBufferSize,
                          &TxStatusSize,
                          &RxStatusSize,
                          Snp
                          );

    if (AllocResult < 0) {
      return EFI_OUT_OF_RESOURCES;
    }
  }

  // Do auto-negotiation if supported
  Status = AutoNegotiate (AUTO_NEGOTIATE_ADVERTISE_ALL, Snp);
  if (EFI_ERROR(Status)) {
    DEBUG ((EFI_D_WARN, "Lan9118: Auto Negociation not supported.\n"));
  }

  // Configure flow control depending on speed capabilities
  Status = ConfigureFlow (0, 0, 0, 0, Snp);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  // Enable the transmitter
  Status = StartTx (START_TX_MAC | START_TX_CFG, Snp);
  if (EFI_ERROR(Status)) {
    return Status;
  }

  // Now acknowledge all interrupts
  MmioWrite32 (LAN9118_INT_STS, ~0);

  // Declare the driver as initialized
  Snp->Mode->State = EfiSimpleNetworkInitialized;

  return Status;
}
示例#9
0
文件: ibmlana.c 项目: xricson/knoppix
static int ibmlana_tx(struct sk_buff *skb, struct net_device *dev)
{
	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
	int retval = 0, tmplen, addr;
	unsigned long flags;
	tda_t tda;
	int baddr;

	/* find out if there are free slots for a frame to transmit. If not,
	   the upper layer is in deep desperation and we simply ignore the frame. */

	if (priv->txusedcnt >= TXBUFCNT) {
		retval = -EIO;
		priv->stat.tx_dropped++;
		goto tx_done;
	}

	/* copy the frame data into the next free transmit buffer - fillup missing */
	tmplen = skb->len;
	if (tmplen < 60)
		tmplen = 60;
	baddr = priv->txbufstart + (priv->nexttxdescr * PKTSIZE);
	isa_memcpy_toio(dev->mem_start + baddr, skb->data, skb->len);

	/* copy filler into RAM - in case we're filling up... 
	   we're filling a bit more than necessary, but that doesn't harm
	   since the buffer is far larger... 
	   Sorry Linus for the filler string but I couldn't resist ;-) */

	if (tmplen > skb->len) {
		char *fill = "NetBSD is a nice OS too! ";
		unsigned int destoffs = skb->len, l = strlen(fill);

		while (destoffs < tmplen) {
			isa_memcpy_toio(dev->mem_start + baddr + destoffs, fill, l);
			destoffs += l;
		}
	}

	/* set up the new frame descriptor */
	addr = priv->tdastart + (priv->nexttxdescr * sizeof(tda_t));
	isa_memcpy_fromio(&tda, dev->mem_start + addr, sizeof(tda_t));
	tda.length = tda.fraglength = tmplen;
	isa_memcpy_toio(dev->mem_start + addr, &tda, sizeof(tda_t));

	/* if there were no active descriptors, trigger the SONIC */
	spin_lock_irqsave(&priv->lock, flags);

	priv->txusedcnt++;
	priv->txused[priv->nexttxdescr] = 1;

	/* are all transmission slots used up ? */
	if (priv->txusedcnt >= TXBUFCNT)
		netif_stop_queue(dev);

	if (priv->txusedcnt == 1)
		StartTx(dev, priv->nexttxdescr);
	priv->nexttxdescr = (priv->nexttxdescr + 1) % TXBUFCNT;

	spin_unlock_irqrestore(&priv->lock, flags);
tx_done:
	dev_kfree_skb(skb);
	return retval;
}
示例#10
0
static int ibmlana_tx(struct sk_buff *skb, struct IBMLANA_NETDEV *dev)
{
	ibmlana_priv *priv = (ibmlana_priv *) dev->priv;
	int retval = 0, tmplen, addr;
	unsigned long flags;
	tda_t tda;
	int baddr;

	/* if we get called with a NULL descriptor, the Ethernet layer thinks 
	   our card is stuck an we should reset it.  We'll do this completely: */

	if (skb == NULL) {
		printk("%s: Resetting SONIC\n", dev->name);
		StopSONIC(dev);
		InitBoard(dev);
		return 0;	/* don't try to free the block here ;-) */
	}

	/* find out if there are free slots for a frame to transmit. If not,
	   the upper layer is in deep desperation and we simply ignore the frame. */

	if (priv->txusedcnt >= TXBUFCNT) {
		retval = -EIO;
		priv->stat.tx_dropped++;
		goto tx_done;
	}

	/* copy the frame data into the next free transmit buffer - fillup missing */

	tmplen = skb->len;
	if (tmplen < 60)
		tmplen = 60;
	baddr = priv->txbufstart + (priv->nexttxdescr * PKTSIZE);
	IBMLANA_TOIO(dev->mem_start + baddr, skb->data, skb->len);

	/* copy filler into RAM - in case we're filling up... 
	   we're filling a bit more than necessary, but that doesn't harm
	   since the buffer is far larger... 
	   Sorry Linus for the filler string but I couldn't resist ;-) */

	if (tmplen > skb->len) {
		char *fill = "NetBSD is a nice OS too! ";
		unsigned int destoffs = skb->len, l = strlen(fill);

		while (destoffs < tmplen) {
			IBMLANA_TOIO(dev->mem_start + baddr + destoffs,
				     fill, l);
			destoffs += l;
		}
	}

	/* set up the new frame descriptor */

	addr = priv->tdastart + (priv->nexttxdescr * sizeof(tda_t));
	IBMLANA_FROMIO(&tda, dev->mem_start + addr, sizeof(tda_t));
	tda.length = tda.fraglength = tmplen;
	IBMLANA_TOIO(dev->mem_start + addr, &tda, sizeof(tda_t));

	/* if there were no active descriptors, trigger the SONIC */

	save_flags(flags);
	cli();

	priv->txusedcnt++;
	priv->txused[priv->nexttxdescr] = 1;

	/* are all transmission slots used up ? */

	if (priv->txusedcnt >= TXBUFCNT)
#if (LINUX_VERSION_CODE >= 0x02032a)
		netif_stop_queue(dev);
#else
		dev->tbusy = 1;
#endif

	if (priv->txusedcnt == 1)
		StartTx(dev, priv->nexttxdescr);
	priv->nexttxdescr = (priv->nexttxdescr + 1) % TXBUFCNT;

	restore_flags(flags);

      tx_done:

	/* When did that change exactly ? */

#if (LINUX_VERSION_CODE >= 0x20200)
	dev_kfree_skb(skb);
#else
	dev_kfree_skb(skb, FREE_WRITE);
#endif
	return retval;
}