From d0e84dfad4e749415fc063094626c864052a0a61 Mon Sep 17 00:00:00 2001 From: DuanqiangWen Date: Tue, 18 Oct 2022 21:51:36 -0400 Subject: [PATCH 1/2] openeuler: configs: delete txgbe/Kconfig, add txgbe_config to netswift/Kconfig add CONFIG_TXGBE_HWMON for hardware monitoring support add CONFIG_TXGBE_DEBUG_FS for debug_fs support add CONFIG_TXGBE_POLL_LINK_STATUS for polling to get phy status support instead of interrupt. add CONFIG_TXGBE_SYSFS for sysfs support driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I5VU60 CVE: NA Signed-off-by: Duanqiang Wen --- drivers/net/ethernet/netswift/Kconfig | 54 ++++++++++++++++++++- drivers/net/ethernet/netswift/txgbe/Kconfig | 13 ----- 2 files changed, 53 insertions(+), 14 deletions(-) delete mode 100644 drivers/net/ethernet/netswift/txgbe/Kconfig diff --git a/drivers/net/ethernet/netswift/Kconfig b/drivers/net/ethernet/netswift/Kconfig index 8be1eadc602c..d88312538a4f 100644 --- a/drivers/net/ethernet/netswift/Kconfig +++ b/drivers/net/ethernet/netswift/Kconfig @@ -16,6 +16,58 @@ config NET_VENDOR_NETSWIFT if NET_VENDOR_NETSWIFT -source "drivers/net/ethernet/netswift/txgbe/Kconfig" +config TXGBE + tristate "Netswift PCI-Express 10Gigabit Ethernet support" + depends on PCI + imply PTP_1588_CLOCK + help + This driver supports Netswift 10gigabit ethernet adapters. + For more information on how to identify your adapter, go + to + + To compile this driver as a module, choose M here. The module + will be called txgbe. +config TXGBE_HWMON + bool "Netswift PCI-Express 10Gigabit adapters HWMON support" + default n + depends on TXGBE && HWMON && !(TXGBE=y && HWMON=m) + help + Say Y if you want to expose thermal sensor data on these devices. + + 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 + depends on TXGBE + help + Say Y if you want to setup debugfs for these devices. + + If unsure, say N. + +config TXGBE_POLL_LINK_STATUS + bool "Netswift PCI-Express 10Gigabit adapters poll mode support" + default n + depends on TXGBE + help + Say Y if you want to turn these devices to poll mode instead of interrupt-trigged TX/RX. + + If unsure, say N. +config TXGBE_SYSFS + bool "Netswift PCI-Express 10Gigabit adapters sysfs support" + default n + depends on TXGBE + help + Say Y if you want to setup sysfs for these devices. + If unsure, say N. endif # NET_VENDOR_NETSWIFT diff --git a/drivers/net/ethernet/netswift/txgbe/Kconfig b/drivers/net/ethernet/netswift/txgbe/Kconfig deleted file mode 100644 index a735e1be9434..000000000000 --- a/drivers/net/ethernet/netswift/txgbe/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# -# Netswift driver configuration -# - -config TXGBE - tristate "Netswift 10G Network Interface Card" - default n - depends on PCI_MSI && NUMA && PCI_IOV && DCB - help - This driver supports Netswift 10G Ethernet cards. - To compile this driver as part of the kernel, choose Y here. - If unsure, choose N. - The default is N. -- Gitee From 79611f436ed90e042c3740d5bb0fe0c66829758c Mon Sep 17 00:00:00 2001 From: DuanqiangWen Date: Tue, 18 Oct 2022 23:17:24 -0400 Subject: [PATCH 2/2] openeuler: net: txgbe: Fix some known bugs, merge net-swift txgbe-1.2.3 out-of-tree MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit driver inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I5Y6RT CVE: NA Bugfix: 1.add cl72_prbs control 2.fix bug of backplane down restart an73 3.fix speed change bug of marvell xaui phy when executing "ethtool -s ethName" 4.fix bug of mac related register configurations in kx4/kx mode 5.adjust input parameters in configure file 6.fix bug of "ethtool -p" function with ocp card 7.fix QinQ TCP/UDP packet traffic bug 8.fix bug of autonegoation between KR board and botong switch chip 9.add support for "ethtool -N xxx ... action" 10.fix bug when in kr mode, core dumping will occassionally happen while os is booting up 11.add support for "ethtool -f xxx" to burn firmware 12.fix flow director udp port match function bug 13.fix bug of "ethtool -f" 14.fix bug of the case that link down event in kr mode may occasionally cause kernel call trace in kr mode 15.change flow director default mode from perfect mode to signature mode so that queue vectors can be bound to cpus automatically 16.add FEC support in kr mode 17.add support for led and polarity configuration in firmware. 18.add NETDEV_F_HW_CSUM feature support 19.turn on/off led light when execute "ifconfig up/down" 20.fix bug of geneve dst port error setting when enable geneve hw offload 21.fix bug of advertise speed error showing by "ethtool -s" 22.fix bug of vxlan/geneve hw offload feature. 23.Add support for vxlan/geneve port number setting in hardware register. 24.add support for oem ssid and svid. 25.add inspur oem ssid 0x0075 support for "ethtool -p". Use speed led to blink. 26.add flash unlock when upgrading image Net-Swift Official Website: https://www.net-swift.com Signed-off-by: Duanqiang Wen --- drivers/net/ethernet/netswift/Kconfig | 9 - drivers/net/ethernet/netswift/txgbe/Makefile | 4 + drivers/net/ethernet/netswift/txgbe/txgbe.h | 130 ++- .../net/ethernet/netswift/txgbe/txgbe_bp.c | 434 +++------ .../ethernet/netswift/txgbe/txgbe_debugfs.c | 788 ++++++++++++++++ .../ethernet/netswift/txgbe/txgbe_ethtool.c | 60 +- .../net/ethernet/netswift/txgbe/txgbe_hw.c | 870 ++++++++++-------- .../net/ethernet/netswift/txgbe/txgbe_hw.h | 44 + .../net/ethernet/netswift/txgbe/txgbe_lib.c | 1 + .../net/ethernet/netswift/txgbe/txgbe_main.c | 411 ++++++--- .../net/ethernet/netswift/txgbe/txgbe_mbx.c | 299 +++++- .../net/ethernet/netswift/txgbe/txgbe_mtd.c | 92 ++ .../net/ethernet/netswift/txgbe/txgbe_mtd.h | 8 + .../net/ethernet/netswift/txgbe/txgbe_param.c | 32 +- .../net/ethernet/netswift/txgbe/txgbe_phy.c | 94 +- .../net/ethernet/netswift/txgbe/txgbe_phy.h | 3 + .../net/ethernet/netswift/txgbe/txgbe_ptp.c | 4 +- .../net/ethernet/netswift/txgbe/txgbe_sysfs.c | 216 +++++ .../net/ethernet/netswift/txgbe/txgbe_type.h | 16 +- 19 files changed, 2649 insertions(+), 866 deletions(-) create mode 100644 drivers/net/ethernet/netswift/txgbe/txgbe_debugfs.c create mode 100644 drivers/net/ethernet/netswift/txgbe/txgbe_sysfs.c diff --git a/drivers/net/ethernet/netswift/Kconfig b/drivers/net/ethernet/netswift/Kconfig index d88312538a4f..b51b5c0cdc66 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 f8531f3356a8..5e50972134d7 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 21b4dbb2a2f2..0064fd58512e 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 68d465da2eee..d51d1e15bedc 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 000000000000..0d65dc7566dc --- /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 399bec32aa3f..a6463465446b 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 876470341639..3f5187b0ef23 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 97ce62a2cd26..45bb3a5a3ae6 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 bb402e45557e..87d1159142c0 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 5e21f1a22984..6be8d8cbbbff 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 08c67fdccc16..e52173c6e4ec 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 5c29a28af075..0f9e7b461df8 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 1c5daae94a54..a0e9cdc5704d 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 214993fb1a9b..129ece20e32c 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 c8a6490874c4..cb8bdffb43f1 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 f033b43cf4fe..a189a64feb3f 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 4a614a550e47..68ad037457b2 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 000000000000..29a4be546ac5 --- /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 cdb4318ac8e8..691750ee4e4b 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) \ -- Gitee