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; }
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 }
/* ------------------------------------------------------------------------- */ 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; }
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); }
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 }
/* * 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; }
/* * 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; }
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; }
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; }