diff --git a/drivers/net/ethernet/netswift/Kconfig b/drivers/net/ethernet/netswift/Kconfig index d88312538a4f21b8920b0c1318c4b58353e81aa8..b51b5c0cdc66c6c4a051f24ef0c1907b76c2da23 100644 --- a/drivers/net/ethernet/netswift/Kconfig +++ b/drivers/net/ethernet/netswift/Kconfig @@ -36,15 +36,6 @@ config TXGBE_HWMON If unsure, say N. -config TXGBE_PROCFS - bool "Netswift PCI-Express 10Gigabit adapters procfs support" - default n - depends on TXGBE && !TXGBE_SYSFS - help - Say Y if you want to setup procfs for these devices. - - If unsure, say N. - config TXGBE_DEBUG_FS bool "Netswift PCI-Express 10Gigabit adapters debugfs support" default n diff --git a/drivers/net/ethernet/netswift/txgbe/Makefile b/drivers/net/ethernet/netswift/txgbe/Makefile index f8531f3356a85ce22fbcdc45542825b9e03fb07a..5e50972134d7207645eb25b6d7196ac1ae9e7ce7 100644 --- a/drivers/net/ethernet/netswift/txgbe/Makefile +++ b/drivers/net/ethernet/netswift/txgbe/Makefile @@ -9,3 +9,7 @@ obj-$(CONFIG_TXGBE) += txgbe.o txgbe-objs := txgbe_main.o txgbe_ethtool.o \ txgbe_hw.o txgbe_phy.o txgbe_bp.o \ txgbe_mbx.o txgbe_mtd.o txgbe_param.o txgbe_lib.o txgbe_ptp.o + +txgbe-$(CONFIG_TXGBE_HWMON) += txgbe_sysfs.o +txgbe-$(CONFIG_TXGBE_DEBUG_FS) += txgbe_debugfs.o +txgbe-$(CONFIG_TXGBE_SYSFS) += txgbe_sysfs.o diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe.h b/drivers/net/ethernet/netswift/txgbe/txgbe.h index 21b4dbb2a2f2c672cedf1c60a712fda90b035927..0064fd58512e94431b166fe5684c3f8ce0ff569f 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe.h +++ b/drivers/net/ethernet/netswift/txgbe/txgbe.h @@ -67,6 +67,10 @@ #define CL72_KRTR_PRBS_MODE_EN 0x2fff /*deepinsw : 512 default to 256*/ #endif +#ifndef TXGBE_STATIC_ITR +#define TXGBE_STATIC_ITR 1 /* static itr configure */ +#endif + #ifndef SFI_SET #define SFI_SET 0 #define SFI_MAIN 24 @@ -95,7 +99,6 @@ #define KX_POST 16 #endif - #ifndef KX4_TXRX_PIN #define KX4_TXRX_PIN 0 /*rx : 0xf tx : 0xf0 */ #endif @@ -118,8 +121,8 @@ #define KR_CL72_TRAINING 1 #endif -#ifndef KR_REINITED -#define KR_REINITED 1 +#ifndef KR_NOREINITED +#define KR_NOREINITED 0 #endif #ifndef KR_AN73_PRESET @@ -140,17 +143,17 @@ #define TXGBE_DEFAULT_TX_WORK DEFAULT_TX_WORK #else #define TXGBE_DEFAULT_TXD 512 -#define TXGBE_DEFAULT_TX_WORK 256 +#define TXGBE_DEFAULT_TX_WORK 256 #endif #define TXGBE_MAX_TXD 8192 #define TXGBE_MIN_TXD 128 #if (PAGE_SIZE < 8192) #define TXGBE_DEFAULT_RXD 512 -#define TXGBE_DEFAULT_RX_WORK 256 +#define TXGBE_DEFAULT_RX_WORK 256 #else #define TXGBE_DEFAULT_RXD 256 -#define TXGBE_DEFAULT_RX_WORK 128 +#define TXGBE_DEFAULT_RX_WORK 128 #endif #define TXGBE_MAX_RXD 8192 @@ -474,6 +477,7 @@ enum txgbe_ring_f_enum { #define MAX_RX_QUEUES (TXGBE_MAX_FDIR_INDICES + 1) #define MAX_TX_QUEUES (TXGBE_MAX_FDIR_INDICES + 1) +#define MAX_XDP_QUEUES (TXGBE_MAX_FDIR_INDICES + 1) #define TXGBE_MAX_L2A_QUEUES 4 #define TXGBE_BAD_L2A_QUEUE 3 @@ -552,6 +556,26 @@ struct txgbe_q_vector { struct txgbe_ring ring[0] ____cacheline_internodealigned_in_smp; }; +#ifdef CONFIG_TXGBE_HWMON + +#define TXGBE_HWMON_TYPE_TEMP 0 +#define TXGBE_HWMON_TYPE_ALARMTHRESH 1 +#define TXGBE_HWMON_TYPE_DALARMTHRESH 2 + +struct hwmon_attr { + struct device_attribute dev_attr; + struct txgbe_hw *hw; + struct txgbe_thermal_diode_data *sensor; + char name[19]; +}; + +struct hwmon_buff { + struct device *device; + struct hwmon_attr *hwmon_list; + unsigned int n_hwmon; +}; +#endif /* CONFIG_TXGBE_HWMON */ + /* * microsecond values for various ITR rates shifted by 2 to fit itr register * with the first 3 bits reserved 0 @@ -603,6 +627,13 @@ struct txgbe_mac_addr { #define TXGBE_MAC_STATE_MODIFIED 0x2 #define TXGBE_MAC_STATE_IN_USE 0x4 +#ifdef CONFIG_TXGBE_PROCFS +struct txgbe_therm_proc_data { + struct txgbe_hw *hw; + struct txgbe_thermal_diode_data *sensor_data; +}; +#endif + /* * Only for array allocations in our adapter struct. * we can actually assign 64 queue vectors based on our extended-extended @@ -718,16 +749,17 @@ struct txgbe_adapter { */ u32 flags; u32 flags2; - u32 vf_mode; - u32 backplane_an; - u32 an73; - u32 an37; - u32 ffe_main; - u32 ffe_pre; - u32 ffe_post; - u32 ffe_set; - u32 backplane_mode; - u32 backplane_auto; + u8 an73_mode; + u8 vf_mode; + u8 backplane_an; + u8 an73; + u8 an37; + u16 ffe_main; + u16 ffe_pre; + u16 ffe_post; + u8 ffe_set; + u8 backplane_mode; + u8 backplane_auto; bool cloud_mode; @@ -744,6 +776,10 @@ struct txgbe_adapter { unsigned int num_vmdqs; /* does not include pools assigned to VFs */ unsigned int queues_per_pool; + /* XDP */ + int num_xdp_queues; + struct txgbe_ring *xdp_ring[MAX_XDP_QUEUES]; + /* TX */ struct txgbe_ring *tx_ring[MAX_TX_QUEUES] ____cacheline_aligned_in_smp; @@ -798,6 +834,9 @@ struct txgbe_adapter { struct timer_list service_timer; struct work_struct service_task; +#ifdef CONFIG_TXGBE_POLL_LINK_STATUS + struct timer_list link_check_timer; +#endif struct hlist_head fdir_filter_list; unsigned long fdir_overflow; /* number of times ATR was backed off */ union txgbe_atr_input fdir_mask; @@ -845,6 +884,23 @@ struct txgbe_adapter { __le16 vxlan_port; __le16 geneve_port; +#ifdef CONFIG_TXGBE_SYSFS +#ifdef CONFIG_TXGBE_HWMON + struct hwmon_buff txgbe_hwmon_buff; +#endif /* CONFIG_TXGBE_HWMON */ +#else /* CONFIG_TXGBE_SYSFS */ +#ifdef CONFIG_TXGBE_PROCFS + struct proc_dir_entry *eth_dir; + struct proc_dir_entry *info_dir; + u64 old_lsc; + struct proc_dir_entry *therm_dir; + struct txgbe_therm_proc_data therm_data; +#endif /* CONFIG_TXGBE_PROCFS */ +#endif /* CONFIG_TXGBE_SYSFS */ + +#ifdef CONFIG_TXGBE_DEBUG_FS + struct dentry *txgbe_dbg_adapter; +#endif /*CONFIG_TXGBE_DEBUG_FS*/ u8 default_up; unsigned long fwd_bitmask; /* bitmask indicating in use pools */ @@ -914,6 +970,17 @@ struct txgbe_cb { /* ESX txgbe CIM IOCTL definition */ +#ifdef CONFIG_TXGBE_SYSFS +void txgbe_sysfs_exit(struct txgbe_adapter *adapter); +int txgbe_sysfs_init(struct txgbe_adapter *adapter); +#endif /* CONFIG_TXGBE_SYSFS */ +#ifdef CONFIG_TXGBE_PROCFS +void txgbe_procfs_exit(struct txgbe_adapter *adapter); +int txgbe_procfs_init(struct txgbe_adapter *adapter); +int txgbe_procfs_topdir_init(void); +void txgbe_procfs_topdir_exit(void); +#endif /* CONFIG_TXGBE_PROCFS */ + extern struct dcbnl_rtnl_ops dcbnl_ops; int txgbe_copy_dcb_cfg(struct txgbe_adapter *adapter, int tc_max); @@ -974,6 +1041,37 @@ void txgbe_disable_rx_queue(struct txgbe_adapter *adapter, void txgbe_vlan_strip_enable(struct txgbe_adapter *adapter); void txgbe_vlan_strip_disable(struct txgbe_adapter *adapter); +#if IS_ENABLED(CONFIG_FCOE) +void txgbe_configure_fcoe(struct txgbe_adapter *adapter); +int txgbe_fso(struct txgbe_ring *tx_ring, + struct txgbe_tx_buffer *first, + u8 *hdr_len); +int txgbe_fcoe_ddp(struct txgbe_adapter *adapter, + union txgbe_rx_desc *rx_desc, + struct sk_buff *skb); +int txgbe_fcoe_ddp_get(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc); +int txgbe_fcoe_ddp_target(struct net_device *netdev, u16 xid, + struct scatterlist *sgl, unsigned int sgc); +int txgbe_fcoe_ddp_put(struct net_device *netdev, u16 xid); +int txgbe_setup_fcoe_ddp_resources(struct txgbe_adapter *adapter); +void txgbe_free_fcoe_ddp_resources(struct txgbe_adapter *adapter); +int txgbe_fcoe_enable(struct net_device *netdev); +int txgbe_fcoe_disable(struct net_device *netdev); +#if IS_ENABLED(CONFIG_DCB) +u8 txgbe_fcoe_getapp(struct net_device *netdev); +u8 txgbe_fcoe_setapp(struct txgbe_adapter *adapter, u8 up); +#endif /* CONFIG_DCB */ +u8 txgbe_fcoe_get_tc(struct txgbe_adapter *adapter); +int txgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type); +#endif /* CONFIG_FCOE */ + +#ifdef CONFIG_TXGBE_DEBUG_FS +void txgbe_dbg_adapter_init(struct txgbe_adapter *adapter); +void txgbe_dbg_adapter_exit(struct txgbe_adapter *adapter); +void txgbe_dbg_init(void); +void txgbe_dbg_exit(void); +#endif /* CONFIG_TXGBE_DEBUG_FS */ void txgbe_dump(struct txgbe_adapter *adapter); static inline struct netdev_queue *txring_txq(const struct txgbe_ring *ring) diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_bp.c b/drivers/net/ethernet/netswift/txgbe/txgbe_bp.c index 68d465da2eee89aa904198e57bfb5bd98b07a65e..d51d1e15bedc86988af98902c122624f36ceec4e 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_bp.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_bp.c @@ -18,26 +18,27 @@ #include "txgbe_bp.h" -int Handle_bkp_an73_flow(unsigned char byLinkMode, struct txgbe_adapter *adapter); -int WaitBkpAn73XnpDone(struct txgbe_adapter *adapter); -int GetBkpAn73Ability(bkpan73ability *ptBkpAn73Ability, unsigned char byLinkPartner, - struct txgbe_adapter *adapter); -int Get_bkp_an73_ability(bkpan73ability *ptBkpAn73Ability, unsigned char byLinkPartner, - struct txgbe_adapter *adapter); -int ClearBkpAn73Interrupt(unsigned int intIndex, unsigned int intIndexHi, struct txgbe_adapter *adapter); -int CheckBkpAn73Interrupt(unsigned int intIndex, struct txgbe_adapter *adapter); -int Check_bkp_an73_ability(bkpan73ability tBkpAn73Ability, bkpan73ability tLpBkpAn73Ability, - struct txgbe_adapter *adapter); +int handle_bkp_an73_flow(unsigned char bp_link_mode, struct txgbe_adapter *adapter); +int wait_bkp_an73_xnp_done(struct txgbe_adapter *adapter); +int get_bkp_an73_ability(bkpan73ability *pt_bkp_an73_ability, + unsigned char byLinkPartner, struct txgbe_adapter *adapter); +int clr_bkp_an73_int(unsigned int intIndex, unsigned int intIndexHi, + struct txgbe_adapter * adapter); +int chk_bkp_an73_Int(unsigned int intIndex, struct txgbe_adapter *adapter); +int chk_bkp_an73_ability(bkpan73ability tBkpAn73Ability, + bkpan73ability tLpBkpAn73Ability, + struct txgbe_adapter *adapter); void txgbe_bp_close_protect(struct txgbe_adapter *adapter) { adapter->flags2 |= TXGBE_FLAG2_KR_PRO_DOWN; - if (adapter->flags2 & TXGBE_FLAG2_KR_PRO_REINIT) { + while (adapter->flags2 & TXGBE_FLAG2_KR_PRO_REINIT){ msleep(100); - printk("wait to reinited ok..%x\n", adapter->flags2); + printk("wait to reinited ok..%x\n",adapter->flags2); } } + int txgbe_bp_mode_setting(struct txgbe_adapter *adapter) { struct txgbe_hw *hw = &adapter->hw; @@ -49,16 +50,12 @@ int txgbe_bp_mode_setting(struct txgbe_adapter *adapter) if (adapter->backplane_mode == TXGBE_BP_M_KR) { hw->subsystem_device_id = TXGBE_ID_WX1820_KR_KX_KX4; - hw->subsystem_id = TXGBE_ID_WX1820_KR_KX_KX4; } else if (adapter->backplane_mode == TXGBE_BP_M_KX4) { hw->subsystem_device_id = TXGBE_ID_WX1820_MAC_XAUI; - hw->subsystem_id = TXGBE_ID_WX1820_MAC_XAUI; } else if (adapter->backplane_mode == TXGBE_BP_M_KX) { hw->subsystem_device_id = TXGBE_ID_WX1820_MAC_SGMII; - hw->subsystem_id = TXGBE_ID_WX1820_MAC_SGMII; } else if (adapter->backplane_mode == TXGBE_BP_M_SFI) { hw->subsystem_device_id = TXGBE_ID_WX1820_SFP; - hw->subsystem_id = TXGBE_ID_WX1820_SFP; } if (adapter->backplane_auto == TXGBE_BP_M_AUTO) { @@ -99,7 +96,7 @@ int txgbe_bp_mode_setting(struct txgbe_adapter *adapter) static int txgbe_kr_subtask(struct txgbe_adapter *adapter) { - Handle_bkp_an73_flow(0, adapter); + handle_bkp_an73_flow(0, adapter); return 0; } @@ -127,32 +124,26 @@ void txgbe_bp_watchdog_event(struct txgbe_adapter *adapter) void txgbe_bp_down_event(struct txgbe_adapter *adapter) { struct txgbe_hw *hw = &adapter->hw; - if (adapter->backplane_an == 1) { - if (KR_NORESET == 1) { - txgbe_wr32_epcs(hw, 0x78003, 0x0000); - txgbe_wr32_epcs(hw, 0x70000, 0x0000); + + if (adapter->backplane_an == 1){ + if (KR_NORESET == 1){ + txgbe_wr32_epcs(hw, TXGBE_VR_AN_KR_MODE_CL, 0x0000); + txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x0000); txgbe_wr32_epcs(hw, 0x78001, 0x0000); - msleep(1050); + msleep(1000); txgbe_set_link_to_kr(hw, 1); - } else if (KR_REINITED == 1) { - txgbe_wr32_epcs(hw, 0x78003, 0x0000); - txgbe_wr32_epcs(hw, 0x70000, 0x0000); + } else if (KR_NOREINITED == 1) { + txgbe_wr32_epcs(hw, TXGBE_VR_AN_KR_MODE_CL, 0x0000); + txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x0000); txgbe_wr32_epcs(hw, 0x78001, 0x0000); - txgbe_wr32_epcs(hw, 0x18035, 0x00FF); - txgbe_wr32_epcs(hw, 0x18055, 0x00FF); msleep(1050); - txgbe_wr32_epcs(hw, 0x78003, 0x0001); - txgbe_wr32_epcs(hw, 0x70000, 0x3200); + txgbe_wr32_epcs(hw, TXGBE_VR_AN_KR_MODE_CL, 0x0001); + txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x3200); txgbe_wr32_epcs(hw, 0x78001, 0x0007); - txgbe_wr32_epcs(hw, 0x18035, 0x00FC); - txgbe_wr32_epcs(hw, 0x18055, 0x00FC); } else { - msleep(1000); - if (!(adapter->flags2&TXGBE_FLAG2_KR_PRO_DOWN)) { - adapter->flags2 |= TXGBE_FLAG2_KR_PRO_REINIT; + msleep(200); + if (!(adapter->flags2&TXGBE_FLAG2_KR_PRO_DOWN)) txgbe_reinit_locked(adapter); - adapter->flags2 &= ~TXGBE_FLAG2_KR_PRO_REINIT; - } } } } @@ -170,18 +161,18 @@ int txgbe_kr_intr_handle(struct txgbe_adapter *adapter) /*1. Get the local AN73 Base Page Ability*/ if (KR_MODE) e_dev_info("<1>. Get the local AN73 Base Page Ability ...\n"); - GetBkpAn73Ability(&tBkpAn73Ability, 0, adapter); + get_bkp_an73_ability(&tBkpAn73Ability, 0, adapter); /*2. Check the AN73 Interrupt Status*/ if (KR_MODE) e_dev_info("<2>. Check the AN73 Interrupt Status ...\n"); /*3.Clear the AN_PG_RCV interrupt*/ - ClearBkpAn73Interrupt(2, 0x0, adapter); + clr_bkp_an73_int(2, 0x0, adapter); /*3.1. Get the link partner AN73 Base Page Ability*/ if (KR_MODE) e_dev_info("<3.1>. Get the link partner AN73 Base Page Ability ...\n"); - Get_bkp_an73_ability(&tLpBkpAn73Ability, 1, adapter); + get_bkp_an73_ability(&tLpBkpAn73Ability, 1, adapter); /*3.2. Check the AN73 Link Ability with Link Partner*/ if (KR_MODE) { @@ -189,7 +180,7 @@ int txgbe_kr_intr_handle(struct txgbe_adapter *adapter) e_dev_info(" Local Link Ability: 0x%x\n", tBkpAn73Ability.linkAbility); e_dev_info(" Link Partner Link Ability: 0x%x\n", tLpBkpAn73Ability.linkAbility); } - Check_bkp_an73_ability(tBkpAn73Ability, tLpBkpAn73Ability, adapter); + chk_bkp_an73_ability(tBkpAn73Ability, tLpBkpAn73Ability, adapter); return 0; } @@ -200,7 +191,7 @@ int txgbe_kr_intr_handle(struct txgbe_adapter *adapter) ** 0 : current link mode matched, wait AN73 to be completed ** 1 : current link mode not matched, set to matched link mode, re-start AN73 external */ -int Check_bkp_an73_ability(bkpan73ability tBkpAn73Ability, bkpan73ability tLpBkpAn73Ability, +int chk_bkp_an73_ability(bkpan73ability tBkpAn73Ability, bkpan73ability tLpBkpAn73Ability, struct txgbe_adapter *adapter) { unsigned int comLinkAbility; @@ -215,8 +206,10 @@ int Check_bkp_an73_ability(bkpan73ability tBkpAn73Ability, bkpan73ability tLpBkp comLinkAbility = tBkpAn73Ability.linkAbility & tLpBkpAn73Ability.linkAbility; if (KR_MODE) e_dev_info("comLinkAbility= 0x%x, linkAbility= 0x%x, lpLinkAbility= 0x%x\n", - comLinkAbility, tBkpAn73Ability.linkAbility, tLpBkpAn73Ability.linkAbility); + comLinkAbility, tBkpAn73Ability.linkAbility, + tLpBkpAn73Ability.linkAbility); + /*only support kr*/ if (comLinkAbility == 0) { if (KR_MODE) e_dev_info("WARNING: The Link Partner does not support any compatible speed mode!!!\n\n"); @@ -234,33 +227,8 @@ int Check_bkp_an73_ability(bkpan73ability tBkpAn73Ability, bkpan73ability tLpBkp txgbe_set_link_to_kr(hw, 1); return 1; } - } else if (comLinkAbility & 0x40) { - if (tBkpAn73Ability.currentLinkMode == 0x10) { - if (KR_MODE) - e_dev_info("Link mode is matched with Link Partner: [LINK_KX4].\n"); - return 0; - } else { - if (KR_MODE) { - e_dev_info("Link mode is not matched with Link Partner: [LINK_KX4].\n"); - e_dev_info("Set the local link mode to [LINK_KX4] ...\n"); - } - txgbe_set_link_to_kx4(hw, 1); - return 1; - } - } else if (comLinkAbility & 0x20) { - if (tBkpAn73Ability.currentLinkMode == 0x1) { - if (KR_MODE) - e_dev_info("Link mode is matched with Link Partner: [LINK_KX].\n"); - return 0; - } else { - if (KR_MODE) { - e_dev_info("Link mode is not matched with Link Partner: [LINK_KX].\n"); - e_dev_info("Set the local link mode to [LINK_KX] ...\n"); - } - txgbe_set_link_to_kx(hw, 1, 1); - return 1; - } } + return 0; } @@ -271,7 +239,7 @@ int Check_bkp_an73_ability(bkpan73ability tBkpAn73Ability, bkpan73ability tLpBkp **- 2: Get Link Partner Next Page (only get NXP Ability Register 1 at the moment) **- 0: Get Local Device Base Page */ -int Get_bkp_an73_ability(bkpan73ability *ptBkpAn73Ability, unsigned char byLinkPartner, +int get_bkp_an73_ability(bkpan73ability *pt_bkp_an73_ability, unsigned char byLinkPartner, struct txgbe_adapter *adapter) { int status = 0; @@ -279,7 +247,7 @@ int Get_bkp_an73_ability(bkpan73ability *ptBkpAn73Ability, unsigned char byLinkP struct txgbe_hw *hw = &adapter->hw; if (KR_MODE) { - e_dev_info("GetBkpAn73Ability(): byLinkPartner = %d\n", byLinkPartner); + e_dev_info("get_bkp_an73_ability(): byLinkPartner = %d\n", byLinkPartner); e_dev_info("----------------------------------------\n"); } @@ -288,20 +256,20 @@ int Get_bkp_an73_ability(bkpan73ability *ptBkpAn73Ability, unsigned char byLinkP if (KR_MODE) e_dev_info("Read the link partner AN73 Base Page Ability Registers...\n"); rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70013); + rdata = txgbe_rd32_epcs(hw, TXGBE_SR_AN_MMD_LP_ABL1); if (KR_MODE) e_dev_info("SR AN MMD LP Base Page Ability Register 1: 0x%x\n", rdata); - ptBkpAn73Ability->nextPage = (rdata >> 15) & 0x01; + pt_bkp_an73_ability->nextPage = (rdata >> 15) & 0x01; if (KR_MODE) - e_dev_info(" Next Page (bit15): %d\n", ptBkpAn73Ability->nextPage); + e_dev_info(" Next Page (bit15): %d\n", pt_bkp_an73_ability->nextPage); rdata = 0; rdata = txgbe_rd32_epcs(hw, 0x70014); if (KR_MODE) e_dev_info("SR AN MMD LP Base Page Ability Register 2: 0x%x\n", rdata); - ptBkpAn73Ability->linkAbility = rdata & 0xE0; + pt_bkp_an73_ability->linkAbility = rdata & 0xE0; if (KR_MODE) { - e_dev_info(" Link Ability (bit[15:0]): 0x%x\n", ptBkpAn73Ability->linkAbility); + e_dev_info(" Link Ability (bit[15:0]): 0x%x\n", pt_bkp_an73_ability->linkAbility); e_dev_info(" (0x20- KX_ONLY, 0x40- KX4_ONLY, 0x60- KX4_KX\n"); e_dev_info(" 0x80- KR_ONLY, 0xA0- KR_KX, 0xC0- KR_KX4, 0xE0- KR_KX4_KX)\n"); } @@ -313,7 +281,7 @@ int Get_bkp_an73_ability(bkpan73ability *ptBkpAn73Ability, unsigned char byLinkP e_dev_info(" FEC Request (bit15): %d\n", ((rdata >> 15) & 0x01)); e_dev_info(" FEC Enable (bit14): %d\n", ((rdata >> 14) & 0x01)); } - ptBkpAn73Ability->fecAbility = (rdata >> 14) & 0x03; + pt_bkp_an73_ability->fecAbility = (rdata >> 14) & 0x03; } else if (byLinkPartner == 2) {/*Link Partner Next Page*/ /*Read the link partner AN73 Next Page Ability Registers*/ if (KR_MODE) @@ -322,28 +290,28 @@ int Get_bkp_an73_ability(bkpan73ability *ptBkpAn73Ability, unsigned char byLinkP rdata = txgbe_rd32_epcs(hw, 0x70019); if (KR_MODE) e_dev_info(" SR AN MMD LP XNP Ability Register 1: 0x%x\n", rdata); - ptBkpAn73Ability->nextPage = (rdata >> 15) & 0x01; + pt_bkp_an73_ability->nextPage = (rdata >> 15) & 0x01; if (KR_MODE) - e_dev_info(" Next Page (bit15): %d\n", ptBkpAn73Ability->nextPage); + e_dev_info(" Next Page (bit15): %d\n", pt_bkp_an73_ability->nextPage); } else { /*Read the local AN73 Base Page Ability Registers*/ if (KR_MODE) e_dev_info("\nRead the local AN73 Base Page Ability Registers...\n"); rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70010); + rdata = txgbe_rd32_epcs(hw, TXGBE_SR_AN_MMD_ADV_REG1); if (KR_MODE) e_dev_info("SR AN MMD Advertisement Register 1: 0x%x\n", rdata); - ptBkpAn73Ability->nextPage = (rdata >> 15) & 0x01; + pt_bkp_an73_ability->nextPage = (rdata >> 15) & 0x01; if (KR_MODE) - e_dev_info(" Next Page (bit15): %d\n", ptBkpAn73Ability->nextPage); + e_dev_info(" Next Page (bit15): %d\n", pt_bkp_an73_ability->nextPage); rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70011); + rdata = txgbe_rd32_epcs(hw, TXGBE_SR_AN_MMD_ADV_REG2); if (KR_MODE) e_dev_info("SR AN MMD Advertisement Register 2: 0x%x\n", rdata); - ptBkpAn73Ability->linkAbility = rdata & 0xE0; + pt_bkp_an73_ability->linkAbility = rdata & 0xE0; if (KR_MODE) { - e_dev_info(" Link Ability (bit[15:0]): 0x%x\n", ptBkpAn73Ability->linkAbility); + e_dev_info(" Link Ability (bit[15:0]): 0x%x\n", pt_bkp_an73_ability->linkAbility); e_dev_info(" (0x20- KX_ONLY, 0x40- KX4_ONLY, 0x60- KX4_KX\n"); e_dev_info(" 0x80- KR_ONLY, 0xA0- KR_KX, 0xC0- KR_KX4, 0xE0- KR_KX4_KX)\n"); } @@ -354,122 +322,24 @@ int Get_bkp_an73_ability(bkpan73ability *ptBkpAn73Ability, unsigned char byLinkP e_dev_info(" FEC Request (bit15): %d\n", ((rdata >> 15) & 0x01)); e_dev_info(" FEC Enable (bit14): %d\n", ((rdata >> 14) & 0x01)); } - ptBkpAn73Ability->fecAbility = (rdata >> 14) & 0x03; + pt_bkp_an73_ability->fecAbility = (rdata >> 14) & 0x03; } /*if (byLinkPartner == 1) Link Partner Base Page*/ if (KR_MODE) - e_dev_info("GetBkpAn73Ability() done.\n"); - - return status; -} - - -/*Get Ethernet Backplane AN73 Base Page Ability -**byLinkPartner: -**- 1: Get Link Partner Base Page -**- 2: Get Link Partner Next Page (only get NXP Ability Register 1 at the moment) -**- 0: Get Local Device Base Page -*/ -int GetBkpAn73Ability(bkpan73ability *ptBkpAn73Ability, unsigned char byLinkPartner, - struct txgbe_adapter *adapter) -{ - int status = 0; - unsigned int rdata; - struct txgbe_hw *hw = &adapter->hw; - - if (KR_MODE) { - e_dev_info("GetBkpAn73Ability(): byLinkPartner = %d\n", byLinkPartner); - e_dev_info("----------------------------------------\n"); - } - - if (byLinkPartner == 1) { //Link Partner Base Page - //Read the link partner AN73 Base Page Ability Registers - if (KR_MODE) - e_dev_info("Read the link partner AN73 Base Page Ability Registers...\n"); - rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70013); - if (KR_MODE) - e_dev_info("SR AN MMD LP Base Page Ability Register 1: 0x%x\n", rdata); - ptBkpAn73Ability->nextPage = (rdata >> 15) & 0x01; - if (KR_MODE) - e_dev_info(" Next Page (bit15): %d\n", ptBkpAn73Ability->nextPage); - - rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70014); - if (KR_MODE) - e_dev_info("SR AN MMD LP Base Page Ability Register 2: 0x%x\n", rdata); - ptBkpAn73Ability->linkAbility = rdata & 0xE0; - if (KR_MODE) { - e_dev_info(" Link Ability (bit[15:0]): 0x%x\n", ptBkpAn73Ability->linkAbility); - e_dev_info(" (0x20- KX_ONLY, 0x40- KX4_ONLY, 0x60- KX4_KX\n"); - e_dev_info(" 0x80- KR_ONLY, 0xA0- KR_KX, 0xC0- KR_KX4, 0xE0- KR_KX4_KX)\n"); - } - - rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70015); - printk("SR AN MMD LP Base Page Ability Register 3: 0x%x\n", rdata); - printk(" FEC Request (bit15): %d\n", ((rdata >> 15) & 0x01)); - printk(" FEC Enable (bit14): %d\n", ((rdata >> 14) & 0x01)); - ptBkpAn73Ability->fecAbility = (rdata >> 14) & 0x03; - } else if (byLinkPartner == 2) { //Link Partner Next Page - //Read the link partner AN73 Next Page Ability Registers - if (KR_MODE) - e_dev_info("Read the link partner AN73 Next Page Ability Registers...\n"); - rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70019); - if (KR_MODE) - e_dev_info(" SR AN MMD LP XNP Ability Register 1: 0x%x\n", rdata); - ptBkpAn73Ability->nextPage = (rdata >> 15) & 0x01; - if (KR_MODE) - e_dev_info(" Next Page (bit15): %d\n", ptBkpAn73Ability->nextPage); - } else { - //Read the local AN73 Base Page Ability Registers - if (KR_MODE) - e_dev_info("Read the local AN73 Base Page Ability Registers...\n"); - rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70010); - if (KR_MODE) - e_dev_info("SR AN MMD Advertisement Register 1: 0x%x\n", rdata); - ptBkpAn73Ability->nextPage = (rdata >> 15) & 0x01; - if (KR_MODE) - e_dev_info(" Next Page (bit15): %d\n", ptBkpAn73Ability->nextPage); - - rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70011); - if (KR_MODE) - e_dev_info("SR AN MMD Advertisement Register 2: 0x%x\n", rdata); - ptBkpAn73Ability->linkAbility = rdata & 0xE0; - if (KR_MODE) { - e_dev_info(" Link Ability (bit[15:0]): 0x%x\n", ptBkpAn73Ability->linkAbility); - e_dev_info(" (0x20- KX_ONLY, 0x40- KX4_ONLY, 0x60- KX4_KX\n"); - e_dev_info(" 0x80- KR_ONLY, 0xA0- KR_KX, 0xC0- KR_KX4, 0xE0- KR_KX4_KX)\n"); - } - - rdata = 0; - rdata = txgbe_rd32_epcs(hw, 0x70012); - if (KR_MODE) { - e_dev_info("SR AN MMD Advertisement Register 3: 0x%x\n", rdata); - e_dev_info(" FEC Request (bit15): %d\n", ((rdata >> 15) & 0x01)); - e_dev_info(" FEC Enable (bit14): %d\n", ((rdata >> 14) & 0x01)); - } - ptBkpAn73Ability->fecAbility = (rdata >> 14) & 0x03; - } - - if (KR_MODE) - e_dev_info("GetBkpAn73Ability() done.\n"); + e_dev_info("get_bkp_an73_ability() done.\n"); return status; } /* DESCRIPTION: Set the source data fields[bitHigh:bitLow] with setValue -** INPUTS: *pSrcData: Source data pointer +** INPUTS: *src_data: Source data pointer ** bitHigh: High bit position of the fields ** bitLow : Low bit position of the fields ** setValue: Set value of the fields ** OUTPUTS: return the updated source data */ -static void SetFields( - unsigned int *pSrcData, +static void set_fields( + unsigned int *src_data, unsigned int bitHigh, unsigned int bitLow, unsigned int setValue) @@ -478,28 +348,28 @@ static void SetFields( if (bitHigh == bitLow) { if (setValue == 0) { - *pSrcData &= ~(1 << bitLow); + *src_data &= ~(1 << bitLow); } else { - *pSrcData |= (1 << bitLow); + *src_data |= (1 << bitLow); } } else { for (i = bitLow; i <= bitHigh; i++) { - *pSrcData &= ~(1 << i); + *src_data &= ~(1 << i); } - *pSrcData |= (setValue << bitLow); + *src_data |= (setValue << bitLow); } } -/*Check Ethernet Backplane AN73 Interrupt status +/* Check Ethernet Backplane AN73 Interrupt status **- return the value of select interrupt index */ -int CheckBkpAn73Interrupt(unsigned int intIndex, struct txgbe_adapter *adapter) +int chk_bkp_an73_Int(unsigned int intIndex, struct txgbe_adapter *adapter) { unsigned int rdata; struct txgbe_hw *hw = &adapter->hw; if (KR_MODE) { - e_dev_info("CheckBkpAn73Interrupt(): intIndex = %d\n", intIndex); + e_dev_info("chk_bkp_an73_Int(): intIndex = %d\n", intIndex); e_dev_info("----------------------------------------\n"); } @@ -513,11 +383,11 @@ int CheckBkpAn73Interrupt(unsigned int intIndex, struct txgbe_adapter *adapter) return ((rdata >> intIndex) & 0x01); } -/*Clear Ethernet Backplane AN73 Interrupt status +/* Clear Ethernet Backplane AN73 Interrupt status **- intIndexHi =0, only intIndex bit will be cleared **- intIndexHi !=0, the [intIndexHi, intIndex] range will be cleared */ -int ClearBkpAn73Interrupt(unsigned int intIndex, unsigned int intIndexHi, struct txgbe_adapter *adapter) +int clr_bkp_an73_int(unsigned int intIndex, unsigned int intIndexHi, struct txgbe_adapter *adapter) { int status = 0; unsigned int rdata, wdata; @@ -535,9 +405,9 @@ int ClearBkpAn73Interrupt(unsigned int intIndex, unsigned int intIndexHi, struct wdata = rdata; if (intIndexHi) { - SetFields(&wdata, intIndexHi, intIndex, 0); + set_fields(&wdata, intIndexHi, intIndex, 0); } else { - SetFields(&wdata, intIndex, intIndex, 0); + set_fields(&wdata, intIndex, intIndex, 0); } txgbe_wr32_epcs(hw, 0x78002, wdata); @@ -551,7 +421,7 @@ int ClearBkpAn73Interrupt(unsigned int intIndex, unsigned int intIndexHi, struct return status; } -int WaitBkpAn73XnpDone(struct txgbe_adapter *adapter) +int wait_bkp_an73_xnp_done(struct txgbe_adapter *adapter) { int status = 0; unsigned int timer = 0; @@ -559,12 +429,12 @@ int WaitBkpAn73XnpDone(struct txgbe_adapter *adapter) /*while(timer++ < BKPAN73_TIMEOUT)*/ while (timer++ < 20) { - if (CheckBkpAn73Interrupt(2, adapter)) { + if (chk_bkp_an73_Int(2, adapter)) { /*Clear the AN_PG_RCV interrupt*/ - ClearBkpAn73Interrupt(2, 0, adapter); + clr_bkp_an73_int(2, 0, adapter); /*Get the link partner AN73 Next Page Ability*/ - Get_bkp_an73_ability(&tLpBkpAn73Ability, 2, adapter); + get_bkp_an73_ability(&tLpBkpAn73Ability, 2, adapter); /*Return when AN_LP_XNP_NP == 0, (bit[15]: Next Page)*/ if (tLpBkpAn73Ability.nextPage == 0) { @@ -579,7 +449,7 @@ int WaitBkpAn73XnpDone(struct txgbe_adapter *adapter) return -1; } -int ReadPhyLaneTxEq(unsigned short lane, struct txgbe_adapter *adapter, int post_t, int mode) +int read_phy_lane_txeq(unsigned short lane, struct txgbe_adapter *adapter, int post_t, int mode) { int status = 0; unsigned int addr, rdata; @@ -642,7 +512,7 @@ int ReadPhyLaneTxEq(unsigned short lane, struct txgbe_adapter *adapter, int post **- bits[1:0] =2'b11: Enable the CL72 KR training **- bits[1:0] =2'b01: Disable the CL72 KR training */ -int EnableCl72KrTr(unsigned int enable, struct txgbe_adapter *adapter) +int en_cl72_krtr(unsigned int enable, struct txgbe_adapter *adapter) { int status = 0; unsigned int wdata = 0; @@ -651,15 +521,15 @@ int EnableCl72KrTr(unsigned int enable, struct txgbe_adapter *adapter) if (enable == 1) { if (KR_MODE) e_dev_info("\nDisable Clause 72 KR Training ...\n"); - status |= ReadPhyLaneTxEq(0, adapter, 0, 0); + status |= read_phy_lane_txeq(0, adapter, 0, 0); } else if (enable == 4) { - status |= ReadPhyLaneTxEq(0, adapter, 20, 1); + status |= read_phy_lane_txeq(0, adapter, 20, 1); } else if (enable == 8) { - status |= ReadPhyLaneTxEq(0, adapter, 16, 1); + status |= read_phy_lane_txeq(0, adapter, 16, 1); } else if (enable == 12) { - status |= ReadPhyLaneTxEq(0, adapter, 24, 1); + status |= read_phy_lane_txeq(0, adapter, 24, 1); } else if (enable == 5) { - status |= ReadPhyLaneTxEq(0, adapter, 0, 1); + status |= read_phy_lane_txeq(0, adapter, 0, 1); } else if (enable == 3) { if (KR_MODE) e_dev_info("\nEnable Clause 72 KR Training ...\n"); @@ -674,15 +544,15 @@ int EnableCl72KrTr(unsigned int enable, struct txgbe_adapter *adapter) /*Enable PRBS Mode to determine KR Training Status by setting Bit 0 of VR_PMA_KRTR_PRBS_CTRL0 Register*/ wdata = 0; - SetFields(&wdata, 0, 0, 1); + set_fields(&wdata, 0, 0, 1); } #ifdef CL72_KRTR_PRBS31_EN /*Enable PRBS31 as the KR Training Pattern by setting Bit 1 of VR_PMA_KRTR_PRBS_CTRL0 Register*/ - SetFields(&wdata, 1, 1, 1); + set_fields(&wdata, 1, 1, 1); #endif /*#ifdef CL72_KRTR_PRBS31_EN*/ txgbe_wr32_epcs(hw, 0x18003, wdata); - status |= ReadPhyLaneTxEq(0, adapter, 0, 0); + status |= read_phy_lane_txeq(0, adapter, 0, 0); } else { if (KR_MODE) e_dev_info("\nInvalid setting for Clause 72 KR Training!!!\n"); @@ -696,7 +566,7 @@ int EnableCl72KrTr(unsigned int enable, struct txgbe_adapter *adapter) return status; } -int CheckCl72KrTrStatus(struct txgbe_adapter *adapter) +int chk_cl72_krtr_status(struct txgbe_adapter *adapter) { int status = 0; unsigned int addr, rdata, rdata1; @@ -753,7 +623,7 @@ int CheckCl72KrTrStatus(struct txgbe_adapter *adapter) if ((rdata >> 3) & 0x01) { if (KR_MODE) e_dev_info("Training is completed with failure!!!\n"); - status |= ReadPhyLaneTxEq(0, adapter, 0, 0); + status |= read_phy_lane_txeq(0, adapter, 0, 0); return status; } @@ -761,7 +631,7 @@ int CheckCl72KrTrStatus(struct txgbe_adapter *adapter) if ((rdata >> 0) & 0x01) { if (KR_MODE) e_dev_info("Receiver trained and ready to receive data ^_^\n"); - status |= ReadPhyLaneTxEq(0, adapter, 0, 0); + status |= read_phy_lane_txeq(0, adapter, 0, 0); return status; } @@ -774,7 +644,7 @@ int CheckCl72KrTrStatus(struct txgbe_adapter *adapter) return status; } -int Handle_bkp_an73_flow(unsigned char byLinkMode, struct txgbe_adapter *adapter) +int handle_bkp_an73_flow(unsigned char bp_link_mode, struct txgbe_adapter *adapter) { int status = 0; unsigned int timer = 0; @@ -784,92 +654,90 @@ int Handle_bkp_an73_flow(unsigned char byLinkMode, struct txgbe_adapter *adapter u32 rdata = 0; u32 rdata1 = 0; struct txgbe_hw *hw = &adapter->hw; - tBkpAn73Ability.currentLinkMode = byLinkMode; + tBkpAn73Ability.currentLinkMode = bp_link_mode; if (KR_MODE) { e_dev_info("HandleBkpAn73Flow() \n"); e_dev_info("---------------------------------\n"); } - txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x0); - txgbe_wr32_epcs(hw, 0x78003, 0x0); + if (adapter->an73_mode == 0) { + txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x0); + txgbe_wr32_epcs(hw, TXGBE_VR_AN_KR_MODE_CL, 0x0); + } /*Check the FEC and KR Training for KR mode*/ - if (1) { - //FEC handling + if (KR_MODE) + e_dev_info("<3.3>. Check the FEC for KR mode ...\n"); + tBkpAn73Ability.fecAbility = 0x03; + tLpBkpAn73Ability.fecAbility = 0x3; + if ((tBkpAn73Ability.fecAbility & tLpBkpAn73Ability.fecAbility) == 0x03) { if (KR_MODE) - e_dev_info("<3.3>. Check the FEC for KR mode ...\n"); - tBkpAn73Ability.fecAbility = 0x03; - tLpBkpAn73Ability.fecAbility = 0x0; - if ((tBkpAn73Ability.fecAbility & tLpBkpAn73Ability.fecAbility) == 0x03) { - if (KR_MODE) - e_dev_info("Enable the Backplane KR FEC ...\n"); - //Write 1 to SR_PMA_KR_FEC_CTRL bit0 to enable the FEC - data = 1; - addr = 0x100ab; //SR_PMA_KR_FEC_CTRL - txgbe_wr32_epcs(hw, addr, data); - } else { - if (KR_MODE) - e_dev_info("Backplane KR FEC is disabled.\n"); + e_dev_info("Enable the Backplane KR FEC ...\n"); + //Write 1 to SR_PMA_KR_FEC_CTRL bit0 to enable the FEC + data = 1; + addr = 0x100ab; //SR_PMA_KR_FEC_CTRL + txgbe_wr32_epcs(hw, addr, data); + } else { + if (KR_MODE) + e_dev_info("Backplane KR FEC is disabled.\n"); + } + + for (i = 0; i < 2; i++) { + if (KR_MODE) { + e_dev_info("\n<3.4>. Check the CL72 KR Training for KR mode ...\n"); + printk("===================%d=======================\n", i); } -#ifdef CL72_KR_TRAINING_ON - for (i = 0; i < 2; i++) { - if (KR_MODE) { - e_dev_info("\n<3.4>. Check the CL72 KR Training for KR mode ...\n"); - printk("===================%d=======================\n", i); - } - status |= EnableCl72KrTr(3, adapter); + status |= en_cl72_krtr(3, adapter); - if (KR_MODE) - e_dev_info("\nCheck the Clause 72 KR Training status ...\n"); - status |= CheckCl72KrTrStatus(adapter); + if (KR_MODE) + e_dev_info("\nCheck the Clause 72 KR Training status ...\n"); + status |= chk_cl72_krtr_status(adapter); - rdata = txgbe_rd32_epcs(hw, 0x10099) & 0x8000; - if (KR_MODE) - e_dev_info("SR PMA MMD 10GBASE-KR LP Coefficient Status Register: 0x%x\n", rdata); - rdata1 = txgbe_rd32_epcs(hw, 0x1009b) & 0x8000; - if (KR_MODE) - e_dev_info("SR PMA MMD 10GBASE-KR LP Coefficient Status Register: 0x%x\n", rdata1); - if (KR_POLLING == 0) { - if (adapter->flags2 & KR) { - rdata = 0x8000; - adapter->flags2 &= ~KR; - } + rdata = txgbe_rd32_epcs(hw, 0x10099) & 0x8000; + if (KR_MODE) + e_dev_info("SR PMA MMD 10GBASE-KR LP Coefficient Status Register: 0x%x\n", rdata); + rdata1 = txgbe_rd32_epcs(hw, 0x1009b) & 0x8000; + if (KR_MODE) + e_dev_info("SR PMA MMD 10GBASE-KR LP Coefficient Status Register: 0x%x\n", rdata1); + if (KR_POLLING == 0) { + if (adapter->flags2 & KR) { + rdata = 0x8000; + adapter->flags2 &= ~KR; } - if ((rdata == 0x8000) & (rdata1 == 0x8000)) { - if (KR_MODE) - e_dev_info("====================out===========================\n"); - status |= EnableCl72KrTr(1, adapter); - txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x0000); - ClearBkpAn73Interrupt(2, 0, adapter); - ClearBkpAn73Interrupt(1, 0, adapter); - ClearBkpAn73Interrupt(0, 0, adapter); - while (timer++ < 10) { - rdata = txgbe_rd32_epcs(hw, 0x30020); - rdata = rdata & 0x1000; - if (rdata == 0x1000) { - if (KR_MODE) - e_dev_info("\nINT_AN_INT_CMPLT =1, AN73 Done Success.\n"); - e_dev_info("AN73 Done Success.\n"); - txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x0000); - return 0; - } - msleep(10); + } + if ((rdata == 0x8000) & (rdata1 == 0x8000)) { + if (KR_MODE) + e_dev_info("====================out===========================\n"); + status |= en_cl72_krtr(1, adapter); + clr_bkp_an73_int(2, 0, adapter); + clr_bkp_an73_int(1, 0, adapter); + clr_bkp_an73_int(0, 0, adapter); + + while (timer++ < 10) { + rdata = txgbe_rd32_epcs(hw, 0x30020); + rdata = rdata & 0x1000; + if (rdata == 0x1000) { + if (KR_MODE) + e_dev_info("\nINT_AN_INT_CMPLT =1, AN73 Done Success.\n"); + e_dev_info("AN73 Done Success.\n"); + txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x0000); + txgbe_wr32_epcs(hw, TXGBE_VR_AN_KR_MODE_CL, 0x0); + return 0; } - msleep(1000); - txgbe_set_link_to_kr(hw, 1); - - return 0; + msleep(10); } - status |= EnableCl72KrTr(1, adapter); + return 0; } -#endif + + status |= en_cl72_krtr(1, adapter); } - ClearBkpAn73Interrupt(0, 0, adapter); - ClearBkpAn73Interrupt(1, 0, adapter); - ClearBkpAn73Interrupt(2, 0, adapter); + + clr_bkp_an73_int(0, 0, adapter); + clr_bkp_an73_int(1, 0, adapter); + clr_bkp_an73_int(2, 0, adapter); return status; } diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_debugfs.c b/drivers/net/ethernet/netswift/txgbe/txgbe_debugfs.c new file mode 100644 index 0000000000000000000000000000000000000000..0d65dc7566dc7dbeb1bc484e6a25d60462c6173e --- /dev/null +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_debugfs.c @@ -0,0 +1,788 @@ +/* + * WangXun 10 Gigabit PCI Express Linux driver + * Copyright (c) 2015 - 2017 Beijing WangXun Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * The full GNU General Public License is included in this distribution in + * the file called "COPYING". + * + * based on ixgbe_debugfs.c, Copyright(c) 1999 - 2017 Intel Corporation. + * Contact Information: + * Linux NICS + * e1000-devel Mailing List + * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + */ + + +#include "txgbe.h" + +#ifdef CONFIG_TXGBE_DEBUG_FS +#include +#include + +static struct dentry *txgbe_dbg_root; +static int txgbe_data_mode; + +#define TXGBE_DATA_FUNC(dm) ((dm) & ~0xFFFF) +#define TXGBE_DATA_ARGS(dm) ((dm) & 0xFFFF) +enum txgbe_data_func { + TXGBE_FUNC_NONE = (0 << 16), + TXGBE_FUNC_DUMP_BAR = (1 << 16), + TXGBE_FUNC_DUMP_RDESC = (2 << 16), + TXGBE_FUNC_DUMP_TDESC = (3 << 16), + TXGBE_FUNC_FLASH_READ = (4 << 16), + TXGBE_FUNC_FLASH_WRITE = (5 << 16), +}; + +/** + * data operation + **/ +ssize_t +txgbe_simple_read_from_pcibar(struct txgbe_adapter *adapter, int res, + void __user *buf, size_t size, loff_t *ppos) +{ + loff_t pos = *ppos; + u32 miss, len, limit = pci_resource_len(adapter->pdev, res); + + if (pos < 0) + return 0; + + limit = (pos + size <= limit ? pos + size : limit); + for (miss = 0; pos < limit && !miss; buf += len, pos += len) { + u32 val = 0, reg = round_down(pos, 4); + u32 off = pos - reg; + + len = (reg + 4 <= limit ? 4 - off : 4 - off - (limit - reg - 4)); + val = txgbe_rd32(adapter->io_addr + reg); + miss = copy_to_user(buf, &val + off, len); + } + + size = pos - *ppos - miss; + *ppos += size; + + return size; +} + +ssize_t +txgbe_simple_read_from_flash(struct txgbe_adapter *adapter, + void __user *buf, size_t size, loff_t *ppos) +{ + struct txgbe_hw *hw = &adapter->hw; + loff_t pos = *ppos; + size_t ret = 0; + loff_t rpos, rtail; + void __user *to = buf; + size_t available = adapter->hw.flash.dword_size << 2; + + if (pos < 0) + return -EINVAL; + if (pos >= available || !size) + return 0; + if (size > available - pos) + size = available - pos; + + rpos = round_up(pos, 4); + rtail = round_down(pos + size, 4); + if (rtail < rpos) + return 0; + + to += rpos - pos; + while (rpos <= rtail) { + u32 value = txgbe_rd32(adapter->io_addr + rpos); + if (TCALL(hw, flash.ops.write_buffer, rpos>>2, 1, &value)) { + ret = size; + break; + } + if (4 == copy_to_user(to, &value, 4)) { + ret = size; + break; + } + to += 4; + rpos += 4; + } + + if (ret == size) + return -EFAULT; + size -= ret; + *ppos = pos + size; + return size; +} + +ssize_t +txgbe_simple_write_to_flash(struct txgbe_adapter *adapter, + const void __user *from, size_t size, loff_t *ppos, size_t available) +{ + return size; +} + +static ssize_t +txgbe_dbg_data_ops_read(struct file *filp, char __user *buffer, + size_t size, loff_t *ppos) +{ + struct txgbe_adapter *adapter = filp->private_data; + u32 func = TXGBE_DATA_FUNC(txgbe_data_mode); + + rmb(); + + switch (func) { + case TXGBE_FUNC_DUMP_BAR: { + u32 bar = TXGBE_DATA_ARGS(txgbe_data_mode); + + return txgbe_simple_read_from_pcibar(adapter, bar, buffer, size, + ppos); + break; + } + case TXGBE_FUNC_FLASH_READ: { + return txgbe_simple_read_from_flash(adapter, buffer, size, ppos); + break; + } + case TXGBE_FUNC_DUMP_RDESC: { + struct txgbe_ring *ring; + u32 queue = TXGBE_DATA_ARGS(txgbe_data_mode); + + if (queue >= adapter->num_rx_queues) + return 0; + queue += VMDQ_P(0) * adapter->queues_per_pool; + ring = adapter->rx_ring[queue]; + + return simple_read_from_buffer(buffer, size, ppos, + ring->desc, ring->size); + break; + } + case TXGBE_FUNC_DUMP_TDESC: { + struct txgbe_ring *ring; + u32 queue = TXGBE_DATA_ARGS(txgbe_data_mode); + + if (queue >= adapter->num_tx_queues) + return 0; + queue += VMDQ_P(0) * adapter->queues_per_pool; + ring = adapter->tx_ring[queue]; + + return simple_read_from_buffer(buffer, size, ppos, + ring->desc, ring->size); + break; + } + default: + break; + } + + return 0; +} + +static ssize_t +txgbe_dbg_data_ops_write(struct file *filp, + const char __user *buffer, + size_t size, loff_t *ppos) +{ + struct txgbe_adapter *adapter = filp->private_data; + u32 func = TXGBE_DATA_FUNC(txgbe_data_mode); + + rmb(); + + switch (func) { + case TXGBE_FUNC_FLASH_WRITE: { + u32 size = TXGBE_DATA_ARGS(txgbe_data_mode); + + if (size > adapter->hw.flash.dword_size << 2) + size = adapter->hw.flash.dword_size << 2; + + return txgbe_simple_write_to_flash(adapter, buffer, size, ppos, size); + break; + } + default: + break; + } + + return size; +} + +static struct file_operations txgbe_dbg_data_ops_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = txgbe_dbg_data_ops_read, + .write = txgbe_dbg_data_ops_write, +}; + +/** + * reg_ops operation + **/ +static char txgbe_dbg_reg_ops_buf[256] = ""; +static ssize_t +txgbe_dbg_reg_ops_read(struct file *filp, char __user *buffer, + size_t count, loff_t *ppos) +{ + struct txgbe_adapter *adapter = filp->private_data; + char *buf; + int len; + + /* don't allow partial reads */ + if (*ppos != 0) + return 0; + + buf = kasprintf(GFP_KERNEL, "%s: mode=0x%08x\n%s\n", + adapter->netdev->name, txgbe_data_mode, + txgbe_dbg_reg_ops_buf); + if (!buf) + return -ENOMEM; + + if (count < strlen(buf)) { + kfree(buf); + return -ENOSPC; + } + + len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); + + kfree(buf); + return len; +} + +static ssize_t +txgbe_dbg_reg_ops_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct txgbe_adapter *adapter = filp->private_data; + char *pc = txgbe_dbg_reg_ops_buf; + int len; + + /* don't allow partial writes */ + if (*ppos != 0) + return 0; + if (count >= sizeof(txgbe_dbg_reg_ops_buf)) + return -ENOSPC; + + len = simple_write_to_buffer(txgbe_dbg_reg_ops_buf, + sizeof(txgbe_dbg_reg_ops_buf) - 1, + ppos, + buffer, + count); + if (len < 0) + return len; + + pc[len] = '\0'; + + if (strncmp(pc, "dump", 4) == 0) { + u32 mode = 0; + u16 args; + + pc += 4; + pc += strspn(pc, " \t"); + + if (!strncmp(pc, "bar", 3)) { + pc += 3; + mode = TXGBE_FUNC_DUMP_BAR; + } else if (!strncmp(pc, "rdesc", 5)) { + pc += 5; + mode = TXGBE_FUNC_DUMP_RDESC; + } else if (!strncmp(pc, "tdesc", 5)) { + pc += 5; + mode = TXGBE_FUNC_DUMP_TDESC; + } else { + txgbe_dump(adapter); + } + + if (mode && 1 == sscanf(pc, "%hu", &args)) { + mode |= args; + } + + txgbe_data_mode = mode; + } else if (strncmp(pc, "flash", 4) == 0) { + u32 mode = 0; + u16 args; + + pc += 5; + pc += strspn(pc, " \t"); + if (!strncmp(pc, "read", 3)) { + pc += 4; + mode = TXGBE_FUNC_FLASH_READ; + } else if (!strncmp(pc, "write", 5)) { + pc += 5; + mode = TXGBE_FUNC_FLASH_WRITE; + } + + if (mode && 1 == sscanf(pc, "%hu", &args)) { + mode |= args; + } + + txgbe_data_mode = mode; + } else if (strncmp(txgbe_dbg_reg_ops_buf, "write", 5) == 0) { + u32 reg, value; + int cnt; + cnt = sscanf(&txgbe_dbg_reg_ops_buf[5], "%x %x", ®, &value); + if (cnt == 2) { + wr32(&adapter->hw, reg, value); + e_dev_info("write: 0x%08x = 0x%08x\n", reg, value); + } else { + e_dev_info("write \n"); + } + } else if (strncmp(txgbe_dbg_reg_ops_buf, "read", 4) == 0) { + u32 reg, value; + int cnt; + cnt = sscanf(&txgbe_dbg_reg_ops_buf[4], "%x", ®); + if (cnt == 1) { + value = rd32(&adapter->hw, reg); + e_dev_info("read 0x%08x = 0x%08x\n", reg, value); + } else { + e_dev_info("read \n"); + } + } else { + e_dev_info("Unknown command %s\n", txgbe_dbg_reg_ops_buf); + e_dev_info("Available commands:\n"); + e_dev_info(" read \n"); + e_dev_info(" write \n"); + } + return count; +} + +static const struct file_operations txgbe_dbg_reg_ops_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = txgbe_dbg_reg_ops_read, + .write = txgbe_dbg_reg_ops_write, +}; + +/** + * netdev_ops operation + **/ +static char txgbe_dbg_netdev_ops_buf[256] = ""; +static ssize_t +txgbe_dbg_netdev_ops_read(struct file *filp, + char __user *buffer, + size_t count, loff_t *ppos) +{ + struct txgbe_adapter *adapter = filp->private_data; + char *buf; + int len; + + /* don't allow partial reads */ + if (*ppos != 0) + return 0; + + buf = kasprintf(GFP_KERNEL, "%s: mode=0x%08x\n%s\n", + adapter->netdev->name, txgbe_data_mode, + txgbe_dbg_netdev_ops_buf); + if (!buf) + return -ENOMEM; + + if (count < strlen(buf)) { + kfree(buf); + return -ENOSPC; + } + + len = simple_read_from_buffer(buffer, count, ppos, buf, strlen(buf)); + + kfree(buf); + return len; +} + +static ssize_t +txgbe_dbg_netdev_ops_write(struct file *filp, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct txgbe_adapter *adapter = filp->private_data; + int len; + + /* don't allow partial writes */ + if (*ppos != 0) + return 0; + if (count >= sizeof(txgbe_dbg_netdev_ops_buf)) + return -ENOSPC; + + len = simple_write_to_buffer(txgbe_dbg_netdev_ops_buf, + sizeof(txgbe_dbg_netdev_ops_buf)-1, + ppos, + buffer, + count); + if (len < 0) + return len; + + txgbe_dbg_netdev_ops_buf[len] = '\0'; + + if (strncmp(txgbe_dbg_netdev_ops_buf, "tx_timeout", 10) == 0) { + adapter->netdev->netdev_ops->ndo_tx_timeout(adapter->netdev, UINT_MAX); + e_dev_info("tx_timeout called\n"); + } else { + e_dev_info("Unknown command: %s\n", txgbe_dbg_netdev_ops_buf); + e_dev_info("Available commands:\n"); + e_dev_info(" tx_timeout\n"); + } + return count; +} + +static struct file_operations txgbe_dbg_netdev_ops_fops = { + .owner = THIS_MODULE, + .open = simple_open, + .read = txgbe_dbg_netdev_ops_read, + .write = txgbe_dbg_netdev_ops_write, +}; + +/** + * txgbe_dbg_adapter_init - setup the debugfs directory for the adapter + * @adapter: the adapter that is starting up + **/ +void txgbe_dbg_adapter_init(struct txgbe_adapter *adapter) +{ + const char *name = pci_name(adapter->pdev); + struct dentry *pfile; + + adapter->txgbe_dbg_adapter = debugfs_create_dir(name, txgbe_dbg_root); + if (!adapter->txgbe_dbg_adapter) { + e_dev_err("debugfs entry for %s failed\n", name); + return; + } + + pfile = debugfs_create_file("data", 0600, + adapter->txgbe_dbg_adapter, adapter, + &txgbe_dbg_data_ops_fops); + if (!pfile) + e_dev_err("debugfs netdev_ops for %s failed\n", name); + + pfile = debugfs_create_file("reg_ops", 0600, + adapter->txgbe_dbg_adapter, adapter, + &txgbe_dbg_reg_ops_fops); + if (!pfile) + e_dev_err("debugfs reg_ops for %s failed\n", name); + + pfile = debugfs_create_file("netdev_ops", 0600, + adapter->txgbe_dbg_adapter, adapter, + &txgbe_dbg_netdev_ops_fops); + if (!pfile) + e_dev_err("debugfs netdev_ops for %s failed\n", name); +} + +/** + * txgbe_dbg_adapter_exit - clear out the adapter's debugfs entries + * @pf: the pf that is stopping + **/ +void txgbe_dbg_adapter_exit(struct txgbe_adapter *adapter) +{ + if (adapter->txgbe_dbg_adapter) + debugfs_remove_recursive(adapter->txgbe_dbg_adapter); + adapter->txgbe_dbg_adapter = NULL; +} + +/** + * txgbe_dbg_init - start up debugfs for the driver + **/ +void txgbe_dbg_init(void) +{ + txgbe_dbg_root = debugfs_create_dir(txgbe_driver_name, NULL); + if (txgbe_dbg_root == NULL) + pr_err("init of debugfs failed\n"); +} + +/** + * txgbe_dbg_exit - clean out the driver's debugfs entries + **/ +void txgbe_dbg_exit(void) +{ + debugfs_remove_recursive(txgbe_dbg_root); +} + +#endif /* CONFIG_TXGBE_DEBUG_FS */ + +struct txgbe_reg_info { + u32 offset; + u32 length; + char *name; +}; + +static struct txgbe_reg_info txgbe_reg_info_tbl[] = { + + /* General Registers */ + {TXGBE_CFG_PORT_CTL, 1, "CTRL"}, + {TXGBE_CFG_PORT_ST, 1, "STATUS"}, + + /* RX Registers */ + {TXGBE_PX_RR_CFG(0), 1, "SRRCTL"}, + {TXGBE_PX_RR_RP(0), 1, "RDH"}, + {TXGBE_PX_RR_WP(0), 1, "RDT"}, + {TXGBE_PX_RR_CFG(0), 1, "RXDCTL"}, + {TXGBE_PX_RR_BAL(0), 1, "RDBAL"}, + {TXGBE_PX_RR_BAH(0), 1, "RDBAH"}, + + /* TX Registers */ + {TXGBE_PX_TR_BAL(0), 1, "TDBAL"}, + {TXGBE_PX_TR_BAH(0), 1, "TDBAH"}, + {TXGBE_PX_TR_RP(0), 1, "TDH"}, + {TXGBE_PX_TR_WP(0), 1, "TDT"}, + {TXGBE_PX_TR_CFG(0), 1, "TXDCTL"}, + + /* MACVLAN */ + {TXGBE_PSR_MAC_SWC_VM_H, 128, "PSR_MAC_SWC_VM"}, + {TXGBE_PSR_MAC_SWC_AD_L, 128, "PSR_MAC_SWC_AD"}, + {TXGBE_PSR_VLAN_TBL(0), 128, "PSR_VLAN_TBL"}, + + /* QoS */ + {TXGBE_TDM_RP_RATE, 128, "TDM_RP_RATE"}, + + /* List Terminator */ + { .name = NULL } +}; + +/** + * txgbe_regdump - register printout routine + **/ +static void +txgbe_regdump(struct txgbe_hw *hw, struct txgbe_reg_info *reg_info) +{ + int i, n = 0; + u32 buffer[32*8]; + + switch (reg_info->offset) { + case TXGBE_PSR_MAC_SWC_VM_H: + for (i = 0; i < reg_info->length; i++) { + wr32(hw, TXGBE_PSR_MAC_SWC_IDX, i); + buffer[n++] = + rd32(hw, TXGBE_PSR_MAC_SWC_VM_H); + buffer[n++] = + rd32(hw, TXGBE_PSR_MAC_SWC_VM_L); + } + break; + case TXGBE_PSR_MAC_SWC_AD_L: + for (i = 0; i < reg_info->length; i++) { + wr32(hw, TXGBE_PSR_MAC_SWC_IDX, i); + buffer[n++] = + rd32(hw, TXGBE_PSR_MAC_SWC_AD_H); + buffer[n++] = + rd32(hw, TXGBE_PSR_MAC_SWC_AD_L); + } + break; + case TXGBE_TDM_RP_RATE: + for (i = 0; i < reg_info->length; i++) { + wr32(hw, TXGBE_TDM_RP_IDX, i); + buffer[n++] = rd32(hw, TXGBE_TDM_RP_RATE); + } + break; + default: + for (i = 0; i < reg_info->length; i++) { + buffer[n++] = rd32(hw, + reg_info->offset + 4*i); + } + break; + } + BUG_ON(n); +} + +/** + * txgbe_dump - Print registers, tx-rings and rx-rings + **/ +void txgbe_dump(struct txgbe_adapter *adapter) +{ + struct net_device *netdev = adapter->netdev; + struct txgbe_hw *hw = &adapter->hw; + struct txgbe_reg_info *reg_info; + int n = 0; + struct txgbe_ring *tx_ring; + struct txgbe_tx_buffer *tx_buffer; + union txgbe_tx_desc *tx_desc; + struct my_u0 { u64 a; u64 b; } *u0; + struct txgbe_ring *rx_ring; + union txgbe_rx_desc *rx_desc; + struct txgbe_rx_buffer *rx_buffer_info; + u32 staterr; + int i = 0; + + if (!netif_msg_hw(adapter)) + return; + + /* Print Registers */ + dev_info(&adapter->pdev->dev, "Register Dump\n"); + pr_info(" Register Name Value\n"); + for (reg_info = txgbe_reg_info_tbl; reg_info->name; reg_info++) { + txgbe_regdump(hw, reg_info); + } + + /* Print TX Ring Summary */ + if (!netdev || !netif_running(netdev)) + return; + + dev_info(&adapter->pdev->dev, "TX Rings Summary\n"); + pr_info(" %s %s %s %s\n", + "Queue [NTU] [NTC] [bi(ntc)->dma ]", + "leng", "ntw", "timestamp"); + for (n = 0; n < adapter->num_tx_queues; n++) { + tx_ring = adapter->tx_ring[n]; + tx_buffer = &tx_ring->tx_buffer_info[tx_ring->next_to_clean]; + pr_info(" %5d %5X %5X %016llX %08X %p %016llX\n", + n, tx_ring->next_to_use, tx_ring->next_to_clean, + (u64)dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + tx_buffer->next_to_watch, + (u64)tx_buffer->time_stamp); + } + + /* Print TX Rings */ + if (!netif_msg_tx_done(adapter)) + goto rx_ring_summary; + + dev_info(&adapter->pdev->dev, "TX Rings Dump\n"); + + /* Transmit Descriptor Formats + * + * Transmit Descriptor (Read) + * +--------------------------------------------------------------+ + * 0 | Buffer Address [63:0] | + * +--------------------------------------------------------------+ + * 8 |PAYLEN |POPTS|CC|IDX |STA |DCMD |DTYP |MAC |RSV |DTALEN | + * +--------------------------------------------------------------+ + * 63 46 45 40 39 38 36 35 32 31 24 23 20 19 18 17 16 15 0 + * + * Transmit Descriptor (Write-Back) + * +--------------------------------------------------------------+ + * 0 | RSV [63:0] | + * +--------------------------------------------------------------+ + * 8 | RSV | STA | RSV | + * +--------------------------------------------------------------+ + * 63 36 35 32 31 0 + */ + + for (n = 0; n < adapter->num_tx_queues; n++) { + tx_ring = adapter->tx_ring[n]; + pr_info("------------------------------------\n"); + pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index); + pr_info("------------------------------------\n"); + pr_info("%s%s %s %s %s %s\n", + "T [desc] [address 63:0 ] ", + "[PlPOIdStDDt Ln] [bi->dma ] ", + "leng", "ntw", "timestamp", "bi->skb"); + + for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) { + tx_desc = TXGBE_TX_DESC(tx_ring, i); + tx_buffer = &tx_ring->tx_buffer_info[i]; + u0 = (struct my_u0 *)tx_desc; + if (dma_unmap_len(tx_buffer, len) > 0) { + pr_info("T [0x%03X] %016llX %016llX %016llX " + "%08X %p %016llX %p", + i, + le64_to_cpu(u0->a), + le64_to_cpu(u0->b), + (u64)dma_unmap_addr(tx_buffer, dma), + dma_unmap_len(tx_buffer, len), + tx_buffer->next_to_watch, + (u64)tx_buffer->time_stamp, + tx_buffer->skb); + if (i == tx_ring->next_to_use && + i == tx_ring->next_to_clean) + pr_cont(" NTC/U\n"); + else if (i == tx_ring->next_to_use) + pr_cont(" NTU\n"); + else if (i == tx_ring->next_to_clean) + pr_cont(" NTC\n"); + else + pr_cont("\n"); + + if (netif_msg_pktdata(adapter) && + tx_buffer->skb) + print_hex_dump(KERN_INFO, "", + DUMP_PREFIX_ADDRESS, 16, 1, + tx_buffer->skb->data, + dma_unmap_len(tx_buffer, len), + true); + } + } + } + + /* Print RX Rings Summary */ +rx_ring_summary: + dev_info(&adapter->pdev->dev, "RX Rings Summary\n"); + pr_info("Queue [NTU] [NTC]\n"); + for (n = 0; n < adapter->num_rx_queues; n++) { + rx_ring = adapter->rx_ring[n]; + pr_info("%5d %5X %5X\n", + n, rx_ring->next_to_use, rx_ring->next_to_clean); + } + + /* Print RX Rings */ + if (!netif_msg_rx_status(adapter)) + return; + + dev_info(&adapter->pdev->dev, "RX Rings Dump\n"); + + /* Receive Descriptor Formats + * + * Receive Descriptor (Read) + * 63 1 0 + * +-----------------------------------------------------+ + * 0 | Packet Buffer Address [63:1] |A0/NSE| + * +----------------------------------------------+------+ + * 8 | Header Buffer Address [63:1] | DD | + * +-----------------------------------------------------+ + * + * + * Receive Descriptor (Write-Back) + * + * 63 48 47 32 31 30 21 20 17 16 4 3 0 + * +------------------------------------------------------+ + * 0 |RSS / Frag Checksum|SPH| HDR_LEN |RSC- |Packet| RSS | + * |/ RTT / PCoE_PARAM | | | CNT | Type | Type | + * |/ Flow Dir Flt ID | | | | | | + * +------------------------------------------------------+ + * 8 | VLAN Tag | Length |Extended Error| Xtnd Status/NEXTP | + * +------------------------------------------------------+ + * 63 48 47 32 31 20 19 0 + */ + + for (n = 0; n < adapter->num_rx_queues; n++) { + rx_ring = adapter->rx_ring[n]; + pr_info("------------------------------------\n"); + pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index); + pr_info("------------------------------------\n"); + pr_info("%s%s%s", + "R [desc] [ PktBuf A0] ", + "[ HeadBuf DD] [bi->dma ] [bi->skb ] ", + "<-- Adv Rx Read format\n"); + pr_info("%s%s%s", + "RWB[desc] [PcsmIpSHl PtRs] ", + "[vl er S cks ln] ---------------- [bi->skb ] ", + "<-- Adv Rx Write-Back format\n"); + + for (i = 0; i < rx_ring->count; i++) { + rx_buffer_info = &rx_ring->rx_buffer_info[i]; + rx_desc = TXGBE_RX_DESC(rx_ring, i); + u0 = (struct my_u0 *)rx_desc; + staterr = le32_to_cpu(rx_desc->wb.upper.status_error); + if (staterr & TXGBE_RXD_STAT_DD) { + /* Descriptor Done */ + pr_info("RWB[0x%03X] %016llX " + "%016llX ---------------- %p", i, + le64_to_cpu(u0->a), + le64_to_cpu(u0->b), + rx_buffer_info->skb); + } else { + pr_info("R [0x%03X] %016llX " + "%016llX %016llX %p", i, + le64_to_cpu(u0->a), + le64_to_cpu(u0->b), + (u64)rx_buffer_info->page_dma, + rx_buffer_info->skb); + + if (netif_msg_pktdata(adapter) && + rx_buffer_info->page_dma) { + print_hex_dump(KERN_INFO, "", + DUMP_PREFIX_ADDRESS, 16, 1, + page_address(rx_buffer_info->page) + + rx_buffer_info->page_offset, + txgbe_rx_bufsz(rx_ring), true); + } + } + + if (i == rx_ring->next_to_use) + pr_cont(" NTU\n"); + else if (i == rx_ring->next_to_clean) + pr_cont(" NTC\n"); + else + pr_cont("\n"); + + } + } +} diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_ethtool.c b/drivers/net/ethernet/netswift/txgbe/txgbe_ethtool.c index 399bec32aa3f20ac39f1e78b097b73edfbbe9674..a6463465446b5e2ddb084f249d5d5fb870630dbe 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_ethtool.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_ethtool.c @@ -212,6 +212,7 @@ int txgbe_get_link_ksettings(struct net_device *netdev, /* set the advertised speeds */ if (hw->phy.autoneg_advertised) { + advertising = 0; if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_100_FULL) advertising |= ADVERTISED_100baseT_Full; if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_10GB_FULL) @@ -2194,6 +2195,7 @@ static int txgbe_set_phys_id(struct net_device *netdev, { struct txgbe_adapter *adapter = netdev_priv(netdev); struct txgbe_hw *hw = &adapter->hw; + u16 value = 0; switch (state) { case ETHTOOL_ID_ACTIVE: @@ -2201,17 +2203,58 @@ static int txgbe_set_phys_id(struct net_device *netdev, return 2; case ETHTOOL_ID_ON: - TCALL(hw, mac.ops.led_on, TXGBE_LED_LINK_UP); + if (hw->oem_ssid == 0x0075 && hw->oem_svid == 0x1bd4) { + if (adapter->link_up) { + switch (adapter->link_speed) { + case TXGBE_LINK_SPEED_10GB_FULL: + TCALL(hw, mac.ops.led_on, TXGBE_LED_LINK_10G); + break; + case TXGBE_LINK_SPEED_1GB_FULL: + TCALL(hw, mac.ops.led_on, TXGBE_LED_LINK_1G); + break; + case TXGBE_LINK_SPEED_100_FULL: + TCALL(hw, mac.ops.led_on, TXGBE_LED_LINK_100M); + break; + default: + break; + } + } else + TCALL(hw, mac.ops.led_on, TXGBE_LED_LINK_10G); + } else + TCALL(hw, mac.ops.led_on, TXGBE_LED_LINK_UP); break; case ETHTOOL_ID_OFF: - TCALL(hw, mac.ops.led_off, TXGBE_LED_LINK_UP); + if (hw->oem_ssid == 0x0075 && hw->oem_svid == 0x1bd4) { + if (adapter->link_up) { + switch (adapter->link_speed) { + case TXGBE_LINK_SPEED_10GB_FULL: + TCALL(hw, mac.ops.led_off, TXGBE_LED_LINK_10G); + break; + case TXGBE_LINK_SPEED_1GB_FULL: + TCALL(hw, mac.ops.led_off, TXGBE_LED_LINK_1G); + break; + case TXGBE_LINK_SPEED_100_FULL: + TCALL(hw, mac.ops.led_off, TXGBE_LED_LINK_100M); + break; + default: + break; + } + } else + TCALL(hw, mac.ops.led_off, TXGBE_LED_LINK_10G); + } else + TCALL(hw, mac.ops.led_off, TXGBE_LED_LINK_UP); break; case ETHTOOL_ID_INACTIVE: /* Restore LED settings */ wr32(&adapter->hw, TXGBE_CFG_LED_CTL, adapter->led_reg); + if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_XAUI) { + txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF021, &value); + txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF021, + (value & 0xFFFC) | 0x0); + } break; } @@ -3319,16 +3362,21 @@ static int txgbe_set_flash(struct net_device *netdev, struct ethtool_flash *ef) if (ret < 0) return ret; - if (txgbe_mng_present(&adapter->hw)) { + if (ef->region == 0) { + ret = txgbe_upgrade_flash(&adapter->hw, ef->region, + fw->data, fw->size); + } else { + if (txgbe_mng_present(&adapter->hw)) { ret = txgbe_upgrade_flash_hostif(&adapter->hw, ef->region, fw->data, fw->size); - } else - ret = -EOPNOTSUPP; + } else + ret = -EOPNOTSUPP; + } release_firmware(fw); if (!ret) dev_info(&netdev->dev, - "loaded firmware %s, reload txgbe driver\n", ef->data); + "loaded firmware %s, reboot to make firmware work\n", ef->data); return ret; } diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_hw.c b/drivers/net/ethernet/netswift/txgbe/txgbe_hw.c index 876470341639502c67d3d62223c27e54bc8b9f04..3f5187b0ef23e76ba067fd792af820a6c20db559 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_hw.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_hw.c @@ -123,8 +123,6 @@ u16 txgbe_get_pcie_msix_count(struct txgbe_hw *hw) u16 max_msix_count; u32 pos; - DEBUGFUNC("\n"); - max_msix_count = TXGBE_MAX_MSIX_VECTORS_SAPPHIRE; pos = pci_find_capability(((struct txgbe_adapter *)hw->back)->pdev, PCI_CAP_ID_MSIX); if (!pos) @@ -159,8 +157,6 @@ s32 txgbe_init_hw(struct txgbe_hw *hw) { s32 status; - DEBUGFUNC("\n"); - /* Reset the hardware */ status = TCALL(hw, mac.ops.reset_hw); @@ -184,8 +180,6 @@ s32 txgbe_clear_hw_cntrs(struct txgbe_hw *hw) { u16 i = 0; - DEBUGFUNC("\n"); - rd32(hw, TXGBE_RX_CRC_ERROR_FRAMES_LOW); for (i = 0; i < 8; i++) rd32(hw, TXGBE_RDB_MPCNT(i)); @@ -239,9 +233,7 @@ bool txgbe_device_supports_autoneg_fc(struct txgbe_hw *hw) bool supported = false; u32 speed; bool link_up; - u8 device_type = hw->subsystem_id & 0xF0; - - DEBUGFUNC("\n"); + u8 device_type = hw->subsystem_device_id & 0xF0; switch (hw->phy.media_type) { case txgbe_media_type_fiber: @@ -284,8 +276,6 @@ s32 txgbe_setup_fc(struct txgbe_hw *hw) u32 value = 0; u32 pcap_backplane = 0; - DEBUGFUNC("\n"); - /* Validate the requested mode */ if (hw->fc.strict_ieee && hw->fc.requested_mode == txgbe_fc_rx_pause) { ERROR_REPORT1(TXGBE_ERROR_UNSUPPORTED, @@ -399,8 +389,6 @@ s32 txgbe_read_pba_string(struct txgbe_hw *hw, u8 *pba_num, u16 offset; u16 length; - DEBUGFUNC("\n"); - if (pba_num == NULL) { DEBUGOUT("PBA string buffer was null\n"); return TXGBE_ERR_INVALID_ARGUMENT; @@ -512,8 +500,6 @@ s32 txgbe_get_mac_addr(struct txgbe_hw *hw, u8 *mac_addr) u32 rar_low; u16 i; - DEBUGFUNC("\n"); - wr32(hw, TXGBE_PSR_MAC_SWC_IDX, 0); rar_high = rd32(hw, TXGBE_PSR_MAC_SWC_AD_H); rar_low = rd32(hw, TXGBE_PSR_MAC_SWC_AD_L); @@ -585,8 +571,6 @@ s32 txgbe_get_bus_info(struct txgbe_hw *hw) { u16 link_status; - DEBUGFUNC("\n"); - /* Get the negotiated link width and speed from PCI config space */ link_status = txgbe_read_pci_cfg_word(hw, TXGBE_PCI_LINK_STATUS); @@ -607,8 +591,6 @@ void txgbe_set_lan_id_multi_port_pcie(struct txgbe_hw *hw) struct txgbe_bus_info *bus = &hw->bus; u32 reg; - DEBUGFUNC("\n"); - reg = rd32(hw, TXGBE_CFG_PORT_ST); bus->lan_id = TXGBE_CFG_PORT_ST_LAN_ID(reg); @@ -633,8 +615,6 @@ s32 txgbe_stop_adapter(struct txgbe_hw *hw) { u16 i; - DEBUGFUNC("\n"); - /* * Set the adapter_stopped flag so other driver functions stop touching * the hardware @@ -683,15 +663,10 @@ s32 txgbe_led_on(struct txgbe_hw *hw, u32 index) { u32 led_reg = rd32(hw, TXGBE_CFG_LED_CTL); u16 value = 0; - DEBUGFUNC("\n"); if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_XAUI) { txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF021, &value); - txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF021, value | 0x3); - txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF022, &value); - txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF022, value | 0x3); - txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF023, &value); - txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF023, value | 0x3); + txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF021, (value & 0xFFFC) | 0x0); } /* To turn on the LED, set mode to ON. */ led_reg |= index | (index << TXGBE_CFG_LED_CTL_LINK_OD_SHIFT); @@ -710,15 +685,10 @@ s32 txgbe_led_off(struct txgbe_hw *hw, u32 index) { u32 led_reg = rd32(hw, TXGBE_CFG_LED_CTL); u16 value = 0; - DEBUGFUNC("\n"); if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_XAUI) { txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF021, &value); - txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF021, value & 0xFFFC); - txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF022, &value); - txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF022, value & 0xFFFC); - txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF023, &value); - txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF023, value & 0xFFFC); + txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xF021, (value & 0xFFFC) | 0x1); } /* To turn off the LED, set mode to OFF. */ @@ -843,8 +813,6 @@ s32 txgbe_validate_mac_addr(u8 *mac_addr) { s32 status = 0; - DEBUGFUNC("\n"); - /* Make sure it is not a multicast address */ if (TXGBE_IS_MULTICAST(mac_addr)) { DEBUGOUT("MAC address is multicast\n"); @@ -878,8 +846,6 @@ s32 txgbe_set_rar(struct txgbe_hw *hw, u32 index, u8 *addr, u64 pools, u32 rar_low, rar_high; u32 rar_entries = hw->mac.num_rar_entries; - DEBUGFUNC("\n"); - /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { ERROR_REPORT2(TXGBE_ERROR_ARGUMENT, @@ -932,8 +898,6 @@ s32 txgbe_clear_rar(struct txgbe_hw *hw, u32 index) { u32 rar_entries = hw->mac.num_rar_entries; - DEBUGFUNC("\n"); - /* Make sure we are using a valid rar index range */ if (index >= rar_entries) { ERROR_REPORT2(TXGBE_ERROR_ARGUMENT, @@ -975,8 +939,6 @@ s32 txgbe_init_rx_addrs(struct txgbe_hw *hw) u32 rar_entries = hw->mac.num_rar_entries; u32 psrctl; - DEBUGFUNC("\n"); - /* * If the current mac address is valid, assume it is a software override * to the permanent address. @@ -1044,13 +1006,7 @@ void txgbe_add_uc_addr(struct txgbe_hw *hw, u8 *addr, u32 vmdq) u32 rar_entries = hw->mac.num_rar_entries; u32 rar; - DEBUGFUNC("\n"); - - DEBUGOUT6(" UC Addr = %.2X %.2X %.2X %.2X %.2X %.2X\n", - addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); - - /* - * Place this address in the RAR if there is room, + /* Place this address in the RAR if there is room, * else put the controller into promiscuous mode */ if (hw->addr_ctrl.rar_used_count < rar_entries) { @@ -1089,8 +1045,6 @@ s32 txgbe_update_uc_addr_list(struct txgbe_hw *hw, u8 *addr_list, u32 uc_addr_in_use; u32 vmdq; - DEBUGFUNC("\n"); - /* * Clear accounting of old secondary address list, * don't count RAR[0] @@ -1150,8 +1104,6 @@ STATIC s32 txgbe_mta_vector(struct txgbe_hw *hw, u8 *mc_addr) { u32 vector = 0; - DEBUGFUNC("\n"); - switch (hw->mac.mc_filter_type) { case 0: /* use bits [47:36] of the address */ vector = ((mc_addr[4] >> 4) | (((u16)mc_addr[5]) << 4)); @@ -1189,8 +1141,6 @@ void txgbe_set_mta(struct txgbe_hw *hw, u8 *mc_addr) u32 vector_bit; u32 vector_reg; - DEBUGFUNC("\n"); - hw->addr_ctrl.mta_in_use++; vector = txgbe_mta_vector(hw, mc_addr); @@ -1229,10 +1179,7 @@ s32 txgbe_update_mc_addr_list(struct txgbe_hw *hw, u8 *mc_addr_list, u32 vmdq; u32 psrctl; - DEBUGFUNC("\n"); - - /* - * Set the new number of MC addresses that we are being requested to + /* Set the new number of MC addresses that we are being requested to * use. */ hw->addr_ctrl.num_mc_addrs = mc_addr_count; @@ -1278,8 +1225,6 @@ s32 txgbe_enable_mc(struct txgbe_hw *hw) struct txgbe_addr_filter_info *a = &hw->addr_ctrl; u32 psrctl; - DEBUGFUNC("\n"); - if (a->mta_in_use > 0) { psrctl = rd32(hw, TXGBE_PSR_CTL); psrctl &= ~(TXGBE_PSR_CTL_MO | TXGBE_PSR_CTL_MFE); @@ -1301,8 +1246,7 @@ s32 txgbe_disable_mc(struct txgbe_hw *hw) { struct txgbe_addr_filter_info *a = &hw->addr_ctrl; u32 psrctl; - DEBUGFUNC("\n"); - + if (a->mta_in_use > 0) { psrctl = rd32(hw, TXGBE_PSR_CTL); psrctl &= ~(TXGBE_PSR_CTL_MO | TXGBE_PSR_CTL_MFE); @@ -1327,8 +1271,6 @@ s32 txgbe_fc_enable(struct txgbe_hw *hw) u32 fcrtl, fcrth; int i; - DEBUGFUNC("\n"); - /* Validate the water mark configuration */ if (!hw->fc.pause_time) { ret_val = TXGBE_ERR_INVALID_LINK_SETTINGS; @@ -1586,10 +1528,7 @@ void txgbe_fc_autoneg(struct txgbe_hw *hw) u32 speed; bool link_up; - DEBUGFUNC("\n"); - - /* - * AN should have completed when the cable was plugged in. + /* AN should have completed when the cable was plugged in. * Look for reasons to bail out. Bail out if: * - FC autoneg is disabled, or if * - link is not up. @@ -1655,8 +1594,6 @@ s32 txgbe_disable_pcie_master(struct txgbe_hw *hw) u16 dev_ctl; u32 vf_bme_clear = 0; - DEBUGFUNC("\n"); - /* Always set this bit to ensure any future transactions are blocked */ pci_clear_master(((struct txgbe_adapter *)hw->back)->pdev); @@ -1773,8 +1710,6 @@ s32 txgbe_disable_sec_rx_path(struct txgbe_hw *hw) int i; int secrxreg; - DEBUGFUNC("\n"); - wr32m(hw, TXGBE_RSC_CTL, TXGBE_RSC_CTL_RX_DIS, TXGBE_RSC_CTL_RX_DIS); for (i = 0; i < TXGBE_MAX_SECRX_POLL; i++) { @@ -1802,8 +1737,6 @@ s32 txgbe_disable_sec_rx_path(struct txgbe_hw *hw) **/ s32 txgbe_enable_sec_rx_path(struct txgbe_hw *hw) { - DEBUGFUNC("\n"); - wr32m(hw, TXGBE_RSC_CTL, TXGBE_RSC_CTL_RX_DIS, 0); TXGBE_WRITE_FLUSH(hw); @@ -1825,8 +1758,6 @@ STATIC s32 txgbe_get_san_mac_addr_offset(struct txgbe_hw *hw, { s32 ret_val; - DEBUGFUNC("\n"); - /* * First read the EEPROM pointer to see if the MAC addresses are * available. @@ -1859,10 +1790,7 @@ s32 txgbe_get_san_mac_addr(struct txgbe_hw *hw, u8 *san_mac_addr) u8 i; s32 ret_val; - DEBUGFUNC("\n"); - - /* - * First read the EEPROM pointer to see if the MAC addresses are + /* First read the EEPROM pointer to see if the MAC addresses are * available. If they're not, no point in calling set_lan_id() here. */ ret_val = txgbe_get_san_mac_addr_offset(hw, &san_mac_offset); @@ -1910,8 +1838,6 @@ s32 txgbe_set_san_mac_addr(struct txgbe_hw *hw, u8 *san_mac_addr) u16 san_mac_data, san_mac_offset; u8 i; - DEBUGFUNC("\n"); - /* Look for SAN mac address pointer. If not defined, return */ ret_val = txgbe_get_san_mac_addr_offset(hw, &san_mac_offset); if (ret_val || san_mac_offset == 0 || san_mac_offset == 0xFFFF) @@ -1948,8 +1874,6 @@ s32 txgbe_insert_mac_addr(struct txgbe_hw *hw, u8 *addr, u32 vmdq) u32 rar_low, rar_high; u32 addr_low, addr_high; - DEBUGFUNC("\n"); - /* swap bytes for HW little endian */ addr_low = addr[5] | (addr[4] << 8) | (addr[3] << 16) @@ -2014,8 +1938,6 @@ s32 txgbe_clear_vmdq(struct txgbe_hw *hw, u32 rar, u32 __maybe_unused vmdq) u32 mpsar_lo, mpsar_hi; u32 rar_entries = hw->mac.num_rar_entries; - DEBUGFUNC("\n"); - /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { ERROR_REPORT2(TXGBE_ERROR_ARGUMENT, @@ -2046,12 +1968,10 @@ s32 txgbe_clear_vmdq(struct txgbe_hw *hw, u32 rar, u32 __maybe_unused vmdq) * @rar: receive address register index to associate with a VMDq index * @vmdq: VMDq pool index **/ -s32 txgbe_set_vmdq(struct txgbe_hw *hw, u32 rar, u32 __maybe_unused pool) +s32 txgbe_set_vmdq(struct txgbe_hw *hw, u32 rar, u32 __always_unused pool) { u32 rar_entries = hw->mac.num_rar_entries; - DEBUGFUNC("\n"); - /* Make sure we are using a valid rar index range */ if (rar >= rar_entries) { ERROR_REPORT2(TXGBE_ERROR_ARGUMENT, @@ -2076,8 +1996,6 @@ s32 txgbe_set_vmdq_san_mac(struct txgbe_hw *hw, u32 vmdq) { u32 rar = hw->mac.san_mac_rar_index; - DEBUGFUNC("\n"); - wr32(hw, TXGBE_PSR_MAC_SWC_IDX, rar); if (vmdq < 32) { wr32(hw, TXGBE_PSR_MAC_SWC_VM_L, 1 << vmdq); @@ -2098,9 +2016,6 @@ s32 txgbe_init_uta_tables(struct txgbe_hw *hw) { int i; - DEBUGFUNC("\n"); - DEBUGOUT(" Clearing UTA\n"); - for (i = 0; i < 128; i++) wr32(hw, TXGBE_PSR_UC_TBL(i), 0); @@ -2175,8 +2090,6 @@ s32 txgbe_set_vfta(struct txgbe_hw *hw, u32 vlan, u32 vind, s32 ret_val = 0; bool vfta_changed = false; - DEBUGFUNC("\n"); - if (vlan > 4095) return TXGBE_ERR_PARAM; @@ -2240,8 +2153,6 @@ s32 txgbe_set_vlvf(struct txgbe_hw *hw, u32 vlan, u32 vind, { u32 vt; - DEBUGFUNC("\n"); - if (vlan > 4095) return TXGBE_ERR_PARAM; @@ -2343,8 +2254,6 @@ s32 txgbe_clear_vfta(struct txgbe_hw *hw) { u32 offset; - DEBUGFUNC("\n"); - for (offset = 0; offset < hw->mac.vft_size; offset++) { wr32(hw, TXGBE_PSR_VLAN_TBL(offset), 0); /* errata 5 */ @@ -2377,8 +2286,6 @@ s32 txgbe_get_wwn_prefix(struct txgbe_hw *hw, u16 *wwnn_prefix, u16 offset, caps; u16 alt_san_mac_blk_offset; - DEBUGFUNC("\n"); - /* clear output first */ *wwnn_prefix = 0xFFFF; *wwpn_prefix = 0xFFFF; @@ -2431,8 +2338,6 @@ void txgbe_set_mac_anti_spoofing(struct txgbe_hw *hw, bool enable, int pf) { u64 pfvfspoof = 0; - DEBUGFUNC("\n"); - if (enable) { /* * The PF should be allowed to spoof so that it can support @@ -2461,8 +2366,6 @@ void txgbe_set_vlan_anti_spoofing(struct txgbe_hw *hw, bool enable, int vf) { u32 pfvfspoof; - DEBUGFUNC("\n"); - if (vf < 32) { pfvfspoof = rd32(hw, TXGBE_TDM_VLAN_AS_L); if (enable) @@ -2492,8 +2395,6 @@ void txgbe_set_ethertype_anti_spoofing(struct txgbe_hw *hw, { u32 pfvfspoof; - DEBUGFUNC("\n"); - if (vf < 32) { pfvfspoof = rd32(hw, TXGBE_TDM_ETYPE_AS_L); if (enable) @@ -2521,8 +2422,6 @@ void txgbe_set_ethertype_anti_spoofing(struct txgbe_hw *hw, **/ s32 txgbe_get_device_caps(struct txgbe_hw *hw, u16 *device_caps) { - DEBUGFUNC("\n"); - TCALL(hw, eeprom.ops.read, hw->eeprom.sw_region_offset + TXGBE_DEVICE_CAPS, device_caps); @@ -2541,8 +2440,6 @@ u8 txgbe_calculate_checksum(u8 *buffer, u32 length) u32 i; u8 sum = 0; - DEBUGFUNC("\n"); - if (!buffer) return 0; @@ -2579,8 +2476,6 @@ s32 txgbe_host_interface_command(struct txgbe_hw *hw, u32 *buffer, s32 status = 0; u32 buf[64] = {}; - DEBUGFUNC("\n"); - if (length == 0 || length > TXGBE_HI_MAX_BLOCK_BYTE_LENGTH) { DEBUGOUT1("Buffer length failure buffersize=%d.\n", length); return TXGBE_ERR_HOST_INTERFACE_COMMAND; @@ -2633,6 +2528,14 @@ s32 txgbe_host_interface_command(struct txgbe_hw *hw, u32 *buffer, msec_delay(1); } + buf[0] = rd32(hw, TXGBE_MNG_MBOX); + + if ((buf[0] & 0xff0000) >> 16 == 0x80) { + DEBUGOUT("It's unknown cmd.\n"); + status = TXGBE_ERR_MNG_ACCESS_FAILED; + goto rel_out; + } + /* Check command completion */ if (timeout != 0 && i == timeout) { ERROR_REPORT1(TXGBE_ERROR_CAUTION, @@ -2647,8 +2550,10 @@ s32 txgbe_host_interface_command(struct txgbe_hw *hw, u32 *buffer, ERROR_REPORT1(TXGBE_ERROR_CAUTION, "%x ", buf[i]); } - status = TXGBE_ERR_HOST_INTERFACE_COMMAND; - goto rel_out; + if ((buffer[0] & 0xff) != (~buf[0] >> 24)) { + status = TXGBE_ERR_HOST_INTERFACE_COMMAND; + goto rel_out; + } } if (!return_data) @@ -2720,8 +2625,6 @@ s32 txgbe_set_fw_drv_ver(struct txgbe_hw *hw, u8 maj, u8 min, int i; s32 ret_val = 0; - DEBUGFUNC("\n"); - fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO; fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN; fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; @@ -2771,8 +2674,6 @@ s32 txgbe_reset_hostif(struct txgbe_hw *hw) int i; s32 status = 0; - DEBUGFUNC("\n"); - reset_cmd.hdr.cmd = FW_RESET_CMD; reset_cmd.hdr.buf_len = FW_RESET_LEN; reset_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; @@ -2809,8 +2710,6 @@ s32 txgbe_setup_mac_link_hostif(struct txgbe_hw *hw, u32 speed) int i; s32 status = 0; - DEBUGFUNC("\n"); - cmd.hdr.cmd = FW_SETUP_MAC_LINK_CMD; cmd.hdr.buf_len = FW_SETUP_MAC_LINK_LEN; cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; @@ -2867,8 +2766,6 @@ s32 txgbe_upgrade_flash_hostif(struct txgbe_hw *hw, u32 region, u32 offset; s32 status = 0; - DEBUGFUNC("\n"); - start_cmd.hdr.cmd = FW_FLASH_UPGRADE_START_CMD; start_cmd.hdr.buf_len = FW_FLASH_UPGRADE_START_LEN; start_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED; @@ -2953,6 +2850,272 @@ s32 txgbe_upgrade_flash_hostif(struct txgbe_hw *hw, u32 region, return status; } +u8 fmgr_cmd_op(struct txgbe_hw *hw, u32 cmd, u32 cmd_addr) +{ + u32 cmd_val = 0; + u32 time_out = 0; + + cmd_val = (cmd << SPI_CLK_CMD_OFFSET) | (SPI_CLK_DIV << SPI_CLK_DIV_OFFSET) | cmd_addr; + wr32(hw, SPI_H_CMD_REG_ADDR, cmd_val); + while (1) { + if (rd32(hw, SPI_H_STA_REG_ADDR) & 0x1) + break; + + if (time_out == SPI_TIME_OUT_VALUE) + return 1; + + time_out = time_out + 1; + udelay(10); + } + + return 0; +} + +u8 fmgr_usr_cmd_op(struct txgbe_hw *hw, u32 usr_cmd) +{ + u8 status = 0; + + wr32(hw, SPI_H_USR_CMD_REG_ADDR, usr_cmd); + status = fmgr_cmd_op(hw, SPI_CMD_USER_CMD, 0); + + return status; +} + +u8 flash_erase_chip(struct txgbe_hw *hw) +{ + u8 status = fmgr_cmd_op(hw, SPI_CMD_ERASE_CHIP, 0); + return status; +} + +u8 flash_erase_sector(struct txgbe_hw *hw, u32 sec_addr) +{ + u8 status = fmgr_cmd_op(hw, SPI_CMD_ERASE_SECTOR, sec_addr); + return status; +} + +u32 flash_read_dword(struct txgbe_hw *hw, u32 addr) +{ + u8 status = fmgr_cmd_op(hw, SPI_CMD_READ_DWORD, addr); + if (status) + return (u32)status; + + return rd32(hw, SPI_H_DAT_REG_ADDR); +} + +u8 flash_write_dword(struct txgbe_hw *hw, u32 addr, u32 dword) +{ + u8 status = 0; + + wr32(hw, SPI_H_DAT_REG_ADDR, dword); + status = fmgr_cmd_op(hw, SPI_CMD_WRITE_DWORD, addr); + if (status) + return status; + + if (dword != flash_read_dword(hw, addr)) { + return 1; + } + return 0; +} + +int txgbe_flash_write_cab(struct txgbe_hw *hw,u32 addr, u32 value,u16 lan_id) +{ + int status; + struct txgbe_hic_read_cab buffer; + + buffer.hdr.req.cmd = 0xE2; + buffer.hdr.req.buf_lenh = 0x6; + buffer.hdr.req.buf_lenl = 0x0; + buffer.hdr.req.checksum = 0xFF; + + /* convert offset from words to bytes */ + buffer.dbuf.d16[0] = cpu_to_le16(lan_id); + /* one word */ + buffer.dbuf.d32[0] = htonl(addr); + buffer.dbuf.d32[1] = htonl(value); + + status = txgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), 5000, true); + + return status; +} + +int txgbe_flash_read_cab(struct txgbe_hw *hw, u32 addr ,u16 lan_id ) +{ + int status; + struct txgbe_hic_read_cab buffer; + u16 *data = NULL; + + buffer.hdr.req.cmd = 0xE1; + buffer.hdr.req.buf_lenh = 0xaa; + buffer.hdr.req.buf_lenl = 0; + buffer.hdr.req.checksum = 0xFF; + + /* convert offset from words to bytes */ + buffer.dbuf.d16[0] = cpu_to_le16(lan_id); + /* one word */ + buffer.dbuf.d32[0] = htonl(addr); + + status = txgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), 5000, true); + + if (status) + return status; + if (txgbe_check_mng_access(hw)) { + *data = (u16)rd32a(hw, 0x1e100,3); + } else { + status = -147; + return status; + } + + return rd32(hw, 0x1e108); +} + +int txgbe_flash_write_unlock(struct txgbe_hw *hw) +{ + int status; + struct txgbe_hic_read_shadow_ram buffer; + + buffer.hdr.req.cmd = 0x40; + buffer.hdr.req.buf_lenh = 0; + buffer.hdr.req.buf_lenl = 0; + buffer.hdr.req.checksum = 0xFF; + + /* convert offset from words to bytes */ + buffer.address = 0; + /* one word */ + buffer.length = 0; + + status = txgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), 5000, false); + if (status) + return status; + + return status; +} + +int txgbe_flash_write_lock(struct txgbe_hw *hw) +{ + int status; + struct txgbe_hic_read_shadow_ram buffer; + + buffer.hdr.req.cmd = 0x39; + buffer.hdr.req.buf_lenh = 0; + buffer.hdr.req.buf_lenl = 0; + buffer.hdr.req.checksum = 0xFF; + + /* convert offset from words to bytes */ + buffer.address = 0; + /* one word */ + buffer.length = 0; + + status = txgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), 5000, false); + if (status) + return status; + + return status; +} + +int txgbe_upgrade_flash(struct txgbe_hw *hw, u32 region, + const u8 *data, u32 size) +{ + u32 sector_num = 0; + u32 read_data = 0; + u8 status = 0; + u8 skip = 0; + u32 i = 0; + u8 flash_vendor = 0; + u32 mac_addr0_dword0_t; + u32 mac_addr0_dword1_t; + u32 mac_addr1_dword0_t; + u32 mac_addr1_dword1_t; + u32 serial_num_dword0_t; + u32 serial_num_dword1_t; + u32 serial_num_dword2_t; + + /* check sub_id, dont care value of 15b ~ 12b*/; + if ((hw->subsystem_device_id & 0xfff) != + ((data[0xfffdc] << 8 | data[0xfffdd]) & 0xfff)) { + return -EOPNOTSUPP; + } + + /*check dev_id*/ + if (!((hw->device_id & 0xfff0) == ((data[0xfffde] << 8 | data[0xfffdf]) & 0xfff0)) && + !(hw->device_id == 0xffff)) { + return -EOPNOTSUPP; + } + + /* unlock flash write protect*/ + wr32(hw, TXGBE_SPI_CMDCFG0, 0x9f050206); + wr32(hw, 0x10194, 0x9f050206); + + msleep(1000); + + mac_addr0_dword0_t = flash_read_dword(hw, MAC_ADDR0_WORD0_OFFSET_1G); + mac_addr0_dword1_t = flash_read_dword(hw, MAC_ADDR0_WORD1_OFFSET_1G) & 0xffff; + mac_addr1_dword0_t = flash_read_dword(hw, MAC_ADDR1_WORD0_OFFSET_1G); + mac_addr1_dword1_t = flash_read_dword(hw, MAC_ADDR1_WORD1_OFFSET_1G) & 0xffff; + + serial_num_dword0_t = flash_read_dword(hw, PRODUCT_SERIAL_NUM_OFFSET_1G); + serial_num_dword1_t = flash_read_dword(hw, PRODUCT_SERIAL_NUM_OFFSET_1G + 4); + serial_num_dword2_t = flash_read_dword(hw, PRODUCT_SERIAL_NUM_OFFSET_1G + 8); + + status = fmgr_usr_cmd_op(hw, 0x6); /* write enable*/ + status = fmgr_usr_cmd_op(hw, 0x98); /* global protection un-lock*/ + txgbe_flash_write_unlock(hw); + msleep(1000); + + /*Note: for Spanish FLASH, first 8 sectors (4KB) in sector0 (64KB) + need to use a special erase command (4K sector erase)*/ + if (flash_vendor == 1) { + wr32(hw, SPI_CMD_CFG1_ADDR, 0x0103c720); + for (i = 0; i < 8; i++) { + flash_erase_sector(hw, i * 128); + msleep(20); // 20 ms + } + wr32(hw, SPI_CMD_CFG1_ADDR, 0x0103c7d8); + } + + sector_num = size / SPI_SECTOR_SIZE; + /* Winbond Flash, erase chip command is okay, but erase sector doestn't work*/ + if (flash_vendor == 2) { + status = flash_erase_chip(hw); + msleep(1000); + } else { + wr32(hw, SPI_CMD_CFG1_ADDR, 0x0103c720); + for (i = 0; i < sector_num; i++) { + status = flash_erase_sector(hw, i * SPI_SECTOR_SIZE); + msleep(50); + } + wr32(hw, SPI_CMD_CFG1_ADDR, 0x0103c7d8); + } + + /* Program Image file in dword*/ + for (i = 0; i < size/4; i++) { + read_data = data[4 * i + 3] << 24 | data[4 * i + 2] << 16 | data[4 * i + 1] << 8 | data[4 * i]; + read_data = __le32_to_cpu(read_data); + skip = ((i * 4 == MAC_ADDR0_WORD0_OFFSET_1G) || (i * 4 == MAC_ADDR0_WORD1_OFFSET_1G) || + (i * 4 == MAC_ADDR1_WORD0_OFFSET_1G) || (i * 4 == MAC_ADDR1_WORD1_OFFSET_1G) || + (i * 4 >= PRODUCT_SERIAL_NUM_OFFSET_1G && i * 4 <= PRODUCT_SERIAL_NUM_OFFSET_1G + 8)); + if (read_data != 0xffffffff && !skip) { + status = flash_write_dword(hw, i * 4, read_data); + if (status) { + read_data = flash_read_dword(hw, i * 4); + return 1; + } + } + } + + flash_write_dword(hw, MAC_ADDR0_WORD0_OFFSET_1G, mac_addr0_dword0_t); + flash_write_dword(hw, MAC_ADDR0_WORD1_OFFSET_1G, (mac_addr0_dword1_t | 0x80000000));//lan0 + flash_write_dword(hw, MAC_ADDR1_WORD0_OFFSET_1G, mac_addr1_dword0_t); + flash_write_dword(hw, MAC_ADDR1_WORD1_OFFSET_1G, (mac_addr1_dword1_t | 0x80000000));//lan1 + flash_write_dword(hw, PRODUCT_SERIAL_NUM_OFFSET_1G, serial_num_dword0_t); + flash_write_dword(hw, PRODUCT_SERIAL_NUM_OFFSET_1G + 4, serial_num_dword1_t); + flash_write_dword(hw, PRODUCT_SERIAL_NUM_OFFSET_1G + 8, serial_num_dword2_t); + + return 0; +} /** * txgbe_set_rxpba - Initialize Rx packet buffer * @hw: pointer to hardware structure @@ -2967,8 +3130,6 @@ void txgbe_set_rxpba(struct txgbe_hw *hw, int num_pb, u32 headroom, int i = 0; u32 rxpktsize, txpktsize, txpbthresh; - DEBUGFUNC("\n"); - /* Reserve headroom */ pbsize -= headroom; @@ -3047,8 +3208,6 @@ s32 txgbe_get_thermal_sensor_data(struct txgbe_hw *hw) int i = 0; struct txgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data; - DEBUGFUNC("\n"); - /* Only support thermal sensors attached to physical port 0 */ if (hw->bus.lan_id) return TXGBE_NOT_IMPLEMENTED; @@ -3102,8 +3261,6 @@ s32 txgbe_init_thermal_sensor_thresh(struct txgbe_hw *hw) struct txgbe_thermal_sensor_data *data = &hw->mac.thermal_sensor_data; - DEBUGFUNC("\n"); - memset(data, 0, sizeof(struct txgbe_thermal_sensor_data)); /* Only support thermal sensors attached to SP physical port 0 */ @@ -3129,8 +3286,6 @@ void txgbe_disable_rx(struct txgbe_hw *hw) u32 pfdtxgswc; u32 rxctrl; - DEBUGFUNC("\n"); - rxctrl = rd32(hw, TXGBE_RDB_PB_CTL); if (rxctrl & TXGBE_RDB_PB_CTL_RXEN) { pfdtxgswc = rd32(hw, TXGBE_PSR_CTL); @@ -3183,8 +3338,6 @@ void txgbe_enable_rx(struct txgbe_hw *hw) { u32 pfdtxgswc; - DEBUGFUNC("\n"); - /* enable mac receiver */ wr32m(hw, TXGBE_MAC_RX_CFG, TXGBE_MAC_RX_CFG_RE, TXGBE_MAC_RX_CFG_RE); @@ -3258,8 +3411,6 @@ s32 txgbe_setup_mac_link_multispeed_fiber(struct txgbe_hw *hw, u32 i = 0; bool autoneg, link_up = false; - DEBUGFUNC("\n"); - /* Mask off requested but non-supported speeds */ status = TCALL(hw, mac.ops.get_link_capabilities, &link_speed, &autoneg); @@ -3728,8 +3879,6 @@ void txgbe_init_mac_link_ops(struct txgbe_hw *hw) { struct txgbe_mac_info *mac = &hw->mac; - DEBUGFUNC("\n"); - /* * enable the laser control functions for SFP+ fiber * and MNG not enabled @@ -3777,8 +3926,6 @@ s32 txgbe_init_phy_ops(struct txgbe_hw *hw) struct txgbe_mac_info *mac = &hw->mac; s32 ret_val = 0; - DEBUGFUNC("\n"); - txgbe_init_i2c(hw); /* Identify the PHY or SFP module */ ret_val = TCALL(hw, phy.ops.identify); @@ -3793,7 +3940,7 @@ s32 txgbe_init_phy_ops(struct txgbe_hw *hw) /* If copper media, overwrite with copper function pointers */ if (TCALL(hw, mac.ops.get_media_type) == txgbe_media_type_copper) { hw->phy.type = txgbe_phy_xaui; - if ((hw->subsystem_id & 0xF0) != TXGBE_ID_SFI_XAUI) { + if ((hw->subsystem_device_id & 0xF0) != TXGBE_ID_SFI_XAUI) { mac->ops.setup_link = txgbe_setup_copper_link; mac->ops.get_link_capabilities = txgbe_get_copper_link_capabilities; @@ -3821,8 +3968,6 @@ s32 txgbe_init_ops(struct txgbe_hw *hw) struct txgbe_flash_info *flash = &hw->flash; s32 ret_val = 0; - DEBUGFUNC("\n"); - /* PHY */ phy->ops.reset = txgbe_reset_phy; phy->ops.read_reg = txgbe_read_phy_reg; @@ -3831,6 +3976,7 @@ s32 txgbe_init_ops(struct txgbe_hw *hw) phy->ops.write_reg_mdi = txgbe_write_phy_reg_mdi; phy->ops.setup_link = txgbe_setup_phy_link; phy->ops.setup_link_speed = txgbe_setup_phy_link_speed; + phy->ops.get_firmware_version = txgbe_get_phy_firmware_version; phy->ops.read_i2c_byte = txgbe_read_i2c_byte; phy->ops.write_i2c_byte = txgbe_write_i2c_byte; phy->ops.read_i2c_sff8472 = txgbe_read_i2c_sff8472; @@ -3952,8 +4098,6 @@ s32 txgbe_get_link_capabilities(struct txgbe_hw *hw, u32 sr_pcs_ctl, sr_pma_mmd_ctl1, sr_an_mmd_ctl; u32 sr_an_mmd_adv_reg2; - DEBUGFUNC("\n"); - /* Check if 1G SFP module. */ if (hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core0 || hw->phy.sfp_type == txgbe_sfp_type_1g_cu_core1 || @@ -3975,14 +4119,14 @@ s32 txgbe_get_link_capabilities(struct txgbe_hw *hw, } /* XAUI */ else if ((txgbe_get_media_type(hw) == txgbe_media_type_copper) && - ((hw->subsystem_id & 0xF0) == TXGBE_ID_XAUI || - (hw->subsystem_id & 0xF0) == TXGBE_ID_SFI_XAUI)) { + ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_XAUI || + (hw->subsystem_device_id & 0xF0) == TXGBE_ID_SFI_XAUI)) { *speed = TXGBE_LINK_SPEED_10GB_FULL; *autoneg = false; hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_10GBASE_T; } /* SGMII */ - else if ((hw->subsystem_id & 0xF0) == TXGBE_ID_SGMII) { + else if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_SGMII) { *speed = TXGBE_LINK_SPEED_1GB_FULL | TXGBE_LINK_SPEED_100_FULL | TXGBE_LINK_SPEED_10_FULL; @@ -3990,12 +4134,12 @@ s32 txgbe_get_link_capabilities(struct txgbe_hw *hw, hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_1000BASE_T | TXGBE_PHYSICAL_LAYER_100BASE_TX; /* MAC XAUI */ - } else if ((hw->subsystem_id & 0xF0) == TXGBE_ID_MAC_XAUI) { + } else if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_MAC_XAUI) { *speed = TXGBE_LINK_SPEED_10GB_FULL; *autoneg = false; hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_10GBASE_KX4; /* MAC SGMII */ - } else if ((hw->subsystem_id & 0xF0) == TXGBE_ID_MAC_SGMII) { + } else if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_MAC_SGMII) { *speed = TXGBE_LINK_SPEED_1GB_FULL; *autoneg = false; hw->phy.link_mode = TXGBE_PHYSICAL_LAYER_1000BASE_KX; @@ -4081,9 +4225,7 @@ s32 txgbe_get_link_capabilities(struct txgbe_hw *hw, enum txgbe_media_type txgbe_get_media_type(struct txgbe_hw *hw) { enum txgbe_media_type media_type; - u8 device_type = hw->subsystem_id & 0xF0; - - DEBUGFUNC("\n"); + u8 device_type = hw->subsystem_device_id & 0xF0; /* Detect if there is a copper PHY attached. */ switch (hw->phy.type) { @@ -4152,6 +4294,11 @@ void txgbe_disable_tx_laser_multispeed_fiber(struct txgbe_hw *hw) /* Blocked by MNG FW so bail */ txgbe_check_reset_blocked(hw); + /* overwrite led when ifdown */ + if (txgbe_close_notify(hw)) + TCALL(hw, mac.ops.led_off, TXGBE_LED_LINK_UP | TXGBE_LED_LINK_10G | + TXGBE_LED_LINK_1G | TXGBE_LED_LINK_ACTIVE); + /* Disable Tx laser; allow 100us to go dark per spec */ esdp_reg |= TXGBE_GPIO_DR_1 | TXGBE_GPIO_DR_0; wr32(hw, TXGBE_GPIO_DR, esdp_reg); @@ -4168,7 +4315,14 @@ void txgbe_disable_tx_laser_multispeed_fiber(struct txgbe_hw *hw) * laser on the PHY, effectively starting physical link. **/ void txgbe_enable_tx_laser_multispeed_fiber(struct txgbe_hw *hw) -{ +{ + if (!(TCALL(hw, mac.ops.get_media_type) == txgbe_media_type_fiber)) + return; + + /* recover led configure when ifup */ + if (txgbe_open_notify(hw)) + wr32(hw, TXGBE_CFG_LED_CTL, 0); + /* Enable Tx laser; allow 100ms to light up */ wr32m(hw, TXGBE_GPIO_DR, TXGBE_GPIO_DR_0 | TXGBE_GPIO_DR_1, 0); @@ -4190,8 +4344,9 @@ void txgbe_enable_tx_laser_multispeed_fiber(struct txgbe_hw *hw) **/ void txgbe_flap_tx_laser_multispeed_fiber(struct txgbe_hw *hw) { - DEBUGFUNC("\n"); - + if (!(TCALL(hw, mac.ops.get_media_type) == txgbe_media_type_fiber)) + return; + /* Blocked by MNG FW so bail */ txgbe_check_reset_blocked(hw); @@ -4261,13 +4416,15 @@ s32 txgbe_set_sgmii_an37_ability(struct txgbe_hw *hw) u32 value; txgbe_wr32_epcs(hw, TXGBE_VR_XS_OR_PCS_MMD_DIGI_CTL1, 0x3002); - /* for sgmii + external phy, set to 0x0105 (mac sgmii mode) */ - if ((hw->subsystem_id & 0xF0) == TXGBE_ID_SGMII) { - txgbe_wr32_epcs(hw, TXGBE_SR_MII_MMD_AN_CTL, 0x0105); - } - /* for sgmii direct link, set to 0x010c (phy sgmii mode) */ - if ((hw->subsystem_id & 0xF0) == TXGBE_ID_MAC_SGMII) { + /* for sgmii + external phy, set to 0x0105 (mac sgmii mode) + ** for sgmii direct link, set to 0x010c (phy sgmii mode) + */ + if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_MAC_SGMII || + txgbe_get_media_type(hw) == txgbe_media_type_fiber) { txgbe_wr32_epcs(hw, TXGBE_SR_MII_MMD_AN_CTL, 0x010c); + } else if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_SGMII || + (hw->subsystem_device_id & 0xF0) == TXGBE_ID_XAUI) { + txgbe_wr32_epcs(hw, TXGBE_SR_MII_MMD_AN_CTL, 0x0105); } txgbe_wr32_epcs(hw, TXGBE_SR_MII_MMD_DIGI_CTL, 0x0200); value = txgbe_rd32_epcs(hw, TXGBE_SR_MII_MMD_CTL); @@ -4299,32 +4456,20 @@ s32 txgbe_set_link_to_kr(struct txgbe_hw *hw, bool autoneg) e_dev_info("It is set to kr.\n"); txgbe_wr32_epcs(hw, 0x78001, 0x7); - txgbe_wr32_epcs(hw, 0x18035, 0x00FC); - txgbe_wr32_epcs(hw, 0x18055, 0x00FC); - if (1) { - /* 2. Disable xpcs AN-73 */ + /* 2. Disable xpcs AN-73 */ + if (adapter->backplane_an == 1) { txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x3000); - txgbe_wr32_epcs(hw, 0x78003, 0x1); - if (!(adapter->backplane_an == 1)) { - txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x0000); - txgbe_wr32_epcs(hw, 0x78003, 0x0); - } - - if (KR_SET == 1 || adapter->ffe_set == TXGBE_BP_M_KR) { - e_dev_info("Set KR TX_EQ MAIN:%d PRE:%d POST:%d\n", - adapter->ffe_main, adapter->ffe_pre, adapter->ffe_post); - value = (0x1804 & ~0x3F3F); - value |= adapter->ffe_main << 8 | adapter->ffe_pre; - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); - - value = (0x50 & ~0x7F) | (1 << 6)| adapter->ffe_post; - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); - } + txgbe_wr32_epcs(hw, TXGBE_VR_AN_KR_MODE_CL, 0x1); + } else { + txgbe_wr32_epcs(hw, TXGBE_SR_AN_MMD_CTL, 0x0); + txgbe_wr32_epcs(hw, TXGBE_VR_AN_KR_MODE_CL, 0x0); + } - if (KR_AN73_PRESET == 1) { - txgbe_wr32_epcs(hw, 0x18037, 0x80); - } + txgbe_wr32_epcs(hw, 0x70012, 0xc000 | txgbe_rd32_epcs(hw, 0x70012)); + if (KR_AN73_PRESET == 1) { + txgbe_wr32_epcs(hw, 0x18037, 0x80 | txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1)); + } if (KR_POLLING == 1) { txgbe_wr32_epcs(hw, 0x18006, 0xffff); @@ -4368,9 +4513,16 @@ s32 txgbe_set_link_to_kr(struct txgbe_hw *hw, bool autoneg) status = TXGBE_ERR_PHY_INIT_NOT_DONE; goto out; } - } else { - txgbe_wr32_epcs(hw, TXGBE_VR_AN_KR_MODE_CL, - 0x1); + + if ((KR_SET == 1) || (adapter->ffe_set == TXGBE_BP_M_KR)) { + e_dev_info("Set KR TX_EQ MAIN:%d PRE:%d POST:%d\n", + adapter->ffe_main,adapter->ffe_pre,adapter->ffe_post); + value = (0x1804 & ~0x3F3F); + value |= adapter->ffe_main << 8 | adapter->ffe_pre; + txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); + + value = (0x50 & ~0x7F) | (1 << 6)| adapter->ffe_post; + txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); } out: return status; @@ -4446,29 +4598,11 @@ s32 txgbe_set_link_to_kx4(struct txgbe_hw *hw, bool autoneg) value = (0xf5f0 & ~0x7F0) | (0x5 << 8) | (0x7 << 5) | 0xF0; txgbe_wr32_epcs(hw, TXGBE_PHY_TX_GENCTRL1, value); - if ((hw->subsystem_id & 0xF0) == TXGBE_ID_MAC_XAUI) + if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_MAC_XAUI) txgbe_wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0xCF00); else txgbe_wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0x4F00); - if (KX4_SET == 1 || adapter->ffe_set) { - e_dev_info("Set KX4 TX_EQ MAIN:%d PRE:%d POST:%d\n", - adapter->ffe_main, adapter->ffe_pre, adapter->ffe_post); - value = (0x1804 & ~0x3F3F); - value |= adapter->ffe_main << 8 | adapter->ffe_pre; - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); - - value = (0x50 & ~0x7F) | (1 << 6)| adapter->ffe_post; - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); - } else { - value = (0x1804 & ~0x3F3F); - value |= 40 << 8 ; - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); - - value = (0x50 & ~0x7F) | (1 << 6); - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); - - } for (i = 0; i < 4; i++) { if (i == 0) value = (0x45 & ~0xFFFF) | (0x7 << 12) | (0x7 << 8) | 0x6; @@ -4589,6 +4723,17 @@ s32 txgbe_set_link_to_kx4(struct txgbe_hw *hw, bool autoneg) goto out; } + if ((KX4_SET == 1) || (adapter->ffe_set == TXGBE_BP_M_KX4)) { + e_dev_info("Set KX4 TX_EQ MAIN:%d PRE:%d POST:%d\n", + adapter->ffe_main,adapter->ffe_pre,adapter->ffe_post); + value = (0x1804 & ~0x3F3F); + value |= adapter->ffe_main << 8 | adapter->ffe_pre; + txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); + + value = (0x50 & ~0x7F) | (1 << 6)| adapter->ffe_post; + txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); + } + out: return status; } @@ -4610,9 +4755,6 @@ s32 txgbe_set_link_to_kx(struct txgbe_hw *hw, } e_dev_info("It is set to kx. speed =0x%x\n", speed); - txgbe_wr32_epcs(hw, 0x18035, 0x00FC); - txgbe_wr32_epcs(hw, 0x18055, 0x00FC); - /* 1. Wait xpcs power-up good */ for (i = 0; i < TXGBE_XPCS_POWER_GOOD_MAX_POLLING_TIME; i++) { if ((txgbe_rd32_epcs(hw, TXGBE_VR_XS_OR_PCS_MMD_DIGI_STATUS) & @@ -4684,29 +4826,6 @@ s32 txgbe_set_link_to_kx(struct txgbe_hw *hw, else txgbe_wr32_epcs(hw, TXGBE_PHY_MISC_CTL0, 0xCF00); - if (KX_SET == 1 || adapter->ffe_set == TXGBE_BP_M_KX) { - e_dev_info("Set KX TX_EQ MAIN:%d PRE:%d POST:%d\n", - adapter->ffe_main, adapter->ffe_pre, adapter->ffe_post); - /* 5. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL0 Register Bit[13:8](TX_EQ_MAIN) - * = 6'd30, Bit[5:0](TX_EQ_PRE) = 6'd4 - */ - value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0); - value = (value & ~0x3F3F) | (adapter->ffe_main << 8) | adapter->ffe_pre; - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); - /* 6. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL1 Register Bit[6](TX_EQ_OVR_RIDE) - * = 1'b1, Bit[5:0](TX_EQ_POST) = 6'd36 - */ - value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1); - value = (value & ~0x7F) | adapter->ffe_post | (1 << 6); - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); - } else { - value = (0x1804 & ~0x3F3F) | (24 << 8) | 4; - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); - - value = (0x50 & ~0x7F) | 16 | (1 << 6); - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); - } - for (i = 0; i < 4; i++) { if (i) { value = 0xff06; @@ -4817,6 +4936,23 @@ s32 txgbe_set_link_to_kx(struct txgbe_hw *hw, goto out; } + if ((KX_SET == 1) || (adapter->ffe_set == TXGBE_BP_M_KX)) { + e_dev_info("Set KX TX_EQ MAIN:%d PRE:%d POST:%d\n", + adapter->ffe_main,adapter->ffe_pre,adapter->ffe_post); + /* 5. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL0 Register Bit[13:8](TX_EQ_MAIN) + * = 6'd30, Bit[5:0](TX_EQ_PRE) = 6'd4 + */ + value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0); + value = (value & ~0x3F3F) | (adapter->ffe_main << 8) | adapter->ffe_pre; + txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); + /* 6. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL1 Register Bit[6](TX_EQ_OVR_RIDE) + * = 1'b1, Bit[5:0](TX_EQ_POST) = 6'd36 + */ + value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1); + value = (value & ~0x7F) | adapter->ffe_post | (1 << 6); + txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); + } + out: return status; } @@ -4917,35 +5053,7 @@ s32 txgbe_set_link_to_sfi(struct txgbe_hw *hw, * MPLLA_DIV16P5_CLK_EN=1, MPLLA_DIV10_CLK_EN=1, MPLLA_DIV8_CLK_EN=0 */ txgbe_wr32_epcs(hw, TXGBE_PHY_MPLLA_CTL2, 0x0600); - if (SFI_SET == 1 || adapter->ffe_set) { - e_dev_info("Set SFI TX_EQ MAIN:%d PRE:%d POST:%d\n", - adapter->ffe_main, adapter->ffe_pre, adapter->ffe_post); - /* 5. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL0 Register Bit[13:8](TX_EQ_MAIN) - * = 6'd30, Bit[5:0](TX_EQ_PRE) = 6'd4 - */ - value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0); - value = (value & ~0x3F3F) | (adapter->ffe_main << 8) | adapter->ffe_pre; - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); - /* 6. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL1 Register Bit[6](TX_EQ_OVR_RIDE) - * = 1'b1, Bit[5:0](TX_EQ_POST) = 6'd36 - */ - value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1); - value = (value & ~0x7F) | adapter->ffe_post | (1 << 6); - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); - } else { - /* 5. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL0 Register Bit[13:8](TX_EQ_MAIN) - * = 6'd30, Bit[5:0](TX_EQ_PRE) = 6'd4 - */ - value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0); - value = (value & ~0x3F3F) | (24 << 8) | 4; - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); - /* 6. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL1 Register Bit[6](TX_EQ_OVR_RIDE) - * = 1'b1, Bit[5:0](TX_EQ_POST) = 6'd36 - */ - value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1); - value = (value & ~0x7F) | 16 | (1 << 6); - txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); - } + if (hw->phy.sfp_type == txgbe_sfp_type_da_cu_core0 || hw->phy.sfp_type == txgbe_sfp_type_da_cu_core1) { /* 7. Set VR_XS_PMA_Gen5_12G_RX_EQ_CTRL0 Register @@ -5111,6 +5219,23 @@ s32 txgbe_set_link_to_sfi(struct txgbe_hw *hw, goto out; } + if ((SFI_SET == 1) || (adapter->ffe_set == TXGBE_BP_M_SFI)) { + e_dev_info("Set SFI TX_EQ MAIN:%d PRE:%d POST:%d\n", + adapter->ffe_main,adapter->ffe_pre,adapter->ffe_post); + /* 5. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL0 Register Bit[13:8](TX_EQ_MAIN) + * = 6'd30, Bit[5:0](TX_EQ_PRE) = 6'd4 + */ + value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0); + value = (value & ~0x3F3F) | (adapter->ffe_main << 8) | adapter->ffe_pre; + txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL0, value); + /* 6. Set VR_XS_PMA_Gen5_12G_TX_EQ_CTRL1 Register Bit[6](TX_EQ_OVR_RIDE) + * = 1'b1, Bit[5:0](TX_EQ_POST) = 6'd36 + */ + value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1); + value = (value & ~0x7F) | adapter->ffe_post | (1 << 6); + txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); + } + out: return status; } @@ -5135,8 +5260,6 @@ s32 txgbe_setup_mac_link(struct txgbe_hw *hw, u32 link_speed = TXGBE_LINK_SPEED_UNKNOWN; bool link_up = false; - DEBUGFUNC("\n"); - /* Check to see if speed passed in is supported. */ status = TCALL(hw, mac.ops.get_link_capabilities, &link_capabilities, &autoneg); @@ -5150,9 +5273,9 @@ s32 txgbe_setup_mac_link(struct txgbe_hw *hw, goto out; } - if (!(((hw->subsystem_device_id & 0xF0) == TXGBE_ID_KR_KX_KX4) || - ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_MAC_XAUI) || - ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_MAC_SGMII))) { + if (!(((hw->subsystem_device_id & TXGBE_DEV_MASK) == TXGBE_ID_KR_KX_KX4) || + ((hw->subsystem_device_id & TXGBE_DEV_MASK) == TXGBE_ID_MAC_XAUI) || + ((hw->subsystem_device_id & TXGBE_DEV_MASK) == TXGBE_ID_MAC_SGMII))) { status = TCALL(hw, mac.ops.check_link, &link_speed, &link_up, false); if (status != 0) @@ -5161,45 +5284,27 @@ s32 txgbe_setup_mac_link(struct txgbe_hw *hw, goto out; } - if ((hw->subsystem_device_id & TXGBE_NCSI_MASK) == TXGBE_NCSI_SUP) - goto out; - - if ((hw->subsystem_id & 0xF0) == TXGBE_ID_KR_KX_KX4) { - if (!autoneg) { - switch (hw->phy.link_mode) { - case TXGBE_PHYSICAL_LAYER_10GBASE_KR: - txgbe_set_link_to_kr(hw, autoneg); - break; - case TXGBE_PHYSICAL_LAYER_10GBASE_KX4: - txgbe_set_link_to_kx4(hw, autoneg); - break; - case TXGBE_PHYSICAL_LAYER_1000BASE_KX: - txgbe_set_link_to_kx(hw, speed, autoneg); - break; - default: - status = TXGBE_ERR_PHY; - goto out; - } - } else { - txgbe_set_link_to_kr(hw, autoneg); - } - } else if ((hw->subsystem_id & 0xF0) == TXGBE_ID_XAUI || - ((hw->subsystem_id & 0xF0) == TXGBE_ID_MAC_XAUI) || - (hw->subsystem_id & 0xF0) == TXGBE_ID_SGMII || - ((hw->subsystem_id & 0xF0) == TXGBE_ID_MAC_SGMII) || - (txgbe_get_media_type(hw) == txgbe_media_type_copper && - (hw->subsystem_id & 0xF0) == TXGBE_ID_SFI_XAUI)) { - if (speed == TXGBE_LINK_SPEED_10GB_FULL) { - txgbe_set_link_to_kx4(hw, autoneg); - } else { - txgbe_set_link_to_kx(hw, speed, 0); - if (adapter->an37 || - (hw->subsystem_id & 0xF0) == TXGBE_ID_SGMII || - (hw->subsystem_id & 0xF0) == TXGBE_ID_XAUI) - txgbe_set_sgmii_an37_ability(hw); + if ((hw->subsystem_device_id & TXGBE_DEV_MASK) == TXGBE_ID_KR_KX_KX4) { + txgbe_set_link_to_kr(hw, autoneg); + } else if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_XAUI || + ((hw->subsystem_device_id & TXGBE_DEV_MASK) == TXGBE_ID_MAC_XAUI) || + (hw->subsystem_device_id & TXGBE_DEV_MASK) == TXGBE_ID_SGMII || + ((hw->subsystem_device_id & TXGBE_DEV_MASK) == TXGBE_ID_MAC_SGMII) || + (txgbe_get_media_type(hw) == txgbe_media_type_copper && + (hw->subsystem_device_id & TXGBE_DEV_MASK) == TXGBE_ID_SFI_XAUI)) { + if (speed == TXGBE_LINK_SPEED_10GB_FULL) { + txgbe_set_link_to_kx4(hw, 0); + } else { + txgbe_set_link_to_kx(hw, speed, 0); + if (adapter->an37) + txgbe_set_sgmii_an37_ability(hw); } } else if (txgbe_get_media_type(hw) == txgbe_media_type_fiber) { txgbe_set_link_to_sfi(hw, speed); + if (speed == TXGBE_LINK_SPEED_1GB_FULL) { + txgbe_setup_fc(hw); + txgbe_set_sgmii_an37_ability(hw); + } } out: @@ -5221,8 +5326,6 @@ STATIC s32 txgbe_setup_copper_link(struct txgbe_hw *hw, s32 status; u32 link_speed; - DEBUGFUNC("\n"); - /* Setup the PHY according to input speed */ link_speed = TCALL(hw, phy.ops.setup_link_speed, speed, autoneg_wait_to_complete); @@ -5312,8 +5415,6 @@ s32 txgbe_reset_hw(struct txgbe_hw *hw) struct txgbe_adapter *adapter = hw->back; u32 value; - DEBUGFUNC("\n"); - /* Call adapter stop to disable tx/rx and clear interrupts */ status = TCALL(hw, mac.ops.stop_adapter); if (status != 0) @@ -5377,14 +5478,12 @@ s32 txgbe_reset_hw(struct txgbe_hw *hw) ~TXGBE_FLAG2_MNG_REG_ACCESS_DISABLED; } } else if (hw->reset_type == TXGBE_GLOBAL_RESET) { -#ifndef _WIN32 struct txgbe_adapter *adapter = (struct txgbe_adapter *)hw->back; msleep(100 * rst_delay + 2000); pci_restore_state(adapter->pdev); pci_save_state(adapter->pdev); pci_wake_from_d3(adapter->pdev, false); -#endif /*_WIN32*/ } } else { if (txgbe_mng_present(hw)) { @@ -5460,6 +5559,9 @@ s32 txgbe_reset_hw(struct txgbe_hw *hw) } + /* wait to make sure phy power is up */ + msleep(100); + /*A temporary solution for set to sfi*/ if (SFI_SET == 1 || adapter->ffe_set == TXGBE_BP_M_SFI) { e_dev_info("Set SFI TX_EQ MAIN:%d PRE:%d POST:%d\n", @@ -5487,8 +5589,6 @@ s32 txgbe_reset_hw(struct txgbe_hw *hw) value = (0x50 & ~0x7F) | (1 << 6)| adapter->ffe_post; txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); - txgbe_wr32_epcs(hw, 0x18035, 0x00FF); - txgbe_wr32_epcs(hw, 0x18055, 0x00FF); } if (KX_SET == 1 || adapter->ffe_set == TXGBE_BP_M_KX) { @@ -5506,9 +5606,6 @@ s32 txgbe_reset_hw(struct txgbe_hw *hw) value = txgbe_rd32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1); value = (value & ~0x7F) | adapter->ffe_post | (1 << 6); txgbe_wr32_epcs(hw, TXGBE_PHY_TX_EQ_CTL1, value); - - txgbe_wr32_epcs(hw, 0x18035, 0x00FF); - txgbe_wr32_epcs(hw, 0x18055, 0x00FF); } /* Store the permanent mac address */ @@ -5578,8 +5675,6 @@ s32 txgbe_reinit_fdir_tables(struct txgbe_hw *hw) u32 fdircmd; fdirctrl &= ~TXGBE_RDB_FDIR_CTL_INIT_DONE; - DEBUGFUNC("\n"); - /* * Before starting reinitialization process, * FDIRCMD.CMD must be zero. @@ -5647,8 +5742,6 @@ STATIC void txgbe_fdir_enable(struct txgbe_hw *hw, u32 fdirctrl) { int i; - DEBUGFUNC("\n"); - /* Prime the keys for hashing */ wr32(hw, TXGBE_RDB_FDIR_HKEY, TXGBE_ATR_BUCKET_HASH_KEY); wr32(hw, TXGBE_RDB_FDIR_SKEY, TXGBE_ATR_SIGNATURE_HASH_KEY); @@ -5687,6 +5780,7 @@ STATIC void txgbe_fdir_enable(struct txgbe_hw *hw, u32 fdirctrl) **/ s32 txgbe_init_fdir_signature(struct txgbe_hw *hw, u32 fdirctrl) { + struct txgbe_adapter __always_unused *adapter = (struct txgbe_adapter *)hw->back; int i = VMDQ_P(0) / 4; int j = VMDQ_P(0) % 4; u32 flex = rd32m(hw, TXGBE_RDB_FDIR_FLEX_CFG(i), @@ -5731,8 +5825,6 @@ s32 txgbe_init_fdir_signature(struct txgbe_hw *hw, u32 fdirctrl) s32 txgbe_init_fdir_perfect(struct txgbe_hw *hw, u32 fdirctrl, bool __maybe_unused cloud_mode) { - DEBUGFUNC("\n"); - /* * Continue setup of fdirctrl register bits: * Turn perfect match filtering on @@ -5870,8 +5962,6 @@ s32 txgbe_fdir_add_signature_filter(struct txgbe_hw *hw, u32 fdircmd; s32 err; - DEBUGFUNC("\n"); - /* * Get the flow_type in order to program FDIRCMD properly * lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6 @@ -5996,10 +6086,7 @@ STATIC u32 txgbe_get_fdirtcpm(union txgbe_atr_input *input_mask) u32 mask = TXGBE_NTOHS(input_mask->formatted.dst_port); mask <<= TXGBE_RDB_FDIR_TCP_MSK_DPORTM_SHIFT; mask |= TXGBE_NTOHS(input_mask->formatted.src_port); - mask = ((mask & 0x55555555) << 1) | ((mask & 0xAAAAAAAA) >> 1); - mask = ((mask & 0x33333333) << 2) | ((mask & 0xCCCCCCCC) >> 2); - mask = ((mask & 0x0F0F0F0F) << 4) | ((mask & 0xF0F0F0F0) >> 4); - return ((mask & 0x00FF00FF) << 8) | ((mask & 0xFF00FF00) >> 8); + return mask; } /* @@ -6028,8 +6115,7 @@ s32 txgbe_fdir_set_input_mask(struct txgbe_hw *hw, u32 fdirtcpm; u32 flex = 0; int i, j; - - DEBUGFUNC("\n"); + struct txgbe_adapter __always_unused *adapter = (struct txgbe_adapter *)hw->back; /* * Program the relevant mask registers. If src/dst_port or src/dst_addr @@ -6123,7 +6209,6 @@ s32 txgbe_fdir_write_perfect_filter(struct txgbe_hw *hw, u32 fdirport, fdirvlan, fdirhash, fdircmd; s32 err; - DEBUGFUNC("\n"); if (!cloud_mode) { /* currently IPv6 is not supported, must be programmed with 0 */ wr32(hw, TXGBE_RDB_FDIR_IP6(2), @@ -6242,8 +6327,6 @@ s32 txgbe_start_hw(struct txgbe_hw *hw) int ret_val = 0; u32 i; - DEBUGFUNC("\n"); - /* Set the media type */ hw->phy.media_type = TCALL(hw, mac.ops.get_media_type); @@ -6290,8 +6373,6 @@ s32 txgbe_identify_phy(struct txgbe_hw *hw) s32 status = TXGBE_ERR_PHY_ADDR_INVALID; enum txgbe_media_type media_type; - DEBUGFUNC("\n"); - if (!hw->phy.phy_semaphore_mask) { hw->phy.phy_semaphore_mask = TXGBE_MNG_SWFW_SYNC_SW_PHY; } @@ -6329,9 +6410,6 @@ s32 txgbe_identify_phy(struct txgbe_hw *hw) **/ s32 txgbe_enable_rx_dma(struct txgbe_hw *hw, u32 regval) { - - DEBUGFUNC("\n"); - /* * Workaround for sapphire silicon errata when enabling the Rx datapath. * If traffic is incoming before we enable the Rx unit, it could hang @@ -6363,8 +6441,6 @@ s32 txgbe_init_flash_params(struct txgbe_hw *hw) struct txgbe_flash_info *flash = &hw->flash; u32 eec; - DEBUGFUNC("\n"); - eec = 0x1000000; flash->semaphore_delay = 10; flash->dword_size = (eec >> 2); @@ -6393,8 +6469,6 @@ s32 txgbe_read_flash_buffer(struct txgbe_hw *hw, u32 offset, s32 status = 0; u32 i; - DEBUGFUNC("\n"); - TCALL(hw, eeprom.ops.init_params); if (!dwords || offset + dwords >= hw->flash.dword_size) { @@ -6437,8 +6511,6 @@ s32 txgbe_write_flash_buffer(struct txgbe_hw *hw, u32 offset, s32 status = 0; u32 i; - DEBUGFUNC("\n"); - TCALL(hw, eeprom.ops.init_params); if (!dwords || offset + dwords >= hw->flash.dword_size) { @@ -6479,8 +6551,6 @@ s32 txgbe_init_eeprom_params(struct txgbe_hw *hw) s32 status = 0; u16 data; - DEBUGFUNC("\n"); - if (eeprom->type == txgbe_eeprom_uninitialized) { eeprom->semaphore_delay = 10; eeprom->type = txgbe_eeprom_none; @@ -6523,7 +6593,6 @@ s32 txgbe_read_ee_hostif_data(struct txgbe_hw *hw, u16 offset, s32 status; struct txgbe_hic_read_shadow_ram buffer; - DEBUGFUNC("\n"); buffer.hdr.req.cmd = FW_READ_SHADOW_RAM_CMD; buffer.hdr.req.buf_lenh = 0; buffer.hdr.req.buf_lenl = FW_READ_SHADOW_RAM_LEN; @@ -6564,8 +6633,6 @@ s32 txgbe_read_ee_hostif(struct txgbe_hw *hw, u16 offset, { s32 status = 0; - DEBUGFUNC("\n"); - if (TCALL(hw, mac.ops.acquire_swfw_sync, TXGBE_MNG_SWFW_SYNC_SW_FLASH) == 0) { status = txgbe_read_ee_hostif_data(hw, offset, data); @@ -6597,8 +6664,6 @@ s32 txgbe_read_ee_hostif_buffer(struct txgbe_hw *hw, u32 i; u32 value = 0; - DEBUGFUNC("\n"); - /* Take semaphore for the entire operation. */ status = TCALL(hw, mac.ops.acquire_swfw_sync, TXGBE_MNG_SWFW_SYNC_SW_FLASH); @@ -6672,8 +6737,6 @@ s32 txgbe_write_ee_hostif_data(struct txgbe_hw *hw, u16 offset, s32 status; struct txgbe_hic_write_shadow_ram buffer; - DEBUGFUNC("\n"); - buffer.hdr.req.cmd = FW_WRITE_SHADOW_RAM_CMD; buffer.hdr.req.buf_lenh = 0; buffer.hdr.req.buf_lenl = FW_WRITE_SHADOW_RAM_LEN; @@ -6691,6 +6754,81 @@ s32 txgbe_write_ee_hostif_data(struct txgbe_hw *hw, u16 offset, return status; } +s32 txgbe_close_notify(struct txgbe_hw *hw) +{ + int tmp; + s32 status; + struct txgbe_hic_write_shadow_ram buffer; + + buffer.hdr.req.cmd = FW_DW_CLOSE_NOTIFY; + buffer.hdr.req.buf_lenh = 0; + buffer.hdr.req.buf_lenl = 0; + buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; + + /* one word */ + buffer.length = 0; + buffer.address = 0; + + status = txgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), + TXGBE_HI_COMMAND_TIMEOUT, false); + if (status) + return status; + + if (txgbe_check_mng_access(hw)){ + tmp = (u32)rd32(hw, TXGBE_MNG_SW_SM); + if(tmp == TXGBE_CHECKSUM_CAP_ST_PASS) + { + status = 0; + } else { + status = TXGBE_ERR_EEPROM_CHECKSUM; + } + }else { + status = TXGBE_ERR_MNG_ACCESS_FAILED; + return status; + } + + return status; +} + +s32 txgbe_open_notify(struct txgbe_hw *hw) +{ + int tmp; + s32 status; + struct txgbe_hic_write_shadow_ram buffer; + + buffer.hdr.req.cmd = FW_DW_OPEN_NOTIFY; + buffer.hdr.req.buf_lenh = 0; + buffer.hdr.req.buf_lenl = 0; + buffer.hdr.req.checksum = FW_DEFAULT_CHECKSUM; + + /* one word */ + buffer.length = 0; + buffer.address = 0; + + status = txgbe_host_interface_command(hw, (u32 *)&buffer, + sizeof(buffer), + TXGBE_HI_COMMAND_TIMEOUT, false); + if (status) + return status; + + if (txgbe_check_mng_access(hw)){ + tmp = (u32)rd32(hw, TXGBE_MNG_SW_SM); + if(tmp == TXGBE_CHECKSUM_CAP_ST_PASS) + { + status = 0; + } else { + status = TXGBE_ERR_EEPROM_CHECKSUM; + } + }else { + status = TXGBE_ERR_MNG_ACCESS_FAILED; + return status; + } + + return status; +} + + /** * txgbe_write_ee_hostif - Write EEPROM word using hostif * @hw: pointer to hardware structure @@ -6704,8 +6842,6 @@ s32 txgbe_write_ee_hostif(struct txgbe_hw *hw, u16 offset, { s32 status = 0; - DEBUGFUNC("\n"); - if (TCALL(hw, mac.ops.acquire_swfw_sync, TXGBE_MNG_SWFW_SYNC_SW_FLASH) == 0) { status = txgbe_write_ee_hostif_data(hw, offset, data); @@ -6734,8 +6870,6 @@ s32 txgbe_write_ee_hostif_buffer(struct txgbe_hw *hw, s32 status = 0; u16 i = 0; - DEBUGFUNC("\n"); - /* Take semaphore for the entire operation. */ status = TCALL(hw, mac.ops.acquire_swfw_sync, TXGBE_MNG_SWFW_SYNC_SW_FLASH); @@ -6779,8 +6913,6 @@ s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw) u16 checksum = 0; u16 i; - DEBUGFUNC("\n"); - TCALL(hw, eeprom.ops.init_params); if (!buffer) { @@ -6827,8 +6959,6 @@ s32 txgbe_update_eeprom_checksum(struct txgbe_hw *hw) s32 status; u16 checksum = 0; - DEBUGFUNC("\n"); - /* Read the first word from the EEPROM. If this times out or fails, do * not continue or we could be in for a very long wait while every * EEPROM read fails @@ -6868,8 +6998,6 @@ s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw, u16 checksum; u16 read_checksum = 0; - DEBUGFUNC("\n"); - /* Read the first word from the EEPROM. If this times out or fails, do * not continue or we could be in for a very long wait while every * EEPROM read fails @@ -6908,6 +7036,16 @@ s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw, return status; } +u32 txgbe_flash_read_dword(struct txgbe_hw *hw, u32 addr) +{ + u8 status = fmgr_cmd_op(hw, SPI_CMD_READ_DWORD, addr); + if (status) + return (u32)status; + + return rd32(hw, SPI_H_DAT_REG_ADDR); +} + + /** * txgbe_update_flash - Instruct HW to copy EEPROM to Flash device * @hw: pointer to hardware structure @@ -6950,12 +7088,10 @@ s32 txgbe_check_mac_link(struct txgbe_hw *hw, u32 *speed, u32 i; u16 value; - DEBUGFUNC("\n"); - if (link_up_wait_to_complete) { for (i = 0; i < TXGBE_LINK_UP_TIME; i++) { if (TCALL(hw, mac.ops.get_media_type) == txgbe_media_type_copper && - ((hw->subsystem_id & 0xF0) != TXGBE_ID_SFI_XAUI)) { + ((hw->subsystem_device_id & 0xF0) != TXGBE_ID_SFI_XAUI)) { /* read ext phy link status */ txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 0x03, 0x8008, &value); if (value & 0x400) { @@ -6980,7 +7116,7 @@ s32 txgbe_check_mac_link(struct txgbe_hw *hw, u32 *speed, } } else { if (TCALL(hw, mac.ops.get_media_type) == txgbe_media_type_copper && - ((hw->subsystem_id & 0xF0) != TXGBE_ID_SFI_XAUI)) { + ((hw->subsystem_device_id & 0xF0) != TXGBE_ID_SFI_XAUI)) { /* read ext phy link status */ txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 0x03, 0x8008, &value); if (value & 0x400) { @@ -7003,7 +7139,7 @@ s32 txgbe_check_mac_link(struct txgbe_hw *hw, u32 *speed, if (*link_up) { if (TCALL(hw, mac.ops.get_media_type) == txgbe_media_type_copper && - ((hw->subsystem_id & 0xF0) != TXGBE_ID_SFI_XAUI)) { + ((hw->subsystem_device_id & 0xF0) != TXGBE_ID_SFI_XAUI)) { if ((value & 0xc000) == 0xc000) { *speed = TXGBE_LINK_SPEED_10GB_FULL; } else if ((value & 0xc000) == 0x8000) { @@ -7045,7 +7181,5 @@ s32 txgbe_check_mac_link(struct txgbe_hw *hw, u32 *speed, s32 txgbe_setup_eee(struct txgbe_hw __maybe_unused *hw, bool __maybe_unused enable_eee) { /* fix eee */ - DEBUGFUNC("\n"); - return 0; } diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_hw.h b/drivers/net/ethernet/netswift/txgbe/txgbe_hw.h index 97ce62a2cd26ac2b0a3e7b178f7a10af778c0a2a..45bb3a5a3ae6d157921fcae4d58a83aaffc5af60 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_hw.h +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_hw.h @@ -27,6 +27,43 @@ #define TXGBE_EMC_DIODE3_DATA 0x2A #define TXGBE_EMC_DIODE3_THERM_LIMIT 0x30 +#define SPI_CLK_DIV 2 + +#define SPI_CMD_ERASE_CHIP 4 // SPI erase chip command +#define SPI_CMD_ERASE_SECTOR 3 // SPI erase sector command +#define SPI_CMD_WRITE_DWORD 0 // SPI write a dword command +#define SPI_CMD_READ_DWORD 1 // SPI read a dword command +#define SPI_CMD_USER_CMD 5 // SPI user command + +#define SPI_CLK_CMD_OFFSET 28 // SPI command field offset in Command register +#define SPI_CLK_DIV_OFFSET 25 // SPI clock divide field offset in Command register + +#define SPI_TIME_OUT_VALUE 10000 +#define SPI_SECTOR_SIZE (4 * 1024) // FLASH sector size is 64KB +#define SPI_H_CMD_REG_ADDR 0x10104 // SPI Command register address +#define SPI_H_DAT_REG_ADDR 0x10108 // SPI Data register address +#define SPI_H_STA_REG_ADDR 0x1010c // SPI Status register address +#define SPI_H_USR_CMD_REG_ADDR 0x10110 // SPI User Command register address +#define SPI_CMD_CFG1_ADDR 0x10118 // Flash command configuration register 1 +#define MISC_RST_REG_ADDR 0x1000c // Misc reset register address +#define MGR_FLASH_RELOAD_REG_ADDR 0x101a0 // MGR reload flash read + +#define MAC_ADDR0_WORD0_OFFSET_1G 0x006000c // MAC Address for LAN0, stored in external FLASH +#define MAC_ADDR0_WORD1_OFFSET_1G 0x0060014 +#define MAC_ADDR1_WORD0_OFFSET_1G 0x007000c // MAC Address for LAN1, stored in external FLASH +#define MAC_ADDR1_WORD1_OFFSET_1G 0x0070014 +/* Product Serial Number, stored in external FLASH last sector */ +#define PRODUCT_SERIAL_NUM_OFFSET_1G 0x00f0000 + +struct txgbe_hic_read_cab { + union txgbe_hic_hdr2 hdr; + union { + u8 d8[252]; + u16 d16[126]; + u32 d32[63]; + } dbuf; +}; + /** * Packet Type decoding **/ @@ -238,6 +275,9 @@ s32 txgbe_calc_eeprom_checksum(struct txgbe_hw *hw); s32 txgbe_validate_eeprom_checksum(struct txgbe_hw *hw, u16 *checksum_val); s32 txgbe_update_flash(struct txgbe_hw *hw); +int txgbe_upgrade_flash(struct txgbe_hw *hw, u32 region, + const u8 *data, u32 size); + s32 txgbe_write_ee_hostif_buffer(struct txgbe_hw *hw, u16 offset, u16 words, u16 *data); s32 txgbe_write_ee_hostif(struct txgbe_hw *hw, u16 offset, @@ -250,9 +290,13 @@ void txgbe_wr32_epcs(struct txgbe_hw *hw, u32 addr, u32 data); void txgbe_wr32_ephy(struct txgbe_hw *hw, u32 addr, u32 data); u32 rd32_ephy(struct txgbe_hw *hw, u32 addr); +u32 txgbe_flash_read_dword(struct txgbe_hw *hw, u32 addr); s32 txgbe_upgrade_flash_hostif(struct txgbe_hw *hw, u32 region, const u8 *data, u32 size); +s32 txgbe_close_notify(struct txgbe_hw *hw); +s32 txgbe_open_notify(struct txgbe_hw *hw); + s32 txgbe_set_link_to_kr(struct txgbe_hw *hw, bool autoneg); s32 txgbe_set_link_to_kx4(struct txgbe_hw *hw, bool autoneg); diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_lib.c b/drivers/net/ethernet/netswift/txgbe/txgbe_lib.c index bb402e45557eb75c8a58979954f8816cf64059c3..87d1159142c06a1998d6f76c1b7b5ac61d36b990 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_lib.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_lib.c @@ -472,6 +472,7 @@ static void txgbe_set_num_queues(struct txgbe_adapter *adapter) adapter->num_rx_queues = 1; adapter->num_tx_queues = 1; adapter->queues_per_pool = 1; + adapter->num_xdp_queues = 0; if (txgbe_set_dcb_vmdq_queues(adapter)) return; diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_main.c b/drivers/net/ethernet/netswift/txgbe/txgbe_main.c index 5e21f1a22984c8a2e4eee11a14b1761a771742fc..6be8d8cbbbffeea4f637439afdeaa3087fb77606 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_main.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_main.c @@ -40,7 +40,14 @@ #include #include #include +#include +#include +#include #include +#include +#include +#include +#include #include "txgbe.h" #include "txgbe_hw.h" @@ -61,7 +68,7 @@ static const char txgbe_driver_string[] = #define RELEASE_TAG -#define DRV_VERSION __stringify(1.1.17oe) +#define DRV_VERSION __stringify(1.3.2oe) const char txgbe_driver_version[32] = DRV_VERSION; static const char txgbe_copyright[] = @@ -472,8 +479,8 @@ static void txgbe_tx_timeout(struct net_device *netdev, unsigned int __always_un wr32(&adapter->hw, TXGBE_PX_IMC(1), value3); } + ERROR_REPORT1(TXGBE_ERROR_POLLING, "tx timeout. do pcie recovery.\n"); if (adapter->hw.bus.lan_id == 0) { - ERROR_REPORT1(TXGBE_ERROR_POLLING, "tx timeout. do pcie recovery.\n"); adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; txgbe_service_event_schedule(adapter); } else @@ -617,8 +624,11 @@ static bool txgbe_clean_tx_irq(struct txgbe_q_vector *q_vector, /* schedule immediate reset if we believe we hung */ e_info(hw, "real tx hang. do pcie recovery.\n"); - adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; - txgbe_service_event_schedule(adapter); + if (adapter->hw.bus.lan_id == 0) { + adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; + txgbe_service_event_schedule(adapter); + } else + wr32(&adapter->hw, TXGBE_MIS_PF_SM, 1); /* the adapter is about to reset, no point in enabling stuff */ return true; @@ -1800,7 +1810,7 @@ void txgbe_irq_enable(struct txgbe_adapter *adapter, bool queues, bool flush) { u32 mask = 0; struct txgbe_hw *hw = &adapter->hw; - u8 device_type = hw->subsystem_id & 0xF0; + u8 device_type = hw->subsystem_device_id & 0xF0; /* enable gpio interrupt */ if (device_type != TXGBE_ID_MAC_XAUI && @@ -2097,27 +2107,32 @@ static irqreturn_t txgbe_intr(int __always_unused irq, void *data) struct txgbe_adapter *adapter = data; struct txgbe_q_vector *q_vector = adapter->q_vector[0]; struct txgbe_hw *hw = &adapter->hw; - u32 eicr; u32 eicr_misc; u32 value ; + u16 pci_value; - eicr = txgbe_misc_isb(adapter, TXGBE_ISB_VEC0); - if (!eicr) { - /* - * shared interrupt alert! - * the interrupt that we masked before the EICR read. - */ - if (!test_bit(__TXGBE_DOWN, &adapter->state)) - txgbe_irq_enable(adapter, true, true); - return IRQ_NONE; /* Not our interrupt */ - } - adapter->isb_mem[TXGBE_ISB_VEC0] = 0; - if (!(adapter->flags & TXGBE_FLAG_MSI_ENABLED)) + if (!(adapter->flags & TXGBE_FLAG_MSI_ENABLED)) { + pci_read_config_word(adapter->pdev, PCI_STATUS, &pci_value); + if (!(pci_value & PCI_STATUS_INTERRUPT)) + return IRQ_HANDLED; /* Not our interrupt */ wr32(&(adapter->hw), TXGBE_PX_INTA, 1); + } eicr_misc = txgbe_misc_isb(adapter, TXGBE_ISB_MISC); - if (eicr_misc & (TXGBE_PX_MISC_IC_ETH_LK | TXGBE_PX_MISC_IC_ETH_LKDN)) - txgbe_check_lsc(adapter); + if (BOND_CHECK_LINK_MODE == 1) { + if (eicr_misc & (TXGBE_PX_MISC_IC_ETH_LKDN)) { + value = rd32(hw, 0x14404); + value = value & 0x1; + if (value == 0) { + adapter->link_up = false; + adapter->flags2 |= TXGBE_FLAG2_LINK_DOWN; + txgbe_service_event_schedule(adapter); + } + } + } else { + if (eicr_misc & (TXGBE_PX_MISC_IC_ETH_LK | TXGBE_PX_MISC_IC_ETH_LKDN)) + txgbe_check_lsc(adapter); + } if (eicr_misc & TXGBE_PX_MISC_IC_ETH_AN) { if (adapter->backplane_an == 1 && (KR_POLLING == 0)) { @@ -3214,13 +3229,24 @@ int txgbe_add_mac_filter(struct txgbe_adapter *adapter, u8 *addr, u16 pool) return -EINVAL; for (i = 0; i < hw->mac.num_rar_entries; i++) { + if (adapter->mac_table[i].state & TXGBE_MAC_STATE_IN_USE) { + if (ether_addr_equal(addr, adapter->mac_table[i].addr)) { + if (adapter->mac_table[i].pools != (1ULL << pool)) { + memcpy(adapter->mac_table[i].addr, addr, ETH_ALEN); + adapter->mac_table[i].pools |= (1ULL << pool); + txgbe_sync_mac_table(adapter); + return i; + } + } + } + if (adapter->mac_table[i].state & TXGBE_MAC_STATE_IN_USE) { continue; } adapter->mac_table[i].state |= (TXGBE_MAC_STATE_MODIFIED | TXGBE_MAC_STATE_IN_USE); memcpy(adapter->mac_table[i].addr, addr, ETH_ALEN); - adapter->mac_table[i].pools = (1ULL << pool); + adapter->mac_table[i].pools |= (1ULL << pool); txgbe_sync_mac_table(adapter); return i; } @@ -3251,16 +3277,29 @@ int txgbe_del_mac_filter(struct txgbe_adapter *adapter, u8 *addr, u16 pool) return -EINVAL; for (i = 0; i < hw->mac.num_rar_entries; i++) { - if (ether_addr_equal(addr, adapter->mac_table[i].addr) && - adapter->mac_table[i].pools | (1ULL << pool)) { - adapter->mac_table[i].state |= TXGBE_MAC_STATE_MODIFIED; - adapter->mac_table[i].state &= ~TXGBE_MAC_STATE_IN_USE; - memset(adapter->mac_table[i].addr, 0, ETH_ALEN); - adapter->mac_table[i].pools = 0; - txgbe_sync_mac_table(adapter); + if (ether_addr_equal(addr, adapter->mac_table[i].addr)) { + if (adapter->mac_table[i].pools & (1ULL << pool)) { + adapter->mac_table[i].state |= TXGBE_MAC_STATE_MODIFIED; + adapter->mac_table[i].state &= ~TXGBE_MAC_STATE_IN_USE; + adapter->mac_table[i].pools &= ~(1ULL << pool) ; + txgbe_sync_mac_table(adapter); + } return 0; } + + if (adapter->mac_table[i].pools != (1 << pool)) + continue; + if ( !ether_addr_equal(addr, adapter->mac_table[i].addr)) + continue; + + adapter->mac_table[i].state |= TXGBE_MAC_STATE_MODIFIED; + adapter->mac_table[i].state &= ~TXGBE_MAC_STATE_IN_USE; + memset(adapter->mac_table[i].addr, 0, ETH_ALEN); + adapter->mac_table[i].pools = 0; + txgbe_sync_mac_table(adapter); + return 0; } + return -ENOMEM; } @@ -3817,7 +3856,7 @@ static int txgbe_non_sfp_link_config(struct txgbe_hw *hw) if (link_up) return 0; - if ((hw->subsystem_id & 0xF0) != TXGBE_ID_SFI_XAUI) { + if ((hw->subsystem_device_id & 0xF0) != TXGBE_ID_SFI_XAUI) { /* setup external PHY Mac Interface */ mtdSetMacInterfaceControl(&hw->phy_dev, hw->phy.addr, MTD_MAC_TYPE_XAUI, MTD_FALSE, MTD_MAC_SNOOP_OFF, @@ -3836,7 +3875,7 @@ static int txgbe_non_sfp_link_config(struct txgbe_hw *hw) autoneg = false; } - ret = TCALL(hw, mac.ops.setup_link, speed, autoneg); + ret = TCALL(hw, mac.ops.setup_link, speed, false); link_cfg_out: return ret; @@ -3956,10 +3995,12 @@ static void txgbe_up_complete(struct txgbe_adapter *adapter) rd32(hw, TXGBE_PX_IC(0)); rd32(hw, TXGBE_PX_IC(1)); rd32(hw, TXGBE_PX_MISC_IC); + if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_XAUI) + wr32(hw, TXGBE_GPIO_EOI, TXGBE_GPIO_EOI_6); txgbe_irq_enable(adapter, true, true); /* enable external PHY interrupt */ - if ((hw->subsystem_id & 0xF0) == TXGBE_ID_XAUI) { + if ((hw->subsystem_device_id & 0xF0) == TXGBE_ID_XAUI) { txgbe_read_mdio(&hw->phy_dev, hw->phy.addr, 0x03, 0x8011, &value); /* only enable T unit int */ txgbe_write_mdio(&hw->phy_dev, hw->phy.addr, 31, 0xf043, 0x1); @@ -3976,8 +4017,23 @@ static void txgbe_up_complete(struct txgbe_adapter *adapter) * link up interrupt but shouldn't be a problem */ adapter->flags |= TXGBE_FLAG_NEED_LINK_UPDATE; adapter->link_check_timeout = jiffies; - + +#ifdef CONFIG_TXGBE_POLL_LINK_STATUS + mod_timer(&adapter->link_check_timer,jiffies); +#endif mod_timer(&adapter->service_timer, jiffies); + + if (hw->bus.lan_id == 0) { + wr32m(hw, TXGBE_MIS_PRB_CTL, + TXGBE_MIS_PRB_CTL_LAN0_UP, TXGBE_MIS_PRB_CTL_LAN0_UP); + } + else if (hw->bus.lan_id == 1) { + wr32m(hw, TXGBE_MIS_PRB_CTL, + TXGBE_MIS_PRB_CTL_LAN1_UP, TXGBE_MIS_PRB_CTL_LAN1_UP); + } + else + e_err(probe, "txgbe_up_complete:invalid bus lan id %d\n", hw->bus.lan_id); + txgbe_clear_vf_stats_counters(adapter); /* Set PF Reset Done bit so PF/VF Mail Ops can work */ @@ -3987,6 +4043,11 @@ static void txgbe_up_complete(struct txgbe_adapter *adapter) void txgbe_reinit_locked(struct txgbe_adapter *adapter) { + if (adapter->flags2 & TXGBE_FLAG2_KR_PRO_REINIT) { + return; + } + + adapter->flags2 |= TXGBE_FLAG2_KR_PRO_REINIT; WARN_ON(in_interrupt()); /* put off any impending NetWatchDogTimeout */ netif_trans_update(adapter->netdev); @@ -4004,6 +4065,7 @@ void txgbe_reinit_locked(struct txgbe_adapter *adapter) msleep(2000); txgbe_up(adapter); clear_bit(__TXGBE_RESETTING, &adapter->state); + adapter->flags2 &= ~TXGBE_FLAG2_KR_PRO_REINIT; } void txgbe_up(struct txgbe_adapter *adapter) @@ -4247,7 +4309,19 @@ void txgbe_disable_device(struct txgbe_adapter *adapter) TXGBE_FLAG2_GLOBAL_RESET_REQUESTED); adapter->flags &= ~TXGBE_FLAG_NEED_LINK_UPDATE; +#ifdef CONFIG_TXGBE_POLL_LINK_STATUS + del_timer_sync(&adapter->link_check_timer); +#endif del_timer_sync(&adapter->service_timer); + + if (hw->bus.lan_id == 0) + wr32m(hw, TXGBE_MIS_PRB_CTL, + TXGBE_MIS_PRB_CTL_LAN0_UP, 0); + else if (hw->bus.lan_id == 1) + wr32m(hw, TXGBE_MIS_PRB_CTL, + TXGBE_MIS_PRB_CTL_LAN1_UP, 0); + else + e_dev_err("txgbe_disable_device:invalid bus lan id %d\n", hw->bus.lan_id); if (adapter->num_vfs) { /* Clear EITR Select mapping */ @@ -4337,6 +4411,7 @@ static int txgbe_sw_init(struct txgbe_adapter *adapter) struct pci_dev *pdev = adapter->pdev; int err; unsigned int fdir; + u32 ssid = 0; /* PCI config space info */ hw->vendor_id = pdev->vendor; @@ -4348,14 +4423,20 @@ static int txgbe_sw_init(struct txgbe_adapter *adapter) err = -ENODEV; goto out; } - hw->subsystem_vendor_id = pdev->subsystem_vendor; - hw->subsystem_device_id = pdev->subsystem_device; - - pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &hw->subsystem_id); - if (hw->subsystem_id == TXGBE_FAILED_READ_CFG_WORD) { - e_err(probe, "read of subsystem id failed\n"); - err = -ENODEV; - goto out; + hw->oem_svid = pdev->subsystem_vendor; + hw->oem_ssid = pdev->subsystem_device; + if (pdev->subsystem_vendor == 0x8088) { + hw->subsystem_vendor_id = pdev->subsystem_vendor; + hw->subsystem_device_id = pdev->subsystem_device; + } else { + ssid = txgbe_flash_read_dword(hw, 0xfffdc); + if (ssid == 0x1) { + e_err(probe, "read of internel subsystem device id failed\n"); + err = -ENODEV; + } + hw->subsystem_device_id = (u16)ssid; + hw->subsystem_device_id = hw->subsystem_device_id >> 8 | + hw->subsystem_device_id << 8; } err = txgbe_init_shared_code(hw); @@ -4375,6 +4456,7 @@ static int txgbe_sw_init(struct txgbe_adapter *adapter) memcpy(adapter->rss_key, def_rss_key, sizeof(def_rss_key)); /* Set common capability flags and settings */ + adapter->flags |= TXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE; adapter->flags2 |= TXGBE_FLAG2_RSC_CAPABLE; fdir = min_t(int, TXGBE_MAX_FDIR_INDICES, num_online_cpus()); adapter->ring_feature[RING_F_FDIR].limit = fdir; @@ -5303,17 +5385,19 @@ static void txgbe_watchdog_update_link(struct txgbe_adapter *adapter) struct txgbe_hw *hw = &adapter->hw; u32 link_speed = adapter->link_speed; bool link_up = adapter->link_up; -// bool pfc_en = adapter->dcb_cfg.pfc_mode_enable; u32 reg; - u32 i = 1; - + u32 __maybe_unused i = 1; + +#ifndef CONFIG_TXGBE_POLL_LINK_STATUS if (!(adapter->flags & TXGBE_FLAG_NEED_LINK_UPDATE)) return; +#endif link_speed = TXGBE_LINK_SPEED_10GB_FULL; link_up = true; TCALL(hw, mac.ops.check_link, &link_speed, &link_up, false); +#ifndef CONFIG_TXGBE_POLL_LINK_STATUS if (link_up || time_after(jiffies, (adapter->link_check_timeout + TXGBE_TRY_LINK_TIMEOUT))) { adapter->flags &= ~TXGBE_FLAG_NEED_LINK_UPDATE; @@ -5323,8 +5407,13 @@ static void txgbe_watchdog_update_link(struct txgbe_adapter *adapter) TCALL(hw, mac.ops.check_link, &link_speed, &link_up, false); msleep(1); } +#endif - if (link_up && !((adapter->flags & TXGBE_FLAG_DCB_ENABLED))) { + adapter->link_up = link_up; + adapter->link_speed = link_speed; + + + if (link_up && !(adapter->flags & TXGBE_FLAG_DCB_ENABLED) ) { TCALL(hw, mac.ops.fc_enable); txgbe_set_rx_drop_en(adapter); } @@ -5419,8 +5508,6 @@ static void txgbe_watchdog_link_is_up(struct txgbe_adapter *adapter) /* update the default user priority for VFs */ txgbe_update_default_up(adapter); - - /* ping all the active vfs to let them know link has changed */ } /** @@ -5435,24 +5522,21 @@ static void txgbe_watchdog_link_is_down(struct txgbe_adapter *adapter) adapter->link_up = false; adapter->link_speed = 0; - /* only continue if link was up previously */ - if (!netif_carrier_ok(netdev)) - return; - if (hw->subsystem_device_id == TXGBE_ID_WX1820_KR_KX_KX4 || hw->subsystem_device_id == TXGBE_ID_SP1000_KR_KX_KX4) { txgbe_bp_down_event(adapter); } + /* only continue if link was up previously */ + if (!netif_carrier_ok(netdev)) + return; + if (test_bit(__TXGBE_PTP_RUNNING, &adapter->state)) txgbe_ptp_start_cyclecounter(adapter); e_info(drv, "NIC Link is Down\n"); netif_carrier_off(netdev); netif_tx_stop_all_queues(netdev); - - /* ping all the active vfs to let them know link has changed */ - } static bool txgbe_ring_tx_pending(struct txgbe_adapter *adapter) @@ -5524,7 +5608,7 @@ static void txgbe_watchdog_flush_tx(struct txgbe_adapter *adapter) **/ static void txgbe_watchdog_subtask(struct txgbe_adapter *adapter) { - u32 value = 0; + u32 __maybe_unused value = 0; struct txgbe_hw *hw = &adapter->hw; /* if interface is down do nothing */ @@ -5538,6 +5622,7 @@ static void txgbe_watchdog_subtask(struct txgbe_adapter *adapter) txgbe_bp_watchdog_event(adapter); } +#ifndef CONFIG_TXGBE_POLL_LINK_STATUS if (BOND_CHECK_LINK_MODE == 1) { value = rd32(hw, 0x14404); value = value & 0x1; @@ -5551,6 +5636,7 @@ static void txgbe_watchdog_subtask(struct txgbe_adapter *adapter) txgbe_watchdog_link_is_up(adapter); else txgbe_watchdog_link_is_down(adapter); +#endif txgbe_update_stats(adapter); @@ -5638,7 +5724,7 @@ static void txgbe_sfp_link_config_subtask(struct txgbe_adapter *adapter) u32 speed; bool autoneg = false; u16 value; - u8 device_type = hw->subsystem_id & 0xF0; + u8 device_type = hw->subsystem_device_id & 0xF0; if (!(adapter->flags & TXGBE_FLAG_NEED_LINK_CONFIG)) return; @@ -5678,7 +5764,7 @@ static void txgbe_sfp_link_config_subtask(struct txgbe_adapter *adapter) } } - TCALL(hw, mac.ops.setup_link, speed, txgbe_is_sfp(hw)); + TCALL(hw, mac.ops.setup_link, speed, false); adapter->flags |= TXGBE_FLAG_NEED_LINK_UPDATE; adapter->link_check_timeout = jiffies; @@ -5721,6 +5807,7 @@ static void txgbe_service_timer(struct timer_list *t) struct txgbe_adapter *adapter = from_timer(adapter, t, service_timer); unsigned long next_event_offset; struct txgbe_hw *hw = &adapter->hw; + u32 val = 0; /* poll faster when waiting for link */ if (adapter->flags & TXGBE_FLAG_NEED_LINK_UPDATE) { @@ -5733,8 +5820,20 @@ static void txgbe_service_timer(struct timer_list *t) } else next_event_offset = HZ * 2; - if ((rd32(&adapter->hw, TXGBE_MIS_PF_SM) == 1) && (hw->bus.lan_id)) { - adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; + if (rd32(&adapter->hw, TXGBE_MIS_PF_SM) == 1) { + val = rd32m(&adapter->hw, TXGBE_MIS_PRB_CTL, TXGBE_MIS_PRB_CTL_LAN0_UP | + TXGBE_MIS_PRB_CTL_LAN1_UP); + if (val & TXGBE_MIS_PRB_CTL_LAN0_UP) { + if (hw->bus.lan_id == 0) { + adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; + e_info(probe, "txgbe_service_timer: set recover on Lan0\n"); + } + } else if (val & TXGBE_MIS_PRB_CTL_LAN1_UP) { + if (hw->bus.lan_id == 1) { + adapter->flags2 |= TXGBE_FLAG2_PCIE_NEED_RECOVER; + e_info(probe, "txgbe_service_timer: set recover on Lan1\n"); + } + } } /* Reset the timer */ @@ -5743,6 +5842,31 @@ static void txgbe_service_timer(struct timer_list *t) txgbe_service_event_schedule(adapter); } +#ifdef CONFIG_TXGBE_POLL_LINK_STATUS +/** + * txgbe_service_timer - Timer Call-back + * @data: pointer to adapter cast into an unsigned long + **/ +static void txgbe_link_check_timer(struct timer_list *t) +{ + struct txgbe_adapter *adapter = from_timer(adapter, t, link_check_timer); + unsigned long next_event_offset = HZ/100; + + mod_timer(&adapter->link_check_timer, next_event_offset + jiffies); + if(test_bit(__TXGBE_DOWN,&adapter->state) || + test_bit(__TXGBE_REMOVING,&adapter->state) || + test_bit(__TXGBE_RESETTING,&adapter->state)) + return; + + txgbe_watchdog_update_link(adapter); + + if (adapter->link_up) + txgbe_watchdog_link_is_up(adapter); + else + txgbe_watchdog_link_is_down(adapter); +} +#endif + static void txgbe_reset_subtask(struct txgbe_adapter *adapter) { u32 reset_flag = 0; @@ -6724,6 +6848,7 @@ netdev_tx_t txgbe_xmit_frame_ring(struct sk_buff *skb, __be16 protocol = skb->protocol; u8 hdr_len = 0; txgbe_dptype dptype; + u8 vlan_addlen = 0; /* work around hw errata 3 */ u16 _llcLen, *llcLen; @@ -6773,6 +6898,17 @@ netdev_tx_t txgbe_xmit_frame_ring(struct sk_buff *skb, tx_flags |= TXGBE_TX_FLAGS_SW_VLAN; } + if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD)) { + struct vlan_hdr *vhdr, _vhdr; + vhdr = skb_header_pointer(skb, ETH_HLEN, sizeof(_vhdr), &_vhdr); + if (!vhdr) + goto out_drop; + + protocol = vhdr->h_vlan_encapsulated_proto; + tx_flags |= TXGBE_TX_FLAGS_SW_VLAN; + vlan_addlen += VLAN_HLEN; + } + if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) && adapter->ptp_clock) { if (!test_and_set_bit_lock(__TXGBE_PTP_TX_IN_PROGRESS, @@ -6984,26 +7120,6 @@ static int txgbe_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) } } -/* txgbe_validate_rtr - verify 802.1Qp to Rx packet buffer mapping is valid. - * @adapter: pointer to txgbe_adapter - * @tc: number of traffic classes currently enabled - * - * Configure a valid 802.1Qp to Rx packet buffer mapping ie confirm - * 802.1Q priority maps to a packet buffer that exists. - */ -static void txgbe_validate_rtr(struct txgbe_adapter *adapter, u8 tc) -{ - struct txgbe_hw *hw = &adapter->hw; - u32 reg, rsave; - - reg = rd32(hw, TXGBE_RDB_UP2TC); - rsave = reg; - if (reg != rsave) - wr32(hw, TXGBE_RDB_UP2TC, reg); - - return; -} - /** * txgbe_set_prio_tc_map - Configure netdev prio tc map * @adapter: Pointer to adapter struct @@ -7046,8 +7162,6 @@ int txgbe_setup_tc(struct net_device *dev, u8 tc) netdev_reset_tc(dev); } - txgbe_validate_rtr(adapter, tc); - txgbe_init_interrupt_scheme(adapter); if (netif_running(dev)) txgbe_open(dev); @@ -7168,13 +7282,9 @@ static int txgbe_set_features(struct net_device *netdev, else txgbe_vlan_strip_disable(adapter); - if (adapter->flags & TXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE && - features & NETIF_F_RXCSUM) { - if (!need_reset) - adapter->flags2 |= TXGBE_FLAG2_VXLAN_REREG_NEEDED; - } else { + if (!(adapter->flags & TXGBE_FLAG_VXLAN_OFFLOAD_CAPABLE && + features & NETIF_F_RXCSUM)) txgbe_clear_vxlan_port(adapter); - } if (features & NETIF_F_RXHASH) { if (!(adapter->flags2 & TXGBE_FLAG2_RSS_ENABLED)) { @@ -7206,7 +7316,7 @@ static void txgbe_add_udp_tunnel_port(struct net_device *dev, { struct txgbe_adapter *adapter = netdev_priv(dev); struct txgbe_hw *hw = &adapter->hw; - __be16 port = ti->port; + __be16 port = ntohs(ti->port); if (ti->sa_family != AF_INET) return; @@ -7492,10 +7602,7 @@ static int txgbe_probe(struct pci_dev *pdev, char *info_string, *i_s_var; u8 part_str[TXGBE_PBANUM_LENGTH]; unsigned int indices = MAX_TX_QUEUES; - bool disable_dev = false; -/* #ifndef NETIF_F_GSO_PARTIA */ - netdev_features_t hw_features; err = pci_enable_device_mem(pdev); if (err) @@ -7614,51 +7721,43 @@ static int txgbe_probe(struct pci_dev *pdev, netdev->features |= NETIF_F_IPV6_CSUM; #endif - netdev->features |= NETIF_F_HW_VLAN_CTAG_TX | - NETIF_F_HW_VLAN_CTAG_RX; - - netdev->features |= txgbe_tso_features(); + netdev->features = NETIF_F_SG | + NETIF_F_TSO | + NETIF_F_TSO6 | + NETIF_F_RXHASH | + NETIF_F_RXCSUM | + NETIF_F_HW_CSUM; - if (adapter->flags2 & TXGBE_FLAG2_RSS_ENABLED) - netdev->features |= NETIF_F_RXHASH; + netdev->gso_partial_features = TXGBE_GSO_PARTIAL_FEATURES; + netdev->features |= NETIF_F_GSO_PARTIAL | + TXGBE_GSO_PARTIAL_FEATURES; - netdev->features |= NETIF_F_RXCSUM; + netdev->features |= NETIF_F_SCTP_CRC; /* copy netdev features into list of user selectable features */ - hw_features = netdev->hw_features; - hw_features |= netdev->features; - - /* give us the option of enabling RSC/LRO later */ - if (adapter->flags2 & TXGBE_FLAG2_RSC_CAPABLE) - hw_features |= NETIF_F_LRO; - - /* set this bit last since it cannot be part of hw_features */ - netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; - - netdev->features |= NETIF_F_NTUPLE; - - adapter->flags |= TXGBE_FLAG_FDIR_PERFECT_CAPABLE; - hw_features |= NETIF_F_NTUPLE; - netdev->hw_features = hw_features; - - netdev->vlan_features |= NETIF_F_SG | - NETIF_F_IP_CSUM | - NETIF_F_IPV6_CSUM | - NETIF_F_TSO | - NETIF_F_TSO6; - - netdev->hw_enc_features |= NETIF_F_SG | NETIF_F_IP_CSUM | - TXGBE_GSO_PARTIAL_FEATURES | NETIF_F_TSO; - if (netdev->features & NETIF_F_LRO) { - if ((adapter->flags2 & TXGBE_FLAG2_RSC_CAPABLE) && - ((adapter->rx_itr_setting == 1) || - (adapter->rx_itr_setting > TXGBE_MIN_RSC_ITR))) { - adapter->flags2 |= TXGBE_FLAG2_RSC_ENABLED; - } else if (adapter->flags2 & TXGBE_FLAG2_RSC_CAPABLE) { - e_dev_info("InterruptThrottleRate set too high, " - "disabling RSC\n"); - } - } + netdev->hw_features |= netdev->features | + NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_TX | + NETIF_F_RXALL; + + netdev->hw_features |= NETIF_F_NTUPLE | + NETIF_F_HW_TC; + + if (pci_using_dac) + netdev->features |= NETIF_F_HIGHDMA; + + netdev->vlan_features |= netdev->features | NETIF_F_TSO_MANGLEID; + netdev->hw_enc_features |= netdev->vlan_features; + netdev->mpls_features |= NETIF_F_HW_CSUM; + + /* set this bit last since it cannot be part of vlan_features */ + netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_CTAG_RX | + NETIF_F_HW_VLAN_CTAG_TX; + + netdev->priv_flags |= IFF_UNICAST_FLT; + netdev->priv_flags |= IFF_SUPP_NOFCS; netdev->priv_flags |= IFF_UNICAST_FLT; netdev->priv_flags |= IFF_SUPP_NOFCS; @@ -7674,6 +7773,7 @@ static int txgbe_probe(struct pci_dev *pdev, /* make sure the EEPROM is good */ if (TCALL(hw, eeprom.ops.validate_checksum, NULL)) { e_dev_err("The EEPROM Checksum Is Not Valid\n"); + wr32(hw, TXGBE_MIS_RST, TXGBE_MIS_RST_SW_RST); err = -EIO; goto err_sw_init; } @@ -7689,6 +7789,9 @@ static int txgbe_probe(struct pci_dev *pdev, txgbe_mac_set_default_filter(adapter, hw->mac.perm_addr); timer_setup(&adapter->service_timer, txgbe_service_timer, 0); +#ifdef CONFIG_TXGBE_POLL_LINK_STATUS + timer_setup(&adapter->link_check_timer, txgbe_link_check_timer, 0); +#endif if (TXGBE_REMOVED(hw->hw_addr)) { err = -EIO; @@ -7780,6 +7883,11 @@ static int txgbe_probe(struct pci_dev *pdev, pci_set_drvdata(pdev, adapter); adapter->netdev_registered = true; + /* + * call save state here in standalone driver because it relies on + * adapter struct to exist, and needs to call netdev_priv + */ + pci_save_state(pdev); if (!((hw->subsystem_device_id & TXGBE_NCSI_MASK) == TXGBE_NCSI_SUP)) /* power down the optics for SFP+ fiber */ @@ -7861,6 +7969,20 @@ static int txgbe_probe(struct pci_dev *pdev, e_info(probe, "WangXun(R) 10 Gigabit Network Connection\n"); cards_found++; +#ifdef CONFIG_TXGBE_SYSFS + if (txgbe_sysfs_init(adapter)) + e_err(probe, "failed to allocate sysfs resources\n"); +#else +#ifdef CONFIG_TXGBE_PROCFS + if (txgbe_procfs_init(adapter)) + e_err(probe, "failed to allocate procfs resources\n"); +#endif /* CONFIG_TXGBE_PROCFS */ +#endif /* CONFIG_TXGBE_SYSFS */ + +#ifdef CONFIG_TXGBE_DEBUG_FS + txgbe_dbg_adapter_init(adapter); +#endif /* CONFIG_TXGBE_DEBUG_FS */ + /* setup link for SFP devices with MNG FW, else wait for TXGBE_UP */ if (txgbe_mng_present(hw) && txgbe_is_sfp(hw)) TCALL(hw, mac.ops.setup_link, @@ -7913,9 +8035,21 @@ static void txgbe_remove(struct pci_dev *pdev) return; netdev = adapter->netdev; +#ifdef CONFIG_TXGBE_DEBUG_FS + txgbe_dbg_adapter_exit(adapter); +#endif + set_bit(__TXGBE_REMOVING, &adapter->state); cancel_work_sync(&adapter->service_task); +#ifdef CONFIG_TXGBE_SYSFS + txgbe_sysfs_exit(adapter); +#else +#ifdef CONFIG_TXGBE_PROCFS + txgbe_procfs_exit(adapter); +#endif +#endif /* CONFIG_TXGBE_SYSFS */ + /* remove the added san mac */ txgbe_del_sanmac_netdev(netdev); @@ -8006,6 +8140,15 @@ static int __init txgbe_init_module(void) return -ENOMEM; } +#ifdef CONFIG_TXGBE_PROCFS + if (txgbe_procfs_topdir_init()) + pr_info("Procfs failed to initialize topdir\n"); +#endif + +#ifdef CONFIG_TXGBE_DEBUG_FS + txgbe_dbg_init(); +#endif + ret = pci_register_driver(&txgbe_driver); return ret; } @@ -8021,9 +8164,15 @@ module_init(txgbe_init_module); static void __exit txgbe_exit_module(void) { pci_unregister_driver(&txgbe_driver); +#ifdef CONFIG_TXGBE_PROCFS + txgbe_procfs_topdir_exit(); +#endif if (txgbe_wq) { destroy_workqueue(txgbe_wq); } +#ifdef CONFIG_TXGBE_DEBUG_FS + txgbe_dbg_exit(); +#endif /* CONFIG_TXGBE_DEBUG_FS */ } module_exit(txgbe_exit_module); diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_mbx.c b/drivers/net/ethernet/netswift/txgbe/txgbe_mbx.c index 08c67fdccc161dd0a6a913831f2885ac982276f9..e52173c6e4ec833ddc23d5d5ce645349332b8ef8 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_mbx.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_mbx.c @@ -21,7 +21,7 @@ * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 */ - +#include "txgbe_type.h" #include "txgbe.h" #include "txgbe_mbx.h" @@ -182,6 +182,303 @@ int txgbe_poll_for_ack(struct txgbe_hw *hw, u16 mbx_id) return countdown ? 0 : TXGBE_ERR_MBX; } +/** + * txgbe_read_posted_mbx - Wait for message notification and receive message + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully received a message notification and + * copied it into the receive buffer. + **/ +int txgbe_read_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) +{ + struct txgbe_mbx_info *mbx = &hw->mbx; + int err = TXGBE_ERR_MBX; + + if (!mbx->ops.read) + goto out; + + err = txgbe_poll_for_msg(hw, mbx_id); + + /* if ack received read message, otherwise we timed out */ + if (!err) + err = TCALL(hw, mbx.ops.read, msg, size, mbx_id); +out: + return err; +} + +/** + * txgbe_write_posted_mbx - Write a message to the mailbox, wait for ack + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully copied message into the buffer and + * received an ack to that message within delay * timeout period + **/ +int txgbe_write_posted_mbx(struct txgbe_hw *hw, u32 *msg, u16 size, + u16 mbx_id) +{ + struct txgbe_mbx_info *mbx = &hw->mbx; + int err; + + /* exit if either we can't write or there isn't a defined timeout */ + if (!mbx->timeout) + return TXGBE_ERR_MBX; + + /* send msg */ + err = TCALL(hw, mbx.ops.write, msg, size, mbx_id); + + /* if msg sent wait until we receive an ack */ + if (!err) + err = txgbe_poll_for_ack(hw, mbx_id); + + return err; +} + +/** + * txgbe_init_mbx_ops - Initialize MB function pointers + * @hw: pointer to the HW structure + * + * Setups up the mailbox read and write message function pointers + **/ +void txgbe_init_mbx_ops(struct txgbe_hw *hw) +{ + struct txgbe_mbx_info *mbx = &hw->mbx; + + mbx->ops.read_posted = txgbe_read_posted_mbx; + mbx->ops.write_posted = txgbe_write_posted_mbx; +} + +/** + * txgbe_read_v2p_mailbox - read v2p mailbox + * @hw: pointer to the HW structure + * + * This function is used to read the v2p mailbox without losing the read to + * clear status bits. + **/ +u32 txgbe_read_v2p_mailbox(struct txgbe_hw *hw) +{ + u32 v2p_mailbox = rd32(hw, TXGBE_VXMAILBOX); + + v2p_mailbox |= hw->mbx.v2p_mailbox; + /* read and clear mirrored mailbox flags */ + v2p_mailbox |= rd32a(hw, TXGBE_VXMBMEM, TXGBE_VXMAILBOX_SIZE); + wr32a(hw, TXGBE_VXMBMEM, TXGBE_VXMAILBOX_SIZE, 0); + hw->mbx.v2p_mailbox |= v2p_mailbox & TXGBE_VXMAILBOX_R2C_BITS; + + return v2p_mailbox; +} + +/** + * txgbe_check_for_bit_vf - Determine if a status bit was set + * @hw: pointer to the HW structure + * @mask: bitmask for bits to be tested and cleared + * + * This function is used to check for the read to clear bits within + * the V2P mailbox. + **/ +int txgbe_check_for_bit_vf(struct txgbe_hw *hw, u32 mask) +{ + u32 mailbox = txgbe_read_v2p_mailbox(hw); + + hw->mbx.v2p_mailbox &= ~mask; + + return (mailbox & mask ? 0 : TXGBE_ERR_MBX); +} + +/** + * txgbe_check_for_msg_vf - checks to see if the PF has sent mail + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to check + * + * returns SUCCESS if the PF has set the Status bit or else ERR_MBX + **/ +int txgbe_check_for_msg_vf(struct txgbe_hw *hw, u16 __always_unused mbx_id) +{ + int err = TXGBE_ERR_MBX; + + /* read clear the pf sts bit */ + if (!txgbe_check_for_bit_vf(hw, TXGBE_VXMAILBOX_PFSTS)) { + err = 0; + hw->mbx.stats.reqs++; + } + + return err; +} + +/** + * txgbe_check_for_ack_vf - checks to see if the PF has ACK'd + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to check + * + * returns SUCCESS if the PF has set the ACK bit or else ERR_MBX + **/ +int txgbe_check_for_ack_vf(struct txgbe_hw *hw, u16 __always_unused mbx_id) +{ + int err = TXGBE_ERR_MBX; + + /* read clear the pf ack bit */ + if (!txgbe_check_for_bit_vf(hw, TXGBE_VXMAILBOX_PFACK)) { + err = 0; + hw->mbx.stats.acks++; + } + + return err; +} + +/** + * txgbe_check_for_rst_vf - checks to see if the PF has reset + * @hw: pointer to the HW structure + * @mbx_id: id of mailbox to check + * + * returns true if the PF has set the reset done bit or else false + **/ +int txgbe_check_for_rst_vf(struct txgbe_hw *hw, u16 __always_unused mbx_id) +{ + int err = TXGBE_ERR_MBX; + + if (!txgbe_check_for_bit_vf(hw, (TXGBE_VXMAILBOX_RSTD | + TXGBE_VXMAILBOX_RSTI))) { + err = 0; + hw->mbx.stats.rsts++; + } + + return err; +} + +/** + * txgbe_obtain_mbx_lock_vf - obtain mailbox lock + * @hw: pointer to the HW structure + * + * return SUCCESS if we obtained the mailbox lock + **/ +int txgbe_obtain_mbx_lock_vf(struct txgbe_hw *hw) +{ + int err = TXGBE_ERR_MBX; + u32 mailbox; + + /* Take ownership of the buffer */ + wr32(hw, TXGBE_VXMAILBOX, TXGBE_VXMAILBOX_VFU); + + /* reserve mailbox for vf use */ + mailbox = txgbe_read_v2p_mailbox(hw); + if (mailbox & TXGBE_VXMAILBOX_VFU) + err = 0; + else + ERROR_REPORT2(TXGBE_ERROR_POLLING, + "Failed to obtain mailbox lock for VF"); + + return err; +} + +/** + * txgbe_write_mbx_vf - Write a message to the mailbox + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to write + * + * returns SUCCESS if it successfully copied message into the buffer + **/ +int txgbe_write_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size, + u16 __always_unused mbx_id) +{ + int err; + u16 i; + + /* lock the mailbox to prevent pf/vf race condition */ + err = txgbe_obtain_mbx_lock_vf(hw); + if (err) + goto out_no_write; + + /* flush msg and acks as we are overwriting the message buffer */ + txgbe_check_for_msg_vf(hw, 0); + txgbe_check_for_ack_vf(hw, 0); + + /* copy the caller specified message to the mailbox memory buffer */ + for (i = 0; i < size; i++) + wr32a(hw, TXGBE_VXMBMEM, i, msg[i]); + + /* update stats */ + hw->mbx.stats.msgs_tx++; + + /* Drop VFU and interrupt the PF to tell it a message has been sent */ + wr32(hw, TXGBE_VXMAILBOX, TXGBE_VXMAILBOX_REQ); + +out_no_write: + return err; +} + +/** + * txgbe_read_mbx_vf - Reads a message from the inbox intended for vf + * @hw: pointer to the HW structure + * @msg: The message buffer + * @size: Length of buffer + * @mbx_id: id of mailbox to read + * + * returns SUCCESS if it successfuly read message from buffer + **/ +int txgbe_read_mbx_vf(struct txgbe_hw *hw, u32 *msg, u16 size, + u16 __always_unused mbx_id) +{ + int err = 0; + u16 i; + + /* lock the mailbox to prevent pf/vf race condition */ + err = txgbe_obtain_mbx_lock_vf(hw); + if (err) + goto out_no_read; + + /* copy the message from the mailbox memory buffer */ + for (i = 0; i < size; i++) + msg[i] = rd32a(hw, TXGBE_VXMBMEM, i); + + /* Acknowledge receipt and release mailbox, then we're done */ + wr32(hw, TXGBE_VXMAILBOX, TXGBE_VXMAILBOX_ACK); + + /* update stats */ + hw->mbx.stats.msgs_rx++; + +out_no_read: + return err; +} + +/** + * txgbe_init_mbx_params_vf - set initial values for vf mailbox + * @hw: pointer to the HW structure + * + * Initializes the hw->mbx struct to correct values for vf mailbox + */ +void txgbe_init_mbx_params_vf(struct txgbe_hw *hw) +{ + struct txgbe_mbx_info *mbx = &hw->mbx; + + /* start mailbox as timed out and let the reset_hw call set the timeout + * value to begin communications */ + mbx->timeout = 0; + mbx->udelay = TXGBE_VF_MBX_INIT_DELAY; + + mbx->size = TXGBE_VXMAILBOX_SIZE; + + mbx->ops.read = txgbe_read_mbx_vf; + mbx->ops.write = txgbe_write_mbx_vf; + mbx->ops.read_posted = txgbe_read_posted_mbx; + mbx->ops.write_posted = txgbe_write_posted_mbx; + mbx->ops.check_for_msg = txgbe_check_for_msg_vf; + mbx->ops.check_for_ack = txgbe_check_for_ack_vf; + mbx->ops.check_for_rst = txgbe_check_for_rst_vf; + + mbx->stats.msgs_tx = 0; + mbx->stats.msgs_rx = 0; + mbx->stats.reqs = 0; + mbx->stats.acks = 0; + mbx->stats.rsts = 0; +} + int txgbe_check_for_bit_pf(struct txgbe_hw *hw, u32 mask, int index) { u32 mbvficr = rd32(hw, TXGBE_MBVFICR(index)); diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_mtd.c b/drivers/net/ethernet/netswift/txgbe/txgbe_mtd.c index 5c29a28af0754aa15a4262b098fb6f044cf0ae06..0f9e7b461df816bba06bbc3d6281275110025e47 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_mtd.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_mtd.c @@ -773,6 +773,98 @@ MTD_STATUS mtdGetAutonegSpeedDuplexResolution( return MTD_OK; } +/****************************************************************************/ +MTD_STATUS mtdIsBaseTUp( + IN MTD_DEV_PTR devPtr, + IN MTD_U16 port, + OUT MTD_U16 *speed, + OUT MTD_BOOL *linkUp) +{ + MTD_BOOL speedIsForced; + MTD_U16 forcedSpeed, cuSpeed, cuLinkStatus; + + *linkUp = MTD_FALSE; + *speed = MTD_ADV_NONE; + + /* first check if speed is forced to one of the speeds not requiring AN to train */ + ATTEMPT(mtdGetForcedSpeed(devPtr, port, &speedIsForced, &forcedSpeed)); + + if (speedIsForced) { + /* check if the link is up at the speed it's forced to */ + ATTEMPT(mtdHwGetPhyRegField(devPtr, port, 3, 0x8008, 14, 2, &cuSpeed)); + ATTEMPT(mtdHwGetPhyRegField(devPtr, port, 3, 0x8008, 10, 1, &cuLinkStatus)); + + switch (forcedSpeed) { + case MTD_SPEED_10M_HD_AN_DIS: + case MTD_SPEED_10M_FD_AN_DIS: + /* might want to add checking the duplex to make sure there + * is no duplex mismatch */ + if (cuSpeed == MTD_CU_SPEED_10_MBPS) { + *speed = forcedSpeed; + } else { + *speed = MTD_SPEED_MISMATCH; + } + if (cuLinkStatus) { + *linkUp = MTD_TRUE; + } + break; + + case MTD_SPEED_100M_HD_AN_DIS: + case MTD_SPEED_100M_FD_AN_DIS: + /* might want to add checking the duplex to make sure there + * is no duplex mismatch */ + if (cuSpeed == MTD_CU_SPEED_100_MBPS) { + *speed = forcedSpeed; + } else { + *speed = MTD_SPEED_MISMATCH; + } + if (cuLinkStatus) { + *linkUp = MTD_TRUE; + } + break; + + default: + return MTD_FAIL; + break; + } + } else { + /* must be going through AN */ + ATTEMPT(mtdGetAutonegSpeedDuplexResolution(devPtr, port, speed)); + + if (*speed != MTD_ADV_NONE) { + /* check if the link is up at the speed it's AN to */ + ATTEMPT(mtdHwGetPhyRegField(devPtr, port, 3, 0x8008, 10, 1, &cuLinkStatus)); + + switch (*speed) { + case MTD_SPEED_10M_HD: + case MTD_SPEED_10M_FD: + case MTD_SPEED_100M_HD: + case MTD_SPEED_100M_FD: + case MTD_SPEED_1GIG_HD: + case MTD_SPEED_1GIG_FD: + case MTD_SPEED_10GIG_FD: + case MTD_SPEED_2P5GIG_FD: + case MTD_SPEED_5GIG_FD: + if (cuLinkStatus) { + *linkUp = MTD_TRUE; + } + break; + default: + return MTD_FAIL; + break; + } + + } + /* else link is down, and AN is in progress, */ + } + + if (*speed == MTD_SPEED_MISMATCH) { + return MTD_FAIL; + } else { + return MTD_OK; + } +} + MTD_STATUS mtdSetPauseAdvertisement( IN MTD_DEV_PTR devPtr, IN MTD_U16 port, diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_mtd.h b/drivers/net/ethernet/netswift/txgbe/txgbe_mtd.h index 1c5daae94a547ca1e2f183f240bf5089bc49fb3a..a0e9cdc5704d0f933e3e683fca5ab7151e8f0d3e 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_mtd.h +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_mtd.h @@ -1109,6 +1109,14 @@ MTD_STATUS mtdGetAutonegSpeedDuplexResolution OUT MTD_U16 *speedResolution ); +MTD_STATUS mtdIsBaseTUp +( + IN MTD_DEV_PTR devPtr, + IN MTD_U16 port, + OUT MTD_U16 *speed, + OUT MTD_BOOL *linkUp +); + MTD_STATUS mtdAutonegIsSpeedDuplexResolutionDone ( IN MTD_DEV_PTR devPtr, diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_param.c b/drivers/net/ethernet/netswift/txgbe/txgbe_param.c index 214993fb1a9b91852812ecf69c67f2f7f06524ae..129ece20e32c9f3586701f1e69d5965e773f5603 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_param.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_param.c @@ -46,6 +46,9 @@ module_param_array(X, int, &num_##X, 0); \ MODULE_PARM_DESC(X, desc); +TXGBE_PARAM(an73_train_mode, "an73_train_mode to different switch(0 to centc, 1 to other)"); +#define TXGBE_DEFAULT_FFE_AN73_TRAIN_MODE 0 + /* ffe_main (KR/KX4/KX/SFI) * * Valid Range: 0-60 @@ -213,7 +216,9 @@ TXGBE_PARAM(VMDQ, * * Default Value: 1 */ -#define DEFAULT_ITR 1 +#define DEFAULT_ITR (TXGBE_STATIC_ITR == 0) || \ + (TXGBE_STATIC_ITR == 1) ? TXGBE_STATIC_ITR : (u16)((1000000/TXGBE_STATIC_ITR) << 2) + TXGBE_PARAM(InterruptThrottleRate, "Maximum interrupts per second, per vector, " "(0,1,980-500000), default 1"); @@ -477,6 +482,30 @@ void txgbe_check_options(struct txgbe_adapter *adapter) "Warning: no configuration for board #%d\n", bd); txgbe_notice("Using defaults for all values\n"); } + + { /* an73_mode */ + u32 an73_mode; + static struct txgbe_option opt = { + .type = range_option, + .name = "an73_train_mode", + .err = + "using default of "__MODULE_STRING(TXGBE_DEFAULT_FFE_AN73_TRAIN_MODE), + .def = TXGBE_DEFAULT_FFE_AN73_TRAIN_MODE, + .arg = { .r = { .min = 0, + .max = 1} } + }; + + if (num_an73_train_mode > bd ) { + an73_mode = an73_train_mode[bd]; + if (an73_mode == OPTION_UNSET) + an73_mode = an73_train_mode[bd]; + txgbe_validate_option(&an73_mode, &opt); + adapter->an73_mode = an73_mode; + } else { + adapter->an73_mode = 0; + } + } + { /* MAIN */ u32 ffe_main; static struct txgbe_option opt = { @@ -760,6 +789,7 @@ void txgbe_check_options(struct txgbe_adapter *adapter) } else if (opt.def == 0) { rss = min_t(int, txgbe_max_rss_indices(adapter), num_online_cpus()); + feature[RING_F_FDIR].limit = (u16)rss; feature[RING_F_RSS].limit = rss; } /* Check Interoperability */ diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_phy.c b/drivers/net/ethernet/netswift/txgbe/txgbe_phy.c index c8a6490874c417d13ee5a125cdba75385c4e6f0d..cb8bdffb43f163462003b01fe424ef564423c706 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_phy.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_phy.c @@ -37,8 +37,6 @@ s32 txgbe_check_reset_blocked(struct txgbe_hw *hw) { u32 mmngc; - DEBUGFUNC("\n"); - mmngc = rd32(hw, TXGBE_MIS_ST); if (mmngc & TXGBE_MIS_ST_MNG_VETO) { ERROR_REPORT1(TXGBE_ERROR_SOFTWARE, @@ -61,7 +59,6 @@ s32 txgbe_get_phy_id(struct txgbe_hw *hw) u16 phy_id_high = 0; u16 phy_id_low = 0; u8 numport, thisport; - DEBUGFUNC("\n"); status = mtdHwXmdioRead(&hw->phy_dev, hw->phy.addr, TXGBE_MDIO_PMA_PMD_DEV_TYPE, @@ -96,8 +93,6 @@ enum txgbe_phy_type txgbe_get_phy_type_from_id(struct txgbe_hw *hw) enum txgbe_phy_type phy_type; u16 ext_ability = 0; - DEBUGFUNC("\n"); - switch (hw->phy.id) { case TN1010_PHY_ID: phy_type = txgbe_phy_tn; @@ -134,9 +129,6 @@ s32 txgbe_reset_phy(struct txgbe_hw *hw) { s32 status = 0; - DEBUGFUNC("\n"); - - if (status != 0 || hw->phy.type == txgbe_phy_none) goto out; @@ -208,8 +200,6 @@ s32 txgbe_read_phy_reg(struct txgbe_hw *hw, u32 reg_addr, s32 status; u32 gssr = hw->phy.phy_semaphore_mask; - DEBUGFUNC("\n"); - if (0 == TCALL(hw, mac.ops.acquire_swfw_sync, gssr)) { status = txgbe_read_phy_reg_mdi(hw, reg_addr, device_type, phy_data); @@ -272,8 +262,6 @@ s32 txgbe_write_phy_reg(struct txgbe_hw *hw, u32 reg_addr, s32 status; u32 gssr = hw->phy.phy_semaphore_mask; - DEBUGFUNC("\n"); - if (TCALL(hw, mac.ops.acquire_swfw_sync, gssr) == 0) { status = txgbe_write_phy_reg_mdi(hw, reg_addr, device_type, phy_data); @@ -325,31 +313,41 @@ u32 txgbe_setup_phy_link(struct txgbe_hw *hw, u32 __maybe_unused speed_set, { u16 speed = MTD_ADV_NONE; MTD_DEV_PTR devptr = &hw->phy_dev; - MTD_BOOL anDone = MTD_FALSE; u16 port = hw->phy.addr; + int i = 0; + MTD_BOOL linkUp = MTD_FALSE; + u16 linkSpeed = MTD_ADV_NONE; + + if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_10GB_FULL) + speed |= MTD_SPEED_10GIG_FD; + if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_1GB_FULL) + speed |= MTD_SPEED_1GIG_FD; + if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_100_FULL) + speed |= MTD_SPEED_100M_FD; + if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_10_FULL) + speed |= MTD_SPEED_10M_FD; + if (!autoneg_wait_to_complete) { + mtdGetAutonegSpeedDuplexResolution(devptr, port, &linkSpeed); + if (linkSpeed & speed) { + speed = linkSpeed; + goto out; + } + } - DEBUGFUNC("\n"); + mtdEnableSpeeds(devptr, port, speed, MTD_TRUE); + msleep(10); - if (!autoneg_wait_to_complete) { - mtdAutonegIsSpeedDuplexResolutionDone(devptr, port, &anDone); - if (anDone) { - mtdGetAutonegSpeedDuplexResolution(devptr, port, &speed); + /* wait autoneg to be done */ + speed = MTD_ADV_NONE; + for (i = 0; i < 300; i++) { + mtdIsBaseTUp(devptr, port ,&speed, &linkUp); + if (linkUp) { + break; } - } else { - if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_10GB_FULL) - speed |= MTD_SPEED_10GIG_FD; - if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_1GB_FULL) - speed |= MTD_SPEED_1GIG_FD; - if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_100_FULL) - speed |= MTD_SPEED_100M_FD; - if (hw->phy.autoneg_advertised & TXGBE_LINK_SPEED_10_FULL) - speed |= MTD_SPEED_10M_FD; - mtdEnableSpeeds(devptr, port, speed, MTD_TRUE); - - /* wait autoneg to be done */ - speed = MTD_ADV_NONE; + msleep(10); } +out: switch (speed) { case MTD_SPEED_10GIG_FD: return TXGBE_LINK_SPEED_10GB_FULL; @@ -374,9 +372,6 @@ u32 txgbe_setup_phy_link_speed(struct txgbe_hw *hw, u32 speed, bool autoneg_wait_to_complete) { - - DEBUGFUNC("\n"); - /* * Clear autoneg_advertised and set new values based on input link * speed. @@ -414,9 +409,6 @@ s32 txgbe_get_copper_link_capabilities(struct txgbe_hw *hw, { s32 status; u16 speed_ability; - - DEBUGFUNC("\n"); - *speed = 0; *autoneg = true; @@ -438,6 +430,24 @@ s32 txgbe_get_copper_link_capabilities(struct txgbe_hw *hw, return status; } +/** + * txgbe_get_phy_firmware_version - Gets the PHY Firmware Version + * @hw: pointer to hardware structure + * @firmware_version: pointer to the PHY Firmware Version + **/ +s32 txgbe_get_phy_firmware_version(struct txgbe_hw *hw, + u16 *firmware_version) +{ + s32 status; + u8 major, minor, inc, test; + + status = mtdGetFirmwareVersion(&hw->phy_dev, hw->phy.addr, + &major, &minor, &inc, &test); + if (status == 0) + *firmware_version = (major << 8) | minor; + return status; +} + /** * txgbe_identify_module - Identifies module type * @hw: pointer to hardware structure @@ -448,8 +458,6 @@ s32 txgbe_identify_module(struct txgbe_hw *hw) { s32 status = TXGBE_ERR_SFP_NOT_PRESENT; - DEBUGFUNC("\n"); - switch (TCALL(hw, mac.ops.get_media_type)) { case txgbe_media_type_fiber: status = txgbe_identify_sfp_module(hw); @@ -482,8 +490,6 @@ s32 txgbe_identify_sfp_module(struct txgbe_hw *hw) u8 cable_tech = 0; u8 cable_spec = 0; - DEBUGFUNC("\n"); - if (TCALL(hw, mac.ops.get_media_type) != txgbe_media_type_fiber) { hw->phy.sfp_type = txgbe_sfp_type_not_present; status = TXGBE_ERR_SFP_NOT_PRESENT; @@ -754,8 +760,6 @@ s32 txgbe_clear_i2c(struct txgbe_hw *hw) s32 txgbe_read_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset, u8 *eeprom_data) { - DEBUGFUNC("\n"); - return TCALL(hw, phy.ops.read_i2c_byte, byte_offset, TXGBE_I2C_EEPROM_DEV_ADDR, eeprom_data); @@ -788,8 +792,6 @@ s32 txgbe_read_i2c_sff8472(struct txgbe_hw *hw, u8 byte_offset, s32 txgbe_write_i2c_eeprom(struct txgbe_hw *hw, u8 byte_offset, u8 eeprom_data) { - DEBUGFUNC("\n"); - return TCALL(hw, phy.ops.write_i2c_byte, byte_offset, TXGBE_I2C_EEPROM_DEV_ADDR, eeprom_data); @@ -944,8 +946,6 @@ s32 txgbe_tn_check_overtemp(struct txgbe_hw *hw) s32 status = 0; u32 ts_state; - DEBUGFUNC("\n"); - /* Check that the LASI temp alarm status was triggered */ ts_state = rd32(hw, TXGBE_TS_ALARM_ST); diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_phy.h b/drivers/net/ethernet/netswift/txgbe/txgbe_phy.h index f033b43cf4fe01e9d54d6d641288cd67fc886c11..a189a64feb3f3f23c9da7a71e23de00574364735 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_phy.h +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_phy.h @@ -150,6 +150,9 @@ s32 txgbe_get_copper_link_capabilities(struct txgbe_hw *hw, bool *autoneg); s32 txgbe_check_reset_blocked(struct txgbe_hw *hw); +s32 txgbe_get_phy_firmware_version(struct txgbe_hw *hw, + u16 *firmware_version); + s32 txgbe_identify_module(struct txgbe_hw *hw); s32 txgbe_identify_sfp_module(struct txgbe_hw *hw); s32 txgbe_tn_check_overtemp(struct txgbe_hw *hw); diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_ptp.c b/drivers/net/ethernet/netswift/txgbe/txgbe_ptp.c index 4a614a550e47a6d854a58f671e5f8c86b88dbb49..68ad037457b28f0b44d6156d8acce691cc41db3b 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_ptp.c +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_ptp.c @@ -670,8 +670,8 @@ static void txgbe_ptp_link_speed_adjust(struct txgbe_adapter *adapter, *incval = TXGBE_INCVAL_100; break; case TXGBE_LINK_SPEED_1GB_FULL: - *shift = TXGBE_INCVAL_SHIFT_FPGA; - *incval = TXGBE_INCVAL_FPGA; + *shift = TXGBE_INCVAL_SHIFT_1GB; + *incval = TXGBE_INCVAL_1GB; break; case TXGBE_LINK_SPEED_10GB_FULL: default: /* TXGBE_LINK_SPEED_10GB_FULL */ diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_sysfs.c b/drivers/net/ethernet/netswift/txgbe/txgbe_sysfs.c new file mode 100644 index 0000000000000000000000000000000000000000..29a4be546ac56cae16cd9a449feb27c5dbc91fc7 --- /dev/null +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_sysfs.c @@ -0,0 +1,216 @@ +/* + * WangXun 10 Gigabit PCI Express Linux driver + * Copyright (c) 2015 - 2017 Beijing WangXun Technology Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// SPDX-License-Identifier: GPL-2.0 +/* Copyright (c) 2019 - 2022 Beijing WangXun Technology Co., Ltd. */ + +#include "txgbe.h" +#include "txgbe_hw.h" +#include "txgbe_type.h" + +#ifdef CONFIG_TXGBE_SYSFS + +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_TXGBE_HWMON +#include +#endif + +#ifdef CONFIG_TXGBE_HWMON +/* hwmon callback functions */ +static ssize_t txgbe_hwmon_show_temp(struct device __always_unused *dev, + struct device_attribute *attr, + char *buf) +{ + struct hwmon_attr *txgbe_attr = container_of(attr, struct hwmon_attr, + dev_attr); + unsigned int value; + + /* reset the temp field */ + TCALL(txgbe_attr->hw, mac.ops.get_thermal_sensor_data); + + value = txgbe_attr->sensor->temp; + + /* display millidegree */ + value *= 1000; + + return sprintf(buf, "%u\n", value); +} + +static ssize_t txgbe_hwmon_show_alarmthresh(struct device __always_unused *dev, + struct device_attribute *attr, + char *buf) +{ + struct hwmon_attr *txgbe_attr = container_of(attr, struct hwmon_attr, + dev_attr); + unsigned int value = txgbe_attr->sensor->alarm_thresh; + + /* display millidegree */ + value *= 1000; + + return sprintf(buf, "%u\n", value); +} + +static ssize_t txgbe_hwmon_show_dalarmthresh(struct device __always_unused *dev, + struct device_attribute *attr, + char *buf) +{ + struct hwmon_attr *txgbe_attr = container_of(attr, struct hwmon_attr, + dev_attr); + unsigned int value = txgbe_attr->sensor->dalarm_thresh; + + /* display millidegree */ + value *= 1000; + + return sprintf(buf, "%u\n", value); +} + +/** + * txgbe_add_hwmon_attr - Create hwmon attr table for a hwmon sysfs file. + * @adapter: pointer to the adapter structure + * @type: type of sensor data to display + * + * For each file we want in hwmon's sysfs interface we need a device_attribute + * This is included in our hwmon_attr struct that contains the references to + * the data structures we need to get the data to display. + */ +static int txgbe_add_hwmon_attr(struct txgbe_adapter *adapter, int type) +{ + int rc; + unsigned int n_attr; + struct hwmon_attr *txgbe_attr; + + n_attr = adapter->txgbe_hwmon_buff.n_hwmon; + txgbe_attr = &adapter->txgbe_hwmon_buff.hwmon_list[n_attr]; + + switch (type) { + case TXGBE_HWMON_TYPE_TEMP: + txgbe_attr->dev_attr.show = txgbe_hwmon_show_temp; + snprintf(txgbe_attr->name, sizeof(txgbe_attr->name), + "temp%u_input", 0); + break; + case TXGBE_HWMON_TYPE_ALARMTHRESH: + txgbe_attr->dev_attr.show = txgbe_hwmon_show_alarmthresh; + snprintf(txgbe_attr->name, sizeof(txgbe_attr->name), + "temp%u_alarmthresh", 0); + break; + case TXGBE_HWMON_TYPE_DALARMTHRESH: + txgbe_attr->dev_attr.show = txgbe_hwmon_show_dalarmthresh; + snprintf(txgbe_attr->name, sizeof(txgbe_attr->name), + "temp%u_dalarmthresh", 0); + break; + default: + rc = -EPERM; + return rc; + } + + /* These always the same regardless of type */ + txgbe_attr->sensor = + &adapter->hw.mac.thermal_sensor_data.sensor; + txgbe_attr->hw = &adapter->hw; + txgbe_attr->dev_attr.store = NULL; + txgbe_attr->dev_attr.attr.mode = S_IRUGO; + txgbe_attr->dev_attr.attr.name = txgbe_attr->name; + + rc = device_create_file(pci_dev_to_dev(adapter->pdev), + &txgbe_attr->dev_attr); + + if (rc == 0) + ++adapter->txgbe_hwmon_buff.n_hwmon; + + return rc; +} +#endif /* CONFIG_TXGBE_HWMON */ + +static void txgbe_sysfs_del_adapter(struct txgbe_adapter __maybe_unused *adapter) +{ +#ifdef CONFIG_TXGBE_HWMON + int i; + + if (!adapter) + return; + + for (i = 0; i < adapter->txgbe_hwmon_buff.n_hwmon; i++) { + device_remove_file(pci_dev_to_dev(adapter->pdev), + &adapter->txgbe_hwmon_buff.hwmon_list[i].dev_attr); + } + + kfree(adapter->txgbe_hwmon_buff.hwmon_list); + + if (adapter->txgbe_hwmon_buff.device) + hwmon_device_unregister(adapter->txgbe_hwmon_buff.device); +#endif /* CONFIG_TXGBE_HWMON */ +} + +/* called from txgbe_main.c */ +void txgbe_sysfs_exit(struct txgbe_adapter *adapter) +{ + txgbe_sysfs_del_adapter(adapter); +} + +/* called from txgbe_main.c */ +int txgbe_sysfs_init(struct txgbe_adapter *adapter) +{ + int rc = 0; +#ifdef CONFIG_TXGBE_HWMON + struct hwmon_buff *txgbe_hwmon = &adapter->txgbe_hwmon_buff; + int n_attrs; + +#endif /* CONFIG_TXGBE_HWMON */ + if (!adapter) + goto err; + +#ifdef CONFIG_TXGBE_HWMON + + /* Don't create thermal hwmon interface if no sensors present */ + if (TCALL(&adapter->hw, mac.ops.init_thermal_sensor_thresh)) + goto no_thermal; + + /* Allocation space for max attributs + * max num sensors * values (temp, alamthresh, dalarmthresh) + */ + n_attrs = 3; + txgbe_hwmon->hwmon_list = kcalloc(n_attrs, sizeof(struct hwmon_attr), + GFP_KERNEL); + if (!txgbe_hwmon->hwmon_list) { + rc = -ENOMEM; + goto err; + } + + txgbe_hwmon->device = + hwmon_device_register(pci_dev_to_dev(adapter->pdev)); + if (IS_ERR(txgbe_hwmon->device)) { + rc = PTR_ERR(txgbe_hwmon->device); + goto err; + } + + /* Bail if any hwmon attr struct fails to initialize */ + rc = txgbe_add_hwmon_attr(adapter, TXGBE_HWMON_TYPE_TEMP); + rc |= txgbe_add_hwmon_attr(adapter, TXGBE_HWMON_TYPE_ALARMTHRESH); + rc |= txgbe_add_hwmon_attr(adapter, TXGBE_HWMON_TYPE_DALARMTHRESH); + if (rc) + goto err; + +no_thermal: +#endif /* CONFIG_TXGBE_HWMON */ + goto exit; + +err: + txgbe_sysfs_del_adapter(adapter); +exit: + return rc; +} +#endif /* CONFIG_TXGBE_SYSFS */ diff --git a/drivers/net/ethernet/netswift/txgbe/txgbe_type.h b/drivers/net/ethernet/netswift/txgbe/txgbe_type.h index cdb4318ac8e817d6335db19f07327806987e0812..691750ee4e4b978b13d46cc803729e4345acba33 100644 --- a/drivers/net/ethernet/netswift/txgbe/txgbe_type.h +++ b/drivers/net/ethernet/netswift/txgbe/txgbe_type.h @@ -128,6 +128,8 @@ #define TXGBE_WOL_SUP 0x4000 #define TXGBE_WOL_MASK 0x4000 +#define TXGBE_DEV_MASK 0xf0 + /* Combined interface*/ #define TXGBE_ID_SFI_XAUI 0x50 @@ -355,6 +357,7 @@ #define TXGBE_MIS_PWR 0x10000 #define TXGBE_MIS_CTL 0x10004 #define TXGBE_MIS_PF_SM 0x10008 +#define TXGBE_MIS_PRB_CTL 0x10010 #define TXGBE_MIS_ST 0x10028 #define TXGBE_MIS_SWSM 0x1002C #define TXGBE_MIS_RST_ST 0x10030 @@ -392,6 +395,8 @@ #define TXGBE_MIS_RST_ST_RST_INI_SHIFT 8 #define TXGBE_MIS_RST_ST_RST_TIM 0x000000FFU #define TXGBE_MIS_PF_SM_SM 1 +#define TXGBE_MIS_PRB_CTL_LAN0_UP 0x2 +#define TXGBE_MIS_PRB_CTL_LAN1_UP 0x1 /* Sensors for PVT(Process Voltage Temperature) */ #define TXGBE_TS_CTL 0x10300 @@ -2262,6 +2267,12 @@ union txgbe_atr_hash_dword { #define FW_FLASH_UPGRADE_WRITE_CMD 0xE4 #define FW_FLASH_UPGRADE_VERIFY_CMD 0xE5 #define FW_FLASH_UPGRADE_VERIFY_LEN 0x4 +#define FW_DW_OPEN_NOTIFY 0xE9 +#define FW_DW_CLOSE_NOTIFY 0xEA + +#define TXGBE_CHECKSUM_CAP_ST_PASS 0x80658383 +#define TXGBE_CHECKSUM_CAP_ST_FAIL 0x70657376 + /* Host Interface Command Structures */ struct txgbe_hic_hdr { @@ -3028,8 +3039,9 @@ struct txgbe_hw { #endif MTD_DEV phy_dev; enum txgbe_link_status link_status; - u16 subsystem_id; - u16 tpid[8]; + u16 tpid[8]; + u16 oem_ssid; + u16 oem_svid; }; #define TCALL(hw, func, args...) (((hw)->func != NULL) \