static int get_flash_mac_addr(struct unm_adapter_s *adapter, u64 mac[]) { uint32_t *pmac = (uint32_t *)&mac[0]; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { uint32_t temp, crbaddr; uint16_t *pmac16 = (uint16_t *)pmac; // FOR P3, read from CAM RAM int pci_func = adapter->ahw.pci_func; pmac16 += (4 * pci_func); crbaddr = CRB_MAC_BLOCK_START + (4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1)); adapter->unm_nic_hw_read_wx(adapter, crbaddr, &temp, 4); if (pci_func & 1) { *pmac16++ = (temp >> 16); adapter->unm_nic_hw_read_wx(adapter, crbaddr+4, &temp, 4); *pmac16++ = (temp & 0xffff); *pmac16++ = (temp >> 16); *pmac16 = 0; } else {
/* * Set the coalescing parameters. Currently only normal is supported. * If rx_coalesce_usecs == 0 or rx_max_coalesced_frames == 0 then set the * firmware coalescing to default. */ static int netxen_set_intr_coalesce(struct net_device *netdev, struct ethtool_coalesce *ethcoal) { struct netxen_adapter *adapter = netdev_priv(netdev); if (!NX_IS_REVISION_P3(adapter->ahw.revision_id)) return -EINVAL; if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) return -EINVAL; /* * Return Error if unsupported values or * unsupported parameters are set. */ if (ethcoal->rx_coalesce_usecs > 0xffff || ethcoal->rx_max_coalesced_frames > 0xffff || ethcoal->tx_coalesce_usecs > 0xffff || ethcoal->tx_max_coalesced_frames > 0xffff || ethcoal->rx_coalesce_usecs_irq || ethcoal->rx_max_coalesced_frames_irq || ethcoal->tx_coalesce_usecs_irq || ethcoal->tx_max_coalesced_frames_irq || ethcoal->stats_block_coalesce_usecs || ethcoal->use_adaptive_rx_coalesce || ethcoal->use_adaptive_tx_coalesce || ethcoal->pkt_rate_low || ethcoal->rx_coalesce_usecs_low || ethcoal->rx_max_coalesced_frames_low || ethcoal->tx_coalesce_usecs_low || ethcoal->tx_max_coalesced_frames_low || ethcoal->pkt_rate_high || ethcoal->rx_coalesce_usecs_high || ethcoal->rx_max_coalesced_frames_high || ethcoal->tx_coalesce_usecs_high || ethcoal->tx_max_coalesced_frames_high) return -EINVAL; if (!ethcoal->rx_coalesce_usecs || !ethcoal->rx_max_coalesced_frames) { adapter->coal.flags = NETXEN_NIC_INTR_DEFAULT; adapter->coal.normal.data.rx_time_us = NETXEN_DEFAULT_INTR_COALESCE_RX_TIME_US; adapter->coal.normal.data.rx_packets = NETXEN_DEFAULT_INTR_COALESCE_RX_PACKETS; } else { adapter->coal.flags = 0; adapter->coal.normal.data.rx_time_us = ethcoal->rx_coalesce_usecs; adapter->coal.normal.data.rx_packets = ethcoal->rx_max_coalesced_frames; } adapter->coal.normal.data.tx_time_us = ethcoal->tx_coalesce_usecs; adapter->coal.normal.data.tx_packets = ethcoal->tx_max_coalesced_frames; netxen_config_intr_coalesce(adapter); return 0; }
static u32 netxen_nic_get_tso(struct net_device *dev) { struct netxen_adapter *adapter = netdev_priv(dev); if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) return (dev->features & (NETIF_F_TSO | NETIF_F_TSO6)) != 0; return (dev->features & NETIF_F_TSO) != 0; }
inline int nx_setup_rx_vmkbounce_buffers(struct unm_adapter_s * adapter, nx_host_rx_ctx_t *nxhal_host_rx_ctx) { int i,ring; struct vmk_bounce *bounce = NULL; nx_host_rds_ring_t *nxhal_host_rds_ring = NULL; rds_host_ring_t *host_rds_ring = NULL; void *vaddr_off; uint64_t dmaddr_off; unsigned int len; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { return 0; } for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { nxhal_host_rds_ring = &nxhal_host_rx_ctx->rds_rings[ring]; host_rds_ring = (rds_host_ring_t *) nxhal_host_rds_ring->os_data; bounce = &host_rds_ring->vmk_bounce; bounce->max = (ring ? (MAX_VMK_BOUNCE / 16) : MAX_VMK_BOUNCE ) ; len = host_rds_ring->dma_size * MAX_VMK_BOUNCE; bounce->len = len; bounce->index = 0; vaddr_off = nx_alloc(adapter, len, (dma_addr_t *)&dmaddr_off, &bounce->pdev); if (vaddr_off == NULL){ printk (KERN_WARNING"%s:%s failed to alloc rx bounce buffers for device %s \n", unm_nic_driver_name, __FUNCTION__, adapter->netdev->name); return -1; } bounce->vaddr_off = vaddr_off; bounce->dmaddr_off = dmaddr_off; TAILQ_INIT (&bounce->free_vmk_bounce); for (i = 0; i < (bounce->max); i++) { bounce->buf[i].data = vaddr_off; bounce->buf[i].phys = dmaddr_off; bounce->buf[i].busy = 0; bounce->buf[i].index = i; TAILQ_INSERT_TAIL(&bounce->free_vmk_bounce, &(bounce->buf[i]), link); vaddr_off += host_rds_ring->dma_size; dmaddr_off += host_rds_ring->dma_size; } spin_lock_init(&bounce->lock); } return 0; }
static int netxen_nic_set_tso(struct net_device *dev, u32 data) { if (data) { struct netxen_adapter *adapter = netdev_priv(dev); dev->features |= NETIF_F_TSO; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) dev->features |= NETIF_F_TSO6; } else dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); return 0; }
inline void nx_free_tx_vmkbounce_buffers(struct unm_adapter_s *adapter) { if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { return ; } if (adapter->vmk_bounce.vaddr_off) { pci_free_consistent (adapter->vmk_bounce.pdev, adapter->vmk_bounce.len, adapter->vmk_bounce.vaddr_off, adapter->vmk_bounce.dmaddr_off); adapter->vmk_bounce.vaddr_off = NULL; } }
inline int nx_setup_tx_vmkbounce_buffers(struct unm_adapter_s * adapter) { int i; void *vaddr_off; uint64_t dmaddr_off; unsigned int len; struct vmk_bounce *bounce = &adapter->vmk_bounce; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { return 0; } adapter->bounce = 1; len = PAGE_SIZE * MAX_VMK_BOUNCE; bounce->len = len; bounce->index = 0; bounce->max = MAX_VMK_BOUNCE; vaddr_off = nx_alloc(adapter, len, (dma_addr_t *)&dmaddr_off, &bounce->pdev); if (vaddr_off == NULL){ printk (KERN_WARNING"%s:%s failed to alloc tx bounce buffers for device %s \n", unm_nic_driver_name, __FUNCTION__, adapter->netdev->name); return -1; } bounce->vaddr_off = vaddr_off; bounce->dmaddr_off = dmaddr_off; TAILQ_INIT (&bounce->free_vmk_bounce); for (i = 0; i < (bounce->max); i++) { bounce->buf[i].data = vaddr_off; bounce->buf[i].phys = dmaddr_off; bounce->buf[i].busy = 0; bounce->buf[i].index = i; TAILQ_INSERT_TAIL(&bounce->free_vmk_bounce, &(bounce->buf[i]), link); vaddr_off += PAGE_SIZE; dmaddr_off += PAGE_SIZE; } spin_lock_init(&bounce->lock); return 0; }
inline int nx_setup_vlan_buffers(struct unm_adapter_s * adapter) { int i; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { return 0; } struct unm_cmd_buffer *cmd_buf = adapter->cmd_buf_arr; for (i = 0; i < (adapter->MaxTxDescCount); i++) { cmd_buf[i].vlan_buf.data = nx_alloc(adapter, HDR_CP * sizeof(uint8_t), (dma_addr_t *)&(cmd_buf[i].vlan_buf.phys), &(cmd_buf[i].pdev)); if (cmd_buf[i].vlan_buf.data == NULL) return -1; } return 0; }
static int netxen_get_intr_coalesce(struct net_device *netdev, struct ethtool_coalesce *ethcoal) { struct netxen_adapter *adapter = netdev_priv(netdev); if (!NX_IS_REVISION_P3(adapter->ahw.revision_id)) return -EINVAL; if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) return -EINVAL; ethcoal->rx_coalesce_usecs = adapter->coal.normal.data.rx_time_us; ethcoal->tx_coalesce_usecs = adapter->coal.normal.data.tx_time_us; ethcoal->rx_max_coalesced_frames = adapter->coal.normal.data.rx_packets; ethcoal->tx_max_coalesced_frames = adapter->coal.normal.data.tx_packets; return 0; }
inline void nx_free_vlan_buffers(struct unm_adapter_s *adapter) { int i; struct unm_cmd_buffer *cmd_buff = adapter->cmd_buf_arr; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { return ; } for (i = 0; i < adapter->MaxTxDescCount; i++) { if (cmd_buff->vlan_buf.data != NULL) { pci_free_consistent(cmd_buff->pdev, HDR_CP, cmd_buff->vlan_buf.data, cmd_buff->vlan_buf.phys); cmd_buff->vlan_buf.data = NULL; } cmd_buff++; } }
void nx_free_frag_bounce_buf(struct unm_adapter_s *adapter, struct unm_skb_frag *frag) { int i; unsigned long flags; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { return ; } BOUNCE_LOCK(&(adapter->vmk_bounce.lock), flags); for (i = 0; i < MAX_PAGES_PER_FRAG; i++ ) { if (!frag->bounce_buf[i]) { BOUNCE_UNLOCK(&(adapter->vmk_bounce.lock), flags); return ; } frag->bounce_buf[i]->busy = 0; TAILQ_INSERT_TAIL( &adapter->vmk_bounce.free_vmk_bounce, frag->bounce_buf[i], link); } BOUNCE_UNLOCK(&(adapter->vmk_bounce.lock), flags); }
inline void nx_free_rx_vmkbounce_buffers(struct unm_adapter_s *adapter, nx_host_rx_ctx_t *nxhal_host_rx_ctx) { int ring; nx_host_rds_ring_t *nxhal_host_rds_ring = NULL; rds_host_ring_t *host_rds_ring = NULL; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { return ; } for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) { nxhal_host_rds_ring = &nxhal_host_rx_ctx->rds_rings[ring]; host_rds_ring = (rds_host_ring_t *) nxhal_host_rds_ring->os_data; if(host_rds_ring->vmk_bounce.vaddr_off ) { pci_free_consistent (host_rds_ring->vmk_bounce.pdev, host_rds_ring->vmk_bounce.len, host_rds_ring->vmk_bounce.vaddr_off, host_rds_ring->vmk_bounce.dmaddr_off); host_rds_ring->vmk_bounce.vaddr_off = NULL; } } }
static int netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct netxen_adapter *adapter = netdev_priv(dev); int check_sfp_module = 0; /* read which mode */ if (adapter->ahw.port_type == NETXEN_NIC_GBE) { ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); ecmd->advertising = (ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); ecmd->port = PORT_TP; ecmd->speed = adapter->link_speed; ecmd->duplex = adapter->link_duplex; ecmd->autoneg = adapter->link_autoneg; } else if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { u32 val; val = NXRD32(adapter, NETXEN_PORT_MODE_ADDR); if (val == NETXEN_PORT_MODE_802_3_AP) { ecmd->supported = SUPPORTED_1000baseT_Full; ecmd->advertising = ADVERTISED_1000baseT_Full; } else { ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->advertising = ADVERTISED_10000baseT_Full; } if (netif_running(dev) && adapter->has_link_events) { ecmd->speed = adapter->link_speed; ecmd->autoneg = adapter->link_autoneg; ecmd->duplex = adapter->link_duplex; goto skip; } ecmd->port = PORT_TP; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { u16 pcifn = adapter->ahw.pci_func; val = NXRD32(adapter, P3_LINK_SPEED_REG(pcifn)); ecmd->speed = P3_LINK_SPEED_MHZ * P3_LINK_SPEED_VAL(pcifn, val); } else ecmd->speed = SPEED_10000; ecmd->duplex = DUPLEX_FULL; ecmd->autoneg = AUTONEG_DISABLE; } else return -EIO; skip: ecmd->phy_address = adapter->physical_port; ecmd->transceiver = XCVR_EXTERNAL; switch (adapter->ahw.board_type) { case NETXEN_BRDTYPE_P2_SB35_4G: case NETXEN_BRDTYPE_P2_SB31_2G: case NETXEN_BRDTYPE_P3_REF_QG: case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: ecmd->supported |= SUPPORTED_Autoneg; ecmd->advertising |= ADVERTISED_Autoneg; case NETXEN_BRDTYPE_P2_SB31_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4_LP: case NETXEN_BRDTYPE_P3_10000_BASE_T: ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; ecmd->autoneg = (adapter->ahw.board_type == NETXEN_BRDTYPE_P2_SB31_10G_CX4) ? (AUTONEG_DISABLE) : (adapter->link_autoneg); break; case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: case NETXEN_BRDTYPE_P3_IMEZ: case NETXEN_BRDTYPE_P3_XG_LOM: case NETXEN_BRDTYPE_P3_HMEZ: ecmd->supported |= SUPPORTED_MII; ecmd->advertising |= ADVERTISED_MII; ecmd->port = PORT_MII; ecmd->autoneg = AUTONEG_DISABLE; break; case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: case NETXEN_BRDTYPE_P3_10G_SFP_CT: case NETXEN_BRDTYPE_P3_10G_SFP_QT: ecmd->advertising |= ADVERTISED_TP; ecmd->supported |= SUPPORTED_TP; check_sfp_module = netif_running(dev) && adapter->has_link_events; case NETXEN_BRDTYPE_P2_SB31_10G: case NETXEN_BRDTYPE_P3_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; case NETXEN_BRDTYPE_P3_10G_TP: if (adapter->ahw.port_type == NETXEN_NIC_XGBE) { ecmd->autoneg = AUTONEG_DISABLE; ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP); ecmd->port = PORT_FIBRE; check_sfp_module = netif_running(dev) && adapter->has_link_events; } else { ecmd->autoneg = AUTONEG_ENABLE; ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg); ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); ecmd->port = PORT_TP; } break; default: printk(KERN_ERR "netxen-nic: Unsupported board model %d\n", adapter->ahw.board_type); return -EIO; } if (check_sfp_module) { switch (adapter->module_type) { case LINKEVENT_MODULE_OPTICAL_UNKNOWN: case LINKEVENT_MODULE_OPTICAL_SRLR: case LINKEVENT_MODULE_OPTICAL_LRM: case LINKEVENT_MODULE_OPTICAL_SFP_1G: ecmd->port = PORT_FIBRE; break; case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLE: case LINKEVENT_MODULE_TWINAX_UNSUPPORTED_CABLELEN: case LINKEVENT_MODULE_TWINAX: ecmd->port = PORT_TP; break; default: ecmd->port = -1; } } return 0; }
static int netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct netxen_adapter *adapter = netdev_priv(dev); struct netxen_board_info *boardinfo = &adapter->ahw.boardcfg; /* read which mode */ if (adapter->ahw.board_type == NETXEN_NIC_GBE) { ecmd->supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full); ecmd->advertising = (ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); ecmd->port = PORT_TP; ecmd->speed = adapter->link_speed; ecmd->duplex = adapter->link_duplex; ecmd->autoneg = adapter->link_autoneg; } else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { u32 val; adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4); if (val == NETXEN_PORT_MODE_802_3_AP) { ecmd->supported = SUPPORTED_1000baseT_Full; ecmd->advertising = ADVERTISED_1000baseT_Full; } else { ecmd->supported = SUPPORTED_10000baseT_Full; ecmd->advertising = ADVERTISED_10000baseT_Full; } ecmd->port = PORT_TP; if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { u16 pcifn = adapter->ahw.pci_func; adapter->hw_read_wx(adapter, P3_LINK_SPEED_REG(pcifn), &val, 4); ecmd->speed = P3_LINK_SPEED_MHZ * P3_LINK_SPEED_VAL(pcifn, val); } else ecmd->speed = SPEED_10000; ecmd->duplex = DUPLEX_FULL; ecmd->autoneg = AUTONEG_DISABLE; } else return -EIO; ecmd->phy_address = adapter->physical_port; ecmd->transceiver = XCVR_EXTERNAL; switch ((netxen_brdtype_t) boardinfo->board_type) { case NETXEN_BRDTYPE_P2_SB35_4G: case NETXEN_BRDTYPE_P2_SB31_2G: case NETXEN_BRDTYPE_P3_REF_QG: case NETXEN_BRDTYPE_P3_4_GB: case NETXEN_BRDTYPE_P3_4_GB_MM: ecmd->supported |= SUPPORTED_Autoneg; ecmd->advertising |= ADVERTISED_Autoneg; case NETXEN_BRDTYPE_P2_SB31_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4: case NETXEN_BRDTYPE_P3_10G_CX4_LP: case NETXEN_BRDTYPE_P3_10000_BASE_T: ecmd->supported |= SUPPORTED_TP; ecmd->advertising |= ADVERTISED_TP; ecmd->port = PORT_TP; ecmd->autoneg = (boardinfo->board_type == NETXEN_BRDTYPE_P2_SB31_10G_CX4) ? (AUTONEG_DISABLE) : (adapter->link_autoneg); break; case NETXEN_BRDTYPE_P2_SB31_10G_HMEZ: case NETXEN_BRDTYPE_P2_SB31_10G_IMEZ: case NETXEN_BRDTYPE_P3_IMEZ: case NETXEN_BRDTYPE_P3_XG_LOM: case NETXEN_BRDTYPE_P3_HMEZ: ecmd->supported |= SUPPORTED_MII; ecmd->advertising |= ADVERTISED_MII; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; case NETXEN_BRDTYPE_P3_10G_SFP_PLUS: case NETXEN_BRDTYPE_P3_10G_SFP_CT: case NETXEN_BRDTYPE_P3_10G_SFP_QT: ecmd->advertising |= ADVERTISED_TP; ecmd->supported |= SUPPORTED_TP; case NETXEN_BRDTYPE_P2_SB31_10G: case NETXEN_BRDTYPE_P3_10G_XFP: ecmd->supported |= SUPPORTED_FIBRE; ecmd->advertising |= ADVERTISED_FIBRE; ecmd->port = PORT_FIBRE; ecmd->autoneg = AUTONEG_DISABLE; break; case NETXEN_BRDTYPE_P3_10G_TP: if (adapter->ahw.board_type == NETXEN_NIC_XGBE) { ecmd->autoneg = AUTONEG_DISABLE; ecmd->supported |= (SUPPORTED_FIBRE | SUPPORTED_TP); ecmd->advertising |= (ADVERTISED_FIBRE | ADVERTISED_TP); ecmd->port = PORT_FIBRE; } else { ecmd->autoneg = AUTONEG_ENABLE; ecmd->supported |= (SUPPORTED_TP |SUPPORTED_Autoneg); ecmd->advertising |= (ADVERTISED_TP | ADVERTISED_Autoneg); ecmd->port = PORT_TP; } break; default: printk(KERN_ERR "netxen-nic: Unsupported board model %d\n", (netxen_brdtype_t) boardinfo->board_type); return -EIO; } return 0; }