/** *Multicast mode set * * The set_multi entry point is called whenever the multicast address * list or the network interface flags are updated. This routine is * responsible for configuring the hardware for proper multicast, * promiscuous mode, and all-multi behavior. **/ IOReturn AtherosL1Ethernet::setMulticastMode(bool enabled) { DbgPrint("setMulticastMode(), %d\n", enabled); at_hw *hw = &adapter_.hw; u32 rctl; /* Check for Promiscuous and All Multicast modes */ rctl = AT_READ_REG(hw, REG_MAC_CTRL); if(enabled){ rctl |= MAC_CTRL_MC_ALL_EN; rctl &= ~MAC_CTRL_PROMIS_EN; } else { rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN); } AT_WRITE_REG(hw, REG_MAC_CTRL, rctl); /* clear the old settings from the multicast hash table */ AT_WRITE_REG(hw, REG_RX_HASH_TABLE, 0); AT_WRITE_REG_ARRAY(hw, REG_RX_HASH_TABLE, 1, 0); return kIOReturnSuccess; }
IOReturn AttansicL2Ethernet::enable(IONetworkInterface *netif) { DbgPrint("enable()\n"); u32 val; at_adapter *adapter=&adapter_; if (!adapter->pdev || (!adapter->pdev->isOpen () && (adapter->pdev->open(this)) == 0)) { DbgPrint( "failed to open PCI device.\n"); return kIOReturnError; } // hardware init if (at_init_hw(&adapter->hw)) { ErrPrint("Couldn't init hw\n"); //stop(provider); return kIOReturnError; } // hardware has been reset, we need to reload some things init_ring_ptrs(adapter); at_configure(adapter); //PHY medium selection const IONetworkMedium *medium = getSelectedMedium(); if (!medium) { DbgPrint("Selected medium is NULL, forcing to autonegotiation\n"); medium = mediumTable[MEDIUM_INDEX_AUTO]; } else { DbgPrint("Selected medium index %d\n", medium->getIndex()); } selectMedium(medium); transmitQueue_->setCapacity(kTransmitQueueCapacity); transmitQueue_->start(); // Enable interrupts. val = AT_READ_REG(&adapter->hw, REG_MASTER_CTRL); AT_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, val|MASTER_CTRL_MANUAL_INT); at_irq_enable(adapter); return kIOReturnSuccess; }
void AtherosL1Ethernet::atGetAndUpdateLinkStatus() { at_adapter *adapter=&adapter_; struct at_hw *hw = &adapter->hw; u16 speed, duplex; u32 currentMediumIndex = MEDIUM_INDEX_AUTO; if(at_get_speed_and_duplex(hw, &speed, &duplex) == AT_SUCCESS) { DbgPrint("Link is active, speed %d, duplex %d\n", speed, duplex); if(speed == SPEED_10 && duplex == FULL_DUPLEX) currentMediumIndex = MEDIUM_INDEX_10FD; if(speed == SPEED_100 && duplex == FULL_DUPLEX) currentMediumIndex = MEDIUM_INDEX_100FD; if(speed == SPEED_1000 && duplex == FULL_DUPLEX) currentMediumIndex = MEDIUM_INDEX_1000FD; if(speed == SPEED_10 && duplex == HALF_DUPLEX) currentMediumIndex = MEDIUM_INDEX_10HD; if(speed == SPEED_100 && duplex == HALF_DUPLEX) currentMediumIndex = MEDIUM_INDEX_100HD; if(speed == SPEED_1000 && duplex == HALF_DUPLEX) currentMediumIndex = MEDIUM_INDEX_1000HD; setLinkStatus(kIONetworkLinkActive | kIONetworkLinkValid, mediumTable[currentMediumIndex], speed * MBit, NULL); adapter->link_speed = speed; adapter->link_duplex = duplex; at_setup_mac_ctrl(adapter); } else { DbgPrint("Link is down\n"); u32 value; //disable rx value = AT_READ_REG(hw, REG_MAC_CTRL); value &= ~MAC_CTRL_RX_EN; AT_WRITE_REG(hw, REG_MAC_CTRL, value); adapter->link_speed = SPEED_0; setLinkStatus(kIONetworkLinkValid, NULL, 0, NULL); } }
static void atl1e_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) { struct atl1e_adapter *adapter = netdev_priv(netdev); struct atl1e_hw *hw = &adapter->hw; u32 *regs_buff = p; u16 phy_data; memset(p, 0, AT_REGS_LEN * sizeof(u32)); regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id; regs_buff[0] = AT_READ_REG(hw, REG_VPD_CAP); regs_buff[1] = AT_READ_REG(hw, REG_SPI_FLASH_CTRL); regs_buff[2] = AT_READ_REG(hw, REG_SPI_FLASH_CONFIG); regs_buff[3] = AT_READ_REG(hw, REG_TWSI_CTRL); regs_buff[4] = AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL); regs_buff[5] = AT_READ_REG(hw, REG_MASTER_CTRL); regs_buff[6] = AT_READ_REG(hw, REG_MANUAL_TIMER_INIT); regs_buff[7] = AT_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT); regs_buff[8] = AT_READ_REG(hw, REG_GPHY_CTRL); regs_buff[9] = AT_READ_REG(hw, REG_CMBDISDMA_TIMER); regs_buff[10] = AT_READ_REG(hw, REG_IDLE_STATUS); regs_buff[11] = AT_READ_REG(hw, REG_MDIO_CTRL); regs_buff[12] = AT_READ_REG(hw, REG_SERDES_LOCK); regs_buff[13] = AT_READ_REG(hw, REG_MAC_CTRL); regs_buff[14] = AT_READ_REG(hw, REG_MAC_IPG_IFG); regs_buff[15] = AT_READ_REG(hw, REG_MAC_STA_ADDR); regs_buff[16] = AT_READ_REG(hw, REG_MAC_STA_ADDR+4); regs_buff[17] = AT_READ_REG(hw, REG_RX_HASH_TABLE); regs_buff[18] = AT_READ_REG(hw, REG_RX_HASH_TABLE+4); regs_buff[19] = AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL); regs_buff[20] = AT_READ_REG(hw, REG_MTU); regs_buff[21] = AT_READ_REG(hw, REG_WOL_CTRL); regs_buff[22] = AT_READ_REG(hw, REG_SRAM_TRD_ADDR); regs_buff[23] = AT_READ_REG(hw, REG_SRAM_TRD_LEN); regs_buff[24] = AT_READ_REG(hw, REG_SRAM_RXF_ADDR); regs_buff[25] = AT_READ_REG(hw, REG_SRAM_RXF_LEN); regs_buff[26] = AT_READ_REG(hw, REG_SRAM_TXF_ADDR); regs_buff[27] = AT_READ_REG(hw, REG_SRAM_TXF_LEN); regs_buff[28] = AT_READ_REG(hw, REG_SRAM_TCPH_ADDR); regs_buff[29] = AT_READ_REG(hw, REG_SRAM_PKTH_ADDR); /* // description address regs_buff[30] = AT_READ_REG(hw, REG_DESC_BASE_ADDR_HI); regs_buff[31] = AT_READ_REG(hw, REG_TPD_BASE_ADDR_LO); regs_buff[32] = AT_READ_REG(hw, REG_TPD_RING_SIZE); regs_buff[33] = AT_READ_REG(hw, REG_HOST_RXF_HEAD); regs_buff[34] = AT_READ_REG(hw, REG_HOST_RXF_TAIL); regs_buff[35] = AT_READ_REG(hw, REG_HOST_RXRAM_SIZE); regs_buff[36] = AT_READ_REG(hw, REG_HOST_RXF1_HEAD); regs_buff[37] = AT_READ_REG(hw, REG_HOST_RXF1_TAIL); regs_buff[38] = AT_READ_REG(hw, REG_HOST_RXF2_HEAD); regs_buff[39] = AT_READ_REG(hw, REG_HOST_RXF2_TAIL); regs_buff[40] = AT_READ_REG(hw, REG_HOST_RXF3_HEAD); regs_buff[41] = AT_READ_REG(hw, REG_HOST_RXF3_TAIL); // mail box regs_buff[42] = AT_READ_REG(hw, REG_HOST_RXF0_WADDR); regs_buff[43] = AT_READ_REG(hw, REG_HOST_RXF1_WADDR); regs_buff[44] = AT_READ_REG(hw, REG_HOST_RXF2_WADDR); regs_buff[45] = AT_READ_REG(hw, REG_HOST_RXF3_WADDR); regs_buff[46] = AT_READ_REG(hw, REG_TPD_CONS_IDX); regs_buff[47] = AT_READ_REG(hw, REG_MB_RXF0_RADDR); regs_buff[48] = AT_READ_REG(hw, REG_MB_RXF1_RADDR); regs_buff[49] = AT_READ_REG(hw, REG_MB_RXF2_RADDR); regs_buff[50] = AT_READ_REG(hw, REG_MB_RXF3_RADDR); regs_buff[51] = AT_READ_REG(hw, REG_MB_TPD_PROD_IDX); // RSS regs_buff[52] = AT_READ_REG(hw, REG_RSS_KEY0); regs_buff[53] = AT_READ_REG(hw, REG_RSS_KEY1); regs_buff[54] = AT_READ_REG(hw, REG_RSS_KEY2); regs_buff[55] = AT_READ_REG(hw, REG_RSS_KEY3); regs_buff[56] = AT_READ_REG(hw, REG_RSS_HASH_VALUE); regs_buff[57] = AT_READ_REG(hw, REG_RSS_HASH_FLAG); regs_buff[58] = AT_READ_REG(hw, REG_IDT_TABLE); regs_buff[59] = AT_READ_REG(hw, REG_BASE_CPU_NUMBER); // TXQ regs_buff[60] = AT_READ_REG(hw, REG_TXQ_CTRL); regs_buff[61] = AT_READ_REG(hw, REG_TX_JUMBO_TASK_TH); // RXQ regs_buff[62] = AT_READ_REG(hw, REG_RXQ_CTRL); regs_buff[63] = AT_READ_REG(hw, REG_RXQ_JMBOSZ_RRDTIM); regs_buff[64] = AT_READ_REG(hw, REG_RXQ_RXF_PAUSE_THRESH); // DMA regs_buff[65] = AT_READ_REG(hw, REG_DMA_CTRL); // misc regs_buff[66] = AT_READ_REG(hw, REG_SMB_STAT_TIMER); regs_buff[67] = AT_READ_REGW(hw, REG_TRIG_RRD_THRESH); regs_buff[68] = AT_READ_REGW(hw, REG_TRIG_TPD_THRESH); regs_buff[69] = AT_READ_REGW(hw, REG_TRIG_RXTIMER); regs_buff[70] = AT_READ_REGW(hw, REG_TRIG_TXTIMER); regs_buff[71] = AT_READ_REG(hw, REG_ISR); regs_buff[72] = AT_READ_REG(hw, REG_IMR); */ atl1e_read_phy_reg(hw, MII_BMCR, &phy_data); regs_buff[73] = (u32)phy_data; atl1e_read_phy_reg(hw, MII_BMSR, &phy_data); regs_buff[74] = (u32)phy_data; }
static void atl1c_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) { struct atl1c_adapter *adapter = netdev_priv(netdev); struct atl1c_hw *hw = &adapter->hw; u32 *regs_buff = p; u16 phy_data; memset(p, 0, AT_REGS_LEN); regs->version = 0; AT_READ_REG(hw, REG_VPD_CAP, p++); AT_READ_REG(hw, REG_PM_CTRL, p++); AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL, p++); AT_READ_REG(hw, REG_TWSI_CTRL, p++); AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL, p++); AT_READ_REG(hw, REG_MASTER_CTRL, p++); AT_READ_REG(hw, REG_MANUAL_TIMER_INIT, p++); AT_READ_REG(hw, REG_IRQ_MODRT_TIMER_INIT, p++); AT_READ_REG(hw, REG_GPHY_CTRL, p++); AT_READ_REG(hw, REG_LINK_CTRL, p++); AT_READ_REG(hw, REG_IDLE_STATUS, p++); AT_READ_REG(hw, REG_MDIO_CTRL, p++); AT_READ_REG(hw, REG_SERDES_LOCK, p++); AT_READ_REG(hw, REG_MAC_CTRL, p++); AT_READ_REG(hw, REG_MAC_IPG_IFG, p++); AT_READ_REG(hw, REG_MAC_STA_ADDR, p++); AT_READ_REG(hw, REG_MAC_STA_ADDR+4, p++); AT_READ_REG(hw, REG_RX_HASH_TABLE, p++); AT_READ_REG(hw, REG_RX_HASH_TABLE+4, p++); AT_READ_REG(hw, REG_RXQ_CTRL, p++); AT_READ_REG(hw, REG_TXQ_CTRL, p++); AT_READ_REG(hw, REG_MTU, p++); AT_READ_REG(hw, REG_WOL_CTRL, p++); atl1c_read_phy_reg(hw, MII_BMCR, &phy_data); regs_buff[73] = (u32) phy_data; atl1c_read_phy_reg(hw, MII_BMSR, &phy_data); regs_buff[74] = (u32) phy_data; }
static void atl1e_get_regs(struct net_device *netdev, struct ethtool_regs *regs, void *p) { struct atl1e_adapter *adapter = netdev_priv(netdev); struct atl1e_hw *hw = &adapter->hw; u32 *regs_buff = p; u16 phy_data; memset(p, 0, AT_REGS_LEN * sizeof(u32)); regs->version = (1 << 24) | (hw->revision_id << 16) | hw->device_id; regs_buff[0] = AT_READ_REG(hw, REG_VPD_CAP); regs_buff[1] = AT_READ_REG(hw, REG_SPI_FLASH_CTRL); regs_buff[2] = AT_READ_REG(hw, REG_SPI_FLASH_CONFIG); regs_buff[3] = AT_READ_REG(hw, REG_TWSI_CTRL); regs_buff[4] = AT_READ_REG(hw, REG_PCIE_DEV_MISC_CTRL); regs_buff[5] = AT_READ_REG(hw, REG_MASTER_CTRL); regs_buff[6] = AT_READ_REG(hw, REG_MANUAL_TIMER_INIT); regs_buff[7] = AT_READ_REG(hw, REG_IRQ_MODU_TIMER_INIT); regs_buff[8] = AT_READ_REG(hw, REG_GPHY_CTRL); regs_buff[9] = AT_READ_REG(hw, REG_CMBDISDMA_TIMER); regs_buff[10] = AT_READ_REG(hw, REG_IDLE_STATUS); regs_buff[11] = AT_READ_REG(hw, REG_MDIO_CTRL); regs_buff[12] = AT_READ_REG(hw, REG_SERDES_LOCK); regs_buff[13] = AT_READ_REG(hw, REG_MAC_CTRL); regs_buff[14] = AT_READ_REG(hw, REG_MAC_IPG_IFG); regs_buff[15] = AT_READ_REG(hw, REG_MAC_STA_ADDR); regs_buff[16] = AT_READ_REG(hw, REG_MAC_STA_ADDR+4); regs_buff[17] = AT_READ_REG(hw, REG_RX_HASH_TABLE); regs_buff[18] = AT_READ_REG(hw, REG_RX_HASH_TABLE+4); regs_buff[19] = AT_READ_REG(hw, REG_MAC_HALF_DUPLX_CTRL); regs_buff[20] = AT_READ_REG(hw, REG_MTU); regs_buff[21] = AT_READ_REG(hw, REG_WOL_CTRL); regs_buff[22] = AT_READ_REG(hw, REG_SRAM_TRD_ADDR); regs_buff[23] = AT_READ_REG(hw, REG_SRAM_TRD_LEN); regs_buff[24] = AT_READ_REG(hw, REG_SRAM_RXF_ADDR); regs_buff[25] = AT_READ_REG(hw, REG_SRAM_RXF_LEN); regs_buff[26] = AT_READ_REG(hw, REG_SRAM_TXF_ADDR); regs_buff[27] = AT_READ_REG(hw, REG_SRAM_TXF_LEN); regs_buff[28] = AT_READ_REG(hw, REG_SRAM_TCPH_ADDR); regs_buff[29] = AT_READ_REG(hw, REG_SRAM_PKTH_ADDR); atl1e_read_phy_reg(hw, MII_BMCR, &phy_data); regs_buff[73] = (u32)phy_data; atl1e_read_phy_reg(hw, MII_BMSR, &phy_data); regs_buff[74] = (u32)phy_data; }
int at_configure(at_adapter *adapter) { at_hw * hw = &adapter->hw; u32 value; // DEBUGFUNC("at_configure() !\n"); // clear interrupt status AT_WRITE_REG(&adapter->hw, REG_ISR, 0xffffffff); // set MAC Address value = (((u32)hw->mac_addr[2]) << 24) | (((u32)hw->mac_addr[3]) << 16) | (((u32)hw->mac_addr[4]) << 8 ) | (((u32)hw->mac_addr[5]) ) ; AT_WRITE_REG(hw, REG_MAC_STA_ADDR, value); value = (((u32)hw->mac_addr[0]) << 8 ) | (((u32)hw->mac_addr[1]) ) ; AT_WRITE_REG(hw, (REG_MAC_STA_ADDR+4), value); // tx / rx ring : // HI base address AT_WRITE_REG( hw, REG_DESC_BASE_ADDR_HI, (u32)((adapter->ring_dma&0xffffffff00000000ULL) >>32)); // LO base address AT_WRITE_REG( hw, REG_TXD_BASE_ADDR_LO, (u32)(adapter->txd_dma&0x00000000ffffffffULL)); AT_WRITE_REG( hw, REG_TXS_BASE_ADDR_LO, (u32)(adapter->txs_dma& 0x00000000ffffffffULL)); AT_WRITE_REG(hw, REG_RXD_BASE_ADDR_LO, (u32)(adapter->rxd_dma& 0x00000000ffffffffULL)); // element count AT_WRITE_REGW(hw, REG_TXD_MEM_SIZE, (u16)(adapter->txd_ring_size/4)); AT_WRITE_REGW(hw, REG_TXS_MEM_SIZE, (u16)adapter->txs_ring_size); AT_WRITE_REGW(hw, REG_RXD_BUF_NUM, (u16)adapter->rxd_ring_size); DEBUGOUT1("txd ring size:%d, txs ring size:%d, rxd ring size:%d\n", adapter->txd_ring_size/4, adapter->txs_ring_size, adapter->rxd_ring_size); /* config Internal SRAM */ /* AT_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_tx_end); AT_WRITE_REGW(hw, REG_SRAM_TXRAM_END, sram_rx_end); */ /* config IPG/IFG */ value = (((u32)hw->ipgt&MAC_IPG_IFG_IPGT_MASK) <<MAC_IPG_IFG_IPGT_SHIFT) | (((u32)hw->min_ifg &MAC_IPG_IFG_MIFG_MASK) <<MAC_IPG_IFG_MIFG_SHIFT) | (((u32)hw->ipgr1&MAC_IPG_IFG_IPGR1_MASK) <<MAC_IPG_IFG_IPGR1_SHIFT)| (((u32)hw->ipgr2&MAC_IPG_IFG_IPGR2_MASK) <<MAC_IPG_IFG_IPGR2_SHIFT); AT_WRITE_REG(hw, REG_MAC_IPG_IFG, value); // DEBUGOUT1("init ipg/ifg with 0x%x\n", value); /* config Half-Duplex Control */ value = ((u32)hw->lcol&MAC_HALF_DUPLX_CTRL_LCOL_MASK) | (((u32)hw->max_retry&MAC_HALF_DUPLX_CTRL_RETRY_MASK) <<MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) | MAC_HALF_DUPLX_CTRL_EXC_DEF_EN | (0xa<<MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) | (((u32)hw->jam_ipg&MAC_HALF_DUPLX_CTRL_JAMIPG_MASK) <<MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT); AT_WRITE_REG(hw, REG_MAC_HALF_DUPLX_CTRL, value); // DEBUGOUT1("init Half Duplex with 0x%x\n", value); /* set Interrupt Moderator Timer */ AT_WRITE_REGW(hw, REG_IRQ_MODU_TIMER_INIT, adapter->imt); AT_WRITE_REG(hw, REG_MASTER_CTRL, MASTER_CTRL_ITIMER_EN); // DEBUGOUT1("init Irq Modurator Timer with 0x%x\n", adapter->imt); /* set Interrupt Clear Timer */ AT_WRITE_REGW(hw, REG_CMBDISDMA_TIMER, adapter->ict); // DEBUGOUT1("init Irq Clear Timer with 0x%x\n", adapter->ict); /* set MTU */ AT_WRITE_REG(hw, REG_MTU, hw->max_frame_size + ENET_HEADER_SIZE + VLAN_SIZE + ETHERNET_FCS_SIZE); // DEBUGOUT1("init MTU with 0x%x\n", hw->max_frame_size); /* 1590 */ AT_WRITE_REG(hw, REG_TX_CUT_THRESH, 0x177); /* flow control */ AT_WRITE_REGW(hw, REG_PAUSE_ON_TH, hw->fc_rxd_hi); AT_WRITE_REGW(hw, REG_PAUSE_OFF_TH, hw->fc_rxd_lo); /* Init mailbox */ AT_WRITE_REGW(hw, REG_MB_TXD_WR_IDX, (u16)adapter->txd_write_ptr); AT_WRITE_REGW(hw, REG_MB_RXD_RD_IDX, (u16)adapter->rxd_read_ptr); /* enable DMA read/write */ AT_WRITE_REGB(hw, REG_DMAR, DMAR_EN); AT_WRITE_REGB(hw, REG_DMAW, DMAW_EN); value = AT_READ_REG(&adapter->hw, REG_ISR); if ((value&ISR_PHY_LINKDOWN) != 0) { value = 1; // config failed } else { value = 0; } // clear all interrupt status AT_WRITE_REG(&adapter->hw, REG_ISR, 0x3fffffff); AT_WRITE_REG(&adapter->hw, REG_ISR, 0); return value; }
/** * at_intr - Interrupt Handler * @irq: interrupt number * @data: pointer to a network interface device structure * @pt_regs: CPU registers structure **/ void AttansicL2Ethernet::atIntr(OSObject *client, IOInterruptEventSource *src, int count) { at_adapter *adapter = &adapter_; at_hw *hw = &adapter->hw; u32 status; status = AT_READ_REG(hw, REG_ISR); if (0 == status) return ; // link event if (status&ISR_PHY) { at_clear_phy_int(adapter); } // clear ISR status, and Enable CMB DMA/Disable Interrupt AT_WRITE_REG(hw, REG_ISR, status|ISR_DIS_INT); // check if PCIE PHY Link down if (status&ISR_PHY_LINKDOWN) { DEBUGOUT1("pcie phy linkdown %x\n", status); // reset MAC AT_WRITE_REG(hw, REG_ISR, 0); AT_WRITE_REG(hw, REG_IMR, 0); AT_WRITE_FLUSH(hw); at_reset_hw(adapter); return ; } // check if DMA read/write error ? if (status&(ISR_DMAR_TO_RST|ISR_DMAW_TO_RST)) { DEBUGOUT1("PCIE DMA RW error (status = 0x%x) !\n", status); //AT_WRITE_REG(&adapter->hw, REG_MASTER_CTRL, MASTER_CTRL_SOFT_RST); AT_WRITE_REG(hw, REG_ISR, 0); AT_WRITE_REG(hw, REG_IMR, 0); AT_WRITE_FLUSH(hw); at_reset_hw(adapter); return ; } // link event if (status&(ISR_PHY|ISR_MANUAL)) { IOSleep(2); atGetAndUpdateLinkStatus(); } // transmit event if ( status&ISR_TX_EVENT ) { at_intr_tx(adapter); } // rx exception if ( status& ISR_RX_EVENT ) { at_intr_rx(adapter); } // re-enable Interrupt AT_WRITE_REG(&adapter->hw, REG_ISR, 0); }