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,				  &reg, 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,				   &reg, 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), &reg, 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 + -
显示快捷键?