/** * e1000_configure_rx - Configure 8254x Receive Unit after Reset * @adapter: board private structure * * Configure the Rx unit of the MAC after a reset. **/ static void e1000e_configure_rx ( struct e1000_adapter *adapter ) { struct e1000_hw *hw = &adapter->hw; uint32_t rctl; DBGP ( "e1000_configure_rx\n" ); /* disable receives while setting up the descriptors */ rctl = E1000_READ_REG ( hw, E1000_RCTL ); E1000_WRITE_REG ( hw, E1000_RCTL, rctl & ~E1000_RCTL_EN ); e1e_flush(); mdelay(10); adapter->rx_curr = 0; /* Setup the HW Rx Head and Tail Descriptor Pointers and * the Base and Length of the Rx Descriptor Ring */ E1000_WRITE_REG ( hw, E1000_RDBAL(0), virt_to_bus ( adapter->rx_base ) ); E1000_WRITE_REG ( hw, E1000_RDBAH(0), 0 ); E1000_WRITE_REG ( hw, E1000_RDLEN(0), adapter->rx_ring_size ); E1000_WRITE_REG ( hw, E1000_RDH(0), 0 ); E1000_WRITE_REG ( hw, E1000_RDT(0), NUM_RX_DESC - 1 ); /* Enable Receives */ rctl |= E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 | E1000_RCTL_MPE; E1000_WRITE_REG ( hw, E1000_RCTL, rctl ); e1e_flush(); DBG ( "E1000_RDBAL(0): %#08x\n", E1000_READ_REG ( hw, E1000_RDBAL(0) ) ); DBG ( "E1000_RDLEN(0): %d\n", E1000_READ_REG ( hw, E1000_RDLEN(0) ) ); DBG ( "E1000_RCTL: %#08x\n", E1000_READ_REG ( hw, E1000_RCTL ) ); }
/** * e1000e_irq_enable - Enable default interrupt generation settings **/ static void e1000e_irq_enable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; ew32(IMS, IMS_ENABLE_MASK); e1e_flush(); }
/** * e1000e_irq_disable - Mask off interrupt generation on the NIC **/ static void e1000e_irq_disable(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; ew32(IMC, ~0); e1e_flush(); }
/** * intelConfigureRx - Configure Receive Unit after Reset * @adapter: board private structure * * Configure the Rx unit of the MAC after a reset. **/ void IntelMausi::intelConfigureRx(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; u32 rctl, rxcsum, ctrl_ext; /* disable receives while setting up the descriptors */ rctl = intelReadMem32(E1000_RCTL); intelFlush(); usleep_range(10000, 20000); /* set the Receive Delay Timer Register */ intelWriteMem32(E1000_RDTR, adapter->rx_int_delay); /* irq moderation */ intelWriteMem32(E1000_RADV, adapter->rx_abs_int_delay); /* Set interrupt throttle value. */ intelWriteMem32(E1000_ITR, intrThrValue); /* Auto-Mask interrupts upon ICR access. */ ctrl_ext = intelReadMem32(E1000_CTRL_EXT); ctrl_ext |= E1000_CTRL_EXT_IAME; intelWriteMem32(E1000_IAM, 0xffffffff); intelWriteMem32(E1000_CTRL_EXT, ctrl_ext); e1e_flush(); /* Setup the HW Rx Head and Tail Descriptor Pointers and * the Base and Length of the Rx Descriptor Ring */ intelInitRxRing(); /* Enable Receive Checksum Offload for TCP and UDP */ rxcsum = intelReadMem32(E1000_RXCSUM); rxcsum |= E1000_RXCSUM_TUOFL; intelWriteMem32(E1000_RXCSUM, rxcsum); /* With jumbo frames, excessive C-state transition latencies result * in dropped transactions. */ if (mtu > ETH_DATA_LEN) { //u32 lat = ((intelReadMem32(E1000_PBA) & E1000_PBA_RXA_MASK) * 1024 - adapter->max_frame_size) * 8 / 1000; if (adapter->flags & FLAG_IS_ICH) { u32 rxdctl = intelReadMem32(E1000_RXDCTL(0)); intelWriteMem32(E1000_RXDCTL(0), rxdctl | 0x3); } //pm_qos_update_request(&adapter->netdev->pm_qos_req, lat); } else { //pm_qos_update_request(&adapter->netdev->pm_qos_req, PM_QOS_DEFAULT_VALUE); } intelWriteMem32(E1000_RCTL, rctl); }
/** * e1000_transmit - Transmit a packet * * @v netdev Network device * @v iobuf I/O buffer * * @ret rc Returns 0 on success, negative on failure */ static int e1000e_transmit ( struct net_device *netdev, struct io_buffer *iobuf ) { struct e1000_adapter *adapter = netdev_priv( netdev ); struct e1000_hw *hw = &adapter->hw; uint32_t tx_curr = adapter->tx_tail; struct e1000_tx_desc *tx_curr_desc; DBGP ("e1000_transmit\n"); if ( adapter->tx_fill_ctr == NUM_TX_DESC ) { DBG ("TX overflow\n"); return -ENOBUFS; } /* Save pointer to iobuf we have been given to transmit, netdev_tx_complete() will need it later */ adapter->tx_iobuf[tx_curr] = iobuf; tx_curr_desc = ( void * ) ( adapter->tx_base ) + ( tx_curr * sizeof ( *adapter->tx_base ) ); DBG ( "tx_curr_desc = %#08lx\n", virt_to_bus ( tx_curr_desc ) ); DBG ( "tx_curr_desc + 16 = %#08lx\n", virt_to_bus ( tx_curr_desc ) + 16 ); DBG ( "iobuf->data = %#08lx\n", virt_to_bus ( iobuf->data ) ); /* Add the packet to TX ring */ tx_curr_desc->buffer_addr = virt_to_bus ( iobuf->data ); tx_curr_desc->upper.data = 0; tx_curr_desc->lower.data = adapter->txd_cmd | iob_len ( iobuf ); DBG ( "TX fill: %d tx_curr: %d addr: %#08lx len: %zd\n", adapter->tx_fill_ctr, tx_curr, virt_to_bus ( iobuf->data ), iob_len ( iobuf ) ); /* Point to next free descriptor */ adapter->tx_tail = ( adapter->tx_tail + 1 ) % NUM_TX_DESC; adapter->tx_fill_ctr++; /* Write new tail to NIC, making packet available for transmit */ E1000_WRITE_REG ( hw, E1000_TDT(0), adapter->tx_tail ); e1e_flush(); return 0; }
/** * e1000_mng_write_cmd_header - Writes manageability command header * @hw: pointer to the HW structure * @hdr: pointer to the host interface command header * * Writes the command header after does the checksum calculation. **/ s32 e1000_mng_write_cmd_header(struct e1000_hw *hw, struct e1000_host_mng_command_header *hdr) { u16 i, length = sizeof(struct e1000_host_mng_command_header); /* Write the whole command header structure with new checksum. */ hdr->checksum = e1000_calculate_checksum((u8 *)hdr, length); length >>= 2; /* Write the relevant command block into the ram area. */ for (i = 0; i < length; i++) { E1000_WRITE_REG_ARRAY(hw, E1000_HOST_IF, i, *((u32 *)hdr + i)); e1e_flush(); } return 0; }
/** * e1000_close - Disables a network interface * * @v netdev network interface device structure * **/ static void e1000e_close ( struct net_device *netdev ) { struct e1000_adapter *adapter = netdev_priv ( netdev ); struct e1000_hw *hw = &adapter->hw; uint32_t rctl; uint32_t icr; DBGP ( "e1000_close\n" ); /* Acknowledge interrupts */ icr = E1000_READ_REG ( hw, E1000_ICR ); e1000e_irq_disable ( adapter ); /* disable receives */ rctl = E1000_READ_REG ( hw, E1000_RCTL ); E1000_WRITE_REG ( hw, E1000_RCTL, rctl & ~E1000_RCTL_EN ); e1e_flush(); e1000e_reset ( adapter ); e1000e_free_tx_resources ( adapter ); e1000e_free_rx_resources ( adapter ); }
static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data) { struct net_device *netdev = adapter->netdev; struct e1000_hw *hw = &adapter->hw; u32 mask; u32 shared_int = 1; u32 irq = adapter->pdev->irq; int i; int ret_val = 0; int int_mode = E1000E_INT_MODE_LEGACY; *data = 0; /* NOTE: we don't test MSI/MSI-X interrupts here, yet */ if (adapter->int_mode == E1000E_INT_MODE_MSIX) { int_mode = adapter->int_mode; e1000e_reset_interrupt_capability(adapter); adapter->int_mode = E1000E_INT_MODE_LEGACY; e1000e_set_interrupt_capability(adapter); } /* Hook up test interrupt handler just for this test */ if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name, netdev)) { shared_int = 0; } else if (request_irq(irq, e1000_test_intr, IRQF_SHARED, netdev->name, netdev)) { *data = 1; ret_val = -1; goto out; } e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared")); /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); e1e_flush(); usleep_range(10000, 20000); /* Test each interrupt */ for (i = 0; i < 10; i++) { /* Interrupt to test */ mask = 1 << i; if (adapter->flags & FLAG_IS_ICH) { switch (mask) { case E1000_ICR_RXSEQ: continue; case 0x00000100: if (adapter->hw.mac.type == e1000_ich8lan || adapter->hw.mac.type == e1000_ich9lan) continue; break; default: break; } } if (!shared_int) { /* * Disable the interrupt to be reported in * the cause register and then force the same * interrupt and see if one gets posted. If * an interrupt was posted to the bus, the * test failed. */ adapter->test_icr = 0; ew32(IMC, mask); ew32(ICS, mask); e1e_flush(); usleep_range(10000, 20000); if (adapter->test_icr & mask) { *data = 3; break; } } /* * Enable the interrupt to be reported in * the cause register and then force the same * interrupt and see if one gets posted. If * an interrupt was not posted to the bus, the * test failed. */ adapter->test_icr = 0; ew32(IMS, mask); ew32(ICS, mask); e1e_flush(); usleep_range(10000, 20000); if (!(adapter->test_icr & mask)) { *data = 4; break; } if (!shared_int) { /* * Disable the other interrupts to be reported in * the cause register and then force the other * interrupts and see if any get posted. If * an interrupt was posted to the bus, the * test failed. */ adapter->test_icr = 0; ew32(IMC, ~mask & 0x00007FFF); ew32(ICS, ~mask & 0x00007FFF); e1e_flush(); usleep_range(10000, 20000); if (adapter->test_icr) { *data = 5; break; } } } /* Disable all the interrupts */ ew32(IMC, 0xFFFFFFFF); e1e_flush(); usleep_range(10000, 20000); /* Unhook test interrupt handler */ free_irq(irq, netdev); out: if (int_mode == E1000E_INT_MODE_MSIX) { e1000e_reset_interrupt_capability(adapter); adapter->int_mode = int_mode; e1000e_set_interrupt_capability(adapter); } return ret_val; }
/** * e1000_configure_tx - Configure 8254x Transmit Unit after Reset * @adapter: board private structure * * Configure the Tx unit of the MAC after a reset. **/ static void e1000e_configure_tx ( struct e1000_adapter *adapter ) { struct e1000_hw *hw = &adapter->hw; u32 tctl, tipg, tarc; u32 ipgr1, ipgr2; DBGP ( "e1000_configure_tx\n" ); /* disable transmits while setting up the descriptors */ tctl = E1000_READ_REG ( hw, E1000_TCTL ); E1000_WRITE_REG ( hw, E1000_TCTL, tctl & ~E1000_TCTL_EN ); e1e_flush(); mdelay(10); E1000_WRITE_REG ( hw, E1000_TDBAH(0), 0 ); E1000_WRITE_REG ( hw, E1000_TDBAL(0), virt_to_bus ( adapter->tx_base ) ); E1000_WRITE_REG ( hw, E1000_TDLEN(0), adapter->tx_ring_size ); DBG ( "E1000_TDBAL(0): %#08x\n", E1000_READ_REG ( hw, E1000_TDBAL(0) ) ); DBG ( "E1000_TDLEN(0): %d\n", E1000_READ_REG ( hw, E1000_TDLEN(0) ) ); /* Setup the HW Tx Head and Tail descriptor pointers */ E1000_WRITE_REG ( hw, E1000_TDH(0), 0 ); E1000_WRITE_REG ( hw, E1000_TDT(0), 0 ); adapter->tx_head = 0; adapter->tx_tail = 0; adapter->tx_fill_ctr = 0; /* Set the default values for the Tx Inter Packet Gap timer */ tipg = DEFAULT_82543_TIPG_IPGT_COPPER; /* 8 */ ipgr1 = DEFAULT_82543_TIPG_IPGR1; /* 8 */ ipgr2 = DEFAULT_82543_TIPG_IPGR2; /* 6 */ if (adapter->flags & FLAG_TIPG_MEDIUM_FOR_80003ESLAN) ipgr2 = DEFAULT_80003ES2LAN_TIPG_IPGR2; /* 7 */ tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT; tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT; ew32(TIPG, tipg); /* Program the Transmit Control Register */ tctl = er32(TCTL); tctl &= ~E1000_TCTL_CT; tctl |= E1000_TCTL_PSP | E1000_TCTL_RTLC | (E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT); if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) { tarc = er32(TARC(0)); /* * set the speed mode bit, we'll clear it if we're not at * gigabit link later */ #define SPEED_MODE_BIT (1 << 21) tarc |= SPEED_MODE_BIT; ew32(TARC(0), tarc); } /* errata: program both queues to unweighted RR */ if (adapter->flags & FLAG_TARC_SET_BIT_ZERO) { tarc = er32(TARC(0)); tarc |= 1; ew32(TARC(0), tarc); tarc = er32(TARC(1)); tarc |= 1; ew32(TARC(1), tarc); } /* Setup Transmit Descriptor Settings for eop descriptor */ adapter->txd_cmd = E1000_TXD_CMD_EOP | E1000_TXD_CMD_IFCS; /* enable Report Status bit */ adapter->txd_cmd |= E1000_TXD_CMD_RS; /* * enable transmits in the hardware, need to do this * after setting TARC(0) */ tctl |= E1000_TCTL_EN; ew32(TCTL, tctl); e1e_flush(); e1000e_config_collision_dist(hw); }