netxen_nic_niu.c
来自「linux 内核源代码」· C语言 代码 · 共 909 行 · 第 1/2 页
C
909 行
{ u32 portnum = physical_port[adapter->portnum]; netxen_crb_writelit_adapter(adapter, NETXEN_NIU_XGE_CONFIG_1+(0x10000*portnum), 0x1447); netxen_crb_writelit_adapter(adapter, NETXEN_NIU_XGE_CONFIG_0+(0x10000*portnum), 0x5); return 0;}/* * netxen_niu_gbe_handle_phy_interrupt - Handles GbE PHY interrupts * @param enable 0 means don't enable the port * 1 means enable (or re-enable) the port */int netxen_niu_gbe_handle_phy_interrupt(struct netxen_adapter *adapter, int port, long enable){ int result = 0; __u32 int_src; printk(KERN_INFO PFX "NETXEN: Handling PHY interrupt on port %d" " (device enable = %d)\n", (int)port, (int)enable); /* * The read of the PHY INT status will clear the pending * interrupt status */ if (netxen_niu_gbe_phy_read(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR_INT_STATUS, &int_src) != 0) result = -EINVAL; else { printk(KERN_INFO PFX "PHY Interrupt source = 0x%x \n", int_src); if (netxen_get_phy_int_jabber(int_src)) printk(KERN_INFO PFX "jabber Interrupt "); if (netxen_get_phy_int_polarity_changed(int_src)) printk(KERN_INFO PFX "polarity changed "); if (netxen_get_phy_int_energy_detect(int_src)) printk(KERN_INFO PFX "energy detect \n"); if (netxen_get_phy_int_downshift(int_src)) printk(KERN_INFO PFX "downshift \n"); if (netxen_get_phy_int_mdi_xover_changed(int_src)) printk(KERN_INFO PFX "mdi_xover_changed "); if (netxen_get_phy_int_fifo_over_underflow(int_src)) printk(KERN_INFO PFX "fifo_over_underflow "); if (netxen_get_phy_int_false_carrier(int_src)) printk(KERN_INFO PFX "false_carrier "); if (netxen_get_phy_int_symbol_error(int_src)) printk(KERN_INFO PFX "symbol_error "); if (netxen_get_phy_int_autoneg_completed(int_src)) printk(KERN_INFO PFX "autoneg_completed "); if (netxen_get_phy_int_page_received(int_src)) printk(KERN_INFO PFX "page_received "); if (netxen_get_phy_int_duplex_changed(int_src)) printk(KERN_INFO PFX "duplex_changed "); if (netxen_get_phy_int_autoneg_error(int_src)) printk(KERN_INFO PFX "autoneg_error "); if ((netxen_get_phy_int_speed_changed(int_src)) || (netxen_get_phy_int_link_status_changed(int_src))) { __u32 status; printk(KERN_INFO PFX "speed_changed or link status changed"); if (netxen_niu_gbe_phy_read (adapter, NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS, &status) == 0) { if (netxen_get_phy_speed(status) == 2) { printk (KERN_INFO PFX "Link speed changed" " to 1000 Mbps\n"); netxen_niu_gbe_set_gmii_mode(adapter, port, enable); } else if (netxen_get_phy_speed(status) == 1) { printk (KERN_INFO PFX "Link speed changed" " to 100 Mbps\n"); netxen_niu_gbe_set_mii_mode(adapter, port, enable); } else if (netxen_get_phy_speed(status) == 0) { printk (KERN_INFO PFX "Link speed changed" " to 10 Mbps\n"); netxen_niu_gbe_set_mii_mode(adapter, port, enable); } else { printk(KERN_ERR PFX "ERROR reading" "PHY status. Illegal speed.\n"); result = -1; } } else { printk(KERN_ERR PFX "ERROR reading PHY status.\n"); result = -1; } } printk(KERN_INFO "\n"); } return result;}/* * Return the current station MAC address. * Note that the passed-in value must already be in network byte order. */int netxen_niu_macaddr_get(struct netxen_adapter *adapter, netxen_ethernet_macaddr_t * addr){ u32 stationhigh; u32 stationlow; int phy = physical_port[adapter->portnum]; u8 val[8]; if (addr == NULL) return -EINVAL; if ((phy < 0) || (phy > 3)) return -EINVAL; if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &stationhigh, 4)) return -EIO; if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &stationlow, 4)) return -EIO; ((__le32 *)val)[1] = cpu_to_le32(stationhigh); ((__le32 *)val)[0] = cpu_to_le32(stationlow); memcpy(addr, val + 2, 6); return 0;}/* * Set the station MAC address. * Note that the passed-in value must already be in network byte order. */int netxen_niu_macaddr_set(struct netxen_adapter *adapter, netxen_ethernet_macaddr_t addr){ u8 temp[4]; u32 val; int phy = physical_port[adapter->portnum]; unsigned char mac_addr[6]; int i; DECLARE_MAC_BUF(mac); for (i = 0; i < 10; i++) { temp[0] = temp[1] = 0; memcpy(temp + 2, addr, 2); val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx (adapter, NETXEN_NIU_GB_STATION_ADDR_1(phy), &val, 4)) return -EIO; memcpy(temp, ((u8 *) addr) + 2, sizeof(__le32)); val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx (adapter, NETXEN_NIU_GB_STATION_ADDR_0(phy), &val, 4)) return -2; netxen_niu_macaddr_get(adapter, (netxen_ethernet_macaddr_t *) mac_addr); if (memcmp(mac_addr, addr, 6) == 0) break; } if (i == 10) { printk(KERN_ERR "%s: cannot set Mac addr for %s\n", netxen_nic_driver_name, adapter->netdev->name); printk(KERN_ERR "MAC address set: %s.\n", print_mac(mac, addr)); printk(KERN_ERR "MAC address get: %s.\n", print_mac(mac, mac_addr)); } return 0;}/* Enable a GbE interface */int netxen_niu_enable_gbe_port(struct netxen_adapter *adapter, int port, netxen_niu_gbe_ifmode_t mode){ __u32 mac_cfg0; __u32 mac_cfg1; __u32 mii_cfg; if ((port < 0) || (port > NETXEN_NIU_MAX_GBE_PORTS)) return -EINVAL; mac_cfg0 = 0; netxen_gb_soft_reset(mac_cfg0); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 4)) return -EIO; mac_cfg0 = 0; netxen_gb_enable_tx(mac_cfg0); netxen_gb_enable_rx(mac_cfg0); netxen_gb_unset_rx_flowctl(mac_cfg0); netxen_gb_tx_reset_pb(mac_cfg0); netxen_gb_rx_reset_pb(mac_cfg0); netxen_gb_tx_reset_mac(mac_cfg0); netxen_gb_rx_reset_mac(mac_cfg0); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 4)) return -EIO; mac_cfg1 = 0; netxen_gb_set_preamblelen(mac_cfg1, 0xf); netxen_gb_set_duplex(mac_cfg1); netxen_gb_set_crc_enable(mac_cfg1); netxen_gb_set_padshort(mac_cfg1); netxen_gb_set_checklength(mac_cfg1); netxen_gb_set_hugeframes(mac_cfg1); if (mode == NETXEN_NIU_10_100_MB) { netxen_gb_set_intfmode(mac_cfg1, 1); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), &mac_cfg1, 4)) return -EIO; /* set mii mode */ netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 0); netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 1); } else if (mode == NETXEN_NIU_1000_MB) { netxen_gb_set_intfmode(mac_cfg1, 2); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_1(port), &mac_cfg1, 4)) return -EIO; /* set gmii mode */ netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_MII_MODE + (port << 3), 0); netxen_crb_writelit_adapter(adapter, NETXEN_NIU_GB0_GMII_MODE + (port << 3), 1); } mii_cfg = 0; netxen_gb_set_mii_mgmt_clockselect(mii_cfg, 7); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CONFIG(port), &mii_cfg, 4)) return -EIO; mac_cfg0 = 0; netxen_gb_enable_tx(mac_cfg0); netxen_gb_enable_rx(mac_cfg0); netxen_gb_unset_rx_flowctl(mac_cfg0); netxen_gb_unset_tx_flowctl(mac_cfg0); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 4)) return -EIO; return 0;}/* Disable a GbE interface */int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter){ __u32 mac_cfg0; u32 port = physical_port[adapter->portnum]; if (port > NETXEN_NIU_MAX_GBE_PORTS) return -EINVAL; mac_cfg0 = 0; netxen_gb_soft_reset(mac_cfg0); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(port), &mac_cfg0, 4)) return -EIO; return 0;}/* Disable an XG interface */int netxen_niu_disable_xg_port(struct netxen_adapter *adapter){ __u32 mac_cfg; u32 port = physical_port[adapter->portnum]; if (port > NETXEN_NIU_MAX_XG_PORTS) return -EINVAL; mac_cfg = 0; if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), &mac_cfg, 4)) return -EIO; return 0;}/* Set promiscuous mode for a GbE interface */int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter, netxen_niu_prom_mode_t mode){ __u32 reg; u32 port = physical_port[adapter->portnum]; if (port > NETXEN_NIU_MAX_GBE_PORTS) return -EINVAL; /* save previous contents */ if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, ®, 4)) return -EIO; if (mode == NETXEN_NIU_PROMISC_MODE) { switch (port) { case 0: netxen_clear_gb_drop_gb0(reg); break; case 1: netxen_clear_gb_drop_gb1(reg); break; case 2: netxen_clear_gb_drop_gb2(reg); break; case 3: netxen_clear_gb_drop_gb3(reg); break; default: return -EIO; } } else { switch (port) { case 0: netxen_set_gb_drop_gb0(reg); break; case 1: netxen_set_gb_drop_gb1(reg); break; case 2: netxen_set_gb_drop_gb2(reg); break; case 3: netxen_set_gb_drop_gb3(reg); break; default: return -EIO; } } if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_DROP_WRONGADDR, ®, 4)) return -EIO; return 0;}/* * Set the MAC address for an XG port * Note that the passed-in value must already be in network byte order. */int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter, netxen_ethernet_macaddr_t addr){ int phy = physical_port[adapter->portnum]; u8 temp[4]; u32 val; if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS)) return -EIO; temp[0] = temp[1] = 0; switch (phy) { case 0: memcpy(temp + 2, addr, 2); val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, &val, 4)) return -EIO; memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, &val, 4)) return -EIO; break; case 1: memcpy(temp + 2, addr, 2); val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_1, &val, 4)) return -EIO; memcpy(&temp, ((u8 *) addr) + 2, sizeof(__le32)); val = le32_to_cpu(*(__le32 *)temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XG1_STATION_ADDR_0_HI, &val, 4)) return -EIO; break; default: printk(KERN_ERR "Unknown port %d\n", phy); break; } return 0;}/* * Return the current station MAC address. * Note that the passed-in value must already be in network byte order. */int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter, netxen_ethernet_macaddr_t * addr){ int phy = physical_port[adapter->portnum]; u32 stationhigh; u32 stationlow; u8 val[8]; if (addr == NULL) return -EINVAL; if (phy != 0) return -EINVAL; if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_HI, &stationhigh, 4)) return -EIO; if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_STATION_ADDR_0_1, &stationlow, 4)) return -EIO; ((__le32 *)val)[1] = cpu_to_le32(stationhigh); ((__le32 *)val)[0] = cpu_to_le32(stationlow); memcpy(addr, val + 2, 6); return 0;}int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter, netxen_niu_prom_mode_t mode){ __u32 reg; u32 port = physical_port[adapter->portnum]; if (port > NETXEN_NIU_MAX_XG_PORTS) return -EINVAL; if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), ®, 4)) return -EIO; if (mode == NETXEN_NIU_PROMISC_MODE) reg = (reg | 0x2000UL); else reg = (reg & ~0x2000UL); netxen_crb_writelit_adapter(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?