/* * 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 = adapter->physical_port; 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; }
/* * 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_port *port, netxen_ethernet_macaddr_t addr) { u8 temp[4]; u32 val; struct netxen_adapter *adapter = port->adapter; int phy = port->portnum; unsigned char mac_addr[6]; int i; 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, phy, (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, port->netdev->name); printk(KERN_ERR "MAC address set: " "%02x:%02x:%02x:%02x:%02x:%02x.\n", addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); printk(KERN_ERR "MAC address get: " "%02x:%02x:%02x:%02x:%02x:%02x.\n", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); } 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 = adapter->physical_port; 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 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 = adapter->physical_port; 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; }
/* * 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_port *port, netxen_ethernet_macaddr_t addr) { u8 temp[4]; u32 val; struct netxen_adapter *adapter = port->adapter; 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_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; return 0; }
/* Disable an XG interface */ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter, int port) { __u32 mac_cfg; if (port != 0) return -EINVAL; mac_cfg = 0; netxen_xg_soft_reset(mac_cfg); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_XGE_CONFIG_0, &mac_cfg, 4)) return -EIO; return 0; }
/* Disable a GbE interface */ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter, int port) { __u32 mac_cfg0; 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; return 0; }
/* Disable an XG interface */ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) { __u32 mac_cfg; u32 port = adapter->physical_port; 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; }
/* * netxen_niu_gbe_phy_read - read a register from the GbE PHY via * mii management interface. * * Note: The MII management interface goes through port 0. * Individual phys are addressed as follows: * @param phy [15:8] phy id * @param reg [7:0] register number * * @returns 0 on success * -1 on error * */ int netxen_niu_gbe_phy_read(struct netxen_adapter *adapter, long phy, long reg, __u32 * readval) { long timeout = 0; long result = 0; long restore = 0; __u32 address; __u32 command; __u32 status; __u32 mac_cfg0; if (phy_lock(adapter) != 0) { return -1; } /* * MII mgmt all goes through port 0 MAC interface, * so it cannot be in reset */ if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4)) return -EIO; if (netxen_gb_get_soft_reset(mac_cfg0)) { __u32 temp; temp = 0; netxen_gb_tx_reset_pb(temp); netxen_gb_rx_reset_pb(temp); netxen_gb_tx_reset_mac(temp); netxen_gb_rx_reset_mac(temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), &temp, 4)) return -EIO; restore = 1; } address = 0; netxen_gb_mii_mgmt_reg_addr(address, reg); netxen_gb_mii_mgmt_phy_addr(address, phy); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), &address, 4)) return -EIO; command = 0; /* turn off any prior activity */ if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), &command, 4)) return -EIO; /* send read command */ netxen_gb_mii_mgmt_set_read_cycle(command); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), &command, 4)) return -EIO; status = 0; do { if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0), &status, 4)) return -EIO; timeout++; } while ((netxen_get_gb_mii_mgmt_busy(status) || netxen_get_gb_mii_mgmt_notvalid(status)) && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); if (timeout < NETXEN_NIU_PHY_WAITMAX) { if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MII_MGMT_STATUS(0), readval, 4)) return -EIO; result = 0; } else result = -1; if (restore) if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4)) return -EIO; phy_unlock(adapter); return result; }
/* 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; }
/* * netxen_niu_gbe_phy_write - write a register to the GbE PHY via * mii management interface. * * Note: The MII management interface goes through port 0. * Individual phys are addressed as follows: * @param phy [15:8] phy id * @param reg [7:0] register number * * @returns 0 on success * -1 on error * */ int netxen_niu_gbe_phy_write(struct netxen_adapter *adapter, long phy, long reg, __u32 val) { long timeout = 0; long result = 0; long restore = 0; __u32 address; __u32 command; __u32 status; __u32 mac_cfg0; /* * MII mgmt all goes through port 0 MAC interface, so it * cannot be in reset */ if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4)) return -EIO; if (netxen_gb_get_soft_reset(mac_cfg0)) { __u32 temp; temp = 0; netxen_gb_tx_reset_pb(temp); netxen_gb_rx_reset_pb(temp); netxen_gb_tx_reset_mac(temp); netxen_gb_rx_reset_mac(temp); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), &temp, 4)) return -EIO; restore = 1; } command = 0; /* turn off any prior activity */ if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_COMMAND(0), &command, 4)) return -EIO; address = 0; netxen_gb_mii_mgmt_reg_addr(address, reg); netxen_gb_mii_mgmt_phy_addr(address, phy); if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_ADDR(0), &address, 4)) return -EIO; if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MII_MGMT_CTRL(0), &val, 4)) return -EIO; status = 0; do { if (netxen_nic_hw_read_wx(adapter, NETXEN_NIU_GB_MII_MGMT_INDICATE(0), &status, 4)) return -EIO; timeout++; } while ((netxen_get_gb_mii_mgmt_busy(status)) && (timeout++ < NETXEN_NIU_PHY_WAITMAX)); if (timeout < NETXEN_NIU_PHY_WAITMAX) result = 0; else result = -EIO; /* restore the state of port 0 MAC in case we tampered with it */ if (restore) if (netxen_nic_hw_write_wx(adapter, NETXEN_NIU_GB_MAC_CONFIG_0(0), &mac_cfg0, 4)) return -EIO; return result; }