diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-11 19:31:52 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-02-11 19:31:52 -0800 |
| commit | 37a93dd5c49b5fda807fd204edf2547c3493319c (patch) | |
| tree | ce1ef5a642b9ea3d7242156438eb96dc5607a752 /drivers/net/ethernet/neterion/s2io.c | |
| parent | 098b6e44cbaa2d526d06af90c862d13fb414a0ec (diff) | |
| parent | 83310d613382f74070fc8b402f3f6c2af8439ead (diff) | |
Pull networking updates from Paolo Abeni:
"Core & protocols:
- A significant effort all around the stack to guide the compiler to
make the right choice when inlining code, to avoid unneeded calls
for small helper and stack canary overhead in the fast-path.
This generates better and faster code with very small or no text
size increases, as in many cases the call generated more code than
the actual inlined helper.
- Extend AccECN implementation so that is now functionally complete,
also allow the user-space enabling it on a per network namespace
basis.
- Add support for memory providers with large (above 4K) rx buffer.
Paired with hw-gro, larger rx buffer sizes reduce the number of
buffers traversing the stack, dincreasing single stream CPU usage
by up to ~30%.
- Do not add HBH header to Big TCP GSO packets. This simplifies the
RX path, the TX path and the NIC drivers, and is possible because
user-space taps can now interpret correctly such packets without
the HBH hint.
- Allow IPv6 routes to be configured with a gateway address that is
resolved out of a different interface than the one specified,
aligning IPv6 to IPv4 behavior.
- Multi-queue aware sch_cake. This makes it possible to scale the
rate shaper of sch_cake across multiple CPUs, while still enforcing
a single global rate on the interface.
- Add support for the nbcon (new buffer console) infrastructure to
netconsole, enabling lock-free, priority-based console operations
that are safer in crash scenarios.
- Improve the TCP ipv6 output path to cache the flow information,
saving cpu cycles, reducing cache line misses and stack use.
- Improve netfilter packet tracker to resolve clashes for most
protocols, avoiding unneeded drops on rare occasions.
- Add IP6IP6 tunneling acceleration to the flowtable infrastructure.
- Reduce tcp socket size by one cache line.
- Notify neighbour changes atomically, avoiding inconsistencies
between the notification sequence and the actual states sequence.
- Add vsock namespace support, allowing complete isolation of vsocks
across different network namespaces.
- Improve xsk generic performances with cache-alignment-oriented
optimizations.
- Support netconsole automatic target recovery, allowing netconsole
to reestablish targets when underlying low-level interface comes
back online.
Driver API:
- Support for switching the working mode (automatic vs manual) of a
DPLL device via netlink.
- Introduce PHY ports representation to expose multiple front-facing
media ports over a single MAC.
- Introduce "rx-polarity" and "tx-polarity" device tree properties,
to generalize polarity inversion requirements for differential
signaling.
- Add helper to create, prepare and enable managed clocks.
Device drivers:
- Add Huawei hinic3 PF etherner driver.
- Add DWMAC glue driver for Motorcomm YT6801 PCIe ethernet
controller.
- Add ethernet driver for MaxLinear MxL862xx switches
- Remove parallel-port Ethernet driver.
- Convert existing driver timestamp configuration reporting to
hwtstamp_get and remove legacy ioctl().
- Convert existing drivers to .get_rx_ring_count(), simplifing the RX
ring count retrieval. Also remove the legacy fallback path.
- Ethernet high-speed NICs:
- Broadcom (bnxt, bng):
- bnxt: add FW interface update to support FEC stats histogram
and NVRAM defragmentation
- bng: add TSO and H/W GRO support
- nVidia/Mellanox (mlx5):
- improve latency of channel restart operations, reducing the
used H/W resources
- add TSO support for UDP over GRE over VLAN
- add flow counters support for hardware steering (HWS) rules
- use a static memory area to store headers for H/W GRO,
leading to 12% RX tput improvement
- Intel (100G, ice, idpf):
- ice: reorganizes layout of Tx and Rx rings for cacheline
locality and utilizes __cacheline_group* macros on the new
layouts
- ice: introduces Synchronous Ethernet (SyncE) support
- Meta (fbnic):
- adds debugfs for firmware mailbox and tx/rx rings vectors
- Ethernet virtual:
- geneve: introduce GRO/GSO support for double UDP encapsulation
- Ethernet NICs consumer, and embedded:
- Synopsys (stmmac):
- some code refactoring and cleanups
- RealTek (r8169):
- add support for RTL8127ATF (10G Fiber SFP)
- add dash and LTR support
- Airoha:
- AN8811HB 2.5 Gbps phy support
- Freescale (fec):
- add XDP zero-copy support
- Thunderbolt:
- add get link setting support to allow bonding
- Renesas:
- add support for RZ/G3L GBETH SoC
- Ethernet switches:
- Maxlinear:
- support R(G)MII slow rate configuration
- add support for Intel GSW150
- Motorcomm (yt921x):
- add DCB/QoS support
- TI:
- icssm-prueth: support bridging (STP/RSTP) via the switchdev
framework
- Ethernet PHYs:
- Realtek:
- enable SGMII and 2500Base-X in-band auto-negotiation
- simplify and reunify C22/C45 drivers
- Micrel: convert bindings to DT schema
- CAN:
- move skb headroom content into skb extensions, making CAN
metadata access more robust
- CAN drivers:
- rcar_canfd:
- add support for FD-only mode
- add support for the RZ/T2H SoC
- sja1000: cleanup the CAN state handling
- WiFi:
- implement EPPKE/802.1X over auth frames support
- split up drop reasons better, removing generic RX_DROP
- additional FTM capabilities: 6 GHz support, supported number of
spatial streams and supported number of LTF repetitions
- better mac80211 iterators to enumerate resources
- initial UHR (Wi-Fi 8) support for cfg80211/mac80211
- WiFi drivers:
- Qualcomm/Atheros:
- ath11k: support for Channel Frequency Response measurement
- ath12k: a significant driver refactor to support multi-wiphy
devices and and pave the way for future device support in the
same driver (rather than splitting to ath13k)
- ath12k: support for the QCC2072 chipset
- Intel:
- iwlwifi: partial Neighbor Awareness Networking (NAN) support
- iwlwifi: initial support for U-NII-9 and IEEE 802.11bn
- RealTek (rtw89):
- preparations for RTL8922DE support
- Bluetooth:
- implement setsockopt(BT_PHY) to set the connection packet type/PHY
- set link_policy on incoming ACL connections
- Bluetooth drivers:
- btusb: add support for MediaTek7920, Realtek RTL8761BU and 8851BE
- btqca: add WCN6855 firmware priority selection feature"
* tag 'net-next-7.0' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1254 commits)
bnge/bng_re: Add a new HSI
net: macb: Fix tx/rx malfunction after phy link down and up
af_unix: Fix memleak of newsk in unix_stream_connect().
net: ti: icssg-prueth: Add optional dependency on HSR
net: dsa: add basic initial driver for MxL862xx switches
net: mdio: add unlocked mdiodev C45 bus accessors
net: dsa: add tag format for MxL862xx switches
dt-bindings: net: dsa: add MaxLinear MxL862xx
selftests: drivers: net: hw: Modify toeplitz.c to poll for packets
octeontx2-pf: Unregister devlink on probe failure
net: renesas: rswitch: fix forwarding offload statemachine
ionic: Rate limit unknown xcvr type messages
tcp: inet6_csk_xmit() optimization
tcp: populate inet->cork.fl.u.ip6 in tcp_v6_syn_recv_sock()
tcp: populate inet->cork.fl.u.ip6 in tcp_v6_connect()
ipv6: inet6_csk_xmit() and inet6_csk_update_pmtu() use inet->cork.fl.u.ip6
ipv6: use inet->cork.fl.u.ip6 and np->final in ip6_datagram_dst_update()
ipv6: use np->final in inet6_sk_rebuild_header()
ipv6: add daddr/final storage in struct ipv6_pinfo
net: stmmac: qcom-ethqos: fix qcom_ethqos_serdes_powerup()
...
Diffstat (limited to 'drivers/net/ethernet/neterion/s2io.c')
| -rw-r--r-- | drivers/net/ethernet/neterion/s2io.c | 8572 |
1 files changed, 0 insertions, 8572 deletions
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c deleted file mode 100644 index 1e55ccb4822b..000000000000 --- a/drivers/net/ethernet/neterion/s2io.c +++ /dev/null @@ -1,8572 +0,0 @@ -/************************************************************************ - * s2io.c: A Linux PCI-X Ethernet driver for Neterion 10GbE Server NIC - * Copyright(c) 2002-2010 Exar Corp. - * - * This software may be used and distributed according to the terms of - * the GNU General Public License (GPL), incorporated herein by reference. - * Drivers based on or derived from this code fall under the GPL and must - * retain the authorship, copyright and license notice. This file is not - * a complete program and may only be used when the entire operating - * system is licensed under the GPL. - * See the file COPYING in this distribution for more information. - * - * Credits: - * Jeff Garzik : For pointing out the improper error condition - * check in the s2io_xmit routine and also some - * issues in the Tx watch dog function. Also for - * patiently answering all those innumerable - * questions regaring the 2.6 porting issues. - * Stephen Hemminger : Providing proper 2.6 porting mechanism for some - * macros available only in 2.6 Kernel. - * Francois Romieu : For pointing out all code part that were - * deprecated and also styling related comments. - * Grant Grundler : For helping me get rid of some Architecture - * dependent code. - * Christopher Hellwig : Some more 2.6 specific issues in the driver. - * - * The module loadable parameters that are supported by the driver and a brief - * explanation of all the variables. - * - * rx_ring_num : This can be used to program the number of receive rings used - * in the driver. - * rx_ring_sz: This defines the number of receive blocks each ring can have. - * This is also an array of size 8. - * rx_ring_mode: This defines the operation mode of all 8 rings. The valid - * values are 1, 2. - * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. - * tx_fifo_len: This too is an array of 8. Each element defines the number of - * Tx descriptors that can be associated with each corresponding FIFO. - * intr_type: This defines the type of interrupt. The values can be 0(INTA), - * 2(MSI_X). Default value is '2(MSI_X)' - * lro_max_pkts: This parameter defines maximum number of packets can be - * aggregated as a single large packet - * napi: This parameter used to enable/disable NAPI (polling Rx) - * Possible values '1' for enable and '0' for disable. Default is '1' - * vlan_tag_strip: This can be used to enable or disable vlan stripping. - * Possible values '1' for enable , '0' for disable. - * Default is '2' - which means disable in promisc mode - * and enable in non-promiscuous mode. - * multiq: This parameter used to enable/disable MULTIQUEUE support. - * Possible values '1' for enable and '0' for disable. Default is '0' - ************************************************************************/ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include <linux/module.h> -#include <linux/types.h> -#include <linux/errno.h> -#include <linux/ioport.h> -#include <linux/pci.h> -#include <linux/dma-mapping.h> -#include <linux/kernel.h> -#include <linux/netdevice.h> -#include <linux/etherdevice.h> -#include <linux/mdio.h> -#include <linux/skbuff.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/stddef.h> -#include <linux/ioctl.h> -#include <linux/timex.h> -#include <linux/ethtool.h> -#include <linux/workqueue.h> -#include <linux/if_vlan.h> -#include <linux/ip.h> -#include <linux/tcp.h> -#include <linux/uaccess.h> -#include <linux/io.h> -#include <linux/io-64-nonatomic-lo-hi.h> -#include <linux/slab.h> -#include <linux/prefetch.h> -#include <net/tcp.h> -#include <net/checksum.h> - -#include <asm/div64.h> -#include <asm/irq.h> - -/* local include */ -#include "s2io.h" -#include "s2io-regs.h" - -#define DRV_VERSION "2.0.26.28" - -/* S2io Driver name & version. */ -static const char s2io_driver_name[] = "Neterion"; -static const char s2io_driver_version[] = DRV_VERSION; - -static const int rxd_size[2] = {32, 48}; -static const int rxd_count[2] = {127, 85}; - -static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) -{ - int ret; - - ret = ((!(rxdp->Control_1 & RXD_OWN_XENA)) && - (GET_RXD_MARKER(rxdp->Control_2) != THE_RXD_MARK)); - - return ret; -} - -/* - * Cards with following subsystem_id have a link state indication - * problem, 600B, 600C, 600D, 640B, 640C and 640D. - * macro below identifies these cards given the subsystem_id. - */ -#define CARDS_WITH_FAULTY_LINK_INDICATORS(dev_type, subid) \ - (dev_type == XFRAME_I_DEVICE) ? \ - ((((subid >= 0x600B) && (subid <= 0x600D)) || \ - ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0) : 0 - -#define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \ - ADAPTER_STATUS_RMAC_LOCAL_FAULT))) - -static inline int is_s2io_card_up(const struct s2io_nic *sp) -{ - return test_bit(__S2IO_STATE_CARD_UP, &sp->state); -} - -/* Ethtool related variables and Macros. */ -static const char s2io_gstrings[][ETH_GSTRING_LEN] = { - "Register test\t(offline)", - "Eeprom test\t(offline)", - "Link test\t(online)", - "RLDRAM test\t(offline)", - "BIST Test\t(offline)" -}; - -static const char ethtool_xena_stats_keys[][ETH_GSTRING_LEN] = { - {"tmac_frms"}, - {"tmac_data_octets"}, - {"tmac_drop_frms"}, - {"tmac_mcst_frms"}, - {"tmac_bcst_frms"}, - {"tmac_pause_ctrl_frms"}, - {"tmac_ttl_octets"}, - {"tmac_ucst_frms"}, - {"tmac_nucst_frms"}, - {"tmac_any_err_frms"}, - {"tmac_ttl_less_fb_octets"}, - {"tmac_vld_ip_octets"}, - {"tmac_vld_ip"}, - {"tmac_drop_ip"}, - {"tmac_icmp"}, - {"tmac_rst_tcp"}, - {"tmac_tcp"}, - {"tmac_udp"}, - {"rmac_vld_frms"}, - {"rmac_data_octets"}, - {"rmac_fcs_err_frms"}, - {"rmac_drop_frms"}, - {"rmac_vld_mcst_frms"}, - {"rmac_vld_bcst_frms"}, - {"rmac_in_rng_len_err_frms"}, - {"rmac_out_rng_len_err_frms"}, - {"rmac_long_frms"}, - {"rmac_pause_ctrl_frms"}, - {"rmac_unsup_ctrl_frms"}, - {"rmac_ttl_octets"}, - {"rmac_accepted_ucst_frms"}, - {"rmac_accepted_nucst_frms"}, - {"rmac_discarded_frms"}, - {"rmac_drop_events"}, - {"rmac_ttl_less_fb_octets"}, - {"rmac_ttl_frms"}, - {"rmac_usized_frms"}, - {"rmac_osized_frms"}, - {"rmac_frag_frms"}, - {"rmac_jabber_frms"}, - {"rmac_ttl_64_frms"}, - {"rmac_ttl_65_127_frms"}, - {"rmac_ttl_128_255_frms"}, - {"rmac_ttl_256_511_frms"}, - {"rmac_ttl_512_1023_frms"}, - {"rmac_ttl_1024_1518_frms"}, - {"rmac_ip"}, - {"rmac_ip_octets"}, - {"rmac_hdr_err_ip"}, - {"rmac_drop_ip"}, - {"rmac_icmp"}, - {"rmac_tcp"}, - {"rmac_udp"}, - {"rmac_err_drp_udp"}, - {"rmac_xgmii_err_sym"}, - {"rmac_frms_q0"}, - {"rmac_frms_q1"}, - {"rmac_frms_q2"}, - {"rmac_frms_q3"}, - {"rmac_frms_q4"}, - {"rmac_frms_q5"}, - {"rmac_frms_q6"}, - {"rmac_frms_q7"}, - {"rmac_full_q0"}, - {"rmac_full_q1"}, - {"rmac_full_q2"}, - {"rmac_full_q3"}, - {"rmac_full_q4"}, - {"rmac_full_q5"}, - {"rmac_full_q6"}, - {"rmac_full_q7"}, - {"rmac_pause_cnt"}, - {"rmac_xgmii_data_err_cnt"}, - {"rmac_xgmii_ctrl_err_cnt"}, - {"rmac_accepted_ip"}, - {"rmac_err_tcp"}, - {"rd_req_cnt"}, - {"new_rd_req_cnt"}, - {"new_rd_req_rtry_cnt"}, - {"rd_rtry_cnt"}, - {"wr_rtry_rd_ack_cnt"}, - {"wr_req_cnt"}, - {"new_wr_req_cnt"}, - {"new_wr_req_rtry_cnt"}, - {"wr_rtry_cnt"}, - {"wr_disc_cnt"}, - {"rd_rtry_wr_ack_cnt"}, - {"txp_wr_cnt"}, - {"txd_rd_cnt"}, - {"txd_wr_cnt"}, - {"rxd_rd_cnt"}, - {"rxd_wr_cnt"}, - {"txf_rd_cnt"}, - {"rxf_wr_cnt"} -}; - -static const char ethtool_enhanced_stats_keys[][ETH_GSTRING_LEN] = { - {"rmac_ttl_1519_4095_frms"}, - {"rmac_ttl_4096_8191_frms"}, - {"rmac_ttl_8192_max_frms"}, - {"rmac_ttl_gt_max_frms"}, - {"rmac_osized_alt_frms"}, - {"rmac_jabber_alt_frms"}, - {"rmac_gt_max_alt_frms"}, - {"rmac_vlan_frms"}, - {"rmac_len_discard"}, - {"rmac_fcs_discard"}, - {"rmac_pf_discard"}, - {"rmac_da_discard"}, - {"rmac_red_discard"}, - {"rmac_rts_discard"}, - {"rmac_ingm_full_discard"}, - {"link_fault_cnt"} -}; - -static const char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = { - {"\n DRIVER STATISTICS"}, - {"single_bit_ecc_errs"}, - {"double_bit_ecc_errs"}, - {"parity_err_cnt"}, - {"serious_err_cnt"}, - {"soft_reset_cnt"}, - {"fifo_full_cnt"}, - {"ring_0_full_cnt"}, - {"ring_1_full_cnt"}, - {"ring_2_full_cnt"}, - {"ring_3_full_cnt"}, - {"ring_4_full_cnt"}, - {"ring_5_full_cnt"}, - {"ring_6_full_cnt"}, - {"ring_7_full_cnt"}, - {"alarm_transceiver_temp_high"}, - {"alarm_transceiver_temp_low"}, - {"alarm_laser_bias_current_high"}, - {"alarm_laser_bias_current_low"}, - {"alarm_laser_output_power_high"}, - {"alarm_laser_output_power_low"}, - {"warn_transceiver_temp_high"}, - {"warn_transceiver_temp_low"}, - {"warn_laser_bias_current_high"}, - {"warn_laser_bias_current_low"}, - {"warn_laser_output_power_high"}, - {"warn_laser_output_power_low"}, - {"lro_aggregated_pkts"}, - {"lro_flush_both_count"}, - {"lro_out_of_sequence_pkts"}, - {"lro_flush_due_to_max_pkts"}, - {"lro_avg_aggr_pkts"}, - {"mem_alloc_fail_cnt"}, - {"pci_map_fail_cnt"}, - {"watchdog_timer_cnt"}, - {"mem_allocated"}, - {"mem_freed"}, - {"link_up_cnt"}, - {"link_down_cnt"}, - {"link_up_time"}, - {"link_down_time"}, - {"tx_tcode_buf_abort_cnt"}, - {"tx_tcode_desc_abort_cnt"}, - {"tx_tcode_parity_err_cnt"}, - {"tx_tcode_link_loss_cnt"}, - {"tx_tcode_list_proc_err_cnt"}, - {"rx_tcode_parity_err_cnt"}, - {"rx_tcode_abort_cnt"}, - {"rx_tcode_parity_abort_cnt"}, - {"rx_tcode_rda_fail_cnt"}, - {"rx_tcode_unkn_prot_cnt"}, - {"rx_tcode_fcs_err_cnt"}, - {"rx_tcode_buf_size_err_cnt"}, - {"rx_tcode_rxd_corrupt_cnt"}, - {"rx_tcode_unkn_err_cnt"}, - {"tda_err_cnt"}, - {"pfc_err_cnt"}, - {"pcc_err_cnt"}, - {"tti_err_cnt"}, - {"tpa_err_cnt"}, - {"sm_err_cnt"}, - {"lso_err_cnt"}, - {"mac_tmac_err_cnt"}, - {"mac_rmac_err_cnt"}, - {"xgxs_txgxs_err_cnt"}, - {"xgxs_rxgxs_err_cnt"}, - {"rc_err_cnt"}, - {"prc_pcix_err_cnt"}, - {"rpa_err_cnt"}, - {"rda_err_cnt"}, - {"rti_err_cnt"}, - {"mc_err_cnt"} -}; - -#define S2IO_XENA_STAT_LEN ARRAY_SIZE(ethtool_xena_stats_keys) -#define S2IO_ENHANCED_STAT_LEN ARRAY_SIZE(ethtool_enhanced_stats_keys) -#define S2IO_DRIVER_STAT_LEN ARRAY_SIZE(ethtool_driver_stats_keys) - -#define XFRAME_I_STAT_LEN (S2IO_XENA_STAT_LEN + S2IO_DRIVER_STAT_LEN) -#define XFRAME_II_STAT_LEN (XFRAME_I_STAT_LEN + S2IO_ENHANCED_STAT_LEN) - -#define XFRAME_I_STAT_STRINGS_LEN (XFRAME_I_STAT_LEN * ETH_GSTRING_LEN) -#define XFRAME_II_STAT_STRINGS_LEN (XFRAME_II_STAT_LEN * ETH_GSTRING_LEN) - -#define S2IO_TEST_LEN ARRAY_SIZE(s2io_gstrings) -#define S2IO_STRINGS_LEN (S2IO_TEST_LEN * ETH_GSTRING_LEN) - -/* copy mac addr to def_mac_addr array */ -static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr) -{ - sp->def_mac_addr[offset].mac_addr[5] = (u8) (mac_addr); - sp->def_mac_addr[offset].mac_addr[4] = (u8) (mac_addr >> 8); - sp->def_mac_addr[offset].mac_addr[3] = (u8) (mac_addr >> 16); - sp->def_mac_addr[offset].mac_addr[2] = (u8) (mac_addr >> 24); - sp->def_mac_addr[offset].mac_addr[1] = (u8) (mac_addr >> 32); - sp->def_mac_addr[offset].mac_addr[0] = (u8) (mac_addr >> 40); -} - -/* - * Constants to be programmed into the Xena's registers, to configure - * the XAUI. - */ - -#define END_SIGN 0x0 -static const u64 herc_act_dtx_cfg[] = { - /* Set address */ - 0x8000051536750000ULL, 0x80000515367500E0ULL, - /* Write data */ - 0x8000051536750004ULL, 0x80000515367500E4ULL, - /* Set address */ - 0x80010515003F0000ULL, 0x80010515003F00E0ULL, - /* Write data */ - 0x80010515003F0004ULL, 0x80010515003F00E4ULL, - /* Set address */ - 0x801205150D440000ULL, 0x801205150D4400E0ULL, - /* Write data */ - 0x801205150D440004ULL, 0x801205150D4400E4ULL, - /* Set address */ - 0x80020515F2100000ULL, 0x80020515F21000E0ULL, - /* Write data */ - 0x80020515F2100004ULL, 0x80020515F21000E4ULL, - /* Done */ - END_SIGN -}; - -static const u64 xena_dtx_cfg[] = { - /* Set address */ - 0x8000051500000000ULL, 0x80000515000000E0ULL, - /* Write data */ - 0x80000515D9350004ULL, 0x80000515D93500E4ULL, - /* Set address */ - 0x8001051500000000ULL, 0x80010515000000E0ULL, - /* Write data */ - 0x80010515001E0004ULL, 0x80010515001E00E4ULL, - /* Set address */ - 0x8002051500000000ULL, 0x80020515000000E0ULL, - /* Write data */ - 0x80020515F2100004ULL, 0x80020515F21000E4ULL, - END_SIGN -}; - -/* - * Constants for Fixing the MacAddress problem seen mostly on - * Alpha machines. - */ -static const u64 fix_mac[] = { - 0x0060000000000000ULL, 0x0060600000000000ULL, - 0x0040600000000000ULL, 0x0000600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0060600000000000ULL, - 0x0020600000000000ULL, 0x0000600000000000ULL, - 0x0040600000000000ULL, 0x0060600000000000ULL, - END_SIGN -}; - -MODULE_DESCRIPTION("Neterion 10GbE driver"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(DRV_VERSION); - - -/* Module Loadable parameters. */ -S2IO_PARM_INT(tx_fifo_num, FIFO_DEFAULT_NUM); -S2IO_PARM_INT(rx_ring_num, 1); -S2IO_PARM_INT(multiq, 0); -S2IO_PARM_INT(rx_ring_mode, 1); -S2IO_PARM_INT(use_continuous_tx_intrs, 1); -S2IO_PARM_INT(rmac_pause_time, 0x100); -S2IO_PARM_INT(mc_pause_threshold_q0q3, 187); -S2IO_PARM_INT(mc_pause_threshold_q4q7, 187); -S2IO_PARM_INT(shared_splits, 0); -S2IO_PARM_INT(tmac_util_period, 5); -S2IO_PARM_INT(rmac_util_period, 5); -S2IO_PARM_INT(l3l4hdr_size, 128); -/* 0 is no steering, 1 is Priority steering, 2 is Default steering */ -S2IO_PARM_INT(tx_steering_type, TX_DEFAULT_STEERING); -/* Frequency of Rx desc syncs expressed as power of 2 */ -S2IO_PARM_INT(rxsync_frequency, 3); -/* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ -S2IO_PARM_INT(intr_type, 2); -/* Large receive offload feature */ - -/* Max pkts to be aggregated by LRO at one time. If not specified, - * aggregation happens until we hit max IP pkt size(64K) - */ -S2IO_PARM_INT(lro_max_pkts, 0xFFFF); -S2IO_PARM_INT(indicate_max_pkts, 0); - -S2IO_PARM_INT(napi, 1); -S2IO_PARM_INT(vlan_tag_strip, NO_STRIP_IN_PROMISC); - -static unsigned int tx_fifo_len[MAX_TX_FIFOS] = -{DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; -static unsigned int rx_ring_sz[MAX_RX_RINGS] = -{[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT}; -static unsigned int rts_frm_len[MAX_RX_RINGS] = -{[0 ...(MAX_RX_RINGS - 1)] = 0 }; - -module_param_array(tx_fifo_len, uint, NULL, 0); -module_param_array(rx_ring_sz, uint, NULL, 0); -module_param_array(rts_frm_len, uint, NULL, 0); - -/* - * S2IO device table. - * This table lists all the devices that this driver supports. - */ -static const struct pci_device_id s2io_tbl[] = { - {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_WIN, - PCI_ANY_ID, PCI_ANY_ID}, - {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_UNI, - PCI_ANY_ID, PCI_ANY_ID}, - {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_WIN, - PCI_ANY_ID, PCI_ANY_ID}, - {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_UNI, - PCI_ANY_ID, PCI_ANY_ID}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, s2io_tbl); - -static const struct pci_error_handlers s2io_err_handler = { - .error_detected = s2io_io_error_detected, - .slot_reset = s2io_io_slot_reset, - .resume = s2io_io_resume, -}; - -static struct pci_driver s2io_driver = { - .name = "S2IO", - .id_table = s2io_tbl, - .probe = s2io_init_nic, - .remove = s2io_rem_nic, - .err_handler = &s2io_err_handler, -}; - -/* A simplifier macro used both by init and free shared_mem Fns(). */ -#define TXD_MEM_PAGE_CNT(len, per_each) DIV_ROUND_UP(len, per_each) - -/* netqueue manipulation helper functions */ -static inline void s2io_stop_all_tx_queue(struct s2io_nic *sp) -{ - if (!sp->config.multiq) { - int i; - - for (i = 0; i < sp->config.tx_fifo_num; i++) - sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_STOP; - } - netif_tx_stop_all_queues(sp->dev); -} - -static inline void s2io_stop_tx_queue(struct s2io_nic *sp, int fifo_no) -{ - if (!sp->config.multiq) - sp->mac_control.fifos[fifo_no].queue_state = - FIFO_QUEUE_STOP; - - netif_tx_stop_all_queues(sp->dev); -} - -static inline void s2io_start_all_tx_queue(struct s2io_nic *sp) -{ - if (!sp->config.multiq) { - int i; - - for (i = 0; i < sp->config.tx_fifo_num; i++) - sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START; - } - netif_tx_start_all_queues(sp->dev); -} - -static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp) -{ - if (!sp->config.multiq) { - int i; - - for (i = 0; i < sp->config.tx_fifo_num; i++) - sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START; - } - netif_tx_wake_all_queues(sp->dev); -} - -static inline void s2io_wake_tx_queue( - struct fifo_info *fifo, int cnt, u8 multiq) -{ - - if (multiq) { - if (cnt && __netif_subqueue_stopped(fifo->dev, fifo->fifo_no)) - netif_wake_subqueue(fifo->dev, fifo->fifo_no); - } else if (cnt && (fifo->queue_state == FIFO_QUEUE_STOP)) { - if (netif_queue_stopped(fifo->dev)) { - fifo->queue_state = FIFO_QUEUE_START; - netif_wake_queue(fifo->dev); - } - } -} - -/** - * init_shared_mem - Allocation and Initialization of Memory - * @nic: Device private variable. - * Description: The function allocates all the memory areas shared - * between the NIC and the driver. This includes Tx descriptors, - * Rx descriptors and the statistics block. - */ - -static int init_shared_mem(struct s2io_nic *nic) -{ - u32 size; - void *tmp_v_addr, *tmp_v_addr_next; - dma_addr_t tmp_p_addr, tmp_p_addr_next; - struct RxD_block *pre_rxd_blk = NULL; - int i, j, blk_cnt; - int lst_size, lst_per_page; - struct net_device *dev = nic->dev; - unsigned long tmp; - struct buffAdd *ba; - struct config_param *config = &nic->config; - struct mac_info *mac_control = &nic->mac_control; - unsigned long long mem_allocated = 0; - - /* Allocation and initialization of TXDLs in FIFOs */ - size = 0; - for (i = 0; i < config->tx_fifo_num; i++) { - struct tx_fifo_config *tx_cfg = &config->tx_cfg[i]; - - size += tx_cfg->fifo_len; - } - if (size > MAX_AVAILABLE_TXDS) { - DBG_PRINT(ERR_DBG, - "Too many TxDs requested: %d, max supported: %d\n", - size, MAX_AVAILABLE_TXDS); - return -EINVAL; - } - - size = 0; - for (i = 0; i < config->tx_fifo_num; i++) { - struct tx_fifo_config *tx_cfg = &config->tx_cfg[i]; - - size = tx_cfg->fifo_len; - /* - * Legal values are from 2 to 8192 - */ - if (size < 2) { - DBG_PRINT(ERR_DBG, "Fifo %d: Invalid length (%d) - " - "Valid lengths are 2 through 8192\n", - i, size); - return -EINVAL; - } - } - - lst_size = (sizeof(struct TxD) * config->max_txds); - lst_per_page = PAGE_SIZE / lst_size; - - for (i = 0; i < config->tx_fifo_num; i++) { - struct fifo_info *fifo = &mac_control->fifos[i]; - struct tx_fifo_config *tx_cfg = &config->tx_cfg[i]; - int fifo_len = tx_cfg->fifo_len; - int list_holder_size = fifo_len * sizeof(struct list_info_hold); - - fifo->list_info = kzalloc(list_holder_size, GFP_KERNEL); - if (!fifo->list_info) { - DBG_PRINT(INFO_DBG, "Malloc failed for list_info\n"); - return -ENOMEM; - } - mem_allocated += list_holder_size; - } - for (i = 0; i < config->tx_fifo_num; i++) { - int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, - lst_per_page); - struct fifo_info *fifo = &mac_control->fifos[i]; - struct tx_fifo_config *tx_cfg = &config->tx_cfg[i]; - - fifo->tx_curr_put_info.offset = 0; - fifo->tx_curr_put_info.fifo_len = tx_cfg->fifo_len - 1; - fifo->tx_curr_get_info.offset = 0; - fifo->tx_curr_get_info.fifo_len = tx_cfg->fifo_len - 1; - fifo->fifo_no = i; - fifo->nic = nic; - fifo->max_txds = MAX_SKB_FRAGS + 2; - fifo->dev = dev; - - for (j = 0; j < page_num; j++) { - int k = 0; - dma_addr_t tmp_p; - void *tmp_v; - tmp_v = dma_alloc_coherent(&nic->pdev->dev, PAGE_SIZE, - &tmp_p, GFP_KERNEL); - if (!tmp_v) { - DBG_PRINT(INFO_DBG, - "dma_alloc_coherent failed for TxDL\n"); - return -ENOMEM; - } - /* If we got a zero DMA address(can happen on - * certain platforms like PPC), reallocate. - * Store virtual address of page we don't want, - * to be freed later. - */ - if (!tmp_p) { - mac_control->zerodma_virt_addr = tmp_v; - DBG_PRINT(INIT_DBG, - "%s: Zero DMA address for TxDL. " - "Virtual address %p\n", - dev->name, tmp_v); - tmp_v = dma_alloc_coherent(&nic->pdev->dev, - PAGE_SIZE, &tmp_p, - GFP_KERNEL); - if (!tmp_v) { - DBG_PRINT(INFO_DBG, - "dma_alloc_coherent failed for TxDL\n"); - return -ENOMEM; - } - mem_allocated += PAGE_SIZE; - } - while (k < lst_per_page) { - int l = (j * lst_per_page) + k; - if (l == tx_cfg->fifo_len) - break; - fifo->list_info[l].list_virt_addr = - tmp_v + (k * lst_size); - fifo->list_info[l].list_phy_addr = - tmp_p + (k * lst_size); - k++; - } - } - } - - for (i = 0; i < config->tx_fifo_num; i++) { - struct fifo_info *fifo = &mac_control->fifos[i]; - struct tx_fifo_config *tx_cfg = &config->tx_cfg[i]; - - size = tx_cfg->fifo_len; - fifo->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL); - if (!fifo->ufo_in_band_v) - return -ENOMEM; - mem_allocated += (size * sizeof(u64)); - } - - /* Allocation and initialization of RXDs in Rings */ - size = 0; - for (i = 0; i < config->rx_ring_num; i++) { - struct rx_ring_config *rx_cfg = &config->rx_cfg[i]; - struct ring_info *ring = &mac_control->rings[i]; - - if (rx_cfg->num_rxd % (rxd_count[nic->rxd_mode] + 1)) { - DBG_PRINT(ERR_DBG, "%s: Ring%d RxD count is not a " - "multiple of RxDs per Block\n", - dev->name, i); - return FAILURE; - } - size += rx_cfg->num_rxd; - ring->block_count = rx_cfg->num_rxd / - (rxd_count[nic->rxd_mode] + 1); - ring->pkt_cnt = rx_cfg->num_rxd - ring->block_count; - } - if (nic->rxd_mode == RXD_MODE_1) - size = (size * (sizeof(struct RxD1))); - else - size = (size * (sizeof(struct RxD3))); - - for (i = 0; i < config->rx_ring_num; i++) { - struct rx_ring_config *rx_cfg = &config->rx_cfg[i]; - struct ring_info *ring = &mac_control->rings[i]; - - ring->rx_curr_get_info.block_index = 0; - ring->rx_curr_get_info.offset = 0; - ring->rx_curr_get_info.ring_len = rx_cfg->num_rxd - 1; - ring->rx_curr_put_info.block_index = 0; - ring->rx_curr_put_info.offset = 0; - ring->rx_curr_put_info.ring_len = rx_cfg->num_rxd - 1; - ring->nic = nic; - ring->ring_no = i; - - blk_cnt = rx_cfg->num_rxd / (rxd_count[nic->rxd_mode] + 1); - /* Allocating all the Rx blocks */ - for (j = 0; j < blk_cnt; j++) { - struct rx_block_info *rx_blocks; - int l; - - rx_blocks = &ring->rx_blocks[j]; - size = SIZE_OF_BLOCK; /* size is always page size */ - tmp_v_addr = dma_alloc_coherent(&nic->pdev->dev, size, - &tmp_p_addr, GFP_KERNEL); - if (tmp_v_addr == NULL) { - /* - * In case of failure, free_shared_mem() - * is called, which should free any - * memory that was alloced till the - * failure happened. - */ - rx_blocks->block_virt_addr = tmp_v_addr; - return -ENOMEM; - } - mem_allocated += size; - - size = sizeof(struct rxd_info) * - rxd_count[nic->rxd_mode]; - rx_blocks->block_virt_addr = tmp_v_addr; - rx_blocks->block_dma_addr = tmp_p_addr; - rx_blocks->rxds = kmalloc(size, GFP_KERNEL); - if (!rx_blocks->rxds) - return -ENOMEM; - mem_allocated += size; - for (l = 0; l < rxd_count[nic->rxd_mode]; l++) { - rx_blocks->rxds[l].virt_addr = - rx_blocks->block_virt_addr + - (rxd_size[nic->rxd_mode] * l); - rx_blocks->rxds[l].dma_addr = - rx_blocks->block_dma_addr + - (rxd_size[nic->rxd_mode] * l); - } - } - /* Interlinking all Rx Blocks */ - for (j = 0; j < blk_cnt; j++) { - int next = (j + 1) % blk_cnt; - tmp_v_addr = ring->rx_blocks[j].block_virt_addr; - tmp_v_addr_next = ring->rx_blocks[next].block_virt_addr; - tmp_p_addr = ring->rx_blocks[j].block_dma_addr; - tmp_p_addr_next = ring->rx_blocks[next].block_dma_addr; - - pre_rxd_blk = tmp_v_addr; - pre_rxd_blk->reserved_2_pNext_RxD_block = - (unsigned long)tmp_v_addr_next; - pre_rxd_blk->pNext_RxD_Blk_physical = - (u64)tmp_p_addr_next; - } - } - if (nic->rxd_mode == RXD_MODE_3B) { - /* - * Allocation of Storages for buffer addresses in 2BUFF mode - * and the buffers as well. - */ - for (i = 0; i < config->rx_ring_num; i++) { - struct rx_ring_config *rx_cfg = &config->rx_cfg[i]; - struct ring_info *ring = &mac_control->rings[i]; - - blk_cnt = rx_cfg->num_rxd / - (rxd_count[nic->rxd_mode] + 1); - size = sizeof(struct buffAdd *) * blk_cnt; - ring->ba = kmalloc(size, GFP_KERNEL); - if (!ring->ba) - return -ENOMEM; - mem_allocated += size; - for (j = 0; j < blk_cnt; j++) { - int k = 0; - - size = sizeof(struct buffAdd) * - (rxd_count[nic->rxd_mode] + 1); - ring->ba[j] = kmalloc(size, GFP_KERNEL); - if (!ring->ba[j]) - return -ENOMEM; - mem_allocated += size; - while (k != rxd_count[nic->rxd_mode]) { - ba = &ring->ba[j][k]; - size = BUF0_LEN + ALIGN_SIZE; - ba->ba_0_org = kmalloc(size, GFP_KERNEL); - if (!ba->ba_0_org) - return -ENOMEM; - mem_allocated += size; - tmp = (unsigned long)ba->ba_0_org; - tmp += ALIGN_SIZE; - tmp &= ~((unsigned long)ALIGN_SIZE); - ba->ba_0 = (void *)tmp; - - size = BUF1_LEN + ALIGN_SIZE; - ba->ba_1_org = kmalloc(size, GFP_KERNEL); - if (!ba->ba_1_org) - return -ENOMEM; - mem_allocated += size; - tmp = (unsigned long)ba->ba_1_org; - tmp += ALIGN_SIZE; - tmp &= ~((unsigned long)ALIGN_SIZE); - ba->ba_1 = (void *)tmp; - k++; - } - } - } - } - - /* Allocation and initialization of Statistics block */ - size = sizeof(struct stat_block); - mac_control->stats_mem = - dma_alloc_coherent(&nic->pdev->dev, size, - &mac_control->stats_mem_phy, GFP_KERNEL); - - if (!mac_control->stats_mem) { - /* - * In case of failure, free_shared_mem() is called, which - * should free any memory that was alloced till the - * failure happened. - */ - return -ENOMEM; - } - mem_allocated += size; - mac_control->stats_mem_sz = size; - - tmp_v_addr = mac_control->stats_mem; - mac_control->stats_info = tmp_v_addr; - memset(tmp_v_addr, 0, size); - DBG_PRINT(INIT_DBG, "%s: Ring Mem PHY: 0x%llx\n", - dev_name(&nic->pdev->dev), (unsigned long long)tmp_p_addr); - mac_control->stats_info->sw_stat.mem_allocated += mem_allocated; - return SUCCESS; -} - -/** - * free_shared_mem - Free the allocated Memory - * @nic: Device private variable. - * Description: This function is to free all memory locations allocated by - * the init_shared_mem() function and return it to the kernel. - */ - -static void free_shared_mem(struct s2io_nic *nic) -{ - int i, j, blk_cnt, size; - void *tmp_v_addr; - dma_addr_t tmp_p_addr; - int lst_size, lst_per_page; - struct net_device *dev; - int page_num = 0; - struct config_param *config; - struct mac_info *mac_control; - struct stat_block *stats; - struct swStat *swstats; - - if (!nic) - return; - - dev = nic->dev; - - config = &nic->config; - mac_control = &nic->mac_control; - stats = mac_control->stats_info; - swstats = &stats->sw_stat; - - lst_size = sizeof(struct TxD) * config->max_txds; - lst_per_page = PAGE_SIZE / lst_size; - - for (i = 0; i < config->tx_fifo_num; i++) { - struct fifo_info *fifo = &mac_control->fifos[i]; - struct tx_fifo_config *tx_cfg = &config->tx_cfg[i]; - - page_num = TXD_MEM_PAGE_CNT(tx_cfg->fifo_len, lst_per_page); - for (j = 0; j < page_num; j++) { - int mem_blks = (j * lst_per_page); - struct list_info_hold *fli; - - if (!fifo->list_info) - return; - - fli = &fifo->list_info[mem_blks]; - if (!fli->list_virt_addr) - break; - dma_free_coherent(&nic->pdev->dev, PAGE_SIZE, - fli->list_virt_ad |
