diff options
author | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-05-13 02:51:01 -0700 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2011-08-11 02:41:47 -0700 |
commit | 86387e1ac4fcaa45ff5578013a78593d1a0ba279 (patch) | |
tree | 25c662fa8226419e73c72873888634fe1df04693 /drivers/net/s2io.c | |
parent | 93f7848b77bcf1108879defd32612422ae80d785 (diff) |
s2io/vxge: Move the Exar drivers
Move the Exar drivers into drivers/net/ethernet/neterion/ and make the
necessary Kconfig and Makefile changes.
CC: Jon Mason <jdmason@kudzu.us>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 8674 |
1 files changed, 0 insertions, 8674 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c deleted file mode 100644 index 277d48b0800..00000000000 --- a/drivers/net/s2io.c +++ /dev/null @@ -1,8674 +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' - * ufo: This parameter used to enable/disable UDP Fragmentation Offload(UFO) - * Possible values '1' for enable and '0' for disable. Default is '0' - * 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/slab.h> -#include <linux/prefetch.h> -#include <net/tcp.h> - -#include <asm/system.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) - -#define S2IO_TIMER_CONF(timer, handle, arg, exp) \ - init_timer(&timer); \ - timer.function = handle; \ - timer.data = (unsigned long)arg; \ - mod_timer(&timer, (jiffies + exp)) \ - -/* 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_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(ufo, 0); -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 DEFINE_PCI_DEVICE_TABLE(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 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 = __devexit_p(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) ((len+per_each - 1) / 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_start_tx_queue(struct s2io_nic *sp, int fifo_no) -{ - if (!sp->config.multiq) - sp->mac_control.fifos[fifo_no].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 = pci_alloc_consistent(nic->pdev, - PAGE_SIZE, &tmp_p); - if (!tmp_v) { - DBG_PRINT(INFO_DBG, - "pci_alloc_consistent 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 = pci_alloc_consistent(nic->pdev, - PAGE_SIZE, &tmp_p); - if (!tmp_v) { - DBG_PRINT(INFO_DBG, - "pci_alloc_consistent 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 = pci_alloc_consistent(nic->pdev, size, - &tmp_p_addr); - 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; - memset(tmp_v_addr, 0, 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 = - pci_alloc_consistent(nic->pdev, size, - &mac_control->stats_mem_phy); - - 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; - pci_free_consistent(nic->pdev, PAGE_SIZE, - fli->list_virt_addr, - fli->list_phy_addr); - swstats->mem_freed += PAGE_SIZE; - } - /* If we got a zero DMA address during allocation, - * free the page now - */ - if (mac_control->zerodma_virt_addr) { - pci_free_consistent(nic->pdev, PAGE_SIZE, - mac_control->zerodma_virt_addr, - (dma_addr_t)0); - DBG_PRINT(INIT_DBG, - "%s: Freeing TxDL with zero DMA address. " - "Virtual address %p\n", - dev->name, mac_control->zerodma_virt_addr); - swstats->mem_freed += PAGE_SIZE; - } - kfree(fifo->list_info); - swstats->mem_freed += tx_cfg->fifo_len * - sizeof(struct list_info_hold); - } - - size = SIZE_OF_BLOCK; - for (i = 0; i < config->rx_ring_num; i++) { - struct ring_info *ring = &mac_control->rings[i]; - - blk_cnt = ring->block_count; - for (j = 0; j < blk_cnt; j++) { - tmp_v_addr = ring->rx_blocks[j].block_virt_addr; - tmp_p_addr = ring->rx_blocks[j].block_dma_addr; - if (tmp_v_addr == NULL) - break; - pci_free_consistent(nic->pdev, size, - tmp_v_addr, tmp_p_addr); - swstats->mem_freed += size; - kfree(ring->rx_blocks[j].rxds); - swstats->mem_freed += sizeof(struct rxd_info) * - rxd_count[nic->rxd_mode]; - } - } - - if (nic->rxd_mode == RXD_MODE_3B) { - /* Freeing buffer storage addresses in 2BUFF mode. */ - 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); - for (j = 0; j < blk_cnt; j++) { - int k = 0; - if (!ring->ba[j]) - continue; - while (k != rxd_count[nic->rxd_mode]) { - struct buffAdd *ba = &ring->ba[j][k]; - kfree(ba->ba_0_org); - swstats->mem_freed += - BUF0_LEN + ALIGN_SIZE; - kfree(ba->ba_1_org); - swstats->mem_freed += - BUF1_LEN + ALIGN_SIZE; - k++; - } - kfree(ring->ba[j]); - swstats->mem_freed += sizeof(struct buffAdd) * - (rxd_count[nic->rxd_mode] + 1); - } - kfree(ring->ba); - swstats->mem_freed += sizeof(struct buffAdd *) * - blk_cnt; - } - } - - for (i = 0; i < nic->config.tx_fifo_num; i++) { - struct fifo_info *fifo = &mac_control->fifos[i]; - struct tx_fifo_config *tx_cfg = &config->tx_cfg[i]; - - if (fifo->ufo_in_band_v) { - swstats->mem_freed += tx_cfg->fifo_len * - sizeof(u64); - kfree(fifo->ufo_in_band_v); - } - } - - if (mac_control->stats_mem) { - swstats->mem_freed += mac_control->stats_mem_sz; - pci_free_consistent(nic->pdev, - mac_control->stats_mem_sz, - mac_control->stats_mem, - mac_control->stats_mem_phy); - } -} - -/** - * s2io_verify_pci_mode - - */ - -static int s2io_verify_pci_mode(struct s2io_nic *nic) -{ - struct XENA_dev_config __iomem *bar0 = nic->bar0; - register u64 val64 = 0; - int mode; - - val64 = readq(&bar0->pci_mode); - mode = (u8)GET_PCI_MODE(val64); - - if (val64 & PCI_MODE_UNKNOWN_MODE) - return -1; /* Unknown PCI mode */ - return mode; -} - -#define NEC_VENID 0x1033 -#define NEC_DEVID 0x0125 -static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) -{ - struct pci_dev *tdev = NULL; - while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { - if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { - if (tdev->bus == s2io_pdev->bus->parent) { - pci_dev_put(tdev); - return 1; - } - } - } - return 0; -} - -static int bus_speed[8] = {33, 133, 133, 200, 266, 133, 200, 266}; -/** - * s2io_print_pci_mode - - */ -static int s2io_print_pci_mode(struct s2io_nic *nic) -{ - struct XENA_dev_config __iomem *bar0 = nic->bar0; - register u64 val64 = 0; - int mode; - struct config_param *config = &nic->config; - const char *pcimode; - - val64 = readq(&bar0->pci_mode); - mode = (u8)GET_PCI_MODE(val64); - - if (val64 & PCI_MODE_UNKNOWN_MODE) - return -1; /* Unknown PCI mode */ - - config->bus_speed = bus_speed[mode]; - - if (s2io_on_nec_bridge(nic->pdev)) { - DBG_PRINT(ERR_DBG, "%s: Device is on PCI-E bus\n", - nic->dev->name); - return mode; - } - - switch (mode) { - case PCI_MODE_PCI_33: - pcimode = "33MHz PCI bus"; - break; - case PCI_MODE_PCI_66: - pcimode = "66MHz PCI bus"; - break; - case PCI_MODE_PCIX_M1_66: - pcimode = "66MHz PCIX(M1) bus"; - break; - case PCI_MODE_PCIX_M1_100: - pcimode = "100MHz PCIX(M1) bus"; - break; - case PCI_MODE_PCIX_M1_133: - pcimode = "133MHz PCIX(M1) bus"; - break; - case PCI_MODE_PCIX_M2_66: - pcimode = "133MHz PCIX(M2) bus"; - break; - case PCI_MODE_PCIX_M2_100: - pcimode = "200MHz PCIX(M2) bus"; - break; - cas |