RDMA/nes: Add support for KR device id 0x0110
Add support for KR device id 0x0110. While at it, cleanup nes_init_phy() by splitting it into nes_init_1g_phy() and nes_init_2025_phy(). Remove support for NES_PHY_TYPE_IRIS, which was used on an XFP board that was only manufactured in small quantities and given out for evals in even smaller quantities. Signed-off-by: Chien Tung <chien.tin.tung@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
		
					parent
					
						
							
								831d06cf5b
							
						
					
				
			
			
				commit
				
					
						09124e1913
					
				
			
		
					 5 changed files with 249 additions and 224 deletions
				
			
		|  | @ -110,6 +110,7 @@ static unsigned int sysfs_idx_addr; | |||
| 
 | ||||
| static struct pci_device_id nes_pci_table[] = { | ||||
| 	{PCI_VENDOR_ID_NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020, PCI_ANY_ID, PCI_ANY_ID}, | ||||
| 	{PCI_VENDOR_ID_NETEFFECT, PCI_DEVICE_ID_NETEFFECT_NE020_KR, PCI_ANY_ID, PCI_ANY_ID}, | ||||
| 	{0} | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -64,8 +64,9 @@ | |||
|  * NetEffect PCI vendor id and NE010 PCI device id. | ||||
|  */ | ||||
| #ifndef PCI_VENDOR_ID_NETEFFECT	/* not in pci.ids yet */ | ||||
| #define PCI_VENDOR_ID_NETEFFECT       0x1678 | ||||
| #define PCI_DEVICE_ID_NETEFFECT_NE020 0x0100 | ||||
| #define PCI_VENDOR_ID_NETEFFECT          0x1678 | ||||
| #define PCI_DEVICE_ID_NETEFFECT_NE020    0x0100 | ||||
| #define PCI_DEVICE_ID_NETEFFECT_NE020_KR 0x0110 | ||||
| #endif | ||||
| 
 | ||||
| #define NE020_REV   4 | ||||
|  |  | |||
|  | @ -748,16 +748,28 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, | |||
| 
 | ||||
| 	if (hw_rev != NE020_REV) { | ||||
| 		/* init serdes 0 */ | ||||
| 		if (wide_ppm_offset && (nesadapter->phy_type[0] == NES_PHY_TYPE_CX4)) | ||||
| 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA); | ||||
| 		else | ||||
| 		switch (nesadapter->phy_type[0]) { | ||||
| 		case NES_PHY_TYPE_CX4: | ||||
| 			if (wide_ppm_offset) | ||||
| 				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000FFFAA); | ||||
| 			else | ||||
| 				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||||
| 			break; | ||||
| 		case NES_PHY_TYPE_KR: | ||||
| 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||||
| 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP0, 0x00000000); | ||||
| 			break; | ||||
| 		case NES_PHY_TYPE_PUMA_1G: | ||||
| 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||||
| 
 | ||||
| 		if (nesadapter->phy_type[0] == NES_PHY_TYPE_PUMA_1G) { | ||||
| 			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0); | ||||
| 			sds |= 0x00000100; | ||||
| 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0, sds); | ||||
| 			break; | ||||
| 		default: | ||||
| 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL0, 0x000000FF); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		if (!OneG_Mode) | ||||
| 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_HIGHZ_LANE_MODE0, 0x11110000); | ||||
| 
 | ||||
|  | @ -778,6 +790,9 @@ static int nes_init_serdes(struct nes_device *nesdev, u8 hw_rev, u8 port_count, | |||
| 			if (wide_ppm_offset) | ||||
| 				nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_CDR_CONTROL1, 0x000FFFAA); | ||||
| 			break; | ||||
| 		case NES_PHY_TYPE_KR: | ||||
| 			nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_TX_EMP1, 0x00000000); | ||||
| 			break; | ||||
| 		case NES_PHY_TYPE_PUMA_1G: | ||||
| 			sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL1); | ||||
| 			sds |= 0x000000100; | ||||
|  | @ -1279,115 +1294,100 @@ int nes_destroy_cqp(struct nes_device *nesdev) | |||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * nes_init_phy | ||||
|  * nes_init_1g_phy | ||||
|  */ | ||||
| int nes_init_phy(struct nes_device *nesdev) | ||||
| int nes_init_1g_phy(struct nes_device *nesdev, u8 phy_type, u8 phy_index) | ||||
| { | ||||
| 	struct nes_adapter *nesadapter = nesdev->nesadapter; | ||||
| 	u32 counter = 0; | ||||
| 	u16 phy_data; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data); | ||||
| 	nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000); | ||||
| 
 | ||||
| 	/* Reset the PHY */ | ||||
| 	nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000); | ||||
| 	udelay(100); | ||||
| 	counter = 0; | ||||
| 	do { | ||||
| 		nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | ||||
| 		if (counter++ > 100) { | ||||
| 			ret = -1; | ||||
| 			break; | ||||
| 		} | ||||
| 	} while (phy_data & 0x8000); | ||||
| 
 | ||||
| 	/* Setting no phy loopback */ | ||||
| 	phy_data &= 0xbfff; | ||||
| 	phy_data |= 0x1140; | ||||
| 	nes_write_1G_phy_reg(nesdev, 0, phy_index,  phy_data); | ||||
| 	nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | ||||
| 	nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data); | ||||
| 	nes_read_1G_phy_reg(nesdev, 0x1e, phy_index, &phy_data); | ||||
| 
 | ||||
| 	/* Setting the interrupt mask */ | ||||
| 	nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); | ||||
| 	nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee); | ||||
| 	nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); | ||||
| 
 | ||||
| 	/* turning on flow control */ | ||||
| 	nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); | ||||
| 	nes_write_1G_phy_reg(nesdev, 4, phy_index, (phy_data & ~(0x03E0)) | 0xc00); | ||||
| 	nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); | ||||
| 
 | ||||
| 	/* Clear Half duplex */ | ||||
| 	nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); | ||||
| 	nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100)); | ||||
| 	nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); | ||||
| 
 | ||||
| 	nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | ||||
| 	nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * nes_init_2025_phy | ||||
|  */ | ||||
| int nes_init_2025_phy(struct nes_device *nesdev, u8 phy_type, u8 phy_index) | ||||
| { | ||||
| 	u32 temp_phy_data = 0; | ||||
| 	u32 temp_phy_data2 = 0; | ||||
| 	u32 counter = 0; | ||||
| 	u32 sds; | ||||
| 	u32 mac_index = nesdev->mac_index; | ||||
| 	u32 tx_config = 0; | ||||
| 	u16 phy_data; | ||||
| 	u32 temp_phy_data = 0; | ||||
| 	u32 temp_phy_data2 = 0; | ||||
| 	u8  phy_type = nesadapter->phy_type[mac_index]; | ||||
| 	u8  phy_index = nesadapter->phy_index[mac_index]; | ||||
| 	int ret = 0; | ||||
| 	unsigned int first_attempt = 1; | ||||
| 
 | ||||
| 	if ((nesadapter->OneG_Mode) && | ||||
| 	    (phy_type != NES_PHY_TYPE_PUMA_1G)) { | ||||
| 		nes_debug(NES_DBG_PHY, "1G PHY, mac_index = %d.\n", mac_index); | ||||
| 		if (phy_type == NES_PHY_TYPE_1G) { | ||||
| 			tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | ||||
| 			tx_config &= 0xFFFFFFE3; | ||||
| 			tx_config |= 0x04; | ||||
| 			nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | ||||
| 		} | ||||
| 	/* Check firmware heartbeat */ | ||||
| 	nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||||
| 	temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 	udelay(1500); | ||||
| 	nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||||
| 	temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 
 | ||||
| 		nes_read_1G_phy_reg(nesdev, 1, phy_index, &phy_data); | ||||
| 		nes_write_1G_phy_reg(nesdev, 23, phy_index, 0xb000); | ||||
| 
 | ||||
| 		/* Reset the PHY */ | ||||
| 		nes_write_1G_phy_reg(nesdev, 0, phy_index, 0x8000); | ||||
| 		udelay(100); | ||||
| 		counter = 0; | ||||
| 		do { | ||||
| 			nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | ||||
| 			if (counter++ > 100) | ||||
| 				break; | ||||
| 		} while (phy_data & 0x8000); | ||||
| 
 | ||||
| 		/* Setting no phy loopback */ | ||||
| 		phy_data &= 0xbfff; | ||||
| 		phy_data |= 0x1140; | ||||
| 		nes_write_1G_phy_reg(nesdev, 0, phy_index,  phy_data); | ||||
| 		nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | ||||
| 		nes_read_1G_phy_reg(nesdev, 0x17, phy_index, &phy_data); | ||||
| 		nes_read_1G_phy_reg(nesdev, 0x1e, phy_index, &phy_data); | ||||
| 
 | ||||
| 		/* Setting the interrupt mask */ | ||||
| 		nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); | ||||
| 		nes_write_1G_phy_reg(nesdev, 0x19, phy_index, 0xffee); | ||||
| 		nes_read_1G_phy_reg(nesdev, 0x19, phy_index, &phy_data); | ||||
| 
 | ||||
| 		/* turning on flow control */ | ||||
| 		nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); | ||||
| 		nes_write_1G_phy_reg(nesdev, 4, phy_index, (phy_data & ~(0x03E0)) | 0xc00); | ||||
| 		nes_read_1G_phy_reg(nesdev, 4, phy_index, &phy_data); | ||||
| 
 | ||||
| 		/* Clear Half duplex */ | ||||
| 		nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); | ||||
| 		nes_write_1G_phy_reg(nesdev, 9, phy_index, phy_data & ~(0x0100)); | ||||
| 		nes_read_1G_phy_reg(nesdev, 9, phy_index, &phy_data); | ||||
| 
 | ||||
| 		nes_read_1G_phy_reg(nesdev, 0, phy_index, &phy_data); | ||||
| 		nes_write_1G_phy_reg(nesdev, 0, phy_index, phy_data | 0x0300); | ||||
| 
 | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	if ((phy_type == NES_PHY_TYPE_IRIS) || | ||||
| 	    (phy_type == NES_PHY_TYPE_ARGUS) || | ||||
| 	    (phy_type == NES_PHY_TYPE_SFP_D)) { | ||||
| 		/* setup 10G MDIO operation */ | ||||
| 		tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | ||||
| 		tx_config &= 0xFFFFFFE3; | ||||
| 		tx_config |= 0x15; | ||||
| 		nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | ||||
| 	} | ||||
| 	if ((phy_type == NES_PHY_TYPE_ARGUS) || | ||||
| 	    (phy_type == NES_PHY_TYPE_SFP_D)) { | ||||
| 		u32 first_time = 1; | ||||
| 
 | ||||
| 		/* Check firmware heartbeat */ | ||||
| 		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||||
| 	if (temp_phy_data != temp_phy_data2) { | ||||
| 		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); | ||||
| 		temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 		udelay(1500); | ||||
| 		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||||
| 		temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 		if ((temp_phy_data & 0xff) > 0x20) | ||||
| 			return 0; | ||||
| 		printk(PFX "Reinitialize external PHY\n"); | ||||
| 	} | ||||
| 
 | ||||
| 		if (temp_phy_data != temp_phy_data2) { | ||||
| 			nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); | ||||
| 			temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 			if ((temp_phy_data & 0xff) > 0x20) | ||||
| 				return 0; | ||||
| 			printk(PFX "Reinitializing PHY\n"); | ||||
| 		} | ||||
| 	/* no heartbeat, configure the PHY */ | ||||
| 	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000); | ||||
| 	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000); | ||||
| 	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); | ||||
| 	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); | ||||
| 
 | ||||
| 		/* no heartbeat, configure the PHY */ | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0x0000, 0x8000); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0000); | ||||
| 	switch (phy_type) { | ||||
| 	case NES_PHY_TYPE_ARGUS: | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); | ||||
| 		if (phy_type == NES_PHY_TYPE_ARGUS) { | ||||
| 			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C); | ||||
| 			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008); | ||||
| 			nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001); | ||||
| 		} else { | ||||
| 			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x0004); | ||||
| 			nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0038); | ||||
| 			nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013); | ||||
| 		} | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0008); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0001); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00); | ||||
| 
 | ||||
|  | @ -1395,71 +1395,151 @@ int nes_init_phy(struct nes_device *nesdev) | |||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009); | ||||
| 		break; | ||||
| 
 | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528); | ||||
| 	case NES_PHY_TYPE_SFP_D: | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x0004); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0038); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0098); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00); | ||||
| 
 | ||||
| 		/* Bring PHY out of reset */ | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002); | ||||
| 		/* setup LEDs */ | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x0007); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x000A); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0009); | ||||
| 		break; | ||||
| 
 | ||||
| 		/* Check for heartbeat */ | ||||
| 		counter = 0; | ||||
| 		mdelay(690); | ||||
| 	case NES_PHY_TYPE_KR: | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc316, 0x000A); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc318, 0x0052); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc302, 0x000C); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc319, 0x0010); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0027, 0x0013); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc31a, 0x0080); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0026, 0x0E00); | ||||
| 
 | ||||
| 		/* setup LEDs */ | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd006, 0x000B); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd007, 0x0003); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd008, 0x0004); | ||||
| 
 | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0022, 0x406D); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0023, 0x0020); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0x0028, 0xA528); | ||||
| 
 | ||||
| 	/* Bring PHY out of reset */ | ||||
| 	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc300, 0x0002); | ||||
| 
 | ||||
| 	/* Check for heartbeat */ | ||||
| 	counter = 0; | ||||
| 	mdelay(690); | ||||
| 	nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||||
| 	temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 	do { | ||||
| 		if (counter++ > 150) { | ||||
| 			printk(PFX "No PHY heartbeat\n"); | ||||
| 			break; | ||||
| 		} | ||||
| 		mdelay(1); | ||||
| 		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||||
| 		temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 	} while ((temp_phy_data2 == temp_phy_data)); | ||||
| 
 | ||||
| 	/* wait for tracking */ | ||||
| 	counter = 0; | ||||
| 	do { | ||||
| 		nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); | ||||
| 		temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 		do { | ||||
| 			if (counter++ > 150) { | ||||
| 				printk(PFX "No PHY heartbeat\n"); | ||||
| 		if (counter++ > 300) { | ||||
| 			if (((temp_phy_data & 0xff) == 0x0) && first_attempt) { | ||||
| 				first_attempt = 0; | ||||
| 				counter = 0; | ||||
| 				/* reset AMCC PHY and try again */ | ||||
| 				nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x00c0); | ||||
| 				nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x0040); | ||||
| 				continue; | ||||
| 			} else { | ||||
| 				ret = 1; | ||||
| 				break; | ||||
| 			} | ||||
| 			mdelay(1); | ||||
| 			nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7ee); | ||||
| 			temp_phy_data2 = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 		} while ((temp_phy_data2 == temp_phy_data)); | ||||
| 		} | ||||
| 		mdelay(10); | ||||
| 	} while ((temp_phy_data & 0xff) < 0x30); | ||||
| 
 | ||||
| 		/* wait for tracking */ | ||||
| 		counter = 0; | ||||
| 		do { | ||||
| 			nes_read_10G_phy_reg(nesdev, phy_index, 0x3, 0xd7fd); | ||||
| 			temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 			if (counter++ > 300) { | ||||
| 				if (((temp_phy_data & 0xff) == 0x0) && first_time) { | ||||
| 					first_time = 0; | ||||
| 					counter = 0; | ||||
| 					/* reset AMCC PHY and try again */ | ||||
| 					nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x00c0); | ||||
| 					nes_write_10G_phy_reg(nesdev, phy_index, 0x3, 0xe854, 0x0040); | ||||
| 					continue; | ||||
| 				} else { | ||||
| 					printk(PFX "PHY did not track\n"); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			mdelay(10); | ||||
| 		} while ((temp_phy_data & 0xff) < 0x30); | ||||
| 
 | ||||
| 		/* setup signal integrity */ | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032); | ||||
| 	/* setup signal integrity */ | ||||
| 	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xd003, 0x0000); | ||||
| 	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00D, 0x00FE); | ||||
| 	nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00E, 0x0032); | ||||
| 	if (phy_type == NES_PHY_TYPE_KR) { | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x000C); | ||||
| 	} else { | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xF00F, 0x0002); | ||||
| 		nes_write_10G_phy_reg(nesdev, phy_index, 0x1, 0xc314, 0x0063); | ||||
| 
 | ||||
| 		/* reset serdes */ | ||||
| 		sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | ||||
| 				       mac_index * 0x200); | ||||
| 		sds |= 0x1; | ||||
| 		nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | ||||
| 				  mac_index * 0x200, sds); | ||||
| 		sds &= 0xfffffffe; | ||||
| 		nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + | ||||
| 				  mac_index * 0x200, sds); | ||||
| 
 | ||||
| 		counter = 0; | ||||
| 		while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | ||||
| 				&& (counter++ < 5000)) | ||||
| 			; | ||||
| 	} | ||||
| 	return 0; | ||||
| 
 | ||||
| 	/* reset serdes */ | ||||
| 	sds = nes_read_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + mac_index * 0x200); | ||||
| 	sds |= 0x1; | ||||
| 	nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + mac_index * 0x200, sds); | ||||
| 	sds &= 0xfffffffe; | ||||
| 	nes_write_indexed(nesdev, NES_IDX_ETH_SERDES_COMMON_CONTROL0 + mac_index * 0x200, sds); | ||||
| 
 | ||||
| 	counter = 0; | ||||
| 	while (((nes_read32(nesdev->regs + NES_SOFTWARE_RESET) & 0x00000040) != 0x00000040) | ||||
| 			&& (counter++ < 5000)) | ||||
| 		; | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /**
 | ||||
|  * nes_init_phy | ||||
|  */ | ||||
| int nes_init_phy(struct nes_device *nesdev) | ||||
| { | ||||
| 	struct nes_adapter *nesadapter = nesdev->nesadapter; | ||||
| 	u32 mac_index = nesdev->mac_index; | ||||
| 	u32 tx_config = 0; | ||||
| 	unsigned long flags; | ||||
| 	u8  phy_type = nesadapter->phy_type[mac_index]; | ||||
| 	u8  phy_index = nesadapter->phy_index[mac_index]; | ||||
| 	int ret = 0; | ||||
| 
 | ||||
| 	tx_config = nes_read_indexed(nesdev, NES_IDX_MAC_TX_CONFIG); | ||||
| 	if (phy_type == NES_PHY_TYPE_1G) { | ||||
| 		/* setup 1G MDIO operation */ | ||||
| 		tx_config &= 0xFFFFFFE3; | ||||
| 		tx_config |= 0x04; | ||||
| 	} else { | ||||
| 		/* setup 10G MDIO operation */ | ||||
| 		tx_config &= 0xFFFFFFE3; | ||||
| 		tx_config |= 0x15; | ||||
| 	} | ||||
| 	nes_write_indexed(nesdev, NES_IDX_MAC_TX_CONFIG, tx_config); | ||||
| 
 | ||||
| 	spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); | ||||
| 
 | ||||
| 	switch (phy_type) { | ||||
| 	case NES_PHY_TYPE_1G: | ||||
| 		ret = nes_init_1g_phy(nesdev, phy_type, phy_index); | ||||
| 		break; | ||||
| 	case NES_PHY_TYPE_ARGUS: | ||||
| 	case NES_PHY_TYPE_SFP_D: | ||||
| 	case NES_PHY_TYPE_KR: | ||||
| 		ret = nes_init_2025_phy(nesdev, phy_type, phy_index); | ||||
| 		break; | ||||
| 	} | ||||
| 
 | ||||
| 	spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); | ||||
| 
 | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -2460,23 +2540,9 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
| 			} | ||||
| 		} else { | ||||
| 			switch (nesadapter->phy_type[mac_index]) { | ||||
| 			case NES_PHY_TYPE_IRIS: | ||||
| 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||||
| 				temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 				u32temp = 20; | ||||
| 				do { | ||||
| 					nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 1); | ||||
| 					phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||||
| 					if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||||
| 						break; | ||||
| 					temp_phy_data = phy_data; | ||||
| 				} while (1); | ||||
| 				nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||||
| 					__func__, phy_data, nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP"); | ||||
| 				break; | ||||
| 
 | ||||
| 			case NES_PHY_TYPE_ARGUS: | ||||
| 			case NES_PHY_TYPE_SFP_D: | ||||
| 			case NES_PHY_TYPE_KR: | ||||
| 				/* clear the alarms */ | ||||
| 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0x0008); | ||||
| 				nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 4, 0xc001); | ||||
|  |  | |||
|  | @ -37,12 +37,12 @@ | |||
| 
 | ||||
| #define NES_PHY_TYPE_CX4       1 | ||||
| #define NES_PHY_TYPE_1G        2 | ||||
| #define NES_PHY_TYPE_IRIS      3 | ||||
| #define NES_PHY_TYPE_ARGUS     4 | ||||
| #define NES_PHY_TYPE_PUMA_1G   5 | ||||
| #define NES_PHY_TYPE_PUMA_10G  6 | ||||
| #define NES_PHY_TYPE_GLADIUS   7 | ||||
| #define NES_PHY_TYPE_SFP_D     8 | ||||
| #define NES_PHY_TYPE_KR	       9 | ||||
| 
 | ||||
| #define NES_MULTICAST_PF_MAX 8 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1461,9 +1461,9 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd | |||
| 		} | ||||
| 		return 0; | ||||
| 	} | ||||
| 	if ((phy_type == NES_PHY_TYPE_IRIS) || | ||||
| 	    (phy_type == NES_PHY_TYPE_ARGUS) || | ||||
| 	    (phy_type == NES_PHY_TYPE_SFP_D)) { | ||||
| 	if ((phy_type == NES_PHY_TYPE_ARGUS) || | ||||
| 	    (phy_type == NES_PHY_TYPE_SFP_D) || | ||||
| 	    (phy_type == NES_PHY_TYPE_KR)) { | ||||
| 		et_cmd->transceiver = XCVR_EXTERNAL; | ||||
| 		et_cmd->port        = PORT_FIBRE; | ||||
| 		et_cmd->supported   = SUPPORTED_FIBRE; | ||||
|  | @ -1583,8 +1583,7 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
| 	struct net_device *netdev; | ||||
| 	struct nic_qp_map *curr_qp_map; | ||||
| 	u32 u32temp; | ||||
| 	u16 phy_data; | ||||
| 	u16 temp_phy_data; | ||||
| 	u8 phy_type = nesdev->nesadapter->phy_type[nesdev->mac_index]; | ||||
| 
 | ||||
| 	netdev = alloc_etherdev(sizeof(struct nes_vnic)); | ||||
| 	if (!netdev) { | ||||
|  | @ -1692,65 +1691,23 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
| 
 | ||||
| 	if ((nesdev->netdev_count == 0) && | ||||
| 	    ((PCI_FUNC(nesdev->pcidev->devfn) == nesdev->mac_index) || | ||||
| 	     ((nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) && | ||||
| 	     ((phy_type == NES_PHY_TYPE_PUMA_1G) && | ||||
| 	      (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || | ||||
| 	       ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { | ||||
| 		/*
 | ||||
| 		 * nes_debug(NES_DBG_INIT, "Setting up PHY interrupt mask. Using register index 0x%04X\n", | ||||
| 		 *		NES_IDX_PHY_PCS_CONTROL_STATUS0 + (0x200 * (nesvnic->logical_port & 1))); | ||||
| 		 */ | ||||
| 		u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | ||||
| 				(0x200 * (nesdev->mac_index & 1))); | ||||
| 		if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_PUMA_1G) { | ||||
| 		if (phy_type != NES_PHY_TYPE_PUMA_1G) { | ||||
| 			u32temp |= 0x00200000; | ||||
| 			nes_write_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | ||||
| 				(0x200 * (nesdev->mac_index & 1)), u32temp); | ||||
| 		} | ||||
| 
 | ||||
| 		u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | ||||
| 				(0x200 * (nesdev->mac_index & 1))); | ||||
| 
 | ||||
| 		if ((u32temp&0x0f1f0000) == 0x0f0f0000) { | ||||
| 			if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_IRIS) { | ||||
| 				nes_init_phy(nesdev); | ||||
| 				nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); | ||||
| 				temp_phy_data = (u16)nes_read_indexed(nesdev, | ||||
| 									NES_IDX_MAC_MDIO_CONTROL); | ||||
| 				u32temp = 20; | ||||
| 				do { | ||||
| 					nes_read_10G_phy_reg(nesdev, nesdev->nesadapter->phy_index[nesdev->mac_index], 1, 1); | ||||
| 					phy_data = (u16)nes_read_indexed(nesdev, | ||||
| 									NES_IDX_MAC_MDIO_CONTROL); | ||||
| 					if ((phy_data == temp_phy_data) || (!(--u32temp))) | ||||
| 						break; | ||||
| 					temp_phy_data = phy_data; | ||||
| 				} while (1); | ||||
| 				if (phy_data & 4) { | ||||
| 					nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | ||||
| 					nesvnic->linkup = 1; | ||||
| 				} else { | ||||
| 					nes_debug(NES_DBG_INIT, "The Link is DOWN!!.\n"); | ||||
| 				} | ||||
| 			} else { | ||||
| 				nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | ||||
| 				nesvnic->linkup = 1; | ||||
| 			} | ||||
| 		} else if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_PUMA_1G) { | ||||
| 			nes_debug(NES_DBG_INIT, "mac_index=%d, logical_port=%d, u32temp=0x%04X, PCI_FUNC=%d\n", | ||||
| 				nesdev->mac_index, nesvnic->logical_port, u32temp, PCI_FUNC(nesdev->pcidev->devfn)); | ||||
| 			if (((nesdev->mac_index < 2) && ((u32temp&0x01010000) == 0x01010000)) || | ||||
| 			    ((nesdev->mac_index > 1) && ((u32temp&0x02020000) == 0x02020000)))  { | ||||
| 				nes_debug(NES_DBG_INIT, "The Link is UP!!.\n"); | ||||
| 				nesvnic->linkup = 1; | ||||
| 			} | ||||
| 		} | ||||
| 		/* clear the MAC interrupt status, assumes direct logical to physical mapping */ | ||||
| 		u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); | ||||
| 		nes_debug(NES_DBG_INIT, "Phy interrupt status = 0x%X.\n", u32temp); | ||||
| 		nes_write_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index), u32temp); | ||||
| 
 | ||||
| 		if (nesdev->nesadapter->phy_type[nesdev->mac_index] != NES_PHY_TYPE_IRIS) | ||||
| 			nes_init_phy(nesdev); | ||||
| 		nes_init_phy(nesdev); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Chien Tung
				Chien Tung